@azure/msal-browser 3.13.0 → 3.15.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 (153) hide show
  1. package/dist/app/IPublicClientApplication.d.ts +2 -1
  2. package/dist/app/IPublicClientApplication.d.ts.map +1 -1
  3. package/dist/app/IPublicClientApplication.mjs +4 -1
  4. package/dist/app/IPublicClientApplication.mjs.map +1 -1
  5. package/dist/app/PublicClientApplication.d.ts +17 -0
  6. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  7. package/dist/app/PublicClientApplication.mjs +37 -9
  8. package/dist/app/PublicClientApplication.mjs.map +1 -1
  9. package/dist/app/PublicClientNext.d.ts +3 -0
  10. package/dist/app/PublicClientNext.d.ts.map +1 -1
  11. package/dist/app/PublicClientNext.mjs +4 -1
  12. package/dist/app/PublicClientNext.mjs.map +1 -1
  13. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  14. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  15. package/dist/cache/AccountManager.d.ts +49 -0
  16. package/dist/cache/AccountManager.d.ts.map +1 -0
  17. package/dist/cache/AccountManager.mjs +131 -0
  18. package/dist/cache/AccountManager.mjs.map +1 -0
  19. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  20. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  21. package/dist/cache/BrowserCacheManager.mjs +9 -2
  22. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  23. package/dist/cache/BrowserStorage.mjs +1 -1
  24. package/dist/cache/DatabaseStorage.mjs +1 -1
  25. package/dist/cache/MemoryStorage.mjs +1 -1
  26. package/dist/cache/TokenCache.mjs +1 -1
  27. package/dist/config/Configuration.d.ts +3 -1
  28. package/dist/config/Configuration.d.ts.map +1 -1
  29. package/dist/config/Configuration.mjs +1 -1
  30. package/dist/config/Configuration.mjs.map +1 -1
  31. package/dist/controllers/ControllerFactory.d.ts.map +1 -1
  32. package/dist/controllers/ControllerFactory.mjs +10 -12
  33. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  34. package/dist/controllers/NestedAppAuthController.d.ts +118 -10
  35. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  36. package/dist/controllers/NestedAppAuthController.mjs +227 -83
  37. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  38. package/dist/controllers/StandardController.d.ts.map +1 -1
  39. package/dist/controllers/StandardController.mjs +98 -115
  40. package/dist/controllers/StandardController.mjs.map +1 -1
  41. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  42. package/dist/crypto/BrowserCrypto.mjs +1 -1
  43. package/dist/crypto/CryptoOps.mjs +1 -1
  44. package/dist/crypto/PkceGenerator.mjs +1 -1
  45. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  46. package/dist/encode/Base64Decode.mjs +1 -1
  47. package/dist/encode/Base64Encode.mjs +1 -1
  48. package/dist/error/BrowserAuthError.mjs +1 -1
  49. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  50. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  51. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  52. package/dist/error/NativeAuthError.mjs +1 -1
  53. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  54. package/dist/error/NestedAppAuthError.mjs +1 -1
  55. package/dist/event/EventHandler.mjs +1 -1
  56. package/dist/event/EventMessage.mjs +1 -1
  57. package/dist/event/EventType.mjs +1 -1
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.mjs +2 -2
  61. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  62. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  63. package/dist/interaction_client/NativeInteractionClient.mjs +1 -1
  64. package/dist/interaction_client/PopupClient.mjs +1 -1
  65. package/dist/interaction_client/RedirectClient.d.ts +4 -5
  66. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  67. package/dist/interaction_client/RedirectClient.mjs +5 -8
  68. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  69. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  70. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  71. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  72. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  73. package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
  74. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  75. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  76. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  77. package/dist/naa/BridgeAccountContext.d.ts +13 -0
  78. package/dist/naa/BridgeAccountContext.d.ts.map +1 -0
  79. package/dist/naa/BridgeCapabilities.d.ts +1 -1
  80. package/dist/naa/BridgeCapabilities.d.ts.map +1 -1
  81. package/dist/naa/BridgeError.mjs +1 -1
  82. package/dist/naa/BridgeProxy.d.ts +3 -2
  83. package/dist/naa/BridgeProxy.d.ts.map +1 -1
  84. package/dist/naa/BridgeProxy.mjs +9 -7
  85. package/dist/naa/BridgeProxy.mjs.map +1 -1
  86. package/dist/naa/BridgeRequestEnvelope.d.ts +1 -1
  87. package/dist/naa/BridgeRequestEnvelope.d.ts.map +1 -1
  88. package/dist/naa/BridgeStatusCode.mjs +1 -1
  89. package/dist/naa/IBridgeProxy.d.ts +2 -2
  90. package/dist/naa/IBridgeProxy.d.ts.map +1 -1
  91. package/dist/naa/InitContext.d.ts +2 -0
  92. package/dist/naa/InitContext.d.ts.map +1 -1
  93. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts +12 -2
  94. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  95. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +43 -6
  96. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  97. package/dist/navigation/NavigationClient.mjs +1 -1
  98. package/dist/network/FetchClient.mjs +1 -1
  99. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  100. package/dist/operatingcontext/{TeamsAppOperatingContext.d.ts → NestedAppOperatingContext.d.ts} +8 -6
  101. package/dist/operatingcontext/NestedAppOperatingContext.d.ts.map +1 -0
  102. package/dist/operatingcontext/{TeamsAppOperatingContext.mjs → NestedAppOperatingContext.mjs} +21 -35
  103. package/dist/operatingcontext/NestedAppOperatingContext.mjs.map +1 -0
  104. package/dist/operatingcontext/StandardOperatingContext.d.ts.map +1 -1
  105. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  106. package/dist/operatingcontext/StandardOperatingContext.mjs.map +1 -1
  107. package/dist/operatingcontext/UnknownOperatingContext.d.ts +5 -5
  108. package/dist/operatingcontext/UnknownOperatingContext.d.ts.map +1 -1
  109. package/dist/operatingcontext/UnknownOperatingContext.mjs +8 -8
  110. package/dist/operatingcontext/UnknownOperatingContext.mjs.map +1 -1
  111. package/dist/packageMetadata.d.ts +1 -1
  112. package/dist/packageMetadata.mjs +2 -2
  113. package/dist/request/RequestHelpers.mjs +1 -1
  114. package/dist/response/ResponseHandler.mjs +1 -1
  115. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  116. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  117. package/dist/utils/BrowserConstants.mjs +1 -1
  118. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  119. package/dist/utils/BrowserUtils.d.ts +3 -0
  120. package/dist/utils/BrowserUtils.d.ts.map +1 -1
  121. package/dist/utils/BrowserUtils.mjs +2 -1
  122. package/dist/utils/BrowserUtils.mjs.map +1 -1
  123. package/lib/msal-browser.cjs +10568 -10231
  124. package/lib/msal-browser.cjs.map +1 -1
  125. package/lib/msal-browser.js +10568 -10231
  126. package/lib/msal-browser.js.map +1 -1
  127. package/lib/msal-browser.min.js +69 -68
  128. package/package.json +6 -4
  129. package/src/app/IPublicClientApplication.ts +5 -0
  130. package/src/app/PublicClientApplication.ts +43 -8
  131. package/src/app/PublicClientNext.ts +3 -0
  132. package/src/cache/AccountManager.ts +184 -0
  133. package/src/cache/BrowserCacheManager.ts +11 -2
  134. package/src/config/Configuration.ts +3 -1
  135. package/src/controllers/ControllerFactory.ts +9 -14
  136. package/src/controllers/NestedAppAuthController.ts +375 -82
  137. package/src/controllers/StandardController.ts +125 -149
  138. package/src/index.ts +5 -1
  139. package/src/interaction_client/RedirectClient.ts +6 -12
  140. package/src/naa/BridgeAccountContext.ts +17 -0
  141. package/src/naa/BridgeCapabilities.ts +2 -1
  142. package/src/naa/BridgeProxy.ts +11 -6
  143. package/src/naa/BridgeRequestEnvelope.ts +1 -6
  144. package/src/naa/IBridgeProxy.ts +2 -2
  145. package/src/naa/InitContext.ts +2 -0
  146. package/src/naa/mapping/NestedAppAuthAdapter.ts +68 -2
  147. package/src/operatingcontext/{TeamsAppOperatingContext.ts → NestedAppOperatingContext.ts} +23 -31
  148. package/src/operatingcontext/StandardOperatingContext.ts +1 -0
  149. package/src/operatingcontext/UnknownOperatingContext.ts +8 -7
  150. package/src/packageMetadata.ts +1 -1
  151. package/src/utils/BrowserUtils.ts +4 -1
  152. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts.map +0 -1
  153. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +0 -1
