UNPKG

@redredgroup/samsungknox-token-library

Version:

utility that creates and signs SamsungKnox Tokens using server-side JavaScript.

157 lines (149 loc) 4.94 kB
// 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 };