jose-browser-runtime
Advanced tools
Comparing version 4.11.4 to 4.12.0
@@ -41,3 +41,3 @@ import { importJWK } from '../key/import.js'; | ||
async getKey(protectedHeader, token) { | ||
const { alg, kid } = { ...protectedHeader, ...token.header }; | ||
const { alg, kid } = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header }; | ||
const kty = getKtyFromAlg(alg); | ||
@@ -84,14 +84,29 @@ const candidates = this._jwks.keys.filter((jwk) => { | ||
else if (length !== 1) { | ||
throw new JWKSMultipleMatchingKeys(); | ||
const error = new JWKSMultipleMatchingKeys(); | ||
const { _cached } = this; | ||
error[Symbol.asyncIterator] = async function* () { | ||
for (const jwk of candidates) { | ||
try { | ||
yield await importWithAlgCache(_cached, jwk, alg); | ||
} | ||
catch (_a) { | ||
continue; | ||
} | ||
} | ||
}; | ||
throw error; | ||
} | ||
const cached = this._cached.get(jwk) || this._cached.set(jwk, {}).get(jwk); | ||
if (cached[alg] === undefined) { | ||
const keyObject = await importJWK({ ...jwk, ext: true }, alg); | ||
if (keyObject instanceof Uint8Array || keyObject.type !== 'public') { | ||
throw new JWKSInvalid('JSON Web Key Set members must be public keys'); | ||
} | ||
cached[alg] = keyObject; | ||
return importWithAlgCache(this._cached, jwk, alg); | ||
} | ||
} | ||
async function importWithAlgCache(cache, jwk, alg) { | ||
const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk); | ||
if (cached[alg] === undefined) { | ||
const keyObject = await importJWK({ ...jwk, ext: true }, alg); | ||
if (keyObject.type !== 'public') { | ||
throw new JWKSInvalid('JSON Web Key Set members must be public keys'); | ||
} | ||
return cached[alg]; | ||
cached[alg] = keyObject; | ||
} | ||
return cached[alg]; | ||
} | ||
@@ -98,0 +113,0 @@ export function createLocalJWKSet(jwks) { |
@@ -128,2 +128,3 @@ export class JOSEError extends Error { | ||
} | ||
Symbol.asyncIterator; | ||
export class JWKSTimeout extends JOSEError { | ||
@@ -130,0 +131,0 @@ constructor() { |
@@ -1,2 +0,2 @@ | ||
import type { KeyLike, JWSHeaderParameters, JSONWebKeySet, FlattenedJWSInput, GetKeyFunction } from '../types'; | ||
import type { KeyLike, JWSHeaderParameters, JSONWebKeySet, FlattenedJWSInput } from '../types'; | ||
/** @private */ | ||
@@ -9,3 +9,3 @@ export declare function isJWKSLike(jwks: unknown): jwks is JSONWebKeySet; | ||
constructor(jwks: unknown); | ||
getKey(protectedHeader: JWSHeaderParameters, token: FlattenedJWSInput): Promise<KeyLike>; | ||
getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<KeyLike>; | ||
} | ||
@@ -16,4 +16,11 @@ /** | ||
* | ||
* Only a single public key must match the selection process. | ||
* It uses the "alg" (JWS Algorithm) Header Parameter to determine the right JWK "kty" (Key Type), | ||
* then proceeds to match the JWK "kid" (Key ID) with one found in the JWS Header Parameters (if | ||
* there is one) while also respecting the JWK "use" (Public Key Use) and JWK "key_ops" (Key | ||
* Operations) Parameters (if they are present on the JWK). | ||
* | ||
* Only a single public key must match the selection process. As shown in the example below when | ||
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt | ||
* verification in an iterative manner. | ||
* | ||
* @example Usage | ||
@@ -48,4 +55,34 @@ * | ||
* | ||
* @example Opting-in to multiple JWKS matches using `createLocalJWKSet` | ||
* | ||
* ```js | ||
* const options = { | ||
* issuer: 'urn:example:issuer', | ||
* audience: 'urn:example:audience', | ||
* } | ||
* const { payload, protectedHeader } = await jose | ||
* .jwtVerify(jwt, JWKS, options) | ||
* .catch(async (error) => { | ||
* if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') { | ||
* for await (const publicKey of error) { | ||
* try { | ||
* return await jose.jwtVerify(jwt, publicKey, options) | ||
* } catch (innerError) { | ||
* if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') { | ||
* continue | ||
* } | ||
* throw innerError | ||
* } | ||
* } | ||
* throw new jose.errors.JWSSignatureVerificationFailed() | ||
* } | ||
* | ||
* throw error | ||
* }) | ||
* console.log(protectedHeader) | ||
* console.log(payload) | ||
* ``` | ||
* | ||
* @param jwks JSON Web Key Set formatted object. | ||
*/ | ||
export declare function createLocalJWKSet(jwks: JSONWebKeySet): GetKeyFunction<JWSHeaderParameters, FlattenedJWSInput>; | ||
export declare function createLocalJWKSet(jwks: JSONWebKeySet): (protectedHeader?: JWSHeaderParameters | undefined, token?: FlattenedJWSInput | undefined) => Promise<KeyLike>; |
@@ -1,2 +0,2 @@ | ||
import type { JWSHeaderParameters, FlattenedJWSInput, GetKeyFunction } from '../types'; | ||
import type { KeyLike, JWSHeaderParameters, FlattenedJWSInput } from '../types'; | ||
/** Options for the remote JSON Web Key Set. */ | ||
@@ -33,7 +33,15 @@ export interface RemoteJWKSetOptions { | ||
* Returns a function that resolves to a key object downloaded from a remote endpoint returning a | ||
* JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC jwks_uri. Only a single public key | ||
* must match the selection process. The JSON Web Key Set is fetched when no key matches the | ||
* selection process but only as frequently as the `cooldownDuration` option allows, to prevent | ||
* abuse. | ||
* JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC jwks_uri. The JSON Web Key Set is | ||
* fetched when no key matches the selection process but only as frequently as the | ||
* `cooldownDuration` option allows to prevent abuse. | ||
* | ||
* It uses the "alg" (JWS Algorithm) Header Parameter to determine the right JWK "kty" (Key Type), | ||
* then proceeds to match the JWK "kid" (Key ID) with one found in the JWS Header Parameters (if | ||
* there is one) while also respecting the JWK "use" (Public Key Use) and JWK "key_ops" (Key | ||
* Operations) Parameters (if they are present on the JWK). | ||
* | ||
* Only a single public key must match the selection process. As shown in the example below when | ||
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt | ||
* verification in an iterative manner. | ||
* | ||
* @example Usage | ||
@@ -52,5 +60,35 @@ * | ||
* | ||
* @example Opting-in to multiple JWKS matches using `createRemoteJWKSet` | ||
* | ||
* ```js | ||
* const options = { | ||
* issuer: 'urn:example:issuer', | ||
* audience: 'urn:example:audience', | ||
* } | ||
* const { payload, protectedHeader } = await jose | ||
* .jwtVerify(jwt, JWKS, options) | ||
* .catch(async (error) => { | ||
* if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') { | ||
* for await (const publicKey of error) { | ||
* try { | ||
* return await jose.jwtVerify(jwt, publicKey, options) | ||
* } catch (innerError) { | ||
* if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') { | ||
* continue | ||
* } | ||
* throw innerError | ||
* } | ||
* } | ||
* throw new jose.errors.JWSSignatureVerificationFailed() | ||
* } | ||
* | ||
* throw error | ||
* }) | ||
* console.log(protectedHeader) | ||
* console.log(payload) | ||
* ``` | ||
* | ||
* @param url URL to fetch the JSON Web Key Set from. | ||
* @param options Options for the remote JSON Web Key Set. | ||
*/ | ||
export declare function createRemoteJWKSet(url: URL, options?: RemoteJWKSetOptions): GetKeyFunction<JWSHeaderParameters, FlattenedJWSInput>; | ||
export declare function createRemoteJWKSet(url: URL, options?: RemoteJWKSetOptions): (protectedHeader?: JWSHeaderParameters | undefined, token?: FlattenedJWSInput | undefined) => Promise<KeyLike>; |
@@ -56,3 +56,3 @@ import type { JWTHeaderParameters, KeyLike, SignOptions } from '../types'; | ||
* ak6k+8+UFd93M4z0Qo74OhXB | ||
* -----END PRIVATE KEY----` | ||
* -----END PRIVATE KEY-----` | ||
* const privateKey = await jose.importPKCS8(pkcs8, alg) | ||
@@ -59,0 +59,0 @@ * |
@@ -0,1 +1,2 @@ | ||
import type { KeyLike } from '../types'; | ||
/** A generic Error subclass that all other specific JOSE Error subclasses inherit from. */ | ||
@@ -81,2 +82,4 @@ export declare class JOSEError extends Error { | ||
export declare class JWKSMultipleMatchingKeys extends JOSEError { | ||
/** @ignore */ | ||
[Symbol.asyncIterator]: () => AsyncIterableIterator<KeyLike>; | ||
static get code(): 'ERR_JWKS_MULTIPLE_MATCHING_KEYS'; | ||
@@ -83,0 +86,0 @@ code: string; |
{ | ||
"name": "jose-browser-runtime", | ||
"version": "4.11.4", | ||
"version": "4.12.0", | ||
"homepage": "https://github.com/panva/jose", | ||
@@ -5,0 +5,0 @@ "repository": "panva/jose", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
231397
5807