@@ -33,6 +33,7 @@ import {
33
33
  BrowserCacheManager,
34
34
  DEFAULT_BROWSER_CACHE_MANAGER,
35
35
  } from "../cache/BrowserCacheManager";
36
+ import * as AccountManager from "../cache/AccountManager";
36
37
  import { BrowserConfiguration, CacheOptions } from "../config/Configuration";
37
38
  import {
38
39
  InteractionType,
@@ -84,6 +85,34 @@ import { ClearCacheRequest } from "../request/ClearCacheRequest";
84
85
  import { createNewGuid } from "../crypto/BrowserCrypto";
85
86
  import { initializeSilentRequest } from "../request/RequestHelpers";
86
87
 
88
+ function getAccountType(
89
+ account?: AccountInfo
90
+ ): "AAD" | "MSA" | "B2C" | undefined {
91
+ const idTokenClaims = account?.idTokenClaims;
92
+ if (idTokenClaims?.tfp || idTokenClaims?.acr) {
93
+ return "B2C";
94
+ }
95
+
96
+ if (!idTokenClaims?.tid) {
97
+ return undefined;
98
+ } else if (idTokenClaims?.tid === "9188040d-6c67-4c5b-b112-36a304b66dad") {
99
+ return "MSA";
100
+ }
101
+ return "AAD";
102
+ }
103
+
104
+ function preflightCheck(
105
+ initialized: boolean,
106
+ performanceEvent: InProgressPerformanceEvent
107
+ ) {
108
+ try {
109
+ BrowserUtils.preflightCheck(initialized);
110
+ } catch (e) {
111
+ performanceEvent.end({ success: false }, e);
112
+ throw e;
113
+ }
114
+ }
115
+
87
116
  export class StandardController implements IController {
88
117
  // OperatingContext
89
118
  protected readonly operatingContext: StandardOperatingContext;
@@ -142,7 +171,7 @@ export class StandardController implements IController {
142
171
  >;
143
172
 
144
173
  // Active Iframe request
145
- private activeIframeRequest: [Promise<void>, string] | undefined;
174
+ private activeIframeRequest: [Promise<boolean>, string] | undefined;
146
175
 
147
176
  private ssoSilentMeasurement?: InProgressPerformanceEvent;
148
177
  private acquireTokenByCodeAsyncMeasurement?: InProgressPerformanceEvent;
@@ -439,11 +468,7 @@ export class StandardController implements IController {
439
468
  this.logger,
440
469
  this.performanceClient,
441
470
  rootMeasurement.event.correlationId
442
- )(
443
- hash,
444
- this.performanceClient,
445
- rootMeasurement.event.correlationId
446
- );
471
+ )(hash, rootMeasurement);
447
472
  }
448
473
 
449
474
  return redirectResponse
@@ -472,13 +497,26 @@ export class StandardController implements IController {
472
497
  "handleRedirectResponse returned result, acquire token success"
473
498
  );
474
499
  }
