@azure/msal-browser 4.25.1 → 4.26.0

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.
Files changed (322) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +1 -1
  3. package/dist/app/PublicClientNext.mjs +1 -1
  4. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  5. package/dist/broker/nativeBroker/PlatformAuthDOMHandler.mjs +1 -1
  6. package/dist/broker/nativeBroker/PlatformAuthExtensionHandler.mjs +1 -1
  7. package/dist/broker/nativeBroker/PlatformAuthProvider.mjs +1 -1
  8. package/dist/cache/AccountManager.mjs +1 -1
  9. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  10. package/dist/cache/BrowserCacheManager.d.ts +64 -7
  11. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  12. package/dist/cache/BrowserCacheManager.mjs +400 -141
  13. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  14. package/dist/cache/CacheHelpers.mjs +1 -1
  15. package/dist/cache/CacheKeys.d.ts +3 -3
  16. package/dist/cache/CacheKeys.mjs +4 -4
  17. package/dist/cache/CookieStorage.mjs +1 -1
  18. package/dist/cache/DatabaseStorage.mjs +1 -1
  19. package/dist/cache/EncryptedData.mjs +1 -1
  20. package/dist/cache/IWindowStorage.d.ts +1 -1
  21. package/dist/cache/IWindowStorage.d.ts.map +1 -1
  22. package/dist/cache/LocalStorage.d.ts +1 -1
  23. package/dist/cache/LocalStorage.d.ts.map +1 -1
  24. package/dist/cache/LocalStorage.mjs +21 -12
  25. package/dist/cache/LocalStorage.mjs.map +1 -1
  26. package/dist/cache/MemoryStorage.mjs +1 -1
  27. package/dist/cache/SessionStorage.mjs +1 -1
  28. package/dist/cache/TokenCache.d.ts.map +1 -1
  29. package/dist/cache/TokenCache.mjs +14 -13
  30. package/dist/cache/TokenCache.mjs.map +1 -1
  31. package/dist/config/Configuration.mjs +1 -1
  32. package/dist/controllers/ControllerFactory.mjs +1 -1
  33. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  34. package/dist/controllers/NestedAppAuthController.mjs +3 -3
  35. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  36. package/dist/controllers/StandardController.d.ts.map +1 -1
  37. package/dist/controllers/StandardController.mjs +3 -3
  38. package/dist/controllers/StandardController.mjs.map +1 -1
  39. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  40. package/dist/crypto/BrowserCrypto.mjs +1 -1
  41. package/dist/crypto/CryptoOps.mjs +1 -1
  42. package/dist/crypto/PkceGenerator.mjs +1 -1
  43. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  44. package/dist/custom-auth-path/app/PublicClientApplication.mjs +1 -1
  45. package/dist/custom-auth-path/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  46. package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthDOMHandler.mjs +1 -1
  47. package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthExtensionHandler.mjs +1 -1
  48. package/dist/custom-auth-path/broker/nativeBroker/PlatformAuthProvider.mjs +1 -1
  49. package/dist/custom-auth-path/cache/AccountManager.mjs +1 -1
  50. package/dist/custom-auth-path/cache/AsyncMemoryStorage.mjs +1 -1
  51. package/dist/custom-auth-path/cache/BrowserCacheManager.d.ts +64 -7
  52. package/dist/custom-auth-path/cache/BrowserCacheManager.d.ts.map +1 -1
  53. package/dist/custom-auth-path/cache/BrowserCacheManager.mjs +400 -141
  54. package/dist/custom-auth-path/cache/BrowserCacheManager.mjs.map +1 -1
  55. package/dist/custom-auth-path/cache/CacheHelpers.mjs +1 -1
  56. package/dist/custom-auth-path/cache/CacheKeys.d.ts +3 -3
  57. package/dist/custom-auth-path/cache/CacheKeys.mjs +4 -4
  58. package/dist/custom-auth-path/cache/CookieStorage.mjs +1 -1
  59. package/dist/custom-auth-path/cache/DatabaseStorage.mjs +1 -1
  60. package/dist/custom-auth-path/cache/EncryptedData.mjs +1 -1
  61. package/dist/custom-auth-path/cache/IWindowStorage.d.ts +1 -1
  62. package/dist/custom-auth-path/cache/IWindowStorage.d.ts.map +1 -1
  63. package/dist/custom-auth-path/cache/LocalStorage.d.ts +1 -1
  64. package/dist/custom-auth-path/cache/LocalStorage.d.ts.map +1 -1
  65. package/dist/custom-auth-path/cache/LocalStorage.mjs +21 -12
  66. package/dist/custom-auth-path/cache/LocalStorage.mjs.map +1 -1
  67. package/dist/custom-auth-path/cache/MemoryStorage.mjs +1 -1
  68. package/dist/custom-auth-path/cache/SessionStorage.mjs +1 -1
  69. package/dist/custom-auth-path/cache/TokenCache.d.ts.map +1 -1
  70. package/dist/custom-auth-path/cache/TokenCache.mjs +14 -13
  71. package/dist/custom-auth-path/cache/TokenCache.mjs.map +1 -1
  72. package/dist/custom-auth-path/config/Configuration.mjs +1 -1
  73. package/dist/custom-auth-path/controllers/ControllerFactory.mjs +1 -1
  74. package/dist/custom-auth-path/controllers/NestedAppAuthController.d.ts.map +1 -1
  75. package/dist/custom-auth-path/controllers/StandardController.d.ts.map +1 -1
  76. package/dist/custom-auth-path/controllers/StandardController.mjs +3 -3
  77. package/dist/custom-auth-path/controllers/StandardController.mjs.map +1 -1
  78. package/dist/custom-auth-path/crypto/BrowserCrypto.mjs +1 -1
  79. package/dist/custom-auth-path/crypto/CryptoOps.mjs +1 -1
  80. package/dist/custom-auth-path/crypto/PkceGenerator.mjs +1 -1
  81. package/dist/custom-auth-path/custom_auth/CustomAuthConstants.d.ts +1 -1
  82. package/dist/custom-auth-path/custom_auth/CustomAuthConstants.mjs +1 -1
  83. package/dist/custom-auth-path/custom_auth/CustomAuthPublicClientApplication.mjs +1 -1
  84. package/dist/custom-auth-path/custom_auth/controller/CustomAuthStandardController.mjs +1 -1
  85. package/dist/custom-auth-path/custom_auth/core/CustomAuthAuthority.mjs +1 -1
  86. package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowErrorBase.mjs +1 -1
  87. package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowResultBase.mjs +1 -1
  88. package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowState.mjs +1 -1
  89. package/dist/custom-auth-path/custom_auth/core/auth_flow/AuthFlowStateTypes.mjs +1 -1
  90. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/error_type/AuthMethodRegistrationError.mjs +1 -1
  91. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationChallengeMethodResult.mjs +1 -1
  92. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/result/AuthMethodRegistrationSubmitChallengeResult.mjs +1 -1
  93. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationCompletedState.mjs +1 -1
  94. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationFailedState.mjs +1 -1
  95. package/dist/custom-auth-path/custom_auth/core/auth_flow/jit/state/AuthMethodRegistrationState.mjs +1 -1
  96. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/error_type/MfaError.mjs +1 -1
  97. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/result/MfaRequestChallengeResult.mjs +1 -1
  98. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/result/MfaSubmitChallengeResult.mjs +1 -1
  99. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaCompletedState.mjs +1 -1
  100. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaFailedState.mjs +1 -1
  101. package/dist/custom-auth-path/custom_auth/core/auth_flow/mfa/state/MfaState.mjs +1 -1
  102. package/dist/custom-auth-path/custom_auth/core/error/CustomAuthApiError.mjs +1 -1
  103. package/dist/custom-auth-path/custom_auth/core/error/CustomAuthError.mjs +1 -1
  104. package/dist/custom-auth-path/custom_auth/core/error/HttpError.mjs +1 -1
  105. package/dist/custom-auth-path/custom_auth/core/error/HttpErrorCodes.mjs +1 -1
  106. package/dist/custom-auth-path/custom_auth/core/error/InvalidArgumentError.mjs +1 -1
  107. package/dist/custom-auth-path/custom_auth/core/error/InvalidConfigurationError.mjs +1 -1
  108. package/dist/custom-auth-path/custom_auth/core/error/InvalidConfigurationErrorCodes.mjs +1 -1
  109. package/dist/custom-auth-path/custom_auth/core/error/MethodNotImplementedError.mjs +1 -1
  110. package/dist/custom-auth-path/custom_auth/core/error/MsalCustomAuthError.mjs +1 -1
  111. package/dist/custom-auth-path/custom_auth/core/error/NoCachedAccountFoundError.mjs +1 -1
  112. package/dist/custom-auth-path/custom_auth/core/error/ParsedUrlError.mjs +1 -1
  113. package/dist/custom-auth-path/custom_auth/core/error/ParsedUrlErrorCodes.mjs +1 -1
  114. package/dist/custom-auth-path/custom_auth/core/error/UnexpectedError.mjs +1 -1
  115. package/dist/custom-auth-path/custom_auth/core/error/UnsupportedEnvironmentError.mjs +1 -1
  116. package/dist/custom-auth-path/custom_auth/core/error/UserAccountAttributeError.mjs +1 -1
  117. package/dist/custom-auth-path/custom_auth/core/error/UserAlreadySignedInError.mjs +1 -1
  118. package/dist/custom-auth-path/custom_auth/core/interaction_client/CustomAuthInteractionClientBase.mjs +1 -1
  119. package/dist/custom-auth-path/custom_auth/core/interaction_client/CustomAuthInterationClientFactory.mjs +1 -1
  120. package/dist/custom-auth-path/custom_auth/core/interaction_client/jit/JitClient.mjs +1 -1
  121. package/dist/custom-auth-path/custom_auth/core/interaction_client/jit/result/JitActionResult.mjs +1 -1
  122. package/dist/custom-auth-path/custom_auth/core/interaction_client/mfa/MfaClient.mjs +1 -1
  123. package/dist/custom-auth-path/custom_auth/core/interaction_client/mfa/result/MfaActionResult.mjs +1 -1
  124. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/BaseApiClient.mjs +1 -1
  125. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/CustomAuthApiClient.mjs +1 -1
  126. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/CustomAuthApiEndpoint.mjs +1 -1
  127. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/RegisterApiClient.mjs +1 -1
  128. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/ResetPasswordApiClient.mjs +1 -1
  129. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/SignInApiClient.mjs +1 -1
  130. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/SignupApiClient.mjs +1 -1
  131. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/types/ApiErrorCodes.mjs +1 -1
  132. package/dist/custom-auth-path/custom_auth/core/network_client/custom_auth_api/types/ApiSuberrors.mjs +1 -1
  133. package/dist/custom-auth-path/custom_auth/core/network_client/http_client/FetchHttpClient.mjs +1 -1
  134. package/dist/custom-auth-path/custom_auth/core/network_client/http_client/IHttpClient.mjs +1 -1
  135. package/dist/custom-auth-path/custom_auth/core/telemetry/PublicApiId.mjs +1 -1
  136. package/dist/custom-auth-path/custom_auth/core/utils/ArgumentValidator.mjs +1 -1
  137. package/dist/custom-auth-path/custom_auth/core/utils/UrlUtils.mjs +1 -1
  138. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/CustomAuthAccountData.mjs +1 -1
  139. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/error_type/GetAccountError.mjs +1 -1
  140. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/GetAccessTokenResult.mjs +1 -1
  141. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/GetAccountResult.mjs +1 -1
  142. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/result/SignOutResult.mjs +1 -1
  143. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/GetAccessTokenState.mjs +1 -1
  144. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/GetAccountState.mjs +1 -1
  145. package/dist/custom-auth-path/custom_auth/get_account/auth_flow/state/SignOutState.mjs +1 -1
  146. package/dist/custom-auth-path/custom_auth/get_account/interaction_client/CustomAuthSilentCacheClient.mjs +1 -1
  147. package/dist/custom-auth-path/custom_auth/index.mjs +1 -1
  148. package/dist/custom-auth-path/custom_auth/operating_context/CustomAuthOperatingContext.mjs +1 -1
  149. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/error_type/ResetPasswordError.mjs +1 -1
  150. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordResendCodeResult.mjs +1 -1
  151. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordStartResult.mjs +1 -1
  152. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordSubmitCodeResult.mjs +1 -1
  153. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/result/ResetPasswordSubmitPasswordResult.mjs +1 -1
  154. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordCodeRequiredState.mjs +1 -1
  155. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordCompletedState.mjs +1 -1
  156. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordFailedState.mjs +1 -1
  157. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordPasswordRequiredState.mjs +1 -1
  158. package/dist/custom-auth-path/custom_auth/reset_password/auth_flow/state/ResetPasswordState.mjs +1 -1
  159. package/dist/custom-auth-path/custom_auth/reset_password/interaction_client/ResetPasswordClient.mjs +1 -1
  160. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/SignInScenario.mjs +1 -1
  161. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/error_type/SignInError.mjs +1 -1
  162. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInResendCodeResult.mjs +1 -1
  163. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInResult.mjs +1 -1
  164. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInSubmitCodeResult.mjs +1 -1
  165. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/result/SignInSubmitPasswordResult.mjs +1 -1
  166. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInCodeRequiredState.mjs +1 -1
  167. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInCompletedState.mjs +1 -1
  168. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInContinuationState.mjs +1 -1
  169. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInFailedState.mjs +1 -1
  170. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInPasswordRequiredState.mjs +1 -1
  171. package/dist/custom-auth-path/custom_auth/sign_in/auth_flow/state/SignInState.mjs +1 -1
  172. package/dist/custom-auth-path/custom_auth/sign_in/interaction_client/SignInClient.mjs +1 -1
  173. package/dist/custom-auth-path/custom_auth/sign_in/interaction_client/result/SignInActionResult.mjs +1 -1
  174. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/error_type/SignUpError.mjs +1 -1
  175. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpResendCodeResult.mjs +1 -1
  176. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpResult.mjs +1 -1
  177. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitAttributesResult.mjs +1 -1
  178. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitCodeResult.mjs +1 -1
  179. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/result/SignUpSubmitPasswordResult.mjs +1 -1
  180. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpAttributesRequiredState.mjs +1 -1
  181. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpCodeRequiredState.mjs +1 -1
  182. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpCompletedState.mjs +1 -1
  183. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpFailedState.mjs +1 -1
  184. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpPasswordRequiredState.mjs +1 -1
  185. package/dist/custom-auth-path/custom_auth/sign_up/auth_flow/state/SignUpState.mjs +1 -1
  186. package/dist/custom-auth-path/custom_auth/sign_up/interaction_client/SignUpClient.mjs +1 -1
  187. package/dist/custom-auth-path/custom_auth/sign_up/interaction_client/result/SignUpActionResult.mjs +1 -1
  188. package/dist/custom-auth-path/encode/Base64Decode.mjs +1 -1
  189. package/dist/custom-auth-path/encode/Base64Encode.mjs +1 -1
  190. package/dist/custom-auth-path/error/BrowserAuthError.mjs +1 -1
  191. package/dist/custom-auth-path/error/BrowserAuthErrorCodes.mjs +1 -1
  192. package/dist/custom-auth-path/error/BrowserConfigurationAuthError.mjs +1 -1
  193. package/dist/custom-auth-path/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  194. package/dist/custom-auth-path/error/NativeAuthError.mjs +1 -1
  195. package/dist/custom-auth-path/error/NativeAuthErrorCodes.mjs +1 -1
  196. package/dist/custom-auth-path/event/EventHandler.mjs +1 -1
  197. package/dist/custom-auth-path/event/EventType.mjs +1 -1
  198. package/dist/custom-auth-path/interaction_client/BaseInteractionClient.mjs +1 -1
  199. package/dist/custom-auth-path/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  200. package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
  201. package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
  202. package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.mjs +7 -7
  203. package/dist/custom-auth-path/interaction_client/PlatformAuthInteractionClient.mjs.map +1 -1
  204. package/dist/custom-auth-path/interaction_client/PopupClient.mjs +1 -1
  205. package/dist/custom-auth-path/interaction_client/RedirectClient.mjs +1 -1
  206. package/dist/custom-auth-path/interaction_client/SilentAuthCodeClient.mjs +1 -1
  207. package/dist/custom-auth-path/interaction_client/SilentCacheClient.mjs +1 -1
  208. package/dist/custom-auth-path/interaction_client/SilentIframeClient.mjs +1 -1
  209. package/dist/custom-auth-path/interaction_client/SilentRefreshClient.mjs +1 -1
  210. package/dist/custom-auth-path/interaction_client/StandardInteractionClient.mjs +1 -1
  211. package/dist/custom-auth-path/interaction_handler/InteractionHandler.mjs +1 -1
  212. package/dist/custom-auth-path/interaction_handler/SilentHandler.mjs +1 -1
  213. package/dist/custom-auth-path/navigation/NavigationClient.mjs +1 -1
  214. package/dist/custom-auth-path/network/FetchClient.mjs +1 -1
  215. package/dist/custom-auth-path/operatingcontext/BaseOperatingContext.mjs +1 -1
  216. package/dist/custom-auth-path/operatingcontext/StandardOperatingContext.mjs +1 -1
  217. package/dist/custom-auth-path/packageMetadata.d.ts +1 -1
  218. package/dist/custom-auth-path/packageMetadata.mjs +2 -2
  219. package/dist/custom-auth-path/protocol/Authorize.mjs +1 -1
  220. package/dist/custom-auth-path/request/RequestHelpers.mjs +1 -1
  221. package/dist/custom-auth-path/response/ResponseHandler.mjs +1 -1
  222. package/dist/custom-auth-path/utils/BrowserConstants.mjs +1 -1
  223. package/dist/custom-auth-path/utils/BrowserProtocolUtils.mjs +1 -1
  224. package/dist/custom-auth-path/utils/BrowserUtils.mjs +1 -1
  225. package/dist/custom-auth-path/utils/Helpers.mjs +1 -1
  226. package/dist/custom-auth-path/utils/MsalFrameStatsUtils.mjs +1 -1
  227. package/dist/custom_auth/CustomAuthConstants.d.ts +1 -1
  228. package/dist/encode/Base64Decode.mjs +1 -1
  229. package/dist/encode/Base64Encode.mjs +1 -1
  230. package/dist/error/BrowserAuthError.mjs +1 -1
  231. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  232. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  233. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  234. package/dist/error/NativeAuthError.mjs +1 -1
  235. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  236. package/dist/error/NestedAppAuthError.mjs +1 -1
  237. package/dist/event/EventHandler.mjs +1 -1
  238. package/dist/event/EventMessage.mjs +1 -1
  239. package/dist/event/EventType.mjs +1 -1
  240. package/dist/index.mjs +1 -1
  241. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  242. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  243. package/dist/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
  244. package/dist/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
  245. package/dist/interaction_client/PlatformAuthInteractionClient.mjs +7 -7
  246. package/dist/interaction_client/PlatformAuthInteractionClient.mjs.map +1 -1
  247. package/dist/interaction_client/PopupClient.mjs +1 -1
  248. package/dist/interaction_client/RedirectClient.mjs +1 -1
  249. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  250. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  251. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  252. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  253. package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
  254. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  255. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  256. package/dist/naa/BridgeError.mjs +1 -1
  257. package/dist/naa/BridgeProxy.mjs +1 -1
  258. package/dist/naa/BridgeStatusCode.mjs +1 -1
  259. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
  260. package/dist/navigation/NavigationClient.mjs +1 -1
  261. package/dist/network/FetchClient.mjs +1 -1
  262. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  263. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  264. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  265. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  266. package/dist/packageMetadata.d.ts +1 -1
  267. package/dist/packageMetadata.mjs +2 -2
  268. package/dist/protocol/Authorize.mjs +1 -1
  269. package/dist/request/RequestHelpers.mjs +1 -1
  270. package/dist/response/ResponseHandler.mjs +1 -1
  271. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  272. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  273. package/dist/utils/BrowserConstants.mjs +1 -1
  274. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  275. package/dist/utils/BrowserUtils.mjs +1 -1
  276. package/dist/utils/Helpers.mjs +1 -1
  277. package/dist/utils/MsalFrameStatsUtils.mjs +1 -1
  278. package/lib/custom-auth-path/msal-custom-auth.cjs +1237 -947
  279. package/lib/custom-auth-path/msal-custom-auth.cjs.map +1 -1
  280. package/lib/custom-auth-path/types/cache/BrowserCacheManager.d.ts +64 -7
  281. package/lib/custom-auth-path/types/cache/BrowserCacheManager.d.ts.map +1 -1
  282. package/lib/custom-auth-path/types/cache/CacheKeys.d.ts +3 -3
  283. package/lib/custom-auth-path/types/cache/IWindowStorage.d.ts +1 -1
  284. package/lib/custom-auth-path/types/cache/IWindowStorage.d.ts.map +1 -1
  285. package/lib/custom-auth-path/types/cache/LocalStorage.d.ts +1 -1
  286. package/lib/custom-auth-path/types/cache/LocalStorage.d.ts.map +1 -1
  287. package/lib/custom-auth-path/types/cache/TokenCache.d.ts.map +1 -1
  288. package/lib/custom-auth-path/types/controllers/NestedAppAuthController.d.ts.map +1 -1
  289. package/lib/custom-auth-path/types/controllers/StandardController.d.ts.map +1 -1
  290. package/lib/custom-auth-path/types/custom_auth/CustomAuthConstants.d.ts +1 -1
  291. package/lib/custom-auth-path/types/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
  292. package/lib/custom-auth-path/types/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
  293. package/lib/custom-auth-path/types/packageMetadata.d.ts +1 -1
  294. package/lib/msal-browser.cjs +946 -656
  295. package/lib/msal-browser.cjs.map +1 -1
  296. package/lib/msal-browser.js +946 -656
  297. package/lib/msal-browser.js.map +1 -1
  298. package/lib/msal-browser.min.js +67 -67
  299. package/lib/types/cache/BrowserCacheManager.d.ts +64 -7
  300. package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
  301. package/lib/types/cache/CacheKeys.d.ts +3 -3
  302. package/lib/types/cache/IWindowStorage.d.ts +1 -1
  303. package/lib/types/cache/IWindowStorage.d.ts.map +1 -1
  304. package/lib/types/cache/LocalStorage.d.ts +1 -1
  305. package/lib/types/cache/LocalStorage.d.ts.map +1 -1
  306. package/lib/types/cache/TokenCache.d.ts.map +1 -1
  307. package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
  308. package/lib/types/controllers/StandardController.d.ts.map +1 -1
  309. package/lib/types/custom_auth/CustomAuthConstants.d.ts +1 -1
  310. package/lib/types/interaction_client/PlatformAuthInteractionClient.d.ts +1 -1
  311. package/lib/types/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -1
  312. package/lib/types/packageMetadata.d.ts +1 -1
  313. package/package.json +2 -2
  314. package/src/cache/BrowserCacheManager.ts +738 -225
  315. package/src/cache/CacheKeys.ts +3 -3
  316. package/src/cache/IWindowStorage.ts +2 -1
  317. package/src/cache/LocalStorage.ts +30 -17
  318. package/src/cache/TokenCache.ts +33 -12
  319. package/src/controllers/NestedAppAuthController.ts +3 -1
  320. package/src/controllers/StandardController.ts +3 -1
  321. package/src/interaction_client/PlatformAuthInteractionClient.ts +15 -5
  322. package/src/packageMetadata.ts +1 -1
