@redredgroup/samsungknox-token-library
Version:
utility that creates and signs SamsungKnox Tokens using server-side JavaScript.
157 lines (149 loc) • 4.94 kB
JavaScript
// src/utils/export-private-key.ts
import NodeRSA from "node-rsa";
var exportCredentialPrivateKey = ({ credential }) => {
const rsaPrivateKey = new NodeRSA(credential.Private, "pkcs8-private-pem");
const privateKey = rsaPrivateKey.exportKey("pkcs8-private-pem");
return { privateKey };
};
// src/utils/export-public-der-key.ts
import NodeRSA2 from "node-rsa";
import Forge from "node-forge";
var exportCredentialPublicDerKey = ({ credential }) => {
const rsaPublicKey = new NodeRSA2(credential.Public, "pkcs8-public-pem");
const exportpublicKey = rsaPublicKey.exportKey("pkcs8-public-pem");
const forgePublicKey = Forge.pki.publicKeyFromPem(exportpublicKey);
const derBuffer = Forge.asn1.toDer(Forge.pki.publicKeyToAsn1(forgePublicKey));
const publicKey = Forge.util.encode64(derBuffer.getBytes());
return { publicKey };
};
// src/utils/init-credential.ts
import fs from "fs";
import { isNil } from "lodash-es";
import * as jwt from "jsonwebtoken";
// src/common/error.common.ts
var ERRORS = {
INVALID_JWT: "clientIdentifierJwtToken is not a json web token type. check your clientIdentifierJwtToken",
BOTH_CREDENTIAL_DETECTED: "credentials exceeded one. You must specify either key or path.",
CREDENTIAL_MISSING: "credential is missing. Please check the credential file or path,",
CREDENTIAL_IS_NOT_JSON_TYPE: "credential is not json type. Please check the credential file or path,",
IDENTIFIER_MISSING: "credential -> identifier is missing. Please check the credential file or path.",
PRIVATE_MISSING: "credential -> Private is missing. Please check the credential file or path.",
PUBLIC_MISSING: "credential -> Public is missing. Please check the credential file or path."
};
// src/utils/init-credential.ts
var validateJWT = (token) => {
const decoded = jwt.decode(token);
if (!decoded) {
throw new TypeError(ERRORS.INVALID_JWT);
}
};
var readCredential = (credential) => {
if (credential.path && credential.key) {
throw new TypeError(ERRORS.BOTH_CREDENTIAL_DETECTED);
}
try {
if (credential.path) {
return JSON.parse(fs.readFileSync(credential.path, "utf8"));
}
if (credential.key) {
return JSON.parse(credential.key);
}
} catch (e) {
throw new TypeError(ERRORS.CREDENTIAL_IS_NOT_JSON_TYPE);
}
return null;
};
var initCredential = async ({
credential,
clientIdentifierJwtToken
}) => {
if (clientIdentifierJwtToken) {
validateJWT(clientIdentifierJwtToken);
}
const credentialManifest = readCredential(credential);
if (isNil(credentialManifest)) {
throw new TypeError(ERRORS.CREDENTIAL_MISSING);
}
if (isNil(credentialManifest.Identifier)) {
throw new TypeError(ERRORS.IDENTIFIER_MISSING);
}
if (isNil(credentialManifest.Private)) {
throw new TypeError(ERRORS.PRIVATE_MISSING);
}
if (isNil(credentialManifest.Public)) {
throw new TypeError(ERRORS.PUBLIC_MISSING);
}
return credentialManifest;
};
// src/utils/generate-jwt-id.ts
import { v1 } from "uuid";
var generateJwtId = () => {
const generateJwtId2 = v1() + v1();
return generateJwtId2;
};
// src/utils/generate-signed-jwt.ts
import jwt2 from "jsonwebtoken";
var jwtSignOptionsBase = {
audience: "KnoxWSM",
expiresIn: "30m",
algorithm: "RS512"
};
var generateSignedJWT = async ({
credential: { key, path },
isClientIdentifier,
tokenOrAccess
}) => {
const credential = await initCredential({
credential: {
path,
key
},
clientIdentifierJwtToken: isClientIdentifier ? tokenOrAccess : void 0
});
const { privateKey } = exportCredentialPrivateKey({ credential });
const { publicKey } = exportCredentialPublicDerKey({ credential });
const payload = {
publicKey
};
if (isClientIdentifier) {
payload.clientIdentifier = tokenOrAccess;
} else {
payload.accessToken = tokenOrAccess;
}
const jwtSignOptions = { ...jwtSignOptionsBase, jwtid: generateJwtId() };
const signJwtToken = jwt2.sign(payload, privateKey, jwtSignOptions);
return { accessToken: signJwtToken };
};
// src/index.ts
var generateSignedClientIdentifierJWT = async (params) => generateSignedJWT({
credential: {
key: params.credential.key,
path: params.credential.path
},
tokenOrAccess: params.clientIdentifierJwtToken,
isClientIdentifier: true
});
var generateSignedAccessTokenJWT = async (params) => generateSignedJWT({
credential: {
key: params.credential.key,
path: params.credential.path
},
tokenOrAccess: params.accessToken,
isClientIdentifier: false
});
var generateBase64EncodedStringPublicKey = async (params) => {
const { publicKey } = exportCredentialPublicDerKey({
credential: await initCredential({
credential: {
key: params.credential.key,
path: params.credential.path
}
})
});
return { publicKey };
};
export {
generateBase64EncodedStringPublicKey,
generateSignedAccessTokenJWT,
generateSignedClientIdentifierJWT
};