Socket
Socket
Sign inDemoInstall

jose

Package Overview
Dependencies
Maintainers
1
Versions
206
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jose - npm Package Compare versions

Comparing version 3.0.2 to 3.1.0

dist/browser/jwk/from_key_like.js

9

CHANGELOG.md

@@ -5,2 +5,11 @@ # Changelog

## [3.1.0](https://github.com/panva/jose/compare/v3.0.2...v3.1.0) (2020-11-22)
### Features
* added "KeyLike to JWK" module ([7a8418e](https://github.com/panva/jose/commit/7a8418eadd68b645fb7edf78873a35980ea8e41d)), closes [#109](https://github.com/panva/jose/issues/109)
* allow compact verify/decrypt tokens to be uint8array encoded ([e39c3db](https://github.com/panva/jose/commit/e39c3dba75e5ae70697e6a4f93096c492a265c07))
* allow http.Agent and https.Agent passed in remote JWK Set ([38494a8](https://github.com/panva/jose/commit/38494a88828a8df2015efa78ca29c1a6317a3a50))
## [3.0.2](https://github.com/panva/jose/compare/v3.0.1...v3.0.2) (2020-11-15)

@@ -7,0 +16,0 @@

16

dist/browser/jwe/compact/decrypt.js
import decrypt from '../flattened/decrypt.js';
import { JWEInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactDecrypt(jwe, key, options) {
if (jwe instanceof Uint8Array) {
jwe = decoder.decode(jwe);
}
if (typeof jwe !== 'string') {
throw new JWEInvalid('Compact JWE must be a string');
throw new JWEInvalid('Compact JWE must be a string or Uint8Array');
}

@@ -12,9 +16,9 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split('.');

const decrypted = await decrypt({
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined),
iv: (iv || undefined),
protected: protectedHeader || undefined,
tag: (tag || undefined),
encrypted_key: encryptedKey || undefined,
}, key, options);
return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
}

@@ -21,27 +21,27 @@ import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';

}
if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new JWEInvalid('JOSE Header missing');
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new JWEInvalid('JWE Initialization Vector missing or incorrect type');
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new JWEInvalid('JWE Ciphertext missing or incorrect type');
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new JWEInvalid('JWE Authentication Tag missing or incorrect type');
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new JWEInvalid('JWE Protected Header incorrect type');
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new JWEInvalid('JWE Encrypted Key incorrect type');
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new JWEInvalid('JWE AAD incorrect type');
}
if ('header' in jwe && !isObject(jwe.header)) {
if (jwe.header !== undefined && !isObject(jwe.header)) {
throw new JWEInvalid('JWE Shared Unprotected Header incorrect type');
}
if ('unprotected' in jwe && !isObject(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {
throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');

@@ -63,3 +63,3 @@ }

checkCrit(parsedProt, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -73,6 +73,6 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');

@@ -89,3 +89,3 @@ }

let encryptedKey;
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url(jwe.encrypted_key);

@@ -110,3 +110,3 @@ }

let additionalData;
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = concat(protectedHeader, encoder.encode('.'), encoder.encode(jwe.aad));

@@ -122,12 +122,12 @@ }

const result = { plaintext };
if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url(jwe.aad);
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected;
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header;

@@ -134,0 +134,0 @@ }

@@ -76,3 +76,3 @@ import ivFactory from '../../lib/iv.js';

checkCrit(this._protectedHeader, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -86,7 +86,7 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing');
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
}
if (!enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing');
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
}

@@ -93,0 +93,0 @@ let encryptedKey;

@@ -24,3 +24,3 @@ import { decode as base64url } from '../runtime/base64url.js';

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is unsupported');

@@ -27,0 +27,0 @@ }

@@ -24,2 +24,3 @@ import parseJWK from '../jwk/parse.js';

this._url = new URL(url.href);
this._options = { agent: options === null || options === void 0 ? void 0 : options.agent };
this._timeoutDuration =

@@ -91,3 +92,3 @@ typeof (options === null || options === void 0 ? void 0 : options.timeoutDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.timeoutDuration : 5000;

const cached = this._cached.get(jwk);
if (!(protectedHeader.alg in cached)) {
if (cached[protectedHeader.alg] === undefined) {
const keyObject = (await parseJWK({ ...jwk, alg: protectedHeader.alg }));

@@ -103,7 +104,6 @@ if (keyObject.type !== 'public') {

if (!this._pendingFetch) {
this._pendingFetch = fetchJson(this._url, this._timeoutDuration)
this._pendingFetch = fetchJson(this._url, this._timeoutDuration, this._options)
.then((json) => {
if (typeof json !== 'object' ||
!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -110,0 +110,0 @@ json.keys.some((key) => typeof key !== 'object' || !key)) {

import verify from '../flattened/verify.js';
import { JWSInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactVerify(jws, key, options) {
if (jws instanceof Uint8Array) {
jws = decoder.decode(jws);
}
if (typeof jws !== 'string') {
throw new JWSInvalid('Compact JWS must be a string');
throw new JWSInvalid('Compact JWS must be a string or Uint8Array');
}

@@ -11,4 +15,8 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.');

}
const verified = await verify({ payload, protected: protectedHeader, signature }, key, options);
const verified = await verify({
payload: (payload || undefined),
protected: protectedHeader || undefined,
signature: (signature || undefined),
}, key, options);
return { payload: verified.payload, protectedHeader: verified.protectedHeader };
}

@@ -47,4 +47,4 @@ import isDisjoint from '../../lib/is_disjoint.js';

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -51,0 +51,0 @@ checkKeyType(alg, key);

@@ -16,15 +16,15 @@ import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';

}
if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new JWSInvalid('JWS Protected Header incorrect type');
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new JWSInvalid('JWS Payload missing');
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new JWSInvalid('JWS Signature missing or incorrect type');
}
if ('header' in jws && !isObject(jws.header)) {
if (jws.header !== undefined && !isObject(jws.header)) {
throw new JWSInvalid('JWS Unprotected Header incorrect type');

@@ -53,4 +53,4 @@ }

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -90,6 +90,6 @@ const algorithms = options && checkAlgOption(options.algorithms);

const result = { payload };
if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header;

@@ -96,0 +96,0 @@ }

@@ -8,9 +8,9 @@ import decrypt from '../jwe/compact/decrypt.js';

const { protectedHeader } = decrypted;
if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch');
}
if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch');
}
if ('aud' in protectedHeader &&
if (protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {

@@ -17,0 +17,0 @@ throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');

@@ -15,3 +15,3 @@ import { JOSENotSupported, JWEInvalid } from '../util/errors.js';

function assertHeaderParameter(joseHeader, parameter, name) {
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);

@@ -37,3 +37,3 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -43,5 +43,5 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk);

let partyVInfo;
if (joseHeader.apu)
if (joseHeader.apu !== undefined)
partyUInfo = base64url(joseHeader.apu);
if (joseHeader.apv)
if (joseHeader.apv !== undefined)
partyVInfo = base64url(joseHeader.apv);

@@ -91,3 +91,3 @@ const sharedSecret = await ECDH.deriveKey(ephemeralKey, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLengths.get(joseHeader.enc), partyUInfo, partyVInfo);

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -94,0 +94,0 @@ }

@@ -25,3 +25,3 @@ import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js';

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -80,3 +80,3 @@ const { apu, apv } = providedParameters;

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -83,0 +83,0 @@ }

@@ -57,11 +57,11 @@ import { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors.js';

const now = epoch(currentDate || new Date());
if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
}
}
if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -74,3 +74,3 @@ throw new JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid');

}
if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -77,0 +77,0 @@ throw new JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid');

@@ -10,3 +10,3 @@ const minute = 60;

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`);
throw new TypeError('invalid time period format');
}

@@ -13,0 +13,0 @@ const value = parseFloat(matched[1]);

import { JOSENotSupported } from '../util/errors.js';
const isString = (input) => typeof input !== 'string' || input.length === 0;
function validateCrit(Err, supported, protectedHeader, joseHeader) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([]);
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set();
}
if (!Array.isArray(protectedHeader.crit) ||
protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)) {
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');

@@ -19,6 +18,6 @@ }

}
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
}
else if (supported.get(parameter) && !(parameter in protectedHeader)) {
else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);

@@ -25,0 +24,0 @@ }

@@ -27,4 +27,5 @@ import { JWEInvalid, JOSENotSupported } from '../util/errors.js';

}
if ('algorithm' in cek) {
if (cek.algorithm.length !== expected) {
if (cek.algorithm !== undefined) {
const { length } = cek.algorithm;
if (length !== expected) {
throw new JWEInvalid('Invalid Content Encryption Key length');

@@ -31,0 +32,0 @@ }

export default (alg, key) => {
if (alg.startsWith('HS')) {
const bitlen = parseInt(alg.substr(-3), 10);
if (!('length' in key.algorithm) || key.algorithm.length < bitlen) {
const { length } = key.algorithm;
if (typeof length !== 'number' || length < bitlen) {
throw new TypeError(`${alg} requires symmetric keys to be ${bitlen} bits or larger`);

@@ -9,4 +10,4 @@ }

if (alg.startsWith('RS') || alg.startsWith('PS')) {
if (!('modulusLength' in key.algorithm) ||
key.algorithm.modulusLength < 2048) {
const { modulusLength } = key.algorithm;
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);

@@ -13,0 +14,0 @@ }

@@ -9,6 +9,4 @@ import { concat, uint64be } from '../lib/buffer_utils.js';

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await crypto.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'decrypt',
]);
const macKey = await crypto.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['decrypt']);
const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -15,0 +13,0 @@ name: 'HMAC',

@@ -7,6 +7,4 @@ import { concat, uint64be } from '../lib/buffer_utils.js';

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await crypto.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'encrypt',
]);
const macKey = await crypto.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt']);
const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -13,0 +11,0 @@ name: 'HMAC',

@@ -5,5 +5,9 @@ "use strict";

const errors_js_1 = require("../../util/errors.js");
const buffer_utils_js_1 = require("../../lib/buffer_utils.js");
async function compactDecrypt(jwe, key, options) {
if (jwe instanceof Uint8Array) {
jwe = buffer_utils_js_1.decoder.decode(jwe);
}
if (typeof jwe !== 'string') {
throw new errors_js_1.JWEInvalid('Compact JWE must be a string');
throw new errors_js_1.JWEInvalid('Compact JWE must be a string or Uint8Array');
}

@@ -15,7 +19,7 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split('.');

const decrypted = await decrypt_js_1.default({
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined),
iv: (iv || undefined),
protected: protectedHeader || undefined,
tag: (tag || undefined),
encrypted_key: encryptedKey || undefined,
}, key, options);

@@ -22,0 +26,0 @@ return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };

@@ -23,27 +23,27 @@ "use strict";

}
if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new errors_js_1.JWEInvalid('JOSE Header missing');
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Initialization Vector missing or incorrect type');
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Ciphertext missing or incorrect type');
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Authentication Tag missing or incorrect type');
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Protected Header incorrect type');
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Encrypted Key incorrect type');
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new errors_js_1.JWEInvalid('JWE AAD incorrect type');
}
if ('header' in jwe && !is_object_js_1.default(jwe.header)) {
if (jwe.header !== undefined && !is_object_js_1.default(jwe.header)) {
throw new errors_js_1.JWEInvalid('JWE Shared Unprotected Header incorrect type');
}
if ('unprotected' in jwe && !is_object_js_1.default(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !is_object_js_1.default(jwe.unprotected)) {
throw new errors_js_1.JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');

@@ -65,3 +65,3 @@ }

checkCrit(parsedProt, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -75,6 +75,6 @@ throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new errors_js_1.JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');

@@ -91,3 +91,3 @@ }

let encryptedKey;
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url_js_1.decode(jwe.encrypted_key);

@@ -112,3 +112,3 @@ }

let additionalData;
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = buffer_utils_js_1.concat(protectedHeader, buffer_utils_js_1.encoder.encode('.'), buffer_utils_js_1.encoder.encode(jwe.aad));

@@ -124,12 +124,12 @@ }

const result = { plaintext };
if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url_js_1.decode(jwe.aad);
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected;
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header;

@@ -136,0 +136,0 @@ }

@@ -78,3 +78,3 @@ "use strict";

checkCrit(this._protectedHeader, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -88,7 +88,7 @@ throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
throw new errors_js_1.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
}
if (!enc) {
throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing');
if (typeof enc !== 'string' || !enc) {
throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
}

@@ -95,0 +95,0 @@ let encryptedKey;

@@ -26,3 +26,3 @@ "use strict";

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new errors_js_1.JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is unsupported');

@@ -29,0 +29,0 @@ }

@@ -26,2 +26,3 @@ "use strict";

this._url = new URL(url.href);
this._options = { agent: options === null || options === void 0 ? void 0 : options.agent };
this._timeoutDuration =

@@ -93,3 +94,3 @@ typeof (options === null || options === void 0 ? void 0 : options.timeoutDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.timeoutDuration : 5000;

const cached = this._cached.get(jwk);
if (!(protectedHeader.alg in cached)) {
if (cached[protectedHeader.alg] === undefined) {
const keyObject = (await parse_js_1.default({ ...jwk, alg: protectedHeader.alg }));

@@ -105,7 +106,6 @@ if (keyObject.type !== 'public') {

if (!this._pendingFetch) {
this._pendingFetch = fetch_js_1.default(this._url, this._timeoutDuration)
this._pendingFetch = fetch_js_1.default(this._url, this._timeoutDuration, this._options)
.then((json) => {
if (typeof json !== 'object' ||
!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -112,0 +112,0 @@ json.keys.some((key) => typeof key !== 'object' || !key)) {

@@ -5,5 +5,9 @@ "use strict";

const errors_js_1 = require("../../util/errors.js");
const buffer_utils_js_1 = require("../../lib/buffer_utils.js");
async function compactVerify(jws, key, options) {
if (jws instanceof Uint8Array) {
jws = buffer_utils_js_1.decoder.decode(jws);
}
if (typeof jws !== 'string') {
throw new errors_js_1.JWSInvalid('Compact JWS must be a string');
throw new errors_js_1.JWSInvalid('Compact JWS must be a string or Uint8Array');
}

@@ -14,5 +18,9 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.');

}
const verified = await verify_js_1.default({ payload, protected: protectedHeader, signature }, key, options);
const verified = await verify_js_1.default({
payload: (payload || undefined),
protected: protectedHeader || undefined,
signature: (signature || undefined),
}, key, options);
return { payload: verified.payload, protectedHeader: verified.protectedHeader };
}
exports.default = compactVerify;

@@ -49,4 +49,4 @@ "use strict";

const { alg } = joseHeader;
if (!alg) {
throw new errors_js_1.JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -53,0 +53,0 @@ check_key_type_js_1.default(alg, key);

@@ -18,15 +18,15 @@ "use strict";

}
if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new errors_js_1.JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new errors_js_1.JWSInvalid('JWS Protected Header incorrect type');
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new errors_js_1.JWSInvalid('JWS Payload missing');
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new errors_js_1.JWSInvalid('JWS Signature missing or incorrect type');
}
if ('header' in jws && !is_object_js_1.default(jws.header)) {
if (jws.header !== undefined && !is_object_js_1.default(jws.header)) {
throw new errors_js_1.JWSInvalid('JWS Unprotected Header incorrect type');

@@ -55,4 +55,4 @@ }

const { alg } = joseHeader;
if (!alg) {
throw new errors_js_1.JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -92,6 +92,6 @@ const algorithms = options && checkAlgOption(options.algorithms);

const result = { payload };
if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header;

@@ -98,0 +98,0 @@ }

@@ -10,9 +10,9 @@ "use strict";

const { protectedHeader } = decrypted;
if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new errors_js_1.JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch');
}
if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new errors_js_1.JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch');
}
if ('aud' in protectedHeader &&
if (protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {

@@ -19,0 +19,0 @@ throw new errors_js_1.JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');

@@ -17,3 +17,3 @@ "use strict";

function assertHeaderParameter(joseHeader, parameter, name) {
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new errors_js_1.JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);

@@ -39,3 +39,3 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new errors_js_1.JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -45,5 +45,5 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk);

let partyVInfo;
if (joseHeader.apu)
if (joseHeader.apu !== undefined)
partyUInfo = base64url_js_1.decode(joseHeader.apu);
if (joseHeader.apv)
if (joseHeader.apv !== undefined)
partyVInfo = base64url_js_1.decode(joseHeader.apv);

@@ -93,3 +93,3 @@ const sharedSecret = await ECDH.deriveKey(ephemeralKey, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.bitLengths.get(joseHeader.enc), partyUInfo, partyVInfo);

default: {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is unsupported`);
throw new errors_js_1.JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -96,0 +96,0 @@ }

@@ -27,3 +27,3 @@ "use strict";

if (!ECDH.ecdhAllowed(key)) {
throw new errors_js_1.JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -82,3 +82,3 @@ const { apu, apv } = providedParameters;

default: {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is unsupported`);
throw new errors_js_1.JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -85,0 +85,0 @@ }

@@ -59,11 +59,11 @@ "use strict";

const now = epoch_js_1.default(currentDate || new Date());
if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new errors_js_1.JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new errors_js_1.JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
}
}
if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -76,3 +76,3 @@ throw new errors_js_1.JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid');

}
if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -79,0 +79,0 @@ throw new errors_js_1.JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid');

@@ -12,3 +12,3 @@ "use strict";

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`);
throw new TypeError('invalid time period format');
}

@@ -15,0 +15,0 @@ const value = parseFloat(matched[1]);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const errors_js_1 = require("../util/errors.js");
const isString = (input) => typeof input !== 'string' || input.length === 0;
function validateCrit(Err, supported, protectedHeader, joseHeader) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([]);
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set();
}
if (!Array.isArray(protectedHeader.crit) ||
protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)) {
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');

@@ -21,6 +20,6 @@ }

}
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
}
else if (supported.get(parameter) && !(parameter in protectedHeader)) {
else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);

