@azure/msal-browser 4.7.0 → 4.9.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 (214) 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/AccountManager.mjs +1 -1
  7. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  8. package/dist/cache/BrowserCacheManager.d.ts +4 -41
  9. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  10. package/dist/cache/BrowserCacheManager.mjs +18 -143
  11. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  12. package/dist/cache/CacheHelpers.mjs +1 -1
  13. package/dist/cache/CookieStorage.mjs +1 -1
  14. package/dist/cache/DatabaseStorage.mjs +1 -1
  15. package/dist/cache/LocalStorage.mjs +1 -1
  16. package/dist/cache/MemoryStorage.mjs +1 -1
  17. package/dist/cache/SessionStorage.mjs +1 -1
  18. package/dist/cache/TokenCache.mjs +1 -1
  19. package/dist/config/Configuration.d.ts.map +1 -1
  20. package/dist/config/Configuration.mjs +12 -3
  21. package/dist/config/Configuration.mjs.map +1 -1
  22. package/dist/controllers/ControllerFactory.mjs +1 -1
  23. package/dist/controllers/NestedAppAuthController.d.ts +2 -2
  24. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  25. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  26. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  27. package/dist/controllers/StandardController.d.ts.map +1 -1
  28. package/dist/controllers/StandardController.mjs +28 -16
  29. package/dist/controllers/StandardController.mjs.map +1 -1
  30. package/dist/controllers/UnknownOperatingContextController.d.ts +2 -2
  31. package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  32. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  33. package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
  34. package/dist/crypto/BrowserCrypto.d.ts +11 -0
  35. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  36. package/dist/crypto/BrowserCrypto.mjs +68 -5
  37. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  38. package/dist/crypto/CryptoOps.mjs +1 -1
  39. package/dist/crypto/PkceGenerator.mjs +1 -1
  40. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  41. package/dist/encode/Base64Decode.mjs +1 -1
  42. package/dist/encode/Base64Encode.mjs +1 -1
  43. package/dist/error/BrowserAuthError.d.ts +3 -5
  44. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  45. package/dist/error/BrowserAuthError.mjs +5 -7
  46. package/dist/error/BrowserAuthError.mjs.map +1 -1
  47. package/dist/error/BrowserAuthErrorCodes.d.ts +3 -1
  48. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  49. package/dist/error/BrowserAuthErrorCodes.mjs +6 -4
  50. package/dist/error/BrowserAuthErrorCodes.mjs.map +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.mjs +1 -1
  56. package/dist/event/EventHandler.mjs +1 -1
  57. package/dist/event/EventMessage.mjs +1 -1
  58. package/dist/event/EventType.mjs +1 -1
  59. package/dist/index.mjs +1 -1
  60. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  61. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  62. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  63. package/dist/interaction_client/NativeInteractionClient.mjs +9 -4
  64. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  65. package/dist/interaction_client/PopupClient.d.ts +14 -1
  66. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  67. package/dist/interaction_client/PopupClient.mjs +66 -57
  68. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  69. package/dist/interaction_client/RedirectClient.d.ts +21 -4
  70. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  71. package/dist/interaction_client/RedirectClient.mjs +133 -70
  72. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  73. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  74. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  75. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  76. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  77. package/dist/interaction_client/SilentIframeClient.d.ts +13 -3
  78. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  79. package/dist/interaction_client/SilentIframeClient.mjs +64 -41
  80. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  81. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  82. package/dist/interaction_client/StandardInteractionClient.d.ts +2 -9
  83. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  84. package/dist/interaction_client/StandardInteractionClient.mjs +2 -22
  85. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  86. package/dist/interaction_handler/InteractionHandler.d.ts +4 -5
  87. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  88. package/dist/interaction_handler/InteractionHandler.mjs +3 -3
  89. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  90. package/dist/interaction_handler/SilentHandler.d.ts +4 -2
  91. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  92. package/dist/interaction_handler/SilentHandler.mjs +13 -3
  93. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  94. package/dist/naa/BridgeError.mjs +1 -1
  95. package/dist/naa/BridgeProxy.mjs +1 -1
  96. package/dist/naa/BridgeStatusCode.mjs +1 -1
  97. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  98. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +2 -3
  99. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  100. package/dist/navigation/NavigationClient.mjs +1 -1
  101. package/dist/network/FetchClient.mjs +1 -1
  102. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  103. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  104. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  105. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  106. package/dist/packageMetadata.d.ts +1 -1
  107. package/dist/packageMetadata.mjs +2 -2
  108. package/dist/protocol/Authorize.d.ts +65 -0
  109. package/dist/protocol/Authorize.d.ts.map +1 -0
  110. package/dist/protocol/Authorize.mjs +217 -0
  111. package/dist/protocol/Authorize.mjs.map +1 -0
  112. package/dist/request/AuthorizationUrlRequest.d.ts +2 -4
  113. package/dist/request/AuthorizationUrlRequest.d.ts.map +1 -1
  114. package/dist/request/PopupRequest.d.ts +1 -1
  115. package/dist/request/PopupRequest.d.ts.map +1 -1
  116. package/dist/request/RedirectRequest.d.ts +1 -1
  117. package/dist/request/RedirectRequest.d.ts.map +1 -1
  118. package/dist/request/RequestHelpers.mjs +1 -1
  119. package/dist/request/SsoSilentRequest.d.ts +1 -1
  120. package/dist/request/SsoSilentRequest.d.ts.map +1 -1
  121. package/dist/response/ResponseHandler.d.ts +3 -3
  122. package/dist/response/ResponseHandler.d.ts.map +1 -1
  123. package/dist/response/ResponseHandler.mjs +1 -1
  124. package/dist/response/ResponseHandler.mjs.map +1 -1
  125. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  126. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  127. package/dist/utils/BrowserConstants.d.ts +1 -10
  128. package/dist/utils/BrowserConstants.d.ts.map +1 -1
  129. package/dist/utils/BrowserConstants.mjs +2 -11
  130. package/dist/utils/BrowserConstants.mjs.map +1 -1
  131. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  132. package/dist/utils/BrowserUtils.mjs +1 -1
  133. package/lib/msal-browser.cjs +2402 -2345
  134. package/lib/msal-browser.cjs.map +1 -1
  135. package/lib/msal-browser.js +2402 -2345
  136. package/lib/msal-browser.js.map +1 -1
  137. package/lib/msal-browser.min.js +68 -66
  138. package/lib/types/cache/BrowserCacheManager.d.ts +4 -41
  139. package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
  140. package/lib/types/config/Configuration.d.ts.map +1 -1
  141. package/lib/types/controllers/NestedAppAuthController.d.ts +2 -2
  142. package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
  143. package/lib/types/controllers/StandardController.d.ts.map +1 -1
  144. package/lib/types/controllers/UnknownOperatingContextController.d.ts +2 -2
  145. package/lib/types/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  146. package/lib/types/crypto/BrowserCrypto.d.ts +11 -0
  147. package/lib/types/crypto/BrowserCrypto.d.ts.map +1 -1
  148. package/lib/types/error/BrowserAuthError.d.ts +3 -5
  149. package/lib/types/error/BrowserAuthError.d.ts.map +1 -1
  150. package/lib/types/error/BrowserAuthErrorCodes.d.ts +3 -1
  151. package/lib/types/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  152. package/lib/types/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  153. package/lib/types/interaction_client/PopupClient.d.ts +14 -1
  154. package/lib/types/interaction_client/PopupClient.d.ts.map +1 -1
  155. package/lib/types/interaction_client/RedirectClient.d.ts +21 -4
  156. package/lib/types/interaction_client/RedirectClient.d.ts.map +1 -1
  157. package/lib/types/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  158. package/lib/types/interaction_client/SilentIframeClient.d.ts +13 -3
  159. package/lib/types/interaction_client/SilentIframeClient.d.ts.map +1 -1
  160. package/lib/types/interaction_client/StandardInteractionClient.d.ts +2 -9
  161. package/lib/types/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  162. package/lib/types/interaction_handler/InteractionHandler.d.ts +4 -5
  163. package/lib/types/interaction_handler/InteractionHandler.d.ts.map +1 -1
  164. package/lib/types/interaction_handler/SilentHandler.d.ts +4 -2
  165. package/lib/types/interaction_handler/SilentHandler.d.ts.map +1 -1
  166. package/lib/types/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  167. package/lib/types/packageMetadata.d.ts +1 -1
  168. package/lib/types/protocol/Authorize.d.ts +65 -0
  169. package/lib/types/protocol/Authorize.d.ts.map +1 -0
  170. package/lib/types/request/AuthorizationUrlRequest.d.ts +2 -4
  171. package/lib/types/request/AuthorizationUrlRequest.d.ts.map +1 -1
  172. package/lib/types/request/PopupRequest.d.ts +1 -1
  173. package/lib/types/request/PopupRequest.d.ts.map +1 -1
  174. package/lib/types/request/RedirectRequest.d.ts +1 -1
  175. package/lib/types/request/RedirectRequest.d.ts.map +1 -1
  176. package/lib/types/request/SsoSilentRequest.d.ts +1 -1
  177. package/lib/types/request/SsoSilentRequest.d.ts.map +1 -1
  178. package/lib/types/response/ResponseHandler.d.ts +3 -3
  179. package/lib/types/response/ResponseHandler.d.ts.map +1 -1
  180. package/lib/types/utils/BrowserConstants.d.ts +1 -10
  181. package/lib/types/utils/BrowserConstants.d.ts.map +1 -1
  182. package/package.json +2 -2
  183. package/src/cache/BrowserCacheManager.ts +30 -205
  184. package/src/config/Configuration.ts +14 -2
  185. package/src/controllers/NestedAppAuthController.ts +2 -0
  186. package/src/controllers/StandardController.ts +35 -24
  187. package/src/controllers/UnknownOperatingContextController.ts +2 -0
  188. package/src/crypto/BrowserCrypto.ts +91 -2
  189. package/src/error/BrowserAuthError.ts +6 -8
  190. package/src/error/BrowserAuthErrorCodes.ts +3 -1
  191. package/src/interaction_client/NativeInteractionClient.ts +11 -2
  192. package/src/interaction_client/PopupClient.ts +174 -111
  193. package/src/interaction_client/RedirectClient.ts +269 -132
  194. package/src/interaction_client/SilentAuthCodeClient.ts +2 -2
  195. package/src/interaction_client/SilentIframeClient.ts +168 -100
  196. package/src/interaction_client/StandardInteractionClient.ts +3 -43
  197. package/src/interaction_handler/InteractionHandler.ts +8 -7
  198. package/src/interaction_handler/SilentHandler.ts +31 -2
  199. package/src/naa/mapping/NestedAppAuthAdapter.ts +1 -2
  200. package/src/packageMetadata.ts +1 -1
  201. package/src/protocol/Authorize.ts +490 -0
  202. package/src/request/AuthorizationUrlRequest.ts +3 -5
  203. package/src/request/PopupRequest.ts +1 -0
  204. package/src/request/RedirectRequest.ts +1 -0
  205. package/src/request/SsoSilentRequest.ts +1 -0
  206. package/src/response/ResponseHandler.ts +3 -3
  207. package/src/utils/BrowserConstants.ts +1 -10
  208. package/dist/interaction_handler/RedirectHandler.d.ts +0 -33
  209. package/dist/interaction_handler/RedirectHandler.d.ts.map +0 -1
  210. package/dist/interaction_handler/RedirectHandler.mjs +0 -144
  211. package/dist/interaction_handler/RedirectHandler.mjs.map +0 -1
  212. package/lib/types/interaction_handler/RedirectHandler.d.ts +0 -33
  213. package/lib/types/interaction_handler/RedirectHandler.d.ts.map +0 -1
  214. package/src/interaction_handler/RedirectHandler.ts +0 -251
@@ -41,7 +41,6 @@ import {
41
41
  ApiId,
42
42
  BrowserCacheLocation,
43
43
  WrapperSKU,
44
- TemporaryCacheKeys,
45
44
  CacheLookupPolicy,
46
45
  DEFAULT_REQUEST,
47
46
  BrowserConstants,
@@ -437,11 +436,18 @@ export class StandardController implements IController {
437
436
  private async handleRedirectPromiseInternal(
438
437
  hash?: string
439
438
  ): Promise<AuthenticationResult | null> {
439
+ if (!this.browserStorage.isInteractionInProgress(true)) {
440
+ this.logger.info(
441
+ "handleRedirectPromise called but there is no interaction in progress, returning null."
442
+ );
443
+ return null;
444
+ }
445
+
440
446
  const loggedInAccounts = this.getAllAccounts();
441
- const request: NativeTokenRequest | null =
447
+ const platformBrokerRequest: NativeTokenRequest | null =
442
448
  this.browserStorage.getCachedNativeRequest();
443
449
  const useNative =
444
- request &&
450
+ platformBrokerRequest &&
445
451
  NativeMessageHandler.isPlatformBrokerAvailable(
446
452
  this.config,
447
453
  this.logger,
@@ -449,15 +455,9 @@ export class StandardController implements IController {
449
455
  ) &&
450
456
  this.nativeExtensionProvider &&
451
457
  !hash;
452
- const correlationId = useNative
453
- ? request?.correlationId
454
- : this.browserStorage.getTemporaryCache(
455
- TemporaryCacheKeys.CORRELATION_ID,
456
- true
457
- ) || "";
458
- const rootMeasurement = this.performanceClient.startMeasurement(
458
+ let rootMeasurement = this.performanceClient.startMeasurement(
459
459
  PerformanceEvents.AcquireTokenRedirect,
460
- correlationId
460
+ platformBrokerRequest?.correlationId || ""
461
461
  );
462
462
  this.eventHandler.emitEvent(
463
463
  EventType.HANDLE_REDIRECT_START,
@@ -479,9 +479,9 @@ export class StandardController implements IController {
479
479
  ApiId.handleRedirectPromise,
480
480
  this.performanceClient,
481
481
  this.nativeExtensionProvider,
482
- request.accountId,
482
+ platformBrokerRequest.accountId,
483
483
  this.nativeInternalStorage,
484
- request.correlationId
484
+ platformBrokerRequest.correlationId
485
485
  );
486
486
 
487
487
  redirectResponse = invokeAsync(
@@ -492,6 +492,15 @@ export class StandardController implements IController {
492
492
  rootMeasurement.event.correlationId
493
493
  )(this.performanceClient, rootMeasurement.event.correlationId);
494
494
  } else {
495
+ const [standardRequest, codeVerifier] =
496
+ this.browserStorage.getCachedRequest();
497
+ const correlationId = standardRequest.correlationId;
498
+ // Reset rootMeasurement now that we have correlationId
499
+ rootMeasurement.discard();
500
+ rootMeasurement = this.performanceClient.startMeasurement(
501
+ PerformanceEvents.AcquireTokenRedirect,
502
+ correlationId
503
+ );
495
504
  this.logger.trace(
496
505
  "handleRedirectPromise - acquiring token from web flow"
497
506
  );
@@ -502,14 +511,14 @@ export class StandardController implements IController {
502
511
  this.logger,
503
512
  this.performanceClient,
504
513
  rootMeasurement.event.correlationId
505
- )(hash, rootMeasurement);
514
+ )(hash, standardRequest, codeVerifier, rootMeasurement);
506
515
  }
507
516
 
508
517
  return redirectResponse
509
518
  .then((result: AuthenticationResult | null) => {
510
519
  if (result) {
520
+ this.browserStorage.resetRequestCache();
511
521
  // Emit login event if number of accounts change
512
-
513
522
  const isLoggingIn =
514
523
  loggedInAccounts.length < this.getAllAccounts().length;
515
524
  if (isLoggingIn) {
@@ -555,6 +564,7 @@ export class StandardController implements IController {
555
564
  return result;
556
565
  })
557
566
  .catch((e) => {
567
+ this.browserStorage.resetRequestCache();
558
568
  const eventError = e as EventError;
559
569
  // Emit login event if there is an account
560
570
  if (loggedInAccounts.length > 0) {
@@ -702,7 +712,6 @@ export class StandardController implements IController {
702
712
  this.createRedirectClient(correlationId);
703
713
  return redirectClient.acquireToken(request);
704
714
  }
705
- this.browserStorage.setInteractionInProgress(false);
706
715
  throw e;
707
716
  });
708
717
  } else {
@@ -712,6 +721,7 @@ export class StandardController implements IController {
712
721
 
713
722
  return await result;
714
723
  } catch (e) {
724
+ this.browserStorage.resetRequestCache();
715
725
  atrMeasurement.end({ success: false }, e);
716
726
  if (isLoggedIn) {
717
727
  this.eventHandler.emitEvent(
@@ -792,7 +802,6 @@ export class StandardController implements IController {
792
802
  ApiId.acquireTokenPopup
793
803
  )
794
804
  .then((response) => {
795
- this.browserStorage.setInteractionInProgress(false);
796
805
  atPopupMeasurement.end({
797
806
  success: true,
798
807
  isNativeBroker: true,
@@ -817,7 +826,6 @@ export class StandardController implements IController {
817
826
  this.createPopupClient(correlationId);
818
827
  return popupClient.acquireToken(request, pkce);
819
828
  }
820
- this.browserStorage.setInteractionInProgress(false);
821
829
  throw e;
822
830
  });
823
831
  } else {
@@ -881,11 +889,12 @@ export class StandardController implements IController {
881
889
  // Since this function is syncronous we need to reject
882
890
  return Promise.reject(e);
883
891
  })
884
- .finally(
885
- () =>
886
- this.config.system.asyncPopups &&
887
- this.preGeneratePkceCodes(correlationId)
888
- );
892
+ .finally(async () => {
893
+ this.browserStorage.setInteractionInProgress(false);
894
+ if (this.config.system.asyncPopups) {
895
+ await this.preGeneratePkceCodes(correlationId);
896
+ }
897
+ });
889
898
  }
890
899
 
891
900
  private trackPageVisibilityWithMeasurement(): void {
@@ -1357,7 +1366,9 @@ export class StandardController implements IController {
1357
1366
  this.browserStorage.setInteractionInProgress(true);
1358
1367
 
1359
1368
  const popupClient = this.createPopupClient(correlationId);
1360
- return popupClient.logout(logoutRequest);
1369
+ return popupClient.logout(logoutRequest).finally(() => {
1370
+ this.browserStorage.setInteractionInProgress(false);
1371
+ });
1361
1372
  } catch (e) {
1362
1373
  // Since this function is syncronous we need to reject
1363
1374
  return Promise.reject(e);
@@ -186,6 +186,7 @@ export class UnknownOperatingContextController implements IController {
186
186
  Omit<
187
187
  CommonAuthorizationUrlRequest,
188
188
  | "responseMode"
189
+ | "earJwk"
189
190
  | "codeChallenge"
190
191
  | "codeChallengeMethod"
191
192
  | "requestedClaimsHash"
@@ -293,6 +294,7 @@ export class UnknownOperatingContextController implements IController {
293
294
  Omit<
294
295
  CommonAuthorizationUrlRequest,
295
296
  | "responseMode"
297
+ | "earJwk"
296
298
  | "codeChallenge"
297
299
  | "codeChallengeMethod"
298
300
  | "requestedClaimsHash"
@@ -12,8 +12,8 @@ import {
12
12
  PerformanceEvents,
13
13
  } from "@azure/msal-common/browser";
14
14
  import { KEY_FORMAT_JWK } from "../utils/BrowserConstants.js";
15
- import { urlEncodeArr } from "../encode/Base64Encode.js";
16
- import { base64DecToArr } from "../encode/Base64Decode.js";
15
+ import { base64Encode, urlEncodeArr } from "../encode/Base64Encode.js";
16
+ import { base64Decode, base64DecToArr } from "../encode/Base64Decode.js";
17
17
 
18
18
  /**
19
19
  * This file defines functions used by the browser library to perform cryptography operations such as
@@ -226,6 +226,95 @@ export async function sign(
226
226
  ) as Promise<ArrayBuffer>;
227
227
  }
228
228
 
229
+ /**
230
+ * Generates Base64 encoded jwk used in the Encrypted Authorize Response (EAR) flow
231
+ */
232
+ export async function generateEarKey(): Promise<string> {
233
+ const key = await generateBaseKey();
234
+ const keyStr = urlEncodeArr(new Uint8Array(key));
235
+
236
+ const jwk = {
237
+ alg: "dir",
238
+ kty: "oct",
239
+ k: keyStr,
240
+ };
241
+
242
+ return base64Encode(JSON.stringify(jwk));
243
+ }
244
+
245
+ /**
246
+ * Parses earJwk for encryption key and returns CryptoKey object
247
+ * @param earJwk
248
+ * @returns
249
+ */
250
+ async function importEarKey(earJwk: string): Promise<CryptoKey> {
251
+ const b64DecodedJwk = base64Decode(earJwk);
252
+ const jwkJson = JSON.parse(b64DecodedJwk);
253
+ const rawKey = jwkJson.k;
254
+ const keyBuffer = base64DecToArr(rawKey);
255
+
256
+ return window.crypto.subtle.importKey(RAW, keyBuffer, AES_GCM, false, [
257
+ DECRYPT,
258
+ ]);
259
+ }
260
+
261
+ /**
262
+ * Decrypt ear_jwe response returned in the Encrypted Authorize Response (EAR) flow
263
+ * @param earJwk
264
+ * @param earJwe
265
+ * @returns
266
+ */
267
+ export async function decryptEarResponse(
268
+ earJwk: string,
269
+ earJwe: string
270
+ ): Promise<string> {
271
+ const earJweParts = earJwe.split(".");
272
+ if (earJweParts.length !== 5) {
273
+ throw createBrowserAuthError(
274
+ BrowserAuthErrorCodes.failedToDecryptEarResponse,
275
+ "jwe_length"
276
+ );
277
+ }
278
+
279
+ const key = await importEarKey(earJwk).catch(() => {
280
+ throw createBrowserAuthError(
281
+ BrowserAuthErrorCodes.failedToDecryptEarResponse,
282
+ "import_key"
283
+ );
284
+ });
285
+
286
+ try {
287
+ const header = new TextEncoder().encode(earJweParts[0]);
288
+ const iv = base64DecToArr(earJweParts[2]);
289
+ const ciphertext = base64DecToArr(earJweParts[3]);
290
+ const tag = base64DecToArr(earJweParts[4]);
291
+ const tagLengthBits = tag.byteLength * 8;
292
+
293
+ // Concat ciphertext and tag
294
+ const encryptedData = new Uint8Array(ciphertext.length + tag.length);
295
+ encryptedData.set(ciphertext);
296
+ encryptedData.set(tag, ciphertext.length);
297
+
298
+ const decryptedData = await window.crypto.subtle.decrypt(
299
+ {
300
+ name: AES_GCM,
301
+ iv: iv,
302
+ tagLength: tagLengthBits,
303
+ additionalData: header,
304
+ },
305
+ key,
306
+ encryptedData
307
+ );
308
+
309
+ return new TextDecoder().decode(decryptedData);
310
+ } catch (e) {
311
+ throw createBrowserAuthError(
312
+ BrowserAuthErrorCodes.failedToDecryptEarResponse,
313
+ "decrypt"
314
+ );
315
+ }
316
+ }
317
+
229
318
  /**
230
319
  * Generates symmetric base encryption key. This may be stored as all encryption/decryption keys will be derived from this one.
231
320
  */
@@ -15,6 +15,10 @@ const ErrorLink = "For more visit: aka.ms/msaljs/browser-errors";
15
15
  export const BrowserAuthErrorMessages = {
16
16
  [BrowserAuthErrorCodes.pkceNotCreated]:
17
17
  "The PKCE code challenge and verifier could not be generated.",
18
+ [BrowserAuthErrorCodes.earJwkEmpty]:
19
+ "No EAR encryption key provided. This is unexpected.",
20
+ [BrowserAuthErrorCodes.earJweEmpty]:
21
+ "Server response does not contain ear_jwe property. This is unexpected.",
18
22
  [BrowserAuthErrorCodes.cryptoNonExistent]:
19
23
  "The crypto object or function is not available.",
20
24
  [BrowserAuthErrorCodes.emptyNavigateUri]:
@@ -52,8 +56,6 @@ export const BrowserAuthErrorMessages = {
52
56
  "No token request found in cache.",
53
57
  [BrowserAuthErrorCodes.unableToParseTokenRequestCacheError]:
54
58
  "The cached token request could not be parsed.",
55
- [BrowserAuthErrorCodes.noCachedAuthorityError]:
56
- "No cached authority found.",
57
59
  [BrowserAuthErrorCodes.authRequestNotSetError]:
58
60
  "Auth Request not set. Please ensure initiateAuthRequest was called from the InteractionHandler",
59
61
  [BrowserAuthErrorCodes.invalidCacheType]: "Invalid cache type",
@@ -96,6 +98,8 @@ export const BrowserAuthErrorMessages = {
96
98
  "Failed to build request headers object.",
97
99
  [BrowserAuthErrorCodes.failedToParseHeaders]:
98
100
  "Failed to parse response headers",
101
+ [BrowserAuthErrorCodes.failedToDecryptEarResponse]:
102
+ "Failed to decrypt ear response",
99
103
  };
100
104
 
101
105
  /**
@@ -221,12 +225,6 @@ export const BrowserAuthErrorMessage = {
221
225
  BrowserAuthErrorCodes.unableToParseTokenRequestCacheError
222
226
  ],
223
227
  },
224
- noCachedAuthorityError: {
225
- code: BrowserAuthErrorCodes.noCachedAuthorityError,
226
- desc: BrowserAuthErrorMessages[
227
- BrowserAuthErrorCodes.noCachedAuthorityError
228
- ],
229
- },
230
228
  authRequestNotSet: {
231
229
  code: BrowserAuthErrorCodes.authRequestNotSetError,
232
230
  desc: BrowserAuthErrorMessages[
@@ -4,6 +4,8 @@
4
4
  */
5
5
 
6
6
  export const pkceNotCreated = "pkce_not_created";
7
+ export const earJwkEmpty = "ear_jwk_empty";
8
+ export const earJweEmpty = "ear_jwe_empty";
7
9
  export const cryptoNonExistent = "crypto_nonexistent";
8
10
  export const emptyNavigateUri = "empty_navigate_uri";
9
11
  export const hashEmptyError = "hash_empty_error";
@@ -28,7 +30,6 @@ export const silentPromptValueError = "silent_prompt_value_error";
28
30
  export const noTokenRequestCacheError = "no_token_request_cache_error";
29
31
  export const unableToParseTokenRequestCacheError =
30
32
  "unable_to_parse_token_request_cache_error";
31
- export const noCachedAuthorityError = "no_cached_authority_error";
32
33
  export const authRequestNotSetError = "auth_request_not_set_error";
33
34
  export const invalidCacheType = "invalid_cache_type";
34
35
  export const nonBrowserEnvironment = "non_browser_environment";
@@ -58,3 +59,4 @@ export const invalidBase64String = "invalid_base64_string";
58
59
  export const invalidPopTokenRequest = "invalid_pop_token_request";
59
60
  export const failedToBuildHeaders = "failed_to_build_headers";
60
61
  export const failedToParseHeaders = "failed_to_parse_headers";
62
+ export const failedToDecryptEarResponse = "failed_to_decrypt_ear_response";
@@ -446,14 +446,12 @@ export class NativeInteractionClient extends BaseInteractionClient {
446
446
  request,
447
447
  reqTimestamp
448
448
  );
449
- this.browserStorage.setInteractionInProgress(false);
450
449
  const res = await result;
451
450
  const serverTelemetryManager =
452
451
  this.initializeServerTelemetryManager(this.apiId);
453
452
  serverTelemetryManager.clearNativeBrokerErrorCode();
454
453
  return res;
455
454
  } catch (e) {
456
- this.browserStorage.setInteractionInProgress(false);
457
455
  throw e;
458
456
  }
459
457
  }
@@ -498,7 +496,15 @@ export class NativeInteractionClient extends BaseInteractionClient {
498
496
  nativeAccountId: request.accountId,
499
497
  })?.homeAccountId;
500
498
 
499
+ // add exception for double brokering, please note this is temporary and will be fortified in future
501
500
  if (
501
+ request.extraParameters?.child_client_id &&
502
+ response.account.id !== request.accountId
503
+ ) {
504
+ this.logger.info(
505
+ "handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch"
506
+ );
507
+ } else if (
502
508
  homeAccountIdentifier !== cachedhomeAccountId &&
503
509
  response.account.id !== request.accountId
504
510
  ) {
@@ -525,6 +531,9 @@ export class NativeInteractionClient extends BaseInteractionClient {
525
531
  this.logger
526
532
  );
527
533
 
534
+ // Ensure expires_in is in number format
535
+ response.expires_in = Number(response.expires_in);
536
+
528
537
  // generate authenticationResult
529
538
  const result = await this.generateAuthenticationResult(
530
539
  response,