@@ -1,8 +1,8 @@
1
- /*! @azure/msal-browser v4.25.1 2025-10-17 */
1
+ /*! @azure/msal-browser v4.26.0 2025-10-29 */
2
2
  'use strict';
3
3
  'use strict';
4
4
 
5
- /*! @azure/msal-common v15.13.0 2025-10-17 */
5
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
279
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
290
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
325
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
375
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
449
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
488
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
679
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
680
680
  /* eslint-disable header/header */
681
681
  const name$1 = "@azure/msal-common";
682
- const version$1 = "15.13.0";
682
+ const version$1 = "15.13.1";
683
683
 
684
- /*! @azure/msal-common v15.13.0 2025-10-17 */
684
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
693
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
722
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
767
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
864
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
1059
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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-10-29 */
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.0 2025-10-17 */
1142
-
1181
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
1143
1182
  /*
1144
1183
  * Copyright (c) Microsoft Corporation. All rights reserved.
1145
1184
  * Licensed under the MIT License.
1146
1185
  */
1147
1186
  /**
1148
- * Extract token by decoding the rawToken
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
- function checkMaxAge(authTime, maxAge) {
1191
- /*
1192
- * per https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
1193
- * To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access,
1194
- * provide a value of 0 for the max_age parameter and the AS will force a fresh login.
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-10-29 */
1204
1197
  /*
1205
1198
  * Copyright (c) Microsoft Corporation. All rights reserved.
1206
1199
  * Licensed under the MIT License.
1207
1200
  */