475
- rootMeasurement.end({ success: true });
500
+ rootMeasurement.end({
501
+ success: true,
502
+ accountType: getAccountType(result.account),
503
+ });
504
+ } else {
505
+ /*
506
+ * Instrument an event only if an error code is set. Otherwise, discard it when the redirect response
507
+ * is empty and the error code is missing.
508
+ */
509
+ if (rootMeasurement.event.errorCode) {
510
+ rootMeasurement.end({ success: false });
511
+ } else {
512
+ rootMeasurement.discard();
513
+ }
476
514
  }
515
+
477
516
  this.eventHandler.emitEvent(
478
517
  EventType.HANDLE_REDIRECT_END,
479
518
  InteractionType.Redirect
480
519
  );
481
- rootMeasurement.end({ success: false });
482
520
 
483
521
  return result;
484
522
  })
@@ -631,9 +669,14 @@ export class StandardController implements IController {
631
669
  correlationId
632
670
  );
633
671
 
672
+ atPopupMeasurement.add({
673
+ scenarioId: request.scenarioId,
674
+ accountType: getAccountType(request.account),
675
+ });
676
+
634
677
  try {
635
678
  this.logger.verbose("acquireTokenPopup called", correlationId);
636
- BrowserUtils.preflightCheck(this.initialized);
679
+ preflightCheck(this.initialized, atPopupMeasurement);
637
680
  this.browserStorage.setInteractionInProgress(true);
638
681
  } catch (e) {
639
682
  // Since this function is syncronous we need to reject
@@ -672,6 +715,7 @@ export class StandardController implements IController {
672
715
  success: true,
673
716
  isNativeBroker: true,
674
717
  requestId: response.requestId,
718
+ accountType: getAccountType(response.account),
675
719
  });
676
720
  return response;
677
721
  })
@@ -721,13 +765,12 @@ export class StandardController implements IController {
721
765
  );
722
766
  }
723
767
 
724
- atPopupMeasurement.add({
725
- accessTokenSize: result.accessToken.length,
726
- idTokenSize: result.idToken.length,
727
- });
728
768
  atPopupMeasurement.end({
729
769
  success: true,
730
770
  requestId: result.requestId,
771
+ accessTokenSize: result.accessToken.length,
772
+ idTokenSize: result.idToken.length,
773
+ accountType: getAccountType(result.account),
731
774
  });
