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