@azure/msal-browser 3.4.0 → 3.5.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 (124) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +1 -1
  3. package/dist/app/PublicClientNext.mjs +1 -1
  4. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  5. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  6. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  7. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  8. package/dist/cache/BrowserCacheManager.mjs +8 -8
  9. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  10. package/dist/cache/BrowserStorage.mjs +1 -1
  11. package/dist/cache/CryptoKeyStore.mjs +1 -1
  12. package/dist/cache/DatabaseStorage.mjs +1 -1
  13. package/dist/cache/MemoryStorage.mjs +1 -1
  14. package/dist/cache/TokenCache.mjs +1 -1
  15. package/dist/config/Configuration.mjs +1 -1
  16. package/dist/controllers/ControllerFactory.mjs +1 -1
  17. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  18. package/dist/controllers/StandardController.d.ts.map +1 -1
  19. package/dist/controllers/StandardController.mjs +23 -22
  20. package/dist/controllers/StandardController.mjs.map +1 -1
  21. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  22. package/dist/crypto/BrowserCrypto.mjs +1 -1
  23. package/dist/crypto/CryptoOps.d.ts +2 -2
  24. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  25. package/dist/crypto/CryptoOps.mjs +4 -3
  26. package/dist/crypto/CryptoOps.mjs.map +1 -1
  27. package/dist/crypto/PkceGenerator.mjs +1 -1
  28. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  29. package/dist/encode/Base64Decode.mjs +1 -1
  30. package/dist/encode/Base64Encode.mjs +1 -1
  31. package/dist/error/BrowserAuthError.mjs +1 -1
  32. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  33. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  34. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  35. package/dist/error/NativeAuthError.mjs +1 -1
  36. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  37. package/dist/error/NestedAppAuthError.mjs +1 -1
  38. package/dist/event/EventHandler.mjs +1 -1
  39. package/dist/event/EventMessage.mjs +1 -1
  40. package/dist/event/EventType.mjs +1 -1
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.mjs +2 -2
  44. package/dist/interaction_client/BaseInteractionClient.d.ts +0 -1
  45. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  46. package/dist/interaction_client/BaseInteractionClient.mjs +2 -3
  47. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  48. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  49. package/dist/interaction_client/NativeInteractionClient.mjs +1 -1
  50. package/dist/interaction_client/PopupClient.d.ts +0 -10
  51. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  52. package/dist/interaction_client/PopupClient.mjs +22 -92
  53. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  54. package/dist/interaction_client/RedirectClient.d.ts +3 -3
  55. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  56. package/dist/interaction_client/RedirectClient.mjs +51 -34
  57. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  58. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  59. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  60. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  61. package/dist/interaction_client/SilentIframeClient.mjs +8 -17
  62. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  63. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  64. package/dist/interaction_client/StandardInteractionClient.d.ts +1 -6
  65. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  66. package/dist/interaction_client/StandardInteractionClient.mjs +2 -24
  67. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  68. package/dist/interaction_handler/InteractionHandler.d.ts +2 -2
  69. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  70. package/dist/interaction_handler/InteractionHandler.mjs +5 -9
  71. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  72. package/dist/interaction_handler/RedirectHandler.d.ts +2 -2
  73. package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
  74. package/dist/interaction_handler/RedirectHandler.mjs +4 -8
  75. package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
  76. package/dist/interaction_handler/SilentHandler.d.ts +2 -2
  77. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  78. package/dist/interaction_handler/SilentHandler.mjs +13 -7
  79. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  80. package/dist/naa/BridgeError.mjs +1 -1
  81. package/dist/naa/BridgeProxy.mjs +1 -1
  82. package/dist/naa/BridgeStatusCode.mjs +1 -1
  83. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
  84. package/dist/navigation/NavigationClient.mjs +1 -1
  85. package/dist/network/FetchClient.mjs +1 -1
  86. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  87. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  88. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +1 -1
  89. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  90. package/dist/packageMetadata.d.ts +1 -1
  91. package/dist/packageMetadata.mjs +2 -2
  92. package/dist/response/ResponseHandler.d.ts +8 -0
  93. package/dist/response/ResponseHandler.d.ts.map +1 -0
  94. package/dist/response/ResponseHandler.mjs +46 -0
  95. package/dist/response/ResponseHandler.mjs.map +1 -0
  96. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  97. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  98. package/dist/utils/BrowserConstants.mjs +1 -1
  99. package/dist/utils/BrowserProtocolUtils.d.ts +7 -14
  100. package/dist/utils/BrowserProtocolUtils.d.ts.map +1 -1
  101. package/dist/utils/BrowserProtocolUtils.mjs +17 -30
  102. package/dist/utils/BrowserProtocolUtils.mjs.map +1 -1
  103. package/dist/utils/BrowserUtils.mjs +1 -1
  104. package/lib/msal-browser.cjs +360 -490
  105. package/lib/msal-browser.cjs.map +1 -1
  106. package/lib/msal-browser.js +360 -490
  107. package/lib/msal-browser.js.map +1 -1
  108. package/lib/msal-browser.min.js +66 -65
  109. package/package.json +2 -2
  110. package/src/cache/BrowserCacheManager.ts +7 -10
  111. package/src/controllers/StandardController.ts +28 -39
  112. package/src/crypto/CryptoOps.ts +5 -3
  113. package/src/index.ts +1 -0
  114. package/src/interaction_client/BaseInteractionClient.ts +1 -2
  115. package/src/interaction_client/PopupClient.ts +34 -137
  116. package/src/interaction_client/RedirectClient.ts +71 -55
  117. package/src/interaction_client/SilentIframeClient.ts +16 -27
  118. package/src/interaction_client/StandardInteractionClient.ts +2 -48
  119. package/src/interaction_handler/InteractionHandler.ts +5 -8
  120. package/src/interaction_handler/RedirectHandler.ts +4 -8
  121. package/src/interaction_handler/SilentHandler.ts +12 -5
  122. package/src/packageMetadata.ts +1 -1
  123. package/src/response/ResponseHandler.ts +73 -0
  124. package/src/utils/BrowserProtocolUtils.ts +17 -36
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "type": "git",
11
11
  "url": "https://github.com/AzureAD/microsoft-authentication-library-for-js.git"
