@openid4vc/openid4vp 0.3.1-alpha-20251124151046 → 0.4.0-alpha-20251127093634

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 DELETED
@@ -1,1761 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
28
- let __openid4vc_oauth2 = require("@openid4vc/oauth2");
29
- let __openid4vc_utils = require("@openid4vc/utils");
30
- let zod = require("zod");
31
- zod = __toESM(zod);
32
-
33
- //#region src/authorization-request/validate-authorization-request.ts
34
- /**
35
- * Validate the OpenId4Vp Authorization Request parameters
36
- */
37
- const validateOpenid4vpAuthorizationRequestPayload = (options) => {
38
- const { params, walletVerificationOptions } = options;
39
- if (!params.redirect_uri && !params.response_uri) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
40
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
41
- error_description: `Missing required 'redirect_uri' or 'response_uri' in openid4vp authorization request.`
42
- });
43
- if (params.response_uri && !["direct_post", "direct_post.jwt"].find((mode) => mode === params.response_mode)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
44
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
45
- error_description: `The 'response_mode' parameter MUST be 'direct_post' or 'direct_post.jwt' when 'response_uri' is provided. Current: ${params.response_mode}`
46
- });
47
- if ([
48
- params.presentation_definition_uri,
49
- params.presentation_definition,
50
- params.dcql_query,
51
- params.scope
52
- ].filter(Boolean).length > 1) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
53
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
54
- 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."
55
- });
56
- if (params.request_uri_method && !params.request_uri) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
57
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
58
- error_description: "The \"request_uri_method\" parameter MUST NOT be present in the authorization request if the \"request_uri\" parameter is not present."
59
- });
60
- if (params.request_uri_method && !["GET", "POST"].includes(params.request_uri_method)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
61
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestUriMethod,
62
- error_description: `The 'request_uri_method' parameter MUST be 'GET' or 'POST'. Current: ${params.request_uri_method}`
63
- });
64
- if (params.trust_chain && !__openid4vc_utils.zHttpsUrl.safeParse(params.client_id).success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
65
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
66
- 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://."
67
- });
68
- if (walletVerificationOptions?.expectedNonce && !params.wallet_nonce) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
69
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
70
- error_description: "The \"wallet_nonce\" parameter MUST be present in the authorization request when the \"expectedNonce\" parameter is provided."
71
- });
72
- if (walletVerificationOptions?.expectedNonce !== params.wallet_nonce) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
73
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
74
- error_description: "The \"wallet_nonce\" parameter MUST match the \"expectedNonce\" parameter when the \"expectedNonce\" parameter is provided."
75
- });
76
- if (params.client_id.startsWith("web-origin:") || params.client_id.startsWith("origin:")) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
77
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
78
- error_description: `The 'client_id' parameter MUST NOT use client identifier scheme '${params.client_id.split(":")[0]}' when not using the dc_api response mode. Current: ${params.client_id}`
79
- });
80
- };
81
-
82
- //#endregion
83
- //#region src/authorization-request/validate-authorization-request-dc-api.ts
84
- /**
85
- * Validate the OpenId4Vp Authorization Request parameters for the dc_api response mode
86
- */
87
- const validateOpenid4vpAuthorizationRequestDcApiPayload = (options) => {
88
- const { params, isJarRequest, disableOriginValidation, origin } = options;
89
- if (isJarRequest && !params.expected_origins) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
90
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
91
- error_description: `The 'expected_origins' parameter MUST be present when using the dc_api response mode in combinaction with jar.`
92
- });
93
- if ([params.presentation_definition, params.dcql_query].filter(Boolean).length !== 1) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
94
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
95
- error_description: "Exactly one of the following parameters MUST be present in the Authorization Request: dcql_query or presentation_definition"
96
- });
97
- if (params.expected_origins && !disableOriginValidation) {
98
- if (!origin) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
99
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
100
- error_description: `Failed to validate the 'origin' of the authorization request. The 'origin' was not provided.`
101
- });
102
- if (params.expected_origins && !params.expected_origins.includes(origin)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
103
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
104
- error_description: `The 'expected_origins' parameter MUST include the origin of the authorization request. Current: ${params.expected_origins.join(", ")}`
105
- });
106
- }
107
- };
108
-
109
- //#endregion
110
- //#region src/jarm/metadata/z-jarm-client-metadata.ts
111
- const zJarmSignOnlyClientMetadata = zod.z.object({
112
- authorization_signed_response_alg: __openid4vc_oauth2.zAlgValueNotNone,
113
- authorization_encrypted_response_alg: zod.z.optional(zod.z.never()),
114
- authorization_encrypted_response_enc: zod.z.optional(zod.z.never())
115
- });
116
- const zJarmEncryptOnlyClientMetadata = zod.z.object({
117
- authorization_signed_response_alg: zod.z.optional(zod.z.never()),
118
- authorization_encrypted_response_alg: zod.z.string(),
119
- authorization_encrypted_response_enc: zod.z.optional(zod.z.string())
120
- });
121
- const zJarmSignEncryptClientMetadata = zod.z.object({
122
- authorization_signed_response_alg: zJarmSignOnlyClientMetadata.shape.authorization_signed_response_alg,
123
- authorization_encrypted_response_alg: zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_alg,
124
- authorization_encrypted_response_enc: zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_enc
125
- });
126
- /**
127
- * Clients may register their public encryption keys using the jwks_uri or jwks metadata parameters.
128
- */
129
- const zJarmClientMetadata = zod.z.object({
130
- authorization_signed_response_alg: zod.z.optional(zJarmSignOnlyClientMetadata.shape.authorization_signed_response_alg),
131
- authorization_encrypted_response_alg: zod.z.optional(zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_alg),
132
- authorization_encrypted_response_enc: zod.z.optional(zJarmEncryptOnlyClientMetadata.shape.authorization_encrypted_response_enc)
133
- });
134
- const zJarmClientMetadataParsed = zJarmClientMetadata.transform((client_metadata) => {
135
- const parsedClientMeta = (0, __openid4vc_utils.parseWithErrorHandling)(zod.z.union([
136
- zJarmEncryptOnlyClientMetadata,
137
- zJarmSignOnlyClientMetadata,
138
- zJarmSignEncryptClientMetadata
139
- ]), client_metadata, "Invalid jarm client metadata.");
140
- const SignEncrypt = zJarmSignEncryptClientMetadata.safeParse(parsedClientMeta);
141
- if (SignEncrypt.success) return {
142
- type: "sign_encrypt",
143
- client_metadata: {
144
- ...SignEncrypt.data,
145
- authorization_encrypted_response_enc: client_metadata.authorization_encrypted_response_enc
146
- }
147
- };
148
- const encryptOnly = zJarmEncryptOnlyClientMetadata.safeParse(parsedClientMeta);
149
- if (encryptOnly.success) return {
150
- type: "encrypt",
151
- client_metadata: {
152
- ...encryptOnly.data,
153
- authorization_encrypted_response_enc: parsedClientMeta.authorization_encrypted_response_enc
154
- }
155
- };
156
- const signOnly = zJarmSignOnlyClientMetadata.safeParse(parsedClientMeta);
157
- if (signOnly.success) return {
158
- type: "sign",
159
- client_metadata: {
160
- ...signOnly.data,
161
- authorization_signed_response_alg: parsedClientMeta.authorization_signed_response_alg
162
- }
163
- };
164
- throw new __openid4vc_oauth2.Oauth2Error("Invalid jarm client metadata. Failed to parse.");
165
- });
166
-
167
- //#endregion
168
- //#region src/models/z-vp-formats-supported.ts
169
- const zVpFormatsSupported = zod.z.object({
170
- "dc+sd-jwt": zod.z.optional(zod.z.object({
171
- "sd-jwt_alg_values": zod.z.optional(zod.z.tuple([zod.z.string()], zod.z.string())),
172
- "kb-jwt_alg_values": zod.z.optional(zod.z.tuple([zod.z.string()], zod.z.string()))
173
- }).loose()),
174
- jwt_vc_json: zod.z.optional(zod.z.object({ alg_values: zod.z.optional(zod.z.tuple([zod.z.string()], zod.z.string())) }).loose()),
175
- ldp_vc: zod.z.optional(zod.z.object({
176
- proof_type_values: zod.z.optional(zod.z.tuple([zod.z.string()], zod.z.string())),
177
- cryptosuite_values: zod.z.optional(zod.z.tuple([zod.z.string()], zod.z.string()))
178
- }).loose()),
179
- mso_mdoc: zod.z.optional(zod.z.object({
180
- issuer_signed_alg_values: zod.z.optional(zod.z.tuple([zod.z.number()], zod.z.number())),
181
- device_signed_alg_values: zod.z.optional(zod.z.tuple([zod.z.number()], zod.z.number())),
182
- issuerauth_alg_values: zod.z.optional(zod.z.tuple([zod.z.number()], zod.z.number())),
183
- deviceauth_alg_values: zod.z.optional(zod.z.tuple([zod.z.number()], zod.z.number()))
184
- }).loose())
185
- }).loose().catchall(zod.z.object({}).loose());
186
- const zLegacyVpFormats = zod.z.record(zod.z.string(), zod.z.object({ alg_values_supported: zod.z.optional(zod.z.array(zod.z.string())) }).loose());
187
-
188
- //#endregion
189
- //#region src/models/z-client-metadata.ts
190
- const zClientMetadata = zod.z.object({
191
- jwks_uri: zod.z.url().optional(),
192
- jwks: zod.z.optional(__openid4vc_oauth2.zJwkSet),
193
- vp_formats: zod.z.optional(zLegacyVpFormats),
194
- vp_formats_supported: zod.z.optional(zVpFormatsSupported),
195
- encrypted_response_enc_values_supported: zod.z.optional(zod.z.array(zod.z.string())),
196
- ...zJarmClientMetadata.shape,
197
- logo_uri: __openid4vc_utils.zHttpsUrl.or(__openid4vc_utils.zDataUrl).optional(),
198
- client_name: zod.z.string().optional()
199
- }).loose();
200
-
201
- //#endregion
202
- //#region src/models/z-verifier-attestations.ts
203
- const zVerifierAttestation = zod.default.object({
204
- format: zod.default.string(),
205
- data: zod.default.record(zod.default.string(), zod.default.unknown()).or(zod.default.string()),
206
- credential_ids: zod.default.array(zod.default.string()).optional()
207
- });
208
- const zVerifierAttestations = zod.default.array(zVerifierAttestation);
209
-
210
- //#endregion
211
- //#region src/authorization-request/z-authorization-request.ts
212
- const zOpenid4vpAuthorizationRequest = zod.z.object({
213
- response_type: zod.z.literal("vp_token"),
214
- client_id: zod.z.string(),
215
- redirect_uri: __openid4vc_utils.zHttpsUrl.optional(),
216
- response_uri: __openid4vc_utils.zHttpsUrl.optional(),
217
- request_uri: __openid4vc_utils.zHttpsUrl.optional(),
218
- request_uri_method: zod.z.optional(zod.z.string()),
219
- response_mode: zod.z.enum(["direct_post", "direct_post.jwt"]).optional(),
220
- nonce: zod.z.string(),
221
- wallet_nonce: zod.z.string().optional(),
222
- scope: zod.z.string().optional(),
223
- presentation_definition: zod.z.record(zod.z.string(), zod.z.any()).or(__openid4vc_utils.zStringToJson).optional(),
224
- presentation_definition_uri: __openid4vc_utils.zHttpsUrl.optional(),
225
- dcql_query: zod.z.record(zod.z.string(), zod.z.any()).or(__openid4vc_utils.zStringToJson).optional(),
226
- client_metadata: zClientMetadata.optional(),
227
- client_metadata_uri: __openid4vc_utils.zHttpsUrl.optional(),
228
- state: zod.z.string().optional(),
229
- transaction_data: zod.z.array(zod.z.base64url()).optional(),
230
- trust_chain: zod.z.tuple([zod.z.string()], zod.z.string()).optional(),
231
- client_id_scheme: zod.z.enum([
232
- "pre-registered",
233
- "redirect_uri",
234
- "entity_id",
235
- "did",
236
- "verifier_attestation",
237
- "x509_san_dns",
238
- "x509_san_uri",
239
- "x509_hash"
240
- ]).optional(),
241
- verifier_attestations: zVerifierAttestations.optional(),
242
- verifier_info: zVerifierAttestations.optional()
243
- }).loose();
244
- const zOpenid4vpAuthorizationRequestFromUriParams = zod.z.url().transform((url) => Object.fromEntries(new __openid4vc_utils.URL(url).searchParams)).pipe(zod.z.object({
245
- presentation_definition: __openid4vc_utils.zStringToJson.optional(),
246
- client_metadata: __openid4vc_utils.zStringToJson.optional(),
247
- dcql_query: __openid4vc_utils.zStringToJson.optional(),
248
- transaction_data: __openid4vc_utils.zStringToJson.optional(),
249
- verifier_attestations: __openid4vc_utils.zStringToJson.optional(),
250
- verifier_info: __openid4vc_utils.zStringToJson.optional()
251
- }).loose());
252
-
253
- //#endregion
254
- //#region src/authorization-request/z-authorization-request-dc-api.ts
255
- const zOpenid4vpResponseModeDcApi = zod.z.enum([
256
- "dc_api",
257
- "dc_api.jwt",
258
- "w3c_dc_api.jwt",
259
- "w3c_dc_api"
260
- ]);
261
- const zOpenid4vpAuthorizationRequestDcApi = zOpenid4vpAuthorizationRequest.pick({
262
- response_type: true,
263
- nonce: true,
264
- presentation_definition: true,
265
- client_metadata: true,
266
- transaction_data: true,
267
- dcql_query: true,
268
- trust_chain: true,
269
- state: true,
270
- verifier_attestations: true,
271
- verifier_info: true
272
- }).extend({
273
- client_id: zod.z.optional(zod.z.string()),
274
- expected_origins: zod.z.array(zod.z.string()).optional(),
275
- response_mode: zOpenid4vpResponseModeDcApi,
276
- client_id_scheme: zod.z.never().optional(),
277
- scope: zod.z.never().optional()
278
- });
279
- function isOpenid4vpResponseModeDcApi(responseMode) {
280
- return responseMode !== void 0 && zOpenid4vpResponseModeDcApi.options.includes(responseMode);
281
- }
282
- function isOpenid4vpAuthorizationRequestDcApi(request) {
283
- return isOpenid4vpResponseModeDcApi(request.response_mode);
284
- }
285
-
286
- //#endregion
287
- //#region src/authorization-request/create-authorization-request.ts
288
- /**
289
- * Creates an OpenID4VP authorization request, optionally with a JWT Secured Authorization Request (JAR)
290
- * If the request is created after receiving wallet metadata via a POST to the request_uri endpoint, the wallet nonce needs to be provided
291
- *
292
- * @param options Configuration options for creating the authorization request
293
- * @param input.scheme Optional URI scheme to use (defaults to 'openid4vp://')
294
- * @param input.authorizationRequestPayload The OpenID4VP authorization request parameters
295
- * @param input.jar Optional JWT Secured Authorization Request (JAR) configuration
296
- * @param input.jar.requestUri The URI where the JAR will be accessible
297
- * @param input.jar.jwtSigner Function to sign the JAR JWT
298
- * @param input.jar.jweEncryptor Optional function to encrypt the JAR JWT
299
- * @param input.jar.additionalJwtPayload Optional additional claims to include in JAR JWT
300
- * @param input.wallet Optional wallet-specific parameters
301
- * @param input.wallet.nonce Optional wallet nonce
302
- * @param input.callbacks Callback functions for JWT operations
303
- * @returns Object containing the authorization request parameters, URI and optional JAR details
304
- */
305
- async function createOpenid4vpAuthorizationRequest(options) {
306
- const { jar, scheme = "openid4vp://", wallet, callbacks } = options;
307
- let additionalJwtPayload;
308
- let authorizationRequestPayload;
309
- if (isOpenid4vpAuthorizationRequestDcApi(options.authorizationRequestPayload)) {
310
- authorizationRequestPayload = (0, __openid4vc_utils.parseWithErrorHandling)(zOpenid4vpAuthorizationRequestDcApi, options.authorizationRequestPayload, "Invalid authorization request. Could not parse openid4vp dc_api authorization request.");
311
- if (jar && !authorizationRequestPayload.expected_origins) throw new __openid4vc_oauth2.Oauth2Error(`The 'expected_origins' parameter MUST be present when using the dc_api response mode in combination with jar.`);
312
- validateOpenid4vpAuthorizationRequestDcApiPayload({
313
- params: authorizationRequestPayload,
314
- isJarRequest: Boolean(jar),
315
- disableOriginValidation: true
316
- });
317
- } else {
318
- authorizationRequestPayload = (0, __openid4vc_utils.parseWithErrorHandling)(zOpenid4vpAuthorizationRequest, options.authorizationRequestPayload, "Invalid authorization request. Could not parse openid4vp authorization request.");
319
- validateOpenid4vpAuthorizationRequestPayload({
320
- params: authorizationRequestPayload,
321
- walletVerificationOptions: wallet
322
- });
323
- }
324
- if (jar) {
325
- if (!jar.additionalJwtPayload?.aud) additionalJwtPayload = {
326
- ...jar.additionalJwtPayload,
327
- aud: jar.requestUri
328
- };
329
- const jarResult = await (0, __openid4vc_oauth2.createJarAuthorizationRequest)({
330
- ...jar,
331
- authorizationRequestPayload,
332
- additionalJwtPayload,
333
- callbacks
334
- });
335
- const url$1 = new __openid4vc_utils.URL(scheme);
336
- url$1.search = `?${new __openid4vc_utils.URLSearchParams([
337
- ...url$1.searchParams.entries(),
338
- ...(0, __openid4vc_utils.objectToQueryParams)(jarResult.jarAuthorizationRequest).entries(),
339
- ...authorizationRequestPayload.client_id_scheme ? [["client_id_scheme", authorizationRequestPayload.client_id_scheme]] : []
340
- ]).toString()}`;
341
- return {
342
- authorizationRequestPayload,
343
- authorizationRequestObject: jarResult.jarAuthorizationRequest,
344
- authorizationRequest: url$1.toString(),
345
- jar: {
346
- ...jar,
347
- ...jarResult
348
- }
349
- };
350
- }
351
- const url = new __openid4vc_utils.URL(scheme);
352
- url.search = `?${new __openid4vc_utils.URLSearchParams([...url.searchParams.entries(), ...(0, __openid4vc_utils.objectToQueryParams)(authorizationRequestPayload).entries()]).toString()}`;
353
- return {
354
- authorizationRequestPayload,
355
- authorizationRequestObject: authorizationRequestPayload,
356
- authorizationRequest: url.toString(),
357
- jar: void 0
358
- };
359
- }
360
-
361
- //#endregion
362
- //#region src/jar/z-jar-authorization-request.ts
363
- const zOpenid4vpJarAuthorizationRequest = __openid4vc_oauth2.zJarAuthorizationRequest.extend({ request_uri_method: zod.z.optional(zod.z.string()) });
364
- function isJarAuthorizationRequest(request) {
365
- return "request" in request || "request_uri" in request;
366
- }
367
-
368
- //#endregion
369
- //#region src/authorization-request/parse-authorization-request-params.ts
370
- function parseOpenid4vpAuthorizationRequest(options) {
371
- const { authorizationRequest } = options;
372
- let provided = "params";
373
- let params;
374
- if (typeof authorizationRequest === "string") if (authorizationRequest.includes(":")) {
375
- params = (0, __openid4vc_utils.parseWithErrorHandling)(zOpenid4vpAuthorizationRequestFromUriParams, authorizationRequest, "Unable to parse openid4vp authorization request uri to a valid object");
376
- provided = "uri";
377
- } else {
378
- params = (0, __openid4vc_oauth2.decodeJwt)({ jwt: authorizationRequest }).payload;
379
- provided = "jwt";
380
- }
381
- else params = authorizationRequest;
382
- const parsedRequest = (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([
383
- zOpenid4vpAuthorizationRequest,
384
- zOpenid4vpJarAuthorizationRequest,
385
- zOpenid4vpAuthorizationRequestDcApi
386
- ]), params);
387
- if (isJarAuthorizationRequest(parsedRequest)) return {
388
- type: "jar",
389
- provided,
390
- params: parsedRequest
391
- };
392
- if (isOpenid4vpAuthorizationRequestDcApi(parsedRequest)) return {
393
- type: "openid4vp_dc_api",
394
- provided,
395
- params: parsedRequest
396
- };
397
- return {
398
- type: "openid4vp",
399
- provided,
400
- params: parsedRequest
401
- };
402
- }
403
-
404
- //#endregion
405
- //#region src/client-identifier-prefix/x509-hash.ts
406
- async function calculateX509HashClientIdPrefixValue({ x509Certificate, hash }) {
407
- return (0, __openid4vc_utils.encodeToBase64Url)(await hash(typeof x509Certificate === "string" ? (0, __openid4vc_utils.decodeBase64)(x509Certificate) : x509Certificate, __openid4vc_oauth2.HashAlgorithm.Sha256));
408
- }
409
-
410
- //#endregion
411
- //#region src/client-identifier-prefix/z-client-id-prefix.ts
412
- const zClientIdPrefix = zod.z.enum([
413
- "pre-registered",
414
- "redirect_uri",
415
- "verifier_attestation",
416
- "https",
417
- "openid_federation",
418
- "did",
419
- "decentralized_identifier",
420
- "x509_san_uri",
421
- "x509_hash",
422
- "x509_san_dns",
423
- "origin",
424
- "web-origin"
425
- ]);
426
- const zUniformClientIdPrefix = zClientIdPrefix.exclude([
427
- "did",
428
- "https",
429
- "web-origin"
430
- ]);
431
- const zClientIdToClientIdPrefixAndIdentifier = zod.z.union([zod.z.string({ message: "client_id MUST be a string" }).includes(":").transform((clientId) => {
432
- const colonIndex = clientId.indexOf(":");
433
- const clientIdPrefix = clientId.slice(0, colonIndex);
434
- const clientIdIdentifier = clientId.slice(colonIndex + 1);
435
- if (clientIdPrefix === "http" && (0, __openid4vc_utils.getGlobalConfig)().allowInsecureUrls) return ["https", clientId];
436
- if (clientIdPrefix === "did" || clientIdPrefix === "http" || clientIdPrefix === "https") return [clientIdPrefix, clientId];
437
- return [clientIdPrefix, clientIdIdentifier];
438
- }).pipe(zod.z.tuple([zClientIdPrefix.exclude(["pre-registered"]), zod.z.string()])), zod.z.string().refine((clientId) => clientId.includes(":") === false).transform((clientId) => ["pre-registered", clientId])], { message: `client_id must either start with a known prefix followed by ':' or contain no ':'. Known prefixes are ${zClientIdPrefix.exclude(["pre-registered"]).options.join(", ")}` });
439
- const zClientIdPrefixToUniform = zClientIdPrefix.transform((prefix) => prefix === "did" ? "decentralized_identifier" : prefix === "https" ? "openid_federation" : prefix === "web-origin" ? "origin" : prefix);
440
- const zLegacyClientIdScheme = zod.z.enum([
441
- "pre-registered",
442
- "redirect_uri",
443
- "entity_id",
444
- "did",
445
- "verifier_attestation",
446
- "x509_san_dns",
447
- "x509_san_uri"
448
- ]);
449
- const zLegacyClientIdSchemeToClientIdPrefix = zLegacyClientIdScheme.optional().default("pre-registered").transform((clientIdScheme) => clientIdScheme === "entity_id" ? "openid_federation" : clientIdScheme === "did" ? "decentralized_identifier" : clientIdScheme);
450
-
451
- //#endregion
452
- //#region src/client-identifier-prefix/parse-client-identifier-prefix.ts
453
- /**
454
- * Get the client id for an authorization request based on the response_mode, client_id, client_id_scheme and origin values.
455
- *
456
- * It will return the client id prefix as used in OpenID4VP v1, and optionally provide the legacyClientId if the
457
- * client id was provided with a client_id_scheme
458
- */
459
- function getOpenid4vpClientId(options) {
460
- const original = { clientId: options.clientId };
461
- const version = options.version ?? 100;
462
- if (isOpenid4vpResponseModeDcApi(options.responseMode)) {
463
- if (!options.clientId) {
464
- if (!options.origin) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
465
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
466
- error_description: "Failed to parse client identifier. 'origin' is required for requests without a client_id and response_mode 'dc_api' and 'dc_api.jwt'"
467
- });
468
- return {
469
- clientIdPrefix: "origin",
470
- effectiveClientIdPrefix: "origin",
471
- clientIdIdentifier: options.origin,
472
- effectiveClientId: version >= 25 ? `origin:${options.origin}` : `web-origin:${options.origin}`,
473
- original
474
- };
475
- }
476
- const parsedClientIdPrefixAndIdentifier$1 = zClientIdToClientIdPrefixAndIdentifier.safeParse(options.clientId);
477
- if (!parsedClientIdPrefixAndIdentifier$1.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
478
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
479
- error_description: `Failed to parse client identifier. Unsupported client_id '${options.clientId}'.`
480
- });
481
- const [clientIdScheme$1, clientIdIdentifier$1] = parsedClientIdPrefixAndIdentifier$1.data;
482
- const uniformClientIdScheme$1 = zClientIdPrefixToUniform.safeParse(clientIdScheme$1);
483
- if (!uniformClientIdScheme$1.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
484
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
485
- error_description: `Failed to parse client identifier. Unsupported client_id '${options.clientId}'.`
486
- });
487
- return {
488
- effectiveClientId: options.clientId,
489
- effectiveClientIdPrefix: clientIdScheme$1,
490
- original,
491
- clientIdPrefix: uniformClientIdScheme$1.data,
492
- clientIdIdentifier: clientIdIdentifier$1
493
- };
494
- }
495
- if (!options.clientId) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
496
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
497
- error_description: `Failed to parse client identifier. Missing required client_id parameter for response_mode '${options.responseMode}'.`
498
- });
499
- if (options.legacyClientIdScheme) {
500
- const parsedClientIdPrefix = zLegacyClientIdSchemeToClientIdPrefix.safeParse(options.legacyClientIdScheme);
501
- if (!parsedClientIdPrefix.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
502
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
503
- error_description: `Failed to parse client identifier. Unsupported client_id_scheme value '${options.legacyClientIdScheme}'.`
504
- });
505
- const clientIdPrefix = parsedClientIdPrefix.data;
506
- return {
507
- effectiveClientId: options.clientId,
508
- clientIdIdentifier: options.clientId,
509
- clientIdPrefix,
510
- effectiveClientIdPrefix: options.legacyClientIdScheme ?? "pre-registered",
511
- original: {
512
- ...original,
513
- clientIdScheme: options.legacyClientIdScheme
514
- }
515
- };
516
- }
517
- const parsedClientIdPrefixAndIdentifier = zClientIdToClientIdPrefixAndIdentifier.safeParse(options.clientId);
518
- if (!parsedClientIdPrefixAndIdentifier.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
519
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
520
- error_description: `Failed to parse client identifier. Unsupported client_id '${options.clientId}'.`
521
- });
522
- const [clientIdScheme, clientIdIdentifier] = parsedClientIdPrefixAndIdentifier.data;
523
- const uniformClientIdScheme = zClientIdPrefixToUniform.safeParse(clientIdScheme);
524
- if (!uniformClientIdScheme.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
525
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
526
- error_description: `Failed to parse client identifier. Unsupported client_id '${options.clientId}'.`
527
- });
528
- return {
529
- effectiveClientId: options.clientId,
530
- clientIdPrefix: uniformClientIdScheme.data,
531
- effectiveClientIdPrefix: clientIdScheme,
532
- clientIdIdentifier,
533
- original
534
- };
535
- }
536
- /**
537
- * Parse and validate a client identifier
538
- */
539
- async function validateOpenid4vpClientId(options, parserConfig) {
540
- const { authorizationRequestPayload, jar, origin } = options;
541
- const parserConfigWithDefaults = { supportedSchemes: parserConfig?.supportedSchemes || Object.values(zClientIdPrefix.options) };
542
- const { clientIdIdentifier, clientIdPrefix, effectiveClientId, original } = getOpenid4vpClientId({
543
- clientId: authorizationRequestPayload.client_id,
544
- legacyClientIdScheme: authorizationRequestPayload.client_id_scheme,
545
- responseMode: authorizationRequestPayload.response_mode,
546
- origin
547
- });
548
- if (clientIdPrefix === "pre-registered") return {
549
- prefix: "pre-registered",
550
- identifier: clientIdIdentifier,
551
- effective: effectiveClientId,
552
- original
553
- };
554
- if (!parserConfigWithDefaults.supportedSchemes.includes(clientIdPrefix)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
555
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
556
- error_description: `Unsupported client identifier prefix. ${clientIdPrefix} is not supported.`
557
- });
558
- if (clientIdPrefix === "openid_federation") {
559
- if (!__openid4vc_utils.zHttpsUrl.safeParse(clientIdIdentifier).success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
560
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
561
- error_description: "Invalid client identifier. Client identifier must start with https://"
562
- }, { internalMessage: `Insecure http:// urls can be enabled by setting the 'allowInsecureUrls' option using setGlobalConfig` });
563
- if (!jar) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
564
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
565
- error_description: "Using client identifier prefix \"https\" requires a signed JAR request."
566
- });
567
- if (jar.signer.method !== "federation") throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
568
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
569
- error_description: "Something went wrong. The JWT signer method is not federation but the client identifier prefix is https."
570
- });
571
- return {
572
- prefix: "openid_federation",
573
- identifier: clientIdIdentifier,
574
- effective: effectiveClientId,
575
- original,
576
- trustChain: authorizationRequestPayload.trust_chain
577
- };
578
- }
579
- if (clientIdPrefix === "redirect_uri") {
580
- if (jar) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
581
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
582
- error_description: "Using client identifier prefix \"redirect_uri\" the request MUST NOT be signed."
583
- });
584
- if (isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
585
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
586
- error_description: `The client identifier prefix 'redirect_uri' is not supported when using the dc_api response mode.`
587
- });
588
- if (authorizationRequestPayload.redirect_uri && authorizationRequestPayload.redirect_uri !== clientIdIdentifier) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
589
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidClient,
590
- error_description: `When the client identifier prefix is 'redirect_uri', the client id identifier MUST match the redirect_uri.`
591
- });
592
- if (authorizationRequestPayload.response_uri && authorizationRequestPayload.response_uri !== clientIdIdentifier) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
593
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidClient,
594
- error_description: `When the client identifier prefix is 'redirect_uri', the client id identifier MUST match the response_uri.`
595
- });
596
- return {
597
- prefix: clientIdPrefix,
598
- identifier: clientIdIdentifier,
599
- effective: effectiveClientId,
600
- original,
601
- clientMetadata: authorizationRequestPayload.client_metadata,
602
- redirectUri: authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri
603
- };
604
- }
605
- if (clientIdPrefix === "decentralized_identifier") {
606
- if (!jar) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
607
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
608
- error_description: "Using client identifier prefix \"did\" requires a signed JAR request."
609
- });
610
- if (jar.signer.method !== "did") throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
611
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
612
- error_description: "Something went wrong. The JWT signer method is not did but the client identifier prefix is did."
613
- });
614
- if (!clientIdIdentifier.startsWith("did:")) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
615
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
616
- error_description: "Invalid client identifier. Client id identifier must start with 'did:'"
617
- });
618
- const [did] = jar.signer.didUrl.split("#");
619
- if (clientIdIdentifier !== did) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
620
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
621
- error_description: `With client identifier prefix '${clientIdPrefix}' the JAR request must be signed by the same DID as the client identifier.`
622
- });
623
- return {
624
- prefix: "decentralized_identifier",
625
- identifier: clientIdIdentifier,
626
- effective: effectiveClientId,
627
- original,
628
- clientMetadata: authorizationRequestPayload.client_metadata,
629
- didUrl: jar.signer.didUrl
630
- };
631
- }
632
- if (clientIdPrefix === "x509_san_dns" || clientIdPrefix === "x509_san_uri" || clientIdPrefix === "x509_hash") {
633
- if (!jar) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
634
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
635
- error_description: `Using client identifier prefix '${clientIdPrefix}' requires a signed JAR request.`
636
- });
637
- if (jar.signer.method !== "x5c") throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
638
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
639
- error_description: `Something went wrong. The JWT signer method is not x5c but the client identifier prefix is '${clientIdPrefix}'`
640
- });
641
- if (!options.callbacks.getX509CertificateMetadata) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({ error: __openid4vc_oauth2.Oauth2ErrorCodes.ServerError }, { internalMessage: `Missing required 'getX509CertificateMetadata' callback for verification of '${clientIdPrefix}' client id prefix` });
642
- if (clientIdPrefix === "x509_san_dns") {
643
- const { sanDnsNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
644
- if (!sanDnsNames.includes(clientIdIdentifier)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
645
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
646
- error_description: `Invalid client identifier. One of the leaf certificates san dns names [${sanDnsNames.join(", ")}] must match the client identifier '${clientIdIdentifier}'. `
647
- });
648
- if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
649
- const uri = authorizationRequestPayload.redirect_uri ?? authorizationRequestPayload.response_uri;
650
- if (!uri || new __openid4vc_utils.URL(uri).hostname !== clientIdIdentifier) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
651
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
652
- 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."
653
- });
654
- }
655
- } else if (clientIdPrefix === "x509_san_uri") {
656
- const { sanUriNames } = options.callbacks.getX509CertificateMetadata(jar.signer.x5c[0]);
657
- if (!sanUriNames.includes(clientIdIdentifier)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
658
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
659
- error_description: `Invalid client identifier. One of the leaf certificates san uri names [${sanUriNames.join(", ")}] must match the client identifier '${clientIdIdentifier}'.`
660
- });
661
- if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
662
- const uri = authorizationRequestPayload.redirect_uri || authorizationRequestPayload.response_uri;
663
- if (!uri || uri !== clientIdIdentifier) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
664
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
665
- error_description: "The redirect_uri value MUST match the Client Identifier without the prefix x509_san_uri"
666
- });
667
- }
668
- } else if (clientIdPrefix === "x509_hash") {
669
- const x509Hash = await calculateX509HashClientIdPrefixValue({
670
- hash: options.callbacks.hash,
671
- x509Certificate: jar.signer.x5c[0]
672
- });
673
- if (x509Hash !== clientIdIdentifier) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
674
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
675
- error_description: `Invalid client identifier. Expected the base64url encoded sha-256 hash of the leaf x5c certificate ('${x509Hash}') to match the client identifier '${clientIdIdentifier}'.`
676
- });
677
- }
678
- return {
679
- prefix: clientIdPrefix,
680
- identifier: clientIdIdentifier,
681
- effective: effectiveClientId,
682
- original,
683
- x5c: jar.signer.x5c,
684
- clientMetadata: authorizationRequestPayload.client_metadata
685
- };
686
- }
687
- if (clientIdPrefix === "origin") return {
688
- prefix: clientIdPrefix,
689
- identifier: clientIdIdentifier,
690
- effective: effectiveClientId,
691
- original,
692
- clientMetadata: authorizationRequestPayload.client_metadata
693
- };
694
- if (clientIdPrefix === "verifier_attestation") {
695
- if (!jar) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
696
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
697
- error_description: "Using client identifier prefix \"verifier_attestation\" requires a signed JAR request."
698
- });
699
- }
700
- return {
701
- prefix: clientIdPrefix,
702
- clientMetadata: authorizationRequestPayload.client_metadata,
703
- identifier: clientIdIdentifier,
704
- effective: effectiveClientId,
705
- original
706
- };
707
- }
708
-
709
- //#endregion
710
- //#region src/fetch-client-metadata.ts
711
- async function fetchClientMetadata(options) {
712
- const { fetch, clientMetadataUri } = options;
713
- const { result, response } = await (0, __openid4vc_utils.createZodFetcher)(fetch)(zClientMetadata, __openid4vc_utils.ContentType.Json, clientMetadataUri, {
714
- method: "GET",
715
- headers: { Accept: __openid4vc_utils.ContentType.Json }
716
- });
717
- if (!response.ok) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
718
- error_description: `Fetching client metadata from '${clientMetadataUri}' failed with status code '${response.status}'.`,
719
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestUri
720
- });
721
- if (!result || !result.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
722
- error_description: `Parsing client metadata from '${clientMetadataUri}' failed.`,
723
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject
724
- });
725
- return result.data;
726
- }
727
-
728
- //#endregion
729
- //#region src/version.ts
730
- function parseAuthorizationRequestVersion(request) {
731
- const requirements = [];
732
- if (request.verifier_info) requirements.push([">=", 100]);
733
- if (request.verifier_attestations) requirements.push(["<", 100]);
734
- if (request.client_metadata?.vp_formats_supported?.mso_mdoc?.deviceauth_alg_values || request.client_metadata?.vp_formats_supported?.mso_mdoc?.deviceauth_alg_values) requirements.push([">=", 28]);
735
- if (request.client_metadata?.vp_formats_supported?.mso_mdoc?.issuer_signed_alg_values || request.client_metadata?.vp_formats_supported?.mso_mdoc?.device_signed_alg_values) requirements.push(["<", 28]);
736
- if (request.client_metadata?.vp_formats_supported) requirements.push([">=", 27]);
737
- if (request.client_metadata?.vp_formats) requirements.push(["<", 27]);
738
- if (request.client_id?.startsWith("openid_federation:") || request.client_id?.startsWith("decentralized_identifier:")) requirements.push([">=", 26]);
739
- if (request.client_id?.startsWith("did:")) requirements.push(["<", 26]);
740
- if (request.presentation_definition || request.presentation_definition_uri) requirements.push(["<", 26]);
741
- if (request.verifier_attestations) requirements.push([">=", 26]);
742
- if (request.client_id?.startsWith("x509_san_uri:")) requirements.push(["<", 25]);
743
- if (request.client_id?.startsWith("x509_hash:")) requirements.push([">=", 25]);
744
- if (request.client_id?.startsWith("web-origin:")) requirements.push(["<", 25]);
745
- if (request.client_id?.startsWith("origin:")) requirements.push([">=", 25]);
746
- if (isOpenid4vpAuthorizationRequestDcApi(request) && (request.response_mode === "w3c_dc_api" || request.response_mode === "w3c_dc_api.jwt")) {
747
- requirements.push(["<", 23]);
748
- requirements.push([">=", 21]);
749
- }
750
- if (isOpenid4vpAuthorizationRequestDcApi(request) && (request.response_mode === "dc_api" || request.response_mode === "dc_api.jwt")) requirements.push([">=", 23]);
751
- if (isOpenid4vpAuthorizationRequestDcApi(request) && (request.transaction_data || request.dcql_query)) requirements.push([">=", 23]);
752
- if (request.transaction_data) requirements.push([">=", 22]);
753
- if (request.client_id_scheme) requirements.push(["<", 22]);
754
- if (request.client_id) {
755
- const colonIndex = request.client_id.indexOf(":");
756
- const schemePart = request.client_id.substring(0, colonIndex);
757
- const parsedScheme = zClientIdPrefix.safeParse(schemePart);
758
- if (parsedScheme.success && parsedScheme.data !== "did" && parsedScheme.data !== "https") requirements.push([">=", 22]);
759
- }
760
- if (!request.client_id) requirements.push([">=", 21]);
761
- if (request.dcql_query) requirements.push([">=", 21]);
762
- if (request.client_metadata_uri) requirements.push(["<", 21]);
763
- if (isOpenid4vpAuthorizationRequestDcApi(request)) requirements.push([">=", 21]);
764
- if (request.request_uri_method || request.wallet_nonce) requirements.push([">=", 21]);
765
- if (request.client_id_scheme === "verifier_attestation") requirements.push([">=", 20]);
766
- if (request.client_id_scheme === "x509_san_dns" || request.client_id_scheme === "x509_san_uri") requirements.push([">=", 19]);
767
- const lessThanVersions = requirements.filter(([operator]) => operator === "<").map(([_, version]) => version);
768
- const greaterThanVersions = requirements.filter(([operator]) => operator === ">=").map(([_, version]) => version);
769
- const highestPossibleVersion = lessThanVersions.length > 0 ? Math.max(Math.min(...lessThanVersions) - 1, 18) : 100;
770
- const lowestRequiredVersion = greaterThanVersions.length > 0 ? Math.max(...greaterThanVersions) : 18;
771
- if (lowestRequiredVersion > highestPossibleVersion) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
772
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
773
- error_description: `Could not infer openid4vp version from the openid4vp request payload. Based on specification requirements, lowest required version is ${lowestRequiredVersion} and highest possible version is ${highestPossibleVersion}`
774
- });
775
- return highestPossibleVersion;
776
- }
777
-
778
- //#endregion
779
- //#region src/jar/jar-request-object/fetch-jar-request-object.ts
780
- /**
781
- * Fetch a request object and parse the response.
782
- * If you want to fetch the request object without providing wallet_metadata or wallet_nonce as defined in jar you can use the `fetchJarRequestObject` function.
783
- *
784
- * Returns validated request object if successful response
785
- * Throws error otherwise
786
- *
787
- * @throws {ValidationError} if successful response but validation of response failed
788
- * @throws {InvalidFetchResponseError} if no successful or 404 response
789
- * @throws {Error} if parsing json from response fails
790
- */
791
- async function fetchJarRequestObject(options) {
792
- const { requestUri, clientIdPrefix, method, wallet, fetch } = options;
793
- let requestBody = wallet.metadata ? {
794
- wallet_metadata: wallet.metadata,
795
- wallet_nonce: wallet.nonce
796
- } : void 0;
797
- if (requestBody?.wallet_metadata?.request_object_signing_alg_values_supported && clientIdPrefix === "redirect_uri") {
798
- const { request_object_signing_alg_values_supported, ...rest } = requestBody.wallet_metadata;
799
- requestBody = {
800
- ...requestBody,
801
- wallet_metadata: { ...rest }
802
- };
803
- }
804
- const response = await (0, __openid4vc_utils.createFetcher)(fetch)(requestUri, {
805
- method,
806
- body: method === "post" ? (0, __openid4vc_utils.objectToQueryParams)(wallet.metadata ?? {}) : void 0,
807
- headers: {
808
- Accept: `${__openid4vc_utils.ContentType.OAuthAuthorizationRequestJwt}, ${__openid4vc_utils.ContentType.Jwt};q=0.9, text/plain`,
809
- "Content-Type": __openid4vc_utils.ContentType.XWwwFormUrlencoded
810
- }
811
- }).catch(() => {
812
- throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
813
- error_description: `Fetching request_object from request_uri '${requestUri}' failed`,
814
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestUri
815
- });
816
- });
817
- if (!response.ok) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
818
- error_description: `Fetching request_object from request_uri '${requestUri}' failed with status code '${response.status}'.`,
819
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestUri
820
- });
821
- return await response.text();
822
- }
823
-
824
- //#endregion
825
- //#region src/jar/handle-jar-request/verify-jar-request.ts
826
- /**
827
- * Verifies a JAR (JWT Secured Authorization Request) request by validating, decrypting, and verifying signatures.
828
- *
829
- * @param options - The input parameters
830
- * @param options.jarRequestParams - The JAR authorization request parameters
831
- * @param options.callbacks - Context containing the relevant Jose crypto operations
832
- * @returns The verified authorization request parameters and metadata
833
- */
834
- async function verifyJarRequest(options) {
835
- const { callbacks, wallet = {} } = options;
836
- const jarRequestParams = {
837
- ...(0, __openid4vc_oauth2.validateJarRequestParams)(options),
838
- ...options.jarRequestParams
839
- };
840
- const sendBy = jarRequestParams.request ? "value" : "reference";
841
- const clientIdPrefix = jarRequestParams.client_id ? zClientIdPrefix.safeParse(jarRequestParams.client_id.split(":")[0]).data : "origin";
842
- const method = jarRequestParams.request_uri_method ?? "get";
843
- if (method !== "get" && method !== "post") throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
844
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestUriMethod,
845
- error_description: `Invalid request_uri_method. Must be 'get' or 'post'.`
846
- });
847
- const requestObject = jarRequestParams.request ?? await fetchJarRequestObject({
848
- requestUri: jarRequestParams.request_uri,
849
- clientIdPrefix,
850
- method,
851
- wallet,
852
- fetch: callbacks.fetch
853
- });
854
- const { decryptionJwk, payload: decryptedRequestObject } = __openid4vc_oauth2.zCompactJwe.safeParse(requestObject).success ? await decryptJarRequest({
855
- jwe: requestObject,
856
- callbacks
857
- }) : {
858
- payload: requestObject,
859
- decryptionJwk: void 0
860
- };
861
- if (!__openid4vc_oauth2.zCompactJwt.safeParse(decryptedRequestObject).success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
862
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject,
863
- error_description: "JAR request object is not a valid JWT."
864
- });
865
- const { authorizationRequestPayload, signer, jwt } = await verifyJarRequestObject({
866
- decryptedRequestObject,
867
- callbacks
868
- });
869
- if (!authorizationRequestPayload.client_id) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
870
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject,
871
- error_description: "Jar Request Object is missing the required \"client_id\" field."
872
- });
873
- if (!isOpenid4vpResponseModeDcApi(authorizationRequestPayload.response_mode) && jarRequestParams.client_id !== authorizationRequestPayload.client_id) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
874
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
875
- error_description: "client_id does not match the request object client_id."
876
- });
877
- if (jarRequestParams.client_id_scheme && jarRequestParams.client_id_scheme !== authorizationRequestPayload.client_id_scheme) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
878
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
879
- error_description: "client_id_scheme does not match the request object client_id_scheme."
880
- });
881
- return {
882
- sendBy,
883
- jwt,
884
- authorizationRequestPayload,
885
- signer,
886
- decryptionJwk
887
- };
888
- }
889
- async function decryptJarRequest(options) {
890
- const { jwe, callbacks } = options;
891
- const { header } = (0, __openid4vc_oauth2.decodeJwt)({ jwt: jwe });
892
- if (!header.kid) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
893
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject,
894
- error_description: "Jar JWE is missing the protected header field \"kid\"."
895
- });
896
- const decryptionResult = await callbacks.decryptJwe(jwe);
897
- if (!decryptionResult.decrypted) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
898
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject,
899
- error_description: "Failed to decrypt jar request object."
900
- });
901
- return decryptionResult;
902
- }
903
- async function verifyJarRequestObject(options) {
904
- const { decryptedRequestObject, callbacks } = options;
905
- const jwt = (0, __openid4vc_oauth2.decodeJwt)({
906
- jwt: decryptedRequestObject,
907
- payloadSchema: __openid4vc_oauth2.zJarRequestObjectPayload
908
- });
909
- let jwtSigner;
910
- const { clientIdPrefix } = getOpenid4vpClientId({
911
- responseMode: jwt.payload.response_mode,
912
- clientId: jwt.payload.client_id,
913
- legacyClientIdScheme: jwt.payload.client_id_scheme
914
- });
915
- const clientIdToSignerMethod = {
916
- decentralized_identifier: ["did"],
917
- "pre-registered": [
918
- "custom",
919
- "did",
920
- "jwk"
921
- ],
922
- origin: [],
923
- redirect_uri: [],
924
- verifier_attestation: [
925
- "did",
926
- "federation",
927
- "jwk",
928
- "x5c",
929
- "custom"
930
- ],
931
- x509_san_dns: ["x5c"],
932
- x509_san_uri: ["x5c"],
933
- x509_hash: ["x5c"],
934
- openid_federation: []
935
- };
936
- if (clientIdPrefix === "openid_federation") {
937
- if (!jwt.header.kid) throw new __openid4vc_oauth2.Oauth2Error(`When OpenID Federation is used for signed authorization request, the 'kid' parameter is required.`);
938
- jwtSigner = {
939
- method: "federation",
940
- alg: jwt.header.alg,
941
- trustChain: jwt.payload.trust_chain,
942
- kid: jwt.header.kid
943
- };
944
- } else jwtSigner = (0, __openid4vc_oauth2.jwtSignerFromJwt)({
945
- ...jwt,
946
- allowedSignerMethods: clientIdToSignerMethod[clientIdPrefix]
947
- });
948
- const { signer } = await (0, __openid4vc_oauth2.verifyJwt)({
949
- verifyJwtCallback: callbacks.verifyJwt,
950
- compact: decryptedRequestObject,
951
- header: jwt.header,
952
- payload: jwt.payload,
953
- signer: jwtSigner
954
- });
955
- const version = parseAuthorizationRequestVersion(jwt.payload);
956
- if (jwt.header.typ !== __openid4vc_oauth2.signedAuthorizationRequestJwtHeaderTyp && version >= 24) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
957
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequestObject,
958
- error_description: `Invalid Jar Request Object typ header. Expected "oauth-authz-req+jwt", received "${jwt.header.typ}".`
959
- });
960
- return {
961
- signer,
962
- jwt,
963
- authorizationRequestPayload: jwt.payload
964
- };
965
- }
966
-
967
- //#endregion
968
- //#region src/transaction-data/z-transaction-data.ts
969
- const zTransactionEntry = zod.z.object({
970
- type: zod.z.string(),
971
- credential_ids: zod.z.tuple([zod.z.string()], zod.z.string()),
972
- transaction_data_hashes_alg: zod.z.tuple([zod.z.string()], zod.z.string()).optional()
973
- }).loose();
974
- const zTransactionData = zod.z.array(zTransactionEntry);
975
-
976
- //#endregion
977
- //#region src/transaction-data/parse-transaction-data.ts
978
- function parseTransactionData(options) {
979
- const { transactionData } = options;
980
- const decoded = transactionData.map((tdEntry) => (0, __openid4vc_utils.parseIfJson)((0, __openid4vc_utils.encodeToUtf8String)((0, __openid4vc_utils.decodeBase64)(tdEntry))));
981
- const parsedResult = zTransactionData.safeParse(decoded);
982
- if (!parsedResult.success) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
983
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidTransactionData,
984
- error_description: "Failed to parse transaction data."
985
- });
986
- return parsedResult.data.map((decoded$1, index) => ({
987
- transactionData: decoded$1,
988
- encoded: transactionData[index],
989
- transactionDataIndex: index
990
- }));
991
- }
992
-
993
- //#endregion
994
- //#region src/authorization-request/resolve-authorization-request.ts
995
- async function resolveOpenid4vpAuthorizationRequest(options) {
996
- const { wallet, callbacks, origin, disableOriginValidation } = options;
997
- let authorizationRequestPayload;
998
- const parsed = (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([
999
- zOpenid4vpAuthorizationRequestDcApi,
1000
- zOpenid4vpAuthorizationRequest,
1001
- zOpenid4vpJarAuthorizationRequest
1002
- ]), options.authorizationRequestPayload, "Invalid authorization request. Could not parse openid4vp authorization request as openid4vp or jar auth request.");
1003
- let jar;
1004
- if (isJarAuthorizationRequest(parsed)) {
1005
- jar = await verifyJarRequest({
1006
- jarRequestParams: parsed,
1007
- callbacks,
1008
- wallet
1009
- });
1010
- authorizationRequestPayload = validateOpenId4vpAuthorizationRequestPayload({
1011
- authorizationRequestPayload: (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([zOpenid4vpAuthorizationRequestDcApi, zOpenid4vpAuthorizationRequest]), jar.authorizationRequestPayload, "Invalid authorization request. Could not parse jar request payload as openid4vp auth request."),
1012
- wallet,
1013
- jar: true,
1014
- origin,
1015
- disableOriginValidation
1016
- });
1017
- } else authorizationRequestPayload = validateOpenId4vpAuthorizationRequestPayload({
1018
- authorizationRequestPayload: parsed,
1019
- wallet,
1020
- jar: false,
1021
- origin,
1022
- disableOriginValidation
1023
- });
1024
- const version = parseAuthorizationRequestVersion(authorizationRequestPayload);
1025
- let clientMetadata = authorizationRequestPayload.client_metadata;
1026
- if (!isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload) && !clientMetadata && authorizationRequestPayload.client_metadata_uri) clientMetadata = await fetchClientMetadata({ clientMetadataUri: authorizationRequestPayload.client_metadata_uri });
1027
- const clientMeta = await validateOpenid4vpClientId({
1028
- authorizationRequestPayload: {
1029
- ...authorizationRequestPayload,
1030
- client_metadata: clientMetadata
1031
- },
1032
- jar,
1033
- callbacks,
1034
- origin,
1035
- version
1036
- });
1037
- let pex;
1038
- let dcql;
1039
- if (authorizationRequestPayload.presentation_definition || authorizationRequestPayload.presentation_definition_uri) {
1040
- if (authorizationRequestPayload.presentation_definition_uri) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1041
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
1042
- error_description: "Cannot fetch presentation definition from URI. Not supported."
1043
- });
1044
- pex = {
1045
- presentation_definition: authorizationRequestPayload.presentation_definition,
1046
- presentation_definition_uri: authorizationRequestPayload.presentation_definition_uri
1047
- };
1048
- }
1049
- if (authorizationRequestPayload.dcql_query) dcql = { query: authorizationRequestPayload.dcql_query };
1050
- return {
1051
- transactionData: authorizationRequestPayload.transaction_data ? parseTransactionData({ transactionData: authorizationRequestPayload.transaction_data }) : void 0,
1052
- authorizationRequestPayload,
1053
- jar,
1054
- client: clientMeta,
1055
- pex,
1056
- dcql,
1057
- version
1058
- };
1059
- }
1060
- function validateOpenId4vpAuthorizationRequestPayload(options) {
1061
- const { authorizationRequestPayload, wallet, jar, origin, disableOriginValidation } = options;
1062
- if (isOpenid4vpAuthorizationRequestDcApi(authorizationRequestPayload)) {
1063
- validateOpenid4vpAuthorizationRequestDcApiPayload({
1064
- params: authorizationRequestPayload,
1065
- isJarRequest: jar,
1066
- disableOriginValidation,
1067
- origin
1068
- });
1069
- return authorizationRequestPayload;
1070
- }
1071
- validateOpenid4vpAuthorizationRequestPayload({
1072
- params: authorizationRequestPayload,
1073
- walletVerificationOptions: wallet
1074
- });
1075
- return authorizationRequestPayload;
1076
- }
1077
-
1078
- //#endregion
1079
- //#region ../utils/src/date.ts
1080
- function addSecondsToDate(date, seconds) {
1081
- return new Date(date.getTime() + seconds * 1e3);
1082
- }
1083
-
1084
- //#endregion
1085
- //#region src/jarm/jarm-authorization-response-create.ts
1086
- async function createJarmAuthorizationResponse(options) {
1087
- const { jarmAuthorizationResponse, jweEncryptor, jwtSigner, callbacks } = options;
1088
- if (!jwtSigner && jweEncryptor) {
1089
- const { jwe } = await callbacks.encryptJwe(jweEncryptor, JSON.stringify(jarmAuthorizationResponse));
1090
- return { jarmAuthorizationResponseJwt: jwe };
1091
- }
1092
- if (jwtSigner && !jweEncryptor) return { jarmAuthorizationResponseJwt: (await callbacks.signJwt(jwtSigner, {
1093
- header: (0, __openid4vc_oauth2.jwtHeaderFromJwtSigner)(jwtSigner),
1094
- payload: jarmAuthorizationResponse
1095
- })).jwt };
1096
- if (!jwtSigner || !jweEncryptor) throw new __openid4vc_oauth2.Oauth2Error("JWT signer and/or encryptor are required to create a JARM auth response.");
1097
- const signed = await callbacks.signJwt(jwtSigner, {
1098
- header: (0, __openid4vc_oauth2.jwtHeaderFromJwtSigner)(jwtSigner),
1099
- payload: jarmAuthorizationResponse
1100
- });
1101
- return { jarmAuthorizationResponseJwt: (await callbacks.encryptJwe(jweEncryptor, signed.jwt)).jwe };
1102
- }
1103
-
1104
- //#endregion
1105
- //#region src/jarm/jarm-extract-jwks.ts
1106
- function extractEncryptionJwkFromJwks(jwks, { kid, supportedAlgValues }) {
1107
- if (kid) return jwks.keys.find((jwk) => jwk.kid === kid);
1108
- let algFiltered = jwks.keys.filter((key) => key.alg && supportedAlgValues?.includes(key.alg));
1109
- if (algFiltered.length === 0) algFiltered = jwks.keys;
1110
- let encFiltered = algFiltered.filter((key) => key.use === "enc");
1111
- if (!encFiltered) encFiltered = algFiltered.filter((key) => key.use !== "sig");
1112
- return encFiltered.length > 0 ? encFiltered[0] : jwks.keys[0];
1113
- }
1114
-
1115
- //#endregion
1116
- //#region src/jarm/jarm-response-mode.ts
1117
- const jarmResponseMode = [
1118
- "jwt",
1119
- "query.jwt",
1120
- "fragment.jwt",
1121
- "form_post.jwt",
1122
- "direct_post.jwt",
1123
- "dc_api.jwt"
1124
- ];
1125
- const zJarmResponseMode = zod.z.enum(jarmResponseMode);
1126
- const isJarmResponseMode = (responseMode) => {
1127
- return jarmResponseMode.includes(responseMode);
1128
- };
1129
-
1130
- //#endregion
1131
- //#region src/jarm/metadata/jarm-assert-metadata-supported.ts
1132
- function assertValueSupported(options) {
1133
- const { errorMessage, supported, actual } = options;
1134
- const intersection = supported.find((value) => value === actual);
1135
- if (!intersection) throw new __openid4vc_oauth2.Oauth2Error(errorMessage);
1136
- return intersection;
1137
- }
1138
- function jarmAssertMetadataSupported(options) {
1139
- const { clientMetadata, serverMetadata } = options;
1140
- const parsedClientMetadata = zJarmClientMetadataParsed.parse(clientMetadata);
1141
- if (parsedClientMetadata.type === "sign_encrypt" || parsedClientMetadata.type === "encrypt") {
1142
- if (serverMetadata.authorization_encryption_alg_values_supported) assertValueSupported({
1143
- supported: serverMetadata.authorization_encryption_alg_values_supported,
1144
- actual: parsedClientMetadata.client_metadata.authorization_encrypted_response_alg,
1145
- errorMessage: "Invalid authorization_encryption_alg"
1146
- });
1147
- if (serverMetadata.authorization_encryption_enc_values_supported) assertValueSupported({
1148
- supported: serverMetadata.authorization_encryption_enc_values_supported,
1149
- actual: parsedClientMetadata.client_metadata.authorization_encrypted_response_enc,
1150
- errorMessage: "Invalid authorization_encryption_enc"
1151
- });
1152
- }
1153
- if (serverMetadata.authorization_signing_alg_values_supported && (parsedClientMetadata.type === "sign" || parsedClientMetadata.type === "sign_encrypt")) assertValueSupported({
1154
- supported: serverMetadata.authorization_signing_alg_values_supported,
1155
- actual: parsedClientMetadata.client_metadata.authorization_signed_response_alg,
1156
- errorMessage: "Invalid authorization_signed_response_alg"
1157
- });
1158
- return parsedClientMetadata;
1159
- }
1160
-
1161
- //#endregion
1162
- //#region src/authorization-response/create-authorization-response.ts
1163
- async function createOpenid4vpAuthorizationResponse(options) {
1164
- const { authorizationRequestPayload, jarm, callbacks, origin } = options;
1165
- const authorizationResponsePayload = {
1166
- ...options.authorizationResponsePayload,
1167
- state: authorizationRequestPayload.state
1168
- };
1169
- const { clientIdPrefix } = getOpenid4vpClientId({
1170
- responseMode: authorizationRequestPayload.response_mode,
1171
- clientId: authorizationRequestPayload.client_id,
1172
- legacyClientIdScheme: authorizationRequestPayload.client_id_scheme,
1173
- origin
1174
- });
1175
- if (authorizationRequestPayload.response_mode && isJarmResponseMode(authorizationRequestPayload.response_mode) && !jarm) throw new __openid4vc_oauth2.Oauth2Error(`Missing jarm options for creating Jarm response with response mode '${authorizationRequestPayload.response_mode}'`);
1176
- if (!jarm) return { authorizationResponsePayload };
1177
- if (clientIdPrefix === "openid_federation" && !options.clientMetadata) throw new __openid4vc_oauth2.Oauth2Error("When OpenID Federation is used as the client id prefix (https/openid_federation), passing externally fetched and verified 'clientMetadata' to the 'createOpenid4vpAuthorizationResponse' is required.");
1178
- const clientMetadata = options.clientMetadata ?? authorizationRequestPayload.client_metadata;
1179
- if (!clientMetadata) throw new __openid4vc_oauth2.Oauth2Error("Missing client metadata in the request params to assert Jarm metadata support.");
1180
- let jwks;
1181
- if (clientMetadata.jwks) jwks = clientMetadata.jwks;
1182
- else if (clientMetadata.jwks_uri) jwks = await (0, __openid4vc_oauth2.fetchJwks)(clientMetadata.jwks_uri, options.callbacks.fetch);
1183
- else throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1184
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
1185
- error_description: `Missing 'jwks' or 'jwks_uri' in client metadata. Cannot extract encryption JWK.`
1186
- });
1187
- if (clientMetadata.authorization_encrypted_response_alg || clientMetadata.authorization_encrypted_response_enc || clientMetadata.authorization_signed_response_alg) jarmAssertMetadataSupported({
1188
- clientMetadata,
1189
- serverMetadata: jarm.serverMetadata
1190
- });
1191
- const encJwk = jarm?.encryption?.jwk ?? extractEncryptionJwkFromJwks(jwks, { supportedAlgValues: jarm.serverMetadata.authorization_encryption_alg_values_supported ?? (clientMetadata.authorization_encrypted_response_alg ? [clientMetadata.authorization_encrypted_response_alg] : void 0) });
1192
- if (!encJwk) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1193
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
1194
- error_description: "No encryption JWK provided and could not extract encryption JWK from client metadata. Failed to create JARM response."
1195
- });
1196
- let enc;
1197
- if (clientMetadata.encrypted_response_enc_values_supported) enc = jarm.serverMetadata.authorization_encryption_enc_values_supported.find((enc$1) => clientMetadata.encrypted_response_enc_values_supported?.includes(enc$1)) ?? clientMetadata.encrypted_response_enc_values_supported[0];
1198
- else enc = clientMetadata.authorization_encrypted_response_enc ?? "A128GCM";
1199
- assertValueSupported({
1200
- actual: enc,
1201
- supported: jarm.serverMetadata.authorization_encryption_enc_values_supported,
1202
- errorMessage: `Invalid 'enc' value ${enc}. Supported values are ${jarm.serverMetadata.authorization_encryption_enc_values_supported.join(", ")}`
1203
- });
1204
- const alg = encJwk.alg ?? clientMetadata.authorization_encrypted_response_alg ?? "ECDH-ES";
1205
- assertValueSupported({
1206
- actual: alg,
1207
- supported: jarm.serverMetadata.authorization_encryption_alg_values_supported,
1208
- errorMessage: `Invalid 'alg' value ${alg}. Supported values are ${jarm.serverMetadata.authorization_encryption_alg_values_supported.join(", ")}`
1209
- });
1210
- let additionalJwtPayload;
1211
- if (jarm?.jwtSigner) {
1212
- if (!jarm.authorizationServer) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1213
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
1214
- error_description: "Missing required iss in JARM configuration for creating OpenID4VP authorization response."
1215
- });
1216
- if (!jarm.audience) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1217
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidRequest,
1218
- error_description: "Missing required aud in JARM configuration for creating OpenID4VP authorization response."
1219
- });
1220
- additionalJwtPayload = {
1221
- iss: jarm.authorizationServer,
1222
- aud: jarm.audience,
1223
- exp: jarm.expiresInSeconds ?? (0, __openid4vc_utils.dateToSeconds)(addSecondsToDate(/* @__PURE__ */ new Date(), 600))
1224
- };
1225
- }
1226
- const jarmResponsePayload = {
1227
- ...authorizationResponsePayload,
1228
- ...additionalJwtPayload
1229
- };
1230
- return {
1231
- authorizationResponsePayload: jarmResponsePayload,
1232
- jarm: {
1233
- responseJwt: (await createJarmAuthorizationResponse({
1234
- jarmAuthorizationResponse: jarmResponsePayload,
1235
- jwtSigner: jarm?.jwtSigner,
1236
- jweEncryptor: jarm?.encryption ? {
1237
- method: "jwk",
1238
- publicJwk: encJwk,
1239
- apu: jarm.encryption.nonce ? (0, __openid4vc_utils.encodeToBase64Url)(jarm.encryption.nonce) : void 0,
1240
- apv: (0, __openid4vc_utils.encodeToBase64Url)(authorizationRequestPayload.nonce),
1241
- alg,
1242
- enc
1243
- } : void 0,
1244
- callbacks: {
1245
- signJwt: callbacks.signJwt,
1246
- encryptJwe: callbacks.encryptJwe
1247
- }
1248
- })).jarmAuthorizationResponseJwt,
1249
- encryptionJwk: encJwk
1250
- }
1251
- };
1252
- }
1253
-
1254
- //#endregion
1255
- //#region src/models/z-pex.ts
1256
- const zPexPresentationDefinition = zod.z.record(zod.z.string(), zod.z.any());
1257
- const zPexPresentationSubmission = zod.z.record(zod.z.string(), zod.z.any());
1258
-
1259
- //#endregion
1260
- //#region src/vp-token/z-vp-token.ts
1261
- const zVpTokenPresentationEntry = zod.z.union([zod.z.string(), zod.z.record(zod.z.string(), zod.z.any())], { message: "vp_token presentation entry must be string or object" });
1262
- const zVpTokenPex = zod.z.union([zVpTokenPresentationEntry, zod.z.tuple([zVpTokenPresentationEntry], zVpTokenPresentationEntry, "Must have at least entry in vp_token array")], { message: "pex vp_token must be a string, object or non-empty array of strings and objects" });
1263
- const zVpTokenDcql = zod.z.record(zod.z.string(), zod.z.union([zod.z.tuple([zVpTokenPresentationEntry], zVpTokenPresentationEntry), zVpTokenPresentationEntry]), { message: "dcql vp_token must be an object with keys referencing the dcql credential query id, and values a non-empty array of strings and objects, or string, or object" });
1264
- const zVpToken = zVpTokenDcql.or(zVpTokenPex);
1265
-
1266
- //#endregion
1267
- //#region src/authorization-response/z-authorization-response.ts
1268
- const zOpenid4vpAuthorizationResponse = zod.z.object({
1269
- state: zod.z.string().optional(),
1270
- id_token: zod.z.string().optional(),
1271
- vp_token: zVpToken,
1272
- presentation_submission: zPexPresentationSubmission.or(__openid4vc_utils.zStringToJson).optional(),
1273
- refresh_token: zod.z.string().optional(),
1274
- token_type: zod.z.string().optional(),
1275
- access_token: zod.z.string().optional(),
1276
- expires_in: zod.z.coerce.number().optional()
1277
- }).loose();
1278
-
1279
- //#endregion
1280
- //#region src/authorization-response/parse-authorization-response-payload.ts
1281
- function parseOpenid4VpAuthorizationResponsePayload(payload) {
1282
- return (0, __openid4vc_utils.parseWithErrorHandling)(zOpenid4vpAuthorizationResponse, payload, "Failed to parse openid4vp authorization response.");
1283
- }
1284
-
1285
- //#endregion
1286
- //#region src/jarm/jarm-authorization-response/z-jarm-authorization-response.ts
1287
- const zJarmHeader = zod.z.object({
1288
- ...__openid4vc_oauth2.zJwtHeader.shape,
1289
- apu: zod.z.string().optional(),
1290
- apv: zod.z.string().optional()
1291
- });
1292
- const zJarmAuthorizationResponse = zod.z.object({
1293
- ...__openid4vc_oauth2.zJwtPayload.shape,
1294
- ...__openid4vc_oauth2.zJwtPayload.pick({
1295
- iss: true,
1296
- aud: true,
1297
- exp: true
1298
- }).required().shape,
1299
- state: zod.z.optional(zod.z.string())
1300
- }).loose();
1301
- const zJarmAuthorizationResponseEncryptedOnly = zod.z.object({
1302
- ...__openid4vc_oauth2.zJwtPayload.shape,
1303
- state: zod.z.optional(zod.z.string())
1304
- }).loose();
1305
-
1306
- //#endregion
1307
- //#region src/jarm/jarm-authorization-response/jarm-validate-authorization-response.ts
1308
- const jarmAuthorizationResponseValidate = (options) => {
1309
- const { expectedClientId, authorizationResponse } = options;
1310
- if (!zJarmAuthorizationResponse.safeParse(authorizationResponse).success) return;
1311
- if (Array.isArray(authorizationResponse.aud) && !authorizationResponse.aud.includes(expectedClientId) || typeof authorizationResponse.aud === "string" && authorizationResponse.aud !== expectedClientId) throw new __openid4vc_oauth2.Oauth2Error(`Invalid 'aud' claim in JARM authorization response. Expected '${expectedClientId}' received '${JSON.stringify(authorizationResponse.aud)}'.`);
1312
- if (authorizationResponse.exp !== void 0 && authorizationResponse.exp < (0, __openid4vc_utils.dateToSeconds)()) throw new __openid4vc_oauth2.Oauth2Error("JARM auth response is expired.");
1313
- };
1314
-
1315
- //#endregion
1316
- //#region src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts
1317
- let JarmMode = /* @__PURE__ */ function(JarmMode$1) {
1318
- JarmMode$1["Signed"] = "Signed";
1319
- JarmMode$1["Encrypted"] = "Encrypted";
1320
- JarmMode$1["SignedEncrypted"] = "SignedEncrypted";
1321
- return JarmMode$1;
1322
- }({});
1323
- /**
1324
- * The client decrypts the JWT using the default key for the respective issuer or,
1325
- * if applicable, determined by the kid JWT header parameter.
1326
- * The key might be a private key, where the corresponding public key is registered
1327
- * with the expected issuer of the response ("use":"enc" via the client's metadata jwks or jwks_uri)
1328
- * or a key derived from its client secret (see Section 2.2).
1329
- */
1330
- const decryptJarmAuthorizationResponseJwt = async (options) => {
1331
- const { jarmAuthorizationResponseJwt, callbacks, authorizationRequestPayload } = options;
1332
- let encryptionJwk;
1333
- const { header } = (0, __openid4vc_oauth2.decodeJwtHeader)({ jwt: jarmAuthorizationResponseJwt });
1334
- if (authorizationRequestPayload.client_metadata?.jwks) encryptionJwk = extractEncryptionJwkFromJwks(authorizationRequestPayload.client_metadata.jwks, {
1335
- kid: header.kid,
1336
- supportedAlgValues: authorizationRequestPayload.client_metadata.authorization_encrypted_response_alg ? [authorizationRequestPayload.client_metadata.authorization_encrypted_response_alg] : void 0
1337
- });
1338
- const result = await callbacks.decryptJwe(jarmAuthorizationResponseJwt, { jwk: encryptionJwk });
1339
- if (!result.decrypted) throw new __openid4vc_oauth2.Oauth2Error("Failed to decrypt jarm auth response.");
1340
- return {
1341
- decryptionJwk: result.decryptionJwk,
1342
- payload: result.payload
1343
- };
1344
- };
1345
- /**
1346
- * Validate a JARM direct_post.jwt compliant authentication response
1347
- * * The decryption key should be resolvable using the the protected header's 'kid' field
1348
- * * The signature verification jwk should be resolvable using the jws protected header's 'kid' field and the payload's 'iss' field.
1349
- */
1350
- async function verifyJarmAuthorizationResponse(options) {
1351
- const { jarmAuthorizationResponseJwt, callbacks, expectedClientId, authorizationRequestPayload } = options;
1352
- const requestDataIsEncrypted = __openid4vc_oauth2.zCompactJwe.safeParse(jarmAuthorizationResponseJwt).success;
1353
- const decryptedRequestData = requestDataIsEncrypted ? await decryptJarmAuthorizationResponseJwt({
1354
- jarmAuthorizationResponseJwt,
1355
- callbacks,
1356
- authorizationRequestPayload
1357
- }) : {
1358
- payload: jarmAuthorizationResponseJwt,
1359
- decryptionJwk: void 0
1360
- };
1361
- const responseIsSigned = __openid4vc_oauth2.zCompactJwt.safeParse(decryptedRequestData.payload).success;
1362
- if (!requestDataIsEncrypted && !responseIsSigned) throw new __openid4vc_oauth2.Oauth2Error("Jarm Auth Response must be either encrypted, signed, or signed and encrypted.");
1363
- let jarmAuthorizationResponse;
1364
- if (responseIsSigned) {
1365
- const { header: jwsProtectedHeader, payload: jwsPayload } = (0, __openid4vc_oauth2.decodeJwt)({
1366
- jwt: decryptedRequestData.payload,
1367
- headerSchema: zod.default.object({
1368
- ...__openid4vc_oauth2.zJwtHeader.shape,
1369
- kid: zod.default.string()
1370
- })
1371
- });
1372
- const response = zJarmAuthorizationResponse.parse(jwsPayload);
1373
- const jwtSigner = (0, __openid4vc_oauth2.jwtSignerFromJwt)({
1374
- header: jwsProtectedHeader,
1375
- payload: jwsPayload
1376
- });
1377
- if (!(await options.callbacks.verifyJwt(jwtSigner, {
1378
- compact: decryptedRequestData.payload,
1379
- header: jwsProtectedHeader,
1380
- payload: jwsPayload
1381
- })).verified) throw new __openid4vc_oauth2.Oauth2Error("Jarm Auth Response is not valid.");
1382
- jarmAuthorizationResponse = response;
1383
- } else {
1384
- const jsonRequestData = (0, __openid4vc_utils.stringToJsonWithErrorHandling)(decryptedRequestData.payload, "Unable to parse decrypted JARM JWE body to JSON");
1385
- jarmAuthorizationResponse = zJarmAuthorizationResponseEncryptedOnly.parse(jsonRequestData);
1386
- }
1387
- jarmAuthorizationResponseValidate({
1388
- expectedClientId,
1389
- authorizationResponse: jarmAuthorizationResponse
1390
- });
1391
- const type = requestDataIsEncrypted && responseIsSigned ? JarmMode.SignedEncrypted : requestDataIsEncrypted ? JarmMode.Encrypted : JarmMode.Signed;
1392
- const issuer = jarmAuthorizationResponse.iss;
1393
- return {
1394
- jarmAuthorizationResponse,
1395
- type,
1396
- issuer,
1397
- decryptionJwk: decryptedRequestData.decryptionJwk
1398
- };
1399
- }
1400
-
1401
- //#endregion
1402
- //#region src/vp-token/parse-vp-token.ts
1403
- function parsePexVpToken(vpToken) {
1404
- const parsedVpToken = (0, __openid4vc_utils.parseWithErrorHandling)(zVpTokenPex, (0, __openid4vc_utils.parseIfJson)(vpToken), "Could not parse presentation exchange vp_token. Expected a string or an array of strings");
1405
- return Array.isArray(parsedVpToken) ? parsedVpToken : [parsedVpToken];
1406
- }
1407
- function parseDcqlVpToken(vpToken) {
1408
- const parsedVpToken = (0, __openid4vc_utils.parseWithErrorHandling)(zVpTokenDcql, (0, __openid4vc_utils.parseIfJson)(vpToken), "Could not parse dcql vp_token. Expected an object where the values are encoded presentations");
1409
- return Object.fromEntries(Object.entries(parsedVpToken).map(([queryId, presentations]) => [queryId, Array.isArray(presentations) ? presentations : [presentations]]));
1410
- }
1411
-
1412
- //#endregion
1413
- //#region src/authorization-response/validate-authorization-response.ts
1414
- /**
1415
- * The following steps need to be performed outside of this library
1416
- * - verifying the presentations
1417
- * - validating the presentations against the presentation definition
1418
- * - checking the revocation status of the presentations
1419
- * - checking the nonce of the presentations matches the nonce of the request (for mdoc's)
1420
- */
1421
- function validateOpenid4vpAuthorizationResponsePayload(options) {
1422
- const { authorizationRequestPayload, authorizationResponsePayload } = options;
1423
- if (authorizationRequestPayload.state && authorizationRequestPayload.state !== authorizationResponsePayload.state) throw new __openid4vc_oauth2.Oauth2Error("OpenId4Vp Authorization Response state mismatch.");
1424
- if (authorizationResponsePayload.id_token) throw new __openid4vc_oauth2.Oauth2Error("OpenId4Vp Authorization Response id_token is not supported.");
1425
- if (authorizationResponsePayload.presentation_submission) {
1426
- if (!authorizationRequestPayload.presentation_definition) throw new __openid4vc_oauth2.Oauth2Error("OpenId4Vp Authorization Request is missing the required presentation_definition.");
1427
- return {
1428
- type: "pex",
1429
- pex: authorizationRequestPayload.scope ? {
1430
- scope: authorizationRequestPayload.scope,
1431
- presentationSubmission: authorizationResponsePayload.presentation_submission,
1432
- presentations: parsePexVpToken(authorizationResponsePayload.vp_token)
1433
- } : {
1434
- presentationDefinition: authorizationRequestPayload.presentation_definition,
1435
- presentationSubmission: authorizationResponsePayload.presentation_submission,
1436
- presentations: parsePexVpToken(authorizationResponsePayload.vp_token)
1437
- }
1438
- };
1439
- }
1440
- if (authorizationRequestPayload.dcql_query) {
1441
- const presentations = parseDcqlVpToken(authorizationResponsePayload.vp_token);
1442
- return {
1443
- type: "dcql",
1444
- dcql: authorizationRequestPayload.scope ? {
1445
- scope: authorizationRequestPayload.scope,
1446
- presentations
1447
- } : {
1448
- query: authorizationRequestPayload.dcql_query,
1449
- presentations
1450
- }
1451
- };
1452
- }
1453
- throw new __openid4vc_oauth2.Oauth2Error("Invalid OpenId4Vp Authorization Response. Response neither contains a presentation_submission nor request contains a dcql_query.");
1454
- }
1455
-
1456
- //#endregion
1457
- //#region src/authorization-response/parse-jarm-authorization-response.ts
1458
- async function parseJarmAuthorizationResponse(options) {
1459
- const { jarmResponseJwt, callbacks, authorizationRequestPayload, expectedClientId } = options;
1460
- const jarmAuthorizationResponseJwt = (0, __openid4vc_utils.parseWithErrorHandling)(zod.default.union([__openid4vc_oauth2.zCompactJwt, __openid4vc_oauth2.zCompactJwe]), jarmResponseJwt, "Invalid jarm authorization response jwt.");
1461
- const verifiedJarmResponse = await verifyJarmAuthorizationResponse({
1462
- jarmAuthorizationResponseJwt,
1463
- callbacks,
1464
- expectedClientId,
1465
- authorizationRequestPayload
1466
- });
1467
- const { header: jarmHeader } = (0, __openid4vc_oauth2.decodeJwtHeader)({
1468
- jwt: jarmAuthorizationResponseJwt,
1469
- headerSchema: zJarmHeader
1470
- });
1471
- const authorizationResponsePayload = parseOpenid4VpAuthorizationResponsePayload(verifiedJarmResponse.jarmAuthorizationResponse);
1472
- const validateOpenId4vpResponse = validateOpenid4vpAuthorizationResponsePayload({
1473
- authorizationRequestPayload,
1474
- authorizationResponsePayload
1475
- });
1476
- if (!authorizationRequestPayload.response_mode || !isJarmResponseMode(authorizationRequestPayload.response_mode)) throw new __openid4vc_oauth2.Oauth2Error(`Invalid response mode for jarm response. Response mode: '${authorizationRequestPayload.response_mode ?? "fragment"}'`);
1477
- return {
1478
- ...validateOpenId4vpResponse,
1479
- jarm: {
1480
- ...verifiedJarmResponse,
1481
- jarmHeader
1482
- },
1483
- expectedNonce: authorizationRequestPayload.nonce,
1484
- authorizationResponsePayload
1485
- };
1486
- }
1487
-
1488
- //#endregion
1489
- //#region src/authorization-response/parse-authorization-response.ts
1490
- async function parseOpenid4vpAuthorizationResponse(options) {
1491
- const { authorizationResponse, callbacks, authorizationRequestPayload, origin } = options;
1492
- const expectedClientId = getOpenid4vpClientId({
1493
- origin,
1494
- responseMode: authorizationRequestPayload.response_mode,
1495
- clientId: authorizationRequestPayload.client_id,
1496
- legacyClientIdScheme: authorizationRequestPayload.client_id_scheme
1497
- });
1498
- if (authorizationResponse.response) return parseJarmAuthorizationResponse({
1499
- jarmResponseJwt: authorizationResponse.response,
1500
- callbacks,
1501
- authorizationRequestPayload,
1502
- expectedClientId: expectedClientId.effectiveClientId
1503
- });
1504
- const authorizationResponsePayload = parseOpenid4VpAuthorizationResponsePayload(authorizationResponse);
1505
- const validatedOpenId4vpResponse = validateOpenid4vpAuthorizationResponsePayload({
1506
- authorizationRequestPayload,
1507
- authorizationResponsePayload
1508
- });
1509
- if (authorizationRequestPayload.response_mode && isJarmResponseMode(authorizationRequestPayload.response_mode)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1510
- error: "invalid_request",
1511
- error_description: "Invalid response mode for openid4vp response. Expected jarm response."
1512
- }, { status: 400 });
1513
- return {
1514
- ...validatedOpenId4vpResponse,
1515
- expectedNonce: authorizationRequestPayload.nonce,
1516
- authorizationResponsePayload,
1517
- jarm: void 0
1518
- };
1519
- }
1520
-
1521
- //#endregion
1522
- //#region src/jarm/jarm-authorizatino-response-send.ts
1523
- const jarmAuthorizationResponseSend = (options) => {
1524
- const { authorizationRequestPayload, jarmAuthorizationResponseJwt, callbacks } = options;
1525
- const responseEndpoint = authorizationRequestPayload.response_uri ?? authorizationRequestPayload.redirect_uri;
1526
- if (!responseEndpoint) throw new __openid4vc_oauth2.Oauth2Error(`Either 'response_uri' or 'redirect_uri' MUST be present in the authorization request`);
1527
- return handleDirectPostJwt(new __openid4vc_utils.URL(responseEndpoint), jarmAuthorizationResponseJwt, callbacks);
1528
- };
1529
- async function handleDirectPostJwt(responseEndpoint, responseJwt, callbacks) {
1530
- return {
1531
- responseMode: "direct_post.jwt",
1532
- response: await (0, __openid4vc_utils.createFetcher)(callbacks.fetch)(responseEndpoint, {
1533
- method: "POST",
1534
- headers: { "Content-Type": __openid4vc_utils.ContentType.XWwwFormUrlencoded },
1535
- body: `response=${responseJwt}`
1536
- })
1537
- };
1538
- }
1539
-
1540
- //#endregion
1541
- //#region src/authorization-response/submit-authorization-response.ts
1542
- async function submitOpenid4vpAuthorizationResponse(options) {
1543
- const { authorizationRequestPayload, authorizationResponsePayload, jarm, callbacks } = options;
1544
- const url = authorizationRequestPayload.response_uri;
1545
- if (jarm) return jarmAuthorizationResponseSend({
1546
- authorizationRequestPayload,
1547
- jarmAuthorizationResponseJwt: jarm.responseJwt,
1548
- callbacks
1549
- });
1550
- if (!url) throw new __openid4vc_oauth2.Oauth2Error("Failed to submit OpenId4Vp Authorization Response. No redirect_uri or response_uri provided.");
1551
- return {
1552
- responseMode: "direct_post",
1553
- response: await (0, __openid4vc_utils.createFetcher)(callbacks.fetch)(url, {
1554
- method: "POST",
1555
- body: (0, __openid4vc_utils.objectToQueryParams)(authorizationResponsePayload).toString(),
1556
- headers: { "Content-Type": __openid4vc_utils.ContentType.XWwwFormUrlencoded }
1557
- })
1558
- };
1559
- }
1560
-
1561
- //#endregion
1562
- //#region src/models/z-credential-formats.ts
1563
- const zCredentialFormat = zod.z.enum([
1564
- "jwt_vc_json",
1565
- "ldp_vc",
1566
- "mso_mdoc",
1567
- "dc+sd-jwt",
1568
- "vc+sd-jwt"
1569
- ]);
1570
-
1571
- //#endregion
1572
- //#region src/models/z-proof-formats.ts
1573
- const zProofFormat = zod.z.enum([
1574
- "jwt_vp_json",
1575
- "ldc_vp",
1576
- "ac_vp",
1577
- "dc+sd-jwt",
1578
- "vc+sd-jwt",
1579
- "mso_mdoc"
1580
- ]);
1581
-
1582
- //#endregion
1583
- //#region src/models/z-wallet-metadata.ts
1584
- const zWalletMetadata = zod.z.object({
1585
- presentation_definition_uri_supported: zod.z.optional(zod.z.boolean()),
1586
- vp_formats_supported: zod.z.optional(zVpFormatsSupported.or(zLegacyVpFormats)),
1587
- client_id_schemes_supported: zod.z.optional(zod.z.array(zClientIdPrefix.exclude(["decentralized_identifier", "openid_federation"]))),
1588
- client_id_prefixes_supported: zod.z.optional(zod.z.array(zUniformClientIdPrefix)),
1589
- request_object_signing_alg_values_supported: zod.z.optional(zod.z.array(zod.z.string())),
1590
- authorization_encryption_alg_values_supported: zod.z.optional(zod.z.array(zod.z.string())),
1591
- authorization_encryption_enc_values_supported: zod.z.optional(zod.z.array(zod.z.string()))
1592
- });
1593
-
1594
- //#endregion
1595
- //#region src/Openid4vpClient.ts
1596
- var Openid4vpClient = class {
1597
- constructor(options) {
1598
- this.options = options;
1599
- }
1600
- parseOpenid4vpAuthorizationRequest(options) {
1601
- return parseOpenid4vpAuthorizationRequest(options);
1602
- }
1603
- async resolveOpenId4vpAuthorizationRequest(options) {
1604
- return resolveOpenid4vpAuthorizationRequest({
1605
- ...options,
1606
- callbacks: this.options.callbacks
1607
- });
1608
- }
1609
- async createOpenid4vpAuthorizationResponse(options) {
1610
- return createOpenid4vpAuthorizationResponse({
1611
- ...options,
1612
- callbacks: this.options.callbacks
1613
- });
1614
- }
1615
- async submitOpenid4vpAuthorizationResponse(options) {
1616
- return submitOpenid4vpAuthorizationResponse({
1617
- ...options,
1618
- callbacks: this.options.callbacks
1619
- });
1620
- }
1621
- };
1622
-
1623
- //#endregion
1624
- //#region src/transaction-data/verify-transaction-data.ts
1625
- async function verifyTransactionData(options) {
1626
- const parsedTransactionData = parseTransactionData({ transactionData: options.transactionData });
1627
- const matchedEntries = [];
1628
- for (const parsedEntry of parsedTransactionData) {
1629
- const matchedEntry = await verifyTransactionDataEntry({
1630
- entry: parsedEntry,
1631
- callbacks: options.callbacks,
1632
- credentials: options.credentials
1633
- });
1634
- matchedEntries.push(matchedEntry);
1635
- }
1636
- return matchedEntries;
1637
- }
1638
- async function verifyTransactionDataEntry({ entry, credentials, callbacks }) {
1639
- const allowedAlgs = entry.transactionData.transaction_data_hashes_alg ?? ["sha-256"];
1640
- const supportedAlgs = allowedAlgs.filter((alg) => Object.values(__openid4vc_oauth2.HashAlgorithm).includes(alg));
1641
- const hashes = {};
1642
- for (const alg of supportedAlgs) hashes[alg] = (0, __openid4vc_utils.encodeToBase64Url)(await callbacks.hash((0, __openid4vc_utils.decodeUtf8String)(entry.encoded), alg));
1643
- for (const credentialId of entry.transactionData.credential_ids) {
1644
- const transactionDataHashesCredentials = credentials[credentialId];
1645
- if (!transactionDataHashesCredentials) continue;
1646
- const presentations = [];
1647
- for (const transactionDataHashesCredential of transactionDataHashesCredentials) {
1648
- const alg = transactionDataHashesCredential.transaction_data_hashes_alg ?? "sha-256";
1649
- const hash = hashes[alg];
1650
- const presentationIndex = transactionDataHashesCredentials.indexOf(transactionDataHashesCredential);
1651
- if (!allowedAlgs.includes(alg)) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1652
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidTransactionData,
1653
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} is hashed using alg '${alg}'. However transaction data only allows alg values ${allowedAlgs.join(", ")}.`
1654
- });
1655
- if (!hash) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1656
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidTransactionData,
1657
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} is hashed using unsupported alg '${alg}'. This library only supports verification of transaction data hashes using alg values ${Object.values(__openid4vc_oauth2.HashAlgorithm).join(", ")}. Either verify the hashes outside of this library, or limit the allowed alg values to the ones supported by this library.`
1658
- });
1659
- const credentialHashIndex = transactionDataHashesCredential.transaction_data_hashes.indexOf(hash);
1660
- if (credentialHashIndex === -1) throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1661
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidTransactionData,
1662
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} for presentation ${credentialId} with index ${presentationIndex} does not have a matching hash in the transaction_data_hashes`
1663
- });
1664
- presentations.push({
1665
- credentialHashIndex,
1666
- hash,
1667
- hashAlg: alg,
1668
- presentationIndex
1669
- });
1670
- }
1671
- return {
1672
- transactionDataEntry: entry,
1673
- credentialId,
1674
- presentations
1675
- };
1676
- }
1677
- throw new __openid4vc_oauth2.Oauth2ServerErrorResponseError({
1678
- error: __openid4vc_oauth2.Oauth2ErrorCodes.InvalidTransactionData,
1679
- error_description: `Transaction data entry with index ${entry.transactionDataIndex} does not have a matching hash in any of the submitted credentials`
1680
- });
1681
- }
1682
-
1683
- //#endregion
1684
- //#region src/Openid4vpVerifier.ts
1685
- var Openid4vpVerifier = class {
1686
- constructor(options) {
1687
- this.options = options;
1688
- }
1689
- async createOpenId4vpAuthorizationRequest(options) {
1690
- return createOpenid4vpAuthorizationRequest({
1691
- ...options,
1692
- callbacks: this.options.callbacks
1693
- });
1694
- }
1695
- parseOpenid4vpAuthorizationRequestPayload(options) {
1696
- return parseOpenid4vpAuthorizationRequest(options);
1697
- }
1698
- parseOpenid4vpAuthorizationResponse(options) {
1699
- return parseOpenid4vpAuthorizationResponse(options);
1700
- }
1701
- validateOpenid4vpAuthorizationResponsePayload(options) {
1702
- return validateOpenid4vpAuthorizationResponsePayload(options);
1703
- }
1704
- parsePexVpToken(vpToken) {
1705
- return parsePexVpToken(vpToken);
1706
- }
1707
- parseDcqlVpToken(vpToken) {
1708
- return parseDcqlVpToken(vpToken);
1709
- }
1710
- parseTransactionData(options) {
1711
- return parseTransactionData(options);
1712
- }
1713
- /**
1714
- * Verify transaction data against submitted credentials.
1715
- *
1716
- * NOTE: this expects transaction data based authorization based on hashes. This is the method defined
1717
- * for SD-JWT VC, but for mDOCs it's much more generic. If you're using transaction data with mDOCs based
1718
- * on hashes, you can extract the values from the DeviceResponse, otherwise you must verify the transaction data
1719
- * manually.
1720
- */
1721
- verifyTransactionData(options) {
1722
- return verifyTransactionData({
1723
- ...options,
1724
- callbacks: this.options.callbacks
1725
- });
1726
- }
1727
- };
1728
-
1729
- //#endregion
1730
- exports.JarmMode = JarmMode;
1731
- exports.Openid4vpClient = Openid4vpClient;
1732
- exports.Openid4vpVerifier = Openid4vpVerifier;
1733
- exports.calculateX509HashClientIdPrefixValue = calculateX509HashClientIdPrefixValue;
1734
- exports.createOpenid4vpAuthorizationRequest = createOpenid4vpAuthorizationRequest;
1735
- exports.createOpenid4vpAuthorizationResponse = createOpenid4vpAuthorizationResponse;
1736
- exports.extractEncryptionJwkFromJwks = extractEncryptionJwkFromJwks;
1737
- exports.getOpenid4vpClientId = getOpenid4vpClientId;
1738
- exports.isJarmResponseMode = isJarmResponseMode;
1739
- exports.isOpenid4vpAuthorizationRequestDcApi = isOpenid4vpAuthorizationRequestDcApi;
1740
- exports.parseAuthorizationRequestVersion = parseAuthorizationRequestVersion;
1741
- exports.parseDcqlVpToken = parseDcqlVpToken;
1742
- exports.parseJarmAuthorizationResponse = parseJarmAuthorizationResponse;
1743
- exports.parseOpenid4VpAuthorizationResponsePayload = parseOpenid4VpAuthorizationResponsePayload;
1744
- exports.parseOpenid4vpAuthorizationRequest = parseOpenid4vpAuthorizationRequest;
1745
- exports.parseOpenid4vpAuthorizationResponse = parseOpenid4vpAuthorizationResponse;
1746
- exports.parsePexVpToken = parsePexVpToken;
1747
- exports.parseTransactionData = parseTransactionData;
1748
- exports.resolveOpenid4vpAuthorizationRequest = resolveOpenid4vpAuthorizationRequest;
1749
- exports.submitOpenid4vpAuthorizationResponse = submitOpenid4vpAuthorizationResponse;
1750
- exports.validateOpenid4vpAuthorizationRequestPayload = validateOpenid4vpAuthorizationRequestPayload;
1751
- exports.validateOpenid4vpAuthorizationResponsePayload = validateOpenid4vpAuthorizationResponsePayload;
1752
- exports.verifyJarmAuthorizationResponse = verifyJarmAuthorizationResponse;
1753
- exports.zClientIdPrefix = zClientIdPrefix;
1754
- exports.zClientMetadata = zClientMetadata;
1755
- exports.zCredentialFormat = zCredentialFormat;
1756
- exports.zJarmClientMetadata = zJarmClientMetadata;
1757
- exports.zOpenid4vpAuthorizationResponse = zOpenid4vpAuthorizationResponse;
1758
- exports.zProofFormat = zProofFormat;
1759
- exports.zVerifierAttestations = zVerifierAttestations;
1760
- exports.zWalletMetadata = zWalletMetadata;
1761
- //# sourceMappingURL=index.cjs.map