oidc-spa 8.4.8 → 8.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/core/createOidc.js +3 -1
- package/core/createOidc.js.map +1 -1
- package/core/earlyInit.d.ts +45 -7
- package/core/earlyInit.js +69 -153
- package/core/earlyInit.js.map +1 -1
- package/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/core/oidcClientTsUserToTokens.js +11 -1
- package/core/oidcClientTsUserToTokens.js.map +1 -1
- package/core/tokenExfiltrationDefense.d.ts +6 -0
- package/core/tokenExfiltrationDefense.js +616 -0
- package/core/tokenExfiltrationDefense.js.map +1 -0
- package/core/tokenExfiltrationDefense_legacy.d.ts +8 -0
- package/core/tokenExfiltrationDefense_legacy.js +133 -0
- package/core/tokenExfiltrationDefense_legacy.js.map +1 -0
- package/core/tokenPlaceholderSubstitution.d.ts +13 -0
- package/core/tokenPlaceholderSubstitution.js +79 -0
- package/core/tokenPlaceholderSubstitution.js.map +1 -0
- package/esm/core/createOidc.js +3 -1
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/earlyInit.d.ts +45 -7
- package/esm/core/earlyInit.js +69 -153
- package/esm/core/earlyInit.js.map +1 -1
- package/esm/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/esm/core/oidcClientTsUserToTokens.js +11 -1
- package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
- package/esm/core/tokenExfiltrationDefense.d.ts +6 -0
- package/esm/core/tokenExfiltrationDefense.js +613 -0
- package/esm/core/tokenExfiltrationDefense.js.map +1 -0
- package/esm/core/tokenExfiltrationDefense_legacy.d.ts +8 -0
- package/esm/core/tokenExfiltrationDefense_legacy.js +130 -0
- package/esm/core/tokenExfiltrationDefense_legacy.js.map +1 -0
- package/esm/core/tokenPlaceholderSubstitution.d.ts +13 -0
- package/esm/core/tokenPlaceholderSubstitution.js +73 -0
- package/esm/core/tokenPlaceholderSubstitution.js.map +1 -0
- package/esm/tools/isDomain.d.ts +1 -0
- package/esm/tools/isDomain.js +16 -0
- package/esm/tools/isDomain.js.map +1 -0
- package/esm/tools/isHostnameAuthorized.d.ts +5 -0
- package/esm/tools/isHostnameAuthorized.js +74 -0
- package/esm/tools/isHostnameAuthorized.js.map +1 -0
- package/esm/tools/isLikelyDevServer.js +18 -10
- package/esm/tools/isLikelyDevServer.js.map +1 -1
- package/package.json +1 -1
- package/src/core/createOidc.ts +2 -0
- package/src/core/earlyInit.ts +138 -192
- package/src/core/oidcClientTsUserToTokens.ts +14 -0
- package/src/core/tokenExfiltrationDefense.ts +874 -0
- package/src/core/tokenExfiltrationDefense_legacy.ts +165 -0
- package/src/core/tokenPlaceholderSubstitution.ts +105 -0
- package/src/tools/isDomain.ts +18 -0
- package/src/tools/isHostnameAuthorized.ts +91 -0
- package/src/tools/isLikelyDevServer.ts +23 -11
- package/src/vite-plugin/handleClientEntrypoint.ts +57 -20
- package/src/vite-plugin/vite-plugin.ts +5 -10
- package/tools/isDomain.d.ts +1 -0
- package/tools/isDomain.js +19 -0
- package/tools/isDomain.js.map +1 -0
- package/tools/isHostnameAuthorized.d.ts +5 -0
- package/tools/isHostnameAuthorized.js +77 -0
- package/tools/isHostnameAuthorized.js.map +1 -0
- package/tools/isLikelyDevServer.js +18 -10
- package/tools/isLikelyDevServer.js.map +1 -1
- package/vite-plugin/handleClientEntrypoint.js +36 -17
- package/vite-plugin/handleClientEntrypoint.js.map +1 -1
- package/vite-plugin/vite-plugin.d.ts +3 -4
- package/vite-plugin/vite-plugin.js +1 -5
- package/vite-plugin/vite-plugin.js.map +1 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { assert } from "../tools/tsafe/assert";
|
|
2
|
+
export function handleTokenExfiltrationDefense_legacy(params) {
|
|
3
|
+
const { freezeFetch, freezeXMLHttpRequest, freezeWebSocket, freezePromise, safeMode = false } = params;
|
|
4
|
+
const createWriteError = (target) => new Error([
|
|
5
|
+
`oidc-spa: Monkey patching of ${target} has been blocked for security reasons.`,
|
|
6
|
+
"You can disable this restriction by setting `safeMode: false` in `oidcEarlyInit()`",
|
|
7
|
+
"or in your Vite plugin configuration,",
|
|
8
|
+
"but please note this will reduce security.",
|
|
9
|
+
"If you believe this restriction is too strict, please open an issue at:",
|
|
10
|
+
"https://github.com/keycloakify/oidc-spa",
|
|
11
|
+
"We're still identifying real-world blockers and can safely add exceptions where needed.",
|
|
12
|
+
"For now, we prefer to err on the side of hardening rather than exposure."
|
|
13
|
+
].join(" "));
|
|
14
|
+
for (const name of [
|
|
15
|
+
"fetch",
|
|
16
|
+
"XMLHttpRequest",
|
|
17
|
+
"WebSocket",
|
|
18
|
+
"Headers",
|
|
19
|
+
"URLSearchParams",
|
|
20
|
+
"String",
|
|
21
|
+
"Object",
|
|
22
|
+
"Promise",
|
|
23
|
+
"Array",
|
|
24
|
+
"RegExp",
|
|
25
|
+
"TextEncoder",
|
|
26
|
+
"Uint8Array",
|
|
27
|
+
"Uint32Array",
|
|
28
|
+
"Response",
|
|
29
|
+
"Reflect",
|
|
30
|
+
"JSON",
|
|
31
|
+
"encodeURIComponent",
|
|
32
|
+
"decodeURIComponent",
|
|
33
|
+
"atob",
|
|
34
|
+
"btoa"
|
|
35
|
+
]) {
|
|
36
|
+
const doSkip = (() => {
|
|
37
|
+
switch (name) {
|
|
38
|
+
case "XMLHttpRequest":
|
|
39
|
+
if (freezeXMLHttpRequest !== undefined) {
|
|
40
|
+
return !freezeXMLHttpRequest;
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case "fetch":
|
|
44
|
+
if (freezeFetch !== undefined) {
|
|
45
|
+
return !freezeFetch;
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
case "WebSocket":
|
|
49
|
+
if (freezeWebSocket !== undefined) {
|
|
50
|
+
return !freezeWebSocket;
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case "Promise":
|
|
54
|
+
if (freezePromise !== undefined) {
|
|
55
|
+
return !freezePromise;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
return !safeMode;
|
|
60
|
+
})();
|
|
61
|
+
if (doSkip) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const original = window[name];
|
|
65
|
+
if (!original) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if ("prototype" in original) {
|
|
69
|
+
for (const propertyName of Object.getOwnPropertyNames(original.prototype)) {
|
|
70
|
+
if (name === "Object") {
|
|
71
|
+
if (propertyName === "toString" ||
|
|
72
|
+
propertyName === "constructor" ||
|
|
73
|
+
propertyName === "valueOf") {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (name === "Array") {
|
|
78
|
+
if (propertyName === "constructor" || propertyName === "concat") {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const pd = Object.getOwnPropertyDescriptor(original.prototype, propertyName);
|
|
83
|
+
assert(pd !== undefined);
|
|
84
|
+
if (!pd.configurable) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
Object.defineProperty(original.prototype, propertyName, {
|
|
88
|
+
enumerable: pd.enumerable,
|
|
89
|
+
configurable: false,
|
|
90
|
+
...("value" in pd
|
|
91
|
+
? {
|
|
92
|
+
get: () => pd.value,
|
|
93
|
+
set: () => {
|
|
94
|
+
throw createWriteError(`window.${name}.prototype.${propertyName}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
: {
|
|
98
|
+
get: pd.get,
|
|
99
|
+
set: pd.set ??
|
|
100
|
+
(() => {
|
|
101
|
+
throw createWriteError(`window.${name}.prototype.${propertyName}`);
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
Object.defineProperty(window, name, {
|
|
108
|
+
configurable: false,
|
|
109
|
+
enumerable: true,
|
|
110
|
+
get: () => original,
|
|
111
|
+
set: () => {
|
|
112
|
+
throw createWriteError(`window.${name}`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (safeMode) {
|
|
117
|
+
for (const name of ["call", "apply", "bind"]) {
|
|
118
|
+
const original = Function.prototype[name];
|
|
119
|
+
Object.defineProperty(Function.prototype, name, {
|
|
120
|
+
configurable: false,
|
|
121
|
+
enumerable: true,
|
|
122
|
+
get: () => original,
|
|
123
|
+
set: () => {
|
|
124
|
+
throw createWriteError(`window.Function.prototype.${name})`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=tokenExfiltrationDefense_legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenExfiltrationDefense_legacy.js","sourceRoot":"","sources":["../../src/core/tokenExfiltrationDefense_legacy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function markTokenSubstitutionAdEnabled(): void;
|
|
2
|
+
export declare function getIsTokenSubstitutionEnabled(): boolean;
|
|
3
|
+
type Tokens = {
|
|
4
|
+
accessToken: string;
|
|
5
|
+
idToken: string;
|
|
6
|
+
refreshToken?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function getTokensPlaceholders(params: {
|
|
9
|
+
configId: string;
|
|
10
|
+
tokens: Tokens;
|
|
11
|
+
}): Tokens;
|
|
12
|
+
export declare function substitutePlaceholderByRealToken(text: string): string;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { assert } from "../tools/tsafe/assert";
|
|
2
|
+
let isTokenSubstitutionEnabled = false;
|
|
3
|
+
export function markTokenSubstitutionAdEnabled() {
|
|
4
|
+
isTokenSubstitutionEnabled = true;
|
|
5
|
+
}
|
|
6
|
+
export function getIsTokenSubstitutionEnabled() {
|
|
7
|
+
return isTokenSubstitutionEnabled;
|
|
8
|
+
}
|
|
9
|
+
const entries = [];
|
|
10
|
+
let counter = Math.floor(Math.random() * 1000000) + 1000000;
|
|
11
|
+
export function getTokensPlaceholders(params) {
|
|
12
|
+
const { configId, tokens } = params;
|
|
13
|
+
assert(isTokenSubstitutionEnabled, "2934482");
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
if (entry.configId !== configId) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
const index = entries.indexOf(entry);
|
|
20
|
+
if (index === -1) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
entries.splice(index, 1);
|
|
24
|
+
}, 30000);
|
|
25
|
+
}
|
|
26
|
+
const id = counter++;
|
|
27
|
+
const entry_new = {
|
|
28
|
+
id,
|
|
29
|
+
configId,
|
|
30
|
+
tokens: {
|
|
31
|
+
accessToken: tokens.accessToken,
|
|
32
|
+
idToken: tokens.idToken,
|
|
33
|
+
refreshToken: tokens.refreshToken
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
entries.push(entry_new);
|
|
37
|
+
return {
|
|
38
|
+
accessToken: `access_token_placeholder_${id}`,
|
|
39
|
+
idToken: `id_token_placeholder_${id}`,
|
|
40
|
+
refreshToken: tokens.refreshToken === undefined ? undefined : `refresh_token_placeholder_${id}`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function substitutePlaceholderByRealToken(text) {
|
|
44
|
+
let text_modified = text;
|
|
45
|
+
for (const [tokenType, regExp] of [
|
|
46
|
+
["access_token", /access_token_placeholder_(\d+)/g],
|
|
47
|
+
["id_token", /id_token_placeholder_(\d+)/g],
|
|
48
|
+
["refresh_token", /refresh_token_placeholder_(\d+)/g]
|
|
49
|
+
]) {
|
|
50
|
+
text_modified = text_modified.replace(regExp, (...[, p1]) => {
|
|
51
|
+
const id = parseInt(p1);
|
|
52
|
+
const entry = entries.find(e => e.id === id);
|
|
53
|
+
if (!entry) {
|
|
54
|
+
throw new Error([
|
|
55
|
+
"oidc-spa: Outdated token used to make a request.",
|
|
56
|
+
"Token should not be stored at the application level, when a token",
|
|
57
|
+
"is needed, it should be requested and used immediately."
|
|
58
|
+
].join(" "));
|
|
59
|
+
}
|
|
60
|
+
switch (tokenType) {
|
|
61
|
+
case "access_token":
|
|
62
|
+
return entry.tokens.accessToken;
|
|
63
|
+
case "id_token":
|
|
64
|
+
return entry.tokens.idToken;
|
|
65
|
+
case "refresh_token":
|
|
66
|
+
assert(entry.tokens.refreshToken !== undefined, "204392284");
|
|
67
|
+
return entry.tokens.refreshToken;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return text_modified;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=tokenPlaceholderSubstitution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenPlaceholderSubstitution.js","sourceRoot":"","sources":["../../src/core/tokenPlaceholderSubstitution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getIsDomain(hostname: string): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function getIsDomain(hostname) {
|
|
2
|
+
// Reject IPv4
|
|
3
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
// Reject IPv6
|
|
7
|
+
if (hostname.includes(":")) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
// Must contain at least one dot (e.g., "example.com")
|
|
11
|
+
if (!hostname.includes(".")) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=isDomain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isDomain.js","sourceRoot":"","sources":["../../src/tools/isDomain.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,QAAgB;IACxC,cAAc;IACd,IAAI,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,cAAc;IACd,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,sDAAsD;IACtD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
|
|
2
|
+
import { getIsDomain } from "../tools/isDomain";
|
|
3
|
+
const MULTI_TENANT_DOMAINS = [
|
|
4
|
+
"vercel.app",
|
|
5
|
+
"netlify.app",
|
|
6
|
+
"github.io",
|
|
7
|
+
"pages.dev",
|
|
8
|
+
"web.app",
|
|
9
|
+
"firebaseapp.com",
|
|
10
|
+
"onrender.com",
|
|
11
|
+
"railway.app",
|
|
12
|
+
"fly.dev",
|
|
13
|
+
"herokuapp.com",
|
|
14
|
+
"amplifyapp.com",
|
|
15
|
+
"surge.sh",
|
|
16
|
+
"stackblitz.io",
|
|
17
|
+
"glitch.me",
|
|
18
|
+
"csb.app",
|
|
19
|
+
"codesandbox.io",
|
|
20
|
+
"repl.co",
|
|
21
|
+
"replit.dev",
|
|
22
|
+
"ondigitalocean.app",
|
|
23
|
+
"bubbleapps.io",
|
|
24
|
+
"wixsite.com",
|
|
25
|
+
"webflow.io",
|
|
26
|
+
"framer.app",
|
|
27
|
+
"deno.dev",
|
|
28
|
+
"azurestaticapps.net",
|
|
29
|
+
"run.app",
|
|
30
|
+
"cloudfront.net",
|
|
31
|
+
"qovery.io",
|
|
32
|
+
"northflank.app",
|
|
33
|
+
"cyclic.app",
|
|
34
|
+
"turso.io",
|
|
35
|
+
"koyeb.app",
|
|
36
|
+
"on.fleek.co",
|
|
37
|
+
"back4app.io"
|
|
38
|
+
];
|
|
39
|
+
export function getIsHostnameAuthorized(params) {
|
|
40
|
+
if (getIsLikelyDevServer()) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const { hostname, allowedHostnames, extendAuthorizationToParentDomain } = params;
|
|
44
|
+
if (hostname === location.host) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
for (let allowedHost of allowedHostnames) {
|
|
48
|
+
allowedHost = allowedHost.toLocaleLowerCase();
|
|
49
|
+
if (allowedHost === hostname) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (allowedHost.startsWith("*") && hostname.endsWith(allowedHost.slice(1))) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!extendAuthorizationToParentDomain) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (!getIsDomain(location.host) || !getIsDomain(hostname)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (MULTI_TENANT_DOMAINS.find(suffix => location.host.endsWith(`.${suffix}`)) !== undefined) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const trustedParentDomain = (() => {
|
|
66
|
+
const [s1, s2] = location.host.split(".").reverse();
|
|
67
|
+
return `${s2}.${s1}`;
|
|
68
|
+
})();
|
|
69
|
+
if (hostname.endsWith(`.${trustedParentDomain}`)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=isHostnameAuthorized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isHostnameAuthorized.js","sourceRoot":"","sources":["../../src/tools/isHostnameAuthorized.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,oBAAoB,GAAG;IACzB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,WAAW;IACX,SAAS;IACT,iBAAiB;IACjB,cAAc;IACd,aAAa;IACb,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,UAAU;IACV,eAAe;IACf,WAAW;IACX,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,YAAY;IACZ,oBAAoB;IACpB,eAAe;IACf,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,qBAAqB;IACrB,SAAS;IACT,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,YAAY;IACZ,UAAU;IACV,WAAW;IACX,aAAa;IACb,aAAa;CAChB,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,MAIvC;IACG,IAAI,oBAAoB,EAAE,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iCAAiC,EAAE,GAAG,MAAM,CAAC;IAEjF,IAAI,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK,IAAI,WAAW,IAAI,gBAAgB,EAAE,CAAC;QACvC,WAAW,GAAG,WAAW,CAAC,iBAAiB,EAAE,CAAC;QAE9C,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,IAAI,CAAC,iCAAiC,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC1F,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE;QAC9B,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QAEpD,OAAO,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC;IAEL,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,mBAAmB,EAAE,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
let isLikelyDevServer_cache = undefined;
|
|
1
2
|
export function getIsLikelyDevServer() {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return true;
|
|
3
|
+
if (isLikelyDevServer_cache !== undefined) {
|
|
4
|
+
return isLikelyDevServer_cache;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const isLikelyDevServer = (() => {
|
|
7
|
+
const origin = window.location.origin;
|
|
8
|
+
if (/^https?:\/\/localhost/.test(origin)) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (/^https?:\/\/\[::\]/.test(origin)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (/^https?:\/\/127.0.0.1/.test(origin)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
})();
|
|
19
|
+
isLikelyDevServer_cache = isLikelyDevServer;
|
|
20
|
+
return isLikelyDevServer;
|
|
13
21
|
}
|
|
14
22
|
//# sourceMappingURL=isLikelyDevServer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isLikelyDevServer.js","sourceRoot":"","sources":["../../src/tools/isLikelyDevServer.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"isLikelyDevServer.js","sourceRoot":"","sources":["../../src/tools/isLikelyDevServer.ts"],"names":[],"mappings":"AAAA,IAAI,uBAAuB,GAAwB,SAAS,CAAC;AAE7D,MAAM,UAAU,oBAAoB;IAChC,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEtC,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,EAAE,CAAC;IAEL,uBAAuB,GAAG,iBAAiB,CAAC;IAE5C,OAAO,iBAAiB,CAAC;AAC7B,CAAC"}
|
package/package.json
CHANGED
package/src/core/createOidc.ts
CHANGED
|
@@ -1211,6 +1211,7 @@ export async function createOidc_nonMemoized<
|
|
|
1211
1211
|
assert(oidcMetadata !== undefined, "30483403");
|
|
1212
1212
|
|
|
1213
1213
|
let currentTokens = oidcClientTsUserToTokens({
|
|
1214
|
+
configId,
|
|
1214
1215
|
oidcClientTsUser: resultOfLoginProcess.oidcClientTsUser,
|
|
1215
1216
|
decodedIdTokenSchema,
|
|
1216
1217
|
__unsafe_useIdTokenAsAccessToken,
|
|
@@ -1537,6 +1538,7 @@ export async function createOidc_nonMemoized<
|
|
|
1537
1538
|
}
|
|
1538
1539
|
|
|
1539
1540
|
currentTokens = oidcClientTsUserToTokens({
|
|
1541
|
+
configId,
|
|
1540
1542
|
oidcClientTsUser,
|
|
1541
1543
|
decodedIdTokenSchema,
|
|
1542
1544
|
__unsafe_useIdTokenAsAccessToken,
|