@openid4vc/oauth2 0.3.0-alpha-20251107130106 → 0.3.0-alpha-20251107132439

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.cjs CHANGED
@@ -530,6 +530,149 @@ var Oauth2ServerErrorResponseError = class extends Oauth2Error {
530
530
  }
531
531
  };
532
532
 
533
+ //#endregion
534
+ //#region src/common/jwt/z-jwe.ts
535
+ const zCompactJwe = zod.z.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/, { message: "Not a valid compact jwe" });
536
+
537
+ //#endregion
538
+ //#region src/jar/z-jar-authorization-request.ts
539
+ const zJarAuthorizationRequest = zod.z.object({
540
+ request: zod.z.optional(zod.z.string()),
541
+ request_uri: zod.z.optional(__openid4vc_utils.zHttpsUrl),
542
+ client_id: zod.z.optional(zod.z.string())
543
+ }).loose();
544
+ function validateJarRequestParams(options) {
545
+ const { jarRequestParams } = options;
546
+ if (jarRequestParams.request && jarRequestParams.request_uri) throw new Oauth2ServerErrorResponseError({
547
+ error: Oauth2ErrorCodes.InvalidRequestObject,
548
+ error_description: "request and request_uri cannot both be present in a JAR request"
549
+ });
550
+ if (!jarRequestParams.request && !jarRequestParams.request_uri) throw new Oauth2ServerErrorResponseError({
551
+ error: Oauth2ErrorCodes.InvalidRequestObject,
552
+ error_description: "request or request_uri must be present"
553
+ });
554
+ return jarRequestParams;
555
+ }
556
+ function isJarAuthorizationRequest(request) {
557
+ return "request" in request || "request_uri" in request;
558
+ }
559
+
560
+ //#endregion
561
+ //#region src/jar/z-jar-request-object.ts
562
+ const zJarRequestObjectPayload = zod.z.object({
563
+ ...zJwtPayload.shape,
564
+ client_id: zod.z.string()
565
+ }).loose();
566
+ const zSignedAuthorizationRequestJwtHeaderTyp = zod.z.literal("oauth-authz-req+jwt");
567
+ const signedAuthorizationRequestJwtHeaderTyp = zSignedAuthorizationRequestJwtHeaderTyp.value;
568
+ const zJwtAuthorizationRequestJwtHeaderTyp = zod.z.literal("jwt");
569
+ const jwtAuthorizationRequestJwtHeaderTyp = zJwtAuthorizationRequestJwtHeaderTyp.value;
570
+
571
+ //#endregion
572
+ //#region src/jar/handle-jar-request/verify-jar-request.ts
573
+ /**
574
+ * Parse a JAR (JWT Secured Authorization Request) request by validating and optionally fetch from uri.
575
+ *
576
+ * @param options - The input parameters
577
+ * @param options.jarRequestParams - The JAR authorization request parameters
578
+ * @param options.callbacks - Context containing the relevant Jose crypto operations
579
+ * @returns An object containing the transmission method ('value' or 'reference') and the JWT request object.
580
+ */
581
+ async function parseJarRequest(options) {
582
+ const { callbacks } = options;
583
+ const jarRequestParams = {
584
+ ...validateJarRequestParams(options),
585
+ ...options.jarRequestParams
586
+ };
587
+ return {
588
+ sendBy: jarRequestParams.request ? "value" : "reference",
589
+ authorizationRequestJwt: jarRequestParams.request ?? await fetchJarRequestObject({
590
+ requestUri: jarRequestParams.request_uri,
591
+ fetch: callbacks.fetch
592
+ })
593
+ };
594
+ }
595
+ /**
596
+ * Verifies a JAR (JWT Secured Authorization Request) request by validating and verifying signatures.
597
+ *
598
+ * @param options - The input parameters
599
+ * @param options.jarRequestParams - The JAR authorization request parameters
600
+ * @param options.callbacks - Context containing the relevant Jose crypto operations
601
+ * @returns The verified authorization request parameters and metadata
602
+ */
603
+ async function verifyJarRequest(options) {
604
+ const { jarRequestParams, authorizationRequestJwt, callbacks, jwtSigner } = options;
605
+ if (zCompactJwe.safeParse(authorizationRequestJwt).success) throw new Oauth2ServerErrorResponseError({
606
+ error: Oauth2ErrorCodes.InvalidRequestObject,
607
+ error_description: "Encrypted JWE request objects are not supported."
608
+ });
609
+ if (!zCompactJwt.safeParse(authorizationRequestJwt).success) throw new Oauth2ServerErrorResponseError({
610
+ error: Oauth2ErrorCodes.InvalidRequestObject,
611
+ error_description: "JAR request object is not a valid JWT."
612
+ });
613
+ const { authorizationRequestPayload, signer, jwt } = await verifyJarRequestObject({
614
+ authorizationRequestJwt,
615
+ callbacks,
616
+ jwtSigner
617
+ });
618
+ if (!authorizationRequestPayload.client_id) throw new Oauth2ServerErrorResponseError({
619
+ error: Oauth2ErrorCodes.InvalidRequestObject,
620
+ error_description: "Jar Request Object is missing the required \"client_id\" field."
621
+ });
622
+ if (jarRequestParams.client_id !== authorizationRequestPayload.client_id) throw new Oauth2ServerErrorResponseError({
623
+ error: Oauth2ErrorCodes.InvalidRequest,
624
+ error_description: "client_id does not match the request object client_id."
625
+ });
626
+ return {
627
+ jwt,
628
+ authorizationRequestPayload,
629
+ signer
630
+ };
631
+ }
632
+ async function fetchJarRequestObject(options) {
633
+ const { requestUri, fetch } = options;
634
+ const response = await (0, __openid4vc_utils.createFetcher)(fetch)(requestUri, {
635
+ method: "get",
636
+ headers: {
637
+ Accept: `${__openid4vc_utils.ContentType.OAuthAuthorizationRequestJwt}, ${__openid4vc_utils.ContentType.Jwt};q=0.9, text/plain`,
638
+ "Content-Type": __openid4vc_utils.ContentType.XWwwFormUrlencoded
639
+ }
640
+ }).catch(() => {
641
+ throw new Oauth2ServerErrorResponseError({
642
+ error_description: `Fetching request_object from request_uri '${requestUri}' failed`,
643
+ error: Oauth2ErrorCodes.InvalidRequestUri
644
+ });
645
+ });
646
+ if (!response.ok) throw new Oauth2ServerErrorResponseError({
647
+ error_description: `Fetching request_object from request_uri '${requestUri}' failed with status code '${response.status}'.`,
648
+ error: Oauth2ErrorCodes.InvalidRequestUri
649
+ });
650
+ return await response.text();
651
+ }
652
+ async function verifyJarRequestObject(options) {
653
+ const { authorizationRequestJwt, callbacks, jwtSigner } = options;
654
+ const jwt = decodeJwt({
655
+ jwt: authorizationRequestJwt,
656
+ payloadSchema: zJarRequestObjectPayload
657
+ });
658
+ const { signer } = await verifyJwt({
659
+ verifyJwtCallback: callbacks.verifyJwt,
660
+ compact: authorizationRequestJwt,
661
+ header: jwt.header,
662
+ payload: jwt.payload,
663
+ signer: jwtSigner
664
+ });
665
+ if (jwt.header.typ !== signedAuthorizationRequestJwtHeaderTyp && jwt.header.typ !== jwtAuthorizationRequestJwtHeaderTyp) throw new Oauth2ServerErrorResponseError({
666
+ error: Oauth2ErrorCodes.InvalidRequestObject,
667
+ error_description: `Invalid Jar Request Object typ header. Expected "oauth-authz-req+jwt" or "jwt", received "${jwt.header.typ}".`
668
+ });
669
+ return {
670
+ signer,
671
+ jwt,
672
+ authorizationRequestPayload: jwt.payload
673
+ };
674
+ }
675
+
533
676
  //#endregion