@@ -27,0 +26,0 @@ }

@@ -10,3 +10,3 @@ "use strict";

const generateIv = iv_js_1.default(random_js_1.default);
exports.wrap = async (alg, key, cek, iv) => {
const wrap = async (alg, key, cek, iv) => {
const jweAlgorithm = alg.substr(0, 7);

@@ -17,5 +17,7 @@ iv || (iv = await generateIv(jweAlgorithm));

};
exports.unwrap = async (alg, key, encryptedKey, iv, tag) => {
exports.wrap = wrap;
const unwrap = async (alg, key, encryptedKey, iv, tag) => {
const jweAlgorithm = alg.substr(0, 7);
return decrypt_js_1.default(jweAlgorithm, key instanceof Uint8Array ? key : key.export(), encryptedKey, iv, tag, new Uint8Array());
};
exports.unwrap = unwrap;

@@ -13,3 +13,3 @@ "use strict";

}
exports.wrap = async (alg, key, cek) => {
const wrap = async (alg, key, cek) => {
const size = parseInt(alg.substr(1, 3), 10);

@@ -25,3 +25,4 @@ const algorithm = `aes${size}-wrap`;

};
exports.unwrap = async (alg, key, encryptedKey) => {
exports.wrap = wrap;
const unwrap = async (alg, key, encryptedKey) => {
const size = parseInt(alg.substr(1, 3), 10);

@@ -37,1 +38,2 @@ const algorithm = `aes${size}-wrap`;

};
exports.unwrap = unwrap;

@@ -5,4 +5,5 @@ "use strict";

const buffer_utils_js_1 = require("../lib/buffer_utils.js");
exports.encode = (input) => Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
exports.decode = (input) => {
const encode = (input) => Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
exports.encode = encode;
const decode = (input) => {
let encoded = input;

@@ -14,1 +15,2 @@ if (encoded instanceof Uint8Array) {

};
exports.decode = decode;

@@ -43,5 +43,6 @@ "use strict";

};
exports.setModulusLength = (keyObject, modulusLength) => {
const setModulusLength = (keyObject, modulusLength) => {
weakMap.set(keyObject, modulusLength);
};
exports.setModulusLength = setModulusLength;
exports.default = (key, alg) => {

@@ -48,0 +49,0 @@ if (getModulusLength(key) < 2048) {

@@ -15,4 +15,4 @@ "use strict";

}
const encKey = cek.slice(keySize >> 3);
const macKey = cek.slice(0, keySize >> 3);
const encKey = cek.subarray(keySize >> 3);
const macKey = cek.subarray(0, keySize >> 3);
const macSize = parseInt(enc.substr(-3), 10);

@@ -19,0 +19,0 @@ const algorithm = `aes-${keySize}-cbc`;

@@ -13,3 +13,3 @@ "use strict";

const concatKdf = buffer_utils_js_1.concatKdf.bind(undefined, digest_js_1.default.bind(undefined, 'sha256'));
exports.deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) => {
const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) => {
const value = buffer_utils_js_1.concat(buffer_utils_js_1.lengthAndInput(buffer_utils_js_1.encoder.encode(algorithm)), buffer_utils_js_1.lengthAndInput(apu), buffer_utils_js_1.lengthAndInput(apv), buffer_utils_js_1.uint32be(keyLength));

@@ -19,3 +19,4 @@ const sharedSecret = crypto_1.diffieHellman({ privateKey, publicKey });

};
exports.ephemeralKeyToPublicJWK = function ephemeralKeyToPublicJWK(key) {
exports.deriveKey = deriveKey;
const ephemeralKeyToPublicJWK = function ephemeralKeyToPublicJWK(key) {
switch (key.asymmetricKeyType) {

@@ -43,3 +44,4 @@ case 'x25519':

};
exports.generateEpk = async (key) => {
exports.ephemeralKeyToPublicJWK = ephemeralKeyToPublicJWK;
const generateEpk = async (key) => {
switch (key.asymmetricKeyType) {

@@ -59,3 +61,4 @@ case 'x25519':

};
exports.publicJwkToEphemeralKey = async (jwk) => {
exports.generateEpk = generateEpk;
const publicJwkToEphemeralKey = async (jwk) => {
let pem;

@@ -101,3 +104,5 @@ switch (jwk.crv) {

};
exports.publicJwkToEphemeralKey = publicJwkToEphemeralKey;
const curves = ['P-256', 'P-384', 'P-521', 'X25519', 'X448'];
exports.ecdhAllowed = (key) => curves.includes(get_named_curve_js_1.default(key));
const ecdhAllowed = (key) => curves.includes(get_named_curve_js_1.default(key));
exports.ecdhAllowed = ecdhAllowed;

@@ -13,4 +13,4 @@ "use strict";

}
const encKey = cek.slice(keySize >> 3);
const macKey = cek.slice(0, keySize >> 3);
const encKey = cek.subarray(keySize >> 3);
const macKey = cek.subarray(0, keySize >> 3);
const algorithm = `aes-${keySize}-cbc`;

@@ -17,0 +17,0 @@ const cipher = crypto_1.createCipheriv(algorithm, encKey, iv);

@@ -12,10 +12,8 @@ "use strict";

const fetch = async (url, timeout, options) => {
if (!(url.protocol in protocols)) {
if (protocols[url.protocol] === undefined) {
throw new TypeError('Unsupported URL protocol.');
}
return new Promise((resolve, reject) => {
protocols[url.protocol](url, {
...options,
timeout,
}, async (response) => {
const { agent } = options;
protocols[url.protocol](url, { agent, timeout }, async (response) => {
if (response.statusCode !== 200) {

@@ -22,0 +20,0 @@ reject(new errors_js_1.JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response'));

@@ -16,5 +16,8 @@ "use strict";

switch (key.asymmetricKeyType) {
case 'ed25519':
case 'ed448':
return `Ed${key.asymmetricKeyType.substr(2)}`;
case 'x25519':
case 'x448':
return key.asymmetricKeyType.toUpperCase();
return `X${key.asymmetricKeyType.substr(1)}`;
case 'ec': {

@@ -25,3 +28,5 @@ if (weakMap.has(key)) {

if (key.type === 'private') {
return getNamedCurve(crypto_1.createPublicKey(key));
const curve = getNamedCurve(crypto_1.createPublicKey(key));
weakMap.set(key, curve);
return curve;
}

@@ -28,0 +33,0 @@ const buf = key.export({ format: 'der', type: 'spki' });

@@ -47,2 +47,7 @@ "use strict";

const isPrivate = jwk.d !== undefined;
const pub = Buffer.concat([
Buffer.alloc(1, 4),
Buffer.from(jwk.x, 'base64'),
Buffer.from(jwk.y, 'base64'),
]);
if (isPrivate) {

@@ -57,6 +62,11 @@ enc.zero();

enc$2.octStr(Buffer.from(jwk.d, 'base64'));
const enc$3 = new asn1_sequence_encoder_js_1.default();
enc$3.bitStr(pub);
const f2 = enc$3.end(Buffer.from([0xa1]));
enc$2.add(f2);
const f = enc$2.end();
enc.add(Buffer.from([0x04]));
enc.add(Buffer.from([f.length]));
enc.add(f);
const enc$4 = new asn1_sequence_encoder_js_1.default();
enc$4.add(f);
const f3 = enc$4.end(Buffer.from([0x04]));
enc.add(f3);
const der = enc.end();

@@ -71,7 +81,2 @@ const keyObject = crypto_1.createPrivateKey({ key: der, format: 'der', type: 'pkcs8' });

enc.add(enc$1.end());
const pub = Buffer.concat([
Buffer.alloc(1, 4),
Buffer.from(jwk.x, 'base64'),
Buffer.from(jwk.y, 'base64'),
]);
enc.bitStr(pub);

@@ -78,0 +83,0 @@ const der = enc.end();

@@ -12,3 +12,3 @@ "use strict";

const pbkdf2 = util_1.promisify(crypto_1.pbkdf2);
exports.encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random_js_1.default(new Uint8Array(16))) => {
const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random_js_1.default(new Uint8Array(16))) => {
check_p2s_js_1.default(p2s);

@@ -22,3 +22,4 @@ const salt = buffer_utils_js_1.p2s(alg, p2s);

};
exports.decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
exports.encrypt = encrypt;
const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
check_p2s_js_1.default(p2s);

@@ -31,1 +32,2 @@ const salt = buffer_utils_js_1.p2s(alg, p2s);

};
exports.decrypt = decrypt;

@@ -39,3 +39,3 @@ "use strict";

};
exports.encrypt = async (alg, key, cek) => {
const encrypt = async (alg, key, cek) => {
const padding = resolvePadding(alg);

@@ -46,3 +46,4 @@ const oaepHash = resolveOaepHash(alg);

};
exports.decrypt = async (alg, key, encryptedKey) => {
exports.encrypt = encrypt;
const decrypt = async (alg, key, encryptedKey) => {
const padding = resolvePadding(alg);

@@ -53,1 +54,2 @@ const oaepHash = resolveOaepHash(alg);

};
exports.decrypt = decrypt;

@@ -8,7 +8,9 @@ "use strict";

const deflateRaw = util_1.promisify(zlib_1.deflateRaw);
exports.inflate = async (input) => {
const inflate = async (input) => {
return inflateRaw(input);
};
exports.deflate = async (input) => {
exports.inflate = inflate;
const deflate = async (input) => {
return deflateRaw(input);
};
exports.deflate = deflate;
import decrypt from '../flattened/decrypt.js';
import { JWEInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactDecrypt(jwe, key, options) {
if (jwe instanceof Uint8Array) {
jwe = decoder.decode(jwe);
}
if (typeof jwe !== 'string') {
throw new JWEInvalid('Compact JWE must be a string');
throw new JWEInvalid('Compact JWE must be a string or Uint8Array');
}

@@ -12,9 +16,9 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split('.');

const decrypted = await decrypt({
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined),
iv: (iv || undefined),
protected: protectedHeader || undefined,
tag: (tag || undefined),
encrypted_key: encryptedKey || undefined,
}, key, options);
return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
}

@@ -21,27 +21,27 @@ import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';

}
if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new JWEInvalid('JOSE Header missing');
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new JWEInvalid('JWE Initialization Vector missing or incorrect type');
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new JWEInvalid('JWE Ciphertext missing or incorrect type');
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new JWEInvalid('JWE Authentication Tag missing or incorrect type');
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new JWEInvalid('JWE Protected Header incorrect type');
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new JWEInvalid('JWE Encrypted Key incorrect type');
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new JWEInvalid('JWE AAD incorrect type');
}
if ('header' in jwe && !isObject(jwe.header)) {
if (jwe.header !== undefined && !isObject(jwe.header)) {
throw new JWEInvalid('JWE Shared Unprotected Header incorrect type');
}
if ('unprotected' in jwe && !isObject(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {
throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');

@@ -63,3 +63,3 @@ }

checkCrit(parsedProt, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -73,6 +73,6 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');

@@ -89,3 +89,3 @@ }

let encryptedKey;
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url(jwe.encrypted_key);

@@ -110,3 +110,3 @@ }

let additionalData;
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = concat(protectedHeader, encoder.encode('.'), encoder.encode(jwe.aad));

@@ -122,12 +122,12 @@ }

const result = { plaintext };
if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url(jwe.aad);
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected;
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header;

@@ -134,0 +134,0 @@ }

@@ -76,3 +76,3 @@ import ivFactory from '../../lib/iv.js';

checkCrit(this._protectedHeader, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -86,7 +86,7 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing');
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
}
if (!enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing');
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
}

@@ -93,0 +93,0 @@ let encryptedKey;

@@ -24,3 +24,3 @@ import { decode as base64url } from '../runtime/base64url.js';

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is unsupported');

@@ -27,0 +27,0 @@ }

@@ -24,2 +24,3 @@ import parseJWK from '../jwk/parse.js';

this._url = new URL(url.href);
this._options = { agent: options === null || options === void 0 ? void 0 : options.agent };
this._timeoutDuration =

@@ -91,3 +92,3 @@ typeof (options === null || options === void 0 ? void 0 : options.timeoutDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.timeoutDuration : 5000;

const cached = this._cached.get(jwk);
if (!(protectedHeader.alg in cached)) {
if (cached[protectedHeader.alg] === undefined) {
const keyObject = (await parseJWK({ ...jwk, alg: protectedHeader.alg }));

@@ -103,7 +104,6 @@ if (keyObject.type !== 'public') {

if (!this._pendingFetch) {
this._pendingFetch = fetchJson(this._url, this._timeoutDuration)
this._pendingFetch = fetchJson(this._url, this._timeoutDuration, this._options)
.then((json) => {
if (typeof json !== 'object' ||
!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -110,0 +110,0 @@ json.keys.some((key) => typeof key !== 'object' || !key)) {

import verify from '../flattened/verify.js';
import { JWSInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactVerify(jws, key, options) {
if (jws instanceof Uint8Array) {
jws = decoder.decode(jws);
}
if (typeof jws !== 'string') {
throw new JWSInvalid('Compact JWS must be a string');
throw new JWSInvalid('Compact JWS must be a string or Uint8Array');
}

@@ -11,4 +15,8 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.');

}
const verified = await verify({ payload, protected: protectedHeader, signature }, key, options);
const verified = await verify({
payload: (payload || undefined),
protected: protectedHeader || undefined,
signature: (signature || undefined),
}, key, options);
return { payload: verified.payload, protectedHeader: verified.protectedHeader };
}

@@ -47,4 +47,4 @@ import isDisjoint from '../../lib/is_disjoint.js';

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -51,0 +51,0 @@ checkKeyType(alg, key);

@@ -16,15 +16,15 @@ import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';

}
if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new JWSInvalid('JWS Protected Header incorrect type');
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new JWSInvalid('JWS Payload missing');
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new JWSInvalid('JWS Signature missing or incorrect type');
}
if ('header' in jws && !isObject(jws.header)) {
if (jws.header !== undefined && !isObject(jws.header)) {
throw new JWSInvalid('JWS Unprotected Header incorrect type');

@@ -53,4 +53,4 @@ }

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -90,6 +90,6 @@ const algorithms = options && checkAlgOption(options.algorithms);

const result = { payload };
if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header;

@@ -96,0 +96,0 @@ }

@@ -8,9 +8,9 @@ import decrypt from '../jwe/compact/decrypt.js';

const { protectedHeader } = decrypted;
if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch');
}
if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch');
}
if ('aud' in protectedHeader &&
if (protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {

@@ -17,0 +17,0 @@ throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');

@@ -15,3 +15,3 @@ import { JOSENotSupported, JWEInvalid } from '../util/errors.js';

function assertHeaderParameter(joseHeader, parameter, name) {
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);

@@ -37,3 +37,3 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -43,5 +43,5 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk);

let partyVInfo;
if (joseHeader.apu)
if (joseHeader.apu !== undefined)
partyUInfo = base64url(joseHeader.apu);
if (joseHeader.apv)
if (joseHeader.apv !== undefined)
partyVInfo = base64url(joseHeader.apv);

@@ -91,3 +91,3 @@ const sharedSecret = await ECDH.deriveKey(ephemeralKey, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLengths.get(joseHeader.enc), partyUInfo, partyVInfo);

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -94,0 +94,0 @@ }

@@ -25,3 +25,3 @@ import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js';

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -80,3 +80,3 @@ const { apu, apv } = providedParameters;

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -83,0 +83,0 @@ }

@@ -57,11 +57,11 @@ import { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors.js';

const now = epoch(currentDate || new Date());
if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
}
}
if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -74,3 +74,3 @@ throw new JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid');

}
if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -77,0 +77,0 @@ throw new JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid');

@@ -10,3 +10,3 @@ const minute = 60;

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`);
throw new TypeError('invalid time period format');
}

@@ -13,0 +13,0 @@ const value = parseFloat(matched[1]);

import { JOSENotSupported } from '../util/errors.js';
const isString = (input) => typeof input !== 'string' || input.length === 0;
function validateCrit(Err, supported, protectedHeader, joseHeader) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([]);
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set();
}
if (!Array.isArray(protectedHeader.crit) ||
protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)) {
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');

@@ -19,6 +18,6 @@ }

}
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
}
else if (supported.get(parameter) && !(parameter in protectedHeader)) {
else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);

@@ -25,0 +24,0 @@ }

@@ -13,4 +13,4 @@ import { getCiphers, KeyObject, createDecipheriv } from 'crypto';

}
const encKey = cek.slice(keySize >> 3);
const macKey = cek.slice(0, keySize >> 3);
const encKey = cek.subarray(keySize >> 3);
const macKey = cek.subarray(0, keySize >> 3);
const macSize = parseInt(enc.substr(-3), 10);

@@ -17,0 +17,0 @@ const algorithm = `aes-${keySize}-cbc`;

@@ -11,4 +11,4 @@ import { KeyObject, createCipheriv } from 'crypto';

}
const encKey = cek.slice(keySize >> 3);
const macKey = cek.slice(0, keySize >> 3);
const encKey = cek.subarray(keySize >> 3);
const macKey = cek.subarray(0, keySize >> 3);
const algorithm = `aes-${keySize}-cbc`;

@@ -15,0 +15,0 @@ const cipher = createCipheriv(algorithm, encKey, iv);

@@ -10,10 +10,8 @@ import { get as http } from 'http';

const fetch = async (url, timeout, options) => {
if (!(url.protocol in protocols)) {
if (protocols[url.protocol] === undefined) {
throw new TypeError('Unsupported URL protocol.');
}
return new Promise((resolve, reject) => {
protocols[url.protocol](url, {
...options,
timeout,
}, async (response) => {
const { agent } = options;
protocols[url.protocol](url, { agent, timeout }, async (response) => {
if (response.statusCode !== 200) {

@@ -20,0 +18,0 @@ reject(new JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response'));

@@ -13,5 +13,8 @@ import { createPublicKey } from 'crypto';

switch (key.asymmetricKeyType) {
case 'ed25519':
case 'ed448':
return `Ed${key.asymmetricKeyType.substr(2)}`;
case 'x25519':
case 'x448':
return key.asymmetricKeyType.toUpperCase();
return `X${key.asymmetricKeyType.substr(1)}`;
case 'ec': {

@@ -22,3 +25,5 @@ if (weakMap.has(key)) {

if (key.type === 'private') {
return getNamedCurve(createPublicKey(key));
const curve = getNamedCurve(createPublicKey(key));
weakMap.set(key, curve);
return curve;
}

@@ -25,0 +30,0 @@ const buf = key.export({ format: 'der', type: 'spki' });

@@ -45,2 +45,7 @@ import { createPrivateKey, createPublicKey, createSecretKey } from 'crypto';

const isPrivate = jwk.d !== undefined;
const pub = Buffer.concat([
Buffer.alloc(1, 4),
Buffer.from(jwk.x, 'base64'),
Buffer.from(jwk.y, 'base64'),
]);
if (isPrivate) {

@@ -55,6 +60,11 @@ enc.zero();

enc$2.octStr(Buffer.from(jwk.d, 'base64'));
const enc$3 = new Asn1SequenceEncoder();
enc$3.bitStr(pub);
const f2 = enc$3.end(Buffer.from([0xa1]));
enc$2.add(f2);
const f = enc$2.end();
enc.add(Buffer.from([0x04]));
enc.add(Buffer.from([f.length]));
enc.add(f);
const enc$4 = new Asn1SequenceEncoder();
enc$4.add(f);
const f3 = enc$4.end(Buffer.from([0x04]));
enc.add(f3);
const der = enc.end();

@@ -69,7 +79,2 @@ const keyObject = createPrivateKey({ key: der, format: 'der', type: 'pkcs8' });

enc.add(enc$1.end());
const pub = Buffer.concat([
Buffer.alloc(1, 4),
Buffer.from(jwk.x, 'base64'),
Buffer.from(jwk.y, 'base64'),
]);
enc.bitStr(pub);

@@ -76,0 +81,0 @@ const der = enc.end();

@@ -5,5 +5,9 @@ "use strict";

const errors_js_1 = require("../../util/errors.js");
const buffer_utils_js_1 = require("../../lib/buffer_utils.js");
async function compactDecrypt(jwe, key, options) {
if (jwe instanceof Uint8Array) {
jwe = buffer_utils_js_1.decoder.decode(jwe);
}
if (typeof jwe !== 'string') {
throw new errors_js_1.JWEInvalid('Compact JWE must be a string');
throw new errors_js_1.JWEInvalid('Compact JWE must be a string or Uint8Array');
}

@@ -15,7 +19,7 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split('.');

const decrypted = await decrypt_js_1.default({
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined),
iv: (iv || undefined),
protected: protectedHeader || undefined,
tag: (tag || undefined),
encrypted_key: encryptedKey || undefined,
}, key, options);

@@ -22,0 +26,0 @@ return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };

@@ -23,27 +23,27 @@ "use strict";

}
if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new errors_js_1.JWEInvalid('JOSE Header missing');
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Initialization Vector missing or incorrect type');
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Ciphertext missing or incorrect type');
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Authentication Tag missing or incorrect type');
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Protected Header incorrect type');
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new errors_js_1.JWEInvalid('JWE Encrypted Key incorrect type');
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new errors_js_1.JWEInvalid('JWE AAD incorrect type');
}
if ('header' in jwe && !is_object_js_1.default(jwe.header)) {
if (jwe.header !== undefined && !is_object_js_1.default(jwe.header)) {
throw new errors_js_1.JWEInvalid('JWE Shared Unprotected Header incorrect type');
}
if ('unprotected' in jwe && !is_object_js_1.default(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !is_object_js_1.default(jwe.unprotected)) {
throw new errors_js_1.JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');

@@ -65,3 +65,3 @@ }

checkCrit(parsedProt, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -75,6 +75,6 @@ throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new errors_js_1.JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');

@@ -91,3 +91,3 @@ }

let encryptedKey;
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url_js_1.decode(jwe.encrypted_key);

@@ -112,3 +112,3 @@ }

let additionalData;
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = buffer_utils_js_1.concat(protectedHeader, buffer_utils_js_1.encoder.encode('.'), buffer_utils_js_1.encoder.encode(jwe.aad));

@@ -124,12 +124,12 @@ }

const result = { plaintext };
if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url_js_1.decode(jwe.aad);
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected;
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header;

@@ -136,0 +136,0 @@ }

@@ -78,3 +78,3 @@ "use strict";

checkCrit(this._protectedHeader, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -88,7 +88,7 @@ throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
throw new errors_js_1.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
}
if (!enc) {
throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing');
if (typeof enc !== 'string' || !enc) {
throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
}

@@ -95,0 +95,0 @@ let encryptedKey;

@@ -26,3 +26,3 @@ "use strict";

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new errors_js_1.JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is unsupported');

@@ -29,0 +29,0 @@ }

@@ -26,2 +26,3 @@ "use strict";

this._url = new URL(url.href);
this._options = { agent: options?.agent };
this._timeoutDuration =

@@ -93,3 +94,3 @@ typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000;

const cached = this._cached.get(jwk);
if (!(protectedHeader.alg in cached)) {
if (cached[protectedHeader.alg] === undefined) {
const keyObject = (await parse_js_1.default({ ...jwk, alg: protectedHeader.alg }));

@@ -105,7 +106,6 @@ if (keyObject.type !== 'public') {

if (!this._pendingFetch) {
this._pendingFetch = fetch_js_1.default(this._url, this._timeoutDuration)
this._pendingFetch = fetch_js_1.default(this._url, this._timeoutDuration, this._options)
.then((json) => {
if (typeof json !== 'object' ||
!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -112,0 +112,0 @@ json.keys.some((key) => typeof key !== 'object' || !key)) {

@@ -5,5 +5,9 @@ "use strict";

const errors_js_1 = require("../../util/errors.js");
const buffer_utils_js_1 = require("../../lib/buffer_utils.js");
async function compactVerify(jws, key, options) {
if (jws instanceof Uint8Array) {
jws = buffer_utils_js_1.decoder.decode(jws);
}
if (typeof jws !== 'string') {
throw new errors_js_1.JWSInvalid('Compact JWS must be a string');
throw new errors_js_1.JWSInvalid('Compact JWS must be a string or Uint8Array');
}

@@ -14,5 +18,9 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.');

}
const verified = await verify_js_1.default({ payload, protected: protectedHeader, signature }, key, options);
const verified = await verify_js_1.default({
payload: (payload || undefined),
protected: protectedHeader || undefined,
signature: (signature || undefined),
}, key, options);
return { payload: verified.payload, protectedHeader: verified.protectedHeader };
}
exports.default = compactVerify;

@@ -49,4 +49,4 @@ "use strict";

const { alg } = joseHeader;
if (!alg) {
throw new errors_js_1.JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -53,0 +53,0 @@ check_key_type_js_1.default(alg, key);

@@ -18,15 +18,15 @@ "use strict";

}
if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new errors_js_1.JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new errors_js_1.JWSInvalid('JWS Protected Header incorrect type');
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new errors_js_1.JWSInvalid('JWS Payload missing');
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new errors_js_1.JWSInvalid('JWS Signature missing or incorrect type');
}
if ('header' in jws && !is_object_js_1.default(jws.header)) {
if (jws.header !== undefined && !is_object_js_1.default(jws.header)) {
throw new errors_js_1.JWSInvalid('JWS Unprotected Header incorrect type');

@@ -55,4 +55,4 @@ }

const { alg } = joseHeader;
if (!alg) {
throw new errors_js_1.JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new errors_js_1.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -92,6 +92,6 @@ const algorithms = options && checkAlgOption(options.algorithms);

const result = { payload };
if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header;

@@ -98,0 +98,0 @@ }

@@ -10,9 +10,9 @@ "use strict";

const { protectedHeader } = decrypted;
if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new errors_js_1.JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch');
}
if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new errors_js_1.JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch');
}
if ('aud' in protectedHeader &&
if (protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {

@@ -19,0 +19,0 @@ throw new errors_js_1.JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');

@@ -17,3 +17,3 @@ "use strict";

function assertHeaderParameter(joseHeader, parameter, name) {
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new errors_js_1.JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);

@@ -39,3 +39,3 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new errors_js_1.JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -45,5 +45,5 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk);

let partyVInfo;
if (joseHeader.apu)
if (joseHeader.apu !== undefined)
partyUInfo = base64url_js_1.decode(joseHeader.apu);
if (joseHeader.apv)
if (joseHeader.apv !== undefined)
partyVInfo = base64url_js_1.decode(joseHeader.apv);

@@ -93,3 +93,3 @@ const sharedSecret = await ECDH.deriveKey(ephemeralKey, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cek_js_1.bitLengths.get(joseHeader.enc), partyUInfo, partyVInfo);

default: {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is unsupported`);
throw new errors_js_1.JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -96,0 +96,0 @@ }

@@ -27,3 +27,3 @@ "use strict";

if (!ECDH.ecdhAllowed(key)) {
throw new errors_js_1.JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new errors_js_1.JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -82,3 +82,3 @@ const { apu, apv } = providedParameters;

default: {
throw new errors_js_1.JOSENotSupported(`alg ${alg} is unsupported`);
throw new errors_js_1.JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -85,0 +85,0 @@ }

@@ -59,11 +59,11 @@ "use strict";

const now = epoch_js_1.default(currentDate || new Date());
if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new errors_js_1.JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new errors_js_1.JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
}
}
if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -76,3 +76,3 @@ throw new errors_js_1.JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid');

}
if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -79,0 +79,0 @@ throw new errors_js_1.JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid');

@@ -12,3 +12,3 @@ "use strict";

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`);
throw new TypeError('invalid time period format');
}

@@ -15,0 +15,0 @@ const value = parseFloat(matched[1]);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const errors_js_1 = require("../util/errors.js");
const isString = (input) => typeof input !== 'string' || input.length === 0;
function validateCrit(Err, supported, protectedHeader, joseHeader) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([]);
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set();
}
if (!Array.isArray(protectedHeader.crit) ||
protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)) {
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');

@@ -21,6 +20,6 @@ }

}
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
}
else if (supported.get(parameter) && !(parameter in protectedHeader)) {
else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);

@@ -27,0 +26,0 @@ }

@@ -10,3 +10,3 @@ "use strict";

const generateIv = iv_js_1.default(random_js_1.default);
exports.wrap = async (alg, key, cek, iv) => {
const wrap = async (alg, key, cek, iv) => {
const jweAlgorithm = alg.substr(0, 7);

@@ -17,5 +17,7 @@ iv ||= await generateIv(jweAlgorithm);

};
exports.unwrap = async (alg, key, encryptedKey, iv, tag) => {
exports.wrap = wrap;
const unwrap = async (alg, key, encryptedKey, iv, tag) => {
const jweAlgorithm = alg.substr(0, 7);
return decrypt_js_1.default(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array());
};
exports.unwrap = unwrap;

@@ -11,3 +11,3 @@ "use strict";

}
exports.wrap = async (alg, key, cek) => {
const wrap = async (alg, key, cek) => {
webcrypto_js_1.ensureSecureContext();

@@ -25,3 +25,4 @@ let cryptoKey;

};
exports.unwrap = async (alg, key, encryptedKey) => {
exports.wrap = wrap;
const unwrap = async (alg, key, encryptedKey) => {
webcrypto_js_1.ensureSecureContext();

@@ -39,1 +40,2 @@ let cryptoKey;

};
exports.unwrap = unwrap;

@@ -5,4 +5,5 @@ "use strict";

const buffer_utils_js_1 = require("../lib/buffer_utils.js");
exports.encode = (input) => Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
exports.decode = (input) => {
const encode = (input) => Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
exports.encode = encode;
const decode = (input) => {
let encoded = input;

@@ -14,1 +15,2 @@ if (encoded instanceof Uint8Array) {

};
exports.decode = decode;

@@ -29,4 +29,5 @@ "use strict";

}
if ('algorithm' in cek) {
if (cek.algorithm.length !== expected) {
if (cek.algorithm !== undefined) {
const { length } = cek.algorithm;
if (length !== expected) {
throw new errors_js_1.JWEInvalid('Invalid Content Encryption Key length');

@@ -33,0 +34,0 @@ }

@@ -6,3 +6,4 @@ "use strict";

const bitlen = parseInt(alg.substr(-3), 10);
if (!('length' in key.algorithm) || key.algorithm.length < bitlen) {
const { length } = key.algorithm;
if (typeof length !== 'number' || length < bitlen) {
throw new TypeError(`${alg} requires symmetric keys to be ${bitlen} bits or larger`);

@@ -12,4 +13,4 @@ }

if (alg.startsWith('RS') || alg.startsWith('PS')) {
if (!('modulusLength' in key.algorithm) ||
key.algorithm.modulusLength < 2048) {
const { modulusLength } = key.algorithm;
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);

@@ -16,0 +17,0 @@ }

@@ -11,6 +11,4 @@ "use strict";

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'decrypt',
]);
const macKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['decrypt']);
const macKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -17,0 +15,0 @@ name: 'HMAC',

@@ -8,3 +8,3 @@ "use strict";

const concatKdf = buffer_utils_js_1.concatKdf.bind(undefined, digest_js_1.default.bind(undefined, 'sha256'));
exports.deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) => {
const deriveKey = async (publicKey, privateKey, algorithm, keyLength, apu = new Uint8Array(), apv = new Uint8Array()) => {
webcrypto_js_1.ensureSecureContext();

@@ -22,3 +22,4 @@ const value = buffer_utils_js_1.concat(buffer_utils_js_1.lengthAndInput(buffer_utils_js_1.encoder.encode(algorithm)), buffer_utils_js_1.lengthAndInput(apu), buffer_utils_js_1.lengthAndInput(apv), buffer_utils_js_1.uint32be(keyLength));

};
exports.ephemeralKeyToPublicJWK = async function ephemeralKeyToPublicJWK(key) {
exports.deriveKey = deriveKey;
const ephemeralKeyToPublicJWK = async function ephemeralKeyToPublicJWK(key) {
webcrypto_js_1.ensureSecureContext();

@@ -28,11 +29,15 @@ const { crv, kty, x, y } = (await webcrypto_js_1.default.subtle.exportKey('jwk', key));

};
exports.generateEpk = async (key) => {
exports.ephemeralKeyToPublicJWK = ephemeralKeyToPublicJWK;
const generateEpk = async (key) => {
webcrypto_js_1.ensureSecureContext();
return (await webcrypto_js_1.default.subtle.generateKey({ name: 'ECDH', namedCurve: key.algorithm.namedCurve }, true, ['deriveBits'])).privateKey;
};
exports.publicJwkToEphemeralKey = async (jwk) => {
exports.generateEpk = generateEpk;
const publicJwkToEphemeralKey = async (jwk) => {
webcrypto_js_1.ensureSecureContext();
return webcrypto_js_1.default.subtle.importKey('jwk', jwk, { name: 'ECDH', namedCurve: jwk.crv }, true, []);
};
exports.publicJwkToEphemeralKey = publicJwkToEphemeralKey;
const curves = ['P-256', 'P-384', 'P-521'];
exports.ecdhAllowed = (key) => curves.includes(key.algorithm.namedCurve);
const ecdhAllowed = (key) => curves.includes(key.algorithm.namedCurve);
exports.ecdhAllowed = ecdhAllowed;

@@ -9,6 +9,4 @@ "use strict";

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'encrypt',
]);
const macKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt']);
const macKey = await webcrypto_js_1.default.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -15,0 +13,0 @@ name: 'HMAC',

@@ -12,10 +12,8 @@ "use strict";

const fetch = async (url, timeout, options) => {
if (!(url.protocol in protocols)) {
if (protocols[url.protocol] === undefined) {
throw new TypeError('Unsupported URL protocol.');
}
return new Promise((resolve, reject) => {
protocols[url.protocol](url, {
...options,
timeout,
}, async (response) => {
const { agent } = options;
protocols[url.protocol](url, { agent, timeout }, async (response) => {
if (response.statusCode !== 200) {

@@ -22,0 +20,0 @@ reject(new errors_js_1.JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response'));

@@ -10,3 +10,3 @@ "use strict";

const webcrypto_js_1 = require("./webcrypto.js");
exports.encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random_js_1.default(new Uint8Array(16))) => {
const encrypt = async (alg, key, cek, p2c = Math.floor(Math.random() * 2049) + 2048, p2s = random_js_1.default(new Uint8Array(16))) => {
webcrypto_js_1.ensureSecureContext();

@@ -46,3 +46,4 @@ check_p2s_js_1.default(p2s);

};
exports.decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
exports.encrypt = encrypt;
const decrypt = async (alg, key, encryptedKey, p2c, p2s) => {
webcrypto_js_1.ensureSecureContext();

@@ -81,1 +82,2 @@ check_p2s_js_1.default(p2s);

};
exports.decrypt = decrypt;

@@ -8,3 +8,3 @@ "use strict";

const check_key_length_js_1 = require("./check_key_length.js");
exports.encrypt = async (alg, key, cek) => {
const encrypt = async (alg, key, cek) => {
webcrypto_js_1.ensureSecureContext();

@@ -21,3 +21,4 @@ check_key_length_js_1.default(alg, key);

};
exports.decrypt = async (alg, key, encryptedKey) => {
exports.encrypt = encrypt;
const decrypt = async (alg, key, encryptedKey) => {
webcrypto_js_1.ensureSecureContext();

@@ -34,1 +35,2 @@ check_key_length_js_1.default(alg, key);

};
exports.decrypt = decrypt;

@@ -5,3 +5,3 @@ "use strict";

const crypto = require("crypto");
if (!('webcrypto' in crypto)) {
if (crypto.webcrypto === undefined) {
throw new Error('Node.js crypto.webcrypto is not available in your runtime');

@@ -8,0 +8,0 @@ }

@@ -8,7 +8,9 @@ "use strict";

const deflateRaw = util_1.promisify(zlib_1.deflateRaw);
exports.inflate = async (input) => {
const inflate = async (input) => {
return inflateRaw(input);
};
exports.deflate = async (input) => {
exports.inflate = inflate;
const deflate = async (input) => {
return deflateRaw(input);
};
exports.deflate = deflate;
import decrypt from '../flattened/decrypt.js';
import { JWEInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactDecrypt(jwe, key, options) {
if (jwe instanceof Uint8Array) {
jwe = decoder.decode(jwe);
}
if (typeof jwe !== 'string') {
throw new JWEInvalid('Compact JWE must be a string');
throw new JWEInvalid('Compact JWE must be a string or Uint8Array');
}

@@ -12,9 +16,9 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split('.');

const decrypted = await decrypt({
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined),
iv: (iv || undefined),
protected: protectedHeader || undefined,
tag: (tag || undefined),
encrypted_key: encryptedKey || undefined,
}, key, options);
return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
}

@@ -21,27 +21,27 @@ import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';

}
if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new JWEInvalid('JOSE Header missing');
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new JWEInvalid('JWE Initialization Vector missing or incorrect type');
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new JWEInvalid('JWE Ciphertext missing or incorrect type');
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new JWEInvalid('JWE Authentication Tag missing or incorrect type');
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new JWEInvalid('JWE Protected Header incorrect type');
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new JWEInvalid('JWE Encrypted Key incorrect type');
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new JWEInvalid('JWE AAD incorrect type');
}
if ('header' in jwe && !isObject(jwe.header)) {
if (jwe.header !== undefined && !isObject(jwe.header)) {
throw new JWEInvalid('JWE Shared Unprotected Header incorrect type');
}
if ('unprotected' in jwe && !isObject(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {
throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type');

@@ -63,3 +63,3 @@ }

checkCrit(parsedProt, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -73,6 +73,6 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header');
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header');

@@ -89,3 +89,3 @@ }

let encryptedKey;
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url(jwe.encrypted_key);

@@ -110,3 +110,3 @@ }

let additionalData;
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = concat(protectedHeader, encoder.encode('.'), encoder.encode(jwe.aad));

@@ -122,12 +122,12 @@ }

const result = { plaintext };
if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url(jwe.aad);
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected;
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header;

@@ -134,0 +134,0 @@ }

@@ -76,3 +76,3 @@ import ivFactory from '../../lib/iv.js';

checkCrit(this._protectedHeader, joseHeader);
if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -86,7 +86,7 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');

const { alg, enc } = joseHeader;
if (!alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing');
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
}
if (!enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing');
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
}

@@ -93,0 +93,0 @@ let encryptedKey;

@@ -24,3 +24,3 @@ import { decode as base64url } from '../runtime/base64url.js';

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is unsupported');

@@ -27,0 +27,0 @@ }

@@ -24,2 +24,3 @@ import parseJWK from '../jwk/parse.js';

this._url = new URL(url.href);
this._options = { agent: options?.agent };
this._timeoutDuration =

@@ -91,3 +92,3 @@ typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000;

const cached = this._cached.get(jwk);
if (!(protectedHeader.alg in cached)) {
if (cached[protectedHeader.alg] === undefined) {
const keyObject = (await parseJWK({ ...jwk, alg: protectedHeader.alg }));

@@ -103,7 +104,6 @@ if (keyObject.type !== 'public') {

if (!this._pendingFetch) {
this._pendingFetch = fetchJson(this._url, this._timeoutDuration)
this._pendingFetch = fetchJson(this._url, this._timeoutDuration, this._options)
.then((json) => {
if (typeof json !== 'object' ||
!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -110,0 +110,0 @@ json.keys.some((key) => typeof key !== 'object' || !key)) {

import verify from '../flattened/verify.js';
import { JWSInvalid } from '../../util/errors.js';
import { decoder } from '../../lib/buffer_utils.js';
export default async function compactVerify(jws, key, options) {
if (jws instanceof Uint8Array) {
jws = decoder.decode(jws);
}
if (typeof jws !== 'string') {
throw new JWSInvalid('Compact JWS must be a string');
throw new JWSInvalid('Compact JWS must be a string or Uint8Array');
}

@@ -11,4 +15,8 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.');

}
const verified = await verify({ payload, protected: protectedHeader, signature }, key, options);
const verified = await verify({
payload: (payload || undefined),
protected: protectedHeader || undefined,
signature: (signature || undefined),
}, key, options);
return { payload: verified.payload, protectedHeader: verified.protectedHeader };
}

@@ -47,4 +47,4 @@ import isDisjoint from '../../lib/is_disjoint.js';

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -51,0 +51,0 @@ checkKeyType(alg, key);

@@ -16,15 +16,15 @@ import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';

}
if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members');
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new JWSInvalid('JWS Protected Header incorrect type');
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new JWSInvalid('JWS Payload missing');
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new JWSInvalid('JWS Signature missing or incorrect type');
}
if ('header' in jws && !isObject(jws.header)) {
if (jws.header !== undefined && !isObject(jws.header)) {
throw new JWSInvalid('JWS Unprotected Header incorrect type');

@@ -53,4 +53,4 @@ }

const { alg } = joseHeader;
if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header');
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
}

@@ -90,6 +90,6 @@ const algorithms = options && checkAlgOption(options.algorithms);

const result = { payload };
if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt;
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header;

@@ -96,0 +96,0 @@ }

@@ -8,9 +8,9 @@ import decrypt from '../jwe/compact/decrypt.js';

const { protectedHeader } = decrypted;
if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch');
}
if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch');
}
if ('aud' in protectedHeader &&
if (protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {

@@ -17,0 +17,0 @@ throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');

@@ -15,3 +15,3 @@ import { JOSENotSupported, JWEInvalid } from '../util/errors.js';

function assertHeaderParameter(joseHeader, parameter, name) {
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new JWEInvalid(`JOSE Header ${name} (${parameter}) missing`);

@@ -37,3 +37,3 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -43,5 +43,5 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk);

let partyVInfo;
if (joseHeader.apu)
if (joseHeader.apu !== undefined)
partyUInfo = base64url(joseHeader.apu);
if (joseHeader.apv)
if (joseHeader.apv !== undefined)
partyVInfo = base64url(joseHeader.apv);

@@ -91,3 +91,3 @@ const sharedSecret = await ECDH.deriveKey(ephemeralKey, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLengths.get(joseHeader.enc), partyUInfo, partyVInfo);

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -94,0 +94,0 @@ }

@@ -25,3 +25,3 @@ import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js';

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime');
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
}

@@ -80,3 +80,3 @@ const { apu, apv } = providedParameters;

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`);
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value');
}

@@ -83,0 +83,0 @@ }

@@ -57,11 +57,11 @@ import { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors.js';

const now = epoch(currentDate || new Date());
if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid');
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed');
}
}
if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -74,3 +74,3 @@ throw new JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid');

}
if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -77,0 +77,0 @@ throw new JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid');

@@ -10,3 +10,3 @@ const minute = 60;

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`);
throw new TypeError('invalid time period format');
}

@@ -13,0 +13,0 @@ const value = parseFloat(matched[1]);

import { JOSENotSupported } from '../util/errors.js';
const isString = (input) => typeof input !== 'string' || input.length === 0;
function validateCrit(Err, supported, protectedHeader, joseHeader) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([]);
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set();
}
if (!Array.isArray(protectedHeader.crit) ||
protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)) {
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');

@@ -19,6 +18,6 @@ }

}
if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
}
else if (supported.get(parameter) && !(parameter in protectedHeader)) {
else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);

@@ -25,0 +24,0 @@ }

@@ -27,4 +27,5 @@ import { JWEInvalid, JOSENotSupported } from '../util/errors.js';

}
if ('algorithm' in cek) {
if (cek.algorithm.length !== expected) {
if (cek.algorithm !== undefined) {
const { length } = cek.algorithm;
if (length !== expected) {
throw new JWEInvalid('Invalid Content Encryption Key length');

@@ -31,0 +32,0 @@ }

export default (alg, key) => {
if (alg.startsWith('HS')) {
const bitlen = parseInt(alg.substr(-3), 10);
if (!('length' in key.algorithm) || key.algorithm.length < bitlen) {
const { length } = key.algorithm;
if (typeof length !== 'number' || length < bitlen) {
throw new TypeError(`${alg} requires symmetric keys to be ${bitlen} bits or larger`);

@@ -9,4 +10,4 @@ }

if (alg.startsWith('RS') || alg.startsWith('PS')) {
if (!('modulusLength' in key.algorithm) ||
key.algorithm.modulusLength < 2048) {
const { modulusLength } = key.algorithm;
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);

@@ -13,0 +14,0 @@ }

@@ -9,6 +9,4 @@ import { concat, uint64be } from '../lib/buffer_utils.js';

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await crypto.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'decrypt',
]);
const macKey = await crypto.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['decrypt']);
const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -15,0 +13,0 @@ name: 'HMAC',

@@ -7,6 +7,4 @@ import { concat, uint64be } from '../lib/buffer_utils.js';

const keySize = parseInt(enc.substr(1, 3), 10);
const encKey = await crypto.subtle.importKey('raw', cek.slice(keySize >> 3), 'AES-CBC', false, [
'encrypt',
]);
const macKey = await crypto.subtle.importKey('raw', cek.slice(0, keySize >> 3), {
const encKey = await crypto.subtle.importKey('raw', cek.subarray(keySize >> 3), 'AES-CBC', false, ['encrypt']);
const macKey = await crypto.subtle.importKey('raw', cek.subarray(0, keySize >> 3), {
hash: `SHA-${keySize << 1}`,

@@ -13,0 +11,0 @@ name: 'HMAC',

@@ -10,10 +10,8 @@ import { get as http } from 'http';

const fetch = async (url, timeout, options) => {
if (!(url.protocol in protocols)) {
if (protocols[url.protocol] === undefined) {
throw new TypeError('Unsupported URL protocol.');
}
return new Promise((resolve, reject) => {
protocols[url.protocol](url, {
...options,
timeout,
}, async (response) => {
const { agent } = options;
protocols[url.protocol](url, { agent, timeout }, async (response) => {
if (response.statusCode !== 200) {

@@ -20,0 +18,0 @@ reject(new JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response'));

import * as crypto from 'crypto';
if (!('webcrypto' in crypto)) {
if (crypto.webcrypto === undefined) {
throw new Error('Node.js crypto.webcrypto is not available in your runtime');

@@ -4,0 +4,0 @@ }

{
"name": "jose",
"version": "3.0.2",
"version": "3.1.0",
"description": "JSON Web Almost Everything - JWA, JWS, JWE, JWK, JWT, JWKS with no dependencies",

@@ -47,177 +47,9 @@ "keywords": [

"imports": {
"#dist/jwe/compact/decrypt": {
"import": "./dist/node/esm/jwe/compact/decrypt.js",
"require": "./dist/node/cjs/jwe/compact/decrypt.js"
"#dist/*": {
"import": "./dist/node/esm/*.js",
"require": "./dist/node/cjs/*.js"
},
"#dist/webcrypto/jwe/compact/decrypt": {
"import": "./dist/node/webcrypto/esm/jwe/compact/decrypt.js",
"require": "./dist/node/webcrypto/cjs/jwe/compact/decrypt.js"
},
"#dist/jwe/compact/encrypt": {
"import": "./dist/node/esm/jwe/compact/encrypt.js",
"require": "./dist/node/cjs/jwe/compact/encrypt.js"
},
"#dist/webcrypto/jwe/compact/encrypt": {
"import": "./dist/node/webcrypto/esm/jwe/compact/encrypt.js",
"require": "./dist/node/webcrypto/cjs/jwe/compact/encrypt.js"
},
"#dist/jwe/flattened/decrypt": {
"import": "./dist/node/esm/jwe/flattened/decrypt.js",
"require": "./dist/node/cjs/jwe/flattened/decrypt.js"
},
"#dist/webcrypto/jwe/flattened/decrypt": {
"import": "./dist/node/webcrypto/esm/jwe/flattened/decrypt.js",
"require": "./dist/node/webcrypto/cjs/jwe/flattened/decrypt.js"
},
"#dist/jwe/flattened/encrypt": {
"import": "./dist/node/esm/jwe/flattened/encrypt.js",
"require": "./dist/node/cjs/jwe/flattened/encrypt.js"
},
"#dist/webcrypto/jwe/flattened/encrypt": {
"import": "./dist/node/webcrypto/esm/jwe/flattened/encrypt.js",
"require": "./dist/node/webcrypto/cjs/jwe/flattened/encrypt.js"
},
"#dist/jwk/embedded": {
"import": "./dist/node/esm/jwk/embedded.js",
"require": "./dist/node/cjs/jwk/embedded.js"
},
"#dist/webcrypto/jwk/embedded": {
"import": "./dist/node/webcrypto/esm/jwk/embedded.js",
"require": "./dist/node/webcrypto/cjs/jwk/embedded.js"
},
"#dist/jwk/parse": {
"import": "./dist/node/esm/jwk/parse.js",
"require": "./dist/node/cjs/jwk/parse.js"
},
"#dist/webcrypto/jwk/parse": {
"import": "./dist/node/webcrypto/esm/jwk/parse.js",
"require": "./dist/node/webcrypto/cjs/jwk/parse.js"
},
"#dist/jwk/thumbprint": {
"import": "./dist/node/esm/jwk/thumbprint.js",
"require": "./dist/node/cjs/jwk/thumbprint.js"
},
"#dist/webcrypto/jwk/thumbprint": {
"import": "./dist/node/webcrypto/esm/jwk/thumbprint.js",
"require": "./dist/node/webcrypto/cjs/jwk/thumbprint.js"
},
"#dist/jwks/remote": {
"import": "./dist/node/esm/jwks/remote.js",
"require": "./dist/node/cjs/jwks/remote.js"
},
"#dist/webcrypto/jwks/remote": {
"import": "./dist/node/webcrypto/esm/jwks/remote.js",
"require": "./dist/node/webcrypto/cjs/jwks/remote.js"
},
"#dist/jws/compact/sign": {
"import": "./dist/node/esm/jws/compact/sign.js",
"require": "./dist/node/cjs/jws/compact/sign.js"
},
"#dist/webcrypto/jws/compact/sign": {
"import": "./dist/node/webcrypto/esm/jws/compact/sign.js",
"require": "./dist/node/webcrypto/cjs/jws/compact/sign.js"
},
"#dist/jws/compact/verify": {
"import": "./dist/node/esm/jws/compact/verify.js",
"require": "./dist/node/cjs/jws/compact/verify.js"
},
"#dist/webcrypto/jws/compact/verify": {
"import": "./dist/node/webcrypto/esm/jws/compact/verify.js",
"require": "./dist/node/webcrypto/cjs/jws/compact/verify.js"
},
"#dist/jws/flattened/sign": {
"import": "./dist/node/esm/jws/flattened/sign.js",
"require": "./dist/node/cjs/jws/flattened/sign.js"
},
"#dist/webcrypto/jws/flattened/sign": {
"import": "./dist/node/webcrypto/esm/jws/flattened/sign.js",
"require": "./dist/node/webcrypto/cjs/jws/flattened/sign.js"
},
"#dist/jws/flattened/verify": {
"import": "./dist/node/esm/jws/flattened/verify.js",
"require": "./dist/node/cjs/jws/flattened/verify.js"
},
"#dist/webcrypto/jws/flattened/verify": {
"import": "./dist/node/webcrypto/esm/jws/flattened/verify.js",
"require": "./dist/node/webcrypto/cjs/jws/flattened/verify.js"
},
"#dist/jwt/decrypt": {
"import": "./dist/node/esm/jwt/decrypt.js",
"require": "./dist/node/cjs/jwt/decrypt.js"
},
"#dist/webcrypto/jwt/decrypt": {
"import": "./dist/node/webcrypto/esm/jwt/decrypt.js",
"require": "./dist/node/webcrypto/cjs/jwt/decrypt.js"
},
"#dist/jwt/encrypt": {
"import": "./dist/node/esm/jwt/encrypt.js",
"require": "./dist/node/cjs/jwt/encrypt.js"
},
"#dist/webcrypto/jwt/encrypt": {
"import": "./dist/node/webcrypto/esm/jwt/encrypt.js",
"require": "./dist/node/webcrypto/cjs/jwt/encrypt.js"
},
"#dist/jwt/sign": {
"import": "./dist/node/esm/jwt/sign.js",
"require": "./dist/node/cjs/jwt/sign.js"
},
"#dist/webcrypto/jwt/sign": {
"import": "./dist/node/webcrypto/esm/jwt/sign.js",
"require": "./dist/node/webcrypto/cjs/jwt/sign.js"
},
"#dist/jwt/unsecured": {
"import": "./dist/node/esm/jwt/unsecured.js",
"require": "./dist/node/cjs/jwt/unsecured.js"
},
"#dist/webcrypto/jwt/unsecured": {
"import": "./dist/node/webcrypto/esm/jwt/unsecured.js",
"require": "./dist/node/webcrypto/cjs/jwt/unsecured.js"
},
"#dist/jwt/verify": {
"import": "./dist/node/esm/jwt/verify.js",
"require": "./dist/node/cjs/jwt/verify.js"
},
"#dist/webcrypto/jwt/verify": {
"import": "./dist/node/webcrypto/esm/jwt/verify.js",
"require": "./dist/node/webcrypto/cjs/jwt/verify.js"
},
"#dist/util/base64url": {
"import": "./dist/node/esm/util/base64url.js",
"require": "./dist/node/cjs/util/base64url.js"
},
"#dist/webcrypto/util/base64url": {
"import": "./dist/node/webcrypto/esm/util/base64url.js",
"require": "./dist/node/webcrypto/cjs/util/base64url.js"
},
"#dist/util/errors": {
"import": "./dist/node/esm/util/errors.js",
"require": "./dist/node/cjs/util/errors.js"
},
"#dist/webcrypto/util/errors": {
"import": "./dist/node/webcrypto/esm/util/errors.js",
"require": "./dist/node/webcrypto/cjs/util/errors.js"
},
"#dist/util/generate_key_pair": {
"import": "./dist/node/esm/util/generate_key_pair.js",
"require": "./dist/node/cjs/util/generate_key_pair.js"
},
"#dist/webcrypto/util/generate_key_pair": {
"import": "./dist/node/webcrypto/esm/util/generate_key_pair.js",
"require": "./dist/node/webcrypto/cjs/util/generate_key_pair.js"
},
"#dist/util/generate_secret": {
"import": "./dist/node/esm/util/generate_secret.js",
"require": "./dist/node/cjs/util/generate_secret.js"
},
"#dist/webcrypto/util/generate_secret": {
"import": "./dist/node/webcrypto/esm/util/generate_secret.js",
"require": "./dist/node/webcrypto/cjs/util/generate_secret.js"
},
"#dist/util/random": {
"import": "./dist/node/esm/util/random.js",
"require": "./dist/node/cjs/util/random.js"
},
"#dist/webcrypto/util/random": {
"import": "./dist/node/webcrypto/esm/util/random.js",
"require": "./dist/node/webcrypto/cjs/util/random.js"
"#dist/webcrypto/*": {
"import": "./dist/node/webcrypto/esm/*.js",
"require": "./dist/node/webcrypto/cjs/*.js"
}

@@ -271,2 +103,11 @@ },

},
"./jwk/from_key_like": {
"browser": "./dist/browser/jwk/from_key_like.js",
"import": "./dist/node/esm/jwk/from_key_like.js",
"require": "./dist/node/cjs/jwk/from_key_like.js"
},
"./webcrypto/jwk/from_key_like": {
"import": "./dist/node/webcrypto/esm/jwk/from_key_like.js",
"require": "./dist/node/webcrypto/cjs/jwk/from_key_like.js"
},
"./jwk/parse": {

@@ -438,7 +279,13 @@ "browser": "./dist/browser/jwk/parse.js",

"build-all": "run-s clear build:*",
"build-fast-all": "run-s clear build-fast:*",
"build-fast:browser": "npm run-script runtime-browser && npm run-script -s esbuild-find | xargs -0 esbuild --target=es2018 --outdir=dist/browser --format=esm && echo '{\"type\": \"module\"}'> dist/browser/package.json",
"build-fast:node-cjs": "npm run-script runtime-node && npm run-script -s esbuild-find | xargs -0 esbuild --platform=node --target=node12 --outdir=dist/node/cjs --format=cjs",
"build-fast:node-esm": "npm run-script runtime-node && npm run-script -s esbuild-find | xargs -0 esbuild --platform=node --target=node12 --outdir=dist/node/esm --format=esm && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
"build-fast:node-webcrypto-cjs": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --platform=node --target=esnext --outdir=dist/node/webcrypto/cjs --format=cjs",
"build-fast:node-webcrypto-esm": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --platform=node --target=esnext --outdir=dist/node/webcrypto/esm --format=esm && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json",
"build:browser": "run-s runtime-browser lint 'build -- -p ./tsconfig/browser.json' && echo '{\"type\": \"module\"}'> dist/browser/package.json",
"build:node-cjs": "run-s runtime-node lint 'build -- -p ./tsconfig/node-cjs.json'",
"build:node-esm": "run-s runtime-node lint 'build -- -p ./tsconfig/node-esm.json' && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
"build:node-webcrypto-cjs": "run-s runtime-node-webcrypto && run-s 'build -- -p ./tsconfig/node-webcrypto-cjs.json'",
"build:node-webcrypto-esm": "run-s runtime-node-webcrypto && run-s 'build -- -p ./tsconfig/node-webcrypto-esm.json' && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json",
"build:node-webcrypto-cjs": "run-s runtime-node-webcrypto lint 'build -- -p ./tsconfig/node-webcrypto-cjs.json'",
"build:node-webcrypto-esm": "run-s runtime-node-webcrypto lint 'build -- -p ./tsconfig/node-webcrypto-esm.json' && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json",
"clear": "rm -rf dist",

@@ -448,3 +295,4 @@ "coverage": "npm run-script runtime-node && c8 npm run-script test",

"docs": "run-s docs:*",
"docs:generate": "npx typedoc --disableOutputCheck --excludeNotExported --excludePrivate --excludeProtected --gitRevision main --readme none --listInvalidSymbolLinks --plugin typedoc-plugin-markdown --out docs --includeDeclarations --excludeExternals --tsconfig ./tsconfig/browser.json --mode modules src/types.d.ts src/jwt/*.ts src/jwe/**/*.ts src/jws/**/*.ts src/jwk/*.ts src/jwks/*.ts src/util/*.ts --hideProjectName --hideGenerator --allReflectionsHaveOwnDocument --hideBreadcrumbs",
"docs:generate": "typedoc --disableOutputCheck --excludeNotExported --excludePrivate --excludeProtected --gitRevision main --readme none --listInvalidSymbolLinks --plugin typedoc-plugin-markdown --out docs --includeDeclarations --excludeExternals --tsconfig ./tsconfig/browser.json --mode modules src/types.d.ts src/jwt/*.ts src/jwe/**/*.ts src/jws/**/*.ts src/jwk/*.ts src/jwks/*.ts src/util/*.ts --hideProjectName --hideGenerator --allReflectionsHaveOwnDocument --hideBreadcrumbs",
"esbuild-find": "find src -type f -name '*.ts' -not -path '*/runtime/*/*' -not -name '*.d.ts' -print0",
"lint": "eslint --config ./src/.eslintrc.json ./src",

@@ -459,5 +307,5 @@ "runtime-browser": "run-s runtime:clear runtime:browser:* runtime:refs",

"runtime:refs": "run-s -s runtime:find | xargs -0 sed -i '' -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\"",
"test": "npm run-script test-rollup && ava",
"test-browser": "webpack && karma start",
"test-rollup": "rm -rf test/cjs && find test -type f -name '*.mjs' -print0 | xargs -0 rollup --silent --no-interop --preserveModules --format cjs --dir test/cjs",
"test": "npm run-script test-cjs && ava",
"test-browser": "find test-browser -type f -name '*.js' -print0 | xargs -0 npx esbuild --outdir=dist-browser-tests --bundle && karma start",
"test-cjs": "rm -rf test/cjs && find test -type f -name '*.mjs' -print0 | xargs -0 npx esbuild --target=esnext --outdir=test/cjs --format=cjs",
"test-webcrypto": "WEBCRYPTO=true npm test"

@@ -476,28 +324,27 @@ },

"devDependencies": {
"@types/node": "^14.14.2",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@types/node": "^14.14.9",
"@typescript-eslint/eslint-plugin": "^4.8.1",
"ava": "^3.13.0",
"bowser": "^2.11.0",
"c8": "^7.3.5",
"eslint": "^7.12.0",
"eslint-config-airbnb-base": "^14.2.0",
"esbuild": "0.8.12",
"eslint": "^7.14.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^30.7.3",
"eslint-plugin-jsdoc": "^30.7.8",
"glob": "^7.1.6",
"karma": "^5.2.3",
"karma-browserstack-launcher": "^1.6.0",
"karma-qunit": "^4.1.1",
"nock": "^13.0.4",
"karma-brief-reporter": "0.2.1",
"karma-browserstack-launcher": "1.6.0",
"karma-qunit": "4.1.1",
"nock": "^13.0.5",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.2",
"prettier": "^2.2.0",
"qunit": "^2.12.0",
"rollup": "^2.33.1",
"timekeeper": "^2.2.0",
"typedoc": "0.19.2",
"typedoc-plugin-markdown": "3.0.11",
"typescript": "~4.0.3",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
"typescript": "~4.0.5"
},

@@ -504,0 +351,0 @@ "c8": {

@@ -47,3 +47,4 @@ # jose

- JSON Web Key (JWK)
- [Parsing & Conversion](docs/functions/_jwk_parse_.parsejwk.md#readme)
- [Parsing (JWK to KeyLike)](docs/functions/_jwk_parse_.parsejwk.md#readme)
- [Conversion (KeyLike to JWK)](docs/functions/_jwk_from_key_like_.fromkeylike.md#readme)
- [Thumbprints](docs/functions/_jwk_thumbprint_.calculatethumbprint.md#readme)

@@ -59,2 +60,6 @@ - [EmbeddedJWK](docs/functions/_jwk_embedded_.embeddedjwk.md#readme)

## Examples
A continuously growing list of examples is available in the [tracker](https://github.com/panva/jose/issues?q=label%3Aexample+label%3Av3.x).
## JOSE Support Matrix

@@ -215,2 +220,11 @@

#### "Module '"crypto"' has no exported member '...'"
Update @types/node as your project's development dependency
```
npm uninstall @types/node
npm install --save-dev @types/node
```
#### Why? Just. Why?

@@ -217,0 +231,0 @@

import decrypt from '../flattened/decrypt.js'
import { JWEInvalid } from '../../util/errors.js'
import { decoder } from '../../lib/buffer_utils.js'
import type {

@@ -63,8 +64,13 @@ KeyLike,

export default async function compactDecrypt(
jwe: string,
jwe: string | Uint8Array,
key: KeyLike | CompactDecryptGetKey,
options?: DecryptOptions,
): Promise<CompactDecryptResult> {
if (jwe instanceof Uint8Array) {
// eslint-disable-next-line no-param-reassign
jwe = decoder.decode(jwe)
}
if (typeof jwe !== 'string') {
throw new JWEInvalid('Compact JWE must be a string')
throw new JWEInvalid('Compact JWE must be a string or Uint8Array')
}

@@ -81,7 +87,7 @@ const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length } = jwe.split(

{
ciphertext,
iv,
protected: protectedHeader,
tag,
...(encryptedKey ? { encrypted_key: encryptedKey } : undefined),
ciphertext: (ciphertext || undefined) as string,
iv: (iv || undefined) as string,
protected: protectedHeader || undefined,
tag: (tag || undefined) as string,
encrypted_key: encryptedKey || undefined,
},

@@ -88,0 +94,0 @@ key as Parameters<typeof decrypt>[1],

@@ -101,35 +101,35 @@ import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js'

if (!('protected' in jwe) && !('header' in jwe) && !('unprotected' in jwe)) {
if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) {
throw new JWEInvalid('JOSE Header missing')
}
if (!('iv' in jwe) || typeof jwe.iv !== 'string') {
if (typeof jwe.iv !== 'string') {
throw new JWEInvalid('JWE Initialization Vector missing or incorrect type')
}
if (!('ciphertext' in jwe) || typeof jwe.ciphertext !== 'string') {
if (typeof jwe.ciphertext !== 'string') {
throw new JWEInvalid('JWE Ciphertext missing or incorrect type')
}
if (!('tag' in jwe) || typeof jwe.tag !== 'string') {
if (typeof jwe.tag !== 'string') {
throw new JWEInvalid('JWE Authentication Tag missing or incorrect type')
}
if ('protected' in jwe && typeof jwe.protected !== 'string') {
if (jwe.protected !== undefined && typeof jwe.protected !== 'string') {
throw new JWEInvalid('JWE Protected Header incorrect type')
}
if ('encrypted_key' in jwe && typeof jwe.encrypted_key !== 'string') {
if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') {
throw new JWEInvalid('JWE Encrypted Key incorrect type')
}
if ('aad' in jwe && typeof jwe.aad !== 'string') {
if (jwe.aad !== undefined && typeof jwe.aad !== 'string') {
throw new JWEInvalid('JWE AAD incorrect type')
}
if ('header' in jwe && !isObject(jwe.header)) {
if (jwe.header !== undefined && !isObject(jwe.header)) {
throw new JWEInvalid('JWE Shared Unprotected Header incorrect type')
}
if ('unprotected' in jwe && !isObject(jwe.unprotected)) {
if (jwe.unprotected !== undefined && !isObject(jwe.unprotected)) {
throw new JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type')

@@ -157,3 +157,3 @@ }

if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!parsedProt || !parsedProt.zip) {

@@ -172,7 +172,7 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected')

if (!alg) {
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('missing JWE Algorithm (alg) in JWE Header')
}
if (!enc) {
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header')

@@ -193,3 +193,3 @@ }

let encryptedKey!: Uint8Array
if ('encrypted_key' in jwe) {
if (jwe.encrypted_key !== undefined) {
encryptedKey = base64url(jwe.encrypted_key!)

@@ -226,3 +226,3 @@ }

if ('aad' in jwe) {
if (jwe.aad !== undefined) {
additionalData = concat(protectedHeader, encoder.encode('.'), encoder.encode(jwe.aad))

@@ -241,15 +241,15 @@ } else {

if ('protected' in jwe) {
if (jwe.protected !== undefined) {
result.protectedHeader = parsedProt
}
if ('aad' in jwe) {
if (jwe.aad !== undefined) {
result.additionalAuthenticatedData = base64url(jwe.aad!)
}
if ('unprotected' in jwe) {
if (jwe.unprotected !== undefined) {
result.sharedUnprotectedHeader = jwe.unprotected
}
if ('header' in jwe) {
if (jwe.header !== undefined) {
result.unprotectedHeader = jwe.header

@@ -256,0 +256,0 @@ }

@@ -210,3 +210,3 @@ import type {

if ('zip' in joseHeader) {
if (joseHeader.zip !== undefined) {
if (!this._protectedHeader || !this._protectedHeader.zip) {

@@ -225,8 +225,8 @@ throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected')

if (!alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing')
if (typeof alg !== 'string' || !alg) {
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid')
}
if (!enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing')
if (typeof enc !== 'string' || !enc) {
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid')
}

@@ -233,0 +233,0 @@

@@ -8,6 +8,6 @@ import { decode as base64url } from '../runtime/base64url.js'

/**
* Converts a JWK to a runtime-specific key representation. Either JWK "alg" (Algorithm)
* Parameter must be present or the optional "alg" argument. When running on a platform
* using [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/) the jwk parameters
* "use", "key_ops", and "ext" are also used in the resulting `CryptoKey`.
* Converts a JWK to a runtime-specific key representation (KeyLike). Either
* JWK "alg" (Algorithm) Parameter must be present or the optional "alg" argument. When
* running on a platform using [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/)
* the jwk parameters "use", "key_ops", and "ext" are also used in the resulting `CryptoKey`.
*

@@ -82,3 +82,3 @@ * @param jwk JSON Web Key.

case 'RSA':
if ('oth' in jwk) {
if (jwk.oth !== undefined) {
throw new JOSENotSupported(

@@ -85,0 +85,0 @@ 'RSA JWK "oth" (Other Primes Info) Parameter value is unsupported',

import type { KeyObject } from 'crypto'
import type { Agent as HttpAgent } from 'http'
import type { Agent as HttpsAgent } from 'https'

@@ -46,2 +48,10 @@ import type { JWSHeaderParameters, JWK, FlattenedJWSInput, GetKeyFunction } from '../types.d'

cooldownDuration?: number
/**
* An instance of http.Agent or https.Agent to pass to the http.get or
* https.get method options. Use when behind an http(s) proxy.
* This is a Node.js runtime specific option, it is ignored
* when used outside of Node.js runtime.
*/
agent?: HttpAgent | HttpsAgent
}

@@ -64,2 +74,4 @@

private _options: Pick<RemoteJWKSetOptions, 'agent'>
constructor(url: URL, options?: RemoteJWKSetOptions) {

@@ -70,2 +82,3 @@ if (!(url instanceof URL)) {

this._url = new URL(url.href)
this._options = { agent: options?.agent }
this._timeoutDuration =

@@ -158,3 +171,3 @@ typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000

const cached = this._cached.get(jwk)!
if (!(protectedHeader.alg! in cached)) {
if (cached[protectedHeader.alg!] === undefined) {
const keyObject = (await parseJWK({ ...jwk, alg: protectedHeader.alg! })) as

@@ -176,3 +189,3 @@ | KeyObject

if (!this._pendingFetch) {
this._pendingFetch = fetchJson(this._url, this._timeoutDuration)
this._pendingFetch = fetchJson(this._url, this._timeoutDuration, this._options)
.then((json: { keys: object[] }) => {

@@ -182,3 +195,2 @@ if (

!json ||
!('keys' in json) ||
!Array.isArray(json.keys) ||

@@ -185,0 +197,0 @@ json.keys.some((key: object) => typeof key !== 'object' || !key)

import verify from '../flattened/verify.js'
import { JWSInvalid } from '../../util/errors.js'
import { decoder } from '../../lib/buffer_utils.js'
import type {

@@ -60,8 +61,13 @@ CompactVerifyResult,

export default async function compactVerify(
jws: string,
jws: string | Uint8Array,
key: KeyLike | CompactVerifyGetKey,
options?: VerifyOptions,
): Promise<CompactVerifyResult> {
if (jws instanceof Uint8Array) {
// eslint-disable-next-line no-param-reassign
jws = decoder.decode(jws)
}
if (typeof jws !== 'string') {
throw new JWSInvalid('Compact JWS must be a string')
throw new JWSInvalid('Compact JWS must be a string or Uint8Array')
}

@@ -75,3 +81,7 @@ const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.')

const verified = await verify(
{ payload, protected: protectedHeader, signature },
{
payload: (payload || undefined) as string,
protected: protectedHeader || undefined,
signature: (signature || undefined) as string,
},
key as Parameters<typeof verify>[1],

@@ -78,0 +88,0 @@ options,

@@ -128,4 +128,4 @@ /* eslint-disable no-underscore-dangle */

if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header')
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid')
}

@@ -132,0 +132,0 @@

@@ -84,19 +84,19 @@ import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js'

if (!('protected' in jws) && !('header' in jws)) {
if (jws.protected === undefined && jws.header === undefined) {
throw new JWSInvalid('Flattened JWS must have either of the "protected" or "header" members')
}
if ('protected' in jws && typeof jws.protected !== 'string') {
if (jws.protected !== undefined && typeof jws.protected !== 'string') {
throw new JWSInvalid('JWS Protected Header incorrect type')
}
if (!('payload' in jws)) {
if (jws.payload === undefined) {
throw new JWSInvalid('JWS Payload missing')
}
if (!('signature' in jws) || typeof jws.signature !== 'string') {
if (typeof jws.signature !== 'string') {
throw new JWSInvalid('JWS Signature missing or incorrect type')
}
if ('header' in jws && !isObject(jws.header)) {
if (jws.header !== undefined && !isObject(jws.header)) {
throw new JWSInvalid('JWS Unprotected Header incorrect type')

@@ -135,4 +135,4 @@ }

if (!alg) {
throw new JWSInvalid('missing JWS signature algorithm in JWS Header')
if (typeof alg !== 'string' || !alg) {
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid')
}

@@ -184,7 +184,7 @@

if ('protected' in jws) {
if (jws.protected !== undefined) {
result.protectedHeader = parsedProt
}
if ('header' in jws) {
if (jws.header !== undefined) {
result.unprotectedHeader = jws.header

@@ -191,0 +191,0 @@ }

@@ -66,3 +66,3 @@ import decrypt from '../jwe/compact/decrypt.js'

export default async function jwtDecrypt(
jwt: string,
jwt: string | Uint8Array,
key: KeyLike | JWTDecryptGetKey,

@@ -76,3 +76,3 @@ options?: JWTDecryptOptions,

if ('iss' in protectedHeader && protectedHeader.iss !== payload.iss) {
if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) {
throw new JWTClaimValidationFailed(

@@ -85,3 +85,3 @@ 'replicated "iss" claim header parameter mismatch',

if ('sub' in protectedHeader && protectedHeader.sub !== payload.sub) {
if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) {
throw new JWTClaimValidationFailed(

@@ -95,3 +95,3 @@ 'replicated "sub" claim header parameter mismatch',

if (
'aud' in protectedHeader &&
protectedHeader.aud !== undefined &&
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)

@@ -98,0 +98,0 @@ ) {

@@ -67,3 +67,3 @@ import verify from '../jws/compact/verify.js'

export default async function jwtVerify(
jwt: string,
jwt: string | Uint8Array,
key: KeyLike | JWTVerifyGetKey,

@@ -70,0 +70,0 @@ options?: JWTVerifyOptions,

@@ -18,4 +18,8 @@ import type { JWEHeaderParameters, KeyLike } from '../types.d'

function assertHeaderParameter(joseHeader: object, parameter: string, name: string) {
if (!(parameter in joseHeader)) {
function assertHeaderParameter(
joseHeader: { [propName: string]: any },
parameter: string,
name: string,
) {
if (joseHeader[parameter] === undefined) {
throw new JWEInvalid(`JOSE Header ${name} (${parameter}) missing`)

@@ -51,3 +55,5 @@ }

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime')
throw new JOSENotSupported(
'ECDH-ES with the provided key is not allowed or not supported by your javascript runtime',
)
}

@@ -57,4 +63,4 @@ const ephemeralKey = await ECDH.publicJwkToEphemeralKey(joseHeader.epk!)

let partyVInfo!: Uint8Array
if (joseHeader.apu) partyUInfo = base64url(joseHeader.apu)
if (joseHeader.apv) partyVInfo = base64url(joseHeader.apv)
if (joseHeader.apu !== undefined) partyUInfo = base64url(joseHeader.apu)
if (joseHeader.apv !== undefined) partyVInfo = base64url(joseHeader.apv)
const sharedSecret = await ECDH.deriveKey(

@@ -117,3 +123,3 @@ ephemeralKey,

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`)
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value')
}

@@ -120,0 +126,0 @@ }

@@ -42,3 +42,5 @@ import type { KeyLike, JWEKeyManagementHeaderParameters } from '../types.d'

if (!ECDH.ecdhAllowed(key)) {
throw new JOSENotSupported('ECDH not allowed or unsupported by your javascript runtime')
throw new JOSENotSupported(
'ECDH-ES with the provided key is not allowed or not supported by your javascript runtime',
)
}

@@ -109,3 +111,3 @@ const { apu, apv } = providedParameters

default: {
throw new JOSENotSupported(`alg ${alg} is unsupported`)
throw new JOSENotSupported('unsupported or invalid "alg" (JWE Algorithm) header value')
}

@@ -112,0 +114,0 @@ }

@@ -85,7 +85,7 @@ import type {

if ('iat' in payload || options.maxTokenAge) {
if (payload.iat !== undefined || options.maxTokenAge) {
if (typeof payload.iat !== 'number') {
throw new JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid')
}
if (!('exp' in payload) && payload.iat > now + tolerance) {
if (payload.exp === undefined && payload.iat > now + tolerance) {
throw new JWTClaimValidationFailed(

@@ -99,3 +99,3 @@ '"iat" claim timestamp check failed (it should be in the past)',

if ('nbf' in payload) {
if (payload.nbf !== undefined) {
if (typeof payload.nbf !== 'number') {

@@ -113,3 +113,3 @@ throw new JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid')

if ('exp' in payload) {
if (payload.exp !== undefined) {
if (typeof payload.exp !== 'number') {

@@ -116,0 +116,0 @@ throw new JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid')

@@ -14,3 +14,3 @@ const minute = 60

if (!matched) {
throw new TypeError(`invalid time period format ("${str}")`)
throw new TypeError('invalid time period format')
}

@@ -17,0 +17,0 @@

import { JOSENotSupported, JWEInvalid, JWSInvalid } from '../util/errors.js'
type CritCheckHeader = object & {
interface CritCheckHeader {
b64?: boolean
crit?: string[]
[propName: string]: any
}
const isString = (input: string) => typeof input !== 'string' || input.length === 0
function validateCrit(

@@ -16,8 +15,8 @@ Err: typeof JWEInvalid | typeof JWSInvalid,

) {
if ('crit' in joseHeader && !('crit' in protectedHeader)) {
if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) {
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected')
}
if (!protectedHeader || !('crit' in protectedHeader)) {
return new Set([])
if (!protectedHeader || protectedHeader.crit === undefined) {
return new Set()
}

@@ -28,3 +27,3 @@

protectedHeader.crit.length === 0 ||
protectedHeader.crit.some(isString)
protectedHeader.crit.some((input: string) => typeof input !== 'string' || input.length === 0)
) {

@@ -44,5 +43,5 @@ throw new Err(

if (!(parameter in joseHeader)) {
if (joseHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" is missing`)
} else if (supported.get(parameter) && !(parameter in protectedHeader)) {
} else if (supported.get(parameter) && protectedHeader[parameter] === undefined) {
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`)

@@ -49,0 +48,0 @@ }

@@ -55,5 +55,9 @@ import type { JWK, KeyLike } from '../types.d'

export interface AesGcmKwUnwrapFunction {
(alg: string, key: any, encryptedKey: Uint8Array, iv: Uint8Array, tag: Uint8Array): Promise<
Uint8Array
>
(
alg: string,
key: any,
encryptedKey: Uint8Array,
iv: Uint8Array,
tag: Uint8Array,
): Promise<Uint8Array>
}

@@ -68,5 +72,9 @@ export interface Pbes2KWEncryptFunction {

export interface Pbes2KWDecryptFunction {
(alg: string, key: any, encryptedKey: Uint8Array, p2c: number, p2s: Uint8Array): Promise<
Uint8Array
>
(
alg: string,
key: any,
encryptedKey: Uint8Array,
p2c: number,
p2s: Uint8Array,
): Promise<Uint8Array>
}

@@ -115,3 +123,3 @@ export interface EcdhESDeriveKeyFunction {

export interface FetchFunction {
(url: URL, timeout: number): Promise<any>
(url: URL, timeout: number, options: any): Promise<any>
}

@@ -124,1 +132,4 @@ export interface DigestFunction {

}
export interface JWKConvertFunction {
(key: any): AsyncOrSync<JWK>
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc