@muze-nl/metro-oidc 0.3.0 → 0.3.2

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/browser.js CHANGED
@@ -520,38 +520,52 @@
520
520
  // node_modules/@muze-nl/metro/src/mw/json.mjs
521
521
  function jsonmw(options) {
522
522
  options = Object.assign({
523
+ mimetype: "application/json",
523
524
  reviver: null,
524
525
  replacer: null,
525
526
  space: ""
526
527
  }, options);
527
528
  return async (req, next) => {
528
- if (["POST", "PUT", "PATCH", "QUERY"].includes(req.method)) {
529
+ if (!isJSON(req.headers.get("Accept"))) {
529
530
  req = req.with({
530
531
  headers: {
531
- "Content-Type": "application/json",
532
- "Accept": "application/json"
532
+ "Accept": options.mimetype
533
533
  }
534
534
  });
535
+ }
536
+ if (["POST", "PUT", "PATCH", "QUERY"].includes(req.method)) {
535
537
  if (req.data && typeof req.data == "object" && !(req.data instanceof ReadableStream)) {
538
+ if (!isJSON(req.headers.get("content-type"))) {
539
+ req = req.with({
540
+ headers: {
541
+ "Content-Type": options.mimetype
542
+ }
543
+ });
544
+ }
536
545
  req = req.with({
537
546
  body: JSON.stringify(req.data, options.replacer, options.space)
538
547
  });
539
548
  }
540
- } else {
541
- req = req.with({
542
- headers: {
543
- "Accept": "application/json"
544
- }
545
- });
546
549
  }
547
550
  let res = await next(req);
548
- let body = await res.text();
549
- let json = JSON.parse(body, options.reviver);
550
- return res.with({
551
- body: json
552
- });
551
+ if (isJSON(res.headers.get("content-type"))) {
552
+ let tempRes = res.clone();
553
+ let body = await tempRes.text();
554
+ try {
555
+ let json = JSON.parse(body, options.reviver);
556
+ return res.with({
557
+ body: json
558
+ });
559
+ } catch (e) {
560
+ }
561
+ }
562
+ return res;
553
563
  };
554
564
  }
565
+ var jsonRE = /^application\/([a-zA-Z0-9\-_]+\+)?json\b/;
566
+ function isJSON(contentType) {
567
+ return jsonRE.exec(contentType);
568
+ }
555
569
 
556
570
  // node_modules/@muze-nl/metro/src/mw/thrower.mjs
557
571
  function thrower(options) {
@@ -577,202 +591,139 @@
577
591
  thrower
578
592
  }
579
593
  });
580
- globalThis.metro = metro;
594
+ if (!globalThis.metro) {
595
+ globalThis.metro = metro;
596
+ }
581
597
  var everything_default = metro;
582
598
 
583
- // node_modules/@muze-nl/assert/src/assert.mjs
599
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
600
+ var oauth2_exports = {};
601
+ __export(oauth2_exports, {
602
+ authorizePopup: () => authorizePopup,
603
+ base64url_encode: () => base64url_encode,
604
+ createState: () => createState,
605
+ default: () => oauth2mw,
606
+ generateCodeChallenge: () => generateCodeChallenge,
607
+ generateCodeVerifier: () => generateCodeVerifier,
608
+ getExpires: () => getExpires,
609
+ isExpired: () => isExpired,
610
+ isRedirected: () => isRedirected
611
+ });
612
+
613
+ // node_modules/@muze-nl/metro-oauth2/node_modules/@muze-nl/assert/src/assert.mjs
584
614
  globalThis.assertEnabled = false;
