oidc-spa 8.2.0 → 8.2.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/core/AuthResponse.d.ts +0 -5
- package/core/AuthResponse.js +0 -25
- package/core/AuthResponse.js.map +1 -1
- package/core/OidcMetadata.d.ts +5 -0
- package/core/OidcMetadata.js +56 -0
- package/core/OidcMetadata.js.map +1 -1
- package/core/createOidc.d.ts +4 -3
- package/core/createOidc.js +229 -197
- package/core/createOidc.js.map +1 -1
- package/core/diagnostic.d.ts +0 -1
- package/core/diagnostic.js +18 -5
- package/core/diagnostic.js.map +1 -1
- package/core/instancesThatCantUseIframes.d.ts +2 -0
- package/core/instancesThatCantUseIframes.js +20 -0
- package/core/instancesThatCantUseIframes.js.map +1 -0
- package/core/loginOrGoToAuthServer.d.ts +1 -1
- package/core/loginOrGoToAuthServer.js +4 -16
- package/core/loginOrGoToAuthServer.js.map +1 -1
- package/core/loginSilent.d.ts +1 -2
- package/core/loginSilent.js +3 -21
- package/core/loginSilent.js.map +1 -1
- package/core/persistedAuthState.d.ts +1 -0
- package/core/persistedAuthState.js +14 -4
- package/core/persistedAuthState.js.map +1 -1
- package/esm/core/AuthResponse.d.ts +0 -5
- package/esm/core/AuthResponse.js +0 -23
- package/esm/core/AuthResponse.js.map +1 -1
- package/esm/core/OidcMetadata.d.ts +5 -0
- package/esm/core/OidcMetadata.js +54 -0
- package/esm/core/OidcMetadata.js.map +1 -1
- package/esm/core/createOidc.d.ts +4 -3
- package/esm/core/createOidc.js +230 -198
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/diagnostic.d.ts +0 -1
- package/esm/core/diagnostic.js +15 -1
- package/esm/core/diagnostic.js.map +1 -1
- package/esm/core/instancesThatCantUseIframes.d.ts +2 -0
- package/esm/core/instancesThatCantUseIframes.js +16 -0
- package/esm/core/instancesThatCantUseIframes.js.map +1 -0
- package/esm/core/loginOrGoToAuthServer.d.ts +1 -1
- package/esm/core/loginOrGoToAuthServer.js +4 -16
- package/esm/core/loginOrGoToAuthServer.js.map +1 -1
- package/esm/core/loginSilent.d.ts +1 -2
- package/esm/core/loginSilent.js +3 -21
- package/esm/core/loginSilent.js.map +1 -1
- package/esm/core/persistedAuthState.d.ts +1 -0
- package/esm/core/persistedAuthState.js +14 -4
- package/esm/core/persistedAuthState.js.map +1 -1
- package/esm/keycloak/keycloakIssuerUriParsed.js +8 -1
- package/esm/keycloak/keycloakIssuerUriParsed.js.map +1 -1
- package/esm/tools/isLikelyDevServer.d.ts +1 -0
- package/esm/tools/isLikelyDevServer.js +14 -0
- package/esm/tools/isLikelyDevServer.js.map +1 -0
- package/esm/tools/{EphemeralSessionStorage.d.ts → lazySessionStorage.d.ts} +2 -4
- package/esm/tools/lazySessionStorage.js +81 -0
- package/esm/tools/lazySessionStorage.js.map +1 -0
- package/keycloak/keycloakIssuerUriParsed.js +8 -1
- package/keycloak/keycloakIssuerUriParsed.js.map +1 -1
- package/package.json +1 -1
- package/src/core/AuthResponse.ts +0 -36
- package/src/core/OidcMetadata.ts +75 -0
- package/src/core/createOidc.ts +277 -264
- package/src/core/diagnostic.ts +21 -2
- package/src/core/instancesThatCantUseIframes.ts +24 -0
- package/src/core/loginOrGoToAuthServer.ts +5 -22
- package/src/core/loginSilent.ts +4 -27
- package/src/core/persistedAuthState.ts +27 -5
- package/src/keycloak/keycloakIssuerUriParsed.ts +10 -1
- package/src/tools/isLikelyDevServer.ts +17 -0
- package/src/tools/lazySessionStorage.ts +119 -0
- package/src/vite-plugin/manageOptimizedDeps.ts +2 -0
- package/tools/isLikelyDevServer.d.ts +1 -0
- package/tools/isLikelyDevServer.js +17 -0
- package/tools/isLikelyDevServer.js.map +1 -0
- package/tools/{EphemeralSessionStorage.d.ts → lazySessionStorage.d.ts} +2 -4
- package/tools/lazySessionStorage.js +84 -0
- package/tools/lazySessionStorage.js.map +1 -0
- package/vite-plugin/manageOptimizedDeps.js +1 -0
- package/vite-plugin/manageOptimizedDeps.js.map +1 -1
- package/esm/tools/EphemeralSessionStorage.js +0 -143
- package/esm/tools/EphemeralSessionStorage.js.map +0 -1
- package/src/tools/EphemeralSessionStorage.ts +0 -225
- package/tools/EphemeralSessionStorage.js +0 -146
- package/tools/EphemeralSessionStorage.js.map +0 -1
package/esm/core/createOidc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { UserManager as OidcClientTsUserManager, WebStorageStateStore, InMemoryWebStorage } from "../vendor/frontend/oidc-client-ts";
|
|
2
|
+
import { fetchOidcMetadata } from "./OidcMetadata";
|
|
2
3
|
import { assert, is } from "../tools/tsafe/assert";
|
|
3
4
|
import { id } from "../tools/tsafe/id";
|
|
4
5
|
import { setTimeout, clearTimeout } from "../tools/workerTimers";
|
|
@@ -14,38 +15,29 @@ import { notifyOtherTabsOfLogin, getPrOtherTabLogin } from "./loginPropagationTo
|
|
|
14
15
|
import { getConfigId } from "./configId";
|
|
15
16
|
import { oidcClientTsUserToTokens } from "./oidcClientTsUserToTokens";
|
|
16
17
|
import { loginSilent } from "./loginSilent";
|
|
17
|
-
import { authResponseToUrl
|
|
18
|
+
import { authResponseToUrl } from "./AuthResponse";
|
|
18
19
|
import { getRootRelativeOriginalLocationHref, getRedirectAuthResponse } from "./earlyInit";
|
|
19
20
|
import { getPersistedAuthState, persistAuthState } from "./persistedAuthState";
|
|
20
21
|
import { createEvt } from "../tools/Evt";
|
|
21
22
|
import { getHaveSharedParentDomain } from "../tools/haveSharedParentDomain";
|
|
22
23
|
import { createLoginOrGoToAuthServer, getPrSafelyRestoredFromBfCacheAfterLoginBackNavigationOrInitializationError } from "./loginOrGoToAuthServer";
|
|
23
|
-
import {
|
|
24
|
+
import { createLazySessionStorage } from "../tools/lazySessionStorage";
|
|
24
25
|
import { startLoginOrRefreshProcess, waitForAllOtherOngoingLoginOrRefreshProcessesToComplete } from "./ongoingLoginOrRefreshProcesses";
|
|
25
26
|
import { createGetIsNewBrowserSession } from "./isNewBrowserSession";
|
|
26
27
|
import { getIsOnline } from "../tools/getIsOnline";
|
|
27
28
|
import { isKeycloak } from "../keycloak/isKeycloak";
|
|
28
29
|
import { INFINITY_TIME } from "../tools/INFINITY_TIME";
|
|
29
|
-
import { getIsValidRemoteJson } from "../tools/getIsValidRemoteJson";
|
|
30
30
|
import { prShouldLoadApp } from "./prShouldLoadApp";
|
|
31
31
|
import { getBASE_URL } from "./BASE_URL";
|
|
32
|
+
import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
|
|
33
|
+
import { createObjectThatThrowsIfAccessed } from "../tools/createObjectThatThrowsIfAccessed";
|
|
34
|
+
import { evtIsThereMoreThanOneInstanceThatCantUserIframes, notifyNewInstanceThatCantUseIframes } from "./instancesThatCantUseIframes";
|
|
32
35
|
// NOTE: Replaced at build time
|
|
33
|
-
const VERSION = "8.2.
|
|
36
|
+
const VERSION = "8.2.2";
|
|
34
37
|
const globalContext = {
|
|
35
38
|
prOidcByConfigId: new Map(),
|
|
36
|
-
hasLogoutBeenCalled: id(false)
|
|
37
|
-
evtRequestToPersistTokens: createEvt()
|
|
39
|
+
hasLogoutBeenCalled: id(false)
|
|
38
40
|
};
|
|
39
|
-
globalContext.evtRequestToPersistTokens.subscribe(() => {
|
|
40
|
-
const { authResponse } = getRedirectAuthResponse();
|
|
41
|
-
if (authResponse === undefined) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const { authResponses } = getPersistedRedirectAuthResponses();
|
|
45
|
-
setPersistedRedirectAuthResponses({
|
|
46
|
-
authResponses: [...authResponses, authResponse]
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
41
|
/** @see: https://docs.oidc-spa.dev/v/v8/usage */
|
|
50
42
|
export async function createOidc(params) {
|
|
51
43
|
for (const name of ["issuerUri", "clientId"]) {
|
|
@@ -54,7 +46,7 @@ export async function createOidc(params) {
|
|
|
54
46
|
throw new Error(`The parameter "${name}" is required, you provided: ${value}. (Forgot a .env variable?)`);
|
|
55
47
|
}
|
|
56
48
|
}
|
|
57
|
-
const { issuerUri: issuerUri_params, clientId,
|
|
49
|
+
const { issuerUri: issuerUri_params, clientId, debugLogs, ...rest } = params;
|
|
58
50
|
const issuerUri = toFullyQualifiedUrl({
|
|
59
51
|
urlish: issuerUri_params,
|
|
60
52
|
doAssertNoQueryParams: true,
|
|
@@ -96,7 +88,6 @@ export async function createOidc(params) {
|
|
|
96
88
|
const oidc = await createOidc_nonMemoized(rest, {
|
|
97
89
|
issuerUri,
|
|
98
90
|
clientId,
|
|
99
|
-
scopes,
|
|
100
91
|
configId,
|
|
101
92
|
log
|
|
102
93
|
});
|
|
@@ -119,9 +110,9 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
119
110
|
return new Promise(() => { });
|
|
120
111
|
}
|
|
121
112
|
}
|
|
122
|
-
const { transformUrlBeforeRedirect, extraQueryParams: extraQueryParamsOrGetter, extraTokenParams: extraTokenParamsOrGetter, decodedIdTokenSchema, idleSessionLifetimeInSeconds, autoLogoutParams = { redirectTo: "current page" }, autoLogin = false, postLoginRedirectUrl: postLoginRedirectUrl_default, __unsafe_clientSecret, __unsafe_useIdTokenAsAccessToken = false, __metadata, noIframe = false } = params;
|
|
113
|
+
const { transformUrlBeforeRedirect, extraQueryParams: extraQueryParamsOrGetter, extraTokenParams: extraTokenParamsOrGetter, decodedIdTokenSchema, idleSessionLifetimeInSeconds, autoLogoutParams = { redirectTo: "current page" }, autoLogin = false, postLoginRedirectUrl: postLoginRedirectUrl_default, __unsafe_clientSecret, __unsafe_useIdTokenAsAccessToken = false, __metadata, noIframe = false, scopes = ["openid", "profile"] } = params;
|
|
123
114
|
const BASE_URL_params = params.BASE_URL ?? params.homeUrl;
|
|
124
|
-
const { issuerUri, clientId,
|
|
115
|
+
const { issuerUri, clientId, configId, log } = preProcessedParams;
|
|
125
116
|
const getExtraQueryParams = (() => {
|
|
126
117
|
if (extraQueryParamsOrGetter === undefined) {
|
|
127
118
|
return undefined;
|
|
@@ -166,75 +157,174 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
166
157
|
issuerUri,
|
|
167
158
|
clientId,
|
|
168
159
|
scopes,
|
|
169
|
-
|
|
170
|
-
homeUrlAndRedirectUri
|
|
160
|
+
oidcRedirectUri: homeUrlAndRedirectUri
|
|
171
161
|
}, null, 2)}`);
|
|
172
162
|
const stateUrlParamValue_instance = generateStateUrlParamValue();
|
|
163
|
+
const oidcMetadata = __metadata ?? (await fetchOidcMetadata({ issuerUri }));
|
|
173
164
|
const canUseIframe = (() => {
|
|
174
165
|
if (noIframe) {
|
|
175
166
|
return false;
|
|
176
167
|
}
|
|
177
168
|
third_party_cookies: {
|
|
178
|
-
|
|
169
|
+
if (oidcMetadata === undefined) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const { authorization_endpoint } = oidcMetadata;
|
|
173
|
+
assert(authorization_endpoint !== undefined, "Missing authorization_endpoint on the provided __metadata");
|
|
174
|
+
const isOidcServerThirdPartyRelativeToApp = !getHaveSharedParentDomain({
|
|
179
175
|
url1: window.location.origin,
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
// TODO: No, here we should test against the authorization endpoint!
|
|
177
|
+
url2: authorization_endpoint
|
|
178
|
+
});
|
|
182
179
|
if (!isOidcServerThirdPartyRelativeToApp) {
|
|
183
180
|
break third_party_cookies;
|
|
184
181
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
const isLikelyDevServer = getIsLikelyDevServer();
|
|
183
|
+
const domain_auth = new URL(authorization_endpoint).origin.split("//")[1];
|
|
184
|
+
assert(domain_auth !== undefined, "33921384");
|
|
185
|
+
const domain_here = window.location.origin.split("//")[1];
|
|
186
|
+
let isWellKnownProviderDomain = false;
|
|
187
|
+
let isIp = false;
|
|
188
|
+
const suggestedDeployments = (() => {
|
|
189
|
+
if (/^(?:\d{1,3}\.){3}\d{1,3}$|^\[?[A-Fa-f0-9:]+\]?$/.test(domain_auth)) {
|
|
190
|
+
isIp = true;
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const baseDomain = (() => {
|
|
194
|
+
const segments = domain_auth.split(".");
|
|
195
|
+
if (segments.length >= 3) {
|
|
196
|
+
segments.shift();
|
|
197
|
+
}
|
|
198
|
+
return segments.join(".");
|
|
199
|
+
})();
|
|
200
|
+
{
|
|
201
|
+
const baseDomain_low = baseDomain.toLowerCase();
|
|
202
|
+
if (baseDomain_low.includes("auth0") ||
|
|
203
|
+
baseDomain_low.includes("clerk") ||
|
|
204
|
+
baseDomain_low.includes("microsoft") ||
|
|
205
|
+
baseDomain_low.includes("okta") ||
|
|
206
|
+
baseDomain_low.includes("aws")) {
|
|
207
|
+
isWellKnownProviderDomain = true;
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const baseUrl = new URL(homeUrlAndRedirectUri).pathname;
|
|
212
|
+
return [
|
|
213
|
+
`myapp.${baseDomain}`,
|
|
214
|
+
baseDomain === domain_auth ? undefined : baseDomain,
|
|
215
|
+
`${baseDomain}/${baseUrl === "/" ? "dashboard" : baseUrl}`
|
|
216
|
+
].filter(x => x !== undefined);
|
|
189
217
|
})();
|
|
190
|
-
if (
|
|
191
|
-
|
|
218
|
+
if (isLikelyDevServer) {
|
|
219
|
+
log?.([
|
|
220
|
+
"Detected localhost environment.",
|
|
221
|
+
"\nWhen reloading while logged in, you will briefly see",
|
|
222
|
+
"some URL params appear in the address bar.",
|
|
223
|
+
"\nThis happens because session restore via iframe is disabled,",
|
|
224
|
+
"the browser treats your auth server as a third party.",
|
|
225
|
+
`\nAuth server: ${domain_auth}`,
|
|
226
|
+
`\nApp domain: ${domain_here}`,
|
|
227
|
+
...(() => {
|
|
228
|
+
if (isIp) {
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
if (isWellKnownProviderDomain) {
|
|
232
|
+
return [
|
|
233
|
+
"\nYou seem to be using a well-known auth provider.",
|
|
234
|
+
"Check your provider's docs, some allow configuring",
|
|
235
|
+
`a your custom domain at least for the authorization endpoint.`,
|
|
236
|
+
"\nIf configured, oidc-spa will restore sessions silently",
|
|
237
|
+
"and improve the user experience."
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
return [
|
|
241
|
+
"\nOnce deployed under the same root domain as your auth server,",
|
|
242
|
+
"oidc-spa will use iframes to restore sessions silently.",
|
|
243
|
+
"\nSuggested deployments:",
|
|
244
|
+
...suggestedDeployments.map(d => `\n • ${d}`)
|
|
245
|
+
];
|
|
246
|
+
})(),
|
|
247
|
+
"\n\nMore info:",
|
|
248
|
+
"https://docs.oidc-spa.dev/v/v8/resources/end-of-third-party-cookies#when-are-cookies-considered-third-party"
|
|
249
|
+
].join(" "));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
log?.([
|
|
253
|
+
"Silent session restore via iframe is disabled.",
|
|
254
|
+
`\nAuth server: ${domain_auth}`,
|
|
255
|
+
`App domain: ${domain_here}`,
|
|
256
|
+
"\nThey do not share a common root domain.",
|
|
257
|
+
...(() => {
|
|
258
|
+
if (isIp) {
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
if (isWellKnownProviderDomain) {
|
|
262
|
+
return [
|
|
263
|
+
"\nYou seem to be using a well-known auth provider.",
|
|
264
|
+
"Check if you can configure a custom auth domain.",
|
|
265
|
+
"\nIf so, oidc-spa can restore sessions silently",
|
|
266
|
+
"and improve the user experience."
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
return [
|
|
270
|
+
"\nTo improve the experience, here are some examples of deployment for your app:",
|
|
271
|
+
...suggestedDeployments.map(d => `\n • ${d}`)
|
|
272
|
+
];
|
|
273
|
+
})(),
|
|
274
|
+
"\nMore info:",
|
|
275
|
+
"https://docs.oidc-spa.dev/v/v8/resources/end-of-third-party-cookies#when-are-cookies-considered-third-party"
|
|
276
|
+
].join(" "));
|
|
192
277
|
}
|
|
193
|
-
log?.([
|
|
194
|
-
"Can't use iframe because your auth server is on a third party domain relative",
|
|
195
|
-
"to the domain of your app and third party cookies are blocked by navigators."
|
|
196
|
-
].join(" "));
|
|
197
278
|
return false;
|
|
198
279
|
}
|
|
199
|
-
// NOTE: Maybe not, it depend if the app can iframe itself.
|
|
200
280
|
return true;
|
|
201
281
|
})();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
return;
|
|
282
|
+
notifyNewInstanceThatCantUseIframes();
|
|
283
|
+
if (evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
284
|
+
log?.([
|
|
285
|
+
"More than one oidc instance can't use iframe",
|
|
286
|
+
"falling back to persisting tokens in session storage"
|
|
287
|
+
].join(" "));
|
|
288
|
+
}
|
|
289
|
+
const oidcClientTsUserManager = oidcMetadata === undefined
|
|
290
|
+
? createObjectThatThrowsIfAccessed({
|
|
291
|
+
debugMessage: "oidc-spa: Wrong assertion 43943"
|
|
292
|
+
})
|
|
293
|
+
: new OidcClientTsUserManager({
|
|
294
|
+
stateUrlParamValue: stateUrlParamValue_instance,
|
|
295
|
+
authority: issuerUri,
|
|
296
|
+
client_id: clientId,
|
|
297
|
+
redirect_uri: homeUrlAndRedirectUri,
|
|
298
|
+
silent_redirect_uri: homeUrlAndRedirectUri,
|
|
299
|
+
post_logout_redirect_uri: homeUrlAndRedirectUri,
|
|
300
|
+
response_mode: isKeycloak({ issuerUri }) ? "fragment" : "query",
|
|
301
|
+
response_type: "code",
|
|
302
|
+
scope: Array.from(new Set(["openid", ...scopes])).join(" "),
|
|
303
|
+
automaticSilentRenew: false,
|
|
304
|
+
userStore: new WebStorageStateStore({
|
|
305
|
+
store: (() => {
|
|
306
|
+
if (canUseIframe) {
|
|
307
|
+
return new InMemoryWebStorage();
|
|
228
308
|
}
|
|
229
|
-
storage
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
309
|
+
const storage = createLazySessionStorage();
|
|
310
|
+
if (evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
311
|
+
storage.persistCurrentStateAndSubsequentChanges();
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
evtIsThereMoreThanOneInstanceThatCantUserIframes.subscribe(() => {
|
|
315
|
+
storage.persistCurrentStateAndSubsequentChanges();
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return storage;
|
|
319
|
+
})()
|
|
320
|
+
}),
|
|
321
|
+
stateStore: new WebStorageStateStore({
|
|
322
|
+
store: localStorage,
|
|
323
|
+
prefix: STATE_STORE_KEY_PREFIX
|
|
324
|
+
}),
|
|
325
|
+
client_secret: __unsafe_clientSecret,
|
|
326
|
+
metadata: oidcMetadata
|
|
327
|
+
});
|
|
238
328
|
const evtInitializationOutcomeUserNotLoggedIn = createEvt();
|
|
239
329
|
const { loginOrGoToAuthServer } = createLoginOrGoToAuthServer({
|
|
240
330
|
configId,
|
|
@@ -252,54 +342,57 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
252
342
|
});
|
|
253
343
|
const { completeLoginOrRefreshProcess } = await startLoginOrRefreshProcess();
|
|
254
344
|
const resultOfLoginProcess = await (async () => {
|
|
345
|
+
if (oidcMetadata === undefined) {
|
|
346
|
+
return (await import("./diagnostic")).createWellKnownOidcConfigurationEndpointUnreachableInitializationError({
|
|
347
|
+
issuerUri
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
restore_from_session_storage: {
|
|
351
|
+
if (canUseIframe) {
|
|
352
|
+
break restore_from_session_storage;
|
|
353
|
+
}
|
|
354
|
+
if (!evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
355
|
+
break restore_from_session_storage;
|
|
356
|
+
}
|
|
357
|
+
let oidcClientTsUser;
|
|
358
|
+
try {
|
|
359
|
+
oidcClientTsUser = await oidcClientTsUserManager.getUser();
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// NOTE: Not sure if it can throw, but let's be safe.
|
|
363
|
+
oidcClientTsUser = null;
|
|
364
|
+
try {
|
|
365
|
+
await oidcClientTsUserManager.removeUser();
|
|
366
|
+
}
|
|
367
|
+
catch { }
|
|
368
|
+
}
|
|
369
|
+
if (oidcClientTsUser === null) {
|
|
370
|
+
break restore_from_session_storage;
|
|
371
|
+
}
|
|
372
|
+
log?.("Session was restored from session storage");
|
|
373
|
+
return {
|
|
374
|
+
oidcClientTsUser,
|
|
375
|
+
backFromAuthServer: undefined
|
|
376
|
+
};
|
|
377
|
+
}
|
|
255
378
|
handle_redirect_auth_response: {
|
|
256
379
|
let stateDataAndAuthResponse = undefined;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (stateData === undefined) {
|
|
265
|
-
clearAuthResponse();
|
|
266
|
-
break from_memory;
|
|
267
|
-
}
|
|
268
|
-
if (stateData.configId !== configId) {
|
|
269
|
-
break from_memory;
|
|
270
|
-
}
|
|
271
|
-
assert(stateData.context === "redirect", "3229492");
|
|
380
|
+
{
|
|
381
|
+
const { authResponse, clearAuthResponse } = getRedirectAuthResponse();
|
|
382
|
+
if (authResponse === undefined) {
|
|
383
|
+
break handle_redirect_auth_response;
|
|
384
|
+
}
|
|
385
|
+
const stateData = getStateData({ stateUrlParamValue: authResponse.state });
|
|
386
|
+
if (stateData === undefined) {
|
|
272
387
|
clearAuthResponse();
|
|
273
|
-
|
|
274
|
-
break get_stateData_and_authResponse;
|
|
388
|
+
break handle_redirect_auth_response;
|
|
275
389
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
// the authResponse in memory had the chance to be processed.
|
|
279
|
-
// This can only happen if:
|
|
280
|
-
// 1) There are multiple oidc instances in the App.
|
|
281
|
-
// 2) They are instantiated in a non deterministic order.
|
|
282
|
-
// 3) We can't use iframe
|
|
283
|
-
// We practically never persist the auth response and do it only in session
|
|
284
|
-
// an ephemeral session storage, when we know it's gonna be required.
|
|
285
|
-
{
|
|
286
|
-
const { authResponses } = getPersistedRedirectAuthResponses();
|
|
287
|
-
for (const authResponse of authResponses) {
|
|
288
|
-
const stateData = getStateData({ stateUrlParamValue: authResponse.state });
|
|
289
|
-
if (stateData === undefined) {
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
if (stateData.configId !== configId) {
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
assert(stateData.context === "redirect", "35935591");
|
|
296
|
-
setPersistedRedirectAuthResponses({
|
|
297
|
-
authResponses: authResponses.filter(authResponse_i => authResponse_i !== authResponse)
|
|
298
|
-
});
|
|
299
|
-
stateDataAndAuthResponse = { stateData, authResponse };
|
|
300
|
-
break get_stateData_and_authResponse;
|
|
301
|
-
}
|
|
390
|
+
if (stateData.configId !== configId) {
|
|
391
|
+
break handle_redirect_auth_response;
|
|
302
392
|
}
|
|
393
|
+
assert(stateData.context === "redirect", "3229492");
|
|
394
|
+
clearAuthResponse();
|
|
395
|
+
stateDataAndAuthResponse = { stateData, authResponse };
|
|
303
396
|
}
|
|
304
397
|
if (stateDataAndAuthResponse === undefined) {
|
|
305
398
|
break handle_redirect_auth_response;
|
|
@@ -378,33 +471,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
378
471
|
assert(false);
|
|
379
472
|
}
|
|
380
473
|
}
|
|
381
|
-
// NOTE: We almost never persist tokens, we have to only to support edge case
|
|
382
|
-
// of multiple oidc instance in a single App with no iframe support.
|
|
383
|
-
restore_from_session_storage: {
|
|
384
|
-
if (isUserStoreInMemoryOnly) {
|
|
385
|
-
break restore_from_session_storage;
|
|
386
|
-
}
|
|
387
|
-
let oidcClientTsUser;
|
|
388
|
-
try {
|
|
389
|
-
oidcClientTsUser = await oidcClientTsUserManager.getUser();
|
|
390
|
-
}
|
|
391
|
-
catch {
|
|
392
|
-
// NOTE: Not sure if it can throw, but let's be safe.
|
|
393
|
-
oidcClientTsUser = null;
|
|
394
|
-
try {
|
|
395
|
-
await oidcClientTsUserManager.removeUser();
|
|
396
|
-
}
|
|
397
|
-
catch { }
|
|
398
|
-
}
|
|
399
|
-
if (oidcClientTsUser === null) {
|
|
400
|
-
break restore_from_session_storage;
|
|
401
|
-
}
|
|
402
|
-
log?.("Restored the auth from ephemeral session storage");
|
|
403
|
-
return {
|
|
404
|
-
oidcClientTsUser,
|
|
405
|
-
backFromAuthServer: undefined
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
474
|
silent_login_if_possible_and_auto_login: {
|
|
409
475
|
const persistedAuthState = getPersistedAuthState({ configId });
|
|
410
476
|
if (persistedAuthState === "explicitly logged out" && !autoLogin) {
|
|
@@ -438,11 +504,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
438
504
|
break actual_silent_signin;
|
|
439
505
|
}
|
|
440
506
|
if (!canUseIframe) {
|
|
441
|
-
if (!(await getIsValidRemoteJson(`${issuerUri}${id("/.well-known/openid-configuration")}`))) {
|
|
442
|
-
return (await import("./diagnostic")).createWellKnownOidcConfigurationEndpointUnreachableInitializationError({
|
|
443
|
-
issuerUri
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
507
|
break actual_silent_signin;
|
|
447
508
|
}
|
|
448
509
|
log?.("Trying to restore the auth from the http only cookie (silent signin with iframe)");
|
|
@@ -457,21 +518,13 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
457
518
|
log
|
|
458
519
|
});
|
|
459
520
|
assert(result_loginSilent.outcome !== "token refreshed using refresh token", "876995");
|
|
460
|
-
if (result_loginSilent.outcome === "
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
return (await import("./diagnostic")).createIframeTimeoutInitializationError({
|
|
468
|
-
redirectUri: homeUrlAndRedirectUri,
|
|
469
|
-
clientId,
|
|
470
|
-
issuerUri,
|
|
471
|
-
noIframe
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
assert(false);
|
|
521
|
+
if (result_loginSilent.outcome === "timeout") {
|
|
522
|
+
return (await import("./diagnostic")).createIframeTimeoutInitializationError({
|
|
523
|
+
redirectUri: homeUrlAndRedirectUri,
|
|
524
|
+
clientId,
|
|
525
|
+
issuerUri,
|
|
526
|
+
noIframe
|
|
527
|
+
});
|
|
475
528
|
}
|
|
476
529
|
assert();
|
|
477
530
|
const { authResponse } = result_loginSilent;
|
|
@@ -502,7 +555,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
502
555
|
authResponse_error === "consent_required" ||
|
|
503
556
|
authResponse_error === "account_selection_required"))) {
|
|
504
557
|
log?.("Performing auto login with redirect");
|
|
505
|
-
persistAuthState({ configId, state: undefined });
|
|
506
558
|
completeLoginOrRefreshProcess();
|
|
507
559
|
if (autoLogin && persistedAuthState !== "logged in") {
|
|
508
560
|
evtInitializationOutcomeUserNotLoggedIn.post();
|
|
@@ -510,16 +562,15 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
510
562
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
511
563
|
prUnlock: getPrSafelyRestoredFromBfCacheAfterLoginBackNavigationOrInitializationError()
|
|
512
564
|
});
|
|
513
|
-
|
|
514
|
-
globalContext.evtRequestToPersistTokens.post({
|
|
515
|
-
configIdOfInstancePostingTheRequest: configId
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
const dCantFetchWellKnownEndpointOrNever = new Deferred();
|
|
519
|
-
loginOrGoToAuthServer({
|
|
565
|
+
await loginOrGoToAuthServer({
|
|
520
566
|
action: "login",
|
|
521
567
|
doForceReloadOnBfCache: true,
|
|
522
|
-
redirectUrl:
|
|
568
|
+
redirectUrl: (() => {
|
|
569
|
+
if (evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
570
|
+
return window.location.href;
|
|
571
|
+
}
|
|
572
|
+
return getRootRelativeOriginalLocationHref();
|
|
573
|
+
})(),
|
|
523
574
|
// NOTE: Wether or not it's the preferred behavior, pushing to history
|
|
524
575
|
// only works on user interaction so it have to be false
|
|
525
576
|
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack: false,
|
|
@@ -534,15 +585,10 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
534
585
|
}
|
|
535
586
|
return "ensure no interaction";
|
|
536
587
|
})(),
|
|
537
|
-
|
|
538
|
-
|
|
588
|
+
preRedirectHook: () => {
|
|
589
|
+
persistAuthState({ configId, state: undefined });
|
|
539
590
|
}
|
|
540
591
|
});
|
|
541
|
-
await dCantFetchWellKnownEndpointOrNever.pr;
|
|
542
|
-
return (await import("./diagnostic")).createFailedToFetchTokenEndpointInitializationError({
|
|
543
|
-
clientId,
|
|
544
|
-
issuerUri
|
|
545
|
-
});
|
|
546
592
|
}
|
|
547
593
|
if (authResponse_error !== undefined) {
|
|
548
594
|
log?.([
|
|
@@ -629,10 +675,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
629
675
|
interaction: getPersistedAuthState({ configId }) === "explicitly logged out"
|
|
630
676
|
? "ensure interaction"
|
|
631
677
|
: "directly redirect if active session show login otherwise",
|
|
632
|
-
|
|
633
|
-
log?.("Login called but the auth server seems to be down..");
|
|
634
|
-
alert("Authentication unavailable please try again later.");
|
|
635
|
-
}
|
|
678
|
+
preRedirectHook: undefined
|
|
636
679
|
});
|
|
637
680
|
},
|
|
638
681
|
initializationError: undefined
|
|
@@ -689,6 +732,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
689
732
|
state: {
|
|
690
733
|
stateDescription: "logged in",
|
|
691
734
|
refreshTokenExpirationTime: currentTokens.refreshTokenExpirationTime,
|
|
735
|
+
serverDateNow: currentTokens.getServerDateNow(),
|
|
692
736
|
idleSessionLifetimeInSeconds
|
|
693
737
|
}
|
|
694
738
|
});
|
|
@@ -806,9 +850,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
806
850
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
807
851
|
prUnlock: new Promise(() => { })
|
|
808
852
|
});
|
|
809
|
-
globalContext.evtRequestToPersistTokens.post({
|
|
810
|
-
configIdOfInstancePostingTheRequest: configId
|
|
811
|
-
});
|
|
812
853
|
await loginOrGoToAuthServer({
|
|
813
854
|
action: "login",
|
|
814
855
|
redirectUrl: window.location.href,
|
|
@@ -817,13 +858,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
817
858
|
transformUrlBeforeRedirect_local: undefined,
|
|
818
859
|
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack: false,
|
|
819
860
|
interaction: "directly redirect if active session show login otherwise",
|
|
820
|
-
|
|
821
|
-
log?.([
|
|
822
|
-
"The auth server seems to be down while we needed to refresh the token",
|
|
823
|
-
"with a full page redirect. Reloading the page"
|
|
824
|
-
].join(" "));
|
|
825
|
-
window.location.reload();
|
|
826
|
-
}
|
|
861
|
+
preRedirectHook: undefined
|
|
827
862
|
});
|
|
828
863
|
assert(false, "136134");
|
|
829
864
|
};
|
|
@@ -849,9 +884,9 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
849
884
|
autoLogin,
|
|
850
885
|
log
|
|
851
886
|
});
|
|
852
|
-
if (result_loginSilent.outcome === "
|
|
887
|
+
if (result_loginSilent.outcome === "timeout") {
|
|
853
888
|
log?.([
|
|
854
|
-
`Silent refresh of the token failed
|
|
889
|
+
`Silent refresh of the token failed the iframe didn't post a response (timeout).`,
|
|
855
890
|
`This isn't recoverable, reloading the page.`
|
|
856
891
|
].join(" "));
|
|
857
892
|
window.location.reload();
|
|
@@ -915,6 +950,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
915
950
|
state: {
|
|
916
951
|
stateDescription: "logged in",
|
|
917
952
|
refreshTokenExpirationTime: currentTokens.refreshTokenExpirationTime,
|
|
953
|
+
serverDateNow: currentTokens.getServerDateNow(),
|
|
918
954
|
idleSessionLifetimeInSeconds
|
|
919
955
|
}
|
|
920
956
|
});
|
|
@@ -989,11 +1025,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
989
1025
|
action: "go to auth server",
|
|
990
1026
|
redirectUrl: redirectUrl ?? window.location.href,
|
|
991
1027
|
extraQueryParams_local: extraQueryParams,
|
|
992
|
-
transformUrlBeforeRedirect_local: transformUrlBeforeRedirect
|
|
993
|
-
onCantFetchWellKnownEndpointError: () => {
|
|
994
|
-
log?.("goToAuthServer called but the auth server seems to be down..");
|
|
995
|
-
alert("Authentication unavailable please try again later.");
|
|
996
|
-
}
|
|
1028
|
+
transformUrlBeforeRedirect_local: transformUrlBeforeRedirect
|
|
997
1029
|
}),
|
|
998
1030
|
backFromAuthServer: resultOfLoginProcess.backFromAuthServer,
|
|
999
1031
|
isNewBrowserSession: (() => {
|