oidc-spa 8.2.1 → 8.2.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/core/AuthResponse.d.ts +0 -5
- package/core/AuthResponse.js +0 -25
- package/core/AuthResponse.js.map +1 -1
- package/core/createOidc.d.ts +49 -16
- package/core/createOidc.js +97 -122
- package/core/createOidc.js.map +1 -1
- package/core/desiredPostLoginRedirectUrl.d.ts +4 -0
- package/core/desiredPostLoginRedirectUrl.js +12 -0
- package/core/desiredPostLoginRedirectUrl.js.map +1 -0
- package/core/diagnostic.d.ts +1 -1
- package/core/diagnostic.js +3 -3
- 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 -0
- package/core/loginOrGoToAuthServer.js +3 -0
- package/core/loginOrGoToAuthServer.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/angular.d.ts +27 -4
- package/esm/angular.js +28 -6
- package/esm/angular.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/createOidc.d.ts +49 -16
- package/esm/core/createOidc.js +98 -123
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/desiredPostLoginRedirectUrl.d.ts +4 -0
- package/esm/core/desiredPostLoginRedirectUrl.js +8 -0
- package/esm/core/desiredPostLoginRedirectUrl.js.map +1 -0
- package/esm/core/diagnostic.d.ts +1 -1
- package/esm/core/diagnostic.js +3 -3
- 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 -0
- package/esm/core/loginOrGoToAuthServer.js +3 -0
- package/esm/core/loginOrGoToAuthServer.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/keycloak-js/Keycloak.d.ts +40 -0
- package/esm/keycloak/keycloak-js/Keycloak.js +2 -1
- package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -1
- package/esm/react/react.js +24 -2
- package/esm/react/react.js.map +1 -1
- package/esm/react-spa/createOidcSpaApi.js +26 -4
- package/esm/react-spa/createOidcSpaApi.js.map +1 -1
- package/esm/react-spa/types.d.ts +26 -3
- package/esm/tanstack-start/react/createOidcSpaApi.js +25 -3
- package/esm/tanstack-start/react/createOidcSpaApi.js.map +1 -1
- package/esm/tanstack-start/react/types.d.ts +26 -3
- package/esm/tools/{EphemeralSessionStorage.d.ts → lazySessionStorage.d.ts} +4 -4
- package/esm/tools/lazySessionStorage.js +83 -0
- package/esm/tools/lazySessionStorage.js.map +1 -0
- package/keycloak/keycloak-js/Keycloak.d.ts +40 -0
- package/keycloak/keycloak-js/Keycloak.js +2 -1
- package/keycloak/keycloak-js/Keycloak.js.map +1 -1
- package/package.json +5 -1
- package/react/react.js +24 -2
- package/react/react.js.map +1 -1
- package/react-spa/createOidcSpaApi.js +26 -4
- package/react-spa/createOidcSpaApi.js.map +1 -1
- package/react-spa/types.d.ts +26 -3
- package/src/angular.ts +72 -18
- package/src/core/AuthResponse.ts +0 -36
- package/src/core/createOidc.ts +160 -173
- package/src/core/desiredPostLoginRedirectUrl.ts +9 -0
- package/src/core/diagnostic.ts +4 -4
- package/src/core/instancesThatCantUseIframes.ts +24 -0
- package/src/core/loginOrGoToAuthServer.ts +5 -0
- package/src/core/persistedAuthState.ts +27 -5
- package/src/keycloak/keycloak-js/Keycloak.ts +43 -1
- package/src/react/react.tsx +32 -3
- package/src/react-spa/createOidcSpaApi.tsx +34 -5
- package/src/react-spa/types.tsx +26 -3
- package/src/tanstack-start/react/createOidcSpaApi.tsx +33 -4
- package/src/tanstack-start/react/types.tsx +26 -3
- package/src/tools/lazySessionStorage.ts +123 -0
- package/src/vite-plugin/manageOptimizedDeps.ts +4 -1
- package/tools/{EphemeralSessionStorage.d.ts → lazySessionStorage.d.ts} +4 -4
- package/tools/lazySessionStorage.js +86 -0
- package/tools/lazySessionStorage.js.map +1 -0
- package/vite-plugin/manageOptimizedDeps.js +3 -1
- 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/AuthResponse.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { addOrUpdateSearchParam } from "../tools/urlSearchParams";
|
|
2
|
-
import { createEphemeralSessionStorage } from "../tools/EphemeralSessionStorage";
|
|
3
2
|
export function authResponseToUrl(authResponse) {
|
|
4
3
|
let authResponseUrl = "https://dummy.com";
|
|
5
4
|
for (const [name, value] of Object.entries(authResponse)) {
|
|
@@ -16,26 +15,4 @@ export function authResponseToUrl(authResponse) {
|
|
|
16
15
|
authResponseUrl = `${authResponseUrl}#${authResponseUrl.split("?")[1]}`;
|
|
17
16
|
return authResponseUrl;
|
|
18
17
|
}
|
|
19
|
-
export const { setPersistedRedirectAuthResponses, getPersistedRedirectAuthResponses } = (() => {
|
|
20
|
-
const { getEphemeralSessionStorage } = (() => {
|
|
21
|
-
let cache = undefined;
|
|
22
|
-
const getEphemeralSessionStorage = () => (cache ?? (cache = createEphemeralSessionStorage({
|
|
23
|
-
sessionStorageTtlMs: 30000
|
|
24
|
-
})));
|
|
25
|
-
return { getEphemeralSessionStorage };
|
|
26
|
-
})();
|
|
27
|
-
const KEY = "oidc-spa:persisted-redirect-auth-response";
|
|
28
|
-
function setPersistedRedirectAuthResponses(params) {
|
|
29
|
-
const { authResponses } = params;
|
|
30
|
-
const storage = getEphemeralSessionStorage();
|
|
31
|
-
storage.persistCurrentStateAndSubsequentChanges();
|
|
32
|
-
storage.setItem(KEY, JSON.stringify(authResponses));
|
|
33
|
-
}
|
|
34
|
-
function getPersistedRedirectAuthResponses() {
|
|
35
|
-
const value = getEphemeralSessionStorage().getItem(KEY);
|
|
36
|
-
const authResponses = value === null ? [] : JSON.parse(value);
|
|
37
|
-
return { authResponses };
|
|
38
|
-
}
|
|
39
|
-
return { setPersistedRedirectAuthResponses, getPersistedRedirectAuthResponses };
|
|
40
|
-
})();
|
|
41
18
|
//# sourceMappingURL=AuthResponse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthResponse.js","sourceRoot":"","sources":["../../src/core/AuthResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthResponse.js","sourceRoot":"","sources":["../../src/core/AuthResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAOlE,MAAM,UAAU,iBAAiB,CAAC,YAA0B;IACxD,IAAI,eAAe,GAAG,mBAAmB,CAAC;IAE1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,SAAS;QACb,CAAC;QACD,eAAe,GAAG,sBAAsB,CAAC;YACrC,GAAG,EAAE,eAAe;YACpB,IAAI;YACJ,KAAK;YACL,YAAY,EAAE,UAAU;SAC3B,CAAC,CAAC;IACP,CAAC;IAED,eAAe,GAAG,GAAG,eAAe,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAExE,OAAO,eAAe,CAAC;AAC3B,CAAC"}
|
package/esm/core/createOidc.d.ts
CHANGED
|
@@ -49,19 +49,6 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
|
|
|
49
49
|
* extraTokenParams: { selectedCustomer: "xxx" }
|
|
50
50
|
*/
|
|
51
51
|
extraTokenParams?: Record<string, string | undefined> | (() => Record<string, string | undefined>);
|
|
52
|
-
/**
|
|
53
|
-
* Usage discouraged, it's here because we don't want to assume too much on your
|
|
54
|
-
* usecase but I can't think of a scenario where you would want anything
|
|
55
|
-
* other than the current page.
|
|
56
|
-
*
|
|
57
|
-
* Where to redirect after successful login.
|
|
58
|
-
* Default: window.location.href (here)
|
|
59
|
-
*
|
|
60
|
-
* It does not need to include the origin, eg: "/dashboard"
|
|
61
|
-
*
|
|
62
|
-
* This parameter can also be passed to login() directly as `redirectUrl`.
|
|
63
|
-
*/
|
|
64
|
-
postLoginRedirectUrl?: string;
|
|
65
52
|
decodedIdTokenSchema?: {
|
|
66
53
|
parse: (decodedIdToken_original: Oidc.Tokens.DecodedIdToken_OidcCoreSpec) => DecodedIdToken;
|
|
67
54
|
};
|
|
@@ -87,9 +74,42 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
|
|
|
87
74
|
autoLogoutParams?: Parameters<Oidc.LoggedIn<any>["logout"]>[0];
|
|
88
75
|
autoLogin?: AutoLogin;
|
|
89
76
|
/**
|
|
77
|
+
* Determines how session restoration is handled.
|
|
78
|
+
* Session restoration allows users to stay logged in between visits
|
|
79
|
+
* without needing to explicitly sign in each time.
|
|
80
|
+
*
|
|
81
|
+
* Options:
|
|
82
|
+
*
|
|
83
|
+
* - **"auto" (default)**:
|
|
84
|
+
* Automatically selects the best method.
|
|
85
|
+
* If the app’s domain shares a common parent domain with the authorization endpoint,
|
|
86
|
+
* an iframe is used for silent session restoration.
|
|
87
|
+
* Otherwise, a full-page redirect is used.
|
|
88
|
+
*
|
|
89
|
+
* - **"full page redirect"**:
|
|
90
|
+
* Forces full-page reloads for session restoration.
|
|
91
|
+
* Use this if your application is served with a restrictive CSP
|
|
92
|
+
* (e.g., `Content-Security-Policy: frame-ancestors "none"`)
|
|
93
|
+
* or `X-Frame-Options: DENY`, and you cannot modify those headers.
|
|
94
|
+
* This mode provides a slightly less seamless UX and will lead oidc-spa to
|
|
95
|
+
* store tokens in `localStorage` if multiple OIDC clients are used
|
|
96
|
+
* (e.g., your app communicates with several APIs).
|
|
97
|
+
*
|
|
98
|
+
* - **"iframe"**:
|
|
99
|
+
* Forces iframe-based session restoration.
|
|
100
|
+
* In development, if you go in your browser setting and allow your auth server’s domain
|
|
101
|
+
* to set third-party cookies this value will let you test your app
|
|
102
|
+
* with the local dev server as it will behave in production.
|
|
103
|
+
*
|
|
104
|
+
* See: https://docs.oidc-spa.dev/v/v8/resources/third-party-cookies-and-session-restoration
|
|
105
|
+
*/
|
|
106
|
+
sessionRestorationMethod?: "iframe" | "full page redirect" | "auto";
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated Use `sessionRestorationMethod: "full page redirect"` instead.
|
|
109
|
+
*
|
|
90
110
|
* Default: false
|
|
91
111
|
*
|
|
92
|
-
* See: https://docs.oidc-spa.dev/v/v8/resources/
|
|
112
|
+
* See: https://docs.oidc-spa.dev/v/v8/resources/third-party-cookies-and-session-restoration
|
|
93
113
|
*/
|
|
94
114
|
noIframe?: boolean;
|
|
95
115
|
debugLogs?: boolean;
|
|
@@ -136,13 +156,26 @@ export type ParamsOfCreateOidc<DecodedIdToken extends Record<string, unknown> =
|
|
|
136
156
|
BASE_URL?: string;
|
|
137
157
|
/** @deprecated: Use BASE_URL (same thing, just renamed). */
|
|
138
158
|
homeUrl?: string;
|
|
159
|
+
/**
|
|
160
|
+
* This parameter is irrelevant in most usecases.
|
|
161
|
+
* It tells where to redirect after a successful login or autoLogin.
|
|
162
|
+
*
|
|
163
|
+
* If you are not in autoLogin mode there is absolutely no reason to use
|
|
164
|
+
* this parameter since you can pass `login({ redirectUrl: "..." })`.
|
|
165
|
+
*
|
|
166
|
+
* It can only be useful in some edge case with `autoLogin: true`
|
|
167
|
+
* When you want to precisely redirect somewhere after login.
|
|
168
|
+
*
|
|
169
|
+
* This can make sense if you have multiple clients to talk with different
|
|
170
|
+
* API and no iframe capabilities.
|
|
171
|
+
*/
|
|
172
|
+
postLoginRedirectUrl?: string;
|
|
139
173
|
};
|
|
140
174
|
/** @see: https://docs.oidc-spa.dev/v/v8/usage */
|
|
141
175
|
export declare function createOidc<DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_OidcCoreSpec, AutoLogin extends boolean = false>(params: ParamsOfCreateOidc<DecodedIdToken, AutoLogin>): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>>;
|
|
142
|
-
export declare function createOidc_nonMemoized<DecodedIdToken extends Record<string, unknown>, AutoLogin extends boolean>(params: Omit<ParamsOfCreateOidc<DecodedIdToken, AutoLogin>, "issuerUri" | "clientId" | "
|
|
176
|
+
export declare function createOidc_nonMemoized<DecodedIdToken extends Record<string, unknown>, AutoLogin extends boolean>(params: Omit<ParamsOfCreateOidc<DecodedIdToken, AutoLogin>, "issuerUri" | "clientId" | "debugLogs">, preProcessedParams: {
|
|
143
177
|
issuerUri: string;
|
|
144
178
|
clientId: string;
|
|
145
|
-
scopes: string[];
|
|
146
179
|
configId: string;
|
|
147
180
|
log: typeof console.log | undefined;
|
|
148
181
|
}): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>>;
|
package/esm/core/createOidc.js
CHANGED
|
@@ -15,13 +15,13 @@ import { notifyOtherTabsOfLogin, getPrOtherTabLogin } from "./loginPropagationTo
|
|
|
15
15
|
import { getConfigId } from "./configId";
|
|
16
16
|
import { oidcClientTsUserToTokens } from "./oidcClientTsUserToTokens";
|
|
17
17
|
import { loginSilent } from "./loginSilent";
|
|
18
|
-
import { authResponseToUrl
|
|
18
|
+
import { authResponseToUrl } from "./AuthResponse";
|
|
19
19
|
import { getRootRelativeOriginalLocationHref, getRedirectAuthResponse } from "./earlyInit";
|
|
20
20
|
import { getPersistedAuthState, persistAuthState } from "./persistedAuthState";
|
|
21
21
|
import { createEvt } from "../tools/Evt";
|
|
22
22
|
import { getHaveSharedParentDomain } from "../tools/haveSharedParentDomain";
|
|
23
23
|
import { createLoginOrGoToAuthServer, getPrSafelyRestoredFromBfCacheAfterLoginBackNavigationOrInitializationError } from "./loginOrGoToAuthServer";
|
|
24
|
-
import {
|
|
24
|
+
import { createLazySessionStorage } from "../tools/lazySessionStorage";
|
|
25
25
|
import { startLoginOrRefreshProcess, waitForAllOtherOngoingLoginOrRefreshProcessesToComplete } from "./ongoingLoginOrRefreshProcesses";
|
|
26
26
|
import { createGetIsNewBrowserSession } from "./isNewBrowserSession";
|
|
27
27
|
import { getIsOnline } from "../tools/getIsOnline";
|
|
@@ -31,23 +31,14 @@ import { prShouldLoadApp } from "./prShouldLoadApp";
|
|
|
31
31
|
import { getBASE_URL } from "./BASE_URL";
|
|
32
32
|
import { getIsLikelyDevServer } from "../tools/isLikelyDevServer";
|
|
33
33
|
import { createObjectThatThrowsIfAccessed } from "../tools/createObjectThatThrowsIfAccessed";
|
|
34
|
+
import { evtIsThereMoreThanOneInstanceThatCantUserIframes, notifyNewInstanceThatCantUseIframes } from "./instancesThatCantUseIframes";
|
|
35
|
+
import { getDesiredPostLoginRedirectUrl } from "./desiredPostLoginRedirectUrl";
|
|
34
36
|
// NOTE: Replaced at build time
|
|
35
|
-
const VERSION = "8.2.
|
|
37
|
+
const VERSION = "8.2.3";
|
|
36
38
|
const globalContext = {
|
|
37
39
|
prOidcByConfigId: new Map(),
|
|
38
|
-
hasLogoutBeenCalled: id(false)
|
|
39
|
-
evtRequestToPersistTokens: createEvt()
|
|
40
|
+
hasLogoutBeenCalled: id(false)
|
|
40
41
|
};
|
|
41
|
-
globalContext.evtRequestToPersistTokens.subscribe(() => {
|
|
42
|
-
const { authResponse } = getRedirectAuthResponse();
|
|
43
|
-
if (authResponse === undefined) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
const { authResponses } = getPersistedRedirectAuthResponses();
|
|
47
|
-
setPersistedRedirectAuthResponses({
|
|
48
|
-
authResponses: [...authResponses, authResponse]
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
42
|
/** @see: https://docs.oidc-spa.dev/v/v8/usage */
|
|
52
43
|
export async function createOidc(params) {
|
|
53
44
|
for (const name of ["issuerUri", "clientId"]) {
|
|
@@ -56,7 +47,7 @@ export async function createOidc(params) {
|
|
|
56
47
|
throw new Error(`The parameter "${name}" is required, you provided: ${value}. (Forgot a .env variable?)`);
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
|
-
const { issuerUri: issuerUri_params, clientId,
|
|
50
|
+
const { issuerUri: issuerUri_params, clientId, debugLogs, ...rest } = params;
|
|
60
51
|
const issuerUri = toFullyQualifiedUrl({
|
|
61
52
|
urlish: issuerUri_params,
|
|
62
53
|
doAssertNoQueryParams: true,
|
|
@@ -98,7 +89,6 @@ export async function createOidc(params) {
|
|
|
98
89
|
const oidc = await createOidc_nonMemoized(rest, {
|
|
99
90
|
issuerUri,
|
|
100
91
|
clientId,
|
|
101
|
-
scopes,
|
|
102
92
|
configId,
|
|
103
93
|
log
|
|
104
94
|
});
|
|
@@ -121,9 +111,9 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
121
111
|
return new Promise(() => { });
|
|
122
112
|
}
|
|
123
113
|
}
|
|
124
|
-
const { transformUrlBeforeRedirect, extraQueryParams: extraQueryParamsOrGetter, extraTokenParams: extraTokenParamsOrGetter, decodedIdTokenSchema, idleSessionLifetimeInSeconds, autoLogoutParams = { redirectTo: "current page" }, autoLogin = false, postLoginRedirectUrl: postLoginRedirectUrl_default, __unsafe_clientSecret, __unsafe_useIdTokenAsAccessToken = false, __metadata,
|
|
114
|
+
const { transformUrlBeforeRedirect, extraQueryParams: extraQueryParamsOrGetter, extraTokenParams: extraTokenParamsOrGetter, decodedIdTokenSchema, idleSessionLifetimeInSeconds, autoLogoutParams = { redirectTo: "current page" }, autoLogin = false, postLoginRedirectUrl: postLoginRedirectUrl_default, __unsafe_clientSecret, __unsafe_useIdTokenAsAccessToken = false, __metadata, scopes = ["openid", "profile"], sessionRestorationMethod = params.autoLogin === true ? "full page redirect" : "auto" } = params;
|
|
125
115
|
const BASE_URL_params = params.BASE_URL ?? params.homeUrl;
|
|
126
|
-
const { issuerUri, clientId,
|
|
116
|
+
const { issuerUri, clientId, configId, log } = preProcessedParams;
|
|
127
117
|
const getExtraQueryParams = (() => {
|
|
128
118
|
if (extraQueryParamsOrGetter === undefined) {
|
|
129
119
|
return undefined;
|
|
@@ -168,14 +158,20 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
168
158
|
issuerUri,
|
|
169
159
|
clientId,
|
|
170
160
|
scopes,
|
|
171
|
-
|
|
172
|
-
homeUrlAndRedirectUri
|
|
161
|
+
oidcRedirectUri: homeUrlAndRedirectUri
|
|
173
162
|
}, null, 2)}`);
|
|
174
163
|
const stateUrlParamValue_instance = generateStateUrlParamValue();
|
|
175
164
|
const oidcMetadata = __metadata ?? (await fetchOidcMetadata({ issuerUri }));
|
|
176
165
|
const canUseIframe = (() => {
|
|
177
|
-
|
|
178
|
-
|
|
166
|
+
switch (sessionRestorationMethod) {
|
|
167
|
+
case "auto":
|
|
168
|
+
break;
|
|
169
|
+
case "full page redirect":
|
|
170
|
+
return false;
|
|
171
|
+
case "iframe":
|
|
172
|
+
return true;
|
|
173
|
+
default:
|
|
174
|
+
assert;
|
|
179
175
|
}
|
|
180
176
|
third_party_cookies: {
|
|
181
177
|
if (oidcMetadata === undefined) {
|
|
@@ -230,7 +226,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
230
226
|
if (isLikelyDevServer) {
|
|
231
227
|
log?.([
|
|
232
228
|
"Detected localhost environment.",
|
|
233
|
-
"\nWhen reloading while logged in, you
|
|
229
|
+
"\nWhen reloading while logged in, you will briefly see",
|
|
234
230
|
"some URL params appear in the address bar.",
|
|
235
231
|
"\nThis happens because session restore via iframe is disabled,",
|
|
236
232
|
"the browser treats your auth server as a third party.",
|
|
@@ -257,7 +253,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
257
253
|
];
|
|
258
254
|
})(),
|
|
259
255
|
"\n\nMore info:",
|
|
260
|
-
"https://docs.oidc-spa.dev/v/v8/resources/
|
|
256
|
+
"https://docs.oidc-spa.dev/v/v8/resources/third-party-cookies-and-session-restoration"
|
|
261
257
|
].join(" "));
|
|
262
258
|
}
|
|
263
259
|
else {
|
|
@@ -284,14 +280,20 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
284
280
|
];
|
|
285
281
|
})(),
|
|
286
282
|
"\nMore info:",
|
|
287
|
-
"https://docs.oidc-spa.dev/v/v8/resources/
|
|
283
|
+
"https://docs.oidc-spa.dev/v/v8/resources/third-party-cookies-and-session-restoration"
|
|
288
284
|
].join(" "));
|
|
289
285
|
}
|
|
290
286
|
return false;
|
|
291
287
|
}
|
|
292
288
|
return true;
|
|
293
289
|
})();
|
|
294
|
-
|
|
290
|
+
notifyNewInstanceThatCantUseIframes();
|
|
291
|
+
if (evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
292
|
+
log?.([
|
|
293
|
+
"More than one oidc instance can't use iframe",
|
|
294
|
+
"falling back to persisting tokens in session storage"
|
|
295
|
+
].join(" "));
|
|
296
|
+
}
|
|
295
297
|
const oidcClientTsUserManager = oidcMetadata === undefined
|
|
296
298
|
? createObjectThatThrowsIfAccessed({
|
|
297
299
|
debugMessage: "oidc-spa: Wrong assertion 43943"
|
|
@@ -310,20 +312,17 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
310
312
|
userStore: new WebStorageStateStore({
|
|
311
313
|
store: (() => {
|
|
312
314
|
if (canUseIframe) {
|
|
313
|
-
isUserStoreInMemoryOnly = true;
|
|
314
315
|
return new InMemoryWebStorage();
|
|
315
316
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
sessionStorageTtlMs: 3 * 60000
|
|
319
|
-
});
|
|
320
|
-
const { evtRequestToPersistTokens } = globalContext;
|
|
321
|
-
evtRequestToPersistTokens.subscribe(({ configIdOfInstancePostingTheRequest }) => {
|
|
322
|
-
if (configIdOfInstancePostingTheRequest === configId) {
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
317
|
+
const storage = createLazySessionStorage({ storageId: configId });
|
|
318
|
+
if (evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
325
319
|
storage.persistCurrentStateAndSubsequentChanges();
|
|
326
|
-
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
evtIsThereMoreThanOneInstanceThatCantUserIframes.subscribe(() => {
|
|
323
|
+
storage.persistCurrentStateAndSubsequentChanges();
|
|
324
|
+
});
|
|
325
|
+
}
|
|
327
326
|
return storage;
|
|
328
327
|
})()
|
|
329
328
|
}),
|
|
@@ -356,54 +355,52 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
356
355
|
issuerUri
|
|
357
356
|
});
|
|
358
357
|
}
|
|
358
|
+
restore_from_session_storage: {
|
|
359
|
+
if (canUseIframe) {
|
|
360
|
+
break restore_from_session_storage;
|
|
361
|
+
}
|
|
362
|
+
if (!evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
363
|
+
break restore_from_session_storage;
|
|
364
|
+
}
|
|
365
|
+
let oidcClientTsUser;
|
|
366
|
+
try {
|
|
367
|
+
oidcClientTsUser = await oidcClientTsUserManager.getUser();
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
// NOTE: Not sure if it can throw, but let's be safe.
|
|
371
|
+
oidcClientTsUser = null;
|
|
372
|
+
try {
|
|
373
|
+
await oidcClientTsUserManager.removeUser();
|
|
374
|
+
}
|
|
375
|
+
catch { }
|
|
376
|
+
}
|
|
377
|
+
if (oidcClientTsUser === null) {
|
|
378
|
+
break restore_from_session_storage;
|
|
379
|
+
}
|
|
380
|
+
log?.("Session was restored from session storage");
|
|
381
|
+
return {
|
|
382
|
+
oidcClientTsUser,
|
|
383
|
+
backFromAuthServer: undefined
|
|
384
|
+
};
|
|
385
|
+
}
|
|
359
386
|
handle_redirect_auth_response: {
|
|
360
387
|
let stateDataAndAuthResponse = undefined;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (stateData === undefined) {
|
|
369
|
-
clearAuthResponse();
|
|
370
|
-
break from_memory;
|
|
371
|
-
}
|
|
372
|
-
if (stateData.configId !== configId) {
|
|
373
|
-
break from_memory;
|
|
374
|
-
}
|
|
375
|
-
assert(stateData.context === "redirect", "3229492");
|
|
388
|
+
{
|
|
389
|
+
const { authResponse, clearAuthResponse } = getRedirectAuthResponse();
|
|
390
|
+
if (authResponse === undefined) {
|
|
391
|
+
break handle_redirect_auth_response;
|
|
392
|
+
}
|
|
393
|
+
const stateData = getStateData({ stateUrlParamValue: authResponse.state });
|
|
394
|
+
if (stateData === undefined) {
|
|
376
395
|
clearAuthResponse();
|
|
377
|
-
|
|
378
|
-
break get_stateData_and_authResponse;
|
|
396
|
+
break handle_redirect_auth_response;
|
|
379
397
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
// the authResponse in memory had the chance to be processed.
|
|
383
|
-
// This can only happen if:
|
|
384
|
-
// 1) There are multiple oidc instances in the App.
|
|
385
|
-
// 2) They are instantiated in a non deterministic order.
|
|
386
|
-
// 3) We can't use iframe
|
|
387
|
-
// We practically never persist the auth response and do it only in session
|
|
388
|
-
// an ephemeral session storage, when we know it's gonna be required.
|
|
389
|
-
{
|
|
390
|
-
const { authResponses } = getPersistedRedirectAuthResponses();
|
|
391
|
-
for (const authResponse of authResponses) {
|
|
392
|
-
const stateData = getStateData({ stateUrlParamValue: authResponse.state });
|
|
393
|
-
if (stateData === undefined) {
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
if (stateData.configId !== configId) {
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
assert(stateData.context === "redirect", "35935591");
|
|
400
|
-
setPersistedRedirectAuthResponses({
|
|
401
|
-
authResponses: authResponses.filter(authResponse_i => authResponse_i !== authResponse)
|
|
402
|
-
});
|
|
403
|
-
stateDataAndAuthResponse = { stateData, authResponse };
|
|
404
|
-
break get_stateData_and_authResponse;
|
|
405
|
-
}
|
|
398
|
+
if (stateData.configId !== configId) {
|
|
399
|
+
break handle_redirect_auth_response;
|
|
406
400
|
}
|
|
401
|
+
assert(stateData.context === "redirect", "3229492");
|
|
402
|
+
clearAuthResponse();
|
|
403
|
+
stateDataAndAuthResponse = { stateData, authResponse };
|
|
407
404
|
}
|
|
408
405
|
if (stateDataAndAuthResponse === undefined) {
|
|
409
406
|
break handle_redirect_auth_response;
|
|
@@ -482,34 +479,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
482
479
|
assert(false);
|
|
483
480
|
}
|
|
484
481
|
}
|
|
485
|
-
// NOTE: We almost never persist tokens, we have to only to support edge case
|
|
486
|
-
// of multiple oidc instance in a single App with no iframe support.
|
|
487
|
-
restore_from_session_storage: {
|
|
488
|
-
assert(isUserStoreInMemoryOnly !== undefined, "3392204");
|
|
489
|
-
if (isUserStoreInMemoryOnly) {
|
|
490
|
-
break restore_from_session_storage;
|
|
491
|
-
}
|
|
492
|
-
let oidcClientTsUser;
|
|
493
|
-
try {
|
|
494
|
-
oidcClientTsUser = await oidcClientTsUserManager.getUser();
|
|
495
|
-
}
|
|
496
|
-
catch {
|
|
497
|
-
// NOTE: Not sure if it can throw, but let's be safe.
|
|
498
|
-
oidcClientTsUser = null;
|
|
499
|
-
try {
|
|
500
|
-
await oidcClientTsUserManager.removeUser();
|
|
501
|
-
}
|
|
502
|
-
catch { }
|
|
503
|
-
}
|
|
504
|
-
if (oidcClientTsUser === null) {
|
|
505
|
-
break restore_from_session_storage;
|
|
506
|
-
}
|
|
507
|
-
log?.("Restored the auth from ephemeral session storage");
|
|
508
|
-
return {
|
|
509
|
-
oidcClientTsUser,
|
|
510
|
-
backFromAuthServer: undefined
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
482
|
silent_login_if_possible_and_auto_login: {
|
|
514
483
|
const persistedAuthState = getPersistedAuthState({ configId });
|
|
515
484
|
if (persistedAuthState === "explicitly logged out" && !autoLogin) {
|
|
@@ -562,7 +531,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
562
531
|
redirectUri: homeUrlAndRedirectUri,
|
|
563
532
|
clientId,
|
|
564
533
|
issuerUri,
|
|
565
|
-
|
|
534
|
+
canUseIframe
|
|
566
535
|
});
|
|
567
536
|
}
|
|
568
537
|
assert();
|
|
@@ -594,7 +563,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
594
563
|
authResponse_error === "consent_required" ||
|
|
595
564
|
authResponse_error === "account_selection_required"))) {
|
|
596
565
|
log?.("Performing auto login with redirect");
|
|
597
|
-
persistAuthState({ configId, state: undefined });
|
|
598
566
|
completeLoginOrRefreshProcess();
|
|
599
567
|
if (autoLogin && persistedAuthState !== "logged in") {
|
|
600
568
|
evtInitializationOutcomeUserNotLoggedIn.post();
|
|
@@ -602,15 +570,18 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
602
570
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
603
571
|
prUnlock: getPrSafelyRestoredFromBfCacheAfterLoginBackNavigationOrInitializationError()
|
|
604
572
|
});
|
|
605
|
-
if (persistedAuthState === "logged in") {
|
|
606
|
-
globalContext.evtRequestToPersistTokens.post({
|
|
607
|
-
configIdOfInstancePostingTheRequest: configId
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
573
|
await loginOrGoToAuthServer({
|
|
611
574
|
action: "login",
|
|
612
575
|
doForceReloadOnBfCache: true,
|
|
613
|
-
redirectUrl:
|
|
576
|
+
redirectUrl: (() => {
|
|
577
|
+
if (postLoginRedirectUrl_default) {
|
|
578
|
+
return postLoginRedirectUrl_default;
|
|
579
|
+
}
|
|
580
|
+
if (!evtIsThereMoreThanOneInstanceThatCantUserIframes.current) {
|
|
581
|
+
return getRootRelativeOriginalLocationHref();
|
|
582
|
+
}
|
|
583
|
+
return getDesiredPostLoginRedirectUrl() ?? window.location.href;
|
|
584
|
+
})(),
|
|
614
585
|
// NOTE: Wether or not it's the preferred behavior, pushing to history
|
|
615
586
|
// only works on user interaction so it have to be false
|
|
616
587
|
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack: false,
|
|
@@ -624,7 +595,10 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
624
595
|
return "directly redirect if active session show login otherwise";
|
|
625
596
|
}
|
|
626
597
|
return "ensure no interaction";
|
|
627
|
-
})()
|
|
598
|
+
})(),
|
|
599
|
+
preRedirectHook: () => {
|
|
600
|
+
persistAuthState({ configId, state: undefined });
|
|
601
|
+
}
|
|
628
602
|
});
|
|
629
603
|
}
|
|
630
604
|
if (authResponse_error !== undefined) {
|
|
@@ -711,7 +685,8 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
711
685
|
transformUrlBeforeRedirect_local: transformUrlBeforeRedirect,
|
|
712
686
|
interaction: getPersistedAuthState({ configId }) === "explicitly logged out"
|
|
713
687
|
? "ensure interaction"
|
|
714
|
-
: "directly redirect if active session show login otherwise"
|
|
688
|
+
: "directly redirect if active session show login otherwise",
|
|
689
|
+
preRedirectHook: undefined
|
|
715
690
|
});
|
|
716
691
|
},
|
|
717
692
|
initializationError: undefined
|
|
@@ -768,6 +743,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
768
743
|
state: {
|
|
769
744
|
stateDescription: "logged in",
|
|
770
745
|
refreshTokenExpirationTime: currentTokens.refreshTokenExpirationTime,
|
|
746
|
+
serverDateNow: currentTokens.getServerDateNow(),
|
|
771
747
|
idleSessionLifetimeInSeconds
|
|
772
748
|
}
|
|
773
749
|
});
|
|
@@ -885,9 +861,6 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
885
861
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
886
862
|
prUnlock: new Promise(() => { })
|
|
887
863
|
});
|
|
888
|
-
globalContext.evtRequestToPersistTokens.post({
|
|
889
|
-
configIdOfInstancePostingTheRequest: configId
|
|
890
|
-
});
|
|
891
864
|
await loginOrGoToAuthServer({
|
|
892
865
|
action: "login",
|
|
893
866
|
redirectUrl: window.location.href,
|
|
@@ -895,7 +868,8 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
895
868
|
extraQueryParams_local: undefined,
|
|
896
869
|
transformUrlBeforeRedirect_local: undefined,
|
|
897
870
|
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack: false,
|
|
898
|
-
interaction: "directly redirect if active session show login otherwise"
|
|
871
|
+
interaction: "directly redirect if active session show login otherwise",
|
|
872
|
+
preRedirectHook: undefined
|
|
899
873
|
});
|
|
900
874
|
assert(false, "136134");
|
|
901
875
|
};
|
|
@@ -987,6 +961,7 @@ export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
|
987
961
|
state: {
|
|
988
962
|
stateDescription: "logged in",
|
|
989
963
|
refreshTokenExpirationTime: currentTokens.refreshTokenExpirationTime,
|
|
964
|
+
serverDateNow: currentTokens.getServerDateNow(),
|
|
990
965
|
idleSessionLifetimeInSeconds
|
|
991
966
|
}
|
|
992
967
|
});
|