@openid4vc/oauth2 0.7.0-alpha-20261007094201 → 0.7.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/dist/index.d.mts CHANGED
@@ -807,7 +807,7 @@ interface DpopVerificationOptions {
807
807
  *
808
808
  * @default 0
809
809
  */
810
- allowedClockSkewSeconds?: number;
810
+ allowedSkewInSeconds?: number;
811
811
  /**
812
812
  * Callback to enforce one-time usage of the DPoP proof `jti`.
813
813
  *
@@ -3305,10 +3305,22 @@ interface Oauth2AuthorizationServerOptions {
3305
3305
  * Callbacks required for the oauth2 authorization server
3306
3306
  */
3307
3307
  callbacks: Omit<CallbackContext, 'decryptJwe' | 'encryptJwe'>;
3308
+ /**
3309
+ * Default allowed clock skew in seconds for DPoP and client attestation verification.
3310
+ *
3311
+ * Applied to the `nbf` and `exp` checks of client attestation and client attestation PoP JWTs, and to the
3312
+ * `iat` checks of DPoP proofs (which are only performed when `maxProofAgeSeconds` is provided).
3313
+ *
3314
+ * A per-call `allowedSkewInSeconds` in the client attestation or DPoP options takes precedence, including `0`.
3315
+ *
3316
+ * @default 0
3317
+ */
3318
+ allowedSkewInSeconds?: number;
3308
3319
  }