12
12
  },
13
- "version": "3.4.0",
13
+ "version": "3.5.0",
14
14
  "description": "Microsoft Authentication Library for js",
15
15
  "keywords": [
16
16
  "implicit",
@@ -100,6 +100,6 @@
100
100
  "typescript": "^4.9.5"
101
101
  },
102
102
  "dependencies": {
103
- "@azure/msal-common": "14.3.0"
103
+ "@azure/msal-common": "14.4.0"
104
104
  }
105
105
  }
@@ -53,7 +53,7 @@ import {
53
53
  import { BrowserStorage } from "./BrowserStorage";
54
54
  import { MemoryStorage } from "./MemoryStorage";
55
55
  import { IWindowStorage } from "./IWindowStorage";
56
- import { BrowserProtocolUtils } from "../utils/BrowserProtocolUtils";
56
+ import { extractBrowserRequestState } from "../utils/BrowserProtocolUtils";
57
57
  import { NativeTokenRequest } from "../broker/nativeBroker/NativeRequest";
58
58
  import { AuthenticationResult } from "../response/AuthenticationResult";
59
59
  import { SilentRequest } from "../request/SilentRequest";
@@ -880,12 +880,12 @@ export class BrowserCacheManager extends CacheManager {
880
880
  );
881
881
  return null;
882
882
  }
