@azure/msal-browser 3.4.0 → 3.5.1-beta.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 (231) hide show
  1. package/dist/app/IPublicClientApplication.d.ts +51 -51
  2. package/dist/app/IPublicClientApplication.mjs +102 -102
  3. package/dist/app/PublicClientApplication.d.ts +268 -268
  4. package/dist/app/PublicClientApplication.mjs +333 -333
  5. package/dist/app/PublicClientNext.d.ts +273 -273
  6. package/dist/app/PublicClientNext.mjs +351 -351
  7. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts +62 -62
  8. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +254 -254
  9. package/dist/broker/nativeBroker/NativeRequest.d.ts +44 -44
  10. package/dist/broker/nativeBroker/NativeResponse.d.ts +48 -48
  11. package/dist/broker/nativeBroker/NativeStatusCodes.d.ts +7 -7
  12. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +11 -11
  13. package/dist/cache/AsyncMemoryStorage.d.ts +51 -51
  14. package/dist/cache/AsyncMemoryStorage.mjs +132 -132
  15. package/dist/cache/BrowserCacheManager.d.ts +383 -383
  16. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  17. package/dist/cache/BrowserCacheManager.mjs +1264 -1264
  18. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  19. package/dist/cache/BrowserStorage.d.ts +11 -11
  20. package/dist/cache/BrowserStorage.mjs +32 -32
  21. package/dist/cache/CryptoKeyStore.d.ts +18 -18
  22. package/dist/cache/CryptoKeyStore.mjs +40 -40
  23. package/dist/cache/DatabaseStorage.d.ts +56 -56
  24. package/dist/cache/DatabaseStorage.mjs +190 -190
  25. package/dist/cache/IAsyncMemoryStorage.d.ts +27 -27
  26. package/dist/cache/ITokenCache.d.ts +11 -11
  27. package/dist/cache/IWindowStorage.d.ts +27 -27
  28. package/dist/cache/MemoryStorage.d.ts +11 -11
  29. package/dist/cache/MemoryStorage.mjs +31 -31
  30. package/dist/cache/TokenCache.d.ts +77 -77
  31. package/dist/cache/TokenCache.mjs +224 -224
  32. package/dist/config/Configuration.d.ts +206 -206
  33. package/dist/config/Configuration.mjs +128 -128
  34. package/dist/controllers/ControllerFactory.d.ts +4 -4
  35. package/dist/controllers/ControllerFactory.mjs +29 -29
  36. package/dist/controllers/IController.d.ts +61 -61
  37. package/dist/controllers/NestedAppAuthController.d.ts +95 -95
  38. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  39. package/dist/controllers/NestedAppAuthController.mjs +335 -333
  40. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  41. package/dist/controllers/StandardController.d.ts +407 -407
  42. package/dist/controllers/StandardController.d.ts.map +1 -1
  43. package/dist/controllers/StandardController.mjs +1294 -1291
  44. package/dist/controllers/StandardController.mjs.map +1 -1
  45. package/dist/controllers/UnknownOperatingContextController.d.ts +87 -87
  46. package/dist/controllers/UnknownOperatingContextController.mjs +264 -264
  47. package/dist/crypto/BrowserCrypto.d.ts +44 -44
  48. package/dist/crypto/BrowserCrypto.mjs +93 -93
  49. package/dist/crypto/CryptoOps.d.ts +63 -63
  50. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  51. package/dist/crypto/CryptoOps.mjs +145 -144
  52. package/dist/crypto/CryptoOps.mjs.map +1 -1
  53. package/dist/crypto/PkceGenerator.d.ts +8 -8
  54. package/dist/crypto/PkceGenerator.mjs +54 -54
  55. package/dist/crypto/SignedHttpRequest.d.ts +30 -30
  56. package/dist/crypto/SignedHttpRequest.mjs +39 -39
  57. package/dist/encode/Base64Decode.d.ts +9 -9
  58. package/dist/encode/Base64Decode.mjs +36 -36
  59. package/dist/encode/Base64Encode.d.ts +19 -19
  60. package/dist/encode/Base64Encode.mjs +43 -43
  61. package/dist/error/BrowserAuthError.d.ts +250 -250
  62. package/dist/error/BrowserAuthError.mjs +258 -258
  63. package/dist/error/BrowserAuthErrorCodes.d.ts +45 -45
  64. package/dist/error/BrowserAuthErrorCodes.mjs +49 -49
  65. package/dist/error/BrowserConfigurationAuthError.d.ts +33 -33
  66. package/dist/error/BrowserConfigurationAuthError.mjs +40 -40
  67. package/dist/error/BrowserConfigurationAuthErrorCodes.d.ts +3 -3
  68. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +7 -7
  69. package/dist/error/NativeAuthError.d.ts +29 -29
  70. package/dist/error/NativeAuthError.mjs +60 -60
  71. package/dist/error/NativeAuthErrorCodes.d.ts +2 -2
  72. package/dist/error/NativeAuthErrorCodes.mjs +6 -6
  73. package/dist/error/NestedAppAuthError.d.ts +14 -14
  74. package/dist/error/NestedAppAuthError.mjs +23 -23
  75. package/dist/event/EventHandler.d.ts +41 -41
  76. package/dist/event/EventHandler.mjs +119 -119
  77. package/dist/event/EventMessage.d.ts +25 -25
  78. package/dist/event/EventMessage.mjs +68 -68
  79. package/dist/event/EventType.d.ts +28 -28
  80. package/dist/event/EventType.mjs +31 -31
  81. package/dist/index.d.ts +39 -39
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.mjs +2 -2
  84. package/dist/interaction_client/BaseInteractionClient.d.ts +54 -55
  85. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  86. package/dist/interaction_client/BaseInteractionClient.mjs +152 -153
  87. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  88. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.d.ts +4 -4
  89. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +10 -10
  90. package/dist/interaction_client/NativeInteractionClient.d.ts +140 -140
  91. package/dist/interaction_client/NativeInteractionClient.mjs +548 -548
  92. package/dist/interaction_client/PopupClient.d.ts +105 -115
  93. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  94. package/dist/interaction_client/PopupClient.mjs +435 -505
  95. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  96. package/dist/interaction_client/RedirectClient.d.ts +49 -49
  97. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  98. package/dist/interaction_client/RedirectClient.mjs +314 -297
  99. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  100. package/dist/interaction_client/SilentAuthCodeClient.d.ts +23 -23
  101. package/dist/interaction_client/SilentAuthCodeClient.mjs +57 -57
  102. package/dist/interaction_client/SilentCacheClient.d.ts +24 -24
  103. package/dist/interaction_client/SilentCacheClient.mjs +61 -61
  104. package/dist/interaction_client/SilentIframeClient.d.ts +32 -32
  105. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  106. package/dist/interaction_client/SilentIframeClient.mjs +99 -108
  107. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  108. package/dist/interaction_client/SilentRefreshClient.d.ts +20 -20
  109. package/dist/interaction_client/SilentRefreshClient.mjs +43 -43
  110. package/dist/interaction_client/StandardInteractionClient.d.ts +54 -59
  111. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  112. package/dist/interaction_client/StandardInteractionClient.mjs +222 -244
  113. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  114. package/dist/interaction_handler/InteractionHandler.d.ts +33 -33
  115. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  116. package/dist/interaction_handler/InteractionHandler.mjs +94 -98
  117. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  118. package/dist/interaction_handler/RedirectHandler.d.ts +32 -32
  119. package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
  120. package/dist/interaction_handler/RedirectHandler.mjs +135 -139
  121. package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
  122. package/dist/interaction_handler/SilentHandler.d.ts +13 -13
  123. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  124. package/dist/interaction_handler/SilentHandler.mjs +134 -128
  125. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  126. package/dist/naa/AccountInfo.d.ts +11 -12
  127. package/dist/naa/AccountInfo.d.ts.map +1 -1
  128. package/dist/naa/AccountRequests.d.ts +9 -9
  129. package/dist/naa/AuthBridge.d.ts +5 -5
  130. package/dist/naa/BridgeCapabilities.d.ts +3 -3
  131. package/dist/naa/BridgeError.d.ts +9 -9
  132. package/dist/naa/BridgeError.d.ts.map +1 -1
  133. package/dist/naa/BridgeError.mjs +7 -7
  134. package/dist/naa/BridgeError.mjs.map +1 -1
  135. package/dist/naa/BridgeProxy.d.ts +72 -71
  136. package/dist/naa/BridgeProxy.d.ts.map +1 -1
  137. package/dist/naa/BridgeProxy.mjs +152 -149
  138. package/dist/naa/BridgeProxy.mjs.map +1 -1
  139. package/dist/naa/BridgeRequest.d.ts +6 -6
  140. package/dist/naa/BridgeRequestEnvelope.d.ts +13 -13
  141. package/dist/naa/BridgeResponseEnvelope.d.ts +10 -10
  142. package/dist/naa/BridgeStatusCode.d.ts +10 -10
  143. package/dist/naa/BridgeStatusCode.mjs +15 -15
  144. package/dist/naa/IBridgeProxy.d.ts +12 -10
  145. package/dist/naa/IBridgeProxy.d.ts.map +1 -1
  146. package/dist/naa/InitializeBridgeResponse.d.ts +6 -6
  147. package/dist/naa/InitializeBridgeResponse.d.ts.map +1 -1
  148. package/dist/naa/TokenRequest.d.ts +19 -21
  149. package/dist/naa/TokenRequest.d.ts.map +1 -1
  150. package/dist/naa/TokenResponse.d.ts +15 -16
  151. package/dist/naa/TokenResponse.d.ts.map +1 -1
  152. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts +23 -25
  153. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  154. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +142 -170
  155. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  156. package/dist/navigation/INavigationClient.d.ts +16 -16
  157. package/dist/navigation/NavigationClient.d.ts +22 -22
  158. package/dist/navigation/NavigationClient.mjs +40 -40
  159. package/dist/navigation/NavigationOptions.d.ts +12 -12
  160. package/dist/network/FetchClient.d.ts +26 -26
  161. package/dist/network/FetchClient.mjs +99 -99
  162. package/dist/operatingcontext/BaseOperatingContext.d.ts +40 -40
  163. package/dist/operatingcontext/BaseOperatingContext.mjs +44 -44
  164. package/dist/operatingcontext/StandardOperatingContext.d.ts +25 -25
  165. package/dist/operatingcontext/StandardOperatingContext.mjs +43 -43
  166. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts +32 -32
  167. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts.map +1 -1
  168. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +85 -82
  169. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +1 -1
  170. package/dist/operatingcontext/UnknownOperatingContext.d.ts +25 -25
  171. package/dist/operatingcontext/UnknownOperatingContext.mjs +42 -42
  172. package/dist/packageMetadata.d.ts +2 -2
  173. package/dist/packageMetadata.mjs +4 -4
  174. package/dist/request/AuthorizationCodeRequest.d.ts +8 -8
  175. package/dist/request/AuthorizationUrlRequest.d.ts +8 -8
  176. package/dist/request/ClearCacheRequest.d.ts +10 -10
  177. package/dist/request/EndSessionPopupRequest.d.ts +18 -18
  178. package/dist/request/EndSessionRequest.d.ts +15 -15
  179. package/dist/request/PopupRequest.d.ts +34 -34
  180. package/dist/request/PopupWindowAttributes.d.ts +15 -15
  181. package/dist/request/RedirectRequest.d.ts +35 -35
  182. package/dist/request/SilentRequest.d.ts +32 -32
  183. package/dist/request/SsoSilentRequest.d.ts +29 -29
  184. package/dist/response/AuthenticationResult.d.ts +4 -4
  185. package/dist/response/ResponseHandler.d.ts +8 -0
  186. package/dist/response/ResponseHandler.d.ts.map +1 -0
  187. package/dist/response/ResponseHandler.mjs +46 -0
  188. package/dist/response/ResponseHandler.mjs.map +1 -0
  189. package/dist/telemetry/BrowserPerformanceClient.d.ts +36 -36
  190. package/dist/telemetry/BrowserPerformanceClient.mjs +125 -125
  191. package/dist/telemetry/BrowserPerformanceMeasurement.d.ts +21 -21
  192. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +92 -92
  193. package/dist/utils/BrowserConstants.d.ts +176 -176
  194. package/dist/utils/BrowserConstants.mjs +204 -204
  195. package/dist/utils/BrowserProtocolUtils.d.ts +11 -18
  196. package/dist/utils/BrowserProtocolUtils.d.ts.map +1 -1
  197. package/dist/utils/BrowserProtocolUtils.mjs +23 -36
  198. package/dist/utils/BrowserProtocolUtils.mjs.map +1 -1
  199. package/dist/utils/BrowserUtils.d.ts +56 -56
  200. package/dist/utils/BrowserUtils.mjs +125 -125
  201. package/lib/msal-browser.cjs +17926 -18062
  202. package/lib/msal-browser.cjs.map +1 -1
  203. package/lib/msal-browser.js +17926 -18062
  204. package/lib/msal-browser.js.map +1 -1
  205. package/lib/msal-browser.min.js +66 -65
  206. package/package.json +102 -102
  207. package/src/cache/BrowserCacheManager.ts +7 -10
  208. package/src/controllers/NestedAppAuthController.ts +8 -3
  209. package/src/controllers/StandardController.ts +31 -40
  210. package/src/crypto/CryptoOps.ts +5 -3
  211. package/src/index.ts +1 -0
  212. package/src/interaction_client/BaseInteractionClient.ts +1 -2
  213. package/src/interaction_client/PopupClient.ts +34 -137
  214. package/src/interaction_client/RedirectClient.ts +71 -55
  215. package/src/interaction_client/SilentIframeClient.ts +16 -27
  216. package/src/interaction_client/StandardInteractionClient.ts +2 -48
  217. package/src/interaction_handler/InteractionHandler.ts +5 -8
  218. package/src/interaction_handler/RedirectHandler.ts +4 -8
  219. package/src/interaction_handler/SilentHandler.ts +12 -5
  220. package/src/naa/AccountInfo.ts +3 -4
  221. package/src/naa/BridgeError.ts +4 -4
  222. package/src/naa/BridgeProxy.ts +6 -2
  223. package/src/naa/IBridgeProxy.ts +2 -0
  224. package/src/naa/InitializeBridgeResponse.ts +1 -1
  225. package/src/naa/TokenRequest.ts +0 -2
  226. package/src/naa/TokenResponse.ts +1 -2
  227. package/src/naa/mapping/NestedAppAuthAdapter.ts +72 -80
  228. package/src/operatingcontext/TeamsAppOperatingContext.ts +4 -1
  229. package/src/packageMetadata.ts +1 -1
  230. package/src/response/ResponseHandler.ts +73 -0
  231. package/src/utils/BrowserProtocolUtils.ts +17 -36
