jose-node-esm-runtime
Advanced tools
Comparing version 4.3.9 to 4.4.0
@@ -19,2 +19,3 @@ export { compactDecrypt } from './jwe/compact/decrypt.js'; | ||
export { EmbeddedJWK } from './jwk/embedded.js'; | ||
export { createLocalJWKSet } from './jwks/local.js'; | ||
export { createRemoteJWKSet } from './jwks/remote.js'; | ||
@@ -21,0 +22,0 @@ export { UnsecuredJWT } from './jwt/unsecured.js'; |
import fetchJwks from '../runtime/fetch_jwks.js'; | ||
import { importJWK } from '../key/import.js'; | ||
import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js'; | ||
import isObject from '../lib/is_object.js'; | ||
function getKtyFromAlg(alg) { | ||
switch (typeof alg === 'string' && alg.slice(0, 2)) { | ||
case 'RS': | ||
case 'PS': | ||
return 'RSA'; | ||
case 'ES': | ||
return 'EC'; | ||
case 'Ed': | ||
return 'OKP'; | ||
default: | ||
throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set'); | ||
} | ||
} | ||
function isJWKLike(key) { | ||
return isObject(key); | ||
} | ||
class RemoteJWKSet { | ||
import { JWKSInvalid, JWKSNoMatchingKey } from '../util/errors.js'; | ||
import { isJWKSLike, LocalJWKSet } from './local.js'; | ||
class RemoteJWKSet extends LocalJWKSet { | ||
constructor(url, options) { | ||
this._cached = new WeakMap(); | ||
super({ keys: [] }); | ||
this._jwks = undefined; | ||
if (!(url instanceof URL)) { | ||
@@ -41,65 +25,17 @@ throw new TypeError('url must be an instance of URL'); | ||
async getKey(protectedHeader, token) { | ||
const joseHeader = { | ||
...protectedHeader, | ||
...token.header, | ||
}; | ||
if (!this._jwks) { | ||
await this.reload(); | ||
} | ||
const candidates = this._jwks.keys.filter((jwk) => { | ||
let candidate = jwk.kty === getKtyFromAlg(joseHeader.alg); | ||
if (candidate && typeof joseHeader.kid === 'string') { | ||
candidate = joseHeader.kid === jwk.kid; | ||
} | ||
if (candidate && typeof jwk.alg === 'string') { | ||
candidate = joseHeader.alg === jwk.alg; | ||
} | ||
if (candidate && typeof jwk.use === 'string') { | ||
candidate = jwk.use === 'sig'; | ||
} | ||
if (candidate && Array.isArray(jwk.key_ops)) { | ||
candidate = jwk.key_ops.includes('verify'); | ||
} | ||
if (candidate && joseHeader.alg === 'EdDSA') { | ||
candidate = jwk.crv === 'Ed25519' || jwk.crv === 'Ed448'; | ||
} | ||
if (candidate) { | ||
switch (joseHeader.alg) { | ||
case 'ES256': | ||
candidate = jwk.crv === 'P-256'; | ||
break; | ||
case 'ES256K': | ||
candidate = jwk.crv === 'secp256k1'; | ||
break; | ||
case 'ES384': | ||
candidate = jwk.crv === 'P-384'; | ||
break; | ||
case 'ES512': | ||
candidate = jwk.crv === 'P-521'; | ||
break; | ||
default: | ||
try { | ||
return await super.getKey(protectedHeader, token); | ||
} | ||
catch (err) { | ||
if (err instanceof JWKSNoMatchingKey) { | ||
if (this.coolingDown() === false) { | ||
await this.reload(); | ||
return super.getKey(protectedHeader, token); | ||
} | ||
} | ||
return candidate; | ||
}); | ||
const { 0: jwk, length } = candidates; | ||
if (length === 0) { | ||
if (this.coolingDown() === false) { | ||
await this.reload(); | ||
return this.getKey(protectedHeader, token); | ||
} | ||
throw new JWKSNoMatchingKey(); | ||
throw err; | ||
} | ||
else if (length !== 1) { | ||
throw new JWKSMultipleMatchingKeys(); | ||
} | ||
const cached = this._cached.get(jwk) || this._cached.set(jwk, {}).get(jwk); | ||
if (cached[joseHeader.alg] === undefined) { | ||
const keyObject = await importJWK({ ...jwk, ext: true }, joseHeader.alg); | ||
if (keyObject instanceof Uint8Array || keyObject.type !== 'public') { | ||
throw new JWKSInvalid('JSON Web Key Set members must be public keys'); | ||
} | ||
cached[joseHeader.alg] = keyObject; | ||
} | ||
return cached[joseHeader.alg]; | ||
} | ||
@@ -110,6 +46,3 @@ async reload() { | ||
.then((json) => { | ||
if (typeof json !== 'object' || | ||
!json || | ||
!Array.isArray(json.keys) || | ||
!json.keys.every(isJWKLike)) { | ||
if (!isJWKSLike(json)) { | ||
throw new JWKSInvalid('JSON Web Key Set malformed'); | ||
@@ -116,0 +49,0 @@ } |
@@ -30,2 +30,3 @@ export { compactDecrypt } from './jwe/compact/decrypt'; | ||
export { EmbeddedJWK } from './jwk/embedded'; | ||
export { createLocalJWKSet } from './jwks/local'; | ||
export { createRemoteJWKSet } from './jwks/remote'; | ||
@@ -46,2 +47,2 @@ export type { RemoteJWKSetOptions } from './jwks/remote'; | ||
export * as base64url from './util/base64url'; | ||
export type { KeyLike, JWK, FlattenedJWSInput, GeneralJWSInput, FlattenedJWS, GeneralJWS, JoseHeaderParameters, JWSHeaderParameters, JWEKeyManagementHeaderParameters, FlattenedJWE, GeneralJWE, JWEHeaderParameters, CritOption, DeflateOption, DecryptOptions, EncryptOptions, JWTClaimVerificationOptions, VerifyOptions, SignOptions, JWTPayload, DeflateFunction, InflateFunction, FlattenedDecryptResult, GeneralDecryptResult, CompactDecryptResult, FlattenedVerifyResult, GeneralVerifyResult, CompactVerifyResult, JWTVerifyResult, JWTDecryptResult, ResolvedKey, CompactJWEHeaderParameters, CompactJWSHeaderParameters, JWTHeaderParameters, } from './types'; | ||
export type { KeyLike, JWK, FlattenedJWSInput, GeneralJWSInput, FlattenedJWS, GeneralJWS, JoseHeaderParameters, JWSHeaderParameters, JWEKeyManagementHeaderParameters, FlattenedJWE, GeneralJWE, JWEHeaderParameters, CritOption, DeflateOption, DecryptOptions, EncryptOptions, JWTClaimVerificationOptions, VerifyOptions, SignOptions, JWTPayload, DeflateFunction, InflateFunction, FlattenedDecryptResult, GeneralDecryptResult, CompactDecryptResult, FlattenedVerifyResult, GeneralVerifyResult, CompactVerifyResult, JWTVerifyResult, JWTDecryptResult, ResolvedKey, CompactJWEHeaderParameters, CompactJWSHeaderParameters, JWTHeaderParameters, JSONWebKeySet, } from './types'; |
@@ -271,1 +271,4 @@ /** | ||
} | ||
export interface JSONWebKeySet { | ||
keys: JWK[] | ||
} |
{ | ||
"name": "jose-node-esm-runtime", | ||
"version": "4.3.9", | ||
"version": "4.4.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
176730
115
4482