@openid4vc/oauth2 0.2.0-alpha-20250109205223

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2703 @@
1
+ "use strict";
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 __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ HashAlgorithm: () => HashAlgorithm,
34
+ InvalidFetchResponseError: () => import_utils43.InvalidFetchResponseError,
35
+ Oauth2AuthorizationServer: () => Oauth2AuthorizationServer,
36
+ Oauth2Client: () => Oauth2Client,
37
+ Oauth2ClientAuthorizationChallengeError: () => Oauth2ClientAuthorizationChallengeError,
38
+ Oauth2ClientErrorResponseError: () => Oauth2ClientErrorResponseError,
39
+ Oauth2Error: () => Oauth2Error,
40
+ Oauth2ErrorCodes: () => Oauth2ErrorCodes,
41
+ Oauth2JwtParseError: () => Oauth2JwtParseError,
42
+ Oauth2JwtVerificationError: () => Oauth2JwtVerificationError,
43
+ Oauth2ResourceServer: () => Oauth2ResourceServer,
44
+ Oauth2ResourceUnauthorizedError: () => Oauth2ResourceUnauthorizedError,
45
+ Oauth2ServerErrorResponseError: () => Oauth2ServerErrorResponseError,
46
+ PkceCodeChallengeMethod: () => PkceCodeChallengeMethod,
47
+ SupportedAuthenticationScheme: () => SupportedAuthenticationScheme,
48
+ authorizationCodeGrantIdentifier: () => authorizationCodeGrantIdentifier,
49
+ calculateJwkThumbprint: () => calculateJwkThumbprint,
50
+ clientAuthenticationClientSecretBasic: () => clientAuthenticationClientSecretBasic,
51
+ clientAuthenticationClientSecretPost: () => clientAuthenticationClientSecretPost,
52
+ clientAuthenticationDynamic: () => clientAuthenticationDynamic,
53
+ clientAuthenticationNone: () => clientAuthenticationNone,
54
+ decodeJwt: () => decodeJwt,
55
+ fetchAuthorizationServerMetadata: () => fetchAuthorizationServerMetadata,
56
+ fetchJwks: () => fetchJwks,
57
+ fetchWellKnownMetadata: () => fetchWellKnownMetadata,
58
+ getAuthorizationServerMetadataFromList: () => getAuthorizationServerMetadataFromList,
59
+ getGlobalConfig: () => import_utils42.getGlobalConfig,
60
+ isJwkInSet: () => isJwkInSet,
61
+ jwtHeaderFromJwtSigner: () => jwtHeaderFromJwtSigner,
62
+ jwtSignerFromJwt: () => jwtSignerFromJwt,
63
+ preAuthorizedCodeGrantIdentifier: () => preAuthorizedCodeGrantIdentifier,
64
+ refreshTokenGrantIdentifier: () => refreshTokenGrantIdentifier,
65
+ resourceRequest: () => resourceRequest,
66
+ setGlobalConfig: () => import_utils42.setGlobalConfig,
67
+ vAuthorizationCodeGrantIdentifier: () => vAuthorizationCodeGrantIdentifier,
68
+ vAuthorizationServerMetadata: () => vAuthorizationServerMetadata,
69
+ vCompactJwt: () => vCompactJwt,
70
+ vJwk: () => vJwk,
71
+ vJwtHeader: () => vJwtHeader,
72
+ vJwtPayload: () => vJwtPayload,
73
+ vOauth2ErrorResponse: () => vOauth2ErrorResponse,
74
+ vPreAuthorizedCodeGrantIdentifier: () => vPreAuthorizedCodeGrantIdentifier,
75
+ vRefreshTokenGrantIdentifier: () => vRefreshTokenGrantIdentifier,
76
+ verifyJwt: () => verifyJwt,
77
+ verifyResourceRequest: () => verifyResourceRequest
78
+ });
79
+ module.exports = __toCommonJS(src_exports);
80
+ var import_utils42 = require("@openid4vc/utils");
81
+
82
+ // src/common/v-oauth2-error.ts
83
+ var v = __toESM(require("valibot"));
84
+ var Oauth2ErrorCodes = /* @__PURE__ */ ((Oauth2ErrorCodes2) => {
85
+ Oauth2ErrorCodes2["ServerError"] = "server_error";
86
+ Oauth2ErrorCodes2["InvalidTarget"] = "invalid_target";
87
+ Oauth2ErrorCodes2["InvalidRequest"] = "invalid_request";
88
+ Oauth2ErrorCodes2["InvalidToken"] = "invalid_token";
89
+ Oauth2ErrorCodes2["InsufficientScope"] = "insufficient_scope";
90
+ Oauth2ErrorCodes2["InvalidGrant"] = "invalid_grant";
91
+ Oauth2ErrorCodes2["InvalidClient"] = "invalid_client";
92
+ Oauth2ErrorCodes2["UnauthorizedClient"] = "unauthorized_client";
93
+ Oauth2ErrorCodes2["UnsupportedGrantType"] = "unsupported_grant_type";
94
+ Oauth2ErrorCodes2["InvalidScope"] = "invalid_scope";
95
+ Oauth2ErrorCodes2["InvalidDpopProof"] = "invalid_dpop_proof";
96
+ Oauth2ErrorCodes2["UseDpopNonce"] = "use_dpop_nonce";
97
+ Oauth2ErrorCodes2["RedirectToWeb"] = "redirect_to_web";
98
+ Oauth2ErrorCodes2["InvalidSession"] = "invalid_session";
99
+ Oauth2ErrorCodes2["InsufficientAuthorization"] = "insufficient_authorization";
100
+ Oauth2ErrorCodes2["InvalidCredentialRequest"] = "invalid_credential_request";
101
+ Oauth2ErrorCodes2["CredentialRequestDenied"] = "credential_request_denied";
102
+ Oauth2ErrorCodes2["UnsupportedCredentialType"] = "unsupported_credential_type";
103
+ Oauth2ErrorCodes2["UnsupportedCredentialFormat"] = "unsupported_credential_format";
104
+ Oauth2ErrorCodes2["InvalidProof"] = "invalid_proof";
105
+ Oauth2ErrorCodes2["InvalidNonce"] = "invalid_nonce";
106
+ Oauth2ErrorCodes2["InvalidEncryptionParameters"] = "invalid_encryption_parameters";
107
+ return Oauth2ErrorCodes2;
108
+ })(Oauth2ErrorCodes || {});
109
+ var vOauth2ErrorResponse = v.looseObject({
110
+ error: v.union([v.enum(Oauth2ErrorCodes), v.string()]),
111
+ error_description: v.optional(v.string()),
112
+ error_uri: v.optional(v.string())
113
+ });
114
+
115
+ // src/common/jwk/jwk-thumbprint.ts
116
+ var v2 = __toESM(require("valibot"));
117
+ var import_utils = require("@openid4vc/utils");
118
+ var vJwkThumbprintComponents = v2.variant("kty", [
119
+ v2.pipe(
120
+ v2.looseObject({
121
+ kty: v2.literal("EC"),
122
+ crv: v2.string(),
123
+ x: v2.string(),
124
+ y: v2.string()
125
+ }),
126
+ v2.transform(({ crv, kty, x, y }) => ({ crv, kty, x, y }))
127
+ ),
128
+ v2.pipe(
129
+ v2.looseObject({
130
+ kty: v2.literal("OKP"),
131
+ crv: v2.string(),
132
+ x: v2.string()
133
+ }),
134
+ v2.transform(({ crv, kty, x }) => ({ crv, kty, x }))
135
+ ),
136
+ v2.pipe(
137
+ v2.looseObject({
138
+ kty: v2.literal("RSA"),
139
+ e: v2.string(),
140
+ n: v2.string()
141
+ }),
142
+ v2.transform(({ e, kty, n }) => ({ e, kty, n }))
143
+ ),
144
+ v2.pipe(
145
+ v2.looseObject({
146
+ kty: v2.literal("oct"),
147
+ k: v2.string()
148
+ }),
149
+ v2.transform(({ k, kty }) => ({ k, kty }))
150
+ )
151
+ ]);
152
+ async function calculateJwkThumbprint(options) {
153
+ const jwkThumbprintComponents = (0, import_utils.parseWithErrorHandling)(
154
+ vJwkThumbprintComponents,
155
+ options.jwk,
156
+ `Provided jwk does not match a supported jwk structure. Either the 'kty' is not supported, or required values are missing.`
157
+ );
158
+ const thumbprint = (0, import_utils.encodeToBase64Url)(
159
+ await options.hashCallback((0, import_utils.decodeUtf8String)(JSON.stringify(jwkThumbprintComponents)), options.hashAlgorithm)
160
+ );
161
+ return thumbprint;
162
+ }
163
+
164
+ // src/callbacks.ts
165
+ var HashAlgorithm = /* @__PURE__ */ ((HashAlgorithm2) => {
166
+ HashAlgorithm2["Sha256"] = "SHA-256";
167
+ return HashAlgorithm2;
168
+ })(HashAlgorithm || {});
169
+
170
+ // src/error/Oauth2Error.ts
171
+ var Oauth2Error = class extends Error {
172
+ constructor(message, options) {
173
+ const errorMessage = message ?? "Unknown error occured.";
174
+ const causeMessage = options?.cause instanceof Error ? ` ${options.cause.message}` : options?.cause ? ` ${options?.cause}` : "";
175
+ super(`${errorMessage}${causeMessage}`);
176
+ this.cause = options?.cause;
177
+ }
178
+ };
179
+
180
+ // src/common/jwk/jwks.ts
181
+ function extractJwkFromJwksForJwt(options) {
182
+ const jwksForUse = options.jwks.keys.filter(({ use }) => !use || use === options.use);
183
+ const jwkForKid = options.kid ? jwksForUse.find(({ kid }) => kid === options.kid) : void 0;
184
+ if (jwkForKid) {
185
+ return jwkForKid;
186
+ }
187
+ if (jwksForUse.length === 1) {
188
+ return jwksForUse[0];
189
+ }
190
+ throw new Oauth2Error(
191
+ `Unable to extract jwk from jwks for use '${options.use}'${options.kid ? `with kid '${options.kid}'.` : ". No kid provided and more than jwk."}`
192
+ );
193
+ }
194
+ async function isJwkInSet({
195
+ jwk,
196
+ jwks,
197
+ callbacks
198
+ }) {
199
+ const jwkThumbprint = await calculateJwkThumbprint({
200
+ hashAlgorithm: "SHA-256" /* Sha256 */,
201
+ hashCallback: callbacks.hash,
202
+ jwk
203
+ });
204
+ for (const jwkFromSet of jwks) {
205
+ const jwkFromSetThumbprint = await calculateJwkThumbprint({
206
+ hashAlgorithm: "SHA-256" /* Sha256 */,
207
+ hashCallback: callbacks.hash,
208
+ jwk: jwkFromSet
209
+ });
210
+ if (jwkFromSetThumbprint === jwkThumbprint) return true;
211
+ }
212
+ return false;
213
+ }
214
+
215
+ // src/common/jwk/v-jwk.ts
216
+ var v3 = __toESM(require("valibot"));
217
+ var vJwk = v3.looseObject({
218
+ kty: v3.string(),
219
+ crv: v3.optional(v3.string()),
220
+ x: v3.optional(v3.string()),
221
+ y: v3.optional(v3.string()),
222
+ e: v3.optional(v3.string()),
223
+ n: v3.optional(v3.string()),
224
+ alg: v3.optional(v3.string()),
225
+ d: v3.optional(v3.string()),
226
+ dp: v3.optional(v3.string()),
227
+ dq: v3.optional(v3.string()),
228
+ ext: v3.optional(v3.boolean()),
229
+ k: v3.optional(v3.string()),
230
+ key_ops: v3.optional(v3.string()),
231
+ kid: v3.optional(v3.string()),
232
+ oth: v3.optional(
233
+ v3.array(
234
+ v3.looseObject({
235
+ d: v3.optional(v3.string()),
236
+ r: v3.optional(v3.string()),
237
+ t: v3.optional(v3.string())
238
+ })
239
+ )
240
+ ),
241
+ p: v3.optional(v3.string()),
242
+ q: v3.optional(v3.string()),
243
+ qi: v3.optional(v3.string()),
244
+ use: v3.optional(v3.string()),
245
+ x5c: v3.optional(v3.string()),
246
+ x5t: v3.optional(v3.string()),
247
+ "x5t#S256": v3.optional(v3.string()),
248
+ x5u: v3.optional(v3.string())
249
+ });
250
+ var vJwkSet = v3.looseObject({
251
+ keys: v3.array(vJwk)
252
+ });
253
+
254
+ // src/common/jwt/verify-jwt.ts
255
+ var import_utils2 = require("@openid4vc/utils");
256
+
257
+ // src/error/Oauth2JwtVerificationError.ts
258
+ var Oauth2JwtVerificationError = class extends Oauth2Error {
259
+ constructor(message, options) {
260
+ const errorMessage = message ?? "Error verifiying jwt.";
261
+ super(errorMessage, options);
262
+ }
263
+ };
264
+
265
+ // src/common/jwt/verify-jwt.ts
266
+ async function verifyJwt(options) {
267
+ const errorMessage = options.errorMessage ?? "Error during verification of jwt.";
268
+ let signerJwk;
269
+ try {
270
+ const result = await options.verifyJwtCallback(options.signer, {
271
+ header: options.header,
272
+ payload: options.payload,
273
+ compact: options.compact
274
+ });
275
+ if (!result.verified) throw new Oauth2JwtVerificationError(errorMessage);
276
+ signerJwk = result.signerJwk;
277
+ } catch (error) {
278
+ if (error instanceof Oauth2JwtVerificationError) throw error;
279
+ throw new Oauth2JwtVerificationError(errorMessage, { cause: error });
280
+ }
281
+ const nowInSeconds = (0, import_utils2.dateToSeconds)(options.now ?? /* @__PURE__ */ new Date());
282
+ const skewInSeconds = options.allowedSkewInSeconds ?? 0;
283
+ const timeBasedValidation = options.skipTimeBasedValidation !== void 0 ? !options.skipTimeBasedValidation : true;
284
+ if (timeBasedValidation && options.payload.nbf && nowInSeconds < options.payload.nbf - skewInSeconds) {
285
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'nbf' is in the future`);
286
+ }
287
+ if (timeBasedValidation && options.payload.exp && nowInSeconds > options.payload.exp + skewInSeconds) {
288
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'exp' is in the past`);
289
+ }
290
+ if (options.expectedAudience && options.expectedAudience !== options.payload.aud) {
291
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'aud' does not match expected value.`);
292
+ }
293
+ if (options.expectedIssuer && options.expectedIssuer !== options.payload.iss) {
294
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'iss' does not match expected value.`);
295
+ }
296
+ if (options.expectedNonce && options.expectedNonce !== options.payload.nonce) {
297
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'nonce' does not match expected value.`);
298
+ }
299
+ if (options.expectedSubject && options.expectedSubject !== options.payload.sub) {
300
+ throw new Oauth2JwtVerificationError(`${errorMessage} jwt 'sub' does not match expected value.`);
301
+ }
302
+ return {
303
+ signer: {
304
+ ...options.signer,
305
+ publicJwk: signerJwk
306
+ }
307
+ };
308
+ }
309
+
310
+ // src/common/jwt/decode-jwt.ts
311
+ var import_utils4 = require("@openid4vc/utils");
312
+
313
+ // src/error/Oauth2JwtParseError.ts
314
+ var Oauth2JwtParseError = class extends Oauth2Error {
315
+ constructor(message) {
316
+ const errorMessage = message ?? "Error parsing jwt";
317
+ super(errorMessage);
318
+ }
319
+ };
320
+
321
+ // src/common/jwt/v-jwt.ts
322
+ var import_utils3 = require("@openid4vc/utils");
323
+ var v5 = __toESM(require("valibot"));
324
+
325
+ // src/common/v-common.ts
326
+ var v4 = __toESM(require("valibot"));
327
+ var vAlgValueNotNone = v4.pipe(
328
+ v4.string(),
329
+ v4.check((alg) => alg !== "none", `alg value may not be 'none'`)
330
+ );
331
+
332
+ // src/common/jwt/v-jwt.ts
333
+ var vCompactJwt = v5.pipe(
334
+ v5.string(),
335
+ v5.regex(/^([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_\-\+\/=]*)$/, "Not a valid compact jwt")
336
+ );
337
+ var vJwtConfirmationPayload = v5.looseObject({
338
+ jwk: v5.optional(vJwk),
339
+ // RFC9449. jwk thumbprint of the dpop public key to which the access token is bound
340
+ jkt: v5.optional(v5.string())
341
+ });
342
+ var vJwtPayload = v5.looseObject({
343
+ iss: v5.optional(v5.string()),
344
+ aud: v5.optional(v5.string()),
345
+ iat: v5.optional(import_utils3.vInteger),
346
+ exp: v5.optional(import_utils3.vInteger),
347
+ nbf: v5.optional(import_utils3.vInteger),
348
+ nonce: v5.optional(v5.string()),
349
+ jti: v5.optional(v5.string()),
350
+ cnf: v5.optional(vJwtConfirmationPayload),
351
+ // Reserved for status parameters
352
+ status: v5.optional(v5.looseObject({}))
353
+ });
354
+ var vJwtHeader = v5.looseObject({
355
+ alg: vAlgValueNotNone,
356
+ typ: v5.optional(v5.string()),
357
+ kid: v5.optional(v5.string()),
358
+ jwk: v5.optional(vJwk),
359
+ x5c: v5.optional(v5.array(v5.string())),
360
+ trust_chain: v5.optional(v5.array(v5.string()))
361
+ });
362
+
363
+ // src/common/jwt/decode-jwt.ts
364
+ function decodeJwt(options) {
365
+ const jwtParts = options.jwt.split(".");
366
+ if (jwtParts.length !== 3) {
367
+ throw new Oauth2JwtParseError("Jwt is not a valid jwt, unable to decode");
368
+ }
369
+ let headerJson;
370
+ let payloadJson;
371
+ try {
372
+ headerJson = (0, import_utils4.stringToJsonWithErrorHandling)(
373
+ (0, import_utils4.encodeToUtf8String)((0, import_utils4.decodeBase64)(jwtParts[0])),
374
+ "Unable to parse jwt header to JSON"
375
+ );
376
+ payloadJson = (0, import_utils4.stringToJsonWithErrorHandling)(
377
+ (0, import_utils4.encodeToUtf8String)((0, import_utils4.decodeBase64)(jwtParts[1])),
378
+ "Unable to parse jwt payload to JSON"
379
+ );
380
+ } catch (error) {
381
+ throw new Oauth2JwtParseError("Error parsing JWT");
382
+ }
383
+ const header = (0, import_utils4.parseWithErrorHandling)(options.headerSchema ?? vJwtHeader, headerJson);
384
+ const payload = (0, import_utils4.parseWithErrorHandling)(options.payloadSchema ?? vJwtPayload, payloadJson);
385
+ return {
386
+ header,
387
+ payload,
388
+ signature: jwtParts[2]
389
+ };
390
+ }
391
+ function jwtHeaderFromJwtSigner(signer) {
392
+ if (signer.method === "did") {
393
+ return {
394
+ alg: signer.alg,
395
+ kid: signer.didUrl
396
+ };
397
+ }
398
+ if (signer.method === "trustChain") {
399
+ return {
400
+ alg: signer.alg,
401
+ kid: signer.kid,
402
+ trust_chain: signer.trustChain
403
+ };
404
+ }
405
+ if (signer.method === "jwk") {
406
+ return {
407
+ alg: signer.alg,
408
+ jwk: signer.publicJwk,
409
+ kid: signer.publicJwk.kid
410
+ };
411
+ }
412
+ if (signer.method === "x5c") {
413
+ return {
414
+ alg: signer.alg,
415
+ x5c: signer.x5c
416
+ };
417
+ }
418
+ return {
419
+ alg: signer.alg
420
+ };
421
+ }
422
+ function jwtSignerFromJwt({ header, payload }) {
423
+ if (header.x5c) {
424
+ return {
425
+ alg: header.alg,
426
+ method: "x5c",
427
+ x5c: header.x5c
428
+ };
429
+ }
430
+ if (header.trust_chain) {
431
+ if (!header.kid) {
432
+ throw new Error(`When 'trust_chain' is used in jwt header, the 'kid' parameter is required.`);
433
+ }
434
+ return {
435
+ method: "trustChain",
436
+ alg: header.alg,
437
+ trustChain: header.trust_chain,
438
+ kid: header.kid
439
+ };
440
+ }
441
+ if (header.kid) {
442
+ if (header.kid.startsWith("did:")) {
443
+ if (payload.iss && header.kid.startsWith(payload.iss)) {
444
+ }
445
+ if (!header.kid.includes("#")) {
446
+ }
447
+ return {
448
+ method: "did",
449
+ didUrl: header.kid,
450
+ alg: header.alg
451
+ };
452
+ }
453
+ if (header.kid.startsWith("#") && payload.iss?.startsWith("did:")) {
454
+ return {
455
+ method: "did",
456
+ didUrl: `${payload.iss}${header.kid}`,
457
+ alg: header.alg
458
+ };
459
+ }
460
+ }
461
+ if (header.jwk) {
462
+ return {
463
+ alg: header.alg,
464
+ method: "jwk",
465
+ publicJwk: header.jwk
466
+ };
467
+ }
468
+ return {
469
+ method: "custom",
470
+ alg: header.alg
471
+ };
472
+ }
473
+
474
+ // src/error/Oauth2ResourceUnauthorizedError.ts
475
+ var import_utils5 = require("@openid4vc/utils");
476
+ var Oauth2ResourceUnauthorizedError = class _Oauth2ResourceUnauthorizedError extends Oauth2Error {
477
+ constructor(internalMessage, wwwAuthenticateHeaders) {
478
+ super(`${internalMessage}
479
+ ${JSON.stringify(wwwAuthenticateHeaders, null, 2)}`);
480
+ this.wwwAuthenticateHeaders = Array.isArray(wwwAuthenticateHeaders) ? wwwAuthenticateHeaders : [wwwAuthenticateHeaders];
481
+ }
482
+ static fromHeaderValue(value) {
483
+ const headers = (0, import_utils5.parseWwwAuthenticateHeader)(value);
484
+ return new _Oauth2ResourceUnauthorizedError(
485
+ void 0,
486
+ headers.map(
487
+ ({ scheme, payload: { error, error_description, scope, ...additionalPayload } }) => ({
488
+ scheme,
489
+ error: Array.isArray(error) ? error.join(",") : error ?? void 0,
490
+ error_description: Array.isArray(error_description) ? error_description.join(",") : error_description ?? void 0,
491
+ scope: Array.isArray(scope) ? scope.join(",") : scope ?? void 0,
492
+ ...additionalPayload
493
+ })
494
+ )
495
+ );
496
+ }
497
+ toHeaderValue() {
498
+ return (0, import_utils5.encodeWwwAuthenticateHeader)(
499
+ this.wwwAuthenticateHeaders.map((header) => ({
500
+ scheme: header.scheme,
501
+ payload: {
502
+ error: header.error ?? null,
503
+ error_description: header.error_description ?? null,
504
+ scope: header.scope ?? null,
505
+ ...header.additionalPayload
506
+ }
507
+ }))
508
+ );
509
+ }
510
+ };
511
+
512
+ // src/index.ts
513
+ var import_utils43 = require("@openid4vc/utils");
514
+
515
+ // src/error/Oauth2ClientErrorResponseError.ts
516
+ var Oauth2ClientErrorResponseError = class extends Oauth2Error {
517
+ constructor(message, errorResponse, response) {
518
+ super(`${message}
519
+ ${JSON.stringify(errorResponse, null, 2)}`);
520
+ this.errorResponse = errorResponse;
521
+ this.response = response.clone();
522
+ }
523
+ };
524
+
525
+ // src/error/Oauth2ClientAuthorizationChallengeError.ts
526
+ var Oauth2ClientAuthorizationChallengeError = class extends Oauth2ClientErrorResponseError {
527
+ constructor(message, errorResponse, response) {
528
+ super(message, errorResponse, response);
529
+ this.errorResponse = errorResponse;
530
+ }
531
+ };
532
+
533
+ // src/error/Oauth2ServerErrorResponseError.ts
534
+ var Oauth2ServerErrorResponseError = class extends Oauth2Error {
535
+ constructor(errorResponse, options) {
536
+ super(
537
+ `${options?.internalMessage ?? errorResponse.error_description}
538
+ ${JSON.stringify(errorResponse, null, 2)}`,
539
+ options
540
+ );
541
+ this.errorResponse = errorResponse;
542
+ this.status = options?.status ?? 400;
543
+ }
544
+ };
545
+
546
+ // src/metadata/authorization-server/v-authorization-server-metadata.ts
547
+ var import_utils6 = require("@openid4vc/utils");
548
+ var v6 = __toESM(require("valibot"));
549
+ var vAuthorizationServerMetadata = v6.pipe(
550
+ v6.looseObject({
551
+ issuer: import_utils6.vHttpsUrl,
552
+ token_endpoint: import_utils6.vHttpsUrl,
553
+ token_endpoint_auth_methods_supported: v6.optional(v6.array(v6.string())),
554
+ authorization_endpoint: v6.optional(import_utils6.vHttpsUrl),
555
+ jwks_uri: v6.optional(import_utils6.vHttpsUrl),
556
+ // RFC7636
557
+ code_challenge_methods_supported: v6.optional(v6.array(v6.string())),
558
+ // RFC9449
559
+ dpop_signing_alg_values_supported: v6.optional(v6.array(v6.string())),
560
+ // RFC9126
561
+ require_pushed_authorization_requests: v6.optional(v6.boolean()),
562
+ pushed_authorization_request_endpoint: v6.optional(import_utils6.vHttpsUrl),
563
+ // RFC9068
564
+ introspection_endpoint: v6.optional(import_utils6.vHttpsUrl),
565
+ introspection_endpoint_auth_methods_supported: v6.optional(
566
+ v6.array(v6.union([v6.literal("client_secret_jwt"), v6.literal("private_key_jwt"), v6.string()]))
567
+ ),
568
+ introspection_endpoint_auth_signing_alg_values_supported: v6.optional(v6.array(vAlgValueNotNone)),
569
+ // FiPA (no RFC yet)
570
+ authorization_challenge_endpoint: v6.optional(import_utils6.vHttpsUrl),
571
+ // From OID4VCI specification
572
+ "pre-authorized_grant_anonymous_access_supported": v6.optional(v6.boolean())
573
+ }),
574
+ v6.check(
575
+ ({
576
+ introspection_endpoint_auth_methods_supported: methodsSupported,
577
+ introspection_endpoint_auth_signing_alg_values_supported: algValuesSupported
578
+ }) => {
579
+ if (!methodsSupported) return true;
580
+ if (!methodsSupported.includes("private_key_jwt") && !methodsSupported.includes("client_secret_jwt")) return true;
581
+ return algValuesSupported !== void 0 && algValuesSupported.length > 0;
582
+ },
583
+ `Metadata value 'introspection_endpoint_auth_signing_alg_values_supported' must be defined if metadata 'introspection_endpoint_auth_methods_supported' value contains values 'private_key_jwt' or 'client_secret_jwt'`
584
+ )
585
+ );
586
+
587
+ // src/metadata/authorization-server/authorization-server-metadata.ts
588
+ var import_utils9 = require("@openid4vc/utils");
589
+
590
+ // src/metadata/fetch-well-known-metadata.ts
591
+ var import_utils7 = require("@openid4vc/utils");
592
+ var import_utils8 = require("@openid4vc/utils");
593
+
594
+ // ../utils/src/parse.ts
595
+ var v7 = __toESM(require("valibot"));
596
+
597
+ // ../utils/src/object.ts
598
+ function isObject(item) {
599
+ return item != null && typeof item === "object" && !Array.isArray(item);
600
+ }
601
+ function mergeDeep(target, ...sources) {
602
+ if (!sources.length) return target;
603
+ const source = sources.shift();
604
+ if (isObject(target) && isObject(source)) {
605
+ for (const key in source) {
606
+ if (isObject(source[key])) {
607
+ if (!target[key]) Object.assign(target, { [key]: {} });
608
+ mergeDeep(target[key], source[key]);
609
+ } else {
610
+ Object.assign(target, { [key]: source[key] });
611
+ }
612
+ }
613
+ }
614
+ return mergeDeep(target, ...sources);
615
+ }
616
+
617
+ // ../utils/src/parse.ts
618
+ function valibotRecursiveFlattenIssues(issues) {
619
+ let flattened = v7.flatten(issues);
620
+ for (const issue of issues) {
621
+ if (issue.issues) {
622
+ flattened = mergeDeep(flattened, valibotRecursiveFlattenIssues(issue.issues));
623
+ }
624
+ }
625
+ return flattened;
626
+ }
627
+
628
+ // ../utils/src/error/ValidationError.ts
629
+ var ValidationError = class extends Error {
630
+ constructor(message, valibotIssues = []) {
631
+ const errorDetails = valibotIssues.length > 0 ? JSON.stringify(valibotRecursiveFlattenIssues(valibotIssues), null, 2) : "No details provided";
632
+ super(`${message}
633
+ ${errorDetails}`);
634
+ this.valibotIssues = valibotIssues;
635
+ }
636
+ };
637
+
638
+ // src/metadata/fetch-well-known-metadata.ts
639
+ async function fetchWellKnownMetadata(wellKnownMetadataUrl, schema, fetch) {
640
+ const fetcher = (0, import_utils7.createValibotFetcher)(fetch);
641
+ const { result, response } = await fetcher(schema, import_utils7.ContentType.Json, wellKnownMetadataUrl);
642
+ if (response.status === 404) {
643
+ return null;
644
+ }
645
+ if (!response.ok) {
646
+ throw new import_utils8.InvalidFetchResponseError(
647
+ `Fetching well known metadata from '${wellKnownMetadataUrl}' resulted in an unsuccessfull response with status '${response.status}'.`,
648
+ await response.clone().text(),
649
+ response
650
+ );
651
+ }
652
+ if (!result || !result.success) {
653
+ throw new ValidationError(`Validation of metadata from '${wellKnownMetadataUrl}' failed`, result?.issues);
654
+ }
655
+ return result.output;
656
+ }
657
+
658
+ // src/metadata/authorization-server/authorization-server-metadata.ts
659
+ var wellKnownAuthorizationServerSuffix = ".well-known/oauth-authorization-server";
660
+ var wellKnownOpenIdConfigurationServerSuffix = ".well-known/openid-configuration";
661
+ async function fetchAuthorizationServerMetadata(issuer, fetch) {
662
+ const openIdConfigurationWellKnownMetadataUrl = (0, import_utils9.joinUriParts)(issuer, [wellKnownOpenIdConfigurationServerSuffix]);
663
+ const openIdConfigurationResult = await fetchWellKnownMetadata(
664
+ openIdConfigurationWellKnownMetadataUrl,
665
+ vAuthorizationServerMetadata,
666
+ fetch
667
+ );
668
+ if (openIdConfigurationResult) {
669
+ if (openIdConfigurationResult.issuer !== issuer) {
670
+ throw new Oauth2Error(
671
+ `The 'issuer' parameter '${openIdConfigurationResult.issuer}' in the well known openid configuration at '${openIdConfigurationWellKnownMetadataUrl}' does not match the provided issuer '${issuer}'.`
672
+ );
673
+ }
674
+ return openIdConfigurationResult;
675
+ }
676
+ const authorizationServerWellKnownMetadataUrl = (0, import_utils9.joinUriParts)(issuer, [wellKnownAuthorizationServerSuffix]);
677
+ const authorizationServerResult = await fetchWellKnownMetadata(
678
+ authorizationServerWellKnownMetadataUrl,
679
+ vAuthorizationServerMetadata,
680
+ fetch
681
+ );
682
+ if (authorizationServerResult) {
683
+ if (authorizationServerResult.issuer !== issuer) {
684
+ throw new Oauth2Error(
685
+ `The 'issuer' parameter '${authorizationServerResult.issuer}' in the well known authorization server metadata at '${authorizationServerWellKnownMetadataUrl}' does not match the provided issuer '${issuer}'.`
686
+ );
687
+ }
688
+ return authorizationServerResult;
689
+ }
690
+ return null;
691
+ }
692
+ function getAuthorizationServerMetadataFromList(authorizationServersMetadata, issuer) {
693
+ const authorizationServerMetadata = authorizationServersMetadata.find(
694
+ (authorizationServerMetadata2) => authorizationServerMetadata2.issuer === issuer
695
+ );
696
+ if (!authorizationServerMetadata) {
697
+ throw new Oauth2Error(
698
+ `Authorization server '${issuer}' not found in list of authorization servers. Availalbe authorization servers are ${authorizationServersMetadata.map((as) => `'${as.issuer}'`).join(", ")}`
699
+ );
700
+ }
701
+ return authorizationServerMetadata;
702
+ }
703
+
704
+ // src/metadata/fetch-jwks-uri.ts
705
+ var import_utils10 = require("@openid4vc/utils");
706
+ var import_utils11 = require("@openid4vc/utils");
707
+ async function fetchJwks(authorizationServer, fetch) {
708
+ const fetcher = (0, import_utils10.createValibotFetcher)(fetch);
709
+ const jwksUrl = authorizationServer.jwks_uri;
710
+ if (!jwksUrl) {
711
+ throw new Oauth2Error(
712
+ `Authorization server '${authorizationServer.issuer}' does not have a 'jwks_uri' parameter to fetch JWKs.`
713
+ );
714
+ }
715
+ const { result, response } = await fetcher(vJwkSet, import_utils10.ContentType.JwkSet, jwksUrl);
716
+ if (!response.ok) {
717
+ throw new import_utils11.InvalidFetchResponseError(
718
+ `Fetching JWKs from jwks_uri '${jwksUrl}' resulted in an unsuccessfull response with status code '${response.status}'.`,
719
+ await response.clone().text(),
720
+ response
721
+ );
722
+ }
723
+ if (!result || !result.success) {
724
+ throw new ValidationError(`Validation of JWKs from jwks_uri '${jwksUrl}' failed`, result?.issues);
725
+ }
726
+ return result.output;
727
+ }
728
+
729
+ // src/access-token/v-access-token-jwt.ts
730
+ var import_utils12 = require("@openid4vc/utils");
731
+ var v8 = __toESM(require("valibot"));
732
+ var vAccessTokenProfileJwtHeader = v8.looseObject({
733
+ ...vJwtHeader.entries,
734
+ typ: v8.picklist(["application/at+jwt", "at+jwt"])
735
+ });
736
+ var vAccessTokenProfileJwtPayload = v8.looseObject({
737
+ ...vJwtPayload.entries,
738
+ iss: v8.string(),
739
+ exp: import_utils12.vInteger,
740
+ iat: import_utils12.vInteger,
741
+ aud: v8.string(),
742
+ sub: v8.string(),
743
+ // REQUIRED according to RFC 9068, but OID4VCI allows anonymous access
744
+ client_id: v8.optional(v8.string()),
745
+ jti: v8.string(),
746
+ // SHOULD be included in the authorization request contained it
747
+ scope: v8.optional(v8.string())
748
+ });
749
+
750
+ // src/access-token/verify-access-token.ts
751
+ var SupportedAuthenticationScheme = /* @__PURE__ */ ((SupportedAuthenticationScheme2) => {
752
+ SupportedAuthenticationScheme2["Bearer"] = "Bearer";
753
+ SupportedAuthenticationScheme2["DPoP"] = "DPoP";
754
+ return SupportedAuthenticationScheme2;
755
+ })(SupportedAuthenticationScheme || {});
756
+ async function verifyJwtProfileAccessToken(options) {
757
+ const decodedJwt = decodeJwt({
758
+ jwt: options.accessToken,
759
+ headerSchema: vAccessTokenProfileJwtHeader,
760
+ payloadSchema: vAccessTokenProfileJwtPayload
761
+ });
762
+ const authorizationServer = options.authorizationServers.find(({ issuer }) => decodedJwt.payload.iss === issuer);
763
+ if (!authorizationServer) {
764
+ throw new Oauth2Error(
765
+ `Access token jwt contains unrecognized authorization server 'iss' value of '${decodedJwt.payload.iss}'`
766
+ );
767
+ }
768
+ const jwks = await fetchJwks(authorizationServer, options.callbacks.fetch);
769
+ const publicJwk = extractJwkFromJwksForJwt({
770
+ kid: decodedJwt.header.kid,
771
+ jwks,
772
+ use: "sig"
773
+ });
774
+ await verifyJwt({
775
+ compact: options.accessToken,
776
+ header: decodedJwt.header,
777
+ payload: decodedJwt.payload,
778
+ signer: { method: "jwk", publicJwk, alg: decodedJwt.header.alg },
779
+ verifyJwtCallback: options.callbacks.verifyJwt,
780
+ errorMessage: "Error during verification of access token jwt.",
781
+ now: options.now,
782
+ expectedAudience: options.resourceServer
783
+ });
784
+ return {
785
+ header: decodedJwt.header,
786
+ payload: decodedJwt.payload,
787
+ authorizationServer
788
+ };
789
+ }
790
+
791
+ // src/resource-request/make-resource-request.ts
792
+ var import_utils15 = require("@openid4vc/utils");
793
+
794
+ // src/dpop/dpop.ts
795
+ var import_utils14 = require("@openid4vc/utils");
796
+
797
+ // src/dpop/v-dpop.ts
798
+ var v9 = __toESM(require("valibot"));
799
+ var import_utils13 = require("@openid4vc/utils");
800
+ var vDpopJwtPayload = v9.looseObject({
801
+ ...vJwtPayload.entries,
802
+ iat: import_utils13.vInteger,
803
+ htu: import_utils13.vHttpsUrl,
804
+ htm: import_utils13.vHttpMethod,
805
+ jti: v9.string(),
806
+ // Only required when presenting in combination with access token
807
+ ath: v9.optional(v9.string())
808
+ });
809
+ var vDpopJwtHeader = v9.looseObject({
810
+ ...vJwtHeader.entries,
811
+ typ: v9.literal("dpop+jwt"),
812
+ jwk: vJwk
813
+ });
814
+
815
+ // src/dpop/dpop.ts
816
+ async function createDpopHeadersForRequest(options) {
817
+ const dpopJwt = await createDpopJwt(options);
818
+ return {
819
+ DPoP: dpopJwt
820
+ };
821
+ }
822
+ async function createDpopJwt(options) {
823
+ let ath = void 0;
824
+ if (options.accessToken) {
825
+ ath = (0, import_utils14.encodeToBase64Url)(await options.callbacks.hash((0, import_utils14.decodeUtf8String)(options.accessToken), "SHA-256" /* Sha256 */));
826
+ }
827
+ const header = (0, import_utils14.parseWithErrorHandling)(vDpopJwtHeader, {
828
+ typ: "dpop+jwt",
829
+ jwk: options.signer.publicJwk,
830
+ alg: options.signer.alg
831
+ });
832
+ const payload = (0, import_utils14.parseWithErrorHandling)(vDpopJwtPayload, {
833
+ htu: htuFromRequestUrl(options.request.url),
834
+ iat: (0, import_utils14.dateToSeconds)(options.issuedAt),
835
+ htm: options.request.method,
836
+ jti: (0, import_utils14.encodeToBase64Url)(await options.callbacks.generateRandom(32)),
837
+ ath,
838
+ nonce: options.nonce,
839
+ ...options.additionalPayload
840
+ });
841
+ const { jwt } = await options.callbacks.signJwt(options.signer, {
842
+ header,
843
+ payload
844
+ });
845
+ return jwt;
846
+ }
847
+ async function verifyDpopJwt(options) {
848
+ const { header, payload } = decodeJwt({
849
+ jwt: options.dpopJwt,
850
+ headerSchema: vDpopJwtHeader,
851
+ payloadSchema: vDpopJwtPayload
852
+ });
853
+ if (options.allowedSigningAlgs && !options.allowedSigningAlgs.includes(header.alg)) {
854
+ throw new Oauth2Error(
855
+ `dpop jwt uses alg value '${header.alg}' but allowed dpop signging alg values are ${options.allowedSigningAlgs.join(", ")}.`
856
+ );
857
+ }
858
+ if (options.expectedNonce) {
859
+ if (!payload.nonce) {
860
+ throw new Oauth2Error(`Dpop jwt does not have a nonce value, but expected nonce value '${options.expectedNonce}'`);
861
+ }
862
+ if (payload.nonce !== options.expectedNonce) {
863
+ throw new Oauth2Error(
864
+ `Dpop jwt contains nonce value '${payload.nonce}', but expected nonce value '${options.expectedNonce}'`
865
+ );
866
+ }
867
+ }
868
+ if (options.request.method !== payload.htm) {
869
+ throw new Oauth2Error(
870
+ `Dpop jwt contains htm value '${payload.htm}', but expected htm value '${options.request.method}'`
871
+ );
872
+ }
873
+ const expectedHtu = htuFromRequestUrl(options.request.url);
874
+ if (expectedHtu !== payload.htu) {
875
+ throw new Oauth2Error(`Dpop jwt contains htu value '${payload.htu}', but expected htu value '${expectedHtu}'.`);
876
+ }
877
+ if (options.accessToken) {
878
+ const expectedAth = (0, import_utils14.encodeToBase64Url)(
879
+ await options.callbacks.hash((0, import_utils14.decodeUtf8String)(options.accessToken), "SHA-256" /* Sha256 */)
880
+ );
881
+ if (!payload.ath) {
882
+ throw new Oauth2Error(`Dpop jwt does not have a ath value, but expected ath value '${expectedAth}'.`);
883
+ }
884
+ if (payload.ath !== expectedAth) {
885
+ throw new Oauth2Error(`Dpop jwt contains ath value '${payload.ath}', but expected ath value '${expectedAth}'.`);
886
+ }
887
+ }
888
+ if (options.expectedJwkThumbprint) {
889
+ const jwkThumprint = await calculateJwkThumbprint({
890
+ hashAlgorithm: "SHA-256" /* Sha256 */,
891
+ hashCallback: options.callbacks.hash,
892
+ jwk: header.jwk
893
+ });
894
+ if (options.expectedJwkThumbprint !== jwkThumprint) {
895
+ throw new Oauth2Error(
896
+ `Dpop is signed with jwk with thumbprint value '${jwkThumprint}', but expect jwk thumbprint value '${options.expectedJwkThumbprint}'`
897
+ );
898
+ }
899
+ }
900
+ await verifyJwt({
901
+ signer: {
902
+ alg: header.alg,
903
+ method: "jwk",
904
+ publicJwk: header.jwk
905
+ },
906
+ now: options.now,
907
+ header,
908
+ payload,
909
+ compact: options.dpopJwt,
910
+ verifyJwtCallback: options.callbacks.verifyJwt,
911
+ errorMessage: "dpop jwt verification failed"
912
+ });
913
+ return {
914
+ header,
915
+ payload
916
+ };
917
+ }
918
+ function htuFromRequestUrl(requestUrl) {
919
+ const htu = new import_utils14.URL(requestUrl);
920
+ htu.search = "";
921
+ htu.hash = "";
922
+ return htu.toString();
923
+ }
924
+ function extractDpopNonceFromHeaders(headers) {
925
+ return headers.get("DPoP-Nonce");
926
+ }
927
+ function extractDpopJwtFromHeaders(headers) {
928
+ const dpopJwt = headers.get("DPoP");
929
+ if (dpopJwt && (typeof dpopJwt !== "string" || dpopJwt.includes(","))) {
930
+ return { valid: false };
931
+ }
932
+ return { valid: true, dpopJwt: dpopJwt ?? void 0 };
933
+ }
934
+
935
+ // src/dpop/dpop-retry.ts
936
+ async function authorizationServerRequestWithDpopRetry(options) {
937
+ try {
938
+ return await options.request(options.dpop);
939
+ } catch (error) {
940
+ if (options.dpop && error instanceof Oauth2ClientErrorResponseError) {
941
+ const dpopRetry = shouldRetryAuthorizationServerRequestWithDPoPNonce({
942
+ responseHeaders: error.response.headers,
943
+ errorResponse: error.errorResponse
944
+ });
945
+ if (dpopRetry.retry) {
946
+ return options.request({
947
+ ...options.dpop,
948
+ nonce: dpopRetry.dpopNonce
949
+ });
950
+ }
951
+ }
952
+ throw error;
953
+ }
954
+ }
955
+ function shouldRetryAuthorizationServerRequestWithDPoPNonce(options) {
956
+ if (options.errorResponse.error !== "use_dpop_nonce") {
957
+ return {
958
+ retry: false
959
+ };
960
+ }
961
+ const dpopNonce = extractDpopNonceFromHeaders(options.responseHeaders);
962
+ if (!dpopNonce) {
963
+ throw new Oauth2Error(
964
+ `Error response error contains error 'use_dpop_nonce' but the response headers do not include a valid 'DPoP-Nonce' header value.`
965
+ );
966
+ }
967
+ return {
968
+ retry: true,
969
+ dpopNonce
970
+ };
971
+ }
972
+ function shouldRetryResourceRequestWithDPoPNonce(options) {
973
+ const useDpopNonceChallenge = options.resourceUnauthorizedError.wwwAuthenticateHeaders.find(
974
+ (challenge) => challenge.scheme === "DPoP" /* DPoP */ && challenge.error === "use_dpop_nonce" /* UseDpopNonce */
975
+ );
976
+ if (!useDpopNonceChallenge) {
977
+ return { retry: false };
978
+ }
979
+ const dpopNonce = extractDpopNonceFromHeaders(options.responseHeaders);
980
+ if (!dpopNonce || typeof dpopNonce !== "string") {
981
+ throw new Oauth2Error(
982
+ `Resource request error in 'WWW-Authenticate' response header contains error 'use_dpop_nonce' but the response headers do not include a valid 'DPoP-Nonce' value.`
983
+ );
984
+ }
985
+ return {
986
+ retry: true,
987
+ dpopNonce
988
+ };
989
+ }
990
+
991
+ // src/resource-request/make-resource-request.ts
992
+ async function resourceRequest(options) {
993
+ const dpopHeaders = options.dpop ? await createDpopHeadersForRequest({
994
+ request: {
995
+ url: options.url,
996
+ // in fetch the default is GET if not provided
997
+ method: options.requestOptions.method ?? "GET"
998
+ },
999
+ signer: options.dpop.signer,
1000
+ callbacks: options.callbacks,
1001
+ nonce: options.dpop.nonce,
1002
+ accessToken: options.accessToken
1003
+ }) : void 0;
1004
+ const fetch = options.callbacks.fetch ?? import_utils15.defaultFetcher;
1005
+ const response = await fetch(options.url, {
1006
+ ...options.requestOptions,
1007
+ headers: {
1008
+ ...options.requestOptions.headers,
1009
+ Authorization: `${dpopHeaders ? "DPoP" : "Bearer"} ${options.accessToken}`,
1010
+ ...dpopHeaders
1011
+ }
1012
+ });
1013
+ const dpopNonce = extractDpopNonceFromHeaders(response.headers);
1014
+ if (response.ok) {
1015
+ return {
1016
+ ok: true,
1017
+ response,
1018
+ dpop: dpopNonce ? {
1019
+ nonce: dpopNonce
1020
+ } : void 0
1021
+ };
1022
+ }
1023
+ const wwwAuthenticateHeader = response.headers.get("WWW-Authenticate");
1024
+ const resourceUnauthorizedError = wwwAuthenticateHeader ? Oauth2ResourceUnauthorizedError.fromHeaderValue(wwwAuthenticateHeader) : void 0;
1025
+ const shouldRetryWithNonce = options.dpop?.retryWithNonce ?? true;
1026
+ const dpopRetry = resourceUnauthorizedError ? shouldRetryResourceRequestWithDPoPNonce({
1027
+ responseHeaders: response.headers,
1028
+ resourceUnauthorizedError
1029
+ }) : void 0;
1030
+ if (shouldRetryWithNonce && dpopRetry?.retry && options.dpop) {
1031
+ return await resourceRequest({
1032
+ ...options,
1033
+ dpop: {
1034
+ ...options.dpop,
1035
+ nonce: dpopRetry.dpopNonce,
1036
+ // We'll never try multiple times (to prevent endless recursion)
1037
+ retryWithNonce: false
1038
+ }
1039
+ });
1040
+ }
1041
+ return {
1042
+ ok: false,
1043
+ response,
1044
+ dpop: dpopNonce ? {
1045
+ nonce: dpopNonce
1046
+ } : void 0,
1047
+ wwwAuthenticate: resourceUnauthorizedError?.wwwAuthenticateHeaders
1048
+ };
1049
+ }
1050
+
1051
+ // src/resource-request/verify-resource-request.ts
1052
+ var import_utils20 = require("@openid4vc/utils");
1053
+
1054
+ // src/access-token/introspect-token.ts
1055
+ var import_utils17 = require("@openid4vc/utils");
1056
+ var import_utils18 = require("@openid4vc/utils");
1057
+ var import_utils19 = require("@openid4vc/utils");
1058
+
1059
+ // src/access-token/v-token-introspection.ts
1060
+ var import_utils16 = require("@openid4vc/utils");
1061
+ var v10 = __toESM(require("valibot"));
1062
+ var vTokenIntrospectionRequest = v10.looseObject({
1063
+ token: v10.string(),
1064
+ token_type_hint: v10.optional(v10.string())
1065
+ });
1066
+ var vTokenIntrospectionResponse = v10.looseObject({
1067
+ active: v10.boolean(),
1068
+ scope: v10.optional(v10.string()),
1069
+ client_id: v10.optional(v10.string()),
1070
+ username: v10.optional(v10.string()),
1071
+ token_type: v10.optional(v10.string()),
1072
+ exp: v10.optional(import_utils16.vInteger),
1073
+ iat: v10.optional(import_utils16.vInteger),
1074
+ nbf: v10.optional(import_utils16.vInteger),
1075
+ sub: v10.optional(v10.string()),
1076
+ aud: v10.optional(v10.string()),
1077
+ iss: v10.optional(v10.string()),
1078
+ jti: v10.optional(v10.string()),
1079
+ cnf: v10.optional(vJwtConfirmationPayload)
1080
+ });
1081
+
1082
+ // src/access-token/introspect-token.ts
1083
+ async function introspectToken(options) {
1084
+ const fetchWithValibot = (0, import_utils17.createValibotFetcher)(options.callbacks.fetch);
1085
+ const introspectionRequest = (0, import_utils17.parseWithErrorHandling)(vTokenIntrospectionRequest, {
1086
+ token: options.token,
1087
+ token_type_hint: options.tokenTypeHint,
1088
+ ...options.additionalPayload
1089
+ });
1090
+ const introspectionEndpoint = options.authorizationServerMetadata.introspection_endpoint;
1091
+ if (!introspectionEndpoint) {
1092
+ throw new Oauth2Error(`Missing required 'introspection_endpoint' parameter in authorization server metadata`);
1093
+ }
1094
+ const headers = new import_utils19.Headers({
1095
+ "Content-Type": import_utils17.ContentType.XWwwFormUrlencoded
1096
+ });
1097
+ await options.callbacks.clientAuthentication({
1098
+ url: introspectionEndpoint,
1099
+ method: "POST",
1100
+ authorizationServerMetata: options.authorizationServerMetadata,
1101
+ body: introspectionRequest,
1102
+ contentType: import_utils17.ContentType.XWwwFormUrlencoded,
1103
+ headers
1104
+ });
1105
+ const { result, response } = await fetchWithValibot(
1106
+ vTokenIntrospectionResponse,
1107
+ import_utils17.ContentType.Json,
1108
+ introspectionEndpoint,
1109
+ {
1110
+ body: (0, import_utils17.objectToQueryParams)(introspectionRequest).toString(),
1111
+ method: "POST",
1112
+ headers
1113
+ }
1114
+ );
1115
+ if (!response.ok || !result?.success) {
1116
+ throw new import_utils18.InvalidFetchResponseError(
1117
+ `Unable to introspect token from '${introspectionEndpoint}'. Received response with status ${response.status}`,
1118
+ await response.clone().text(),
1119
+ response
1120
+ );
1121
+ }
1122
+ return result.output;
1123
+ }
1124
+
1125
+ // src/resource-request/verify-resource-request.ts
1126
+ async function verifyResourceRequest(options) {
1127
+ const allowedAuthenticationSchemes = options.allowedAuthenticationSchemes ?? Object.values(SupportedAuthenticationScheme);
1128
+ if (allowedAuthenticationSchemes.length === 0) {
1129
+ throw new Oauth2Error(
1130
+ `Emtpy array provided for 'allowedAuthenticationSchemes', provide at least one allowed authentication scheme, or remove the value to allow all supported authentication schemes`
1131
+ );
1132
+ }
1133
+ const authorizationHeader = options.request.headers.get("Authorization");
1134
+ if (!authorizationHeader) {
1135
+ throw new Oauth2ResourceUnauthorizedError(
1136
+ `No 'Authorization' header provided in request.`,
1137
+ allowedAuthenticationSchemes.map((scheme2) => ({ scheme: scheme2 }))
1138
+ );
1139
+ }
1140
+ const [scheme, accessToken] = authorizationHeader.split(" ", 2);
1141
+ if (!scheme || !accessToken) {
1142
+ throw new Oauth2ResourceUnauthorizedError(
1143
+ `Malformed 'Authorization' header provided in request.`,
1144
+ allowedAuthenticationSchemes.map((scheme2) => ({ scheme: scheme2 }))
1145
+ );
1146
+ }
1147
+ if (!allowedAuthenticationSchemes.includes(scheme) || scheme !== "Bearer" /* Bearer */ && scheme !== "DPoP" /* DPoP */) {
1148
+ throw new Oauth2ResourceUnauthorizedError(
1149
+ `Provided authentication scheme '${scheme}' is not allowed. Allowed authentication schemes are ${allowedAuthenticationSchemes.map((s) => `'${s}'`).join(", ")}.`,
1150
+ allowedAuthenticationSchemes.map((scheme2) => ({ scheme: scheme2 }))
1151
+ );
1152
+ }
1153
+ const verificationResult = await verifyJwtProfileAccessToken({
1154
+ accessToken,
1155
+ callbacks: options.callbacks,
1156
+ authorizationServers: options.authorizationServers,
1157
+ resourceServer: options.resourceServer,
1158
+ now: options.now
1159
+ }).catch((error) => {
1160
+ if (error instanceof Oauth2JwtParseError || error instanceof import_utils20.ValidationError) return null;
1161
+ const errorMessage = error instanceof Oauth2Error ? error.message : "Invalid access token";
1162
+ throw new Oauth2ResourceUnauthorizedError(
1163
+ `Error occured during verification of jwt profile access token: ${error.message}`,
1164
+ {
1165
+ scheme,
1166
+ error: "invalid_token" /* InvalidToken */,
1167
+ error_description: errorMessage
1168
+ }
1169
+ );
1170
+ });
1171
+ let tokenPayload = verificationResult?.payload;
1172
+ let authorizationServer = verificationResult?.authorizationServer;
1173
+ if (!tokenPayload) {
1174
+ for (const authorizationServerMetadata of options.authorizationServers) {
1175
+ try {
1176
+ tokenPayload = await introspectToken({
1177
+ authorizationServerMetadata,
1178
+ callbacks: options.callbacks,
1179
+ token: accessToken,
1180
+ tokenTypeHint: scheme
1181
+ });
1182
+ authorizationServer = authorizationServerMetadata;
1183
+ if (tokenPayload.active) break;
1184
+ } catch (error) {
1185
+ }
1186
+ }
1187
+ }
1188
+ if (!tokenPayload || !authorizationServer) {
1189
+ throw new Oauth2ResourceUnauthorizedError("Could not verify token as jwt or using token introspection.", {
1190
+ scheme,
1191
+ error: "invalid_token" /* InvalidToken */,
1192
+ error_description: "Token is not valid"
1193
+ });
1194
+ }
1195
+ let dpopJwk = void 0;
1196
+ if (scheme === "DPoP" /* DPoP */ || // two alternative methods to determine whether DPoP was used. As the user can
1197
+ // choose to include `Bearer` scheme even if DPoP was used
1198
+ tokenPayload.token_type === "DPoP" /* DPoP */ || tokenPayload.cnf?.jkt) {
1199
+ const dpopJwtResult = extractDpopJwtFromHeaders(options.request.headers);
1200
+ if (!dpopJwtResult.valid) {
1201
+ throw new Oauth2ResourceUnauthorizedError(
1202
+ `Request contains a 'DPoP' header, but the value is not a valid DPoP jwt.`,
1203
+ {
1204
+ scheme,
1205
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1206
+ error_description: `Request contains a 'DPoP' header, but the value is not a valid DPoP jwt.`
1207
+ }
1208
+ );
1209
+ }
1210
+ if (!dpopJwtResult.dpopJwt) {
1211
+ throw new Oauth2ResourceUnauthorizedError(`Request is missing required 'DPoP' header.`, {
1212
+ scheme,
1213
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1214
+ error_description: `Request is missing required 'DPoP' header.`
1215
+ });
1216
+ }
1217
+ if (!tokenPayload.cnf?.jkt) {
1218
+ throw new Oauth2ResourceUnauthorizedError(
1219
+ `Token payload is missing required 'cnf.jkt' value for DPoP verification.`,
1220
+ {
1221
+ scheme,
1222
+ error: "invalid_token" /* InvalidToken */,
1223
+ error_description: `Token payload is missing required 'cnf.jkt' value for DPoP verification.`
1224
+ }
1225
+ );
1226
+ }
1227
+ try {
1228
+ const decodedDpopJwt = await verifyDpopJwt({
1229
+ callbacks: options.callbacks,
1230
+ dpopJwt: dpopJwtResult.dpopJwt,
1231
+ request: options.request,
1232
+ accessToken,
1233
+ now: options.now,
1234
+ expectedJwkThumbprint: tokenPayload.cnf?.jkt,
1235
+ allowedSigningAlgs: authorizationServer.dpop_signing_alg_values_supported
1236
+ });
1237
+ dpopJwk = decodedDpopJwt.header.jwk;
1238
+ } catch (error) {
1239
+ const errorMessage = error instanceof Oauth2Error ? error.message : "Error verifying DPoP jwt";
1240
+ throw new Oauth2ResourceUnauthorizedError(
1241
+ `Error occured during verification of jwt profile access token: ${error instanceof Error ? error.message : error}`,
1242
+ {
1243
+ scheme,
1244
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1245
+ error_description: errorMessage
1246
+ }
1247
+ );
1248
+ }
1249
+ }
1250
+ return {
1251
+ tokenPayload,
1252
+ dpopJwk,
1253
+ scheme,
1254
+ accessToken,
1255
+ authorizationServer: authorizationServer.issuer
1256
+ };
1257
+ }
1258
+
1259
+ // src/client-authentication.ts
1260
+ var import_utils21 = require("@openid4vc/utils");
1261
+ var SupportedClientAuthenticationMethod = /* @__PURE__ */ ((SupportedClientAuthenticationMethod2) => {
1262
+ SupportedClientAuthenticationMethod2["ClientSecretBasic"] = "client_secret_basic";
1263
+ SupportedClientAuthenticationMethod2["ClientSecretPost"] = "client_secret_post";
1264
+ return SupportedClientAuthenticationMethod2;
1265
+ })(SupportedClientAuthenticationMethod || {});
1266
+ function getSupportedClientAuthenticationMethod(authorizationServer, endpointType) {
1267
+ if (endpointType === "introspection" && authorizationServer.introspection_endpoint_auth_methods_supported) {
1268
+ const supportedMethod = authorizationServer.introspection_endpoint_auth_methods_supported.find(
1269
+ (m) => Object.values(SupportedClientAuthenticationMethod).includes(m)
1270
+ );
1271
+ if (!supportedMethod) {
1272
+ throw new Oauth2Error(
1273
+ `Authorization server metadata for issuer '${authorizationServer.issuer}' has 'introspection_endpoint_auth_methods_supported' metadata, but does not contain a supported value. Supported values are '${Object.values(
1274
+ SupportedClientAuthenticationMethod
1275
+ ).join(
1276
+ ", "
1277
+ )}', found values are '${authorizationServer.introspection_endpoint_auth_methods_supported.join(", ")}'`
1278
+ );
1279
+ }
1280
+ return supportedMethod;
1281
+ }
1282
+ if (authorizationServer.token_endpoint_auth_methods_supported) {
1283
+ const supportedMethod = authorizationServer.token_endpoint_auth_methods_supported.find(
1284
+ (m) => Object.values(SupportedClientAuthenticationMethod).includes(m)
1285
+ );
1286
+ if (!supportedMethod) {
1287
+ throw new Oauth2Error(
1288
+ `Authorization server metadata for issuer '${authorizationServer.issuer}' has 'token_endpoint_auth_methods_supported' metadata, but does not contain a supported value. Supported values are '${Object.values(
1289
+ SupportedClientAuthenticationMethod
1290
+ ).join(", ")}', found values are '${authorizationServer.token_endpoint_auth_methods_supported.join(", ")}'`
1291
+ );
1292
+ }
1293
+ return supportedMethod;
1294
+ }
1295
+ return "client_secret_basic" /* ClientSecretBasic */;
1296
+ }
1297
+ function clientAuthenticationDynamic(options) {
1298
+ return (callbackOptions) => {
1299
+ const { url: url3, authorizationServerMetata } = callbackOptions;
1300
+ const endpointType = url3 === authorizationServerMetata.introspection_endpoint ? "introspection" : "endpoint";
1301
+ const method = getSupportedClientAuthenticationMethod(authorizationServerMetata, endpointType);
1302
+ if (method === "client_secret_basic" /* ClientSecretBasic */) {
1303
+ return clientAuthenticationClientSecretBasic(options)(callbackOptions);
1304
+ }
1305
+ if (method === "client_secret_post" /* ClientSecretPost */) {
1306
+ return clientAuthenticationClientSecretPost(options)(callbackOptions);
1307
+ }
1308
+ throw new Oauth2Error(
1309
+ `Unsupported client auth method ${method}. Supported values are ${Object.values(
1310
+ SupportedClientAuthenticationMethod
1311
+ ).join(", ")}`
1312
+ );
1313
+ };
1314
+ }
1315
+ function clientAuthenticationClientSecretPost(options) {
1316
+ return ({ body }) => {
1317
+ body.client_id = options.clientId;
1318
+ body.client_secret = options.clientSecret;
1319
+ };
1320
+ }
1321
+ function clientAuthenticationClientSecretBasic(options) {
1322
+ return ({ headers }) => {
1323
+ const authorization = (0, import_utils21.encodeToBase64Url)((0, import_utils21.decodeUtf8String)(`${options.clientId}:${options.clientSecret}`));
1324
+ headers.set("Authorization", `Basic ${authorization}`);
1325
+ };
1326
+ }
1327
+ function clientAuthenticationNone() {
1328
+ return () => {
1329
+ };
1330
+ }
1331
+
1332
+ // src/Oauth2AuthorizationServer.ts
1333
+ var import_utils34 = require("@openid4vc/utils");
1334
+
1335
+ // src/access-token/create-access-token.ts
1336
+ var import_utils22 = require("@openid4vc/utils");
1337
+ async function createAccessTokenJwt(options) {
1338
+ const header = (0, import_utils22.parseWithErrorHandling)(vAccessTokenProfileJwtHeader, {
1339
+ ...jwtHeaderFromJwtSigner(options.signer),
1340
+ typ: "at+jwt"
1341
+ });
1342
+ const now = options.now ?? /* @__PURE__ */ new Date();
1343
+ const payload = (0, import_utils22.parseWithErrorHandling)(vAccessTokenProfileJwtPayload, {
1344
+ iat: (0, import_utils22.dateToSeconds)(now),
1345
+ exp: (0, import_utils22.dateToSeconds)((0, import_utils22.addSecondsToDate)(now, options.expiresInSeconds)),
1346
+ aud: options.audience,
1347
+ iss: options.authorizationServer,
1348
+ jti: (0, import_utils22.encodeToBase64Url)(await options.callbacks.generateRandom(32)),
1349
+ client_id: options.clientId,
1350
+ sub: options.subject,
1351
+ scope: options.scope,
1352
+ cnf: options.dpopJwk ? {
1353
+ jkt: await calculateJwkThumbprint({
1354
+ hashAlgorithm: "SHA-256" /* Sha256 */,
1355
+ hashCallback: options.callbacks.hash,
1356
+ jwk: options.dpopJwk
1357
+ })
1358
+ } : void 0,
1359
+ ...options.additionalPayload
1360
+ });
1361
+ const { jwt } = await options.callbacks.signJwt(options.signer, {
1362
+ header,
1363
+ payload
1364
+ });
1365
+ return {
1366
+ jwt
1367
+ };
1368
+ }
1369
+
1370
+ // src/access-token/create-access-token-response.ts
1371
+ var import_utils24 = require("@openid4vc/utils");
1372
+
1373
+ // src/access-token/v-access-token.ts
1374
+ var v12 = __toESM(require("valibot"));
1375
+ var import_utils23 = require("@openid4vc/utils");
1376
+
1377
+ // src/v-grant-type.ts
1378
+ var v11 = __toESM(require("valibot"));
1379
+ var vPreAuthorizedCodeGrantIdentifier = v11.literal("urn:ietf:params:oauth:grant-type:pre-authorized_code");
1380
+ var preAuthorizedCodeGrantIdentifier = vPreAuthorizedCodeGrantIdentifier.literal;
1381
+ var vAuthorizationCodeGrantIdentifier = v11.literal("authorization_code");
1382
+ var authorizationCodeGrantIdentifier = vAuthorizationCodeGrantIdentifier.literal;
1383
+ var vRefreshTokenGrantIdentifier = v11.literal("refresh_token");
1384
+ var refreshTokenGrantIdentifier = vRefreshTokenGrantIdentifier.literal;
1385
+
1386
+ // src/access-token/v-access-token.ts
1387
+ var vAccessTokenRequest = v12.intersect([
1388
+ v12.looseObject({
1389
+ // Pre authorized code flow
1390
+ "pre-authorized_code": v12.optional(v12.string()),
1391
+ // Authorization code flow
1392
+ code: v12.optional(v12.string()),
1393
+ redirect_uri: v12.optional(v12.pipe(v12.string(), v12.url())),
1394
+ // Refresh token grant
1395
+ refresh_token: v12.optional(v12.string()),
1396
+ resource: v12.optional(import_utils23.vHttpsUrl),
1397
+ code_verifier: v12.optional(v12.string()),
1398
+ grant_type: v12.union([
1399
+ vPreAuthorizedCodeGrantIdentifier,
1400
+ vAuthorizationCodeGrantIdentifier,
1401
+ vRefreshTokenGrantIdentifier,
1402
+ // string makes the previous ones unessary, but it does help with error messages
1403
+ v12.string()
1404
+ ])
1405
+ }),
1406
+ v12.pipe(
1407
+ v12.looseObject({
1408
+ tx_code: v12.optional(v12.string()),
1409
+ // user_pin is from OID4VCI draft 11
1410
+ user_pin: v12.optional(v12.string())
1411
+ }),
1412
+ // Check that user_pin and tx_code are the same if both are provided
1413
+ // and transform user_pin to tx_code if only user_pin is provided
1414
+ v12.check(
1415
+ ({ tx_code, user_pin }) => !tx_code || !user_pin || user_pin === tx_code,
1416
+ `If both 'tx_code' and 'user_pin' are present they must match`
1417
+ ),
1418
+ v12.transform(({ tx_code, user_pin, ...rest }) => {
1419
+ return {
1420
+ ...rest,
1421
+ ...tx_code ?? user_pin ? { tx_code: tx_code ?? user_pin } : {}
1422
+ };
1423
+ })
1424
+ )
1425
+ ]);
1426
+ var vAccessTokenResponse = v12.looseObject({
1427
+ access_token: v12.string(),
1428
+ token_type: v12.string(),
1429
+ expires_in: v12.optional(v12.pipe(v12.number(), v12.integer())),
1430
+ scope: v12.optional(v12.string()),
1431
+ state: v12.optional(v12.string()),
1432
+ refresh_token: v12.optional(v12.string()),
1433
+ // Oid4vci specific parameters
1434
+ c_nonce: v12.optional(v12.string()),
1435
+ c_nonce_expires_in: v12.optional(v12.pipe(v12.number(), v12.integer())),
1436
+ // TODO: add additional params
1437
+ authorization_details: v12.optional(
1438
+ v12.array(
1439
+ v12.looseObject({
1440
+ // requried when type is openid_credential (so we probably need a discriminator)
1441
+ // credential_identifiers: v.array(v.string()),
1442
+ })
1443
+ )
1444
+ )
1445
+ });
1446
+ var vAccessTokenErrorResponse = vOauth2ErrorResponse;
1447
+
1448
+ // src/access-token/create-access-token-response.ts
1449
+ async function createAccessTokenResponse(options) {
1450
+ const accessTokenResponse = (0, import_utils24.parseWithErrorHandling)(vAccessTokenResponse, {
1451
+ access_token: options.accessToken,
1452
+ token_type: options.tokenType,
1453
+ expires_in: options.expiresInSeconds,
1454
+ c_nonce: options.cNonce,
1455
+ c_nonce_expires_in: options.cNonceExpiresIn,
1456
+ ...options.additionalPayload
1457
+ });
1458
+ return accessTokenResponse;
1459
+ }
1460
+
1461
+ // src/access-token/parse-access-token-request.ts
1462
+ var import_utils25 = require("@openid4vc/utils");
1463
+ var v13 = __toESM(require("valibot"));
1464
+ function parseAccessTokenRequest(options) {
1465
+ const parsedAccessTokenRequest = v13.safeParse(vAccessTokenRequest, options.accessTokenRequest);
1466
+ if (!parsedAccessTokenRequest.success) {
1467
+ throw new Oauth2ServerErrorResponseError({
1468
+ error: "invalid_request" /* InvalidRequest */,
1469
+ error_description: `Error occured during validation of authorization request.
1470
+ ${JSON.stringify((0, import_utils25.valibotRecursiveFlattenIssues)(parsedAccessTokenRequest.issues), null, 2)}`
1471
+ });
1472
+ }
1473
+ const accessTokenRequest = parsedAccessTokenRequest.output;
1474
+ let grant;
1475
+ if (accessTokenRequest.grant_type === preAuthorizedCodeGrantIdentifier) {
1476
+ if (!accessTokenRequest["pre-authorized_code"]) {
1477
+ throw new Oauth2ServerErrorResponseError({
1478
+ error: "invalid_request" /* InvalidRequest */,
1479
+ error_description: `Missing required 'pre-authorized_code' for grant type '${preAuthorizedCodeGrantIdentifier}'`
1480
+ });
1481
+ }
1482
+ grant = {
1483
+ grantType: preAuthorizedCodeGrantIdentifier,
1484
+ preAuthorizedCode: accessTokenRequest["pre-authorized_code"],
1485
+ txCode: accessTokenRequest.tx_code
1486
+ };
1487
+ } else if (accessTokenRequest.grant_type === authorizationCodeGrantIdentifier) {
1488
+ if (!accessTokenRequest.code) {
1489
+ throw new Oauth2ServerErrorResponseError({
1490
+ error: "invalid_request" /* InvalidRequest */,
1491
+ error_description: `Missing required 'code' for grant type '${authorizationCodeGrantIdentifier}'`
1492
+ });
1493
+ }
1494
+ grant = {
1495
+ grantType: authorizationCodeGrantIdentifier,
1496
+ code: accessTokenRequest.code
1497
+ };
1498
+ } else {
1499
+ throw new Oauth2ServerErrorResponseError({
1500
+ error: "unsupported_grant_type" /* UnsupportedGrantType */,
1501
+ error_description: `The grant type '${accessTokenRequest.grant_type}' is not supported`
1502
+ });
1503
+ }
1504
+ const extractedDpopJwt = extractDpopJwtFromHeaders(options.request.headers);
1505
+ if (!extractedDpopJwt.valid) {
1506
+ throw new Oauth2ServerErrorResponseError({
1507
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1508
+ error_description: `Request contains a 'DPoP' header, but the value is not a valid DPoP jwt`
1509
+ });
1510
+ }
1511
+ const pkceCodeVerifier = accessTokenRequest.code_verifier;
1512
+ return {
1513
+ accessTokenRequest,
1514
+ grant,
1515
+ dpopJwt: extractedDpopJwt.dpopJwt,
1516
+ pkceCodeVerifier
1517
+ };
1518
+ }
1519
+
1520
+ // src/pkce.ts
1521
+ var import_utils26 = require("@openid4vc/utils");
1522
+ var PkceCodeChallengeMethod = /* @__PURE__ */ ((PkceCodeChallengeMethod2) => {
1523
+ PkceCodeChallengeMethod2["Plain"] = "plain";
1524
+ PkceCodeChallengeMethod2["S256"] = "S256";
1525
+ return PkceCodeChallengeMethod2;
1526
+ })(PkceCodeChallengeMethod || {});
1527
+ async function createPkce(options) {
1528
+ const allowedCodeChallengeMethods = options.allowedCodeChallengeMethods ?? [
1529
+ "S256" /* S256 */,
1530
+ "plain" /* Plain */
1531
+ ];
1532
+ if (allowedCodeChallengeMethods.length === 0) {
1533
+ throw new Oauth2Error(`Unable to create PKCE code verifier. 'allowedCodeChallengeMethods' is an empty array.`);
1534
+ }
1535
+ const codeChallengeMethod = allowedCodeChallengeMethods.includes("S256" /* S256 */) ? "S256" /* S256 */ : "plain" /* Plain */;
1536
+ const codeVerifier = options.codeVerifier ?? (0, import_utils26.encodeToBase64Url)(await options.callbacks.generateRandom(64));
1537
+ return {
1538
+ codeVerifier,
1539
+ codeChallenge: await calculateCodeChallenge({
1540
+ codeChallengeMethod,
1541
+ codeVerifier,
1542
+ hashCallback: options.callbacks.hash
1543
+ }),
1544
+ codeChallengeMethod
1545
+ };
1546
+ }
1547
+ async function verifyPkce(options) {
1548
+ const calculatedCodeChallenge = await calculateCodeChallenge({
1549
+ codeChallengeMethod: options.codeChallengeMethod,
1550
+ codeVerifier: options.codeVerifier,
1551
+ hashCallback: options.callbacks.hash
1552
+ });
1553
+ if (options.codeChallenge !== calculatedCodeChallenge) {
1554
+ throw new Oauth2Error(
1555
+ `Derived code challenge '${calculatedCodeChallenge}' from code_verifier '${options.codeVerifier}' using code challenge method '${options.codeChallengeMethod}' does not match the expected code challenge.`
1556
+ );
1557
+ }
1558
+ }
1559
+ async function calculateCodeChallenge(options) {
1560
+ if (options.codeChallengeMethod === "plain" /* Plain */) {
1561
+ return options.codeVerifier;
1562
+ }
1563
+ if (options.codeChallengeMethod === "S256" /* S256 */) {
1564
+ return (0, import_utils26.encodeToBase64Url)(await options.hashCallback((0, import_utils26.decodeUtf8String)(options.codeVerifier), "SHA-256" /* Sha256 */));
1565
+ }
1566
+ throw new Oauth2Error(`Unsupported code challenge method ${options.codeChallengeMethod}`);
1567
+ }
1568
+
1569
+ // src/access-token/verify-access-token-request.ts
1570
+ async function verifyPreAuthorizedCodeAccessTokenRequest(options) {
1571
+ if (options.grant.preAuthorizedCode !== options.expectedPreAuthorizedCode) {
1572
+ throw new Oauth2ServerErrorResponseError({
1573
+ error: "invalid_grant" /* InvalidGrant */,
1574
+ error_description: `Invalid 'pre-authorized_code' provided`
1575
+ });
1576
+ }
1577
+ if (options.grant.txCode !== options.expectedTxCode) {
1578
+ if (!options.expectedTxCode) {
1579
+ throw new Oauth2ServerErrorResponseError({
1580
+ error: "invalid_request" /* InvalidRequest */,
1581
+ error_description: `Request contains 'tx_code' that was not expected`
1582
+ });
1583
+ }
1584
+ if (!options.grant.txCode) {
1585
+ throw new Oauth2ServerErrorResponseError({
1586
+ error: "invalid_request" /* InvalidRequest */,
1587
+ error_description: `Missing required 'tx_code' in request`
1588
+ });
1589
+ }
1590
+ throw new Oauth2ServerErrorResponseError({
1591
+ error: "invalid_grant" /* InvalidGrant */,
1592
+ error_description: `Invalid 'tx_code' provided`
1593
+ });
1594
+ }
1595
+ if (options.preAuthorizedCodeExpiresAt) {
1596
+ const now = options.now ?? /* @__PURE__ */ new Date();
1597
+ if (now.getTime() > options.preAuthorizedCodeExpiresAt.getTime()) {
1598
+ throw new Oauth2ServerErrorResponseError(
1599
+ {
1600
+ error: "invalid_grant" /* InvalidGrant */,
1601
+ error_description: `Expired 'pre-authorized_code' provided`
1602
+ },
1603
+ {
1604
+ internalMessage: `The provided 'pre-authorized_code' in the request expired at '${options.preAuthorizedCodeExpiresAt.getTime()}', now is '${now.getTime()}'`
1605
+ }
1606
+ );
1607
+ }
1608
+ }
1609
+ if (options.pkce) {
1610
+ await verifyAccessTokenRequestPkce(options.pkce, options.callbacks);
1611
+ }
1612
+ const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks) : null;
1613
+ return { dpopJwk: dpopResult?.dpopJwk };
1614
+ }
1615
+ async function verifyAuthorizationCodeAccessTokenRequest(options) {
1616
+ if (options.grant.code !== options.expectedCode) {
1617
+ throw new Oauth2ServerErrorResponseError({
1618
+ error: "invalid_grant" /* InvalidGrant */,
1619
+ error_description: `Invalid 'code' provided`
1620
+ });
1621
+ }
1622
+ if (options.codeExpiresAt) {
1623
+ const now = options.now ?? /* @__PURE__ */ new Date();
1624
+ if (now.getTime() > options.codeExpiresAt.getTime()) {
1625
+ throw new Oauth2ServerErrorResponseError(
1626
+ {
1627
+ error: "invalid_grant" /* InvalidGrant */,
1628
+ error_description: `Expired 'code' provided`
1629
+ },
1630
+ {
1631
+ internalMessage: `The provided 'code' in the request expired at '${options.codeExpiresAt.getTime()}', now is '${now.getTime()}'`
1632
+ }
1633
+ );
1634
+ }
1635
+ }
1636
+ if (options.pkce) {
1637
+ await verifyAccessTokenRequestPkce(options.pkce, options.callbacks);
1638
+ }
1639
+ const dpopResult = options.dpop ? await verifyAccessTokenRequestDpop(options.dpop, options.request, options.callbacks) : null;
1640
+ return { dpopJwk: dpopResult?.dpopJwk };
1641
+ }
1642
+ async function verifyAccessTokenRequestDpop(options, request, callbacks) {
1643
+ if (options.required && !options.jwt) {
1644
+ throw new Oauth2ServerErrorResponseError({
1645
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1646
+ error_description: "Missing required DPoP proof"
1647
+ });
1648
+ }
1649
+ if (!options.jwt) return null;
1650
+ try {
1651
+ const { header } = await verifyDpopJwt({
1652
+ callbacks,
1653
+ dpopJwt: options.jwt,
1654
+ request,
1655
+ allowedSigningAlgs: options.allowedSigningAlgs
1656
+ });
1657
+ return {
1658
+ dpopJwk: header.jwk
1659
+ };
1660
+ } catch (error) {
1661
+ if (error instanceof Oauth2Error) {
1662
+ throw new Oauth2ServerErrorResponseError({
1663
+ error: "invalid_dpop_proof" /* InvalidDpopProof */,
1664
+ error_description: error.message
1665
+ });
1666
+ }
1667
+ throw error;
1668
+ }
1669
+ }
1670
+ async function verifyAccessTokenRequestPkce(options, callbacks) {
1671
+ if (options.codeChallenge && !options.codeVerifier) {
1672
+ throw new Oauth2ServerErrorResponseError({
1673
+ error: "invalid_request" /* InvalidRequest */,
1674
+ error_description: `Missing required 'code_verifier' in access token request`
1675
+ });
1676
+ }
1677
+ if (!options.codeVerifier) return null;
1678
+ try {
1679
+ await verifyPkce({
1680
+ callbacks,
1681
+ codeChallenge: options.codeChallenge,
1682
+ codeChallengeMethod: options.codeChallengeMethod,
1683
+ codeVerifier: options.codeVerifier
1684
+ });
1685
+ } catch (error) {
1686
+ if (error instanceof Oauth2Error) {
1687
+ throw new Oauth2ServerErrorResponseError({
1688
+ error: "invalid_grant" /* InvalidGrant */,
1689
+ error_description: error.message
1690
+ });
1691
+ }
1692
+ throw error;
1693
+ }
1694
+ }
1695
+
1696
+ // src/authorization-challenge/create-authorization-challenge-response.ts
1697
+ var import_utils29 = require("@openid4vc/utils");
1698
+
1699
+ // src/authorization-challenge/v-authorization-challenge.ts
1700
+ var import_utils28 = require("@openid4vc/utils");
1701
+ var v15 = __toESM(require("valibot"));
1702
+
1703
+ // src/authorization-request/v-authorization-request.ts
1704
+ var import_utils27 = require("@openid4vc/utils");
1705
+ var v14 = __toESM(require("valibot"));
1706
+ var vAuthorizationRequest = v14.looseObject({
1707
+ response_type: v14.string(),
1708
+ client_id: v14.string(),
1709
+ issuer_state: v14.optional(v14.string()),
1710
+ redirect_uri: v14.optional(v14.pipe(v14.string(), v14.url())),
1711
+ resource: v14.optional(import_utils27.vHttpsUrl),
1712
+ scope: v14.optional(v14.string()),
1713
+ // DPoP jwk thumbprint
1714
+ dpop_jkt: v14.optional(v14.string()),
1715
+ code_challenge: v14.optional(v14.string()),
1716
+ code_challenge_method: v14.optional(v14.string())
1717
+ });
1718
+ var vPushedAuthorizationRequest = v14.looseObject({
1719
+ request_uri: v14.string(),
1720
+ client_id: v14.string()
1721
+ });
1722
+ var vPushedAuthorizationResponse = v14.looseObject({
1723
+ request_uri: v14.string(),
1724
+ expires_in: v14.pipe(v14.number(), v14.integer())
1725
+ });
1726
+
1727
+ // src/authorization-challenge/v-authorization-challenge.ts
1728
+ var vAuthorizationChallengeRequest = v15.looseObject({
1729
+ // authorization challenge request can include same parameters as an authorization request
1730
+ // except for response_type (always `code`), and `client_id` is optional (becase
1731
+ // it's possible to do client authentication using different methods)
1732
+ ...v15.omit(vAuthorizationRequest, ["response_type", "client_id"]).entries,
1733
+ client_id: v15.optional(vAuthorizationRequest.entries.client_id),
1734
+ auth_session: v15.optional(v15.string()),
1735
+ // DRAFT presentation during issuance
1736
+ presentation_during_issuance_session: v15.optional(v15.string())
1737
+ });
1738
+ var vAuthorizationChallengeResponse = v15.looseObject({
1739
+ authorization_code: v15.string()
1740
+ });
1741
+ var vAuthorizationChallengeErrorResponse = v15.looseObject({
1742
+ ...vOauth2ErrorResponse.entries,
1743
+ auth_session: v15.optional(v15.string()),
1744
+ request_uri: v15.optional(v15.string()),
1745
+ expires_in: v15.optional(import_utils28.vInteger),
1746
+ // DRAFT: presentation during issuance
1747
+ presentation: v15.optional(v15.string())
1748
+ });
1749
+
1750
+ // src/authorization-challenge/create-authorization-challenge-response.ts
1751
+ function createAuthorizationChallengeResponse(options) {
1752
+ const authorizationChallengeResponse = (0, import_utils29.parseWithErrorHandling)(vAuthorizationChallengeResponse, {
1753
+ ...options.additionalPayload,
1754
+ authorization_code: options.authorizationCode
1755
+ });
1756
+ return { authorizationChallengeResponse };
1757
+ }
1758
+ function createAuthorizationChallengeErrorResponse(options) {
1759
+ const authorizationChallengeErrorResponse = (0, import_utils29.parseWithErrorHandling)(vAuthorizationChallengeErrorResponse, {
1760
+ ...options.additionalPayload,
1761
+ // General FiPA
1762
+ error: options.error,
1763
+ error_description: options.errorDescription,
1764
+ auth_session: options.authSession,
1765
+ // Presentation during issuance
1766
+ presentation: options.presentation,
1767
+ // PAR
1768
+ request_uri: options.requestUri,
1769
+ expires_in: options.expiresIn
1770
+ });
1771
+ return authorizationChallengeErrorResponse;
1772
+ }
1773
+
1774
+ // src/authorization-challenge/parse-authorization-challenge-request.ts
1775
+ var import_utils30 = require("@openid4vc/utils");
1776
+ function parseAuthorizationChallengeRequest(options) {
1777
+ const authorizationChallengeRequest = (0, import_utils30.parseWithErrorHandling)(
1778
+ vAuthorizationChallengeRequest,
1779
+ options.authorizationChallengeRequest
1780
+ );
1781
+ return { authorizationChallengeRequest };
1782
+ }
1783
+
1784
+ // src/client-attestation/clent-attestation.ts
1785
+ var import_utils32 = require("@openid4vc/utils");
1786
+
1787
+ // src/client-attestation/v-client-attestation.ts
1788
+ var v16 = __toESM(require("valibot"));
1789
+ var import_utils31 = require("@openid4vc/utils");
1790
+ var vOauthClientAttestationHeader = v16.literal("OAuth-Client-Attestation");
1791
+ var oauthClientAttestationHeader = vOauthClientAttestationHeader.literal;
1792
+ var vClientAttestationJwtPayload = v16.looseObject({
1793
+ ...vJwtPayload.entries,
1794
+ iss: v16.string(),
1795
+ sub: v16.string(),
1796
+ exp: import_utils31.vInteger,
1797
+ cnf: v16.looseObject({
1798
+ jwk: vJwk,
1799
+ key_type: v16.optional(
1800
+ v16.union([
1801
+ v16.picklist(["software", "hardware", "tee", "secure_enclave", "strong_box", "secure_element", "hsm"]),
1802
+ v16.string()
1803
+ ])
1804
+ ),
1805
+ user_authentication: v16.optional(
1806
+ v16.union([
1807
+ v16.picklist(["system_biometry", "system_pin", "internal_biometry", "internal_pin", "secure_element_pin"]),
1808
+ v16.string()
1809
+ ])
1810
+ )
1811
+ }),
1812
+ aal: v16.optional(v16.string())
1813
+ });
1814
+ var vClientAttestationJwtHeader = v16.looseObject({
1815
+ ...vJwtHeader.entries,
1816
+ typ: v16.literal("oauth-client-attestation+jwt")
1817
+ });
1818
+ var vOauthClientAttestationPopHeader = v16.literal("OAuth-Client-Attestation-PoP");
1819
+ var oauthClientAttestationPopHeader = vOauthClientAttestationPopHeader.literal;
1820
+ var vClientAttestationPopJwtPayload = v16.looseObject({
1821
+ ...vJwtPayload.entries,
1822
+ iss: v16.string(),
1823
+ exp: import_utils31.vInteger,
1824
+ aud: import_utils31.vHttpsUrl,
1825
+ jti: v16.string(),
1826
+ nonce: v16.optional(v16.string())
1827
+ });
1828
+ var vClientAttestationPopJwtHeader = v16.looseObject({
1829
+ ...vJwtHeader.entries,
1830
+ typ: v16.literal("oauth-client-attestation-pop+jwt")
1831
+ });
1832
+
1833
+ // src/client-attestation/clent-attestation.ts
1834
+ async function verifyClientAttestationJwt(options) {
1835
+ const { header, payload } = decodeJwt({
1836
+ jwt: options.clientAttestationJwt,
1837
+ headerSchema: vClientAttestationJwtHeader,
1838
+ payloadSchema: vClientAttestationJwtPayload
1839
+ });
1840
+ const { signer } = await verifyJwt({
1841
+ signer: jwtSignerFromJwt({ header, payload }),
1842
+ now: options.now,
1843
+ header,
1844
+ payload,
1845
+ compact: options.clientAttestationJwt,
1846
+ verifyJwtCallback: options.callbacks.verifyJwt,
1847
+ errorMessage: "client attestation jwt verification failed"
1848
+ });
1849
+ return {
1850
+ header,
1851
+ payload,
1852
+ signer
1853
+ };
1854
+ }
1855
+ async function createClientAttestationJwt(options) {
1856
+ const header = (0, import_utils32.parseWithErrorHandling)(vClientAttestationJwtHeader, {
1857
+ typ: "oauth-client-attestation+jwt",
1858
+ ...jwtHeaderFromJwtSigner(options.signer)
1859
+ });
1860
+ const payload = (0, import_utils32.parseWithErrorHandling)(vClientAttestationJwtPayload, {
1861
+ iss: options.issuer,
1862
+ iat: (0, import_utils32.dateToSeconds)(options.issuedAt),
1863
+ exp: (0, import_utils32.dateToSeconds)(options.expiresAt),
1864
+ sub: options.clientId,
1865
+ cnf: options.confirmation,
1866
+ ...options.additionalPayload
1867
+ });
1868
+ const { jwt } = await options.callbacks.signJwt(options.signer, {
1869
+ header,
1870
+ payload
1871
+ });
1872
+ return jwt;
1873
+ }
1874
+ function extractClientAttestationJwtsFromHeaders(headers) {
1875
+ const clientAttestationHeader = headers.get(oauthClientAttestationHeader);
1876
+ const clientAttestationPopHeader = headers.get(oauthClientAttestationPopHeader);
1877
+ if (!clientAttestationHeader || clientAttestationHeader.includes(",")) {
1878
+ throw new Oauth2Error(`Missing or invalid '${oauthClientAttestationHeader}' header.`);
1879
+ }
1880
+ if (!clientAttestationPopHeader || clientAttestationPopHeader.includes(",")) {
1881
+ throw new Oauth2Error(`Missing or invalid '${oauthClientAttestationPopHeader}' header.`);
1882
+ }
1883
+ return {
1884
+ clientAttestationPopHeader,
1885
+ clientAttestationHeader
1886
+ };
1887
+ }
1888
+
1889
+ // src/client-attestation/client-attestation-pop.ts
1890
+ var import_utils33 = require("@openid4vc/utils");
1891
+ async function createClientAttestationForRequest(options) {
1892
+ const clientAttestationPopJwt = await createClientAttestationPopJwt({
1893
+ authorizationServer: options.authorizationServer,
1894
+ clientAttestation: options.clientAttestation.jwt,
1895
+ callbacks: options.callbacks,
1896
+ expiresAt: options.clientAttestation.expiresAt,
1897
+ signer: options.clientAttestation.signer,
1898
+ nonce: options.clientAttestation.nonce
1899
+ });
1900
+ return {
1901
+ headers: {
1902
+ [oauthClientAttestationHeader]: options.clientAttestation.jwt,
1903
+ [oauthClientAttestationPopHeader]: clientAttestationPopJwt
1904
+ },
1905
+ body: options.clientAttestation.includeLegacyDraft2ClientAssertion ? {
1906
+ client_assertion: `${options.clientAttestation.jwt}~${clientAttestationPopJwt}`,
1907
+ client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-client-attestation"
1908
+ } : void 0
1909
+ };
1910
+ }
1911
+ async function verifyClientAttestationPopJwt(options) {
1912
+ const { header, payload } = decodeJwt({
1913
+ jwt: options.clientAttestationPopJwt,
1914
+ headerSchema: vClientAttestationPopJwtHeader,
1915
+ payloadSchema: vClientAttestationPopJwtPayload
1916
+ });
1917
+ if (payload.iss !== options.clientAttestation.payload.sub) {
1918
+ throw new Oauth2Error(
1919
+ `Client Attestation Pop jwt contains 'iss' (client_id) value '${payload.iss}', but expected 'sub' value from client attestation '${options.clientAttestation.payload.sub}'`
1920
+ );
1921
+ }
1922
+ if (payload.aud !== options.authorizationServer) {
1923
+ throw new Oauth2Error(
1924
+ `Client Attestation Pop jwt contains 'aud' value '${payload.aud}', but expected authorization server identifier '${options.authorizationServer}'`
1925
+ );
1926
+ }
1927
+ const { signer } = await verifyJwt({
1928
+ signer: {
1929
+ alg: header.alg,
1930
+ method: "jwk",
1931
+ publicJwk: options.clientAttestation.payload.cnf.jwk
1932
+ },
1933
+ now: options.now,
1934
+ header,
1935
+ expectedNonce: options.expectedNonce,
1936
+ payload,
1937
+ compact: options.clientAttestationPopJwt,
1938
+ verifyJwtCallback: options.callbacks.verifyJwt,
1939
+ errorMessage: "client attestation pop jwt verification failed"
1940
+ });
1941
+ return {
1942
+ header,
1943
+ payload,
1944
+ signer
1945
+ };
1946
+ }
1947
+ async function createClientAttestationPopJwt(options) {
1948
+ const header = (0, import_utils33.parseWithErrorHandling)(vClientAttestationPopJwtHeader, {
1949
+ typ: "oauth-client-attestation-pop+jwt",
1950
+ alg: options.signer.alg
1951
+ });
1952
+ const clientAttestation = decodeJwt({
1953
+ jwt: options.clientAttestation,
1954
+ headerSchema: vClientAttestationJwtHeader,
1955
+ payloadSchema: vClientAttestationJwtPayload
1956
+ });
1957
+ const expiresAt = options.expiresAt ?? (0, import_utils33.addSecondsToDate)(options.issuedAt ?? /* @__PURE__ */ new Date(), 1 * 60);
1958
+ const payload = (0, import_utils33.parseWithErrorHandling)(vClientAttestationPopJwtPayload, {
1959
+ aud: options.authorizationServer,
1960
+ iss: clientAttestation.payload.sub,
1961
+ iat: (0, import_utils33.dateToSeconds)(options.issuedAt),
1962
+ exp: (0, import_utils33.dateToSeconds)(expiresAt),
1963
+ jti: (0, import_utils33.encodeToBase64Url)(await options.callbacks.generateRandom(32)),
1964
+ nonce: options.nonce,
1965
+ ...options.additionalPayload
1966
+ });
1967
+ const { jwt } = await options.callbacks.signJwt(options.signer, {
1968
+ header,
1969
+ payload
1970
+ });
1971
+ return jwt;
1972
+ }
1973
+
1974
+ // src/Oauth2AuthorizationServer.ts
1975
+ var Oauth2AuthorizationServer = class {
1976
+ constructor(options) {
1977
+ this.options = options;
1978
+ }
1979
+ createAuthorizationServerMetadata(authorizationServerMetadata) {
1980
+ return (0, import_utils34.parseWithErrorHandling)(
1981
+ vAuthorizationServerMetadata,
1982
+ authorizationServerMetadata,
1983
+ "Error validating authorization server metadata"
1984
+ );
1985
+ }
1986
+ /**
1987
+ * Parse access token request and extract the grant specific properties.
1988
+ *
1989
+ * If something goes wrong, such as the grant is not supported, missing parameters, etc,
1990
+ * it will throw `Oauth2ServerErrorResponseError` containing an error response object
1991
+ * that can be returned to the client.
1992
+ */
1993
+ parseAccessTokenRequest(options) {
1994
+ return parseAccessTokenRequest(options);
1995
+ }
1996
+ verifyPreAuthorizedCodeAccessTokenRequest(options) {
1997
+ return verifyPreAuthorizedCodeAccessTokenRequest({
1998
+ ...options,
1999
+ callbacks: this.options.callbacks
2000
+ });
2001
+ }
2002
+ verifyAuthorizationCodeAccessTokenRequest(options) {
2003
+ return verifyAuthorizationCodeAccessTokenRequest({
2004
+ ...options,
2005
+ callbacks: this.options.callbacks
2006
+ });
2007
+ }
2008
+ /**
2009
+ * Create an access token response.
2010
+ *
2011
+ * The `sub` claim can be used to identify the resource owner is subsequent requests.
2012
+ * For pre-auth flow this can be the pre-authorized_code but there are no requirements
2013
+ * on the value.
2014
+ */
2015
+ async createAccessTokenResponse(options) {
2016
+ const { jwt: accessToken } = await createAccessTokenJwt({
2017
+ audience: options.audience,
2018
+ authorizationServer: options.authorizationServer,
2019
+ callbacks: this.options.callbacks,
2020
+ expiresInSeconds: options.expiresInSeconds,
2021
+ subject: options.subject,
2022
+ scope: options.scope,
2023
+ clientId: options.clientId,
2024
+ signer: options.signer,
2025
+ dpopJwk: options.dpopJwk,
2026
+ now: options.now,
2027
+ additionalPayload: options.additionalAccessTokenPayload
2028
+ });
2029
+ return createAccessTokenResponse({
2030
+ accessToken,
2031
+ callbacks: this.options.callbacks,
2032
+ expiresInSeconds: options.expiresInSeconds,
2033
+ tokenType: options.dpopJwk ? "DPoP" : "Bearer",
2034
+ cNonce: options.cNonce,
2035
+ cNonceExpiresIn: options.cNonceExpiresIn,
2036
+ additionalPayload: options.additionalAccessTokenResponsePayload
2037
+ });
2038
+ }
2039
+ /**
2040
+ * Parse an authorization challenge request
2041
+ */
2042
+ parseAuthorizationChallengeRequest(options) {
2043
+ return parseAuthorizationChallengeRequest(options);
2044
+ }
2045
+ createAuthorizationChallengeResponse(options) {
2046
+ return createAuthorizationChallengeResponse(options);
2047
+ }
2048
+ /**
2049
+ * Create an authorization challenge error response indicating presentation of credenitals
2050
+ * using OpenID4VP is required before authorization can be granted.
2051
+ *
2052
+ * The `presentation` parameter should be an OpenID4VP authorization request url.
2053
+ * The `authSession` should be used to track the session
2054
+ */
2055
+ createAuthorizationChallengePresentationErrorResponse(options) {
2056
+ return createAuthorizationChallengeErrorResponse({
2057
+ error: "insufficient_authorization" /* InsufficientAuthorization */,
2058
+ errorDescription: options.errorDescription,
2059
+ additionalPayload: options.additionalPayload,
2060
+ authSession: options.authSession,
2061
+ presentation: options.presentation
2062
+ });
2063
+ }
2064
+ createAuthorizationChallengeErrorResponse(options) {
2065
+ return createAuthorizationChallengeErrorResponse(options);
2066
+ }
2067
+ async verifyClientAttestation({
2068
+ authorizationServer,
2069
+ headers
2070
+ }) {
2071
+ const { clientAttestationHeader, clientAttestationPopHeader } = extractClientAttestationJwtsFromHeaders(headers);
2072
+ const clientAttestation = await verifyClientAttestationJwt({
2073
+ callbacks: this.options.callbacks,
2074
+ clientAttestationJwt: clientAttestationHeader
2075
+ });
2076
+ const clientAttestationPop = await verifyClientAttestationPopJwt({
2077
+ callbacks: this.options.callbacks,
2078
+ authorizationServer,
2079
+ clientAttestation,
2080
+ clientAttestationPopJwt: clientAttestationPopHeader
2081
+ });
2082
+ return {
2083
+ clientAttestation,
2084
+ clientAttestationPop
2085
+ };
2086
+ }
2087
+ };
2088
+
2089
+ // src/Oauth2ResourceServer.ts
2090
+ var Oauth2ResourceServer = class {
2091
+ constructor(options) {
2092
+ this.options = options;
2093
+ }
2094
+ async verifyResourceRequest(options) {
2095
+ return verifyResourceRequest({
2096
+ callbacks: this.options.callbacks,
2097
+ ...options
2098
+ });
2099
+ }
2100
+ };
2101
+
2102
+ // src/Oauth2Client.ts
2103
+ var import_utils41 = require("@openid4vc/utils");
2104
+
2105
+ // src/access-token/retrieve-access-token.ts
2106
+ var import_utils35 = require("@openid4vc/utils");
2107
+ var import_utils36 = require("@openid4vc/utils");
2108
+ var v17 = __toESM(require("valibot"));
2109
+ async function retrievePreAuthorizedCodeAccessToken(options) {
2110
+ const request = {
2111
+ grant_type: preAuthorizedCodeGrantIdentifier,
2112
+ "pre-authorized_code": options.preAuthorizedCode,
2113
+ tx_code: options.txCode,
2114
+ resource: options.resource,
2115
+ ...options.additionalRequestPayload
2116
+ };
2117
+ return retrieveAccessToken({
2118
+ authorizationServerMetadata: options.authorizationServerMetadata,
2119
+ request,
2120
+ dpop: options.dpop,
2121
+ callbacks: options.callbacks,
2122
+ resource: options.resource,
2123
+ clientAttestation: options.clientAttestation
2124
+ });
2125
+ }
2126
+ async function retrieveAuthorizationCodeAccessToken(options) {
2127
+ const request = {
2128
+ grant_type: authorizationCodeGrantIdentifier,
2129
+ code: options.authorizationCode,
2130
+ code_verifier: options.pkceCodeVerifier,
2131
+ redirect_uri: options.redirectUri,
2132
+ resource: options.resource,
2133
+ ...options.additionalRequestPayload
2134
+ };
2135
+ return retrieveAccessToken({
2136
+ authorizationServerMetadata: options.authorizationServerMetadata,
2137
+ request,
2138
+ dpop: options.dpop,
2139
+ resource: options.resource,
2140
+ callbacks: options.callbacks,
2141
+ clientAttestation: options.clientAttestation
2142
+ });
2143
+ }
2144
+ async function retrieveRefreshTokenAccessToken(options) {
2145
+ const request = {
2146
+ grant_type: refreshTokenGrantIdentifier,
2147
+ refresh_token: options.refreshToken,
2148
+ resource: options.resource,
2149
+ ...options.additionalRequestPayload
2150
+ };
2151
+ return retrieveAccessToken({
2152
+ authorizationServerMetadata: options.authorizationServerMetadata,
2153
+ request,
2154
+ dpop: options.dpop,
2155
+ callbacks: options.callbacks,
2156
+ resource: options.resource,
2157
+ clientAttestation: options.clientAttestation
2158
+ });
2159
+ }
2160
+ async function retrieveAccessToken(options) {
2161
+ const fetchWithValibot = (0, import_utils35.createValibotFetcher)(options.callbacks.fetch);
2162
+ const accessTokenRequest = (0, import_utils35.parseWithErrorHandling)(
2163
+ vAccessTokenRequest,
2164
+ options.request,
2165
+ "Error validating access token request"
2166
+ );
2167
+ if (accessTokenRequest.tx_code) {
2168
+ accessTokenRequest.user_pin = accessTokenRequest.tx_code;
2169
+ }
2170
+ const clientAttestation = options.clientAttestation ? await createClientAttestationForRequest({
2171
+ authorizationServer: options.authorizationServerMetadata.issuer,
2172
+ clientAttestation: options.clientAttestation,
2173
+ callbacks: options.callbacks
2174
+ }) : void 0;
2175
+ return await authorizationServerRequestWithDpopRetry({
2176
+ dpop: options.dpop,
2177
+ request: async (dpop) => {
2178
+ const dpopHeaders = dpop ? await createDpopHeadersForRequest({
2179
+ request: {
2180
+ method: "POST",
2181
+ url: options.authorizationServerMetadata.token_endpoint
2182
+ },
2183
+ signer: dpop.signer,
2184
+ callbacks: options.callbacks,
2185
+ nonce: dpop.nonce
2186
+ }) : void 0;
2187
+ const requestQueryParams = (0, import_utils35.objectToQueryParams)({
2188
+ ...accessTokenRequest,
2189
+ ...clientAttestation?.body
2190
+ });
2191
+ const { response, result } = await fetchWithValibot(
2192
+ vAccessTokenResponse,
2193
+ import_utils35.ContentType.Json,
2194
+ options.authorizationServerMetadata.token_endpoint,
2195
+ {
2196
+ body: requestQueryParams.toString(),
2197
+ method: "POST",
2198
+ headers: {
2199
+ "Content-Type": import_utils35.ContentType.XWwwFormUrlencoded,
2200
+ ...clientAttestation?.headers,
2201
+ ...dpopHeaders
2202
+ }
2203
+ }
2204
+ );
2205
+ if (!response.ok || !result) {
2206
+ const tokenErrorResponse = v17.safeParse(
2207
+ vAccessTokenErrorResponse,
2208
+ await response.clone().json().catch(() => null)
2209
+ );
2210
+ if (tokenErrorResponse.success) {
2211
+ throw new Oauth2ClientErrorResponseError(
2212
+ `Unable to retrieve access token from '${options.authorizationServerMetadata.token_endpoint}'. Received token error response with status ${response.status}`,
2213
+ tokenErrorResponse.output,
2214
+ response
2215
+ );
2216
+ }
2217
+ throw new import_utils36.InvalidFetchResponseError(
2218
+ `Unable to retrieve access token from '${options.authorizationServerMetadata.token_endpoint}'. Received response with status ${response.status}`,
2219
+ await response.clone().text(),
2220
+ response
2221
+ );
2222
+ }
2223
+ if (!result.success) {
2224
+ throw new ValidationError("Error validating access token response", result.issues);
2225
+ }
2226
+ const dpopNonce = extractDpopNonceFromHeaders(response.headers) ?? void 0;
2227
+ return {
2228
+ dpop: dpop ? {
2229
+ ...dpop,
2230
+ nonce: dpopNonce
2231
+ } : void 0,
2232
+ accessTokenResponse: result.output
2233
+ };
2234
+ }
2235
+ });
2236
+ }
2237
+
2238
+ // src/authorization-challenge/send-authorization-challenge.ts
2239
+ var import_utils37 = require("@openid4vc/utils");
2240
+ var import_utils38 = require("@openid4vc/utils");
2241
+ var v18 = __toESM(require("valibot"));
2242
+ async function sendAuthorizationChallengeRequest(options) {
2243
+ const fetchWithValibot = (0, import_utils37.createValibotFetcher)(options.callbacks.fetch);
2244
+ const authorizationServerMetadata = options.authorizationServerMetadata;
2245
+ const authorizationChallengeEndpoint = authorizationServerMetadata.authorization_challenge_endpoint;
2246
+ if (!authorizationChallengeEndpoint) {
2247
+ throw new Oauth2Error(
2248
+ `Unable to send authorization challange. Authorization server '${authorizationServerMetadata.issuer}' has no 'authorization_challenge_endpoint'`
2249
+ );
2250
+ }
2251
+ const pkce = authorizationServerMetadata.code_challenge_methods_supported && !options.authSession ? await createPkce({
2252
+ allowedCodeChallengeMethods: authorizationServerMetadata.code_challenge_methods_supported,
2253
+ callbacks: options.callbacks,
2254
+ codeVerifier: options.pkceCodeVerifier
2255
+ }) : void 0;
2256
+ const clientAttestation = options.clientAttestation ? await createClientAttestationForRequest({
2257
+ authorizationServer: options.authorizationServerMetadata.issuer,
2258
+ clientAttestation: options.clientAttestation,
2259
+ callbacks: options.callbacks
2260
+ }) : void 0;
2261
+ const authorizationChallengeRequest = (0, import_utils37.parseWithErrorHandling)(vAuthorizationChallengeRequest, {
2262
+ ...options.additionalRequestPayload,
2263
+ auth_session: options.authSession,
2264
+ client_id: options.clientId,
2265
+ scope: options.scope,
2266
+ resource: options.resource,
2267
+ code_challenge: pkce?.codeChallenge,
2268
+ code_challenge_method: pkce?.codeChallengeMethod,
2269
+ presentation_during_issuance_session: options.presentationDuringIssuanceSession,
2270
+ ...clientAttestation?.body
2271
+ });
2272
+ return authorizationServerRequestWithDpopRetry({
2273
+ dpop: options.dpop,
2274
+ request: async (dpop) => {
2275
+ const dpopHeaders = dpop ? await createDpopHeadersForRequest({
2276
+ request: {
2277
+ method: "POST",
2278
+ url: authorizationChallengeEndpoint
2279
+ },
2280
+ signer: dpop.signer,
2281
+ callbacks: options.callbacks,
2282
+ nonce: dpop.nonce
2283
+ }) : void 0;
2284
+ const { response, result } = await fetchWithValibot(
2285
+ vAuthorizationChallengeResponse,
2286
+ import_utils37.ContentType.Json,
2287
+ authorizationChallengeEndpoint,
2288
+ {
2289
+ method: "POST",
2290
+ body: (0, import_utils37.objectToQueryParams)(authorizationChallengeRequest).toString(),
2291
+ headers: {
2292
+ ...clientAttestation?.headers,
2293
+ ...dpopHeaders,
2294
+ "Content-Type": import_utils37.ContentType.XWwwFormUrlencoded
2295
+ }
2296
+ }
2297
+ );
2298
+ if (!response.ok || !result) {
2299
+ const authorizationChallengeErrorResponse = v18.safeParse(
2300
+ vAuthorizationChallengeErrorResponse,
2301
+ await response.clone().json().catch(() => null)
2302
+ );
2303
+ if (authorizationChallengeErrorResponse.success) {
2304
+ throw new Oauth2ClientAuthorizationChallengeError(
2305
+ `Error requesting authorization code from authorization challenge endpoint '${authorizationServerMetadata.authorization_challenge_endpoint}'. Received response with status ${response.status}`,
2306
+ authorizationChallengeErrorResponse.output,
2307
+ response
2308
+ );
2309
+ }
2310
+ throw new import_utils38.InvalidFetchResponseError(
2311
+ `Error requesting authorization code from authorization challenge endpoint '${authorizationServerMetadata.authorization_challenge_endpoint}'. Received response with status ${response.status}`,
2312
+ await response.clone().text(),
2313
+ response
2314
+ );
2315
+ }
2316
+ if (!result.success) {
2317
+ throw new import_utils37.ValidationError("Error validating authorization challenge response", result.issues);
2318
+ }
2319
+ const dpopNonce = extractDpopNonceFromHeaders(response.headers) ?? void 0;
2320
+ return {
2321
+ pkce,
2322
+ dpop: dpop ? {
2323
+ ...dpop,
2324
+ nonce: dpopNonce
2325
+ } : void 0,
2326
+ authorizationChallengeResponse: result.output
2327
+ };
2328
+ }
2329
+ });
2330
+ }
2331
+
2332
+ // src/authorization-request/create-authorization-request.ts
2333
+ var import_utils39 = require("@openid4vc/utils");
2334
+ var import_utils40 = require("@openid4vc/utils");
2335
+ var v19 = __toESM(require("valibot"));
2336
+ async function createAuthorizationRequestUrl(options) {
2337
+ const authorizationServerMetadata = options.authorizationServerMetadata;
2338
+ const pushedAuthorizationRequestEndpoint = authorizationServerMetadata.pushed_authorization_request_endpoint;
2339
+ if (!authorizationServerMetadata.authorization_endpoint) {
2340
+ throw new Oauth2Error(
2341
+ `Unable to create authorization request url. Authorization server '${authorizationServerMetadata.issuer}' has no 'authorization_endpoint'`
2342
+ );
2343
+ }
2344
+ const pkce = authorizationServerMetadata.code_challenge_methods_supported ? await createPkce({
2345
+ allowedCodeChallengeMethods: authorizationServerMetadata.code_challenge_methods_supported,
2346
+ callbacks: options.callbacks,
2347
+ codeVerifier: options.pkceCodeVerifier
2348
+ }) : void 0;
2349
+ const authorizationRequest = {
2350
+ ...options.additionalRequestPayload,
2351
+ response_type: "code",
2352
+ client_id: options.clientId,
2353
+ redirect_uri: options.redirectUri,
2354
+ resource: options.resource,
2355
+ scope: options.scope,
2356
+ code_challenge: pkce?.codeChallenge,
2357
+ code_challenge_method: pkce?.codeChallengeMethod
2358
+ };
2359
+ let pushedAuthorizationRequest = void 0;
2360
+ let dpop = options.dpop;
2361
+ if (authorizationServerMetadata.require_pushed_authorization_requests || pushedAuthorizationRequestEndpoint) {
2362
+ if (!pushedAuthorizationRequestEndpoint) {
2363
+ throw new Oauth2Error(
2364
+ `Authorization server '${authorizationServerMetadata.issuer}' indicated that pushed authorization requests are required, but the 'pushed_authorization_request_endpoint' is missing in the authorization server metadata.`
2365
+ );
2366
+ }
2367
+ const clientAttestation = options.clientAttestation ? await createClientAttestationForRequest({
2368
+ authorizationServer: options.authorizationServerMetadata.issuer,
2369
+ clientAttestation: options.clientAttestation,
2370
+ callbacks: options.callbacks
2371
+ }) : void 0;
2372
+ const { pushedAuthorizationResponse, dpopNonce } = await authorizationServerRequestWithDpopRetry({
2373
+ dpop: options.dpop,
2374
+ request: async (dpop2) => {
2375
+ const dpopHeaders = dpop2 ? await createDpopHeadersForRequest({
2376
+ request: {
2377
+ method: "POST",
2378
+ url: pushedAuthorizationRequestEndpoint
2379
+ },
2380
+ signer: dpop2.signer,
2381
+ callbacks: options.callbacks,
2382
+ nonce: dpop2.nonce
2383
+ }) : void 0;
2384
+ return await pushAuthorizationRequest({
2385
+ authorizationRequest: {
2386
+ ...authorizationRequest,
2387
+ ...clientAttestation?.headers
2388
+ },
2389
+ pushedAuthorizationRequestEndpoint,
2390
+ fetch: options.callbacks.fetch,
2391
+ headers: {
2392
+ ...clientAttestation?.headers,
2393
+ ...dpopHeaders
2394
+ }
2395
+ });
2396
+ }
2397
+ });
2398
+ pushedAuthorizationRequest = {
2399
+ request_uri: pushedAuthorizationResponse.request_uri,
2400
+ client_id: authorizationRequest.client_id
2401
+ };
2402
+ if (options.dpop && dpopNonce) {
2403
+ dpop = {
2404
+ ...options.dpop,
2405
+ nonce: dpopNonce
2406
+ };
2407
+ }
2408
+ } else {
2409
+ if (options.dpop) {
2410
+ authorizationRequest.dpop_jkt = await calculateJwkThumbprint({
2411
+ hashAlgorithm: "SHA-256" /* Sha256 */,
2412
+ hashCallback: options.callbacks.hash,
2413
+ jwk: options.dpop.signer.publicJwk
2414
+ });
2415
+ }
2416
+ }
2417
+ const authorizationRequestUrl = `${authorizationServerMetadata.authorization_endpoint}?${(0, import_utils39.objectToQueryParams)(pushedAuthorizationRequest ?? authorizationRequest).toString()}`;
2418
+ return {
2419
+ authorizationRequestUrl,
2420
+ pkce,
2421
+ dpop
2422
+ };
2423
+ }
2424
+ async function pushAuthorizationRequest(options) {
2425
+ const fetchWithValibot = (0, import_utils39.createValibotFetcher)(options.fetch);
2426
+ if (options.authorizationRequest.request_uri) {
2427
+ throw new Oauth2Error(
2428
+ `Authorization request contains 'request_uri' parameter. This is not allowed for pushed authorization reuqests.`
2429
+ );
2430
+ }
2431
+ const { response, result } = await fetchWithValibot(
2432
+ vPushedAuthorizationResponse,
2433
+ import_utils39.ContentType.Json,
2434
+ options.pushedAuthorizationRequestEndpoint,
2435
+ {
2436
+ method: "POST",
2437
+ body: (0, import_utils39.objectToQueryParams)(options.authorizationRequest).toString(),
2438
+ headers: {
2439
+ ...options.headers,
2440
+ "Content-Type": import_utils39.ContentType.XWwwFormUrlencoded
2441
+ }
2442
+ }
2443
+ );
2444
+ if (!response.ok || !result) {
2445
+ const parErrorResponse = v19.safeParse(
2446
+ vOauth2ErrorResponse,
2447
+ await response.clone().json().catch(() => null)
2448
+ );
2449
+ if (parErrorResponse.success) {
2450
+ throw new Oauth2ClientErrorResponseError(
2451
+ `Unable to push authorization request to '${options.pushedAuthorizationRequestEndpoint}'. Received response with status ${response.status}`,
2452
+ parErrorResponse.output,
2453
+ response
2454
+ );
2455
+ }
2456
+ throw new import_utils40.InvalidFetchResponseError(
2457
+ `Unable to push authorization request to '${options.pushedAuthorizationRequestEndpoint}'. Received response with status ${response.status}`,
2458
+ await response.clone().text(),
2459
+ response
2460
+ );
2461
+ }
2462
+ if (!result.success) {
2463
+ throw new ValidationError("Error validating pushed authorization response", result.issues);
2464
+ }
2465
+ const dpopNonce = extractDpopNonceFromHeaders(response.headers);
2466
+ return {
2467
+ dpopNonce,
2468
+ pushedAuthorizationResponse: result.output
2469
+ };
2470
+ }
2471
+
2472
+ // src/Oauth2Client.ts
2473
+ var Oauth2Client = class {
2474
+ constructor(options) {
2475
+ this.options = options;
2476
+ }
2477
+ isDpopSupported(options) {
2478
+ if (!options.authorizationServerMetadata.dpop_signing_alg_values_supported || options.authorizationServerMetadata.dpop_signing_alg_values_supported.length === 0) {
2479
+ return {
2480
+ supported: false
2481
+ };
2482
+ }
2483
+ return {
2484
+ supported: true,
2485
+ dpopSigningAlgValuesSupported: options.authorizationServerMetadata.dpop_signing_alg_values_supported
2486
+ };
2487
+ }
2488
+ async fetchAuthorizationServerMetadata(issuer) {
2489
+ return fetchAuthorizationServerMetadata(issuer, this.options.callbacks.fetch);
2490
+ }
2491
+ /**
2492
+ * Initiate authorization.
2493
+ *
2494
+ * It will take the followings steps:
2495
+ * - if `authorization_challenge_endpoint` is defined, send an authorization challenge request
2496
+ * - if authorization challenge request returns a `redirect_to_web` error code with `request_uri`
2497
+ * then construct the authorization request url based on the `request_uri`
2498
+ * - if the `authorization_challenge_endpoint` is not defined, or authorization challenge request reuturns a `redirect_to_web` error code without `request_uri`
2499
+ * then the authorization request url will be constructed as usual (optionally using PAR).
2500
+ *
2501
+ * @throws {Oauth2ClientAuthorizationChallengeError} in case of an error response. If `error` is
2502
+ * `insufficient_authorization` possible extra steps can be taken.
2503
+ */
2504
+ async initiateAuthorization(options) {
2505
+ const pkce = options.authorizationServerMetadata.code_challenge_methods_supported ? await createPkce({
2506
+ allowedCodeChallengeMethods: options.authorizationServerMetadata.code_challenge_methods_supported,
2507
+ callbacks: this.options.callbacks,
2508
+ codeVerifier: options.pkceCodeVerifier
2509
+ }) : void 0;
2510
+ if (options.authorizationServerMetadata.authorization_challenge_endpoint) {
2511
+ try {
2512
+ await this.sendAuthorizationChallengeRequest({
2513
+ authorizationServerMetadata: options.authorizationServerMetadata,
2514
+ additionalRequestPayload: options.additionalRequestPayload,
2515
+ clientId: options.clientId,
2516
+ pkceCodeVerifier: pkce?.codeVerifier,
2517
+ scope: options.scope,
2518
+ resource: options.resource,
2519
+ clientAttestation: options.clientAttestation,
2520
+ dpop: options.dpop
2521
+ });
2522
+ } catch (error) {
2523
+ const isRecoverableError = error instanceof Oauth2ClientAuthorizationChallengeError && error.errorResponse.error === "redirect_to_web" /* RedirectToWeb */;
2524
+ if (!isRecoverableError) throw error;
2525
+ if (error.errorResponse.request_uri) {
2526
+ const authorizationRequestUrl = `${options.authorizationServerMetadata.authorization_endpoint}?${(0, import_utils41.objectToQueryParams)(
2527
+ {
2528
+ request_uri: error.errorResponse.request_uri,
2529
+ client_id: options.clientId
2530
+ }
2531
+ ).toString()}`;
2532
+ const dpopNonce = extractDpopNonceFromHeaders(error.response.headers);
2533
+ return {
2534
+ dpop: options.dpop ? {
2535
+ ...options.dpop,
2536
+ nonce: dpopNonce
2537
+ } : void 0,
2538
+ authorizationRequestUrl,
2539
+ pkce
2540
+ };
2541
+ }
2542
+ }
2543
+ }
2544
+ return this.createAuthorizationRequestUrl({
2545
+ authorizationServerMetadata: options.authorizationServerMetadata,
2546
+ clientId: options.clientId,
2547
+ additionalRequestPayload: options.additionalRequestPayload,
2548
+ redirectUri: options.redirectUri,
2549
+ scope: options.scope,
2550
+ pkceCodeVerifier: pkce?.codeVerifier,
2551
+ resource: options.resource,
2552
+ clientAttestation: options.clientAttestation,
2553
+ dpop: options.dpop
2554
+ });
2555
+ }
2556
+ sendAuthorizationChallengeRequest(options) {
2557
+ return sendAuthorizationChallengeRequest({
2558
+ ...options,
2559
+ callbacks: this.options.callbacks
2560
+ });
2561
+ }
2562
+ async createAuthorizationRequestUrl(options) {
2563
+ return createAuthorizationRequestUrl({
2564
+ authorizationServerMetadata: options.authorizationServerMetadata,
2565
+ clientId: options.clientId,
2566
+ additionalRequestPayload: options.additionalRequestPayload,
2567
+ redirectUri: options.redirectUri,
2568
+ resource: options.resource,
2569
+ scope: options.scope,
2570
+ callbacks: this.options.callbacks,
2571
+ pkceCodeVerifier: options.pkceCodeVerifier,
2572
+ clientAttestation: options.clientAttestation,
2573
+ dpop: options.dpop
2574
+ });
2575
+ }
2576
+ async retrievePreAuthorizedCodeAccessToken({
2577
+ authorizationServerMetadata,
2578
+ preAuthorizedCode,
2579
+ additionalRequestPayload,
2580
+ txCode,
2581
+ dpop,
2582
+ resource,
2583
+ clientAttestation
2584
+ }) {
2585
+ const result = await retrievePreAuthorizedCodeAccessToken({
2586
+ authorizationServerMetadata,
2587
+ preAuthorizedCode,
2588
+ txCode,
2589
+ resource,
2590
+ additionalRequestPayload: {
2591
+ ...additionalRequestPayload,
2592
+ tx_code: txCode
2593
+ },
2594
+ callbacks: this.options.callbacks,
2595
+ dpop,
2596
+ clientAttestation
2597
+ });
2598
+ return result;
2599
+ }
2600
+ async retrieveAuthorizationCodeAccessToken({
2601
+ authorizationServerMetadata,
2602
+ additionalRequestPayload,
2603
+ authorizationCode,
2604
+ pkceCodeVerifier,
2605
+ redirectUri,
2606
+ resource,
2607
+ dpop,
2608
+ clientAttestation
2609
+ }) {
2610
+ const result = await retrieveAuthorizationCodeAccessToken({
2611
+ authorizationServerMetadata,
2612
+ authorizationCode,
2613
+ pkceCodeVerifier,
2614
+ additionalRequestPayload,
2615
+ resource,
2616
+ callbacks: this.options.callbacks,
2617
+ dpop,
2618
+ redirectUri,
2619
+ clientAttestation
2620
+ });
2621
+ return result;
2622
+ }
2623
+ async retrieveRefreshTokenAccessToken({
2624
+ authorizationServerMetadata,
2625
+ additionalRequestPayload,
2626
+ refreshToken,
2627
+ resource,
2628
+ dpop,
2629
+ clientAttestation
2630
+ }) {
2631
+ const result = await retrieveRefreshTokenAccessToken({
2632
+ authorizationServerMetadata,
2633
+ refreshToken,
2634
+ additionalRequestPayload,
2635
+ resource,
2636
+ callbacks: this.options.callbacks,
2637
+ dpop,
2638
+ clientAttestation
2639
+ });
2640
+ return result;
2641
+ }
2642
+ async resourceRequest(options) {
2643
+ return resourceRequest(options);
2644
+ }
2645
+ /**
2646
+ * @todo move this to another class?
2647
+ */
2648
+ async createClientAttestationJwt(options) {
2649
+ return await createClientAttestationJwt({
2650
+ callbacks: this.options.callbacks,
2651
+ ...options
2652
+ });
2653
+ }
2654
+ };
2655
+ // Annotate the CommonJS export names for ESM import in node:
2656
+ 0 && (module.exports = {
2657
+ HashAlgorithm,
2658
+ InvalidFetchResponseError,
2659
+ Oauth2AuthorizationServer,
2660
+ Oauth2Client,
2661
+ Oauth2ClientAuthorizationChallengeError,
2662
+ Oauth2ClientErrorResponseError,
2663
+ Oauth2Error,
2664
+ Oauth2ErrorCodes,
2665
+ Oauth2JwtParseError,
2666
+ Oauth2JwtVerificationError,
2667
+ Oauth2ResourceServer,
2668
+ Oauth2ResourceUnauthorizedError,
2669
+ Oauth2ServerErrorResponseError,
2670
+ PkceCodeChallengeMethod,
2671
+ SupportedAuthenticationScheme,
2672
+ authorizationCodeGrantIdentifier,
2673
+ calculateJwkThumbprint,
2674
+ clientAuthenticationClientSecretBasic,
2675
+ clientAuthenticationClientSecretPost,
2676
+ clientAuthenticationDynamic,
2677
+ clientAuthenticationNone,
2678
+ decodeJwt,
2679
+ fetchAuthorizationServerMetadata,
2680
+ fetchJwks,
2681
+ fetchWellKnownMetadata,
2682
+ getAuthorizationServerMetadataFromList,
2683
+ getGlobalConfig,
2684
+ isJwkInSet,
2685
+ jwtHeaderFromJwtSigner,
2686
+ jwtSignerFromJwt,
2687
+ preAuthorizedCodeGrantIdentifier,
2688
+ refreshTokenGrantIdentifier,
2689
+ resourceRequest,
2690
+ setGlobalConfig,
2691
+ vAuthorizationCodeGrantIdentifier,
2692
+ vAuthorizationServerMetadata,
2693
+ vCompactJwt,
2694
+ vJwk,
2695
+ vJwtHeader,
2696
+ vJwtPayload,
2697
+ vOauth2ErrorResponse,
2698
+ vPreAuthorizedCodeGrantIdentifier,
2699
+ vRefreshTokenGrantIdentifier,
2700
+ verifyJwt,
2701
+ verifyResourceRequest
2702
+ });
2703
+ //# sourceMappingURL=index.js.map