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