@muze-nl/metro-oidc 0.3.2 → 0.3.3
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 +14 -1
- package/dist/browser.js +105 -60
- 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 +2 -2
- package/src/oidcmw.mjs +0 -4
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ async function fetchMovies() {
|
|
|
24
24
|
````
|
|
25
25
|
|
|
26
26
|
The OIDC middleware will automatically discover the configuration of the issuer, as well as do a dynamic client registration, if you haven't set a `client_info.client_id`.
|
|
27
|
-
It will then configure the correct OAuth2 settings and handle the request with [metro oauth2](https://github.com/muze-nl/metro-oauth2) middleware. It may redirect the browser to let the user login with the OIDC issuer. You can skip the automatic configuration step, if you provide the `openid_configuration` parameter set yourself, the oidcmw middleware will only
|
|
27
|
+
It will then configure the correct OAuth2 settings and handle the request with [metro oauth2](https://github.com/muze-nl/metro-oauth2) middleware. It may redirect the browser to let the user login with the OIDC issuer. You can skip the automatic configuration step, if you provide the `openid_configuration` parameter set yourself. If you don't, the oidcmw middleware will only run the discovery process once, and store the information in localStorage. The same with the client_info and dynamic registration.
|
|
28
28
|
|
|
29
29
|
## Security features
|
|
30
30
|
|
|
@@ -32,3 +32,16 @@ metro.oidc uses OAuth2.1 by default, including PKCE and DPoP. The Keypair used i
|
|
|
32
32
|
|
|
33
33
|
You can disable PCKE by setting `options.client_info.code_verifier` to false.
|
|
34
34
|
You can disable DPoP by setting `options.use_dpop` to false.
|
|
35
|
+
|
|
36
|
+
## id_token
|
|
37
|
+
|
|
38
|
+
The metro oidc middleware doesn't use the id_token, or verify any of its contents. This is left up to you, if you need it. You can retrieve the id_token by calling the `idToken` function, after the user is logged in:
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
import oidc from '@muze-nl/metro-oidc'
|
|
42
|
+
|
|
43
|
+
let id_token = oidc.idToken()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
[project-stage-badge: Experimental]: https://img.shields.io/badge/Project%20Stage-Experimental-yellow.svg
|
|
47
|
+
[project-stage-page]: https://blog.pother.ca/project-stages/
|
package/dist/browser.js
CHANGED
|
@@ -599,13 +599,13 @@
|
|
|
599
599
|
// node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
|
|
600
600
|
var oauth2_exports = {};
|
|
601
601
|
__export(oauth2_exports, {
|
|
602
|
-
authorizePopup: () => authorizePopup,
|
|
603
602
|
base64url_encode: () => base64url_encode,
|
|
604
603
|
createState: () => createState,
|
|
605
604
|
default: () => oauth2mw,
|
|
606
605
|
generateCodeChallenge: () => generateCodeChallenge,
|
|
607
606
|
generateCodeVerifier: () => generateCodeVerifier,
|
|
608
607
|
getExpires: () => getExpires,
|
|
608
|
+
isAuthorized: () => isAuthorized,
|
|
609
609
|
isExpired: () => isExpired,
|
|
610
610
|
isRedirected: () => isRedirected
|
|
611
611
|
});
|
|
@@ -632,15 +632,15 @@
|
|
|
632
632
|
return false;
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
|
-
return
|
|
635
|
+
return error2("data does not match oneOf patterns", data, patterns);
|
|
636
636
|
};
|
|
637
637
|
var anyOf = (...patterns) => (data) => {
|
|
638
638
|
if (!Array.isArray(data)) {
|
|
639
|
-
return
|
|
639
|
+
return error2("data is not an array", data, "anyOf");
|
|
640
640
|
}
|
|
641
641
|
for (let value of data) {
|
|
642
642
|
if (oneOf(...patterns)(value)) {
|
|
643
|
-
return
|
|
643
|
+
return error2("data does not match anyOf patterns", value, patterns);
|
|
644
644
|
}
|
|
645
645
|
}
|
|
646
646
|
return false;
|
|
@@ -652,10 +652,10 @@
|
|
|
652
652
|
}
|
|
653
653
|
let url2 = new URL(data);
|
|
654
654
|
if (url2.href != data) {
|
|
655
|
-
return
|
|
655
|
+
return error2("data is not a valid url", data, "validURL");
|
|
656
656
|
}
|
|
657
657
|
} catch (e) {
|
|
658
|
-
return
|
|
658
|
+
return error2("data is not a valid url", data, "validURL");
|
|
659
659
|
}
|
|
660
660
|
return false;
|
|
661
661
|
}
|
|
@@ -666,28 +666,28 @@
|
|
|
666
666
|
let problems = [];
|
|
667
667
|
if (pattern === Boolean) {
|
|
668
668
|
if (typeof data != "boolean") {
|
|
669
|
-
problems.push(
|
|
669
|
+
problems.push(error2("data is not a boolean", data, pattern));
|
|
670
670
|
}
|
|
671
671
|
} else if (pattern === Number) {
|
|
672
672
|
if (typeof data != "number") {
|
|
673
|
-
problems.push(
|
|
673
|
+
problems.push(error2("data is not a number", data, pattern));
|
|
674
674
|
}
|
|
675
675
|
} else if (pattern instanceof RegExp) {
|
|
676
676
|
if (Array.isArray(data)) {
|
|
677
677
|
let index = data.findIndex((element) => fails(element, pattern, root));
|
|
678
678
|
if (index > -1) {
|
|
679
|
-
problems.push(
|
|
679
|
+
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
|
|
680
680
|
}
|
|
681
681
|
} else if (!pattern.test(data)) {
|
|
682
|
-
problems.push(
|
|
682
|
+
problems.push(error2("data does not match pattern", data, pattern));
|
|
683
683
|
}
|
|
684
684
|
} else if (pattern instanceof Function) {
|
|
685
685
|
if (pattern(data, root)) {
|
|
686
|
-
problems.push(
|
|
686
|
+
problems.push(error2("data does not match function", data, pattern));
|
|
687
687
|
}
|
|
688
688
|
} else if (Array.isArray(pattern)) {
|
|
689
689
|
if (!Array.isArray(data)) {
|
|
690
|
-
problems.push(
|
|
690
|
+
problems.push(error2("data is not an array", data, []));
|
|
691
691
|
}
|
|
692
692
|
for (p of pattern) {
|
|
693
693
|
let problem = fails(data, p, root);
|
|
@@ -701,10 +701,10 @@
|
|
|
701
701
|
if (Array.isArray(data)) {
|
|
702
702
|
let index = data.findIndex((element) => fails(element, pattern, root));
|
|
703
703
|
if (index > -1) {
|
|
704
|
-
problems.push(
|
|
704
|
+
problems.push(error2("data[" + index + "] does not match pattern", data[index], pattern));
|
|
705
705
|
}
|
|
706
706
|
} else if (!data || typeof data != "object") {
|
|
707
|
-
problems.push(
|
|
707
|
+
problems.push(error2("data is not an object, pattern is", data, pattern));
|
|
708
708
|
} else {
|
|
709
709
|
if (data instanceof URLSearchParams) {
|
|
710
710
|
data = Object.fromEntries(data);
|
|
@@ -715,7 +715,7 @@
|
|
|
715
715
|
if (result) {
|
|
716
716
|
if (!p2 || typeof p2 == "string") {
|
|
717
717
|
p2 = {};
|
|
718
|
-
problems.push(
|
|
718
|
+
problems.push(error2(p2, data[wKey], wVal));
|
|
719
719
|
}
|
|
720
720
|
p2[wKey] = result.problems;
|
|
721
721
|
}
|
|
@@ -723,7 +723,7 @@
|
|
|
723
723
|
}
|
|
724
724
|
} else {
|
|
725
725
|
if (pattern != data) {
|
|
726
|
-
problems.push(
|
|
726
|
+
problems.push(error2("data and pattern are not equal", data, pattern));
|
|
727
727
|
}
|
|
728
728
|
}
|
|
729
729
|
if (problems.length) {
|
|
@@ -738,7 +738,7 @@
|
|
|
738
738
|
this.details = details;
|
|
739
739
|
}
|
|
740
740
|
};
|
|
741
|
-
function
|
|
741
|
+
function error2(message, found, expected) {
|
|
742
742
|
return {
|
|
743
743
|
message,
|
|
744
744
|
found,
|
|
@@ -1108,13 +1108,19 @@
|
|
|
1108
1108
|
}
|
|
1109
1109
|
return true;
|
|
1110
1110
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1111
|
+
function isAuthorized(tokens) {
|
|
1112
|
+
if (typeof tokens == "string") {
|
|
1113
|
+
tokens = tokenStore(tokens).tokens;
|
|
1114
|
+
}
|
|
1115
|
+
let accessToken = tokens.get("access_token");
|
|
1116
|
+
if (accessToken && !isExpired(accessToken)) {
|
|
1117
|
+
return true;
|
|
1118
|
+
}
|
|
1119
|
+
let refreshToken = tokens.get("refresh_token");
|
|
1120
|
+
if (refreshToken) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
return false;
|
|
1118
1124
|
}
|
|
1119
1125
|
|
|
1120
1126
|
// node_modules/@muze-nl/metro-oauth2/src/oauth2.mockserver.mjs
|
|
@@ -1129,7 +1135,7 @@
|
|
|
1129
1135
|
"Content-Type": "application/json"
|
|
1130
1136
|
}
|
|
1131
1137
|
};
|
|
1132
|
-
var badRequest = (
|
|
1138
|
+
var badRequest = (error5) => {
|
|
1133
1139
|
return {
|
|
1134
1140
|
status: 400,
|
|
1135
1141
|
statusText: "Bad Request",
|
|
@@ -1138,11 +1144,11 @@
|
|
|
1138
1144
|
},
|
|
1139
1145
|
body: JSON.stringify({
|
|
1140
1146
|
error: "invalid_request",
|
|
1141
|
-
error_description:
|
|
1147
|
+
error_description: error5
|
|
1142
1148
|
})
|
|
1143
1149
|
};
|
|
1144
1150
|
};
|
|
1145
|
-
var
|
|
1151
|
+
var error3;
|
|
1146
1152
|
var pkce = {};
|
|
1147
1153
|
function oauth2mockserver(options = {}) {
|
|
1148
1154
|
const defaultOptions = {
|
|
@@ -1154,12 +1160,12 @@
|
|
|
1154
1160
|
let url2 = everything_default.url(req.url);
|
|
1155
1161
|
switch (url2.pathname) {
|
|
1156
1162
|
case "/authorize/":
|
|
1157
|
-
if (
|
|
1163
|
+
if (error3 = fails(url2.searchParams, {
|
|
1158
1164
|
response_type: "code",
|
|
1159
1165
|
client_id: "mockClientId",
|
|
1160
1166
|
state: Optional(/.*/)
|
|
1161
1167
|
})) {
|
|
1162
|
-
return everything_default.response(badRequest(
|
|
1168
|
+
return everything_default.response(badRequest(error3));
|
|
1163
1169
|
}
|
|
1164
1170
|
if (url2.searchParams.has("code_challenge")) {
|
|
1165
1171
|
if (!url2.searchParams.has("code_challenge_method")) {
|
|
@@ -1181,17 +1187,17 @@
|
|
|
1181
1187
|
req.data.forEach((value, key) => body[key] = value);
|
|
1182
1188
|
req = req.with({ body });
|
|
1183
1189
|
}
|
|
1184
|
-
if (
|
|
1190
|
+
if (error3 = fails(req, {
|
|
1185
1191
|
method: "POST",
|
|
1186
1192
|
data: {
|
|
1187
1193
|
grant_type: oneOf("refresh_token", "authorization_code")
|
|
1188
1194
|
}
|
|
1189
1195
|
})) {
|
|
1190
|
-
return everything_default.response(badRequest(
|
|
1196
|
+
return everything_default.response(badRequest(error3));
|
|
1191
1197
|
}
|
|
1192
1198
|
switch (req.data.grant_type) {
|
|
1193
1199
|
case "refresh_token":
|
|
1194
|
-
if (
|
|
1200
|
+
if (error3 = fails(req.data, oneOf({
|
|
1195
1201
|
refresh_token: "mockRefreshToken",
|
|
1196
1202
|
client_id: "mockClientId",
|
|
1197
1203
|
client_secret: "mockClientSecret"
|
|
@@ -1200,11 +1206,11 @@
|
|
|
1200
1206
|
client_id: "mockClientId",
|
|
1201
1207
|
code_verifier: /.+/
|
|
1202
1208
|
}))) {
|
|
1203
|
-
return everything_default.response(badRequest(
|
|
1209
|
+
return everything_default.response(badRequest(error3));
|
|
1204
1210
|
}
|
|
1205
1211
|
break;
|
|
1206
1212
|
case "access_token":
|
|
1207
|
-
if (
|
|
1213
|
+
if (error3 = fails(req.data, oneOf({
|
|
1208
1214
|
client_id: "mockClientId",
|
|
1209
1215
|
client_secret: "mockClientSecret"
|
|
1210
1216
|
}, {
|
|
@@ -1213,7 +1219,7 @@
|
|
|
1213
1219
|
//FIXME: check that this matches code_verifier
|
|
1214
1220
|
code_challenge_method: "S256"
|
|
1215
1221
|
}))) {
|
|
1216
|
-
return everything_default.response(badRequest(
|
|
1222
|
+
return everything_default.response(badRequest(error3));
|
|
1217
1223
|
}
|
|
1218
1224
|
break;
|
|
1219
1225
|
}
|
|
@@ -1329,6 +1335,43 @@
|
|
|
1329
1335
|
throw everything_default.metroError("metro.oidcmw: Error while fetching " + issuer + ".wellknown/oauth_authorization_server", res);
|
|
1330
1336
|
}
|
|
1331
1337
|
|
|
1338
|
+
// node_modules/@muze-nl/metro-oauth2/src/oauth2.popup.mjs
|
|
1339
|
+
function handleRedirect() {
|
|
1340
|
+
let params2 = new URLSearchParams(window.location.search);
|
|
1341
|
+
if (!params2.has("code") && window.location.hash) {
|
|
1342
|
+
let query = window.location.hash.substr(1);
|
|
1343
|
+
params2 = new URLSearchParams("?" + query);
|
|
1344
|
+
}
|
|
1345
|
+
let parent = window.parent ? window.parent : window.opener;
|
|
1346
|
+
if (params2.has("code")) {
|
|
1347
|
+
parent.postMessage({
|
|
1348
|
+
authorization_code: params2.get("code")
|
|
1349
|
+
}, window.location.origin);
|
|
1350
|
+
} else if (params2.has("error")) {
|
|
1351
|
+
parent.postMessage({
|
|
1352
|
+
error
|
|
1353
|
+
}, window.location.origin);
|
|
1354
|
+
} else {
|
|
1355
|
+
parent.postMessage({
|
|
1356
|
+
error: "Could not find an authorization_code"
|
|
1357
|
+
}, window.location.origin);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function authorizePopup(authorizationCodeURL) {
|
|
1361
|
+
return new Promise((resolve, reject) => {
|
|
1362
|
+
addEventListener("message", (evt) => {
|
|
1363
|
+
if (event.data.authorization_code) {
|
|
1364
|
+
resolve(event.data.authorization_code);
|
|
1365
|
+
} else if (event.data.error) {
|
|
1366
|
+
reject(event.data.error);
|
|
1367
|
+
} else {
|
|
1368
|
+
reject("Unknown authorization error");
|
|
1369
|
+
}
|
|
1370
|
+
}, { once: true });
|
|
1371
|
+
window.open(authorizationCodeURL);
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1332
1375
|
// node_modules/@muze-nl/metro-oauth2/src/keysstore.mjs
|
|
1333
1376
|
function keysStore() {
|
|
1334
1377
|
return new Promise((resolve, reject) => {
|
|
@@ -1638,7 +1681,9 @@
|
|
|
1638
1681
|
discover: oauth2_discovery_exports,
|
|
1639
1682
|
tokenstore: tokenStore,
|
|
1640
1683
|
dpopmw,
|
|
1641
|
-
keysstore: keysStore
|
|
1684
|
+
keysstore: keysStore,
|
|
1685
|
+
authorizePopup,
|
|
1686
|
+
popupHandleRedirect: handleRedirect
|
|
1642
1687
|
});
|
|
1643
1688
|
if (!globalThis.metro.oauth2) {
|
|
1644
1689
|
globalThis.metro.oauth2 = oauth2;
|
|
@@ -1667,7 +1712,7 @@
|
|
|
1667
1712
|
function Required2(pattern) {
|
|
1668
1713
|
return function _Required(data, root, path) {
|
|
1669
1714
|
if (data == null || typeof data == "undefined") {
|
|
1670
|
-
return
|
|
1715
|
+
return error4("data is required", data, pattern || "any value", path);
|
|
1671
1716
|
} else if (typeof pattern != "undefined") {
|
|
1672
1717
|
return fails2(data, pattern, root, path);
|
|
1673
1718
|
} else {
|
|
@@ -1692,17 +1737,17 @@
|
|
|
1692
1737
|
return false;
|
|
1693
1738
|
}
|
|
1694
1739
|
}
|
|
1695
|
-
return
|
|
1740
|
+
return error4("data does not match oneOf patterns", data, patterns, path);
|
|
1696
1741
|
};
|
|
1697
1742
|
}
|
|
1698
1743
|
function anyOf2(...patterns) {
|
|
1699
1744
|
return function _anyOf(data, root, path) {
|
|
1700
1745
|
if (!Array.isArray(data)) {
|
|
1701
|
-
return
|
|
1746
|
+
return error4("data is not an array", data, "anyOf", path);
|
|
1702
1747
|
}
|
|
1703
1748
|
for (let value of data) {
|
|
1704
1749
|
if (oneOf2(...patterns)(value)) {
|
|
1705
|
-
return
|
|
1750
|
+
return error4("data does not match anyOf patterns", value, patterns, path);
|
|
1706
1751
|
}
|
|
1707
1752
|
}
|
|
1708
1753
|
return false;
|
|
@@ -1716,7 +1761,7 @@
|
|
|
1716
1761
|
}
|
|
1717
1762
|
problems = problems.filter(Boolean);
|
|
1718
1763
|
if (problems.length) {
|
|
1719
|
-
return
|
|
1764
|
+
return error4("data does not match all given patterns", data, patterns, path, problems);
|
|
1720
1765
|
}
|
|
1721
1766
|
};
|
|
1722
1767
|
}
|
|
@@ -1728,29 +1773,29 @@
|
|
|
1728
1773
|
let url2 = new URL(data);
|
|
1729
1774
|
if (url2.href != data) {
|
|
1730
1775
|
if (!(url2.href + "/" == data || url2.href == data + "/")) {
|
|
1731
|
-
return
|
|
1776
|
+
return error4("data is not a valid url", data, "validURL", path);
|
|
1732
1777
|
}
|
|
1733
1778
|
}
|
|
1734
1779
|
} catch (e) {
|
|
1735
|
-
return
|
|
1780
|
+
return error4("data is not a valid url", data, "validURL", path);
|
|
1736
1781
|
}
|
|
1737
1782
|
}
|
|
1738
1783
|
function validEmail(data, root, path) {
|
|
1739
1784
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
|
|
1740
|
-
return
|
|
1785
|
+
return error4("data is not a valid email", data, "validEmail", path);
|
|
1741
1786
|
}
|
|
1742
1787
|
}
|
|
1743
1788
|
function instanceOf(constructor) {
|
|
1744
1789
|
return function _instanceOf(data, root, path) {
|
|
1745
1790
|
if (!(data instanceof constructor)) {
|
|
1746
|
-
return
|
|
1791
|
+
return error4("data is not an instanceof pattern", data, constructor, path);
|
|
1747
1792
|
}
|
|
1748
1793
|
};
|
|
1749
1794
|
}
|
|
1750
1795
|
function not(pattern) {
|
|
1751
1796
|
return function _not(data, root, path) {
|
|
1752
1797
|
if (!fails2(data, pattern, root, path)) {
|
|
1753
|
-
return
|
|
1798
|
+
return error4("data matches pattern, when required not to", data, pattern, path);
|
|
1754
1799
|
}
|
|
1755
1800
|
};
|
|
1756
1801
|
}
|
|
@@ -1761,29 +1806,29 @@
|
|
|
1761
1806
|
let problems = [];
|
|
1762
1807
|
if (pattern === Boolean) {
|
|
1763
1808
|
if (typeof data != "boolean" && !(data instanceof Boolean)) {
|
|
1764
|
-
problems.push(
|
|
1809
|
+
problems.push(error4("data is not a boolean", data, pattern, path));
|
|
1765
1810
|
}
|
|
1766
1811
|
} else if (pattern === Number) {
|
|
1767
1812
|
if (typeof data != "number" && !(data instanceof Number)) {
|
|
1768
|
-
problems.push(
|
|
1813
|
+
problems.push(error4("data is not a number", data, pattern, path));
|
|
1769
1814
|
}
|
|
1770
1815
|
} else if (pattern === String) {
|
|
1771
1816
|
if (typeof data != "string" && !(data instanceof String)) {
|
|
1772
|
-
problems.push(
|
|
1817
|
+
problems.push(error4("data is not a string", data, pattern, path));
|
|
1773
1818
|
}
|
|
1774
1819
|
if (data == "") {
|
|
1775
|
-
problems.push(
|
|
1820
|
+
problems.push(error4("data is an empty string, which is not allowed", data, pattern, path));
|
|
1776
1821
|
}
|
|
1777
1822
|
} else if (pattern instanceof RegExp) {
|
|
1778
1823
|
if (Array.isArray(data)) {
|
|
1779
1824
|
let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
|
|
1780
1825
|
if (index > -1) {
|
|
1781
|
-
problems.push(
|
|
1826
|
+
problems.push(error4("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
1782
1827
|
}
|
|
1783
1828
|
} else if (typeof data == "undefined") {
|
|
1784
|
-
problems.push(
|
|
1829
|
+
problems.push(error4("data is undefined, should match pattern", data, pattern, path));
|
|
1785
1830
|
} else if (!pattern.test(data)) {
|
|
1786
|
-
problems.push(
|
|
1831
|
+
problems.push(error4("data does not match pattern", data, pattern, path));
|
|
1787
1832
|
}
|
|
1788
1833
|
} else if (pattern instanceof Function) {
|
|
1789
1834
|
let problem = pattern(data, root, path);
|
|
@@ -1796,7 +1841,7 @@
|
|
|
1796
1841
|
}
|
|
1797
1842
|
} else if (Array.isArray(pattern)) {
|
|
1798
1843
|
if (!Array.isArray(data)) {
|
|
1799
|
-
problems.push(
|
|
1844
|
+
problems.push(error4("data is not an array", data, [], path));
|
|
1800
1845
|
}
|
|
1801
1846
|
for (let p2 of pattern) {
|
|
1802
1847
|
for (let index of data.keys()) {
|
|
@@ -1812,10 +1857,10 @@
|
|
|
1812
1857
|
if (Array.isArray(data)) {
|
|
1813
1858
|
let index = data.findIndex((element, index2) => fails2(element, pattern, root, path + "[" + index2 + "]"));
|
|
1814
1859
|
if (index > -1) {
|
|
1815
|
-
problems.push(
|
|
1860
|
+
problems.push(error4("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
|
|
1816
1861
|
}
|
|
1817
1862
|
} else if (!data || typeof data != "object") {
|
|
1818
|
-
problems.push(
|
|
1863
|
+
problems.push(error4("data is not an object, pattern is", data, pattern, path));
|
|
1819
1864
|
} else {
|
|
1820
1865
|
if (data instanceof URLSearchParams) {
|
|
1821
1866
|
data = Object.fromEntries(data);
|
|
@@ -1836,7 +1881,7 @@
|
|
|
1836
1881
|
}
|
|
1837
1882
|
} else {
|
|
1838
1883
|
if (pattern != data) {
|
|
1839
|
-
problems.push(
|
|
1884
|
+
problems.push(error4("data and pattern are not equal", data, pattern, path));
|
|
1840
1885
|
}
|
|
1841
1886
|
}
|
|
1842
1887
|
if (problems.length) {
|
|
@@ -1844,7 +1889,7 @@
|
|
|
1844
1889
|
}
|
|
1845
1890
|
return false;
|
|
1846
1891
|
}
|
|
1847
|
-
function
|
|
1892
|
+
function error4(message, found, expected, path, problems) {
|
|
1848
1893
|
let result = {
|
|
1849
1894
|
message,
|
|
1850
1895
|
found,
|
|
@@ -1862,13 +1907,13 @@
|
|
|
1862
1907
|
if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
|
|
1863
1908
|
return false;
|
|
1864
1909
|
}
|
|
1865
|
-
return
|
|
1910
|
+
return error4("root data must have all of", root, options);
|
|
1866
1911
|
};
|
|
1867
1912
|
var MustInclude = (...options) => (value) => {
|
|
1868
1913
|
if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
|
|
1869
1914
|
return false;
|
|
1870
1915
|
} else {
|
|
1871
|
-
return
|
|
1916
|
+
return error4("data must be an array which includes", value, options);
|
|
1872
1917
|
}
|
|
1873
1918
|
};
|
|
1874
1919
|
var validJWA = [
|