@bepalo/jwt
Version:
A secure and tested json-web-token class-based utility library for generating keys, signing, verifying, and decoding JWT payloads for use with your high-security demanding projects.
738 lines • 31.6 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _JWT_instances, _a, _JWT_alg, _JWT_algorithm, _JWT_privateKey, _JWT_publicKey, _JWT_isAsymmetric, _JWT_timingSafeEqual, _JWT_signData, _JWT_verifySignature, _JWT_validateAudience, _JWT_validateClaims, _JWT_safelyParseJson;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JWT = exports.validJwtAlgorithms = exports.validJwtAsymmetricAlgorithms = exports.validJwtSymmetricAlgorithms = exports.JwtError = exports.JwtErrorCode = void 0;
/**
* A secure and tested json-web-token class-based utility library for generating keys, signing,
* verifying, and decoding JWT payloads for use with your high-security projects.
*
* @module @bepalo/jwt
* @exports JWT class
* @exports JwtKey type
* @exports JwtVerifyOptions type
* @exports JwtHeader type
* @exports JwtPayload type
* @exports JwtResult type
* @exports JwtErrorCode enum
* @exports JwtError class
* @exports validJwtSymmetricAlgorithms
* @exports validJwtAsymmetricAlgorithms
* @exports validJwtAlgorithms
* @exports JwtSymmetricAlgorithm type
* @exports JwtAsymmetricAlgorithm type
* @exports JwtAlgorithm type
* @exports SURecord type
*/
const node_crypto_1 = require("node:crypto");
const time_1 = require("@bepalo/time");
const node_buffer_1 = require("node:buffer");
/**
* Smart Error codes for use with this JWT library
*/
var JwtErrorCode;
(function (JwtErrorCode) {
JwtErrorCode[JwtErrorCode["internalError"] = 0] = "internalError";
JwtErrorCode[JwtErrorCode["invalid"] = 100] = "invalid";
JwtErrorCode[JwtErrorCode["tokenInvalid"] = 110] = "tokenInvalid";
JwtErrorCode[JwtErrorCode["tokenTypeInvalid"] = 111] = "tokenTypeInvalid";
JwtErrorCode[JwtErrorCode["tokenHeaderInvalid"] = 120] = "tokenHeaderInvalid";
JwtErrorCode[JwtErrorCode["algorithmInvalid"] = 130] = "algorithmInvalid";
JwtErrorCode[JwtErrorCode["algorithmMismatch"] = 131] = "algorithmMismatch";
JwtErrorCode[JwtErrorCode["signatureInvalid"] = 140] = "signatureInvalid";
JwtErrorCode[JwtErrorCode["signatureMismatch"] = 141] = "signatureMismatch";
JwtErrorCode[JwtErrorCode["payloadInvalid"] = 150] = "payloadInvalid";
// for use with your custom validation errors
JwtErrorCode[JwtErrorCode["claimInvalid"] = 200] = "claimInvalid";
JwtErrorCode[JwtErrorCode["claimMismatch"] = 201] = "claimMismatch";
JwtErrorCode[JwtErrorCode["jti"] = 210] = "jti";
JwtErrorCode[JwtErrorCode["jtiMismatch"] = 210] = "jtiMismatch";
JwtErrorCode[JwtErrorCode["jtId"] = 210] = "jtId";
JwtErrorCode[JwtErrorCode["jtIdMismatch"] = 210] = "jtIdMismatch";
JwtErrorCode[JwtErrorCode["iss"] = 220] = "iss";
JwtErrorCode[JwtErrorCode["issMismatch"] = 220] = "issMismatch";
JwtErrorCode[JwtErrorCode["issuer"] = 220] = "issuer";
JwtErrorCode[JwtErrorCode["issuerMismatch"] = 220] = "issuerMismatch";
JwtErrorCode[JwtErrorCode["sub"] = 230] = "sub";
JwtErrorCode[JwtErrorCode["subMismatch"] = 230] = "subMismatch";
JwtErrorCode[JwtErrorCode["subjet"] = 230] = "subjet";
JwtErrorCode[JwtErrorCode["subjectMismatch"] = 230] = "subjectMismatch";
JwtErrorCode[JwtErrorCode["aud"] = 240] = "aud";
JwtErrorCode[JwtErrorCode["audMismatch"] = 240] = "audMismatch";
JwtErrorCode[JwtErrorCode["audience"] = 240] = "audience";
JwtErrorCode[JwtErrorCode["audienceMismatch"] = 240] = "audienceMismatch";
JwtErrorCode[JwtErrorCode["exp"] = 250] = "exp";
JwtErrorCode[JwtErrorCode["expired"] = 250] = "expired";
JwtErrorCode[JwtErrorCode["nbf"] = 260] = "nbf";
JwtErrorCode[JwtErrorCode["notValidYet"] = 260] = "notValidYet";
JwtErrorCode[JwtErrorCode["notYetValid"] = 260] = "notYetValid";
JwtErrorCode[JwtErrorCode["notBefore"] = 260] = "notBefore";
JwtErrorCode[JwtErrorCode["keyInvalid"] = 300] = "keyInvalid";
JwtErrorCode[JwtErrorCode["privateKeyInvalid"] = 301] = "privateKeyInvalid";
JwtErrorCode[JwtErrorCode["publicKeyInvalid"] = 302] = "publicKeyInvalid";
})(JwtErrorCode || (exports.JwtErrorCode = JwtErrorCode = {}));
/**
* Error class for use with this JWT library
*/
class JwtError extends Error {
constructor(message, code = JwtErrorCode.internalError) {
super(message);
this.code = code;
}
}
exports.JwtError = JwtError;
/**
* Internal mapping of algorithms to Node.js crypto identifiers.
*/
var JwtAlgorithmEnum;
(function (JwtAlgorithmEnum) {
JwtAlgorithmEnum["HS256"] = "sha256";
JwtAlgorithmEnum["HS384"] = "sha384";
JwtAlgorithmEnum["HS512"] = "sha512";
JwtAlgorithmEnum["RS256"] = "RSA-SHA256";
JwtAlgorithmEnum["RS384"] = "RSA-SHA384";
JwtAlgorithmEnum["RS512"] = "RSA-SHA512";
JwtAlgorithmEnum["PS256"] = "RSA-PSS-SHA256";
JwtAlgorithmEnum["PS384"] = "RSA-PSS-SHA384";
JwtAlgorithmEnum["PS512"] = "RSA-PSS-SHA512";
JwtAlgorithmEnum["ES256"] = "sha256";
JwtAlgorithmEnum["ES384"] = "sha384";
JwtAlgorithmEnum["ES512"] = "sha512";
JwtAlgorithmEnum["none"] = "none";
})(JwtAlgorithmEnum || (JwtAlgorithmEnum = {}));
/**
* Internal mapping of algorithms to Node.js crypto hash algorithms.
*/
var JwtAlgorithmHashEnum;
(function (JwtAlgorithmHashEnum) {
JwtAlgorithmHashEnum["HS256"] = "sha256";
JwtAlgorithmHashEnum["HS384"] = "sha384";
JwtAlgorithmHashEnum["HS512"] = "sha512";
JwtAlgorithmHashEnum["RS256"] = "sha256";
JwtAlgorithmHashEnum["RS384"] = "sha384";
JwtAlgorithmHashEnum["RS512"] = "sha512";
JwtAlgorithmHashEnum["PS256"] = "sha256";
JwtAlgorithmHashEnum["PS384"] = "sha384";
JwtAlgorithmHashEnum["PS512"] = "sha512";
JwtAlgorithmHashEnum["ES256"] = "sha256";
JwtAlgorithmHashEnum["ES384"] = "sha384";
JwtAlgorithmHashEnum["ES512"] = "sha512";
JwtAlgorithmHashEnum["none"] = "none";
})(JwtAlgorithmHashEnum || (JwtAlgorithmHashEnum = {}));
/**
* Internal mapping of algorithms to modulus length.
*/
var JwtAlgorithmModulusLenEnum;
(function (JwtAlgorithmModulusLenEnum) {
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["RS256"] = 2048] = "RS256";
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["RS384"] = 3072] = "RS384";
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["RS512"] = 4096] = "RS512";
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["PS256"] = 2048] = "PS256";
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["PS384"] = 3072] = "PS384";
JwtAlgorithmModulusLenEnum[JwtAlgorithmModulusLenEnum["PS512"] = 4096] = "PS512";
})(JwtAlgorithmModulusLenEnum || (JwtAlgorithmModulusLenEnum = {}));
/**
* Valid symmetric jwt algorithm sets for quick lookup
*/
exports.validJwtSymmetricAlgorithms = Object.freeze(new Set(["HS256", "HS384", "HS512"]));
/**
* Valid asymmetric jwt algorithm set for quick lookup
*/
exports.validJwtAsymmetricAlgorithms = Object.freeze(new Set([
"RS256",
"RS384",
"RS512",
"PS256",
"PS384",
"PS512",
"ES256",
"ES384",
"ES512",
]));
/**
* Valid jwt algorithm set for quick lookup
*/
exports.validJwtAlgorithms = Object.freeze(new Set([
"HS256",
"HS384",
"HS512",
"RS256",
"RS384",
"RS512",
"PS256",
"PS384",
"PS512",
"ES256",
"ES384",
"ES512",
"none",
]));
const encUtf8 = "utf-8";
const encBase64url = "base64url";
/**
* JWT class providing utility function and methods to generate keys, and sign, verify and decode tokens.
*/
class JWT {
get alg() {
return __classPrivateFieldGet(this, _JWT_alg, "f");
}
get isAsymmetric() {
return __classPrivateFieldGet(this, _JWT_isAsymmetric, "f");
}
/**
* Get the current time in seconds.
*/
static now() {
return Math.floor(Date.now() / 1000);
}
/**
* Get the given date-time in seconds.
*/
static on(date) {
return Math.floor(new Date(date).getTime() / 1000);
}
/**
* Define absolute time in seconds. eg. `JWT.for(1).Day`
*/
static for(time) {
return new time_1.Time(time);
}
/**
* Define the future time in seconds. eg. `JWT.in(10).Hours`
*/
static in(time) {
return new time_1.RelativeTime(time, _a.now());
}
/**
* Define the future time in seconds. eg. `JWT.after(5).Minutes`
*/
static after(time) {
return new time_1.RelativeTime(time, _a.now());
}
/**
* Define the past time in seconds. eg. `JWT.before(1).Week`
*/
static before(time) {
return new time_1.RelativeTime(-time, _a.now());
}
/**
* Generate a random HMAC key for HS256 (32 bytes), HS384 (48 bytes), or HS512 (64 bytes) encoded in base64url format.
*
* @throws {JwtError} If the algorithm is invalid.
*/
static genHmac(alg) {
switch (alg) {
case "HS256":
return (0, node_crypto_1.randomBytes)(32).toString(encBase64url);
case "HS384":
return (0, node_crypto_1.randomBytes)(48).toString(encBase64url);
case "HS512":
return (0, node_crypto_1.randomBytes)(64).toString(encBase64url);
default: {
throw new JwtError("invalid algorithm", JwtErrorCode.algorithmInvalid);
}
}
}
/**
* Generate a generic jwt key based on algorithm and optional parameters.
*
* HMAC: HS256 (32 bytes), HS384 (48 bytes), or HS512 (64 bytes) encoded in base64url format.
*
* Default options: modulusLength of RS256|PS256 (2048), RS384|PS384 (3072), RS512|PS512 (4096).
*
* @returns JwtKey { alg, publicKey, privateKey }
* @throws {JwtError} If the algorithm is invalid.
*/
static genKey(alg, options) {
var _b;
try {
switch (alg) {
case "HS256": {
const key = (0, node_crypto_1.randomBytes)(32).toString(encBase64url);
return { alg, privateKey: key, publicKey: key };
}
case "HS384": {
const key = (0, node_crypto_1.randomBytes)(48).toString(encBase64url);
return { alg, privateKey: key, publicKey: key };
}
case "HS512": {
const key = (0, node_crypto_1.randomBytes)(64).toString(encBase64url);
return { alg, privateKey: key, publicKey: key };
}
case "ES256": {
const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)("ec", {
namedCurve: "P-256",
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
},
});
return { alg, publicKey, privateKey };
}
case "ES384": {
const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)("ec", {
namedCurve: "P-384",
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
},
});
return { alg, publicKey, privateKey };
}
case "ES512": {
const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)("ec", {
namedCurve: "P-521",
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
},
});
return { alg, publicKey, privateKey };
}
case "RS256":
case "RS384":
case "RS512":
case "PS256":
case "PS384":
case "PS512": {
const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)("rsa", {
modulusLength: (_b = options === null || options === void 0 ? void 0 : options.modulusLength) !== null && _b !== void 0 ? _b : JwtAlgorithmModulusLenEnum[alg],
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs8",
format: "pem",
},
});
return { alg, publicKey, privateKey };
}
case "none": {
return { alg, publicKey: "", privateKey: "" };
}
default: {
throw new JwtError("invalid algorithm", JwtErrorCode.algorithmInvalid);
}
}
}
catch (error) {
throw new JwtError(error instanceof Error ? error.message : "internal error", JwtErrorCode.internalError);
}
}
/**
* Create a JWT instance using a symmetric algorithm.
*
* @throws {JwtError} If the secret is null/empty or the algorithm is invalid.
*/
static createSymmetric(secret, alg) {
if (!secret) {
throw new JwtError("null or empty symmetric secret", JwtErrorCode.keyInvalid);
}
if (!exports.validJwtSymmetricAlgorithms.has(alg)) {
throw new JwtError("invalid symmetric JWT algorithm", JwtErrorCode.algorithmInvalid);
}
const key = { alg, privateKey: secret, publicKey: secret };
return new _a(key, false);
}
/**
* Create a JWT instance using an asymmetric algorithm.
*
* @throws {JwtError} If the algorithm is invalid.
*/
static createAsymmetric(key) {
if (!exports.validJwtAsymmetricAlgorithms.has(key.alg)) {
throw new JwtError("invalid asymmetric JWT algorithm", JwtErrorCode.algorithmInvalid);
}
return new _a(key, true);
}
/**
* Create a JWT instance using a symmetric or asymmetric algorithm.
*
* @throws {JwtError} If the algorithm is invalid.
*/
static create(key) {
if (!exports.validJwtAlgorithms.has(key.alg)) {
throw new JwtError("invalid JWT algorithm", JwtErrorCode.algorithmInvalid);
}
const isAsymmetric = exports.validJwtAsymmetricAlgorithms.has(key.alg);
return new _a(key, isAsymmetric);
}
constructor(key, isAsymmetric) {
_JWT_instances.add(this);
_JWT_alg.set(this, void 0);
_JWT_algorithm.set(this, void 0);
_JWT_privateKey.set(this, void 0);
_JWT_publicKey.set(this, void 0);
_JWT_isAsymmetric.set(this, false);
if (key.alg !== "none" && !(key.privateKey || key.publicKey)) {
throw new JwtError("null or empty JWT private and public key. either are required", JwtErrorCode.keyInvalid);
}
__classPrivateFieldSet(this, _JWT_alg, key.alg, "f");
__classPrivateFieldSet(this, _JWT_algorithm, JwtAlgorithmEnum[key.alg], "f");
__classPrivateFieldSet(this, _JWT_privateKey, key.privateKey, "f");
__classPrivateFieldSet(this, _JWT_publicKey, key.publicKey, "f");
__classPrivateFieldSet(this, _JWT_isAsymmetric, isAsymmetric, "f");
}
/**
* Synchronously sign a payload and return a JWT token string.
*
* @throws {JwtError} If signing fails due to an invalid algorithm or key.
*/
signSync(payload) {
const alg = __classPrivateFieldGet(this, _JWT_alg, "f");
const algorithm = __classPrivateFieldGet(this, _JWT_algorithm, "f");
const header = node_buffer_1.Buffer.from(JSON.stringify({ typ: "JWT", alg }), encUtf8).toString(encBase64url);
const payload_ = node_buffer_1.Buffer.from(JSON.stringify(payload), encUtf8).toString(encBase64url);
const dataToSign = `${header}.${payload_}`;
try {
const signature = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_signData).call(this, alg, algorithm, dataToSign);
return `${dataToSign}.${signature}`;
}
catch (error) {
throw new JwtError(error instanceof Error ? error.message : "internal error", JwtErrorCode.internalError);
}
}
/**
* Asynchronously sign a payload and return a JWT token string.
*
* @throws {JwtError} If signing fails due to an invalid token.
*/
sign(payload) {
return new Promise((resolve, reject) => {
try {
const token = this.signSync(payload);
resolve(token);
}
catch (error) {
reject(error);
}
});
}
/**
* Synchronously verify only the token and the signature (no payload or claims are checked).
*
* @returns a JwtResult with only the valid propery set to true on success.
* @throws {JwtError} If the token is malformed or the signature is invalid.
*/
verifySignatureSync(token, verifyJwt) {
verifyJwt = Object.assign({ strict: true }, verifyJwt);
const [header, body, signature] = token.split(".", 3);
if (!(header && body)) {
return { valid: false, error: new JwtError("invalid token", JwtErrorCode.tokenInvalid) };
}
const jwtHeader = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_safelyParseJson).call(this, node_buffer_1.Buffer.from(header, encBase64url).toString(encUtf8));
if (!jwtHeader) {
return {
valid: false,
error: new JwtError("invalid token header", JwtErrorCode.tokenHeaderInvalid),
};
}
const { typ, alg } = jwtHeader;
if (typ !== "JWT") {
return {
valid: false,
error: new JwtError("invalid token type", JwtErrorCode.tokenTypeInvalid),
};
}
if (verifyJwt.strict && __classPrivateFieldGet(this, _JWT_alg, "f") !== alg) {
return {
valid: false,
error: new JwtError("algorithm mismatch", JwtErrorCode.algorithmMismatch),
};
}
if (!alg || !exports.validJwtAlgorithms.has(alg)) {
return {
valid: false,
error: new JwtError("invalid algorithm", JwtErrorCode.algorithmInvalid),
};
}
if (!signature && alg !== "none") {
return {
valid: false,
error: new JwtError("invalid signature", JwtErrorCode.signatureInvalid),
};
}
const algorithm = JwtAlgorithmEnum[alg];
const dataToVerify = `${header}.${body}`;
try {
const signaturesMatch = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_verifySignature).call(this, alg, algorithm, dataToVerify, signature);
if (!signaturesMatch) {
return {
valid: false,
error: new JwtError("signature mismatch", JwtErrorCode.signatureMismatch),
};
}
}
catch (error) {
return {
valid: false,
error: new JwtError(error instanceof Error ? error.message : "internal error", JwtErrorCode.internalError),
};
}
return { valid: true };
}
/**
* Asynchronously verify only the signature of the token (no claims checked).
*
* @returns a Promise to a boolean set to true on success.
* @throws {JwtError} If the token is malformed or the signature is invalid.
*/
verifySignature(token, verifyJwt) {
return new Promise((resolve, reject) => {
const { valid, error } = this.verifySignatureSync(token, verifyJwt);
if (!valid) {
return reject(error);
}
resolve(valid);
});
}
/**
* Synchronously verify a token, signature, payload and claims.
*
* @returns a JwtResult with a valid payload and the valid propery set to true on success.
* @throws {JwtError} If the token, payload, signature, or claims are invalid.
*/
verifySync(token, verifyJwt) {
verifyJwt = Object.assign({ strict: true, exp: true, nbf: true }, verifyJwt);
const [header, body, signature] = token.split(".", 3);
if (!(header && body)) {
return { valid: false, error: new JwtError("invalid token", JwtErrorCode.tokenInvalid) };
}
const jwtHeader = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_safelyParseJson).call(this, node_buffer_1.Buffer.from(header, encBase64url).toString(encUtf8));
if (!jwtHeader) {
return {
valid: false,
error: new JwtError("invalid token header", JwtErrorCode.tokenHeaderInvalid),
};
}
const { typ, alg } = jwtHeader;
if (typ !== "JWT") {
return {
valid: false,
error: new JwtError("invalid token type", JwtErrorCode.tokenTypeInvalid),
};
}
if (verifyJwt.strict && __classPrivateFieldGet(this, _JWT_alg, "f") !== alg) {
return {
valid: false,
error: new JwtError("algorithm mismatch", JwtErrorCode.algorithmMismatch),
};
}
if (!alg || !exports.validJwtAlgorithms.has(alg)) {
return {
valid: false,
error: new JwtError("invalid algorithm", JwtErrorCode.algorithmInvalid),
};
}
if (!signature && alg !== "none") {
return {
valid: false,
error: new JwtError("invalid signature", JwtErrorCode.signatureInvalid),
};
}
const algorithm = JwtAlgorithmEnum[alg];
const dataToVerify = `${header}.${body}`;
try {
const signaturesMatch = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_verifySignature).call(this, alg, algorithm, dataToVerify, signature);
if (!signaturesMatch) {
return {
valid: false,
error: new JwtError("signature mismatch", JwtErrorCode.signatureMismatch),
};
}
const jwtPayload = __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_safelyParseJson).call(this, node_buffer_1.Buffer.from(body, encBase64url).toString(encUtf8));
if (!jwtPayload) {
return {
valid: false,
error: new JwtError("invalid payload", JwtErrorCode.payloadInvalid),
};
}
return __classPrivateFieldGet(this, _JWT_instances, "m", _JWT_validateClaims).call(this, jwtPayload, verifyJwt);
}
catch (error) {
return {
valid: false,
error: new JwtError(error instanceof Error ? error.message : "internal error", JwtErrorCode.internalError),
};
}
}
/**
* Asynchronously verify a token, signature, payload and claims.
*
* @returns a Promise to a valid payload on success.
* @throws {JwtError} If the token, payload, signature, or claims are invalid.
*/
verify(token, verifyJwt) {
return new Promise((resolve, reject) => {
const { valid, payload, error } = this.verifySync(token, verifyJwt);
if (!(valid && payload)) {
return reject(error);
}
resolve(payload);
});
}
}
exports.JWT = JWT;
_a = JWT, _JWT_alg = new WeakMap(), _JWT_algorithm = new WeakMap(), _JWT_privateKey = new WeakMap(), _JWT_publicKey = new WeakMap(), _JWT_isAsymmetric = new WeakMap(), _JWT_instances = new WeakSet(), _JWT_timingSafeEqual = function _JWT_timingSafeEqual(a, b) {
if (a.byteLength !== b.byteLength) {
return false;
}
return (0, node_crypto_1.timingSafeEqual)(a, b);
}, _JWT_signData = function _JWT_signData(alg, algorithm, dataToSign) {
switch (alg) {
case "HS256":
case "HS384":
case "HS512":
if (!__classPrivateFieldGet(this, _JWT_privateKey, "f")) {
throw new JwtError("null or empty JWT private key", JwtErrorCode.privateKeyInvalid);
}
return (0, node_crypto_1.createHmac)(algorithm, __classPrivateFieldGet(this, _JWT_privateKey, "f"), { encoding: encBase64url })
.update(dataToSign)
.digest(encBase64url);
case "ES256":
case "ES384":
case "ES512":
case "RS256":
case "RS384":
case "RS512":
if (!__classPrivateFieldGet(this, _JWT_privateKey, "f")) {
throw new JwtError("null or empty JWT private key", JwtErrorCode.privateKeyInvalid);
}
return (0, node_crypto_1.createSign)(algorithm)
.update(dataToSign)
.sign(__classPrivateFieldGet(this, _JWT_privateKey, "f"), encBase64url);
case "PS256":
case "PS384":
case "PS512":
if (!__classPrivateFieldGet(this, _JWT_privateKey, "f")) {
throw new JwtError("null or empty JWT private key", JwtErrorCode.privateKeyInvalid);
}
return (0, node_crypto_1.sign)(JwtAlgorithmHashEnum[alg], node_buffer_1.Buffer.from(dataToSign, encUtf8), {
key: __classPrivateFieldGet(this, _JWT_privateKey, "f"),
padding: node_crypto_1.constants.RSA_PKCS1_PSS_PADDING,
saltLength: node_crypto_1.constants.RSA_PSS_SALTLEN_DIGEST,
}).toString(encBase64url);
// case "none":
default:
return "";
}
}, _JWT_verifySignature = function _JWT_verifySignature(alg, algorithm, dataToVerify, signature) {
switch (alg) {
case "HS256":
case "HS384":
case "HS512":
if (!__classPrivateFieldGet(this, _JWT_publicKey, "f")) {
throw new JwtError("null or empty JWT public key", JwtErrorCode.publicKeyInvalid);
}
return __classPrivateFieldGet(_a, _a, "m", _JWT_timingSafeEqual).call(_a, (0, node_crypto_1.createHmac)(algorithm, __classPrivateFieldGet(this, _JWT_publicKey, "f"), { encoding: encBase64url })
.update(dataToVerify).digest(), node_buffer_1.Buffer.from(signature, encBase64url));
case "ES256":
case "ES384":
case "ES512":
case "RS256":
case "RS384":
case "RS512":
if (!__classPrivateFieldGet(this, _JWT_publicKey, "f")) {
throw new JwtError("null or empty JWT public key", JwtErrorCode.publicKeyInvalid);
}
return (0, node_crypto_1.createVerify)(algorithm)
.update(dataToVerify)
.verify(__classPrivateFieldGet(this, _JWT_publicKey, "f"), signature, encBase64url);
case "PS256":
case "PS384":
case "PS512":
if (!__classPrivateFieldGet(this, _JWT_publicKey, "f")) {
throw new JwtError("null or empty JWT public key", JwtErrorCode.publicKeyInvalid);
}
return (0, node_crypto_1.verify)(JwtAlgorithmHashEnum[alg], node_buffer_1.Buffer.from(dataToVerify, encUtf8), {
key: __classPrivateFieldGet(this, _JWT_publicKey, "f"),
padding: node_crypto_1.constants.RSA_PKCS1_PSS_PADDING,
saltLength: node_crypto_1.constants.RSA_PSS_SALTLEN_DIGEST,
}, node_buffer_1.Buffer.from(signature, encBase64url));
case "none":
return signature === "";
default:
throw new JwtError("invalid algorithm", JwtErrorCode.algorithmInvalid);
}
}, _JWT_validateAudience = function _JWT_validateAudience(expectedAudience, audience) {
if (!audience)
return false;
if (Array.isArray(audience)) {
if (Array.isArray(expectedAudience)) {
return audience.some((actual) => expectedAudience.includes(actual));
}
return audience.includes(expectedAudience);
}
if (Array.isArray(expectedAudience)) {
return expectedAudience.includes(audience);
}
return audience === expectedAudience;
}, _JWT_validateClaims = function _JWT_validateClaims(payload, verifyJwt, now = _a.now()) {
var _b, _c;
if (verifyJwt.jti != null && payload.jti !== verifyJwt.jti) {
return {
valid: false,
error: new JwtError("jti (jwt id) mismatch", JwtErrorCode.jtiMismatch),
};
}
if (verifyJwt.iss != null && payload.iss !== verifyJwt.iss) {
return {
valid: false,
error: new JwtError("iss (issuer) mismatch", JwtErrorCode.issMismatch),
};
}
if (verifyJwt.sub != null && payload.sub !== verifyJwt.sub) {
return {
valid: false,
error: new JwtError("sub (subject) mismatch", JwtErrorCode.subMismatch),
};
}
if (verifyJwt.aud != null && !__classPrivateFieldGet(this, _JWT_instances, "m", _JWT_validateAudience).call(this, verifyJwt.aud, payload.aud)) {
return {
valid: false,
error: new JwtError("aud (audience) mismatch", JwtErrorCode.audMismatch),
};
}
if (verifyJwt.exp != null && now > payload.exp + ((_b = verifyJwt.expLeeway) !== null && _b !== void 0 ? _b : 0)) {
return { valid: false, error: new JwtError("token expired", JwtErrorCode.expired) };
}
if (verifyJwt.nbf != null && payload.nbf - ((_c = verifyJwt.nbfLeeway) !== null && _c !== void 0 ? _c : 0) > now) {
return {
valid: false,
error: new JwtError("token not yet valid (nbf)", JwtErrorCode.notValidYet),
};
}
return { valid: true, payload };
}, _JWT_safelyParseJson = function _JWT_safelyParseJson(jsonStr) {
try {
const result = JSON.parse(jsonStr);
return result;
}
catch (_err) {
return undefined;
}
};
//# sourceMappingURL=index.js.map