732
775
  return result;
733
776
  })
@@ -803,14 +846,19 @@ export class StandardController implements IController {
803
846
  prompt: request.prompt,
804
847
  correlationId: correlationId,
805
848
  };
806
- BrowserUtils.preflightCheck(this.initialized);
807
849
  this.ssoSilentMeasurement = this.performanceClient.startMeasurement(
808
850
  PerformanceEvents.SsoSilent,
809
851
  correlationId
810
852
  );
853
+ this.ssoSilentMeasurement?.add({
854
+ scenarioId: request.scenarioId,
855
+ accountType: getAccountType(request.account),
856
+ });
857
+ preflightCheck(this.initialized, this.ssoSilentMeasurement);
811
858
  this.ssoSilentMeasurement?.increment({
812
859
  visibilityChangeCount: 0,
813
860
  });
861
+
814
862
  document.addEventListener(
815
863
  "visibilitychange",
816
864
  this.trackPageVisibilityWithMeasurement
@@ -853,14 +901,13 @@ export class StandardController implements IController {
853
901
  InteractionType.Silent,
854
902
  response
855
903
  );
856
- this.ssoSilentMeasurement?.add({
857
- accessTokenSize: response.accessToken.length,
858
- idTokenSize: response.idToken.length,
859
- });
860
904
  this.ssoSilentMeasurement?.end({
861
905
  success: true,
862
906
  isNativeBroker: response.fromNativeBroker,
863
907
  requestId: response.requestId,
908
+ accessTokenSize: response.accessToken.length,
909
+ idTokenSize: response.idToken.length,
910
+ accountType: getAccountType(response.account),
864
911
  });
865
912
  return response;
866
913
  })
