@openid4vc/oauth2 0.4.4-alpha-20260105092906 → 0.4.4-alpha-20260106132628

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 CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ContentType, Headers, InvalidFetchResponseError, InvalidFetchResponseError as InvalidFetchResponseError$1, OpenId4VcBaseError, URL, ValidationError, addSecondsToDate, createFetcher, createZodFetcher, dateToSeconds, decodeBase64, decodeUtf8String, encodeToBase64Url, encodeToUtf8String, encodeWwwAuthenticateHeader, formatZodError, getGlobalConfig, joinUriParts, objectToQueryParams, parseWithErrorHandling, parseWwwAuthenticateHeader, setGlobalConfig, stringToJsonWithErrorHandling, zHttpMethod, zHttpsUrl, zInteger } from "@openid4vc/utils";
2
2
  import z$1, { z } from "zod";
3
+ import "zod/v4/core";
3
4
 
4
5
  //#region src/callbacks.ts
5
6
  /**
@@ -347,6 +348,533 @@ async function verifyJwt(options) {
347
348
  } };
348
349
  }
349
350
 
351
+ //#endregion
352
+ //#region ../../node_modules/.pnpm/zod-validation-error@5.0.0_zod@4.3.5/node_modules/zod-validation-error/v4/index.mjs
353
+ function isZodErrorLike(err) {
354
+ return err instanceof Object && "name" in err && (err.name === "ZodError" || err.name === "$ZodError") && "issues" in err && Array.isArray(err.issues);
355
+ }
356
+ var ZOD_VALIDATION_ERROR_NAME = "ZodValidationError";
357
+ var ValidationError$2 = class extends Error {
358
+ name;
359
+ details;
360
+ constructor(message, options) {
361
+ super(message, options);
362
+ this.name = ZOD_VALIDATION_ERROR_NAME;
363
+ this.details = getIssuesFromErrorOptions(options);
364
+ }
365
+ toString() {
366
+ return this.message;
367
+ }
368
+ };
369
+ function getIssuesFromErrorOptions(options) {
370
+ if (options) {
371
+ const cause = options.cause;
372
+ if (isZodErrorLike(cause)) return cause.issues;
373
+ }
374
+ return [];
375
+ }
376
+ function parseCustomIssue(issue) {
377
+ return {
378
+ type: issue.code,
379
+ path: issue.path,
380
+ message: issue.message ?? "Invalid input"
381
+ };
382
+ }
383
+ function parseInvalidElementIssue(issue) {
384
+ return {
385
+ type: issue.code,
386
+ path: issue.path,
387
+ message: `unexpected element in ${issue.origin}`
388
+ };
389
+ }
390
+ function parseInvalidKeyIssue(issue) {
391
+ return {
392
+ type: issue.code,
393
+ path: issue.path,
394
+ message: `unexpected key in ${issue.origin}`
395
+ };
396
+ }
397
+ var vowelSoundCharSet = /* @__PURE__ */ new Set([
398
+ "a",
399
+ "e",
400
+ "i",
401
+ "o",
402
+ "u",
403
+ "h"
404
+ ]);
405
+ function prependWithAOrAn(value) {
406
+ const firstLetter = value.charAt(0).toLowerCase();
407
+ return [vowelSoundCharSet.has(firstLetter) ? "an" : "a", value].join(" ");
408
+ }
409
+ function stringifySymbol(symbol) {
410
+ return symbol.description ?? "";
411
+ }
412
+ function stringify(value, options = {}) {
413
+ switch (typeof value) {
414
+ case "symbol": return stringifySymbol(value);
415
+ case "bigint":
416
+ case "number": switch (options.localization) {
417
+ case true: return value.toLocaleString();
418
+ case false: return value.toString();
419
+ default: return value.toLocaleString(options.localization);
420
+ }
421
+ case "string":
422
+ if (options.wrapStringValueInQuote) return `"${value}"`;
423
+ return value;
424
+ default:
425
+ if (value instanceof Date) switch (options.localization) {
426
+ case true: return value.toLocaleString();
427
+ case false: return value.toISOString();
428
+ default: return value.toLocaleString(options.localization);
429
+ }
430
+ return String(value);
431
+ }
432
+ }
433
+ function parseInvalidStringFormatIssue(issue, options) {
434
+ let message = "";
435
+ switch (issue.format) {
436
+ case "lowercase":
437
+ case "uppercase":
438
+ message += `expected ${issue.format} string`;
439
+ break;
440
+ case "starts_with":
441
+ message += `expected string to start with "${issue.prefix}"`;
442
+ break;
443
+ case "ends_with":
444
+ message += `expected string to end with "${issue.suffix}"`;
445
+ break;
446
+ case "includes":
447
+ message += `expected string to include "${issue.includes}"`;
448
+ break;
449
+ case "regex":
450
+ message += "expected string to match pattern";
451
+ if (options.displayInvalidFormatDetails) message += ` "${issue.pattern}"`;
452
+ break;
453
+ case "jwt":
454
+ message += "expected a jwt";
455
+ if (options.displayInvalidFormatDetails && issue.inst && "alg" in issue.inst._zod.def) message += `/${issue.inst._zod.def.alg}`;
456
+ message += " token";
457
+ break;
458
+ case "email":
459
+ message += "expected an email address";
460
+ break;
461
+ case "url":
462
+ case "uuid":
463
+ case "guid":
464
+ case "cuid":
465
+ case "cuid2":
466
+ case "ulid":
467
+ case "xid":
468
+ case "ksuid":
469
+ message += `expected a ${issue.format.toUpperCase()}`;
470
+ if (issue.inst && "version" in issue.inst._zod.def) message += ` ${issue.inst._zod.def.version}`;
471
+ break;
472
+ case "date":
473
+ case "datetime":
474
+ case "time":
475
+ case "duration":
476
+ message += `expected an ISO ${issue.format}`;
477
+ break;
478
+ case "ipv4":
479
+ case "ipv6":
480
+ message += `expected an ${issue.format.slice(0, 2).toUpperCase()}${issue.format.slice(2)} address`;
481
+ break;
482
+ case "cidrv4":
483
+ case "cidrv6":
484
+ message += `expected a ${issue.format.slice(0, 4).toUpperCase()}${issue.format.slice(4)} address range`;
485
+ break;
486
+ case "base64":
487
+ case "base64url":
488
+ message += `expected a ${issue.format} encoded string`;
489
+ break;
490
+ case "e164":
491
+ message += "expected an E.164 formatted phone number";
492
+ break;
493
+ default:
494
+ if (issue.format.startsWith("sha") || issue.format.startsWith("md5")) {
495
+ const [alg, encoding] = issue.format.split("_");
496
+ message += `expected a ${alg.toUpperCase()}`;
497
+ if (encoding) message += ` ${encoding}-encoded`;
498
+ message += ` hash`;
499
+ break;
500
+ }
501
+ message += `expected ${prependWithAOrAn(issue.format)}`;
502
+ }
503
+ if ("input" in issue && options.reportInput === "typeAndValue") {
504
+ const valueStr = stringify(issue.input, {
505
+ wrapStringValueInQuote: true,
506
+ localization: options.numberLocalization
507
+ });
508
+ message += `, received ${valueStr}`;
509
+ }
510
+ return {
511
+ type: issue.code,
512
+ path: issue.path,
513
+ message
514
+ };
515
+ }
516
+ function isPrimitive(value) {
517
+ if (value === null) return true;
518
+ switch (typeof value) {
519
+ case "string":
520
+ case "number":
521
+ case "bigint":
522
+ case "boolean":
523
+ case "symbol":
524
+ case "undefined": return true;
525
+ default: return false;
526
+ }
527
+ }
528
+ function parseInvalidTypeIssue(issue, options) {
529
+ let message = `expected ${issue.expected}`;
530
+ if ("input" in issue && options.reportInput !== false) {
531
+ const value = issue.input;
532
+ message += `, received ${getTypeName(value)}`;
533
+ if (options.reportInput === "typeAndValue") {
534
+ if (isPrimitive(value)) {
535
+ const valueStr = stringify(value, {
536
+ wrapStringValueInQuote: true,
537
+ localization: options.numberLocalization
538
+ });
539
+ message += ` (${valueStr})`;
540
+ } else if (value instanceof Date) {
541
+ const valueStr = stringify(value, { localization: options.dateLocalization });
542
+ message += ` (${valueStr})`;
543
+ }
544
+ }
545
+ }
546
+ return {
547
+ type: issue.code,
548
+ path: issue.path,
549
+ message
550
+ };
551
+ }
552
+ function getTypeName(value) {
553
+ if (typeof value === "object") {
554
+ if (value === null) return "null";
555
+ if (value === void 0) return "undefined";
556
+ if (Array.isArray(value)) return "array";
557
+ if (value instanceof Date) return "date";
558
+ if (value instanceof RegExp) return "regexp";
559
+ if (value instanceof Map) return "map";
560
+ if (value instanceof Set) return "set";
561
+ if (value instanceof Error) return "error";
562
+ if (value instanceof Function) return "function";
563
+ return "object";
564
+ }
565
+ return typeof value;
566
+ }
567
+ function parseInvalidUnionIssue(issue) {
568
+ return {
569
+ type: issue.code,
570
+ path: issue.path,
571
+ message: issue.message ?? "Invalid input"
572
+ };
573
+ }
574
+ function joinValues(values, options) {
575
+ const valuesToDisplay = (options.maxValuesToDisplay ? values.slice(0, options.maxValuesToDisplay) : values).map((value) => {
576
+ return stringify(value, { wrapStringValueInQuote: options.wrapStringValuesInQuote });
577
+ });
578
+ if (valuesToDisplay.length < values.length) valuesToDisplay.push(`${values.length - valuesToDisplay.length} more value(s)`);
579
+ return valuesToDisplay.reduce((acc, value, index) => {
580
+ if (index > 0) if (index === valuesToDisplay.length - 1 && options.lastSeparator) acc += options.lastSeparator;
581
+ else acc += options.separator;
582
+ acc += value;
583
+ return acc;
584
+ }, "");
585
+ }
586
+ function parseInvalidValueIssue(issue, options) {
587
+ let message;
588
+ if (issue.expected === "stringbool") message = "expected boolean as string";
589
+ else if (issue.values.length === 0) message = "invalid value";
590
+ else if (issue.values.length === 1) message = `expected value to be ${stringify(issue.values[0], { wrapStringValueInQuote: true })}`;
591
+ else message = `expected value to be one of ${joinValues(issue.values, {
592
+ separator: options.allowedValuesSeparator,
593
+ lastSeparator: options.allowedValuesLastSeparator,
594
+ wrapStringValuesInQuote: options.wrapAllowedValuesInQuote,
595
+ maxValuesToDisplay: options.maxAllowedValuesToDisplay
596
+ })}`;
597
+ if ("input" in issue && options.reportInput === "typeAndValue") {
598
+ if (isPrimitive(issue.input)) {
599
+ const valueStr = stringify(issue.input, {
600
+ wrapStringValueInQuote: true,
601
+ localization: options.numberLocalization
602
+ });
603
+ message += `, received ${valueStr}`;
604
+ } else if (issue.input instanceof Date) {
605
+ const valueStr = stringify(issue.input, { localization: options.dateLocalization });
606
+ message += `, received ${valueStr}`;
607
+ }
608
+ }
609
+ return {
610
+ type: issue.code,
611
+ path: issue.path,
612
+ message
613
+ };
614
+ }
615
+ function parseNotMultipleOfIssue(issue, options) {
616
+ let message = `expected multiple of ${issue.divisor}`;
617
+ if ("input" in issue && options.reportInput === "typeAndValue") {
618
+ const valueStr = stringify(issue.input, {
619
+ wrapStringValueInQuote: true,
620
+ localization: options.numberLocalization
621
+ });
622
+ message += `, received ${valueStr}`;
623
+ }
624
+ return {
625
+ type: issue.code,
626
+ path: issue.path,
627
+ message
628
+ };
629
+ }
630
+ function parseTooBigIssue(issue, options) {
631
+ const maxValueStr = issue.origin === "date" ? stringify(new Date(issue.maximum), { localization: options.dateLocalization }) : stringify(issue.maximum, { localization: options.numberLocalization });
632
+ let message = "";
633
+ switch (issue.origin) {
634
+ case "number":
635
+ case "int":
636
+ case "bigint":
637
+ message += `expected number to be less than${issue.inclusive ? " or equal to" : ""} ${maxValueStr}`;
638
+ break;
639
+ case "string":
640
+ message += `expected string to contain at most ${maxValueStr} character(s)`;
641
+ break;
642
+ case "date":
643
+ message += `expected date to be prior ${issue.inclusive ? "or equal to" : "to"} "${maxValueStr}"`;
644
+ break;
645
+ case "array":
646
+ message += `expected array to contain at most ${maxValueStr} item(s)`;
647
+ break;
648
+ case "set":
649
+ message += `expected set to contain at most ${maxValueStr} item(s)`;
650
+ break;
651
+ case "file":
652
+ message += `expected file to not exceed ${maxValueStr} byte(s) in size`;
653
+ break;
654
+ default: message += `expected value to be less than${issue.inclusive ? " or equal to" : ""} ${maxValueStr}`;
655
+ }
656
+ if ("input" in issue && options.reportInput === "typeAndValue") {
657
+ const value = issue.input;
658
+ if (isPrimitive(value)) {
659
+ const valueStr = stringify(value, {
660
+ wrapStringValueInQuote: true,
661
+ localization: options.numberLocalization
662
+ });
663
+ message += `, received ${valueStr}`;
664
+ } else if (value instanceof Date) {
665
+ const valueStr = stringify(value, { localization: options.dateLocalization });
666
+ message += `, received ${valueStr}`;
667
+ }
668
+ }
669
+ return {
670
+ type: issue.code,
671
+ path: issue.path,
672
+ message
673
+ };
674
+ }
675
+ function parseTooSmallIssue(issue, options) {
676
+ const minValueStr = issue.origin === "date" ? stringify(new Date(issue.minimum), { localization: options.dateLocalization }) : stringify(issue.minimum, { localization: options.numberLocalization });
677
+ let message = "";
678
+ switch (issue.origin) {
679
+ case "number":
680
+ case "int":
681
+ case "bigint":
682
+ message += `expected number to be greater than${issue.inclusive ? " or equal to" : ""} ${minValueStr}`;
683
+ break;
684
+ case "date":
685
+ message += `expected date to be ${issue.inclusive ? "later or equal to" : "later to"} "${minValueStr}"`;
686
+ break;
687
+ case "string":
688
+ message += `expected string to contain at least ${minValueStr} character(s)`;
689
+ break;
690
+ case "array":
691
+ message += `expected array to contain at least ${minValueStr} item(s)`;
692
+ break;
693
+ case "set":
694
+ message += `expected set to contain at least ${minValueStr} item(s)`;
695
+ break;
696
+ case "file":
697
+ message += `expected file to be at least ${minValueStr} byte(s) in size`;
698
+ break;
699
+ default: message += `expected value to be greater than${issue.inclusive ? " or equal to" : ""} ${minValueStr}`;
700
+ }
701
+ if ("input" in issue && options.reportInput === "typeAndValue") {
702
+ const value = issue.input;
703
+ if (isPrimitive(value)) {
704
+ const valueStr = stringify(value, {
705
+ wrapStringValueInQuote: true,
706
+ localization: options.numberLocalization
707
+ });
708
+ message += `, received ${valueStr}`;
709
+ } else if (value instanceof Date) {
710
+ const valueStr = stringify(value, { localization: options.dateLocalization });
711
+ message += `, received ${valueStr}`;
712
+ }
713
+ }
714
+ return {
715
+ type: issue.code,
716
+ path: issue.path,
717
+ message
718
+ };
719
+ }
720
+ function parseUnrecognizedKeysIssue(issue, options) {
721
+ const keysStr = joinValues(issue.keys, {
722
+ separator: options.unrecognizedKeysSeparator,
723
+ lastSeparator: options.unrecognizedKeysLastSeparator,
724
+ wrapStringValuesInQuote: options.wrapUnrecognizedKeysInQuote,
725
+ maxValuesToDisplay: options.maxUnrecognizedKeysToDisplay
726
+ });
727
+ return {
728
+ type: issue.code,
729
+ path: issue.path,
730
+ message: `unrecognized key(s) ${keysStr} in object`
731
+ };
732
+ }
733
+ var issueParsers = {
734
+ invalid_type: parseInvalidTypeIssue,
735
+ too_big: parseTooBigIssue,
736
+ too_small: parseTooSmallIssue,
737
+ invalid_format: parseInvalidStringFormatIssue,
738
+ invalid_value: parseInvalidValueIssue,
739
+ invalid_element: parseInvalidElementIssue,
740
+ not_multiple_of: parseNotMultipleOfIssue,
741
+ unrecognized_keys: parseUnrecognizedKeysIssue,
742
+ invalid_key: parseInvalidKeyIssue,
743
+ custom: parseCustomIssue,
744
+ invalid_union: parseInvalidUnionIssue
745
+ };
746
+ var defaultErrorMapOptions = {
747
+ reportInput: "type",
748
+ displayInvalidFormatDetails: false,
749
+ allowedValuesSeparator: ", ",
750
+ allowedValuesLastSeparator: " or ",
751
+ wrapAllowedValuesInQuote: true,
752
+ maxAllowedValuesToDisplay: 10,
753
+ unrecognizedKeysSeparator: ", ",
754
+ unrecognizedKeysLastSeparator: " and ",
755
+ wrapUnrecognizedKeysInQuote: true,
756
+ maxUnrecognizedKeysToDisplay: 5,
757
+ dateLocalization: true,
758
+ numberLocalization: true
759
+ };
760
+ function createErrorMap(partialOptions = {}) {
761
+ const options = {
762
+ ...defaultErrorMapOptions,
763
+ ...partialOptions
764
+ };
765
+ const errorMap = (issue) => {
766
+ if (issue.code === void 0) return "Not supported issue type";
767
+ const parseFunc = issueParsers[issue.code];
768
+ return parseFunc(issue, options).message;
769
+ };
770
+ return errorMap;
771
+ }
772
+ function isNonEmptyArray(value) {
773
+ return value.length !== 0;
774
+ }
775
+ var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
776
+ function joinPath(path) {
777
+ if (path.length === 1) {
778
+ let propertyKey = path[0];
779
+ if (typeof propertyKey === "symbol") propertyKey = stringifySymbol(propertyKey);
780
+ return propertyKey.toString() || "\"\"";
781
+ }
782
+ return path.reduce((acc, propertyKey) => {
783
+ if (typeof propertyKey === "number") return acc + "[" + propertyKey.toString() + "]";
784
+ if (typeof propertyKey === "symbol") propertyKey = stringifySymbol(propertyKey);
785
+ if (propertyKey.includes("\"")) return acc + "[\"" + escapeQuotes(propertyKey) + "\"]";
786
+ if (!identifierRegex.test(propertyKey)) return acc + "[\"" + propertyKey + "\"]";
787
+ return acc + (acc.length === 0 ? "" : ".") + propertyKey;
788
+ }, "");
789
+ }
790
+ function escapeQuotes(str) {
791
+ return str.replace(/"/g, "\\\"");
792
+ }
793
+ function titleCase(value) {
794
+ if (value.length === 0) return value;
795
+ return value.charAt(0).toUpperCase() + value.slice(1);
796
+ }
797
+ var defaultMessageBuilderOptions = {
798
+ prefix: "Validation error",
799
+ prefixSeparator: ": ",
800
+ maxIssuesInMessage: 99,
801
+ unionSeparator: " or ",
802
+ issueSeparator: "; ",
803
+ includePath: true,
804
+ forceTitleCase: true
805
+ };
806
+ function createMessageBuilder(partialOptions = {}) {
807
+ const options = {
808
+ ...defaultMessageBuilderOptions,
809
+ ...partialOptions
810
+ };
811
+ return function messageBuilder(issues) {
812
+ return conditionallyPrefixMessage(issues.slice(0, options.maxIssuesInMessage).map((issue) => mapIssue(issue, options)).join(options.issueSeparator), options);
813
+ };
814
+ }
815
+ function mapIssue(issue, options) {
816
+ if (issue.code === "invalid_union" && isNonEmptyArray(issue.errors)) {
817
+ const individualMessages = issue.errors.map((issues) => issues.map((subIssue) => mapIssue({
818
+ ...subIssue,
819
+ path: issue.path.concat(subIssue.path)
820
+ }, options)).join(options.issueSeparator));
821
+ return Array.from(new Set(individualMessages)).join(options.unionSeparator);
822
+ }
823
+ const buf = [];
824
+ if (options.forceTitleCase) buf.push(titleCase(issue.message));
825
+ else buf.push(issue.message);
826
+ pathCondition: if (options.includePath && issue.path !== void 0 && isNonEmptyArray(issue.path)) {
827
+ if (issue.path.length === 1) {
828
+ const identifier = issue.path[0];
829
+ if (typeof identifier === "number") {
830
+ buf.push(` at index ${identifier}`);
831
+ break pathCondition;
832
+ }
833
+ }
834
+ buf.push(` at "${joinPath(issue.path)}"`);
835
+ }
836
+ return buf.join("");
837
+ }
838
+ function conditionallyPrefixMessage(message, options) {
839
+ if (options.prefix != null) {
840
+ if (message.length > 0) return [options.prefix, message].join(options.prefixSeparator);
841
+ return options.prefix;
842
+ }
843
+ if (message.length > 0) return message;
844
+ return defaultMessageBuilderOptions.prefix;
845
+ }
846
+ function fromZodErrorWithoutRuntimeCheck(zodError, options = {}) {
847
+ const zodIssues = zodError.issues;
848
+ let message;
849
+ if (isNonEmptyArray(zodIssues)) message = createMessageBuilderFromOptions(options)(zodIssues);
850
+ else message = zodError.message;
851
+ return new ValidationError$2(message, { cause: zodError });
852
+ }
853
+ function createMessageBuilderFromOptions(options) {
854
+ if ("messageBuilder" in options) return options.messageBuilder;
855
+ return createMessageBuilder(options);
856
+ }
857
+ var toValidationError = (options = {}) => (err) => {
858
+ if (isZodErrorLike(err)) return fromZodErrorWithoutRuntimeCheck(err, options);
859
+ if (err instanceof Error) return new ValidationError$2(err.message, { cause: err });
860
+ return new ValidationError$2("Unknown error");
861
+ };
862
+ function fromError(err, options = {}) {
863
+ return toValidationError(options)(err);
864
+ }
865
+
866
+ //#endregion
867
+ //#region ../utils/src/zod-error.ts
868
+ z$1.config({ customError: createErrorMap() });
869
+ function formatZodError$1(error) {
870
+ if (!error) return "";
871
+ return fromError(error, {
872
+ prefix: "",
873
+ prefixSeparator: "✖ ",
874
+ issueSeparator: "\n✖ "
875
+ }).toString();
876
+ }
877
+
350
878
  //#endregion
