@azure/msal-browser 2.37.0 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/app/IPublicClientApplication.d.ts.map +1 -1
  2. package/dist/app/IPublicClientApplication.js +33 -33
  3. package/dist/app/IPublicClientApplication.js.map +1 -1
  4. package/dist/app/PublicClientApplication.d.ts +198 -24
  5. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  6. package/dist/app/PublicClientApplication.js +263 -220
  7. package/dist/app/PublicClientApplication.js.map +1 -1
  8. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts +5 -4
  9. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts.map +1 -1
  10. package/dist/broker/nativeBroker/NativeMessageHandler.js +118 -124
  11. package/dist/broker/nativeBroker/NativeMessageHandler.js.map +1 -1
  12. package/dist/broker/nativeBroker/NativeRequest.d.ts +4 -4
  13. package/dist/broker/nativeBroker/NativeRequest.d.ts.map +1 -1
  14. package/dist/broker/nativeBroker/NativeResponse.d.ts +4 -4
  15. package/dist/broker/nativeBroker/NativeResponse.d.ts.map +1 -1
  16. package/dist/cache/AsyncMemoryStorage.d.ts.map +1 -1
  17. package/dist/cache/AsyncMemoryStorage.js +83 -152
  18. package/dist/cache/AsyncMemoryStorage.js.map +1 -1
  19. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  20. package/dist/cache/BrowserCacheManager.js +420 -412
  21. package/dist/cache/BrowserCacheManager.js.map +1 -1
  22. package/dist/cache/BrowserStorage.d.ts.map +1 -1
  23. package/dist/cache/BrowserStorage.js +19 -19
  24. package/dist/cache/BrowserStorage.js.map +1 -1
  25. package/dist/cache/CryptoKeyStore.d.ts.map +1 -1
  26. package/dist/cache/CryptoKeyStore.js +26 -36
  27. package/dist/cache/CryptoKeyStore.js.map +1 -1
  28. package/dist/cache/DatabaseStorage.d.ts.map +1 -1
  29. package/dist/cache/DatabaseStorage.js +127 -191
  30. package/dist/cache/DatabaseStorage.js.map +1 -1
  31. package/dist/cache/ITokenCache.d.ts.map +1 -1
  32. package/dist/cache/MemoryStorage.d.ts.map +1 -1
  33. package/dist/cache/MemoryStorage.js +18 -19
  34. package/dist/cache/MemoryStorage.js.map +1 -1
  35. package/dist/cache/TokenCache.d.ts +1 -1
  36. package/dist/cache/TokenCache.d.ts.map +1 -1
  37. package/dist/cache/TokenCache.js +55 -49
  38. package/dist/cache/TokenCache.js.map +1 -1
  39. package/dist/config/Configuration.d.ts +8 -8
  40. package/dist/config/Configuration.d.ts.map +1 -1
  41. package/dist/config/Configuration.js +53 -31
  42. package/dist/config/Configuration.js.map +1 -1
  43. package/dist/controllers/ControllerFactory.d.ts +10 -0
  44. package/dist/controllers/ControllerFactory.d.ts.map +1 -0
  45. package/dist/controllers/ControllerFactory.js +47 -0
  46. package/dist/controllers/ControllerFactory.js.map +1 -0
  47. package/dist/controllers/IController.d.ts +67 -0
  48. package/dist/controllers/IController.d.ts.map +1 -0
  49. package/dist/{app/ClientApplication.d.ts → controllers/StandardController.d.ts} +96 -15
  50. package/dist/controllers/StandardController.d.ts.map +1 -0
  51. package/dist/controllers/StandardController.js +1299 -0
  52. package/dist/controllers/StandardController.js.map +1 -0
  53. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  54. package/dist/crypto/BrowserCrypto.js +36 -60
  55. package/dist/crypto/BrowserCrypto.js.map +1 -1
  56. package/dist/crypto/CryptoOps.d.ts +1 -1
  57. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  58. package/dist/crypto/CryptoOps.js +93 -151
  59. package/dist/crypto/CryptoOps.js.map +1 -1
  60. package/dist/crypto/GuidGenerator.d.ts.map +1 -1
  61. package/dist/crypto/GuidGenerator.js +36 -25
  62. package/dist/crypto/GuidGenerator.js.map +1 -1
  63. package/dist/crypto/ISubtleCrypto.d.ts.map +1 -1
  64. package/dist/crypto/ModernBrowserCrypto.d.ts.map +1 -1
  65. package/dist/crypto/ModernBrowserCrypto.js +20 -44
  66. package/dist/crypto/ModernBrowserCrypto.js.map +1 -1
  67. package/dist/crypto/MsBrowserCrypto.d.ts.map +1 -1
  68. package/dist/crypto/MsBrowserCrypto.js +65 -89
  69. package/dist/crypto/MsBrowserCrypto.js.map +1 -1
  70. package/dist/crypto/MsrBrowserCrypto.d.ts.map +1 -1
  71. package/dist/crypto/MsrBrowserCrypto.js +23 -47
  72. package/dist/crypto/MsrBrowserCrypto.js.map +1 -1
  73. package/dist/crypto/PkceGenerator.d.ts.map +1 -1
  74. package/dist/crypto/PkceGenerator.js +28 -49
  75. package/dist/crypto/PkceGenerator.js.map +1 -1
  76. package/dist/crypto/SignedHttpRequest.d.ts +1 -1
  77. package/dist/crypto/SignedHttpRequest.d.ts.map +1 -1
  78. package/dist/crypto/SignedHttpRequest.js +15 -37
  79. package/dist/crypto/SignedHttpRequest.js.map +1 -1
  80. package/dist/encode/Base64Decode.d.ts.map +1 -1
  81. package/dist/encode/Base64Decode.js +32 -33
  82. package/dist/encode/Base64Decode.js.map +1 -1
  83. package/dist/encode/Base64Encode.d.ts.map +1 -1
  84. package/dist/encode/Base64Encode.js +34 -35
  85. package/dist/encode/Base64Encode.js.map +1 -1
  86. package/dist/error/BrowserAuthError.d.ts +1 -1
  87. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  88. package/dist/error/BrowserAuthError.js +161 -163
  89. package/dist/error/BrowserAuthError.js.map +1 -1
  90. package/dist/error/BrowserConfigurationAuthError.d.ts.map +1 -1
  91. package/dist/error/BrowserConfigurationAuthError.js +32 -36
  92. package/dist/error/BrowserConfigurationAuthError.js.map +1 -1
  93. package/dist/error/NativeAuthError.d.ts +1 -1
  94. package/dist/error/NativeAuthError.d.ts.map +1 -1
  95. package/dist/error/NativeAuthError.js +26 -27
  96. package/dist/error/NativeAuthError.js.map +1 -1
  97. package/dist/event/EventHandler.d.ts.map +1 -1
  98. package/dist/event/EventHandler.js +33 -33
  99. package/dist/event/EventHandler.js.map +1 -1
  100. package/dist/event/EventMessage.d.ts +5 -5
  101. package/dist/event/EventMessage.d.ts.map +1 -1
  102. package/dist/event/EventMessage.js +18 -14
  103. package/dist/event/EventMessage.js.map +1 -1
  104. package/dist/event/EventType.js +1 -1
  105. package/dist/event/EventType.js.map +1 -1
  106. package/dist/index.d.ts +8 -8
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +1 -1
  109. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  110. package/dist/interaction_client/BaseInteractionClient.js +92 -123
  111. package/dist/interaction_client/BaseInteractionClient.js.map +1 -1
  112. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.d.ts.map +1 -1
  113. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.js +6 -10
  114. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.js.map +1 -1
  115. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  116. package/dist/interaction_client/NativeInteractionClient.js +336 -393
  117. package/dist/interaction_client/NativeInteractionClient.js.map +1 -1
  118. package/dist/interaction_client/PopupClient.d.ts +1 -1
  119. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  120. package/dist/interaction_client/PopupClient.js +224 -246
  121. package/dist/interaction_client/PopupClient.js.map +1 -1
  122. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  123. package/dist/interaction_client/RedirectClient.js +244 -292
  124. package/dist/interaction_client/RedirectClient.js.map +1 -1
  125. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  126. package/dist/interaction_client/SilentAuthCodeClient.js +50 -63
  127. package/dist/interaction_client/SilentAuthCodeClient.js.map +1 -1
  128. package/dist/interaction_client/SilentCacheClient.d.ts.map +1 -1
  129. package/dist/interaction_client/SilentCacheClient.js +50 -81
  130. package/dist/interaction_client/SilentCacheClient.js.map +1 -1
  131. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  132. package/dist/interaction_client/SilentIframeClient.js +107 -125
  133. package/dist/interaction_client/SilentIframeClient.js.map +1 -1
  134. package/dist/interaction_client/SilentRefreshClient.d.ts.map +1 -1
  135. package/dist/interaction_client/SilentRefreshClient.js +44 -72
  136. package/dist/interaction_client/SilentRefreshClient.js.map +1 -1
  137. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  138. package/dist/interaction_client/StandardInteractionClient.js +144 -180
  139. package/dist/interaction_client/StandardInteractionClient.js.map +1 -1
  140. package/dist/interaction_handler/InteractionHandler.d.ts +1 -1
  141. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  142. package/dist/interaction_handler/InteractionHandler.js +84 -110
  143. package/dist/interaction_handler/InteractionHandler.js.map +1 -1
  144. package/dist/interaction_handler/RedirectHandler.d.ts +1 -1
  145. package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
  146. package/dist/interaction_handler/RedirectHandler.js +105 -122
  147. package/dist/interaction_handler/RedirectHandler.js.map +1 -1
  148. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  149. package/dist/interaction_handler/SilentHandler.js +76 -65
  150. package/dist/interaction_handler/SilentHandler.js.map +1 -1
  151. package/dist/internals.js +1 -1
  152. package/dist/internals.js.map +1 -1
  153. package/dist/navigation/NavigationClient.d.ts.map +1 -1
  154. package/dist/navigation/NavigationClient.js +11 -14
  155. package/dist/navigation/NavigationClient.js.map +1 -1
  156. package/dist/navigation/NavigationOptions.d.ts +1 -1
  157. package/dist/navigation/NavigationOptions.d.ts.map +1 -1
  158. package/dist/network/FetchClient.d.ts.map +1 -1
  159. package/dist/network/FetchClient.js +66 -96
  160. package/dist/network/FetchClient.js.map +1 -1
  161. package/dist/network/XhrClient.d.ts.map +1 -1
  162. package/dist/network/XhrClient.js +38 -51
  163. package/dist/network/XhrClient.js.map +1 -1
  164. package/dist/operatingcontext/BaseOperatingContext.d.ts +41 -0
  165. package/dist/operatingcontext/BaseOperatingContext.d.ts.map +1 -0
  166. package/dist/operatingcontext/BaseOperatingContext.js +53 -0
  167. package/dist/operatingcontext/BaseOperatingContext.js.map +1 -0
  168. package/dist/operatingcontext/StandardOperatingContext.d.ts +26 -0
  169. package/dist/operatingcontext/StandardOperatingContext.d.ts.map +1 -0
  170. package/dist/operatingcontext/StandardOperatingContext.js +50 -0
  171. package/dist/operatingcontext/StandardOperatingContext.js.map +1 -0
  172. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts +26 -0
  173. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts.map +1 -0
  174. package/dist/operatingcontext/TeamsAppOperatingContext.js +49 -0
  175. package/dist/operatingcontext/TeamsAppOperatingContext.js.map +1 -0
  176. package/dist/packageMetadata.d.ts +1 -1
  177. package/dist/packageMetadata.d.ts.map +1 -1
  178. package/dist/packageMetadata.js +3 -3
  179. package/dist/packageMetadata.js.map +1 -1
  180. package/dist/request/AuthorizationCodeRequest.d.ts +1 -1
  181. package/dist/request/AuthorizationCodeRequest.d.ts.map +1 -1
  182. package/dist/request/AuthorizationUrlRequest.d.ts +1 -1
  183. package/dist/request/AuthorizationUrlRequest.d.ts.map +1 -1
  184. package/dist/request/EndSessionPopupRequest.d.ts +1 -1
  185. package/dist/request/EndSessionPopupRequest.d.ts.map +1 -1
  186. package/dist/request/EndSessionRequest.d.ts +1 -1
  187. package/dist/request/EndSessionRequest.d.ts.map +1 -1
  188. package/dist/request/PopupRequest.d.ts +1 -1
  189. package/dist/request/PopupRequest.d.ts.map +1 -1
  190. package/dist/request/PopupWindowAttributes.d.ts +3 -3
  191. package/dist/request/PopupWindowAttributes.d.ts.map +1 -1
  192. package/dist/request/RedirectRequest.d.ts +1 -1
  193. package/dist/request/RedirectRequest.d.ts.map +1 -1
  194. package/dist/request/SilentRequest.d.ts +1 -1
  195. package/dist/request/SilentRequest.d.ts.map +1 -1
  196. package/dist/request/SsoSilentRequest.d.ts +1 -1
  197. package/dist/request/SsoSilentRequest.d.ts.map +1 -1
  198. package/dist/telemetry/BrowserPerformanceClient.d.ts +1 -1
  199. package/dist/telemetry/BrowserPerformanceClient.d.ts.map +1 -1
  200. package/dist/telemetry/BrowserPerformanceClient.js +62 -57
  201. package/dist/telemetry/BrowserPerformanceClient.js.map +1 -1
  202. package/dist/telemetry/BrowserPerformanceMeasurement.d.ts.map +1 -1
  203. package/dist/telemetry/BrowserPerformanceMeasurement.js +30 -31
  204. package/dist/telemetry/BrowserPerformanceMeasurement.js.map +1 -1
  205. package/dist/utils/BrowserConstants.d.ts.map +1 -1
  206. package/dist/utils/BrowserConstants.js +10 -10
  207. package/dist/utils/BrowserConstants.js.map +1 -1
  208. package/dist/utils/BrowserProtocolUtils.d.ts +1 -1
  209. package/dist/utils/BrowserProtocolUtils.d.ts.map +1 -1
  210. package/dist/utils/BrowserProtocolUtils.js +9 -12
  211. package/dist/utils/BrowserProtocolUtils.js.map +1 -1
  212. package/dist/utils/BrowserStringUtils.d.ts.map +1 -1
  213. package/dist/utils/BrowserStringUtils.js +83 -49
  214. package/dist/utils/BrowserStringUtils.js.map +1 -1
  215. package/dist/utils/BrowserUtils.d.ts.map +1 -1
  216. package/dist/utils/BrowserUtils.js +51 -49
  217. package/dist/utils/BrowserUtils.js.map +1 -1
  218. package/dist/utils/MathUtils.d.ts.map +1 -1
  219. package/dist/utils/MathUtils.js +6 -9
  220. package/dist/utils/MathUtils.js.map +1 -1
  221. package/package.json +17 -16
  222. package/dist/_virtual/_tslib.js +0 -117
  223. package/dist/_virtual/_tslib.js.map +0 -1
  224. package/dist/app/ClientApplication.d.ts.map +0 -1
  225. package/dist/app/ClientApplication.js +0 -1053
  226. package/dist/app/ClientApplication.js.map +0 -1
  227. package/dist/index.cjs.js +0 -18080
  228. package/dist/index.cjs.js.map +0 -1
  229. package/lib/msal-browser.js +0 -18086
  230. package/lib/msal-browser.js.map +0 -1
  231. package/lib/msal-browser.min.js +0 -70
