@muze-nl/metro-oidc 0.3.0 → 0.3.1

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