@@ -11,9 +11,7 @@ import {
11
11
  UrlString,
12
12
  AuthError,
13
13
  OIDC_DEFAULT_SCOPES,
14
- Constants,
15
14
  ProtocolUtils,
16
- ServerAuthorizationCodeResponse,
17
15
  PerformanceEvents,
18
16
  IPerformanceClient,
19
17
  Logger,
@@ -21,6 +19,7 @@ import {
21
19
  ProtocolMode,
22
20
  ServerResponseType,
23
21
  invokeAsync,
22
+ invoke,
24
23
  } from "@azure/msal-common";
25
24
  import { StandardInteractionClient } from "./StandardInteractionClient";
26
25
  import { EventType } from "../event/EventType";
@@ -47,6 +46,7 @@ import { InteractionHandler } from "../interaction_handler/InteractionHandler";
47
46
  import { PopupWindowAttributes } from "../request/PopupWindowAttributes";
48
47
  import { EventError } from "../event/EventMessage";
49
48
  import { AuthenticationResult } from "../response/AuthenticationResult";
49
+ import * as ResponseHandler from "../response/ResponseHandler";
50
50
 
51
51
  export type PopupParams = {
52
52
  popup?: Window | null;
@@ -284,10 +284,19 @@ export class PopupClient extends StandardInteractionClient {
284
284
  );
285
285
 
286
286
  // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
287
- const hash = await this.monitorPopupForHash(popupWindow);
288
- // Deserialize hash fragment response parameters.
289
- const serverParams: ServerAuthorizationCodeResponse =
290
- UrlString.getDeserializedHash(hash);
287
+ const responseString = await this.monitorPopupForHash(popupWindow);
288
+
289
+ const serverParams = invoke(
290
+ ResponseHandler.deserializeResponse,
291
+ PerformanceEvents.DeserializeResponse,
292
+ this.logger,
293
+ this.performanceClient,
294
+ this.correlationId
295
+ )(
296
+ responseString,
297
+ this.config.auth.OIDCOptions.serverResponseType,
298
+ this.logger
299
+ );
291
300
  // Remove throttle if it exists
292
301
  ThrottlingUtils.removeThrottle(
293
302
  this.browserStorage,
@@ -338,8 +347,8 @@ export class PopupClient extends StandardInteractionClient {
338
347
  }
339
348
 
340
349
  // Handle response from hash string.
341
- const result = await interactionHandler.handleCodeResponseFromHash(
342
- hash,
350
+ const result = await interactionHandler.handleCodeResponse(
351
+ serverParams,
343
352
  validRequest
344
353
  );
345
354
 
@@ -464,7 +473,9 @@ export class PopupClient extends StandardInteractionClient {
464
473
  null
465
474
  );
466
475
 
467
- await this.waitForLogoutPopup(popupWindow);
476
+ await this.monitorPopupForHash(popupWindow).catch(() => {
477
+ // Swallow any errors related to monitoring the window. Server logout is best effort
478
+ });
468
479
 
469
480
  if (mainWindowRedirectUri) {
470
481
  const navigationOptions: NavigationOptions = {
@@ -545,16 +556,7 @@ export class PopupClient extends StandardInteractionClient {
545
556
  * @param timeout - timeout for processing hash once popup is redirected back to application
546
557
  */
547
558
  monitorPopupForHash(popupWindow: Window): Promise<string> {
548
- return new Promise((resolve, reject) => {
549
- /*
550
- * Polling for popups needs to be tick-based,
551
- * since a non-trivial amount of time can be spent on interaction (which should not count against the timeout).
552
- */
553
- const maxTicks =
554
- this.config.system.windowHashTimeout /
555
- this.config.system.pollIntervalMilliseconds;
556
- let ticks = 0;
557
-
559
+ return new Promise<string>((resolve, reject) => {
558
560
  this.logger.verbose(
559
561
  "PopupHandler.monitorPopupForHash - polling started"
560
562
  );
@@ -565,7 +567,6 @@ export class PopupClient extends StandardInteractionClient {
565
567
  this.logger.error(
566
568
  "PopupHandler.monitorPopupForHash - window closed"
567
569
  );
568
- this.cleanPopup();
569
570
  clearInterval(intervalId);
570
571
  reject(
571
572
  createBrowserAuthError(
@@ -575,8 +576,7 @@ export class PopupClient extends StandardInteractionClient {
575
576
  return;
576
577
  }
577
578
 
578
- let href = Constants.EMPTY_STRING;
579
- let serverResponseString = Constants.EMPTY_STRING;
579
+ let href = "";
580
580
  try {
581
581
  /*
582
582
  * Will throw if cross origin,
@@ -584,117 +584,33 @@ export class PopupClient extends StandardInteractionClient {
584
584
  * since we need the interval to keep running while on STS UI.
585
585
  */
586
586
  href = popupWindow.location.href;
587
- serverResponseString =
588
- this.extractServerResponseStringFromPopup(
589
- popupWindow,
590
- href
591
- );
592
587
  } catch (e) {}
593
588
 
594
589
  // Don't process blank pages or cross domain
595
590
  if (!href || href === "about:blank") {
596
591
  return;
597
592
  }
593
+ clearInterval(intervalId);
598
594
 
599
- this.logger.verbose(
600
- "PopupHandler.monitorPopupForHash - popup window is on same origin as caller"
601
- );
602
-
603
- /*
604
- * Only run clock when we are on same domain for popups
605
- * as popup operations can take a long time.
606
- */
607
- ticks++;
608
-
609
- if (serverResponseString) {
610
- this.logger.verbose(
611
- "PopupHandler.monitorPopupForHash - found hash in url"
612
- );
613
- clearInterval(intervalId);
614
- this.cleanPopup(popupWindow);
615
-
616
- if (
617
- UrlString.hashContainsKnownProperties(
618
- serverResponseString
619
- )
620
- ) {
621
- this.logger.verbose(
622
- "PopupHandler.monitorPopupForHash - hash contains known properties, returning."
623
- );
624
- resolve(serverResponseString);
595
+ let responseString = "";
596
+ const responseType =
597
+ this.config.auth.OIDCOptions.serverResponseType;
598
+ if (popupWindow) {
599
+ if (responseType === ServerResponseType.QUERY) {
600
+ responseString = popupWindow.location.search;
625
601
  } else {
626
- this.logger.error(
627
- "PopupHandler.monitorPopupForHash - found hash in url but it does not contain known properties. Check that your router is not changing the hash prematurely."
628
- );
629
- this.logger.errorPii(
630
- `PopupHandler.monitorPopupForHash - hash found: ${serverResponseString}`
631
- );
632
- reject(
633
- createBrowserAuthError(
634
- BrowserAuthErrorCodes.hashDoesNotContainKnownProperties
635
- )
636
- );
602
+ responseString = popupWindow.location.hash;
637
603
  }
638
- } else if (ticks > maxTicks) {
639
- this.logger.error(
640
- "PopupHandler.monitorPopupForHash - unable to find hash in url, timing out"
641
- );
642
- clearInterval(intervalId);
643
- reject(
644
- createBrowserAuthError(
645
- BrowserAuthErrorCodes.monitorPopupTimeout
646
- )
647
- );
648
- }
649
- }, this.config.system.pollIntervalMilliseconds);
650
- });
651
- }
652
-
653
- /**
654
- * Waits for user interaction in logout popup window
655
- * @param popupWindow
656
- * @returns
657
- */
658
- waitForLogoutPopup(popupWindow: Window): Promise<void> {
659
- return new Promise((resolve) => {
660
- this.logger.verbose(
661
- "PopupHandler.waitForLogoutPopup - polling started"
662
- );
663
-
664
- const intervalId = setInterval(() => {
665
- // Window is closed
666
- if (popupWindow.closed) {
667
- this.logger.error(
668
- "PopupHandler.waitForLogoutPopup - window closed"
669
- );
670
- this.cleanPopup();
671
- clearInterval(intervalId);
672
- resolve();
673
- }
674
-
675
- let href: string = Constants.EMPTY_STRING;
676
- try {
677
- /*
678
- * Will throw if cross origin,
679
- * which should be caught and ignored
680
- * since we need the interval to keep running while on STS UI.
681
- */
682
- href = popupWindow.location.href;
683
- } catch (e) {}
684
-
685
- // Don't process blank pages or cross domain
686
- if (!href || href === "about:blank") {
687
- return;
688
604
  }
689
605
 
690
606
  this.logger.verbose(
691
- "PopupHandler.waitForLogoutPopup - popup window is on same origin as caller, closing."
607
+ "PopupHandler.monitorPopupForHash - popup window is on same origin as caller"
692
608
  );
693
609
 
694
- clearInterval(intervalId);
695
- this.cleanPopup(popupWindow);
696
- resolve();
610
+ resolve(responseString);
697
611
  }, this.config.system.pollIntervalMilliseconds);
612
+ }).finally(() => {
613
+ this.cleanPopup(popupWindow);
698
614
  });
699
615
  }
700
616
 
@@ -884,23 +800,4 @@ export class PopupClient extends StandardInteractionClient {
884
800
  const homeAccountId = request.account && request.account.homeAccountId;
885
801
  return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${homeAccountId}.${this.correlationId}`;
886
802
  }
887
-
888
- /**
889
- * Extracts the server response from the popup window
890
- */
891
- extractServerResponseStringFromPopup(
892
- popupWindow: Window,
893
- href: string
894
- ): string {
895
- let serverResponseString;
896
- if (
897
- this.config.auth.OIDCOptions?.serverResponseType ===
898
- ServerResponseType.QUERY
899
- ) {
900
- serverResponseString = UrlString.parseQueryServerResponse(href);
901
- } else {
902
- serverResponseString = popupWindow.location.hash;
903
- }
904
- return serverResponseString;
905
- }
906
803
  }
@@ -19,6 +19,8 @@ import {
19
19
  PerformanceEvents,
20
20
  ProtocolMode,
21
21
  invokeAsync,
22
+ ServerResponseType,
23
+ UrlUtils,
22
24
  } from "@azure/msal-common";
23
25
  import { StandardInteractionClient } from "./StandardInteractionClient";
24
26
  import {
@@ -44,6 +46,7 @@ import { EventHandler } from "../event/EventHandler";
44
46
  import { INavigationClient } from "../navigation/INavigationClient";
45
47
  import { EventError } from "../event/EventMessage";
46
48
  import { AuthenticationResult } from "../response/AuthenticationResult";
49
+ import * as ResponseHandler from "../response/ResponseHandler";
47
50
 
48
51
  export class RedirectClient extends StandardInteractionClient {
49
52
  protected nativeStorage: BrowserCacheManager;
@@ -201,33 +204,13 @@ export class RedirectClient extends StandardInteractionClient {
201
204
  );
202
205
  return null;
203
206
  }
204
- const responseHash = this.getRedirectResponseHash(
205
- hash || window.location.hash
207
+ const [serverParams, responseString] = this.getRedirectResponse(
208
+ hash || ""
206
209
  );
207
- if (!responseHash) {
210
+ if (!serverParams) {
208
211
  // Not a recognized server response hash or hash not associated with a redirect request
209
212
  this.logger.info(
210
- "handleRedirectPromise did not detect a response hash as a result of a redirect. Cleaning temporary cache."
211
- );
212
- this.browserStorage.cleanRequestByInteractionType(
213
- InteractionType.Redirect
214
- );
215
- return null;
216
- }
217
-
218
- let state: string;
219
- try {
220
- // Deserialize hash fragment response parameters.
221
- const serverParams: ServerAuthorizationCodeResponse =
222
- UrlString.getDeserializedHash(responseHash);
223
- state = this.validateAndExtractStateFromHash(
224
- serverParams,
225
- InteractionType.Redirect
226
- );
227
- this.logger.verbose("State extracted from hash");
228
- } catch (e) {
229
- this.logger.info(
230
- `handleRedirectPromise was unable to extract state due to: ${e}`
213
+ "handleRedirectPromise did not detect a response as a result of a redirect. Cleaning temporary cache."
231
214
  );
232
215
  this.browserStorage.cleanRequestByInteractionType(
233
216
  InteractionType.Redirect
@@ -253,12 +236,7 @@ export class RedirectClient extends StandardInteractionClient {
253
236
  ) {
254
237
  // We are on the page we need to navigate to - handle hash
255
238
  this.logger.verbose(
256
- "Current page is loginRequestUrl, handling hash"
257
- );
258
- const handleHashResult = await this.handleHash(
259
- responseHash,
260
- state,
261
- serverTelemetryManager
239
+ "Current page is loginRequestUrl, handling response"
262
240
  );
263
241
 
264
242
  if (loginRequestUrl.indexOf("#") > -1) {
@@ -266,14 +244,18 @@ export class RedirectClient extends StandardInteractionClient {
266
244
  BrowserUtils.replaceHash(loginRequestUrl);
267
245
  }
268
246
 
247
+ const handleHashResult = await this.handleResponse(
248
+ serverParams,
249
+ serverTelemetryManager
250
+ );
251
+
269
252
  return handleHashResult;
270
253
  } else if (!this.config.auth.navigateToLoginRequestUrl) {
271
254
  this.logger.verbose(
272
- "NavigateToLoginRequestUrl set to false, handling hash"
255
+ "NavigateToLoginRequestUrl set to false, handling response"
273
256
  );
274
- return this.handleHash(
275
- responseHash,
276
- state,
257
+ return this.handleResponse(
258
+ serverParams,
277
259
  serverTelemetryManager
278
260
  );
279
261
  } else if (
@@ -286,7 +268,7 @@ export class RedirectClient extends StandardInteractionClient {
286
268
  */
287
269
  this.browserStorage.setTemporaryCache(
288
270
  TemporaryCacheKeys.URL_HASH,
289
- responseHash,
271
+ responseString,
290
272
  true
291
273
  );
292
274
  const navigationOptions: NavigationOptions = {
@@ -331,9 +313,8 @@ export class RedirectClient extends StandardInteractionClient {
331
313
 
332
314
  // If navigateInternal implementation returns false, handle the hash now
333
315
  if (!processHashOnRedirect) {
334
- return this.handleHash(
335
- responseHash,
336
- state,
316
+ return this.handleResponse(
317
+ serverParams,
337
318
  serverTelemetryManager
338
319
  );
339
320
  }
@@ -357,18 +338,45 @@ export class RedirectClient extends StandardInteractionClient {
357
338
  * Returns null if interactionType in the state value is not "redirect" or the hash does not contain known properties
358
339
  * @param hash
359
340
  */
360
- protected getRedirectResponseHash(hash: string): string | null {
341
+ protected getRedirectResponse(
342
+ userProvidedResponse: string
343
+ ): [ServerAuthorizationCodeResponse | null, string] {
361
344
  this.logger.verbose("getRedirectResponseHash called");
362
345
  // Get current location hash from window or cache.
363
- const isResponseHash: boolean =
364
- UrlString.hashContainsKnownProperties(hash);
346
+ let responseString = userProvidedResponse;
347
+ if (!responseString) {
348
+ if (
349
+ this.config.auth.OIDCOptions.serverResponseType ===
350
+ ServerResponseType.QUERY
351
+ ) {
352
+ responseString = window.location.search;
353
+ } else {
354
+ responseString = window.location.hash;
355
+ }
356
+ }
357
+ let response = UrlUtils.getDeserializedResponse(responseString);
358
+
359
+ if (response) {
360
+ try {
361
+ ResponseHandler.validateInteractionType(
362
+ response,
363
+ this.browserCrypto,
364
+ InteractionType.Redirect
365
+ );
366
+ } catch (e) {
367
+ if (e instanceof AuthError) {
368
+ this.logger.error(
369
+ `Interaction type validation failed due to ${e.errorCode}: ${e.errorMessage}`
370
+ );
371
+ }
372
+ return [null, ""];
373
+ }
365
374
 
366
- if (isResponseHash) {
367
375
  BrowserUtils.clearHash(window);
368
376
  this.logger.verbose(
369
377
  "Hash contains known properties, returning response hash"
370
378
  );
371
- return hash;
379
+ return [response, responseString];
372
380
  }
373
381
 
374
382
  const cachedHash = this.browserStorage.getTemporaryCache(
@@ -379,10 +387,17 @@ export class RedirectClient extends StandardInteractionClient {
379
387
  this.browserStorage.generateCacheKey(TemporaryCacheKeys.URL_HASH)
380
388
  );
381
389
 
382
- this.logger.verbose(
383
- "Hash does not contain known properties, returning cached hash"
384
- );
385
- return cachedHash;
390
+ if (cachedHash) {
391
+ response = UrlUtils.getDeserializedResponse(cachedHash);
392
+ if (response) {
393
+ this.logger.verbose(
394
+ "Hash does not contain known properties, returning cached hash"
395
+ );
396
+ return [response, cachedHash];
397
+ }
398
+ }
399
+
400
+ return [null, ""];
386
401
  }
387
402
 
388
403
  /**
@@ -390,16 +405,17 @@ export class RedirectClient extends StandardInteractionClient {
390
405
  * @param hash
391
406
  * @param state
392
407
  */
393
- protected async handleHash(
394
- hash: string,
395
- state: string,
408
+ protected async handleResponse(
409
+ serverParams: ServerAuthorizationCodeResponse,
396
410
  serverTelemetryManager: ServerTelemetryManager
397
411
  ): Promise<AuthenticationResult> {
398
- const cachedRequest = this.browserStorage.getCachedRequest(state);
399
- this.logger.verbose("handleHash called, retrieved cached request");
412
+ const state = serverParams.state;
413
+ if (!state) {
414
+ throw createBrowserAuthError(BrowserAuthErrorCodes.noStateInHash);
415
+ }
400
416
 
401
- const serverParams: ServerAuthorizationCodeResponse =
402
- UrlString.getDeserializedHash(hash);
417
+ const cachedRequest = this.browserStorage.getCachedRequest(state);
418
+ this.logger.verbose("handleResponse called, retrieved cached request");
403
419
 
404
420
  if (serverParams.accountId) {
405
421
  this.logger.verbose(
@@ -467,7 +483,7 @@ export class RedirectClient extends StandardInteractionClient {
467
483
  this.logger,
468
484
  this.performanceClient
469
485
  );
470
- return await interactionHandler.handleCodeResponseFromHash(hash, state);
486
+ return await interactionHandler.handleCodeResponse(serverParams, state);
471
487
  }
472
488
 
473
489
  /**
@@ -10,12 +10,11 @@ import {
10
10
  CommonAuthorizationCodeRequest,
11
11
  AuthorizationCodeClient,
12
12
  AuthError,
13
- UrlString,
14
- ServerAuthorizationCodeResponse,
15
13
  ProtocolUtils,
16
14
  IPerformanceClient,
17
15
  PerformanceEvents,
18
16
  invokeAsync,
17
+ invoke,
19
18
  } from "@azure/msal-common";
20
19
  import { StandardInteractionClient } from "./StandardInteractionClient";
21
20
  import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest";
@@ -38,6 +37,7 @@ import { NativeInteractionClient } from "./NativeInteractionClient";
38
37
  import { AuthenticationResult } from "../response/AuthenticationResult";
39
38
  import { InteractionHandler } from "../interaction_handler/InteractionHandler";
40
39
  import * as BrowserUtils from "../utils/BrowserUtils";
40
+ import * as ResponseHandler from "../response/ResponseHandler";
41
41
 
42
42
  export class SilentIframeClient extends StandardInteractionClient {
43
43
  protected apiId: ApiId;
@@ -231,8 +231,9 @@ export class SilentIframeClient extends StandardInteractionClient {
231
231
  correlationId,
232
232
  this.config.system.navigateFrameWait
233
233
  );
234
+ const responseType = this.config.auth.OIDCOptions.serverResponseType;
234
235
  // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
235
- const hash = await invokeAsync(
236
+ const responseString = await invokeAsync(
236
237
  monitorIframeForHash,
237
238
  PerformanceEvents.SilentHandlerMonitorIframeForHash,
238
239
  this.logger,
@@ -244,26 +245,16 @@ export class SilentIframeClient extends StandardInteractionClient {
244
245
  this.config.system.pollIntervalMilliseconds,
245
246
  this.performanceClient,
246
247
  this.logger,
247
- correlationId
248
+ correlationId,
249
+ responseType
248
250
  );
249
- if (!hash) {
250
- // No hash is present
251
- this.logger.error(
252
- "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."
253
- );
254
- throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError);
255
- } else if (!UrlString.hashContainsKnownProperties(hash)) {
256
- this.logger.error(
257
- "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."
258
- );
259
- this.logger.errorPii(`The hash detected in the iframe is: ${hash}`);
260
- throw createBrowserAuthError(
261
- BrowserAuthErrorCodes.hashDoesNotContainKnownProperties
262
- );
263
- }
264
- // Deserialize hash fragment response parameters.
265
- const serverParams: ServerAuthorizationCodeResponse =
266
- UrlString.getDeserializedHash(hash);
251
+ const serverParams = invoke(
252
+ ResponseHandler.deserializeResponse,
253
+ PerformanceEvents.DeserializeResponse,
254
+ this.logger,
255
+ this.performanceClient,
256
+ this.correlationId
257
+ )(responseString, responseType, this.logger);
267
258
 
268
259
  if (serverParams.accountId) {
269
260
  this.logger.verbose(
@@ -309,13 +300,11 @@ export class SilentIframeClient extends StandardInteractionClient {
309
300
 
310
301
  // Handle response from hash string
311
302
  return invokeAsync(
312
- interactionHandler.handleCodeResponseFromHash.bind(
313
- interactionHandler
314
- ),
315
- PerformanceEvents.HandleCodeResponseFromHash,
303
+ interactionHandler.handleCodeResponse.bind(interactionHandler),
304
+ PerformanceEvents.HandleCodeResponse,
316
305
  this.logger,
317
306
  this.performanceClient,
318
307
  correlationId
319
- )(hash, silentRequest);
308
+ )(serverParams, silentRequest);
320
309
  }
321
310
  }
@@ -12,7 +12,6 @@ import {
12
12
  AuthorityOptions,
13
13
  Authority,
14
14
  AuthorityFactory,
15
- ServerAuthorizationCodeResponse,
16
15
  UrlString,
17
16
  CommonEndSessionRequest,
18
17
  ProtocolUtils,
@@ -28,14 +27,7 @@ import { BaseInteractionClient } from "./BaseInteractionClient";
28
27
  import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest";
29
28
  import { BrowserConstants, InteractionType } from "../utils/BrowserConstants";
30
29
  import { version } from "../packageMetadata";
31
- import {
32
- createBrowserAuthError,
33
- BrowserAuthErrorCodes,
34
- } from "../error/BrowserAuthError";
35
- import {
36
- BrowserProtocolUtils,
37
- BrowserStateObject,
38
- } from "../utils/BrowserProtocolUtils";
30
+ import { BrowserStateObject } from "../utils/BrowserProtocolUtils";
39
31
  import { EndSessionRequest } from "../request/EndSessionRequest";
40
32
  import * as BrowserUtils from "../utils/BrowserUtils";
41
33
  import { RedirectRequest } from "../request/RedirectRequest";
@@ -57,7 +49,7 @@ export abstract class StandardInteractionClient extends BaseInteractionClient {
57
49
  ): Promise<CommonAuthorizationCodeRequest> {
58
50
  this.performanceClient.addQueueMeasurement(
59
51
  PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
60
- request.correlationId
52
+ this.correlationId
61
53
  );
62
54
  const generatedPkceParams = await invokeAsync(
63
55
  generatePkceCodes,
@@ -294,44 +286,6 @@ export abstract class StandardInteractionClient extends BaseInteractionClient {
294
286
  };
295
287
  }
296
288
 
297
- /**
298
- * @param hash
299
- * @param interactionType
300
- */
301
- protected validateAndExtractStateFromHash(
302
- serverParams: ServerAuthorizationCodeResponse,
303
- interactionType: InteractionType,
304
- requestCorrelationId?: string
305
- ): string {
306
- this.logger.verbose(
307
- "validateAndExtractStateFromHash called",
308
- requestCorrelationId
309
- );
310
- if (!serverParams.state) {
311
- throw createBrowserAuthError(BrowserAuthErrorCodes.noStateInHash);
312
- }
313
-
314
- const platformStateObj =
315
- BrowserProtocolUtils.extractBrowserRequestState(
316
- this.browserCrypto,
317
- serverParams.state
318
- );
319
- if (!platformStateObj) {
320
- throw createBrowserAuthError(
321
- BrowserAuthErrorCodes.unableToParseState
322
- );
323
- }
324
-
325
- if (platformStateObj.interactionType !== interactionType) {
326
- throw createBrowserAuthError(
327
- BrowserAuthErrorCodes.stateInteractionTypeMismatch
328
- );
329
- }
330
-
331
- this.logger.verbose("Returning state from hash", requestCorrelationId);
332
- return serverParams.state;
333
- }
334
-
335
289
  /**
336
290
  * Used to get a discovered version of the default authority.
337
291
  * @param requestAuthority
@@ -14,6 +14,7 @@ import {
14
14
  PerformanceEvents,
15
15
  invokeAsync,
16
16
  CcsCredentialType,
17
+ ServerAuthorizationCodeResponse,
17
18
  } from "@azure/msal-common";
18
19
 
19
20
  import { BrowserCacheManager } from "../cache/BrowserCacheManager";
@@ -52,23 +53,19 @@ export class InteractionHandler {
52
53
  * Function to handle response parameters from hash.
53
54
  * @param locationHash
54
55
  */
55
- async handleCodeResponseFromHash(
56
- locationHash: string,
56
+ async handleCodeResponse(
57
+ response: ServerAuthorizationCodeResponse,
57
58
  request: AuthorizationUrlRequest
58
59
  ): Promise<AuthenticationResult> {
59
60
  this.performanceClient.addQueueMeasurement(
60
- PerformanceEvents.HandleCodeResponseFromHash,
61
+ PerformanceEvents.HandleCodeResponse,
61
62
  request.correlationId
62
63
  );
63
- // Check that location hash isn't empty.
64
- if (!locationHash) {
65
- throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError);
66
- }
67
64
 
68
65
  let authCodeResponse;
69
66
  try {
70
67
  authCodeResponse = this.authModule.handleFragmentResponse(
71
- locationHash,
68
+ response,
72
69
  request.state
73
70
  );
74
71
  } catch (e) {