@azure/msal-browser 4.25.1 → 4.26.1
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/dist/app/IPublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientNext.mjs +1 -1
- package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
- package/dist/broker/nativeBroker/PlatformAuthDOMHandler.mjs +1 -1
- package/dist/broker/nativeBroker/PlatformAuthExtensionHandler.mjs +1 -1
- package/dist/broker/nativeBroker/PlatformAuthProvider.mjs +1 -1
- package/dist/cache/AccountManager.mjs +1 -1
- package/dist/cache/AsyncMemoryStorage.mjs +1 -1
- package/dist/cache/BrowserCacheManager.d.ts +64 -7
- package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
- package/dist/cache/BrowserCacheManager.mjs +400 -141
- package/dist/cache/BrowserCacheManager.mjs.map +1 -1
- package/dist/cache/CacheHelpers.mjs +1 -1
- package/dist/cache/CacheKeys.d.ts +3 -3
- package/dist/cache/CacheKeys.mjs +4 -4
- package/dist/cache/CookieStorage.mjs +1 -1
- package/dist/cache/DatabaseStorage.mjs +1 -1
- package/dist/cache/EncryptedData.mjs +1 -1
- package/dist/cache/IWindowStorage.d.ts +1 -1
- package/dist/cache/IWindowStorage.d.ts.map +1 -1
- package/dist/cache/LocalStorage.d.ts +1 -1
- package/dist/cache/LocalStorage.d.ts.map +1 -1
- package/dist/cache/LocalStorage.mjs +21 -12
- package/dist/cache/LocalStorage.mjs.map +1 -1
- package/dist/cache/MemoryStorage.mjs +1 -1
- package/dist/cache/SessionStorage.mjs +1 -1
- package/dist/cache/TokenCache.d.ts.map +1 -1
- package/dist/cache/TokenCache.mjs +14 -13
- package/dist/cache/TokenCache.mjs.map +1 -1
- package/dist/config/Configuration.mjs +1 -1
- package/dist/controllers/ControllerFactory.mjs +1 -1
- package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.mjs +3 -3
- package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +3 -3
- package/dist/controllers/StandardController.mjs.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
- package/dist/crypto/BrowserCrypto.mjs +1 -1
- package/dist/crypto/CryptoOps.mjs +1 -1
- package/dist/crypto/PkceGenerator.mjs +1 -1
- package/dist/crypto/SignedHttpRequest.mjs +1 -1
- package/dist/custom-auth-path/app/PublicClientApplication.mjs +1 -1
- package/dist/custom-auth-path/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
- package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthDOMHandler.mjs +1 -1
- package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthExtensionHandler.mjs +1 -1
- package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthProvider.mjs +1 -1
- package/dist/custom-auth-path/cache/AccountManager.mjs +1 -1
- package/dist/custom-auth-path/cache/AsyncMemoryStorage.mjs +1 -1
- package/dist/custom-auth-path/cache/BrowserCacheManager.d.ts +64 -7
- package/dist/custom-auth-path/cache/BrowserCacheManager.d.ts.map +1 -1
- package/dist/custom-auth-path/cache/BrowserCacheManager.mjs +400 -141
- package/dist/custom-auth-path/cache/BrowserCacheManager.mjs.map +1 -1
- package/dist/custom-auth-path/cache/CacheHelpers.mjs +1 -1
- package/dist/custom-auth-path/cache/CacheKeys.d.ts +3 -3
- package/dist/custom-auth-path/cache/CacheKeys.mjs +4 -4
- package/dist/custom-auth-path/cache/CookieStorage.mjs +1 -1
- package/dist/custom-auth-path/cache/DatabaseStorage.mjs +1 -1
- package/dist/custom-auth-path/cache/EncryptedData.mjs +1 -1
- package/dist/custom-auth-path/cache/IWindowStorage.d.ts +1 -1
- package/dist/custom-auth-path/cache/IWindowStorage.d.ts.map +1 -1
- package/dist/custom-auth-path/cache/LocalStorage.d.ts +1 -1
- package/dist/custom-auth-path/cache/LocalStorage.d.ts.map +1 -1
- package/dist/custom-auth-path/cache/LocalStorage.mjs +21 -12
- package/dist/custom-auth-path/cache/LocalStorage.mjs.map +1 -1
- package/dist/custom-auth-path/cache/MemoryStorage.mjs +1 -1
- package/dist/custom-auth-path/cache/SessionStorage.mjs +1 -1
- package/dist/custom-auth-path/cache/TokenCache.d.ts.map +1 -1
- package/dist/custom-auth-path/cache/TokenCache.mjs +14 -13
- package/dist/custom-auth-path/cache/TokenCache.mjs.map +1 -1
- package/dist/custom-auth-path/config/Configuration.mjs +1 -1
- package/dist/custom-auth-path/controllers/ControllerFactory.mjs +1 -1
- package/dist/custom-auth-path/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/dist/custom-auth-path/controllers/StandardController.d.ts.map +1 -1
- package/dist/custom-auth-path/controllers/StandardController.mjs +3 -3
- package/dist/custom-auth-path/controllers/StandardController.mjs.map +1 -1
- package/dist/custom-auth-path/crypto/BrowserCrypto.mjs +1 -1
- package/dist/custom-auth-path/crypto/CryptoOps.mjs +1 -1
- package/dist/custom-auth-path/crypto/PkceGenerator.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/CustomAuthConstants.d.ts +1 -1
- package/dist/custom-auth-path/custom_auth/CustomAuthConstants.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/CustomAuthPublicClientApplication.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/controller/CustomAuthStandardController.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/CustomAuthAuthority.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowErrorBase.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowResultBase.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowStateTypes.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/error_type/AuthMethodRegistrationError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationChallengeMethodResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationSubmitChallengeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationCompletedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationFailedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/error_type/MfaError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/result/MfaRequestChallengeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/result/MfaSubmitChallengeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaCompletedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaFailedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/CustomAuthApiError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/CustomAuthError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/HttpError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/HttpErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/InvalidArgumentError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/InvalidConfigurationError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/InvalidConfigurationErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/MethodNotImplementedError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/MsalCustomAuthError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/NoCachedAccountFoundError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/ParsedUrlError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/ParsedUrlErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/UnexpectedError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/UnsupportedEnvironmentError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/UserAccountAttributeError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/error/UserAlreadySignedInError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/CustomAuthInteractionClientBase.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/CustomAuthInterationClientFactory.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/jit/JitClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/jit/result/JitActionResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/mfa/MfaClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/interaction_client/mfa/result/MfaActionResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/BaseApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/CustomAuthApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/CustomAuthApiEndpoint.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/RegisterApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/ResetPasswordApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/SignInApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/SignupApiClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/types/ApiErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/types/ApiSuberrors.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/http_client/FetchHttpClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/network_client/http_client/IHttpClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/telemetry/PublicApiId.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/utils/ArgumentValidator.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/core/utils/UrlUtils.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/CustomAuthAccountData.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/error_type/GetAccountError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/GetAccessTokenResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/GetAccountResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/SignOutResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/GetAccessTokenState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/GetAccountState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/SignOutState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/get_account/interaction_client/CustomAuthSilentCacheClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/index.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/operating_context/CustomAuthOperatingContext.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/error_type/ResetPasswordError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordResendCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordStartResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordSubmitCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordSubmitPasswordResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordCodeRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordCompletedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordFailedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordPasswordRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/reset_password/interaction_client/ResetPasswordClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/SignInScenario.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/error_type/SignInError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInResendCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInSubmitCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInSubmitPasswordResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInCodeRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInCompletedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInContinuationState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInFailedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInPasswordRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/interaction_client/SignInClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_in/interaction_client/result/SignInActionResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/error_type/SignUpError.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpResendCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitAttributesResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitCodeResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitPasswordResult.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpAttributesRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpCodeRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpCompletedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpFailedState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpPasswordRequiredState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpState.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/interaction_client/SignUpClient.mjs +1 -1
- package/dist/custom-auth-path/custom_auth/sign_up/interaction_client/result/SignUpActionResult.mjs +1 -1
- package/dist/custom-auth-path/encode/Base64Decode.mjs +1 -1
- package/dist/custom-auth-path/encode/Base64Encode.mjs +1 -1
- package/dist/custom-auth-path/error/BrowserAuthError.mjs +1 -1
- package/dist/custom-auth-path/error/BrowserAuthErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/error/BrowserConfigurationAuthError.mjs +1 -1
- package/dist/custom-auth-path/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/error/NativeAuthError.mjs +1 -1
- package/dist/custom-auth-path/error/NativeAuthErrorCodes.mjs +1 -1
- package/dist/custom-auth-path/event/EventHandler.mjs +1 -1
- package/dist/custom-auth-path/event/EventType.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/BaseInteractionClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
- package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
- package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.mjs +7 -7
- package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.mjs.map +1 -1
- package/dist/custom-auth-path/interaction_client/PopupClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/RedirectClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/SilentAuthCodeClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/SilentCacheClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/SilentIframeClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/SilentRefreshClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_client/StandardInteractionClient.mjs +1 -1
- package/dist/custom-auth-path/interaction_handler/InteractionHandler.mjs +1 -1
- package/dist/custom-auth-path/interaction_handler/SilentHandler.mjs +2 -1
- package/dist/custom-auth-path/interaction_handler/SilentHandler.mjs.map +1 -1
- package/dist/custom-auth-path/navigation/NavigationClient.mjs +1 -1
- package/dist/custom-auth-path/network/FetchClient.mjs +1 -1
- package/dist/custom-auth-path/operatingcontext/BaseOperatingContext.mjs +1 -1
- package/dist/custom-auth-path/operatingcontext/StandardOperatingContext.mjs +1 -1
- package/dist/custom-auth-path/packageMetadata.d.ts +1 -1
- package/dist/custom-auth-path/packageMetadata.mjs +2 -2
- package/dist/custom-auth-path/protocol/Authorize.mjs +1 -1
- package/dist/custom-auth-path/request/RequestHelpers.mjs +1 -1
- package/dist/custom-auth-path/response/ResponseHandler.mjs +1 -1
- package/dist/custom-auth-path/utils/BrowserConstants.mjs +1 -1
- package/dist/custom-auth-path/utils/BrowserProtocolUtils.mjs +1 -1
- package/dist/custom-auth-path/utils/BrowserUtils.mjs +1 -1
- package/dist/custom-auth-path/utils/Helpers.mjs +1 -1
- package/dist/custom-auth-path/utils/MsalFrameStatsUtils.mjs +1 -1
- package/dist/custom_auth/CustomAuthConstants.d.ts +1 -1
- package/dist/encode/Base64Decode.mjs +1 -1
- package/dist/encode/Base64Encode.mjs +1 -1
- package/dist/error/BrowserAuthError.mjs +1 -1
- package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
- package/dist/error/NativeAuthError.mjs +1 -1
- package/dist/error/NativeAuthErrorCodes.mjs +1 -1
- package/dist/error/NestedAppAuthError.mjs +1 -1
- package/dist/event/EventHandler.mjs +1 -1
- package/dist/event/EventMessage.mjs +1 -1
- package/dist/event/EventType.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
- package/dist/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
- package/dist/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
- package/dist/interaction_client/PlatformAuthInteractionClient.mjs +7 -7
- package/dist/interaction_client/PlatformAuthInteractionClient.mjs.map +1 -1
- package/dist/interaction_client/PopupClient.mjs +1 -1
- package/dist/interaction_client/RedirectClient.mjs +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
- package/dist/interaction_client/SilentCacheClient.mjs +1 -1
- package/dist/interaction_client/SilentIframeClient.mjs +1 -1
- package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
- package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
- package/dist/interaction_handler/InteractionHandler.mjs +1 -1
- package/dist/interaction_handler/SilentHandler.mjs +2 -1
- package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
- package/dist/naa/BridgeError.mjs +1 -1
- package/dist/naa/BridgeProxy.mjs +1 -1
- package/dist/naa/BridgeStatusCode.mjs +1 -1
- package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
- package/dist/navigation/NavigationClient.mjs +1 -1
- package/dist/network/FetchClient.mjs +1 -1
- package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
- package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
- package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
- package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
- package/dist/packageMetadata.d.ts +1 -1
- package/dist/packageMetadata.mjs +2 -2
- package/dist/protocol/Authorize.mjs +1 -1
- package/dist/request/RequestHelpers.mjs +1 -1
- package/dist/response/ResponseHandler.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
- package/dist/utils/BrowserConstants.mjs +1 -1
- package/dist/utils/BrowserProtocolUtils.mjs +1 -1
- package/dist/utils/BrowserUtils.mjs +1 -1
- package/dist/utils/Helpers.mjs +1 -1
- package/dist/utils/MsalFrameStatsUtils.mjs +1 -1
- package/lib/custom-auth-path/msal-custom-auth.cjs +1238 -947
- package/lib/custom-auth-path/msal-custom-auth.cjs.map +1 -1
- package/lib/custom-auth-path/types/cache/BrowserCacheManager.d.ts +64 -7
- package/lib/custom-auth-path/types/cache/BrowserCacheManager.d.ts.map +1 -1
- package/lib/custom-auth-path/types/cache/CacheKeys.d.ts +3 -3
- package/lib/custom-auth-path/types/cache/IWindowStorage.d.ts +1 -1
- package/lib/custom-auth-path/types/cache/IWindowStorage.d.ts.map +1 -1
- package/lib/custom-auth-path/types/cache/LocalStorage.d.ts +1 -1
- package/lib/custom-auth-path/types/cache/LocalStorage.d.ts.map +1 -1
- package/lib/custom-auth-path/types/cache/TokenCache.d.ts.map +1 -1
- package/lib/custom-auth-path/types/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/lib/custom-auth-path/types/controllers/StandardController.d.ts.map +1 -1
- package/lib/custom-auth-path/types/custom_auth/CustomAuthConstants.d.ts +1 -1
- package/lib/custom-auth-path/types/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
- package/lib/custom-auth-path/types/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
- package/lib/custom-auth-path/types/packageMetadata.d.ts +1 -1
- package/lib/msal-browser.cjs +947 -656
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +947 -656
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +67 -67
- package/lib/types/cache/BrowserCacheManager.d.ts +64 -7
- package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
- package/lib/types/cache/CacheKeys.d.ts +3 -3
- package/lib/types/cache/IWindowStorage.d.ts +1 -1
- package/lib/types/cache/IWindowStorage.d.ts.map +1 -1
- package/lib/types/cache/LocalStorage.d.ts +1 -1
- package/lib/types/cache/LocalStorage.d.ts.map +1 -1
- package/lib/types/cache/TokenCache.d.ts.map +1 -1
- package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/lib/types/controllers/StandardController.d.ts.map +1 -1
- package/lib/types/custom_auth/CustomAuthConstants.d.ts +1 -1
- package/lib/types/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
- package/lib/types/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
- package/lib/types/packageMetadata.d.ts +1 -1
- package/package.json +2 -2
- package/src/cache/BrowserCacheManager.ts +738 -225
- package/src/cache/CacheKeys.ts +3 -3
- package/src/cache/IWindowStorage.ts +2 -1
- package/src/cache/LocalStorage.ts +30 -17
- package/src/cache/TokenCache.ts +33 -12
- package/src/controllers/NestedAppAuthController.ts +3 -1
- package/src/controllers/StandardController.ts +3 -1
- package/src/interaction_client/PlatformAuthInteractionClient.ts +15 -5
- package/src/interaction_handler/SilentHandler.ts +1 -0
- package/src/packageMetadata.ts +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @azure/msal-browser v4.
|
|
1
|
+
/*! @azure/msal-browser v4.26.1 2025-11-06 */
|
|
2
2
|
'use strict';
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
/*! @azure/msal-common v15.13.
|
|
5
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6
6
|
/*
|
|
7
7
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
8
8
|
* Licensed under the MIT License.
|
|
@@ -276,7 +276,7 @@ const JsonWebTokenTypes = {
|
|
|
276
276
|
// Token renewal offset default in seconds
|
|
277
277
|
const DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
|
|
278
278
|
|
|
279
|
-
/*! @azure/msal-common v15.13.
|
|
279
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
280
280
|
/*
|
|
281
281
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
282
282
|
* Licensed under the MIT License.
|
|
@@ -287,7 +287,7 @@ const DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
|
|
|
287
287
|
const unexpectedError = "unexpected_error";
|
|
288
288
|
const postRequestFailed$1 = "post_request_failed";
|
|
289
289
|
|
|
290
|
-
/*! @azure/msal-common v15.13.
|
|
290
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
291
291
|
|
|
292
292
|
/*
|
|
293
293
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -322,7 +322,7 @@ function createAuthError(code, additionalMessage) {
|
|
|
322
322
|
: AuthErrorMessages[code]);
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
-
/*! @azure/msal-common v15.13.
|
|
325
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
326
326
|
/*
|
|
327
327
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
328
328
|
* Licensed under the MIT License.
|
|
@@ -372,7 +372,7 @@ const missingTenantIdError = "missing_tenant_id_error";
|
|
|
372
372
|
const methodNotImplemented = "method_not_implemented";
|
|
373
373
|
const nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled";
|
|
374
374
|
|
|
375
|
-
/*! @azure/msal-common v15.13.
|
|
375
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
376
376
|
|
|
377
377
|
/*
|
|
378
378
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -446,7 +446,7 @@ function createClientAuthError(errorCode, additionalMessage) {
|
|
|
446
446
|
return new ClientAuthError(errorCode, additionalMessage);
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
-
/*! @azure/msal-common v15.13.
|
|
449
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
450
450
|
|
|
451
451
|
/*
|
|
452
452
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -485,7 +485,7 @@ const DEFAULT_CRYPTO_IMPLEMENTATION = {
|
|
|
485
485
|
},
|
|
486
486
|
};
|
|
487
487
|
|
|
488
|
-
/*! @azure/msal-common v15.13.
|
|
488
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
489
489
|
|
|
490
490
|
/*
|
|
491
491
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -676,12 +676,12 @@ class Logger {
|
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
678
|
|
|
679
|
-
/*! @azure/msal-common v15.13.
|
|
679
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
680
680
|
/* eslint-disable header/header */
|
|
681
681
|
const name$1 = "@azure/msal-common";
|
|
682
|
-
const version$1 = "15.13.
|
|
682
|
+
const version$1 = "15.13.1";
|
|
683
683
|
|
|
684
|
-
/*! @azure/msal-common v15.13.
|
|
684
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
685
685
|
/*
|
|
686
686
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
687
687
|
* Licensed under the MIT License.
|
|
@@ -690,7 +690,7 @@ const AzureCloudInstance = {
|
|
|
690
690
|
// AzureCloudInstance is not specified.
|
|
691
691
|
None: "none"};
|
|
692
692
|
|
|
693
|
-
/*! @azure/msal-common v15.13.
|
|
693
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
694
694
|
/*
|
|
695
695
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
696
696
|
* Licensed under the MIT License.
|
|
@@ -719,7 +719,7 @@ const authorityMismatch = "authority_mismatch";
|
|
|
719
719
|
const invalidRequestMethodForEAR = "invalid_request_method_for_EAR";
|
|
720
720
|
const invalidAuthorizePostBodyParameters = "invalid_authorize_post_body_parameters";
|
|
721
721
|
|
|
722
|
-
/*! @azure/msal-common v15.13.
|
|
722
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
723
723
|
|
|
724
724
|
/*
|
|
725
725
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -764,7 +764,7 @@ function createClientConfigurationError(errorCode) {
|
|
|
764
764
|
return new ClientConfigurationError(errorCode);
|
|
765
765
|
}
|
|
766
766
|
|
|
767
|
-
/*! @azure/msal-common v15.13.
|
|
767
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
768
768
|
/*
|
|
769
769
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
770
770
|
* Licensed under the MIT License.
|
|
@@ -861,7 +861,7 @@ class StringUtils {
|
|
|
861
861
|
}
|
|
862
862
|
}
|
|
863
863
|
|
|
864
|
-
/*! @azure/msal-common v15.13.
|
|
864
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
865
865
|
|
|
866
866
|
/*
|
|
867
867
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1056,7 +1056,47 @@ class ScopeSet {
|
|
|
1056
1056
|
}
|
|
1057
1057
|
}
|
|
1058
1058
|
|
|
1059
|
-
/*! @azure/msal-common v15.13.
|
|
1059
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1060
|
+
|
|
1061
|
+
/*
|
|
1062
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1063
|
+
* Licensed under the MIT License.
|
|
1064
|
+
*/
|
|
1065
|
+
/**
|
|
1066
|
+
* Function to build a client info object from server clientInfo string
|
|
1067
|
+
* @param rawClientInfo
|
|
1068
|
+
* @param crypto
|
|
1069
|
+
*/
|
|
1070
|
+
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
1071
|
+
if (!rawClientInfo) {
|
|
1072
|
+
throw createClientAuthError(clientInfoEmptyError);
|
|
1073
|
+
}
|
|
1074
|
+
try {
|
|
1075
|
+
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
1076
|
+
return JSON.parse(decodedClientInfo);
|
|
1077
|
+
}
|
|
1078
|
+
catch (e) {
|
|
1079
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Function to build a client info object from cached homeAccountId string
|
|
1084
|
+
* @param homeAccountId
|
|
1085
|
+
*/
|
|
1086
|
+
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
1087
|
+
if (!homeAccountId) {
|
|
1088
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
1089
|
+
}
|
|
1090
|
+
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
1091
|
+
return {
|
|
1092
|
+
uid: clientInfoParts[0],
|
|
1093
|
+
utid: clientInfoParts.length < 2
|
|
1094
|
+
? Constants.EMPTY_STRING
|
|
1095
|
+
: clientInfoParts[1],
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1060
1100
|
/*
|
|
1061
1101
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1062
1102
|
* Licensed under the MIT License.
|
|
@@ -1138,228 +1178,530 @@ function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenC
|
|
|
1138
1178
|
return updatedAccountInfo;
|
|
1139
1179
|
}
|
|
1140
1180
|
|
|
1141
|
-
/*! @azure/msal-common v15.13.
|
|
1142
|
-
|
|
1181
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1143
1182
|
/*
|
|
1144
1183
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1145
1184
|
* Licensed under the MIT License.
|
|
1146
1185
|
*/
|
|
1147
1186
|
/**
|
|
1148
|
-
*
|
|
1149
|
-
*
|
|
1150
|
-
* @param encodedToken
|
|
1151
|
-
*/
|
|
1152
|
-
function extractTokenClaims(encodedToken, base64Decode) {
|
|
1153
|
-
const jswPayload = getJWSPayload(encodedToken);
|
|
1154
|
-
// token will be decoded to get the username
|
|
1155
|
-
try {
|
|
1156
|
-
// base64Decode() should throw an error if there is an issue
|
|
1157
|
-
const base64Decoded = base64Decode(jswPayload);
|
|
1158
|
-
return JSON.parse(base64Decoded);
|
|
1159
|
-
}
|
|
1160
|
-
catch (err) {
|
|
1161
|
-
throw createClientAuthError(tokenParsingError);
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* decode a JWT
|
|
1166
|
-
*
|
|
1167
|
-
* @param authToken
|
|
1168
|
-
*/
|
|
1169
|
-
function getJWSPayload(authToken) {
|
|
1170
|
-
if (!authToken) {
|
|
1171
|
-
throw createClientAuthError(nullOrEmptyToken);
|
|
1172
|
-
}
|
|
1173
|
-
const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/;
|
|
1174
|
-
const matches = tokenPartsRegex.exec(authToken);
|
|
1175
|
-
if (!matches || matches.length < 4) {
|
|
1176
|
-
throw createClientAuthError(tokenParsingError);
|
|
1177
|
-
}
|
|
1178
|
-
/**
|
|
1179
|
-
* const crackedToken = {
|
|
1180
|
-
* header: matches[1],
|
|
1181
|
-
* JWSPayload: matches[2],
|
|
1182
|
-
* JWSSig: matches[3],
|
|
1183
|
-
* };
|
|
1184
|
-
*/
|
|
1185
|
-
return matches[2];
|
|
1186
|
-
}
|
|
1187
|
-
/**
|
|
1188
|
-
* Determine if the token's max_age has transpired
|
|
1187
|
+
* Authority types supported by MSAL.
|
|
1189
1188
|
*/
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
const fiveMinuteSkew = 300000; // five minutes in milliseconds
|
|
1197
|
-
if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) {
|
|
1198
|
-
throw createClientAuthError(maxAgeTranspired);
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
1189
|
+
const AuthorityType = {
|
|
1190
|
+
Default: 0,
|
|
1191
|
+
Adfs: 1,
|
|
1192
|
+
Dsts: 2,
|
|
1193
|
+
Ciam: 3,
|
|
1194
|
+
};
|
|
1203
1195
|
|
|
1196
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1204
1197
|
/*
|
|
1205
1198
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1206
1199
|
* Licensed under the MIT License.
|
|
1207
1200
|
*/
|
|
1208
1201
|
/**
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
return url;
|
|
1217
|
-
}
|
|
1218
|
-
let lowerCaseUrl = url.toLowerCase();
|
|
1219
|
-
if (StringUtils.endsWith(lowerCaseUrl, "?")) {
|
|
1220
|
-
lowerCaseUrl = lowerCaseUrl.slice(0, -1);
|
|
1221
|
-
}
|
|
1222
|
-
else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
|
|
1223
|
-
lowerCaseUrl = lowerCaseUrl.slice(0, -2);
|
|
1224
|
-
}
|
|
1225
|
-
if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
|
|
1226
|
-
lowerCaseUrl += "/";
|
|
1227
|
-
}
|
|
1228
|
-
return lowerCaseUrl;
|
|
1229
|
-
}
|
|
1230
|
-
/**
|
|
1231
|
-
* Parses hash string from given string. Returns empty string if no hash symbol is found.
|
|
1232
|
-
* @param hashString
|
|
1233
|
-
*/
|
|
1234
|
-
function stripLeadingHashOrQuery(responseString) {
|
|
1235
|
-
if (responseString.startsWith("#/")) {
|
|
1236
|
-
return responseString.substring(2);
|
|
1237
|
-
}
|
|
1238
|
-
else if (responseString.startsWith("#") ||
|
|
1239
|
-
responseString.startsWith("?")) {
|
|
1240
|
-
return responseString.substring(1);
|
|
1241
|
-
}
|
|
1242
|
-
return responseString;
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Returns URL hash as server auth code response object.
|
|
1202
|
+
* Gets tenantId from available ID token claims to set as credential realm with the following precedence:
|
|
1203
|
+
* 1. tid - if the token is acquired from an Azure AD tenant tid will be present
|
|
1204
|
+
* 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
|
|
1205
|
+
* 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
|
|
1206
|
+
* Downcased to match the realm case-insensitive comparison requirements
|
|
1207
|
+
* @param idTokenClaims
|
|
1208
|
+
* @returns
|
|
1246
1209
|
*/
|
|
1247
|
-
function
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
return null;
|
|
1251
|
-
}
|
|
1252
|
-
try {
|
|
1253
|
-
// Strip the # or ? symbol if present
|
|
1254
|
-
const normalizedResponse = stripLeadingHashOrQuery(responseString);
|
|
1255
|
-
// If # symbol was not present, above will return empty string, so give original hash value
|
|
1256
|
-
const deserializedHash = Object.fromEntries(new URLSearchParams(normalizedResponse));
|
|
1257
|
-
// Check for known response properties
|
|
1258
|
-
if (deserializedHash.code ||
|
|
1259
|
-
deserializedHash.ear_jwe ||
|
|
1260
|
-
deserializedHash.error ||
|
|
1261
|
-
deserializedHash.error_description ||
|
|
1262
|
-
deserializedHash.state) {
|
|
1263
|
-
return deserializedHash;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
catch (e) {
|
|
1267
|
-
throw createClientAuthError(hashNotDeserialized);
|
|
1210
|
+
function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
1211
|
+
if (idTokenClaims) {
|
|
1212
|
+
const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
|
|
1213
|
+
return tenantId || null;
|
|
1268
1214
|
}
|
|
1269
1215
|
return null;
|
|
1270
|
-
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Utility to create a URL from the params map
|
|
1273
|
-
*/
|
|
1274
|
-
function mapToQueryString(parameters, encodeExtraParams = true, extraQueryParameters) {
|
|
1275
|
-
const queryParameterArray = new Array();
|
|
1276
|
-
parameters.forEach((value, key) => {
|
|
1277
|
-
if (!encodeExtraParams &&
|
|
1278
|
-
extraQueryParameters &&
|
|
1279
|
-
key in extraQueryParameters) {
|
|
1280
|
-
queryParameterArray.push(`${key}=${value}`);
|
|
1281
|
-
}
|
|
1282
|
-
else {
|
|
1283
|
-
queryParameterArray.push(`${key}=${encodeURIComponent(value)}`);
|
|
1284
|
-
}
|
|
1285
|
-
});
|
|
1286
|
-
return queryParameterArray.join("&");
|
|
1287
|
-
}
|
|
1288
|
-
/**
|
|
1289
|
-
* Normalizes URLs for comparison by removing hash, canonicalizing,
|
|
1290
|
-
* and ensuring consistent URL encoding in query parameters.
|
|
1291
|
-
* This fixes redirect loops when URLs contain encoded characters like apostrophes (%27).
|
|
1292
|
-
* @param url - URL to normalize
|
|
1293
|
-
* @returns Normalized URL string for comparison
|
|
1294
|
-
*/
|
|
1295
|
-
function normalizeUrlForComparison(url) {
|
|
1296
|
-
if (!url) {
|
|
1297
|
-
return url;
|
|
1298
|
-
}
|
|
1299
|
-
// Remove hash first
|
|
1300
|
-
const urlWithoutHash = url.split("#")[0];
|
|
1301
|
-
try {
|
|
1302
|
-
// Parse the URL to handle encoding consistently
|
|
1303
|
-
const urlObj = new URL(urlWithoutHash);
|
|
1304
|
-
/*
|
|
1305
|
-
* Reconstruct the URL with properly decoded query parameters
|
|
1306
|
-
* This ensures that %27 and ' are treated as equivalent
|
|
1307
|
-
*/
|
|
1308
|
-
const normalizedUrl = urlObj.origin + urlObj.pathname + urlObj.search;
|
|
1309
|
-
// Apply canonicalization logic inline to avoid circular dependency
|
|
1310
|
-
return canonicalizeUrl(normalizedUrl);
|
|
1311
|
-
}
|
|
1312
|
-
catch (e) {
|
|
1313
|
-
// Fallback to original logic if URL parsing fails
|
|
1314
|
-
return canonicalizeUrl(urlWithoutHash);
|
|
1315
|
-
}
|
|
1316
1216
|
}
|
|
1317
1217
|
|
|
1318
|
-
/*! @azure/msal-common v15.13.
|
|
1319
|
-
|
|
1218
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1320
1219
|
/*
|
|
1321
1220
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1322
1221
|
* Licensed under the MIT License.
|
|
1323
1222
|
*/
|
|
1324
1223
|
/**
|
|
1325
|
-
*
|
|
1224
|
+
* Protocol modes supported by MSAL.
|
|
1326
1225
|
*/
|
|
1327
|
-
|
|
1328
|
-
get urlString() {
|
|
1329
|
-
return this._urlString;
|
|
1330
|
-
}
|
|
1331
|
-
constructor(url) {
|
|
1332
|
-
this._urlString = url;
|
|
1333
|
-
if (!this._urlString) {
|
|
1334
|
-
// Throws error if url is empty
|
|
1335
|
-
throw createClientConfigurationError(urlEmptyError);
|
|
1336
|
-
}
|
|
1337
|
-
if (!url.includes("#")) {
|
|
1338
|
-
this._urlString = UrlString.canonicalizeUri(url);
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1226
|
+
const ProtocolMode = {
|
|
1341
1227
|
/**
|
|
1342
|
-
*
|
|
1343
|
-
* @param url
|
|
1228
|
+
* Auth Code + PKCE with Entra ID (formerly AAD) specific optimizations and features
|
|
1344
1229
|
*/
|
|
1345
|
-
|
|
1346
|
-
if (url) {
|
|
1347
|
-
let lowerCaseUrl = url.toLowerCase();
|
|
1348
|
-
if (StringUtils.endsWith(lowerCaseUrl, "?")) {
|
|
1349
|
-
lowerCaseUrl = lowerCaseUrl.slice(0, -1);
|
|
1350
|
-
}
|
|
1351
|
-
else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
|
|
1352
|
-
lowerCaseUrl = lowerCaseUrl.slice(0, -2);
|
|
1353
|
-
}
|
|
1354
|
-
if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
|
|
1355
|
-
lowerCaseUrl += "/";
|
|
1356
|
-
}
|
|
1357
|
-
return lowerCaseUrl;
|
|
1358
|
-
}
|
|
1359
|
-
return url;
|
|
1360
|
-
}
|
|
1230
|
+
AAD: "AAD",
|
|
1361
1231
|
/**
|
|
1362
|
-
*
|
|
1232
|
+
* Auth Code + PKCE without Entra ID specific optimizations and features. For use only with non-Microsoft owned authorities.
|
|
1233
|
+
* Support is limited for this mode.
|
|
1234
|
+
*/
|
|
1235
|
+
OIDC: "OIDC",
|
|
1236
|
+
/**
|
|
1237
|
+
* Encrypted Authorize Response (EAR) with Entra ID specific optimizations and features
|
|
1238
|
+
*/
|
|
1239
|
+
EAR: "EAR",
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1242
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1243
|
+
|
|
1244
|
+
/*
|
|
1245
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1246
|
+
* Licensed under the MIT License.
|
|
1247
|
+
*/
|
|
1248
|
+
/**
|
|
1249
|
+
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
|
|
1250
|
+
*
|
|
1251
|
+
* Key : Value Schema
|
|
1252
|
+
*
|
|
1253
|
+
* Key: <home_account_id>-<environment>-<realm*>
|
|
1254
|
+
*
|
|
1255
|
+
* Value Schema:
|
|
1256
|
+
* {
|
|
1257
|
+
* homeAccountId: home account identifier for the auth scheme,
|
|
1258
|
+
* environment: entity that issued the token, represented as a full host
|
|
1259
|
+
* realm: Full tenant or organizational identifier that the account belongs to
|
|
1260
|
+
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
1261
|
+
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
1262
|
+
* authorityType: Accounts authority type as a string
|
|
1263
|
+
* name: Full name for the account, including given name and family name,
|
|
1264
|
+
* lastModificationTime: last time this entity was modified in the cache
|
|
1265
|
+
* lastModificationApp:
|
|
1266
|
+
* nativeAccountId: Account identifier on the native device
|
|
1267
|
+
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
1268
|
+
* }
|
|
1269
|
+
* @internal
|
|
1270
|
+
*/
|
|
1271
|
+
class AccountEntity {
|
|
1272
|
+
/**
|
|
1273
|
+
* Returns the AccountInfo interface for this account.
|
|
1274
|
+
*/
|
|
1275
|
+
static getAccountInfo(accountEntity) {
|
|
1276
|
+
return {
|
|
1277
|
+
homeAccountId: accountEntity.homeAccountId,
|
|
1278
|
+
environment: accountEntity.environment,
|
|
1279
|
+
tenantId: accountEntity.realm,
|
|
1280
|
+
username: accountEntity.username,
|
|
1281
|
+
localAccountId: accountEntity.localAccountId,
|
|
1282
|
+
loginHint: accountEntity.loginHint,
|
|
1283
|
+
name: accountEntity.name,
|
|
1284
|
+
nativeAccountId: accountEntity.nativeAccountId,
|
|
1285
|
+
authorityType: accountEntity.authorityType,
|
|
1286
|
+
// Deserialize tenant profiles array into a Map
|
|
1287
|
+
tenantProfiles: new Map((accountEntity.tenantProfiles || []).map((tenantProfile) => {
|
|
1288
|
+
return [tenantProfile.tenantId, tenantProfile];
|
|
1289
|
+
})),
|
|
1290
|
+
dataBoundary: accountEntity.dataBoundary,
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Returns true if the account entity is in single tenant format (outdated), false otherwise
|
|
1295
|
+
*/
|
|
1296
|
+
isSingleTenant() {
|
|
1297
|
+
return !this.tenantProfiles;
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
1301
|
+
* @param accountDetails
|
|
1302
|
+
*/
|
|
1303
|
+
static createAccount(accountDetails, authority, base64Decode) {
|
|
1304
|
+
const account = new AccountEntity();
|
|
1305
|
+
if (authority.authorityType === AuthorityType.Adfs) {
|
|
1306
|
+
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
1307
|
+
}
|
|
1308
|
+
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
1309
|
+
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
1310
|
+
}
|
|
1311
|
+
else {
|
|
1312
|
+
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
1313
|
+
}
|
|
1314
|
+
let clientInfo;
|
|
1315
|
+
if (accountDetails.clientInfo && base64Decode) {
|
|
1316
|
+
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
|
|
1317
|
+
if (clientInfo.xms_tdbr) {
|
|
1318
|
+
account.dataBoundary =
|
|
1319
|
+
clientInfo.xms_tdbr === "EU" ? "EU" : "None";
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
account.clientInfo = accountDetails.clientInfo;
|
|
1323
|
+
account.homeAccountId = accountDetails.homeAccountId;
|
|
1324
|
+
account.nativeAccountId = accountDetails.nativeAccountId;
|
|
1325
|
+
const env = accountDetails.environment ||
|
|
1326
|
+
(authority && authority.getPreferredCache());
|
|
1327
|
+
if (!env) {
|
|
1328
|
+
throw createClientAuthError(invalidCacheEnvironment);
|
|
1329
|
+
}
|
|
1330
|
+
account.environment = env;
|
|
1331
|
+
// non AAD scenarios can have empty realm
|
|
1332
|
+
account.realm =
|
|
1333
|
+
clientInfo?.utid ||
|
|
1334
|
+
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
1335
|
+
"";
|
|
1336
|
+
// How do you account for MSA CID here?
|
|
1337
|
+
account.localAccountId =
|
|
1338
|
+
clientInfo?.uid ||
|
|
1339
|
+
accountDetails.idTokenClaims?.oid ||
|
|
1340
|
+
accountDetails.idTokenClaims?.sub ||
|
|
1341
|
+
"";
|
|
1342
|
+
/*
|
|
1343
|
+
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
1344
|
+
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
1345
|
+
* policy is configured to return more than 1 email.
|
|
1346
|
+
*/
|
|
1347
|
+
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
1348
|
+
accountDetails.idTokenClaims?.upn;
|
|
1349
|
+
const email = accountDetails.idTokenClaims?.emails
|
|
1350
|
+
? accountDetails.idTokenClaims.emails[0]
|
|
1351
|
+
: null;
|
|
1352
|
+
account.username = preferredUsername || email || "";
|
|
1353
|
+
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
1354
|
+
account.name = accountDetails.idTokenClaims?.name || "";
|
|
1355
|
+
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
1356
|
+
account.msGraphHost = accountDetails.msGraphHost;
|
|
1357
|
+
if (accountDetails.tenantProfiles) {
|
|
1358
|
+
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
1359
|
+
}
|
|
1360
|
+
else {
|
|
1361
|
+
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
1362
|
+
account.tenantProfiles = [tenantProfile];
|
|
1363
|
+
}
|
|
1364
|
+
return account;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Creates an AccountEntity object from AccountInfo
|
|
1368
|
+
* @param accountInfo
|
|
1369
|
+
* @param cloudGraphHostName
|
|
1370
|
+
* @param msGraphHost
|
|
1371
|
+
* @returns
|
|
1372
|
+
*/
|
|
1373
|
+
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
|
|
1374
|
+
const account = new AccountEntity();
|
|
1375
|
+
account.authorityType =
|
|
1376
|
+
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
1377
|
+
account.homeAccountId = accountInfo.homeAccountId;
|
|
1378
|
+
account.localAccountId = accountInfo.localAccountId;
|
|
1379
|
+
account.nativeAccountId = accountInfo.nativeAccountId;
|
|
1380
|
+
account.realm = accountInfo.tenantId;
|
|
1381
|
+
account.environment = accountInfo.environment;
|
|
1382
|
+
account.username = accountInfo.username;
|
|
1383
|
+
account.name = accountInfo.name;
|
|
1384
|
+
account.loginHint = accountInfo.loginHint;
|
|
1385
|
+
account.cloudGraphHostName = cloudGraphHostName;
|
|
1386
|
+
account.msGraphHost = msGraphHost;
|
|
1387
|
+
// Serialize tenant profiles map into an array
|
|
1388
|
+
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
|
|
1389
|
+
account.dataBoundary = accountInfo.dataBoundary;
|
|
1390
|
+
return account;
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Generate HomeAccountId from server response
|
|
1394
|
+
* @param serverClientInfo
|
|
1395
|
+
* @param authType
|
|
1396
|
+
*/
|
|
1397
|
+
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
|
|
1398
|
+
// since ADFS/DSTS do not have tid and does not set client_info
|
|
1399
|
+
if (!(authType === AuthorityType.Adfs ||
|
|
1400
|
+
authType === AuthorityType.Dsts)) {
|
|
1401
|
+
// for cases where there is clientInfo
|
|
1402
|
+
if (serverClientInfo) {
|
|
1403
|
+
try {
|
|
1404
|
+
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
|
|
1405
|
+
if (clientInfo.uid && clientInfo.utid) {
|
|
1406
|
+
return `${clientInfo.uid}.${clientInfo.utid}`;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
catch (e) { }
|
|
1410
|
+
}
|
|
1411
|
+
logger.warning("No client info in response");
|
|
1412
|
+
}
|
|
1413
|
+
// default to "sub" claim
|
|
1414
|
+
return idTokenClaims?.sub || "";
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Validates an entity: checks for all expected params
|
|
1418
|
+
* @param entity
|
|
1419
|
+
*/
|
|
1420
|
+
static isAccountEntity(entity) {
|
|
1421
|
+
if (!entity) {
|
|
1422
|
+
return false;
|
|
1423
|
+
}
|
|
1424
|
+
return (entity.hasOwnProperty("homeAccountId") &&
|
|
1425
|
+
entity.hasOwnProperty("environment") &&
|
|
1426
|
+
entity.hasOwnProperty("realm") &&
|
|
1427
|
+
entity.hasOwnProperty("localAccountId") &&
|
|
1428
|
+
entity.hasOwnProperty("username") &&
|
|
1429
|
+
entity.hasOwnProperty("authorityType"));
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Helper function to determine whether 2 accountInfo objects represent the same account
|
|
1433
|
+
* @param accountA
|
|
1434
|
+
* @param accountB
|
|
1435
|
+
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
1436
|
+
*/
|
|
1437
|
+
static accountInfoIsEqual(accountA, accountB, compareClaims) {
|
|
1438
|
+
if (!accountA || !accountB) {
|
|
1439
|
+
return false;
|
|
1440
|
+
}
|
|
1441
|
+
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
|
|
1442
|
+
if (compareClaims) {
|
|
1443
|
+
const accountAClaims = (accountA.idTokenClaims ||
|
|
1444
|
+
{});
|
|
1445
|
+
const accountBClaims = (accountB.idTokenClaims ||
|
|
1446
|
+
{});
|
|
1447
|
+
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
1448
|
+
claimsMatch =
|
|
1449
|
+
accountAClaims.iat === accountBClaims.iat &&
|
|
1450
|
+
accountAClaims.nonce === accountBClaims.nonce;
|
|
1451
|
+
}
|
|
1452
|
+
return (accountA.homeAccountId === accountB.homeAccountId &&
|
|
1453
|
+
accountA.localAccountId === accountB.localAccountId &&
|
|
1454
|
+
accountA.username === accountB.username &&
|
|
1455
|
+
accountA.tenantId === accountB.tenantId &&
|
|
1456
|
+
accountA.loginHint === accountB.loginHint &&
|
|
1457
|
+
accountA.environment === accountB.environment &&
|
|
1458
|
+
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
1459
|
+
claimsMatch);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1464
|
+
|
|
1465
|
+
/*
|
|
1466
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1467
|
+
* Licensed under the MIT License.
|
|
1468
|
+
*/
|
|
1469
|
+
/**
|
|
1470
|
+
* Extract token by decoding the rawToken
|
|
1471
|
+
*
|
|
1472
|
+
* @param encodedToken
|
|
1473
|
+
*/
|
|
1474
|
+
function extractTokenClaims(encodedToken, base64Decode) {
|
|
1475
|
+
const jswPayload = getJWSPayload(encodedToken);
|
|
1476
|
+
// token will be decoded to get the username
|
|
1477
|
+
try {
|
|
1478
|
+
// base64Decode() should throw an error if there is an issue
|
|
1479
|
+
const base64Decoded = base64Decode(jswPayload);
|
|
1480
|
+
return JSON.parse(base64Decoded);
|
|
1481
|
+
}
|
|
1482
|
+
catch (err) {
|
|
1483
|
+
throw createClientAuthError(tokenParsingError);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
/**
|
|
1487
|
+
* Check if the signin_state claim contains "kmsi"
|
|
1488
|
+
* @param idTokenClaims
|
|
1489
|
+
* @returns
|
|
1490
|
+
*/
|
|
1491
|
+
function isKmsi(idTokenClaims) {
|
|
1492
|
+
if (!idTokenClaims.signin_state) {
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Signin_state claim known values:
|
|
1497
|
+
* dvc_mngd - device is managed
|
|
1498
|
+
* dvc_dmjd - device is domain joined
|
|
1499
|
+
* kmsi - user opted to "keep me signed in"
|
|
1500
|
+
* inknownntwk - Request made inside a known network. Don't use this, use CAE instead.
|
|
1501
|
+
*/
|
|
1502
|
+
const kmsiClaims = ["kmsi", "dvc_dmjd"]; // There are some cases where kmsi may not be returned but persistent storage is still OK - allow dvc_dmjd as well
|
|
1503
|
+
const kmsi = idTokenClaims.signin_state.some((value) => kmsiClaims.includes(value.trim().toLowerCase()));
|
|
1504
|
+
return kmsi;
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* decode a JWT
|
|
1508
|
+
*
|
|
1509
|
+
* @param authToken
|
|
1510
|
+
*/
|
|
1511
|
+
function getJWSPayload(authToken) {
|
|
1512
|
+
if (!authToken) {
|
|
1513
|
+
throw createClientAuthError(nullOrEmptyToken);
|
|
1514
|
+
}
|
|
1515
|
+
const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/;
|
|
1516
|
+
const matches = tokenPartsRegex.exec(authToken);
|
|
1517
|
+
if (!matches || matches.length < 4) {
|
|
1518
|
+
throw createClientAuthError(tokenParsingError);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* const crackedToken = {
|
|
1522
|
+
* header: matches[1],
|
|
1523
|
+
* JWSPayload: matches[2],
|
|
1524
|
+
* JWSSig: matches[3],
|
|
1525
|
+
* };
|
|
1526
|
+
*/
|
|
1527
|
+
return matches[2];
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* Determine if the token's max_age has transpired
|
|
1531
|
+
*/
|
|
1532
|
+
function checkMaxAge(authTime, maxAge) {
|
|
1533
|
+
/*
|
|
1534
|
+
* per https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
|
1535
|
+
* To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access,
|
|
1536
|
+
* provide a value of 0 for the max_age parameter and the AS will force a fresh login.
|
|
1537
|
+
*/
|
|
1538
|
+
const fiveMinuteSkew = 300000; // five minutes in milliseconds
|
|
1539
|
+
if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) {
|
|
1540
|
+
throw createClientAuthError(maxAgeTranspired);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1545
|
+
|
|
1546
|
+
/*
|
|
1547
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1548
|
+
* Licensed under the MIT License.
|
|
1549
|
+
*/
|
|
1550
|
+
/**
|
|
1551
|
+
* Canonicalizes a URL by making it lowercase and ensuring it ends with /
|
|
1552
|
+
* Inlined version of UrlString.canonicalizeUri to avoid circular dependency
|
|
1553
|
+
* @param url - URL to canonicalize
|
|
1554
|
+
* @returns Canonicalized URL
|
|
1555
|
+
*/
|
|
1556
|
+
function canonicalizeUrl(url) {
|
|
1557
|
+
if (!url) {
|
|
1558
|
+
return url;
|
|
1559
|
+
}
|
|
1560
|
+
let lowerCaseUrl = url.toLowerCase();
|
|
1561
|
+
if (StringUtils.endsWith(lowerCaseUrl, "?")) {
|
|
1562
|
+
lowerCaseUrl = lowerCaseUrl.slice(0, -1);
|
|
1563
|
+
}
|
|
1564
|
+
else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
|
|
1565
|
+
lowerCaseUrl = lowerCaseUrl.slice(0, -2);
|
|
1566
|
+
}
|
|
1567
|
+
if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
|
|
1568
|
+
lowerCaseUrl += "/";
|
|
1569
|
+
}
|
|
1570
|
+
return lowerCaseUrl;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Parses hash string from given string. Returns empty string if no hash symbol is found.
|
|
1574
|
+
* @param hashString
|
|
1575
|
+
*/
|
|
1576
|
+
function stripLeadingHashOrQuery(responseString) {
|
|
1577
|
+
if (responseString.startsWith("#/")) {
|
|
1578
|
+
return responseString.substring(2);
|
|
1579
|
+
}
|
|
1580
|
+
else if (responseString.startsWith("#") ||
|
|
1581
|
+
responseString.startsWith("?")) {
|
|
1582
|
+
return responseString.substring(1);
|
|
1583
|
+
}
|
|
1584
|
+
return responseString;
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Returns URL hash as server auth code response object.
|
|
1588
|
+
*/
|
|
1589
|
+
function getDeserializedResponse(responseString) {
|
|
1590
|
+
// Check if given hash is empty
|
|
1591
|
+
if (!responseString || responseString.indexOf("=") < 0) {
|
|
1592
|
+
return null;
|
|
1593
|
+
}
|
|
1594
|
+
try {
|
|
1595
|
+
// Strip the # or ? symbol if present
|
|
1596
|
+
const normalizedResponse = stripLeadingHashOrQuery(responseString);
|
|
1597
|
+
// If # symbol was not present, above will return empty string, so give original hash value
|
|
1598
|
+
const deserializedHash = Object.fromEntries(new URLSearchParams(normalizedResponse));
|
|
1599
|
+
// Check for known response properties
|
|
1600
|
+
if (deserializedHash.code ||
|
|
1601
|
+
deserializedHash.ear_jwe ||
|
|
1602
|
+
deserializedHash.error ||
|
|
1603
|
+
deserializedHash.error_description ||
|
|
1604
|
+
deserializedHash.state) {
|
|
1605
|
+
return deserializedHash;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
catch (e) {
|
|
1609
|
+
throw createClientAuthError(hashNotDeserialized);
|
|
1610
|
+
}
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1614
|
+
* Utility to create a URL from the params map
|
|
1615
|
+
*/
|
|
1616
|
+
function mapToQueryString(parameters, encodeExtraParams = true, extraQueryParameters) {
|
|
1617
|
+
const queryParameterArray = new Array();
|
|
1618
|
+
parameters.forEach((value, key) => {
|
|
1619
|
+
if (!encodeExtraParams &&
|
|
1620
|
+
extraQueryParameters &&
|
|
1621
|
+
key in extraQueryParameters) {
|
|
1622
|
+
queryParameterArray.push(`${key}=${value}`);
|
|
1623
|
+
}
|
|
1624
|
+
else {
|
|
1625
|
+
queryParameterArray.push(`${key}=${encodeURIComponent(value)}`);
|
|
1626
|
+
}
|
|
1627
|
+
});
|
|
1628
|
+
return queryParameterArray.join("&");
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Normalizes URLs for comparison by removing hash, canonicalizing,
|
|
1632
|
+
* and ensuring consistent URL encoding in query parameters.
|
|
1633
|
+
* This fixes redirect loops when URLs contain encoded characters like apostrophes (%27).
|
|
1634
|
+
* @param url - URL to normalize
|
|
1635
|
+
* @returns Normalized URL string for comparison
|
|
1636
|
+
*/
|
|
1637
|
+
function normalizeUrlForComparison(url) {
|
|
1638
|
+
if (!url) {
|
|
1639
|
+
return url;
|
|
1640
|
+
}
|
|
1641
|
+
// Remove hash first
|
|
1642
|
+
const urlWithoutHash = url.split("#")[0];
|
|
1643
|
+
try {
|
|
1644
|
+
// Parse the URL to handle encoding consistently
|
|
1645
|
+
const urlObj = new URL(urlWithoutHash);
|
|
1646
|
+
/*
|
|
1647
|
+
* Reconstruct the URL with properly decoded query parameters
|
|
1648
|
+
* This ensures that %27 and ' are treated as equivalent
|
|
1649
|
+
*/
|
|
1650
|
+
const normalizedUrl = urlObj.origin + urlObj.pathname + urlObj.search;
|
|
1651
|
+
// Apply canonicalization logic inline to avoid circular dependency
|
|
1652
|
+
return canonicalizeUrl(normalizedUrl);
|
|
1653
|
+
}
|
|
1654
|
+
catch (e) {
|
|
1655
|
+
// Fallback to original logic if URL parsing fails
|
|
1656
|
+
return canonicalizeUrl(urlWithoutHash);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1661
|
+
|
|
1662
|
+
/*
|
|
1663
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1664
|
+
* Licensed under the MIT License.
|
|
1665
|
+
*/
|
|
1666
|
+
/**
|
|
1667
|
+
* Url object class which can perform various transformations on url strings.
|
|
1668
|
+
*/
|
|
1669
|
+
class UrlString {
|
|
1670
|
+
get urlString() {
|
|
1671
|
+
return this._urlString;
|
|
1672
|
+
}
|
|
1673
|
+
constructor(url) {
|
|
1674
|
+
this._urlString = url;
|
|
1675
|
+
if (!this._urlString) {
|
|
1676
|
+
// Throws error if url is empty
|
|
1677
|
+
throw createClientConfigurationError(urlEmptyError);
|
|
1678
|
+
}
|
|
1679
|
+
if (!url.includes("#")) {
|
|
1680
|
+
this._urlString = UrlString.canonicalizeUri(url);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Ensure urls are lower case and end with a / character.
|
|
1685
|
+
* @param url
|
|
1686
|
+
*/
|
|
1687
|
+
static canonicalizeUri(url) {
|
|
1688
|
+
if (url) {
|
|
1689
|
+
let lowerCaseUrl = url.toLowerCase();
|
|
1690
|
+
if (StringUtils.endsWith(lowerCaseUrl, "?")) {
|
|
1691
|
+
lowerCaseUrl = lowerCaseUrl.slice(0, -1);
|
|
1692
|
+
}
|
|
1693
|
+
else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
|
|
1694
|
+
lowerCaseUrl = lowerCaseUrl.slice(0, -2);
|
|
1695
|
+
}
|
|
1696
|
+
if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
|
|
1697
|
+
lowerCaseUrl += "/";
|
|
1698
|
+
}
|
|
1699
|
+
return lowerCaseUrl;
|
|
1700
|
+
}
|
|
1701
|
+
return url;
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Throws if urlString passed is not a valid authority URI string.
|
|
1363
1705
|
*/
|
|
1364
1706
|
validateAsUri() {
|
|
1365
1707
|
// Attempts to parse url for uri components
|
|
@@ -1479,7 +1821,7 @@ class UrlString {
|
|
|
1479
1821
|
}
|
|
1480
1822
|
}
|
|
1481
1823
|
|
|
1482
|
-
/*! @azure/msal-common v15.13.
|
|
1824
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1483
1825
|
|
|
1484
1826
|
/*
|
|
1485
1827
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1618,7 +1960,7 @@ function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) {
|
|
|
1618
1960
|
return null;
|
|
1619
1961
|
}
|
|
1620
1962
|
|
|
1621
|
-
/*! @azure/msal-common v15.13.
|
|
1963
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1622
1964
|
/*
|
|
1623
1965
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1624
1966
|
* Licensed under the MIT License.
|
|
@@ -1626,7 +1968,7 @@ function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) {
|
|
|
1626
1968
|
const cacheQuotaExceeded = "cache_quota_exceeded";
|
|
1627
1969
|
const cacheErrorUnknown = "cache_error_unknown";
|
|
1628
1970
|
|
|
1629
|
-
/*! @azure/msal-common v15.13.
|
|
1971
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1630
1972
|
|
|
1631
1973
|
/*
|
|
1632
1974
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1671,7 +2013,7 @@ function createCacheError(e) {
|
|
|
1671
2013
|
}
|
|
1672
2014
|
}
|
|
1673
2015
|
|
|
1674
|
-
/*! @azure/msal-common v15.13.
|
|
2016
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
1675
2017
|
|
|
1676
2018
|
/*
|
|
1677
2019
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1730,7 +2072,7 @@ class CacheManager {
|
|
|
1730
2072
|
getBaseAccountInfo(accountFilter, correlationId) {
|
|
1731
2073
|
const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
|
|
1732
2074
|
if (accountEntities.length > 0) {
|
|
1733
|
-
return accountEntities[0]
|
|
2075
|
+
return AccountEntity.getAccountInfo(accountEntities[0]);
|
|
1734
2076
|
}
|
|
1735
2077
|
else {
|
|
1736
2078
|
return null;
|
|
@@ -1769,7 +2111,7 @@ class CacheManager {
|
|
|
1769
2111
|
return tenantedAccountInfo;
|
|
1770
2112
|
}
|
|
1771
2113
|
getTenantProfilesFromAccountEntity(accountEntity, correlationId, targetTenantId, tenantProfileFilter) {
|
|
1772
|
-
const accountInfo =
|
|
2114
|
+
const accountInfo = AccountEntity.getAccountInfo(accountEntity);
|
|
1773
2115
|
let searchTenantProfiles = accountInfo.tenantProfiles || new Map();
|
|
1774
2116
|
const tokenKeys = this.getTokenKeys();
|
|
1775
2117
|
// If a tenant ID was provided, only return the tenant profile for that tenant ID if it exists
|
|
@@ -1839,27 +2181,28 @@ class CacheManager {
|
|
|
1839
2181
|
/**
|
|
1840
2182
|
* saves a cache record
|
|
1841
2183
|
* @param cacheRecord {CacheRecord}
|
|
1842
|
-
* @param storeInCache {?StoreInCache}
|
|
1843
2184
|
* @param correlationId {?string} correlation id
|
|
2185
|
+
* @param kmsi - Keep Me Signed In
|
|
2186
|
+
* @param storeInCache {?StoreInCache}
|
|
1844
2187
|
*/
|
|
1845
|
-
async saveCacheRecord(cacheRecord, correlationId, storeInCache) {
|
|
2188
|
+
async saveCacheRecord(cacheRecord, correlationId, kmsi, storeInCache) {
|
|
1846
2189
|
if (!cacheRecord) {
|
|
1847
2190
|
throw createClientAuthError(invalidCacheRecord);
|
|
1848
2191
|
}
|
|
1849
2192
|
try {
|
|
1850
2193
|
if (!!cacheRecord.account) {
|
|
1851
|
-
await this.setAccount(cacheRecord.account, correlationId);
|
|
2194
|
+
await this.setAccount(cacheRecord.account, correlationId, kmsi);
|
|
1852
2195
|
}
|
|
1853
2196
|
if (!!cacheRecord.idToken && storeInCache?.idToken !== false) {
|
|
1854
|
-
await this.setIdTokenCredential(cacheRecord.idToken, correlationId);
|
|
2197
|
+
await this.setIdTokenCredential(cacheRecord.idToken, correlationId, kmsi);
|
|
1855
2198
|
}
|
|
1856
2199
|
if (!!cacheRecord.accessToken &&
|
|
1857
2200
|
storeInCache?.accessToken !== false) {
|
|
1858
|
-
await this.saveAccessToken(cacheRecord.accessToken, correlationId);
|
|
2201
|
+
await this.saveAccessToken(cacheRecord.accessToken, correlationId, kmsi);
|
|
1859
2202
|
}
|
|
1860
2203
|
if (!!cacheRecord.refreshToken &&
|
|
1861
2204
|
storeInCache?.refreshToken !== false) {
|
|
1862
|
-
await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId);
|
|
2205
|
+
await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId, kmsi);
|
|
1863
2206
|
}
|
|
1864
2207
|
if (!!cacheRecord.appMetadata) {
|
|
1865
2208
|
this.setAppMetadata(cacheRecord.appMetadata, correlationId);
|
|
@@ -1879,7 +2222,7 @@ class CacheManager {
|
|
|
1879
2222
|
* saves access token credential
|
|
1880
2223
|
* @param credential
|
|
1881
2224
|
*/
|
|
1882
|
-
async saveAccessToken(credential, correlationId) {
|
|
2225
|
+
async saveAccessToken(credential, correlationId, kmsi) {
|
|
1883
2226
|
const accessTokenFilter = {
|
|
1884
2227
|
clientId: credential.clientId,
|
|
1885
2228
|
credentialType: credential.credentialType,
|
|
@@ -1904,7 +2247,7 @@ class CacheManager {
|
|
|
1904
2247
|
}
|
|
1905
2248
|
}
|
|
1906
2249
|
});
|
|
1907
|
-
await this.setAccessTokenCredential(credential, correlationId);
|
|
2250
|
+
await this.setAccessTokenCredential(credential, correlationId, kmsi);
|
|
1908
2251
|
}
|
|
1909
2252
|
/**
|
|
1910
2253
|
* Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache
|
|
@@ -2774,36 +3117,12 @@ class DefaultStorageClass extends CacheManager {
|
|
|
2774
3117
|
generateCredentialKey() {
|
|
2775
3118
|
throw createClientAuthError(methodNotImplemented);
|
|
2776
3119
|
}
|
|
2777
|
-
generateAccountKey() {
|
|
2778
|
-
throw createClientAuthError(methodNotImplemented);
|
|
2779
|
-
}
|
|
2780
|
-
}
|
|
2781
|
-
|
|
2782
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
2783
|
-
/*
|
|
2784
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2785
|
-
* Licensed under the MIT License.
|
|
2786
|
-
*/
|
|
2787
|
-
/**
|
|
2788
|
-
* Protocol modes supported by MSAL.
|
|
2789
|
-
*/
|
|
2790
|
-
const ProtocolMode = {
|
|
2791
|
-
/**
|
|
2792
|
-
* Auth Code + PKCE with Entra ID (formerly AAD) specific optimizations and features
|
|
2793
|
-
*/
|
|
2794
|
-
AAD: "AAD",
|
|
2795
|
-
/**
|
|
2796
|
-
* Auth Code + PKCE without Entra ID specific optimizations and features. For use only with non-Microsoft owned authorities.
|
|
2797
|
-
* Support is limited for this mode.
|
|
2798
|
-
*/
|
|
2799
|
-
OIDC: "OIDC",
|
|
2800
|
-
/**
|
|
2801
|
-
* Encrypted Authorize Response (EAR) with Entra ID specific optimizations and features
|
|
2802
|
-
*/
|
|
2803
|
-
EAR: "EAR",
|
|
2804
|
-
};
|
|
3120
|
+
generateAccountKey() {
|
|
3121
|
+
throw createClientAuthError(methodNotImplemented);
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
2805
3124
|
|
|
2806
|
-
/*! @azure/msal-common v15.13.
|
|
3125
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
2807
3126
|
/*
|
|
2808
3127
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2809
3128
|
* Licensed under the MIT License.
|
|
@@ -3070,7 +3389,7 @@ const PerformanceEvents = {
|
|
|
3070
3389
|
const PerformanceEventStatus = {
|
|
3071
3390
|
InProgress: 1};
|
|
3072
3391
|
|
|
3073
|
-
/*! @azure/msal-common v15.13.
|
|
3392
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3074
3393
|
|
|
3075
3394
|
/*
|
|
3076
3395
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3149,7 +3468,7 @@ class StubPerformanceClient {
|
|
|
3149
3468
|
}
|
|
3150
3469
|
}
|
|
3151
3470
|
|
|
3152
|
-
/*! @azure/msal-common v15.13.
|
|
3471
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3153
3472
|
|
|
3154
3473
|
/*
|
|
3155
3474
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3249,7 +3568,7 @@ function isOidcProtocolMode(config) {
|
|
|
3249
3568
|
return (config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC);
|
|
3250
3569
|
}
|
|
3251
3570
|
|
|
3252
|
-
/*! @azure/msal-common v15.13.
|
|
3571
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3253
3572
|
/*
|
|
3254
3573
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3255
3574
|
* Licensed under the MIT License.
|
|
@@ -3259,47 +3578,7 @@ const CcsCredentialType = {
|
|
|
3259
3578
|
UPN: "UPN",
|
|
3260
3579
|
};
|
|
3261
3580
|
|
|
3262
|
-
/*! @azure/msal-common v15.13.
|
|
3263
|
-
|
|
3264
|
-
/*
|
|
3265
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3266
|
-
* Licensed under the MIT License.
|
|
3267
|
-
*/
|
|
3268
|
-
/**
|
|
3269
|
-
* Function to build a client info object from server clientInfo string
|
|
3270
|
-
* @param rawClientInfo
|
|
3271
|
-
* @param crypto
|
|
3272
|
-
*/
|
|
3273
|
-
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
3274
|
-
if (!rawClientInfo) {
|
|
3275
|
-
throw createClientAuthError(clientInfoEmptyError);
|
|
3276
|
-
}
|
|
3277
|
-
try {
|
|
3278
|
-
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
3279
|
-
return JSON.parse(decodedClientInfo);
|
|
3280
|
-
}
|
|
3281
|
-
catch (e) {
|
|
3282
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
3283
|
-
}
|
|
3284
|
-
}
|
|
3285
|
-
/**
|
|
3286
|
-
* Function to build a client info object from cached homeAccountId string
|
|
3287
|
-
* @param homeAccountId
|
|
3288
|
-
*/
|
|
3289
|
-
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
3290
|
-
if (!homeAccountId) {
|
|
3291
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
3292
|
-
}
|
|
3293
|
-
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
3294
|
-
return {
|
|
3295
|
-
uid: clientInfoParts[0],
|
|
3296
|
-
utid: clientInfoParts.length < 2
|
|
3297
|
-
? Constants.EMPTY_STRING
|
|
3298
|
-
: clientInfoParts[1],
|
|
3299
|
-
};
|
|
3300
|
-
}
|
|
3301
|
-
|
|
3302
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
3581
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3303
3582
|
/*
|
|
3304
3583
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3305
3584
|
* Licensed under the MIT License.
|
|
@@ -3349,7 +3628,7 @@ const INSTANCE_AWARE = "instance_aware";
|
|
|
3349
3628
|
const EAR_JWK = "ear_jwk";
|
|
3350
3629
|
const EAR_JWE_CRYPTO = "ear_jwe_crypto";
|
|
3351
3630
|
|
|
3352
|
-
/*! @azure/msal-common v15.13.
|
|
3631
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3353
3632
|
|
|
3354
3633
|
/*
|
|
3355
3634
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3729,22 +4008,7 @@ function addPostBodyParameters(parameters, bodyParameters) {
|
|
|
3729
4008
|
});
|
|
3730
4009
|
}
|
|
3731
4010
|
|
|
3732
|
-
/*! @azure/msal-common v15.13.
|
|
3733
|
-
/*
|
|
3734
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3735
|
-
* Licensed under the MIT License.
|
|
3736
|
-
*/
|
|
3737
|
-
/**
|
|
3738
|
-
* Authority types supported by MSAL.
|
|
3739
|
-
*/
|
|
3740
|
-
const AuthorityType = {
|
|
3741
|
-
Default: 0,
|
|
3742
|
-
Adfs: 1,
|
|
3743
|
-
Dsts: 2,
|
|
3744
|
-
Ciam: 3,
|
|
3745
|
-
};
|
|
3746
|
-
|
|
3747
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
4011
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3748
4012
|
/*
|
|
3749
4013
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3750
4014
|
* Licensed under the MIT License.
|
|
@@ -3756,7 +4020,7 @@ function isOpenIdConfigResponse(response) {
|
|
|
3756
4020
|
response.hasOwnProperty("jwks_uri"));
|
|
3757
4021
|
}
|
|
3758
4022
|
|
|
3759
|
-
/*! @azure/msal-common v15.13.
|
|
4023
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3760
4024
|
/*
|
|
3761
4025
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3762
4026
|
* Licensed under the MIT License.
|
|
@@ -3766,7 +4030,7 @@ function isCloudInstanceDiscoveryResponse(response) {
|
|
|
3766
4030
|
response.hasOwnProperty("metadata"));
|
|
3767
4031
|
}
|
|
3768
4032
|
|
|
3769
|
-
/*! @azure/msal-common v15.13.
|
|
4033
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3770
4034
|
/*
|
|
3771
4035
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3772
4036
|
* Licensed under the MIT License.
|
|
@@ -3776,7 +4040,7 @@ function isCloudInstanceDiscoveryErrorResponse(response) {
|
|
|
3776
4040
|
response.hasOwnProperty("error_description"));
|
|
3777
4041
|
}
|
|
3778
4042
|
|
|
3779
|
-
/*! @azure/msal-common v15.13.
|
|
4043
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3780
4044
|
/*
|
|
3781
4045
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3782
4046
|
* Licensed under the MIT License.
|
|
@@ -3872,7 +4136,7 @@ const invokeAsync = (callback, eventName, logger, telemetryClient, correlationId
|
|
|
3872
4136
|
};
|
|
3873
4137
|
};
|
|
3874
4138
|
|
|
3875
|
-
/*! @azure/msal-common v15.13.
|
|
4139
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3876
4140
|
|
|
3877
4141
|
/*
|
|
3878
4142
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3978,7 +4242,7 @@ RegionDiscovery.IMDS_OPTIONS = {
|
|
|
3978
4242
|
},
|
|
3979
4243
|
};
|
|
3980
4244
|
|
|
3981
|
-
/*! @azure/msal-common v15.13.
|
|
4245
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
3982
4246
|
/*
|
|
3983
4247
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3984
4248
|
* Licensed under the MIT License.
|
|
@@ -4043,7 +4307,7 @@ function wasClockTurnedBack(cachedAt) {
|
|
|
4043
4307
|
return cachedAtSec > nowSeconds();
|
|
4044
4308
|
}
|
|
4045
4309
|
|
|
4046
|
-
/*! @azure/msal-common v15.13.
|
|
4310
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
4047
4311
|
|
|
4048
4312
|
/*
|
|
4049
4313
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4305,7 +4569,7 @@ function isAuthorityMetadataExpired(metadata) {
|
|
|
4305
4569
|
return metadata.expiresAt <= nowSeconds();
|
|
4306
4570
|
}
|
|
4307
4571
|
|
|
4308
|
-
/*! @azure/msal-common v15.13.
|
|
4572
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
4309
4573
|
|
|
4310
4574
|
/*
|
|
4311
4575
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5144,7 +5408,7 @@ function buildStaticAuthorityOptions(authOptions) {
|
|
|
5144
5408
|
};
|
|
5145
5409
|
}
|
|
5146
5410
|
|
|
5147
|
-
/*! @azure/msal-common v15.13.
|
|
5411
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5148
5412
|
|
|
5149
5413
|
/*
|
|
5150
5414
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5175,7 +5439,7 @@ async function createDiscoveredInstance(authorityUri, networkClient, cacheManage
|
|
|
5175
5439
|
}
|
|
5176
5440
|
}
|
|
5177
5441
|
|
|
5178
|
-
/*! @azure/msal-common v15.13.
|
|
5442
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5179
5443
|
|
|
5180
5444
|
/*
|
|
5181
5445
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5194,7 +5458,7 @@ class ServerError extends AuthError {
|
|
|
5194
5458
|
}
|
|
5195
5459
|
}
|
|
5196
5460
|
|
|
5197
|
-
/*! @azure/msal-common v15.13.
|
|
5461
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5198
5462
|
/*
|
|
5199
5463
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5200
5464
|
* Licensed under the MIT License.
|
|
@@ -5215,7 +5479,7 @@ function getRequestThumbprint(clientId, request, homeAccountId) {
|
|
|
5215
5479
|
};
|
|
5216
5480
|
}
|
|
5217
5481
|
|
|
5218
|
-
/*! @azure/msal-common v15.13.
|
|
5482
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5219
5483
|
|
|
5220
5484
|
/*
|
|
5221
5485
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5248,483 +5512,240 @@ class ThrottlingUtils {
|
|
|
5248
5512
|
}
|
|
5249
5513
|
/**
|
|
5250
5514
|
* Performs necessary throttling checks after a network request.
|
|
5251
|
-
* @param cacheManager
|
|
5252
|
-
* @param thumbprint
|
|
5253
|
-
* @param response
|
|
5254
|
-
*/
|
|
5255
|
-
static postProcess(cacheManager, thumbprint, response, correlationId) {
|
|
5256
|
-
if (ThrottlingUtils.checkResponseStatus(response) ||
|
|
5257
|
-
ThrottlingUtils.checkResponseForRetryAfter(response)) {
|
|
5258
|
-
const thumbprintValue = {
|
|
5259
|
-
throttleTime: ThrottlingUtils.calculateThrottleTime(parseInt(response.headers[HeaderNames.RETRY_AFTER])),
|
|
5260
|
-
error: response.body.error,
|
|
5261
|
-
errorCodes: response.body.error_codes,
|
|
5262
|
-
errorMessage: response.body.error_description,
|
|
5263
|
-
subError: response.body.suberror,
|
|
5264
|
-
};
|
|
5265
|
-
cacheManager.setThrottlingCache(ThrottlingUtils.generateThrottlingStorageKey(thumbprint), thumbprintValue, correlationId);
|
|
5266
|
-
}
|
|
5267
|
-
}
|
|
5268
|
-
/**
|
|
5269
|
-
* Checks a NetworkResponse object's status codes against 429 or 5xx
|
|
5270
|
-
* @param response
|
|
5271
|
-
*/
|
|
5272
|
-
static checkResponseStatus(response) {
|
|
5273
|
-
return (response.status === 429 ||
|
|
5274
|
-
(response.status >= 500 && response.status < 600));
|
|
5275
|
-
}
|
|
5276
|
-
/**
|
|
5277
|
-
* Checks a NetworkResponse object's RetryAfter header
|
|
5278
|
-
* @param response
|
|
5279
|
-
*/
|
|
5280
|
-
static checkResponseForRetryAfter(response) {
|
|
5281
|
-
if (response.headers) {
|
|
5282
|
-
return (response.headers.hasOwnProperty(HeaderNames.RETRY_AFTER) &&
|
|
5283
|
-
(response.status < 200 || response.status >= 300));
|
|
5284
|
-
}
|
|
5285
|
-
return false;
|
|
5286
|
-
}
|
|
5287
|
-
/**
|
|
5288
|
-
* Calculates the Unix-time value for a throttle to expire given throttleTime in seconds.
|
|
5289
|
-
* @param throttleTime
|
|
5290
|
-
*/
|
|
5291
|
-
static calculateThrottleTime(throttleTime) {
|
|
5292
|
-
const time = throttleTime <= 0 ? 0 : throttleTime;
|
|
5293
|
-
const currentSeconds = Date.now() / 1000;
|
|
5294
|
-
return Math.floor(Math.min(currentSeconds +
|
|
5295
|
-
(time || ThrottlingConstants.DEFAULT_THROTTLE_TIME_SECONDS), currentSeconds +
|
|
5296
|
-
ThrottlingConstants.DEFAULT_MAX_THROTTLE_TIME_SECONDS) * 1000);
|
|
5297
|
-
}
|
|
5298
|
-
static removeThrottle(cacheManager, clientId, request, homeAccountIdentifier) {
|
|
5299
|
-
const thumbprint = getRequestThumbprint(clientId, request, homeAccountIdentifier);
|
|
5300
|
-
const key = this.generateThrottlingStorageKey(thumbprint);
|
|
5301
|
-
cacheManager.removeItem(key, request.correlationId);
|
|
5302
|
-
}
|
|
5303
|
-
}
|
|
5304
|
-
|
|
5305
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
5306
|
-
|
|
5307
|
-
/*
|
|
5308
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5309
|
-
* Licensed under the MIT License.
|
|
5310
|
-
*/
|
|
5311
|
-
/**
|
|
5312
|
-
* Represents network related errors
|
|
5313
|
-
*/
|
|
5314
|
-
class NetworkError extends AuthError {
|
|
5315
|
-
constructor(error, httpStatus, responseHeaders) {
|
|
5316
|
-
super(error.errorCode, error.errorMessage, error.subError);
|
|
5317
|
-
Object.setPrototypeOf(this, NetworkError.prototype);
|
|
5318
|
-
this.name = "NetworkError";
|
|
5319
|
-
this.error = error;
|
|
5320
|
-
this.httpStatus = httpStatus;
|
|
5321
|
-
this.responseHeaders = responseHeaders;
|
|
5322
|
-
}
|
|
5323
|
-
}
|
|
5324
|
-
/**
|
|
5325
|
-
* Creates NetworkError object for a failed network request
|
|
5326
|
-
* @param error - Error to be thrown back to the caller
|
|
5327
|
-
* @param httpStatus - Status code of the network request
|
|
5328
|
-
* @param responseHeaders - Response headers of the network request, when available
|
|
5329
|
-
* @returns NetworkError object
|
|
5330
|
-
*/
|
|
5331
|
-
function createNetworkError(error, httpStatus, responseHeaders, additionalError) {
|
|
5332
|
-
error.errorMessage = `${error.errorMessage}, additionalErrorInfo: error.name:${additionalError?.name}, error.message:${additionalError?.message}`;
|
|
5333
|
-
return new NetworkError(error, httpStatus, responseHeaders);
|
|
5334
|
-
}
|
|
5335
|
-
|
|
5336
|
-
/*! @azure/msal-common v15.13.0 2025-10-17 */
|
|
5337
|
-
|
|
5338
|
-
/*
|
|
5339
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5340
|
-
* Licensed under the MIT License.
|
|
5341
|
-
*/
|
|
5342
|
-
/**
|
|
5343
|
-
* Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
|
|
5344
|
-
* @internal
|
|
5345
|
-
*/
|
|
5346
|
-
class BaseClient {
|
|
5347
|
-
constructor(configuration, performanceClient) {
|
|
5348
|
-
// Set the configuration
|
|
5349
|
-
this.config = buildClientConfiguration(configuration);
|
|
5350
|
-
// Initialize the logger
|
|
5351
|
-
this.logger = new Logger(this.config.loggerOptions, name$1, version$1);
|
|
5352
|
-
// Initialize crypto
|
|
5353
|
-
this.cryptoUtils = this.config.cryptoInterface;
|
|
5354
|
-
// Initialize storage interface
|
|
5355
|
-
this.cacheManager = this.config.storageInterface;
|
|
5356
|
-
// Set the network interface
|
|
5357
|
-
this.networkClient = this.config.networkInterface;
|
|
5358
|
-
// Set TelemetryManager
|
|
5359
|
-
this.serverTelemetryManager = this.config.serverTelemetryManager;
|
|
5360
|
-
// set Authority
|
|
5361
|
-
this.authority = this.config.authOptions.authority;
|
|
5362
|
-
// set performance telemetry client
|
|
5363
|
-
this.performanceClient = performanceClient;
|
|
5364
|
-
}
|
|
5365
|
-
/**
|
|
5366
|
-
* Creates default headers for requests to token endpoint
|
|
5367
|
-
*/
|
|
5368
|
-
createTokenRequestHeaders(ccsCred) {
|
|
5369
|
-
const headers = {};
|
|
5370
|
-
headers[HeaderNames.CONTENT_TYPE] = Constants.URL_FORM_CONTENT_TYPE;
|
|
5371
|
-
if (!this.config.systemOptions.preventCorsPreflight && ccsCred) {
|
|
5372
|
-
switch (ccsCred.type) {
|
|
5373
|
-
case CcsCredentialType.HOME_ACCOUNT_ID:
|
|
5374
|
-
try {
|
|
5375
|
-
const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
|
|
5376
|
-
headers[HeaderNames.CCS_HEADER] = `Oid:${clientInfo.uid}@${clientInfo.utid}`;
|
|
5377
|
-
}
|
|
5378
|
-
catch (e) {
|
|
5379
|
-
this.logger.verbose("Could not parse home account ID for CCS Header: " +
|
|
5380
|
-
e);
|
|
5381
|
-
}
|
|
5382
|
-
break;
|
|
5383
|
-
case CcsCredentialType.UPN:
|
|
5384
|
-
headers[HeaderNames.CCS_HEADER] = `UPN: ${ccsCred.credential}`;
|
|
5385
|
-
break;
|
|
5386
|
-
}
|
|
5387
|
-
}
|
|
5388
|
-
return headers;
|
|
5389
|
-
}
|
|
5390
|
-
/**
|
|
5391
|
-
* Http post to token endpoint
|
|
5392
|
-
* @param tokenEndpoint
|
|
5393
|
-
* @param queryString
|
|
5394
|
-
* @param headers
|
|
5395
|
-
* @param thumbprint
|
|
5396
|
-
*/
|
|
5397
|
-
async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, queuedEvent) {
|
|
5398
|
-
if (queuedEvent) {
|
|
5399
|
-
this.performanceClient?.addQueueMeasurement(queuedEvent, correlationId);
|
|
5400
|
-
}
|
|
5401
|
-
const response = await this.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers: headers }, correlationId);
|
|
5402
|
-
if (this.config.serverTelemetryManager &&
|
|
5403
|
-
response.status < 500 &&
|
|
5404
|
-
response.status !== 429) {
|
|
5405
|
-
// Telemetry data successfully logged by server, clear Telemetry cache
|
|
5406
|
-
this.config.serverTelemetryManager.clearTelemetryCache();
|
|
5407
|
-
}
|
|
5408
|
-
return response;
|
|
5409
|
-
}
|
|
5410
|
-
/**
|
|
5411
|
-
* Wraps sendPostRequestAsync with necessary preflight and postflight logic
|
|
5412
|
-
* @param thumbprint - Request thumbprint for throttling
|
|
5413
|
-
* @param tokenEndpoint - Endpoint to make the POST to
|
|
5414
|
-
* @param options - Body and Headers to include on the POST request
|
|
5415
|
-
* @param correlationId - CorrelationId for telemetry
|
|
5416
|
-
*/
|
|
5417
|
-
async sendPostRequest(thumbprint, tokenEndpoint, options, correlationId) {
|
|
5418
|
-
ThrottlingUtils.preProcess(this.cacheManager, thumbprint, correlationId);
|
|
5419
|
-
let response;
|
|
5420
|
-
try {
|
|
5421
|
-
response = await invokeAsync((this.networkClient.sendPostRequestAsync.bind(this.networkClient)), PerformanceEvents.NetworkClientSendPostRequestAsync, this.logger, this.performanceClient, correlationId)(tokenEndpoint, options);
|
|
5422
|
-
const responseHeaders = response.headers || {};
|
|
5423
|
-
this.performanceClient?.addFields({
|
|
5424
|
-
refreshTokenSize: response.body.refresh_token?.length || 0,
|
|
5425
|
-
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
|
|
5426
|
-
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "",
|
|
5427
|
-
}, correlationId);
|
|
5428
|
-
}
|
|
5429
|
-
catch (e) {
|
|
5430
|
-
if (e instanceof NetworkError) {
|
|
5431
|
-
const responseHeaders = e.responseHeaders;
|
|
5432
|
-
if (responseHeaders) {
|
|
5433
|
-
this.performanceClient?.addFields({
|
|
5434
|
-
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
|
|
5435
|
-
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] ||
|
|
5436
|
-
"",
|
|
5437
|
-
contentTypeHeader: responseHeaders[HeaderNames.CONTENT_TYPE] ||
|
|
5438
|
-
undefined,
|
|
5439
|
-
contentLengthHeader: responseHeaders[HeaderNames.CONTENT_LENGTH] ||
|
|
5440
|
-
undefined,
|
|
5441
|
-
httpStatus: e.httpStatus,
|
|
5442
|
-
}, correlationId);
|
|
5443
|
-
}
|
|
5444
|
-
throw e.error;
|
|
5445
|
-
}
|
|
5446
|
-
if (e instanceof AuthError) {
|
|
5447
|
-
throw e;
|
|
5448
|
-
}
|
|
5449
|
-
else {
|
|
5450
|
-
throw createClientAuthError(networkError);
|
|
5451
|
-
}
|
|
5515
|
+
* @param cacheManager
|
|
5516
|
+
* @param thumbprint
|
|
5517
|
+
* @param response
|
|
5518
|
+
*/
|
|
5519
|
+
static postProcess(cacheManager, thumbprint, response, correlationId) {
|
|
5520
|
+
if (ThrottlingUtils.checkResponseStatus(response) ||
|
|
5521
|
+
ThrottlingUtils.checkResponseForRetryAfter(response)) {
|
|
5522
|
+
const thumbprintValue = {
|
|
5523
|
+
throttleTime: ThrottlingUtils.calculateThrottleTime(parseInt(response.headers[HeaderNames.RETRY_AFTER])),
|
|
5524
|
+
error: response.body.error,
|
|
5525
|
+
errorCodes: response.body.error_codes,
|
|
5526
|
+
errorMessage: response.body.error_description,
|
|
5527
|
+
subError: response.body.suberror,
|
|
5528
|
+
};
|
|
5529
|
+
cacheManager.setThrottlingCache(ThrottlingUtils.generateThrottlingStorageKey(thumbprint), thumbprintValue, correlationId);
|
|
5452
5530
|
}
|
|
5453
|
-
ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response, correlationId);
|
|
5454
|
-
return response;
|
|
5455
5531
|
}
|
|
5456
5532
|
/**
|
|
5457
|
-
*
|
|
5458
|
-
* @param
|
|
5533
|
+
* Checks a NetworkResponse object's status codes against 429 or 5xx
|
|
5534
|
+
* @param response
|
|
5459
5535
|
*/
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
const cloudInstanceAuthority = await createDiscoveredInstance(cloudInstanceAuthorityUri, this.networkClient, this.cacheManager, this.authority.options, this.logger, correlationId, this.performanceClient);
|
|
5464
|
-
this.authority = cloudInstanceAuthority;
|
|
5536
|
+
static checkResponseStatus(response) {
|
|
5537
|
+
return (response.status === 429 ||
|
|
5538
|
+
(response.status >= 500 && response.status < 600));
|
|
5465
5539
|
}
|
|
5466
5540
|
/**
|
|
5467
|
-
*
|
|
5468
|
-
* @param
|
|
5541
|
+
* Checks a NetworkResponse object's RetryAfter header
|
|
5542
|
+
* @param response
|
|
5469
5543
|
*/
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
}
|
|
5475
|
-
if (request.tokenQueryParameters) {
|
|
5476
|
-
addExtraQueryParameters(parameters, request.tokenQueryParameters);
|
|
5544
|
+
static checkResponseForRetryAfter(response) {
|
|
5545
|
+
if (response.headers) {
|
|
5546
|
+
return (response.headers.hasOwnProperty(HeaderNames.RETRY_AFTER) &&
|
|
5547
|
+
(response.status < 200 || response.status >= 300));
|
|
5477
5548
|
}
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5549
|
+
return false;
|
|
5550
|
+
}
|
|
5551
|
+
/**
|
|
5552
|
+
* Calculates the Unix-time value for a throttle to expire given throttleTime in seconds.
|
|
5553
|
+
* @param throttleTime
|
|
5554
|
+
*/
|
|
5555
|
+
static calculateThrottleTime(throttleTime) {
|
|
5556
|
+
const time = throttleTime <= 0 ? 0 : throttleTime;
|
|
5557
|
+
const currentSeconds = Date.now() / 1000;
|
|
5558
|
+
return Math.floor(Math.min(currentSeconds +
|
|
5559
|
+
(time || ThrottlingConstants.DEFAULT_THROTTLE_TIME_SECONDS), currentSeconds +
|
|
5560
|
+
ThrottlingConstants.DEFAULT_MAX_THROTTLE_TIME_SECONDS) * 1000);
|
|
5561
|
+
}
|
|
5562
|
+
static removeThrottle(cacheManager, clientId, request, homeAccountIdentifier) {
|
|
5563
|
+
const thumbprint = getRequestThumbprint(clientId, request, homeAccountIdentifier);
|
|
5564
|
+
const key = this.generateThrottlingStorageKey(thumbprint);
|
|
5565
|
+
cacheManager.removeItem(key, request.correlationId);
|
|
5481
5566
|
}
|
|
5482
5567
|
}
|
|
5483
5568
|
|
|
5484
|
-
/*! @azure/msal-common v15.13.
|
|
5569
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5570
|
+
|
|
5485
5571
|
/*
|
|
5486
5572
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5487
5573
|
* Licensed under the MIT License.
|
|
5488
5574
|
*/
|
|
5489
5575
|
/**
|
|
5490
|
-
*
|
|
5491
|
-
* 1. tid - if the token is acquired from an Azure AD tenant tid will be present
|
|
5492
|
-
* 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
|
|
5493
|
-
* 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
|
|
5494
|
-
* Downcased to match the realm case-insensitive comparison requirements
|
|
5495
|
-
* @param idTokenClaims
|
|
5496
|
-
* @returns
|
|
5576
|
+
* Represents network related errors
|
|
5497
5577
|
*/
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5578
|
+
class NetworkError extends AuthError {
|
|
5579
|
+
constructor(error, httpStatus, responseHeaders) {
|
|
5580
|
+
super(error.errorCode, error.errorMessage, error.subError);
|
|
5581
|
+
Object.setPrototypeOf(this, NetworkError.prototype);
|
|
5582
|
+
this.name = "NetworkError";
|
|
5583
|
+
this.error = error;
|
|
5584
|
+
this.httpStatus = httpStatus;
|
|
5585
|
+
this.responseHeaders = responseHeaders;
|
|
5502
5586
|
}
|
|
5503
|
-
|
|
5587
|
+
}
|
|
5588
|
+
/**
|
|
5589
|
+
* Creates NetworkError object for a failed network request
|
|
5590
|
+
* @param error - Error to be thrown back to the caller
|
|
5591
|
+
* @param httpStatus - Status code of the network request
|
|
5592
|
+
* @param responseHeaders - Response headers of the network request, when available
|
|
5593
|
+
* @returns NetworkError object
|
|
5594
|
+
*/
|
|
5595
|
+
function createNetworkError(error, httpStatus, responseHeaders, additionalError) {
|
|
5596
|
+
error.errorMessage = `${error.errorMessage}, additionalErrorInfo: error.name:${additionalError?.name}, error.message:${additionalError?.message}`;
|
|
5597
|
+
return new NetworkError(error, httpStatus, responseHeaders);
|
|
5504
5598
|
}
|
|
5505
5599
|
|
|
5506
|
-
/*! @azure/msal-common v15.13.
|
|
5600
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5507
5601
|
|
|
5508
5602
|
/*
|
|
5509
5603
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5510
5604
|
* Licensed under the MIT License.
|
|
5511
5605
|
*/
|
|
5512
5606
|
/**
|
|
5513
|
-
*
|
|
5514
|
-
*
|
|
5515
|
-
* Key : Value Schema
|
|
5516
|
-
*
|
|
5517
|
-
* Key: <home_account_id>-<environment>-<realm*>
|
|
5518
|
-
*
|
|
5519
|
-
* Value Schema:
|
|
5520
|
-
* {
|
|
5521
|
-
* homeAccountId: home account identifier for the auth scheme,
|
|
5522
|
-
* environment: entity that issued the token, represented as a full host
|
|
5523
|
-
* realm: Full tenant or organizational identifier that the account belongs to
|
|
5524
|
-
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
5525
|
-
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
5526
|
-
* authorityType: Accounts authority type as a string
|
|
5527
|
-
* name: Full name for the account, including given name and family name,
|
|
5528
|
-
* lastModificationTime: last time this entity was modified in the cache
|
|
5529
|
-
* lastModificationApp:
|
|
5530
|
-
* nativeAccountId: Account identifier on the native device
|
|
5531
|
-
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
5532
|
-
* }
|
|
5607
|
+
* Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
|
|
5533
5608
|
* @internal
|
|
5534
5609
|
*/
|
|
5535
|
-
class
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
})),
|
|
5554
|
-
dataBoundary: this.dataBoundary,
|
|
5555
|
-
};
|
|
5556
|
-
}
|
|
5557
|
-
/**
|
|
5558
|
-
* Returns true if the account entity is in single tenant format (outdated), false otherwise
|
|
5559
|
-
*/
|
|
5560
|
-
isSingleTenant() {
|
|
5561
|
-
return !this.tenantProfiles;
|
|
5562
|
-
}
|
|
5563
|
-
/**
|
|
5564
|
-
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
5565
|
-
* @param accountDetails
|
|
5566
|
-
*/
|
|
5567
|
-
static createAccount(accountDetails, authority, base64Decode) {
|
|
5568
|
-
const account = new AccountEntity();
|
|
5569
|
-
if (authority.authorityType === AuthorityType.Adfs) {
|
|
5570
|
-
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
5571
|
-
}
|
|
5572
|
-
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
5573
|
-
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
5574
|
-
}
|
|
5575
|
-
else {
|
|
5576
|
-
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
5577
|
-
}
|
|
5578
|
-
let clientInfo;
|
|
5579
|
-
if (accountDetails.clientInfo && base64Decode) {
|
|
5580
|
-
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
|
|
5581
|
-
if (clientInfo.xms_tdbr) {
|
|
5582
|
-
account.dataBoundary =
|
|
5583
|
-
clientInfo.xms_tdbr === "EU" ? "EU" : "None";
|
|
5584
|
-
}
|
|
5585
|
-
}
|
|
5586
|
-
account.clientInfo = accountDetails.clientInfo;
|
|
5587
|
-
account.homeAccountId = accountDetails.homeAccountId;
|
|
5588
|
-
account.nativeAccountId = accountDetails.nativeAccountId;
|
|
5589
|
-
const env = accountDetails.environment ||
|
|
5590
|
-
(authority && authority.getPreferredCache());
|
|
5591
|
-
if (!env) {
|
|
5592
|
-
throw createClientAuthError(invalidCacheEnvironment);
|
|
5593
|
-
}
|
|
5594
|
-
account.environment = env;
|
|
5595
|
-
// non AAD scenarios can have empty realm
|
|
5596
|
-
account.realm =
|
|
5597
|
-
clientInfo?.utid ||
|
|
5598
|
-
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
5599
|
-
"";
|
|
5600
|
-
// How do you account for MSA CID here?
|
|
5601
|
-
account.localAccountId =
|
|
5602
|
-
clientInfo?.uid ||
|
|
5603
|
-
accountDetails.idTokenClaims?.oid ||
|
|
5604
|
-
accountDetails.idTokenClaims?.sub ||
|
|
5605
|
-
"";
|
|
5606
|
-
/*
|
|
5607
|
-
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
5608
|
-
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
5609
|
-
* policy is configured to return more than 1 email.
|
|
5610
|
-
*/
|
|
5611
|
-
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
5612
|
-
accountDetails.idTokenClaims?.upn;
|
|
5613
|
-
const email = accountDetails.idTokenClaims?.emails
|
|
5614
|
-
? accountDetails.idTokenClaims.emails[0]
|
|
5615
|
-
: null;
|
|
5616
|
-
account.username = preferredUsername || email || "";
|
|
5617
|
-
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
5618
|
-
account.name = accountDetails.idTokenClaims?.name || "";
|
|
5619
|
-
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
5620
|
-
account.msGraphHost = accountDetails.msGraphHost;
|
|
5621
|
-
if (accountDetails.tenantProfiles) {
|
|
5622
|
-
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
5623
|
-
}
|
|
5624
|
-
else {
|
|
5625
|
-
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
5626
|
-
account.tenantProfiles = [tenantProfile];
|
|
5627
|
-
}
|
|
5628
|
-
return account;
|
|
5610
|
+
class BaseClient {
|
|
5611
|
+
constructor(configuration, performanceClient) {
|
|
5612
|
+
// Set the configuration
|
|
5613
|
+
this.config = buildClientConfiguration(configuration);
|
|
5614
|
+
// Initialize the logger
|
|
5615
|
+
this.logger = new Logger(this.config.loggerOptions, name$1, version$1);
|
|
5616
|
+
// Initialize crypto
|
|
5617
|
+
this.cryptoUtils = this.config.cryptoInterface;
|
|
5618
|
+
// Initialize storage interface
|
|
5619
|
+
this.cacheManager = this.config.storageInterface;
|
|
5620
|
+
// Set the network interface
|
|
5621
|
+
this.networkClient = this.config.networkInterface;
|
|
5622
|
+
// Set TelemetryManager
|
|
5623
|
+
this.serverTelemetryManager = this.config.serverTelemetryManager;
|
|
5624
|
+
// set Authority
|
|
5625
|
+
this.authority = this.config.authOptions.authority;
|
|
5626
|
+
// set performance telemetry client
|
|
5627
|
+
this.performanceClient = performanceClient;
|
|
5629
5628
|
}
|
|
5630
5629
|
/**
|
|
5631
|
-
* Creates
|
|
5632
|
-
* @param accountInfo
|
|
5633
|
-
* @param cloudGraphHostName
|
|
5634
|
-
* @param msGraphHost
|
|
5635
|
-
* @returns
|
|
5630
|
+
* Creates default headers for requests to token endpoint
|
|
5636
5631
|
*/
|
|
5637
|
-
|
|
5638
|
-
const
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5632
|
+
createTokenRequestHeaders(ccsCred) {
|
|
5633
|
+
const headers = {};
|
|
5634
|
+
headers[HeaderNames.CONTENT_TYPE] = Constants.URL_FORM_CONTENT_TYPE;
|
|
5635
|
+
if (!this.config.systemOptions.preventCorsPreflight && ccsCred) {
|
|
5636
|
+
switch (ccsCred.type) {
|
|
5637
|
+
case CcsCredentialType.HOME_ACCOUNT_ID:
|
|
5638
|
+
try {
|
|
5639
|
+
const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
|
|
5640
|
+
headers[HeaderNames.CCS_HEADER] = `Oid:${clientInfo.uid}@${clientInfo.utid}`;
|
|
5641
|
+
}
|
|
5642
|
+
catch (e) {
|
|
5643
|
+
this.logger.verbose("Could not parse home account ID for CCS Header: " +
|
|
5644
|
+
e);
|
|
5645
|
+
}
|
|
5646
|
+
break;
|
|
5647
|
+
case CcsCredentialType.UPN:
|
|
5648
|
+
headers[HeaderNames.CCS_HEADER] = `UPN: ${ccsCred.credential}`;
|
|
5649
|
+
break;
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
return headers;
|
|
5655
5653
|
}
|
|
5656
5654
|
/**
|
|
5657
|
-
*
|
|
5658
|
-
* @param
|
|
5659
|
-
* @param
|
|
5655
|
+
* Http post to token endpoint
|
|
5656
|
+
* @param tokenEndpoint
|
|
5657
|
+
* @param queryString
|
|
5658
|
+
* @param headers
|
|
5659
|
+
* @param thumbprint
|
|
5660
5660
|
*/
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5661
|
+
async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId, queuedEvent) {
|
|
5662
|
+
if (queuedEvent) {
|
|
5663
|
+
this.performanceClient?.addQueueMeasurement(queuedEvent, correlationId);
|
|
5664
|
+
}
|
|
5665
|
+
const response = await this.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers: headers }, correlationId);
|
|
5666
|
+
if (this.config.serverTelemetryManager &&
|
|
5667
|
+
response.status < 500 &&
|
|
5668
|
+
response.status !== 429) {
|
|
5669
|
+
// Telemetry data successfully logged by server, clear Telemetry cache
|
|
5670
|
+
this.config.serverTelemetryManager.clearTelemetryCache();
|
|
5671
|
+
}
|
|
5672
|
+
return response;
|
|
5673
|
+
}
|
|
5674
|
+
/**
|
|
5675
|
+
* Wraps sendPostRequestAsync with necessary preflight and postflight logic
|
|
5676
|
+
* @param thumbprint - Request thumbprint for throttling
|
|
5677
|
+
* @param tokenEndpoint - Endpoint to make the POST to
|
|
5678
|
+
* @param options - Body and Headers to include on the POST request
|
|
5679
|
+
* @param correlationId - CorrelationId for telemetry
|
|
5680
|
+
*/
|
|
5681
|
+
async sendPostRequest(thumbprint, tokenEndpoint, options, correlationId) {
|
|
5682
|
+
ThrottlingUtils.preProcess(this.cacheManager, thumbprint, correlationId);
|
|
5683
|
+
let response;
|
|
5684
|
+
try {
|
|
5685
|
+
response = await invokeAsync((this.networkClient.sendPostRequestAsync.bind(this.networkClient)), PerformanceEvents.NetworkClientSendPostRequestAsync, this.logger, this.performanceClient, correlationId)(tokenEndpoint, options);
|
|
5686
|
+
const responseHeaders = response.headers || {};
|
|
5687
|
+
this.performanceClient?.addFields({
|
|
5688
|
+
refreshTokenSize: response.body.refresh_token?.length || 0,
|
|
5689
|
+
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
|
|
5690
|
+
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] || "",
|
|
5691
|
+
}, correlationId);
|
|
5692
|
+
}
|
|
5693
|
+
catch (e) {
|
|
5694
|
+
if (e instanceof NetworkError) {
|
|
5695
|
+
const responseHeaders = e.responseHeaders;
|
|
5696
|
+
if (responseHeaders) {
|
|
5697
|
+
this.performanceClient?.addFields({
|
|
5698
|
+
httpVerToken: responseHeaders[HeaderNames.X_MS_HTTP_VERSION] || "",
|
|
5699
|
+
requestId: responseHeaders[HeaderNames.X_MS_REQUEST_ID] ||
|
|
5700
|
+
"",
|
|
5701
|
+
contentTypeHeader: responseHeaders[HeaderNames.CONTENT_TYPE] ||
|
|
5702
|
+
undefined,
|
|
5703
|
+
contentLengthHeader: responseHeaders[HeaderNames.CONTENT_LENGTH] ||
|
|
5704
|
+
undefined,
|
|
5705
|
+
httpStatus: e.httpStatus,
|
|
5706
|
+
}, correlationId);
|
|
5672
5707
|
}
|
|
5673
|
-
|
|
5708
|
+
throw e.error;
|
|
5709
|
+
}
|
|
5710
|
+
if (e instanceof AuthError) {
|
|
5711
|
+
throw e;
|
|
5712
|
+
}
|
|
5713
|
+
else {
|
|
5714
|
+
throw createClientAuthError(networkError);
|
|
5674
5715
|
}
|
|
5675
|
-
logger.warning("No client info in response");
|
|
5676
5716
|
}
|
|
5677
|
-
|
|
5678
|
-
return
|
|
5717
|
+
ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response, correlationId);
|
|
5718
|
+
return response;
|
|
5679
5719
|
}
|
|
5680
5720
|
/**
|
|
5681
|
-
*
|
|
5682
|
-
* @param
|
|
5721
|
+
* Updates the authority object of the client. Endpoint discovery must be completed.
|
|
5722
|
+
* @param updatedAuthority
|
|
5683
5723
|
*/
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
entity.hasOwnProperty("environment") &&
|
|
5690
|
-
entity.hasOwnProperty("realm") &&
|
|
5691
|
-
entity.hasOwnProperty("localAccountId") &&
|
|
5692
|
-
entity.hasOwnProperty("username") &&
|
|
5693
|
-
entity.hasOwnProperty("authorityType"));
|
|
5724
|
+
async updateAuthority(cloudInstanceHostname, correlationId) {
|
|
5725
|
+
this.performanceClient?.addQueueMeasurement(PerformanceEvents.UpdateTokenEndpointAuthority, correlationId);
|
|
5726
|
+
const cloudInstanceAuthorityUri = `https://${cloudInstanceHostname}/${this.authority.tenant}/`;
|
|
5727
|
+
const cloudInstanceAuthority = await createDiscoveredInstance(cloudInstanceAuthorityUri, this.networkClient, this.cacheManager, this.authority.options, this.logger, correlationId, this.performanceClient);
|
|
5728
|
+
this.authority = cloudInstanceAuthority;
|
|
5694
5729
|
}
|
|
5695
5730
|
/**
|
|
5696
|
-
*
|
|
5697
|
-
* @param
|
|
5698
|
-
* @param accountB
|
|
5699
|
-
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
5731
|
+
* Creates query string for the /token request
|
|
5732
|
+
* @param request
|
|
5700
5733
|
*/
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5734
|
+
createTokenQueryParameters(request) {
|
|
5735
|
+
const parameters = new Map();
|
|
5736
|
+
if (request.embeddedClientId) {
|
|
5737
|
+
addBrokerParameters(parameters, this.config.authOptions.clientId, this.config.authOptions.redirectUri);
|
|
5704
5738
|
}
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
const accountAClaims = (accountA.idTokenClaims ||
|
|
5708
|
-
{});
|
|
5709
|
-
const accountBClaims = (accountB.idTokenClaims ||
|
|
5710
|
-
{});
|
|
5711
|
-
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
5712
|
-
claimsMatch =
|
|
5713
|
-
accountAClaims.iat === accountBClaims.iat &&
|
|
5714
|
-
accountAClaims.nonce === accountBClaims.nonce;
|
|
5739
|
+
if (request.tokenQueryParameters) {
|
|
5740
|
+
addExtraQueryParameters(parameters, request.tokenQueryParameters);
|
|
5715
5741
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
accountA.tenantId === accountB.tenantId &&
|
|
5720
|
-
accountA.loginHint === accountB.loginHint &&
|
|
5721
|
-
accountA.environment === accountB.environment &&
|
|
5722
|
-
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
5723
|
-
claimsMatch);
|
|
5742
|
+
addCorrelationId(parameters, request.correlationId);
|
|
5743
|
+
instrumentBrokerParams(parameters, request.correlationId, this.performanceClient);
|
|
5744
|
+
return mapToQueryString(parameters);
|
|
5724
5745
|
}
|
|
5725
5746
|
}
|
|
5726
5747
|
|
|
5727
|
-
/*! @azure/msal-common v15.13.
|
|
5748
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5728
5749
|
/*
|
|
5729
5750
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5730
5751
|
* Licensed under the MIT License.
|
|
@@ -5740,7 +5761,7 @@ const consentRequired = "consent_required";
|
|
|
5740
5761
|
const loginRequired = "login_required";
|
|
5741
5762
|
const badToken = "bad_token";
|
|
5742
5763
|
|
|
5743
|
-
/*! @azure/msal-common v15.13.
|
|
5764
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5744
5765
|
|
|
5745
5766
|
/*
|
|
5746
5767
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5812,7 +5833,7 @@ function createInteractionRequiredAuthError(errorCode) {
|
|
|
5812
5833
|
return new InteractionRequiredAuthError(errorCode, InteractionRequiredAuthErrorMessages[errorCode]);
|
|
5813
5834
|
}
|
|
5814
5835
|
|
|
5815
|
-
/*! @azure/msal-common v15.13.
|
|
5836
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5816
5837
|
|
|
5817
5838
|
/*
|
|
5818
5839
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5884,7 +5905,7 @@ class ProtocolUtils {
|
|
|
5884
5905
|
}
|
|
5885
5906
|
}
|
|
5886
5907
|
|
|
5887
|
-
/*! @azure/msal-common v15.13.
|
|
5908
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5888
5909
|
|
|
5889
5910
|
/*
|
|
5890
5911
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5966,7 +5987,7 @@ class PopTokenGenerator {
|
|
|
5966
5987
|
}
|
|
5967
5988
|
}
|
|
5968
5989
|
|
|
5969
|
-
/*! @azure/msal-common v15.13.
|
|
5990
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5970
5991
|
/*
|
|
5971
5992
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5972
5993
|
* Licensed under the MIT License.
|
|
@@ -5993,7 +6014,7 @@ class PopTokenGenerator {
|
|
|
5993
6014
|
}
|
|
5994
6015
|
}
|
|
5995
6016
|
|
|
5996
|
-
/*! @azure/msal-common v15.13.
|
|
6017
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
5997
6018
|
|
|
5998
6019
|
/*
|
|
5999
6020
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6105,14 +6126,14 @@ class ResponseHandler {
|
|
|
6105
6126
|
if (handlingRefreshTokenResponse &&
|
|
6106
6127
|
!forceCacheRefreshTokenResponse &&
|
|
6107
6128
|
cacheRecord.account) {
|
|
6108
|
-
const key = this.cacheStorage.generateAccountKey(cacheRecord.account
|
|
6129
|
+
const key = this.cacheStorage.generateAccountKey(AccountEntity.getAccountInfo(cacheRecord.account));
|
|
6109
6130
|
const account = this.cacheStorage.getAccount(key, request.correlationId);
|
|
6110
6131
|
if (!account) {
|
|
6111
6132
|
this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
|
|
6112
6133
|
return await ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, undefined, serverRequestId);
|
|
6113
6134
|
}
|
|
6114
6135
|
}
|
|
6115
|
-
await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, request.storeInCache);
|
|
6136
|
+
await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, isKmsi(idTokenClaims || {}), request.storeInCache);
|
|
6116
6137
|
}
|
|
6117
6138
|
finally {
|
|
6118
6139
|
if (this.persistencePlugin &&
|
|
@@ -6259,7 +6280,7 @@ class ResponseHandler {
|
|
|
6259
6280
|
serverTokenResponse?.spa_accountid;
|
|
6260
6281
|
}
|
|
6261
6282
|
const accountInfo = cacheRecord.account
|
|
6262
|
-
? updateAccountTenantProfileData(cacheRecord.account
|
|
6283
|
+
? updateAccountTenantProfileData(AccountEntity.getAccountInfo(cacheRecord.account), undefined, // tenantProfile optional
|
|
6263
6284
|
idTokenClaims, cacheRecord.idToken?.secret)
|
|
6264
6285
|
: null;
|
|
6265
6286
|
return {
|
|
@@ -6324,7 +6345,7 @@ function buildAccountToCache(cacheStorage, authority, homeAccountId, base64Decod
|
|
|
6324
6345
|
return baseAccount;
|
|
6325
6346
|
}
|
|
6326
6347
|
|
|
6327
|
-
/*! @azure/msal-common v15.13.
|
|
6348
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6328
6349
|
/*
|
|
6329
6350
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6330
6351
|
* Licensed under the MIT License.
|
|
@@ -6342,7 +6363,7 @@ async function getClientAssertion(clientAssertion, clientId, tokenEndpoint) {
|
|
|
6342
6363
|
}
|
|
6343
6364
|
}
|
|
6344
6365
|
|
|
6345
|
-
/*! @azure/msal-common v15.13.
|
|
6366
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6346
6367
|
|
|
6347
6368
|
/*
|
|
6348
6369
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6577,7 +6598,7 @@ class AuthorizationCodeClient extends BaseClient {
|
|
|
6577
6598
|
}
|
|
6578
6599
|
}
|
|
6579
6600
|
|
|
6580
|
-
/*! @azure/msal-common v15.13.
|
|
6601
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6581
6602
|
|
|
6582
6603
|
/*
|
|
6583
6604
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6786,7 +6807,7 @@ class RefreshTokenClient extends BaseClient {
|
|
|
6786
6807
|
}
|
|
6787
6808
|
}
|
|
6788
6809
|
|
|
6789
|
-
/*! @azure/msal-common v15.13.
|
|
6810
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6790
6811
|
|
|
6791
6812
|
/*
|
|
6792
6813
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6884,7 +6905,7 @@ class SilentFlowClient extends BaseClient {
|
|
|
6884
6905
|
}
|
|
6885
6906
|
}
|
|
6886
6907
|
|
|
6887
|
-
/*! @azure/msal-common v15.13.
|
|
6908
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6888
6909
|
|
|
6889
6910
|
/*
|
|
6890
6911
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6899,7 +6920,7 @@ const StubbedNetworkModule = {
|
|
|
6899
6920
|
},
|
|
6900
6921
|
};
|
|
6901
6922
|
|
|
6902
|
-
/*! @azure/msal-common v15.13.
|
|
6923
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
6903
6924
|
|
|
6904
6925
|
/*
|
|
6905
6926
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7123,7 +7144,7 @@ function extractLoginHint(account) {
|
|
|
7123
7144
|
return account.loginHint || account.idTokenClaims?.login_hint || null;
|
|
7124
7145
|
}
|
|
7125
7146
|
|
|
7126
|
-
/*! @azure/msal-common v15.13.
|
|
7147
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
7127
7148
|
|
|
7128
7149
|
/*
|
|
7129
7150
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7386,7 +7407,7 @@ class ServerTelemetryManager {
|
|
|
7386
7407
|
}
|
|
7387
7408
|
}
|
|
7388
7409
|
|
|
7389
|
-
/*! @azure/msal-common v15.13.
|
|
7410
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
7390
7411
|
/*
|
|
7391
7412
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
7392
7413
|
* Licensed under the MIT License.
|
|
@@ -7394,7 +7415,7 @@ class ServerTelemetryManager {
|
|
|
7394
7415
|
const missingKidError = "missing_kid_error";
|
|
7395
7416
|
const missingAlgError = "missing_alg_error";
|
|
7396
7417
|
|
|
7397
|
-
/*! @azure/msal-common v15.13.
|
|
7418
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
7398
7419
|
|
|
7399
7420
|
/*
|
|
7400
7421
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7419,7 +7440,7 @@ function createJoseHeaderError(code) {
|
|
|
7419
7440
|
return new JoseHeaderError(code, JoseHeaderErrorMessages[code]);
|
|
7420
7441
|
}
|
|
7421
7442
|
|
|
7422
|
-
/*! @azure/msal-common v15.13.
|
|
7443
|
+
/*! @azure/msal-common v15.13.1 2025-11-06 */
|
|
7423
7444
|
|
|
7424
7445
|
/*
|
|
7425
7446
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7854,7 +7875,7 @@ function ensureArgumentIsJSONString(argName, argValue, correlationId) {
|
|
|
7854
7875
|
|
|
7855
7876
|
/* eslint-disable header/header */
|
|
7856
7877
|
const name = "@azure/msal-browser";
|
|
7857
|
-
const version = "4.
|
|
7878
|
+
const version = "4.26.1";
|
|
7858
7879
|
|
|
7859
7880
|
/*
|
|
7860
7881
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -14148,9 +14169,9 @@ function getSortedObjectString(obj) {
|
|
|
14148
14169
|
*/
|
|
14149
14170
|
const PREFIX = "msal";
|
|
14150
14171
|
const BROWSER_PREFIX = "browser";
|
|
14151
|
-
const CACHE_KEY_SEPARATOR = "
|
|
14152
|
-
const CREDENTIAL_SCHEMA_VERSION =
|
|
14153
|
-
const ACCOUNT_SCHEMA_VERSION =
|
|
14172
|
+
const CACHE_KEY_SEPARATOR = "|";
|
|
14173
|
+
const CREDENTIAL_SCHEMA_VERSION = 2;
|
|
14174
|
+
const ACCOUNT_SCHEMA_VERSION = 2;
|
|
14154
14175
|
const LOG_LEVEL_CACHE_KEY = `${PREFIX}.${BROWSER_PREFIX}.log.level`;
|
|
14155
14176
|
const LOG_PII_CACHE_KEY = `${PREFIX}.${BROWSER_PREFIX}.log.pii`;
|
|
14156
14177
|
const PLATFORM_AUTH_DOM_SUPPORT = `${PREFIX}.${BROWSER_PREFIX}.platform.auth.dom`;
|
|
@@ -14378,7 +14399,10 @@ class LocalStorage {
|
|
|
14378
14399
|
return null;
|
|
14379
14400
|
}
|
|
14380
14401
|
try {
|
|
14381
|
-
return
|
|
14402
|
+
return {
|
|
14403
|
+
...JSON.parse(decryptedData),
|
|
14404
|
+
lastUpdatedAt: data.lastUpdatedAt,
|
|
14405
|
+
};
|
|
14382
14406
|
}
|
|
14383
14407
|
catch (e) {
|
|
14384
14408
|
this.performanceClient.incrementFields({ encryptedCacheCorruptionCount: 1 }, correlationId);
|
|
@@ -14388,19 +14412,24 @@ class LocalStorage {
|
|
|
14388
14412
|
setItem(key, value) {
|
|
14389
14413
|
window.localStorage.setItem(key, value);
|
|
14390
14414
|
}
|
|
14391
|
-
async setUserData(key, value, correlationId, timestamp) {
|
|
14415
|
+
async setUserData(key, value, correlationId, timestamp, kmsi) {
|
|
14392
14416
|
if (!this.initialized || !this.encryptionCookie) {
|
|
14393
14417
|
throw createBrowserAuthError(uninitializedPublicClientApplication);
|
|
14394
14418
|
}
|
|
14395
|
-
|
|
14396
|
-
|
|
14397
|
-
|
|
14398
|
-
|
|
14399
|
-
|
|
14400
|
-
|
|
14401
|
-
|
|
14419
|
+
if (kmsi) {
|
|
14420
|
+
this.setItem(key, value);
|
|
14421
|
+
}
|
|
14422
|
+
else {
|
|
14423
|
+
const { data, nonce } = await invokeAsync(encrypt, PerformanceEvents.Encrypt, this.logger, this.performanceClient, correlationId)(this.encryptionCookie.key, value, this.getContext(key));
|
|
14424
|
+
const encryptedData = {
|
|
14425
|
+
id: this.encryptionCookie.id,
|
|
14426
|
+
nonce: nonce,
|
|
14427
|
+
data: data,
|
|
14428
|
+
lastUpdatedAt: timestamp,
|
|
14429
|
+
};
|
|
14430
|
+
this.setItem(key, JSON.stringify(encryptedData));
|
|
14431
|
+
}
|
|
14402
14432
|
this.memoryStorage.setItem(key, value);
|
|
14403
|
-
this.setItem(key, JSON.stringify(encryptedData));
|
|
14404
14433
|
// Notify other frames to update their in-memory cache
|
|
14405
14434
|
this.broadcast.postMessage({
|
|
14406
14435
|
key: key,
|
|
@@ -14500,13 +14529,14 @@ class LocalStorage {
|
|
|
14500
14529
|
if (!isEncrypted(encObj)) {
|
|
14501
14530
|
// Data is not encrypted
|
|
14502
14531
|
this.performanceClient.incrementFields({ unencryptedCacheCount: 1 }, correlationId);
|
|
14503
|
-
return
|
|
14532
|
+
return rawCache;
|
|
14504
14533
|
}
|
|
14505
14534
|
if (encObj.id !== this.encryptionCookie.id) {
|
|
14506
14535
|
// Data was encrypted with a different key. It must be removed because it is from a previous session.
|
|
14507
14536
|
this.performanceClient.incrementFields({ encryptedCacheExpiredCount: 1 }, correlationId);
|
|
14508
14537
|
return null;
|
|
14509
14538
|
}
|
|
14539
|
+
this.performanceClient.incrementFields({ encryptedCacheCount: 1 }, correlationId);
|
|
14510
14540
|
return invokeAsync(decrypt, PerformanceEvents.Decrypt, this.logger, this.performanceClient, correlationId)(this.encryptionCookie.key, encObj.nonce, this.getContext(key), encObj.data);
|
|
14511
14541
|
}
|
|
14512
14542
|
/**
|
|
@@ -14698,108 +14728,338 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14698
14728
|
* Migrates any existing cache data from previous versions of MSAL.js into the current cache structure.
|
|
14699
14729
|
*/
|
|
14700
14730
|
async migrateExistingCache(correlationId) {
|
|
14701
|
-
|
|
14702
|
-
|
|
14731
|
+
let accountKeys = getAccountKeys(this.browserStorage);
|
|
14732
|
+
let tokenKeys = getTokenKeys(this.clientId, this.browserStorage);
|
|
14703
14733
|
this.performanceClient.addFields({
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14734
|
+
preMigrateAcntCount: accountKeys.length,
|
|
14735
|
+
preMigrateATCount: tokenKeys.accessToken.length,
|
|
14736
|
+
preMigrateITCount: tokenKeys.idToken.length,
|
|
14737
|
+
preMigrateRTCount: tokenKeys.refreshToken.length,
|
|
14708
14738
|
}, correlationId);
|
|
14709
|
-
|
|
14710
|
-
|
|
14739
|
+
for (let i = 0; i < ACCOUNT_SCHEMA_VERSION; i++) {
|
|
14740
|
+
const credentialSchema = i; // For now account and credential schemas are the same, but may diverge in future
|
|
14741
|
+
await this.removeStaleAccounts(i, credentialSchema, correlationId);
|
|
14742
|
+
}
|
|
14743
|
+
// Must migrate idTokens first to ensure we have KMSI info for the rest
|
|
14744
|
+
for (let i = 0; i < CREDENTIAL_SCHEMA_VERSION; i++) {
|
|
14745
|
+
const accountSchema = i; // For now account and credential schemas are the same, but may diverge in future
|
|
14746
|
+
await this.migrateIdTokens(i, accountSchema, correlationId);
|
|
14747
|
+
}
|
|
14748
|
+
const kmsiMap = this.getKMSIValues();
|
|
14749
|
+
for (let i = 0; i < CREDENTIAL_SCHEMA_VERSION; i++) {
|
|
14750
|
+
await this.migrateAccessTokens(i, kmsiMap, correlationId);
|
|
14751
|
+
await this.migrateRefreshTokens(i, kmsiMap, correlationId);
|
|
14752
|
+
}
|
|
14753
|
+
accountKeys = getAccountKeys(this.browserStorage);
|
|
14754
|
+
tokenKeys = getTokenKeys(this.clientId, this.browserStorage);
|
|
14711
14755
|
this.performanceClient.addFields({
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14756
|
+
postMigrateAcntCount: accountKeys.length,
|
|
14757
|
+
postMigrateATCount: tokenKeys.accessToken.length,
|
|
14758
|
+
postMigrateITCount: tokenKeys.idToken.length,
|
|
14759
|
+
postMigrateRTCount: tokenKeys.refreshToken.length,
|
|
14716
14760
|
}, correlationId);
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14761
|
+
}
|
|
14762
|
+
/**
|
|
14763
|
+
* Parses entry, adds lastUpdatedAt if it doesn't exist, removes entry if expired or invalid
|
|
14764
|
+
* @param key
|
|
14765
|
+
* @param correlationId
|
|
14766
|
+
* @returns
|
|
14767
|
+
*/
|
|
14768
|
+
async updateOldEntry(key, correlationId) {
|
|
14769
|
+
const rawValue = this.browserStorage.getItem(key);
|
|
14770
|
+
const parsedValue = this.validateAndParseJson(rawValue || "");
|
|
14771
|
+
if (!parsedValue) {
|
|
14772
|
+
this.browserStorage.removeItem(key);
|
|
14773
|
+
return null;
|
|
14725
14774
|
}
|
|
14726
|
-
|
|
14727
|
-
|
|
14775
|
+
if (!parsedValue.lastUpdatedAt) {
|
|
14776
|
+
// Add lastUpdatedAt to the existing v0 entry if it doesnt exist so we know when it's safe to remove it
|
|
14777
|
+
parsedValue.lastUpdatedAt = Date.now().toString();
|
|
14778
|
+
this.setItem(key, JSON.stringify(parsedValue), correlationId);
|
|
14728
14779
|
}
|
|
14729
|
-
if (
|
|
14730
|
-
this.browserStorage.
|
|
14780
|
+
else if (isCacheExpired(parsedValue.lastUpdatedAt, this.cacheConfig.cacheRetentionDays)) {
|
|
14781
|
+
this.browserStorage.removeItem(key);
|
|
14782
|
+
this.performanceClient.incrementFields({ expiredCacheRemovedCount: 1 }, correlationId);
|
|
14783
|
+
return null;
|
|
14731
14784
|
}
|
|
14732
|
-
|
|
14733
|
-
this.browserStorage.
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14785
|
+
const decryptedData = isEncrypted(parsedValue)
|
|
14786
|
+
? await this.browserStorage.decryptData(key, parsedValue, correlationId)
|
|
14787
|
+
: parsedValue;
|
|
14788
|
+
if (!decryptedData || !isCredentialEntity(decryptedData)) {
|
|
14789
|
+
this.performanceClient.incrementFields({ invalidCacheCount: 1 }, correlationId);
|
|
14790
|
+
return null;
|
|
14791
|
+
}
|
|
14792
|
+
if ((isAccessTokenEntity(decryptedData) ||
|
|
14793
|
+
isRefreshTokenEntity(decryptedData)) &&
|
|
14794
|
+
decryptedData.expiresOn &&
|
|
14795
|
+
isTokenExpired(decryptedData.expiresOn, DEFAULT_TOKEN_RENEWAL_OFFSET_SEC)) {
|
|
14796
|
+
this.browserStorage.removeItem(key);
|
|
14797
|
+
this.performanceClient.incrementFields({ expiredCacheRemovedCount: 1 }, correlationId);
|
|
14798
|
+
return null;
|
|
14799
|
+
}
|
|
14800
|
+
return decryptedData;
|
|
14801
|
+
}
|
|
14802
|
+
/**
|
|
14803
|
+
* Remove accounts from the cache for older schema versions if they have not been updated in the last cacheRetentionDays
|
|
14804
|
+
* @param accountSchema
|
|
14805
|
+
* @param credentialSchema
|
|
14806
|
+
* @param correlationId
|
|
14807
|
+
* @returns
|
|
14808
|
+
*/
|
|
14809
|
+
async removeStaleAccounts(accountSchema, credentialSchema, correlationId) {
|
|
14810
|
+
const accountKeysToCheck = getAccountKeys(this.browserStorage, accountSchema);
|
|
14811
|
+
if (accountKeysToCheck.length === 0) {
|
|
14812
|
+
return;
|
|
14813
|
+
}
|
|
14814
|
+
for (const accountKey of [...accountKeysToCheck]) {
|
|
14815
|
+
this.performanceClient.incrementFields({ oldAcntCount: 1 }, correlationId);
|
|
14816
|
+
const rawValue = this.browserStorage.getItem(accountKey);
|
|
14817
|
+
const parsedValue = this.validateAndParseJson(rawValue || "");
|
|
14818
|
+
if (!parsedValue) {
|
|
14819
|
+
removeElementFromArray(accountKeysToCheck, accountKey);
|
|
14820
|
+
continue;
|
|
14821
|
+
}
|
|
14822
|
+
if (!parsedValue.lastUpdatedAt) {
|
|
14823
|
+
// Add lastUpdatedAt to the existing entry if it doesnt exist so we know when it's safe to remove it
|
|
14824
|
+
parsedValue.lastUpdatedAt = Date.now().toString();
|
|
14825
|
+
this.setItem(accountKey, JSON.stringify(parsedValue), correlationId);
|
|
14826
|
+
continue;
|
|
14827
|
+
}
|
|
14828
|
+
else if (isCacheExpired(parsedValue.lastUpdatedAt, this.cacheConfig.cacheRetentionDays)) {
|
|
14829
|
+
// Cache expired remove account and associated tokens
|
|
14830
|
+
await this.removeAccountOldSchema(accountKey, parsedValue, credentialSchema, correlationId);
|
|
14831
|
+
removeElementFromArray(accountKeysToCheck, accountKey);
|
|
14832
|
+
}
|
|
14833
|
+
}
|
|
14834
|
+
this.setAccountKeys(accountKeysToCheck, correlationId, accountSchema);
|
|
14835
|
+
}
|
|
14836
|
+
/**
|
|
14837
|
+
* Remove the given account and all associated tokens from the cache
|
|
14838
|
+
* @param accountKey
|
|
14839
|
+
* @param rawObject
|
|
14840
|
+
* @param credentialSchema
|
|
14841
|
+
* @param correlationId
|
|
14842
|
+
*/
|
|
14843
|
+
async removeAccountOldSchema(accountKey, rawObject, credentialSchema, correlationId) {
|
|
14844
|
+
const decryptedData = isEncrypted(rawObject)
|
|
14845
|
+
? (await this.browserStorage.decryptData(accountKey, rawObject, correlationId))
|
|
14846
|
+
: rawObject;
|
|
14847
|
+
const homeAccountId = decryptedData?.homeAccountId;
|
|
14848
|
+
if (homeAccountId) {
|
|
14849
|
+
const tokenKeys = this.getTokenKeys(credentialSchema);
|
|
14850
|
+
[...tokenKeys.idToken]
|
|
14851
|
+
.filter((key) => key.includes(homeAccountId))
|
|
14852
|
+
.forEach((key) => {
|
|
14853
|
+
this.browserStorage.removeItem(key);
|
|
14854
|
+
removeElementFromArray(tokenKeys.idToken, key);
|
|
14855
|
+
});
|
|
14856
|
+
[...tokenKeys.accessToken]
|
|
14857
|
+
.filter((key) => key.includes(homeAccountId))
|
|
14858
|
+
.forEach((key) => {
|
|
14859
|
+
this.browserStorage.removeItem(key);
|
|
14860
|
+
removeElementFromArray(tokenKeys.accessToken, key);
|
|
14861
|
+
});
|
|
14862
|
+
[...tokenKeys.refreshToken]
|
|
14863
|
+
.filter((key) => key.includes(homeAccountId))
|
|
14864
|
+
.forEach((key) => {
|
|
14865
|
+
this.browserStorage.removeItem(key);
|
|
14866
|
+
removeElementFromArray(tokenKeys.refreshToken, key);
|
|
14867
|
+
});
|
|
14868
|
+
this.setTokenKeys(tokenKeys, correlationId, credentialSchema);
|
|
14869
|
+
}
|
|
14870
|
+
this.performanceClient.incrementFields({ expiredAcntRemovedCount: 1 }, correlationId);
|
|
14871
|
+
this.browserStorage.removeItem(accountKey);
|
|
14872
|
+
}
|
|
14873
|
+
/**
|
|
14874
|
+
* Gets key value pair mapping homeAccountId to KMSI value
|
|
14875
|
+
* @returns
|
|
14876
|
+
*/
|
|
14877
|
+
getKMSIValues() {
|
|
14878
|
+
const kmsiMap = {};
|
|
14879
|
+
const tokenKeys = this.getTokenKeys().idToken;
|
|
14880
|
+
for (const key of tokenKeys) {
|
|
14881
|
+
const rawValue = this.browserStorage.getUserData(key);
|
|
14882
|
+
if (rawValue) {
|
|
14883
|
+
const idToken = JSON.parse(rawValue);
|
|
14884
|
+
const claims = extractTokenClaims(idToken.secret, base64Decode);
|
|
14885
|
+
if (claims) {
|
|
14886
|
+
kmsiMap[idToken.homeAccountId] = isKmsi(claims);
|
|
14887
|
+
}
|
|
14888
|
+
}
|
|
14889
|
+
}
|
|
14890
|
+
return kmsiMap;
|
|
14891
|
+
}
|
|
14892
|
+
/**
|
|
14893
|
+
* Migrates id tokens from the old schema to the new schema, also migrates associated account object if it doesn't already exist in the new schema
|
|
14894
|
+
* @param credentialSchema
|
|
14895
|
+
* @param accountSchema
|
|
14896
|
+
* @param correlationId
|
|
14897
|
+
* @returns
|
|
14898
|
+
*/
|
|
14899
|
+
async migrateIdTokens(credentialSchema, accountSchema, correlationId) {
|
|
14900
|
+
const credentialKeysToMigrate = getTokenKeys(this.clientId, this.browserStorage, credentialSchema);
|
|
14901
|
+
if (credentialKeysToMigrate.idToken.length === 0) {
|
|
14902
|
+
return;
|
|
14903
|
+
}
|
|
14904
|
+
const currentCredentialKeys = getTokenKeys(this.clientId, this.browserStorage, CREDENTIAL_SCHEMA_VERSION);
|
|
14905
|
+
const currentAccountKeys = getAccountKeys(this.browserStorage);
|
|
14906
|
+
const previousAccountKeys = getAccountKeys(this.browserStorage, accountSchema);
|
|
14907
|
+
for (const idTokenKey of [...credentialKeysToMigrate.idToken]) {
|
|
14908
|
+
this.performanceClient.incrementFields({ oldITCount: 1 }, correlationId);
|
|
14909
|
+
const oldSchemaData = (await this.updateOldEntry(idTokenKey, correlationId));
|
|
14910
|
+
if (!oldSchemaData) {
|
|
14911
|
+
removeElementFromArray(credentialKeysToMigrate.idToken, idTokenKey);
|
|
14912
|
+
continue;
|
|
14913
|
+
}
|
|
14914
|
+
const currentAccountKey = currentAccountKeys.find((key) => key.includes(oldSchemaData.homeAccountId));
|
|
14915
|
+
const previousAccountKey = previousAccountKeys.find((key) => key.includes(oldSchemaData.homeAccountId));
|
|
14916
|
+
let account = null;
|
|
14917
|
+
if (currentAccountKey) {
|
|
14918
|
+
account = this.getAccount(currentAccountKey, correlationId);
|
|
14919
|
+
}
|
|
14920
|
+
else if (previousAccountKey) {
|
|
14921
|
+
const rawValue = this.browserStorage.getItem(previousAccountKey);
|
|
14922
|
+
const parsedValue = this.validateAndParseJson(rawValue || "");
|
|
14923
|
+
account =
|
|
14924
|
+
parsedValue && isEncrypted(parsedValue)
|
|
14925
|
+
? (await this.browserStorage.decryptData(previousAccountKey, parsedValue, correlationId))
|
|
14926
|
+
: parsedValue;
|
|
14927
|
+
}
|
|
14928
|
+
if (!account) {
|
|
14929
|
+
// Don't migrate idToken if we don't have an account for it
|
|
14930
|
+
this.performanceClient.incrementFields({ skipITMigrateCount: 1 }, correlationId);
|
|
14745
14931
|
continue;
|
|
14746
14932
|
}
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14933
|
+
const claims = extractTokenClaims(oldSchemaData.secret, base64Decode);
|
|
14934
|
+
const newIdTokenKey = this.generateCredentialKey(oldSchemaData);
|
|
14935
|
+
const currentIdToken = this.getIdTokenCredential(newIdTokenKey, correlationId);
|
|
14936
|
+
const oldTokenHasSignInState = Object.keys(claims).includes("signin_state");
|
|
14937
|
+
const currentTokenHasSignInState = currentIdToken &&
|
|
14938
|
+
Object.keys(extractTokenClaims(currentIdToken.secret, base64Decode) || {}).includes("signin_state");
|
|
14939
|
+
/**
|
|
14940
|
+
* Only migrate if:
|
|
14941
|
+
* 1. Token doesn't yet exist in current schema
|
|
14942
|
+
* 2. Old schema token has been updated more recently than the current one AND migrating it won't result in loss of KMSI state
|
|
14943
|
+
*/
|
|
14944
|
+
if (!currentIdToken ||
|
|
14945
|
+
(oldSchemaData.lastUpdatedAt > currentIdToken.lastUpdatedAt &&
|
|
14946
|
+
(oldTokenHasSignInState || !currentTokenHasSignInState))) {
|
|
14947
|
+
const tenantProfiles = account.tenantProfiles || [];
|
|
14948
|
+
const tenantId = getTenantIdFromIdTokenClaims(claims) || account.realm;
|
|
14949
|
+
if (tenantId &&
|
|
14950
|
+
!tenantProfiles.find((tenantProfile) => {
|
|
14951
|
+
return tenantProfile.tenantId === tenantId;
|
|
14952
|
+
})) {
|
|
14953
|
+
const newTenantProfile = buildTenantProfile(account.homeAccountId, account.localAccountId, tenantId, claims);
|
|
14954
|
+
tenantProfiles.push(newTenantProfile);
|
|
14759
14955
|
}
|
|
14760
|
-
|
|
14761
|
-
|
|
14956
|
+
account.tenantProfiles = tenantProfiles;
|
|
14957
|
+
const newAccountKey = this.generateAccountKey(AccountEntity.getAccountInfo(account));
|
|
14958
|
+
const kmsi = isKmsi(claims);
|
|
14959
|
+
await this.setUserData(newAccountKey, JSON.stringify(account), correlationId, account.lastUpdatedAt, kmsi);
|
|
14960
|
+
if (!currentAccountKeys.includes(newAccountKey)) {
|
|
14961
|
+
currentAccountKeys.push(newAccountKey);
|
|
14762
14962
|
}
|
|
14963
|
+
await this.setUserData(newIdTokenKey, JSON.stringify(oldSchemaData), correlationId, oldSchemaData.lastUpdatedAt, kmsi);
|
|
14964
|
+
this.performanceClient.incrementFields({ migratedITCount: 1 }, correlationId);
|
|
14965
|
+
currentCredentialKeys.idToken.push(newIdTokenKey);
|
|
14966
|
+
}
|
|
14967
|
+
}
|
|
14968
|
+
this.setTokenKeys(credentialKeysToMigrate, correlationId, credentialSchema);
|
|
14969
|
+
this.setTokenKeys(currentCredentialKeys, correlationId);
|
|
14970
|
+
this.setAccountKeys(currentAccountKeys, correlationId);
|
|
14971
|
+
}
|
|
14972
|
+
/**
|
|
14973
|
+
* Migrates access tokens from old cache schema to current schema
|
|
14974
|
+
* @param credentialSchema
|
|
14975
|
+
* @param kmsiMap
|
|
14976
|
+
* @param correlationId
|
|
14977
|
+
* @returns
|
|
14978
|
+
*/
|
|
14979
|
+
async migrateAccessTokens(credentialSchema, kmsiMap, correlationId) {
|
|
14980
|
+
const credentialKeysToMigrate = getTokenKeys(this.clientId, this.browserStorage, credentialSchema);
|
|
14981
|
+
if (credentialKeysToMigrate.accessToken.length === 0) {
|
|
14982
|
+
return;
|
|
14983
|
+
}
|
|
14984
|
+
const currentCredentialKeys = getTokenKeys(this.clientId, this.browserStorage, CREDENTIAL_SCHEMA_VERSION);
|
|
14985
|
+
for (const accessTokenKey of [...credentialKeysToMigrate.accessToken]) {
|
|
14986
|
+
this.performanceClient.incrementFields({ oldATCount: 1 }, correlationId);
|
|
14987
|
+
const oldSchemaData = (await this.updateOldEntry(accessTokenKey, correlationId));
|
|
14988
|
+
if (!oldSchemaData) {
|
|
14989
|
+
removeElementFromArray(credentialKeysToMigrate.accessToken, accessTokenKey);
|
|
14990
|
+
continue;
|
|
14763
14991
|
}
|
|
14764
|
-
if (!
|
|
14765
|
-
|
|
14766
|
-
(
|
|
14767
|
-
isTokenExpired(expirationTime, DEFAULT_TOKEN_RENEWAL_OFFSET_SEC))) {
|
|
14768
|
-
this.browserStorage.removeItem(v0Key);
|
|
14769
|
-
removeElementFromArray(v0Keys, v0Key);
|
|
14770
|
-
this.performanceClient.incrementFields({ expiredCacheRemovedCount: 1 }, correlationId);
|
|
14992
|
+
if (!Object.keys(kmsiMap).includes(oldSchemaData.homeAccountId)) {
|
|
14993
|
+
// Don't migrate tokens if we don't have an idToken for them
|
|
14994
|
+
this.performanceClient.incrementFields({ skipATMigrateCount: 1 }, correlationId);
|
|
14771
14995
|
continue;
|
|
14772
14996
|
}
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
|
|
14997
|
+
const newKey = this.generateCredentialKey(oldSchemaData);
|
|
14998
|
+
const kmsi = kmsiMap[oldSchemaData.homeAccountId];
|
|
14999
|
+
if (!currentCredentialKeys.accessToken.includes(newKey)) {
|
|
15000
|
+
await this.setUserData(newKey, JSON.stringify(oldSchemaData), correlationId, oldSchemaData.lastUpdatedAt, kmsi);
|
|
15001
|
+
this.performanceClient.incrementFields({ migratedATCount: 1 }, correlationId);
|
|
15002
|
+
currentCredentialKeys.accessToken.push(newKey);
|
|
15003
|
+
}
|
|
15004
|
+
else {
|
|
15005
|
+
const currentToken = this.getAccessTokenCredential(newKey, correlationId);
|
|
15006
|
+
if (!currentToken ||
|
|
15007
|
+
oldSchemaData.lastUpdatedAt > currentToken.lastUpdatedAt) {
|
|
15008
|
+
// If the token already exists, only overwrite it if the old token has a more recent lastUpdatedAt
|
|
15009
|
+
await this.setUserData(newKey, JSON.stringify(oldSchemaData), correlationId, oldSchemaData.lastUpdatedAt, kmsi);
|
|
15010
|
+
this.performanceClient.incrementFields({ migratedATCount: 1 }, correlationId);
|
|
14784
15011
|
}
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
15012
|
+
}
|
|
15013
|
+
}
|
|
15014
|
+
this.setTokenKeys(credentialKeysToMigrate, correlationId, credentialSchema);
|
|
15015
|
+
this.setTokenKeys(currentCredentialKeys, correlationId);
|
|
15016
|
+
}
|
|
15017
|
+
/**
|
|
15018
|
+
* Migrates refresh tokens from old cache schema to current schema
|
|
15019
|
+
* @param credentialSchema
|
|
15020
|
+
* @param kmsiMap
|
|
15021
|
+
* @param correlationId
|
|
15022
|
+
* @returns
|
|
15023
|
+
*/
|
|
15024
|
+
async migrateRefreshTokens(credentialSchema, kmsiMap, correlationId) {
|
|
15025
|
+
const credentialKeysToMigrate = getTokenKeys(this.clientId, this.browserStorage, credentialSchema);
|
|
15026
|
+
if (credentialKeysToMigrate.refreshToken.length === 0) {
|
|
15027
|
+
return;
|
|
15028
|
+
}
|
|
15029
|
+
const currentCredentialKeys = getTokenKeys(this.clientId, this.browserStorage, CREDENTIAL_SCHEMA_VERSION);
|
|
15030
|
+
for (const refreshTokenKey of [
|
|
15031
|
+
...credentialKeysToMigrate.refreshToken,
|
|
15032
|
+
]) {
|
|
15033
|
+
this.performanceClient.incrementFields({ oldRTCount: 1 }, correlationId);
|
|
15034
|
+
const oldSchemaData = (await this.updateOldEntry(refreshTokenKey, correlationId));
|
|
15035
|
+
if (!oldSchemaData) {
|
|
15036
|
+
removeElementFromArray(credentialKeysToMigrate.refreshToken, refreshTokenKey);
|
|
15037
|
+
continue;
|
|
15038
|
+
}
|
|
15039
|
+
if (!Object.keys(kmsiMap).includes(oldSchemaData.homeAccountId)) {
|
|
15040
|
+
// Don't migrate tokens if we don't have an idToken for them
|
|
15041
|
+
this.performanceClient.incrementFields({ skipRTMigrateCount: 1 }, correlationId);
|
|
15042
|
+
continue;
|
|
15043
|
+
}
|
|
15044
|
+
const newKey = this.generateCredentialKey(oldSchemaData);
|
|
15045
|
+
const kmsi = kmsiMap[oldSchemaData.homeAccountId];
|
|
15046
|
+
if (!currentCredentialKeys.refreshToken.includes(newKey)) {
|
|
15047
|
+
await this.setUserData(newKey, JSON.stringify(oldSchemaData), correlationId, oldSchemaData.lastUpdatedAt, kmsi);
|
|
15048
|
+
this.performanceClient.incrementFields({ migratedRTCount: 1 }, correlationId);
|
|
15049
|
+
currentCredentialKeys.refreshToken.push(newKey);
|
|
15050
|
+
}
|
|
15051
|
+
else {
|
|
15052
|
+
const currentToken = this.getRefreshTokenCredential(newKey, correlationId);
|
|
15053
|
+
if (!currentToken ||
|
|
15054
|
+
oldSchemaData.lastUpdatedAt > currentToken.lastUpdatedAt) {
|
|
15055
|
+
// If the token already exists, only overwrite it if the old token has a more recent lastUpdatedAt
|
|
15056
|
+
await this.setUserData(newKey, JSON.stringify(oldSchemaData), correlationId, oldSchemaData.lastUpdatedAt, kmsi);
|
|
15057
|
+
this.performanceClient.incrementFields({ migratedRTCount: 1 }, correlationId);
|
|
14795
15058
|
}
|
|
14796
15059
|
}
|
|
14797
|
-
/*
|
|
14798
|
-
* Note: If we reach here for unencrypted localStorage data, we continue without migrating
|
|
14799
|
-
* as we can't migrate unencrypted localStorage data right now since we can't guarantee KMSI=no
|
|
14800
|
-
*/
|
|
14801
15060
|
}
|
|
14802
|
-
|
|
15061
|
+
this.setTokenKeys(credentialKeysToMigrate, correlationId, credentialSchema);
|
|
15062
|
+
this.setTokenKeys(currentCredentialKeys, correlationId);
|
|
14803
15063
|
}
|
|
14804
15064
|
/**
|
|
14805
15065
|
* Tracks upgrades and downgrades for telemetry and debugging purposes
|
|
@@ -14844,20 +15104,31 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14844
15104
|
* @param value
|
|
14845
15105
|
*/
|
|
14846
15106
|
setItem(key, value, correlationId) {
|
|
14847
|
-
|
|
14848
|
-
|
|
15107
|
+
const tokenKeysCount = new Array(CREDENTIAL_SCHEMA_VERSION + 1).fill(0); // Array mapping schema version to number of token keys stored for that version
|
|
15108
|
+
const accessTokenKeys = []; // Flat map of all access token keys stored, ordered by schema version
|
|
14849
15109
|
const maxRetries = 20;
|
|
14850
15110
|
for (let i = 0; i <= maxRetries; i++) {
|
|
15111
|
+
// Attempt to store item in cache, if cache is full this call will throw and we'll attempt to clear space by removing access tokens from the cache one by one, starting with tokens stored by previous versions of MSAL.js
|
|
14851
15112
|
try {
|
|
14852
15113
|
this.browserStorage.setItem(key, value);
|
|
14853
15114
|
if (i > 0) {
|
|
14854
|
-
//
|
|
14855
|
-
|
|
14856
|
-
this
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
15115
|
+
// If any tokens were removed in order to store this item update the token keys array with the tokens removed
|
|
15116
|
+
for (let schemaVersion = 0; schemaVersion <= CREDENTIAL_SCHEMA_VERSION; schemaVersion++) {
|
|
15117
|
+
// Get the sum of all previous token counts to use as start index for this schema version
|
|
15118
|
+
const startIndex = tokenKeysCount
|
|
15119
|
+
.slice(0, schemaVersion)
|
|
15120
|
+
.reduce((sum, count) => sum + count, 0);
|
|
15121
|
+
if (startIndex >= i) {
|
|
15122
|
+
// Done removing tokens
|
|
15123
|
+
break;
|
|
15124
|
+
}
|
|
15125
|
+
const endIndex = i > startIndex + tokenKeysCount[schemaVersion]
|
|
15126
|
+
? startIndex + tokenKeysCount[schemaVersion]
|
|
15127
|
+
: i;
|
|
15128
|
+
if (i > startIndex &&
|
|
15129
|
+
tokenKeysCount[schemaVersion] > 0) {
|
|
15130
|
+
this.removeAccessTokenKeys(accessTokenKeys.slice(startIndex, endIndex), correlationId, schemaVersion);
|
|
15131
|
+
}
|
|
14861
15132
|
}
|
|
14862
15133
|
}
|
|
14863
15134
|
break; // If setItem succeeds, exit the loop
|
|
@@ -14869,16 +15140,19 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14869
15140
|
i < maxRetries) {
|
|
14870
15141
|
if (!accessTokenKeys.length) {
|
|
14871
15142
|
// If we are currently trying to set the token keys, use the value we're trying to set
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14875
|
-
|
|
14876
|
-
|
|
14877
|
-
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
15143
|
+
for (let i = 0; i <= CREDENTIAL_SCHEMA_VERSION; i++) {
|
|
15144
|
+
if (key ===
|
|
15145
|
+
getTokenKeysCacheKey(this.clientId, i)) {
|
|
15146
|
+
const tokenKeys = JSON.parse(value).accessToken;
|
|
15147
|
+
accessTokenKeys.push(...tokenKeys);
|
|
15148
|
+
tokenKeysCount[i] = tokenKeys.length;
|
|
15149
|
+
}
|
|
15150
|
+
else {
|
|
15151
|
+
const tokenKeys = this.getTokenKeys(i).accessToken;
|
|
15152
|
+
accessTokenKeys.push(...tokenKeys);
|
|
15153
|
+
tokenKeysCount[i] = tokenKeys.length;
|
|
15154
|
+
}
|
|
15155
|
+
}
|
|
14882
15156
|
}
|
|
14883
15157
|
if (accessTokenKeys.length <= i) {
|
|
14884
15158
|
// Nothing to remove, rethrow the error
|
|
@@ -14901,21 +15175,32 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14901
15175
|
* @param value
|
|
14902
15176
|
* @param correlationId
|
|
14903
15177
|
*/
|
|
14904
|
-
async setUserData(key, value, correlationId, timestamp) {
|
|
14905
|
-
|
|
14906
|
-
|
|
15178
|
+
async setUserData(key, value, correlationId, timestamp, kmsi) {
|
|
15179
|
+
const tokenKeysCount = new Array(CREDENTIAL_SCHEMA_VERSION + 1).fill(0); // Array mapping schema version to number of token keys stored for that version
|
|
15180
|
+
const accessTokenKeys = []; // Flat map of all access token keys stored, ordered by schema version
|
|
14907
15181
|
const maxRetries = 20;
|
|
14908
15182
|
for (let i = 0; i <= maxRetries; i++) {
|
|
14909
15183
|
try {
|
|
14910
|
-
|
|
15184
|
+
// Attempt to store item in cache, if cache is full this call will throw and we'll attempt to clear space by removing access tokens from the cache one by one, starting with tokens stored by previous versions of MSAL.js
|
|
15185
|
+
await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(key, value, correlationId, timestamp, kmsi);
|
|
14911
15186
|
if (i > 0) {
|
|
14912
|
-
//
|
|
14913
|
-
|
|
14914
|
-
this
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
15187
|
+
// If any tokens were removed in order to store this item update the token keys array with the tokens removed
|
|
15188
|
+
for (let schemaVersion = 0; schemaVersion <= CREDENTIAL_SCHEMA_VERSION; schemaVersion++) {
|
|
15189
|
+
// Get the sum of all previous token counts to use as start index for this schema version
|
|
15190
|
+
const startIndex = tokenKeysCount
|
|
15191
|
+
.slice(0, schemaVersion)
|
|
15192
|
+
.reduce((sum, count) => sum + count, 0);
|
|
15193
|
+
if (startIndex >= i) {
|
|
15194
|
+
// Done removing tokens
|
|
15195
|
+
break;
|
|
15196
|
+
}
|
|
15197
|
+
const endIndex = i > startIndex + tokenKeysCount[schemaVersion]
|
|
15198
|
+
? startIndex + tokenKeysCount[schemaVersion]
|
|
15199
|
+
: i;
|
|
15200
|
+
if (i > startIndex &&
|
|
15201
|
+
tokenKeysCount[schemaVersion] > 0) {
|
|
15202
|
+
this.removeAccessTokenKeys(accessTokenKeys.slice(startIndex, endIndex), correlationId, schemaVersion);
|
|
15203
|
+
}
|
|
14919
15204
|
}
|
|
14920
15205
|
}
|
|
14921
15206
|
break; // If setItem succeeds, exit the loop
|
|
@@ -14926,10 +15211,12 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14926
15211
|
cacheQuotaExceeded &&
|
|
14927
15212
|
i < maxRetries) {
|
|
14928
15213
|
if (!accessTokenKeys.length) {
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
15214
|
+
// If we are currently trying to set the token keys, use the value we're trying to set
|
|
15215
|
+
for (let i = 0; i <= CREDENTIAL_SCHEMA_VERSION; i++) {
|
|
15216
|
+
const tokenKeys = this.getTokenKeys(i).accessToken;
|
|
15217
|
+
accessTokenKeys.push(...tokenKeys);
|
|
15218
|
+
tokenKeysCount[i] = tokenKeys.length;
|
|
15219
|
+
}
|
|
14933
15220
|
}
|
|
14934
15221
|
if (accessTokenKeys.length <= i) {
|
|
14935
15222
|
// Nothing left to remove, rethrow the error
|
|
@@ -14969,20 +15256,21 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14969
15256
|
* set account entity in the platform cache
|
|
14970
15257
|
* @param account
|
|
14971
15258
|
*/
|
|
14972
|
-
async setAccount(account, correlationId) {
|
|
15259
|
+
async setAccount(account, correlationId, kmsi) {
|
|
14973
15260
|
this.logger.trace("BrowserCacheManager.setAccount called");
|
|
14974
|
-
const key = this.generateAccountKey(
|
|
15261
|
+
const key = this.generateAccountKey(AccountEntity.getAccountInfo(account));
|
|
14975
15262
|
const timestamp = Date.now().toString();
|
|
14976
15263
|
account.lastUpdatedAt = timestamp;
|
|
14977
|
-
await this.setUserData(key, JSON.stringify(account), correlationId, timestamp);
|
|
15264
|
+
await this.setUserData(key, JSON.stringify(account), correlationId, timestamp, kmsi);
|
|
14978
15265
|
const wasAdded = this.addAccountKeyToMap(key, correlationId);
|
|
15266
|
+
this.performanceClient.addFields({ kmsi: kmsi }, correlationId);
|
|
14979
15267
|
/**
|
|
14980
15268
|
* @deprecated - Remove this in next major version in favor of more consistent LOGIN event
|
|
14981
15269
|
*/
|
|
14982
15270
|
if (this.cacheConfig.cacheLocation ===
|
|
14983
15271
|
BrowserCacheLocation.LocalStorage &&
|
|
14984
15272
|
wasAdded) {
|
|
14985
|
-
this.eventHandler.emitEvent(EventType.ACCOUNT_ADDED, undefined,
|
|
15273
|
+
this.eventHandler.emitEvent(EventType.ACCOUNT_ADDED, undefined, AccountEntity.getAccountInfo(account));
|
|
14986
15274
|
}
|
|
14987
15275
|
}
|
|
14988
15276
|
/**
|
|
@@ -14992,6 +15280,14 @@ class BrowserCacheManager extends CacheManager {
|
|
|
14992
15280
|
getAccountKeys() {
|
|
14993
15281
|
return getAccountKeys(this.browserStorage);
|
|
14994
15282
|
}
|
|
15283
|
+
setAccountKeys(accountKeys, correlationId, schemaVersion = ACCOUNT_SCHEMA_VERSION) {
|
|
15284
|
+
if (accountKeys.length === 0) {
|
|
15285
|
+
this.removeItem(getAccountKeysCacheKey(schemaVersion));
|
|
15286
|
+
}
|
|
15287
|
+
else {
|
|
15288
|
+
this.setItem(getAccountKeysCacheKey(schemaVersion), JSON.stringify(accountKeys), correlationId);
|
|
15289
|
+
}
|
|
15290
|
+
}
|
|
14995
15291
|
/**
|
|
14996
15292
|
* Add a new account to the key map
|
|
14997
15293
|
* @param key
|
|
@@ -15023,14 +15319,7 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15023
15319
|
const removalIndex = accountKeys.indexOf(key);
|
|
15024
15320
|
if (removalIndex > -1) {
|
|
15025
15321
|
accountKeys.splice(removalIndex, 1);
|
|
15026
|
-
|
|
15027
|
-
// If no keys left, remove the map
|
|
15028
|
-
this.removeItem(getAccountKeysCacheKey());
|
|
15029
|
-
return;
|
|
15030
|
-
}
|
|
15031
|
-
else {
|
|
15032
|
-
this.setItem(getAccountKeysCacheKey(), JSON.stringify(accountKeys), correlationId);
|
|
15033
|
-
}
|
|
15322
|
+
this.setAccountKeys(accountKeys, correlationId);
|
|
15034
15323
|
this.logger.trace("BrowserCacheManager.removeAccountKeyFromMap account key removed");
|
|
15035
15324
|
}
|
|
15036
15325
|
else {
|
|
@@ -15170,12 +15459,12 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15170
15459
|
* set IdToken credential to the platform cache
|
|
15171
15460
|
* @param idToken
|
|
15172
15461
|
*/
|
|
15173
|
-
async setIdTokenCredential(idToken, correlationId) {
|
|
15462
|
+
async setIdTokenCredential(idToken, correlationId, kmsi) {
|
|
15174
15463
|
this.logger.trace("BrowserCacheManager.setIdTokenCredential called");
|
|
15175
15464
|
const idTokenKey = this.generateCredentialKey(idToken);
|
|
15176
15465
|
const timestamp = Date.now().toString();
|
|
15177
15466
|
idToken.lastUpdatedAt = timestamp;
|
|
15178
|
-
await this.setUserData(idTokenKey, JSON.stringify(idToken), correlationId, timestamp);
|
|
15467
|
+
await this.setUserData(idTokenKey, JSON.stringify(idToken), correlationId, timestamp, kmsi);
|
|
15179
15468
|
const tokenKeys = this.getTokenKeys();
|
|
15180
15469
|
if (tokenKeys.idToken.indexOf(idTokenKey) === -1) {
|
|
15181
15470
|
this.logger.info("BrowserCacheManager: addTokenKey - idToken added to map");
|
|
@@ -15207,12 +15496,12 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15207
15496
|
* set accessToken credential to the platform cache
|
|
15208
15497
|
* @param accessToken
|
|
15209
15498
|
*/
|
|
15210
|
-
async setAccessTokenCredential(accessToken, correlationId) {
|
|
15499
|
+
async setAccessTokenCredential(accessToken, correlationId, kmsi) {
|
|
15211
15500
|
this.logger.trace("BrowserCacheManager.setAccessTokenCredential called");
|
|
15212
15501
|
const accessTokenKey = this.generateCredentialKey(accessToken);
|
|
15213
15502
|
const timestamp = Date.now().toString();
|
|
15214
15503
|
accessToken.lastUpdatedAt = timestamp;
|
|
15215
|
-
await this.setUserData(accessTokenKey, JSON.stringify(accessToken), correlationId, timestamp);
|
|
15504
|
+
await this.setUserData(accessTokenKey, JSON.stringify(accessToken), correlationId, timestamp, kmsi);
|
|
15216
15505
|
const tokenKeys = this.getTokenKeys();
|
|
15217
15506
|
const index = tokenKeys.accessToken.indexOf(accessTokenKey);
|
|
15218
15507
|
if (index !== -1) {
|
|
@@ -15246,12 +15535,12 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15246
15535
|
* set refreshToken credential to the platform cache
|
|
15247
15536
|
* @param refreshToken
|
|
15248
15537
|
*/
|
|
15249
|
-
async setRefreshTokenCredential(refreshToken, correlationId) {
|
|
15538
|
+
async setRefreshTokenCredential(refreshToken, correlationId, kmsi) {
|
|
15250
15539
|
this.logger.trace("BrowserCacheManager.setRefreshTokenCredential called");
|
|
15251
15540
|
const refreshTokenKey = this.generateCredentialKey(refreshToken);
|
|
15252
15541
|
const timestamp = Date.now().toString();
|
|
15253
15542
|
refreshToken.lastUpdatedAt = timestamp;
|
|
15254
|
-
await this.setUserData(refreshTokenKey, JSON.stringify(refreshToken), correlationId, timestamp);
|
|
15543
|
+
await this.setUserData(refreshTokenKey, JSON.stringify(refreshToken), correlationId, timestamp, kmsi);
|
|
15255
15544
|
const tokenKeys = this.getTokenKeys();
|
|
15256
15545
|
if (tokenKeys.refreshToken.indexOf(refreshTokenKey) === -1) {
|
|
15257
15546
|
this.logger.info("BrowserCacheManager: addTokenKey - refreshToken added to map");
|
|
@@ -15751,7 +16040,7 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15751
16040
|
idToken: idTokenEntity,
|
|
15752
16041
|
accessToken: accessTokenEntity,
|
|
15753
16042
|
};
|
|
15754
|
-
return this.saveCacheRecord(cacheRecord, result.correlationId);
|
|
16043
|
+
return this.saveCacheRecord(cacheRecord, result.correlationId, isKmsi(extractTokenClaims(result.idToken, base64Decode)));
|
|
15755
16044
|
}
|
|
15756
16045
|
/**
|
|
15757
16046
|
* saves a cache record
|
|
@@ -15759,9 +16048,9 @@ class BrowserCacheManager extends CacheManager {
|
|
|
15759
16048
|
* @param storeInCache {?StoreInCache}
|
|
15760
16049
|
* @param correlationId {?string} correlation id
|
|
15761
16050
|
*/
|
|
15762
|
-
async saveCacheRecord(cacheRecord, correlationId, storeInCache) {
|
|
16051
|
+
async saveCacheRecord(cacheRecord, correlationId, kmsi, storeInCache) {
|
|
15763
16052
|
try {
|
|
15764
|
-
await super.saveCacheRecord(cacheRecord, correlationId, storeInCache);
|
|
16053
|
+
await super.saveCacheRecord(cacheRecord, correlationId, kmsi, storeInCache);
|
|
15765
16054
|
}
|
|
15766
16055
|
catch (e) {
|
|
15767
16056
|
if (e instanceof CacheError &&
|
|
@@ -16595,7 +16884,7 @@ class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
|
16595
16884
|
// generate authenticationResult
|
|
16596
16885
|
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
16597
16886
|
// cache accounts and tokens in the appropriate storage
|
|
16598
|
-
await this.cacheAccount(baseAccount, this.correlationId);
|
|
16887
|
+
await this.cacheAccount(baseAccount, this.correlationId, isKmsi(idTokenClaims));
|
|
16599
16888
|
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
16600
16889
|
return result;
|
|
16601
16890
|
}
|
|
@@ -16682,7 +16971,7 @@ class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
|
16682
16971
|
const tid = accountProperties["TenantId"] ||
|
|
16683
16972
|
idTokenClaims.tid ||
|
|
16684
16973
|
Constants.EMPTY_STRING;
|
|
16685
|
-
const accountInfo = updateAccountTenantProfileData(
|
|
16974
|
+
const accountInfo = updateAccountTenantProfileData(AccountEntity.getAccountInfo(accountEntity), undefined, // tenantProfile optional
|
|
16686
16975
|
idTokenClaims, response.id_token);
|
|
16687
16976
|
/**
|
|
16688
16977
|
* In pairwise broker flows, this check prevents the broker's native account id
|
|
@@ -16719,11 +17008,11 @@ class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
|
16719
17008
|
* cache the account entity in browser storage
|
|
16720
17009
|
* @param accountEntity
|
|
16721
17010
|
*/
|
|
16722
|
-
async cacheAccount(accountEntity, correlationId) {
|
|
17011
|
+
async cacheAccount(accountEntity, correlationId, kmsi) {
|
|
16723
17012
|
// Store the account info and hence `nativeAccountId` in browser cache
|
|
16724
|
-
await this.browserStorage.setAccount(accountEntity, this.correlationId);
|
|
17013
|
+
await this.browserStorage.setAccount(accountEntity, this.correlationId, kmsi);
|
|
16725
17014
|
// Remove any existing cached tokens for this account in browser storage
|
|
16726
|
-
this.browserStorage.removeAccountContext(
|
|
17015
|
+
this.browserStorage.removeAccountContext(AccountEntity.getAccountInfo(accountEntity), correlationId);
|
|
16727
17016
|
}
|
|
16728
17017
|
/**
|
|
16729
17018
|
* Stores the access_token and id_token in inmemory storage
|
|
@@ -16750,7 +17039,7 @@ class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
|
16750
17039
|
idToken: cachedIdToken,
|
|
16751
17040
|
accessToken: cachedAccessToken,
|
|
16752
17041
|
};
|
|
16753
|
-
return this.nativeStorageManager.saveCacheRecord(nativeCacheRecord, this.correlationId, request.storeInCache);
|
|
17042
|
+
return this.nativeStorageManager.saveCacheRecord(nativeCacheRecord, this.correlationId, isKmsi(idTokenClaims), request.storeInCache);
|
|
16754
17043
|
}
|
|
16755
17044
|
getExpiresInValue(tokenType, expiresIn) {
|
|
16756
17045
|
return tokenType === AuthenticationScheme.POP
|
|
@@ -19052,6 +19341,7 @@ function createHiddenIframe() {
|
|
|
19052
19341
|
authFrame.style.width = authFrame.style.height = "0";
|
|
19053
19342
|
authFrame.style.border = "0";
|
|
19054
19343
|
authFrame.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
19344
|
+
authFrame.setAttribute("allow", "local-network-access *");
|
|
19055
19345
|
document.body.appendChild(authFrame);
|
|
19056
19346
|
return authFrame;
|
|
19057
19347
|
}
|
|
@@ -19304,6 +19594,7 @@ class TokenCache {
|
|
|
19304
19594
|
const idTokenClaims = response.id_token
|
|
19305
19595
|
? extractTokenClaims(response.id_token, base64Decode)
|
|
19306
19596
|
: undefined;
|
|
19597
|
+
const kmsi = isKmsi(idTokenClaims || {});
|
|
19307
19598
|
const authorityOptions = {
|
|
19308
19599
|
protocolMode: this.config.auth.protocolMode,
|
|
19309
19600
|
knownAuthorities: this.config.auth.knownAuthorities,
|
|
@@ -19315,9 +19606,9 @@ class TokenCache {
|
|
|
19315
19606
|
? new Authority(Authority.generateAuthority(request.authority, request.azureCloudOptions), this.config.system.networkClient, this.storage, authorityOptions, this.logger, request.correlationId || createNewGuid())
|
|
19316
19607
|
: undefined;
|
|
19317
19608
|
const cacheRecordAccount = await this.loadAccount(request, options.clientInfo || response.client_info || "", correlationId, idTokenClaims, authority);
|
|
19318
|
-
const idToken = await this.loadIdToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, correlationId);
|
|
19319
|
-
const accessToken = await this.loadAccessToken(request, response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, options, correlationId);
|
|
19320
|
-
const refreshToken = await this.loadRefreshToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, correlationId);
|
|
19609
|
+
const idToken = await this.loadIdToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, correlationId, kmsi);
|
|
19610
|
+
const accessToken = await this.loadAccessToken(request, response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, options, correlationId, kmsi);
|
|
19611
|
+
const refreshToken = await this.loadRefreshToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, correlationId, kmsi);
|
|
19321
19612
|
return this.generateAuthenticationResult(request, {
|
|
19322
19613
|
account: cacheRecordAccount,
|
|
19323
19614
|
idToken,
|
|
@@ -19338,7 +19629,7 @@ class TokenCache {
|
|
|
19338
19629
|
this.logger.verbose("TokenCache - loading account");
|
|
19339
19630
|
if (request.account) {
|
|
19340
19631
|
const accountEntity = AccountEntity.createFromAccountInfo(request.account);
|
|
19341
|
-
await this.storage.setAccount(accountEntity, correlationId);
|
|
19632
|
+
await this.storage.setAccount(accountEntity, correlationId, isKmsi(idTokenClaims || {}));
|
|
19342
19633
|
return accountEntity;
|
|
19343
19634
|
}
|
|
19344
19635
|
else if (!authority || (!clientInfo && !idTokenClaims)) {
|
|
@@ -19350,7 +19641,7 @@ class TokenCache {
|
|
|
19350
19641
|
const cachedAccount = buildAccountToCache(this.storage, authority, homeAccountId, base64Decode, correlationId, idTokenClaims, clientInfo, authority.hostnameAndPort, claimsTenantId, undefined, // authCodePayload
|
|
19351
19642
|
undefined, // nativeAccountId
|
|
19352
19643
|
this.logger);
|
|
19353
|
-
await this.storage.setAccount(cachedAccount, correlationId);
|
|
19644
|
+
await this.storage.setAccount(cachedAccount, correlationId, isKmsi(idTokenClaims || {}));
|
|
19354
19645
|
return cachedAccount;
|
|
19355
19646
|
}
|
|
19356
19647
|
/**
|
|
@@ -19361,14 +19652,14 @@ class TokenCache {
|
|
|
19361
19652
|
* @param tenantId
|
|
19362
19653
|
* @returns `IdTokenEntity`
|
|
19363
19654
|
*/
|
|
19364
|
-
async loadIdToken(response, homeAccountId, environment, tenantId, correlationId) {
|
|
19655
|
+
async loadIdToken(response, homeAccountId, environment, tenantId, correlationId, kmsi) {
|
|
19365
19656
|
if (!response.id_token) {
|
|
19366
19657
|
this.logger.verbose("TokenCache - no id token found in response");
|
|
19367
19658
|
return null;
|
|
19368
19659
|
}
|
|
19369
19660
|
this.logger.verbose("TokenCache - loading id token");
|
|
19370
19661
|
const idTokenEntity = createIdTokenEntity(homeAccountId, environment, response.id_token, this.config.auth.clientId, tenantId);
|
|
19371
|
-
await this.storage.setIdTokenCredential(idTokenEntity, correlationId);
|
|
19662
|
+
await this.storage.setIdTokenCredential(idTokenEntity, correlationId, kmsi);
|
|
19372
19663
|
return idTokenEntity;
|
|
19373
19664
|
}
|
|
19374
19665
|
/**
|
|
@@ -19380,7 +19671,7 @@ class TokenCache {
|
|
|
19380
19671
|
* @param tenantId
|
|
19381
19672
|
* @returns `AccessTokenEntity`
|
|
19382
19673
|
*/
|
|
19383
|
-
async loadAccessToken(request, response, homeAccountId, environment, tenantId, options, correlationId) {
|
|
19674
|
+
async loadAccessToken(request, response, homeAccountId, environment, tenantId, options, correlationId, kmsi) {
|
|
19384
19675
|
if (!response.access_token) {
|
|
19385
19676
|
this.logger.verbose("TokenCache - no access token found in response");
|
|
19386
19677
|
return null;
|
|
@@ -19403,7 +19694,7 @@ class TokenCache {
|
|
|
19403
19694
|
(response.ext_expires_in || response.expires_in) +
|
|
19404
19695
|
nowSeconds();
|
|
19405
19696
|
const accessTokenEntity = createAccessTokenEntity(homeAccountId, environment, response.access_token, this.config.auth.clientId, tenantId, scopes.printScopes(), expiresOn, extendedExpiresOn, base64Decode);
|
|
19406
|
-
await this.storage.setAccessTokenCredential(accessTokenEntity, correlationId);
|
|
19697
|
+
await this.storage.setAccessTokenCredential(accessTokenEntity, correlationId, kmsi);
|
|
19407
19698
|
return accessTokenEntity;
|
|
19408
19699
|
}
|
|
19409
19700
|
/**
|
|
@@ -19414,7 +19705,7 @@ class TokenCache {
|
|
|
19414
19705
|
* @param environment
|
|
19415
19706
|
* @returns `RefreshTokenEntity`
|
|
19416
19707
|
*/
|
|
19417
|
-
async loadRefreshToken(response, homeAccountId, environment, correlationId) {
|
|
19708
|
+
async loadRefreshToken(response, homeAccountId, environment, correlationId, kmsi) {
|
|
19418
19709
|
if (!response.refresh_token) {
|
|
19419
19710
|
this.logger.verbose("TokenCache - no refresh token found in response");
|
|
19420
19711
|
return null;
|
|
@@ -19422,7 +19713,7 @@ class TokenCache {
|
|
|
19422
19713
|
this.logger.verbose("TokenCache - loading refresh token");
|
|
19423
19714
|
const refreshTokenEntity = createRefreshTokenEntity(homeAccountId, environment, response.refresh_token, this.config.auth.clientId, response.foci, undefined, // userAssertionHash
|
|
19424
19715
|
response.refresh_token_expires_in);
|
|
19425
|
-
await this.storage.setRefreshTokenCredential(refreshTokenEntity, correlationId);
|
|
19716
|
+
await this.storage.setRefreshTokenCredential(refreshTokenEntity, correlationId, kmsi);
|
|
19426
19717
|
return refreshTokenEntity;
|
|
19427
19718
|
}
|
|
19428
19719
|
/**
|
|
@@ -19451,7 +19742,7 @@ class TokenCache {
|
|
|
19451
19742
|
uniqueId: cacheRecord.account.localAccountId,
|
|
19452
19743
|
tenantId: cacheRecord.account.realm,
|
|
19453
19744
|
scopes: responseScopes,
|
|
19454
|
-
account:
|
|
19745
|
+
account: AccountEntity.getAccountInfo(accountEntity),
|
|
19455
19746
|
idToken: cacheRecord.idToken?.secret || "",
|
|
19456
19747
|
idTokenClaims: idTokenClaims || {},
|
|
19457
19748
|
accessToken: accessToken,
|
|
@@ -20469,7 +20760,7 @@ class StandardController {
|
|
|
20469
20760
|
this.logger.verbose("hydrateCache called");
|
|
20470
20761
|
// Account gets saved to browser storage regardless of native or not
|
|
20471
20762
|
const accountEntity = AccountEntity.createFromAccountInfo(result.account, result.cloudGraphHostName, result.msGraphHost);
|
|
20472
|
-
await this.browserStorage.setAccount(accountEntity, result.correlationId);
|
|
20763
|
+
await this.browserStorage.setAccount(accountEntity, result.correlationId, isKmsi(result.idTokenClaims));
|
|
20473
20764
|
if (result.fromNativeBroker) {
|
|
20474
20765
|
this.logger.verbose("Response was from native broker, storing in-memory");
|
|
20475
20766
|
// Tokens from native broker are stored in-memory
|