1208
1201
  /**
1209
- * Canonicalizes a URL by making it lowercase and ensuring it ends with /
1210
- * Inlined version of UrlString.canonicalizeUri to avoid circular dependency
1211
- * @param url - URL to canonicalize
1212
- * @returns Canonicalized URL
1213
- */
1214
- function canonicalizeUrl(url) {
1215
- if (!url) {
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 getDeserializedResponse(responseString) {
1248
- // Check if given hash is empty
1249
- if (!responseString || responseString.indexOf("=") < 0) {
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.0 2025-10-17 */
1319
-
1218
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
1320
1219
  /*
1321
1220
  * Copyright (c) Microsoft Corporation. All rights reserved.
1322
1221
  * Licensed under the MIT License.
1323
1222
  */
1324
1223
  /**
1325
- * Url object class which can perform various transformations on url strings.
1224
+ * Protocol modes supported by MSAL.
1326
1225
  */
1327
- class UrlString {
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
- * Ensure urls are lower case and end with a / character.
1343
- * @param url
1228
+ * Auth Code + PKCE with Entra ID (formerly AAD) specific optimizations and features
1344
1229
  */
1345
- static canonicalizeUri(url) {
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
- * Throws if urlString passed is not a valid authority URI string.
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-10-29 */
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-10-29 */
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-10-29 */
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-10-29 */
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.0 2025-10-17 */
1824
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
1963
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
1971
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
2016
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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].getAccountInfo();
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 = accountEntity.getAccountInfo();
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.0 2025-10-17 */
3125
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
3392
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
3471
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
3571
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
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-10-29 */
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.0 2025-10-17 */
3631
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
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-10-29 */
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.0 2025-10-17 */
4023
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4033
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4043
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4139
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4245
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4310
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
4572
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5411
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5442
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5461
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5482
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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
- * Updates the authority object of the client. Endpoint discovery must be completed.
5458
- * @param updatedAuthority
5533
+ * Checks a NetworkResponse object's status codes against 429 or 5xx
5534
+ * @param response
5459
5535
  */
5460
- async updateAuthority(cloudInstanceHostname, correlationId) {
5461
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.UpdateTokenEndpointAuthority, correlationId);
5462
- const cloudInstanceAuthorityUri = `https://${cloudInstanceHostname}/${this.authority.tenant}/`;
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
- * Creates query string for the /token request
5468
- * @param request
5541
+ * Checks a NetworkResponse object's RetryAfter header
5542
+ * @param response
5469
5543
  */
5470
- createTokenQueryParameters(request) {
5471
- const parameters = new Map();
5472
- if (request.embeddedClientId) {
5473
- addBrokerParameters(parameters, this.config.authOptions.clientId, this.config.authOptions.redirectUri);
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
- addCorrelationId(parameters, request.correlationId);
5479
- instrumentBrokerParams(parameters, request.correlationId, this.performanceClient);
5480
- return mapToQueryString(parameters);
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.0 2025-10-17 */
5569
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
5570
+
5485
5571
  /*
5486
5572
  * Copyright (c) Microsoft Corporation. All rights reserved.
5487
5573
  * Licensed under the MIT License.
5488
5574
  */
5489
5575
  /**
5490
- * Gets tenantId from available ID token claims to set as credential realm with the following precedence:
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
- function getTenantIdFromIdTokenClaims(idTokenClaims) {
5499
- if (idTokenClaims) {
5500
- const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
5501
- return tenantId || null;
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
- return null;
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.0 2025-10-17 */
5600
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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
- * Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
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 AccountEntity {
5536
- /**
5537
- * Returns the AccountInfo interface for this account.
5538
- */
5539
- getAccountInfo() {
5540
- return {
5541
- homeAccountId: this.homeAccountId,
5542
- environment: this.environment,
5543
- tenantId: this.realm,
5544
- username: this.username,
5545
- localAccountId: this.localAccountId,
5546
- loginHint: this.loginHint,
5547
- name: this.name,
5548
- nativeAccountId: this.nativeAccountId,
5549
- authorityType: this.authorityType,
5550
- // Deserialize tenant profiles array into a Map
5551
- tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => {
5552
- return [tenantProfile.tenantId, tenantProfile];
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 an AccountEntity object from AccountInfo
5632
- * @param accountInfo
5633
- * @param cloudGraphHostName
5634
- * @param msGraphHost
5635
- * @returns
5630
+ * Creates default headers for requests to token endpoint
5636
5631
  */
5637
- static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
5638
- const account = new AccountEntity();
5639
- account.authorityType =
5640
- accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
5641
- account.homeAccountId = accountInfo.homeAccountId;
5642
- account.localAccountId = accountInfo.localAccountId;
5643
- account.nativeAccountId = accountInfo.nativeAccountId;
5644
- account.realm = accountInfo.tenantId;
5645
- account.environment = accountInfo.environment;
5646
- account.username = accountInfo.username;
5647
- account.name = accountInfo.name;
5648
- account.loginHint = accountInfo.loginHint;
5649
- account.cloudGraphHostName = cloudGraphHostName;
5650
- account.msGraphHost = msGraphHost;
5651
- // Serialize tenant profiles map into an array
5652
- account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
5653
- account.dataBoundary = accountInfo.dataBoundary;
5654
- return account;
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
- * Generate HomeAccountId from server response
5658
- * @param serverClientInfo
5659
- * @param authType
5655
+ * Http post to token endpoint
5656
+ * @param tokenEndpoint
5657
+ * @param queryString
5658
+ * @param headers
5659
+ * @param thumbprint
5660
5660
  */
5661
- static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
5662
- // since ADFS/DSTS do not have tid and does not set client_info
5663
- if (!(authType === AuthorityType.Adfs ||
5664
- authType === AuthorityType.Dsts)) {
5665
- // for cases where there is clientInfo
5666
- if (serverClientInfo) {
5667
- try {
5668
- const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
5669
- if (clientInfo.uid && clientInfo.utid) {
5670
- return `${clientInfo.uid}.${clientInfo.utid}`;
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
- catch (e) { }
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
- // default to "sub" claim
5678
- return idTokenClaims?.sub || "";
5717
+ ThrottlingUtils.postProcess(this.cacheManager, thumbprint, response, correlationId);
5718
+ return response;
5679
5719
  }
5680
5720
  /**
5681
- * Validates an entity: checks for all expected params
5682
- * @param entity
5721
+ * Updates the authority object of the client. Endpoint discovery must be completed.
5722
+ * @param updatedAuthority
5683
5723
  */
5684
- static isAccountEntity(entity) {
5685
- if (!entity) {
5686
- return false;
5687
- }
5688
- return (entity.hasOwnProperty("homeAccountId") &&
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
- * Helper function to determine whether 2 accountInfo objects represent the same account
5697
- * @param accountA
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
- static accountInfoIsEqual(accountA, accountB, compareClaims) {
5702
- if (!accountA || !accountB) {
5703
- return false;
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
- let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
5706
- if (compareClaims) {
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
- return (accountA.homeAccountId === accountB.homeAccountId &&
5717
- accountA.localAccountId === accountB.localAccountId &&
5718
- accountA.username === accountB.username &&
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.0 2025-10-17 */
5748
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5764
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5836
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5908
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
5990
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6017
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.getAccountInfo());
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.getAccountInfo(), undefined, // tenantProfile optional
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.0 2025-10-17 */
6348
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6366
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6601
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6810
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6908
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
6923
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
7147
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
7410
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
7418
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.0 2025-10-17 */
7443
+ /*! @azure/msal-common v15.13.1 2025-10-29 */
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.25.1";
7878
+ const version = "4.26.0";
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 = 1;
14153
- const ACCOUNT_SCHEMA_VERSION = 1;
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 JSON.parse(decryptedData);
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
- const { data, nonce } = await invokeAsync(encrypt, PerformanceEvents.Encrypt, this.logger, this.performanceClient, correlationId)(this.encryptionCookie.key, value, this.getContext(key));
14396
- const encryptedData = {
14397
- id: this.encryptionCookie.id,
14398
- nonce: nonce,
14399
- data: data,
14400
- lastUpdatedAt: timestamp,
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 encObj;
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
- const accountKeys0 = getAccountKeys(this.browserStorage, 0);
14702
- const tokenKeys0 = getTokenKeys(this.clientId, this.browserStorage, 0);
14731
+ let accountKeys = getAccountKeys(this.browserStorage);
14732
+ let tokenKeys = getTokenKeys(this.clientId, this.browserStorage);
14703
14733
  this.performanceClient.addFields({
14704
- oldAccountCount: accountKeys0.length,
14705
- oldAccessCount: tokenKeys0.accessToken.length,
14706
- oldIdCount: tokenKeys0.idToken.length,
14707
- oldRefreshCount: tokenKeys0.refreshToken.length,
14734
+ preMigrateAcntCount: accountKeys.length,
14735
+ preMigrateATCount: tokenKeys.accessToken.length,
14736
+ preMigrateITCount: tokenKeys.idToken.length,
14737
+ preMigrateRTCount: tokenKeys.refreshToken.length,
14708
14738
  }, correlationId);
14709
- const accountKeys1 = getAccountKeys(this.browserStorage, 1);
14710
- const tokenKeys1 = getTokenKeys(this.clientId, this.browserStorage, 1);
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
- currAccountCount: accountKeys1.length,
14713
- currAccessCount: tokenKeys1.accessToken.length,
14714
- currIdCount: tokenKeys1.idToken.length,
14715
- currRefreshCount: tokenKeys1.refreshToken.length,
14756
+ postMigrateAcntCount: accountKeys.length,
14757
+ postMigrateATCount: tokenKeys.accessToken.length,
14758
+ postMigrateITCount: tokenKeys.idToken.length,
14759
+ postMigrateRTCount: tokenKeys.refreshToken.length,
14716
14760
  }, correlationId);
14717
- await Promise.all([
14718
- this.updateV0ToCurrent(ACCOUNT_SCHEMA_VERSION, accountKeys0, accountKeys1, correlationId),
14719
- this.updateV0ToCurrent(CREDENTIAL_SCHEMA_VERSION, tokenKeys0.idToken, tokenKeys1.idToken, correlationId),
14720
- this.updateV0ToCurrent(CREDENTIAL_SCHEMA_VERSION, tokenKeys0.accessToken, tokenKeys1.accessToken, correlationId),
14721
- this.updateV0ToCurrent(CREDENTIAL_SCHEMA_VERSION, tokenKeys0.refreshToken, tokenKeys1.refreshToken, correlationId),
14722
- ]);
14723
- if (accountKeys0.length > 0) {
14724
- this.browserStorage.setItem(getAccountKeysCacheKey(0), JSON.stringify(accountKeys0));
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
- else {
14727
- this.browserStorage.removeItem(getAccountKeysCacheKey(0));
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 (accountKeys1.length > 0) {
14730
- this.browserStorage.setItem(getAccountKeysCacheKey(1), JSON.stringify(accountKeys1));
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
- else {
14733
- this.browserStorage.removeItem(getAccountKeysCacheKey(1));
14734
- }
14735
- this.setTokenKeys(tokenKeys0, correlationId, 0);
14736
- this.setTokenKeys(tokenKeys1, correlationId, 1);
14737
- }
14738
- async updateV0ToCurrent(currentSchema, v0Keys, v1Keys, correlationId) {
14739
- const upgradePromises = [];
14740
- for (const v0Key of [...v0Keys]) {
14741
- const rawV0Value = this.browserStorage.getItem(v0Key);
14742
- const parsedV0Value = this.validateAndParseJson(rawV0Value || "");
14743
- if (!parsedV0Value) {
14744
- removeElementFromArray(v0Keys, v0Key);
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
- if (!parsedV0Value.lastUpdatedAt) {
14748
- // Add lastUpdatedAt to the existing v0 entry if it doesnt exist so we know when it's safe to remove it
14749
- parsedV0Value.lastUpdatedAt = Date.now().toString();
14750
- this.setItem(v0Key, JSON.stringify(parsedV0Value), correlationId);
14751
- }
14752
- const decryptedData = isEncrypted(parsedV0Value)
14753
- ? await this.browserStorage.decryptData(v0Key, parsedV0Value, correlationId)
14754
- : parsedV0Value;
14755
- let expirationTime;
14756
- if (decryptedData) {
14757
- if (isAccessTokenEntity(decryptedData)) {
14758
- expirationTime = decryptedData.expiresOn;
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
- else if (isRefreshTokenEntity(decryptedData)) {
14761
- expirationTime = decryptedData.expiresOn;
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 (!decryptedData ||
14765
- isCacheExpired(parsedV0Value.lastUpdatedAt, this.cacheConfig.cacheRetentionDays) ||
14766
- (expirationTime &&
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
- if (this.cacheConfig.cacheLocation !==
14774
- BrowserCacheLocation.LocalStorage ||
14775
- isEncrypted(parsedV0Value)) {
14776
- const v1Key = `${PREFIX}.${currentSchema}${CACHE_KEY_SEPARATOR}${v0Key}`;
14777
- const rawV1Entry = this.browserStorage.getItem(v1Key);
14778
- if (!rawV1Entry) {
14779
- upgradePromises.push(this.setUserData(v1Key, JSON.stringify(decryptedData), correlationId, parsedV0Value.lastUpdatedAt).then(() => {
14780
- v1Keys.push(v1Key);
14781
- this.performanceClient.incrementFields({ upgradedCacheCount: 1 }, correlationId);
14782
- }));
14783
- continue;
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
- else {
14786
- const parsedV1Entry = this.validateAndParseJson(rawV1Entry);
14787
- // If the entry already exists but is older than the v0 entry, replace it
14788
- if (Number(parsedV0Value.lastUpdatedAt) >
14789
- Number(parsedV1Entry.lastUpdatedAt)) {
14790
- upgradePromises.push(this.setUserData(v1Key, JSON.stringify(decryptedData), correlationId, parsedV0Value.lastUpdatedAt).then(() => {
14791
- this.performanceClient.incrementFields({ updatedCacheFromV0Count: 1 }, correlationId);
14792
- }));
14793
- continue;
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
- return Promise.all(upgradePromises);
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
- let tokenKeysV0Count = 0;
14848
- let accessTokenKeys = [];
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
- // Finally update the token keys array with the tokens removed
14855
- if (i <= tokenKeysV0Count) {
14856
- this.removeAccessTokenKeys(accessTokenKeys.slice(0, i), correlationId, 0);
14857
- }
14858
- else {
14859
- this.removeAccessTokenKeys(accessTokenKeys.slice(0, tokenKeysV0Count), correlationId, 0);
14860
- this.removeAccessTokenKeys(accessTokenKeys.slice(tokenKeysV0Count, i), correlationId);
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
- const tokenKeys0 = key ===
14873
- getTokenKeysCacheKey(this.clientId, 0)
14874
- ? JSON.parse(value).accessToken
14875
- : this.getTokenKeys(0).accessToken;
14876
- const tokenKeys1 = key ===
14877
- getTokenKeysCacheKey(this.clientId)
14878
- ? JSON.parse(value).accessToken
14879
- : this.getTokenKeys().accessToken;
14880
- accessTokenKeys = [...tokenKeys0, ...tokenKeys1];
14881
- tokenKeysV0Count = tokenKeys0.length;
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
- let tokenKeysV0Count = 0;
14906
- let accessTokenKeys = [];
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
- await invokeAsync(this.browserStorage.setUserData.bind(this.browserStorage), PerformanceEvents.SetUserData, this.logger, this.performanceClient)(key, value, correlationId, timestamp);
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
- // Finally update the token keys array with the tokens removed
14913
- if (i <= tokenKeysV0Count) {
14914
- this.removeAccessTokenKeys(accessTokenKeys.slice(0, i), correlationId, 0);
14915
- }
14916
- else {
14917
- this.removeAccessTokenKeys(accessTokenKeys.slice(0, tokenKeysV0Count), correlationId, 0);
14918
- this.removeAccessTokenKeys(accessTokenKeys.slice(tokenKeysV0Count, i), correlationId);
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
- const tokenKeys0 = this.getTokenKeys(0).accessToken;
14930
- const tokenKeys1 = this.getTokenKeys().accessToken;
14931
- accessTokenKeys = [...tokenKeys0, ...tokenKeys1];
14932
- tokenKeysV0Count = tokenKeys0.length;
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(account.getAccountInfo());
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, account.getAccountInfo());
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
- if (accountKeys.length === 0) {
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(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
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(accountEntity.getAccountInfo(), correlationId);
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
@@ -19304,6 +19593,7 @@ class TokenCache {
19304
19593
  const idTokenClaims = response.id_token
19305
19594
  ? extractTokenClaims(response.id_token, base64Decode)
19306
19595
  : undefined;
19596
+ const kmsi = isKmsi(idTokenClaims || {});
19307
19597
  const authorityOptions = {
19308
19598
  protocolMode: this.config.auth.protocolMode,
19309
19599
  knownAuthorities: this.config.auth.knownAuthorities,
@@ -19315,9 +19605,9 @@ class TokenCache {
19315
19605
  ? new Authority(Authority.generateAuthority(request.authority, request.azureCloudOptions), this.config.system.networkClient, this.storage, authorityOptions, this.logger, request.correlationId || createNewGuid())
19316
19606
  : undefined;
19317
19607
  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);
19608
+ const idToken = await this.loadIdToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, correlationId, kmsi);
19609
+ const accessToken = await this.loadAccessToken(request, response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, cacheRecordAccount.realm, options, correlationId, kmsi);
19610
+ const refreshToken = await this.loadRefreshToken(response, cacheRecordAccount.homeAccountId, cacheRecordAccount.environment, correlationId, kmsi);
19321
19611
  return this.generateAuthenticationResult(request, {
19322
19612
  account: cacheRecordAccount,
19323
19613
  idToken,
@@ -19338,7 +19628,7 @@ class TokenCache {
19338
19628
  this.logger.verbose("TokenCache - loading account");
19339
19629
  if (request.account) {
19340
19630
  const accountEntity = AccountEntity.createFromAccountInfo(request.account);
19341
- await this.storage.setAccount(accountEntity, correlationId);
19631
+ await this.storage.setAccount(accountEntity, correlationId, isKmsi(idTokenClaims || {}));
19342
19632
  return accountEntity;
19343
19633
  }
19344
19634
  else if (!authority || (!clientInfo && !idTokenClaims)) {
@@ -19350,7 +19640,7 @@ class TokenCache {
19350
19640
  const cachedAccount = buildAccountToCache(this.storage, authority, homeAccountId, base64Decode, correlationId, idTokenClaims, clientInfo, authority.hostnameAndPort, claimsTenantId, undefined, // authCodePayload
19351
19641
  undefined, // nativeAccountId
19352
19642
  this.logger);
19353
- await this.storage.setAccount(cachedAccount, correlationId);
19643
+ await this.storage.setAccount(cachedAccount, correlationId, isKmsi(idTokenClaims || {}));
19354
19644
  return cachedAccount;
19355
19645
  }
19356
19646
  /**
@@ -19361,14 +19651,14 @@ class TokenCache {
19361
19651
  * @param tenantId
19362
19652
  * @returns `IdTokenEntity`
19363
19653
  */
19364
- async loadIdToken(response, homeAccountId, environment, tenantId, correlationId) {
19654
+ async loadIdToken(response, homeAccountId, environment, tenantId, correlationId, kmsi) {
19365
19655
  if (!response.id_token) {
19366
19656
  this.logger.verbose("TokenCache - no id token found in response");
19367
19657
  return null;
19368
19658
  }
19369
19659
  this.logger.verbose("TokenCache - loading id token");
19370
19660
  const idTokenEntity = createIdTokenEntity(homeAccountId, environment, response.id_token, this.config.auth.clientId, tenantId);
19371
- await this.storage.setIdTokenCredential(idTokenEntity, correlationId);
19661
+ await this.storage.setIdTokenCredential(idTokenEntity, correlationId, kmsi);
19372
19662
  return idTokenEntity;
19373
19663
  }
19374
19664
  /**
@@ -19380,7 +19670,7 @@ class TokenCache {
19380
19670
  * @param tenantId
19381
19671
  * @returns `AccessTokenEntity`
19382
19672
  */
19383
- async loadAccessToken(request, response, homeAccountId, environment, tenantId, options, correlationId) {
19673
+ async loadAccessToken(request, response, homeAccountId, environment, tenantId, options, correlationId, kmsi) {
19384
19674
  if (!response.access_token) {
19385
19675
  this.logger.verbose("TokenCache - no access token found in response");
19386
19676
  return null;
@@ -19403,7 +19693,7 @@ class TokenCache {
19403
19693
  (response.ext_expires_in || response.expires_in) +
19404
19694
  nowSeconds();
19405
19695
  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);
19696
+ await this.storage.setAccessTokenCredential(accessTokenEntity, correlationId, kmsi);
19407
19697
  return accessTokenEntity;
19408
19698
  }
19409
19699
  /**
@@ -19414,7 +19704,7 @@ class TokenCache {
19414
19704
  * @param environment
19415
19705
  * @returns `RefreshTokenEntity`
19416
19706
  */
19417
- async loadRefreshToken(response, homeAccountId, environment, correlationId) {
19707
+ async loadRefreshToken(response, homeAccountId, environment, correlationId, kmsi) {
19418
19708
  if (!response.refresh_token) {
19419
19709
  this.logger.verbose("TokenCache - no refresh token found in response");
19420
19710
  return null;
@@ -19422,7 +19712,7 @@ class TokenCache {
19422
19712
  this.logger.verbose("TokenCache - loading refresh token");
19423
19713
  const refreshTokenEntity = createRefreshTokenEntity(homeAccountId, environment, response.refresh_token, this.config.auth.clientId, response.foci, undefined, // userAssertionHash
19424
19714
  response.refresh_token_expires_in);
19425
- await this.storage.setRefreshTokenCredential(refreshTokenEntity, correlationId);
19715
+ await this.storage.setRefreshTokenCredential(refreshTokenEntity, correlationId, kmsi);
19426
19716
  return refreshTokenEntity;
19427
19717
  }
19428
19718
  /**
@@ -19451,7 +19741,7 @@ class TokenCache {
19451
19741
  uniqueId: cacheRecord.account.localAccountId,
19452
19742
  tenantId: cacheRecord.account.realm,
19453
19743
  scopes: responseScopes,
19454
- account: accountEntity.getAccountInfo(),
19744
+ account: AccountEntity.getAccountInfo(accountEntity),
19455
19745
  idToken: cacheRecord.idToken?.secret || "",
19456
19746
  idTokenClaims: idTokenClaims || {},
19457
19747
  accessToken: accessToken,
@@ -20469,7 +20759,7 @@ class StandardController {
20469
20759
  this.logger.verbose("hydrateCache called");
20470
20760
  // Account gets saved to browser storage regardless of native or not
20471
20761
  const accountEntity = AccountEntity.createFromAccountInfo(result.account, result.cloudGraphHostName, result.msGraphHost);
20472
- await this.browserStorage.setAccount(accountEntity, result.correlationId);
20762
+ await this.browserStorage.setAccount(accountEntity, result.correlationId, isKmsi(result.idTokenClaims));
20473
20763
  if (result.fromNativeBroker) {
20474
20764
  this.logger.verbose("Response was from native broker, storing in-memory");
20475
20765
  // Tokens from native broker are stored in-memory