oidc-spa 7.2.0-rc.1 → 7.2.0-rc.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/backend.js.map +1 -1
- package/core/AuthResponse.js.map +1 -1
- package/core/Oidc.js.map +1 -1
- package/core/OidcInitializationError.d.ts +0 -13
- package/core/OidcInitializationError.js +0 -243
- package/core/OidcInitializationError.js.map +1 -1
- package/core/OidcMetadata.js.map +1 -1
- package/core/StateData.js.map +1 -1
- package/core/configId.js.map +1 -1
- package/core/createOidc.js +38 -5
- package/core/createOidc.js.map +1 -1
- package/core/diagnostic.d.ts +14 -0
- package/core/diagnostic.js +214 -0
- package/core/diagnostic.js.map +1 -0
- package/core/evtIsUserActive.js.map +1 -1
- package/core/handleOidcCallback.js.map +1 -1
- package/core/iframeMessageProtection.js.map +1 -1
- package/core/index.js.map +1 -1
- package/core/initialLocationHref.js.map +1 -1
- package/core/isNewBrowserSession.js.map +1 -1
- package/core/loginOrGoToAuthServer.js.map +1 -1
- package/core/loginPropagationToOtherTabs.js.map +1 -1
- package/core/loginSilent.js.map +1 -1
- package/core/logoutPropagationToOtherTabs.js.map +1 -1
- package/core/oidcClientTsUserToTokens.js.map +1 -1
- package/core/ongoingLoginOrRefreshProcesses.js.map +1 -1
- package/core/persistedAuthState.js.map +1 -1
- package/entrypoint.js.map +1 -1
- package/esm/core/AuthResponse.d.ts +5 -0
- package/{src/core/AuthResponse.ts → esm/core/AuthResponse.js} +2 -10
- package/esm/core/AuthResponse.js.map +1 -0
- package/esm/core/Oidc.d.ts +126 -0
- package/esm/core/Oidc.js +2 -0
- package/esm/core/Oidc.js.map +1 -0
- package/esm/core/OidcInitializationError.d.ts +7 -0
- package/esm/core/OidcInitializationError.js +17 -0
- package/esm/core/OidcInitializationError.js.map +1 -0
- package/{src/core/OidcMetadata.ts → esm/core/OidcMetadata.d.ts} +0 -5
- package/esm/core/OidcMetadata.js +3 -0
- package/esm/core/OidcMetadata.js.map +1 -0
- package/esm/core/StateData.d.ts +42 -0
- package/esm/core/StateData.js +55 -0
- package/esm/core/StateData.js.map +1 -0
- package/esm/core/configId.d.ts +4 -0
- package/esm/core/configId.js +4 -0
- package/esm/core/configId.js.map +1 -0
- package/esm/core/createOidc.d.ts +132 -0
- package/{src/core/createOidc.ts → esm/core/createOidc.js} +269 -806
- package/esm/core/createOidc.js.map +1 -0
- package/esm/core/diagnostic.d.ts +14 -0
- package/{src/core/OidcInitializationError.ts → esm/core/diagnostic.js} +32 -109
- package/esm/core/diagnostic.js.map +1 -0
- package/esm/core/evtIsUserActive.d.ts +5 -0
- package/{src/core/evtIsUserActive.ts → esm/core/evtIsUserActive.js} +14 -46
- package/esm/core/evtIsUserActive.js.map +1 -0
- package/esm/core/handleOidcCallback.d.ts +13 -0
- package/{src/core/handleOidcCallback.ts → esm/core/handleOidcCallback.js} +25 -121
- package/esm/core/handleOidcCallback.js.map +1 -0
- package/esm/core/iframeMessageProtection.d.ts +20 -0
- package/{src/core/iframeMessageProtection.ts → esm/core/iframeMessageProtection.js} +10 -45
- package/esm/core/iframeMessageProtection.js.map +1 -0
- package/esm/core/index.js +4 -0
- package/esm/core/index.js.map +1 -0
- package/esm/core/initialLocationHref.d.ts +1 -0
- package/{src/core/initialLocationHref.ts → esm/core/initialLocationHref.js} +1 -1
- package/esm/core/initialLocationHref.js.map +1 -0
- package/esm/core/isNewBrowserSession.d.ts +9 -0
- package/{src/core/isNewBrowserSession.ts → esm/core/isNewBrowserSession.js} +3 -15
- package/esm/core/isNewBrowserSession.js.map +1 -0
- package/esm/core/loginOrGoToAuthServer.d.ts +40 -0
- package/{src/core/loginOrGoToAuthServer.ts → esm/core/loginOrGoToAuthServer.js} +60 -168
- package/esm/core/loginOrGoToAuthServer.js.map +1 -0
- package/esm/core/loginPropagationToOtherTabs.d.ts +8 -0
- package/{src/core/loginPropagationToOtherTabs.ts → esm/core/loginPropagationToOtherTabs.js} +7 -25
- package/esm/core/loginPropagationToOtherTabs.js.map +1 -0
- package/esm/core/loginSilent.d.ts +28 -0
- package/esm/core/loginSilent.js +125 -0
- package/esm/core/loginSilent.js.map +1 -0
- package/esm/core/logoutPropagationToOtherTabs.d.ts +10 -0
- package/{src/core/logoutPropagationToOtherTabs.ts → esm/core/logoutPropagationToOtherTabs.js} +8 -28
- package/esm/core/logoutPropagationToOtherTabs.js.map +1 -0
- package/esm/core/oidcClientTsUserToTokens.d.ts +11 -0
- package/esm/core/oidcClientTsUserToTokens.js +155 -0
- package/esm/core/oidcClientTsUserToTokens.js.map +1 -0
- package/esm/core/ongoingLoginOrRefreshProcesses.d.ts +6 -0
- package/{src/core/ongoingLoginOrRefreshProcesses.ts → esm/core/ongoingLoginOrRefreshProcesses.js} +6 -24
- package/esm/core/ongoingLoginOrRefreshProcesses.js.map +1 -0
- package/esm/core/persistedAuthState.d.ts +28 -0
- package/esm/core/persistedAuthState.js +64 -0
- package/esm/core/persistedAuthState.js.map +1 -0
- package/esm/entrypoint.d.ts +7 -0
- package/{src/entrypoint.ts → esm/entrypoint.js} +3 -26
- package/esm/entrypoint.js.map +1 -0
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -0
- package/esm/keycloak/index.d.ts +3 -0
- package/esm/keycloak/index.js +3 -0
- package/esm/keycloak/index.js.map +1 -0
- package/esm/keycloak/isKeycloak.d.ts +3 -0
- package/{src/keycloak/isKeycloak.ts → esm/keycloak/isKeycloak.js} +2 -8
- package/esm/keycloak/isKeycloak.js.map +1 -0
- package/esm/keycloak/keycloak-js/Keycloak.d.ts +284 -0
- package/{src/keycloak/keycloak-js/Keycloak.ts → esm/keycloak/keycloak-js/Keycloak.js} +116 -439
- package/esm/keycloak/keycloak-js/Keycloak.js.map +1 -0
- package/esm/keycloak/keycloak-js/index.js +2 -0
- package/esm/keycloak/keycloak-js/index.js.map +1 -0
- package/{src/keycloak/keycloak-js/types.ts → esm/keycloak/keycloak-js/types.d.ts} +3 -84
- package/esm/keycloak/keycloak-js/types.js +2 -0
- package/esm/keycloak/keycloak-js/types.js.map +1 -0
- package/esm/keycloak/keycloakIssuerUriParsed.d.ts +9 -0
- package/{src/keycloak/keycloakIssuerUriParsed.ts → esm/keycloak/keycloakIssuerUriParsed.js} +2 -15
- package/esm/keycloak/keycloakIssuerUriParsed.js.map +1 -0
- package/esm/keycloak/keycloakUtils.d.ts +37 -0
- package/esm/keycloak/keycloakUtils.js +44 -0
- package/esm/keycloak/keycloakUtils.js.map +1 -0
- package/esm/keycloak-js.js +2 -0
- package/esm/keycloak-js.js.map +1 -0
- package/esm/mock/index.js +2 -0
- package/esm/mock/index.js.map +1 -0
- package/esm/mock/oidc.d.ts +19 -0
- package/{src/mock/oidc.ts → esm/mock/oidc.js} +28 -88
- package/esm/mock/oidc.js.map +1 -0
- package/esm/mock/react.d.ts +58 -0
- package/esm/mock/react.js +7 -0
- package/esm/mock/react.js.map +1 -0
- package/esm/react/index.js +2 -0
- package/esm/react/index.js.map +1 -0
- package/esm/react/react.d.ts +102 -0
- package/esm/react/react.js +221 -0
- package/esm/react/react.js.map +1 -0
- package/esm/tools/Deferred.d.ts +14 -0
- package/esm/tools/Deferred.js +23 -0
- package/esm/tools/Deferred.js.map +1 -0
- package/esm/tools/EphemeralSessionStorage.d.ts +12 -0
- package/{src/tools/EphemeralSessionStorage.ts → esm/tools/EphemeralSessionStorage.js} +30 -112
- package/esm/tools/EphemeralSessionStorage.js.map +1 -0
- package/esm/tools/Evt.d.ts +11 -0
- package/{src/tools/Evt.ts → esm/tools/Evt.js} +7 -25
- package/esm/tools/Evt.js.map +1 -0
- package/esm/tools/StatefulEvt.d.ts +12 -0
- package/esm/tools/StatefulEvt.js +21 -0
- package/esm/tools/StatefulEvt.js.map +1 -0
- package/esm/tools/ValueOrAsyncGetter.js +2 -0
- package/esm/tools/ValueOrAsyncGetter.js.map +1 -0
- package/esm/tools/asymmetricEncryption.d.ts +18 -0
- package/esm/tools/asymmetricEncryption.js +85 -0
- package/esm/tools/asymmetricEncryption.js.map +1 -0
- package/esm/tools/base64.d.ts +2 -0
- package/{src/tools/base64.ts → esm/tools/base64.js} +3 -3
- package/esm/tools/base64.js.map +1 -0
- package/esm/tools/createObjectThatThrowsIfAccessed.d.ts +8 -0
- package/{src/tools/createObjectThatThrowsIfAccessed.ts → esm/tools/createObjectThatThrowsIfAccessed.js} +7 -18
- package/esm/tools/createObjectThatThrowsIfAccessed.js.map +1 -0
- package/esm/tools/decodeJwt.d.ts +25 -0
- package/esm/tools/decodeJwt.js +60 -0
- package/esm/tools/decodeJwt.js.map +1 -0
- package/esm/tools/generateUrlSafeRandom.d.ts +3 -0
- package/{src/tools/generateUrlSafeRandom.ts → esm/tools/generateUrlSafeRandom.js} +5 -8
- package/esm/tools/generateUrlSafeRandom.js.map +1 -0
- package/esm/tools/getDownlinkAndRtt.d.ts +4 -0
- package/{src/tools/getDownlinkAndRtt.ts → esm/tools/getDownlinkAndRtt.js} +6 -10
- package/esm/tools/getDownlinkAndRtt.js.map +1 -0
- package/esm/tools/getIsOnline.d.ts +7 -0
- package/{src/tools/getIsOnline.ts → esm/tools/getIsOnline.js} +3 -9
- package/esm/tools/getIsOnline.js.map +1 -0
- package/esm/tools/getIsValidRemoteJson.d.ts +1 -0
- package/esm/tools/getIsValidRemoteJson.js +15 -0
- package/esm/tools/getIsValidRemoteJson.js.map +1 -0
- package/esm/tools/getPrUserInteraction.d.ts +4 -0
- package/{src/tools/getPrUserInteraction.ts → esm/tools/getPrUserInteraction.js} +2 -6
- package/esm/tools/getPrUserInteraction.js.map +1 -0
- package/esm/tools/getUserEnvironmentInfo.d.ts +1 -0
- package/esm/tools/getUserEnvironmentInfo.js +50 -0
- package/esm/tools/getUserEnvironmentInfo.js.map +1 -0
- package/esm/tools/haveSharedParentDomain.d.ts +4 -0
- package/{src/tools/haveSharedParentDomain.ts → esm/tools/haveSharedParentDomain.js} +3 -5
- package/esm/tools/haveSharedParentDomain.js.map +1 -0
- package/esm/tools/isDev.d.ts +1 -0
- package/{src/tools/isDev.ts → esm/tools/isDev.js} +5 -12
- package/esm/tools/isDev.js.map +1 -0
- package/esm/tools/parseKeycloakIssuerUri.d.ts +30 -0
- package/{src/tools/parseKeycloakIssuerUri.ts → esm/tools/parseKeycloakIssuerUri.js} +2 -18
- package/esm/tools/parseKeycloakIssuerUri.js.map +1 -0
- package/esm/tools/readExpirationTimeInJwt.d.ts +1 -0
- package/{src/tools/readExpirationTimeInJwt.ts → esm/tools/readExpirationTimeInJwt.js} +6 -7
- package/esm/tools/readExpirationTimeInJwt.js.map +1 -0
- package/esm/tools/startCountdown.d.ts +11 -0
- package/{src/tools/startCountdown.ts → esm/tools/startCountdown.js} +6 -17
- package/esm/tools/startCountdown.js.map +1 -0
- package/esm/tools/subscribeToUserInteraction.d.ts +6 -0
- package/{src/tools/subscribeToUserInteraction.ts → esm/tools/subscribeToUserInteraction.js} +4 -13
- package/esm/tools/subscribeToUserInteraction.js.map +1 -0
- package/esm/tools/toFullyQualifiedUrl.d.ts +10 -0
- package/{src/tools/toFullyQualifiedUrl.ts → esm/tools/toFullyQualifiedUrl.js} +7 -25
- package/esm/tools/toFullyQualifiedUrl.js.map +1 -0
- package/esm/tools/toHumanReadableDuration.d.ts +1 -0
- package/{src/tools/toHumanReadableDuration.ts → esm/tools/toHumanReadableDuration.js} +8 -5
- package/esm/tools/toHumanReadableDuration.js.map +1 -0
- package/esm/tools/urlSearchParams.d.ts +19 -0
- package/{src/tools/urlSearchParams.ts → esm/tools/urlSearchParams.js} +24 -70
- package/esm/tools/urlSearchParams.js.map +1 -0
- package/esm/tools/workerTimers.d.ts +5 -0
- package/{src/tools/workerTimers.ts → esm/tools/workerTimers.js} +7 -27
- package/esm/tools/workerTimers.js.map +1 -0
- package/esm/vendor/frontend/oidc-client-ts.js +3636 -0
- package/esm/vendor/frontend/tsafe.js +1 -0
- package/esm/vendor/frontend/worker-timers.js +1 -0
- package/index.js.map +1 -1
- package/keycloak/index.js.map +1 -1
- package/keycloak/isKeycloak.js.map +1 -1
- package/keycloak/keycloak-js/Keycloak.js.map +1 -1
- package/keycloak/keycloak-js/index.js.map +1 -1
- package/keycloak/keycloak-js/types.js.map +1 -1
- package/keycloak/keycloakIssuerUriParsed.js.map +1 -1
- package/keycloak/keycloakUtils.js.map +1 -1
- package/keycloak-js.js.map +1 -1
- package/mock/index.js.map +1 -1
- package/mock/oidc.js.map +1 -1
- package/mock/react.js.map +1 -1
- package/package.json +74 -328
- package/react/index.js.map +1 -1
- package/react/react.js.map +1 -1
- package/tools/Deferred.js.map +1 -1
- package/tools/EphemeralSessionStorage.js.map +1 -1
- package/tools/Evt.js.map +1 -1
- package/tools/StatefulEvt.js.map +1 -1
- package/tools/ValueOrAsyncGetter.js.map +1 -1
- package/tools/asymmetricEncryption.js.map +1 -1
- package/tools/base64.js.map +1 -1
- package/tools/createObjectThatThrowsIfAccessed.js.map +1 -1
- package/tools/decodeJwt.js.map +1 -1
- package/tools/generateUrlSafeRandom.js.map +1 -1
- package/tools/getDownlinkAndRtt.js.map +1 -1
- package/tools/getIsOnline.js.map +1 -1
- package/tools/getIsValidRemoteJson.js.map +1 -1
- package/tools/getPrUserInteraction.js.map +1 -1
- package/tools/getUserEnvironmentInfo.js.map +1 -1
- package/tools/haveSharedParentDomain.js.map +1 -1
- package/tools/isDev.js.map +1 -1
- package/tools/parseKeycloakIssuerUri.js.map +1 -1
- package/tools/readExpirationTimeInJwt.js.map +1 -1
- package/tools/startCountdown.js.map +1 -1
- package/tools/subscribeToUserInteraction.js.map +1 -1
- package/tools/toFullyQualifiedUrl.js.map +1 -1
- package/tools/toHumanReadableDuration.js.map +1 -1
- package/tools/urlSearchParams.js.map +1 -1
- package/tools/workerTimers.js.map +1 -1
- package/LICENSE +0 -21
- package/README.md +0 -185
- package/src/backend.ts +0 -391
- package/src/core/Oidc.ts +0 -140
- package/src/core/StateData.ts +0 -118
- package/src/core/configId.ts +0 -3
- package/src/core/loginSilent.ts +0 -209
- package/src/core/oidcClientTsUserToTokens.ts +0 -229
- package/src/core/persistedAuthState.ts +0 -122
- package/src/keycloak/index.ts +0 -8
- package/src/keycloak/keycloakUtils.ts +0 -90
- package/src/mock/react.tsx +0 -11
- package/src/react/react.tsx +0 -476
- package/src/tools/Deferred.ts +0 -39
- package/src/tools/StatefulEvt.ts +0 -38
- package/src/tools/asymmetricEncryption.ts +0 -184
- package/src/tools/decodeJwt.ts +0 -95
- package/src/tools/getIsValidRemoteJson.ts +0 -18
- package/src/tools/getUserEnvironmentInfo.ts +0 -42
- package/src/vendor/backend/evt.ts +0 -2
- package/src/vendor/backend/jsonwebtoken.ts +0 -1
- package/src/vendor/backend/node-fetch.ts +0 -2
- package/src/vendor/backend/node-jose.ts +0 -1
- package/src/vendor/backend/tsafe.ts +0 -5
- package/src/vendor/backend/zod.ts +0 -1
- /package/{src/core/index.ts → esm/core/index.d.ts} +0 -0
- /package/{src/index.ts → esm/index.d.ts} +0 -0
- /package/{src/keycloak/keycloak-js/index.ts → esm/keycloak/keycloak-js/index.d.ts} +0 -0
- /package/{src/keycloak-js.ts → esm/keycloak-js.d.ts} +0 -0
- /package/{src/mock/index.ts → esm/mock/index.d.ts} +0 -0
- /package/{src/react/index.ts → esm/react/index.d.ts} +0 -0
- /package/{src/tools/ValueOrAsyncGetter.ts → esm/tools/ValueOrAsyncGetter.d.ts} +0 -0
- /package/{src/vendor/frontend/oidc-client-ts.ts → esm/vendor/frontend/oidc-client-ts.d.ts} +0 -0
- /package/{src/vendor/frontend/tsafe.ts → esm/vendor/frontend/tsafe.d.ts} +0 -0
- /package/{src/vendor/frontend/worker-timers.ts → esm/vendor/frontend/worker-timers.d.ts} +0 -0
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
WebStorageStateStore,
|
|
4
|
-
type User as OidcClientTsUser,
|
|
5
|
-
InMemoryWebStorage
|
|
6
|
-
} from "../vendor/frontend/oidc-client-ts";
|
|
7
|
-
import type { OidcMetadata } from "./OidcMetadata";
|
|
8
|
-
import { id, assert, is, type Equals } from "../vendor/frontend/tsafe";
|
|
1
|
+
import { UserManager as OidcClientTsUserManager, WebStorageStateStore, InMemoryWebStorage } from "../vendor/frontend/oidc-client-ts";
|
|
2
|
+
import { id, assert, is } from "../vendor/frontend/tsafe";
|
|
9
3
|
import { setTimeout, clearTimeout } from "../tools/workerTimers";
|
|
10
4
|
import { Deferred } from "../tools/Deferred";
|
|
11
5
|
import { createEvtIsUserActive } from "./evtIsUserActive";
|
|
12
6
|
import { createStartCountdown } from "../tools/startCountdown";
|
|
13
7
|
import { toHumanReadableDuration } from "../tools/toHumanReadableDuration";
|
|
14
8
|
import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
createFailedToFetchTokenEndpointInitializationError,
|
|
18
|
-
createIframeTimeoutInitializationError,
|
|
19
|
-
createWellKnownOidcConfigurationEndpointUnreachableInitializationError
|
|
20
|
-
} from "./OidcInitializationError";
|
|
21
|
-
import { type StateData, generateStateUrlParamValue, STATE_STORE_KEY_PREFIX } from "./StateData";
|
|
9
|
+
import { OidcInitializationError } from "./OidcInitializationError";
|
|
10
|
+
import { generateStateUrlParamValue, STATE_STORE_KEY_PREFIX } from "./StateData";
|
|
22
11
|
import { notifyOtherTabsOfLogout, getPrOtherTabLogout } from "./logoutPropagationToOtherTabs";
|
|
23
12
|
import { notifyOtherTabsOfLogin, getPrOtherTabLogin } from "./loginPropagationToOtherTabs";
|
|
24
13
|
import { getConfigId } from "./configId";
|
|
@@ -27,233 +16,69 @@ import { loginSilent } from "./loginSilent";
|
|
|
27
16
|
import { authResponseToUrl } from "./AuthResponse";
|
|
28
17
|
import { handleOidcCallback, retrieveRedirectAuthResponseAndStateData } from "./handleOidcCallback";
|
|
29
18
|
import { getPersistedAuthState, persistAuthState } from "./persistedAuthState";
|
|
30
|
-
import type { Oidc } from "./Oidc";
|
|
31
19
|
import { createEvt } from "../tools/Evt";
|
|
32
20
|
import { getHaveSharedParentDomain } from "../tools/haveSharedParentDomain";
|
|
33
|
-
import {
|
|
34
|
-
createLoginOrGoToAuthServer,
|
|
35
|
-
getPrSafelyRestoredFromBfCacheAfterLoginBackNavigation
|
|
36
|
-
} from "./loginOrGoToAuthServer";
|
|
21
|
+
import { createLoginOrGoToAuthServer, getPrSafelyRestoredFromBfCacheAfterLoginBackNavigation } from "./loginOrGoToAuthServer";
|
|
37
22
|
import { createEphemeralSessionStorage } from "../tools/EphemeralSessionStorage";
|
|
38
|
-
import {
|
|
39
|
-
startLoginOrRefreshProcess,
|
|
40
|
-
waitForAllOtherOngoingLoginOrRefreshProcessesToComplete
|
|
41
|
-
} from "./ongoingLoginOrRefreshProcesses";
|
|
23
|
+
import { startLoginOrRefreshProcess, waitForAllOtherOngoingLoginOrRefreshProcessesToComplete } from "./ongoingLoginOrRefreshProcesses";
|
|
42
24
|
import { initialLocationHref } from "./initialLocationHref";
|
|
43
25
|
import { createGetIsNewBrowserSession } from "./isNewBrowserSession";
|
|
44
26
|
import { getIsOnline } from "../tools/getIsOnline";
|
|
45
27
|
import { isKeycloak } from "../keycloak/isKeycloak";
|
|
46
|
-
|
|
47
28
|
// NOTE: Replaced at build time
|
|
48
|
-
const VERSION = "
|
|
49
|
-
|
|
50
|
-
export type ParamsOfCreateOidc<
|
|
51
|
-
DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
|
|
52
|
-
AutoLogin extends boolean = false
|
|
53
|
-
> = {
|
|
54
|
-
issuerUri: string;
|
|
55
|
-
clientId: string;
|
|
56
|
-
/**
|
|
57
|
-
* The scopes being requested from the OIDC/OAuth2 provider (default: `["profile"]`
|
|
58
|
-
* (the scope "openid" is added automatically as it's mandatory)
|
|
59
|
-
**/
|
|
60
|
-
scopes?: string[];
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Transform the url (authorization endpoint) before redirecting to the login pages.
|
|
64
|
-
*
|
|
65
|
-
* The isSilent parameter is true when the redirect is initiated in the background iframe for silent signin.
|
|
66
|
-
* This can be used to omit ui related query parameters (like `ui_locales`).
|
|
67
|
-
*/
|
|
68
|
-
transformUrlBeforeRedirect?: (params: { authorizationUrl: string; isSilent: boolean }) => string;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extra query params to be added to the authorization endpoint url before redirecting or silent signing in.
|
|
72
|
-
* You can provide a function that returns those extra query params, it will be called
|
|
73
|
-
* when login() is called.
|
|
74
|
-
*
|
|
75
|
-
* Example: extraQueryParams: ()=> ({ ui_locales: "fr" })
|
|
76
|
-
*
|
|
77
|
-
* This parameter can also be passed to login() directly.
|
|
78
|
-
*/
|
|
79
|
-
extraQueryParams?:
|
|
80
|
-
| Record<string, string | undefined>
|
|
81
|
-
| ((params: { isSilent: boolean; url: string }) => Record<string, string | undefined>);
|
|
82
|
-
/**
|
|
83
|
-
* Extra body params to be added to the /token POST request.
|
|
84
|
-
*
|
|
85
|
-
* It will be used when for the initial request, whenever the token is getting refreshed and if you call `renewTokens()`.
|
|
86
|
-
* You can also provide this parameter directly to the `renewTokens()` method.
|
|
87
|
-
*
|
|
88
|
-
* It can be either a string to string record or a function that returns a string to string record.
|
|
89
|
-
*
|
|
90
|
-
* Example: extraTokenParams: ()=> ({ selectedCustomer: "xxx" })
|
|
91
|
-
* extraTokenParams: { selectedCustomer: "xxx" }
|
|
92
|
-
*/
|
|
93
|
-
extraTokenParams?: Record<string, string | undefined> | (() => Record<string, string | undefined>);
|
|
94
|
-
/**
|
|
95
|
-
* Usage discouraged, it's here because we don't want to assume too much on your
|
|
96
|
-
* usecase but I can't think of a scenario where you would want anything
|
|
97
|
-
* other than the current page.
|
|
98
|
-
*
|
|
99
|
-
* Where to redirect after successful login.
|
|
100
|
-
* Default: window.location.href (here)
|
|
101
|
-
*
|
|
102
|
-
* It does not need to include the origin, eg: "/dashboard"
|
|
103
|
-
*
|
|
104
|
-
* This parameter can also be passed to login() directly as `redirectUrl`.
|
|
105
|
-
*/
|
|
106
|
-
postLoginRedirectUrl?: string;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* What should you put in this parameter?
|
|
110
|
-
* - Vite project: `BASE_URL: import.meta.env.BASE_URL`
|
|
111
|
-
* - Create React App project: `BASE_URL: process.env.PUBLIC_URL`
|
|
112
|
-
* - Other: `BASE_URL: "/"` (Usually, or `/dashboard` if your app is not at the root of the domain)
|
|
113
|
-
*/
|
|
114
|
-
homeUrl: string;
|
|
115
|
-
|
|
116
|
-
decodedIdTokenSchema?: {
|
|
117
|
-
parse: (decodedIdToken_original: Oidc.Tokens.DecodedIdToken_base) => DecodedIdToken;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* This parameter defines after how many seconds of inactivity the user should be
|
|
122
|
-
* logged out automatically.
|
|
123
|
-
*
|
|
124
|
-
* WARNING: It should be configured on the identity server side
|
|
125
|
-
* as it's the authoritative source for security policies and not the client.
|
|
126
|
-
* If you don't provide this parameter it will be inferred from the refresh token expiration time.
|
|
127
|
-
* */
|
|
128
|
-
idleSessionLifetimeInSeconds?: number;
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Usage discouraged, this parameter exists because we don't want to assume
|
|
132
|
-
* too much about your usecase but I can't think of a scenario where you would
|
|
133
|
-
* want anything other than the current page.
|
|
134
|
-
*
|
|
135
|
-
* Default: { redirectTo: "current page" }
|
|
136
|
-
*/
|
|
137
|
-
autoLogoutParams?: Parameters<Oidc.LoggedIn<any>["logout"]>[0];
|
|
138
|
-
autoLogin?: AutoLogin;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Default: false
|
|
142
|
-
*
|
|
143
|
-
* See: https://docs.oidc-spa.dev/v/v7/resources/iframe-related-issues
|
|
144
|
-
*/
|
|
145
|
-
noIframe?: boolean;
|
|
146
|
-
|
|
147
|
-
debugLogs?: boolean;
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* WARNING: This option exists solely as a workaround
|
|
151
|
-
* for limitations in the Google OAuth API.
|
|
152
|
-
* See: https://docs.oidc-spa.dev/providers-configuration/google-oauth
|
|
153
|
-
*
|
|
154
|
-
* Do not use this for other providers.
|
|
155
|
-
* If you think you need a client secret in a SPA, you are likely
|
|
156
|
-
* trying to use a confidential (private) client in the browser,
|
|
157
|
-
* which is insecure and not supported.
|
|
158
|
-
*/
|
|
159
|
-
__unsafe_clientSecret?: string;
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* WARNING: Setting this to true is a workaround for provider
|
|
163
|
-
* like Google OAuth that don't support JWT access token.
|
|
164
|
-
* Use at your own risk, this is a hack.
|
|
165
|
-
*/
|
|
166
|
-
__unsafe_useIdTokenAsAccessToken?: boolean;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* This option should only be used as a last resort.
|
|
170
|
-
*
|
|
171
|
-
* If your OIDC provider is correctly configured, this should not be necessary.
|
|
172
|
-
*
|
|
173
|
-
* The metadata is normally retrieved automatically from:
|
|
174
|
-
* `${issuerUri}/.well-known/openid-configuration`
|
|
175
|
-
*
|
|
176
|
-
* Use this only if that endpoint is not accessible (e.g. due to missing CORS headers
|
|
177
|
-
* or non-standard deployments), and you cannot fix the server-side configuration.
|
|
178
|
-
*/
|
|
179
|
-
__metadata?: Partial<OidcMetadata>;
|
|
180
|
-
};
|
|
181
|
-
|
|
29
|
+
const VERSION = "7.2.0-rc.2";
|
|
182
30
|
const globalContext = {
|
|
183
|
-
prOidcByConfigId: new Map
|
|
184
|
-
hasLogoutBeenCalled: id
|
|
185
|
-
evtRequestToPersistTokens: createEvt
|
|
31
|
+
prOidcByConfigId: new Map(),
|
|
32
|
+
hasLogoutBeenCalled: id(false),
|
|
33
|
+
evtRequestToPersistTokens: createEvt()
|
|
186
34
|
};
|
|
187
|
-
|
|
188
35
|
/** @see: https://docs.oidc-spa.dev/v/v7/usage */
|
|
189
|
-
export async function createOidc
|
|
190
|
-
|
|
191
|
-
AutoLogin extends boolean = false
|
|
192
|
-
>(
|
|
193
|
-
params: ParamsOfCreateOidc<DecodedIdToken, AutoLogin>
|
|
194
|
-
): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>> {
|
|
195
|
-
for (const name of ["issuerUri", "clientId"] as const) {
|
|
36
|
+
export async function createOidc(params) {
|
|
37
|
+
for (const name of ["issuerUri", "clientId"]) {
|
|
196
38
|
const value = params[name];
|
|
197
39
|
if (!value) {
|
|
198
|
-
throw new Error(
|
|
199
|
-
`The parameter "${name}" is required, you provided: ${value}. (Forgot a .env variable?)`
|
|
200
|
-
);
|
|
40
|
+
throw new Error(`The parameter "${name}" is required, you provided: ${value}. (Forgot a .env variable?)`);
|
|
201
41
|
}
|
|
202
42
|
}
|
|
203
|
-
|
|
204
43
|
const { issuerUri: issuerUri_params, clientId, scopes = ["profile"], debugLogs, ...rest } = params;
|
|
205
|
-
|
|
206
44
|
const issuerUri = toFullyQualifiedUrl({
|
|
207
45
|
urlish: issuerUri_params,
|
|
208
46
|
doAssertNoQueryParams: true,
|
|
209
47
|
doOutputWithTrailingSlash: false
|
|
210
48
|
});
|
|
211
|
-
|
|
212
49
|
const log = (() => {
|
|
213
50
|
if (!debugLogs) {
|
|
214
51
|
return undefined;
|
|
215
52
|
}
|
|
216
|
-
|
|
217
|
-
return id<typeof console.log>((...[first, ...rest]) => {
|
|
53
|
+
return id((...[first, ...rest]) => {
|
|
218
54
|
const label = "oidc-spa";
|
|
219
|
-
|
|
220
55
|
if (typeof first === "string") {
|
|
221
56
|
console.log(...[`${label}: ${first}`, ...rest]);
|
|
222
|
-
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
223
59
|
console.log(...[`${label}:`, first, ...rest]);
|
|
224
60
|
}
|
|
225
61
|
});
|
|
226
62
|
})();
|
|
227
|
-
|
|
228
63
|
const configId = getConfigId({ issuerUri, clientId });
|
|
229
|
-
|
|
230
64
|
const { prOidcByConfigId } = globalContext;
|
|
231
|
-
|
|
232
65
|
use_previous_instance: {
|
|
233
66
|
const prOidc = prOidcByConfigId.get(configId);
|
|
234
|
-
|
|
235
67
|
if (prOidc === undefined) {
|
|
236
68
|
break use_previous_instance;
|
|
237
69
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
`Returning the previous instance. All potential different parameters are ignored.`
|
|
246
|
-
].join(" ")
|
|
247
|
-
);
|
|
248
|
-
|
|
70
|
+
log?.([
|
|
71
|
+
`createOidc was called again with the same config (${JSON.stringify({
|
|
72
|
+
issuerUri,
|
|
73
|
+
clientId
|
|
74
|
+
})})`,
|
|
75
|
+
`Returning the previous instance. All potential different parameters are ignored.`
|
|
76
|
+
].join(" "));
|
|
249
77
|
// @ts-expect-error: We know what we're doing
|
|
250
78
|
return prOidc;
|
|
251
79
|
}
|
|
252
|
-
|
|
253
|
-
const dOidc = new Deferred<Oidc<any>>();
|
|
254
|
-
|
|
80
|
+
const dOidc = new Deferred();
|
|
255
81
|
prOidcByConfigId.set(configId, dOidc.pr);
|
|
256
|
-
|
|
257
82
|
const oidc = await createOidc_nonMemoized(rest, {
|
|
258
83
|
issuerUri,
|
|
259
84
|
clientId,
|
|
@@ -261,145 +86,79 @@ export async function createOidc<
|
|
|
261
86
|
configId,
|
|
262
87
|
log
|
|
263
88
|
});
|
|
264
|
-
|
|
265
89
|
dOidc.resolve(oidc);
|
|
266
|
-
|
|
267
90
|
return oidc;
|
|
268
91
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
DecodedIdToken extends Record<string, unknown> = Record<string, unknown>,
|
|
272
|
-
AutoLogin extends boolean = false
|
|
273
|
-
>(
|
|
274
|
-
params: Omit<
|
|
275
|
-
ParamsOfCreateOidc<DecodedIdToken, AutoLogin>,
|
|
276
|
-
"issuerUri" | "clientId" | "scopes" | "debugLogs"
|
|
277
|
-
>,
|
|
278
|
-
preProcessedParams: {
|
|
279
|
-
issuerUri: string;
|
|
280
|
-
clientId: string;
|
|
281
|
-
scopes: string[];
|
|
282
|
-
configId: string;
|
|
283
|
-
log: typeof console.log | undefined;
|
|
284
|
-
}
|
|
285
|
-
): Promise<AutoLogin extends true ? Oidc.LoggedIn<DecodedIdToken> : Oidc<DecodedIdToken>> {
|
|
286
|
-
const {
|
|
287
|
-
transformUrlBeforeRedirect,
|
|
288
|
-
extraQueryParams: extraQueryParamsOrGetter,
|
|
289
|
-
extraTokenParams: extraTokenParamsOrGetter,
|
|
290
|
-
homeUrl: homeUrl_params,
|
|
291
|
-
decodedIdTokenSchema,
|
|
292
|
-
idleSessionLifetimeInSeconds,
|
|
293
|
-
autoLogoutParams = { redirectTo: "current page" },
|
|
294
|
-
autoLogin = false,
|
|
295
|
-
postLoginRedirectUrl: postLoginRedirectUrl_default,
|
|
296
|
-
__unsafe_clientSecret,
|
|
297
|
-
__unsafe_useIdTokenAsAccessToken = false,
|
|
298
|
-
__metadata,
|
|
299
|
-
noIframe = false
|
|
300
|
-
} = params;
|
|
301
|
-
|
|
92
|
+
export async function createOidc_nonMemoized(params, preProcessedParams) {
|
|
93
|
+
const { transformUrlBeforeRedirect, extraQueryParams: extraQueryParamsOrGetter, extraTokenParams: extraTokenParamsOrGetter, homeUrl: homeUrl_params, decodedIdTokenSchema, idleSessionLifetimeInSeconds, autoLogoutParams = { redirectTo: "current page" }, autoLogin = false, postLoginRedirectUrl: postLoginRedirectUrl_default, __unsafe_clientSecret, __unsafe_useIdTokenAsAccessToken = false, __metadata, noIframe = false } = params;
|
|
302
94
|
const { issuerUri, clientId, scopes, configId, log } = preProcessedParams;
|
|
303
|
-
|
|
304
95
|
const getExtraQueryParams = (() => {
|
|
305
96
|
if (extraQueryParamsOrGetter === undefined) {
|
|
306
97
|
return undefined;
|
|
307
98
|
}
|
|
308
|
-
|
|
309
99
|
if (typeof extraQueryParamsOrGetter !== "function") {
|
|
310
100
|
return () => extraQueryParamsOrGetter;
|
|
311
101
|
}
|
|
312
|
-
|
|
313
102
|
return extraQueryParamsOrGetter;
|
|
314
103
|
})();
|
|
315
|
-
|
|
316
104
|
const getExtraTokenParams = (() => {
|
|
317
105
|
if (extraTokenParamsOrGetter === undefined) {
|
|
318
106
|
return undefined;
|
|
319
107
|
}
|
|
320
|
-
|
|
321
108
|
if (typeof extraTokenParamsOrGetter !== "function") {
|
|
322
109
|
return () => extraTokenParamsOrGetter;
|
|
323
110
|
}
|
|
324
|
-
|
|
325
111
|
return extraTokenParamsOrGetter;
|
|
326
112
|
})();
|
|
327
|
-
|
|
328
113
|
const homeUrlAndRedirectUri = toFullyQualifiedUrl({
|
|
329
114
|
urlish: homeUrl_params,
|
|
330
115
|
doAssertNoQueryParams: true,
|
|
331
116
|
doOutputWithTrailingSlash: true
|
|
332
117
|
});
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
configId,
|
|
341
|
-
homeUrlAndRedirectUri
|
|
342
|
-
},
|
|
343
|
-
null,
|
|
344
|
-
2
|
|
345
|
-
)}`
|
|
346
|
-
);
|
|
347
|
-
|
|
118
|
+
log?.(`Calling createOidc v${VERSION} ${JSON.stringify({
|
|
119
|
+
issuerUri,
|
|
120
|
+
clientId,
|
|
121
|
+
scopes,
|
|
122
|
+
configId,
|
|
123
|
+
homeUrlAndRedirectUri
|
|
124
|
+
}, null, 2)}`);
|
|
348
125
|
{
|
|
349
126
|
const { isHandled } = handleOidcCallback();
|
|
350
|
-
|
|
351
127
|
if (isHandled) {
|
|
352
|
-
await new Promise
|
|
128
|
+
await new Promise(() => { });
|
|
353
129
|
}
|
|
354
130
|
}
|
|
355
|
-
|
|
356
131
|
const stateUrlParamValue_instance = generateStateUrlParamValue();
|
|
357
|
-
|
|
358
132
|
const canUseIframe = (() => {
|
|
359
133
|
if (noIframe) {
|
|
360
134
|
return false;
|
|
361
135
|
}
|
|
362
|
-
|
|
363
136
|
third_party_cookies: {
|
|
364
|
-
const isOidcServerThirdPartyRelativeToApp =
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}) === false;
|
|
369
|
-
|
|
137
|
+
const isOidcServerThirdPartyRelativeToApp = getHaveSharedParentDomain({
|
|
138
|
+
url1: window.location.origin,
|
|
139
|
+
url2: issuerUri
|
|
140
|
+
}) === false;
|
|
370
141
|
if (!isOidcServerThirdPartyRelativeToApp) {
|
|
371
142
|
break third_party_cookies;
|
|
372
143
|
}
|
|
373
|
-
|
|
374
144
|
const isGoogleChrome = (() => {
|
|
375
145
|
const ua = navigator.userAgent;
|
|
376
146
|
const vendor = navigator.vendor;
|
|
377
|
-
|
|
378
|
-
return (
|
|
379
|
-
/Chrome/.test(ua) && /Google Inc/.test(vendor) && !/Edg/.test(ua) && !/OPR/.test(ua)
|
|
380
|
-
);
|
|
147
|
+
return (/Chrome/.test(ua) && /Google Inc/.test(vendor) && !/Edg/.test(ua) && !/OPR/.test(ua));
|
|
381
148
|
})();
|
|
382
|
-
|
|
383
149
|
if (window.location.origin.startsWith("http://localhost") && isGoogleChrome) {
|
|
384
150
|
break third_party_cookies;
|
|
385
151
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
"to the domain of your app and third party cookies are blocked by navigators."
|
|
391
|
-
].join(" ")
|
|
392
|
-
);
|
|
393
|
-
|
|
152
|
+
log?.([
|
|
153
|
+
"Can't use iframe because your auth server is on a third party domain relative",
|
|
154
|
+
"to the domain of your app and third party cookies are blocked by navigators."
|
|
155
|
+
].join(" "));
|
|
394
156
|
return false;
|
|
395
157
|
}
|
|
396
|
-
|
|
397
158
|
// NOTE: Maybe not, it depend if the app can iframe itself.
|
|
398
159
|
return true;
|
|
399
160
|
})();
|
|
400
|
-
|
|
401
|
-
let isUserStoreInMemoryOnly: boolean;
|
|
402
|
-
|
|
161
|
+
let isUserStoreInMemoryOnly;
|
|
403
162
|
const oidcClientTsUserManager = new OidcClientTsUserManager({
|
|
404
163
|
stateUrlParamValue: stateUrlParamValue_instance,
|
|
405
164
|
authority: issuerUri,
|
|
@@ -417,23 +176,17 @@ export async function createOidc_nonMemoized<
|
|
|
417
176
|
isUserStoreInMemoryOnly = true;
|
|
418
177
|
return new InMemoryWebStorage();
|
|
419
178
|
}
|
|
420
|
-
|
|
421
179
|
isUserStoreInMemoryOnly = false;
|
|
422
|
-
|
|
423
180
|
const storage = createEphemeralSessionStorage({
|
|
424
|
-
sessionStorageTtlMs: 3 *
|
|
181
|
+
sessionStorageTtlMs: 3 * 60000
|
|
425
182
|
});
|
|
426
|
-
|
|
427
183
|
const { evtRequestToPersistTokens } = globalContext;
|
|
428
|
-
|
|
429
184
|
evtRequestToPersistTokens.subscribe(({ configIdOfInstancePostingTheRequest }) => {
|
|
430
185
|
if (configIdOfInstancePostingTheRequest === configId) {
|
|
431
186
|
return;
|
|
432
187
|
}
|
|
433
|
-
|
|
434
188
|
storage.persistCurrentStateAndSubsequentChanges();
|
|
435
189
|
});
|
|
436
|
-
|
|
437
190
|
return storage;
|
|
438
191
|
})()
|
|
439
192
|
}),
|
|
@@ -441,9 +194,7 @@ export async function createOidc_nonMemoized<
|
|
|
441
194
|
client_secret: __unsafe_clientSecret,
|
|
442
195
|
metadata: __metadata
|
|
443
196
|
});
|
|
444
|
-
|
|
445
|
-
const evtIsUserLoggedIn = createEvt<boolean>();
|
|
446
|
-
|
|
197
|
+
const evtIsUserLoggedIn = createEvt();
|
|
447
198
|
const { loginOrGoToAuthServer } = createLoginOrGoToAuthServer({
|
|
448
199
|
configId,
|
|
449
200
|
oidcClientTsUserManager,
|
|
@@ -454,110 +205,71 @@ export async function createOidc_nonMemoized<
|
|
|
454
205
|
evtIsUserLoggedIn,
|
|
455
206
|
log
|
|
456
207
|
});
|
|
457
|
-
|
|
458
208
|
const { getIsNewBrowserSession } = createGetIsNewBrowserSession({
|
|
459
209
|
configId,
|
|
460
210
|
evtUserNotLoggedIn: (() => {
|
|
461
|
-
const evt = createEvt
|
|
462
|
-
|
|
211
|
+
const evt = createEvt();
|
|
463
212
|
evtIsUserLoggedIn.subscribe(isUserLoggedIn => {
|
|
464
213
|
if (!isUserLoggedIn) {
|
|
465
214
|
evt.post();
|
|
466
215
|
}
|
|
467
216
|
});
|
|
468
|
-
|
|
469
217
|
return evt;
|
|
470
218
|
})()
|
|
471
219
|
});
|
|
472
|
-
|
|
473
220
|
const { completeLoginOrRefreshProcess } = await startLoginOrRefreshProcess();
|
|
474
|
-
|
|
475
|
-
const resultOfLoginProcess = await (async (): Promise<
|
|
476
|
-
| undefined // User is currently not logged in
|
|
477
|
-
| Error // Initialization error
|
|
478
|
-
| {
|
|
479
|
-
oidcClientTsUser: OidcClientTsUser;
|
|
480
|
-
backFromAuthServer: Oidc.LoggedIn["backFromAuthServer"]; // Undefined is silent signin
|
|
481
|
-
}
|
|
482
|
-
> => {
|
|
221
|
+
const resultOfLoginProcess = await (async () => {
|
|
483
222
|
handle_redirect_auth_response: {
|
|
484
223
|
const authResponseAndStateData = retrieveRedirectAuthResponseAndStateData({ configId });
|
|
485
|
-
|
|
486
224
|
if (authResponseAndStateData === undefined) {
|
|
487
225
|
break handle_redirect_auth_response;
|
|
488
226
|
}
|
|
489
|
-
|
|
490
227
|
const { authResponse, stateData } = authResponseAndStateData;
|
|
491
|
-
|
|
492
228
|
switch (stateData.action) {
|
|
493
229
|
case "login":
|
|
494
230
|
{
|
|
495
|
-
log?.(
|
|
496
|
-
`Handling login redirect auth response ${JSON.stringify(
|
|
497
|
-
authResponse,
|
|
498
|
-
null,
|
|
499
|
-
2
|
|
500
|
-
)}`
|
|
501
|
-
);
|
|
502
|
-
|
|
231
|
+
log?.(`Handling login redirect auth response ${JSON.stringify(authResponse, null, 2)}`);
|
|
503
232
|
const authResponseUrl = authResponseToUrl(authResponse);
|
|
504
|
-
|
|
505
|
-
let oidcClientTsUser: OidcClientTsUser | undefined = undefined;
|
|
506
|
-
|
|
233
|
+
let oidcClientTsUser = undefined;
|
|
507
234
|
try {
|
|
508
|
-
oidcClientTsUser = await oidcClientTsUserManager.signinRedirectCallback(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
} catch (error) {
|
|
235
|
+
oidcClientTsUser = await oidcClientTsUserManager.signinRedirectCallback(authResponseUrl);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
512
238
|
assert(error instanceof Error, "741947");
|
|
513
|
-
|
|
514
239
|
if (error.message === "Failed to fetch") {
|
|
515
|
-
return createFailedToFetchTokenEndpointInitializationError({
|
|
240
|
+
return (await import("./diagnostic")).createFailedToFetchTokenEndpointInitializationError({
|
|
516
241
|
clientId,
|
|
517
242
|
issuerUri
|
|
518
243
|
});
|
|
519
244
|
}
|
|
520
|
-
|
|
521
245
|
{
|
|
522
246
|
const authResponse_error = authResponse.error;
|
|
523
|
-
|
|
524
247
|
if (authResponse_error !== undefined) {
|
|
525
|
-
log?.(
|
|
526
|
-
`The auth server responded with: ${authResponse_error}, trying to restore from the http only cookie`
|
|
527
|
-
);
|
|
248
|
+
log?.(`The auth server responded with: ${authResponse_error}, trying to restore from the http only cookie`);
|
|
528
249
|
break handle_redirect_auth_response;
|
|
529
250
|
}
|
|
530
251
|
}
|
|
531
|
-
|
|
532
252
|
return error;
|
|
533
253
|
}
|
|
534
|
-
|
|
535
254
|
notifyOtherTabsOfLogin({ configId });
|
|
536
|
-
|
|
537
255
|
return {
|
|
538
256
|
oidcClientTsUser,
|
|
539
257
|
backFromAuthServer: {
|
|
540
258
|
extraQueryParams: stateData.extraQueryParams,
|
|
541
|
-
result: Object.fromEntries(
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return [name, value];
|
|
558
|
-
})
|
|
559
|
-
.filter(entry => entry !== undefined)
|
|
560
|
-
)
|
|
259
|
+
result: Object.fromEntries(Object.entries(authResponse)
|
|
260
|
+
.map(([name, value]) => {
|
|
261
|
+
if (name === "state" ||
|
|
262
|
+
name === "session_state" ||
|
|
263
|
+
name === "iss" ||
|
|
264
|
+
name === "code") {
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
if (value === undefined) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
return [name, value];
|
|
271
|
+
})
|
|
272
|
+
.filter(entry => entry !== undefined))
|
|
561
273
|
}
|
|
562
274
|
};
|
|
563
275
|
}
|
|
@@ -565,108 +277,86 @@ export async function createOidc_nonMemoized<
|
|
|
565
277
|
case "logout":
|
|
566
278
|
{
|
|
567
279
|
log?.("Handling logout redirect auth response", authResponse);
|
|
568
|
-
|
|
569
280
|
const authResponseUrl = authResponseToUrl(authResponse);
|
|
570
|
-
|
|
571
281
|
try {
|
|
572
282
|
await oidcClientTsUserManager.signoutRedirectCallback(authResponseUrl);
|
|
573
|
-
}
|
|
574
|
-
|
|
283
|
+
}
|
|
284
|
+
catch { }
|
|
575
285
|
notifyOtherTabsOfLogout({
|
|
576
286
|
configId,
|
|
577
287
|
sessionId: stateData.sessionId
|
|
578
288
|
});
|
|
579
|
-
|
|
580
289
|
if (autoLogin) {
|
|
581
290
|
location.reload();
|
|
582
|
-
await new Promise
|
|
291
|
+
await new Promise(() => { });
|
|
583
292
|
}
|
|
584
|
-
|
|
585
293
|
// NOTE: The user is no longer logged in.
|
|
586
294
|
return undefined;
|
|
587
295
|
}
|
|
588
296
|
break;
|
|
589
297
|
}
|
|
590
298
|
}
|
|
591
|
-
|
|
592
299
|
restore_from_session_storage: {
|
|
593
300
|
if (isUserStoreInMemoryOnly) {
|
|
594
301
|
break restore_from_session_storage;
|
|
595
302
|
}
|
|
596
|
-
|
|
597
|
-
let oidcClientTsUser: OidcClientTsUser | null;
|
|
598
|
-
|
|
303
|
+
let oidcClientTsUser;
|
|
599
304
|
try {
|
|
600
305
|
oidcClientTsUser = await oidcClientTsUserManager.getUser();
|
|
601
|
-
}
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
602
308
|
// NOTE: Not sure if it can throw, but let's be safe.
|
|
603
309
|
oidcClientTsUser = null;
|
|
604
310
|
try {
|
|
605
311
|
await oidcClientTsUserManager.removeUser();
|
|
606
|
-
}
|
|
312
|
+
}
|
|
313
|
+
catch { }
|
|
607
314
|
}
|
|
608
|
-
|
|
609
315
|
if (oidcClientTsUser === null) {
|
|
610
316
|
break restore_from_session_storage;
|
|
611
317
|
}
|
|
612
|
-
|
|
613
318
|
log?.("Restored the auth from ephemeral session storage");
|
|
614
|
-
|
|
615
319
|
return {
|
|
616
320
|
oidcClientTsUser,
|
|
617
321
|
backFromAuthServer: undefined
|
|
618
322
|
};
|
|
619
323
|
}
|
|
620
|
-
|
|
621
324
|
silent_login_if_possible_and_auto_login: {
|
|
622
325
|
const persistedAuthState = getPersistedAuthState({ configId });
|
|
623
|
-
|
|
624
326
|
if (persistedAuthState === "explicitly logged out" && !autoLogin) {
|
|
625
327
|
log?.("Skipping silent signin with iframe, the user has logged out");
|
|
626
328
|
break silent_login_if_possible_and_auto_login;
|
|
627
329
|
}
|
|
628
|
-
|
|
629
330
|
{
|
|
630
331
|
const { isOnline, prOnline } = getIsOnline();
|
|
631
|
-
|
|
632
332
|
if (!isOnline) {
|
|
633
333
|
if (autoLogin) {
|
|
634
|
-
log?.(
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
].join(" ")
|
|
640
|
-
);
|
|
334
|
+
log?.([
|
|
335
|
+
"The browser is currently offline",
|
|
336
|
+
"Since autoLogin is enabled we wait until it comes back online",
|
|
337
|
+
"to continue with authentication"
|
|
338
|
+
].join(" "));
|
|
641
339
|
await prOnline;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
log?.([
|
|
343
|
+
"The browser is not currently online so we proceed with initialization",
|
|
344
|
+
"assuming the user isn't authenticated"
|
|
345
|
+
].join(" "));
|
|
649
346
|
break silent_login_if_possible_and_auto_login;
|
|
650
347
|
}
|
|
651
348
|
}
|
|
652
349
|
}
|
|
653
|
-
|
|
654
|
-
let
|
|
655
|
-
let oidcClientTsUser: OidcClientTsUser | undefined = undefined;
|
|
656
|
-
|
|
350
|
+
let authResponse_error = undefined;
|
|
351
|
+
let oidcClientTsUser = undefined;
|
|
657
352
|
actual_silent_signin: {
|
|
658
353
|
if (persistedAuthState === "explicitly logged out") {
|
|
659
354
|
break actual_silent_signin;
|
|
660
355
|
}
|
|
661
|
-
|
|
662
356
|
if (!canUseIframe) {
|
|
663
357
|
break actual_silent_signin;
|
|
664
358
|
}
|
|
665
|
-
|
|
666
|
-
log?.(
|
|
667
|
-
"Trying to restore the auth from the http only cookie (silent signin with iframe)"
|
|
668
|
-
);
|
|
669
|
-
|
|
359
|
+
log?.("Trying to restore the auth from the http only cookie (silent signin with iframe)");
|
|
670
360
|
const result_loginSilent = await loginSilent({
|
|
671
361
|
oidcClientTsUserManager,
|
|
672
362
|
stateUrlParamValue_instance,
|
|
@@ -676,87 +366,65 @@ export async function createOidc_nonMemoized<
|
|
|
676
366
|
getExtraTokenParams,
|
|
677
367
|
autoLogin
|
|
678
368
|
});
|
|
679
|
-
|
|
680
369
|
assert(result_loginSilent.outcome !== "token refreshed using refresh token", "876995");
|
|
681
|
-
|
|
682
370
|
if (result_loginSilent.outcome === "failure") {
|
|
683
371
|
switch (result_loginSilent.cause) {
|
|
684
372
|
case "can't reach well-known oidc endpoint":
|
|
685
|
-
return createWellKnownOidcConfigurationEndpointUnreachableInitializationError(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
);
|
|
373
|
+
return (await import("./diagnostic")).createWellKnownOidcConfigurationEndpointUnreachableInitializationError({
|
|
374
|
+
issuerUri
|
|
375
|
+
});
|
|
690
376
|
case "timeout":
|
|
691
|
-
return createIframeTimeoutInitializationError({
|
|
377
|
+
return (await import("./diagnostic")).createIframeTimeoutInitializationError({
|
|
692
378
|
redirectUri: homeUrlAndRedirectUri,
|
|
693
379
|
clientId,
|
|
694
380
|
issuerUri,
|
|
695
381
|
noIframe
|
|
696
382
|
});
|
|
697
383
|
}
|
|
698
|
-
|
|
699
|
-
assert<Equals<typeof result_loginSilent.cause, never>>(false);
|
|
384
|
+
assert(false);
|
|
700
385
|
}
|
|
701
|
-
|
|
702
|
-
assert<Equals<typeof result_loginSilent.outcome, "got auth response from iframe">>();
|
|
703
|
-
|
|
386
|
+
assert();
|
|
704
387
|
const { authResponse } = result_loginSilent;
|
|
705
|
-
|
|
706
388
|
log?.(`Silent signin auth response ${JSON.stringify(authResponse, null, 2)}`);
|
|
707
|
-
|
|
708
389
|
authResponse_error = authResponse.error;
|
|
709
|
-
|
|
710
390
|
try {
|
|
711
|
-
oidcClientTsUser = await oidcClientTsUserManager.signinRedirectCallback(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
} catch (error) {
|
|
391
|
+
oidcClientTsUser = await oidcClientTsUserManager.signinRedirectCallback(authResponseToUrl(authResponse));
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
715
394
|
assert(error instanceof Error, "433344");
|
|
716
|
-
|
|
717
395
|
if (error.message === "Failed to fetch") {
|
|
718
|
-
return createFailedToFetchTokenEndpointInitializationError({
|
|
396
|
+
return (await import("./diagnostic")).createFailedToFetchTokenEndpointInitializationError({
|
|
719
397
|
clientId,
|
|
720
398
|
issuerUri
|
|
721
399
|
});
|
|
722
400
|
}
|
|
723
|
-
|
|
724
401
|
if (authResponse_error === undefined) {
|
|
725
402
|
return error;
|
|
726
403
|
}
|
|
727
404
|
}
|
|
728
405
|
}
|
|
729
|
-
|
|
730
406
|
if (oidcClientTsUser === undefined) {
|
|
731
|
-
if (
|
|
732
|
-
autoLogin ||
|
|
407
|
+
if (autoLogin ||
|
|
733
408
|
(persistedAuthState === "logged in" &&
|
|
734
409
|
(authResponse_error === undefined ||
|
|
735
410
|
authResponse_error === "interaction_required" ||
|
|
736
411
|
authResponse_error === "login_required" ||
|
|
737
412
|
authResponse_error === "consent_required" ||
|
|
738
|
-
authResponse_error === "account_selection_required"))
|
|
739
|
-
) {
|
|
413
|
+
authResponse_error === "account_selection_required"))) {
|
|
740
414
|
log?.("Performing auto login with redirect");
|
|
741
|
-
|
|
742
415
|
persistAuthState({ configId, state: undefined });
|
|
743
|
-
|
|
744
416
|
completeLoginOrRefreshProcess();
|
|
745
|
-
|
|
746
417
|
if (autoLogin && persistedAuthState !== "logged in") {
|
|
747
418
|
evtIsUserLoggedIn.post(false);
|
|
748
419
|
}
|
|
749
|
-
|
|
750
420
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
751
|
-
prUnlock: new Promise
|
|
421
|
+
prUnlock: new Promise(() => { })
|
|
752
422
|
});
|
|
753
|
-
|
|
754
423
|
if (persistedAuthState === "logged in") {
|
|
755
424
|
globalContext.evtRequestToPersistTokens.post({
|
|
756
425
|
configIdOfInstancePostingTheRequest: configId
|
|
757
426
|
});
|
|
758
427
|
}
|
|
759
|
-
|
|
760
428
|
await loginOrGoToAuthServer({
|
|
761
429
|
action: "login",
|
|
762
430
|
doForceReloadOnBfCache: true,
|
|
@@ -770,167 +438,123 @@ export async function createOidc_nonMemoized<
|
|
|
770
438
|
if (persistedAuthState === "explicitly logged out") {
|
|
771
439
|
return "ensure interaction";
|
|
772
440
|
}
|
|
773
|
-
|
|
774
441
|
if (autoLogin) {
|
|
775
442
|
return "directly redirect if active session show login otherwise";
|
|
776
443
|
}
|
|
777
|
-
|
|
778
444
|
return "ensure no interaction";
|
|
779
445
|
})()
|
|
780
446
|
});
|
|
781
447
|
assert(false, "321389");
|
|
782
448
|
}
|
|
783
|
-
|
|
784
449
|
if (authResponse_error !== undefined) {
|
|
785
|
-
log?.(
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
].join("")
|
|
792
|
-
);
|
|
450
|
+
log?.([
|
|
451
|
+
`The auth server responded with: ${authResponse_error} `,
|
|
452
|
+
"login_required" === authResponse_error
|
|
453
|
+
? `(login_required just means that there's no active session for the user)`
|
|
454
|
+
: ""
|
|
455
|
+
].join(""));
|
|
793
456
|
}
|
|
794
|
-
|
|
795
457
|
break silent_login_if_possible_and_auto_login;
|
|
796
458
|
}
|
|
797
|
-
|
|
798
459
|
log?.("Successful silent signed in");
|
|
799
|
-
|
|
800
460
|
return {
|
|
801
461
|
oidcClientTsUser,
|
|
802
462
|
backFromAuthServer: undefined
|
|
803
463
|
};
|
|
804
464
|
}
|
|
805
|
-
|
|
806
465
|
// NOTE: The user is not logged in.
|
|
807
466
|
return undefined;
|
|
808
467
|
})();
|
|
809
|
-
|
|
810
468
|
completeLoginOrRefreshProcess();
|
|
811
|
-
|
|
812
469
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
813
470
|
prUnlock: Promise.resolve()
|
|
814
471
|
});
|
|
815
|
-
|
|
816
|
-
const oidc_common: Oidc.Common = {
|
|
472
|
+
const oidc_common = {
|
|
817
473
|
params: {
|
|
818
474
|
issuerUri,
|
|
819
475
|
clientId
|
|
820
476
|
}
|
|
821
477
|
};
|
|
822
|
-
|
|
823
478
|
not_loggedIn_case: {
|
|
824
479
|
if (!(resultOfLoginProcess instanceof Error) && resultOfLoginProcess !== undefined) {
|
|
825
480
|
break not_loggedIn_case;
|
|
826
481
|
}
|
|
827
|
-
|
|
828
482
|
evtIsUserLoggedIn.post(false);
|
|
829
|
-
|
|
830
483
|
if (getPersistedAuthState({ configId }) !== "explicitly logged out") {
|
|
831
484
|
persistAuthState({ configId, state: undefined });
|
|
832
485
|
}
|
|
833
|
-
|
|
834
|
-
const oidc_notLoggedIn: Oidc.NotLoggedIn = (() => {
|
|
486
|
+
const oidc_notLoggedIn = (() => {
|
|
835
487
|
if (resultOfLoginProcess instanceof Error) {
|
|
836
488
|
log?.("User not logged in and there was an initialization error");
|
|
837
|
-
|
|
838
489
|
const error = resultOfLoginProcess;
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
:
|
|
844
|
-
|
|
845
|
-
messageOrCause: error
|
|
846
|
-
});
|
|
847
|
-
|
|
490
|
+
const initializationError = error instanceof OidcInitializationError
|
|
491
|
+
? error
|
|
492
|
+
: new OidcInitializationError({
|
|
493
|
+
isAuthServerLikelyDown: false,
|
|
494
|
+
messageOrCause: error
|
|
495
|
+
});
|
|
848
496
|
if (autoLogin) {
|
|
849
497
|
throw initializationError;
|
|
850
498
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
].join("\n")
|
|
859
|
-
);
|
|
860
|
-
|
|
861
|
-
return id<Oidc.NotLoggedIn>({
|
|
499
|
+
console.error([
|
|
500
|
+
`oidc-spa Initialization Error: `,
|
|
501
|
+
`isAuthServerLikelyDown: ${initializationError.isAuthServerLikelyDown}`,
|
|
502
|
+
``,
|
|
503
|
+
initializationError.message
|
|
504
|
+
].join("\n"));
|
|
505
|
+
return id({
|
|
862
506
|
...oidc_common,
|
|
863
507
|
isUserLoggedIn: false,
|
|
864
508
|
login: async () => {
|
|
865
509
|
alert("Authentication is currently unavailable. Please try again later.");
|
|
866
|
-
return new Promise
|
|
510
|
+
return new Promise(() => { });
|
|
867
511
|
},
|
|
868
512
|
initializationError
|
|
869
513
|
});
|
|
870
514
|
}
|
|
871
|
-
|
|
872
515
|
if (resultOfLoginProcess === undefined) {
|
|
873
516
|
log?.("User not logged in");
|
|
874
|
-
|
|
875
|
-
return id<Oidc.NotLoggedIn>({
|
|
517
|
+
return id({
|
|
876
518
|
...oidc_common,
|
|
877
519
|
isUserLoggedIn: false,
|
|
878
|
-
login: async ({
|
|
879
|
-
doesCurrentHrefRequiresAuth,
|
|
880
|
-
extraQueryParams,
|
|
881
|
-
redirectUrl,
|
|
882
|
-
transformUrlBeforeRedirect
|
|
883
|
-
}) => {
|
|
520
|
+
login: async ({ doesCurrentHrefRequiresAuth, extraQueryParams, redirectUrl, transformUrlBeforeRedirect }) => {
|
|
884
521
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
885
522
|
prUnlock: getPrSafelyRestoredFromBfCacheAfterLoginBackNavigation()
|
|
886
523
|
});
|
|
887
|
-
|
|
888
524
|
return loginOrGoToAuthServer({
|
|
889
525
|
action: "login",
|
|
890
|
-
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack:
|
|
891
|
-
doesCurrentHrefRequiresAuth,
|
|
526
|
+
doNavigateBackToLastPublicUrlIfTheTheUserNavigateBack: doesCurrentHrefRequiresAuth,
|
|
892
527
|
doForceReloadOnBfCache: false,
|
|
893
|
-
redirectUrl:
|
|
894
|
-
redirectUrl ?? postLoginRedirectUrl_default ?? window.location.href,
|
|
528
|
+
redirectUrl: redirectUrl ?? postLoginRedirectUrl_default ?? window.location.href,
|
|
895
529
|
extraQueryParams_local: extraQueryParams,
|
|
896
530
|
transformUrlBeforeRedirect_local: transformUrlBeforeRedirect,
|
|
897
|
-
interaction:
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
: "directly redirect if active session show login otherwise"
|
|
531
|
+
interaction: getPersistedAuthState({ configId }) === "explicitly logged out"
|
|
532
|
+
? "ensure interaction"
|
|
533
|
+
: "directly redirect if active session show login otherwise"
|
|
901
534
|
});
|
|
902
535
|
},
|
|
903
536
|
initializationError: undefined
|
|
904
537
|
});
|
|
905
538
|
}
|
|
906
|
-
|
|
907
|
-
assert<Equals<typeof resultOfLoginProcess, never>>(false);
|
|
539
|
+
assert(false);
|
|
908
540
|
})();
|
|
909
|
-
|
|
910
541
|
{
|
|
911
542
|
const { prOtherTabLogin } = getPrOtherTabLogin({
|
|
912
543
|
configId
|
|
913
544
|
});
|
|
914
|
-
|
|
915
545
|
prOtherTabLogin.then(async () => {
|
|
916
546
|
log?.(`Other tab has logged in, reloading this tab`);
|
|
917
|
-
|
|
918
547
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
919
|
-
prUnlock: new Promise
|
|
548
|
+
prUnlock: new Promise(() => { })
|
|
920
549
|
});
|
|
921
|
-
|
|
922
550
|
window.location.reload();
|
|
923
551
|
});
|
|
924
552
|
}
|
|
925
|
-
|
|
926
553
|
// @ts-expect-error: We know what we're doing
|
|
927
554
|
return oidc_notLoggedIn;
|
|
928
555
|
}
|
|
929
|
-
|
|
930
556
|
log?.("User is logged in");
|
|
931
|
-
|
|
932
557
|
evtIsUserLoggedIn.post(true);
|
|
933
|
-
|
|
934
558
|
let currentTokens = oidcClientTsUserToTokens({
|
|
935
559
|
oidcClientTsUser: resultOfLoginProcess.oidcClientTsUser,
|
|
936
560
|
decodedIdTokenSchema,
|
|
@@ -938,12 +562,10 @@ export async function createOidc_nonMemoized<
|
|
|
938
562
|
decodedIdToken_previous: undefined,
|
|
939
563
|
log
|
|
940
564
|
});
|
|
941
|
-
|
|
942
565
|
{
|
|
943
566
|
if (getPersistedAuthState({ configId }) !== undefined) {
|
|
944
567
|
persistAuthState({ configId, state: undefined });
|
|
945
568
|
}
|
|
946
|
-
|
|
947
569
|
if (!canUseIframe) {
|
|
948
570
|
persistAuthState({
|
|
949
571
|
configId,
|
|
@@ -955,21 +577,13 @@ export async function createOidc_nonMemoized<
|
|
|
955
577
|
});
|
|
956
578
|
}
|
|
957
579
|
}
|
|
958
|
-
|
|
959
|
-
const
|
|
960
|
-
(params: { secondsLeft: number | undefined }) => void
|
|
961
|
-
>();
|
|
962
|
-
|
|
963
|
-
const onTokenChanges = new Set<(tokens: Oidc.Tokens<DecodedIdToken>) => void>();
|
|
964
|
-
|
|
580
|
+
const autoLogoutCountdownTickCallbacks = new Set();
|
|
581
|
+
const onTokenChanges = new Set();
|
|
965
582
|
const { sid: sessionId, sub: subjectId } = currentTokens.decodedIdToken_original;
|
|
966
|
-
|
|
967
583
|
assert(subjectId !== undefined, "The 'sub' claim is missing from the id token");
|
|
968
584
|
assert(sessionId === undefined || typeof sessionId === "string");
|
|
969
|
-
|
|
970
585
|
let wouldHaveAutoLoggedOutIfBrowserWasOnline = false;
|
|
971
|
-
|
|
972
|
-
const oidc_loggedIn = id<Oidc.LoggedIn<DecodedIdToken>>({
|
|
586
|
+
const oidc_loggedIn = id({
|
|
973
587
|
...oidc_common,
|
|
974
588
|
isUserLoggedIn: true,
|
|
975
589
|
getTokens: async () => {
|
|
@@ -977,40 +591,31 @@ export async function createOidc_nonMemoized<
|
|
|
977
591
|
await oidc_loggedIn.logout(autoLogoutParams);
|
|
978
592
|
assert(false);
|
|
979
593
|
}
|
|
980
|
-
|
|
981
594
|
renew_tokens: {
|
|
982
595
|
{
|
|
983
|
-
const msBeforeExpirationOfTheAccessToken =
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
if (msBeforeExpirationOfTheAccessToken > 30_000) {
|
|
596
|
+
const msBeforeExpirationOfTheAccessToken = currentTokens.accessTokenExpirationTime - Date.now();
|
|
597
|
+
if (msBeforeExpirationOfTheAccessToken > 30000) {
|
|
987
598
|
break renew_tokens;
|
|
988
599
|
}
|
|
989
600
|
}
|
|
990
|
-
|
|
991
601
|
{
|
|
992
602
|
const msElapsedSinceCurrentTokenWereIssued = Date.now() - currentTokens.issuedAtTime;
|
|
993
|
-
|
|
994
|
-
if (msElapsedSinceCurrentTokenWereIssued < 5_000) {
|
|
603
|
+
if (msElapsedSinceCurrentTokenWereIssued < 5000) {
|
|
995
604
|
break renew_tokens;
|
|
996
605
|
}
|
|
997
606
|
}
|
|
998
|
-
|
|
999
607
|
await oidc_loggedIn.renewTokens();
|
|
1000
608
|
}
|
|
1001
|
-
|
|
1002
609
|
return currentTokens;
|
|
1003
610
|
},
|
|
1004
611
|
getDecodedIdToken: () => currentTokens.decodedIdToken,
|
|
1005
|
-
logout: async params => {
|
|
612
|
+
logout: async (params) => {
|
|
1006
613
|
if (globalContext.hasLogoutBeenCalled) {
|
|
1007
614
|
log?.("logout() has already been called, ignoring the call");
|
|
1008
|
-
return new Promise
|
|
615
|
+
return new Promise(() => { });
|
|
1009
616
|
}
|
|
1010
|
-
|
|
1011
617
|
globalContext.hasLogoutBeenCalled = true;
|
|
1012
|
-
|
|
1013
|
-
const postLogoutRedirectUrl: string = (() => {
|
|
618
|
+
const postLogoutRedirectUrl = (() => {
|
|
1014
619
|
switch (params.redirectTo) {
|
|
1015
620
|
case "current page":
|
|
1016
621
|
return window.location.href;
|
|
@@ -1023,18 +628,15 @@ export async function createOidc_nonMemoized<
|
|
|
1023
628
|
});
|
|
1024
629
|
}
|
|
1025
630
|
})();
|
|
1026
|
-
|
|
1027
631
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
1028
|
-
prUnlock: new Promise
|
|
632
|
+
prUnlock: new Promise(() => { })
|
|
1029
633
|
});
|
|
1030
|
-
|
|
1031
634
|
window.addEventListener("pageshow", () => {
|
|
1032
635
|
location.reload();
|
|
1033
636
|
});
|
|
1034
|
-
|
|
1035
637
|
try {
|
|
1036
638
|
await oidcClientTsUserManager.signoutRedirect({
|
|
1037
|
-
state: id
|
|
639
|
+
state: id({
|
|
1038
640
|
configId,
|
|
1039
641
|
context: "redirect",
|
|
1040
642
|
redirectUrl: postLogoutRedirectUrl,
|
|
@@ -1044,50 +646,41 @@ export async function createOidc_nonMemoized<
|
|
|
1044
646
|
}),
|
|
1045
647
|
redirectMethod: "assign"
|
|
1046
648
|
});
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
|
|
649
|
+
}
|
|
650
|
+
catch (error) {
|
|
651
|
+
assert(is(error));
|
|
1050
652
|
if (error.message === "No end session endpoint") {
|
|
1051
653
|
log?.("No end session endpoint, managing logging state locally");
|
|
1052
|
-
|
|
1053
654
|
persistAuthState({ configId, state: { stateDescription: "explicitly logged out" } });
|
|
1054
|
-
|
|
1055
655
|
try {
|
|
1056
656
|
await oidcClientTsUserManager.removeUser();
|
|
1057
|
-
}
|
|
657
|
+
}
|
|
658
|
+
catch {
|
|
1058
659
|
// NOTE: Not sure if it can throw
|
|
1059
660
|
}
|
|
1060
|
-
|
|
1061
661
|
notifyOtherTabsOfLogout({
|
|
1062
662
|
configId,
|
|
1063
663
|
sessionId
|
|
1064
664
|
});
|
|
1065
|
-
|
|
1066
665
|
window.location.href = postLogoutRedirectUrl;
|
|
1067
|
-
}
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
1068
668
|
throw error;
|
|
1069
669
|
}
|
|
1070
670
|
}
|
|
1071
|
-
|
|
1072
|
-
return new Promise<never>(() => {});
|
|
671
|
+
return new Promise(() => { });
|
|
1073
672
|
},
|
|
1074
673
|
renewTokens: (() => {
|
|
1075
|
-
async function renewTokens_nonMutexed(params
|
|
1076
|
-
extraTokenParams: Record<string, string | undefined>;
|
|
1077
|
-
}) {
|
|
674
|
+
async function renewTokens_nonMutexed(params) {
|
|
1078
675
|
const { extraTokenParams } = params;
|
|
1079
|
-
|
|
1080
|
-
const fallbackToFullPageReload = async (): Promise<never> => {
|
|
676
|
+
const fallbackToFullPageReload = async () => {
|
|
1081
677
|
persistAuthState({ configId, state: undefined });
|
|
1082
|
-
|
|
1083
678
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
1084
|
-
prUnlock: new Promise
|
|
679
|
+
prUnlock: new Promise(() => { })
|
|
1085
680
|
});
|
|
1086
|
-
|
|
1087
681
|
globalContext.evtRequestToPersistTokens.post({
|
|
1088
682
|
configIdOfInstancePostingTheRequest: configId
|
|
1089
683
|
});
|
|
1090
|
-
|
|
1091
684
|
await loginOrGoToAuthServer({
|
|
1092
685
|
action: "login",
|
|
1093
686
|
redirectUrl: window.location.href,
|
|
@@ -1099,26 +692,18 @@ export async function createOidc_nonMemoized<
|
|
|
1099
692
|
});
|
|
1100
693
|
assert(false, "136134");
|
|
1101
694
|
};
|
|
1102
|
-
|
|
1103
695
|
if (!currentTokens.hasRefreshToken && !canUseIframe) {
|
|
1104
|
-
log?.(
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
].join(" ")
|
|
1111
|
-
);
|
|
1112
|
-
|
|
696
|
+
log?.([
|
|
697
|
+
"Unable to refresh tokens without a full app reload,",
|
|
698
|
+
"because no refresh token is available",
|
|
699
|
+
"and your app setup prevents silent sign-in via iframe.",
|
|
700
|
+
"Your only option to refresh tokens is to call `window.location.reload()`"
|
|
701
|
+
].join(" "));
|
|
1113
702
|
await fallbackToFullPageReload();
|
|
1114
|
-
|
|
1115
703
|
assert(false, "136135");
|
|
1116
704
|
}
|
|
1117
|
-
|
|
1118
705
|
log?.("Renewing tokens");
|
|
1119
|
-
|
|
1120
706
|
const { completeLoginOrRefreshProcess } = await startLoginOrRefreshProcess();
|
|
1121
|
-
|
|
1122
707
|
const result_loginSilent = await loginSilent({
|
|
1123
708
|
oidcClientTsUserManager,
|
|
1124
709
|
stateUrlParamValue_instance,
|
|
@@ -1128,16 +713,13 @@ export async function createOidc_nonMemoized<
|
|
|
1128
713
|
getExtraTokenParams: () => extraTokenParams,
|
|
1129
714
|
autoLogin
|
|
1130
715
|
});
|
|
1131
|
-
|
|
1132
716
|
if (result_loginSilent.outcome === "failure") {
|
|
1133
717
|
completeLoginOrRefreshProcess();
|
|
1134
718
|
// NOTE: This is a configuration or network error, okay to throw,
|
|
1135
719
|
// this exception doesn't have to be handle if it fails it fails.
|
|
1136
720
|
throw new Error(result_loginSilent.cause);
|
|
1137
721
|
}
|
|
1138
|
-
|
|
1139
|
-
let oidcClientTsUser: OidcClientTsUser;
|
|
1140
|
-
|
|
722
|
+
let oidcClientTsUser;
|
|
1141
723
|
switch (result_loginSilent.outcome) {
|
|
1142
724
|
case "token refreshed using refresh token":
|
|
1143
725
|
{
|
|
@@ -1148,54 +730,39 @@ export async function createOidc_nonMemoized<
|
|
|
1148
730
|
case "got auth response from iframe":
|
|
1149
731
|
{
|
|
1150
732
|
const { authResponse } = result_loginSilent;
|
|
1151
|
-
|
|
1152
733
|
log?.("Tokens refresh using iframe", authResponse);
|
|
1153
|
-
|
|
1154
734
|
const authResponse_error = authResponse.error;
|
|
1155
|
-
|
|
1156
|
-
let oidcClientTsUser_scope: OidcClientTsUser | undefined = undefined;
|
|
1157
|
-
|
|
735
|
+
let oidcClientTsUser_scope = undefined;
|
|
1158
736
|
try {
|
|
1159
737
|
oidcClientTsUser_scope =
|
|
1160
|
-
await oidcClientTsUserManager.signinRedirectCallback(
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
} catch (error) {
|
|
738
|
+
await oidcClientTsUserManager.signinRedirectCallback(authResponseToUrl(authResponse));
|
|
739
|
+
}
|
|
740
|
+
catch (error) {
|
|
1164
741
|
assert(error instanceof Error, "321389");
|
|
1165
|
-
|
|
1166
742
|
if (authResponse_error === undefined) {
|
|
1167
743
|
completeLoginOrRefreshProcess();
|
|
1168
744
|
// Same here, if it fails it fails.
|
|
1169
745
|
throw error;
|
|
1170
746
|
}
|
|
1171
747
|
}
|
|
1172
|
-
|
|
1173
748
|
if (oidcClientTsUser_scope === undefined) {
|
|
1174
749
|
// NOTE: Here we got a response but it's an error, session might have been
|
|
1175
750
|
// deleted or other edge case.
|
|
1176
|
-
|
|
1177
751
|
completeLoginOrRefreshProcess();
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
"need to redirect to login pages"
|
|
1183
|
-
].join(" ")
|
|
1184
|
-
);
|
|
1185
|
-
|
|
752
|
+
log?.([
|
|
753
|
+
"The user is probably not logged in anymore,",
|
|
754
|
+
"need to redirect to login pages"
|
|
755
|
+
].join(" "));
|
|
1186
756
|
await fallbackToFullPageReload();
|
|
1187
|
-
|
|
1188
757
|
assert(false, "136135");
|
|
1189
758
|
}
|
|
1190
|
-
|
|
1191
759
|
oidcClientTsUser = oidcClientTsUser_scope;
|
|
1192
760
|
}
|
|
1193
761
|
break;
|
|
1194
762
|
default:
|
|
1195
|
-
assert
|
|
763
|
+
assert(false);
|
|
1196
764
|
break;
|
|
1197
765
|
}
|
|
1198
|
-
|
|
1199
766
|
currentTokens = oidcClientTsUserToTokens({
|
|
1200
767
|
oidcClientTsUser,
|
|
1201
768
|
decodedIdTokenSchema,
|
|
@@ -1203,7 +770,6 @@ export async function createOidc_nonMemoized<
|
|
|
1203
770
|
decodedIdToken_previous: currentTokens.decodedIdToken,
|
|
1204
771
|
log
|
|
1205
772
|
});
|
|
1206
|
-
|
|
1207
773
|
if (getPersistedAuthState({ configId }) !== undefined) {
|
|
1208
774
|
persistAuthState({
|
|
1209
775
|
configId,
|
|
@@ -1214,77 +780,54 @@ export async function createOidc_nonMemoized<
|
|
|
1214
780
|
}
|
|
1215
781
|
});
|
|
1216
782
|
}
|
|
1217
|
-
|
|
1218
783
|
Array.from(onTokenChanges).forEach(onTokenChange => onTokenChange(currentTokens));
|
|
1219
|
-
|
|
1220
784
|
completeLoginOrRefreshProcess();
|
|
1221
785
|
}
|
|
1222
|
-
|
|
1223
|
-
let ongoingCall:
|
|
1224
|
-
| {
|
|
1225
|
-
pr: Promise<void>;
|
|
1226
|
-
extraTokenParams: Record<string, string | undefined>;
|
|
1227
|
-
}
|
|
1228
|
-
| undefined = undefined;
|
|
1229
|
-
|
|
786
|
+
let ongoingCall = undefined;
|
|
1230
787
|
function handleFinally() {
|
|
1231
788
|
assert(ongoingCall !== undefined, "131276");
|
|
1232
|
-
|
|
1233
789
|
const { pr } = ongoingCall;
|
|
1234
|
-
|
|
1235
790
|
pr.finally(() => {
|
|
1236
791
|
assert(ongoingCall !== undefined, "549462");
|
|
1237
|
-
|
|
1238
792
|
if (ongoingCall.pr !== pr) {
|
|
1239
793
|
return;
|
|
1240
794
|
}
|
|
1241
|
-
|
|
1242
795
|
ongoingCall = undefined;
|
|
1243
796
|
});
|
|
1244
797
|
}
|
|
1245
|
-
|
|
1246
|
-
return async params => {
|
|
798
|
+
return async (params) => {
|
|
1247
799
|
const { extraTokenParams: extraTokenParams_local } = params ?? {};
|
|
1248
|
-
|
|
1249
800
|
const extraTokenParams = {
|
|
1250
801
|
...getExtraTokenParams?.(),
|
|
1251
802
|
...extraTokenParams_local
|
|
1252
803
|
};
|
|
1253
|
-
|
|
1254
804
|
if (ongoingCall === undefined) {
|
|
1255
805
|
ongoingCall = {
|
|
1256
806
|
pr: renewTokens_nonMutexed({ extraTokenParams }),
|
|
1257
807
|
extraTokenParams
|
|
1258
808
|
};
|
|
1259
|
-
|
|
1260
809
|
handleFinally();
|
|
1261
|
-
|
|
1262
810
|
return ongoingCall.pr;
|
|
1263
811
|
}
|
|
1264
|
-
|
|
1265
812
|
if (JSON.stringify(extraTokenParams) === JSON.stringify(ongoingCall.extraTokenParams)) {
|
|
1266
813
|
return ongoingCall.pr;
|
|
1267
814
|
}
|
|
1268
|
-
|
|
1269
815
|
ongoingCall = {
|
|
1270
816
|
pr: (async () => {
|
|
1271
817
|
try {
|
|
1272
818
|
await ongoingCall.pr;
|
|
1273
|
-
}
|
|
1274
|
-
|
|
819
|
+
}
|
|
820
|
+
catch { }
|
|
1275
821
|
return renewTokens_nonMutexed({ extraTokenParams });
|
|
1276
822
|
})(),
|
|
1277
823
|
extraTokenParams
|
|
1278
824
|
};
|
|
1279
|
-
|
|
1280
825
|
handleFinally();
|
|
1281
|
-
|
|
1282
826
|
return ongoingCall.pr;
|
|
1283
827
|
};
|
|
1284
828
|
})(),
|
|
1285
829
|
subscribeToTokensChange: onTokenChange => {
|
|
1286
830
|
onTokenChanges.add(onTokenChange);
|
|
1287
|
-
|
|
1288
831
|
return {
|
|
1289
832
|
unsubscribe: () => {
|
|
1290
833
|
onTokenChanges.delete(onTokenChange);
|
|
@@ -1293,283 +836,203 @@ export async function createOidc_nonMemoized<
|
|
|
1293
836
|
},
|
|
1294
837
|
subscribeToAutoLogoutCountdown: tickCallback => {
|
|
1295
838
|
autoLogoutCountdownTickCallbacks.add(tickCallback);
|
|
1296
|
-
|
|
1297
839
|
const unsubscribeFromAutoLogoutCountdown = () => {
|
|
1298
840
|
autoLogoutCountdownTickCallbacks.delete(tickCallback);
|
|
1299
841
|
};
|
|
1300
|
-
|
|
1301
842
|
return { unsubscribeFromAutoLogoutCountdown };
|
|
1302
843
|
},
|
|
1303
|
-
goToAuthServer: ({ extraQueryParams, redirectUrl, transformUrlBeforeRedirect }) =>
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
}),
|
|
844
|
+
goToAuthServer: ({ extraQueryParams, redirectUrl, transformUrlBeforeRedirect }) => loginOrGoToAuthServer({
|
|
845
|
+
action: "go to auth server",
|
|
846
|
+
redirectUrl: redirectUrl ?? window.location.href,
|
|
847
|
+
extraQueryParams_local: extraQueryParams,
|
|
848
|
+
transformUrlBeforeRedirect_local: transformUrlBeforeRedirect
|
|
849
|
+
}),
|
|
1310
850
|
backFromAuthServer: resultOfLoginProcess.backFromAuthServer,
|
|
1311
851
|
isNewBrowserSession: (() => {
|
|
1312
852
|
const value = getIsNewBrowserSession({ subjectId });
|
|
1313
|
-
|
|
1314
853
|
log?.(`isNewBrowserSession: ${value}`);
|
|
1315
|
-
|
|
1316
854
|
return value;
|
|
1317
855
|
})()
|
|
1318
856
|
});
|
|
1319
|
-
|
|
1320
857
|
{
|
|
1321
858
|
const { prOtherTabLogout } = getPrOtherTabLogout({
|
|
1322
859
|
configId,
|
|
1323
860
|
sessionId
|
|
1324
861
|
});
|
|
1325
|
-
|
|
1326
862
|
prOtherTabLogout.then(async () => {
|
|
1327
863
|
log?.(`Other tab has logged out, refreshing current tab`);
|
|
1328
|
-
|
|
1329
864
|
await waitForAllOtherOngoingLoginOrRefreshProcessesToComplete({
|
|
1330
|
-
prUnlock: new Promise
|
|
865
|
+
prUnlock: new Promise(() => { })
|
|
1331
866
|
});
|
|
1332
|
-
|
|
1333
867
|
location.reload();
|
|
1334
868
|
});
|
|
1335
869
|
}
|
|
1336
|
-
|
|
1337
870
|
(function scheduleRenew() {
|
|
1338
871
|
if (!currentTokens.hasRefreshToken && !canUseIframe) {
|
|
1339
|
-
log?.(
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
].join(" ")
|
|
1344
|
-
);
|
|
872
|
+
log?.([
|
|
873
|
+
"Disabling token auto refresh mechanism because we",
|
|
874
|
+
"have no way to renew the tokens without a full page reload"
|
|
875
|
+
].join(" "));
|
|
1345
876
|
return;
|
|
1346
877
|
}
|
|
1347
|
-
|
|
1348
|
-
const msBeforeExpiration =
|
|
1349
|
-
(currentTokens.refreshTokenExpirationTime ?? currentTokens.accessTokenExpirationTime) -
|
|
878
|
+
const msBeforeExpiration = (currentTokens.refreshTokenExpirationTime ?? currentTokens.accessTokenExpirationTime) -
|
|
1350
879
|
Date.now();
|
|
1351
|
-
|
|
1352
|
-
const
|
|
1353
|
-
currentTokens.refreshTokenExpirationTime !== undefined ? "refresh" : "access";
|
|
1354
|
-
|
|
1355
|
-
const RENEW_MS_BEFORE_EXPIRES = 30_000;
|
|
1356
|
-
|
|
880
|
+
const typeOfTheTokenWeGotTheTtlFrom = currentTokens.refreshTokenExpirationTime !== undefined ? "refresh" : "access";
|
|
881
|
+
const RENEW_MS_BEFORE_EXPIRES = 30000;
|
|
1357
882
|
if (msBeforeExpiration <= RENEW_MS_BEFORE_EXPIRES) {
|
|
1358
883
|
// NOTE: We just got a new token that is about to expire. This means that
|
|
1359
884
|
// the refresh token has reached it's max SSO time.
|
|
1360
885
|
// ...or that the refresh token have a very short lifespan...
|
|
1361
886
|
// anyway, no need to keep alive, it will probably redirect on the next getTokens() or refreshTokens() call
|
|
1362
|
-
log?.(
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
(
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
].join(" ")
|
|
1387
|
-
);
|
|
887
|
+
log?.([
|
|
888
|
+
"Disabling auto renew mechanism. We just got fresh tokens",
|
|
889
|
+
(() => {
|
|
890
|
+
switch (typeOfTheTokenWeGotTheTtlFrom) {
|
|
891
|
+
case "refresh":
|
|
892
|
+
return [
|
|
893
|
+
" and the refresh token is already about to expires.",
|
|
894
|
+
"This means that we have reached the max session lifespan, we can't keep",
|
|
895
|
+
"the session alive any longer.",
|
|
896
|
+
"(This can also mean that the refresh token was configured with a TTL,",
|
|
897
|
+
"aka the idle session lifespan, too low to make sense)"
|
|
898
|
+
].join(" ");
|
|
899
|
+
case "access":
|
|
900
|
+
return [
|
|
901
|
+
currentTokens.hasRefreshToken
|
|
902
|
+
? ", we can't read the expiration time of the refresh token"
|
|
903
|
+
: ", we don't have a refresh token",
|
|
904
|
+
` and the access token is already about to expire`,
|
|
905
|
+
"we would spam the auth server by constantly renewing the access token in the background",
|
|
906
|
+
"avoiding to do so."
|
|
907
|
+
].join(" ");
|
|
908
|
+
}
|
|
909
|
+
})()
|
|
910
|
+
].join(" "));
|
|
1388
911
|
return;
|
|
1389
912
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
prOnline.then(() => true)
|
|
1412
|
-
]);
|
|
1413
|
-
|
|
1414
|
-
if (!didCameBackOnlineInTime) {
|
|
1415
|
-
log?.(
|
|
1416
|
-
[
|
|
1417
|
-
"The session expired on the OIDC server.",
|
|
1418
|
-
"We couldn't keep it alive because the browser was offline.",
|
|
1419
|
-
"We are not redirecting to the login page to support PWAs with offline features.",
|
|
1420
|
-
"However, the next getTokens() call will trigger a redirect to the Auth server login page."
|
|
1421
|
-
].join(" ")
|
|
1422
|
-
);
|
|
1423
|
-
return;
|
|
1424
|
-
}
|
|
913
|
+
log?.([
|
|
914
|
+
toHumanReadableDuration(msBeforeExpiration),
|
|
915
|
+
`before expiration of the ${typeOfTheTokenWeGotTheTtlFrom} token.`,
|
|
916
|
+
`Scheduling renewal ${toHumanReadableDuration(RENEW_MS_BEFORE_EXPIRES)} before expiration to keep the session alive on the OIDC server.`
|
|
917
|
+
].join(" "));
|
|
918
|
+
const timer = setTimeout(async () => {
|
|
919
|
+
{
|
|
920
|
+
const { isOnline, prOnline } = getIsOnline();
|
|
921
|
+
if (!isOnline) {
|
|
922
|
+
const didCameBackOnlineInTime = await Promise.race([
|
|
923
|
+
new Promise(resolve => setTimeout(() => resolve(false), RENEW_MS_BEFORE_EXPIRES - 1000)),
|
|
924
|
+
prOnline.then(() => true)
|
|
925
|
+
]);
|
|
926
|
+
if (!didCameBackOnlineInTime) {
|
|
927
|
+
log?.([
|
|
928
|
+
"The session expired on the OIDC server.",
|
|
929
|
+
"We couldn't keep it alive because the browser was offline.",
|
|
930
|
+
"We are not redirecting to the login page to support PWAs with offline features.",
|
|
931
|
+
"However, the next getTokens() call will trigger a redirect to the Auth server login page."
|
|
932
|
+
].join(" "));
|
|
933
|
+
return;
|
|
1425
934
|
}
|
|
1426
935
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
},
|
|
1436
|
-
Math.min(
|
|
1437
|
-
msBeforeExpiration - RENEW_MS_BEFORE_EXPIRES,
|
|
1438
|
-
// NOTE: We want to make sure we do not overflow the setTimeout
|
|
1439
|
-
// that must be a 32 bit unsigned integer.
|
|
1440
|
-
// This can happen if the tokenExpirationTime is more than 24.8 days in the future.
|
|
1441
|
-
Math.pow(2, 31) - 1
|
|
1442
|
-
)
|
|
1443
|
-
);
|
|
1444
|
-
|
|
936
|
+
}
|
|
937
|
+
log?.(`Renewing the tokens now as the ${typeOfTheTokenWeGotTheTtlFrom} token will expire in ${toHumanReadableDuration(RENEW_MS_BEFORE_EXPIRES)}`);
|
|
938
|
+
await oidc_loggedIn.renewTokens();
|
|
939
|
+
}, Math.min(msBeforeExpiration - RENEW_MS_BEFORE_EXPIRES,
|
|
940
|
+
// NOTE: We want to make sure we do not overflow the setTimeout
|
|
941
|
+
// that must be a 32 bit unsigned integer.
|
|
942
|
+
// This can happen if the tokenExpirationTime is more than 24.8 days in the future.
|
|
943
|
+
Math.pow(2, 31) - 1));
|
|
1445
944
|
const { unsubscribe: tokenChangeUnsubscribe } = oidc_loggedIn.subscribeToTokensChange(() => {
|
|
1446
945
|
clearTimeout(timer);
|
|
1447
946
|
tokenChangeUnsubscribe();
|
|
1448
947
|
scheduleRenew();
|
|
1449
948
|
});
|
|
1450
949
|
})();
|
|
1451
|
-
|
|
1452
950
|
auto_logout: {
|
|
1453
951
|
const getCurrentRefreshTokenTtlInSeconds = () => {
|
|
1454
952
|
if (idleSessionLifetimeInSeconds !== undefined) {
|
|
1455
953
|
return idleSessionLifetimeInSeconds;
|
|
1456
954
|
}
|
|
1457
|
-
|
|
1458
955
|
if (currentTokens.refreshTokenExpirationTime === undefined) {
|
|
1459
956
|
return undefined;
|
|
1460
957
|
}
|
|
1461
|
-
|
|
1462
958
|
return (currentTokens.refreshTokenExpirationTime - currentTokens.issuedAtTime) / 1000;
|
|
1463
959
|
};
|
|
1464
|
-
|
|
1465
960
|
if (getCurrentRefreshTokenTtlInSeconds() === undefined) {
|
|
1466
|
-
log?.(
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
? "The refresh token is opaque, we can't read it's expiration time"
|
|
1470
|
-
: "No refresh token"
|
|
1471
|
-
}, and idleSessionLifetimeInSeconds was not set, can't implement auto logout mechanism`
|
|
1472
|
-
);
|
|
961
|
+
log?.(`${currentTokens.hasRefreshToken
|
|
962
|
+
? "The refresh token is opaque, we can't read it's expiration time"
|
|
963
|
+
: "No refresh token"}, and idleSessionLifetimeInSeconds was not set, can't implement auto logout mechanism`);
|
|
1473
964
|
break auto_logout;
|
|
1474
965
|
}
|
|
1475
|
-
|
|
1476
966
|
const { startCountdown } = createStartCountdown({
|
|
1477
967
|
tickCallback: async ({ secondsLeft }) => {
|
|
1478
|
-
const invokeAllCallbacks = (params
|
|
968
|
+
const invokeAllCallbacks = (params) => {
|
|
1479
969
|
const { secondsLeft } = params;
|
|
1480
|
-
Array.from(autoLogoutCountdownTickCallbacks).forEach(tickCallback =>
|
|
1481
|
-
tickCallback({ secondsLeft })
|
|
1482
|
-
);
|
|
970
|
+
Array.from(autoLogoutCountdownTickCallbacks).forEach(tickCallback => tickCallback({ secondsLeft }));
|
|
1483
971
|
};
|
|
1484
|
-
|
|
1485
972
|
invokeAllCallbacks({ secondsLeft });
|
|
1486
|
-
|
|
1487
973
|
if (secondsLeft === 0) {
|
|
1488
974
|
cancel_if_offline: {
|
|
1489
975
|
const { isOnline, prOnline } = getIsOnline();
|
|
1490
|
-
|
|
1491
976
|
if (isOnline) {
|
|
1492
977
|
break cancel_if_offline;
|
|
1493
978
|
}
|
|
1494
|
-
|
|
1495
979
|
const didCameBackOnline = await Promise.race([
|
|
1496
|
-
new Promise
|
|
980
|
+
new Promise(resolve => setTimeout(() => resolve(false), 10000)),
|
|
1497
981
|
prOnline.then(() => true)
|
|
1498
982
|
]);
|
|
1499
|
-
|
|
1500
983
|
if (didCameBackOnline) {
|
|
1501
984
|
break cancel_if_offline;
|
|
1502
985
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
"Next getTokens() is called logout will be called"
|
|
1511
|
-
].join(" ")
|
|
1512
|
-
);
|
|
1513
|
-
|
|
986
|
+
log?.([
|
|
987
|
+
"Normally now we should auto logout.",
|
|
988
|
+
"However since the browser is currently offline",
|
|
989
|
+
"we avoid calling logout() now to play nice in case",
|
|
990
|
+
"this app is a PWA.",
|
|
991
|
+
"Next getTokens() is called logout will be called"
|
|
992
|
+
].join(" "));
|
|
1514
993
|
unsubscribeFromIsUserActive();
|
|
1515
|
-
|
|
1516
994
|
invokeAllCallbacks({ secondsLeft: undefined });
|
|
1517
|
-
|
|
1518
995
|
wouldHaveAutoLoggedOutIfBrowserWasOnline = true;
|
|
1519
|
-
|
|
1520
996
|
return;
|
|
1521
997
|
}
|
|
1522
|
-
|
|
1523
998
|
await oidc_loggedIn.logout(autoLogoutParams);
|
|
1524
999
|
}
|
|
1525
1000
|
}
|
|
1526
1001
|
});
|
|
1527
|
-
|
|
1528
|
-
let stopCountdown: (() => void) | undefined = undefined;
|
|
1529
|
-
|
|
1002
|
+
let stopCountdown = undefined;
|
|
1530
1003
|
const evtIsUserActive = createEvtIsUserActive({
|
|
1531
1004
|
configId,
|
|
1532
1005
|
sessionId
|
|
1533
1006
|
});
|
|
1534
|
-
|
|
1535
1007
|
const { unsubscribe: unsubscribeFromIsUserActive } = evtIsUserActive.subscribe(isUserActive => {
|
|
1536
1008
|
if (isUserActive) {
|
|
1537
1009
|
if (stopCountdown !== undefined) {
|
|
1538
1010
|
stopCountdown();
|
|
1539
1011
|
stopCountdown = undefined;
|
|
1540
1012
|
}
|
|
1541
|
-
}
|
|
1013
|
+
}
|
|
1014
|
+
else {
|
|
1542
1015
|
assert(stopCountdown === undefined, "902992");
|
|
1543
|
-
|
|
1544
1016
|
const currentRefreshTokenTtlInSeconds = getCurrentRefreshTokenTtlInSeconds();
|
|
1545
|
-
|
|
1546
1017
|
assert(currentRefreshTokenTtlInSeconds !== undefined, "902992326");
|
|
1547
|
-
|
|
1548
1018
|
stopCountdown = startCountdown({
|
|
1549
1019
|
countDownFromSeconds: currentRefreshTokenTtlInSeconds
|
|
1550
1020
|
}).stopCountdown;
|
|
1551
1021
|
}
|
|
1552
1022
|
});
|
|
1553
|
-
|
|
1554
1023
|
{
|
|
1555
1024
|
const currentRefreshTokenTtlInSeconds = getCurrentRefreshTokenTtlInSeconds();
|
|
1556
|
-
|
|
1557
1025
|
assert(currentRefreshTokenTtlInSeconds !== undefined, "9029923253");
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
: `It was artificially defined by using the idleSessionLifetimeInSeconds param.`
|
|
1567
|
-
]
|
|
1568
|
-
.filter(x => x !== undefined)
|
|
1569
|
-
.join("\n")
|
|
1570
|
-
);
|
|
1026
|
+
log?.([
|
|
1027
|
+
`The user will be automatically logged out after ${toHumanReadableDuration(currentRefreshTokenTtlInSeconds * 1000)} of inactivity.`,
|
|
1028
|
+
idleSessionLifetimeInSeconds === undefined
|
|
1029
|
+
? undefined
|
|
1030
|
+
: `It was artificially defined by using the idleSessionLifetimeInSeconds param.`
|
|
1031
|
+
]
|
|
1032
|
+
.filter(x => x !== undefined)
|
|
1033
|
+
.join("\n"));
|
|
1571
1034
|
}
|
|
1572
1035
|
}
|
|
1573
|
-
|
|
1574
1036
|
return oidc_loggedIn;
|
|
1575
1037
|
}
|
|
1038
|
+
//# sourceMappingURL=createOidc.js.map
|