@@ -0,0 +1,1299 @@
1
+ /*! @azure/msal-browser v3.0.0-alpha.1 2023-05-08 */
2
+ 'use strict';
3
+ import { CryptoOps } from '../crypto/CryptoOps.js';
4
+ import { StubPerformanceClient, DEFAULT_CRYPTO_IMPLEMENTATION, PerformanceEvents, Constants, InteractionRequiredAuthError, AuthError, ClientAuthError, PromptValue, ServerError } from '@azure/msal-common';
5
+ import { BrowserCacheManager, DEFAULT_BROWSER_CACHE_MANAGER } from '../cache/BrowserCacheManager.js';
6
+ import { InteractionType, ApiId, TemporaryCacheKeys, CacheLookupPolicy, BrowserCacheLocation, DEFAULT_REQUEST, BrowserConstants } from '../utils/BrowserConstants.js';
7
+ import { BrowserUtils } from '../utils/BrowserUtils.js';
8
+ import { EventType } from '../event/EventType.js';
9
+ import { BrowserConfigurationAuthError } from '../error/BrowserConfigurationAuthError.js';
10
+ import { EventHandler } from '../event/EventHandler.js';
11
+ import { PopupClient } from '../interaction_client/PopupClient.js';
12
+ import { RedirectClient } from '../interaction_client/RedirectClient.js';
13
+ import { SilentIframeClient } from '../interaction_client/SilentIframeClient.js';
14
+ import { SilentRefreshClient } from '../interaction_client/SilentRefreshClient.js';
15
+ import { TokenCache } from '../cache/TokenCache.js';
16
+ import { NativeInteractionClient } from '../interaction_client/NativeInteractionClient.js';
17
+ import { NativeMessageHandler } from '../broker/nativeBroker/NativeMessageHandler.js';
18
+ import { NativeAuthError } from '../error/NativeAuthError.js';
19
+ import { SilentCacheClient } from '../interaction_client/SilentCacheClient.js';
20
+ import { SilentAuthCodeClient } from '../interaction_client/SilentAuthCodeClient.js';
21
+ import { BrowserAuthError } from '../error/BrowserAuthError.js';
22
+ import { BrowserPerformanceClient } from '../telemetry/BrowserPerformanceClient.js';
23
+ import { name, version } from '../packageMetadata.js';
24
+
25
+ /*
26
+ * Copyright (c) Microsoft Corporation. All rights reserved.
27
+ * Licensed under the MIT License.
28
+ */
29
+ class StandardController {
30
+ /**
31
+ * @constructor
32
+ * Constructor for the PublicClientApplication used to instantiate the PublicClientApplication object
33
+ *
34
+ * Important attributes in the Configuration object for auth are:
35
+ * - clientID: the application ID of your application. You can obtain one by registering your application with our Application registration portal : https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview
36
+ * - authority: the authority URL for your application.
37
+ * - redirect_uri: the uri of your application registered in the portal.
38
+ *
39
+ * In Azure AD, authority is a URL indicating the Azure active directory that MSAL uses to obtain tokens.
40
+ * It is of the form https://login.microsoftonline.com/{Enter_the_Tenant_Info_Here}
41
+ * If your application supports Accounts in one organizational directory, replace "Enter_the_Tenant_Info_Here" value with the Tenant Id or Tenant name (for example, contoso.microsoft.com).
42
+ * If your application supports Accounts in any organizational directory, replace "Enter_the_Tenant_Info_Here" value with organizations.
43
+ * If your application supports Accounts in any organizational directory and personal Microsoft accounts, replace "Enter_the_Tenant_Info_Here" value with common.
44
+ * To restrict support to Personal Microsoft accounts only, replace "Enter_the_Tenant_Info_Here" value with consumers.
45
+ *
46
+ * In Azure B2C, authority is of the form https://{instance}/tfp/{tenant}/{policyName}/
47
+ * Full B2C functionality will be available in this library in future versions.
48
+ *
49
+ * @param configuration Object for the MSAL PublicClientApplication instance
50
+ */
51
+ constructor(operatingContext) {
52
+ this.atsAsyncMeasurement = undefined;
53
+ this.operatingContext = operatingContext;
54
+ this.isBrowserEnvironment =
55
+ this.operatingContext.isBrowserEnvironment();
56
+ // Set the configuration.
57
+ this.config = operatingContext.getConfig();
58
+ this.initialized = false;
59
+ // Initialize logger
60
+ this.logger = this.operatingContext.getLogger();
61
+ // Initialize the network module class.
62
+ this.networkClient = this.config.system.networkClient;
63
+ // Initialize the navigation client class.
64
+ this.navigationClient = this.config.system.navigationClient;
65
+ // Initialize redirectResponse Map
66
+ this.redirectResponse = new Map();
67
+ // Initial hybrid spa map
68
+ this.hybridAuthCodeResponses = new Map();
69
+ // Initialize performance client
70
+ this.performanceClient = this.isBrowserEnvironment
71
+ ? new BrowserPerformanceClient(this.config.auth.clientId, this.config.auth.authority, this.logger, name, version, this.config.telemetry.application, this.config.system.cryptoOptions)
72
+ : new StubPerformanceClient(this.config.auth.clientId, this.config.auth.authority, this.logger, name, version, this.config.telemetry.application);
73
+ // Initialize the crypto class.
74
+ this.browserCrypto = this.isBrowserEnvironment
75
+ ? new CryptoOps(this.logger, this.performanceClient, this.config.system.cryptoOptions)
76
+ : DEFAULT_CRYPTO_IMPLEMENTATION;
77
+ this.eventHandler = new EventHandler(this.logger, this.browserCrypto);
78
+ // Initialize the browser storage class.
79
+ this.browserStorage = this.isBrowserEnvironment
80
+ ? new BrowserCacheManager(this.config.auth.clientId, this.config.cache, this.browserCrypto, this.logger)
81
+ : DEFAULT_BROWSER_CACHE_MANAGER(this.config.auth.clientId, this.logger);
82
+ // initialize in memory storage for native flows
83
+ const nativeCacheOptions = {
84
+ cacheLocation: BrowserCacheLocation.MemoryStorage,
85
+ temporaryCacheLocation: BrowserCacheLocation.MemoryStorage,
86
+ storeAuthStateInCookie: false,
87
+ secureCookies: false,
88
+ cacheMigrationEnabled: false,
89
+ };
90
+ this.nativeInternalStorage = new BrowserCacheManager(this.config.auth.clientId, nativeCacheOptions, this.browserCrypto, this.logger);
91
+ // Initialize the token cache
92
+ this.tokenCache = new TokenCache(this.config, this.browserStorage, this.logger, this.browserCrypto);
93
+ this.activeSilentTokenRequests = new Map();
94
+ // Register listener functions
95
+ this.trackPageVisibility = this.trackPageVisibility.bind(this);
96
+ // Register listener functions
97
+ this.trackPageVisibilityWithMeasurement =
98
+ this.trackPageVisibilityWithMeasurement.bind(this);
99
+ }
100
+ static async createController(operatingContext) {
101
+ const controller = new StandardController(operatingContext);
102
+ controller.initialize();
103
+ return controller;
104
+ }
105
+ trackPageVisibility() {
106
+ if (!this.atsAsyncMeasurement) {
107
+ return;
108
+ }
109
+ this.logger.info("Perf: Visibility change detected");
110
+ this.atsAsyncMeasurement.increment({
111
+ visibilityChangeCount: 1,
112
+ });
113
+ }
114
+ /**
115
+ * Initializer function to perform async startup tasks such as connecting to WAM extension
116
+ */
117
+ async initialize() {
118
+ this.logger.trace("initialize called");
119
+ if (this.initialized) {
120
+ this.logger.info("initialize has already been called, exiting early.");
121
+ return;
122
+ }
123
+ const allowNativeBroker = this.config.system.allowNativeBroker;
124
+ const initMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.InitializeClientApplication);
125
+ this.eventHandler.emitEvent(EventType.INITIALIZE_START);
126
+ if (allowNativeBroker) {
127
+ try {
128
+ this.nativeExtensionProvider =
129
+ await NativeMessageHandler.createProvider(this.logger, this.config.system.nativeBrokerHandshakeTimeout, this.performanceClient, this.browserCrypto);
130
+ }
131
+ catch (e) {
132
+ this.logger.verbose(e);
133
+ }
134
+ }
135
+ this.initialized = true;
136
+ this.eventHandler.emitEvent(EventType.INITIALIZE_END);
137
+ initMeasurement.endMeasurement({ allowNativeBroker, success: true });
138
+ }
139
+ // #region Redirect Flow
140
+ /**
141
+ * Event handler function which allows users to fire events after the PublicClientApplication object
142
+ * has loaded during redirect flows. This should be invoked on all page loads involved in redirect
143
+ * auth flows.
144
+ * @param hash Hash to process. Defaults to the current value of window.location.hash. Only needs to be provided explicitly if the response to be handled is not contained in the current value.
145
+ * @returns Token response or null. If the return value is null, then no auth redirect was detected.
146
+ */
147
+ async handleRedirectPromise(hash) {
148
+ this.logger.verbose("handleRedirectPromise called");
149
+ // Block token acquisition before initialize has been called if native brokering is enabled
150
+ BrowserUtils.blockNativeBrokerCalledBeforeInitialized(this.config.system.allowNativeBroker, this.initialized);
151
+ const loggedInAccounts = this.getAllAccounts();
152
+ if (this.isBrowserEnvironment) {
153
+ /**
154
+ * Store the promise on the PublicClientApplication instance if this is the first invocation of handleRedirectPromise,
155
+ * otherwise return the promise from the first invocation. Prevents race conditions when handleRedirectPromise is called
156
+ * several times concurrently.
157
+ */
158
+ const redirectResponseKey = hash || Constants.EMPTY_STRING;
159
+ let response = this.redirectResponse.get(redirectResponseKey);
160
+ if (typeof response === "undefined") {
161
+ this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_START, InteractionType.Redirect);
162
+ this.logger.verbose("handleRedirectPromise has been called for the first time, storing the promise");
163
+ const request = this.browserStorage.getCachedNativeRequest();
164
+ let redirectResponse;
165
+ if (request &&
166
+ NativeMessageHandler.isNativeAvailable(this.config, this.logger, this.nativeExtensionProvider) &&
167
+ this.nativeExtensionProvider &&
168
+ !hash) {
169
+ this.logger.trace("handleRedirectPromise - acquiring token from native platform");
170
+ const nativeClient = new NativeInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.handleRedirectPromise, this.performanceClient, this.nativeExtensionProvider, request.accountId, this.nativeInternalStorage, request.correlationId);
171
+ redirectResponse = nativeClient.handleRedirectPromise();
172
+ }
173
+ else {
174
+ this.logger.trace("handleRedirectPromise - acquiring token from web flow");
175
+ const correlationId = this.browserStorage.getTemporaryCache(TemporaryCacheKeys.CORRELATION_ID, true) || Constants.EMPTY_STRING;
176
+ const redirectClient = this.createRedirectClient(correlationId);
177
+ redirectResponse =
178
+ redirectClient.handleRedirectPromise(hash);
179
+ }
180
+ response = redirectResponse
181
+ .then((result) => {
182
+ if (result) {
183
+ // Emit login event if number of accounts change
184
+ const isLoggingIn = loggedInAccounts.length <
185
+ this.getAllAccounts().length;
186
+ if (isLoggingIn) {
187
+ this.eventHandler.emitEvent(EventType.LOGIN_SUCCESS, InteractionType.Redirect, result);
188
+ this.logger.verbose("handleRedirectResponse returned result, login success");
189
+ }
190
+ else {
191
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Redirect, result);
192
+ this.logger.verbose("handleRedirectResponse returned result, acquire token success");
193
+ }
194
+ }
195
+ this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_END, InteractionType.Redirect);
196
+ return result;
197
+ })
198
+ .catch((e) => {
199
+ // Emit login event if there is an account
200
+ if (loggedInAccounts.length > 0) {
201
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Redirect, null, e);
202
+ }
203
+ else {
204
+ this.eventHandler.emitEvent(EventType.LOGIN_FAILURE, InteractionType.Redirect, null, e);
205
+ }
206
+ this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_END, InteractionType.Redirect);
207
+ throw e;
208
+ });
209
+ this.redirectResponse.set(redirectResponseKey, response);
210
+ }
211
+ else {
212
+ this.logger.verbose("handleRedirectPromise has been called previously, returning the result from the first call");
213
+ }
214
+ return response;
215
+ }
216
+ this.logger.verbose("handleRedirectPromise returns null, not browser environment");
217
+ return null;
218
+ }
219
+ /**
220
+ * Use when you want to obtain an access_token for your API by redirecting the user's browser window to the authorization endpoint. This function redirects
221
+ * the page, so any code that follows this function will not execute.
222
+ *
223
+ * IMPORTANT: It is NOT recommended to have code that is dependent on the resolution of the Promise. This function will navigate away from the current
224
+ * browser window. It currently returns a Promise in order to reflect the asynchronous nature of the code running in this function.
225
+ *
226
+ * @param request
227
+ */
228
+ async acquireTokenRedirect(request) {
229
+ // Preflight request
230
+ const correlationId = this.getRequestCorrelationId(request);
231
+ this.logger.verbose("acquireTokenRedirect called", correlationId);
232
+ this.preflightBrowserEnvironmentCheck(InteractionType.Redirect);
233
+ // If logged in, emit acquire token events
234
+ const isLoggedIn = this.getAllAccounts().length > 0;
235
+ if (isLoggedIn) {
236
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Redirect, request);
237
+ }
238
+ else {
239
+ this.eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Redirect, request);
240
+ }
241
+ let result;
242
+ if (this.nativeExtensionProvider && this.canUseNative(request)) {
243
+ const nativeClient = new NativeInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenRedirect, this.performanceClient, this.nativeExtensionProvider, this.getNativeAccountId(request), this.nativeInternalStorage, request.correlationId);
244
+ result = nativeClient
245
+ .acquireTokenRedirect(request)
246
+ .catch((e) => {
247
+ if (e instanceof NativeAuthError && e.isFatal()) {
248
+ this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
249
+ const redirectClient = this.createRedirectClient(request.correlationId);
250
+ return redirectClient.acquireToken(request);
251
+ }
252
+ else if (e instanceof InteractionRequiredAuthError) {
253
+ this.logger.verbose("acquireTokenRedirect - Resolving interaction required error thrown by native broker by falling back to web flow");
254
+ const redirectClient = this.createRedirectClient(request.correlationId);
255
+ return redirectClient.acquireToken(request);
256
+ }
257
+ this.browserStorage.setInteractionInProgress(false);
258
+ throw e;
259
+ });
260
+ }
261
+ else {
262
+ const redirectClient = this.createRedirectClient(request.correlationId);
263
+ result = redirectClient.acquireToken(request);
264
+ }
265
+ return result.catch((e) => {
266
+ // If logged in, emit acquire token events
267
+ if (isLoggedIn) {
268
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Redirect, null, e);
269
+ }
270
+ else {
271
+ this.eventHandler.emitEvent(EventType.LOGIN_FAILURE, InteractionType.Redirect, null, e);
272
+ }
273
+ throw e;
274
+ });
275
+ }
276
+ // #endregion
277
+ // #region Popup Flow
278
+ /**
279
+ * Use when you want to obtain an access_token for your API via opening a popup window in the user's browser
280
+ *
281
+ * @param request
282
+ *
283
+ * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
284
+ */
285
+ acquireTokenPopup(request) {
286
+ const correlationId = this.getRequestCorrelationId(request);
287
+ const atPopupMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenPopup, correlationId);
288
+ try {
289
+ this.logger.verbose("acquireTokenPopup called", correlationId);
290
+ this.preflightBrowserEnvironmentCheck(InteractionType.Popup);
291
+ }
292
+ catch (e) {
293
+ // Since this function is syncronous we need to reject
294
+ return Promise.reject(e);
295
+ }
296
+ // If logged in, emit acquire token events
297
+ const loggedInAccounts = this.getAllAccounts();
298
+ if (loggedInAccounts.length > 0) {
299
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Popup, request);
300
+ }
301
+ else {
302
+ this.eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Popup, request);
303
+ }
304
+ let result;
305
+ if (this.canUseNative(request)) {
306
+ result = this.acquireTokenNative(request, ApiId.acquireTokenPopup)
307
+ .then((response) => {
308
+ this.browserStorage.setInteractionInProgress(false);
309
+ atPopupMeasurement.endMeasurement({
310
+ success: true,
311
+ isNativeBroker: true,
312
+ requestId: response.requestId,
313
+ });
314
+ return response;
315
+ })
316
+ .catch((e) => {
317
+ if (e instanceof NativeAuthError && e.isFatal()) {
318
+ this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
319
+ const popupClient = this.createPopupClient(request.correlationId);
320
+ return popupClient.acquireToken(request);
321
+ }
322
+ else if (e instanceof InteractionRequiredAuthError) {
323
+ this.logger.verbose("acquireTokenPopup - Resolving interaction required error thrown by native broker by falling back to web flow");
324
+ const popupClient = this.createPopupClient(request.correlationId);
325
+ return popupClient.acquireToken(request);
326
+ }
327
+ this.browserStorage.setInteractionInProgress(false);
328
+ throw e;
329
+ });
330
+ }
331
+ else {
332
+ const popupClient = this.createPopupClient(request.correlationId);
333
+ result = popupClient.acquireToken(request);
334
+ }
335
+ return result
336
+ .then((result) => {
337
+ /*
338
+ * If logged in, emit acquire token events
339
+ */
340
+ const isLoggingIn = loggedInAccounts.length < this.getAllAccounts().length;
341
+ if (isLoggingIn) {
342
+ this.eventHandler.emitEvent(EventType.LOGIN_SUCCESS, InteractionType.Popup, result);
343
+ }
344
+ else {
345
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Popup, result);
346
+ }
347
+ atPopupMeasurement.addStaticFields({
348
+ accessTokenSize: result.accessToken.length,
349
+ idTokenSize: result.idToken.length,
350
+ });
351
+ atPopupMeasurement.endMeasurement({
352
+ success: true,
353
+ requestId: result.requestId,
354
+ });
355
+ return result;
356
+ })
357
+ .catch((e) => {
358
+ if (loggedInAccounts.length > 0) {
359
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Popup, null, e);
360
+ }
361
+ else {
362
+ this.eventHandler.emitEvent(EventType.LOGIN_FAILURE, InteractionType.Popup, null, e);
363
+ }
364
+ atPopupMeasurement.endMeasurement({
365
+ errorCode: e.errorCode,
366
+ subErrorCode: e.subError,
367
+ success: false,
368
+ });
369
+ // Since this function is syncronous we need to reject
370
+ return Promise.reject(e);
371
+ });
372
+ }
373
+ trackPageVisibilityWithMeasurement() {
374
+ const measurement = this.ssoSilentMeasurement ||
375
+ this.acquireTokenByCodeAsyncMeasurement;
376
+ if (!measurement) {
377
+ return;
378
+ }
379
+ this.logger.info("Perf: Visibility change detected in ", measurement.event.name);
380
+ measurement.increment({
381
+ visibilityChangeCount: 1,
382
+ });
383
+ }
384
+ // #endregion
385
+ // #region Silent Flow
386
+ /**
387
+ * This function uses a hidden iframe to fetch an authorization code from the eSTS. There are cases where this may not work:
388
+ * - Any browser using a form of Intelligent Tracking Prevention
389
+ * - If there is not an established session with the service
390
+ *
391
+ * In these cases, the request must be done inside a popup or full frame redirect.
392
+ *
393
+ * For the cases where interaction is required, you cannot send a request with prompt=none.
394
+ *
395
+ * If your refresh token has expired, you can use this function to fetch a new set of tokens silently as long as
396
+ * you session on the server still exists.
397
+ * @param request {@link SsoSilentRequest}
398
+ *
399
+ * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
400
+ */
401
+ async ssoSilent(request) {
402
+ const correlationId = this.getRequestCorrelationId(request);
403
+ const validRequest = {
404
+ ...request,
405
+ // will be PromptValue.NONE or PromptValue.NO_SESSION
406
+ prompt: request.prompt,
407
+ correlationId: correlationId,
408
+ };
409
+ this.preflightBrowserEnvironmentCheck(InteractionType.Silent);
410
+ this.ssoSilentMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.SsoSilent, correlationId);
411
+ this.ssoSilentMeasurement?.increment({
412
+ visibilityChangeCount: 0,
413
+ });
414
+ document.addEventListener("visibilitychange", this.trackPageVisibilityWithMeasurement);
415
+ this.logger.verbose("ssoSilent called", correlationId);
416
+ this.eventHandler.emitEvent(EventType.SSO_SILENT_START, InteractionType.Silent, validRequest);
417
+ let result;
418
+ if (this.canUseNative(validRequest)) {
419
+ result = this.acquireTokenNative(validRequest, ApiId.ssoSilent).catch((e) => {
420
+ // If native token acquisition fails for availability reasons fallback to standard flow
421
+ if (e instanceof NativeAuthError && e.isFatal()) {
422
+ this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
423
+ const silentIframeClient = this.createSilentIframeClient(validRequest.correlationId);
424
+ return silentIframeClient.acquireToken(validRequest);
425
+ }
426
+ throw e;
427
+ });
428
+ }
429
+ else {
430
+ const silentIframeClient = this.createSilentIframeClient(validRequest.correlationId);
431
+ result = silentIframeClient.acquireToken(validRequest);
432
+ }
433
+ return result
434
+ .then((response) => {
435
+ this.eventHandler.emitEvent(EventType.SSO_SILENT_SUCCESS, InteractionType.Silent, response);
436
+ this.ssoSilentMeasurement?.addStaticFields({
437
+ accessTokenSize: response.accessToken.length,
438
+ idTokenSize: response.idToken.length,
439
+ });
440
+ this.ssoSilentMeasurement?.endMeasurement({
441
+ success: true,
442
+ isNativeBroker: response.fromNativeBroker,
443
+ requestId: response.requestId,
444
+ });
445
+ return response;
446
+ })
447
+ .catch((e) => {
448
+ this.eventHandler.emitEvent(EventType.SSO_SILENT_FAILURE, InteractionType.Silent, null, e);
449
+ this.ssoSilentMeasurement?.endMeasurement({
450
+ errorCode: e.errorCode,
451
+ subErrorCode: e.subError,
452
+ success: false,
453
+ });
454
+ throw e;
455
+ })
456
+ .finally(() => {
457
+ document.removeEventListener("visibilitychange", this.trackPageVisibilityWithMeasurement);
458
+ });
459
+ }
460
+ /**
461
+ * This function redeems an authorization code (passed as code) from the eSTS token endpoint.
462
+ * This authorization code should be acquired server-side using a confidential client to acquire a spa_code.
463
+ * This API is not indended for normal authorization code acquisition and redemption.
464
+ *
465
+ * Redemption of this authorization code will not require PKCE, as it was acquired by a confidential client.
466
+ *
467
+ * @param request {@link AuthorizationCodeRequest}
468
+ * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
469
+ */
470
+ async acquireTokenByCode(request) {
471
+ const correlationId = this.getRequestCorrelationId(request);
472
+ this.preflightBrowserEnvironmentCheck(InteractionType.Silent);
473
+ this.logger.trace("acquireTokenByCode called", correlationId);
474
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_BY_CODE_START, InteractionType.Silent, request);
475
+ const atbcMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenByCode, request.correlationId);
476
+ try {
477
+ if (request.code && request.nativeAccountId) {
478
+ // Throw error in case server returns both spa_code and spa_accountid in exchange for auth code.
479
+ throw BrowserAuthError.createSpaCodeAndNativeAccountIdPresentError();
480
+ }
481
+ else if (request.code) {
482
+ const hybridAuthCode = request.code;
483
+ let response = this.hybridAuthCodeResponses.get(hybridAuthCode);
484
+ if (!response) {
485
+ this.logger.verbose("Initiating new acquireTokenByCode request", correlationId);
486
+ response = this.acquireTokenByCodeAsync({
487
+ ...request,
488
+ correlationId,
489
+ })
490
+ .then((result) => {
491
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_BY_CODE_SUCCESS, InteractionType.Silent, result);
492
+ this.hybridAuthCodeResponses.delete(hybridAuthCode);
493
+ atbcMeasurement.addStaticFields({
494
+ accessTokenSize: result.accessToken.length,
495
+ idTokenSize: result.idToken.length,
496
+ });
497
+ atbcMeasurement.endMeasurement({
498
+ success: true,
499
+ isNativeBroker: result.fromNativeBroker,
500
+ requestId: result.requestId,
501
+ });
502
+ return result;
503
+ })
504
+ .catch((error) => {
505
+ this.hybridAuthCodeResponses.delete(hybridAuthCode);
506
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_BY_CODE_FAILURE, InteractionType.Silent, null, error);
507
+ atbcMeasurement.endMeasurement({
508
+ errorCode: error.errorCode,
509
+ subErrorCode: error.subError,
510
+ success: false,
511
+ });
512
+ throw error;
513
+ });
514
+ this.hybridAuthCodeResponses.set(hybridAuthCode, response);
515
+ }
516
+ else {
517
+ this.logger.verbose("Existing acquireTokenByCode request found", request.correlationId);
518
+ atbcMeasurement.discardMeasurement();
519
+ }
520
+ return response;
521
+ }
522
+ else if (request.nativeAccountId) {
523
+ if (this.canUseNative(request, request.nativeAccountId)) {
524
+ return this.acquireTokenNative(request, ApiId.acquireTokenByCode, request.nativeAccountId).catch((e) => {
525
+ // If native token acquisition fails for availability reasons fallback to standard flow
526
+ if (e instanceof NativeAuthError && e.isFatal()) {
527
+ this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
528
+ }
529
+ throw e;
530
+ });
531
+ }
532
+ else {
533
+ throw BrowserAuthError.createUnableToAcquireTokenFromNativePlatformError();
534
+ }
535
+ }
536
+ else {
537
+ throw BrowserAuthError.createAuthCodeOrNativeAccountIdRequiredError();
538
+ }
539
+ }
540
+ catch (e) {
541
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_BY_CODE_FAILURE, InteractionType.Silent, null, e);
542
+ atbcMeasurement.endMeasurement({
543
+ errorCode: (e instanceof AuthError && e.errorCode) || undefined,
544
+ subErrorCode: (e instanceof AuthError && e.subError) || undefined,
545
+ success: false,
546
+ });
547
+ throw e;
548
+ }
549
+ }
550
+ /**
551
+ * Creates a SilentAuthCodeClient to redeem an authorization code.
552
+ * @param request
553
+ * @returns Result of the operation to redeem the authorization code
554
+ */
555
+ async acquireTokenByCodeAsync(request) {
556
+ this.logger.trace("acquireTokenByCodeAsync called", request.correlationId);
557
+ this.acquireTokenByCodeAsyncMeasurement =
558
+ this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenByCodeAsync, request.correlationId);
559
+ this.acquireTokenByCodeAsyncMeasurement?.increment({
560
+ visibilityChangeCount: 0,
561
+ });
562
+ document.addEventListener("visibilitychange", this.trackPageVisibilityWithMeasurement);
563
+ const silentAuthCodeClient = this.createSilentAuthCodeClient(request.correlationId);
564
+ const silentTokenResult = await silentAuthCodeClient
565
+ .acquireToken(request)
566
+ .then((response) => {
567
+ this.acquireTokenByCodeAsyncMeasurement?.endMeasurement({
568
+ success: true,
569
+ fromCache: response.fromCache,
570
+ isNativeBroker: response.fromNativeBroker,
571
+ requestId: response.requestId,
572
+ });
573
+ return response;
574
+ })
575
+ .catch((tokenRenewalError) => {
576
+ this.acquireTokenByCodeAsyncMeasurement?.endMeasurement({
577
+ errorCode: tokenRenewalError.errorCode,
578
+ subErrorCode: tokenRenewalError.subError,
579
+ success: false,
580
+ });
581
+ throw tokenRenewalError;
582
+ })
583
+ .finally(() => {
584
+ document.removeEventListener("visibilitychange", this.trackPageVisibilityWithMeasurement);
585
+ });
586
+ return silentTokenResult;
587
+ }
588
+ /**
589
+ * Attempt to acquire an access token from the cache
590
+ * @param silentCacheClient SilentCacheClient
591
+ * @param commonRequest CommonSilentFlowRequest
592
+ * @param silentRequest SilentRequest
593
+ * @returns A promise that, when resolved, returns the access token
594
+ */
595
+ async acquireTokenFromCache(silentCacheClient, commonRequest, silentRequest) {
596
+ this.performanceClient.addQueueMeasurement(PerformanceEvents.AcquireTokenFromCache, commonRequest.correlationId);
597
+ switch (silentRequest.cacheLookupPolicy) {
598
+ case CacheLookupPolicy.Default:
599
+ case CacheLookupPolicy.AccessToken:
600
+ case CacheLookupPolicy.AccessTokenAndRefreshToken:
601
+ return silentCacheClient.acquireToken(commonRequest);
602
+ default:
603
+ throw ClientAuthError.createRefreshRequiredError();
604
+ }
605
+ }
606
+ /**
607
+ * Attempt to acquire an access token via a refresh token
608
+ * @param commonRequest CommonSilentFlowRequest
609
+ * @param silentRequest SilentRequest
610
+ * @returns A promise that, when resolved, returns the access token
611
+ */
612
+ async acquireTokenByRefreshToken(commonRequest, silentRequest) {
613
+ this.performanceClient.addQueueMeasurement(PerformanceEvents.AcquireTokenByRefreshToken, commonRequest.correlationId);
614
+ switch (silentRequest.cacheLookupPolicy) {
615
+ case CacheLookupPolicy.Default:
616
+ case CacheLookupPolicy.AccessTokenAndRefreshToken:
617
+ case CacheLookupPolicy.RefreshToken:
618
+ case CacheLookupPolicy.RefreshTokenAndNetwork:
619
+ const silentRefreshClient = this.createSilentRefreshClient(commonRequest.correlationId);
620
+ this.performanceClient.setPreQueueTime(PerformanceEvents.SilentRefreshClientAcquireToken, commonRequest.correlationId);
621
+ return silentRefreshClient.acquireToken(commonRequest);
622
+ default:
623
+ throw ClientAuthError.createRefreshRequiredError();
624
+ }
625
+ }
626
+ /**
627
+ * Attempt to acquire an access token via an iframe
628
+ * @param request CommonSilentFlowRequest
629
+ * @returns A promise that, when resolved, returns the access token
630
+ */
631
+ async acquireTokenBySilentIframe(request) {
632
+ this.performanceClient.addQueueMeasurement(PerformanceEvents.AcquireTokenBySilentIframe, request.correlationId);
633
+ const silentIframeClient = this.createSilentIframeClient(request.correlationId);
634
+ this.performanceClient.setPreQueueTime(PerformanceEvents.SilentIframeClientAcquireToken, request.correlationId);
635
+ return silentIframeClient.acquireToken(request);
636
+ }
637
+ // #endregion
638
+ // #region Logout
639
+ /**
640
+ * Deprecated logout function. Use logoutRedirect or logoutPopup instead
641
+ * @param logoutRequest
642
+ * @deprecated
643
+ */
644
+ async logout(logoutRequest) {
645
+ const correlationId = this.getRequestCorrelationId(logoutRequest);
646
+ this.logger.warning("logout API is deprecated and will be removed in msal-browser v3.0.0. Use logoutRedirect instead.", correlationId);
647
+ return this.logoutRedirect({
648
+ correlationId,
649
+ ...logoutRequest,
650
+ });
651
+ }
652
+ /**
653
+ * Use to log out the current user, and redirect the user to the postLogoutRedirectUri.
654
+ * Default behaviour is to redirect the user to `window.location.href`.
655
+ * @param logoutRequest
656
+ */
657
+ async logoutRedirect(logoutRequest) {
658
+ const correlationId = this.getRequestCorrelationId(logoutRequest);
659
+ this.preflightBrowserEnvironmentCheck(InteractionType.Redirect);
660
+ const redirectClient = this.createRedirectClient(correlationId);
661
+ return redirectClient.logout(logoutRequest);
662
+ }
663
+ /**
664
+ * Clears local cache for the current user then opens a popup window prompting the user to sign-out of the server
665
+ * @param logoutRequest
666
+ */
667
+ logoutPopup(logoutRequest) {
668
+ try {
669
+ const correlationId = this.getRequestCorrelationId(logoutRequest);
670
+ this.preflightBrowserEnvironmentCheck(InteractionType.Popup);
671
+ const popupClient = this.createPopupClient(correlationId);
672
+ return popupClient.logout(logoutRequest);
673
+ }
674
+ catch (e) {
675
+ // Since this function is syncronous we need to reject
676
+ return Promise.reject(e);
677
+ }
678
+ }
679
+ // #endregion
680
+ // #region Account APIs
681
+ /**
682
+ * Returns all accounts that MSAL currently has data for.
683
+ * (the account object is created at the time of successful login)
684
+ * or empty array when no accounts are found
685
+ * @returns Array of account objects in cache
686
+ */
687
+ getAllAccounts() {
688
+ this.logger.verbose("getAllAccounts called");
689
+ return this.isBrowserEnvironment
690
+ ? this.browserStorage.getAllAccounts()
691
+ : [];
692
+ }
693
+ /**
694
+ * Returns the signed in account matching username.
695
+ * (the account object is created at the time of successful login)
696
+ * or null when no matching account is found.
697
+ * This API is provided for convenience but getAccountById should be used for best reliability
698
+ * @param username
699
+ * @returns The account object stored in MSAL
700
+ */
701
+ getAccountByUsername(username) {
702
+ this.logger.trace("getAccountByUsername called");
703
+ if (!username) {
704
+ this.logger.warning("getAccountByUsername: No username provided");
705
+ return null;
706
+ }
707
+ const account = this.browserStorage.getAccountInfoFilteredBy({
708
+ username,
709
+ });
710
+ if (account) {
711
+ this.logger.verbose("getAccountByUsername: Account matching username found, returning");
712
+ this.logger.verbosePii(`getAccountByUsername: Returning signed-in accounts matching username: ${username}`);
713
+ return account;
714
+ }
715
+ else {
716
+ this.logger.verbose("getAccountByUsername: No matching account found, returning null");
717
+ return null;
718
+ }
719
+ }
720
+ /**
721
+ * Returns the signed in account matching homeAccountId.
722
+ * (the account object is created at the time of successful login)
723
+ * or null when no matching account is found
724
+ * @param homeAccountId
725
+ * @returns The account object stored in MSAL
726
+ */
727
+ getAccountByHomeId(homeAccountId) {
728
+ this.logger.trace("getAccountByHomeId called");
729
+ if (!homeAccountId) {
730
+ this.logger.warning("getAccountByHomeId: No homeAccountId provided");
731
+ return null;
732
+ }
733
+ const account = this.browserStorage.getAccountInfoFilteredBy({
734
+ homeAccountId,
735
+ });
736
+ if (account) {
737
+ this.logger.verbose("getAccountByHomeId: Account matching homeAccountId found, returning");
738
+ this.logger.verbosePii(`getAccountByHomeId: Returning signed-in accounts matching homeAccountId: ${homeAccountId}`);
739
+ return account;
740
+ }
741
+ else {
742
+ this.logger.verbose("getAccountByHomeId: No matching account found, returning null");
743
+ return null;
744
+ }
745
+ }
746
+ /**
747
+ * Returns the signed in account matching localAccountId.
748
+ * (the account object is created at the time of successful login)
749
+ * or null when no matching account is found
750
+ * @param localAccountId
751
+ * @returns The account object stored in MSAL
752
+ */
753
+ getAccountByLocalId(localAccountId) {
754
+ this.logger.trace("getAccountByLocalId called");
755
+ if (!localAccountId) {
756
+ this.logger.warning("getAccountByLocalId: No localAccountId provided");
757
+ return null;
758
+ }
759
+ const account = this.browserStorage.getAccountInfoFilteredBy({
760
+ localAccountId,
761
+ });
762
+ if (account) {
763
+ this.logger.verbose("getAccountByLocalId: Account matching localAccountId found, returning");
764
+ this.logger.verbosePii(`getAccountByLocalId: Returning signed-in accounts matching localAccountId: ${localAccountId}`);
765
+ return account;
766
+ }
767
+ else {
768
+ this.logger.verbose("getAccountByLocalId: No matching account found, returning null");
769
+ return null;
770
+ }
771
+ }
772
+ /**
773
+ * Sets the account to use as the active account. If no account is passed to the acquireToken APIs, then MSAL will use this active account.
774
+ * @param account
775
+ */
776
+ setActiveAccount(account) {
777
+ this.browserStorage.setActiveAccount(account);
778
+ }
779
+ /**
780
+ * Gets the currently active account
781
+ */
782
+ getActiveAccount() {
783
+ return this.browserStorage.getActiveAccount();
784
+ }
785
+ // #endregion
786
+ // #region Helpers
787
+ /**
788
+ * Helper to validate app environment before making an auth request
789
+ *
790
+ * @protected
791
+ * @param {InteractionType} interactionType What kind of interaction is being used
792
+ * @param {boolean} [setInteractionInProgress=true] Whether to set interaction in progress temp cache flag
793
+ */
794
+ preflightBrowserEnvironmentCheck(interactionType, setInteractionInProgress = true) {
795
+ this.logger.verbose("preflightBrowserEnvironmentCheck started");
796
+ // Block request if not in browser environment
797
+ BrowserUtils.blockNonBrowserEnvironment(this.isBrowserEnvironment);
798
+ // Block redirects if in an iframe
799
+ BrowserUtils.blockRedirectInIframe(interactionType, this.config.system.allowRedirectInIframe);
800
+ // Block auth requests inside a hidden iframe
801
+ BrowserUtils.blockReloadInHiddenIframes();
802
+ // Block redirectUri opened in a popup from calling MSAL APIs
803
+ BrowserUtils.blockAcquireTokenInPopups();
804
+ // Block token acquisition before initialize has been called if native brokering is enabled
805
+ BrowserUtils.blockNativeBrokerCalledBeforeInitialized(this.config.system.allowNativeBroker, this.initialized);
806
+ // Block redirects if memory storage is enabled but storeAuthStateInCookie is not
807
+ if (interactionType === InteractionType.Redirect &&
808
+ this.config.cache.cacheLocation ===
809
+ BrowserCacheLocation.MemoryStorage &&
810
+ !this.config.cache.storeAuthStateInCookie) {
811
+ throw BrowserConfigurationAuthError.createInMemoryRedirectUnavailableError();
812
+ }
813
+ if (interactionType === InteractionType.Redirect ||
814
+ interactionType === InteractionType.Popup) {
815
+ this.preflightInteractiveRequest(setInteractionInProgress);
816
+ }
817
+ }
818
+ /**
819
+ * Preflight check for interactive requests
820
+ *
821
+ * @protected
822
+ * @param {boolean} setInteractionInProgress Whether to set interaction in progress temp cache flag
823
+ */
824
+ preflightInteractiveRequest(setInteractionInProgress) {
825
+ this.logger.verbose("preflightInteractiveRequest called, validating app environment");
826
+ // block the reload if it occurred inside a hidden iframe
827
+ BrowserUtils.blockReloadInHiddenIframes();
828
+ // Set interaction in progress temporary cache or throw if alread set.
829
+ if (setInteractionInProgress) {
830
+ this.browserStorage.setInteractionInProgress(true);
831
+ }
832
+ }
833
+ /**
834
+ * Acquire a token from native device (e.g. WAM)
835
+ * @param request
836
+ */
837
+ async acquireTokenNative(request, apiId, accountId) {
838
+ this.logger.trace("acquireTokenNative called");
839
+ if (!this.nativeExtensionProvider) {
840
+ throw BrowserAuthError.createNativeConnectionNotEstablishedError();
841
+ }
842
+ const nativeClient = new NativeInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, apiId, this.performanceClient, this.nativeExtensionProvider, accountId || this.getNativeAccountId(request), this.nativeInternalStorage, request.correlationId);
843
+ return nativeClient.acquireToken(request);
844
+ }
845
+ /**
846
+ * Returns boolean indicating if this request can use the native broker
847
+ * @param request
848
+ */
849
+ canUseNative(request, accountId) {
850
+ this.logger.trace("canUseNative called");
851
+ if (!NativeMessageHandler.isNativeAvailable(this.config, this.logger, this.nativeExtensionProvider, request.authenticationScheme)) {
852
+ this.logger.trace("canUseNative: isNativeAvailable returned false, returning false");
853
+ return false;
854
+ }
855
+ if (request.prompt) {
856
+ switch (request.prompt) {
857
+ case PromptValue.NONE:
858
+ case PromptValue.CONSENT:
859
+ case PromptValue.LOGIN:
860
+ this.logger.trace("canUseNative: prompt is compatible with native flow");
861
+ break;
862
+ default:
863
+ this.logger.trace(`canUseNative: prompt = ${request.prompt} is not compatible with native flow, returning false`);
864
+ return false;
865
+ }
866
+ }
867
+ if (!accountId && !this.getNativeAccountId(request)) {
868
+ this.logger.trace("canUseNative: nativeAccountId is not available, returning false");
869
+ return false;
870
+ }
871
+ return true;
872
+ }
873
+ /**
874
+ * Get the native accountId from the account
875
+ * @param request
876
+ * @returns
877
+ */
878
+ getNativeAccountId(request) {
879
+ const account = request.account ||
880
+ this.browserStorage.getAccountInfoByHints(request.loginHint, request.sid) ||
881
+ this.getActiveAccount();
882
+ return (account && account.nativeAccountId) || "";
883
+ }
884
+ /**
885
+ * Returns new instance of the Popup Interaction Client
886
+ * @param correlationId
887
+ */
888
+ createPopupClient(correlationId) {
889
+ return new PopupClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.nativeExtensionProvider, correlationId);
890
+ }
891
+ /**
892
+ * Returns new instance of the Redirect Interaction Client
893
+ * @param correlationId
894
+ */
895
+ createRedirectClient(correlationId) {
896
+ return new RedirectClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.nativeExtensionProvider, correlationId);
897
+ }
898
+ /**
899
+ * Returns new instance of the Silent Iframe Interaction Client
900
+ * @param correlationId
901
+ */
902
+ createSilentIframeClient(correlationId) {
903
+ return new SilentIframeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.ssoSilent, this.performanceClient, this.nativeInternalStorage, this.nativeExtensionProvider, correlationId);
904
+ }
905
+ /**
906
+ * Returns new instance of the Silent Cache Interaction Client
907
+ */
908
+ createSilentCacheClient(correlationId) {
909
+ return new SilentCacheClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeExtensionProvider, correlationId);
910
+ }
911
+ /**
912
+ * Returns new instance of the Silent Refresh Interaction Client
913
+ */
914
+ createSilentRefreshClient(correlationId) {
915
+ return new SilentRefreshClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeExtensionProvider, correlationId);
916
+ }
917
+ /**
918
+ * Returns new instance of the Silent AuthCode Interaction Client
919
+ */
920
+ createSilentAuthCodeClient(correlationId) {
921
+ return new SilentAuthCodeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenByCode, this.performanceClient, this.nativeExtensionProvider, correlationId);
922
+ }
923
+ /**
924
+ * Adds event callbacks to array
925
+ * @param callback
926
+ */
927
+ addEventCallback(callback) {
928
+ return this.eventHandler.addEventCallback(callback);
929
+ }
930
+ /**
931
+ * Removes callback with provided id from callback array
932
+ * @param callbackId
933
+ */
934
+ removeEventCallback(callbackId) {
935
+ this.eventHandler.removeEventCallback(callbackId);
936
+ }
937
+ /**
938
+ * Registers a callback to receive performance events.
939
+ *
940
+ * @param {PerformanceCallbackFunction} callback
941
+ * @returns {string}
942
+ */
943
+ addPerformanceCallback(callback) {
944
+ return this.performanceClient.addPerformanceCallback(callback);
945
+ }
946
+ /**
947
+ * Removes a callback registered with addPerformanceCallback.
948
+ *
949
+ * @param {string} callbackId
950
+ * @returns {boolean}
951
+ */
952
+ removePerformanceCallback(callbackId) {
953
+ return this.performanceClient.removePerformanceCallback(callbackId);
954
+ }
955
+ /**
956
+ * Adds event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
957
+ */
958
+ enableAccountStorageEvents() {
959
+ this.eventHandler.enableAccountStorageEvents();
960
+ }
961
+ /**
962
+ * Removes event listener that emits an event when a user account is added or removed from localstorage in a different browser tab or window
963
+ */
964
+ disableAccountStorageEvents() {
965
+ this.eventHandler.disableAccountStorageEvents();
966
+ }
967
+ /**
968
+ * Gets the token cache for the application.
969
+ */
970
+ getTokenCache() {
971
+ return this.tokenCache;
972
+ }
973
+ /**
974
+ * Returns the logger instance
975
+ */
976
+ getLogger() {
977
+ return this.logger;
978
+ }
979
+ /**
980
+ * Replaces the default logger set in configurations with new Logger with new configurations
981
+ * @param logger Logger instance
982
+ */
983
+ setLogger(logger) {
984
+ this.logger = logger;
985
+ }
986
+ /**
987
+ * Called by wrapper libraries (Angular & React) to set SKU and Version passed down to telemetry, logger, etc.
988
+ * @param sku
989
+ * @param version
990
+ */
991
+ initializeWrapperLibrary(sku, version) {
992
+ // Validate the SKU passed in is one we expect
993
+ this.browserStorage.setWrapperMetadata(sku, version);
994
+ }
995
+ /**
996
+ * Sets navigation client
997
+ * @param navigationClient
998
+ */
999
+ setNavigationClient(navigationClient) {
1000
+ this.navigationClient = navigationClient;
1001
+ }
1002
+ /**
1003
+ * Returns the configuration object
1004
+ */
1005
+ getConfiguration() {
1006
+ return this.config;
1007
+ }
1008
+ /**
1009
+ * Returns the performance client
1010
+ */
1011
+ getPerformanceClient() {
1012
+ return this.performanceClient;
1013
+ }
1014
+ /**
1015
+ * Returns the browser storage
1016
+ */
1017
+ getBrowserStorage() {
1018
+ return this.browserStorage;
1019
+ }
1020
+ /**
1021
+ * Returns the native internal storage
1022
+ */
1023
+ getNativeInternalStorage() {
1024
+ return this.nativeInternalStorage;
1025
+ }
1026
+ /**
1027
+ * Returns the instance of interface for crypto functions
1028
+ */
1029
+ getBrowserCrypto() {
1030
+ return this.browserCrypto;
1031
+ }
1032
+ /**
1033
+ * Returns the browser env indicator
1034
+ */
1035
+ isBrowserEnv() {
1036
+ return this.isBrowserEnvironment;
1037
+ }
1038
+ /**
1039
+ * Returns the native message handler
1040
+ */
1041
+ getNativeExtensionProvider() {
1042
+ return this.nativeExtensionProvider;
1043
+ }
1044
+ /**
1045
+ * Sets the native message handler
1046
+ * @param provider {?NativeMessageHandler}
1047
+ */
1048
+ setNativeExtensionProvider(provider) {
1049
+ this.nativeExtensionProvider = provider;
1050
+ }
1051
+ /**
1052
+ * Returns the event handler
1053
+ */
1054
+ getEventHandler() {
1055
+ return this.eventHandler;
1056
+ }
1057
+ /**
1058
+ * Returns the navigation client
1059
+ */
1060
+ getNavigationClient() {
1061
+ return this.navigationClient;
1062
+ }
1063
+ /**
1064
+ * Returns the redirect response map
1065
+ */
1066
+ getRedirectResponse() {
1067
+ return this.redirectResponse;
1068
+ }
1069
+ /**
1070
+ * Generates a correlation id for a request if none is provided.
1071
+ *
1072
+ * @protected
1073
+ * @param {?Partial<BaseAuthRequest>} [request]
1074
+ * @returns {string}
1075
+ */
1076
+ getRequestCorrelationId(request) {
1077
+ if (request?.correlationId) {
1078
+ return request.correlationId;
1079
+ }
1080
+ if (this.isBrowserEnvironment) {
1081
+ return this.browserCrypto.createNewGuid();
1082
+ }
1083
+ /*
1084
+ * Included for fallback for non-browser environments,
1085
+ * and to ensure this method always returns a string.
1086
+ */
1087
+ return Constants.EMPTY_STRING;
1088
+ }
1089
+ // #endregion
1090
+ /**
1091
+ * Use when initiating the login process by redirecting the user's browser to the authorization endpoint. This function redirects the page, so
1092
+ * any code that follows this function will not execute.
1093
+ *
1094
+ * IMPORTANT: It is NOT recommended to have code that is dependent on the resolution of the Promise. This function will navigate away from the current
1095
+ * browser window. It currently returns a Promise in order to reflect the asynchronous nature of the code running in this function.
1096
+ *
1097
+ * @param request
1098
+ */
1099
+ async loginRedirect(request) {
1100
+ const correlationId = this.getRequestCorrelationId(request);
1101
+ this.logger.verbose("loginRedirect called", correlationId);
1102
+ return this.acquireTokenRedirect({
1103
+ correlationId,
1104
+ ...(request || DEFAULT_REQUEST),
1105
+ });
1106
+ }
1107
+ /**
1108
+ * Use when initiating the login process via opening a popup window in the user's browser
1109
+ *
1110
+ * @param request
1111
+ *
1112
+ * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
1113
+ */
1114
+ loginPopup(request) {
1115
+ const correlationId = this.getRequestCorrelationId(request);
1116
+ this.logger.verbose("loginPopup called", correlationId);
1117
+ return this.acquireTokenPopup({
1118
+ correlationId,
1119
+ ...(request || DEFAULT_REQUEST),
1120
+ });
1121
+ }
1122
+ /**
1123
+ * Silently acquire an access token for a given set of scopes. Returns currently processing promise if parallel requests are made.
1124
+ *
1125
+ * @param {@link (SilentRequest:type)}
1126
+ * @returns {Promise.<AuthenticationResult>} - a promise that is fulfilled when this function has completed, or rejected if an error was raised. Returns the {@link AuthResponse} object
1127
+ */
1128
+ async acquireTokenSilent(request) {
1129
+ const correlationId = this.getRequestCorrelationId(request);
1130
+ const atsMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenSilent, correlationId);
1131
+ atsMeasurement.addStaticFields({
1132
+ cacheLookupPolicy: request.cacheLookupPolicy,
1133
+ });
1134
+ this.preflightBrowserEnvironmentCheck(InteractionType.Silent);
1135
+ this.logger.verbose("acquireTokenSilent called", correlationId);
1136
+ const account = request.account || this.getActiveAccount();
1137
+ if (!account) {
1138
+ throw BrowserAuthError.createNoAccountError();
1139
+ }
1140
+ const thumbprint = {
1141
+ clientId: this.config.auth.clientId,
1142
+ authority: request.authority || Constants.EMPTY_STRING,
1143
+ scopes: request.scopes,
1144
+ homeAccountIdentifier: account.homeAccountId,
1145
+ claims: request.claims,
1146
+ authenticationScheme: request.authenticationScheme,
1147
+ resourceRequestMethod: request.resourceRequestMethod,
1148
+ resourceRequestUri: request.resourceRequestUri,
1149
+ shrClaims: request.shrClaims,
1150
+ sshKid: request.sshKid,
1151
+ };
1152
+ const silentRequestKey = JSON.stringify(thumbprint);
1153
+ const cachedResponse = this.activeSilentTokenRequests.get(silentRequestKey);
1154
+ if (typeof cachedResponse === "undefined") {
1155
+ this.logger.verbose("acquireTokenSilent called for the first time, storing active request", correlationId);
1156
+ this.performanceClient.setPreQueueTime(PerformanceEvents.AcquireTokenSilentAsync, correlationId);
1157
+ const response = this.acquireTokenSilentAsync({
1158
+ ...request,
1159
+ correlationId,
1160
+ }, account)
1161
+ .then((result) => {
1162
+ this.activeSilentTokenRequests.delete(silentRequestKey);
1163
+ atsMeasurement.addStaticFields({
1164
+ accessTokenSize: result.accessToken.length,
1165
+ idTokenSize: result.idToken.length,
1166
+ });
1167
+ atsMeasurement.endMeasurement({
1168
+ success: true,
1169
+ fromCache: result.fromCache,
1170
+ isNativeBroker: result.fromNativeBroker,
1171
+ cacheLookupPolicy: request.cacheLookupPolicy,
1172
+ requestId: result.requestId,
1173
+ });
1174
+ return result;
1175
+ })
1176
+ .catch((error) => {
1177
+ this.activeSilentTokenRequests.delete(silentRequestKey);
1178
+ atsMeasurement.endMeasurement({
1179
+ errorCode: error.errorCode,
1180
+ subErrorCode: error.subError,
1181
+ success: false,
1182
+ });
1183
+ throw error;
1184
+ });
1185
+ this.activeSilentTokenRequests.set(silentRequestKey, response);
1186
+ return response;
1187
+ }
1188
+ else {
1189
+ this.logger.verbose("acquireTokenSilent has been called previously, returning the result from the first call", correlationId);
1190
+ // Discard measurements for memoized calls, as they are usually only a couple of ms and will artificially deflate metrics
1191
+ atsMeasurement.discardMeasurement();
1192
+ return cachedResponse;
1193
+ }
1194
+ }
1195
+ /**
1196
+ * Silently acquire an access token for a given set of scopes. Will use cached token if available, otherwise will attempt to acquire a new token from the network via refresh token.
1197
+ * @param {@link (SilentRequest:type)}
1198
+ * @param {@link (AccountInfo:type)}
1199
+ * @returns {Promise.<AuthenticationResult>} - a promise that is fulfilled when this function has completed, or rejected if an error was raised. Returns the {@link AuthResponse}
1200
+ */
1201
+ async acquireTokenSilentAsync(request, account) {
1202
+ this.performanceClient.addQueueMeasurement(PerformanceEvents.AcquireTokenSilentAsync, request.correlationId);
1203
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Silent, request);
1204
+ this.atsAsyncMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenSilentAsync, request.correlationId);
1205
+ this.atsAsyncMeasurement?.increment({
1206
+ visibilityChangeCount: 0,
1207
+ });
1208
+ document.addEventListener("visibilitychange", this.trackPageVisibility);
1209
+ let result;
1210
+ if (NativeMessageHandler.isNativeAvailable(this.config, this.logger, this.nativeExtensionProvider, request.authenticationScheme) &&
1211
+ account.nativeAccountId) {
1212
+ this.logger.verbose("acquireTokenSilent - attempting to acquire token from native platform");
1213
+ const silentRequest = {
1214
+ ...request,
1215
+ account,
1216
+ };
1217
+ result = this.acquireTokenNative(silentRequest, ApiId.acquireTokenSilent_silentFlow).catch(async (e) => {
1218
+ // If native token acquisition fails for availability reasons fallback to web flow
1219
+ if (e instanceof NativeAuthError && e.isFatal()) {
1220
+ this.logger.verbose("acquireTokenSilent - native platform unavailable, falling back to web flow");
1221
+ this.nativeExtensionProvider = undefined; // Prevent future requests from continuing to attempt
1222
+ // Cache will not contain tokens, given that previous WAM requests succeeded. Skip cache and RT renewal and go straight to iframe renewal
1223
+ const silentIframeClient = this.createSilentIframeClient(request.correlationId);
1224
+ return silentIframeClient.acquireToken(request);
1225
+ }
1226
+ throw e;
1227
+ });
1228
+ }
1229
+ else {
1230
+ this.logger.verbose("acquireTokenSilent - attempting to acquire token from web flow");
1231
+ const silentCacheClient = this.createSilentCacheClient(request.correlationId);
1232
+ this.performanceClient.setPreQueueTime(PerformanceEvents.InitializeSilentRequest, request.correlationId);
1233
+ const silentRequest = await silentCacheClient.initializeSilentRequest(request, account);
1234
+ const requestWithCLP = {
1235
+ ...request,
1236
+ // set the request's CacheLookupPolicy to Default if it was not optionally passed in
1237
+ cacheLookupPolicy: request.cacheLookupPolicy || CacheLookupPolicy.Default,
1238
+ };
1239
+ this.performanceClient.setPreQueueTime(PerformanceEvents.AcquireTokenFromCache, silentRequest.correlationId);
1240
+ result = this.acquireTokenFromCache(silentCacheClient, silentRequest, requestWithCLP).catch((cacheError) => {
1241
+ if (requestWithCLP.cacheLookupPolicy ===
1242
+ CacheLookupPolicy.AccessToken) {
1243
+ throw cacheError;
1244
+ }
1245
+ // block the reload if it occurred inside a hidden iframe
1246
+ BrowserUtils.blockReloadInHiddenIframes();
1247
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_NETWORK_START, InteractionType.Silent, silentRequest);
1248
+ this.performanceClient.setPreQueueTime(PerformanceEvents.AcquireTokenByRefreshToken, silentRequest.correlationId);
1249
+ return this.acquireTokenByRefreshToken(silentRequest, requestWithCLP).catch((refreshTokenError) => {
1250
+ const isServerError = refreshTokenError instanceof ServerError;
1251
+ const isInteractionRequiredError = refreshTokenError instanceof
1252
+ InteractionRequiredAuthError;
1253
+ const isInvalidGrantError = refreshTokenError.errorCode ===
1254
+ BrowserConstants.INVALID_GRANT_ERROR;
1255
+ if ((!isServerError ||
1256
+ !isInvalidGrantError ||
1257
+ isInteractionRequiredError ||
1258
+ requestWithCLP.cacheLookupPolicy ===
1259
+ CacheLookupPolicy.AccessTokenAndRefreshToken ||
1260
+ requestWithCLP.cacheLookupPolicy ===
1261
+ CacheLookupPolicy.RefreshToken) &&
1262
+ requestWithCLP.cacheLookupPolicy !==
1263
+ CacheLookupPolicy.Skip) {
1264
+ throw refreshTokenError;
1265
+ }
1266
+ this.logger.verbose("Refresh token expired/invalid or CacheLookupPolicy is set to Skip, attempting acquire token by iframe.", request.correlationId);
1267
+ this.performanceClient.setPreQueueTime(PerformanceEvents.AcquireTokenBySilentIframe, silentRequest.correlationId);
1268
+ return this.acquireTokenBySilentIframe(silentRequest);
1269
+ });
1270
+ });
1271
+ }
1272
+ return result
1273
+ .then((response) => {
1274
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, response);
1275
+ this.atsAsyncMeasurement?.endMeasurement({
1276
+ success: true,
1277
+ fromCache: response.fromCache,
1278
+ isNativeBroker: response.fromNativeBroker,
1279
+ requestId: response.requestId,
1280
+ });
1281
+ return response;
1282
+ })
1283
+ .catch((tokenRenewalError) => {
1284
+ this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null, tokenRenewalError);
1285
+ this.atsAsyncMeasurement?.endMeasurement({
1286
+ errorCode: tokenRenewalError.errorCode,
1287
+ subErrorCode: tokenRenewalError.subError,
1288
+ success: false,
1289
+ });
1290
+ throw tokenRenewalError;
1291
+ })
1292
+ .finally(() => {
1293
+ document.removeEventListener("visibilitychange", this.trackPageVisibility);
1294
+ });
1295
+ }
1296
+ }
1297
+
1298
+ export { StandardController };
1299
+ //# sourceMappingURL=StandardController.js.map