@azure/msal-browser 3.2.0 → 3.3.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 (202) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +2 -2
  3. package/dist/app/PublicClientApplication.mjs.map +1 -1
  4. package/dist/app/PublicClientNext.d.ts +274 -0
  5. package/dist/app/PublicClientNext.d.ts.map +1 -0
  6. package/dist/app/PublicClientNext.mjs +362 -0
  7. package/dist/app/PublicClientNext.mjs.map +1 -0
  8. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  9. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  10. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  11. package/dist/cache/BrowserCacheManager.d.ts +2 -13
  12. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  13. package/dist/cache/BrowserCacheManager.mjs +7 -64
  14. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  15. package/dist/cache/BrowserStorage.mjs +1 -1
  16. package/dist/cache/CryptoKeyStore.mjs +1 -1
  17. package/dist/cache/DatabaseStorage.mjs +1 -1
  18. package/dist/cache/MemoryStorage.mjs +1 -1
  19. package/dist/cache/TokenCache.mjs +1 -1
  20. package/dist/config/Configuration.d.ts +4 -0
  21. package/dist/config/Configuration.d.ts.map +1 -1
  22. package/dist/config/Configuration.mjs +2 -1
  23. package/dist/config/Configuration.mjs.map +1 -1
  24. package/dist/controllers/ControllerFactory.d.ts +2 -1
  25. package/dist/controllers/ControllerFactory.d.ts.map +1 -1
  26. package/dist/controllers/ControllerFactory.mjs +26 -19
  27. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  28. package/dist/controllers/NestedAppAuthController.d.ts +96 -0
  29. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -0
  30. package/dist/controllers/NestedAppAuthController.mjs +345 -0
  31. package/dist/controllers/NestedAppAuthController.mjs.map +1 -0
  32. package/dist/controllers/StandardController.d.ts.map +1 -1
  33. package/dist/controllers/StandardController.mjs +16 -13
  34. package/dist/controllers/StandardController.mjs.map +1 -1
  35. package/dist/controllers/UnknownOperatingContextController.d.ts +88 -0
  36. package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -0
  37. package/dist/controllers/UnknownOperatingContextController.mjs +275 -0
  38. package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -0
  39. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  40. package/dist/crypto/BrowserCrypto.mjs +3 -3
  41. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  42. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  43. package/dist/crypto/CryptoOps.mjs +8 -5
  44. package/dist/crypto/CryptoOps.mjs.map +1 -1
  45. package/dist/crypto/PkceGenerator.mjs +1 -1
  46. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  47. package/dist/encode/Base64Decode.mjs +1 -1
  48. package/dist/encode/Base64Encode.mjs +1 -1
  49. package/dist/error/BrowserAuthError.mjs +1 -1
  50. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  51. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  52. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  53. package/dist/error/NativeAuthError.mjs +1 -1
  54. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  55. package/dist/error/NestedAppAuthError.d.ts +15 -0
  56. package/dist/error/NestedAppAuthError.d.ts.map +1 -0
  57. package/dist/error/NestedAppAuthError.mjs +30 -0
  58. package/dist/error/NestedAppAuthError.mjs.map +1 -0
  59. package/dist/event/EventHandler.mjs +1 -1
  60. package/dist/event/EventMessage.mjs +1 -1
  61. package/dist/event/EventType.mjs +1 -1
  62. package/dist/index.d.ts +3 -5
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.mjs +4 -2
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/interaction_client/BaseInteractionClient.mjs +4 -4
  67. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  68. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  69. package/dist/interaction_client/NativeInteractionClient.mjs +15 -4
  70. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  71. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  72. package/dist/interaction_client/PopupClient.mjs +5 -4
  73. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  74. package/dist/interaction_client/RedirectClient.mjs +7 -7
  75. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  76. package/dist/interaction_client/SilentAuthCodeClient.mjs +4 -4
  77. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  78. package/dist/interaction_client/SilentCacheClient.d.ts.map +1 -1
  79. package/dist/interaction_client/SilentCacheClient.mjs +4 -3
  80. package/dist/interaction_client/SilentCacheClient.mjs.map +1 -1
  81. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  82. package/dist/interaction_client/SilentIframeClient.mjs +27 -13
  83. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  84. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  85. package/dist/interaction_client/StandardInteractionClient.mjs +5 -5
  86. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  87. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  88. package/dist/interaction_handler/SilentHandler.d.ts +13 -47
  89. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  90. package/dist/interaction_handler/SilentHandler.mjs +120 -155
  91. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  92. package/dist/naa/AccountInfo.d.ts +13 -0
  93. package/dist/naa/AccountInfo.d.ts.map +1 -0
  94. package/dist/naa/AccountRequests.d.ts +10 -0
  95. package/dist/naa/AccountRequests.d.ts.map +1 -0
  96. package/dist/naa/AuthBridge.d.ts +6 -0
  97. package/dist/naa/AuthBridge.d.ts.map +1 -0
  98. package/dist/naa/BridgeCapabilities.d.ts +4 -0
  99. package/dist/naa/BridgeCapabilities.d.ts.map +1 -0
  100. package/dist/naa/BridgeError.d.ts +10 -0
  101. package/dist/naa/BridgeError.d.ts.map +1 -0
  102. package/dist/naa/BridgeError.mjs +12 -0
  103. package/dist/naa/BridgeError.mjs.map +1 -0
  104. package/dist/naa/BridgeProxy.d.ts +72 -0
  105. package/dist/naa/BridgeProxy.d.ts.map +1 -0
  106. package/dist/naa/BridgeProxy.mjs +154 -0
  107. package/dist/naa/BridgeProxy.mjs.map +1 -0
  108. package/dist/naa/BridgeRequest.d.ts +7 -0
  109. package/dist/naa/BridgeRequest.d.ts.map +1 -0
  110. package/dist/naa/BridgeRequestEnvelope.d.ts +14 -0
  111. package/dist/naa/BridgeRequestEnvelope.d.ts.map +1 -0
  112. package/dist/naa/BridgeResponseEnvelope.d.ts +11 -0
  113. package/dist/naa/BridgeResponseEnvelope.d.ts.map +1 -0
  114. package/dist/naa/BridgeStatusCode.d.ts +11 -0
  115. package/dist/naa/BridgeStatusCode.d.ts.map +1 -0
  116. package/dist/naa/BridgeStatusCode.mjs +20 -0
  117. package/dist/naa/BridgeStatusCode.mjs.map +1 -0
  118. package/dist/naa/IBridgeProxy.d.ts +11 -0
  119. package/dist/naa/IBridgeProxy.d.ts.map +1 -0
  120. package/dist/naa/InitializeBridgeResponse.d.ts +7 -0
  121. package/dist/naa/InitializeBridgeResponse.d.ts.map +1 -0
  122. package/dist/naa/TokenRequest.d.ts +22 -0
  123. package/dist/naa/TokenRequest.d.ts.map +1 -0
  124. package/dist/naa/TokenResponse.d.ts +17 -0
  125. package/dist/naa/TokenResponse.d.ts.map +1 -0
  126. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts +26 -0
  127. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -0
  128. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +178 -0
  129. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -0
  130. package/dist/navigation/NavigationClient.mjs +1 -1
  131. package/dist/network/FetchClient.mjs +1 -1
  132. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  133. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  134. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts +7 -0
  135. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts.map +1 -1
  136. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +45 -4
  137. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +1 -1
  138. package/dist/operatingcontext/UnknownOperatingContext.d.ts +26 -0
  139. package/dist/operatingcontext/UnknownOperatingContext.d.ts.map +1 -0
  140. package/dist/operatingcontext/UnknownOperatingContext.mjs +49 -0
  141. package/dist/operatingcontext/UnknownOperatingContext.mjs.map +1 -0
  142. package/dist/packageMetadata.d.ts +1 -1
  143. package/dist/packageMetadata.mjs +2 -2
  144. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  145. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  146. package/dist/utils/BrowserConstants.mjs +1 -1
  147. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  148. package/dist/utils/BrowserUtils.d.ts +54 -53
  149. package/dist/utils/BrowserUtils.d.ts.map +1 -1
  150. package/dist/utils/BrowserUtils.mjs +114 -102
  151. package/dist/utils/BrowserUtils.mjs.map +1 -1
  152. package/lib/msal-browser.cjs +61 -17728
  153. package/lib/msal-browser.cjs.map +1 -1
  154. package/lib/msal-browser.js +14625 -13223
  155. package/lib/msal-browser.js.map +1 -1
  156. package/lib/msal-browser.min.js +66 -68
  157. package/package.json +2 -2
  158. package/src/app/PublicClientApplication.ts +1 -1
  159. package/src/app/PublicClientNext.ts +442 -0
  160. package/src/cache/BrowserCacheManager.ts +11 -100
  161. package/src/config/Configuration.ts +5 -0
  162. package/src/controllers/ControllerFactory.ts +36 -25
  163. package/src/controllers/NestedAppAuthController.ts +525 -0
  164. package/src/controllers/StandardController.ts +8 -6
  165. package/src/controllers/UnknownOperatingContextController.ts +383 -0
  166. package/src/crypto/BrowserCrypto.ts +2 -2
  167. package/src/crypto/CryptoOps.ts +8 -5
  168. package/src/error/NestedAppAuthError.ts +32 -0
  169. package/src/index.ts +3 -10
  170. package/src/interaction_client/BaseInteractionClient.ts +1 -1
  171. package/src/interaction_client/NativeInteractionClient.ts +19 -3
  172. package/src/interaction_client/PopupClient.ts +2 -1
  173. package/src/interaction_client/RedirectClient.ts +1 -1
  174. package/src/interaction_client/SilentAuthCodeClient.ts +5 -4
  175. package/src/interaction_client/SilentCacheClient.ts +11 -3
  176. package/src/interaction_client/SilentIframeClient.ts +53 -17
  177. package/src/interaction_client/StandardInteractionClient.ts +1 -1
  178. package/src/interaction_handler/SilentHandler.ts +177 -233
  179. package/src/naa/AccountInfo.ts +17 -0
  180. package/src/naa/AccountRequests.ts +16 -0
  181. package/src/naa/AuthBridge.ts +16 -0
  182. package/src/naa/BridgeCapabilities.ts +8 -0
  183. package/src/naa/BridgeError.ts +18 -0
  184. package/src/naa/BridgeProxy.ts +230 -0
  185. package/src/naa/BridgeRequest.ts +12 -0
  186. package/src/naa/BridgeRequestEnvelope.ts +46 -0
  187. package/src/naa/BridgeResponseEnvelope.ts +21 -0
  188. package/src/naa/BridgeStatusCode.ts +15 -0
  189. package/src/naa/IBridgeProxy.ts +25 -0
  190. package/src/naa/InitializeBridgeResponse.ts +12 -0
  191. package/src/naa/TokenRequest.ts +26 -0
  192. package/src/naa/TokenResponse.ts +61 -0
  193. package/src/naa/mapping/NestedAppAuthAdapter.ts +252 -0
  194. package/src/operatingcontext/TeamsAppOperatingContext.ts +43 -3
  195. package/src/operatingcontext/UnknownOperatingContext.ts +48 -0
  196. package/src/packageMetadata.ts +1 -1
  197. package/src/utils/BrowserUtils.ts +133 -125
  198. package/dist/utils/BrowserStringUtils.d.ts +0 -22
  199. package/dist/utils/BrowserStringUtils.d.ts.map +0 -1
  200. package/dist/utils/BrowserStringUtils.mjs +0 -144
  201. package/dist/utils/BrowserStringUtils.mjs.map +0 -1
  202. package/src/utils/BrowserStringUtils.ts +0 -143
