@azure/msal-common 15.13.0 → 15.13.2

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 (146) hide show
  1. package/dist/account/AccountInfo.mjs +1 -1
  2. package/dist/account/AuthToken.d.ts +6 -0
  3. package/dist/account/AuthToken.d.ts.map +1 -1
  4. package/dist/account/AuthToken.mjs +22 -2
  5. package/dist/account/AuthToken.mjs.map +1 -1
  6. package/dist/account/CcsCredential.mjs +1 -1
  7. package/dist/account/ClientInfo.mjs +1 -1
  8. package/dist/account/TokenClaims.d.ts +4 -0
  9. package/dist/account/TokenClaims.d.ts.map +1 -1
  10. package/dist/account/TokenClaims.mjs +1 -1
  11. package/dist/account/TokenClaims.mjs.map +1 -1
  12. package/dist/authority/Authority.mjs +1 -1
  13. package/dist/authority/AuthorityFactory.mjs +1 -1
  14. package/dist/authority/AuthorityMetadata.mjs +1 -1
  15. package/dist/authority/AuthorityOptions.mjs +1 -1
  16. package/dist/authority/AuthorityType.mjs +1 -1
  17. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  18. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  19. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  20. package/dist/authority/ProtocolMode.mjs +1 -1
  21. package/dist/authority/RegionDiscovery.mjs +1 -1
  22. package/dist/cache/CacheManager.d.ts +7 -6
  23. package/dist/cache/CacheManager.d.ts.map +1 -1
  24. package/dist/cache/CacheManager.mjs +13 -11
  25. package/dist/cache/CacheManager.mjs.map +1 -1
  26. package/dist/cache/entities/AccountEntity.d.ts +2 -2
  27. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  28. package/dist/cache/entities/AccountEntity.mjs +13 -13
  29. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  30. package/dist/cache/interface/ICacheManager.d.ts +16 -5
  31. package/dist/cache/interface/ICacheManager.d.ts.map +1 -1
  32. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  33. package/dist/cache/utils/CacheHelpers.mjs +1 -1
  34. package/dist/client/AuthorizationCodeClient.mjs +1 -1
  35. package/dist/client/BaseClient.mjs +1 -1
  36. package/dist/client/RefreshTokenClient.mjs +1 -1
  37. package/dist/client/SilentFlowClient.mjs +1 -1
  38. package/dist/config/ClientConfiguration.mjs +1 -1
  39. package/dist/constants/AADServerParamKeys.mjs +1 -1
  40. package/dist/crypto/ICrypto.mjs +1 -1
  41. package/dist/crypto/JoseHeader.mjs +1 -1
  42. package/dist/crypto/PopTokenGenerator.mjs +1 -1
  43. package/dist/error/AuthError.d.ts +5 -0
  44. package/dist/error/AuthError.d.ts.map +1 -1
  45. package/dist/error/AuthError.mjs +1 -1
  46. package/dist/error/AuthError.mjs.map +1 -1
  47. package/dist/error/AuthErrorCodes.mjs +1 -1
  48. package/dist/error/CacheError.mjs +1 -1
  49. package/dist/error/CacheErrorCodes.mjs +1 -1
  50. package/dist/error/ClientAuthError.d.ts +5 -0
  51. package/dist/error/ClientAuthError.d.ts.map +1 -1
  52. package/dist/error/ClientAuthError.mjs +7 -2
  53. package/dist/error/ClientAuthError.mjs.map +1 -1
  54. package/dist/error/ClientAuthErrorCodes.d.ts +1 -0
  55. package/dist/error/ClientAuthErrorCodes.d.ts.map +1 -1
  56. package/dist/error/ClientAuthErrorCodes.mjs +4 -3
  57. package/dist/error/ClientAuthErrorCodes.mjs.map +1 -1
  58. package/dist/error/ClientConfigurationError.mjs +1 -1
  59. package/dist/error/ClientConfigurationErrorCodes.mjs +1 -1
  60. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  61. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  62. package/dist/error/JoseHeaderError.mjs +1 -1
  63. package/dist/error/JoseHeaderErrorCodes.mjs +1 -1
  64. package/dist/error/NetworkError.mjs +1 -1
  65. package/dist/error/PlatformBrokerError.d.ts +16 -0
  66. package/dist/error/PlatformBrokerError.d.ts.map +1 -0
  67. package/dist/error/PlatformBrokerError.mjs +48 -0
  68. package/dist/error/PlatformBrokerError.mjs.map +1 -0
  69. package/dist/error/ServerError.mjs +1 -1
  70. package/dist/exports-common.d.ts +1 -0
  71. package/dist/exports-common.d.ts.map +1 -1
  72. package/dist/index-browser.mjs +2 -1
  73. package/dist/index-browser.mjs.map +1 -1
  74. package/dist/index-node.mjs +2 -1
  75. package/dist/index-node.mjs.map +1 -1
  76. package/dist/index.mjs +2 -1
  77. package/dist/index.mjs.map +1 -1
  78. package/dist/logger/Logger.mjs +1 -1
  79. package/dist/network/INetworkModule.mjs +1 -1
  80. package/dist/network/RequestThumbprint.mjs +1 -1
  81. package/dist/network/ThrottlingUtils.mjs +1 -1
  82. package/dist/packageMetadata.d.ts +1 -1
  83. package/dist/packageMetadata.mjs +2 -2
  84. package/dist/protocol/Authorize.mjs +1 -1
  85. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  86. package/dist/request/RequestParameterBuilder.mjs +1 -1
  87. package/dist/request/ScopeSet.mjs +1 -1
  88. package/dist/response/ResponseHandler.d.ts.map +1 -1
  89. package/dist/response/ResponseHandler.mjs +5 -5
  90. package/dist/response/ResponseHandler.mjs.map +1 -1
  91. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  92. package/dist/telemetry/performance/PerformanceEvent.mjs +1 -1
  93. package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
  94. package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
  95. package/dist/url/UrlString.mjs +1 -1
  96. package/dist/utils/ClientAssertionUtils.mjs +1 -1
  97. package/dist/utils/Constants.mjs +1 -1
  98. package/dist/utils/FunctionWrappers.mjs +1 -1
  99. package/dist/utils/ProtocolUtils.mjs +1 -1
  100. package/dist/utils/StringUtils.mjs +1 -1
  101. package/dist/utils/TimeUtils.mjs +1 -1
  102. package/dist/utils/UrlUtils.mjs +1 -1
  103. package/lib/index-browser.cjs +3 -2
  104. package/lib/index-browser.cjs.map +1 -1
  105. package/lib/{index-node-D8Iaiqq3.js → index-node-BF0Vz18w.js} +471 -399
  106. package/lib/index-node-BF0Vz18w.js.map +1 -0
  107. package/lib/index-node.cjs +3 -2
  108. package/lib/index-node.cjs.map +1 -1
  109. package/lib/index.cjs +3 -2
  110. package/lib/index.cjs.map +1 -1
  111. package/lib/types/account/AuthToken.d.ts +6 -0
  112. package/lib/types/account/AuthToken.d.ts.map +1 -1
  113. package/lib/types/account/TokenClaims.d.ts +4 -0
  114. package/lib/types/account/TokenClaims.d.ts.map +1 -1
  115. package/lib/types/cache/CacheManager.d.ts +7 -6
  116. package/lib/types/cache/CacheManager.d.ts.map +1 -1
  117. package/lib/types/cache/entities/AccountEntity.d.ts +2 -2
  118. package/lib/types/cache/entities/AccountEntity.d.ts.map +1 -1
  119. package/lib/types/cache/interface/ICacheManager.d.ts +16 -5
  120. package/lib/types/cache/interface/ICacheManager.d.ts.map +1 -1
  121. package/lib/types/error/AuthError.d.ts +5 -0
  122. package/lib/types/error/AuthError.d.ts.map +1 -1
  123. package/lib/types/error/ClientAuthError.d.ts +5 -0
  124. package/lib/types/error/ClientAuthError.d.ts.map +1 -1
  125. package/lib/types/error/ClientAuthErrorCodes.d.ts +1 -0
  126. package/lib/types/error/ClientAuthErrorCodes.d.ts.map +1 -1
  127. package/lib/types/error/PlatformBrokerError.d.ts +16 -0
  128. package/lib/types/error/PlatformBrokerError.d.ts.map +1 -0
  129. package/lib/types/exports-common.d.ts +1 -0
  130. package/lib/types/exports-common.d.ts.map +1 -1
  131. package/lib/types/packageMetadata.d.ts +1 -1
  132. package/lib/types/response/ResponseHandler.d.ts.map +1 -1
  133. package/package.json +1 -1
  134. package/src/account/AuthToken.ts +23 -0
  135. package/src/account/TokenClaims.ts +4 -0
  136. package/src/cache/CacheManager.ts +23 -13
  137. package/src/cache/entities/AccountEntity.ts +13 -13
  138. package/src/cache/interface/ICacheManager.ts +23 -4
  139. package/src/error/AuthError.ts +6 -0
  140. package/src/error/ClientAuthError.ts +6 -0
  141. package/src/error/ClientAuthErrorCodes.ts +1 -0
  142. package/src/error/PlatformBrokerError.ts +66 -0
  143. package/src/exports-common.ts +1 -0
  144. package/src/packageMetadata.ts +1 -1
  145. package/src/response/ResponseHandler.ts +8 -3
  146. package/lib/index-node-D8Iaiqq3.js.map +0 -1
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-common v15.13.0 2025-09-24 */
1
+ /*! @azure/msal-common v15.13.2 2025-11-19 */
2
2
  'use strict';