3309
3320
  export declare class Oauth2AuthorizationServer {
3310
3321
  private options;
3311
3322
  constructor(options: Oauth2AuthorizationServerOptions);
3323
+ private withDefaultSkew;
3312
3324
  createAuthorizationServerMetadata(authorizationServerMetadata: AuthorizationServerMetadata): {
3313
3325
  [x: string]: unknown;
3314
3326
  issuer: string;
package/dist/index.mjs CHANGED
@@ -736,7 +736,7 @@ async function verifyDpopJwt(options) {
736
736
  if (options.maxProofAgeSeconds !== void 0) {
737
737
  if (options.maxProofAgeSeconds < 0) throw new Oauth2Error(`maxProofAgeSeconds must be greater than or equal to 0, received '${options.maxProofAgeSeconds}'.`);
738
738
  const nowInSeconds = dateToSeconds(now);
739
- const allowedSkew = options.allowedClockSkewSeconds ?? 0;
739
+ const allowedSkew = options.allowedSkewInSeconds ?? 0;
740
740
  const proofAgeInSeconds = nowInSeconds - payload.iat;
741
741
  if (payload.iat > nowInSeconds + allowedSkew) throw new Oauth2Error(`Dpop jwt contains iat value '${payload.iat}' that is in the future relative to now '${nowInSeconds}' with allowed skew '${allowedSkew}'.`);
742
742
  if (proofAgeInSeconds > options.maxProofAgeSeconds + allowedSkew) throw new Oauth2Error(`Dpop jwt is too old. Proof age is '${proofAgeInSeconds}' seconds, but max allowed age is '${options.maxProofAgeSeconds}' seconds with allowed skew '${allowedSkew}'.`);
@@ -1121,7 +1121,7 @@ async function verifyAuthorizationRequestDpop(options, request, callbacks, now)
1121
1121
  request,
1122
1122
  allowedSigningAlgs: options.allowedSigningAlgs,
1123
1123
  maxProofAgeSeconds: options.maxProofAgeSeconds,
1124
- allowedClockSkewSeconds: options.allowedClockSkewSeconds,
1124
+ allowedSkewInSeconds: options.allowedSkewInSeconds,
1125
1125
  assertJtiUniqueness: options.assertJtiUniqueness,
1126
1126
  now
1127
1127
  }) : void 0;
@@ -2050,7 +2050,7 @@ async function calculateCodeChallenge(options) {
2050
2050
  //#region src/access-token/verify-access-token-request.ts
2051
2051
  async function verifyPreAuthorizedCodeAccessTokenRequest(options) {
2052
2052
  await verifyAccessTokenRequestPkce(options.pkce, options.accessTokenRequest, options.callbacks);
2053
- const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks) : void 0;
2053
+ const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks, options.now) : void 0;
2054
2054
  const clientAttestationResult = options.clientAttestation ? await verifyAccessTokenRequestClientAttestation(options.clientAttestation, options.authorizationServerMetadata, options.callbacks, dpopResult?.jwkThumbprint, options.now) : void 0;
2055
2055
  if (options.grant.preAuthorizedCode !== options.expectedPreAuthorizedCode) throw new Oauth2ServerErrorResponseError({
2056
2056
  error: "invalid_grant",
@@ -2084,7 +2084,7 @@ async function verifyPreAuthorizedCodeAccessTokenRequest(options) {
2084
2084
  }
2085
2085
  async function verifyAuthorizationCodeAccessTokenRequest(options) {
2086
2086
  await verifyAccessTokenRequestPkce(options.pkce, options.accessTokenRequest, options.callbacks);
2087
- const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks) : void 0;
2087
+ const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks, options.now) : void 0;
2088
2088
  const clientAttestationResult = options.clientAttestation ? await verifyAccessTokenRequestClientAttestation(options.clientAttestation, options.authorizationServerMetadata, options.callbacks, dpopResult?.jwkThumbprint, options.now) : void 0;
2089
2089
  if (options.grant.code !== options.expectedCode) throw new Oauth2ServerErrorResponseError({
2090
2090
  error: "invalid_grant",
@@ -2104,7 +2104,7 @@ async function verifyAuthorizationCodeAccessTokenRequest(options) {
2104
2104
  }
2105
2105
  async function verifyRefreshTokenAccessTokenRequest(options) {
2106
2106
  await verifyAccessTokenRequestPkce(options.pkce, options.accessTokenRequest, options.callbacks);
2107
- const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks) : void 0;
2107
+ const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks, options.now) : void 0;
2108
2108
  const clientAttestationResult = options.clientAttestation ? await verifyAccessTokenRequestClientAttestation(options.clientAttestation, options.authorizationServerMetadata, options.callbacks, dpopResult?.jwkThumbprint, options.now) : void 0;
2109
2109
  if (options.grant.refreshToken !== options.expectedRefreshToken) throw new Oauth2ServerErrorResponseError({
2110
2110
  error: "invalid_grant",
@@ -2194,7 +2194,7 @@ async function assertConfirmationKeyMatchesDpopKey(confirmationJwk, dpopJwkThumb
2194
2194
  error_description: "Expected the DPoP JWK thumbprint value to match the JWK thumbprint of the client attestation confirmation JWK. Ensure both DPoP and client attestation use the same key."
2195
2195
  }, { status: 401 });
2196
2196
  }
2197
- async function verifyAccessTokenRequestDpop(options, request, callbacks) {
2197
+ async function verifyAccessTokenRequestDpop(options, request, callbacks, now) {
2198
2198
  if (options.required && !options.jwt) throw new Oauth2ServerErrorResponseError({
2199
2199
  error: "invalid_dpop_proof",
2200
2200
  error_description: "Missing required DPoP proof"
@@ -2208,8 +2208,9 @@ async function verifyAccessTokenRequestDpop(options, request, callbacks) {
2208
2208
  expectedJwkThumbprint: options.expectedJwkThumbprint,
2209
2209
  expectedNonce: options.expectedNonce,
2210
2210
  maxProofAgeSeconds: options.maxProofAgeSeconds,
2211
- allowedClockSkewSeconds: options.allowedClockSkewSeconds,
2212
- assertJtiUniqueness: options.assertJtiUniqueness
2211
+ allowedSkewInSeconds: options.allowedSkewInSeconds,
2212
+ assertJtiUniqueness: options.assertJtiUniqueness,
2213
+ now
2213
2214
  });
2214
2215
  return {
2215
2216
  jwk: header.jwk,
@@ -2377,6 +2378,13 @@ var Oauth2AuthorizationServer = class {
2377
2378
  constructor(options) {
2378
2379
  this.options = options;
2379
2380
  }
2381
+ withDefaultSkew(options) {
2382
+ if (!options) return void 0;
2383
+ return {
2384
+ ...options,
2385
+ allowedSkewInSeconds: options.allowedSkewInSeconds ?? this.options.allowedSkewInSeconds
2386
+ };
2387
+ }
2380
2388
  createAuthorizationServerMetadata(authorizationServerMetadata) {
2381
2389
  return parseWithErrorHandling(zAuthorizationServerMetadata, authorizationServerMetadata, "Error validating authorization server metadata");
2382
2390
  }
@@ -2393,19 +2401,25 @@ var Oauth2AuthorizationServer = class {
2393
2401
  verifyPreAuthorizedCodeAccessTokenRequest(options) {
2394
2402
  return verifyPreAuthorizedCodeAccessTokenRequest({
2395
2403
  ...options,
2396
- callbacks: this.options.callbacks
2404
+ callbacks: this.options.callbacks,
2405
+ clientAttestation: this.withDefaultSkew(options.clientAttestation),
2406
+ dpop: this.withDefaultSkew(options.dpop)
2397
2407
  });
2398
2408
  }
2399
2409
  verifyAuthorizationCodeAccessTokenRequest(options) {
2400
2410
  return verifyAuthorizationCodeAccessTokenRequest({
2401
2411
  ...options,
2402
- callbacks: this.options.callbacks
2412
+ callbacks: this.options.callbacks,
2413
+ clientAttestation: this.withDefaultSkew(options.clientAttestation),
2414
+ dpop: this.withDefaultSkew(options.dpop)
2403
2415
  });
2404
2416
  }
2405
2417
  verifyRefreshTokenAccessTokenRequest(options) {
2406
2418
  return verifyRefreshTokenAccessTokenRequest({
2407
2419
  ...options,
2408
- callbacks: this.options.callbacks
2420
+ callbacks: this.options.callbacks,
2421
+ clientAttestation: this.withDefaultSkew(options.clientAttestation),
2422
+ dpop: this.withDefaultSkew(options.dpop)
2409
2423
  });
2410
2424
  }
2411
2425
  /**
@@ -2460,7 +2474,9 @@ var Oauth2AuthorizationServer = class {
2460
2474
  verifyPushedAuthorizationRequest(options) {
2461
2475
  return verifyPushedAuthorizationRequest({
2462
2476
  ...options,
2463
- callbacks: this.options.callbacks
2477
+ callbacks: this.options.callbacks,
2478
+ clientAttestation: this.withDefaultSkew(options.clientAttestation),
2479
+ dpop: this.withDefaultSkew(options.dpop)
2464
2480
  });
2465
2481
  }
2466
2482
  createPushedAuthorizationResponse(options) {
@@ -2478,7 +2494,9 @@ var Oauth2AuthorizationServer = class {
2478
2494
  verifyAuthorizationChallengeRequest(options) {
2479
2495
  return verifyAuthorizationChallengeRequest({
2480
2496
  ...options,
2481
- callbacks: this.options.callbacks
2497
+ callbacks: this.options.callbacks,
2498
+ clientAttestation: this.withDefaultSkew(options.clientAttestation),
2499
+ dpop: this.withDefaultSkew(options.dpop)
2482
2500
  });
2483
2501
  }
2484
2502
  createAuthorizationChallengeResponse(options) {
@@ -2506,13 +2524,15 @@ var Oauth2AuthorizationServer = class {
2506
2524
  async verifyDpopJwt(options) {
2507
2525
  return verifyDpopJwt({
2508
2526
  ...options,
2509
- callbacks: this.options.callbacks
2527
+ callbacks: this.options.callbacks,
2528
+ allowedSkewInSeconds: options.allowedSkewInSeconds ?? this.options.allowedSkewInSeconds
2510
2529
  });
2511
2530
  }
2512
2531
  async verifyClientAttestation(options) {
2513
2532
  return verifyClientAttestation({
2514
2533
  ...options,
2515
- callbacks: this.options.callbacks
2534
+ callbacks: this.options.callbacks,
2535
+ allowedSkewInSeconds: options.allowedSkewInSeconds ?? this.options.allowedSkewInSeconds
2516
2536
  });
2517
2537
  }
2518
2538
  };
@@ -3174,7 +3194,7 @@ async function verifyResourceRequest(options) {
3174
3194
  expectedJwkThumbprint: tokenPayload.cnf?.jkt,
3175
3195
  allowedSigningAlgs: authorizationServer.dpop_signing_alg_values_supported,
3176
3196
  maxProofAgeSeconds: options.dpop?.maxProofAgeSeconds,
3177
- allowedClockSkewSeconds: options.dpop?.allowedClockSkewSeconds,
3197
+ allowedSkewInSeconds: options.dpop?.allowedSkewInSeconds,
3178
3198
  assertJtiUniqueness: options.dpop?.assertJtiUniqueness
3179
3199
  })).header.jwk;
3180
3200
  } catch (error) {