351
879
  //#region ../utils/src/error/OpenId4VcBaseError.ts
352
880
  var OpenId4VcBaseError$1 = class extends Error {};
@@ -356,7 +884,7 @@ var OpenId4VcBaseError$1 = class extends Error {};
356
884
  var ValidationError$1 = class extends OpenId4VcBaseError$1 {
357
885
  constructor(message, zodError) {
358
886
  super(message);
359
- this.message = `${message}\n${zodError ? z$1.prettifyError(zodError) : ""}`;
887
+ this.message = `${message}\n${zodError ? formatZodError$1(zodError) : ""}`;
360
888
  Object.defineProperty(this, "zodError", {
361
889
  value: zodError,
362
890
  writable: false,
@@ -1074,12 +1602,14 @@ function parsePushedAuthorizationRequestUriReferenceValue(options) {
1074
1602
  const zAuthorizationResponse = z$1.object({
1075
1603
  state: z$1.string().optional(),
1076
1604
  code: z$1.string().nonempty(),
1605
+ iss: zHttpsUrl.optional(),
1077
1606
  error: z$1.optional(z$1.never())
1078
1607
  }).loose();
1079
1608
  const zAuthorizationResponseFromUriParams = z$1.url().transform((url) => Object.fromEntries(new URL(url).searchParams)).pipe(zAuthorizationResponse);
1080
1609
  const zAuthorizationErrorResponse = z$1.object({
1081
1610
  ...zOauth2ErrorResponse.shape,
1082
1611
  state: z$1.string().optional(),
1612
+ iss: zHttpsUrl.optional(),
1083
1613
  code: z$1.optional(z$1.never())
1084
1614
  }).loose();
1085
1615
 
@@ -1100,6 +1630,30 @@ function parseAuthorizationResponseRedirectUrl(options) {
1100
1630
  return parsedAuthorizationResponse.data;
1101
1631
  }
1102
1632
 
1633
+ //#endregion
1634
+ //#region src/authorization-response/verify-authorization-response.ts
1635
+ /**
1636
+ * Verifies an authorization (error) response.
1637
+ *
1638
+ * Currently it only verifies that the 'iss' value in an authorization (error) response matches the 'issuer' value of the authorization server metadata
1639
+ * according to RFC 9207.
1640
+ *
1641
+ * You can call this method after calling `parseAuthorizationResponse` and having fetched the associated session/authorization server
1642
+ * for the authorization response, to be able to verify the issuer
1643
+ */
1644
+ function verifyAuthorizationResponse({ authorizationResponse, authorizationServerMetadata }) {
1645
+ const expectedIssuer = authorizationServerMetadata.issuer;
1646
+ const responseIssuer = authorizationResponse.iss;
1647
+ if (authorizationServerMetadata.authorization_response_iss_parameter_supported && !responseIssuer) throw new Oauth2ServerErrorResponseError({
1648
+ error: Oauth2ErrorCodes.InvalidRequest,
1649
+ error_description: "Authorization server requires 'iss' parameter in authorization response (authorization_response_iss_parameter_supported), but no 'iss' parameter is present in the authorization response."
1650
+ });
1651
+ if (responseIssuer && responseIssuer !== expectedIssuer) throw new Oauth2ServerErrorResponseError({
1652
+ error: Oauth2ErrorCodes.InvalidRequest,
1653
+ error_description: "The 'iss' value in the authorization response does not match the expected 'issuer' value from the authorization server metadata."
1654
+ });
1655
+ }
1656
+
1103
1657
  //#endregion
1104
1658
  //#region src/z-grant-type.ts
1105
1659
  const zPreAuthorizedCodeGrantIdentifier = z$1.literal("urn:ietf:params:oauth:grant-type:pre-authorized_code");
@@ -1590,7 +2144,8 @@ const zAuthorizationServerMetadata = z$1.object({
1590
2144
  introspection_endpoint_auth_signing_alg_values_supported: z$1.optional(z$1.array(zAlgValueNotNone)),
1591
2145
  authorization_challenge_endpoint: z$1.optional(zHttpsUrl),
1592
2146
  "pre-authorized_grant_anonymous_access_supported": z$1.optional(z$1.boolean()),
1593
- client_attestation_pop_nonce_required: z$1.boolean().optional()
2147
+ client_attestation_pop_nonce_required: z$1.boolean().optional(),
2148
+ authorization_response_iss_parameter_supported: z$1.boolean().optional()
1594
2149
  }).loose().refine(({ introspection_endpoint_auth_methods_supported: methodsSupported, introspection_endpoint_auth_signing_alg_values_supported: algValuesSupported }) => {
1595
2150
  if (!methodsSupported) return true;
1596
2151
  if (!methodsSupported.includes("private_key_jwt") && !methodsSupported.includes("client_secret_jwt")) return true;
@@ -1621,6 +2176,7 @@ async function fetchAuthorizationServerMetadata(issuer, fetch) {
1621
2176
  if (!authorizationServerResult) authorizationServerResult = await fetchWellKnownMetadata(openIdConfigurationWellKnownMetadataUrl, zAuthorizationServerMetadata, { fetch }).catch((error) => {
1622
2177
  throw firstError ?? error;
1623
2178
  });
2179
+ if (!authorizationServerResult && firstError) throw firstError;
1624
2180
  if (authorizationServerResult && authorizationServerResult.issuer !== issuer) throw new Oauth2Error(`The 'issuer' parameter '${authorizationServerResult.issuer}' in the well known authorization server metadata at '${authorizationServerWellKnownMetadataUrl}' does not match the provided issuer '${issuer}'.`);
1625
2181
  return authorizationServerResult;
1626
2182
  }
@@ -2829,6 +3385,18 @@ var Oauth2Client = class {
2829
3385
  async resourceRequest(options) {
2830
3386
  return resourceRequest(options);
2831
3387
  }
3388
+ /**
3389
+ * Parses an authorization response redirect URL into an authorization (error) response.
3390
+ *
3391
+ * Make sure to call `Oauth2Client.verifyAuthorizationResponse` after fetching the session
3392
+ * based on the parsed response, to ensure the authorization response `iss` value is verified.
3393
+ */
3394
+ parseAuthorizationResponseRedirectUrl(options) {
3395
+ return parseAuthorizationResponseRedirectUrl(options);
3396
+ }
3397
+ verifyAuthorizationResponse(options) {
3398
+ return verifyAuthorizationResponse(options);
3399
+ }
2832
3400
  };
2833
3401
 
2834
3402
  //#endregion
@@ -2985,5 +3553,5 @@ async function verifyResourceRequest(options) {
2985
3553
  }
2986
3554
 
2987
3555
  //#endregion
2988
- export { HashAlgorithm, InvalidFetchResponseError, Oauth2AuthorizationServer, Oauth2Client, Oauth2ClientAuthorizationChallengeError, Oauth2ClientErrorResponseError, Oauth2Error, Oauth2ErrorCodes, Oauth2JwtParseError, Oauth2JwtVerificationError, Oauth2ResourceServer, Oauth2ResourceUnauthorizedError, Oauth2ServerErrorResponseError, PkceCodeChallengeMethod, SupportedAuthenticationScheme, SupportedClientAuthenticationMethod, authorizationCodeGrantIdentifier, calculateJwkThumbprint, clientAuthenticationAnonymous, clientAuthenticationClientAttestationJwt, clientAuthenticationClientSecretBasic, clientAuthenticationClientSecretPost, clientAuthenticationDynamic, clientAuthenticationNone, createClientAttestationJwt, createJarAuthorizationRequest, decodeJwt, decodeJwtHeader, fetchAuthorizationServerMetadata, fetchJwks, fetchWellKnownMetadata, fullySpecifiedCoseAlgorithmArrayToJwaSignatureAlgorithmArray, fullySpecifiedCoseAlgorithmToJwaSignatureAlgorithm, getAuthorizationServerMetadataFromList, getGlobalConfig, isJwkInSet, jwaSignatureAlgorithmArrayToFullySpecifiedCoseAlgorithmArray, jwaSignatureAlgorithmToFullySpecifiedCoseAlgorithm, jwtAuthorizationRequestJwtHeaderTyp, jwtHeaderFromJwtSigner, jwtSignerFromJwt, parseAuthorizationResponseRedirectUrl, parsePushedAuthorizationRequestUriReferenceValue, preAuthorizedCodeGrantIdentifier, pushedAuthorizationRequestUriPrefix, refreshTokenGrantIdentifier, resourceRequest, setGlobalConfig, signedAuthorizationRequestJwtHeaderTyp, validateJarRequestParams, verifyClientAttestationJwt, verifyIdTokenJwt, verifyJwt, verifyResourceRequest, zAlgValueNotNone, zAuthorizationCodeGrantIdentifier, zAuthorizationErrorResponse, zAuthorizationResponse, zAuthorizationResponseFromUriParams, zAuthorizationServerMetadata, zCompactJwe, zCompactJwt, zIdTokenJwtHeader, zIdTokenJwtPayload, zJarAuthorizationRequest, zJarRequestObjectPayload, zJwk, zJwkSet, zJwtHeader, zJwtPayload, zOauth2ErrorResponse, zPreAuthorizedCodeGrantIdentifier, zPushedAuthorizationRequestUriPrefix, zRefreshTokenGrantIdentifier };
3556
+ export { HashAlgorithm, InvalidFetchResponseError, Oauth2AuthorizationServer, Oauth2Client, Oauth2ClientAuthorizationChallengeError, Oauth2ClientErrorResponseError, Oauth2Error, Oauth2ErrorCodes, Oauth2JwtParseError, Oauth2JwtVerificationError, Oauth2ResourceServer, Oauth2ResourceUnauthorizedError, Oauth2ServerErrorResponseError, PkceCodeChallengeMethod, SupportedAuthenticationScheme, SupportedClientAuthenticationMethod, authorizationCodeGrantIdentifier, calculateJwkThumbprint, clientAuthenticationAnonymous, clientAuthenticationClientAttestationJwt, clientAuthenticationClientSecretBasic, clientAuthenticationClientSecretPost, clientAuthenticationDynamic, clientAuthenticationNone, createClientAttestationJwt, createJarAuthorizationRequest, decodeJwt, decodeJwtHeader, fetchAuthorizationServerMetadata, fetchJwks, fetchWellKnownMetadata, fullySpecifiedCoseAlgorithmArrayToJwaSignatureAlgorithmArray, fullySpecifiedCoseAlgorithmToJwaSignatureAlgorithm, getAuthorizationServerMetadataFromList, getGlobalConfig, isJwkInSet, jwaSignatureAlgorithmArrayToFullySpecifiedCoseAlgorithmArray, jwaSignatureAlgorithmToFullySpecifiedCoseAlgorithm, jwtAuthorizationRequestJwtHeaderTyp, jwtHeaderFromJwtSigner, jwtSignerFromJwt, parseAuthorizationResponseRedirectUrl, parsePushedAuthorizationRequestUriReferenceValue, preAuthorizedCodeGrantIdentifier, pushedAuthorizationRequestUriPrefix, refreshTokenGrantIdentifier, resourceRequest, setGlobalConfig, signedAuthorizationRequestJwtHeaderTyp, validateJarRequestParams, verifyAuthorizationResponse, verifyClientAttestationJwt, verifyIdTokenJwt, verifyJwt, verifyResourceRequest, zAlgValueNotNone, zAuthorizationCodeGrantIdentifier, zAuthorizationErrorResponse, zAuthorizationResponse, zAuthorizationResponseFromUriParams, zAuthorizationServerMetadata, zCompactJwe, zCompactJwt, zIdTokenJwtHeader, zIdTokenJwtPayload, zJarAuthorizationRequest, zJarRequestObjectPayload, zJwk, zJwkSet, zJwtHeader, zJwtPayload, zOauth2ErrorResponse, zPreAuthorizedCodeGrantIdentifier, zPushedAuthorizationRequestUriPrefix, zRefreshTokenGrantIdentifier };
2989
3557
  //# sourceMappingURL=index.mjs.map