3
3
  'use strict';
4
4
 
@@ -433,7 +433,8 @@ const noNetworkConnectivity = "no_network_connectivity";
433
433
  const userCanceled = "user_canceled";
434
434
  const missingTenantIdError = "missing_tenant_id_error";
435
435
  const methodNotImplemented = "method_not_implemented";
436
- const nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled";
436
+ const nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled";
437
+ const platformBrokerError = "platform_broker_error";
437
438
 
438
439
  var ClientAuthErrorCodes = /*#__PURE__*/Object.freeze({
439
440
  __proto__: null,
@@ -472,6 +473,7 @@ var ClientAuthErrorCodes = /*#__PURE__*/Object.freeze({
472
473
  nonceMismatch: nonceMismatch,
473
474
  nullOrEmptyToken: nullOrEmptyToken,
474
475
  openIdConfigError: openIdConfigError,
476
+ platformBrokerError: platformBrokerError,
475
477
  requestCannotBeMade: requestCannotBeMade,
476
478
  stateMismatch: stateMismatch,
477
479
  stateNotFound: stateNotFound,
@@ -538,6 +540,7 @@ const ClientAuthErrorMessages = {
538
540
  [missingTenantIdError]: "A tenant id - not common, organizations, or consumers - must be specified when using the client_credentials flow.",
539
541
  [methodNotImplemented]: "This method has not been implemented",
540
542
  [nestedAppAuthBridgeDisabled]: "The nested app auth bridge is disabled",
543
+ [platformBrokerError]: "An error occurred in the native broker. See the platformBrokerError property for details.",
541
544
  };
542
545
  /**
543
546
  * String constants used by error codes and messages.
@@ -716,6 +719,10 @@ const ClientAuthErrorMessage = {
716
719
  code: nestedAppAuthBridgeDisabled,
717
720
  desc: ClientAuthErrorMessages[nestedAppAuthBridgeDisabled],
718
721
  },
722
+ platformBrokerError: {
723
+ code: platformBrokerError,
724
+ desc: ClientAuthErrorMessages[platformBrokerError],
725
+ },
719
726
  };
720
727
  /**
721
728
  * Error thrown when there is an error in the client code running on the browser.
@@ -754,6 +761,26 @@ function extractTokenClaims(encodedToken, base64Decode) {
754
761
  throw createClientAuthError(tokenParsingError);
755
762
  }
756
763
  }
764
+ /**
765
+ * Check if the signin_state claim contains "kmsi"
766
+ * @param idTokenClaims
767
+ * @returns
768
+ */
769
+ function isKmsi(idTokenClaims) {
770
+ if (!idTokenClaims.signin_state) {
771
+ return false;
772
+ }
773
+ /**
774
+ * Signin_state claim known values:
775
+ * dvc_mngd - device is managed
776
+ * dvc_dmjd - device is domain joined
777
+ * kmsi - user opted to "keep me signed in"
778
+ * inknownntwk - Request made inside a known network. Don't use this, use CAE instead.
779
+ */
780
+ const kmsiClaims = ["kmsi", "dvc_dmjd"]; // There are some cases where kmsi may not be returned but persistent storage is still OK - allow dvc_dmjd as well
781
+ const kmsi = idTokenClaims.signin_state.some((value) => kmsiClaims.includes(value.trim().toLowerCase()));
782
+ return kmsi;
783
+ }
757
784
  /**
758
785
  * decode a JWT
759
786
  *
@@ -796,7 +823,8 @@ var AuthToken = /*#__PURE__*/Object.freeze({
796
823
  __proto__: null,
797
824
  checkMaxAge: checkMaxAge,
798
825
  extractTokenClaims: extractTokenClaims,
799
- getJWSPayload: getJWSPayload
826
+ getJWSPayload: getJWSPayload,
827
+ isKmsi: isKmsi
800
828
  });
801
829
 
802
830
  /*
@@ -3905,7 +3933,7 @@ class Logger {
3905
3933
 
3906
3934
  /* eslint-disable header/header */
3907
3935
  const name = "@azure/msal-common";
3908
- const version = "15.13.0";
3936
+ const version = "15.13.2";
3909
3937
 
3910
3938
  /*
3911
3939
  * Copyright (c) Microsoft Corporation. All rights reserved.
@@ -4100,6 +4128,44 @@ class ScopeSet {
4100
4128
  }
4101
4129
  }
4102
4130
 
4131
+ /*
4132
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4133
+ * Licensed under the MIT License.
4134
+ */
4135
+ /**
4136
+ * Function to build a client info object from server clientInfo string
4137
+ * @param rawClientInfo
4138
+ * @param crypto
4139
+ */
4140
+ function buildClientInfo(rawClientInfo, base64Decode) {
4141
+ if (!rawClientInfo) {
4142
+ throw createClientAuthError(clientInfoEmptyError);
4143
+ }
4144
+ try {
4145
+ const decodedClientInfo = base64Decode(rawClientInfo);
4146
+ return JSON.parse(decodedClientInfo);
4147
+ }
4148
+ catch (e) {
4149
+ throw createClientAuthError(clientInfoDecodingError);
4150
+ }
4151
+ }
4152
+ /**
4153
+ * Function to build a client info object from cached homeAccountId string
4154
+ * @param homeAccountId
4155
+ */
4156
+ function buildClientInfoFromHomeAccountId(homeAccountId) {
4157
+ if (!homeAccountId) {
4158
+ throw createClientAuthError(clientInfoDecodingError);
4159
+ }
4160
+ const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
4161
+ return {
4162
+ uid: clientInfoParts[0],
4163
+ utid: clientInfoParts.length < 2
4164
+ ? Constants.EMPTY_STRING
4165
+ : clientInfoParts[1],
4166
+ };
4167
+ }
4168
+
4103
4169
  /*
4104
4170
  * Copyright (c) Microsoft Corporation. All rights reserved.
4105
4171
  * Licensed under the MIT License.
@@ -4185,56 +4251,21 @@ function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenC
4185
4251
  * Copyright (c) Microsoft Corporation. All rights reserved.
4186
4252
  * Licensed under the MIT License.
4187
4253
  */
4188
- const cacheQuotaExceeded = "cache_quota_exceeded";
4189
- const cacheErrorUnknown = "cache_error_unknown";
4190
-
4191
- var CacheErrorCodes = /*#__PURE__*/Object.freeze({
4192
- __proto__: null,
4193
- cacheErrorUnknown: cacheErrorUnknown,
4194
- cacheQuotaExceeded: cacheQuotaExceeded
4195
- });
4196
-
4197
- /*
4198
- * Copyright (c) Microsoft Corporation. All rights reserved.
4199
- * Licensed under the MIT License.
4200
- */
4201
- const CacheErrorMessages = {
4202
- [cacheQuotaExceeded]: "Exceeded cache storage capacity.",
4203
- [cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
4204
- };
4205
- /**
4206
- * Error thrown when there is an error with the cache
4207
- */
4208
- class CacheError extends AuthError {
4209
- constructor(errorCode, errorMessage) {
4210
- const message = errorMessage ||
4211
- (CacheErrorMessages[errorCode]
4212
- ? CacheErrorMessages[errorCode]
4213
- : CacheErrorMessages[cacheErrorUnknown]);
4214
- super(`${errorCode}: ${message}`);
4215
- Object.setPrototypeOf(this, CacheError.prototype);
4216
- this.name = "CacheError";
4217
- this.errorCode = errorCode;
4218
- this.errorMessage = message;
4219
- }
4220
- }
4221
4254
  /**
4222
- * Helper function to wrap browser errors in a CacheError object
4223
- * @param e
4255
+ * Gets tenantId from available ID token claims to set as credential realm with the following precedence:
4256
+ * 1. tid - if the token is acquired from an Azure AD tenant tid will be present
4257
+ * 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
4258
+ * 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
4259
+ * Downcased to match the realm case-insensitive comparison requirements
4260
+ * @param idTokenClaims
4224
4261
  * @returns
4225
4262
  */
4226
- function createCacheError(e) {
4227
- if (!(e instanceof Error)) {
4228
- return new CacheError(cacheErrorUnknown);
4229
- }
4230
- if (e.name === "QuotaExceededError" ||
4231
- e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
4232
- e.message.includes("exceeded the quota")) {
4233
- return new CacheError(cacheQuotaExceeded);
4234
- }
4235
- else {
4236
- return new CacheError(e.name, e.message);
4263
+ function getTenantIdFromIdTokenClaims(idTokenClaims) {
4264
+ if (idTokenClaims) {
4265
+ const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
4266
+ return tenantId || null;
4237
4267
  }
4268
+ return null;
4238
4269
  }
4239
4270
 
4240
4271
  /*
@@ -4242,82 +4273,357 @@ function createCacheError(e) {
4242
4273
  * Licensed under the MIT License.
4243
4274
  */
4244
4275
  /**
4245
- * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
4276
+ * Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
4277
+ *
4278
+ * Key : Value Schema
4279
+ *
4280
+ * Key: <home_account_id>-<environment>-<realm*>
4281
+ *
4282
+ * Value Schema:
4283
+ * {
4284
+ * homeAccountId: home account identifier for the auth scheme,
4285
+ * environment: entity that issued the token, represented as a full host
4286
+ * realm: Full tenant or organizational identifier that the account belongs to
4287
+ * localAccountId: Original tenant-specific accountID, usually used for legacy cases
4288
+ * username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
4289
+ * authorityType: Accounts authority type as a string
4290
+ * name: Full name for the account, including given name and family name,
4291
+ * lastModificationTime: last time this entity was modified in the cache
4292
+ * lastModificationApp:
4293
+ * nativeAccountId: Account identifier on the native device
4294
+ * tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
4295
+ * }
4246
4296
  * @internal
4247
4297
  */
4248
- class CacheManager {
4249
- constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) {
4250
- this.clientId = clientId;
4251
- this.cryptoImpl = cryptoImpl;
4252
- this.commonLogger = logger.clone(name, version);
4253
- this.staticAuthorityOptions = staticAuthorityOptions;
4254
- this.performanceClient = performanceClient;
4298
+ class AccountEntity {
4299
+ /**
4300
+ * Returns the AccountInfo interface for this account.
4301
+ */
4302
+ static getAccountInfo(accountEntity) {
4303
+ return {
4304
+ homeAccountId: accountEntity.homeAccountId,
4305
+ environment: accountEntity.environment,
4306
+ tenantId: accountEntity.realm,
4307
+ username: accountEntity.username,
4308
+ localAccountId: accountEntity.localAccountId,
4309
+ loginHint: accountEntity.loginHint,
4310
+ name: accountEntity.name,
4311
+ nativeAccountId: accountEntity.nativeAccountId,
4312
+ authorityType: accountEntity.authorityType,
4313
+ // Deserialize tenant profiles array into a Map
4314
+ tenantProfiles: new Map((accountEntity.tenantProfiles || []).map((tenantProfile) => {
4315
+ return [tenantProfile.tenantId, tenantProfile];
4316
+ })),
4317
+ dataBoundary: accountEntity.dataBoundary,
4318
+ };
4255
4319
  }
4256
4320
  /**
4257
- * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
4258
- * @param accountFilter - (Optional) filter to narrow down the accounts returned
4259
- * @returns Array of AccountInfo objects in cache
4321
+ * Returns true if the account entity is in single tenant format (outdated), false otherwise
4260
4322
  */
4261
- getAllAccounts(accountFilter, correlationId) {
4262
- return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter);
4323
+ isSingleTenant() {
4324
+ return !this.tenantProfiles;
4263
4325
  }
4264
4326
  /**
4265
- * Gets first tenanted AccountInfo object found based on provided filters
4327
+ * Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
4328
+ * @param accountDetails
4266
4329
  */
4267
- getAccountInfoFilteredBy(accountFilter, correlationId) {
4268
- if (Object.keys(accountFilter).length === 0 ||
4269
- Object.values(accountFilter).every((value) => !value)) {
4270
- this.commonLogger.warning("getAccountInfoFilteredBy: Account filter is empty or invalid, returning null");
4271
- return null;
4272
- }
4273
- const allAccounts = this.getAllAccounts(accountFilter, correlationId);
4274
- if (allAccounts.length > 1) {
4275
- // If one or more accounts are found, prioritize accounts that have an ID token
4276
- const sortedAccounts = allAccounts.sort((account) => {
4277
- return account.idTokenClaims ? -1 : 1;
4278
- });
4279
- return sortedAccounts[0];
4330
+ static createAccount(accountDetails, authority, base64Decode) {
4331
+ const account = new AccountEntity();
4332
+ if (authority.authorityType === AuthorityType.Adfs) {
4333
+ account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
4280
4334
  }
4281
- else if (allAccounts.length === 1) {
4282
- // If only one account is found, return it regardless of whether a matching ID token was found
4283
- return allAccounts[0];
4335
+ else if (authority.protocolMode === ProtocolMode.OIDC) {
4336
+ account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
4284
4337
  }
4285
4338
  else {
4286
- return null;
4339
+ account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
4287
4340
  }
4288
- }
4289
- /**
4290
- * Returns a single matching
4291
- * @param accountFilter
4292
- * @returns
4293
- */
4294
- getBaseAccountInfo(accountFilter, correlationId) {
4295
- const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
4296
- if (accountEntities.length > 0) {
4297
- return accountEntities[0].getAccountInfo();
4341
+ let clientInfo;
4342
+ if (accountDetails.clientInfo && base64Decode) {
4343
+ clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
4344
+ if (clientInfo.xms_tdbr) {
4345
+ account.dataBoundary =
4346
+ clientInfo.xms_tdbr === "EU" ? "EU" : "None";
4347
+ }
4348
+ }
4349
+ account.clientInfo = accountDetails.clientInfo;
4350
+ account.homeAccountId = accountDetails.homeAccountId;
4351
+ account.nativeAccountId = accountDetails.nativeAccountId;
4352
+ const env = accountDetails.environment ||
4353
+ (authority && authority.getPreferredCache());
4354
+ if (!env) {
4355
+ throw createClientAuthError(invalidCacheEnvironment);
4356
+ }
4357
+ account.environment = env;
4358
+ // non AAD scenarios can have empty realm
4359
+ account.realm =
4360
+ clientInfo?.utid ||
4361
+ getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
4362
+ "";
4363
+ // How do you account for MSA CID here?
4364
+ account.localAccountId =
4365
+ clientInfo?.uid ||
4366
+ accountDetails.idTokenClaims?.oid ||
4367
+ accountDetails.idTokenClaims?.sub ||
4368
+ "";
4369
+ /*
4370
+ * In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
4371
+ * In most cases it will contain a single email. This field should not be relied upon if a custom
4372
+ * policy is configured to return more than 1 email.
4373
+ */
4374
+ const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
4375
+ accountDetails.idTokenClaims?.upn;
4376
+ const email = accountDetails.idTokenClaims?.emails
4377
+ ? accountDetails.idTokenClaims.emails[0]
4378
+ : null;
4379
+ account.username = preferredUsername || email || "";
4380
+ account.loginHint = accountDetails.idTokenClaims?.login_hint;
4381
+ account.name = accountDetails.idTokenClaims?.name || "";
4382
+ account.cloudGraphHostName = accountDetails.cloudGraphHostName;
4383
+ account.msGraphHost = accountDetails.msGraphHost;
4384
+ if (accountDetails.tenantProfiles) {
4385
+ account.tenantProfiles = accountDetails.tenantProfiles;
4298
4386
  }
4299
4387
  else {
4300
- return null;
4388
+ const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
4389
+ account.tenantProfiles = [tenantProfile];
4301
4390
  }
4391
+ return account;
4302
4392
  }
4303
4393
  /**
4304
- * Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
4305
- * and builds the account info objects from the matching ID token's claims
4306
- * @param cachedAccounts
4307
- * @param accountFilter
4308
- * @returns Array of AccountInfo objects that match account and tenant profile filters
4394
+ * Creates an AccountEntity object from AccountInfo
4395
+ * @param accountInfo
4396
+ * @param cloudGraphHostName
4397
+ * @param msGraphHost
4398
+ * @returns
4309
4399
  */
4310
- buildTenantProfiles(cachedAccounts, correlationId, accountFilter) {
4311
- return cachedAccounts.flatMap((accountEntity) => {
4312
- return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter);
4313
- });
4314
- }
4315
- getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) {
4316
- let tenantedAccountInfo = null;
4317
- let idTokenClaims;
4318
- if (tenantProfileFilter) {
4319
- if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) {
4320
- return null;
4400
+ static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
4401
+ const account = new AccountEntity();
4402
+ account.authorityType =
4403
+ accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
4404
+ account.homeAccountId = accountInfo.homeAccountId;
4405
+ account.localAccountId = accountInfo.localAccountId;
4406
+ account.nativeAccountId = accountInfo.nativeAccountId;
4407
+ account.realm = accountInfo.tenantId;
4408
+ account.environment = accountInfo.environment;
4409
+ account.username = accountInfo.username;
4410
+ account.name = accountInfo.name;
4411
+ account.loginHint = accountInfo.loginHint;
4412
+ account.cloudGraphHostName = cloudGraphHostName;
4413
+ account.msGraphHost = msGraphHost;
4414
+ // Serialize tenant profiles map into an array
4415
+ account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
4416
+ account.dataBoundary = accountInfo.dataBoundary;
4417
+ return account;
4418
+ }
4419
+ /**
4420
+ * Generate HomeAccountId from server response
4421
+ * @param serverClientInfo
4422
+ * @param authType
4423
+ */
4424
+ static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
4425
+ // since ADFS/DSTS do not have tid and does not set client_info
4426
+ if (!(authType === AuthorityType.Adfs ||
4427
+ authType === AuthorityType.Dsts)) {
4428
+ // for cases where there is clientInfo
4429
+ if (serverClientInfo) {
4430
+ try {
4431
+ const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
4432
+ if (clientInfo.uid && clientInfo.utid) {
4433
+ return `${clientInfo.uid}.${clientInfo.utid}`;
4434
+ }
4435
+ }
4436
+ catch (e) { }
4437
+ }
4438
+ logger.warning("No client info in response");
4439
+ }
4440
+ // default to "sub" claim
4441
+ return idTokenClaims?.sub || "";
4442
+ }
4443
+ /**
4444
+ * Validates an entity: checks for all expected params
4445
+ * @param entity
4446
+ */
4447
+ static isAccountEntity(entity) {
4448
+ if (!entity) {
4449
+ return false;
4450
+ }
4451
+ return (entity.hasOwnProperty("homeAccountId") &&
4452
+ entity.hasOwnProperty("environment") &&
4453
+ entity.hasOwnProperty("realm") &&
4454
+ entity.hasOwnProperty("localAccountId") &&
4455
+ entity.hasOwnProperty("username") &&
4456
+ entity.hasOwnProperty("authorityType"));
4457
+ }
4458
+ /**
4459
+ * Helper function to determine whether 2 accountInfo objects represent the same account
4460
+ * @param accountA
4461
+ * @param accountB
4462
+ * @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
4463
+ */
4464
+ static accountInfoIsEqual(accountA, accountB, compareClaims) {
4465
+ if (!accountA || !accountB) {
4466
+ return false;
4467
+ }
4468
+ let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
4469
+ if (compareClaims) {
4470
+ const accountAClaims = (accountA.idTokenClaims ||
4471
+ {});
4472
+ const accountBClaims = (accountB.idTokenClaims ||
4473
+ {});
4474
+ // issued at timestamp and nonce are expected to change each time a new id token is acquired
4475
+ claimsMatch =
4476
+ accountAClaims.iat === accountBClaims.iat &&
4477
+ accountAClaims.nonce === accountBClaims.nonce;
4478
+ }
4479
+ return (accountA.homeAccountId === accountB.homeAccountId &&
4480
+ accountA.localAccountId === accountB.localAccountId &&
4481
+ accountA.username === accountB.username &&
4482
+ accountA.tenantId === accountB.tenantId &&
4483
+ accountA.loginHint === accountB.loginHint &&
4484
+ accountA.environment === accountB.environment &&
4485
+ accountA.nativeAccountId === accountB.nativeAccountId &&
4486
+ claimsMatch);
4487
+ }
4488
+ }
4489
+
4490
+ /*
4491
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4492
+ * Licensed under the MIT License.
4493
+ */
4494
+ const cacheQuotaExceeded = "cache_quota_exceeded";
4495
+ const cacheErrorUnknown = "cache_error_unknown";
4496
+
4497
+ var CacheErrorCodes = /*#__PURE__*/Object.freeze({
4498
+ __proto__: null,
4499
+ cacheErrorUnknown: cacheErrorUnknown,
4500
+ cacheQuotaExceeded: cacheQuotaExceeded
4501
+ });
4502
+
4503
+ /*
4504
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4505
+ * Licensed under the MIT License.
4506
+ */
4507
+ const CacheErrorMessages = {
4508
+ [cacheQuotaExceeded]: "Exceeded cache storage capacity.",
4509
+ [cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
4510
+ };
4511
+ /**
4512
+ * Error thrown when there is an error with the cache
4513
+ */
4514
+ class CacheError extends AuthError {
4515
+ constructor(errorCode, errorMessage) {
4516
+ const message = errorMessage ||
4517
+ (CacheErrorMessages[errorCode]
4518
+ ? CacheErrorMessages[errorCode]
4519
+ : CacheErrorMessages[cacheErrorUnknown]);
4520
+ super(`${errorCode}: ${message}`);
4521
+ Object.setPrototypeOf(this, CacheError.prototype);
4522
+ this.name = "CacheError";
4523
+ this.errorCode = errorCode;
4524
+ this.errorMessage = message;
4525
+ }
4526
+ }
4527
+ /**
4528
+ * Helper function to wrap browser errors in a CacheError object
4529
+ * @param e
4530
+ * @returns
4531
+ */
4532
+ function createCacheError(e) {
4533
+ if (!(e instanceof Error)) {
4534
+ return new CacheError(cacheErrorUnknown);
4535
+ }
4536
+ if (e.name === "QuotaExceededError" ||
4537
+ e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
4538
+ e.message.includes("exceeded the quota")) {
4539
+ return new CacheError(cacheQuotaExceeded);
4540
+ }
4541
+ else {
4542
+ return new CacheError(e.name, e.message);
4543
+ }
4544
+ }
4545
+
4546
+ /*
4547
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4548
+ * Licensed under the MIT License.
4549
+ */
4550
+ /**
4551
+ * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
4552
+ * @internal
4553
+ */
4554
+ class CacheManager {
4555
+ constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) {
4556
+ this.clientId = clientId;
4557
+ this.cryptoImpl = cryptoImpl;
4558
+ this.commonLogger = logger.clone(name, version);
4559
+ this.staticAuthorityOptions = staticAuthorityOptions;
4560
+ this.performanceClient = performanceClient;
4561
+ }
4562
+ /**
4563
+ * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
4564
+ * @param accountFilter - (Optional) filter to narrow down the accounts returned
4565
+ * @returns Array of AccountInfo objects in cache
4566
+ */
4567
+ getAllAccounts(accountFilter, correlationId) {
4568
+ return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter);
4569
+ }
4570
+ /**
4571
+ * Gets first tenanted AccountInfo object found based on provided filters
4572
+ */
4573
+ getAccountInfoFilteredBy(accountFilter, correlationId) {
4574
+ if (Object.keys(accountFilter).length === 0 ||
4575
+ Object.values(accountFilter).every((value) => !value)) {
4576
+ this.commonLogger.warning("getAccountInfoFilteredBy: Account filter is empty or invalid, returning null");
4577
+ return null;
4578
+ }
4579
+ const allAccounts = this.getAllAccounts(accountFilter, correlationId);
4580
+ if (allAccounts.length > 1) {
4581
+ // If one or more accounts are found, prioritize accounts that have an ID token
4582
+ const sortedAccounts = allAccounts.sort((account) => {
4583
+ return account.idTokenClaims ? -1 : 1;
4584
+ });
4585
+ return sortedAccounts[0];
4586
+ }
4587
+ else if (allAccounts.length === 1) {
4588
+ // If only one account is found, return it regardless of whether a matching ID token was found
4589
+ return allAccounts[0];
4590
+ }
4591
+ else {
4592
+ return null;
4593
+ }
4594
+ }
4595
+ /**
4596
+ * Returns a single matching
4597
+ * @param accountFilter
4598
+ * @returns
4599
+ */
4600
+ getBaseAccountInfo(accountFilter, correlationId) {
4601
+ const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
4602
+ if (accountEntities.length > 0) {
4603
+ return AccountEntity.getAccountInfo(accountEntities[0]);
4604
+ }
4605
+ else {
4606
+ return null;
4607
+ }
4608
+ }
4609
+ /**
4610
+ * Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
4611
+ * and builds the account info objects from the matching ID token's claims
4612
+ * @param cachedAccounts
4613
+ * @param accountFilter
4614
+ * @returns Array of AccountInfo objects that match account and tenant profile filters
4615
+ */
4616
+ buildTenantProfiles(cachedAccounts, correlationId, accountFilter) {
4617
+ return cachedAccounts.flatMap((accountEntity) => {
4618
+ return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter);
4619
+ });
4620
+ }
4621
+ getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) {
4622
+ let tenantedAccountInfo = null;
4623
+ let idTokenClaims;
4624
+ if (tenantProfileFilter) {
4625
+ if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) {
4626
+ return null;
4321
4627
  }
4322
4628
  }
4323
4629
  const idToken = this.getIdToken(accountInfo, correlationId, tokenKeys, tenantProfile.tenantId);
@@ -4333,7 +4639,7 @@ class CacheManager {
4333
4639
  return tenantedAccountInfo;
4334
4640
  }
4335
4641
  getTenantProfilesFromAccountEntity(accountEntity, correlationId, targetTenantId, tenantProfileFilter) {
4336
- const accountInfo = accountEntity.getAccountInfo();
4642
+ const accountInfo = AccountEntity.getAccountInfo(accountEntity);
4337
4643
  let searchTenantProfiles = accountInfo.tenantProfiles || new Map();
4338
4644
  const tokenKeys = this.getTokenKeys();
4339
4645
  // If a tenant ID was provided, only return the tenant profile for that tenant ID if it exists
@@ -4403,27 +4709,28 @@ class CacheManager {
4403
4709
  /**
4404
4710
  * saves a cache record
4405
4711
  * @param cacheRecord {CacheRecord}
4406
- * @param storeInCache {?StoreInCache}
4407
4712
  * @param correlationId {?string} correlation id
4713
+ * @param kmsi - Keep Me Signed In
4714
+ * @param storeInCache {?StoreInCache}
4408
4715
  */
4409
- async saveCacheRecord(cacheRecord, correlationId, storeInCache) {
4716
+ async saveCacheRecord(cacheRecord, correlationId, kmsi, storeInCache) {
4410
4717
  if (!cacheRecord) {
4411
4718
  throw createClientAuthError(invalidCacheRecord);
4412
4719
  }
4413
4720
  try {
4414
4721
  if (!!cacheRecord.account) {
4415
- await this.setAccount(cacheRecord.account, correlationId);
4722
+ await this.setAccount(cacheRecord.account, correlationId, kmsi);
4416
4723
  }
4417
4724
  if (!!cacheRecord.idToken && storeInCache?.idToken !== false) {
4418
- await this.setIdTokenCredential(cacheRecord.idToken, correlationId);
4725
+ await this.setIdTokenCredential(cacheRecord.idToken, correlationId, kmsi);
4419
4726
  }
4420
4727
  if (!!cacheRecord.accessToken &&
4421
4728
  storeInCache?.accessToken !== false) {
4422
- await this.saveAccessToken(cacheRecord.accessToken, correlationId);
4729
+ await this.saveAccessToken(cacheRecord.accessToken, correlationId, kmsi);
4423
4730
  }
4424
4731
  if (!!cacheRecord.refreshToken &&
4425
4732
  storeInCache?.refreshToken !== false) {
4426
- await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId);
4733
+ await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId, kmsi);
4427
4734
  }
4428
4735
  if (!!cacheRecord.appMetadata) {
4429
4736
  this.setAppMetadata(cacheRecord.appMetadata, correlationId);
@@ -4443,7 +4750,7 @@ class CacheManager {
4443
4750
  * saves access token credential
4444
4751
  * @param credential
4445
4752
  */
4446
- async saveAccessToken(credential, correlationId) {
4753
+ async saveAccessToken(credential, correlationId, kmsi) {
4447
4754
  const accessTokenFilter = {
4448
4755
  clientId: credential.clientId,
4449
4756
  credentialType: credential.credentialType,
@@ -4468,7 +4775,7 @@ class CacheManager {
4468
4775
  }
4469
4776
  }
4470
4777
  });
4471
- await this.setAccessTokenCredential(credential, correlationId);
4778
+ await this.setAccessTokenCredential(credential, correlationId, kmsi);
4472
4779
  }
4473
4780
  /**
4474
4781
  * Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache
@@ -5528,44 +5835,6 @@ const CcsCredentialType = {
5528
5835
  UPN: "UPN",
5529
5836
  };
5530
5837
 
5531
- /*
5532
- * Copyright (c) Microsoft Corporation. All rights reserved.
5533
- * Licensed under the MIT License.
5534
- */
5535
- /**
5536
- * Function to build a client info object from server clientInfo string
5537
- * @param rawClientInfo
5538
- * @param crypto
5539
- */
5540
- function buildClientInfo(rawClientInfo, base64Decode) {
5541
- if (!rawClientInfo) {
5542
- throw createClientAuthError(clientInfoEmptyError);
5543
- }
5544
- try {
5545
- const decodedClientInfo = base64Decode(rawClientInfo);
5546
- return JSON.parse(decodedClientInfo);
5547
- }
5548
- catch (e) {
5549
- throw createClientAuthError(clientInfoDecodingError);
5550
- }
5551
- }
5552
- /**
5553
- * Function to build a client info object from cached homeAccountId string
5554
- * @param homeAccountId
5555
- */
5556
- function buildClientInfoFromHomeAccountId(homeAccountId) {
5557
- if (!homeAccountId) {
5558
- throw createClientAuthError(clientInfoDecodingError);
5559
- }
5560
- const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
5561
- return {
5562
- uid: clientInfoParts[0],
5563
- utid: clientInfoParts.length < 2
5564
- ? Constants.EMPTY_STRING
5565
- : clientInfoParts[1],
5566
- };
5567
- }
5568
-
5569
5838
  /*
5570
5839
  * Copyright (c) Microsoft Corporation. All rights reserved.
5571
5840
  * Licensed under the MIT License.
@@ -6326,246 +6595,6 @@ class BaseClient {
6326
6595
  }
6327
6596
  }
6328
6597
 
6329
- /*
6330
- * Copyright (c) Microsoft Corporation. All rights reserved.
6331
- * Licensed under the MIT License.
6332
- */
6333
- /**
6334
- * Gets tenantId from available ID token claims to set as credential realm with the following precedence:
6335
- * 1. tid - if the token is acquired from an Azure AD tenant tid will be present
6336
- * 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
6337
- * 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
6338
- * Downcased to match the realm case-insensitive comparison requirements
6339
- * @param idTokenClaims
6340
- * @returns
6341
- */
6342
- function getTenantIdFromIdTokenClaims(idTokenClaims) {
6343
- if (idTokenClaims) {
6344
- const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
6345
- return tenantId || null;
6346
- }
6347
- return null;
6348
- }
6349
-
6350
- /*
6351
- * Copyright (c) Microsoft Corporation. All rights reserved.
6352
- * Licensed under the MIT License.
6353
- */
6354
- /**
6355
- * Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
6356
- *
6357
- * Key : Value Schema
6358
- *
6359
- * Key: <home_account_id>-<environment>-<realm*>
6360
- *
6361
- * Value Schema:
6362
- * {
6363
- * homeAccountId: home account identifier for the auth scheme,
6364
- * environment: entity that issued the token, represented as a full host
6365
- * realm: Full tenant or organizational identifier that the account belongs to
6366
- * localAccountId: Original tenant-specific accountID, usually used for legacy cases
6367
- * username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
6368
- * authorityType: Accounts authority type as a string
6369
- * name: Full name for the account, including given name and family name,
6370
- * lastModificationTime: last time this entity was modified in the cache
6371
- * lastModificationApp:
6372
- * nativeAccountId: Account identifier on the native device
6373
- * tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
6374
- * }
6375
- * @internal
6376
- */
6377
- class AccountEntity {
6378
- /**
6379
- * Returns the AccountInfo interface for this account.
6380
- */
6381
- getAccountInfo() {
6382
- return {
6383
- homeAccountId: this.homeAccountId,
6384
- environment: this.environment,
6385
- tenantId: this.realm,
6386
- username: this.username,
6387
- localAccountId: this.localAccountId,
6388
- loginHint: this.loginHint,
6389
- name: this.name,
6390
- nativeAccountId: this.nativeAccountId,
6391
- authorityType: this.authorityType,
6392
- // Deserialize tenant profiles array into a Map
6393
- tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => {
6394
- return [tenantProfile.tenantId, tenantProfile];
6395
- })),
6396
- dataBoundary: this.dataBoundary,
6397
- };
6398
- }
6399
- /**
6400
- * Returns true if the account entity is in single tenant format (outdated), false otherwise
6401
- */
6402
- isSingleTenant() {
6403
- return !this.tenantProfiles;
6404
- }
6405
- /**
6406
- * Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
6407
- * @param accountDetails
6408
- */
6409
- static createAccount(accountDetails, authority, base64Decode) {
6410
- const account = new AccountEntity();
6411
- if (authority.authorityType === AuthorityType.Adfs) {
6412
- account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
6413
- }
6414
- else if (authority.protocolMode === ProtocolMode.OIDC) {
6415
- account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
6416
- }
6417
- else {
6418
- account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
6419
- }
6420
- let clientInfo;
6421
- if (accountDetails.clientInfo && base64Decode) {
6422
- clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
6423
- if (clientInfo.xms_tdbr) {
6424
- account.dataBoundary =
6425
- clientInfo.xms_tdbr === "EU" ? "EU" : "None";
6426
- }
6427
- }
6428
- account.clientInfo = accountDetails.clientInfo;
6429
- account.homeAccountId = accountDetails.homeAccountId;
6430
- account.nativeAccountId = accountDetails.nativeAccountId;
6431
- const env = accountDetails.environment ||
6432
- (authority && authority.getPreferredCache());
6433
- if (!env) {
6434
- throw createClientAuthError(invalidCacheEnvironment);
6435
- }
6436
- account.environment = env;
6437
- // non AAD scenarios can have empty realm
6438
- account.realm =
6439
- clientInfo?.utid ||
6440
- getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
6441
- "";
6442
- // How do you account for MSA CID here?
6443
- account.localAccountId =
6444
- clientInfo?.uid ||
6445
- accountDetails.idTokenClaims?.oid ||
6446
- accountDetails.idTokenClaims?.sub ||
6447
- "";
6448
- /*
6449
- * In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
6450
- * In most cases it will contain a single email. This field should not be relied upon if a custom
6451
- * policy is configured to return more than 1 email.
6452
- */
6453
- const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
6454
- accountDetails.idTokenClaims?.upn;
6455
- const email = accountDetails.idTokenClaims?.emails
6456
- ? accountDetails.idTokenClaims.emails[0]
6457
- : null;
6458
- account.username = preferredUsername || email || "";
6459
- account.loginHint = accountDetails.idTokenClaims?.login_hint;
6460
- account.name = accountDetails.idTokenClaims?.name || "";
6461
- account.cloudGraphHostName = accountDetails.cloudGraphHostName;
6462
- account.msGraphHost = accountDetails.msGraphHost;
6463
- if (accountDetails.tenantProfiles) {
6464
- account.tenantProfiles = accountDetails.tenantProfiles;
6465
- }
6466
- else {
6467
- const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
6468
- account.tenantProfiles = [tenantProfile];
6469
- }
6470
- return account;
6471
- }
6472
- /**
6473
- * Creates an AccountEntity object from AccountInfo
6474
- * @param accountInfo
6475
- * @param cloudGraphHostName
6476
- * @param msGraphHost
6477
- * @returns
6478
- */
6479
- static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
6480
- const account = new AccountEntity();
6481
- account.authorityType =
6482
- accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
6483
- account.homeAccountId = accountInfo.homeAccountId;
6484
- account.localAccountId = accountInfo.localAccountId;
6485
- account.nativeAccountId = accountInfo.nativeAccountId;
6486
- account.realm = accountInfo.tenantId;
6487
- account.environment = accountInfo.environment;
6488
- account.username = accountInfo.username;
6489
- account.name = accountInfo.name;
6490
- account.loginHint = accountInfo.loginHint;
6491
- account.cloudGraphHostName = cloudGraphHostName;
6492
- account.msGraphHost = msGraphHost;
6493
- // Serialize tenant profiles map into an array
6494
- account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
6495
- account.dataBoundary = accountInfo.dataBoundary;
6496
- return account;
6497
- }
6498
- /**
6499
- * Generate HomeAccountId from server response
6500
- * @param serverClientInfo
6501
- * @param authType
6502
- */
6503
- static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
6504
- // since ADFS/DSTS do not have tid and does not set client_info
6505
- if (!(authType === AuthorityType.Adfs ||
6506
- authType === AuthorityType.Dsts)) {
6507
- // for cases where there is clientInfo
6508
- if (serverClientInfo) {
6509
- try {
6510
- const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
6511
- if (clientInfo.uid && clientInfo.utid) {
6512
- return `${clientInfo.uid}.${clientInfo.utid}`;
6513
- }
6514
- }
6515
- catch (e) { }
6516
- }
6517
- logger.warning("No client info in response");
6518
- }
6519
- // default to "sub" claim
6520
- return idTokenClaims?.sub || "";
6521
- }
6522
- /**
6523
- * Validates an entity: checks for all expected params
6524
- * @param entity
6525
- */
6526
- static isAccountEntity(entity) {
6527
- if (!entity) {
6528
- return false;
6529
- }
6530
- return (entity.hasOwnProperty("homeAccountId") &&
6531
- entity.hasOwnProperty("environment") &&
6532
- entity.hasOwnProperty("realm") &&
6533
- entity.hasOwnProperty("localAccountId") &&
6534
- entity.hasOwnProperty("username") &&
6535
- entity.hasOwnProperty("authorityType"));
6536
- }
6537
- /**
6538
- * Helper function to determine whether 2 accountInfo objects represent the same account
6539
- * @param accountA
6540
- * @param accountB
6541
- * @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
6542
- */
6543
- static accountInfoIsEqual(accountA, accountB, compareClaims) {
6544
- if (!accountA || !accountB) {
6545
- return false;
6546
- }
6547
- let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
6548
- if (compareClaims) {
6549
- const accountAClaims = (accountA.idTokenClaims ||
6550
- {});
6551
- const accountBClaims = (accountB.idTokenClaims ||
6552
- {});
6553
- // issued at timestamp and nonce are expected to change each time a new id token is acquired
6554
- claimsMatch =
6555
- accountAClaims.iat === accountBClaims.iat &&
6556
- accountAClaims.nonce === accountBClaims.nonce;
6557
- }
6558
- return (accountA.homeAccountId === accountB.homeAccountId &&
6559
- accountA.localAccountId === accountB.localAccountId &&
6560
- accountA.username === accountB.username &&
6561
- accountA.tenantId === accountB.tenantId &&
6562
- accountA.loginHint === accountB.loginHint &&
6563
- accountA.environment === accountB.environment &&
6564
- accountA.nativeAccountId === accountB.nativeAccountId &&
6565
- claimsMatch);
6566
- }
6567
- }
6568
-
6569
6598
  /*
6570
6599
  * Copyright (c) Microsoft Corporation. All rights reserved.
6571
6600
  * Licensed under the MIT License.
@@ -6967,14 +6996,14 @@ class ResponseHandler {
6967
6996
  if (handlingRefreshTokenResponse &&
6968
6997
  !forceCacheRefreshTokenResponse &&
6969
6998
  cacheRecord.account) {
6970
- const key = this.cacheStorage.generateAccountKey(cacheRecord.account.getAccountInfo());
6999
+ const key = this.cacheStorage.generateAccountKey(AccountEntity.getAccountInfo(cacheRecord.account));
6971
7000
  const account = this.cacheStorage.getAccount(key, request.correlationId);
6972
7001
  if (!account) {
6973
7002
  this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
6974
7003
  return await ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, undefined, serverRequestId);
6975
7004
  }
6976
7005
  }
6977
- await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, request.storeInCache);
7006
+ await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, isKmsi(idTokenClaims || {}), request.storeInCache);
6978
7007
  }
6979
7008
  finally {
6980
7009
  if (this.persistencePlugin &&
@@ -7121,7 +7150,7 @@ class ResponseHandler {
7121
7150
  serverTokenResponse?.spa_accountid;
7122
7151
  }
7123
7152
  const accountInfo = cacheRecord.account
7124
- ? updateAccountTenantProfileData(cacheRecord.account.getAccountInfo(), undefined, // tenantProfile optional
7153
+ ? updateAccountTenantProfileData(AccountEntity.getAccountInfo(cacheRecord.account), undefined, // tenantProfile optional
7125
7154
  idTokenClaims, cacheRecord.idToken?.secret)
7126
7155
  : null;
7127
7156
  return {
@@ -8043,6 +8072,48 @@ class AuthenticationHeaderParser {
8043
8072
  }
8044
8073
  }
8045
8074
 
8075
+ /*
8076
+ * Copyright (c) Microsoft Corporation. All rights reserved.
8077
+ * Licensed under the MIT License.
8078
+ */
8079
+ /**
8080
+ * Converts a numeric tag to a string representation
8081
+ * @param tag - The numeric tag to convert
8082
+ * @returns The string representation of the tag
8083
+ */
8084
+ function tagToString(tag) {
8085
+ if (tag === 0) {
8086
+ return "UNTAG";
8087
+ }
8088
+ const tagSymbolSpace = "abcdefghijklmnopqrstuvwxyz0123456789****************************";
8089
+ let tagBuffer = "*****";
8090
+ const chars = [
8091
+ tagSymbolSpace[(tag >> 24) & 0x3f],
8092
+ tagSymbolSpace[(tag >> 18) & 0x3f],
8093
+ tagSymbolSpace[(tag >> 12) & 0x3f],
8094
+ tagSymbolSpace[(tag >> 6) & 0x3f],
8095
+ tagSymbolSpace[(tag >> 0) & 0x3f],
8096
+ ];
8097
+ tagBuffer = chars.join("");
8098
+ return tagBuffer;
8099
+ }
8100
+ /**
8101
+ * Error class for MSAL Runtime errors that preserves detailed broker information
8102
+ */
8103
+ class PlatformBrokerError extends AuthError {
8104
+ constructor(errorStatus, errorContext, errorCode, errorTag) {
8105
+ const tagString = tagToString(errorTag);
8106
+ const enhancedErrorContext = errorContext
8107
+ ? `${errorContext} (Error Code: ${errorCode}, Tag: ${tagString})`
8108
+ : `(Error Code: ${errorCode}, Tag: ${tagString})`;
8109
+ super(errorStatus, enhancedErrorContext);
8110
+ this.name = "PlatformBrokerError";
8111
+ this.statusCode = errorCode;
8112
+ this.tag = tagString;
8113
+ Object.setPrototypeOf(this, PlatformBrokerError.prototype);
8114
+ }
8115
+ }
8116
+
8046
8117
  /*
8047
8118
  * Copyright (c) Microsoft Corporation. All rights reserved.
8048
8119
  * Licensed under the MIT License.
@@ -8364,6 +8435,7 @@ exports.PerformanceEventAbbreviations = PerformanceEventAbbreviations;
8364
8435
  exports.PerformanceEventStatus = PerformanceEventStatus;
8365
8436
  exports.PerformanceEvents = PerformanceEvents;
8366
8437
  exports.PersistentCacheKeys = PersistentCacheKeys;
8438
+ exports.PlatformBrokerError = PlatformBrokerError;
8367
8439
  exports.PopTokenGenerator = PopTokenGenerator;
8368
8440
  exports.PromptValue = PromptValue;
8369
8441
  exports.ProtocolMode = ProtocolMode;
@@ -8408,4 +8480,4 @@ exports.invokeAsync = invokeAsync;
8408
8480
  exports.tenantIdMatchesHomeTenant = tenantIdMatchesHomeTenant;
8409
8481
  exports.updateAccountTenantProfileData = updateAccountTenantProfileData;
8410
8482
  exports.version = version;
8411
- //# sourceMappingURL=index-node-D8Iaiqq3.js.map
8483
+ //# sourceMappingURL=index-node-BF0Vz18w.js.map