oauth4webapi 2.15.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -60,8 +60,9 @@ import * as oauth from 'oauth4webapi'
60
60
  - Device Authorization Grant - [source](examples/device_authorization_grant.ts)
61
61
  - Refresh Token Grant - [source](examples/refresh_token.ts) | [diff](examples/refresh_token.diff)
62
62
  - FAPI
63
- - FAPI 1.0 Advanced (Private Key JWT, MTLS, JAR) - [source](examples/fapi1-advanced.ts) | [diff](examples/fapi1-advanced.diff)
64
- - FAPI 2.0 Security Profile (Private Key JWT, PAR, DPoP) - [source](examples/fapi2.ts) | [diff](examples/fapi2.diff)
63
+ - FAPI 1.0 Advanced - [source](examples/fapi1-advanced.ts) | [diff](examples/fapi1-advanced.diff)
64
+ - FAPI 2.0 Security Profile - [source](examples/fapi2.ts) | [diff](examples/fapi2.diff)
65
+ - FAPI 2.0 Message Signing - [source](examples/fapi2-message-signing.ts) | [diff](examples/fapi2-message-signing.diff)
65
66
 
66
67
 
67
68
  ## Supported Runtimes
package/build/index.d.ts CHANGED
@@ -16,6 +16,17 @@ export type JsonPrimitive = string | number | boolean | null;
16
16
  * JSON Values
17
17
  */
18
18
  export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
19
+ export interface ModifyAssertionFunction {
20
+ (
21
+ /**
22
+ * JWS Header to modify right before it is signed.
23
+ */
24
+ header: Record<string, JsonValue | undefined>,
25
+ /**
26
+ * JWT Claims Set to modify right before it is signed.
27
+ */
28
+ payload: Record<string, JsonValue | undefined>): void;
29
+ }
19
30
  /**
20
31
  * Interface to pass an asymmetric private key and, optionally, its associated JWK Key ID to be
21
32
  * added as a `kid` JOSE Header Parameter.
@@ -32,6 +43,12 @@ export interface PrivateKey {
32
43
  * ID) will be added to the JOSE Header.
33
44
  */
34
45
  kid?: string;
46
+ /**
47
+ * Use to modify the JWT signed by this key right before it is signed.
48
+ *
49
+ * @see {@link modifyAssertion}
50
+ */
51
+ [modifyAssertion]?: ModifyAssertionFunction;
35
52
  }
36
53
  /**
37
54
  * Supported Client Authentication Methods.
@@ -278,6 +295,100 @@ export declare const clockTolerance: unique symbol;
278
295
  * ```
279
296
  */
280
297
  export declare const customFetch: unique symbol;