585
- function assert(source, test) {
615
+ var assert = (source, test) => {
586
616
  if (globalThis.assertEnabled) {
587
617
  let problems = fails(source, test);
588
618
  if (problems) {
589
- console.error("\u{1F170}\uFE0F Assertions failed because of:", problems, "in this source:", source);
590
- throw new Error("Assertions failed", {
591
- cause: { problems, source }
592
- });
619
+ throw new assertError("Assertions failed", problems, source);
593
620
  }
594
621
  }
595
- }
596
- function Optional(pattern) {
597
- return function _Optional(data, root, path) {
598
- if (typeof data != "undefined" && data != null && typeof pattern != "undefined") {
599
- return fails(data, pattern, root, path);
600
- }
601
- };
602
- }
603
- function Required(pattern) {
604
- return function _Required(data, root, path) {
605
- if (data == null || typeof data == "undefined") {
606
- return error("data is required", data, pattern || "any value", path);
607
- } else if (typeof pattern != "undefined") {
608
- return fails(data, pattern, root, path);
609
- } else {
610
- return false;
611
- }
612
- };
613
- }
614
- function Recommended(pattern) {
615
- return function _Recommended(data, root, path) {
616
- if (data == null || typeof data == "undefined") {
617
- console.warn("data does not contain recommended value", data, pattern, path);
622
+ };
623
+ var Optional = (pattern) => (data) => data == null || typeof data == "undefined" ? false : fails(data, pattern);
624
+ var Required = (pattern) => (data) => fails(data, pattern);
625
+ var Recommended = (pattern) => (data) => data == null || typeof data == "undefined" ? (() => {
626
+ console.warning("data does not contain recommended value", data, pattern);
627
+ return false;
628
+ })() : fails(data, pattern);
629
+ var oneOf = (...patterns) => (data) => {
630
+ for (let pattern of patterns) {
631
+ if (!fails(data, pattern)) {
618
632
  return false;
619
- } else {
620
- return fails(data, pattern, root, path);
621
- }
622
- };
623
- }
624
- function oneOf(...patterns) {
625
- return function _oneOf(data, root, path) {
626
- for (let pattern of patterns) {
627
- if (!fails(data, pattern, root, path)) {
628
- return false;
629
- }
630
- }
631
- return error("data does not match oneOf patterns", data, patterns, path);
632
- };
633
- }
634
- function anyOf(...patterns) {
635
- return function _anyOf(data, root, path) {
636
- if (!Array.isArray(data)) {
637
- return error("data is not an array", data, "anyOf", path);
638
- }
639
- for (let value of data) {
640
- if (oneOf(...patterns)(value)) {
641
- return error("data does not match anyOf patterns", value, patterns, path);
642
- }
643
- }
644
- return false;
645
- };
646
- }
647
- function allOf(...patterns) {
648
- return function _allOf(data, root, path) {
649
- let problems = [];
650
- for (let pattern of patterns) {
651
- problems = problems.concat(fails(data, pattern, root, path));
652
633
  }
653
- problems = problems.filter(Boolean);
654
- if (problems.length) {
655
- return error("data does not match all given patterns", data, patterns, path, problems);
634
+ }
635
+ return error("data does not match oneOf patterns", data, patterns);
636
+ };
637
+ var anyOf = (...patterns) => (data) => {
638
+ if (!Array.isArray(data)) {
639
+ return error("data is not an array", data, "anyOf");
640
+ }
641
+ for (let value of data) {
642
+ if (oneOf(...patterns)(value)) {
643
+ return error("data does not match anyOf patterns", value, patterns);
656
644
  }
657
- };
658
- }
659
- function validURL(data, root, path) {
645
+ }
646
+ return false;
647
+ };
648
+ function validURL(data) {
660
649
  try {
661
650
  if (data instanceof URL) {
662
651
  data = data.href;
663
652
  }
664
653
  let url2 = new URL(data);
665
654
  if (url2.href != data) {
666
- if (!(url2.href + "/" == data || url2.href == data + "/")) {
667
- return error("data is not a valid url", data, "validURL", path);
668
- }
655
+ return error("data is not a valid url", data, "validURL");
669
656
  }
670
657
  } catch (e) {
671
- return error("data is not a valid url", data, "validURL", path);
672
- }
673
- }
674
- function validEmail(data, root, path) {
675
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
676
- return error("data is not a valid email", data, "validEmail", path);
658
+ return error("data is not a valid url", data, "validURL");
677
659
  }
660
+ return false;
678
661
  }
679
- function instanceOf(constructor) {
680
- return function _instanceOf(data, root, path) {
681
- if (!(data instanceof constructor)) {
682
- return error("data is not an instanceof pattern", data, constructor, path);
683
- }
684
- };
685
- }
686
- function not(pattern) {
687
- return function _not(data, root, path) {
688
- if (!fails(data, pattern, root, path)) {
689
- return error("data matches pattern, when required not to", data, pattern, path);
690
- }
691
- };
692
- }
693
- function fails(data, pattern, root, path = "") {
662
+ function fails(data, pattern, root) {
694
663
  if (!root) {
695
664
  root = data;
696
665
  }
697
666
  let problems = [];
698
667
  if (pattern === Boolean) {
699
- if (typeof data != "boolean" && !(data instanceof Boolean)) {
700
- problems.push(error("data is not a boolean", data, pattern, path));
668
+ if (typeof data != "boolean") {
669
+ problems.push(error("data is not a boolean", data, pattern));
701
670
  }
702
671
  } else if (pattern === Number) {
703
- if (typeof data != "number" && !(data instanceof Number)) {
704
- problems.push(error("data is not a number", data, pattern, path));
705
- }
706
- } else if (pattern === String) {
707
- if (typeof data != "string" && !(data instanceof String)) {
708
- problems.push(error("data is not a string", data, pattern, path));
709
- }
710
- if (data == "") {
711
- problems.push(error("data is an empty string, which is not allowed", data, pattern, path));
672
+ if (typeof data != "number") {
673
+ problems.push(error("data is not a number", data, pattern));
712
674
  }
713
675
  } else if (pattern instanceof RegExp) {
714
676
  if (Array.isArray(data)) {
715
- let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
677
+ let index = data.findIndex((element) => fails(element, pattern, root));
716
678
  if (index > -1) {
717
- problems.push(error("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
679
+ problems.push(error("data[" + index + "] does not match pattern", data[index], pattern));
718
680
  }
719
- } else if (typeof data == "undefined") {
720
- problems.push(error("data is undefined, should match pattern", data, pattern, path));
721
681
  } else if (!pattern.test(data)) {
722
- problems.push(error("data does not match pattern", data, pattern, path));
682
+ problems.push(error("data does not match pattern", data, pattern));
723
683
  }
724
684
  } else if (pattern instanceof Function) {
725
- let problem = pattern(data, root, path);
726
- if (problem) {
727
- if (Array.isArray(problem)) {
728
- problems = problems.concat(problem);
729
- } else {
730
- problems.push(problem);
731
- }
685
+ if (pattern(data, root)) {
686
+ problems.push(error("data does not match function", data, pattern));
732
687
  }
733
688
  } else if (Array.isArray(pattern)) {
734
689
  if (!Array.isArray(data)) {
735
- problems.push(error("data is not an array", data, [], path));
690
+ problems.push(error("data is not an array", data, []));
736
691
  }
737
- for (let p2 of pattern) {
738
- for (let index of data.keys()) {
739
- let problem = fails(data[index], p2, root, path + "[" + index + "]");
740
- if (Array.isArray(problem)) {
741
- problems = problems.concat(problem);
742
- } else if (problem) {
743
- problems.push(problem);
744
- }
692
+ for (p of pattern) {
693
+ let problem = fails(data, p, root);
694
+ if (Array.isArray(problem)) {
695
+ problems.concat(problem);
696
+ } else if (problem) {
697
+ problems.push(problem);
745
698
  }
746
699
  }
747
700
  } else if (pattern && typeof pattern == "object") {
748
701
  if (Array.isArray(data)) {
749
- let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
702
+ let index = data.findIndex((element) => fails(element, pattern, root));
750
703
  if (index > -1) {
751
- problems.push(error("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
704
+ problems.push(error("data[" + index + "] does not match pattern", data[index], pattern));
752
705
  }
753
706
  } else if (!data || typeof data != "object") {
754
- problems.push(error("data is not an object, pattern is", data, pattern, path));
707
+ problems.push(error("data is not an object, pattern is", data, pattern));
755
708
  } else {
756
709
  if (data instanceof URLSearchParams) {
757
710
  data = Object.fromEntries(data);
758
711
  }
759
- if (pattern instanceof Function) {
760
- let result = fails(data, pattern, root, path);
712
+ let p2 = problems[problems.length - 1];
713
+ for (const [wKey, wVal] of Object.entries(pattern)) {
714
+ let result = fails(data[wKey], wVal, root);
761
715
  if (result) {
762
- problems = problems.concat(result);
763
- }
764
- } else {
765
- for (const [wKey, wVal] of Object.entries(pattern)) {
766
- let result = fails(data[wKey], wVal, root, path + "." + wKey);
767
- if (result) {
768
- problems = problems.concat(result);
716
+ if (!p2 || typeof p2 == "string") {
717
+ p2 = {};
718
+ problems.push(error(p2, data[wKey], wVal));
769
719
  }
720
+ p2[wKey] = result.problems;
770
721
  }
771
722
  }
772
723
  }
773
724
  } else {
774
725
  if (pattern != data) {
775
- problems.push(error("data and pattern are not equal", data, pattern, path));
726
+ problems.push(error("data and pattern are not equal", data, pattern));
776
727
  }
777
728
  }
778
729
  if (problems.length) {
@@ -780,389 +731,88 @@
780
731
  }
781
732
  return false;
782
733
  }
783
- function error(message, found, expected, path, problems) {
784
- let result = {
734
+ var assertError = class extends Error {
735
+ constructor(message, problems, ...details) {
736
+ super(message);
737
+ this.problems = problems;
738
+ this.details = details;
739
+ }
740
+ };
741
+ function error(message, found, expected) {
742
+ return {
785
743
  message,
786
744
  found,
787
- expected,
788
- path
745
+ expected
789
746
  };
790
- if (problems) {
791
- result.problems = problems;
792
- }
793
- return result;
794
747
  }
795
748
 
796
- // src/oidc.util.mjs
797
- var MustHave = (...options) => (value, root) => {
798
- if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
799
- return false;
800
- }
801
- return error("root data must have all of", root, options);
802
- };
803
- var MustInclude = (...options) => (value) => {
804
- if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
805
- return false;
749
+ // node_modules/@muze-nl/metro-oauth2/src/tokenstore.mjs
750
+ function tokenStore(site) {
751
+ let localState, localTokens;
752
+ if (typeof localStorage !== "undefined") {
753
+ localState = {
754
+ get: () => localStorage.getItem("metro/state:" + site),
755
+ set: (value) => localStorage.setItem("metro/state:" + site, value),
756
+ has: () => localStorage.getItem("metro/state:" + site) !== null
757
+ };
758
+ localTokens = {
759
+ get: (name) => JSON.parse(localStorage.getItem(site + ":" + name)),
760
+ set: (name, value) => localStorage.setItem(site + ":" + name, JSON.stringify(value)),
761
+ has: (name) => localStorage.getItem(site + ":" + name) !== null
762
+ };
806
763
  } else {
807
- return error("data must be an array which includes", value, options);
764
+ let stateMap = /* @__PURE__ */ new Map();
765
+ localState = {
766
+ get: () => stateMap.get("metro/state:" + site),
767
+ set: (value) => stateMap.set("metro/state:" + site, value),
768
+ has: () => stateMap.has("metro/state:" + site)
769
+ };
770
+ localTokens = /* @__PURE__ */ new Map();
808
771
  }
809
- };
810
- var validJWA = [
811
- "HS256",
812
- "HS384",
813
- "HS512",
814
- "RS256",
815
- "RS384",
816
- "RS512",
817
- "ES256",
818
- "ES384",
819
- "ES512"
820
- ];
821
- var validAuthMethods = [
822
- "client_secret_post",
823
- "client_secret_basic",
824
- "client_secret_jwt",
825
- "private_key_jwt"
826
- ];
772
+ return {
773
+ state: localState,
774
+ tokens: localTokens
775
+ };
776
+ }
827
777
 
828
- // src/oidc.discovery.mjs
829
- async function oidcDiscovery(options = {}) {
830
- assert(options, {
831
- client: Optional(instanceOf(everything_default.client().constructor)),
832
- issuer: Required(validURL)
833
- });
778
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
779
+ function oauth2mw(options) {
834
780
  const defaultOptions = {
835
- client: everything_default.client().with(thrower()).with(jsonmw()),
836
- requireDynamicRegistration: false
781
+ client: client(),
782
+ force_authorization: false,
783
+ site: "default",
784
+ oauth2_configuration: {
785
+ authorization_endpoint: "/authorize",
786
+ token_endpoint: "/token",
787
+ redirect_uri: globalThis.document?.location.href,
788
+ grant_type: "authorization_code",
789
+ code_verifier: generateCodeVerifier(64)
790
+ },
791
+ authorize_callback: async (url2) => {
792
+ if (window.location.href != url2.href) {
793
+ window.location.replace(url2.href);
794
+ }
795
+ return false;
796
+ }
837
797
  };
798
+ assert(options, {});
799
+ const oauth22 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
838
800
  options = Object.assign({}, defaultOptions, options);
839
- const TestSucceeded = false;
840
- function MustUseHTTPS(url2) {
841
- return TestSucceeded;
842
- }
843
- const openid_provider_metadata = {
844
- issuer: Required(allOf(options.issuer, MustUseHTTPS)),
845
- authorization_endpoint: Required(validURL),
846
- token_endpoint: Required(validURL),
847
- userinfo_endpoint: Recommended(validURL),
848
- // todo: test for https protocol
849
- jwks_uri: Required(validURL),
850
- registration_endpoint: options.requireDynamicRegistration ? Required(validURL) : Recommended(validURL),
851
- scopes_supported: Recommended(MustInclude("openid")),
852
- response_types_supported: options.requireDynamicRegistration ? Required(MustInclude("code", "id_token", "id_token token")) : Required([]),
853
- response_modes_supported: Optional([]),
854
- grant_types_supported: options.requireDynamicRegistration ? Optional(MustInclude("authorization_code")) : Optional([]),
855
- acr_values_supported: Optional([]),
856
- subject_types_supported: Required([]),
857
- id_token_signing_alg_values_supported: Required(MustInclude("RS256")),
858
- id_token_encryption_alg_values_supported: Optional([]),
859
- id_token_encryption_enc_values_supported: Optional([]),
860
- userinfo_signing_alg_values_supported: Optional([]),
861
- userinfo_encryption_alg_values_supported: Optional([]),
862
- userinfo_encryption_enc_values_supported: Optional([]),
863
- request_object_signing_alg_values_supported: Optional(MustInclude("RS256")),
864
- // not testing for 'none'
865
- request_object_encryption_alg_values_supported: Optional([]),
866
- request_object_encryption_enc_values_supported: Optional([]),
867
- token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods)),
868
- token_endpoint_auth_signing_alg_values_supported: Optional(MustInclude("RS256"), not(MustInclude("none"))),
869
- display_values_supported: Optional(anyOf("page", "popup", "touch", "wap")),
870
- claim_types_supported: Optional(anyOf("normal", "aggregated", "distributed")),
871
- claims_supported: Recommended([]),
872
- service_documentation: Optional(validURL),
873
- claims_locales_supported: Optional([]),
874
- ui_locales_supported: Optional([]),
875
- claims_parameter_supported: Optional(Boolean),
876
- request_parameter_supported: Optional(Boolean),
877
- request_uri_parameter_supported: Optional(Boolean),
878
- op_policy_uri: Optional(validURL),
879
- op_tos_uri: Optional(validURL)
880
- };
881
- const configURL = everything_default.url(options.issuer, ".well-known/openid-configuration");
882
- const response2 = await options.client.get(
883
- // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
884
- // note: this allows path components in the options.issuer url
885
- configURL
886
- );
887
- const openid_config = response2.data;
888
- assert(openid_config, openid_provider_metadata);
889
- assert(openid_config.issuer, options.issuer);
890
- return openid_config;
891
- }
892
-
893
- // src/oidc.register.mjs
894
- async function register(options) {
895
- const openid_client_metadata = {
896
- redirect_uris: Required([validURL]),
897
- response_types: Optional([]),
898
- grant_types: Optional(anyOf("authorization_code", "refresh_token")),
899
- //TODO: match response_types with grant_types
900
- application_type: Optional(oneOf("native", "web")),
901
- contacts: Optional([validEmail]),
902
- client_name: Optional(String),
903
- logo_uri: Optional(validURL),
904
- client_uri: Optional(validURL),
905
- policy_uri: Optional(validURL),
906
- tos_uri: Optional(validURL),
907
- jwks_uri: Optional(validURL, not(MustHave("jwks"))),
908
- jwks: Optional(validURL, not(MustHave("jwks_uri"))),
909
- sector_identifier_uri: Optional(validURL),
910
- subject_type: Optional(String),
911
- id_token_signed_response_alg: Optional(oneOf(...validJWA)),
912
- id_token_encrypted_response_alg: Optional(oneOf(...validJWA)),
913
- id_token_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("id_token_encrypted_response_alg")),
914
- userinfo_signed_response_alg: Optional(oneOf(...validJWA)),
915
- userinfo_encrypted_response_alg: Optional(oneOf(...validJWA)),
916
- userinfo_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("userinfo_encrypted_response_alg")),
917
- request_object_signing_alg: Optional(oneOf(...validJWA)),
918
- request_object_encryption_alg: Optional(oneOf(...validJWA)),
919
- request_object_encryption_enc: Optional(oneOf(...validJWA)),
920
- token_endpoint_auth_method: Optional(oneOf(...validAuthMethods)),
921
- token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
922
- default_max_age: Optional(Number),
923
- require_auth_time: Optional(Boolean),
924
- default_acr_values: Optional([String]),
925
- initiate_login_uri: Optional([validURL]),
926
- request_uris: Optional([validURL])
927
- };
928
- assert(options, {
929
- client: Optional(instanceOf(everything_default.client().constructor)),
930
- registration_endpoint: validURL,
931
- client_info: openid_client_metadata
932
- });
933
- const defaultOptions = {
934
- client: everything_default.client().with(thrower()).with(jsonmw())
935
- };
936
- options = Object.assign({}, defaultOptions, options);
937
- let response2 = await options.client.post(options.registration_endpoint, {
938
- body: options.client_info
939
- });
940
- let info = response2.data;
941
- if (!info.client_id || !info.client_secret) {
942
- throw everything_default.metroError("metro.oidc: Error: dynamic registration of client failed, no client_id or client_secret returned", response2);
943
- }
944
- options.client_info = Object.assign(options.client_info, info);
945
- return options.client_info;
946
- }
947
-
948
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
949
- var oauth2_exports = {};
950
- __export(oauth2_exports, {
951
- base64url_encode: () => base64url_encode,
952
- createState: () => createState,
953
- default: () => oauth2mw,
954
- generateCodeChallenge: () => generateCodeChallenge,
955
- generateCodeVerifier: () => generateCodeVerifier,
956
- getExpires: () => getExpires,
957
- isExpired: () => isExpired,
958
- isRedirected: () => isRedirected
959
- });
960
-
961
- // node_modules/@muze-nl/metro-oauth2/node_modules/@muze-nl/assert/src/assert.mjs
962
- globalThis.assertEnabled = false;
963
- var assert2 = (source, test) => {
964
- if (globalThis.assertEnabled) {
965
- let problems = fails2(source, test);
966
- if (problems) {
967
- throw new assertError("Assertions failed", problems, source);
968
- }
969
- }
970
- };
971
- var Optional2 = (pattern) => (data) => data == null || typeof data == "undefined" ? false : fails2(data, pattern);
972
- var Required2 = (pattern) => (data) => fails2(data, pattern);
973
- var Recommended2 = (pattern) => (data) => data == null || typeof data == "undefined" ? (() => {
974
- console.warning("data does not contain recommended value", data, pattern);
975
- return false;
976
- })() : fails2(data, pattern);
977
- var oneOf2 = (...patterns) => (data) => {
978
- for (let pattern of patterns) {
979
- if (!fails2(data, pattern)) {
980
- return false;
981
- }
982
- }
983
- return error2("data does not match oneOf patterns", data, patterns);
984
- };
985
- var anyOf2 = (...patterns) => (data) => {
986
- if (!Array.isArray(data)) {
987
- return error2("data is not an array", data, "anyOf");
988
- }
989
- for (let value of data) {
990
- if (oneOf2(...patterns)(value)) {
991
- return error2("data does not match anyOf patterns", value, patterns);
992
- }
993
- }
994
- return false;
995
- };
996
- function validURL2(data) {
997
- try {
998
- if (data instanceof URL) {
999
- data = data.href;
1000
- }
1001
- let url2 = new URL(data);
1002
- if (url2.href != data) {
1003
- return error2("data is not a valid url", data, "validURL");
1004
- }
1005
- } catch (e) {
1006
- return error2("data is not a valid url", data, "validURL");
1007
- }
1008
- return false;
1009
- }
1010
- function fails2(data, pattern, root) {
1011
- if (!root) {
1012
- root = data;
1013
- }
1014
- let problems = [];
1015
- if (pattern === Boolean) {
1016
- if (typeof data != "boolean") {
1017
- problems.push(error2("data is not a boolean", data, pattern));
1018
- }
1019
- } else if (pattern === Number) {
1020
- if (typeof data != "number") {
1021
- problems.push(error2("data is not a number", data, pattern));
1022
- }
1023
- } else if (pattern instanceof RegExp) {
1024
- if (Array.isArray(data)) {
1025
- let index = data.findIndex((element) => fails2(element, pattern, root));
1026
- if (index > -1) {
1027
- problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
1028
- }
1029
- } else if (!pattern.test(data)) {
1030
- problems.push(error2("data does not match pattern", data, pattern));
1031
- }
1032
- } else if (pattern instanceof Function) {
1033
- if (pattern(data, root)) {
1034
- problems.push(error2("data does not match function", data, pattern));
1035
- }
1036
- } else if (Array.isArray(pattern)) {
1037
- if (!Array.isArray(data)) {
1038
- problems.push(error2("data is not an array", data, []));
1039
- }
1040
- for (p of pattern) {
1041
- let problem = fails2(data, p, root);
1042
- if (Array.isArray(problem)) {
1043
- problems.concat(problem);
1044
- } else if (problem) {
1045
- problems.push(problem);
1046
- }
1047
- }
1048
- } else if (pattern && typeof pattern == "object") {
1049
- if (Array.isArray(data)) {
1050
- let index = data.findIndex((element) => fails2(element, pattern, root));
1051
- if (index > -1) {
1052
- problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
1053
- }
1054
- } else if (!data || typeof data != "object") {
1055
- problems.push(error2("data is not an object, pattern is", data, pattern));
1056
- } else {
1057
- if (data instanceof URLSearchParams) {
1058
- data = Object.fromEntries(data);
1059
- }
1060
- let p2 = problems[problems.length - 1];
1061
- for (const [wKey, wVal] of Object.entries(pattern)) {
1062
- let result = fails2(data[wKey], wVal, root);
1063
- if (result) {
1064
- if (!p2 || typeof p2 == "string") {
1065
- p2 = {};
1066
- problems.push(error2(p2, data[wKey], wVal));
1067
- }
1068
- p2[wKey] = result.problems;
1069
- }
1070
- }
1071
- }
1072
- } else {
1073
- if (pattern != data) {
1074
- problems.push(error2("data and pattern are not equal", data, pattern));
1075
- }
1076
- }
1077
- if (problems.length) {
1078
- return problems;
1079
- }
1080
- return false;
1081
- }
1082
- var assertError = class extends Error {
1083
- constructor(message, problems, ...details) {
1084
- super(message);
1085
- this.problems = problems;
1086
- this.details = details;
1087
- }
1088
- };
1089
- function error2(message, found, expected) {
1090
- return {
1091
- message,
1092
- found,
1093
- expected
1094
- };
1095
- }
1096
-
1097
- // node_modules/@muze-nl/metro-oauth2/src/tokenstore.mjs
1098
- function tokenStore(site) {
1099
- let localState, localTokens;
1100
- if (typeof localStorage !== "undefined") {
1101
- localState = {
1102
- get: () => localStorage.getItem("metro/state:" + site),
1103
- set: (value) => localStorage.setItem("metro/state:" + site, value),
1104
- has: () => localStorage.getItem("metro/state:" + site) !== null
1105
- };
1106
- localTokens = {
1107
- get: (name) => JSON.parse(localStorage.getItem(site + ":" + name)),
1108
- set: (name, value) => localStorage.setItem(site + ":" + name, JSON.stringify(value)),
1109
- has: (name) => localStorage.getItem(site + ":" + name) !== null
1110
- };
1111
- } else {
1112
- let stateMap = /* @__PURE__ */ new Map();
1113
- localState = {
1114
- get: () => stateMap.get("metro/state:" + site),
1115
- set: (value) => stateMap.set("metro/state:" + site, value),
1116
- has: () => stateMap.has("metro/state:" + site)
1117
- };
1118
- localTokens = /* @__PURE__ */ new Map();
1119
- }
1120
- return {
1121
- state: localState,
1122
- tokens: localTokens
1123
- };
1124
- }
1125
-
1126
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
1127
- function oauth2mw(options) {
1128
- const defaultOptions = {
1129
- client: everything_default.client(),
1130
- force_authorization: false,
1131
- site: "default",
1132
- oauth2_configuration: {
1133
- authorization_endpoint: "/authorize",
1134
- token_endpoint: "/token",
1135
- redirect_uri: globalThis.document?.location.href,
1136
- grant_type: "authorization_code",
1137
- code_verifier: generateCodeVerifier(64)
1138
- },
1139
- callbacks: {
1140
- authorize: async (url2) => {
1141
- if (window.location.href != url2.href) {
1142
- window.location.replace(url2.href);
1143
- }
1144
- return false;
1145
- }
1146
- }
1147
- };
1148
- assert2(options, {});
1149
- const oauth22 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
1150
- options = Object.assign({}, defaultOptions, options);
1151
- options.oauth2_configuration = oauth22;
1152
- const store = tokenStore(options.site);
1153
- if (!options.tokens) {
1154
- options.tokens = store.tokens;
801
+ options.oauth2_configuration = oauth22;
802
+ const store = tokenStore(options.site);
803
+ if (!options.tokens) {
804
+ options.tokens = store.tokens;
1155
805
  }
1156
806
  if (!options.state) {
1157
807
  options.state = store.state;
1158
808
  }
1159
- assert2(options, {
809
+ assert(options, {
1160
810
  oauth2_configuration: {
1161
- client_id: Required2(/.+/),
811
+ client_id: Required(/.+/),
1162
812
  grant_type: "authorization_code",
1163
- authorization_endpoint: Required2(validURL2),
1164
- token_endpoint: Required2(validURL2),
1165
- redirect_uri: Required2(validURL2)
813
+ authorization_endpoint: Required(validURL),
814
+ token_endpoint: Required(validURL),
815
+ redirect_uri: Required(validURL)
1166
816
  }
1167
817
  });
1168
818
  for (let option in oauth22) {
@@ -1212,7 +862,7 @@
1212
862
  try {
1213
863
  let token = await fetchAccessToken();
1214
864
  if (!token) {
1215
- return everything_default.response("false");
865
+ return response("false");
1216
866
  }
1217
867
  } catch (e) {
1218
868
  throw e;
@@ -1222,14 +872,14 @@
1222
872
  try {
1223
873
  let token = await fetchRefreshToken();
1224
874
  if (!token) {
1225
- return everything_default.response("false");
875
+ return response("false");
1226
876
  }
1227
877
  } catch (e) {
1228
878
  throw e;
1229
879
  }
1230
880
  return oauth2authorized(req, next);
1231
881
  } else {
1232
- req = everything_default.request(req, {
882
+ req = request(req, {
1233
883
  headers: {
1234
884
  Authorization: accessToken.type + " " + accessToken.value
1235
885
  }
@@ -1239,7 +889,7 @@
1239
889
  }
1240
890
  function getTokensFromLocation() {
1241
891
  if (typeof window !== "undefined" && window?.location) {
1242
- let url2 = everything_default.url(window.location);
892
+ let url2 = url(window.location);
1243
893
  let code, state, params2;
1244
894
  if (url2.searchParams.has("code")) {
1245
895
  params2 = url2.searchParams;
@@ -1267,10 +917,10 @@
1267
917
  async function fetchAccessToken() {
1268
918
  if (oauth22.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1269
919
  let authReqURL = await getAuthorizationCodeURL();
1270
- if (!options.callbacks.authorize || typeof options.callbacks.authorize !== "function") {
1271
- throw everything_default.metroError("oauth2mw: oauth2 with grant_type:authorization_code requires a callback function in client options.options.callbacks.authorize");
920
+ if (!options.authorize_callback || typeof options.authorize_callback !== "function") {
921
+ throw metroError("oauth2mw: oauth2 with grant_type:authorization_code requires a callback function in client options.authorize_callback");
1272
922
  }
1273
- let token = await options.callbacks.authorize(authReqURL);
923
+ let token = await options.authorize_callback(authReqURL);
1274
924
  if (token) {
1275
925
  options.tokens.set("authorization_code", token);
1276
926
  } else {
@@ -1281,7 +931,7 @@
1281
931
  let response2 = await options.client.post(tokenReq);
1282
932
  if (!response2.ok) {
1283
933
  let msg = await response2.text();
1284
- throw everything_default.metroError("OAuth2mw: fetch access_token: " + response2.status + ": " + response2.statusText, { cause: tokenReq });
934
+ throw metroError("OAuth2mw: fetch access_token: " + response2.status + ": " + response2.statusText, { cause: tokenReq });
1285
935
  }
1286
936
  let data = await response2.json();
1287
937
  options.tokens.set("access_token", {
@@ -1302,7 +952,7 @@
1302
952
  let refreshTokenReq = getAccessTokenRequest("refresh_token");
1303
953
  let response2 = await options.client.post(refreshTokenReq);
1304
954
  if (!response2.ok) {
1305
- throw everything_default.metroError("OAuth2mw: refresh access_token: " + response2.status + ": " + response2.statusText, { cause: refreshTokenReq });
955
+ throw metroError("OAuth2mw: refresh access_token: " + response2.status + ": " + response2.statusText, { cause: refreshTokenReq });
1306
956
  }
1307
957
  let data = await response2.json();
1308
958
  options.tokens.set("access_token", {
@@ -1323,10 +973,10 @@
1323
973
  }
1324
974
  async function getAuthorizationCodeURL() {
1325
975
  if (!oauth22.authorization_endpoint) {
1326
- throw everything_default.metroError("oauth2mw: Missing options.oauth2_configuration.authorization_endpoint");
976
+ throw metroError("oauth2mw: Missing options.oauth2_configuration.authorization_endpoint");
1327
977
  }
1328
- let url2 = everything_default.url(oauth22.authorization_endpoint, { hash: "" });
1329
- assert2(oauth22, {
978
+ let url2 = url(oauth22.authorization_endpoint, { hash: "" });
979
+ assert(oauth22, {
1330
980
  client_id: /.+/,
1331
981
  redirect_uri: /.+/,
1332
982
  scope: /.*/
@@ -1350,7 +1000,7 @@
1350
1000
  search.client_secret = oauth22.client_secret;
1351
1001
  }
1352
1002
  if (oauth22.code_verifier) {
1353
- search.code_challenge = base64url_encode(await generateCodeChallenge(oauth22.code_verifier));
1003
+ search.code_challenge = await generateCodeChallenge(oauth22.code_verifier);
1354
1004
  search.code_challenge_method = "S256";
1355
1005
  }
1356
1006
  if (oauth22.scope) {
@@ -1359,23 +1009,23 @@
1359
1009
  if (oauth22.prompt) {
1360
1010
  search.prompt = oauth22.prompt;
1361
1011
  }
1362
- return everything_default.url(url2, { search });
1012
+ return url(url2, { search });
1363
1013
  }
1364
1014
  function getAccessTokenRequest(grant_type = null) {
1365
- assert2(oauth22, {
1015
+ assert(oauth22, {
1366
1016
  client_id: /.+/,
1367
1017
  redirect_uri: /.+/
1368
1018
  });
1369
1019
  if (!oauth22.token_endpoint) {
1370
- throw everything_default.metroError("oauth2mw: Missing options.endpoints.token url");
1020
+ throw metroError("oauth2mw: Missing options.endpoints.token url");
1371
1021
  }
1372
- let url2 = everything_default.url(oauth22.token_endpoint, { hash: "" });
1022
+ let url2 = url(oauth22.token_endpoint, { hash: "" });
1373
1023
  let params2 = {
1374
1024
  grant_type: grant_type || oauth22.grant_type,
1375
1025
  client_id: oauth22.client_id
1376
1026
  };
1377
1027
  if (oauth22.code_verifier) {
1378
- params2.code_verifier = base64url_encode(oauth22.code_verifier);
1028
+ params2.code_verifier = oauth22.code_verifier;
1379
1029
  }
1380
1030
  if (oauth22.client_secret) {
1381
1031
  params2.client_secret = oauth22.client_secret;
@@ -1387,10 +1037,6 @@
1387
1037
  case "authorization_code":
1388
1038
  params2.redirect_uri = oauth22.redirect_uri;
1389
1039
  params2.code = options.tokens.get("authorization_code");
1390
- if (options.dpop) {
1391
- const keyPair = options.tokens.get("keyPair");
1392
- params2.dpop_jkt = keyPair.publicKey;
1393
- }
1394
1040
  break;
1395
1041
  case "client_credentials":
1396
1042
  break;
@@ -1401,7 +1047,7 @@
1401
1047
  throw new Error("Unknown grant_type: ".oauth2.grant_type);
1402
1048
  break;
1403
1049
  }
1404
- return everything_default.request(url2, { method: "POST", body: new URLSearchParams(params2) });
1050
+ return request(url2, { method: "POST", body: new URLSearchParams(params2) });
1405
1051
  }
1406
1052
  }
1407
1053
  function isExpired(token) {
@@ -1426,13 +1072,13 @@
1426
1072
  function generateCodeVerifier(size = 64) {
1427
1073
  const code_verifier = new Uint8Array(size);
1428
1074
  globalThis.crypto.getRandomValues(code_verifier);
1429
- return code_verifier;
1075
+ return base64url_encode(code_verifier);
1430
1076
  }
1431
1077
  async function generateCodeChallenge(code_verifier) {
1432
- const b64encoded = base64url_encode(code_verifier);
1433
1078
  const encoder2 = new TextEncoder();
1434
- const data = encoder2.encode(b64encoded);
1435
- return await globalThis.crypto.subtle.digest("SHA-256", data);
1079
+ const data = encoder2.encode(code_verifier);
1080
+ const challenge = await globalThis.crypto.subtle.digest("SHA-256", data);
1081
+ return base64url_encode(challenge);
1436
1082
  }
1437
1083
  function base64url_encode(buffer) {
1438
1084
  const byteString = Array.from(new Uint8Array(buffer), (b) => String.fromCharCode(b)).join("");
@@ -1462,6 +1108,14 @@
1462
1108
  }
1463
1109
  return true;
1464
1110
  }
1111
+ async function authorizePopup(authorizationCodeURL) {
1112
+ return new Promise((resolve, reject) => {
1113
+ addEventListener("oauth2authorized", (evt) => {
1114
+ resolve(event.authorization_code);
1115
+ }, { once: true });
1116
+ window.open(authorizationCodeURL);
1117
+ });
1118
+ }
1465
1119
 
1466
1120
  // node_modules/@muze-nl/metro-oauth2/src/oauth2.mockserver.mjs
1467
1121
  var oauth2_mockserver_exports = {};
@@ -1488,7 +1142,7 @@
1488
1142
  })
1489
1143
  };
1490
1144
  };
1491
- var error3;
1145
+ var error2;
1492
1146
  var pkce = {};
1493
1147
  function oauth2mockserver(options = {}) {
1494
1148
  const defaultOptions = {
@@ -1500,12 +1154,12 @@
1500
1154
  let url2 = everything_default.url(req.url);
1501
1155
  switch (url2.pathname) {
1502
1156
  case "/authorize/":
1503
- if (error3 = fails2(url2.searchParams, {
1157
+ if (error2 = fails(url2.searchParams, {
1504
1158
  response_type: "code",
1505
1159
  client_id: "mockClientId",
1506
- state: Optional2(/.*/)
1160
+ state: Optional(/.*/)
1507
1161
  })) {
1508
- return everything_default.response(badRequest(error3));
1162
+ return everything_default.response(badRequest(error2));
1509
1163
  }
1510
1164
  if (url2.searchParams.has("code_challenge")) {
1511
1165
  if (!url2.searchParams.has("code_challenge_method")) {
@@ -1527,17 +1181,17 @@
1527
1181
  req.data.forEach((value, key) => body[key] = value);
1528
1182
  req = req.with({ body });
1529
1183
  }
1530
- if (error3 = fails2(req, {
1184
+ if (error2 = fails(req, {
1531
1185
  method: "POST",
1532
1186
  data: {
1533
- grant_type: oneOf2("refresh_token", "authorization_code")
1187
+ grant_type: oneOf("refresh_token", "authorization_code")
1534
1188
  }
1535
1189
  })) {
1536
- return everything_default.response(badRequest(error3));
1190
+ return everything_default.response(badRequest(error2));
1537
1191
  }
1538
1192
  switch (req.data.grant_type) {
1539
1193
  case "refresh_token":
1540
- if (error3 = fails2(req.data, oneOf2({
1194
+ if (error2 = fails(req.data, oneOf({
1541
1195
  refresh_token: "mockRefreshToken",
1542
1196
  client_id: "mockClientId",
1543
1197
  client_secret: "mockClientSecret"
@@ -1546,11 +1200,11 @@
1546
1200
  client_id: "mockClientId",
1547
1201
  code_verifier: /.+/
1548
1202
  }))) {
1549
- return everything_default.response(badRequest(error3));
1203
+ return everything_default.response(badRequest(error2));
1550
1204
  }
1551
1205
  break;
1552
1206
  case "access_token":
1553
- if (error3 = fails2(req.data, oneOf2({
1207
+ if (error2 = fails(req.data, oneOf({
1554
1208
  client_id: "mockClientId",
1555
1209
  client_secret: "mockClientSecret"
1556
1210
  }, {
@@ -1559,7 +1213,7 @@
1559
1213
  //FIXME: check that this matches code_verifier
1560
1214
  code_challenge_method: "S256"
1561
1215
  }))) {
1562
- return everything_default.response(badRequest(error3));
1216
+ return everything_default.response(badRequest(error2));
1563
1217
  }
1564
1218
  break;
1565
1219
  }
@@ -1623,43 +1277,43 @@
1623
1277
  "ES384",
1624
1278
  "ES512"
1625
1279
  ];
1626
- var validAuthMethods2 = [
1280
+ var validAuthMethods = [
1627
1281
  "client_secret_post",
1628
1282
  "client_secret_base",
1629
1283
  "client_secret_jwt",
1630
1284
  "private_key_jwt"
1631
1285
  ];
1632
1286
  var oauth_authorization_server_metadata = {
1633
- issuer: Required2(validURL2),
1634
- authorization_endpoint: Required2(validURL2),
1635
- token_endpoint: Required2(validURL2),
1636
- jwks_uri: Optional2(validURL2),
1637
- registration_endpoint: Optional2(validURL2),
1638
- scopes_supported: Recommended2([]),
1639
- response_types_supported: Required2(anyOf2("code", "token")),
1640
- response_modes_supported: Optional2([]),
1641
- grant_types_supported: Optional2([]),
1642
- token_endpoint_auth_methods_supported: Optional2([]),
1643
- token_endpoint_auth_signing_alg_values_supported: Optional2([]),
1644
- service_documentation: Optional2(validURL2),
1645
- ui_locales_supported: Optional2([]),
1646
- op_policy_uri: Optional2(validURL2),
1647
- op_tos_uri: Optional2(validURL2),
1648
- revocation_endpoint: Optional2(validURL2),
1649
- revocation_endpoint_auth_methods_supported: Optional2(validAuthMethods2),
1650
- revocation_endpoint_auth_signing_alg_values_supported: Optional2(validAlgorithms),
1651
- introspection_endpoint: Optional2(validURL2),
1652
- introspection_endpoint_auth_methods_supported: Optional2(validAuthMethods2),
1653
- introspection_endpoint_auth_signing_alg_values_supported: Optional2(validAlgorithms),
1654
- code_challendge_methods_supported: Optional2([])
1287
+ issuer: Required(validURL),
1288
+ authorization_endpoint: Required(validURL),
1289
+ token_endpoint: Required(validURL),
1290
+ jwks_uri: Optional(validURL),
1291
+ registration_endpoint: Optional(validURL),
1292
+ scopes_supported: Recommended([]),
1293
+ response_types_supported: Required(anyOf("code", "token")),
1294
+ response_modes_supported: Optional([]),
1295
+ grant_types_supported: Optional([]),
1296
+ token_endpoint_auth_methods_supported: Optional([]),
1297
+ token_endpoint_auth_signing_alg_values_supported: Optional([]),
1298
+ service_documentation: Optional(validURL),
1299
+ ui_locales_supported: Optional([]),
1300
+ op_policy_uri: Optional(validURL),
1301
+ op_tos_uri: Optional(validURL),
1302
+ revocation_endpoint: Optional(validURL),
1303
+ revocation_endpoint_auth_methods_supported: Optional(validAuthMethods),
1304
+ revocation_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1305
+ introspection_endpoint: Optional(validURL),
1306
+ introspection_endpoint_auth_methods_supported: Optional(validAuthMethods),
1307
+ introspection_endpoint_auth_signing_alg_values_supported: Optional(validAlgorithms),
1308
+ code_challendge_methods_supported: Optional([])
1655
1309
  };
1656
1310
  function makeClient(options = {}) {
1657
1311
  const defaultOptions = {
1658
1312
  client: everything_default.client()
1659
1313
  };
1660
1314
  options = Object.assign({}, defaultOptions, options);
1661
- assert2(options, {
1662
- issuer: Required2(validURL2)
1315
+ assert(options, {
1316
+ issuer: Required(validURL)
1663
1317
  });
1664
1318
  const oauth_authorization_server_configuration = fetchWellknownOauthAuthorizationServer(options.issuer);
1665
1319
  let client2 = options.client.with(options.issuer);
@@ -1667,9 +1321,9 @@
1667
1321
  async function fetchWellknownOauthAuthorizationServer(issuer, client2) {
1668
1322
  let res = client2.get(everything_default.url(issuer, ".wellknown/oauth_authorization_server"));
1669
1323
  if (res.ok) {
1670
- assert2(res.headers.get("Content-Type"), /application\/json.*/);
1324
+ assert(res.headers.get("Content-Type"), /application\/json.*/);
1671
1325
  let configuration = await res.json();
1672
- assert2(configuration, oauth_authorization_server_metadata);
1326
+ assert(configuration, oauth_authorization_server_metadata);
1673
1327
  return configuration;
1674
1328
  }
1675
1329
  throw everything_default.metroError("metro.oidcmw: Error while fetching " + issuer + ".wellknown/oauth_authorization_server", res);
@@ -1680,11 +1334,11 @@
1680
1334
  return new Promise((resolve, reject) => {
1681
1335
  const request2 = globalThis.indexedDB.open("metro", 1);
1682
1336
  request2.onupgradeneeded = () => request2.result.createObjectStore("keyPairs", { keyPath: "domain" });
1683
- request2.onerror = (event) => {
1684
- reject(event);
1337
+ request2.onerror = (event2) => {
1338
+ reject(event2);
1685
1339
  };
1686
- request2.onsuccess = (event) => {
1687
- const db = event.target.result;
1340
+ request2.onsuccess = (event2) => {
1341
+ const db = event2.target.result;
1688
1342
  resolve({
1689
1343
  set: function(value, key) {
1690
1344
  return new Promise((resolve2, reject2) => {
@@ -1812,175 +1466,549 @@
1812
1466
  default:
1813
1467
  throw new UnsupportedOperationError("unsupported RsaHashedKeyAlgorithm hash name");
1814
1468
  }
1815
- }
1816
- function esAlg(key) {
1817
- switch (key.algorithm.namedCurve) {
1818
- case "P-256":
1819
- return "ES256";
1820
- default:
1821
- throw new UnsupportedOperationError("unsupported EcKeyAlgorithm namedCurve");
1469
+ }
1470
+ function esAlg(key) {
1471
+ switch (key.algorithm.namedCurve) {
1472
+ case "P-256":
1473
+ return "ES256";
1474
+ default:
1475
+ throw new UnsupportedOperationError("unsupported EcKeyAlgorithm namedCurve");
1476
+ }
1477
+ }
1478
+ function determineJWSAlgorithm(key) {
1479
+ switch (key.algorithm.name) {
1480
+ case "RSA-PSS":
1481
+ return psAlg(key);
1482
+ case "RSASSA-PKCS1-v1_5":
1483
+ return rsAlg(key);
1484
+ case "ECDSA":
1485
+ return esAlg(key);
1486
+ case "Ed25519":
1487
+ return "EdDSA";
1488
+ default:
1489
+ throw new UnsupportedOperationError("unsupported CryptoKey algorithm name");
1490
+ }
1491
+ }
1492
+ function isCryptoKey(key) {
1493
+ return key instanceof CryptoKey;
1494
+ }
1495
+ function isPrivateKey(key) {
1496
+ return isCryptoKey(key) && key.type === "private";
1497
+ }
1498
+ function isPublicKey(key) {
1499
+ return isCryptoKey(key) && key.type === "public";
1500
+ }
1501
+ function epochTime() {
1502
+ return Math.floor(Date.now() / 1e3);
1503
+ }
1504
+ async function DPoP(keypair, htu, htm, nonce, accessToken, additional) {
1505
+ const privateKey = keypair?.privateKey;
1506
+ const publicKey = keypair?.publicKey;
1507
+ if (!isPrivateKey(privateKey)) {
1508
+ throw new TypeError('"keypair.privateKey" must be a private CryptoKey');
1509
+ }
1510
+ if (!isPublicKey(publicKey)) {
1511
+ throw new TypeError('"keypair.publicKey" must be a public CryptoKey');
1512
+ }
1513
+ if (publicKey.extractable !== true) {
1514
+ throw new TypeError('"keypair.publicKey.extractable" must be true');
1515
+ }
1516
+ if (typeof htu !== "string") {
1517
+ throw new TypeError('"htu" must be a string');
1518
+ }
1519
+ if (typeof htm !== "string") {
1520
+ throw new TypeError('"htm" must be a string');
1521
+ }
1522
+ if (nonce !== void 0 && typeof nonce !== "string") {
1523
+ throw new TypeError('"nonce" must be a string or undefined');
1524
+ }
1525
+ if (accessToken !== void 0 && typeof accessToken !== "string") {
1526
+ throw new TypeError('"accessToken" must be a string or undefined');
1527
+ }
1528
+ if (additional !== void 0 && (typeof additional !== "object" || additional === null || Array.isArray(additional))) {
1529
+ throw new TypeError('"additional" must be an object');
1530
+ }
1531
+ return jwt({
1532
+ alg: determineJWSAlgorithm(privateKey),
1533
+ typ: "dpop+jwt",
1534
+ jwk: await publicJwk(publicKey)
1535
+ }, {
1536
+ ...additional,
1537
+ iat: epochTime(),
1538
+ jti: randomBytes(),
1539
+ htm,
1540
+ nonce,
1541
+ htu,
1542
+ ath: accessToken ? b64u(await crypto.subtle.digest("SHA-256", buf(accessToken))) : void 0
1543
+ }, privateKey);
1544
+ }
1545
+ async function publicJwk(key) {
1546
+ const { kty, e, n, x, y, crv } = await crypto.subtle.exportKey("jwk", key);
1547
+ return { kty, crv, e, n, x, y };
1548
+ }
1549
+ async function generateKeyPair(alg, options) {
1550
+ let algorithm;
1551
+ if (typeof alg !== "string" || alg.length === 0) {
1552
+ throw new TypeError('"alg" must be a non-empty string');
1553
+ }
1554
+ switch (alg) {
1555
+ case "PS256":
1556
+ algorithm = {
1557
+ name: "RSA-PSS",
1558
+ hash: "SHA-256",
1559
+ modulusLength: options?.modulusLength ?? 2048,
1560
+ publicExponent: new Uint8Array([1, 0, 1])
1561
+ };
1562
+ break;
1563
+ case "RS256":
1564
+ algorithm = {
1565
+ name: "RSASSA-PKCS1-v1_5",
1566
+ hash: "SHA-256",
1567
+ modulusLength: options?.modulusLength ?? 2048,
1568
+ publicExponent: new Uint8Array([1, 0, 1])
1569
+ };
1570
+ break;
1571
+ case "ES256":
1572
+ algorithm = { name: "ECDSA", namedCurve: "P-256" };
1573
+ break;
1574
+ case "EdDSA":
1575
+ algorithm = { name: "Ed25519" };
1576
+ break;
1577
+ default:
1578
+ throw new UnsupportedOperationError();
1579
+ }
1580
+ return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ["sign", "verify"]);
1581
+ }
1582
+
1583
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.dpop.mjs
1584
+ function dpopmw(options) {
1585
+ assert(options, {
1586
+ site: Required(validURL),
1587
+ authorization_endpoint: Required(validURL),
1588
+ token_endpoint: Required(validURL),
1589
+ dpop_signing_alg_values_supported: Optional([])
1590
+ // this property is unfortunately rarely supported
1591
+ });
1592
+ return async (req, next) => {
1593
+ const keys = await keysStore();
1594
+ let keyInfo = await keys.get(options.site);
1595
+ if (!keyInfo) {
1596
+ let keyPair = await generateKeyPair("ES256");
1597
+ keyInfo = { domain: options.site, keyPair };
1598
+ await keys.set(keyInfo);
1599
+ }
1600
+ const url2 = everything_default.url(req.url);
1601
+ if (req.url.startsWith(options.authorization_endpoint)) {
1602
+ let params2 = req.body;
1603
+ if (params2 instanceof URLSearchParams || params2 instanceof FormData) {
1604
+ params2.set("dpop_jkt", keyInfo.keyPair.publicKey);
1605
+ } else {
1606
+ params2.dpop_jkt = keyInfo.keyPair.publicKey;
1607
+ }
1608
+ } else if (req.url.startsWith(options.token_endpoint)) {
1609
+ const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method);
1610
+ req = req.with({
1611
+ headers: {
1612
+ "DPoP": dpopHeader
1613
+ }
1614
+ });
1615
+ } else if (req.headers.has("Authorization")) {
1616
+ const nonce = localStorage.getItem(url2.host + ":nonce") || void 0;
1617
+ const accessToken = req.headers.get("Authorization").split(" ")[1];
1618
+ const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method, nonce, accessToken);
1619
+ req = req.with({
1620
+ headers: {
1621
+ "Authorization": "DPoP " + accessToken,
1622
+ "DPoP": dpopHeader
1623
+ }
1624
+ });
1625
+ }
1626
+ let response2 = await next(req);
1627
+ if (response2.headers.get("DPoP-Nonce")) {
1628
+ localStorage.setItem(url2.host + ":nonce", response2.headers.get("DPoP-Nonce"));
1629
+ }
1630
+ return response2;
1631
+ };
1632
+ }
1633
+
1634
+ // node_modules/@muze-nl/metro-oauth2/src/browser.mjs
1635
+ var oauth2 = Object.assign(oauth2_exports, {
1636
+ oauth2mw,
1637
+ mockserver: oauth2_mockserver_exports,
1638
+ discover: oauth2_discovery_exports,
1639
+ tokenstore: tokenStore,
1640
+ dpopmw,
1641
+ keysstore: keysStore
1642
+ });
1643
+ if (!globalThis.metro.oauth2) {
1644
+ globalThis.metro.oauth2 = oauth2;
1645
+ }
1646
+
1647
+ // node_modules/@muze-nl/assert/src/assert.mjs
1648
+ globalThis.assertEnabled = false;
1649
+ function assert2(source, test) {
1650
+ if (globalThis.assertEnabled) {
1651
+ let problems = fails2(source, test);
1652
+ if (problems) {
1653
+ console.error("\u{1F170}\uFE0F Assertions failed because of:", problems, "in this source:", source);
1654
+ throw new Error("Assertions failed", {
1655
+ cause: { problems, source }
1656
+ });
1657
+ }
1658
+ }
1659
+ }
1660
+ function Optional2(pattern) {
1661
+ return function _Optional(data, root, path) {
1662
+ if (typeof data != "undefined" && data != null && typeof pattern != "undefined") {
1663
+ return fails2(data, pattern, root, path);
1664
+ }
1665
+ };
1666
+ }
1667
+ function Required2(pattern) {
1668
+ return function _Required(data, root, path) {
1669
+ if (data == null || typeof data == "undefined") {
1670
+ return error3("data is required", data, pattern || "any value", path);
1671
+ } else if (typeof pattern != "undefined") {
1672
+ return fails2(data, pattern, root, path);
1673
+ } else {
1674
+ return false;
1675
+ }
1676
+ };
1677
+ }
1678
+ function Recommended2(pattern) {
1679
+ return function _Recommended(data, root, path) {
1680
+ if (data == null || typeof data == "undefined") {
1681
+ console.warn("data does not contain recommended value", data, pattern, path);
1682
+ return false;
1683
+ } else {
1684
+ return fails2(data, pattern, root, path);
1685
+ }
1686
+ };
1687
+ }
1688
+ function oneOf2(...patterns) {
1689
+ return function _oneOf(data, root, path) {
1690
+ for (let pattern of patterns) {
1691
+ if (!fails2(data, pattern, root, path)) {
1692
+ return false;
1693
+ }
1694
+ }
1695
+ return error3("data does not match oneOf patterns", data, patterns, path);
1696
+ };
1697
+ }
1698
+ function anyOf2(...patterns) {
1699
+ return function _anyOf(data, root, path) {
1700
+ if (!Array.isArray(data)) {
1701
+ return error3("data is not an array", data, "anyOf", path);
1702
+ }
1703
+ for (let value of data) {
1704
+ if (oneOf2(...patterns)(value)) {
1705
+ return error3("data does not match anyOf patterns", value, patterns, path);
1706
+ }
1707
+ }
1708
+ return false;
1709
+ };
1710
+ }
1711
+ function allOf(...patterns) {
1712
+ return function _allOf(data, root, path) {
1713
+ let problems = [];
1714
+ for (let pattern of patterns) {
1715
+ problems = problems.concat(fails2(data, pattern, root, path));
1716
+ }
1717
+ problems = problems.filter(Boolean);
1718
+ if (problems.length) {
1719
+ return error3("data does not match all given patterns", data, patterns, path, problems);
1720
+ }
1721
+ };
1722
+ }
1723
+ function validURL2(data, root, path) {
1724
+ try {
1725
+ if (data instanceof URL) {
1726
+ data = data.href;
1727
+ }
1728
+ let url2 = new URL(data);
1729
+ if (url2.href != data) {
1730
+ if (!(url2.href + "/" == data || url2.href == data + "/")) {
1731
+ return error3("data is not a valid url", data, "validURL", path);
1732
+ }
1733
+ }
1734
+ } catch (e) {
1735
+ return error3("data is not a valid url", data, "validURL", path);
1736
+ }
1737
+ }
1738
+ function validEmail(data, root, path) {
1739
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
1740
+ return error3("data is not a valid email", data, "validEmail", path);
1741
+ }
1742
+ }
1743
+ function instanceOf(constructor) {
1744
+ return function _instanceOf(data, root, path) {
1745
+ if (!(data instanceof constructor)) {
1746
+ return error3("data is not an instanceof pattern", data, constructor, path);
1747
+ }
1748
+ };
1749
+ }
1750
+ function not(pattern) {
1751
+ return function _not(data, root, path) {
1752
+ if (!fails2(data, pattern, root, path)) {
1753
+ return error3("data matches pattern, when required not to", data, pattern, path);
1754
+ }
1755
+ };
1756
+ }
1757
+ function fails2(data, pattern, root, path = "") {
1758
+ if (!root) {
1759
+ root = data;
1760
+ }
1761
+ let problems = [];
1762
+ if (pattern === Boolean) {
1763
+ if (typeof data != "boolean" && !(data instanceof Boolean)) {
1764
+ problems.push(error3("data is not a boolean", data, pattern, path));
1765
+ }
1766
+ } else if (pattern === Number) {
1767
+ if (typeof data != "number" && !(data instanceof Number)) {
1768
+ problems.push(error3("data is not a number", data, pattern, path));
1769
+ }
1770
+ } else if (pattern === String) {
1771
+ if (typeof data != "string" && !(data instanceof String)) {
1772
+ problems.push(error3("data is not a string", data, pattern, path));
1773
+ }
1774
+ if (data == "") {
1775
+ problems.push(error3("data is an empty string, which is not allowed", data, pattern, path));
1776
+ }
1777
+ } else if (pattern instanceof RegExp) {
1778
+ if (Array.isArray(data)) {
1779
+ let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
1780
+ if (index > -1) {
1781
+ problems.push(error3("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
1782
+ }
1783
+ } else if (typeof data == "undefined") {
1784
+ problems.push(error3("data is undefined, should match pattern", data, pattern, path));
1785
+ } else if (!pattern.test(data)) {
1786
+ problems.push(error3("data does not match pattern", data, pattern, path));
1787
+ }
1788
+ } else if (pattern instanceof Function) {
1789
+ let problem = pattern(data, root, path);
1790
+ if (problem) {
1791
+ if (Array.isArray(problem)) {
1792
+ problems = problems.concat(problem);
1793
+ } else {
1794
+ problems.push(problem);
1795
+ }
1796
+ }
1797
+ } else if (Array.isArray(pattern)) {
1798
+ if (!Array.isArray(data)) {
1799
+ problems.push(error3("data is not an array", data, [], path));
1800
+ }
1801
+ for (let p2 of pattern) {
1802
+ for (let index of data.keys()) {
1803
+ let problem = fails2(data[index], p2, root, path + "[" + index + "]");
1804
+ if (Array.isArray(problem)) {
1805
+ problems = problems.concat(problem);
1806
+ } else if (problem) {
1807
+ problems.push(problem);
1808
+ }
1809
+ }
1810
+ }
1811
+ } else if (pattern && typeof pattern == "object") {
1812
+ if (Array.isArray(data)) {
1813
+ let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
1814
+ if (index > -1) {
1815
+ problems.push(error3("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
1816
+ }
1817
+ } else if (!data || typeof data != "object") {
1818
+ problems.push(error3("data is not an object, pattern is", data, pattern, path));
1819
+ } else {
1820
+ if (data instanceof URLSearchParams) {
1821
+ data = Object.fromEntries(data);
1822
+ }
1823
+ if (pattern instanceof Function) {
1824
+ let result = fails2(data, pattern, root, path);
1825
+ if (result) {
1826
+ problems = problems.concat(result);
1827
+ }
1828
+ } else {
1829
+ for (const [wKey, wVal] of Object.entries(pattern)) {
1830
+ let result = fails2(data[wKey], wVal, root, path + "." + wKey);
1831
+ if (result) {
1832
+ problems = problems.concat(result);
1833
+ }
1834
+ }
1835
+ }
1836
+ }
1837
+ } else {
1838
+ if (pattern != data) {
1839
+ problems.push(error3("data and pattern are not equal", data, pattern, path));
1840
+ }
1841
+ }
1842
+ if (problems.length) {
1843
+ return problems;
1822
1844
  }
1845
+ return false;
1823
1846
  }
1824
- function determineJWSAlgorithm(key) {
1825
- switch (key.algorithm.name) {
1826
- case "RSA-PSS":
1827
- return psAlg(key);
1828
- case "RSASSA-PKCS1-v1_5":
1829
- return rsAlg(key);
1830
- case "ECDSA":
1831
- return esAlg(key);
1832
- case "Ed25519":
1833
- return "EdDSA";
1834
- default:
1835
- throw new UnsupportedOperationError("unsupported CryptoKey algorithm name");
1847
+ function error3(message, found, expected, path, problems) {
1848
+ let result = {
1849
+ message,
1850
+ found,
1851
+ expected,
1852
+ path
1853
+ };
1854
+ if (problems) {
1855
+ result.problems = problems;
1836
1856
  }
1857
+ return result;
1837
1858
  }
1838
- function isCryptoKey(key) {
1839
- return key instanceof CryptoKey;
1840
- }
1841
- function isPrivateKey(key) {
1842
- return isCryptoKey(key) && key.type === "private";
1843
- }
1844
- function isPublicKey(key) {
1845
- return isCryptoKey(key) && key.type === "public";
1846
- }
1847
- function epochTime() {
1848
- return Math.floor(Date.now() / 1e3);
1849
- }
1850
- async function DPoP(keypair, htu, htm, nonce, accessToken, additional) {
1851
- const privateKey = keypair?.privateKey;
1852
- const publicKey = keypair?.publicKey;
1853
- if (!isPrivateKey(privateKey)) {
1854
- throw new TypeError('"keypair.privateKey" must be a private CryptoKey');
1855
- }
1856
- if (!isPublicKey(publicKey)) {
1857
- throw new TypeError('"keypair.publicKey" must be a public CryptoKey');
1858
- }
1859
- if (publicKey.extractable !== true) {
1860
- throw new TypeError('"keypair.publicKey.extractable" must be true');
1861
- }
1862
- if (typeof htu !== "string") {
1863
- throw new TypeError('"htu" must be a string');
1864
- }
1865
- if (typeof htm !== "string") {
1866
- throw new TypeError('"htm" must be a string');
1867
- }
1868
- if (nonce !== void 0 && typeof nonce !== "string") {
1869
- throw new TypeError('"nonce" must be a string or undefined');
1870
- }
1871
- if (accessToken !== void 0 && typeof accessToken !== "string") {
1872
- throw new TypeError('"accessToken" must be a string or undefined');
1873
- }
1874
- if (additional !== void 0 && (typeof additional !== "object" || additional === null || Array.isArray(additional))) {
1875
- throw new TypeError('"additional" must be an object');
1859
+
1860
+ // src/oidc.util.mjs
1861
+ var MustHave = (...options) => (value, root) => {
1862
+ if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
1863
+ return false;
1876
1864
  }
1877
- return jwt({
1878
- alg: determineJWSAlgorithm(privateKey),
1879
- typ: "dpop+jwt",
1880
- jwk: await publicJwk(publicKey)
1881
- }, {
1882
- ...additional,
1883
- iat: epochTime(),
1884
- jti: randomBytes(),
1885
- htm,
1886
- nonce,
1887
- htu,
1888
- ath: accessToken ? b64u(await crypto.subtle.digest("SHA-256", buf(accessToken))) : void 0
1889
- }, privateKey);
1890
- }
1891
- async function publicJwk(key) {
1892
- const { kty, e, n, x, y, crv } = await crypto.subtle.exportKey("jwk", key);
1893
- return { kty, crv, e, n, x, y };
1894
- }
1895
- async function generateKeyPair(alg, options) {
1896
- let algorithm;
1897
- if (typeof alg !== "string" || alg.length === 0) {
1898
- throw new TypeError('"alg" must be a non-empty string');
1865
+ return error3("root data must have all of", root, options);
1866
+ };
1867
+ var MustInclude = (...options) => (value) => {
1868
+ if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
1869
+ return false;
1870
+ } else {
1871
+ return error3("data must be an array which includes", value, options);
1899
1872
  }
1900
- switch (alg) {
1901
- case "PS256":
1902
- algorithm = {
1903
- name: "RSA-PSS",
1904
- hash: "SHA-256",
1905
- modulusLength: options?.modulusLength ?? 2048,
1906
- publicExponent: new Uint8Array([1, 0, 1])
1907
- };
1908
- break;
1909
- case "RS256":
1910
- algorithm = {
1911
- name: "RSASSA-PKCS1-v1_5",
1912
- hash: "SHA-256",
1913
- modulusLength: options?.modulusLength ?? 2048,
1914
- publicExponent: new Uint8Array([1, 0, 1])
1915
- };
1916
- break;
1917
- case "ES256":
1918
- algorithm = { name: "ECDSA", namedCurve: "P-256" };
1919
- break;
1920
- case "EdDSA":
1921
- algorithm = { name: "Ed25519" };
1922
- break;
1923
- default:
1924
- throw new UnsupportedOperationError();
1873
+ };
1874
+ var validJWA = [
1875
+ "HS256",
1876
+ "HS384",
1877
+ "HS512",
1878
+ "RS256",
1879
+ "RS384",
1880
+ "RS512",
1881
+ "ES256",
1882
+ "ES384",
1883
+ "ES512"
1884
+ ];
1885
+ var validAuthMethods2 = [
1886
+ "client_secret_post",
1887
+ "client_secret_basic",
1888
+ "client_secret_jwt",
1889
+ "private_key_jwt"
1890
+ ];
1891
+
1892
+ // src/oidc.discovery.mjs
1893
+ async function oidcDiscovery(options = {}) {
1894
+ assert2(options, {
1895
+ client: Optional2(instanceOf(everything_default.client().constructor)),
1896
+ issuer: Required2(validURL2)
1897
+ });
1898
+ const defaultOptions = {
1899
+ client: everything_default.client().with(thrower()).with(jsonmw()),
1900
+ requireDynamicRegistration: false
1901
+ };
1902
+ options = Object.assign({}, defaultOptions, options);
1903
+ const TestSucceeded = false;
1904
+ function MustUseHTTPS(url2) {
1905
+ return TestSucceeded;
1925
1906
  }
1926
- return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ["sign", "verify"]);
1907
+ const openid_provider_metadata = {
1908
+ issuer: Required2(allOf(options.issuer, MustUseHTTPS)),
1909
+ authorization_endpoint: Required2(validURL2),
1910
+ token_endpoint: Required2(validURL2),
1911
+ userinfo_endpoint: Recommended2(validURL2),
1912
+ // todo: test for https protocol
1913
+ jwks_uri: Required2(validURL2),
1914
+ registration_endpoint: options.requireDynamicRegistration ? Required2(validURL2) : Recommended2(validURL2),
1915
+ scopes_supported: Recommended2(MustInclude("openid")),
1916
+ response_types_supported: options.requireDynamicRegistration ? Required2(MustInclude("code", "id_token", "id_token token")) : Required2([]),
1917
+ response_modes_supported: Optional2([]),
1918
+ grant_types_supported: options.requireDynamicRegistration ? Optional2(MustInclude("authorization_code")) : Optional2([]),
1919
+ acr_values_supported: Optional2([]),
1920
+ subject_types_supported: Required2([]),
1921
+ id_token_signing_alg_values_supported: Required2(MustInclude("RS256")),
1922
+ id_token_encryption_alg_values_supported: Optional2([]),
1923
+ id_token_encryption_enc_values_supported: Optional2([]),
1924
+ userinfo_signing_alg_values_supported: Optional2([]),
1925
+ userinfo_encryption_alg_values_supported: Optional2([]),
1926
+ userinfo_encryption_enc_values_supported: Optional2([]),
1927
+ request_object_signing_alg_values_supported: Optional2(MustInclude("RS256")),
1928
+ // not testing for 'none'
1929
+ request_object_encryption_alg_values_supported: Optional2([]),
1930
+ request_object_encryption_enc_values_supported: Optional2([]),
1931
+ token_endpoint_auth_methods_supported: Optional2(anyOf2(...validAuthMethods2)),
1932
+ token_endpoint_auth_signing_alg_values_supported: Optional2(MustInclude("RS256"), not(MustInclude("none"))),
1933
+ display_values_supported: Optional2(anyOf2("page", "popup", "touch", "wap")),
1934
+ claim_types_supported: Optional2(anyOf2("normal", "aggregated", "distributed")),
1935
+ claims_supported: Recommended2([]),
1936
+ service_documentation: Optional2(validURL2),
1937
+ claims_locales_supported: Optional2([]),
1938
+ ui_locales_supported: Optional2([]),
1939
+ claims_parameter_supported: Optional2(Boolean),
1940
+ request_parameter_supported: Optional2(Boolean),
1941
+ request_uri_parameter_supported: Optional2(Boolean),
1942
+ op_policy_uri: Optional2(validURL2),
1943
+ op_tos_uri: Optional2(validURL2)
1944
+ };
1945
+ const configURL = everything_default.url(options.issuer, ".well-known/openid-configuration");
1946
+ const response2 = await options.client.get(
1947
+ // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
1948
+ // note: this allows path components in the options.issuer url
1949
+ configURL
1950
+ );
1951
+ const openid_config = response2.data;
1952
+ assert2(openid_config, openid_provider_metadata);
1953
+ assert2(openid_config.issuer, options.issuer);
1954
+ return openid_config;
1927
1955
  }
1928
1956
 
1929
- // node_modules/@muze-nl/metro-oauth2/src/oauth2.dpop.mjs
1930
- function dpopmw(options) {
1957
+ // src/oidc.register.mjs
1958
+ async function register(options) {
1959
+ const openid_client_metadata = {
1960
+ redirect_uris: Required2([validURL2]),
1961
+ response_types: Optional2([]),
1962
+ grant_types: Optional2(anyOf2("authorization_code", "refresh_token")),
1963
+ //TODO: match response_types with grant_types
1964
+ application_type: Optional2(oneOf2("native", "web")),
1965
+ contacts: Optional2([validEmail]),
1966
+ client_name: Optional2(String),
1967
+ logo_uri: Optional2(validURL2),
1968
+ client_uri: Optional2(validURL2),
1969
+ policy_uri: Optional2(validURL2),
1970
+ tos_uri: Optional2(validURL2),
1971
+ jwks_uri: Optional2(validURL2, not(MustHave("jwks"))),
1972
+ jwks: Optional2(validURL2, not(MustHave("jwks_uri"))),
1973
+ sector_identifier_uri: Optional2(validURL2),
1974
+ subject_type: Optional2(String),
1975
+ id_token_signed_response_alg: Optional2(oneOf2(...validJWA)),
1976
+ id_token_encrypted_response_alg: Optional2(oneOf2(...validJWA)),
1977
+ id_token_encrypted_response_enc: Optional2(oneOf2(...validJWA), MustHave("id_token_encrypted_response_alg")),
1978
+ userinfo_signed_response_alg: Optional2(oneOf2(...validJWA)),
1979
+ userinfo_encrypted_response_alg: Optional2(oneOf2(...validJWA)),
1980
+ userinfo_encrypted_response_enc: Optional2(oneOf2(...validJWA), MustHave("userinfo_encrypted_response_alg")),
1981
+ request_object_signing_alg: Optional2(oneOf2(...validJWA)),
1982
+ request_object_encryption_alg: Optional2(oneOf2(...validJWA)),
1983
+ request_object_encryption_enc: Optional2(oneOf2(...validJWA)),
1984
+ token_endpoint_auth_method: Optional2(oneOf2(...validAuthMethods2)),
1985
+ token_endpoint_auth_signing_alg: Optional2(oneOf2(...validJWA)),
1986
+ default_max_age: Optional2(Number),
1987
+ require_auth_time: Optional2(Boolean),
1988
+ default_acr_values: Optional2([String]),
1989
+ initiate_login_uri: Optional2([validURL2]),
1990
+ request_uris: Optional2([validURL2])
1991
+ };
1931
1992
  assert2(options, {
1932
- site: Required2(validURL2),
1933
- authorization_endpoint: Required2(validURL2),
1934
- token_endpoint: Required2(validURL2)
1935
- // dpop_signing_alg_values_supported: Required([]) // this property is unfortunately rarely supported
1993
+ client: Optional2(instanceOf(everything_default.client().constructor)),
1994
+ registration_endpoint: validURL2,
1995
+ client_info: openid_client_metadata
1936
1996
  });
1937
- return async (req, next) => {
1938
- const keys = await keysStore();
1939
- let keyInfo = await keys.get(options.site);
1940
- if (!keyInfo) {
1941
- let keyPair = await generateKeyPair("ES256");
1942
- keyInfo = { domain: options.site, keyPair };
1943
- await keys.set(keyInfo);
1944
- }
1945
- const url2 = everything_default.url(req.url);
1946
- if (req.url.startsWith(options.authorization_endpoint) || req.url.startsWith(options.token_endpoint)) {
1947
- const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method);
1948
- req = req.with({
1949
- headers: {
1950
- "DPoP": dpopHeader
1951
- }
1952
- });
1953
- } else if (req.headers.has("Authorization")) {
1954
- const nonce = localStorage.getItem(url2.host + ":nonce") || void 0;
1955
- const accessToken = req.headers.get("Authorization").split(" ")[1];
1956
- const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method, nonce, accessToken);
1957
- req = req.with({
1958
- headers: {
1959
- "Authorization": "DPoP " + accessToken,
1960
- //solidcommunity server sends accesstoken with type Bearer
1961
- "DPoP": dpopHeader
1962
- }
1963
- });
1964
- }
1965
- let response2 = await next(req);
1966
- if (response2.headers.get("DPoP-Nonce")) {
1967
- localStorage.setItem(url2.host + ":nonce", response2.headers.get("DPoP-Nonce"));
1968
- }
1969
- return response2;
1997
+ const defaultOptions = {
1998
+ client: everything_default.client().with(thrower()).with(jsonmw())
1970
1999
  };
2000
+ options = Object.assign({}, defaultOptions, options);
2001
+ let response2 = await options.client.post(options.registration_endpoint, {
2002
+ body: options.client_info
2003
+ });
2004
+ let info = response2.data;
2005
+ if (!info.client_id || !info.client_secret) {
2006
+ throw everything_default.metroError("metro.oidc: Error: dynamic registration of client failed, no client_id or client_secret returned", response2);
2007
+ }
2008
+ options.client_info = Object.assign(options.client_info, info);
2009
+ return options.client_info;
1971
2010
  }
1972
2011
 
1973
- // node_modules/@muze-nl/metro-oauth2/src/browser.mjs
1974
- var oauth2 = Object.assign(oauth2mw, oauth2_exports, {
1975
- mockserver: oauth2_mockserver_exports,
1976
- discovery: oauth2_discovery_exports,
1977
- tokenstore: tokenStore,
1978
- dpopmw,
1979
- keysstore: keysStore
1980
- });
1981
- globalThis.oauth2 = oauth2;
1982
- var browser_default = oauth2;
1983
-
1984
2012
  // src/oidc.store.mjs
1985
2013
  function oidcStore(site) {
1986
2014
  let store;
@@ -2004,17 +2032,24 @@
2004
2032
  // src/oidcmw.mjs
2005
2033
  function oidcmw(options = {}) {
2006
2034
  const defaultOptions = {
2007
- client: everything_default.client(),
2008
- force_authorization: false
2035
+ client: client(),
2036
+ force_authorization: false,
2037
+ use_dpop: true,
2038
+ authorize_callback: async (url2) => {
2039
+ if (window.location.href != url2.href) {
2040
+ window.location.replace(url2.href);
2041
+ }
2042
+ return false;
2043
+ }
2009
2044
  };
2010
2045
  options = Object.assign({}, defaultOptions, options);
2011
- assert(options, {
2012
- client: Required(instanceOf(everything_default.client().constructor)),
2046
+ assert2(options, {
2047
+ client: Required2(instanceOf(client().constructor)),
2013
2048
  // required because it is set in defaultOptions
2014
- client_info: Required(),
2015
- issuer: Required(validURL),
2016
- oauth2: Optional({}),
2017
- openid_configuration: Optional()
2049
+ client_info: Required2(),
2050
+ issuer: Required2(validURL2),
2051
+ oauth2: Optional2({}),
2052
+ openid_configuration: Optional2()
2018
2053
  });
2019
2054
  if (!options.store) {
2020
2055
  options.store = oidcStore(options.issuer);
@@ -2046,9 +2081,9 @@
2046
2081
  options.store.set("openid_configuration", options.openid_configuration);
2047
2082
  }
2048
2083
  if (!options.client_info?.client_id) {
2049
- assert(options.client_info?.client_name, Required());
2084
+ assert2(options.client_info?.client_name, Required2());
2050
2085
  if (!options.openid_configuration.registration_endpoint) {
2051
- throw everything_default.metroError("metro.oidcmw: Error: issuer " + options.issuer + " does not support dynamic client registration, but you haven't specified a client_id");
2086
+ throw metroError("metro.oidcmw: Error: issuer " + options.issuer + " does not support dynamic client registration, but you haven't specified a client_id");
2052
2087
  }
2053
2088
  options.client_info = await register({
2054
2089
  registration_endpoint: options.openid_configuration.registration_endpoint,
@@ -2062,6 +2097,7 @@
2062
2097
  site: options.issuer,
2063
2098
  client: options.client,
2064
2099
  force_authorization: true,
2100
+ authorize_callback: options.authorize_callback,
2065
2101
  oauth2_configuration: {
2066
2102
  client_id: options.client_info.client_id,
2067
2103
  client_secret: options.client_info.client_secret,
@@ -2078,48 +2114,61 @@
2078
2114
  }
2079
2115
  //...
2080
2116
  );
2081
- const dpopOptions = {
2082
- site: options.issuer,
2083
- authorization_endpoint: options.openid_configuration.authorization_endpoint,
2084
- token_endpoint: options.openid_configuration.token_endpoint,
2085
- dpop_signing_alg_values_supported: options.openid_configuration.dpop_signing_alg_values_supported
2086
- };
2087
2117
  const storeIdToken = async (req2, next2) => {
2088
2118
  const res2 = await next2(req2);
2089
2119
  const contentType = res2.headers.get("content-type");
2090
2120
  if (contentType?.startsWith("application/json")) {
2091
- const res22 = res2.clone();
2092
- try {
2093
- let data = await res22.json();
2094
- if (data && data.id_token) {
2095
- options.store.set("id_token", data.id_token);
2121
+ let id_token = res2.data?.id_token;
2122
+ if (!id_token) {
2123
+ const res22 = res2.clone();
2124
+ try {
2125
+ let data = await res22.json();
2126
+ if (data && data.id_token) {
2127
+ id_token = data.id_token;
2128
+ }
2129
+ } catch (e) {
2096
2130
  }
2097
- } catch (e) {
2131
+ }
2132
+ if (id_token) {
2133
+ options.store.set("id_token", id_token);
2098
2134
  }
2099
2135
  }
2100
2136
  return res2;
2101
2137
  };
2102
- const dPopClient = options.client.with(options.issuer).with(storeIdToken).with(browser_default.dpopmw(dpopOptions));
2103
- oauth2Options.client = dPopClient;
2104
- const oauth2client = dPopClient.with(browser_default(oauth2Options));
2138
+ let oauth2client = options.client.with(options.issuer).with(storeIdToken);
2139
+ if (options.use_dpop) {
2140
+ const dpopOptions = {
2141
+ site: options.issuer,
2142
+ authorization_endpoint: options.openid_configuration.authorization_endpoint,
2143
+ token_endpoint: options.openid_configuration.token_endpoint,
2144
+ dpop_signing_alg_values_supported: options.openid_configuration.dpop_signing_alg_values_supported
2145
+ };
2146
+ oauth2client = oauth2client.with(dpopmw(dpopOptions));
2147
+ oauth2Options.client = oauth2client;
2148
+ }
2149
+ oauth2client = oauth2client.with(oauth2mw(oauth2Options));
2105
2150
  res = await oauth2client.fetch(req);
2106
2151
  return res;
2107
2152
  };
2108
2153
  }
2109
2154
  function isRedirected2() {
2110
- return browser_default.isRedirected();
2155
+ return isRedirected();
2111
2156
  }
2112
2157
  function idToken(options) {
2113
2158
  return options.store.get("id_token");
2114
2159
  }
2115
2160
 
2116
2161
  // src/browser.mjs
2117
- var oidc = Object.assign(oidcmw, {
2162
+ var oidc = {
2163
+ oidcmw,
2118
2164
  discover: oidcDiscovery,
2119
2165
  register,
2120
2166
  isRedirected: isRedirected2,
2121
2167
  idToken
2122
- });
2123
- globalThis.oidc = oidc;
2168
+ };
2169
+ if (!globalThis.metro.oidc) {
2170
+ globalThis.metro.oidc = oidc;
2171
+ }
2172
+ var browser_default2 = oidc;
2124
2173
  })();
2125
2174
  //# sourceMappingURL=browser.js.map