883
- const parsedMetadata = this.validateAndParseJson(value);
883
+ const parsedEntity = this.validateAndParseJson(value);
884
884
  if (
885
- !parsedMetadata ||
886
- !ServerTelemetryEntity.isServerTelemetryEntity(
885
+ !parsedEntity ||
886
+ !CacheHelpers.isServerTelemetryEntity(
887
887
  serverTelemetryKey,
888
- parsedMetadata
888
+ parsedEntity
889
889
  )
890
890
  ) {
891
891
  this.logger.trace(
@@ -895,10 +895,7 @@ export class BrowserCacheManager extends CacheManager {
895
895
  }
896
896
 
897
897
  this.logger.trace("BrowserCacheManager.getServerTelemetry: cache hit");
898
- return CacheManager.toObject(
899
- new ServerTelemetryEntity(),
900
- parsedMetadata
901
- );
898
+ return parsedEntity as ServerTelemetryEntity;
902
899
  }
903
900
 
904
901
  /**
@@ -1587,7 +1584,7 @@ export class BrowserCacheManager extends CacheManager {
1587
1584
  return;
1588
1585
  }
1589
1586
  // Extract state and ensure it matches given InteractionType, then clean request cache
1590
- const parsedState = BrowserProtocolUtils.extractBrowserRequestState(
1587
+ const parsedState = extractBrowserRequestState(
1591
1588
  this.cryptoImpl,
1592
1589
  stateValue
1593
1590
  );
@@ -22,8 +22,6 @@ import {
22
22
  InProgressPerformanceEvent,
23
23
  RequestThumbprint,
24
24
  AccountEntity,
25
- ServerResponseType,
26
- UrlString,
27
25
  invokeAsync,
28
26
  createClientAuthError,
29
27
  ClientAuthErrorCodes,
@@ -336,16 +334,6 @@ export class StandardController implements IController {
336
334
  // Block token acquisition before initialize has been called
337
335
  BrowserUtils.blockAPICallsBeforeInitialize(this.initialized);
338
336
 
339
- let foundServerResponse = hash;
340
-
341
- if (
342
- this.config.auth.OIDCOptions?.serverResponseType ===
343
- ServerResponseType.QUERY
344
- ) {
345
- const url = window.location.href;
346
- foundServerResponse = UrlString.parseQueryServerResponse(url);
347
- }
348
-
349
337
  const loggedInAccounts = this.getAllAccounts();
350
338
  if (this.isBrowserEnvironment) {
351
339
  /**
@@ -353,8 +341,7 @@ export class StandardController implements IController {
353
341
  * otherwise return the promise from the first invocation. Prevents race conditions when handleRedirectPromise is called
354
342
  * several times concurrently.
355
343
  */
356
- const redirectResponseKey =
357
- foundServerResponse || Constants.EMPTY_STRING;
344
+ const redirectResponseKey = hash || "";
358
345
  let response = this.redirectResponse.get(redirectResponseKey);
359
346
  if (typeof response === "undefined") {
360
347
  this.eventHandler.emitEvent(
@@ -376,7 +363,7 @@ export class StandardController implements IController {
376
363
  this.nativeExtensionProvider
377
364
  ) &&
378
365
  this.nativeExtensionProvider &&
379
- !foundServerResponse
366
+ !hash
380
367
  ) {
381
368
  this.logger.trace(
382
369
  "handleRedirectPromise - acquiring token from native platform"
@@ -408,9 +395,7 @@ export class StandardController implements IController {
408
395
  const redirectClient =
409
396
  this.createRedirectClient(correlationId);
410
397
  redirectResponse =
411
- redirectClient.handleRedirectPromise(
412
- foundServerResponse
413
- );
398
+ redirectClient.handleRedirectPromise(hash);
414
399
  }
415
400
 
416
401
  response = redirectResponse
@@ -533,7 +518,7 @@ export class StandardController implements IController {
533
518
  this.nativeExtensionProvider,
534
519
  this.getNativeAccountId(request),
535
520
  this.nativeInternalStorage,
536
- request.correlationId
521
+ correlationId
537
522
  );
538
523
  result = nativeClient
539
524
  .acquireTokenRedirect(request)
@@ -543,26 +528,22 @@ export class StandardController implements IController {
543
528
  isFatalNativeAuthError(e)
544
529
  ) {
545
530
  this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
546
- const redirectClient = this.createRedirectClient(
547
- request.correlationId
548
- );
531
+ const redirectClient =
532
+ this.createRedirectClient(correlationId);
549
533
  return redirectClient.acquireToken(request);
550
534
  } else if (e instanceof InteractionRequiredAuthError) {
551
535
  this.logger.verbose(
552
536
  "acquireTokenRedirect - Resolving interaction required error thrown by native broker by falling back to web flow"
553
537
  );
554
- const redirectClient = this.createRedirectClient(
555
- request.correlationId
556
- );
538
+ const redirectClient =
539
+ this.createRedirectClient(correlationId);
557
540
  return redirectClient.acquireToken(request);
558
541
  }
559
542
  this.getBrowserStorage().setInteractionInProgress(false);
560
543
  throw e;
561
544
  });
562
545
  } else {
563
- const redirectClient = this.createRedirectClient(
564
- request.correlationId
565
- );
546
+ const redirectClient = this.createRedirectClient(correlationId);
566
547
  result = redirectClient.acquireToken(request);
567
548
  }
568
549
 
@@ -632,7 +613,13 @@ export class StandardController implements IController {
632
613
  let result: Promise<AuthenticationResult>;
633
614
 
634
615
  if (this.canUseNative(request)) {
635
- result = this.acquireTokenNative(request, ApiId.acquireTokenPopup)
616
+ result = this.acquireTokenNative(
617
+ {
618
+ ...request,
619
+ correlationId,
620
+ },
621
+ ApiId.acquireTokenPopup
622
+ )
636
623
  .then((response) => {
637
624
  this.getBrowserStorage().setInteractionInProgress(false);
638
625
  atPopupMeasurement.end({
@@ -648,24 +635,22 @@ export class StandardController implements IController {
648
635
  isFatalNativeAuthError(e)
649
636
  ) {
650
637
  this.nativeExtensionProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
651
- const popupClient = this.createPopupClient(
652
- request.correlationId
653
- );
638
+ const popupClient =
639
+ this.createPopupClient(correlationId);
654
640
  return popupClient.acquireToken(request);
655
641
  } else if (e instanceof InteractionRequiredAuthError) {
656
642
  this.logger.verbose(
657
643
  "acquireTokenPopup - Resolving interaction required error thrown by native broker by falling back to web flow"
658
644
  );
659
- const popupClient = this.createPopupClient(
660
- request.correlationId
661
- );
645
+ const popupClient =
646
+ this.createPopupClient(correlationId);
662
647
  return popupClient.acquireToken(request);
663
648
  }
664
649
  this.getBrowserStorage().setInteractionInProgress(false);
665
650
  throw e;
666
651
  });
667
652
  } else {
668
- const popupClient = this.createPopupClient(request.correlationId);
653
+ const popupClient = this.createPopupClient(correlationId);
669
654
  result = popupClient.acquireToken(request);
670
655
  }
671
656
 
@@ -876,7 +861,7 @@ export class StandardController implements IController {
876
861
  );
877
862
  const atbcMeasurement = this.performanceClient.startMeasurement(
878
863
  PerformanceEvents.AcquireTokenByCode,
879
- request.correlationId
864
+ correlationId
880
865
  );
881
866
 
882
867
  try {
@@ -934,7 +919,7 @@ export class StandardController implements IController {
934
919
  } else {
935
920
  this.logger.verbose(
936
921
  "Existing acquireTokenByCode request found",
937
- request.correlationId
922
+ correlationId
938
923
  );
939
924
  atbcMeasurement.discard();
940
925
  }
@@ -942,7 +927,10 @@ export class StandardController implements IController {
942
927
  } else if (request.nativeAccountId) {
943
928
  if (this.canUseNative(request, request.nativeAccountId)) {
944
929
  return this.acquireTokenNative(
945
- request,
930
+ {
931
+ ...request,
932
+ correlationId,
933
+ },
946
934
  ApiId.acquireTokenByCode,
947
935
  request.nativeAccountId
948
936
  ).catch((e: AuthError) => {
@@ -1911,6 +1899,7 @@ export class StandardController implements IController {
1911
1899
  resourceRequestUri: request.resourceRequestUri,
1912
1900
  shrClaims: request.shrClaims,
1913
1901
  sshKid: request.sshKid,
1902
+ shrOptions: request.shrOptions,
1914
1903
  };
1915
1904
  const silentRequestKey = JSON.stringify(thumbprint);
1916
1905
 
@@ -9,6 +9,7 @@ import {
9
9
  JoseHeader,
10
10
  Logger,
11
11
  PerformanceEvents,
12
+ ShrOptions,
12
13
  SignedHttpRequest,
13
14
  SignedHttpRequestParameters,
14
15
  } from "@azure/msal-common";
@@ -161,6 +162,7 @@ export class CryptoOps implements ICrypto {
161
162
  async signJwt(
162
163
  payload: SignedHttpRequest,
163
164
  kid: string,
165
+ shrOptions?: ShrOptions,
164
166
  correlationId?: string
165
167
  ): Promise<string> {
166
168
  const signJwtMeasurement = this.performanceClient?.startMeasurement(
@@ -180,15 +182,15 @@ export class CryptoOps implements ICrypto {
180
182
  cachedKeyPair.publicKey
181
183
  );
182
184
  const publicKeyJwkString = getSortedObjectString(publicKeyJwk);
183
-
184
185
  // Base64URL encode public key thumbprint with keyId only: BASE64URL({ kid: "FULL_PUBLIC_KEY_HASH" })
185
186
  const encodedKeyIdThumbprint = urlEncode(JSON.stringify({ kid: kid }));
186
-
187
187
  // Generate header
188
188
  const shrHeader = JoseHeader.getShrHeaderString({
189
- kid: encodedKeyIdThumbprint,
189
+ ...shrOptions?.header,
190
190
  alg: publicKeyJwk.alg,
191
+ kid: encodedKeyIdThumbprint,
191
192
  });
193
+
192
194
  const encodedShrHeader = urlEncode(shrHeader);
193
195
 
194
196
  // Generate payload
package/src/index.ts CHANGED
@@ -135,6 +135,7 @@ export {
135
135
  // Utils
136
136
  StringUtils,
137
137
  UrlString,
138
+ JsonWebTokenTypes,
138
139
  // AzureCloudInstance enum
139
140
  AzureCloudInstance,
140
141
  AzureCloudOptions,
@@ -141,7 +141,7 @@ export abstract class BaseInteractionClient {
141
141
  ): Promise<BaseAuthRequest> {
142
142
  this.performanceClient.addQueueMeasurement(
143
143
  PerformanceEvents.InitializeBaseRequest,
144
- request.correlationId
144
+ this.correlationId
145
145
  );
146
146
  const authority = request.authority || this.config.auth.authority;
147
147
 
@@ -266,7 +266,6 @@ export abstract class BaseInteractionClient {
266
266
  /**
267
267
  * Used to get a discovered version of the default authority.
268
268
  * @param requestAuthority
269
- * @param requestCorrelationId
270
269
  */
271
270
  protected async getDiscoveredAuthority(
272
271
  requestAuthority?: string
@@ -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
  }