@muze-nl/metro-oidc 0.3.3 → 0.3.5
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/README.md +5 -3
- package/dist/browser.js +285 -396
- package/dist/browser.js.map +4 -4
- package/dist/browser.min.js +1 -1
- package/dist/browser.min.js.map +4 -4
- package/package.json +3 -3
- package/src/oidcmw.mjs +8 -1
package/dist/browser.js
CHANGED
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
}
|
|
81
81
|
let index = middlewares.findIndex((m) => typeof m != "function");
|
|
82
82
|
if (index >= 0) {
|
|
83
|
-
throw metroError("metro.client: middlewares must be a function or an array of functions " + metroURL + "client/invalid-middlewares
|
|
83
|
+
throw metroError("metro.client: middlewares must be a function or an array of functions " + metroURL + "client/invalid-middlewares/", middlewares[index]);
|
|
84
84
|
}
|
|
85
85
|
if (!Array.isArray(this.#options.middlewares)) {
|
|
86
86
|
this.#options.middlewares = [];
|
|
@@ -97,13 +97,13 @@
|
|
|
97
97
|
fetch(req, options) {
|
|
98
98
|
req = request(req, options);
|
|
99
99
|
if (!req.url) {
|
|
100
|
-
throw metroError("metro.client." + req.method.toLowerCase() + ": Missing url parameter " + metroURL + "client/missing-url
|
|
100
|
+
throw metroError("metro.client." + req.method.toLowerCase() + ": Missing url parameter " + metroURL + "client/fetch-missing-url/", req);
|
|
101
101
|
}
|
|
102
102
|
if (!options) {
|
|
103
103
|
options = {};
|
|
104
104
|
}
|
|
105
|
-
if (!(typeof options === "object") ||
|
|
106
|
-
throw metroError("metro.client.fetch:
|
|
105
|
+
if (!(typeof options === "object") || options instanceof String) {
|
|
106
|
+
throw metroError("metro.client.fetch: Invalid options parameter " + metroURL + "client/fetch-invalid-options/", options);
|
|
107
107
|
}
|
|
108
108
|
const metrofetch = async function browserFetch(req2) {
|
|
109
109
|
if (req2[Symbol.metroProxy]) {
|
|
@@ -210,13 +210,16 @@
|
|
|
210
210
|
Object.assign(requestParams, getRequestParams(option, requestParams));
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
let r = new Request(requestParams.url, requestParams);
|
|
213
214
|
let data = requestParams.body;
|
|
214
215
|
if (data) {
|
|
215
216
|
if (typeof data == "object" && !(data instanceof String) && !(data instanceof ReadableStream) && !(data instanceof Blob) && !(data instanceof ArrayBuffer) && !(data instanceof DataView) && !(data instanceof FormData) && !(data instanceof URLSearchParams) && (typeof TypedArray == "undefined" || !(data instanceof TypedArray))) {
|
|
216
|
-
|
|
217
|
+
if (typeof data.toString == "function") {
|
|
218
|
+
requestParams.body = data.toString({ headers: r.headers });
|
|
219
|
+
r = new Request(requestParams.url, requestParams);
|
|
220
|
+
}
|
|
217
221
|
}
|
|
218
222
|
}
|
|
219
|
-
let r = new Request(requestParams.url, requestParams);
|
|
220
223
|
Object.freeze(r);
|
|
221
224
|
return new Proxy(r, {
|
|
222
225
|
get(target, prop, receiver) {
|
|
@@ -235,8 +238,6 @@
|
|
|
235
238
|
return request(target, ...options2);
|
|
236
239
|
};
|
|
237
240
|
break;
|
|
238
|
-
case "body":
|
|
239
|
-
break;
|
|
240
241
|
case "data":
|
|
241
242
|
return data;
|
|
242
243
|
break;
|
|
@@ -297,6 +298,9 @@
|
|
|
297
298
|
if (responseParams.body) {
|
|
298
299
|
data = responseParams.body;
|
|
299
300
|
}
|
|
301
|
+
if ([101, 204, 205, 304].includes(responseParams.status)) {
|
|
302
|
+
responseParams.body = null;
|
|
303
|
+
}
|
|
300
304
|
let r = new Response(responseParams.body, responseParams);
|
|
301
305
|
Object.freeze(r);
|
|
302
306
|
return new Proxy(r, {
|
|
@@ -361,27 +365,31 @@
|
|
|
361
365
|
appendSearchParams(u, option);
|
|
362
366
|
} else if (option && typeof option == "object") {
|
|
363
367
|
for (let param in option) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
option.search
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
368
|
+
switch (param) {
|
|
369
|
+
case "search":
|
|
370
|
+
if (typeof option.search == "function") {
|
|
371
|
+
option.search(u.search, u);
|
|
372
|
+
} else {
|
|
373
|
+
u.search = new URLSearchParams(option.search);
|
|
374
|
+
}
|
|
375
|
+
break;
|
|
376
|
+
case "searchParams":
|
|
377
|
+
appendSearchParams(u, option.searchParams);
|
|
378
|
+
break;
|
|
379
|
+
default:
|
|
380
|
+
if (!validParams.includes(param)) {
|
|
381
|
+
throw metroError("metro.url: unknown url parameter " + metroURL + "url/unknown-param-name/", param);
|
|
382
|
+
}
|
|
383
|
+
if (typeof option[param] == "function") {
|
|
384
|
+
option[param](u[param], u);
|
|
385
|
+
} else if (typeof option[param] == "string" || option[param] instanceof String || typeof option[param] == "number" || option[param] instanceof Number || typeof option[param] == "boolean" || option[param] instanceof Boolean) {
|
|
386
|
+
u[param] = "" + option[param];
|
|
387
|
+
} else if (typeof option[param] == "object" && option[param].toString) {
|
|
388
|
+
u[param] = option[param].toString();
|
|
389
|
+
} else {
|
|
390
|
+
throw metroError("metro.url: unsupported value for " + param + " " + metroURL + "url/unsupported-param-value/", options[param]);
|
|
391
|
+
}
|
|
392
|
+
break;
|
|
385
393
|
}
|
|
386
394
|
}
|
|
387
395
|
} else {
|
|
@@ -403,6 +411,12 @@
|
|
|
403
411
|
return url(target, ...options2);
|
|
404
412
|
};
|
|
405
413
|
break;
|
|
414
|
+
case "filename":
|
|
415
|
+
return target.pathname.split("/").pop();
|
|
416
|
+
break;
|
|
417
|
+
case "folderpath":
|
|
418
|
+
return target.pathname.substring(0, target.pathname.lastIndexOf("\\") + 1);
|
|
419
|
+
break;
|
|
406
420
|
}
|
|
407
421
|
if (target[prop] instanceof Function) {
|
|
408
422
|
return target[prop].bind(target);
|
|
@@ -414,6 +428,9 @@
|
|
|
414
428
|
function formdata(...options) {
|
|
415
429
|
var params2 = new FormData();
|
|
416
430
|
for (let option of options) {
|
|
431
|
+
if (option instanceof HTMLFormElement) {
|
|
432
|
+
option = new FormData(option);
|
|
433
|
+
}
|
|
417
434
|
if (option instanceof FormData) {
|
|
418
435
|
for (let entry of option.entries()) {
|
|
419
436
|
params2.append(entry[0], entry[1]);
|
|
@@ -429,7 +446,7 @@
|
|
|
429
446
|
}
|
|
430
447
|
}
|
|
431
448
|
} else {
|
|
432
|
-
throw new metroError("metro.formdata: unknown option type
|
|
449
|
+
throw new metroError("metro.formdata: unknown option type " + metroURL + "formdata/unknown-option-value/", option);
|
|
433
450
|
}
|
|
434
451
|
}
|
|
435
452
|
Object.freeze(params2);
|
|
@@ -442,6 +459,9 @@
|
|
|
442
459
|
case Symbol.metroSource:
|
|
443
460
|
return target;
|
|
444
461
|
break;
|
|
462
|
+
//TODO: add toString() that can check
|
|
463
|
+
//headers param: toString({headers:request.headers})
|
|
464
|
+
//for the content-type
|
|
445
465
|
case "with":
|
|
446
466
|
return function(...options2) {
|
|
447
467
|
return formdata(target, ...options2);
|
|
@@ -610,120 +630,199 @@
|
|
|
610
630
|
isRedirected: () => isRedirected
|
|
611
631
|
});
|
|
612
632
|
|
|
613
|
-
// node_modules/@muze-nl/
|
|
633
|
+
// node_modules/@muze-nl/assert/src/assert.mjs
|
|
614
634
|
globalThis.assertEnabled = false;
|
|
615
|
-
|
|
635
|
+
function assert(source, test) {
|
|
616
636
|
if (globalThis.assertEnabled) {
|
|
617
637
|
let problems = fails(source, test);
|
|
618
638
|
if (problems) {
|
|
619
|
-
|
|
639
|
+
console.error("\u{1F170}\uFE0F Assertions failed because of:", problems, "in this source:", source);
|
|
640
|
+
throw new Error("Assertions failed", {
|
|
641
|
+
cause: { problems, source }
|
|
642
|
+
});
|
|
620
643
|
}
|
|
621
644
|
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
645
|
+
}
|
|
646
|
+
function Optional(pattern) {
|
|
647
|
+
return function _Optional(data, root, path) {
|
|
648
|
+
if (typeof data != "undefined" && data != null && typeof pattern != "undefined") {
|
|
649
|
+
return fails(data, pattern, root, path);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
function Required(pattern) {
|
|
654
|
+
return function _Required(data, root, path) {
|
|
655
|
+
if (data == null || typeof data == "undefined") {
|
|
656
|
+
return error2("data is required", data, pattern || "any value", path);
|
|
657
|
+
} else if (typeof pattern != "undefined") {
|
|
658
|
+
return fails(data, pattern, root, path);
|
|
659
|
+
} else {
|
|
632
660
|
return false;
|
|
633
661
|
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
return error2("data does not match anyOf patterns", value, patterns);
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
function Recommended(pattern) {
|
|
665
|
+
return function _Recommended(data, root, path) {
|
|
666
|
+
if (data == null || typeof data == "undefined") {
|
|
667
|
+
console.warn("data does not contain recommended value", data, pattern, path);
|
|
668
|
+
return false;
|
|
669
|
+
} else {
|
|
670
|
+
return fails(data, pattern, root, path);
|
|
644
671
|
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function oneOf(...patterns) {
|
|
675
|
+
return function _oneOf(data, root, path) {
|
|
676
|
+
for (let pattern of patterns) {
|
|
677
|
+
if (!fails(data, pattern, root, path)) {
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return error2("data does not match oneOf patterns", data, patterns, path);
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function anyOf(...patterns) {
|
|
685
|
+
return function _anyOf(data, root, path) {
|
|
686
|
+
if (!Array.isArray(data)) {
|
|
687
|
+
return error2("data is not an array", data, "anyOf", path);
|
|
688
|
+
}
|
|
689
|
+
for (let value of data) {
|
|
690
|
+
if (oneOf(...patterns)(value)) {
|
|
691
|
+
return error2("data does not match anyOf patterns", value, patterns, path);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return false;
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
function allOf(...patterns) {
|
|
698
|
+
return function _allOf(data, root, path) {
|
|
699
|
+
let problems = [];
|
|
700
|
+
for (let pattern of patterns) {
|
|
701
|
+
problems = problems.concat(fails(data, pattern, root, path));
|
|
702
|
+
}
|
|
703
|
+
problems = problems.filter(Boolean);
|
|
704
|
+
if (problems.length) {
|
|
705
|
+
return error2("data does not match all given patterns", data, patterns, path, problems);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
function validURL(data, root, path) {
|
|
649
710
|
try {
|
|
650
711
|
if (data instanceof URL) {
|
|
651
712
|
data = data.href;
|
|
652
713
|
}
|
|
653
714
|
let url2 = new URL(data);
|
|
654
715
|
if (url2.href != data) {
|
|
655
|
-
|
|
716
|
+
if (!(url2.href + "/" == data || url2.href == data + "/")) {
|
|
717
|
+
return error2("data is not a valid url", data, "validURL", path);
|
|
718
|
+
}
|
|
656
719
|
}
|
|
657
720
|
} catch (e) {
|
|
658
|
-
return error2("data is not a valid url", data, "validURL");
|
|
721
|
+
return error2("data is not a valid url", data, "validURL", path);
|
|
659
722
|
}
|
|
660
|
-
return false;
|
|
661
723
|
}
|
|
662
|
-
function
|
|
724
|
+
function validEmail(data, root, path) {
|
|
725
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
|
|
726
|
+
return error2("data is not a valid email", data, "validEmail", path);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function instanceOf(constructor) {
|
|
730
|
+
return function _instanceOf(data, root, path) {
|
|
731
|
+
if (!(data instanceof constructor)) {
|
|
732
|
+
return error2("data is not an instanceof pattern", data, constructor, path);
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function not(pattern) {
|
|
737
|
+
return function _not(data, root, path) {
|
|
738
|
+
if (!fails(data, pattern, root, path)) {
|
|
739
|
+
return error2("data matches pattern, when required not to", data, pattern, path);
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
function fails(data, pattern, root, path = "") {
|
|
663
744
|
if (!root) {
|
|
664
745
|
root = data;
|
|
665
746
|
}
|
|
666
747
|
let problems = [];
|
|
667
748
|
if (pattern === Boolean) {
|
|
668
|
-
if (typeof data != "boolean") {
|
|
669
|
-
problems.push(error2("data is not a boolean", data, pattern));
|
|
749
|
+
if (typeof data != "boolean" && !(data instanceof Boolean)) {
|
|
750
|
+
problems.push(error2("data is not a boolean", data, pattern, path));
|
|
670
751
|
}
|
|
671
752
|
} else if (pattern === Number) {
|
|
672
|
-
if (typeof data != "number") {
|
|
673
|
-
problems.push(error2("data is not a number", data, pattern));
|
|
753
|
+
if (typeof data != "number" && !(data instanceof Number)) {
|
|
754
|
+
problems.push(error2("data is not a number", data, pattern, path));
|
|
755
|
+
}
|
|
756
|
+
} else if (pattern === String) {
|
|
757
|
+
if (typeof data != "string" && !(data instanceof String)) {
|
|
758
|
+
problems.push(error2("data is not a string", data, pattern, path));
|
|
759
|
+
}
|
|
760
|
+
if (data == "") {
|
|
761
|
+
problems.push(error2("data is an empty string, which is not allowed", data, pattern, path));
|
|
674
762
|
}
|
|
675
763
|
} else if (pattern instanceof RegExp) {
|
|
676
764
|
if (Array.isArray(data)) {
|
|
677
|
-
let index = data.findIndex((element) => fails(element, pattern, root));
|
|
765
|
+
let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
|
|
678
766
|
if (index > -1) {
|
|
679
|
-
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
|
|
767
|
+
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
680
768
|
}
|
|
769
|
+
} else if (typeof data == "undefined") {
|
|
770
|
+
problems.push(error2("data is undefined, should match pattern", data, pattern, path));
|
|
681
771
|
} else if (!pattern.test(data)) {
|
|
682
|
-
problems.push(error2("data does not match pattern", data, pattern));
|
|
772
|
+
problems.push(error2("data does not match pattern", data, pattern, path));
|
|
683
773
|
}
|
|
684
774
|
} else if (pattern instanceof Function) {
|
|
685
|
-
|
|
686
|
-
|
|
775
|
+
let problem = pattern(data, root, path);
|
|
776
|
+
if (problem) {
|
|
777
|
+
if (Array.isArray(problem)) {
|
|
778
|
+
problems = problems.concat(problem);
|
|
779
|
+
} else {
|
|
780
|
+
problems.push(problem);
|
|
781
|
+
}
|
|
687
782
|
}
|
|
688
783
|
} else if (Array.isArray(pattern)) {
|
|
689
784
|
if (!Array.isArray(data)) {
|
|
690
|
-
problems.push(error2("data is not an array", data, []));
|
|
785
|
+
problems.push(error2("data is not an array", data, [], path));
|
|
691
786
|
}
|
|
692
|
-
for (p of pattern) {
|
|
693
|
-
let
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
787
|
+
for (let p of pattern) {
|
|
788
|
+
for (let index of data.keys()) {
|
|
789
|
+
let problem = fails(data[index], p, root, path + "[" + index + "]");
|
|
790
|
+
if (Array.isArray(problem)) {
|
|
791
|
+
problems = problems.concat(problem);
|
|
792
|
+
} else if (problem) {
|
|
793
|
+
problems.push(problem);
|
|
794
|
+
}
|
|
698
795
|
}
|
|
699
796
|
}
|
|
700
797
|
} else if (pattern && typeof pattern == "object") {
|
|
701
798
|
if (Array.isArray(data)) {
|
|
702
|
-
let index = data.findIndex((element) => fails(element, pattern, root));
|
|
799
|
+
let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
|
|
703
800
|
if (index > -1) {
|
|
704
|
-
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
|
|
801
|
+
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
705
802
|
}
|
|
706
803
|
} else if (!data || typeof data != "object") {
|
|
707
|
-
problems.push(error2("data is not an object, pattern is", data, pattern));
|
|
804
|
+
problems.push(error2("data is not an object, pattern is", data, pattern, path));
|
|
708
805
|
} else {
|
|
709
806
|
if (data instanceof URLSearchParams) {
|
|
710
807
|
data = Object.fromEntries(data);
|
|
711
808
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
let result = fails(data[wKey], wVal, root);
|
|
809
|
+
if (pattern instanceof Function) {
|
|
810
|
+
let result = fails(data, pattern, root, path);
|
|
715
811
|
if (result) {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
812
|
+
problems = problems.concat(result);
|
|
813
|
+
}
|
|
814
|
+
} else {
|
|
815
|
+
for (const [wKey, wVal] of Object.entries(pattern)) {
|
|
816
|
+
let result = fails(data[wKey], wVal, root, path + "." + wKey);
|
|
817
|
+
if (result) {
|
|
818
|
+
problems = problems.concat(result);
|
|
719
819
|
}
|
|
720
|
-
p2[wKey] = result.problems;
|
|
721
820
|
}
|
|
722
821
|
}
|
|
723
822
|
}
|
|
724
823
|
} else {
|
|
725
824
|
if (pattern != data) {
|
|
726
|
-
problems.push(error2("data and pattern are not equal", data, pattern));
|
|
825
|
+
problems.push(error2("data and pattern are not equal", data, pattern, path));
|
|
727
826
|
}
|
|
728
827
|
}
|
|
729
828
|
if (problems.length) {
|
|
@@ -731,19 +830,17 @@
|
|
|
731
830
|
}
|
|
732
831
|
return false;
|
|
733
832
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
super(message);
|
|
737
|
-
this.problems = problems;
|
|
738
|
-
this.details = details;
|
|
739
|
-
}
|
|
740
|
-
};
|
|
741
|
-
function error2(message, found, expected) {
|
|
742
|
-
return {
|
|
833
|
+
function error2(message, found, expected, path, problems) {
|
|
834
|
+
let result = {
|
|
743
835
|
message,
|
|
744
836
|
found,
|
|
745
|
-
expected
|
|
837
|
+
expected,
|
|
838
|
+
path
|
|
746
839
|
};
|
|
840
|
+
if (problems) {
|
|
841
|
+
result.problems = problems;
|
|
842
|
+
}
|
|
843
|
+
return result;
|
|
747
844
|
}
|
|
748
845
|
|
|
749
846
|
// node_modules/@muze-nl/metro-oauth2/src/tokenstore.mjs
|
|
@@ -1135,7 +1232,7 @@
|
|
|
1135
1232
|
"Content-Type": "application/json"
|
|
1136
1233
|
}
|
|
1137
1234
|
};
|
|
1138
|
-
var badRequest = (
|
|
1235
|
+
var badRequest = (error4) => {
|
|
1139
1236
|
return {
|
|
1140
1237
|
status: 400,
|
|
1141
1238
|
statusText: "Bad Request",
|
|
@@ -1144,7 +1241,7 @@
|
|
|
1144
1241
|
},
|
|
1145
1242
|
body: JSON.stringify({
|
|
1146
1243
|
error: "invalid_request",
|
|
1147
|
-
error_description:
|
|
1244
|
+
error_description: error4
|
|
1148
1245
|
})
|
|
1149
1246
|
};
|
|
1150
1247
|
};
|
|
@@ -1675,7 +1772,7 @@
|
|
|
1675
1772
|
}
|
|
1676
1773
|
|
|
1677
1774
|
// node_modules/@muze-nl/metro-oauth2/src/browser.mjs
|
|
1678
|
-
var oauth2 = Object.assign(oauth2_exports, {
|
|
1775
|
+
var oauth2 = Object.assign({}, oauth2_exports, {
|
|
1679
1776
|
oauth2mw,
|
|
1680
1777
|
mockserver: oauth2_mockserver_exports,
|
|
1681
1778
|
discover: oauth2_discovery_exports,
|
|
@@ -1689,231 +1786,18 @@
|
|
|
1689
1786
|
globalThis.metro.oauth2 = oauth2;
|
|
1690
1787
|
}
|
|
1691
1788
|
|
|
1692
|
-
// node_modules/@muze-nl/assert/src/assert.mjs
|
|
1693
|
-
globalThis.assertEnabled = false;
|
|
1694
|
-
function assert2(source, test) {
|
|
1695
|
-
if (globalThis.assertEnabled) {
|
|
1696
|
-
let problems = fails2(source, test);
|
|
1697
|
-
if (problems) {
|
|
1698
|
-
console.error("\u{1F170}\uFE0F Assertions failed because of:", problems, "in this source:", source);
|
|
1699
|
-
throw new Error("Assertions failed", {
|
|
1700
|
-
cause: { problems, source }
|
|
1701
|
-
});
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
|
-
function Optional2(pattern) {
|
|
1706
|
-
return function _Optional(data, root, path) {
|
|
1707
|
-
if (typeof data != "undefined" && data != null && typeof pattern != "undefined") {
|
|
1708
|
-
return fails2(data, pattern, root, path);
|
|
1709
|
-
}
|
|
1710
|
-
};
|
|
1711
|
-
}
|
|
1712
|
-
function Required2(pattern) {
|
|
1713
|
-
return function _Required(data, root, path) {
|
|
1714
|
-
if (data == null || typeof data == "undefined") {
|
|
1715
|
-
return error4("data is required", data, pattern || "any value", path);
|
|
1716
|
-
} else if (typeof pattern != "undefined") {
|
|
1717
|
-
return fails2(data, pattern, root, path);
|
|
1718
|
-
} else {
|
|
1719
|
-
return false;
|
|
1720
|
-
}
|
|
1721
|
-
};
|
|
1722
|
-
}
|
|
1723
|
-
function Recommended2(pattern) {
|
|
1724
|
-
return function _Recommended(data, root, path) {
|
|
1725
|
-
if (data == null || typeof data == "undefined") {
|
|
1726
|
-
console.warn("data does not contain recommended value", data, pattern, path);
|
|
1727
|
-
return false;
|
|
1728
|
-
} else {
|
|
1729
|
-
return fails2(data, pattern, root, path);
|
|
1730
|
-
}
|
|
1731
|
-
};
|
|
1732
|
-
}
|
|
1733
|
-
function oneOf2(...patterns) {
|
|
1734
|
-
return function _oneOf(data, root, path) {
|
|
1735
|
-
for (let pattern of patterns) {
|
|
1736
|
-
if (!fails2(data, pattern, root, path)) {
|
|
1737
|
-
return false;
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
return error4("data does not match oneOf patterns", data, patterns, path);
|
|
1741
|
-
};
|
|
1742
|
-
}
|
|
1743
|
-
function anyOf2(...patterns) {
|
|
1744
|
-
return function _anyOf(data, root, path) {
|
|
1745
|
-
if (!Array.isArray(data)) {
|
|
1746
|
-
return error4("data is not an array", data, "anyOf", path);
|
|
1747
|
-
}
|
|
1748
|
-
for (let value of data) {
|
|
1749
|
-
if (oneOf2(...patterns)(value)) {
|
|
1750
|
-
return error4("data does not match anyOf patterns", value, patterns, path);
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
1753
|
-
return false;
|
|
1754
|
-
};
|
|
1755
|
-
}
|
|
1756
|
-
function allOf(...patterns) {
|
|
1757
|
-
return function _allOf(data, root, path) {
|
|
1758
|
-
let problems = [];
|
|
1759
|
-
for (let pattern of patterns) {
|
|
1760
|
-
problems = problems.concat(fails2(data, pattern, root, path));
|
|
1761
|
-
}
|
|
1762
|
-
problems = problems.filter(Boolean);
|
|
1763
|
-
if (problems.length) {
|
|
1764
|
-
return error4("data does not match all given patterns", data, patterns, path, problems);
|
|
1765
|
-
}
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
function validURL2(data, root, path) {
|
|
1769
|
-
try {
|
|
1770
|
-
if (data instanceof URL) {
|
|
1771
|
-
data = data.href;
|
|
1772
|
-
}
|
|
1773
|
-
let url2 = new URL(data);
|
|
1774
|
-
if (url2.href != data) {
|
|
1775
|
-
if (!(url2.href + "/" == data || url2.href == data + "/")) {
|
|
1776
|
-
return error4("data is not a valid url", data, "validURL", path);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
} catch (e) {
|
|
1780
|
-
return error4("data is not a valid url", data, "validURL", path);
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
function validEmail(data, root, path) {
|
|
1784
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
|
|
1785
|
-
return error4("data is not a valid email", data, "validEmail", path);
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
function instanceOf(constructor) {
|
|
1789
|
-
return function _instanceOf(data, root, path) {
|
|
1790
|
-
if (!(data instanceof constructor)) {
|
|
1791
|
-
return error4("data is not an instanceof pattern", data, constructor, path);
|
|
1792
|
-
}
|
|
1793
|
-
};
|
|
1794
|
-
}
|
|
1795
|
-
function not(pattern) {
|
|
1796
|
-
return function _not(data, root, path) {
|
|
1797
|
-
if (!fails2(data, pattern, root, path)) {
|
|
1798
|
-
return error4("data matches pattern, when required not to", data, pattern, path);
|
|
1799
|
-
}
|
|
1800
|
-
};
|
|
1801
|
-
}
|
|
1802
|
-
function fails2(data, pattern, root, path = "") {
|
|
1803
|
-
if (!root) {
|
|
1804
|
-
root = data;
|
|
1805
|
-
}
|
|
1806
|
-
let problems = [];
|
|
1807
|
-
if (pattern === Boolean) {
|
|
1808
|
-
if (typeof data != "boolean" && !(data instanceof Boolean)) {
|
|
1809
|
-
problems.push(error4("data is not a boolean", data, pattern, path));
|
|
1810
|
-
}
|
|
1811
|
-
} else if (pattern === Number) {
|
|
1812
|
-
if (typeof data != "number" && !(data instanceof Number)) {
|
|
1813
|
-
problems.push(error4("data is not a number", data, pattern, path));
|
|
1814
|
-
}
|
|
1815
|
-
} else if (pattern === String) {
|
|
1816
|
-
if (typeof data != "string" && !(data instanceof String)) {
|
|
1817
|
-
problems.push(error4("data is not a string", data, pattern, path));
|
|
1818
|
-
}
|
|
1819
|
-
if (data == "") {
|
|
1820
|
-
problems.push(error4("data is an empty string, which is not allowed", data, pattern, path));
|
|
1821
|
-
}
|
|
1822
|
-
} else if (pattern instanceof RegExp) {
|
|
1823
|
-
if (Array.isArray(data)) {
|
|
1824
|
-
let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
|
|
1825
|
-
if (index > -1) {
|
|
1826
|
-
problems.push(error4("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
1827
|
-
}
|
|
1828
|
-
} else if (typeof data == "undefined") {
|
|
1829
|
-
problems.push(error4("data is undefined, should match pattern", data, pattern, path));
|
|
1830
|
-
} else if (!pattern.test(data)) {
|
|
1831
|
-
problems.push(error4("data does not match pattern", data, pattern, path));
|
|
1832
|
-
}
|
|
1833
|
-
} else if (pattern instanceof Function) {
|
|
1834
|
-
let problem = pattern(data, root, path);
|
|
1835
|
-
if (problem) {
|
|
1836
|
-
if (Array.isArray(problem)) {
|
|
1837
|
-
problems = problems.concat(problem);
|
|
1838
|
-
} else {
|
|
1839
|
-
problems.push(problem);
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
} else if (Array.isArray(pattern)) {
|
|
1843
|
-
if (!Array.isArray(data)) {
|
|
1844
|
-
problems.push(error4("data is not an array", data, [], path));
|
|
1845
|
-
}
|
|
1846
|
-
for (let p2 of pattern) {
|
|
1847
|
-
for (let index of data.keys()) {
|
|
1848
|
-
let problem = fails2(data[index], p2, root, path + "[" + index + "]");
|
|
1849
|
-
if (Array.isArray(problem)) {
|
|
1850
|
-
problems = problems.concat(problem);
|
|
1851
|
-
} else if (problem) {
|
|
1852
|
-
problems.push(problem);
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
|
-
} else if (pattern && typeof pattern == "object") {
|
|
1857
|
-
if (Array.isArray(data)) {
|
|
1858
|
-
let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
|
|
1859
|
-
if (index > -1) {
|
|
1860
|
-
problems.push(error4("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
1861
|
-
}
|
|
1862
|
-
} else if (!data || typeof data != "object") {
|
|
1863
|
-
problems.push(error4("data is not an object, pattern is", data, pattern, path));
|
|
1864
|
-
} else {
|
|
1865
|
-
if (data instanceof URLSearchParams) {
|
|
1866
|
-
data = Object.fromEntries(data);
|
|
1867
|
-
}
|
|
1868
|
-
if (pattern instanceof Function) {
|
|
1869
|
-
let result = fails2(data, pattern, root, path);
|
|
1870
|
-
if (result) {
|
|
1871
|
-
problems = problems.concat(result);
|
|
1872
|
-
}
|
|
1873
|
-
} else {
|
|
1874
|
-
for (const [wKey, wVal] of Object.entries(pattern)) {
|
|
1875
|
-
let result = fails2(data[wKey], wVal, root, path + "." + wKey);
|
|
1876
|
-
if (result) {
|
|
1877
|
-
problems = problems.concat(result);
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
} else {
|
|
1883
|
-
if (pattern != data) {
|
|
1884
|
-
problems.push(error4("data and pattern are not equal", data, pattern, path));
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
if (problems.length) {
|
|
1888
|
-
return problems;
|
|
1889
|
-
}
|
|
1890
|
-
return false;
|
|
1891
|
-
}
|
|
1892
|
-
function error4(message, found, expected, path, problems) {
|
|
1893
|
-
let result = {
|
|
1894
|
-
message,
|
|
1895
|
-
found,
|
|
1896
|
-
expected,
|
|
1897
|
-
path
|
|
1898
|
-
};
|
|
1899
|
-
if (problems) {
|
|
1900
|
-
result.problems = problems;
|
|
1901
|
-
}
|
|
1902
|
-
return result;
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
1789
|
// src/oidc.util.mjs
|
|
1906
1790
|
var MustHave = (...options) => (value, root) => {
|
|
1907
1791
|
if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
|
|
1908
1792
|
return false;
|
|
1909
1793
|
}
|
|
1910
|
-
return
|
|
1794
|
+
return error2("root data must have all of", root, options);
|
|
1911
1795
|
};
|
|
1912
1796
|
var MustInclude = (...options) => (value) => {
|
|
1913
1797
|
if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
|
|
1914
1798
|
return false;
|
|
1915
1799
|
} else {
|
|
1916
|
-
return
|
|
1800
|
+
return error2("data must be an array which includes", value, options);
|
|
1917
1801
|
}
|
|
1918
1802
|
};
|
|
1919
1803
|
var validJWA = [
|
|
@@ -1936,9 +1820,9 @@
|
|
|
1936
1820
|
|
|
1937
1821
|
// src/oidc.discovery.mjs
|
|
1938
1822
|
async function oidcDiscovery(options = {}) {
|
|
1939
|
-
|
|
1940
|
-
client:
|
|
1941
|
-
issuer:
|
|
1823
|
+
assert(options, {
|
|
1824
|
+
client: Optional(instanceOf(everything_default.client().constructor)),
|
|
1825
|
+
issuer: Required(validURL)
|
|
1942
1826
|
});
|
|
1943
1827
|
const defaultOptions = {
|
|
1944
1828
|
client: everything_default.client().with(thrower()).with(jsonmw()),
|
|
@@ -1950,42 +1834,42 @@
|
|
|
1950
1834
|
return TestSucceeded;
|
|
1951
1835
|
}
|
|
1952
1836
|
const openid_provider_metadata = {
|
|
1953
|
-
issuer:
|
|
1954
|
-
authorization_endpoint:
|
|
1955
|
-
token_endpoint:
|
|
1956
|
-
userinfo_endpoint:
|
|
1837
|
+
issuer: Required(allOf(options.issuer, MustUseHTTPS)),
|
|
1838
|
+
authorization_endpoint: Required(validURL),
|
|
1839
|
+
token_endpoint: Required(validURL),
|
|
1840
|
+
userinfo_endpoint: Recommended(validURL),
|
|
1957
1841
|
// todo: test for https protocol
|
|
1958
|
-
jwks_uri:
|
|
1959
|
-
registration_endpoint: options.requireDynamicRegistration ?
|
|
1960
|
-
scopes_supported:
|
|
1961
|
-
response_types_supported: options.requireDynamicRegistration ?
|
|
1962
|
-
response_modes_supported:
|
|
1963
|
-
grant_types_supported: options.requireDynamicRegistration ?
|
|
1964
|
-
acr_values_supported:
|
|
1965
|
-
subject_types_supported:
|
|
1966
|
-
id_token_signing_alg_values_supported:
|
|
1967
|
-
id_token_encryption_alg_values_supported:
|
|
1968
|
-
id_token_encryption_enc_values_supported:
|
|
1969
|
-
userinfo_signing_alg_values_supported:
|
|
1970
|
-
userinfo_encryption_alg_values_supported:
|
|
1971
|
-
userinfo_encryption_enc_values_supported:
|
|
1972
|
-
request_object_signing_alg_values_supported:
|
|
1842
|
+
jwks_uri: Required(validURL),
|
|
1843
|
+
registration_endpoint: options.requireDynamicRegistration ? Required(validURL) : Recommended(validURL),
|
|
1844
|
+
scopes_supported: Recommended(MustInclude("openid")),
|
|
1845
|
+
response_types_supported: options.requireDynamicRegistration ? Required(MustInclude("code", "id_token", "id_token token")) : Required([]),
|
|
1846
|
+
response_modes_supported: Optional([]),
|
|
1847
|
+
grant_types_supported: options.requireDynamicRegistration ? Optional(MustInclude("authorization_code")) : Optional([]),
|
|
1848
|
+
acr_values_supported: Optional([]),
|
|
1849
|
+
subject_types_supported: Required([]),
|
|
1850
|
+
id_token_signing_alg_values_supported: Required(MustInclude("RS256")),
|
|
1851
|
+
id_token_encryption_alg_values_supported: Optional([]),
|
|
1852
|
+
id_token_encryption_enc_values_supported: Optional([]),
|
|
1853
|
+
userinfo_signing_alg_values_supported: Optional([]),
|
|
1854
|
+
userinfo_encryption_alg_values_supported: Optional([]),
|
|
1855
|
+
userinfo_encryption_enc_values_supported: Optional([]),
|
|
1856
|
+
request_object_signing_alg_values_supported: Optional(MustInclude("RS256")),
|
|
1973
1857
|
// not testing for 'none'
|
|
1974
|
-
request_object_encryption_alg_values_supported:
|
|
1975
|
-
request_object_encryption_enc_values_supported:
|
|
1976
|
-
token_endpoint_auth_methods_supported:
|
|
1977
|
-
token_endpoint_auth_signing_alg_values_supported:
|
|
1978
|
-
display_values_supported:
|
|
1979
|
-
claim_types_supported:
|
|
1980
|
-
claims_supported:
|
|
1981
|
-
service_documentation:
|
|
1982
|
-
claims_locales_supported:
|
|
1983
|
-
ui_locales_supported:
|
|
1984
|
-
claims_parameter_supported:
|
|
1985
|
-
request_parameter_supported:
|
|
1986
|
-
request_uri_parameter_supported:
|
|
1987
|
-
op_policy_uri:
|
|
1988
|
-
op_tos_uri:
|
|
1858
|
+
request_object_encryption_alg_values_supported: Optional([]),
|
|
1859
|
+
request_object_encryption_enc_values_supported: Optional([]),
|
|
1860
|
+
token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods2)),
|
|
1861
|
+
token_endpoint_auth_signing_alg_values_supported: Optional(MustInclude("RS256"), not(MustInclude("none"))),
|
|
1862
|
+
display_values_supported: Optional(anyOf("page", "popup", "touch", "wap")),
|
|
1863
|
+
claim_types_supported: Optional(anyOf("normal", "aggregated", "distributed")),
|
|
1864
|
+
claims_supported: Recommended([]),
|
|
1865
|
+
service_documentation: Optional(validURL),
|
|
1866
|
+
claims_locales_supported: Optional([]),
|
|
1867
|
+
ui_locales_supported: Optional([]),
|
|
1868
|
+
claims_parameter_supported: Optional(Boolean),
|
|
1869
|
+
request_parameter_supported: Optional(Boolean),
|
|
1870
|
+
request_uri_parameter_supported: Optional(Boolean),
|
|
1871
|
+
op_policy_uri: Optional(validURL),
|
|
1872
|
+
op_tos_uri: Optional(validURL)
|
|
1989
1873
|
};
|
|
1990
1874
|
const configURL = everything_default.url(options.issuer, ".well-known/openid-configuration");
|
|
1991
1875
|
const response2 = await options.client.get(
|
|
@@ -1994,49 +1878,49 @@
|
|
|
1994
1878
|
configURL
|
|
1995
1879
|
);
|
|
1996
1880
|
const openid_config = response2.data;
|
|
1997
|
-
|
|
1998
|
-
|
|
1881
|
+
assert(openid_config, openid_provider_metadata);
|
|
1882
|
+
assert(openid_config.issuer, options.issuer);
|
|
1999
1883
|
return openid_config;
|
|
2000
1884
|
}
|
|
2001
1885
|
|
|
2002
1886
|
// src/oidc.register.mjs
|
|
2003
1887
|
async function register(options) {
|
|
2004
1888
|
const openid_client_metadata = {
|
|
2005
|
-
redirect_uris:
|
|
2006
|
-
response_types:
|
|
2007
|
-
grant_types:
|
|
1889
|
+
redirect_uris: Required([validURL]),
|
|
1890
|
+
response_types: Optional([]),
|
|
1891
|
+
grant_types: Optional(anyOf("authorization_code", "refresh_token")),
|
|
2008
1892
|
//TODO: match response_types with grant_types
|
|
2009
|
-
application_type:
|
|
2010
|
-
contacts:
|
|
2011
|
-
client_name:
|
|
2012
|
-
logo_uri:
|
|
2013
|
-
client_uri:
|
|
2014
|
-
policy_uri:
|
|
2015
|
-
tos_uri:
|
|
2016
|
-
jwks_uri:
|
|
2017
|
-
jwks:
|
|
2018
|
-
sector_identifier_uri:
|
|
2019
|
-
subject_type:
|
|
2020
|
-
id_token_signed_response_alg:
|
|
2021
|
-
id_token_encrypted_response_alg:
|
|
2022
|
-
id_token_encrypted_response_enc:
|
|
2023
|
-
userinfo_signed_response_alg:
|
|
2024
|
-
userinfo_encrypted_response_alg:
|
|
2025
|
-
userinfo_encrypted_response_enc:
|
|
2026
|
-
request_object_signing_alg:
|
|
2027
|
-
request_object_encryption_alg:
|
|
2028
|
-
request_object_encryption_enc:
|
|
2029
|
-
token_endpoint_auth_method:
|
|
2030
|
-
token_endpoint_auth_signing_alg:
|
|
2031
|
-
default_max_age:
|
|
2032
|
-
require_auth_time:
|
|
2033
|
-
default_acr_values:
|
|
2034
|
-
initiate_login_uri:
|
|
2035
|
-
request_uris:
|
|
1893
|
+
application_type: Optional(oneOf("native", "web")),
|
|
1894
|
+
contacts: Optional([validEmail]),
|
|
1895
|
+
client_name: Optional(String),
|
|
1896
|
+
logo_uri: Optional(validURL),
|
|
1897
|
+
client_uri: Optional(validURL),
|
|
1898
|
+
policy_uri: Optional(validURL),
|
|
1899
|
+
tos_uri: Optional(validURL),
|
|
1900
|
+
jwks_uri: Optional(validURL, not(MustHave("jwks"))),
|
|
1901
|
+
jwks: Optional(validURL, not(MustHave("jwks_uri"))),
|
|
1902
|
+
sector_identifier_uri: Optional(validURL),
|
|
1903
|
+
subject_type: Optional(String),
|
|
1904
|
+
id_token_signed_response_alg: Optional(oneOf(...validJWA)),
|
|
1905
|
+
id_token_encrypted_response_alg: Optional(oneOf(...validJWA)),
|
|
1906
|
+
id_token_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("id_token_encrypted_response_alg")),
|
|
1907
|
+
userinfo_signed_response_alg: Optional(oneOf(...validJWA)),
|
|
1908
|
+
userinfo_encrypted_response_alg: Optional(oneOf(...validJWA)),
|
|
1909
|
+
userinfo_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("userinfo_encrypted_response_alg")),
|
|
1910
|
+
request_object_signing_alg: Optional(oneOf(...validJWA)),
|
|
1911
|
+
request_object_encryption_alg: Optional(oneOf(...validJWA)),
|
|
1912
|
+
request_object_encryption_enc: Optional(oneOf(...validJWA)),
|
|
1913
|
+
token_endpoint_auth_method: Optional(oneOf(...validAuthMethods2)),
|
|
1914
|
+
token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
|
|
1915
|
+
default_max_age: Optional(Number),
|
|
1916
|
+
require_auth_time: Optional(Boolean),
|
|
1917
|
+
default_acr_values: Optional([String]),
|
|
1918
|
+
initiate_login_uri: Optional([validURL]),
|
|
1919
|
+
request_uris: Optional([validURL])
|
|
2036
1920
|
};
|
|
2037
|
-
|
|
2038
|
-
client:
|
|
2039
|
-
registration_endpoint:
|
|
1921
|
+
assert(options, {
|
|
1922
|
+
client: Optional(instanceOf(everything_default.client().constructor)),
|
|
1923
|
+
registration_endpoint: validURL,
|
|
2040
1924
|
client_info: openid_client_metadata
|
|
2041
1925
|
});
|
|
2042
1926
|
const defaultOptions = {
|
|
@@ -2088,13 +1972,13 @@
|
|
|
2088
1972
|
}
|
|
2089
1973
|
};
|
|
2090
1974
|
options = Object.assign({}, defaultOptions, options);
|
|
2091
|
-
|
|
2092
|
-
client:
|
|
1975
|
+
assert(options, {
|
|
1976
|
+
client: Required(instanceOf(client().constructor)),
|
|
2093
1977
|
// required because it is set in defaultOptions
|
|
2094
|
-
client_info:
|
|
2095
|
-
issuer:
|
|
2096
|
-
oauth2:
|
|
2097
|
-
openid_configuration:
|
|
1978
|
+
client_info: Required(),
|
|
1979
|
+
issuer: Required(validURL),
|
|
1980
|
+
oauth2: Optional({}),
|
|
1981
|
+
openid_configuration: Optional()
|
|
2098
1982
|
});
|
|
2099
1983
|
if (!options.store) {
|
|
2100
1984
|
options.store = oidcStore(options.issuer);
|
|
@@ -2126,7 +2010,7 @@
|
|
|
2126
2010
|
options.store.set("openid_configuration", options.openid_configuration);
|
|
2127
2011
|
}
|
|
2128
2012
|
if (!options.client_info?.client_id) {
|
|
2129
|
-
|
|
2013
|
+
assert(options.client_info?.client_name, Required());
|
|
2130
2014
|
if (!options.openid_configuration.registration_endpoint) {
|
|
2131
2015
|
throw metroError("metro.oidcmw: Error: issuer " + options.issuer + " does not support dynamic client registration, but you haven't specified a client_id");
|
|
2132
2016
|
}
|
|
@@ -2154,7 +2038,6 @@
|
|
|
2154
2038
|
scope,
|
|
2155
2039
|
//FIXME: should only use scopes supported by server
|
|
2156
2040
|
redirect_uri: options.client_info.redirect_uris[0]
|
|
2157
|
-
//FIXME: find the best match?
|
|
2158
2041
|
}
|
|
2159
2042
|
}
|
|
2160
2043
|
//...
|
|
@@ -2200,6 +2083,12 @@
|
|
|
2200
2083
|
return isRedirected();
|
|
2201
2084
|
}
|
|
2202
2085
|
function idToken(options) {
|
|
2086
|
+
if (!options.store) {
|
|
2087
|
+
if (!options.issuer) {
|
|
2088
|
+
throw metroError("Must supply options.issuer or options.store to get the id_token");
|
|
2089
|
+
}
|
|
2090
|
+
options.store = oidcStore(options.issuer);
|
|
2091
|
+
}
|
|
2203
2092
|
return options.store.get("id_token");
|
|
2204
2093
|
}
|
|
2205
2094
|
|