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