534
677
  //#region src/client-attestation/z-client-attestation.ts
535
678
  const zOauthClientAttestationHeader = zod.default.literal("OAuth-Client-Attestation");
@@ -897,12 +1040,29 @@ const zPushedAuthorizationResponse = zod.default.object({
897
1040
  *
898
1041
  * @throws {Oauth2ServerErrorResponseError}
899
1042
  */
900
- function parsePushedAuthorizationRequest(options) {
901
- const parsedAuthorizationRequest = zAuthorizationRequest.safeParse(options.authorizationRequest);
902
- if (!parsedAuthorizationRequest.success) throw new Oauth2ServerErrorResponseError({
903
- error: Oauth2ErrorCodes.InvalidRequest,
904
- error_description: `Error occurred during validation of pushed authorization request.\n${(0, __openid4vc_utils.formatZodError)(parsedAuthorizationRequest.error)}`
905
- });
1043
+ async function parsePushedAuthorizationRequest(options) {
1044
+ const parsed = (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([zAuthorizationRequest, zJarAuthorizationRequest]), options.authorizationRequest, "Invalid authorization request. Could not parse authorization request or jar.");
1045
+ let parsedAuthorizationRequest;
1046
+ let authorizationRequestJwt;
1047
+ if (isJarAuthorizationRequest(parsed)) {
1048
+ const parsedJar = await parseJarRequest({
1049
+ jarRequestParams: parsed,
1050
+ callbacks: options.callbacks
1051
+ });
1052
+ const jwt = decodeJwt({ jwt: parsedJar.authorizationRequestJwt });
1053
+ parsedAuthorizationRequest = zAuthorizationRequest.safeParse(jwt.payload);
1054
+ if (!parsedAuthorizationRequest.success) throw new Oauth2ServerErrorResponseError({
1055
+ error: Oauth2ErrorCodes.InvalidRequest,
1056
+ error_description: `Invalid authorization request. Could not parse jar request payload.\n${(0, __openid4vc_utils.formatZodError)(parsedAuthorizationRequest.error)}`
1057
+ });
1058
+ authorizationRequestJwt = parsedJar.authorizationRequestJwt;
1059
+ } else {
1060
+ parsedAuthorizationRequest = zAuthorizationRequest.safeParse(options.authorizationRequest);
1061
+ if (!parsedAuthorizationRequest.success) throw new Oauth2ServerErrorResponseError({
1062
+ error: Oauth2ErrorCodes.InvalidRequest,
1063
+ error_description: `Error occurred during validation of pushed authorization request.\n${(0, __openid4vc_utils.formatZodError)(parsedAuthorizationRequest.error)}`
1064
+ });
1065
+ }
906
1066
  const authorizationRequest = parsedAuthorizationRequest.data;
907
1067
  const { clientAttestation, dpop } = parseAuthorizationRequest({
908
1068
  authorizationRequest,
@@ -910,6 +1070,7 @@ function parsePushedAuthorizationRequest(options) {
910
1070
  });
911
1071
  return {
912
1072
  authorizationRequest,
1073
+ authorizationRequestJwt,
913
1074
  dpop,
914
1075
  clientAttestation
915
1076
  };
@@ -1060,10 +1221,6 @@ function clientAuthenticationClientAttestationJwt(options) {
1060
1221
  };
1061
1222
  }
1062
1223
 
1063
- //#endregion
1064
- //#region src/common/jwt/z-jwe.ts
1065
- const zCompactJwe = zod.z.string().regex(/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/, { message: "Not a valid compact jwe" });
1066
-
1067
1224
  //#endregion
1068
1225
  //#region src/error/Oauth2ClientErrorResponseError.ts
1069
1226
  var Oauth2ClientErrorResponseError = class extends Oauth2Error {
@@ -1197,6 +1354,57 @@ async function verifyIdTokenJwt(options) {
1197
1354
  };
1198
1355
  }
1199
1356
 
1357
+ //#endregion
1358
+ //#region src/jar/create-jar-authorization-request.ts
1359
+ /**
1360
+ * Creates a JAR (JWT Authorization Request) request object.
1361
+ *
1362
+ * @param options - The input parameters
1363
+ * @param options.authorizationRequestPayload - The authorization request parameters
1364
+ * @param options.jwtSigner - The JWT signer
1365
+ * @param options.jweEncryptor - The JWE encryptor (optional) if provided, the request object will be encrypted
1366
+ * @param options.requestUri - The request URI (optional) if provided, the request object needs to be fetched from the URI
1367
+ * @param options.callbacks - The callback context
1368
+ * @returns the requestParams, signerJwk, encryptionJwk, and requestObjectJwt
1369
+ */
1370
+ async function createJarAuthorizationRequest(options) {
1371
+ const { jwtSigner, jweEncryptor, authorizationRequestPayload, requestUri, callbacks } = options;
1372
+ let authorizationRequestJwt;
1373
+ let encryptionJwk;
1374
+ const now = options.now ?? /* @__PURE__ */ new Date();
1375
+ const { jwt, signerJwk } = await callbacks.signJwt(jwtSigner, {
1376
+ header: {
1377
+ ...jwtHeaderFromJwtSigner(jwtSigner),
1378
+ typ: "oauth-authz-req+jwt"
1379
+ },
1380
+ payload: {
1381
+ iat: (0, __openid4vc_utils.dateToSeconds)(now),
1382
+ exp: (0, __openid4vc_utils.dateToSeconds)((0, __openid4vc_utils.addSecondsToDate)(now, options.expiresInSeconds)),
1383
+ ...options.additionalJwtPayload,
1384
+ ...authorizationRequestPayload
1385
+ }
1386
+ });
1387
+ authorizationRequestJwt = jwt;
1388
+ if (jweEncryptor) {
1389
+ const encryptionResult = await callbacks.encryptJwe(jweEncryptor, authorizationRequestJwt);
1390
+ authorizationRequestJwt = encryptionResult.jwe;
1391
+ encryptionJwk = encryptionResult.encryptionJwk;
1392
+ }
1393
+ const client_id = authorizationRequestPayload.client_id;
1394
+ return {
1395
+ jarAuthorizationRequest: requestUri ? {
1396
+ client_id,
1397
+ request_uri: requestUri
1398
+ } : {
1399
+ client_id,
1400
+ request: authorizationRequestJwt
1401
+ },
1402
+ signerJwk,
1403
+ encryptionJwk,
1404
+ authorizationRequestJwt
1405
+ };
1406
+ }
1407
+
1200
1408
  //#endregion
1201
1409
  //#region src/metadata/fetch-well-known-metadata.ts
1202
1410
  /**
@@ -1800,10 +2008,18 @@ function createPushedAuthorizationErrorResponse(options) {
1800
2008
  //#endregion
1801
2009
  //#region src/authorization-request/verify-pushed-authorization-request.ts
1802
2010
  async function verifyPushedAuthorizationRequest(options) {
2011
+ let jar;
2012
+ if (options.authorizationRequestJwt) jar = await verifyJarRequest({
2013
+ authorizationRequestJwt: options.authorizationRequestJwt.jwt,
2014
+ jarRequestParams: options.authorizationRequest,
2015
+ callbacks: options.callbacks,
2016
+ jwtSigner: options.authorizationRequestJwt.signer
2017
+ });
1803
2018
  const { clientAttestation, dpop } = await verifyAuthorizationRequest(options);
1804
2019
  return {
1805
2020
  dpop,
1806
- clientAttestation
2021
+ clientAttestation,
2022
+ jar
1807
2023
  };
1808
2024
  }
1809
2025
 
@@ -1882,9 +2098,14 @@ var Oauth2AuthorizationServer = class {
1882
2098
  /**
1883
2099
  * Parse a pushed authorization request
1884
2100
  */
1885
- parsePushedAuthorizationRequest(options) {
1886
- return parsePushedAuthorizationRequest(options);
2101
+ async parsePushedAuthorizationRequest(options) {
2102
+ return await parsePushedAuthorizationRequest(options);
1887
2103
  }
2104
+ /**
2105
+ * Verify pushed authorization request.
2106
+ *
2107
+ * Make sure to provide the `authorizationRequestJwt` if this was returned in the `parsePushedAuthorizationRequest`
2108
+ */
1888
2109
  verifyPushedAuthorizationRequest(options) {
1889
2110
  return verifyPushedAuthorizationRequest({
1890
2111
  ...options,
@@ -2644,6 +2865,7 @@ exports.clientAuthenticationClientSecretPost = clientAuthenticationClientSecretP
2644
2865
  exports.clientAuthenticationDynamic = clientAuthenticationDynamic;
2645
2866
  exports.clientAuthenticationNone = clientAuthenticationNone;
2646
2867
  exports.createClientAttestationJwt = createClientAttestationJwt;
2868
+ exports.createJarAuthorizationRequest = createJarAuthorizationRequest;
2647
2869
  exports.decodeJwt = decodeJwt;
2648
2870
  exports.decodeJwtHeader = decodeJwtHeader;
2649
2871
  exports.fetchAuthorizationServerMetadata = fetchAuthorizationServerMetadata;
@@ -2657,6 +2879,7 @@ Object.defineProperty(exports, 'getGlobalConfig', {
2657
2879
  }
2658
2880
  });
2659
2881
  exports.isJwkInSet = isJwkInSet;
2882
+ exports.jwtAuthorizationRequestJwtHeaderTyp = jwtAuthorizationRequestJwtHeaderTyp;
2660
2883
  exports.jwtHeaderFromJwtSigner = jwtHeaderFromJwtSigner;
2661
2884
  exports.jwtSignerFromJwt = jwtSignerFromJwt;
2662
2885
  exports.parseAuthorizationResponseRedirectUrl = parseAuthorizationResponseRedirectUrl;
@@ -2671,6 +2894,8 @@ Object.defineProperty(exports, 'setGlobalConfig', {
2671
2894
  return __openid4vc_utils.setGlobalConfig;
2672
2895
  }
2673
2896
  });
2897
+ exports.signedAuthorizationRequestJwtHeaderTyp = signedAuthorizationRequestJwtHeaderTyp;
2898
+ exports.validateJarRequestParams = validateJarRequestParams;
2674
2899
  exports.verifyClientAttestationJwt = verifyClientAttestationJwt;
2675
2900
  exports.verifyIdTokenJwt = verifyIdTokenJwt;
2676
2901
  exports.verifyJwt = verifyJwt;
@@ -2685,6 +2910,8 @@ exports.zCompactJwe = zCompactJwe;
2685
2910
  exports.zCompactJwt = zCompactJwt;
2686
2911
  exports.zIdTokenJwtHeader = zIdTokenJwtHeader;
2687
2912
  exports.zIdTokenJwtPayload = zIdTokenJwtPayload;
2913
+ exports.zJarAuthorizationRequest = zJarAuthorizationRequest;
2914
+ exports.zJarRequestObjectPayload = zJarRequestObjectPayload;
2688
2915
  exports.zJwk = zJwk;
2689
2916
  exports.zJwkSet = zJwkSet;
2690
2917
  exports.zJwtHeader = zJwtHeader;