@@ -902,16 +949,17 @@ export class StandardController implements IController {
902
949
  ): Promise<AuthenticationResult> {
903
950
  const correlationId = this.getRequestCorrelationId(request);
904
951
  this.logger.trace("acquireTokenByCode called", correlationId);
905
- BrowserUtils.preflightCheck(this.initialized);
952
+ const atbcMeasurement = this.performanceClient.startMeasurement(
953
+ PerformanceEvents.AcquireTokenByCode,
954
+ correlationId
955
+ );
956
+ preflightCheck(this.initialized, atbcMeasurement);
906
957
  this.eventHandler.emitEvent(
907
958
  EventType.ACQUIRE_TOKEN_BY_CODE_START,
908
959
  InteractionType.Silent,
909
960
  request
910
961
  );
911
- const atbcMeasurement = this.performanceClient.startMeasurement(
912
- PerformanceEvents.AcquireTokenByCode,
913
- correlationId
914
- );
962
+ atbcMeasurement.add({ scenarioId: request.scenarioId });
915
963
 
916
964
  try {
917
965
  if (request.code && request.nativeAccountId) {
@@ -938,14 +986,13 @@ export class StandardController implements IController {
938
986
  result
939
987
  );
940
988
  this.hybridAuthCodeResponses.delete(hybridAuthCode);
941
- atbcMeasurement.add({
942
- accessTokenSize: result.accessToken.length,
943
- idTokenSize: result.idToken.length,
944
- });
945
989
  atbcMeasurement.end({
946
990
  success: true,
947
991
  isNativeBroker: result.fromNativeBroker,
948
992
  requestId: result.requestId,
993
+ accessTokenSize: result.accessToken.length,
994
+ idTokenSize: result.idToken.length,
995
+ accountType: getAccountType(result.account),
949
996
  });
950
997
  return result;
951
998
  })
@@ -976,7 +1023,7 @@ export class StandardController implements IController {
976
1023
  return await response;
977
1024
  } else if (request.nativeAccountId) {
978
1025
  if (this.canUseNative(request, request.nativeAccountId)) {
979
- return await this.acquireTokenNative(
1026
+ const result = await this.acquireTokenNative(
980
1027
  {
981
1028
  ...request,
982
1029
  correlationId,
@@ -993,6 +1040,11 @@ export class StandardController implements IController {
993
1040
  }
994
1041
  throw e;
995
1042
  });
1043
+ atbcMeasurement.end({
1044
+ accountType: getAccountType(result.account),
1045
+ success: true,
1046
+ });
1047
+ return result;
996
1048
  } else {
997
1049
  throw createBrowserAuthError(
998
1050
  BrowserAuthErrorCodes.unableToAcquireTokenFromNativePlatform
@@ -1248,10 +1300,12 @@ export class StandardController implements IController {
1248
1300
  * @returns Array of AccountInfo objects in cache
1249
1301
  */
1250
1302
  getAllAccounts(accountFilter?: AccountFilter): AccountInfo[] {
1251
- this.logger.verbose("getAllAccounts called");
1252
- return this.isBrowserEnvironment
1253
- ? this.browserStorage.getAllAccounts(accountFilter)
1254
- : [];
1303
+ return AccountManager.getAllAccounts(
1304
+ this.logger,
1305
+ this.browserStorage,
1306
+ this.isBrowserEnvironment,
1307
+ accountFilter
1308
+ );
1255
1309
  }
1256
1310
 
1257
1311
  /**
@@ -1260,26 +1314,11 @@ export class StandardController implements IController {
1260
1314
  * @returns The first account found in the cache matching the provided filter or null if no account could be found.
1261
1315
  */
1262
1316
  getAccount(accountFilter: AccountFilter): AccountInfo | null {
1263
- this.logger.trace("getAccount called");
1264
- if (Object.keys(accountFilter).length === 0) {
1265
- this.logger.warning("getAccount: No accountFilter provided");
1266
- return null;
1267
- }
1268
-
1269
- const account: AccountInfo | null =
1270
- this.browserStorage.getAccountInfoFilteredBy(accountFilter);
1271
-
1272
- if (account) {
1273
- this.logger.verbose(
1274
- "getAccount: Account matching provided filter found, returning"
1275
- );
1276
- return account;
1277
- } else {
1278
- this.logger.verbose(
1279
- "getAccount: No matching account found, returning null"
1280
- );
1281
- return null;
1282
- }
1317
+ return AccountManager.getAccount(
1318
+ accountFilter,
1319
+ this.logger,
1320
+ this.browserStorage
1321
+ );
1283
1322
  }
1284
1323
 
1285
1324
  /**
@@ -1291,29 +1330,11 @@ export class StandardController implements IController {
1291
1330
  * @returns The account object stored in MSAL
1292
1331
  */
1293
1332
  getAccountByUsername(username: string): AccountInfo | null {
1294
- this.logger.trace("getAccountByUsername called");
1295
- if (!username) {
1296
- this.logger.warning("getAccountByUsername: No username provided");
1297
- return null;
1298
- }
1299
-
1300
- const account = this.browserStorage.getAccountInfoFilteredBy({
1333
+ return AccountManager.getAccountByUsername(
1301
1334
  username,
1302
- });
1303
- if (account) {
1304
- this.logger.verbose(
1305
- "getAccountByUsername: Account matching username found, returning"
1306
- );
1307
- this.logger.verbosePii(
1308
- `getAccountByUsername: Returning signed-in accounts matching username: ${username}`
1309
- );
1310
- return account;
1311
- } else {
1312
- this.logger.verbose(
1313
- "getAccountByUsername: No matching account found, returning null"
1314
- );
1315
- return null;
1316
- }
1335
+ this.logger,
1336
+ this.browserStorage
1337
+ );
1317
1338
  }
1318
1339
 
1319
1340
  /**
@@ -1324,31 +1345,11 @@ export class StandardController implements IController {
1324
1345
  * @returns The account object stored in MSAL
1325
1346
  */
1326
1347
  getAccountByHomeId(homeAccountId: string): AccountInfo | null {
1327
- this.logger.trace("getAccountByHomeId called");
1328
- if (!homeAccountId) {
1329
- this.logger.warning(
1330
- "getAccountByHomeId: No homeAccountId provided"
1331
- );
1332
- return null;
1333
- }
1334
-
1335
- const account = this.browserStorage.getAccountInfoFilteredBy({
1348
+ return AccountManager.getAccountByHomeId(
1336
1349
  homeAccountId,
1337
- });
1338
- if (account) {
1339
- this.logger.verbose(
1340
- "getAccountByHomeId: Account matching homeAccountId found, returning"
1341
- );
1342
- this.logger.verbosePii(
1343
- `getAccountByHomeId: Returning signed-in accounts matching homeAccountId: ${homeAccountId}`
1344
- );
1345
- return account;
1346
- } else {
1347
- this.logger.verbose(
1348
- "getAccountByHomeId: No matching account found, returning null"
1349
- );
1350
- return null;
1351
- }
1350
+ this.logger,
1351
+ this.browserStorage
1352
+ );
1352
1353
  }
1353
1354
 
1354
1355
  /**
@@ -1359,31 +1360,11 @@ export class StandardController implements IController {
1359
1360
  * @returns The account object stored in MSAL
1360
1361
  */
1361
1362
  getAccountByLocalId(localAccountId: string): AccountInfo | null {
1362
- this.logger.trace("getAccountByLocalId called");
1363
- if (!localAccountId) {
1364
- this.logger.warning(
1365
- "getAccountByLocalId: No localAccountId provided"
1366
- );
1367
- return null;
1368
- }
1369
-
1370
- const account = this.browserStorage.getAccountInfoFilteredBy({
1363
+ return AccountManager.getAccountByLocalId(
1371
1364
  localAccountId,
1372
- });
1373
- if (account) {
1374
- this.logger.verbose(
1375
- "getAccountByLocalId: Account matching localAccountId found, returning"
1376
- );
1377
- this.logger.verbosePii(
1378
- `getAccountByLocalId: Returning signed-in accounts matching localAccountId: ${localAccountId}`
1379
- );
1380
- return account;
1381
- } else {
1382
- this.logger.verbose(
1383
- "getAccountByLocalId: No matching account found, returning null"
1384
- );
1385
- return null;
1386
- }
1365
+ this.logger,
1366
+ this.browserStorage
1367
+ );
1387
1368
  }
1388
1369
 
1389
1370
  /**
@@ -1391,14 +1372,14 @@ export class StandardController implements IController {
1391
1372
  * @param account
1392
1373
  */
1393
1374
  setActiveAccount(account: AccountInfo | null): void {
1394
- this.browserStorage.setActiveAccount(account);
1375
+ AccountManager.setActiveAccount(account, this.browserStorage);
1395
1376
  }
1396
1377
 
1397
1378
  /**
1398
1379
  * Gets the currently active account
1399
1380
  */
1400
1381
  getActiveAccount(): AccountInfo | null {
1401
- return this.browserStorage.getActiveAccount();
1382
+ return AccountManager.getActiveAccount(this.browserStorage);
1402
1383
  }
1403
1384
 
1404
1385
  // #endregion
@@ -1856,15 +1837,17 @@ export class StandardController implements IController {
1856
1837
  );
1857
1838
  atsMeasurement.add({
1858
1839
  cacheLookupPolicy: request.cacheLookupPolicy,
1840
+ scenarioId: request.scenarioId,
1859
1841
  });
1860
1842
 
1861
- BrowserUtils.preflightCheck(this.initialized);
1843
+ preflightCheck(this.initialized, atsMeasurement);
1862
1844
  this.logger.verbose("acquireTokenSilent called", correlationId);
1863
1845
 
1864
1846
  const account = request.account || this.getActiveAccount();
1865
1847
  if (!account) {
1866
1848
  throw createBrowserAuthError(BrowserAuthErrorCodes.noAccountError);
1867
1849
  }
1850
+ atsMeasurement.add({ accountType: getAccountType(account) });
1868
1851
 
1869
1852
  const thumbprint: RequestThumbprint = {
1870
1853
  clientId: this.config.auth.clientId,
@@ -1904,16 +1887,14 @@ export class StandardController implements IController {
1904
1887
  )
1905
1888
  .then((result) => {
1906
1889
  this.activeSilentTokenRequests.delete(silentRequestKey);
1907
- atsMeasurement.add({
1908
- accessTokenSize: result.accessToken.length,
1909
- idTokenSize: result.idToken.length,
1910
- });
1911
1890
  atsMeasurement.end({
1912
1891
  success: true,
1913
1892
  fromCache: result.fromCache,
1914
1893
  isNativeBroker: result.fromNativeBroker,
1915
1894
  cacheLookupPolicy: request.cacheLookupPolicy,
1916
1895
  requestId: result.requestId,
1896
+ accessTokenSize: result.accessToken.length,
1897
+ idTokenSize: result.idToken.length,
1917
1898
  });
1918
1899
  return result;
1919
1900
  })
@@ -2000,13 +1981,11 @@ export class StandardController implements IController {
2000
1981
 
2001
1982
  if (shouldTryToResolveSilently) {
2002
1983
  if (!this.activeIframeRequest) {
2003
- let _resolve: () => void,
2004
- _reject: (reason?: AuthError | Error) => void;
1984
+ let _resolve: (result: boolean) => void;
2005
1985
  // Always set the active request tracker immediately after checking it to prevent races
2006
1986
  this.activeIframeRequest = [
2007
- new Promise((resolve, reject) => {
1987
+ new Promise((resolve) => {
2008
1988
  _resolve = resolve;
2009
- _reject = reject;
2010
1989
  }),
2011
1990
  silentRequest.correlationId,
2012
1991
  ];
@@ -2022,11 +2001,11 @@ export class StandardController implements IController {
2022
2001
  silentRequest.correlationId
2023
2002
  )(silentRequest)
2024
2003
  .then((iframeResult) => {
2025
- _resolve();
2004
+ _resolve(true);
2026
2005
  return iframeResult;
2027
2006
  })
2028
2007
  .catch((e) => {
2029
- _reject(e);
2008
+ _resolve(false);
2030
2009
  throw e;
2031
2010
  })
2032
2011
  .finally(() => {
@@ -2048,20 +2027,11 @@ export class StandardController implements IController {
2048
2027
  awaitIframeCorrelationId: activeCorrelationId,
2049
2028
  });
2050
2029
 
2051
- // Await for errors first so we can distinguish errors thrown by activePromise versus errors thrown by .then below
2052
- await activePromise.catch(() => {
2053
- awaitConcurrentIframeMeasure.end({
2054
- success: false,
2055
- });
2056
- this.logger.info(
2057
- `Iframe request with correlationId: ${activeCorrelationId} failed. Interaction is required.`
2058
- );
2059
- // If previous iframe request failed, it's unlikely to succeed this time. Throw original error.
2060
- throw refreshTokenError;
2030
+ const activePromiseResult = await activePromise;
2031
+ awaitConcurrentIframeMeasure.end({
2032
+ success: activePromiseResult,
2061
2033
  });
2062
-
2063
- return activePromise.then(() => {
2064
- awaitConcurrentIframeMeasure.end({ success: true });
2034
+ if (activePromiseResult) {
2065
2035
  this.logger.verbose(
2066
2036
  `Parallel iframe request with correlationId: ${activeCorrelationId} succeeded. Retrying cache and/or RT redemption`,
2067
2037
  silentRequest.correlationId
@@ -2071,7 +2041,13 @@ export class StandardController implements IController {
2071
2041
  silentRequest,
2072
2042
  cacheLookupPolicy
2073
2043
  );
2074
- });
2044
+ } else {
2045
+ this.logger.info(
2046
+ `Iframe request with correlationId: ${activeCorrelationId} failed. Interaction is required.`
2047
+ );
2048
+ // If previous iframe request failed, it's unlikely to succeed this time. Throw original error.
2049
+ throw refreshTokenError;
2050
+ }
2075
2051
  } else {
2076
2052
  // Cache policy set to skip and another iframe request is already in progress
2077
2053
  this.logger.warning(
package/src/index.ts CHANGED
@@ -11,7 +11,11 @@
11
11
  import * as BrowserUtils from "./utils/BrowserUtils";
12
12
  export { BrowserUtils };
13
13
 
14
- export { PublicClientApplication } from "./app/PublicClientApplication";
14
+ export {
15
+ PublicClientApplication,
16
+ createNestablePublicClientApplication,
17
+ createStandardPublicClientApplication,
18
+ } from "./app/PublicClientApplication";
15
19
  export { PublicClientNext } from "./app/PublicClientNext";
16
20
  export { IController } from "./controllers/IController";
17
21
  export {
@@ -21,6 +21,7 @@ import {
21
21
  invokeAsync,
22
22
  ServerResponseType,
23
23
  UrlUtils,
24
+ InProgressPerformanceEvent,
24
25
  } from "@azure/msal-common";
25
26
  import { StandardInteractionClient } from "./StandardInteractionClient";
26
27
  import {
@@ -190,14 +191,12 @@ export class RedirectClient extends StandardInteractionClient {
190
191
  * Checks if navigateToLoginRequestUrl is set, and:
191
192
  * - if true, performs logic to cache and navigate
192
193
  * - if false, handles hash string and parses response
193
- * @param hash {string?} url hash
194
- * @param performanceClient {IPerformanceClient?}
195
- * @param correlationId {string?} correlation identifier
194
+ * @param hash {string} url hash
195
+ * @param parentMeasurement {InProgressPerformanceEvent} parent measurement
196
196
  */
197
197
  async handleRedirectPromise(
198
- hash?: string,
199
- performanceClient?: IPerformanceClient,
200
- correlationId?: string
198
+ hash: string = "",
199
+ parentMeasurement: InProgressPerformanceEvent
201
200
  ): Promise<AuthenticationResult | null> {
202
201
  const serverTelemetryManager = this.initializeServerTelemetryManager(
203
202
  ApiId.handleRedirectPromise
@@ -220,12 +219,7 @@ export class RedirectClient extends StandardInteractionClient {
220
219
  this.browserStorage.cleanRequestByInteractionType(
221
220
  InteractionType.Redirect
222
221
  );
223
- if (performanceClient && correlationId) {
224
- performanceClient?.addFields(
225
- { errorCode: "no_server_response" },
226
- correlationId
227
- );
228
- }
222
+ parentMeasurement.event.errorCode = "no_server_response";
229
223
  return null;
230
224
  }
231
225
 
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * AccountContext is used to pass account information when the bridge is initialized
8
+ *
9
+ * NAA (MetaOS) apps are created and destroyed for the same session multiple times.
10
+ * `AccountContext` helps in booting up the cached account when the bridge
11
+ * is recreated for a new NAA instance in the same auth session.
12
+ */
13
+ export interface AccountContext {
14
+ homeAccountId: string;
15
+ environment: string;
16
+ tenantId: string;
17
+ }
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ // Capabilities are intended to future proof the bridge against any feature support
6
7
  export interface BridgeCapabilities {
7
- queryAccount: boolean;
8
+ queryAccount?: boolean;
8
9
  }
@@ -3,10 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { AccountInfo } from "./AccountInfo";
7
6
  import { AuthBridge, AuthBridgeResponse } from "./AuthBridge";
8
7
  import { AuthResult } from "./AuthResult";
9
8
  import { BridgeCapabilities } from "./BridgeCapabilities";
9
+ import { AccountContext } from "./BridgeAccountContext";
10
10
  import { BridgeError } from "./BridgeError";
11
11
  import { BridgeRequest } from "./BridgeRequest";
12
12
  import { BridgeRequestEnvelope, BridgeMethods } from "./BridgeRequestEnvelope";
@@ -33,6 +33,7 @@ export class BridgeProxy implements IBridgeProxy {
33
33
  sdkName: string;
34
34
  sdkVersion: string;
35
35
  capabilities?: BridgeCapabilities;
36
+ accountContext?: AccountContext;
36
37
 
37
38
  /**
38
39
  * initializeNestedAppAuthBridge - Initializes the bridge to the host app
@@ -80,6 +81,7 @@ export class BridgeProxy implements IBridgeProxy {
80
81
  messageType: "NestedAppAuthRequest",
81
82
  method: "GetInitContext",
82
83
  requestId: BrowserCrypto.createNewGuid(),
84
+ sendTime: Date.now(),
83
85
  };
84
86
  const request: BridgeRequest = {
85
87
  requestId: message.requestId,
@@ -134,15 +136,14 @@ export class BridgeProxy implements IBridgeProxy {
134
136
  };
135
137
  }
136
138
 
137
- public async getActiveAccount(): Promise<AccountInfo> {
138
- const result = await this.sendRequest("GetActiveAccount");
139
- return BridgeProxy.validateBridgeResultOrThrow(result.account);
140
- }
141
-
142
139
  public getHostCapabilities(): BridgeCapabilities | null {
143
140
  return this.capabilities ?? null;
144
141
  }
145
142
 
143
+ public getAccountContext(): AccountContext | null {
144
+ return this.accountContext ? this.accountContext : null;
145
+ }
146
+
146
147
  /**
147
148
  * A method used to send a request to the bridge
148
149
  * @param request A token request
@@ -156,6 +157,7 @@ export class BridgeProxy implements IBridgeProxy {
156
157
  messageType: "NestedAppAuthRequest",
157
158
  method: method,
158
159
  requestId: BrowserCrypto.createNewGuid(),
160
+ sendTime: Date.now(),
159
161
  ...requestParams,
160
162
  };
161
163
 
@@ -194,10 +196,12 @@ export class BridgeProxy implements IBridgeProxy {
194
196
  private constructor(
195
197
  sdkName: string,
196
198
  sdkVersion: string,
199
+ accountContext?: AccountContext,
197
200
  capabilities?: BridgeCapabilities
198
201
  ) {
199
202
  this.sdkName = sdkName;
200
203
  this.sdkVersion = sdkVersion;
204
+ this.accountContext = accountContext;
201
205
  this.capabilities = capabilities;
202
206
  }
203
207
 
@@ -210,6 +214,7 @@ export class BridgeProxy implements IBridgeProxy {
210
214
  return new BridgeProxy(
211
215
  response.sdkName,
212
216
  response.sdkVersion,
217
+ response.accountContext,
213
218
  response.capabilities
214
219
  );
215
220
  }
@@ -5,12 +5,7 @@
5
5
 
6
6
  import { TokenRequest } from "./TokenRequest";
7
7
 
8
- export type BridgeMethods =
9
- | "GetToken"
10
- | "GetActiveAccount"
11
- | "GetAllAccounts"
12
- | "GetInitContext"
13
- | "GetTokenPopup";
8
+ export type BridgeMethods = "GetToken" | "GetInitContext" | "GetTokenPopup";
14
9
 
15
10
  export type BridgeRequestEnvelope = {
16
11
  messageType: "NestedAppAuthRequest";