298
+ /**
299
+ * Use to mutate JWT header and payload before they are signed. Its intended use is working around
300
+ * non-conform server behaviours, such as modifying JWT "aud" (audience) claims, or otherwise
301
+ * changing fixed claims used by this library.
302
+ *
303
+ * @example
304
+ *
305
+ * Changing Private Key JWT client assertion audience issued from an array to a string
306
+ *
307
+ * ```ts
308
+ * import * as oauth from 'oauth4webapi'
309
+ *
310
+ * // Prerequisites
311
+ * let as!: oauth.AuthorizationServer
312
+ * let client!: oauth.Client
313
+ * let parameters!: URLSearchParams
314
+ * let clientPrivateKey!: CryptoKey
315
+ *
316
+ * const response = await oauth.pushedAuthorizationRequest(as, client, parameters, {
317
+ * clientPrivateKey: {
318
+ * key: clientPrivateKey,
319
+ * [oauth.modifyAssertion](header, payload) {
320
+ * payload.aud = as.issuer
321
+ * },
322
+ * },
323
+ * })
324
+ * ```
325
+ *
326
+ * @example
327
+ *
328
+ * Changing Request Object issued by {@link issueRequestObject} to have an expiration of 5 minutes
329
+ *
330
+ * ```ts
331
+ * import * as oauth from 'oauth4webapi'
332
+ *
333
+ * // Prerequisites
334
+ * let as!: oauth.AuthorizationServer
335
+ * let client!: oauth.Client
336
+ * let parameters!: URLSearchParams
337
+ * let jarPrivateKey!: CryptoKey
338
+ *
339
+ * const request = await oauth.issueRequestObject(as, client, parameters, {
340
+ * key: jarPrivateKey,
341
+ * [oauth.modifyAssertion](header, payload) {
342
+ * payload.exp = <number>payload.iat + 300
343
+ * },
344
+ * })
345
+ * ```
346
+ */
347
+ export declare const modifyAssertion: unique symbol;
348
+ /**
349
+ * Use to add support for decrypting JWEs the client encounters, namely
350
+ *
351
+ * - Encrypted ID Tokens returned by the Token Endpoint
352
+ * - Encrypted ID Tokens returned as part of FAPI 1.0 Advanced Detached Signature authorization
353
+ * responses
354
+ * - Encrypted JWT UserInfo responses
355
+ * - Encrypted JWT Introspection responses
356
+ * - Encrypted JARM Responses
357
+ *
358
+ * @example
359
+ *
360
+ * Decrypting JARM responses
361
+ *
362
+ * ```ts
363
+ * import * as oauth from 'oauth4webapi'
364
+ * import * as jose from 'jose'
365
+ *
366
+ * // Prerequisites
367
+ * let as!: oauth.AuthorizationServer
368
+ * let key!: CryptoKey
369
+ * let alg!: string
370
+ * let enc!: string
371
+ *
372
+ * const decoder = new TextDecoder()
373
+ *
374
+ * const client: oauth.Client = {
375
+ * client_id: 'urn:example:client_id',
376
+ * async [oauth.jweDecrypt](jwe) {
377
+ * const { plaintext } = await compactDecrypt(jwe, key, {
378
+ * keyManagementAlgorithms: [alg],
379
+ * contentEncryptionAlgorithms: [enc],
380
+ * }).catch((cause) => {
381
+ * throw new oauth.OperationProcessingError('decryption failed', { cause })
382
+ * })
383
+ *
384
+ * return decoder.decode(plaintext)
385
+ * },
386
+ * }
387
+ *
388
+ * const params = await oauth.validateJwtAuthResponse(as, client, currentUrl)
389
+ * ```
390
+ */
391
+ export declare const jweDecrypt: unique symbol;
281
392
  /**
282
393
  * DANGER ZONE - This option has security implications that must be understood, assessed for
283
394
  * applicability, and accepted before use. It is critical that the JSON Web Key Set cache only be
@@ -347,48 +458,45 @@ export declare const jwksCache: unique symbol;
347
458
  * (Node.js) Using [nodejs/undici](https://github.com/nodejs/undici) for Mutual-TLS Client
348
459
  * Authentication and Certificate-Bound Access Tokens support.
349
460
  *
350
- * ```js
461
+ * ```ts
351
462
  * import * as undici from 'undici'
352
463
  * import * as oauth from 'oauth4webapi'
353
464
  *
465
+ * // Prerequisites
466
+ * let as!: oauth.AuthorizationServer
467
+ * let client!: oauth.Client
468
+ * let params!: URLSearchParams
469
+ * let key!: string // PEM-encoded key
470
+ * let cert!: string // PEM-encoded certificate
471
+ *
472
+ * const agent = new undici.Agent({ connect: { key, cert } })
473
+ *
354
474
  * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
355
475
  * [oauth.useMtlsAlias]: true,
356
- * [oauth.customFetch]: (...args) => {
357
- * return undici.fetch(args[0], {
358
- * ...args[1],
359
- * dispatcher: new undici.Agent({
360
- * connect: {
361
- * key: clientKey,
362
- * cert: clientCertificate,
363
- * },
364
- * }),
365
- * })
366
- * },
476
+ * [oauth.customFetch]: (...args) => undici.fetch(args[0], { ...args[1], dispatcher: agent }),
367
477
  * })
368
478
  * ```
369
479
  *
370
480
  * @example
371
481
  *
372
482
  * (Deno) Using Deno.createHttpClient API for Mutual-TLS Client Authentication and Certificate-Bound
373
- * Access Tokens support. This is currently (Jan 2023) locked behind the --unstable command line
374
- * flag.
483
+ * Access Tokens support.
375
484
  *
376
- * ```js
485
+ * ```ts
377
486
  * import * as oauth from 'oauth4webapi'
378
487
  *
379
- * const agent = Deno.createHttpClient({
380
- * certChain: clientCertificate,
381
- * privateKey: clientKey,
382
- * })
488
+ * // Prerequisites
489
+ * let as!: oauth.AuthorizationServer
490
+ * let client!: oauth.Client
491
+ * let params!: URLSearchParams
492
+ * let key!: string // PEM-encoded key
493
+ * let cert!: string // PEM-encoded certificate
494
+ *
495
+ * const agent = Deno.createHttpClient({ key, cert })
383
496
  *
384
497
  * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
385
498
  * [oauth.useMtlsAlias]: true,
386
- * [oauth.customFetch]: (...args) => {
387
- * return fetch(args[0], {
388
- * ...args[1],
389
- * client: agent,
390
- * })
391
- * },
499
+ * [oauth.customFetch]: (...args) => fetch(args[0], { ...args[1], client: agent }),
392
500
  * })
393
501
  * ```
394
502
  *
@@ -782,6 +890,10 @@ export interface Client {
782
890
  * See {@link clockTolerance}.
783
891
  */