@@ -29,11 +29,16 @@ import {
29
29
  BrowserAuthErrorCodes,
30
30
  } from "../error/BrowserAuthError";
31
31
  import { InteractionType, ApiId } from "../utils/BrowserConstants";
32
- import { SilentHandler } from "../interaction_handler/SilentHandler";
32
+ import {
33
+ initiateAuthRequest,
34
+ monitorIframeForHash,
35
+ } from "../interaction_handler/SilentHandler";
33
36
  import { SsoSilentRequest } from "../request/SsoSilentRequest";
34
37
  import { NativeMessageHandler } from "../broker/nativeBroker/NativeMessageHandler";
35
38
  import { NativeInteractionClient } from "./NativeInteractionClient";
36
39
  import { AuthenticationResult } from "../response/AuthenticationResult";
40
+ import { InteractionHandler } from "../interaction_handler/InteractionHandler";
41
+ import * as BrowserUtils from "../utils/BrowserUtils";
37
42
 
38
43
  export class SilentIframeClient extends StandardInteractionClient {
39
44
  protected apiId: ApiId;
@@ -114,6 +119,7 @@ export class SilentIframeClient extends StandardInteractionClient {
114
119
  },
115
120
  InteractionType.Silent
116
121
  );
122
+ BrowserUtils.preconnect(silentRequest.authority);
117
123
  this.browserStorage.updateCacheEntries(
118
124
  silentRequest.state,
119
125
  silentRequest.nonce,
@@ -179,9 +185,10 @@ export class SilentIframeClient extends StandardInteractionClient {
179
185
  authClient: AuthorizationCodeClient,
180
186
  silentRequest: AuthorizationUrlRequest
181
187
  ): Promise<AuthenticationResult> {
188
+ const correlationId = silentRequest.correlationId;
182
189
  this.performanceClient.addQueueMeasurement(
183
190
  PerformanceEvents.SilentIframeClientTokenHelper,
184
- silentRequest.correlationId
191
+ correlationId
185
192
  );
186
193
 
187
194
  // Create auth code request and generate PKCE params
@@ -191,7 +198,7 @@ export class SilentIframeClient extends StandardInteractionClient {
191
198
  PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
192
199
  this.logger,
193
200
  this.performanceClient,
194
- silentRequest.correlationId
201
+ correlationId
195
202
  )(silentRequest);
196
203
 
197
204
  // Create authorize request url
@@ -200,7 +207,7 @@ export class SilentIframeClient extends StandardInteractionClient {
200
207
  PerformanceEvents.GetAuthCodeUrl,
201
208
  this.logger,
202
209
  this.performanceClient,
203
- silentRequest.correlationId
210
+ correlationId
204
211
  )({
205
212
  ...silentRequest,
206
213
  nativeBroker: NativeMessageHandler.isNativeAvailable(
@@ -212,37 +219,64 @@ export class SilentIframeClient extends StandardInteractionClient {
212
219
  });
213
220
 
214
221
  // Create silent handler
215
- const silentHandler = new SilentHandler(
222
+ const interactionHandler = new InteractionHandler(
216
223
  authClient,
217
224
  this.browserStorage,
218
225
  authCodeRequest,
219
226
  this.logger,
220
- this.config.system,
221
227
  this.performanceClient
222
228
  );
223
229
  // Get the frame handle for the silent request
224
230
  const msalFrame = await invokeAsync(
225
- silentHandler.initiateAuthRequest.bind(silentHandler),
231
+ initiateAuthRequest,
226
232
  PerformanceEvents.SilentHandlerInitiateAuthRequest,
227
233
  this.logger,
228
234
  this.performanceClient,
229
- silentRequest.correlationId
230
- )(navigateUrl);
235
+ correlationId
236
+ )(
237
+ navigateUrl,
238
+ this.performanceClient,
239
+ this.logger,
240
+ correlationId,
241
+ this.config.system.navigateFrameWait
242
+ );
231
243
  // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
232
244
  const hash = await invokeAsync(
233
- silentHandler.monitorIframeForHash.bind(silentHandler),
245
+ monitorIframeForHash,
234
246
  PerformanceEvents.SilentHandlerMonitorIframeForHash,
235
247
  this.logger,
236
248
  this.performanceClient,
237
- silentRequest.correlationId
238
- )(msalFrame, this.config.system.iframeHashTimeout);
249
+ correlationId
250
+ )(
251
+ msalFrame,
252
+ this.config.system.iframeHashTimeout,
253
+ this.config.system.pollIntervalMilliseconds,
254
+ this.performanceClient,
255
+ this.logger,
256
+ correlationId
257
+ );
258
+ if (!hash) {
259
+ // No hash is present
260
+ this.logger.error(
261
+ "The request has returned to the redirectUri but a hash is not present in the iframe. It's likely that the hash has been removed or the page has been redirected by code running on the redirectUri page."
262
+ );
263
+ throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError);
264
+ } else if (!UrlString.hashContainsKnownProperties(hash)) {
265
+ this.logger.error(
266
+ "A hash is present in the iframe but it does not contain known properties. It's likely that the hash has been replaced by code running on the redirectUri page."
267
+ );
268
+ this.logger.errorPii(`The hash detected in the iframe is: ${hash}`);
269
+ throw createBrowserAuthError(
270
+ BrowserAuthErrorCodes.hashDoesNotContainKnownProperties
271
+ );
272
+ }
239
273
  // Deserialize hash fragment response parameters.
240
274
  const serverParams: ServerAuthorizationCodeResponse =
241
275
  UrlString.getDeserializedHash(hash);
242
276
  const state = this.validateAndExtractStateFromHash(
243
277
  serverParams,
244
278
  InteractionType.Silent,
245
- authCodeRequest.correlationId
279
+ correlationId
246
280
  );
247
281
 
248
282
  if (serverParams.accountId) {
@@ -266,7 +300,7 @@ export class SilentIframeClient extends StandardInteractionClient {
266
300
  this.nativeMessageHandler,
267
301
  serverParams.accountId,
268
302
  this.browserStorage,
269
- this.correlationId
303
+ correlationId
270
304
  );
271
305
  const { userRequestState } = ProtocolUtils.parseRequestState(
272
306
  this.browserCrypto,
@@ -279,7 +313,7 @@ export class SilentIframeClient extends StandardInteractionClient {
279
313
  PerformanceEvents.NativeInteractionClientAcquireToken,
280
314
  this.logger,
281
315
  this.performanceClient,
282
- silentRequest.correlationId
316
+ correlationId
283
317
  )({
284
318
  ...silentRequest,
285
319
  state: userRequestState,
@@ -291,11 +325,13 @@ export class SilentIframeClient extends StandardInteractionClient {
291
325
 
292
326
  // Handle response from hash string
293
327
  return invokeAsync(
294
- silentHandler.handleCodeResponseFromHash.bind(silentHandler),
328
+ interactionHandler.handleCodeResponseFromHash.bind(
329
+ interactionHandler
330
+ ),
295
331
  PerformanceEvents.HandleCodeResponseFromHash,
296
332
  this.logger,
297
333
  this.performanceClient,
298
- silentRequest.correlationId
334
+ correlationId
299
335
  )(hash, state, authClient.authority, this.networkClient);
300
336
  }
301
337
  }
@@ -37,7 +37,7 @@ import {
37
37
  BrowserStateObject,
38
38
  } from "../utils/BrowserProtocolUtils";
39
39
  import { EndSessionRequest } from "../request/EndSessionRequest";
40
- import { BrowserUtils } from "../utils/BrowserUtils";
40
+ import * as BrowserUtils from "../utils/BrowserUtils";
41
41
  import { RedirectRequest } from "../request/RedirectRequest";
42
42
  import { PopupRequest } from "../request/PopupRequest";
43
43
  import { SsoSilentRequest } from "../request/SsoSilentRequest";
@@ -4,266 +4,210 @@
4
4
  */
5
5
 
6
6
  import {
7
- UrlString,
8
- CommonAuthorizationCodeRequest,
9
- AuthorizationCodeClient,
10
- Constants,
11
7
  Logger,
12
8
  IPerformanceClient,
13
9
  PerformanceEvents,
14
10
  invokeAsync,
11
+ invoke,
15
12
  } from "@azure/msal-common";
16
- import { InteractionHandler } from "./InteractionHandler";
17
13
  import {
18
14
  createBrowserAuthError,
19
15
  BrowserAuthErrorCodes,
20
16
  } from "../error/BrowserAuthError";
21
- import { BrowserCacheManager } from "../cache/BrowserCacheManager";
22
- import {
23
- BrowserSystemOptions,
24
- DEFAULT_IFRAME_TIMEOUT_MS,
25
- } from "../config/Configuration";
26
-
27
- export class SilentHandler extends InteractionHandler {
28
- private navigateFrameWait: number;
29
- private pollIntervalMilliseconds: number;
17
+ import { DEFAULT_IFRAME_TIMEOUT_MS } from "../config/Configuration";
30
18
 
31
- constructor(
32
- authCodeModule: AuthorizationCodeClient,
33
- storageImpl: BrowserCacheManager,
34
- authCodeRequest: CommonAuthorizationCodeRequest,
35
- logger: Logger,
36
- systemOptions: Required<
37
- Pick<
38
- BrowserSystemOptions,
39
- "navigateFrameWait" | "pollIntervalMilliseconds"
40
- >
41
- >,
42
- performanceClient: IPerformanceClient
43
- ) {
44
- super(
45
- authCodeModule,
46
- storageImpl,
47
- authCodeRequest,
19
+ /**
20
+ * Creates a hidden iframe to given URL using user-requested scopes as an id.
21
+ * @param urlNavigate
22
+ * @param userRequestScopes
23
+ */
24
+ export async function initiateAuthRequest(
25
+ requestUrl: string,
26
+ performanceClient: IPerformanceClient,
27
+ logger: Logger,
28
+ correlationId: string,
29
+ navigateFrameWait?: number
30
+ ): Promise<HTMLIFrameElement> {
31
+ performanceClient.addQueueMeasurement(
32
+ PerformanceEvents.SilentHandlerInitiateAuthRequest,
33
+ correlationId
34
+ );
35
+
36
+ if (!requestUrl) {
37
+ // Throw error if request URL is empty.
38
+ logger.info("Navigate url is empty");
39
+ throw createBrowserAuthError(BrowserAuthErrorCodes.emptyNavigateUri);
40
+ }
41
+ if (navigateFrameWait) {
42
+ return await invokeAsync(
43
+ loadFrame,
44
+ PerformanceEvents.SilentHandlerLoadFrame,
48
45
  logger,
49
- performanceClient
50
- );
51
- this.navigateFrameWait = systemOptions.navigateFrameWait;
52
- this.pollIntervalMilliseconds = systemOptions.pollIntervalMilliseconds;
46
+ performanceClient,
47
+ correlationId
48
+ )(requestUrl, navigateFrameWait, performanceClient, correlationId);
53
49
  }
50
+ return invoke(
51
+ loadFrameSync,
52
+ PerformanceEvents.SilentHandlerLoadFrameSync,
53
+ logger,
54
+ performanceClient,
55
+ correlationId
56
+ )(requestUrl);
57
+ }
54
58
 
55
- /**
56
- * Creates a hidden iframe to given URL using user-requested scopes as an id.
57
- * @param urlNavigate
58
- * @param userRequestScopes
59
- */
60
- async initiateAuthRequest(requestUrl: string): Promise<HTMLIFrameElement> {
61
- this.performanceClient.addQueueMeasurement(
62
- PerformanceEvents.SilentHandlerInitiateAuthRequest,
63
- this.authCodeRequest.correlationId
64
- );
65
-
66
- if (!requestUrl) {
67
- // Throw error if request URL is empty.
68
- this.logger.info("Navigate url is empty");
69
- throw createBrowserAuthError(
70
- BrowserAuthErrorCodes.emptyNavigateUri
59
+ /**
60
+ * Monitors an iframe content window until it loads a url with a known hash, or hits a specified timeout.
61
+ * @param iframe
62
+ * @param timeout
63
+ */
64
+ export async function monitorIframeForHash(
65
+ iframe: HTMLIFrameElement,
66
+ timeout: number,
67
+ pollIntervalMilliseconds: number,
68
+ performanceClient: IPerformanceClient,
69
+ logger: Logger,
70
+ correlationId: string
71
+ ): Promise<string> {
72
+ performanceClient.addQueueMeasurement(
73
+ PerformanceEvents.SilentHandlerMonitorIframeForHash,
74
+ correlationId
75
+ );
76
+
77
+ return new Promise<string>((resolve, reject) => {
78
+ if (timeout < DEFAULT_IFRAME_TIMEOUT_MS) {
79
+ logger.warning(
80
+ `system.loadFrameTimeout or system.iframeHashTimeout set to lower (${timeout}ms) than the default (${DEFAULT_IFRAME_TIMEOUT_MS}ms). This may result in timeouts.`
71
81
  );
72
82
  }
73
83
 
74
- if (this.navigateFrameWait) {
75
- return await invokeAsync(
76
- this.loadFrame.bind(this),
77
- PerformanceEvents.SilentHandlerLoadFrame,
78
- this.logger,
79
- this.performanceClient,
80
- this.authCodeRequest.correlationId
81
- )(requestUrl);
82
- }
83
- return this.loadFrameSync(requestUrl);
84
- }
85
-
86
- /**
87
- * Monitors an iframe content window until it loads a url with a known hash, or hits a specified timeout.
88
- * @param iframe
89
- * @param timeout
90
- */
91
- monitorIframeForHash(
92
- iframe: HTMLIFrameElement,
93
- timeout: number
94
- ): Promise<string> {
95
- this.performanceClient.addQueueMeasurement(
96
- PerformanceEvents.SilentHandlerMonitorIframeForHash,
97
- this.authCodeRequest.correlationId
98
- );
99
-
100
- return new Promise((resolve, reject) => {
101
- if (timeout < DEFAULT_IFRAME_TIMEOUT_MS) {
102
- this.logger.warning(
103
- `system.loadFrameTimeout or system.iframeHashTimeout set to lower (${timeout}ms) than the default (${DEFAULT_IFRAME_TIMEOUT_MS}ms). This may result in timeouts.`
104
- );
105
- }
106
-
107
- /*
108
- * Polling for iframes can be purely timing based,
109
- * since we don't need to account for interaction.
110
- */
111
- const nowMark = window.performance.now();
112
- const timeoutMark = nowMark + timeout;
113
-
114
- const intervalId = setInterval(() => {
115
- if (window.performance.now() > timeoutMark) {
116
- this.removeHiddenIframe(iframe);
117
- clearInterval(intervalId);
118
- reject(
119
- createBrowserAuthError(
120
- BrowserAuthErrorCodes.monitorWindowTimeout
121
- )
122
- );
123
- return;
124
- }
125
-
126
- let href: string = Constants.EMPTY_STRING;
127
- const contentWindow = iframe.contentWindow;
128
- try {
129
- /*
130
- * Will throw if cross origin,
131
- * which should be caught and ignored
132
- * since we need the interval to keep running while on STS UI.
133
- */
134
- href = contentWindow
135
- ? contentWindow.location.href
136
- : Constants.EMPTY_STRING;
137
- } catch (e) {}
138
-
139
- if (!href || href === "about:blank") {
140
- return;
141
- }
142
-
143
- const contentHash = contentWindow
144
- ? contentWindow.location.hash
145
- : Constants.EMPTY_STRING;
146
- if (contentHash) {
147
- if (UrlString.hashContainsKnownProperties(contentHash)) {
148
- // Success case
149
- this.removeHiddenIframe(iframe);
150
- clearInterval(intervalId);
151
- resolve(contentHash);
152
- return;
153
- } else {
154
- // Hash is present but incorrect
155
- this.logger.error(
156
- "SilentHandler:monitorIFrameForHash - a hash is present in the iframe but it does not contain known properties. It's likely that the hash has been replaced by code running on the redirectUri page."
157
- );
158
- this.logger.errorPii(
159
- `SilentHandler:monitorIFrameForHash - the url detected in the iframe is: ${href}`
160
- );
161
- this.removeHiddenIframe(iframe);
162
- clearInterval(intervalId);
163
- reject(
164
- createBrowserAuthError(
165
- BrowserAuthErrorCodes.hashDoesNotContainKnownProperties
166
- )
167
- );
168
- return;
169
- }
170
- } else {
171
- // No hash is present
172
- this.logger.error(
173
- "SilentHandler:monitorIFrameForHash - the request has returned to the redirectUri but a hash is not present in the iframe. It's likely that the hash has been removed or the page has been redirected by code running on the redirectUri page."
174
- );
175
- this.logger.errorPii(
176
- `SilentHandler:monitorIFrameForHash - the url detected in the iframe is: ${href}`
177
- );
178
- this.removeHiddenIframe(iframe);
179
- clearInterval(intervalId);
180
- reject(
181
- createBrowserAuthError(
182
- BrowserAuthErrorCodes.hashEmptyError
183
- )
184
- );
185
- return;
186
- }
187
- }, this.pollIntervalMilliseconds);
188
- });
189
- }
190
-
191
- /**
192
- * @hidden
193
- * Loads iframe with authorization endpoint URL
194
- * @ignore
195
- */
196
- private loadFrame(urlNavigate: string): Promise<HTMLIFrameElement> {
197
- this.performanceClient.addQueueMeasurement(
198
- PerformanceEvents.SilentHandlerLoadFrame,
199
- this.authCodeRequest.correlationId
200
- );
201
-
202
84
  /*
203
- * This trick overcomes iframe navigation in IE
204
- * IE does not load the page consistently in iframe
85
+ * Polling for iframes can be purely timing based,
86
+ * since we don't need to account for interaction.
205
87
  */
88
+ const timeoutId = window.setTimeout(() => {
89
+ window.clearInterval(intervalId);
90
+ reject(
91
+ createBrowserAuthError(
92
+ BrowserAuthErrorCodes.monitorWindowTimeout
93
+ )
94
+ );
95
+ }, timeout);
96
+
97
+ const intervalId = window.setInterval(() => {
98
+ let href: string = "";
99
+ const contentWindow = iframe.contentWindow;
100
+ try {
101
+ /*
102
+ * Will throw if cross origin,
103
+ * which should be caught and ignored
104
+ * since we need the interval to keep running while on STS UI.
105
+ */
106
+ href = contentWindow ? contentWindow.location.href : "";
107
+ } catch (e) {}
108
+
109
+ if (!href || href === "about:blank") {
110
+ return;
111
+ }
206
112
 
207
- return new Promise((resolve, reject) => {
208
- const frameHandle = this.createHiddenIframe();
209
-
210
- setTimeout(() => {
211
- if (!frameHandle) {
212
- reject("Unable to load iframe");
213
- return;
214
- }
113
+ const contentHash = contentWindow
114
+ ? contentWindow.location.hash
115
+ : "";
116
+ window.clearTimeout(timeoutId);
117
+ window.clearInterval(intervalId);
118
+ resolve(contentHash);
119
+ }, pollIntervalMilliseconds);
120
+ }).finally(() => {
121
+ invoke(
122
+ removeHiddenIframe,
123
+ PerformanceEvents.RemoveHiddenIframe,
124
+ logger,
125
+ performanceClient,
126
+ correlationId
127
+ )(iframe);
128
+ });
129
+ }
215
130
 
216
- frameHandle.src = urlNavigate;
131
+ /**
132
+ * @hidden
133
+ * Loads iframe with authorization endpoint URL
134
+ * @ignore
135
+ * @deprecated
136
+ */
137
+ function loadFrame(
138
+ urlNavigate: string,
139
+ navigateFrameWait: number,
140
+ performanceClient: IPerformanceClient,
141
+ correlationId: string
142
+ ): Promise<HTMLIFrameElement> {
143
+ performanceClient.addQueueMeasurement(
144
+ PerformanceEvents.SilentHandlerLoadFrame,
145
+ correlationId
146
+ );
147
+
148
+ /*
149
+ * This trick overcomes iframe navigation in IE
150
+ * IE does not load the page consistently in iframe
151
+ */
217
152
 
218
- resolve(frameHandle);
219
- }, this.navigateFrameWait);
220
- });
221
- }
153
+ return new Promise((resolve, reject) => {
154
+ const frameHandle = createHiddenIframe();
222
155
 
223
- /**
224
- * @hidden
225
- * Loads the iframe synchronously when the navigateTimeFrame is set to `0`
226
- * @param urlNavigate
227
- * @param frameName
228
- * @param logger
229
- */
230
- private loadFrameSync(urlNavigate: string): HTMLIFrameElement {
231
- const frameHandle = this.createHiddenIframe();
156
+ window.setTimeout(() => {
157
+ if (!frameHandle) {
158
+ reject("Unable to load iframe");
159
+ return;
160
+ }
232
161
 
233
- frameHandle.src = urlNavigate;
162
+ frameHandle.src = urlNavigate;
234
163
 
235
- return frameHandle;
236
- }
164
+ resolve(frameHandle);
165
+ }, navigateFrameWait);
166
+ });
167
+ }
168
+ /**
169
+ * @hidden
170
+ * Loads the iframe synchronously when the navigateTimeFrame is set to `0`
171
+ * @param urlNavigate
172
+ * @param frameName
173
+ * @param logger
174
+ */
175
+ function loadFrameSync(urlNavigate: string): HTMLIFrameElement {
176
+ const frameHandle = createHiddenIframe();
237
177
 
238
- /**
239
- * @hidden
240
- * Creates a new hidden iframe or gets an existing one for silent token renewal.
241
- * @ignore
242
- */
243
- private createHiddenIframe(): HTMLIFrameElement {
244
- const authFrame = document.createElement("iframe");
178
+ frameHandle.src = urlNavigate;
245
179
 
246
- authFrame.style.visibility = "hidden";
247
- authFrame.style.position = "absolute";
248
- authFrame.style.width = authFrame.style.height = "0";
249
- authFrame.style.border = "0";
250
- authFrame.setAttribute(
251
- "sandbox",
252
- "allow-scripts allow-same-origin allow-forms"
253
- );
254
- document.getElementsByTagName("body")[0].appendChild(authFrame);
180
+ return frameHandle;
181
+ }
255
182
 
256
- return authFrame;
257
- }
183
+ /**
184
+ * @hidden
185
+ * Creates a new hidden iframe or gets an existing one for silent token renewal.
186
+ * @ignore
187
+ */
188
+ function createHiddenIframe(): HTMLIFrameElement {
189
+ const authFrame = document.createElement("iframe");
190
+
191
+ authFrame.style.visibility = "hidden";
192
+ authFrame.style.position = "absolute";
193
+ authFrame.style.width = authFrame.style.height = "0";
194
+ authFrame.style.border = "0";
195
+ authFrame.setAttribute(
196
+ "sandbox",
197
+ "allow-scripts allow-same-origin allow-forms"
198
+ );
199
+ document.getElementsByTagName("body")[0].appendChild(authFrame);
200
+
201
+ return authFrame;
202
+ }
258
203
 
259
- /**
260
- * @hidden
261
- * Removes a hidden iframe from the page.
262
- * @ignore
263
- */
264
- private removeHiddenIframe(iframe: HTMLIFrameElement): void {
265
- if (document.body === iframe.parentNode) {
266
- document.body.removeChild(iframe);
267
- }
204
+ /**
205
+ * @hidden
206
+ * Removes a hidden iframe from the page.
207
+ * @ignore
208
+ */
209
+ function removeHiddenIframe(iframe: HTMLIFrameElement): void {
210
+ if (document.body === iframe.parentNode) {
211
+ document.body.removeChild(iframe);
268
212
  }
269
213
  }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type AccountInfo = {
7
+ homeAccountId: string;
8
+ environment: string;
9
+ tenantId: string;
10
+ username: string;
11
+ localAccountId: string;
12
+ name?: string;
13
+ idToken?: string; // idTokenClaims can be parsed from idToken in MSAL.js
14
+ platformBrokerId?: string; // Used by WAM previous called nativeAccountId
15
+ idTokenClaims?: object;
16
+ client_info?: string;
17
+ };
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type AccountByHomeIdRequest = {
7
+ homeAccountId: string;
8
+ };
9
+
10
+ export type AccountByLocalIdRequest = {
11
+ localAccountId: string;
12
+ };
13
+
14
+ export type AccountByUsernameRequest = {
15
+ username: string;
16
+ };
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export interface AuthBridge {
7
+ addEventListener: (
8
+ eventName: string,
9
+ callback: (response: string) => void
10
+ ) => void;
11
+ postMessage: (message: string) => void;
12
+ removeEventListener: (
13
+ eventName: string,
14
+ callback: (response: string) => void
15
+ ) => void;
16
+ }
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export interface BridgeCapabilities {
7
+ queryAccount: boolean;
8
+ }