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
package/src/core/Oidc.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import type { OidcInitializationError } from "./OidcInitializationError";
|
|
2
|
-
|
|
3
|
-
export declare type Oidc<
|
|
4
|
-
DecodedIdToken extends Record<string, unknown> = Oidc.Tokens.DecodedIdToken_base
|
|
5
|
-
> = Oidc.LoggedIn<DecodedIdToken> | Oidc.NotLoggedIn;
|
|
6
|
-
|
|
7
|
-
export declare namespace Oidc {
|
|
8
|
-
export type Common = {
|
|
9
|
-
params: {
|
|
10
|
-
issuerUri: string;
|
|
11
|
-
clientId: string;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type NotLoggedIn = Common & {
|
|
16
|
-
isUserLoggedIn: false;
|
|
17
|
-
login: (params: {
|
|
18
|
-
doesCurrentHrefRequiresAuth: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Add extra query parameters to the url before redirecting to the login pages.
|
|
21
|
-
*/
|
|
22
|
-
extraQueryParams?: Record<string, string | undefined>;
|
|
23
|
-
/**
|
|
24
|
-
* Where to redirect after successful login.
|
|
25
|
-
* Default: window.location.href (here)
|
|
26
|
-
*
|
|
27
|
-
* It does not need to include the origin, eg: "/dashboard"
|
|
28
|
-
*/
|
|
29
|
-
redirectUrl?: string;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Transform the url before redirecting to the login pages.
|
|
33
|
-
* Prefer using the extraQueryParams parameter if you're only adding query parameters.
|
|
34
|
-
*/
|
|
35
|
-
transformUrlBeforeRedirect?: (url: string) => string;
|
|
36
|
-
}) => Promise<never>;
|
|
37
|
-
initializationError: OidcInitializationError | undefined;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type LoggedIn<DecodedIdToken extends Record<string, unknown> = Record<string, unknown>> =
|
|
41
|
-
Common & {
|
|
42
|
-
isUserLoggedIn: true;
|
|
43
|
-
renewTokens(params?: {
|
|
44
|
-
extraTokenParams?: Record<string, string | undefined>;
|
|
45
|
-
}): Promise<void>;
|
|
46
|
-
getTokens: () => Promise<Tokens<DecodedIdToken>>;
|
|
47
|
-
subscribeToTokensChange: (onTokenChange: (tokens: Tokens<DecodedIdToken>) => void) => {
|
|
48
|
-
unsubscribe: () => void;
|
|
49
|
-
};
|
|
50
|
-
getDecodedIdToken: () => DecodedIdToken;
|
|
51
|
-
logout: (
|
|
52
|
-
params:
|
|
53
|
-
| { redirectTo: "home" | "current page" }
|
|
54
|
-
| { redirectTo: "specific url"; url: string }
|
|
55
|
-
) => Promise<never>;
|
|
56
|
-
goToAuthServer: (params: {
|
|
57
|
-
extraQueryParams?: Record<string, string>;
|
|
58
|
-
redirectUrl?: string;
|
|
59
|
-
transformUrlBeforeRedirect?: (url: string) => string;
|
|
60
|
-
}) => Promise<never>;
|
|
61
|
-
subscribeToAutoLogoutCountdown: (
|
|
62
|
-
tickCallback: (params: { secondsLeft: number | undefined }) => void
|
|
63
|
-
) => { unsubscribeFromAutoLogoutCountdown: () => void };
|
|
64
|
-
/**
|
|
65
|
-
* Defined when authMethod is "back from auth server".
|
|
66
|
-
* If you called `goToAuthServer` or `login` with extraQueryParams, this object let you know the outcome of the
|
|
67
|
-
* of the action that was intended.
|
|
68
|
-
*
|
|
69
|
-
* For example, on a Keycloak server, if you called `goToAuthServer({ extraQueryParams: { kc_action: "UPDATE_PASSWORD" } })`
|
|
70
|
-
* you'll get back: `{ extraQueryParams: { kc_action: "UPDATE_PASSWORD" }, result: { kc_action_status: "success" } }` (or "cancelled")
|
|
71
|
-
*/
|
|
72
|
-
backFromAuthServer:
|
|
73
|
-
| {
|
|
74
|
-
extraQueryParams: Record<string, string>;
|
|
75
|
-
result: Record<string, string>;
|
|
76
|
-
}
|
|
77
|
-
| undefined;
|
|
78
|
-
/**
|
|
79
|
-
* This is true when the user has just returned from the login pages.
|
|
80
|
-
* This is also true when the user navigate to your app and was able to be silently signed in because there was still a valid session.
|
|
81
|
-
* This false however when the use just reload the page.
|
|
82
|
-
*
|
|
83
|
-
* This can be used to perform some action related to session initialization
|
|
84
|
-
* but avoiding doing it repeatedly every time the user reload the page.
|
|
85
|
-
*
|
|
86
|
-
* Note that this is referring to the browser session and not the OIDC session
|
|
87
|
-
* on the server side.
|
|
88
|
-
*
|
|
89
|
-
* If you want to perform an action only when a new OIDC session is created
|
|
90
|
-
* you can test oidc.isNewBrowserSession && oidc.backFromAuthServer !== undefined
|
|
91
|
-
*/
|
|
92
|
-
isNewBrowserSession: boolean;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export type Tokens<DecodedIdToken extends Record<string, unknown> = Tokens.DecodedIdToken_base> =
|
|
96
|
-
| Tokens.WithRefreshToken<DecodedIdToken>
|
|
97
|
-
| Tokens.WithoutRefreshToken<DecodedIdToken>;
|
|
98
|
-
|
|
99
|
-
export namespace Tokens {
|
|
100
|
-
export type Common<DecodedIdToken> = {
|
|
101
|
-
accessToken: string;
|
|
102
|
-
accessTokenExpirationTime: number;
|
|
103
|
-
idToken: string;
|
|
104
|
-
decodedIdToken: DecodedIdToken;
|
|
105
|
-
/**
|
|
106
|
-
* decodedIdToken_original = decodeJwt(idToken);
|
|
107
|
-
* decodedIdToken = decodedIdTokenSchema.parse(decodedIdToken_original)
|
|
108
|
-
*
|
|
109
|
-
* The idea here is that if you have provided a zod schema as `decodedIdTokenSchema`
|
|
110
|
-
* it will strip out every claim that you haven't specified.
|
|
111
|
-
* You might even be applying some transformation.
|
|
112
|
-
*
|
|
113
|
-
* `decodedIdToken_original` is the actual decoded payload of the id_token, untransformed.
|
|
114
|
-
* */
|
|
115
|
-
decodedIdToken_original: DecodedIdToken_base;
|
|
116
|
-
/** Read from id_token's JWT, iat claim value, it's a JavaScript timestamp (millisecond epoch) */
|
|
117
|
-
issuedAtTime: number;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export type WithRefreshToken<DecodedIdToken> = Common<DecodedIdToken> & {
|
|
121
|
-
hasRefreshToken: true;
|
|
122
|
-
refreshToken: string;
|
|
123
|
-
refreshTokenExpirationTime: number | undefined;
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export type WithoutRefreshToken<DecodedIdToken> = Common<DecodedIdToken> & {
|
|
127
|
-
hasRefreshToken: false;
|
|
128
|
-
refreshToken?: never;
|
|
129
|
-
refreshTokenExpirationTime?: never;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export type DecodedIdToken_base = {
|
|
133
|
-
iss: string;
|
|
134
|
-
sub: string;
|
|
135
|
-
aud: string | string[];
|
|
136
|
-
exp: number;
|
|
137
|
-
iat: number;
|
|
138
|
-
[claimName: string]: unknown;
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
}
|
package/src/core/StateData.ts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { typeGuard, assert } from "../vendor/frontend/tsafe";
|
|
2
|
-
import { generateUrlSafeRandom } from "../tools/generateUrlSafeRandom";
|
|
3
|
-
|
|
4
|
-
export type StateData = StateData.IFrame | StateData.Redirect;
|
|
5
|
-
|
|
6
|
-
export namespace StateData {
|
|
7
|
-
type Common = {
|
|
8
|
-
configId: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type IFrame = Common & {
|
|
12
|
-
context: "iframe";
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type Redirect = Redirect.Login | Redirect.Logout;
|
|
16
|
-
export namespace Redirect {
|
|
17
|
-
type Common_Redirect = Common & {
|
|
18
|
-
context: "redirect";
|
|
19
|
-
redirectUrl: string;
|
|
20
|
-
hasBeenProcessedByCallback: boolean;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type Login = Common_Redirect & {
|
|
24
|
-
action: "login";
|
|
25
|
-
redirectUrl_consentRequiredCase: string;
|
|
26
|
-
extraQueryParams: Record<string, string>;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type Logout = Common_Redirect & {
|
|
30
|
-
action: "logout";
|
|
31
|
-
sessionId: string | undefined;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const STATE_QUERY_PARAM_VALUE_IDENTIFIER_PREFIX = "b2lkYy1zcGEu";
|
|
37
|
-
const RANDOM_STRING_LENGTH = 32 - STATE_QUERY_PARAM_VALUE_IDENTIFIER_PREFIX.length;
|
|
38
|
-
|
|
39
|
-
export function generateStateQueryParamValue(): string {
|
|
40
|
-
return `${STATE_QUERY_PARAM_VALUE_IDENTIFIER_PREFIX}${generateUrlSafeRandom({
|
|
41
|
-
length: RANDOM_STRING_LENGTH
|
|
42
|
-
})}`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function getIsStatQueryParamValue(params: { maybeStateQueryParamValue: string }): boolean {
|
|
46
|
-
const { maybeStateQueryParamValue } = params;
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
maybeStateQueryParamValue.startsWith(STATE_QUERY_PARAM_VALUE_IDENTIFIER_PREFIX) &&
|
|
50
|
-
maybeStateQueryParamValue.length ===
|
|
51
|
-
STATE_QUERY_PARAM_VALUE_IDENTIFIER_PREFIX.length + RANDOM_STRING_LENGTH
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const STATE_STORE_KEY_PREFIX = "oidc.";
|
|
56
|
-
|
|
57
|
-
function getKey(params: { stateQueryParamValue: string }) {
|
|
58
|
-
const { stateQueryParamValue } = params;
|
|
59
|
-
|
|
60
|
-
return `${STATE_STORE_KEY_PREFIX}${stateQueryParamValue}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function getStateStore(params: { stateQueryParamValue: string }): { data: StateData } | undefined {
|
|
64
|
-
const { stateQueryParamValue } = params;
|
|
65
|
-
|
|
66
|
-
const item = localStorage.getItem(getKey({ stateQueryParamValue }));
|
|
67
|
-
|
|
68
|
-
if (item === null) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const obj = JSON.parse(item);
|
|
73
|
-
|
|
74
|
-
assert(
|
|
75
|
-
typeGuard<{ data: StateData }>(
|
|
76
|
-
obj,
|
|
77
|
-
obj instanceof Object && obj.data instanceof Object && typeof obj.data.context === "string"
|
|
78
|
-
)
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
return obj;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function setStateStore(params: { stateQueryParamValue: string; obj: { data: StateData } }) {
|
|
85
|
-
const { stateQueryParamValue, obj } = params;
|
|
86
|
-
|
|
87
|
-
localStorage.setItem(getKey({ stateQueryParamValue }), JSON.stringify(obj));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function clearStateStore(params: { stateQueryParamValue: string }) {
|
|
91
|
-
const { stateQueryParamValue } = params;
|
|
92
|
-
localStorage.removeItem(getKey({ stateQueryParamValue }));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function getStateData(params: { stateQueryParamValue: string }): StateData | undefined {
|
|
96
|
-
const { stateQueryParamValue } = params;
|
|
97
|
-
|
|
98
|
-
const stateStore = getStateStore({ stateQueryParamValue });
|
|
99
|
-
|
|
100
|
-
if (stateStore === undefined) {
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return stateStore.data;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function markStateDataAsProcessedByCallback(params: { stateQueryParamValue: string }) {
|
|
108
|
-
const { stateQueryParamValue } = params;
|
|
109
|
-
|
|
110
|
-
const obj = getStateStore({ stateQueryParamValue });
|
|
111
|
-
|
|
112
|
-
assert(obj !== undefined, "180465");
|
|
113
|
-
assert(obj.data.context === "redirect", "649531");
|
|
114
|
-
|
|
115
|
-
obj.data.hasBeenProcessedByCallback = true;
|
|
116
|
-
|
|
117
|
-
setStateStore({ stateQueryParamValue, obj });
|
|
118
|
-
}
|
package/src/core/configId.ts
DELETED
package/src/core/loginSilent.ts
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import type { UserManager as OidcClientTsUserManager } from "../vendor/frontend/oidc-client-ts-and-jwt-decode";
|
|
2
|
-
import { Deferred } from "../tools/Deferred";
|
|
3
|
-
import { id, assert, noUndefined } from "../vendor/frontend/tsafe";
|
|
4
|
-
import { getStateData, clearStateStore, type StateData } from "./StateData";
|
|
5
|
-
import { getDownlinkAndRtt } from "../tools/getDownlinkAndRtt";
|
|
6
|
-
import { getIsDev } from "../tools/isDev";
|
|
7
|
-
import type { User as OidcClientTsUser } from "../vendor/frontend/oidc-client-ts-and-jwt-decode";
|
|
8
|
-
import { type AuthResponse } from "./AuthResponse";
|
|
9
|
-
import { addOrUpdateSearchParam } from "../tools/urlSearchParams";
|
|
10
|
-
import { initIframeMessageProtection } from "./iframeMessageProtection";
|
|
11
|
-
|
|
12
|
-
type ResultOfLoginSilent =
|
|
13
|
-
| {
|
|
14
|
-
outcome: "got auth response from iframe";
|
|
15
|
-
authResponse: AuthResponse;
|
|
16
|
-
}
|
|
17
|
-
| {
|
|
18
|
-
outcome: "failure";
|
|
19
|
-
cause: "timeout" | "can't reach well-known oidc endpoint";
|
|
20
|
-
}
|
|
21
|
-
| {
|
|
22
|
-
outcome: "token refreshed using refresh token";
|
|
23
|
-
oidcClientTsUser: OidcClientTsUser;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export async function loginSilent(params: {
|
|
27
|
-
oidcClientTsUserManager: OidcClientTsUserManager;
|
|
28
|
-
stateQueryParamValue_instance: string;
|
|
29
|
-
configId: string;
|
|
30
|
-
|
|
31
|
-
transformUrlBeforeRedirect:
|
|
32
|
-
| ((params: { authorizationUrl: string; isSilent: true }) => string)
|
|
33
|
-
| undefined;
|
|
34
|
-
|
|
35
|
-
getExtraQueryParams:
|
|
36
|
-
| ((params: { isSilent: true; url: string }) => Record<string, string | undefined>)
|
|
37
|
-
| undefined;
|
|
38
|
-
|
|
39
|
-
getExtraTokenParams: (() => Record<string, string | undefined>) | undefined;
|
|
40
|
-
autoLogin: boolean;
|
|
41
|
-
}): Promise<ResultOfLoginSilent> {
|
|
42
|
-
const {
|
|
43
|
-
oidcClientTsUserManager,
|
|
44
|
-
stateQueryParamValue_instance,
|
|
45
|
-
configId,
|
|
46
|
-
transformUrlBeforeRedirect,
|
|
47
|
-
getExtraQueryParams,
|
|
48
|
-
getExtraTokenParams,
|
|
49
|
-
autoLogin
|
|
50
|
-
} = params;
|
|
51
|
-
|
|
52
|
-
const dResult = new Deferred<ResultOfLoginSilent>();
|
|
53
|
-
|
|
54
|
-
const timeoutDelayMs: number = (() => {
|
|
55
|
-
if (autoLogin) {
|
|
56
|
-
return 25_000;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const downlinkAndRtt = getDownlinkAndRtt();
|
|
60
|
-
const isDev = getIsDev();
|
|
61
|
-
|
|
62
|
-
// Base delay is the minimum delay we should wait in any case
|
|
63
|
-
const BASE_DELAY_MS = isDev ? 9_000 : 7_000;
|
|
64
|
-
|
|
65
|
-
if (downlinkAndRtt === undefined) {
|
|
66
|
-
return BASE_DELAY_MS;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const { downlink, rtt } = downlinkAndRtt;
|
|
70
|
-
|
|
71
|
-
// Calculate dynamic delay based on RTT and downlink
|
|
72
|
-
// Add 1 to downlink to avoid division by zero
|
|
73
|
-
const dynamicDelay = rtt * 2.5 + BASE_DELAY_MS / (downlink + 1);
|
|
74
|
-
|
|
75
|
-
return Math.max(BASE_DELAY_MS, dynamicDelay);
|
|
76
|
-
})();
|
|
77
|
-
|
|
78
|
-
const { decodeEncryptedAuth, getIsEncryptedAuthResponse, clearSessionStoragePublicKey } =
|
|
79
|
-
await initIframeMessageProtection({
|
|
80
|
-
stateQueryParamValue: stateQueryParamValue_instance
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const timeout = setTimeout(async () => {
|
|
84
|
-
dResult.resolve({
|
|
85
|
-
outcome: "failure",
|
|
86
|
-
cause: "timeout"
|
|
87
|
-
});
|
|
88
|
-
}, timeoutDelayMs);
|
|
89
|
-
|
|
90
|
-
const listener = async (event: MessageEvent) => {
|
|
91
|
-
if (event.origin !== window.location.origin) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
!getIsEncryptedAuthResponse({
|
|
97
|
-
message: event.data
|
|
98
|
-
})
|
|
99
|
-
) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const { authResponse } = await decodeEncryptedAuth({ encryptedAuthResponse: event.data });
|
|
104
|
-
|
|
105
|
-
const stateData = getStateData({ stateQueryParamValue: authResponse.state });
|
|
106
|
-
|
|
107
|
-
assert(stateData !== undefined, "765645");
|
|
108
|
-
assert(stateData.context === "iframe", "250711");
|
|
109
|
-
|
|
110
|
-
if (stateData.configId !== configId) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
clearTimeout(timeout);
|
|
115
|
-
|
|
116
|
-
window.removeEventListener("message", listener);
|
|
117
|
-
|
|
118
|
-
dResult.resolve({
|
|
119
|
-
outcome: "got auth response from iframe",
|
|
120
|
-
authResponse
|
|
121
|
-
});
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
window.addEventListener("message", listener, false);
|
|
125
|
-
|
|
126
|
-
const transformUrl_oidcClientTs = (url: string) => {
|
|
127
|
-
add_extra_query_params: {
|
|
128
|
-
if (getExtraQueryParams === undefined) {
|
|
129
|
-
break add_extra_query_params;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const extraQueryParams = getExtraQueryParams({ isSilent: true, url });
|
|
133
|
-
|
|
134
|
-
for (const [name, value] of Object.entries(extraQueryParams)) {
|
|
135
|
-
if (value === undefined) {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
url = addOrUpdateSearchParam({ url, name, value, encodeMethod: "www-form" });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
apply_transform_url: {
|
|
143
|
-
if (transformUrlBeforeRedirect === undefined) {
|
|
144
|
-
break apply_transform_url;
|
|
145
|
-
}
|
|
146
|
-
url = transformUrlBeforeRedirect({ authorizationUrl: url, isSilent: true });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return url;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
oidcClientTsUserManager
|
|
153
|
-
.signinSilent({
|
|
154
|
-
state: id<StateData.IFrame>({
|
|
155
|
-
context: "iframe",
|
|
156
|
-
configId
|
|
157
|
-
}),
|
|
158
|
-
silentRequestTimeoutInSeconds: timeoutDelayMs / 1000,
|
|
159
|
-
extraTokenParams:
|
|
160
|
-
getExtraTokenParams === undefined ? undefined : noUndefined(getExtraTokenParams()),
|
|
161
|
-
transformUrl: transformUrl_oidcClientTs
|
|
162
|
-
})
|
|
163
|
-
.then(
|
|
164
|
-
oidcClientTsUser => {
|
|
165
|
-
assert(oidcClientTsUser !== null, "oidcClientTsUser is not supposed to be null here");
|
|
166
|
-
|
|
167
|
-
clearTimeout(timeout);
|
|
168
|
-
|
|
169
|
-
dResult.resolve({
|
|
170
|
-
outcome: "token refreshed using refresh token",
|
|
171
|
-
oidcClientTsUser
|
|
172
|
-
});
|
|
173
|
-
},
|
|
174
|
-
(error: Error) => {
|
|
175
|
-
if (error.message === "Failed to fetch") {
|
|
176
|
-
// NOTE: If we got an error here it means that the fetch to the
|
|
177
|
-
// well-known oidc endpoint failed.
|
|
178
|
-
// This usually means that the server is down or that the issuerUri
|
|
179
|
-
// is not pointing to a valid oidc server.
|
|
180
|
-
// It could be a CORS error on the well-known endpoint but it's unlikely.
|
|
181
|
-
|
|
182
|
-
clearTimeout(timeout);
|
|
183
|
-
|
|
184
|
-
dResult.resolve({
|
|
185
|
-
outcome: "failure",
|
|
186
|
-
cause: "can't reach well-known oidc endpoint"
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// NOTE: Here, except error on our understanding there can't be any other
|
|
193
|
-
// error than timeout so we fail silently and let the timeout expire.
|
|
194
|
-
}
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
dResult.pr.then(result => {
|
|
198
|
-
clearSessionStoragePublicKey();
|
|
199
|
-
|
|
200
|
-
if (result.outcome === "failure") {
|
|
201
|
-
clearStateStore({ stateQueryParamValue: stateQueryParamValue_instance });
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
return dResult.pr;
|
|
206
|
-
}
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import type { User as OidcClientTsUser } from "../vendor/frontend/oidc-client-ts-and-jwt-decode";
|
|
2
|
-
import { assert, id } from "../vendor/frontend/tsafe";
|
|
3
|
-
import { readExpirationTimeInJwt } from "../tools/readExpirationTimeInJwt";
|
|
4
|
-
import { decodeJwt } from "../tools/decodeJwt";
|
|
5
|
-
import type { Oidc } from "./Oidc";
|
|
6
|
-
|
|
7
|
-
export function oidcClientTsUserToTokens<DecodedIdToken extends Record<string, unknown>>(params: {
|
|
8
|
-
oidcClientTsUser: OidcClientTsUser;
|
|
9
|
-
decodedIdTokenSchema?: {
|
|
10
|
-
parse: (decodedIdToken_original: Oidc.Tokens.DecodedIdToken_base) => DecodedIdToken;
|
|
11
|
-
};
|
|
12
|
-
__unsafe_useIdTokenAsAccessToken: boolean;
|
|
13
|
-
decodedIdToken_previous: DecodedIdToken | undefined;
|
|
14
|
-
log: typeof console.log | undefined;
|
|
15
|
-
}): Oidc.Tokens<DecodedIdToken> {
|
|
16
|
-
const {
|
|
17
|
-
oidcClientTsUser,
|
|
18
|
-
decodedIdTokenSchema,
|
|
19
|
-
__unsafe_useIdTokenAsAccessToken,
|
|
20
|
-
decodedIdToken_previous,
|
|
21
|
-
log
|
|
22
|
-
} = params;
|
|
23
|
-
|
|
24
|
-
const isFirstInit = decodedIdToken_previous === undefined;
|
|
25
|
-
|
|
26
|
-
const accessToken = oidcClientTsUser.access_token;
|
|
27
|
-
|
|
28
|
-
const refreshToken = oidcClientTsUser.refresh_token;
|
|
29
|
-
|
|
30
|
-
const idToken = oidcClientTsUser.id_token;
|
|
31
|
-
|
|
32
|
-
assert(idToken !== undefined, "No id token provided by the oidc server");
|
|
33
|
-
|
|
34
|
-
const decodedIdToken_original = decodeJwt<Oidc.Tokens.DecodedIdToken_base>(idToken);
|
|
35
|
-
|
|
36
|
-
if (isFirstInit) {
|
|
37
|
-
log?.(
|
|
38
|
-
[
|
|
39
|
-
`Decoded ID token`,
|
|
40
|
-
decodedIdTokenSchema === undefined ? "" : " before `decodedIdTokenSchema.parse()`\n",
|
|
41
|
-
JSON.stringify(decodedIdToken_original, null, 2)
|
|
42
|
-
].join("")
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const decodedIdToken = (() => {
|
|
47
|
-
let decodedIdToken: DecodedIdToken;
|
|
48
|
-
|
|
49
|
-
if (decodedIdTokenSchema !== undefined) {
|
|
50
|
-
decodedIdToken = decodedIdTokenSchema.parse(decodedIdToken_original);
|
|
51
|
-
|
|
52
|
-
if (isFirstInit) {
|
|
53
|
-
log?.(
|
|
54
|
-
[
|
|
55
|
-
"Decoded ID token after `decodedIdTokenSchema.parse()`\n",
|
|
56
|
-
JSON.stringify(decodedIdToken, null, 2)
|
|
57
|
-
].join("")
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
// @ts-expect-error
|
|
62
|
-
decodedIdToken = decodedIdToken_original;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
decodedIdToken_previous !== undefined &&
|
|
67
|
-
JSON.stringify(decodedIdToken) === JSON.stringify(decodedIdToken_previous)
|
|
68
|
-
) {
|
|
69
|
-
// NOTE: For stable ref, prevent re-render for component that would memoize
|
|
70
|
-
return decodedIdToken_previous;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return decodedIdToken;
|
|
74
|
-
})();
|
|
75
|
-
|
|
76
|
-
const issuedAtTime = (() => {
|
|
77
|
-
// NOTE: The id_token is always a JWT as per the protocol.
|
|
78
|
-
// We don't use Date.now() due to network latency.
|
|
79
|
-
const id_token_iat = (() => {
|
|
80
|
-
let iat: number | undefined;
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
const iat_claimValue = decodedIdToken_original.iat;
|
|
84
|
-
assert(iat_claimValue === undefined || typeof iat_claimValue === "number");
|
|
85
|
-
iat = iat_claimValue;
|
|
86
|
-
} catch {
|
|
87
|
-
iat = undefined;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (iat === undefined) {
|
|
91
|
-
return undefined;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return iat;
|
|
95
|
-
})();
|
|
96
|
-
|
|
97
|
-
if (id_token_iat === undefined) {
|
|
98
|
-
return Date.now();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return id_token_iat * 1000;
|
|
102
|
-
})();
|
|
103
|
-
|
|
104
|
-
const tokens_common: Oidc.Tokens.Common<DecodedIdToken> = {
|
|
105
|
-
...(__unsafe_useIdTokenAsAccessToken
|
|
106
|
-
? {
|
|
107
|
-
accessToken: idToken,
|
|
108
|
-
accessTokenExpirationTime: (() => {
|
|
109
|
-
const expirationTime = readExpirationTimeInJwt(idToken);
|
|
110
|
-
|
|
111
|
-
assert(
|
|
112
|
-
expirationTime !== undefined,
|
|
113
|
-
"Failed to get id token expiration time while trying to substitute the access token by the id token"
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
return expirationTime;
|
|
117
|
-
})()
|
|
118
|
-
}
|
|
119
|
-
: {
|
|
120
|
-
accessToken,
|
|
121
|
-
accessTokenExpirationTime: (() => {
|
|
122
|
-
read_from_jwt: {
|
|
123
|
-
const expirationTime = readExpirationTimeInJwt(accessToken);
|
|
124
|
-
|
|
125
|
-
if (expirationTime === undefined) {
|
|
126
|
-
break read_from_jwt;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return expirationTime;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
read_from_token_response_expires_at: {
|
|
133
|
-
const { expires_at } = oidcClientTsUser.__oidc_spa_tokenResponse;
|
|
134
|
-
|
|
135
|
-
if (expires_at === undefined) {
|
|
136
|
-
break read_from_token_response_expires_at;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
assert(typeof expires_at === "number", "2033392");
|
|
140
|
-
|
|
141
|
-
return expires_at * 1000;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
read_from_token_response_expires_in: {
|
|
145
|
-
const { expires_in } = oidcClientTsUser.__oidc_spa_tokenResponse;
|
|
146
|
-
|
|
147
|
-
if (expires_in === undefined) {
|
|
148
|
-
break read_from_token_response_expires_in;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
assert(typeof expires_in === "number", "203333425");
|
|
152
|
-
|
|
153
|
-
return issuedAtTime + expires_in * 1_000;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
assert(false, "Failed to get access token expiration time");
|
|
157
|
-
})()
|
|
158
|
-
}),
|
|
159
|
-
idToken,
|
|
160
|
-
decodedIdToken,
|
|
161
|
-
decodedIdToken_original,
|
|
162
|
-
issuedAtTime
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const tokens: Oidc.Tokens<DecodedIdToken> =
|
|
166
|
-
refreshToken === undefined
|
|
167
|
-
? id<Oidc.Tokens.WithoutRefreshToken<DecodedIdToken>>({
|
|
168
|
-
...tokens_common,
|
|
169
|
-
hasRefreshToken: false
|
|
170
|
-
})
|
|
171
|
-
: id<Oidc.Tokens.WithRefreshToken<DecodedIdToken>>({
|
|
172
|
-
...tokens_common,
|
|
173
|
-
hasRefreshToken: true,
|
|
174
|
-
refreshToken,
|
|
175
|
-
refreshTokenExpirationTime: (() => {
|
|
176
|
-
read_from_token_response_expires_at: {
|
|
177
|
-
const { refresh_expires_at } = oidcClientTsUser.__oidc_spa_tokenResponse;
|
|
178
|
-
|
|
179
|
-
if (refresh_expires_at === undefined) {
|
|
180
|
-
break read_from_token_response_expires_at;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
assert(typeof refresh_expires_at === "number", "2033392");
|
|
184
|
-
|
|
185
|
-
return refresh_expires_at * 1000;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
read_from_token_response_expires_in: {
|
|
189
|
-
const { refresh_expires_in } = oidcClientTsUser.__oidc_spa_tokenResponse;
|
|
190
|
-
|
|
191
|
-
if (refresh_expires_in === undefined) {
|
|
192
|
-
break read_from_token_response_expires_in;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
assert(typeof refresh_expires_in === "number", "2033425330");
|
|
196
|
-
|
|
197
|
-
return issuedAtTime + refresh_expires_in * 1000;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
read_from_jwt: {
|
|
201
|
-
const expirationTime = readExpirationTimeInJwt(refreshToken);
|
|
202
|
-
|
|
203
|
-
if (expirationTime === undefined) {
|
|
204
|
-
break read_from_jwt;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return expirationTime;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return undefined;
|
|
211
|
-
})()
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
if (
|
|
215
|
-
isFirstInit &&
|
|
216
|
-
tokens.hasRefreshToken &&
|
|
217
|
-
tokens.refreshTokenExpirationTime !== undefined &&
|
|
218
|
-
tokens.refreshTokenExpirationTime < tokens.accessTokenExpirationTime
|
|
219
|
-
) {
|
|
220
|
-
console.warn(
|
|
221
|
-
[
|
|
222
|
-
"The OIDC refresh token expirationTime is shorter than the one of the access token.",
|
|
223
|
-
"This is very unusual and probably a misconfiguration."
|
|
224
|
-
].join(" ")
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return tokens;
|
|
229
|
-
}
|