784
892
  [clockTolerance]?: number;
893
+ /**
894
+ * See {@link jweDecrypt}.
895
+ */
896
+ [jweDecrypt]?: JweDecryptFunction;
785
897
  [metadata: string]: JsonValue | undefined;
786
898
  }
787
899
  /**
@@ -923,6 +1035,12 @@ export interface DPoPOptions extends CryptoKeyPair {
923
1035
  * will be used automatically.
924
1036
  */
925
1037
  nonce?: string;
1038
+ /**
1039
+ * Use to modify the DPoP Proof JWT right before it is signed.
1040
+ *
1041
+ * @see {@link modifyAssertion}
1042
+ */
1043
+ [modifyAssertion]?: ModifyAssertionFunction;
926
1044
  }
927
1045
  export interface DPoPRequestOptions {
928
1046
  /**
@@ -1611,6 +1729,9 @@ export declare function processIntrospectionResponse(as: AuthorizationServer, cl
1611
1729
  export interface JWKS {
1612
1730
  readonly keys: JWK[];
1613
1731
  }
1732
+ export interface JweDecryptFunction {
1733
+ (jwe: string): Promise<string>;
1734
+ }
1614
1735
  /**
1615
1736
  * Same as {@link validateAuthResponse} but for signed JARM responses.
1616
1737
  *
package/build/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  let USER_AGENT;
2
2
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
3
3
  const NAME = 'oauth4webapi';
4
- const VERSION = 'v2.15.0';
4
+ const VERSION = 'v2.16.0';
5
5
  USER_AGENT = `${NAME}/${VERSION}`;
6
6
  }
7
7
  function looseInstanceOf(input, expected) {
@@ -19,6 +19,8 @@ function looseInstanceOf(input, expected) {
19
19
  export const clockSkew = Symbol();
20
20
  export const clockTolerance = Symbol();
21
21
  export const customFetch = Symbol();
22
+ export const modifyAssertion = Symbol();
23
+ export const jweDecrypt = Symbol();
22
24
  export const jwksCache = Symbol();
23
25
  export const useMtlsAlias = Symbol();
24
26
  const encoder = new TextEncoder();
@@ -279,7 +281,11 @@ function getKeyAndKid(input) {
279
281
  if (input.kid !== undefined && !validateString(input.kid)) {
280
282
  throw new TypeError('"kid" must be a non-empty string');
281
283
  }
282
- return { key: input.key, kid: input.kid };
284
+ return {
285
+ key: input.key,
286
+ kid: input.kid,
287
+ modifyAssertion: input[modifyAssertion],
288
+ };
283
289
  }
284
290
  function formUrlEncode(token) {
285
291
  return encodeURIComponent(token).replace(/%20/g, '+');
@@ -366,11 +372,11 @@ function clientAssertion(as, client) {
366
372
  sub: client.client_id,
367
373
  };
368
374
  }
369
- async function privateKeyJwt(as, client, key, kid) {
370
- return jwt({
371
- alg: keyToJws(key),
372
- kid,
373
- }, clientAssertion(as, client), key);
375
+ async function privateKeyJwt(as, client, key, kid, modifyAssertion) {
376
+ const header = { alg: keyToJws(key), kid };
377
+ const payload = clientAssertion(as, client);
378
+ modifyAssertion?.(header, payload);
379
+ return jwt(header, payload, key);
374
380
  }
375
381
  function assertAs(as) {
376
382
  if (typeof as !== 'object' || as === null) {
@@ -428,13 +434,13 @@ async function clientAuthentication(as, client, body, headers, clientPrivateKey)
428
434
  if (clientPrivateKey === undefined) {
429
435
  throw new TypeError('"options.clientPrivateKey" must be provided when "client.token_endpoint_auth_method" is "private_key_jwt"');
430
436
  }
431
- const { key, kid } = getKeyAndKid(clientPrivateKey);
437
+ const { key, kid, modifyAssertion } = getKeyAndKid(clientPrivateKey);
432
438
  if (!isPrivateKey(key)) {
433
439
  throw new TypeError('"options.clientPrivateKey.key" must be a private CryptoKey');
434
440
  }
435
441
  body.set('client_id', client.client_id);
436
442
  body.set('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
437
- body.set('client_assertion', await privateKeyJwt(as, client, key, kid));
443
+ body.set('client_assertion', await privateKeyJwt(as, client, key, kid, modifyAssertion));
438
444
  break;
439
445
  }
440
446
  case 'tls_client_auth':
@@ -449,11 +455,11 @@ async function clientAuthentication(as, client, body, headers, clientPrivateKey)
449
455
  throw new UnsupportedOperationError('unsupported client token_endpoint_auth_method');
450
456
  }
451
457
  }
452
- async function jwt(header, claimsSet, key) {
458
+ async function jwt(header, payload, key) {
453
459
  if (!key.usages.includes('sign')) {
454
460
  throw new TypeError('CryptoKey instances used for signing assertions must include "sign" in their "usages"');
455
461
  }
456
- const input = `${b64u(buf(JSON.stringify(header)))}.${b64u(buf(JSON.stringify(claimsSet)))}`;
462
+ const input = `${b64u(buf(JSON.stringify(header)))}.${b64u(buf(JSON.stringify(payload)))}`;
457
463
  const signature = b64u(await crypto.subtle.sign(keyToSubtle(key), key, buf(input)));
458
464
  return `${input}.${signature}`;
459
465
  }
@@ -461,7 +467,7 @@ export async function issueRequestObject(as, client, parameters, privateKey) {
461
467
  assertAs(as);
462
468
  assertClient(client);
463
469
  parameters = new URLSearchParams(parameters);
464
- const { key, kid } = getKeyAndKid(privateKey);
470
+ const { key, kid, modifyAssertion } = getKeyAndKid(privateKey);
465
471
  if (!isPrivateKey(key)) {
466
472
  throw new TypeError('"privateKey.key" must be a private CryptoKey');
467
473
  }
@@ -519,11 +525,13 @@ export async function issueRequestObject(as, client, parameters, privateKey) {
519
525
  }
520
526
  }
521
527
  }
522
- return jwt({
528
+ const header = {
523
529
  alg: keyToJws(key),
524
530
  typ: 'oauth-authz-req+jwt',
525
531
  kid,
526
- }, claims, key);
532
+ };
533
+ modifyAssertion?.(header, claims);
534
+ return jwt(header, claims, key);
527
535
  }
528
536
  async function dpopProofJwt(headers, options, url, htm, clockSkew, accessToken) {
529
537
  const { privateKey, publicKey, nonce = dpopNonces.get(url.origin) } = options;
@@ -540,19 +548,21 @@ async function dpopProofJwt(headers, options, url, htm, clockSkew, accessToken)
540
548
  throw new TypeError('"DPoP.publicKey.extractable" must be true');
541
549
  }
542
550
  const now = epochTime() + clockSkew;
543
- const proof = await jwt({
551
+ const header = {
544
552
  alg: keyToJws(privateKey),
545
553
  typ: 'dpop+jwt',
546
554
  jwk: await publicJwk(publicKey),
547
- }, {
555
+ };
556
+ const payload = {
548
557
  iat: now,
549
558
  jti: randomBytes(),
550
559
  htm,
551
560
  nonce,
552
561
  htu: `${url.origin}${url.pathname}`,
553
562
  ath: accessToken ? b64u(await crypto.subtle.digest('SHA-256', buf(accessToken))) : undefined,
554
- }, privateKey);
555
- headers.set('dpop', proof);
563
+ };
564
+ options[modifyAssertion]?.(header, payload);
565
+ headers.set('dpop', await jwt(header, payload, privateKey));
556
566
  }
557
567
  let jwkCache;
558
568
  async function getSetPublicJwkCache(key) {
@@ -858,8 +868,7 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
858
868
  let json;
859
869
  if (getContentType(response) === 'application/jwt') {
860
870
  assertReadableResponse(response);
861
- const jwt = await response.text();
862
- const { claims } = await validateJwt(jwt, checkSigningAlgorithm.bind(undefined, client.userinfo_signed_response_alg, as.userinfo_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client))
871
+ const { claims, jwt } = await validateJwt(await response.text(), checkSigningAlgorithm.bind(undefined, client.userinfo_signed_response_alg, as.userinfo_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client), client[jweDecrypt])
863
872
  .then(validateOptionalAudience.bind(undefined, client.client_id))
864
873
  .then(validateOptionalIssuer.bind(undefined, as.issuer));
865
874
  jwtResponseBodies.set(response, jwt);
@@ -937,14 +946,14 @@ export function getValidatedIdTokenClaims(ref) {
937
946
  if (!claims) {
938
947
  throw new TypeError('"ref" was already garbage collected or did not resolve from the proper sources');
939
948
  }
940
- return claims;
949
+ return claims[0];
941
950
  }
942
951
  export async function validateIdTokenSignature(as, ref, options) {
943
952
  assertAs(as);
944
- if (!getValidatedIdTokenClaims(ref)) {
953
+ if (!idTokenClaims.has(ref)) {
945
954
  throw new OPE('"ref" does not contain an ID Token to verify the signature of');
946
955
  }
947
- const { 0: protectedHeader, 1: payload, 2: encodedSignature } = ref.id_token.split('.');
956
+ const { 0: protectedHeader, 1: payload, 2: encodedSignature, } = idTokenClaims.get(ref)[1].split('.');
948
957
  const header = JSON.parse(buf(b64u(protectedHeader)));
949
958
  if (header.alg.startsWith('HS')) {
950
959
  throw new UnsupportedOperationError();
@@ -1024,7 +1033,7 @@ async function processGenericAccessTokenResponse(as, client, response, ignoreIdT
1024
1033
  throw new OPE('"response" body "id_token" property must be a non-empty string');
1025
1034
  }
1026
1035
  if (json.id_token) {
1027
- const { claims } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client))
1036
+ const { claims, jwt } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client), client[jweDecrypt])
1028
1037
  .then(validatePresence.bind(undefined, ['aud', 'exp', 'iat', 'iss', 'sub']))
1029
1038
  .then(validateIssuer.bind(undefined, as.issuer))
1030
1039
  .then(validateAudience.bind(undefined, client.client_id));
@@ -1040,7 +1049,7 @@ async function processGenericAccessTokenResponse(as, client, response, ignoreIdT
1040
1049
  (!Number.isFinite(claims.auth_time) || Math.sign(claims.auth_time) !== 1)) {
1041
1050
  throw new OPE('ID Token "auth_time" (authentication time) must be a positive number');
1042
1051
  }
1043
- idTokenClaims.set(json, claims);
1052
+ idTokenClaims.set(json, [claims, jwt]);
1044
1053
  }
1045
1054
  }
1046
1055
  return json;
@@ -1278,8 +1287,7 @@ export async function processIntrospectionResponse(as, client, response) {
1278
1287
  let json;
1279
1288
  if (getContentType(response) === 'application/token-introspection+jwt') {
1280
1289
  assertReadableResponse(response);
1281
- const jwt = await response.text();
1282
- const { claims } = await validateJwt(jwt, checkSigningAlgorithm.bind(undefined, client.introspection_signed_response_alg, as.introspection_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client))
1290
+ const { claims, jwt } = await validateJwt(await response.text(), checkSigningAlgorithm.bind(undefined, client.introspection_signed_response_alg, as.introspection_signing_alg_values_supported), noSignatureCheck, getClockSkew(client), getClockTolerance(client), client[jweDecrypt])
1283
1291
  .then(checkJwtType.bind(undefined, 'token-introspection+jwt'))
1284
1292
  .then(validatePresence.bind(undefined, ['aud', 'iat', 'iss']))
1285
1293
  .then(validateIssuer.bind(undefined, as.issuer))
@@ -1432,10 +1440,16 @@ async function validateJwsSignature(protectedHeader, payload, key, signature) {
1432
1440
  throw new OPE('JWT signature verification failed');
1433
1441
  }
1434
1442
  }
1435
- async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
1436
- const { 0: protectedHeader, 1: payload, 2: encodedSignature, length } = jws.split('.');
1443
+ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance, decryptJwt) {
1444
+ let { 0: protectedHeader, 1: payload, 2: encodedSignature, length } = jws.split('.');
1437
1445
  if (length === 5) {
1438
- throw new UnsupportedOperationError('JWE structure JWTs are not supported');
1446
+ if (decryptJwt !== undefined) {
1447
+ jws = await decryptJwt(jws);
1448
+ ({ 0: protectedHeader, 1: payload, 2: encodedSignature, length } = jws.split('.'));
1449
+ }
1450
+ else {
1451
+ throw new UnsupportedOperationError('JWE structure JWTs are not supported');
1452
+ }
1439
1453
  }
1440
1454
  if (length !== 3) {
1441
1455
  throw new OPE('Invalid JWT');
@@ -1502,7 +1516,7 @@ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
1502
1516
  throw new OPE('unexpected JWT "aud" (audience) claim type');
1503
1517
  }
1504
1518
  }
1505
- return { header, claims, signature, key };
1519
+ return { header, claims, signature, key, jwt: jws };
1506
1520
  }
1507
1521
  export async function validateJwtAuthResponse(as, client, parameters, expectedState, options) {
1508
1522
  assertAs(as);
@@ -1517,7 +1531,7 @@ export async function validateJwtAuthResponse(as, client, parameters, expectedSt
1517
1531
  if (!response) {
1518
1532
  throw new OPE('"parameters" does not contain a JARM response');
1519
1533
  }
1520
- const { claims } = await validateJwt(response, checkSigningAlgorithm.bind(undefined, client.authorization_signed_response_alg, as.authorization_signing_alg_values_supported), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(client), getClockTolerance(client))
1534
+ const { claims } = await validateJwt(response, checkSigningAlgorithm.bind(undefined, client.authorization_signed_response_alg, as.authorization_signing_alg_values_supported), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(client), getClockTolerance(client), client[jweDecrypt])
1521
1535
  .then(validatePresence.bind(undefined, ['aud', 'exp', 'iss']))
1522
1536
  .then(validateIssuer.bind(undefined, as.issuer))
1523
1537
  .then(validateAudience.bind(undefined, client.client_id));
@@ -1613,7 +1627,7 @@ export async function validateDetachedSignatureResponse(as, client, parameters,
1613
1627
  if (typeof expectedState === 'string') {
1614
1628
  requiredClaims.push('s_hash');
1615
1629
  }
1616
- const { claims, header, key } = await validateJwt(id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(client), getClockTolerance(client))
1630
+ const { claims, header, key } = await validateJwt(id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(client), getClockTolerance(client), client[jweDecrypt])
1617
1631
  .then(validatePresence.bind(undefined, requiredClaims))
1618
1632
  .then(validateIssuer.bind(undefined, as.issuer))
1619
1633
  .then(validateAudience.bind(undefined, client.client_id));
@@ -1890,7 +1904,7 @@ async function validateDPoP(as, request, accessToken, accessTokenClaims, options
1890
1904
  throw new OPE('DPoP Proof jwk header parameter must contain a public key');
1891
1905
  }
1892
1906
  return key;
1893
- }, clockSkew, getClockTolerance(options))
1907
+ }, clockSkew, getClockTolerance(options), undefined)
1894
1908
  .then(checkJwtType.bind(undefined, 'dpop+jwt'))
1895
1909
  .then(validatePresence.bind(undefined, ['iat', 'jti', 'ath', 'htm', 'htu']));
1896
1910
  const now = epochTime() + clockSkew;
@@ -1981,7 +1995,7 @@ export async function validateJwtAccessToken(as, request, expectedAudience, opti
1981
1995
  if (options?.requireDPoP || scheme === 'dpop' || request.headers.has('dpop')) {
1982
1996
  requiredClaims.push('cnf');
1983
1997
  }
1984
- const { claims } = await validateJwt(accessToken, checkSigningAlgorithm.bind(undefined, undefined, SUPPORTED_JWS_ALGS), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(options), getClockTolerance(options))
1998
+ const { claims } = await validateJwt(accessToken, checkSigningAlgorithm.bind(undefined, undefined, SUPPORTED_JWS_ALGS), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(options), getClockTolerance(options), undefined)
1985
1999
  .then(checkJwtType.bind(undefined, 'at+jwt'))
1986
2000
  .then(validatePresence.bind(undefined, requiredClaims))
1987
2001
  .then(validateIssuer.bind(undefined, as.issuer))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauth4webapi",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "description": "OAuth 2 / OpenID Connect for JavaScript Runtimes",
5
5
  "keywords": [
6
6
  "access token",