@openid4vc/openid4vp 0.3.0-alpha-20250315153126 → 0.3.0-alpha-20250318163628

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.js CHANGED
@@ -34,11 +34,12 @@ __export(src_exports, {
34
34
  Openid4vpVerifier: () => Openid4vpVerifier,
35
35
  createOpenid4vpAuthorizationRequest: () => createOpenid4vpAuthorizationRequest,
36
36
  createOpenid4vpAuthorizationResponse: () => createOpenid4vpAuthorizationResponse,
37
+ getOpenid4vpClientId: () => getOpenid4vpClientId,
37
38
  isJarmResponseMode: () => isJarmResponseMode,
38
39
  isOpenid4vpAuthorizationRequestDcApi: () => isOpenid4vpAuthorizationRequestDcApi,
39
40
  parseDcqlVpToken: () => parseDcqlVpToken,
40
41
  parseJarmAuthorizationResponse: () => parseJarmAuthorizationResponse,
41
- parseOpenid4vpAuthorizationRequestPayload: () => parseOpenid4vpAuthorizationRequestPayload,
42
+ parseOpenid4vpAuthorizationRequest: () => parseOpenid4vpAuthorizationRequest,
42
43
  parseOpenid4vpAuthorizationResponse: () => parseOpenid4vpAuthorizationResponse,
43
44
  parsePexVpToken: () => parsePexVpToken,
44
45
  parseTransactionData: () => parseTransactionData,
@@ -57,54 +58,53 @@ __export(src_exports, {
57
58
  });
58
59
  module.exports = __toCommonJS(src_exports);
59
60
 
60
- // src/client-identifier-scheme/z-client-id-scheme.ts
61
- var import_zod = require("zod");
62
- var zClientIdScheme = import_zod.z.enum([
63
- "pre-registered",
64
- "redirect_uri",
65
- "https",
66
- "verifier_attestation",
67
- "did",
68
- "x509_san_dns",
69
- "x509_san_uri",
70
- "web-origin"
71
- ]);
72
-
73
- // src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts
61
+ // src/client-identifier-scheme/parse-client-identifier-scheme.ts
74
62
  var import_oauth24 = require("@openid4vc/oauth2");
75
- var import_zod4 = __toESM(require("zod"));
63
+ var import_utils4 = require("@openid4vc/utils");
64
+
65
+ // src/authorization-request/z-authorization-request-dc-api.ts
66
+ var import_zod5 = require("zod");
67
+
68
+ // src/authorization-request/z-authorization-request.ts
69
+ var import_utils3 = require("@openid4vc/utils");
70
+ var import_zod4 = require("zod");
71
+
72
+ // src/models/z-client-metadata.ts
73
+ var import_oauth22 = require("@openid4vc/oauth2");
74
+ var import_utils2 = require("@openid4vc/utils");
75
+ var import_zod3 = require("zod");
76
76
 
77
77
  // src/jarm/metadata/z-jarm-client-metadata.ts
78
78
  var import_oauth2 = require("@openid4vc/oauth2");
79
79
  var import_utils = require("@openid4vc/utils");
80
- var import_zod2 = require("zod");
81
- var zJarmSignOnlyClientMetadata = import_zod2.z.object({
80
+ var import_zod = require("zod");
81
+ var zJarmSignOnlyClientMetadata = import_zod.z.object({
82
82
  authorization_signed_response_alg: import_oauth2.zAlgValueNotNone,
83
- authorization_encrypted_response_alg: import_zod2.z.optional(import_zod2.z.never()),
84
- authorization_encrypted_response_enc: import_zod2.z.optional(import_zod2.z.never())
83
+ authorization_encrypted_response_alg: import_zod.z.optional(import_zod.z.never()),
84
+ authorization_encrypted_response_enc: import_zod.z.optional(import_zod.z.never())
85
85
  });
86
- var zJarmEncryptOnlyClientMetadata = import_zod2.z.object({
87
- authorization_signed_response_alg: import_zod2.z.optional(import_zod2.z.never()),
88
- authorization_encrypted_response_alg: import_zod2.z.string(),
89
- authorization_encrypted_response_enc: import_zod2.z.optional(import_zod2.z.string())
86
+ var zJarmEncryptOnlyClientMetadata = import_zod.z.object({
87
+ authorization_signed_response_alg: import_zod.z.optional(import_zod.z.never()),
88
+ authorization_encrypted_response_alg: import_zod.z.string(),
89
+ authorization_encrypted_response_enc: import_zod.z.optional(import_zod.z.string())
90
90
  });
91
- var zJarmSignEncryptClientMetadata = import_zod2.z.object({
91
+ var zJarmSignEncryptClientMetadata = import_zod.z.object({
92
92
  authorization_signed_response_alg: zJarmSignOnlyClientMetadata.shape.authorization_signed_response_alg,
93
93
  authorization_encrypted_response_alg: zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_alg,
94
94
  authorization_encrypted_response_enc: zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_enc
95
95
  });
96
- var zJarmClientMetadata = import_zod2.z.object({
97
- authorization_signed_response_alg: import_zod2.z.optional(zJarmSignOnlyClientMetadata.shape.authorization_signed_response_alg),
98
- authorization_encrypted_response_alg: import_zod2.z.optional(
96
+ var zJarmClientMetadata = import_zod.z.object({
97
+ authorization_signed_response_alg: import_zod.z.optional(zJarmSignOnlyClientMetadata.shape.authorization_signed_response_alg),
98
+ authorization_encrypted_response_alg: import_zod.z.optional(
99
99
  zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_alg
100
100
  ),
101
- authorization_encrypted_response_enc: import_zod2.z.optional(
101
+ authorization_encrypted_response_enc: import_zod.z.optional(
102
102
  zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_enc
103
103
  )
104
104
  });
105
105
  var zJarmClientMetadataParsed = zJarmClientMetadata.transform((client_metadata) => {
106
106
  const parsedClientMeta = (0, import_utils.parseWithErrorHandling)(
107
- import_zod2.z.union([zJarmEncryptOnlyClientMetadata, zJarmSignOnlyClientMetadata, zJarmSignEncryptClientMetadata]),
107
+ import_zod.z.union([zJarmEncryptOnlyClientMetadata, zJarmSignOnlyClientMetadata, zJarmSignEncryptClientMetadata]),
108
108
  client_metadata,
109
109
  "Invalid jarm client metadata."
110
110
  );
@@ -141,280 +141,56 @@ var zJarmClientMetadataParsed = zJarmClientMetadata.transform((client_metadata)
141
141
  throw new import_oauth2.Oauth2Error("Invalid jarm client metadata. Failed to parse.");
142
142
  });
143
143
 
144
- // src/jarm/jarm-extract-jwks.ts
145
- function extractJwksFromClientMetadata(clientMetadata) {
146
- const parsed = zJarmClientMetadataParsed.parse(clientMetadata);
147
- const encryptionAlg = parsed.client_metadata.authorization_encrypted_response_enc;
148
- const signingAlg = parsed.client_metadata.authorization_signed_response_alg;
149
- const encJwk = clientMetadata.jwks.keys.find((key) => key.use === "enc" && key.alg === encryptionAlg) ?? clientMetadata.jwks.keys.find((key) => key.use === "enc") ?? // fallback, take first key. HAIP does not specify requirement on enc
150
- clientMetadata.jwks.keys?.[0];
151
- const sigJwk = clientMetadata.jwks.keys.find((key) => key.use === "sig" && key.alg === signingAlg) ?? clientMetadata.jwks.keys.find((key) => key.use === "sig") ?? // falback, take first key
152
- clientMetadata.jwks.keys?.[0];
153
- return { encJwk, sigJwk };
154
- }
155
-
156
- // src/jarm/jarm-authorization-response/jarm-validate-authorization-response.ts
157
- var import_oauth23 = require("@openid4vc/oauth2");
158
- var import_utils2 = require("@openid4vc/utils");
159
-
160
- // src/jarm/jarm-authorization-response/z-jarm-authorization-response.ts
161
- var import_oauth22 = require("@openid4vc/oauth2");
162
- var import_zod3 = require("zod");
163
- var zJarmHeader = import_zod3.z.object({ ...import_oauth22.zJwtHeader.shape, apu: import_zod3.z.string().optional(), apv: import_zod3.z.string().optional() });
164
- var zJarmAuthorizationResponse = import_zod3.z.object({
165
- /**
166
- * iss: The issuer URL of the authorization server that created the response
167
- * aud: The client_id of the client the response is intended for
168
- * exp: The expiration time of the JWT. A maximum JWT lifetime of 10 minutes is RECOMMENDED.
169
- */
170
- ...import_oauth22.zJwtPayload.shape,
171
- ...import_oauth22.zJwtPayload.pick({ iss: true, aud: true, exp: true }).required().shape,
172
- state: import_zod3.z.optional(import_zod3.z.string())
173
- }).passthrough();
174
- var zJarmAuthorizationResponseEncryptedOnly = import_zod3.z.object({
175
- ...import_oauth22.zJwtPayload.shape,
176
- state: import_zod3.z.optional(import_zod3.z.string())
177
- }).passthrough();
178
-
179
- // src/jarm/jarm-authorization-response/jarm-validate-authorization-response.ts
180
- var jarmAuthorizationResponseValidate = (options) => {
181
- const { expectedClientId, authorizationResponse } = options;
182
- if (!zJarmAuthorizationResponse.safeParse(authorizationResponse).success) {
183
- return;
184
- }
185
- if (expectedClientId !== authorizationResponse.aud) {
186
- throw new import_oauth23.Oauth2Error(
187
- `Invalid 'aud' claim in JARM authorization response. Expected '${expectedClientId}' received '${JSON.stringify(authorizationResponse.aud)}'.`
188
- );
189
- }
190
- if (authorizationResponse.exp !== void 0 && authorizationResponse.exp < (0, import_utils2.dateToSeconds)()) {
191
- throw new import_oauth23.Oauth2Error("Jarm auth response is expired.");
192
- }
193
- };
194
-
195
- // src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts
196
- var decryptJarmAuthorizationResponseJwt = async (options) => {
197
- const { jarmAuthorizationResponseJwt, callbacks, authorizationRequestPayload } = options;
198
- const encryptionJwk = authorizationRequestPayload.client_metadata?.jwks ? extractJwksFromClientMetadata({
199
- ...authorizationRequestPayload.client_metadata,
200
- jwks: authorizationRequestPayload.client_metadata.jwks
201
- }).encJwk : void 0;
202
- const result = await callbacks.decryptJwe(jarmAuthorizationResponseJwt, { jwk: encryptionJwk });
203
- if (!result.decrypted) {
204
- throw new import_oauth24.Oauth2Error("Failed to decrypt jarm auth response.");
205
- }
206
- return result.payload;
207
- };
208
- async function verifyJarmAuthorizationResponse(options) {
209
- const { jarmAuthorizationResponseJwt, callbacks, expectedClientId, authorizationRequestPayload } = options;
210
- const requestDataIsEncrypted = import_oauth24.zCompactJwe.safeParse(jarmAuthorizationResponseJwt).success;
211
- const decryptedRequestData = requestDataIsEncrypted ? await decryptJarmAuthorizationResponseJwt({
212
- jarmAuthorizationResponseJwt,
213
- callbacks,
214
- authorizationRequestPayload
215
- }) : jarmAuthorizationResponseJwt;
216
- const responseIsSigned = import_oauth24.zCompactJwt.safeParse(decryptedRequestData).success;
217
- if (!requestDataIsEncrypted && !responseIsSigned) {
218
- throw new import_oauth24.Oauth2Error("Jarm Auth Response must be either encrypted, signed, or signed and encrypted.");
219
- }
220
- let jarmAuthorizationResponse;
221
- if (responseIsSigned) {
222
- const { header: jwsProtectedHeader, payload: jwsPayload } = (0, import_oauth24.decodeJwt)({
223
- jwt: decryptedRequestData,
224
- headerSchema: import_zod4.default.object({ ...import_oauth24.zJwtHeader.shape, kid: import_zod4.default.string() })
225
- });
226
- const response = zJarmAuthorizationResponse.parse(jwsPayload);
227
- const jwtSigner = (0, import_oauth24.jwtSignerFromJwt)({ header: jwsProtectedHeader, payload: jwsPayload });
228
- const verificationResult = await options.callbacks.verifyJwt(jwtSigner, {
229
- compact: decryptedRequestData,
230
- header: jwsProtectedHeader,
231
- payload: jwsPayload
232
- });
233
- if (!verificationResult.verified) {
234
- throw new import_oauth24.Oauth2Error("Jarm Auth Response is not valid.");
235
- }
236
- jarmAuthorizationResponse = response;
237
- } else {
238
- const jsonRequestData = JSON.parse(decryptedRequestData);
239
- jarmAuthorizationResponse = zJarmAuthorizationResponseEncryptedOnly.parse(jsonRequestData);
240
- }
241
- jarmAuthorizationResponseValidate({
242
- expectedClientId,
243
- authorizationResponse: jarmAuthorizationResponse
244
- });
245
- const type = requestDataIsEncrypted && responseIsSigned ? "SignedEncrypted" /* SignedEncrypted */ : requestDataIsEncrypted ? "Encrypted" /* Encrypted */ : "Signed" /* Signed */;
246
- const issuer = jarmAuthorizationResponse.iss;
247
- return { jarmAuthorizationResponse, type, issuer };
248
- }
249
-
250
- // src/authorization-request/create-authorization-request.ts
251
- var import_oauth29 = require("@openid4vc/oauth2");
252
- var import_utils6 = require("@openid4vc/utils");
253
-
254
- // src/jar/create-jar-authorization-request.ts
255
- var import_oauth25 = require("@openid4vc/oauth2");
256
- async function createJarAuthorizationRequest(options) {
257
- const { jwtSigner, jweEncryptor, authorizationRequestPayload, requestUri, callbacks } = options;
258
- let authorizationRequestJwt;
259
- let encryptionJwk;
260
- const { jwt, signerJwk } = await callbacks.signJwt(jwtSigner, {
261
- header: { ...(0, import_oauth25.jwtHeaderFromJwtSigner)(jwtSigner), typ: "oauth-authz-req+jwt" },
262
- payload: { ...options.additionalJwtPayload, ...authorizationRequestPayload }
263
- });
264
- authorizationRequestJwt = jwt;
265
- if (jweEncryptor) {
266
- const encryptionResult = await callbacks.encryptJwe(jweEncryptor, authorizationRequestJwt);
267
- authorizationRequestJwt = encryptionResult.jwe;
268
- encryptionJwk = encryptionResult.encryptionJwk;
269
- }
270
- const client_id = authorizationRequestPayload.client_id;
271
- const jarAuthorizationRequest = requestUri ? { client_id, request_uri: requestUri } : { client_id, request: authorizationRequestJwt };
272
- return { jarAuthorizationRequest, signerJwk, encryptionJwk, authorizationRequestJwt };
273
- }
274
-
275
- // src/authorization-request/validate-authorization-request.ts
276
- var import_oauth26 = require("@openid4vc/oauth2");
277
- var import_utils3 = require("@openid4vc/utils");
278
- var validateOpenid4vpAuthorizationRequestPayload = (options) => {
279
- const { params, walletVerificationOptions } = options;
280
- if (!params.redirect_uri && !params.response_uri) {
281
- throw new import_oauth26.Oauth2ServerErrorResponseError({
282
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
283
- error_description: `Missing required 'redirect_uri' or 'response_uri' in openid4vp authorization request.`
284
- });
285
- }
286
- if (params.response_uri && !["direct_post", "direct_post.jwt"].find((mode) => mode === params.response_mode)) {
287
- throw new import_oauth26.Oauth2ServerErrorResponseError({
288
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
289
- error_description: `The 'response_mode' parameter MUST be 'direct_post' or 'direct_post.jwt' when 'response_uri' is provided. Current: ${params.response_mode}`
290
- });
291
- }
292
- if ([params.presentation_definition_uri, params.presentation_definition, params.dcql_query, params.scope].filter(
293
- Boolean
294
- ).length > 1) {
295
- throw new import_oauth26.Oauth2ServerErrorResponseError({
296
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
297
- error_description: "Exactly one of the following parameters MUST be present in the authorization request: dcql_query, presentation_definition, presentation_definition_uri, or a scope value representing a Presentation Definition."
298
- });
299
- }
300
- if (params.request_uri_method && !params.request_uri) {
301
- throw new import_oauth26.Oauth2ServerErrorResponseError({
302
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
303
- error_description: 'The "request_uri_method" parameter MUST NOT be present in the authorization request if the "request_uri" parameter is not present.'
304
- });
305
- }
306
- if (params.request_uri_method && !["GET", "POST"].includes(params.request_uri_method)) {
307
- throw new import_oauth26.Oauth2ServerErrorResponseError({
308
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequestUriMethod,
309
- error_description: `The 'request_uri_method' parameter MUST be 'GET' or 'POST'. Current: ${params.request_uri_method}`
310
- });
311
- }
312
- if (params.trust_chain && !import_utils3.zHttpsUrl.safeParse(params.client_id).success) {
313
- throw new import_oauth26.Oauth2ServerErrorResponseError({
314
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
315
- error_description: 'The "trust_chain" parameter MUST NOT be present in the authorization request if the "client_id" is not an OpenId Federation Entity Identifier starting with http:// or https://.'
316
- });
317
- }
318
- if (walletVerificationOptions?.expectedNonce && !params.wallet_nonce) {
319
- throw new import_oauth26.Oauth2ServerErrorResponseError({
320
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
321
- error_description: 'The "wallet_nonce" parameter MUST be present in the authorization request when the "expectedNonce" parameter is provided.'
322
- });
323
- }
324
- if (walletVerificationOptions?.expectedNonce !== params.wallet_nonce) {
325
- throw new import_oauth26.Oauth2ServerErrorResponseError({
326
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
327
- error_description: 'The "wallet_nonce" parameter MUST match the "expectedNonce" parameter when the "expectedNonce" parameter is provided.'
328
- });
329
- }
330
- if (params.client_id.startsWith("web-origin:")) {
331
- throw new import_oauth26.Oauth2ServerErrorResponseError({
332
- error: import_oauth26.Oauth2ErrorCodes.InvalidRequest,
333
- error_description: `The 'client_id' parameter MUST NOT use client identifier scheme 'web-origin' when not using the dc_api response mode. Current: ${params.client_id}`
334
- });
335
- }
336
- };
337
-
338
- // src/authorization-request/validate-authorization-request-dc-api.ts
339
- var import_oauth27 = require("@openid4vc/oauth2");
340
- var validateOpenid4vpAuthorizationRequestDcApiPayload = (options) => {
341
- const { params, isJarRequest, disableOriginValidation, origin } = options;
342
- if (isJarRequest && !params.expected_origins) {
343
- throw new import_oauth27.Oauth2ServerErrorResponseError({
344
- error: import_oauth27.Oauth2ErrorCodes.InvalidRequest,
345
- error_description: `The 'expected_origins' parameter MUST be present when using the dc_api response mode in combinaction with jar.`
346
- });
347
- }
348
- if ([params.presentation_definition, params.dcql_query].filter(Boolean).length !== 1) {
349
- throw new import_oauth27.Oauth2ServerErrorResponseError({
350
- error: import_oauth27.Oauth2ErrorCodes.InvalidRequest,
351
- error_description: "Exactly one of the following parameters MUST be present in the Authorization Request: dcql_query or presentation_definition"
352
- });
353
- }
354
- if (params.expected_origins && !disableOriginValidation) {
355
- if (!origin) {
356
- throw new import_oauth27.Oauth2ServerErrorResponseError({
357
- error: import_oauth27.Oauth2ErrorCodes.InvalidRequest,
358
- error_description: `Failed to validate the 'origin' of the authorization request. The 'origin' was not provided.`
359
- });
360
- }
361
- if (params.expected_origins && !params.expected_origins.includes(origin)) {
362
- throw new import_oauth27.Oauth2ServerErrorResponseError({
363
- error: import_oauth27.Oauth2ErrorCodes.InvalidRequest,
364
- error_description: `The 'expected_origins' parameter MUST include the origin of the authorization request. Current: ${params.expected_origins.join(", ")}`
365
- });
366
- }
367
- }
368
- };
369
-
370
- // src/authorization-request/z-authorization-request.ts
371
- var import_utils5 = require("@openid4vc/utils");
372
- var import_zod7 = require("zod");
373
-
374
- // src/models/z-client-metadata.ts
375
- var import_oauth28 = require("@openid4vc/oauth2");
376
- var import_utils4 = require("@openid4vc/utils");
377
- var import_zod6 = require("zod");
378
-
379
144
  // src/models/z-vp-formats-supported.ts
380
- var import_zod5 = require("zod");
381
- var zVpFormatsSupported = import_zod5.z.record(
382
- import_zod5.z.string(),
383
- import_zod5.z.object({
384
- alg_values_supported: import_zod5.z.optional(import_zod5.z.array(import_zod5.z.string()))
145
+ var import_zod2 = require("zod");
146
+ var zVpFormatsSupported = import_zod2.z.record(
147
+ import_zod2.z.string(),
148
+ import_zod2.z.object({
149
+ alg_values_supported: import_zod2.z.optional(import_zod2.z.array(import_zod2.z.string()))
385
150
  }).passthrough()
386
151
  );
387
152
 
388
153
  // src/models/z-client-metadata.ts
389
- var zClientMetadata = import_zod6.z.object({
390
- jwks: import_zod6.z.optional(import_oauth28.zJwkSet),
391
- vp_formats: import_zod6.z.optional(zVpFormatsSupported),
154
+ var zClientMetadata = import_zod3.z.object({
155
+ jwks: import_zod3.z.optional(import_oauth22.zJwkSet),
156
+ vp_formats: import_zod3.z.optional(zVpFormatsSupported),
392
157
  ...zJarmClientMetadata.shape,
393
- logo_uri: import_utils4.zHttpsUrl.optional(),
394
- client_name: import_zod6.z.string().optional()
158
+ logo_uri: import_utils2.zHttpsUrl.optional(),
159
+ client_name: import_zod3.z.string().optional()
395
160
  }).passthrough();
396
161
 
397
162
  // src/authorization-request/z-authorization-request.ts
398
- var zOpenid4vpAuthorizationRequest = import_zod7.z.object({
399
- response_type: import_zod7.z.literal("vp_token"),
400
- client_id: import_zod7.z.string(),
401
- redirect_uri: import_utils5.zHttpsUrl.optional(),
402
- response_uri: import_utils5.zHttpsUrl.optional(),
403
- request_uri: import_utils5.zHttpsUrl.optional(),
404
- request_uri_method: import_zod7.z.optional(import_zod7.z.string()),
405
- response_mode: import_zod7.z.enum(["direct_post", "direct_post.jwt"]).optional(),
406
- nonce: import_zod7.z.string(),
407
- wallet_nonce: import_zod7.z.string().optional(),
408
- scope: import_zod7.z.string().optional(),
409
- presentation_definition: import_zod7.z.record(import_zod7.z.any()).optional(),
410
- presentation_definition_uri: import_utils5.zHttpsUrl.optional(),
411
- dcql_query: import_zod7.z.record(import_zod7.z.any()).optional(),
163
+ var zStringToJson = import_zod4.z.string().transform((string, ctx) => {
164
+ try {
165
+ return JSON.parse(string);
166
+ } catch (error) {
167
+ ctx.addIssue({
168
+ code: "custom",
169
+ message: "Expected a JSON string, but could not parse the string to JSON"
170
+ });
171
+ return import_zod4.z.NEVER;
172
+ }
173
+ });
174
+ var zOpenid4vpAuthorizationRequest = import_zod4.z.object({
175
+ response_type: import_zod4.z.literal("vp_token"),
176
+ client_id: import_zod4.z.string(),
177
+ redirect_uri: import_utils3.zHttpsUrl.optional(),
178
+ response_uri: import_utils3.zHttpsUrl.optional(),
179
+ request_uri: import_utils3.zHttpsUrl.optional(),
180
+ request_uri_method: import_zod4.z.optional(import_zod4.z.string()),
181
+ response_mode: import_zod4.z.enum(["direct_post", "direct_post.jwt"]).optional(),
182
+ nonce: import_zod4.z.string(),
183
+ wallet_nonce: import_zod4.z.string().optional(),
184
+ scope: import_zod4.z.string().optional(),
185
+ presentation_definition: import_zod4.z.record(import_zod4.z.any()).or(zStringToJson).optional(),
186
+ presentation_definition_uri: import_utils3.zHttpsUrl.optional(),
187
+ dcql_query: import_zod4.z.record(import_zod4.z.any()).or(zStringToJson).optional(),
412
188
  client_metadata: zClientMetadata.optional(),
413
- client_metadata_uri: import_utils5.zHttpsUrl.optional(),
414
- state: import_zod7.z.string().optional(),
415
- transaction_data: import_zod7.z.array(import_zod7.z.string()).optional(),
416
- trust_chain: import_zod7.z.unknown().optional(),
417
- client_id_scheme: import_zod7.z.enum([
189
+ client_metadata_uri: import_utils3.zHttpsUrl.optional(),
190
+ state: import_zod4.z.string().optional(),
191
+ transaction_data: import_zod4.z.array(import_zod4.z.string().base64url()).optional(),
192
+ trust_chain: import_zod4.z.unknown().optional(),
193
+ client_id_scheme: import_zod4.z.enum([
418
194
  "pre-registered",
419
195
  "redirect_uri",
420
196
  "entity_id",
@@ -424,9 +200,16 @@ var zOpenid4vpAuthorizationRequest = import_zod7.z.object({
424
200
  "x509_san_uri"
425
201
  ]).optional()
426
202
  }).passthrough();
203
+ var zOpenid4vpAuthorizationRequestFromUriParams = import_zod4.z.string().url().transform((url) => Object.fromEntries(new import_utils3.URL(url).searchParams)).pipe(
204
+ import_zod4.z.object({
205
+ presentation_definition: zStringToJson.optional(),
206
+ client_metadata: zStringToJson.optional(),
207
+ dcql_query: zStringToJson.optional(),
208
+ transaction_data: zStringToJson.optional()
209
+ }).passthrough()
210
+ );
427
211
 
428
212
  // src/authorization-request/z-authorization-request-dc-api.ts
429
- var import_zod8 = require("zod");
430
213
  var zOpenid4vpAuthorizationRequestDcApi = zOpenid4vpAuthorizationRequest.pick({
431
214
  client_id: true,
432
215
  response_type: true,
@@ -438,10 +221,10 @@ var zOpenid4vpAuthorizationRequestDcApi = zOpenid4vpAuthorizationRequest.pick({
438
221
  dcql_query: true,
439
222
  trust_chain: true
440
223
  }).extend({
441
- client_id: import_zod8.z.optional(import_zod8.z.string()),
442
- expected_origins: import_zod8.z.array(import_zod8.z.string()).optional(),
443
- response_mode: import_zod8.z.enum(["dc_api", "dc_api.jwt", "w3c_dc_api.jwt", "w3c_dc_api"]),
444
- client_id_scheme: import_zod8.z.enum([
224
+ client_id: import_zod5.z.optional(import_zod5.z.string()),
225
+ expected_origins: import_zod5.z.array(import_zod5.z.string()).optional(),
226
+ response_mode: import_zod5.z.enum(["dc_api", "dc_api.jwt", "w3c_dc_api.jwt", "w3c_dc_api"]),
227
+ client_id_scheme: import_zod5.z.enum([
445
228
  "pre-registered",
446
229
  "redirect_uri",
447
230
  "entity_id",
@@ -455,163 +238,23 @@ function isOpenid4vpAuthorizationRequestDcApi(request) {
455
238
  return request.response_mode === "dc_api" || request.response_mode === "dc_api.jwt" || request.response_mode === "w3c_dc_api.jwt" || request.response_mode === "w3c_dc_api";
456
239
  }
457
240
 
458
- // src/authorization-request/create-authorization-request.ts
459
- async function createOpenid4vpAuthorizationRequest(options) {
460
- const { jar, scheme = "openid4vp://", wallet, callbacks } = options;
461
- let additionalJwtPayload;
462
- let authorizationRequestPayload;
463
- if (isOpenid4vpAuthorizationRequestDcApi(options.authorizationRequestPayload)) {
464
- authorizationRequestPayload = (0, import_utils6.parseWithErrorHandling)(
465
- zOpenid4vpAuthorizationRequestDcApi,
466
- options.authorizationRequestPayload,
467
- "Invalid authorization request. Could not parse openid4vp dc_api authorization request."
468
- );
469
- if (jar && !authorizationRequestPayload.expected_origins) {
470
- throw new import_oauth29.Oauth2Error(
471
- `The 'expected_origins' parameter MUST be present when using the dc_api response mode in combination with jar.`
472
- );
473
- }
474
- validateOpenid4vpAuthorizationRequestDcApiPayload({
475
- params: authorizationRequestPayload,
476
- isJarRequest: Boolean(jar),
477
- disableOriginValidation: true
478
- });
479
- } else {
480
- authorizationRequestPayload = (0, import_utils6.parseWithErrorHandling)(
481
- zOpenid4vpAuthorizationRequest,
482
- options.authorizationRequestPayload,
483
- "Invalid authorization request. Could not parse openid4vp authorization request."
484
- );
485
- validateOpenid4vpAuthorizationRequestPayload({
486
- params: authorizationRequestPayload,
487
- walletVerificationOptions: wallet
488
- });
489
- }
490
- if (jar) {
491
- if (!jar.additionalJwtPayload?.aud) {
492
- additionalJwtPayload = { ...jar.additionalJwtPayload, aud: jar.requestUri };
493
- }
494
- const jarResult = await createJarAuthorizationRequest({
495
- ...jar,
496
- authorizationRequestPayload,
497
- additionalJwtPayload,
498
- callbacks
499
- });
500
- const url2 = new import_utils6.URL(scheme);
501
- url2.search = `?${new import_utils6.URLSearchParams([
502
- ...url2.searchParams.entries(),
503
- ...(0, import_utils6.objectToQueryParams)(jarResult.jarAuthorizationRequest).entries()
504
- ]).toString()}`;
505
- return {
506
- authorizationRequestPayload,
507
- authorizationRequestObject: jarResult.jarAuthorizationRequest,
508
- authorizationRequest: url2.toString(),
509
- jar: { ...jar, ...jarResult }
510
- };
511
- }
512
- const url = new import_utils6.URL(scheme);
513
- url.search = `?${new import_utils6.URLSearchParams([
514
- ...url.searchParams.entries(),
515
- ...(0, import_utils6.objectToQueryParams)(authorizationRequestPayload).entries()
516
- ]).toString()}`;
517
- return {
518
- authorizationRequestPayload,
519
- authorizationRequestObject: authorizationRequestPayload,
520
- authorizationRequest: url.toString(),
521
- jar: void 0
522
- };
523
- }
524
-
525
- // src/authorization-request/parse-authorization-request-params.ts
526
- var import_oauth211 = require("@openid4vc/oauth2");
527
- var import_utils8 = require("@openid4vc/utils");
528
- var import_utils9 = require("@openid4vc/utils");
529
- var import_zod10 = __toESM(require("zod"));
530
-
531
- // src/jar/z-jar-authorization-request.ts
532
- var import_oauth210 = require("@openid4vc/oauth2");
533
- var import_utils7 = require("@openid4vc/utils");
534
- var import_zod9 = require("zod");
535
- var zJarAuthorizationRequest = import_zod9.z.object({
536
- request: import_zod9.z.optional(import_zod9.z.string()),
537
- request_uri: import_zod9.z.optional(import_utils7.zHttpsUrl),
538
- request_uri_method: import_zod9.z.optional(import_zod9.z.string()),
539
- client_id: import_zod9.z.optional(import_zod9.z.string())
540
- }).passthrough();
541
- function validateJarRequestParams(options) {
542
- const { jarRequestParams } = options;
543
- if (jarRequestParams.request && jarRequestParams.request_uri) {
544
- throw new import_oauth210.Oauth2ServerErrorResponseError({
545
- error: "invalid_request_object",
546
- error_description: "request and request_uri cannot both be present in a JAR request"
547
- });
548
- }
549
- if (!jarRequestParams.request && !jarRequestParams.request_uri) {
550
- throw new import_oauth210.Oauth2ServerErrorResponseError({
551
- error: "invalid_request_object",
552
- error_description: "request or request_uri must be present"
553
- });
554
- }
555
- return jarRequestParams;
556
- }
557
- function isJarAuthorizationRequest(request) {
558
- return "request" in request || "request_uri" in request;
559
- }
560
-
561
- // src/authorization-request/parse-authorization-request-params.ts
562
- function parseOpenid4vpAuthorizationRequestPayload(options) {
563
- const { authorizationRequest } = options;
564
- let provided = "params";
565
- let params;
566
- if (typeof authorizationRequest === "string") {
567
- if (authorizationRequest.includes("://")) {
568
- const url = new import_utils8.URL(authorizationRequest);
569
- params = Object.fromEntries(url.searchParams);
570
- provided = "uri";
571
- } else {
572
- const decoded = (0, import_oauth211.decodeJwt)({ jwt: authorizationRequest });
573
- params = decoded.payload;
574
- provided = "jwt";
575
- }
576
- } else {
577
- params = authorizationRequest;
578
- }
579
- const parsedRequest = (0, import_utils9.parseWithErrorHandling)(
580
- import_zod10.default.union([zOpenid4vpAuthorizationRequest, zJarAuthorizationRequest, zOpenid4vpAuthorizationRequestDcApi]),
581
- params
582
- );
583
- if (isJarAuthorizationRequest(parsedRequest)) {
584
- return {
585
- type: "jar",
586
- provided,
587
- params: parsedRequest
588
- };
589
- }
590
- if (isOpenid4vpAuthorizationRequestDcApi(parsedRequest)) {
591
- return {
592
- type: "openid4vp_dc_api",
593
- provided,
594
- params: parsedRequest
595
- };
596
- }
597
- return {
598
- type: "openid4vp",
599
- provided,
600
- params: parsedRequest
601
- };
602
- }
603
-
604
- // src/authorization-request/resolve-authorization-request.ts
605
- var import_oauth219 = require("@openid4vc/oauth2");
606
- var import_utils14 = require("@openid4vc/utils");
607
- var import_zod14 = __toESM(require("zod"));
241
+ // src/version.ts
242
+ var import_oauth23 = require("@openid4vc/oauth2");
608
243
 
609
- // src/client-identifier-scheme/parse-client-identifier-scheme.ts
610
- var import_oauth213 = require("@openid4vc/oauth2");
611
- var import_utils10 = require("@openid4vc/utils");
244
+ // src/client-identifier-scheme/z-client-id-scheme.ts
245
+ var import_zod6 = require("zod");
246
+ var zClientIdScheme = import_zod6.z.enum([
247
+ "pre-registered",
248
+ "redirect_uri",
249
+ "https",
250
+ "verifier_attestation",
251
+ "did",
252
+ "x509_san_dns",
253
+ "x509_san_uri",
254
+ "web-origin"
255
+ ]);
612
256
 
613
257
  // src/version.ts
614
- var import_oauth212 = require("@openid4vc/oauth2");
615
258
  function parseAuthorizationRequestVersion(request) {
616
259
  const requirements = [];
617
260
  if (isOpenid4vpAuthorizationRequestDcApi(request) && (request.response_mode === "w3c_dc_api" || request.response_mode === "w3c_dc_api.jwt")) {
@@ -664,8 +307,8 @@ function parseAuthorizationRequestVersion(request) {
664
307
  const highestPossibleVersion = lessThanVersions.length > 0 ? Math.max(Math.min(...lessThanVersions) - 1, 18) : 24;
665
308
  const lowestRequiredVersion = greaterThanVersions.length > 0 ? Math.max(...greaterThanVersions) : 18;
666
309
  if (lowestRequiredVersion > highestPossibleVersion) {
667
- throw new import_oauth212.Oauth2ServerErrorResponseError({
668
- error: import_oauth212.Oauth2ErrorCodes.InvalidRequest,
310
+ throw new import_oauth23.Oauth2ServerErrorResponseError({
311
+ error: import_oauth23.Oauth2ErrorCodes.InvalidRequest,
669
312
  error_description: "Could not infer openid4vp version from the openid4vp request payload."
670
313
  });
671
314
  }
@@ -673,15 +316,15 @@ function parseAuthorizationRequestVersion(request) {
673
316
  }
674
317
 
675
318
  // src/client-identifier-scheme/parse-client-identifier-scheme.ts
676
- function getClientId(options) {
319
+ function getOpenid4vpClientId(options) {
677
320
  const version = parseAuthorizationRequestVersion(options.authorizationRequestPayload);
678
321
  if (version < 22) {
679
322
  return getLegacyClientId(options);
680
323
  }
681
324
  if (isOpenid4vpAuthorizationRequestDcApi(options.authorizationRequestPayload)) {
682
325
  if (!options.origin) {
683
- throw new import_oauth213.Oauth2ServerErrorResponseError({
684
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
326
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
327
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
685
328
  error_description: "Failed to parse client identifier. 'origin' is required for requests with response_mode 'dc_api' and 'dc_api.jwt'"
686
329
  });
687
330
  }
@@ -695,8 +338,8 @@ function getLegacyClientId(options) {
695
338
  const clientIdScheme = legacyClientIdScheme === "entity_id" ? "https" : legacyClientIdScheme;
696
339
  if (isOpenid4vpAuthorizationRequestDcApi(options.authorizationRequestPayload)) {
697
340
  if (!options.origin) {
698
- throw new import_oauth213.Oauth2ServerErrorResponseError({
699
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
341
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
342
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
700
343
  error_description: "Failed to parse client identifier. 'origin' is required for requests with response_mode 'dc_api' and 'dc_api.jwt'"
701
344
  });
702
345
  }
@@ -716,7 +359,7 @@ function parseClientIdentifier(options, parserConfig) {
716
359
  const parserConfigWithDefaults = {
717
360
  supportedSchemes: parserConfig?.supportedSchemes || Object.values(zClientIdScheme.options)
718
361
  };
719
- const clientId = getClientId(options);
362
+ const clientId = getOpenid4vpClientId(options);
720
363
  const colonIndex = clientId.indexOf(":");
721
364
  if (colonIndex === -1) {
722
365
  return {
@@ -729,16 +372,16 @@ function parseClientIdentifier(options, parserConfig) {
729
372
  const schemePart = clientId.substring(0, colonIndex);
730
373
  const identifierPart = clientId.substring(colonIndex + 1);
731
374
  if (!parserConfigWithDefaults.supportedSchemes.includes(schemePart)) {
732
- throw new import_oauth213.Oauth2ServerErrorResponseError({
733
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
375
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
376
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
734
377
  error_description: `Unsupported client identifier scheme. ${schemePart} is not supported.`
735
378
  });
736
379
  }
737
380
  const scheme = schemePart;
738
381
  if (scheme === "https") {
739
- if (!clientId.startsWith("https://") && !((0, import_oauth213.getGlobalConfig)().allowInsecureUrls && clientId.startsWith("http://"))) {
740
- throw new import_oauth213.Oauth2ServerErrorResponseError({
741
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
382
+ if (!clientId.startsWith("https://") && !((0, import_oauth24.getGlobalConfig)().allowInsecureUrls && clientId.startsWith("http://"))) {
383
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
384
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
742
385
  error_description: "Invalid client identifier. Client identifier must start with https:// or http:// if allowInsecureUrls is true."
743
386
  });
744
387
  }
@@ -749,166 +392,549 @@ function parseClientIdentifier(options, parserConfig) {
749
392
  trustChain: authorizationRequestPayload.trust_chain
750
393
  };
751
394
  }
752
- if (scheme === "redirect_uri") {
753
- if (jar) {
754
- throw new import_oauth213.Oauth2ServerErrorResponseError({
755
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
756
- error_description: 'Using client identifier scheme "redirect_uri" the request MUST NOT be signed.'
757
- });
758
- }
759
- if (isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
760
- throw new import_oauth213.Oauth2ServerErrorResponseError({
761
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
762
- error_description: `The client identifier scheme 'redirect_uri' is not supported when using the dc_api response mode.`
763
- });
764
- }
765
- return {
766
- scheme,
767
- identifier: identifierPart,
768
- originalValue: clientId,
769
- redirectUri: authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri
770
- };
395
+ if (scheme === "redirect_uri") {
396
+ if (jar) {
397
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
398
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
399
+ error_description: 'Using client identifier scheme "redirect_uri" the request MUST NOT be signed.'
400
+ });
401
+ }
402
+ if (isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
403
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
404
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
405
+ error_description: `The client identifier scheme 'redirect_uri' is not supported when using the dc_api response mode.`
406
+ });
407
+ }
408
+ return {
409
+ scheme,
410
+ identifier: identifierPart,
411
+ originalValue: clientId,
412
+ redirectUri: authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri
413
+ };
414
+ }
415
+ if (scheme === "did") {
416
+ if (!jar) {
417
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
418
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
419
+ error_description: 'Using client identifier scheme "did" requires a signed JAR request.'
420
+ });
421
+ }
422
+ if (!clientId.startsWith("did:")) {
423
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
424
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
425
+ error_description: "Invalid client identifier. Client identifier must start with 'did:'"
426
+ });
427
+ }
428
+ if (!jar.signer.publicJwk.kid) {
429
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
430
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
431
+ error_description: `Missing required 'kid' for client identifier scheme: did`
432
+ });
433
+ }
434
+ if (!jar.signer.publicJwk.kid?.startsWith(clientId)) {
435
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
436
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
437
+ error_description: 'With client identifier scheme "did" the JAR request must be signed by the same DID as the client identifier.'
438
+ });
439
+ }
440
+ return {
441
+ scheme,
442
+ identifier: clientId,
443
+ originalValue: clientId,
444
+ didUrl: jar.signer.publicJwk.kid
445
+ };
446
+ }
447
+ if (scheme === "x509_san_dns" || scheme === "x509_san_uri") {
448
+ if (!jar) {
449
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
450
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
451
+ error_description: 'Using client identifier scheme "x509_san_dns" or "x509_san_uri" requires a signed JAR request.'
452
+ });
453
+ }
454
+ if (jar.signer.method !== "x5c") {
455
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
456
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
457
+ error_description: "Something went wrong. The JWT signer method is not x5c but the client identifier scheme is x509_san_dns."
458
+ });
459
+ }
460
+ if (scheme === "x509_san_dns") {
461
+ if (!options.callbacks.getX509CertificateMetadata) {
462
+ throw new import_oauth24.Oauth2ServerErrorResponseError(
463
+ {
464
+ error: import_oauth24.Oauth2ErrorCodes.ServerError
465
+ },
466
+ {
467
+ internalMessage: "Missing required 'getX509CertificateMetadata' callback for verification of 'x509_san_dns' client id scheme"
468
+ }
469
+ );
470
+ }
471
+ const { sanDnsNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
472
+ if (!sanDnsNames.includes(identifierPart)) {
473
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
474
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
475
+ error_description: `Invalid client identifier. One of the leaf certificates san dns names [${sanDnsNames.join(", ")}] must match the client identifier '${identifierPart}'. `
476
+ });
477
+ }
478
+ if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
479
+ const uri = authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri;
480
+ if (!uri || new import_utils4.URL(uri).hostname !== identifierPart) {
481
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
482
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
483
+ error_description: "Invalid client identifier. The fully qualified domain name of the redirect_uri value MUST match the Client Identifier without the prefix x509_san_dns."
484
+ });
485
+ }
486
+ }
487
+ } else if (scheme === "x509_san_uri") {
488
+ if (!options.callbacks.getX509CertificateMetadata) {
489
+ throw new import_oauth24.Oauth2ServerErrorResponseError(
490
+ {
491
+ error: import_oauth24.Oauth2ErrorCodes.ServerError
492
+ },
493
+ {
494
+ internalMessage: "Missing required 'getX509CertificateMetadata' callback for verification of 'x509_san_uri' client id scheme"
495
+ }
496
+ );
497
+ }
498
+ const { sanUriNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
499
+ if (!sanUriNames.includes(identifierPart)) {
500
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
501
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
502
+ error_description: `Invalid client identifier. One of the leaf certificates san uri names [${sanUriNames.join(", ")}] must match the client identifier '${identifierPart}'.`
503
+ });
504
+ }
505
+ if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
506
+ const uri = authorizationRequestPayload.redirect_uri || authorizationRequestPayload.response_uri;
507
+ if (!uri || uri !== identifierPart) {
508
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
509
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
510
+ error_description: "The redirect_uri value MUST match the Client Identifier without the prefix x509_san_uri"
511
+ });
512
+ }
513
+ }
514
+ }
515
+ return {
516
+ scheme,
517
+ identifier: identifierPart,
518
+ originalValue: clientId,
519
+ x5c: jar.signer.x5c
520
+ };
521
+ }
522
+ if (scheme === "web-origin") {
523
+ return {
524
+ scheme,
525
+ identifier: identifierPart,
526
+ originalValue: clientId,
527
+ clientMetadata: authorizationRequestPayload.client_metadata
528
+ };
529
+ }
530
+ if (scheme === "verifier_attestation") {
531
+ if (!jar) {
532
+ throw new import_oauth24.Oauth2ServerErrorResponseError({
533
+ error: import_oauth24.Oauth2ErrorCodes.InvalidRequest,
534
+ error_description: 'Using client identifier scheme "verifier_attestation" requires a signed JAR request.'
535
+ });
536
+ }
537
+ }
538
+ return {
539
+ scheme,
540
+ identifier: identifierPart,
541
+ originalValue: clientId
542
+ };
543
+ }
544
+
545
+ // src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts
546
+ var import_oauth27 = require("@openid4vc/oauth2");
547
+ var import_zod8 = __toESM(require("zod"));
548
+
549
+ // src/jarm/jarm-extract-jwks.ts
550
+ function extractJwksFromClientMetadata(clientMetadata) {
551
+ const parsed = zJarmClientMetadataParsed.parse(clientMetadata);
552
+ const encryptionAlg = parsed.client_metadata.authorization_encrypted_response_enc;
553
+ const signingAlg = parsed.client_metadata.authorization_signed_response_alg;
554
+ const encJwk = clientMetadata.jwks.keys.find((key) => key.use === "enc" && key.alg === encryptionAlg) ?? clientMetadata.jwks.keys.find((key) => key.use === "enc") ?? // fallback, take first key. HAIP does not specify requirement on enc
555
+ clientMetadata.jwks.keys?.[0];
556
+ const sigJwk = clientMetadata.jwks.keys.find((key) => key.use === "sig" && key.alg === signingAlg) ?? clientMetadata.jwks.keys.find((key) => key.use === "sig") ?? // falback, take first key
557
+ clientMetadata.jwks.keys?.[0];
558
+ return { encJwk, sigJwk };
559
+ }
560
+
561
+ // src/jarm/jarm-authorization-response/jarm-validate-authorization-response.ts
562
+ var import_oauth26 = require("@openid4vc/oauth2");
563
+ var import_utils5 = require("@openid4vc/utils");
564
+
565
+ // src/jarm/jarm-authorization-response/z-jarm-authorization-response.ts
566
+ var import_oauth25 = require("@openid4vc/oauth2");
567
+ var import_zod7 = require("zod");
568
+ var zJarmHeader = import_zod7.z.object({ ...import_oauth25.zJwtHeader.shape, apu: import_zod7.z.string().optional(), apv: import_zod7.z.string().optional() });
569
+ var zJarmAuthorizationResponse = import_zod7.z.object({
570
+ /**
571
+ * iss: The issuer URL of the authorization server that created the response
572
+ * aud: The client_id of the client the response is intended for
573
+ * exp: The expiration time of the JWT. A maximum JWT lifetime of 10 minutes is RECOMMENDED.
574
+ */
575
+ ...import_oauth25.zJwtPayload.shape,
576
+ ...import_oauth25.zJwtPayload.pick({ iss: true, aud: true, exp: true }).required().shape,
577
+ state: import_zod7.z.optional(import_zod7.z.string())
578
+ }).passthrough();
579
+ var zJarmAuthorizationResponseEncryptedOnly = import_zod7.z.object({
580
+ ...import_oauth25.zJwtPayload.shape,
581
+ state: import_zod7.z.optional(import_zod7.z.string())
582
+ }).passthrough();
583
+
584
+ // src/jarm/jarm-authorization-response/jarm-validate-authorization-response.ts
585
+ var jarmAuthorizationResponseValidate = (options) => {
586
+ const { expectedClientId, authorizationResponse } = options;
587
+ if (!zJarmAuthorizationResponse.safeParse(authorizationResponse).success) {
588
+ return;
589
+ }
590
+ if (expectedClientId !== authorizationResponse.aud) {
591
+ throw new import_oauth26.Oauth2Error(
592
+ `Invalid 'aud' claim in JARM authorization response. Expected '${expectedClientId}' received '${JSON.stringify(authorizationResponse.aud)}'.`
593
+ );
594
+ }
595
+ if (authorizationResponse.exp !== void 0 && authorizationResponse.exp < (0, import_utils5.dateToSeconds)()) {
596
+ throw new import_oauth26.Oauth2Error("Jarm auth response is expired.");
597
+ }
598
+ };
599
+
600
+ // src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts
601
+ var decryptJarmAuthorizationResponseJwt = async (options) => {
602
+ const { jarmAuthorizationResponseJwt, callbacks, authorizationRequestPayload } = options;
603
+ const encryptionJwk = authorizationRequestPayload.client_metadata?.jwks ? extractJwksFromClientMetadata({
604
+ ...authorizationRequestPayload.client_metadata,
605
+ jwks: authorizationRequestPayload.client_metadata.jwks
606
+ }).encJwk : void 0;
607
+ const result = await callbacks.decryptJwe(jarmAuthorizationResponseJwt, { jwk: encryptionJwk });
608
+ if (!result.decrypted) {
609
+ throw new import_oauth27.Oauth2Error("Failed to decrypt jarm auth response.");
610
+ }
611
+ return result.payload;
612
+ };
613
+ async function verifyJarmAuthorizationResponse(options) {
614
+ const { jarmAuthorizationResponseJwt, callbacks, expectedClientId, authorizationRequestPayload } = options;
615
+ const requestDataIsEncrypted = import_oauth27.zCompactJwe.safeParse(jarmAuthorizationResponseJwt).success;
616
+ const decryptedRequestData = requestDataIsEncrypted ? await decryptJarmAuthorizationResponseJwt({
617
+ jarmAuthorizationResponseJwt,
618
+ callbacks,
619
+ authorizationRequestPayload
620
+ }) : jarmAuthorizationResponseJwt;
621
+ const responseIsSigned = import_oauth27.zCompactJwt.safeParse(decryptedRequestData).success;
622
+ if (!requestDataIsEncrypted && !responseIsSigned) {
623
+ throw new import_oauth27.Oauth2Error("Jarm Auth Response must be either encrypted, signed, or signed and encrypted.");
624
+ }
625
+ let jarmAuthorizationResponse;
626
+ if (responseIsSigned) {
627
+ const { header: jwsProtectedHeader, payload: jwsPayload } = (0, import_oauth27.decodeJwt)({
628
+ jwt: decryptedRequestData,
629
+ headerSchema: import_zod8.default.object({ ...import_oauth27.zJwtHeader.shape, kid: import_zod8.default.string() })
630
+ });
631
+ const response = zJarmAuthorizationResponse.parse(jwsPayload);
632
+ const jwtSigner = (0, import_oauth27.jwtSignerFromJwt)({ header: jwsProtectedHeader, payload: jwsPayload });
633
+ const verificationResult = await options.callbacks.verifyJwt(jwtSigner, {
634
+ compact: decryptedRequestData,
635
+ header: jwsProtectedHeader,
636
+ payload: jwsPayload
637
+ });
638
+ if (!verificationResult.verified) {
639
+ throw new import_oauth27.Oauth2Error("Jarm Auth Response is not valid.");
640
+ }
641
+ jarmAuthorizationResponse = response;
642
+ } else {
643
+ const jsonRequestData = JSON.parse(decryptedRequestData);
644
+ jarmAuthorizationResponse = zJarmAuthorizationResponseEncryptedOnly.parse(jsonRequestData);
645
+ }
646
+ jarmAuthorizationResponseValidate({
647
+ expectedClientId,
648
+ authorizationResponse: jarmAuthorizationResponse
649
+ });
650
+ const type = requestDataIsEncrypted && responseIsSigned ? "SignedEncrypted" /* SignedEncrypted */ : requestDataIsEncrypted ? "Encrypted" /* Encrypted */ : "Signed" /* Signed */;
651
+ const issuer = jarmAuthorizationResponse.iss;
652
+ return { jarmAuthorizationResponse, type, issuer };
653
+ }
654
+
655
+ // src/authorization-request/create-authorization-request.ts
656
+ var import_oauth211 = require("@openid4vc/oauth2");
657
+ var import_utils7 = require("@openid4vc/utils");
658
+
659
+ // src/jar/create-jar-authorization-request.ts
660
+ var import_oauth28 = require("@openid4vc/oauth2");
661
+ async function createJarAuthorizationRequest(options) {
662
+ const { jwtSigner, jweEncryptor, authorizationRequestPayload, requestUri, callbacks } = options;
663
+ let authorizationRequestJwt;
664
+ let encryptionJwk;
665
+ const { jwt, signerJwk } = await callbacks.signJwt(jwtSigner, {
666
+ header: { ...(0, import_oauth28.jwtHeaderFromJwtSigner)(jwtSigner), typ: "oauth-authz-req+jwt" },
667
+ payload: { ...options.additionalJwtPayload, ...authorizationRequestPayload }
668
+ });
669
+ authorizationRequestJwt = jwt;
670
+ if (jweEncryptor) {
671
+ const encryptionResult = await callbacks.encryptJwe(jweEncryptor, authorizationRequestJwt);
672
+ authorizationRequestJwt = encryptionResult.jwe;
673
+ encryptionJwk = encryptionResult.encryptionJwk;
674
+ }
675
+ const client_id = authorizationRequestPayload.client_id;
676
+ const jarAuthorizationRequest = requestUri ? { client_id, request_uri: requestUri } : { client_id, request: authorizationRequestJwt };
677
+ return { jarAuthorizationRequest, signerJwk, encryptionJwk, authorizationRequestJwt };
678
+ }
679
+
680
+ // src/authorization-request/validate-authorization-request.ts
681
+ var import_oauth29 = require("@openid4vc/oauth2");
682
+ var import_utils6 = require("@openid4vc/utils");
683
+ var validateOpenid4vpAuthorizationRequestPayload = (options) => {
684
+ const { params, walletVerificationOptions } = options;
685
+ if (!params.redirect_uri && !params.response_uri) {
686
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
687
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
688
+ error_description: `Missing required 'redirect_uri' or 'response_uri' in openid4vp authorization request.`
689
+ });
690
+ }
691
+ if (params.response_uri && !["direct_post", "direct_post.jwt"].find((mode) => mode === params.response_mode)) {
692
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
693
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
694
+ error_description: `The 'response_mode' parameter MUST be 'direct_post' or 'direct_post.jwt' when 'response_uri' is provided. Current: ${params.response_mode}`
695
+ });
696
+ }
697
+ if ([params.presentation_definition_uri, params.presentation_definition, params.dcql_query, params.scope].filter(
698
+ Boolean
699
+ ).length > 1) {
700
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
701
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
702
+ error_description: "Exactly one of the following parameters MUST be present in the authorization request: dcql_query, presentation_definition, presentation_definition_uri, or a scope value representing a Presentation Definition."
703
+ });
704
+ }
705
+ if (params.request_uri_method && !params.request_uri) {
706
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
707
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
708
+ error_description: 'The "request_uri_method" parameter MUST NOT be present in the authorization request if the "request_uri" parameter is not present.'
709
+ });
710
+ }
711
+ if (params.request_uri_method && !["GET", "POST"].includes(params.request_uri_method)) {
712
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
713
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequestUriMethod,
714
+ error_description: `The 'request_uri_method' parameter MUST be 'GET' or 'POST'. Current: ${params.request_uri_method}`
715
+ });
716
+ }
717
+ if (params.trust_chain && !import_utils6.zHttpsUrl.safeParse(params.client_id).success) {
718
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
719
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
720
+ error_description: 'The "trust_chain" parameter MUST NOT be present in the authorization request if the "client_id" is not an OpenId Federation Entity Identifier starting with http:// or https://.'
721
+ });
722
+ }
723
+ if (walletVerificationOptions?.expectedNonce && !params.wallet_nonce) {
724
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
725
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
726
+ error_description: 'The "wallet_nonce" parameter MUST be present in the authorization request when the "expectedNonce" parameter is provided.'
727
+ });
728
+ }
729
+ if (walletVerificationOptions?.expectedNonce !== params.wallet_nonce) {
730
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
731
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
732
+ error_description: 'The "wallet_nonce" parameter MUST match the "expectedNonce" parameter when the "expectedNonce" parameter is provided.'
733
+ });
734
+ }
735
+ if (params.client_id.startsWith("web-origin:")) {
736
+ throw new import_oauth29.Oauth2ServerErrorResponseError({
737
+ error: import_oauth29.Oauth2ErrorCodes.InvalidRequest,
738
+ error_description: `The 'client_id' parameter MUST NOT use client identifier scheme 'web-origin' when not using the dc_api response mode. Current: ${params.client_id}`
739
+ });
740
+ }
741
+ };
742
+
743
+ // src/authorization-request/validate-authorization-request-dc-api.ts
744
+ var import_oauth210 = require("@openid4vc/oauth2");
745
+ var validateOpenid4vpAuthorizationRequestDcApiPayload = (options) => {
746
+ const { params, isJarRequest, disableOriginValidation, origin } = options;
747
+ if (isJarRequest && !params.expected_origins) {
748
+ throw new import_oauth210.Oauth2ServerErrorResponseError({
749
+ error: import_oauth210.Oauth2ErrorCodes.InvalidRequest,
750
+ error_description: `The 'expected_origins' parameter MUST be present when using the dc_api response mode in combinaction with jar.`
751
+ });
752
+ }
753
+ if ([params.presentation_definition, params.dcql_query].filter(Boolean).length !== 1) {
754
+ throw new import_oauth210.Oauth2ServerErrorResponseError({
755
+ error: import_oauth210.Oauth2ErrorCodes.InvalidRequest,
756
+ error_description: "Exactly one of the following parameters MUST be present in the Authorization Request: dcql_query or presentation_definition"
757
+ });
771
758
  }
772
- if (scheme === "did") {
773
- if (!jar) {
774
- throw new import_oauth213.Oauth2ServerErrorResponseError({
775
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
776
- error_description: 'Using client identifier scheme "did" requires a signed JAR request.'
759
+ if (params.expected_origins && !disableOriginValidation) {
760
+ if (!origin) {
761
+ throw new import_oauth210.Oauth2ServerErrorResponseError({
762
+ error: import_oauth210.Oauth2ErrorCodes.InvalidRequest,
763
+ error_description: `Failed to validate the 'origin' of the authorization request. The 'origin' was not provided.`
777
764
  });
778
765
  }
779
- if (!clientId.startsWith("did:")) {
780
- throw new import_oauth213.Oauth2ServerErrorResponseError({
781
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
782
- error_description: "Invalid client identifier. Client identifier must start with 'did:'"
766
+ if (params.expected_origins && !params.expected_origins.includes(origin)) {
767
+ throw new import_oauth210.Oauth2ServerErrorResponseError({
768
+ error: import_oauth210.Oauth2ErrorCodes.InvalidRequest,
769
+ error_description: `The 'expected_origins' parameter MUST include the origin of the authorization request. Current: ${params.expected_origins.join(", ")}`
783
770
  });
784
771
  }
785
- if (!jar.signer.publicJwk.kid) {
786
- throw new import_oauth213.Oauth2ServerErrorResponseError({
787
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
788
- error_description: `Missing required 'kid' for client identifier scheme: did`
789
- });
772
+ }
773
+ };
774
+
775
+ // src/authorization-request/create-authorization-request.ts
776
+ async function createOpenid4vpAuthorizationRequest(options) {
777
+ const { jar, scheme = "openid4vp://", wallet, callbacks } = options;
778
+ let additionalJwtPayload;
779
+ let authorizationRequestPayload;
780
+ if (isOpenid4vpAuthorizationRequestDcApi(options.authorizationRequestPayload)) {
781
+ authorizationRequestPayload = (0, import_utils7.parseWithErrorHandling)(
782
+ zOpenid4vpAuthorizationRequestDcApi,
783
+ options.authorizationRequestPayload,
784
+ "Invalid authorization request. Could not parse openid4vp dc_api authorization request."
785
+ );
786
+ if (jar && !authorizationRequestPayload.expected_origins) {
787
+ throw new import_oauth211.Oauth2Error(
788
+ `The 'expected_origins' parameter MUST be present when using the dc_api response mode in combination with jar.`
789
+ );
790
790
  }
791
- if (!jar.signer.publicJwk.kid?.startsWith(clientId)) {
792
- throw new import_oauth213.Oauth2ServerErrorResponseError({
793
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
794
- error_description: 'With client identifier scheme "did" the JAR request must be signed by the same DID as the client identifier.'
795
- });
791
+ validateOpenid4vpAuthorizationRequestDcApiPayload({
792
+ params: authorizationRequestPayload,
793
+ isJarRequest: Boolean(jar),
794
+ disableOriginValidation: true
795
+ });
796
+ } else {
797
+ authorizationRequestPayload = (0, import_utils7.parseWithErrorHandling)(
798
+ zOpenid4vpAuthorizationRequest,
799
+ options.authorizationRequestPayload,
800
+ "Invalid authorization request. Could not parse openid4vp authorization request."
801
+ );
802
+ validateOpenid4vpAuthorizationRequestPayload({
803
+ params: authorizationRequestPayload,
804
+ walletVerificationOptions: wallet
805
+ });
806
+ }
807
+ if (jar) {
808
+ if (!jar.additionalJwtPayload?.aud) {
809
+ additionalJwtPayload = { ...jar.additionalJwtPayload, aud: jar.requestUri };
796
810
  }
811
+ const jarResult = await createJarAuthorizationRequest({
812
+ ...jar,
813
+ authorizationRequestPayload,
814
+ additionalJwtPayload,
815
+ callbacks
816
+ });
817
+ const url2 = new import_utils7.URL(scheme);
818
+ url2.search = `?${new import_utils7.URLSearchParams([
819
+ ...url2.searchParams.entries(),
820
+ ...(0, import_utils7.objectToQueryParams)(jarResult.jarAuthorizationRequest).entries()
821
+ ]).toString()}`;
797
822
  return {
798
- scheme,
799
- identifier: clientId,
800
- originalValue: clientId,
801
- didUrl: jar.signer.publicJwk.kid
823
+ authorizationRequestPayload,
824
+ authorizationRequestObject: jarResult.jarAuthorizationRequest,
825
+ authorizationRequest: url2.toString(),
826
+ jar: { ...jar, ...jarResult }
802
827
  };
803
828
  }
804
- if (scheme === "x509_san_dns" || scheme === "x509_san_uri") {
805
- if (!jar) {
806
- throw new import_oauth213.Oauth2ServerErrorResponseError({
807
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
808
- error_description: 'Using client identifier scheme "x509_san_dns" or "x509_san_uri" requires a signed JAR request.'
809
- });
810
- }
811
- if (jar.signer.method !== "x5c") {
812
- throw new import_oauth213.Oauth2ServerErrorResponseError({
813
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
814
- error_description: "Something went wrong. The JWT signer method is not x5c but the client identifier scheme is x509_san_dns."
815
- });
816
- }
817
- if (scheme === "x509_san_dns") {
818
- if (!options.callbacks.getX509CertificateMetadata) {
819
- throw new import_oauth213.Oauth2ServerErrorResponseError(
820
- {
821
- error: import_oauth213.Oauth2ErrorCodes.ServerError
822
- },
823
- {
824
- internalMessage: "Missing required 'getX509CertificateMetadata' callback for verification of 'x509_san_dns' client id scheme"
825
- }
826
- );
827
- }
828
- const { sanDnsNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
829
- if (!sanDnsNames.includes(identifierPart)) {
830
- throw new import_oauth213.Oauth2ServerErrorResponseError({
831
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
832
- error_description: `Invalid client identifier. One of the leaf certificates san dns names [${sanDnsNames.join(", ")}] must match the client identifier '${identifierPart}'. `
833
- });
834
- }
835
- if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
836
- const uri = authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri;
837
- if (!uri || new import_utils10.URL(uri).hostname !== identifierPart) {
838
- throw new import_oauth213.Oauth2ServerErrorResponseError({
839
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
840
- error_description: "Invalid client identifier. The fully qualified domain name of the redirect_uri value MUST match the Client Identifier without the prefix x509_san_dns."
841
- });
842
- }
843
- }
844
- } else if (scheme === "x509_san_uri") {
845
- if (!options.callbacks.getX509CertificateMetadata) {
846
- throw new import_oauth213.Oauth2ServerErrorResponseError(
847
- {
848
- error: import_oauth213.Oauth2ErrorCodes.ServerError
849
- },
850
- {
851
- internalMessage: "Missing required 'getX509CertificateMetadata' callback for verification of 'x509_san_uri' client id scheme"
852
- }
853
- );
854
- }
855
- const { sanUriNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
856
- if (!sanUriNames.includes(identifierPart)) {
857
- throw new import_oauth213.Oauth2ServerErrorResponseError({
858
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
859
- error_description: `Invalid client identifier. One of the leaf certificates san uri names [${sanUriNames.join(", ")}] must match the client identifier '${identifierPart}'.`
860
- });
861
- }
862
- if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
863
- const uri = authorizationRequestPayload.redirect_uri || authorizationRequestPayload.response_uri;
864
- if (!uri || uri !== identifierPart) {
865
- throw new import_oauth213.Oauth2ServerErrorResponseError({
866
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
867
- error_description: "The redirect_uri value MUST match the Client Identifier without the prefix x509_san_uri"
868
- });
869
- }
870
- }
829
+ const url = new import_utils7.URL(scheme);
830
+ url.search = `?${new import_utils7.URLSearchParams([
831
+ ...url.searchParams.entries(),
832
+ ...(0, import_utils7.objectToQueryParams)(authorizationRequestPayload).entries()
833
+ ]).toString()}`;
834
+ return {
835
+ authorizationRequestPayload,
836
+ authorizationRequestObject: authorizationRequestPayload,
837
+ authorizationRequest: url.toString(),
838
+ jar: void 0
839
+ };
840
+ }
841
+
842
+ // src/authorization-request/parse-authorization-request-params.ts
843
+ var import_oauth213 = require("@openid4vc/oauth2");
844
+ var import_utils9 = require("@openid4vc/utils");
845
+ var import_zod10 = __toESM(require("zod"));
846
+
847
+ // src/jar/z-jar-authorization-request.ts
848
+ var import_oauth212 = require("@openid4vc/oauth2");
849
+ var import_utils8 = require("@openid4vc/utils");
850
+ var import_zod9 = require("zod");
851
+ var zJarAuthorizationRequest = import_zod9.z.object({
852
+ request: import_zod9.z.optional(import_zod9.z.string()),
853
+ request_uri: import_zod9.z.optional(import_utils8.zHttpsUrl),
854
+ request_uri_method: import_zod9.z.optional(import_zod9.z.string()),
855
+ client_id: import_zod9.z.optional(import_zod9.z.string())
856
+ }).passthrough();
857
+ function validateJarRequestParams(options) {
858
+ const { jarRequestParams } = options;
859
+ if (jarRequestParams.request && jarRequestParams.request_uri) {
860
+ throw new import_oauth212.Oauth2ServerErrorResponseError({
861
+ error: "invalid_request_object",
862
+ error_description: "request and request_uri cannot both be present in a JAR request"
863
+ });
864
+ }
865
+ if (!jarRequestParams.request && !jarRequestParams.request_uri) {
866
+ throw new import_oauth212.Oauth2ServerErrorResponseError({
867
+ error: "invalid_request_object",
868
+ error_description: "request or request_uri must be present"
869
+ });
870
+ }
871
+ return jarRequestParams;
872
+ }
873
+ function isJarAuthorizationRequest(request) {
874
+ return "request" in request || "request_uri" in request;
875
+ }
876
+
877
+ // src/authorization-request/parse-authorization-request-params.ts
878
+ function parseOpenid4vpAuthorizationRequest(options) {
879
+ const { authorizationRequest } = options;
880
+ let provided = "params";
881
+ let params;
882
+ if (typeof authorizationRequest === "string") {
883
+ if (authorizationRequest.includes("://")) {
884
+ params = (0, import_utils9.parseWithErrorHandling)(
885
+ zOpenid4vpAuthorizationRequestFromUriParams,
886
+ authorizationRequest,
887
+ "Unable to parse openid4vp authorization request uri to a valid object"
888
+ );
889
+ provided = "uri";
890
+ } else {
891
+ const decoded = (0, import_oauth213.decodeJwt)({ jwt: authorizationRequest });
892
+ params = decoded.payload;
893
+ provided = "jwt";
871
894
  }
895
+ } else {
896
+ params = authorizationRequest;
897
+ }
898
+ const parsedRequest = (0, import_utils9.parseWithErrorHandling)(
899
+ import_zod10.default.union([zOpenid4vpAuthorizationRequest, zJarAuthorizationRequest, zOpenid4vpAuthorizationRequestDcApi]),
900
+ params
901
+ );
902
+ if (isJarAuthorizationRequest(parsedRequest)) {
872
903
  return {
873
- scheme,
874
- identifier: identifierPart,
875
- originalValue: clientId,
876
- x5c: jar.signer.x5c
904
+ type: "jar",
905
+ provided,
906
+ params: parsedRequest
877
907
  };
878
908
  }
879
- if (scheme === "web-origin") {
909
+ if (isOpenid4vpAuthorizationRequestDcApi(parsedRequest)) {
880
910
  return {
881
- scheme,
882
- identifier: identifierPart,
883
- originalValue: clientId,
884
- clientMetadata: authorizationRequestPayload.client_metadata
911
+ type: "openid4vp_dc_api",
912
+ provided,
913
+ params: parsedRequest
885
914
  };
886
915
  }
887
- if (scheme === "verifier_attestation") {
888
- if (!jar) {
889
- throw new import_oauth213.Oauth2ServerErrorResponseError({
890
- error: import_oauth213.Oauth2ErrorCodes.InvalidRequest,
891
- error_description: 'Using client identifier scheme "verifier_attestation" requires a signed JAR request.'
892
- });
893
- }
894
- }
895
916
  return {
896
- scheme,
897
- identifier: identifierPart,
898
- originalValue: clientId
917
+ type: "openid4vp",
918
+ provided,
919
+ params: parsedRequest
899
920
  };
900
921
  }
901
922
 
923
+ // src/authorization-request/resolve-authorization-request.ts
924
+ var import_oauth219 = require("@openid4vc/oauth2");
925
+ var import_utils13 = require("@openid4vc/utils");
926
+ var import_zod14 = __toESM(require("zod"));
927
+
902
928
  // src/fetch-client-metadata.ts
903
929
  var import_oauth214 = require("@openid4vc/oauth2");
904
- var import_utils11 = require("@openid4vc/utils");
930
+ var import_utils10 = require("@openid4vc/utils");
905
931
  async function fetchClientMetadata(options) {
906
932
  const { fetch, clientMetadataUri } = options;
907
- const fetcher = (0, import_utils11.createZodFetcher)(fetch);
908
- const { result, response } = await fetcher(zClientMetadata, import_utils11.ContentType.Json, clientMetadataUri, {
933
+ const fetcher = (0, import_utils10.createZodFetcher)(fetch);
934
+ const { result, response } = await fetcher(zClientMetadata, import_utils10.ContentType.Json, clientMetadataUri, {
909
935
  method: "GET",
910
936
  headers: {
911
- Accept: import_utils11.ContentType.Json
937
+ Accept: import_utils10.ContentType.Json
912
938
  }
913
939
  });
914
940
  if (!response.ok) {
@@ -931,23 +957,23 @@ var import_oauth217 = require("@openid4vc/oauth2");
931
957
 
932
958
  // src/jar/jar-request-object/fetch-jar-request-object.ts
933
959
  var import_oauth215 = require("@openid4vc/oauth2");
934
- var import_utils12 = require("@openid4vc/utils");
960
+ var import_utils11 = require("@openid4vc/utils");
935
961
  var import_zod11 = require("zod");
936
962
  async function fetchJarRequestObject(options) {
937
963
  const { requestUri, clientIdentifierScheme, method, wallet, fetch } = options;
938
- const fetcher = (0, import_utils12.createZodFetcher)(fetch);
964
+ const fetcher = (0, import_utils11.createZodFetcher)(fetch);
939
965
  let requestBody = wallet.metadata ? { wallet_metadata: wallet.metadata, wallet_nonce: wallet.nonce } : void 0;
940
966
  if (requestBody?.wallet_metadata?.request_object_signing_alg_values_supported && clientIdentifierScheme === "redirect_uri") {
941
967
  const { request_object_signing_alg_values_supported, ...rest } = requestBody.wallet_metadata;
942
968
  requestBody = { ...requestBody, wallet_metadata: { ...rest } };
943
969
  }
944
- const { result, response } = await fetcher(import_zod11.z.string(), import_utils12.ContentType.OAuthAuthorizationRequestJwt, requestUri, {
970
+ const { result, response } = await fetcher(import_zod11.z.string(), import_utils11.ContentType.OAuthAuthorizationRequestJwt, requestUri, {
945
971
  method,
946
972
  headers: {
947
- Accept: `${import_utils12.ContentType.OAuthAuthorizationRequestJwt}, ${import_utils12.ContentType.Jwt};q=0.9`,
948
- "Content-Type": import_utils12.ContentType.XWwwFormUrlencoded
973
+ Accept: `${import_utils11.ContentType.OAuthAuthorizationRequestJwt}, ${import_utils11.ContentType.Jwt};q=0.9`,
974
+ "Content-Type": import_utils11.ContentType.XWwwFormUrlencoded
949
975
  },
950
- body: method === "POST" ? (0, import_utils12.objectToQueryParams)(wallet.metadata ?? {}) : void 0
976
+ body: method === "POST" ? (0, import_utils11.objectToQueryParams)(wallet.metadata ?? {}) : void 0
951
977
  });
952
978
  if (!response.ok) {
953
979
  throw new import_oauth215.Oauth2ServerErrorResponseError({
@@ -1064,7 +1090,7 @@ async function verifyJarRequestObject(options) {
1064
1090
 
1065
1091
  // src/transaction-data/parse-transaction-data.ts
1066
1092
  var import_oauth218 = require("@openid4vc/oauth2");
1067
- var import_utils13 = require("@openid4vc/utils");
1093
+ var import_utils12 = require("@openid4vc/utils");
1068
1094
 
1069
1095
  // src/transaction-data/z-transaction-data.ts
1070
1096
  var import_zod13 = require("zod");
@@ -1078,7 +1104,7 @@ var zTransactionData = import_zod13.z.array(zTransactionEntry);
1078
1104
  // src/transaction-data/parse-transaction-data.ts
1079
1105
  function parseTransactionData(options) {
1080
1106
  const { transactionData } = options;
1081
- const decoded = transactionData.map((tdEntry) => (0, import_utils13.parseIfJson)((0, import_utils13.encodeToUtf8String)((0, import_utils13.decodeBase64)(tdEntry))));
1107
+ const decoded = transactionData.map((tdEntry) => (0, import_utils12.parseIfJson)((0, import_utils12.encodeToUtf8String)((0, import_utils12.decodeBase64)(tdEntry))));
1082
1108
  const parsedResult = zTransactionData.safeParse(decoded);
1083
1109
  if (!parsedResult.success) {
1084
1110
  throw new import_oauth218.Oauth2ServerErrorResponseError({
@@ -1097,7 +1123,7 @@ function parseTransactionData(options) {
1097
1123
  async function resolveOpenid4vpAuthorizationRequest(options) {
1098
1124
  const { wallet, callbacks, origin, disableOriginValidation } = options;
1099
1125
  let authorizationRequestPayload;
1100
- const parsed = (0, import_utils14.parseWithErrorHandling)(
1126
+ const parsed = (0, import_utils13.parseWithErrorHandling)(
1101
1127
  import_zod14.default.union([zOpenid4vpAuthorizationRequestDcApi, zOpenid4vpAuthorizationRequest, zJarAuthorizationRequest]),
1102
1128
  options.authorizationRequestPayload,
1103
1129
  "Invalid authorization request. Could not parse openid4vp authorization request as openid4vp or jar auth request."
@@ -1105,7 +1131,7 @@ async function resolveOpenid4vpAuthorizationRequest(options) {
1105
1131
  let jar;
1106
1132
  if (isJarAuthorizationRequest(parsed)) {
1107
1133
  jar = await verifyJarRequest({ jarRequestParams: parsed, callbacks, wallet });
1108
- const parsedJarAuthorizationRequestPayload = (0, import_utils14.parseWithErrorHandling)(
1134
+ const parsedJarAuthorizationRequestPayload = (0, import_utils13.parseWithErrorHandling)(
1109
1135
  import_zod14.default.union([zOpenid4vpAuthorizationRequestDcApi, zOpenid4vpAuthorizationRequest]),
1110
1136
  jar.authorizationRequestParams,
1111
1137
  "Invalid authorization request. Could not parse jar request payload as openid4vp auth request."
@@ -1186,7 +1212,7 @@ function validateOpenId4vpAuthorizationRequestPayload(options) {
1186
1212
 
1187
1213
  // src/authorization-response/create-authorization-response.ts
1188
1214
  var import_oauth222 = require("@openid4vc/oauth2");
1189
- var import_utils15 = require("@openid4vc/utils");
1215
+ var import_utils14 = require("@openid4vc/utils");
1190
1216
 
1191
1217
  // ../utils/src/date.ts
1192
1218
  function addSecondsToDate(date, seconds) {
@@ -1330,7 +1356,7 @@ async function createOpenid4vpAuthorizationResponse(options) {
1330
1356
  additionalJwtPayload = {
1331
1357
  iss: jarm.authorizationServer,
1332
1358
  aud: jarm.audience,
1333
- exp: jarm.expiresInSeconds ?? (0, import_utils15.dateToSeconds)(addSecondsToDate(/* @__PURE__ */ new Date(), 60 * 10))
1359
+ exp: jarm.expiresInSeconds ?? (0, import_utils14.dateToSeconds)(addSecondsToDate(/* @__PURE__ */ new Date(), 60 * 10))
1334
1360
  // default: 10 minutes
1335
1361
  };
1336
1362
  }
@@ -1362,25 +1388,25 @@ async function createOpenid4vpAuthorizationResponse(options) {
1362
1388
 
1363
1389
  // src/authorization-response/submit-authorization-response.ts
1364
1390
  var import_oauth224 = require("@openid4vc/oauth2");
1391
+ var import_utils16 = require("@openid4vc/utils");
1365
1392
  var import_utils17 = require("@openid4vc/utils");
1366
- var import_utils18 = require("@openid4vc/utils");
1367
1393
 
1368
1394
  // src/jarm/jarm-authorizatino-response-send.ts
1369
1395
  var import_oauth223 = require("@openid4vc/oauth2");
1370
- var import_utils16 = require("@openid4vc/utils");
1396
+ var import_utils15 = require("@openid4vc/utils");
1371
1397
  var jarmAuthorizationResponseSend = (options) => {
1372
1398
  const { authorizationRequestPayload, jarmAuthorizationResponseJwt, callbacks } = options;
1373
1399
  const responseEndpoint = authorizationRequestPayload.response_uri ?? authorizationRequestPayload.redirect_uri;
1374
1400
  if (!responseEndpoint) {
1375
1401
  throw new import_oauth223.Oauth2Error(`Either 'response_uri' or 'redirect_uri' MUST be present in the authorization request`);
1376
1402
  }
1377
- const responseEndpointUrl = new import_utils16.URL(responseEndpoint);
1403
+ const responseEndpointUrl = new import_utils15.URL(responseEndpoint);
1378
1404
  return handleDirectPostJwt(responseEndpointUrl, jarmAuthorizationResponseJwt, callbacks);
1379
1405
  };
1380
1406
  async function handleDirectPostJwt(responseEndpoint, responseJwt, callbacks) {
1381
- const response = await (callbacks.fetch ?? import_utils16.defaultFetcher)(responseEndpoint, {
1407
+ const response = await (callbacks.fetch ?? import_utils15.defaultFetcher)(responseEndpoint, {
1382
1408
  method: "POST",
1383
- headers: { "Content-Type": import_utils16.ContentType.XWwwFormUrlencoded },
1409
+ headers: { "Content-Type": import_utils15.ContentType.XWwwFormUrlencoded },
1384
1410
  body: `response=${responseJwt}`
1385
1411
  });
1386
1412
  return {
@@ -1405,13 +1431,13 @@ async function submitOpenid4vpAuthorizationResponse(options) {
1405
1431
  "Failed to submit OpenId4Vp Authorization Response. No redirect_uri or response_uri provided."
1406
1432
  );
1407
1433
  }
1408
- const fetch = callbacks.fetch ?? import_utils17.defaultFetcher;
1409
- const encodedResponse = (0, import_utils18.objectToQueryParams)(authorizationResponsePayload);
1434
+ const fetch = callbacks.fetch ?? import_utils16.defaultFetcher;
1435
+ const encodedResponse = (0, import_utils17.objectToQueryParams)(authorizationResponsePayload);
1410
1436
  const submissionResponse = await fetch(url, {
1411
1437
  method: "POST",
1412
1438
  body: encodedResponse,
1413
1439
  headers: {
1414
- "Content-Type": import_utils17.ContentType.XWwwFormUrlencoded
1440
+ "Content-Type": import_utils16.ContentType.XWwwFormUrlencoded
1415
1441
  }
1416
1442
  });
1417
1443
  return {
@@ -1424,7 +1450,7 @@ async function submitOpenid4vpAuthorizationResponse(options) {
1424
1450
  var import_oauth225 = require("@openid4vc/oauth2");
1425
1451
 
1426
1452
  // src/vp-token/parse-vp-token.ts
1427
- var import_utils19 = require("@openid4vc/utils");
1453
+ var import_utils18 = require("@openid4vc/utils");
1428
1454
 
1429
1455
  // src/vp-token/z-vp-token.ts
1430
1456
  var import_zod16 = require("zod");
@@ -1444,17 +1470,17 @@ var zVpToken = zVpTokenDcql.or(zVpTokenPex);
1444
1470
 
1445
1471
  // src/vp-token/parse-vp-token.ts
1446
1472
  function parsePexVpToken(vpToken) {
1447
- const parsedVpToken = (0, import_utils19.parseWithErrorHandling)(
1473
+ const parsedVpToken = (0, import_utils18.parseWithErrorHandling)(
1448
1474
  zVpTokenPex,
1449
- (0, import_utils19.parseIfJson)(vpToken),
1475
+ (0, import_utils18.parseIfJson)(vpToken),
1450
1476
  "Could not parse presentation exchange vp_token. Expected a string or an array of strings"
1451
1477
  );
1452
1478
  return Array.isArray(parsedVpToken) ? parsedVpToken : [parsedVpToken];
1453
1479
  }
1454
1480
  function parseDcqlVpToken(vpToken) {
1455
- return (0, import_utils19.parseWithErrorHandling)(
1481
+ return (0, import_utils18.parseWithErrorHandling)(
1456
1482
  zVpTokenDcql,
1457
- (0, import_utils19.parseIfJson)(vpToken),
1483
+ (0, import_utils18.parseIfJson)(vpToken),
1458
1484
  "Could not parse dcql vp_token. Expected an object where the values are encoded presentations"
1459
1485
  );
1460
1486
  }
@@ -1507,7 +1533,7 @@ function validateOpenid4vpAuthorizationResponsePayload(options) {
1507
1533
  var import_oauth227 = require("@openid4vc/oauth2");
1508
1534
 
1509
1535
  // src/authorization-response/parse-authorization-response-payload.ts
1510
- var import_utils20 = require("@openid4vc/utils");
1536
+ var import_utils19 = require("@openid4vc/utils");
1511
1537
 
1512
1538
  // src/authorization-response/z-authorization-response.ts
1513
1539
  var import_zod18 = require("zod");
@@ -1531,7 +1557,7 @@ var zOpenid4vpAuthorizationResponse = import_zod18.z.object({
1531
1557
 
1532
1558
  // src/authorization-response/parse-authorization-response-payload.ts
1533
1559
  function parseOpenid4VpAuthorizationResponsePayload(payload) {
1534
- return (0, import_utils20.parseWithErrorHandling)(
1560
+ return (0, import_utils19.parseWithErrorHandling)(
1535
1561
  zOpenid4vpAuthorizationResponse,
1536
1562
  payload,
1537
1563
  "Failed to parse openid4vp authorization response."
@@ -1540,11 +1566,11 @@ function parseOpenid4VpAuthorizationResponsePayload(payload) {
1540
1566
 
1541
1567
  // src/authorization-response/parse-jarm-authorization-response.ts
1542
1568
  var import_oauth226 = require("@openid4vc/oauth2");
1543
- var import_utils21 = require("@openid4vc/utils");
1569
+ var import_utils20 = require("@openid4vc/utils");
1544
1570
  var import_zod19 = __toESM(require("zod"));
1545
1571
  async function parseJarmAuthorizationResponse(options) {
1546
1572
  const { jarmResponseJwt, callbacks, authorizationRequestPayload, expectedClientId } = options;
1547
- const jarmAuthorizationResponseJwt = (0, import_utils21.parseWithErrorHandling)(
1573
+ const jarmAuthorizationResponseJwt = (0, import_utils20.parseWithErrorHandling)(
1548
1574
  import_zod19.default.union([import_oauth226.zCompactJwt, import_oauth226.zCompactJwe]),
1549
1575
  jarmResponseJwt,
1550
1576
  "Invalid jarm authorization response jwt."
@@ -1582,7 +1608,7 @@ async function parseJarmAuthorizationResponse(options) {
1582
1608
  // src/authorization-response/parse-authorization-response.ts
1583
1609
  async function parseOpenid4vpAuthorizationResponse(options) {
1584
1610
  const { authorizationResponse, callbacks, authorizationRequestPayload, origin } = options;
1585
- const expectedClientId = getClientId({ authorizationRequestPayload, origin });
1611
+ const expectedClientId = getOpenid4vpClientId({ authorizationRequestPayload, origin });
1586
1612
  if (authorizationResponse.response) {
1587
1613
  return parseJarmAuthorizationResponse({
1588
1614
  jarmResponseJwt: authorizationResponse.response,
@@ -1620,8 +1646,8 @@ var Openid4vpClient = class {
1620
1646
  constructor(options) {
1621
1647
  this.options = options;
1622
1648
  }
1623
- parseOpenid4vpAuthorizationRequestPayload(options) {
1624
- return parseOpenid4vpAuthorizationRequestPayload(options);
1649
+ parseOpenid4vpAuthorizationRequest(options) {
1650
+ return parseOpenid4vpAuthorizationRequest(options);
1625
1651
  }
1626
1652
  async resolveOpenId4vpAuthorizationRequest(options) {
1627
1653
  return resolveOpenid4vpAuthorizationRequest({ ...options, callbacks: this.options.callbacks });
@@ -1636,7 +1662,7 @@ var Openid4vpClient = class {
1636
1662
 
1637
1663
  // src/transaction-data/verify-transaction-data.ts
1638
1664
  var import_oauth228 = require("@openid4vc/oauth2");
1639
- var import_utils22 = require("@openid4vc/utils");
1665
+ var import_utils21 = require("@openid4vc/utils");
1640
1666
  async function verifyTransactionData(options) {
1641
1667
  const parsedTransactionData = parseTransactionData({
1642
1668
  transactionData: options.transactionData
@@ -1663,7 +1689,7 @@ async function verifyTransactionDataEntry({
1663
1689
  );
1664
1690
  const hashes = {};
1665
1691
  for (const alg of supportedAlgs) {
1666
- hashes[alg] = (0, import_utils22.encodeToBase64Url)(await callbacks.hash((0, import_utils22.decodeUtf8String)(entry.encoded), alg));
1692
+ hashes[alg] = (0, import_utils21.encodeToBase64Url)(await callbacks.hash((0, import_utils21.decodeUtf8String)(entry.encoded), alg));
1667
1693
  }
1668
1694
  for (const credentialId of entry.transactionData.credential_ids) {
1669
1695
  const transactionDataHashesCredential = credentials[credentialId];
@@ -1708,7 +1734,7 @@ var Openid4vpVerifier = class {
1708
1734
  return createOpenid4vpAuthorizationRequest({ ...options, callbacks: this.options.callbacks });
1709
1735
  }
1710
1736
  parseOpenid4vpAuthorizationRequestPayload(options) {
1711
- return parseOpenid4vpAuthorizationRequestPayload(options);
1737
+ return parseOpenid4vpAuthorizationRequest(options);
1712
1738
  }
1713
1739
  parseOpenid4vpAuthorizationResponse(options) {
1714
1740
  return parseOpenid4vpAuthorizationResponse(options);
@@ -1726,7 +1752,10 @@ var Openid4vpVerifier = class {
1726
1752
  return parseTransactionData(options);
1727
1753
  }
1728
1754
  verifyTransactionData(options) {
1729
- return verifyTransactionData(options);
1755
+ return verifyTransactionData({
1756
+ ...options,
1757
+ callbacks: this.options.callbacks
1758
+ });
1730
1759
  }
1731
1760
  };
1732
1761
 
@@ -1754,11 +1783,12 @@ var zWalletMetadata = import_zod22.z.object({
1754
1783
  Openid4vpVerifier,
1755
1784
  createOpenid4vpAuthorizationRequest,
1756
1785
  createOpenid4vpAuthorizationResponse,
1786
+ getOpenid4vpClientId,
1757
1787
  isJarmResponseMode,
1758
1788
  isOpenid4vpAuthorizationRequestDcApi,
1759
1789
  parseDcqlVpToken,
1760
1790
  parseJarmAuthorizationResponse,
1761
- parseOpenid4vpAuthorizationRequestPayload,
1791
+ parseOpenid4vpAuthorizationRequest,
1762
1792
  parseOpenid4vpAuthorizationResponse,
1763
1793
  parsePexVpToken,
1764
1794
  parseTransactionData,