@azure/msal-common 10.0.0 → 12.0.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 (127) hide show
  1. package/dist/_virtual/_tslib.js +1 -1
  2. package/dist/account/AuthToken.js +1 -1
  3. package/dist/account/CcsCredential.js +1 -1
  4. package/dist/account/ClientInfo.js +1 -1
  5. package/dist/account/TokenClaims.d.ts +5 -0
  6. package/dist/account/TokenClaims.d.ts.map +1 -1
  7. package/dist/authority/Authority.js +1 -1
  8. package/dist/authority/AuthorityFactory.js +1 -1
  9. package/dist/authority/AuthorityMetadata.js +1 -1
  10. package/dist/authority/AuthorityOptions.js +1 -1
  11. package/dist/authority/AuthorityType.js +1 -1
  12. package/dist/authority/CloudInstanceDiscoveryErrorResponse.js +1 -1
  13. package/dist/authority/CloudInstanceDiscoveryResponse.js +1 -1
  14. package/dist/authority/OpenIdConfigResponse.js +1 -1
  15. package/dist/authority/ProtocolMode.js +1 -1
  16. package/dist/authority/RegionDiscovery.js +1 -1
  17. package/dist/broker/nativeBroker/INativeBrokerPlugin.d.ts +16 -0
  18. package/dist/broker/nativeBroker/INativeBrokerPlugin.d.ts.map +1 -0
  19. package/dist/cache/CacheManager.d.ts +102 -51
  20. package/dist/cache/CacheManager.d.ts.map +1 -1
  21. package/dist/cache/CacheManager.js +414 -245
  22. package/dist/cache/CacheManager.js.map +1 -1
  23. package/dist/cache/entities/AccessTokenEntity.js +1 -1
  24. package/dist/cache/entities/AccountEntity.js +1 -1
  25. package/dist/cache/entities/AppMetadataEntity.js +1 -1
  26. package/dist/cache/entities/AuthorityMetadataEntity.js +1 -1
  27. package/dist/cache/entities/CacheRecord.js +1 -1
  28. package/dist/cache/entities/CredentialEntity.d.ts +0 -11
  29. package/dist/cache/entities/CredentialEntity.d.ts.map +1 -1
  30. package/dist/cache/entities/CredentialEntity.js +3 -39
  31. package/dist/cache/entities/CredentialEntity.js.map +1 -1
  32. package/dist/cache/entities/IdTokenEntity.js +1 -1
  33. package/dist/cache/entities/RefreshTokenEntity.js +1 -1
  34. package/dist/cache/entities/ServerTelemetryEntity.js +1 -1
  35. package/dist/cache/entities/ThrottlingEntity.js +1 -1
  36. package/dist/cache/interface/ICacheManager.d.ts +26 -17
  37. package/dist/cache/interface/ICacheManager.d.ts.map +1 -1
  38. package/dist/cache/persistence/TokenCacheContext.js +1 -1
  39. package/dist/cache/utils/CacheTypes.d.ts +9 -6
  40. package/dist/cache/utils/CacheTypes.d.ts.map +1 -1
  41. package/dist/client/AuthorizationCodeClient.js +1 -1
  42. package/dist/client/BaseClient.js +1 -1
  43. package/dist/client/ClientCredentialClient.d.ts +0 -1
  44. package/dist/client/ClientCredentialClient.d.ts.map +1 -1
  45. package/dist/client/ClientCredentialClient.js +3 -5
  46. package/dist/client/ClientCredentialClient.js.map +1 -1
  47. package/dist/client/DeviceCodeClient.js +1 -1
  48. package/dist/client/OnBehalfOfClient.d.ts.map +1 -1
  49. package/dist/client/OnBehalfOfClient.js +6 -8
  50. package/dist/client/OnBehalfOfClient.js.map +1 -1
  51. package/dist/client/RefreshTokenClient.js +3 -3
  52. package/dist/client/RefreshTokenClient.js.map +1 -1
  53. package/dist/client/SilentFlowClient.js +2 -2
  54. package/dist/client/SilentFlowClient.js.map +1 -1
  55. package/dist/client/UsernamePasswordClient.js +1 -1
  56. package/dist/config/ClientConfiguration.d.ts.map +1 -1
  57. package/dist/config/ClientConfiguration.js +3 -3
  58. package/dist/config/ClientConfiguration.js.map +1 -1
  59. package/dist/crypto/ICrypto.js +1 -1
  60. package/dist/crypto/JoseHeader.js +3 -3
  61. package/dist/crypto/JoseHeader.js.map +1 -1
  62. package/dist/crypto/PopTokenGenerator.js +1 -1
  63. package/dist/error/AuthError.js +1 -1
  64. package/dist/error/ClientAuthError.d.ts +16 -0
  65. package/dist/error/ClientAuthError.d.ts.map +1 -1
  66. package/dist/error/ClientAuthError.js +21 -1
  67. package/dist/error/ClientAuthError.js.map +1 -1
  68. package/dist/error/ClientConfigurationError.js +1 -1
  69. package/dist/error/InteractionRequiredAuthError.js +1 -1
  70. package/dist/error/JoseHeaderError.js +1 -1
  71. package/dist/error/ServerError.js +1 -1
  72. package/dist/index.cjs.js +700 -627
  73. package/dist/index.cjs.js.map +1 -1
  74. package/dist/index.d.ts +8 -5
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2 -2
  77. package/dist/logger/Logger.js +1 -1
  78. package/dist/network/INetworkModule.js +1 -1
  79. package/dist/network/NetworkManager.d.ts +11 -0
  80. package/dist/network/NetworkManager.d.ts.map +1 -1
  81. package/dist/network/NetworkManager.js +1 -1
  82. package/dist/network/NetworkManager.js.map +1 -1
  83. package/dist/network/ThrottlingUtils.d.ts +1 -1
  84. package/dist/network/ThrottlingUtils.d.ts.map +1 -1
  85. package/dist/network/ThrottlingUtils.js +4 -4
  86. package/dist/network/ThrottlingUtils.js.map +1 -1
  87. package/dist/packageMetadata.d.ts +1 -1
  88. package/dist/packageMetadata.js +2 -2
  89. package/dist/packageMetadata.js.map +1 -1
  90. package/dist/request/AuthenticationHeaderParser.js +1 -1
  91. package/dist/request/NativeRequest.d.ts +20 -0
  92. package/dist/request/NativeRequest.d.ts.map +1 -0
  93. package/dist/request/NativeSignOutRequest.d.ts +6 -0
  94. package/dist/request/NativeSignOutRequest.d.ts.map +1 -0
  95. package/dist/request/RequestParameterBuilder.js +1 -1
  96. package/dist/request/RequestValidator.js +1 -1
  97. package/dist/request/ScopeSet.d.ts +6 -0
  98. package/dist/request/ScopeSet.d.ts.map +1 -1
  99. package/dist/request/ScopeSet.js +17 -2
  100. package/dist/request/ScopeSet.js.map +1 -1
  101. package/dist/response/ResponseHandler.d.ts +1 -1
  102. package/dist/response/ResponseHandler.d.ts.map +1 -1
  103. package/dist/response/ResponseHandler.js +8 -4
  104. package/dist/response/ResponseHandler.js.map +1 -1
  105. package/dist/response/ServerAuthorizationTokenResponse.d.ts +1 -0
  106. package/dist/response/ServerAuthorizationTokenResponse.d.ts.map +1 -1
  107. package/dist/telemetry/performance/IPerformanceClient.d.ts +5 -3
  108. package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
  109. package/dist/telemetry/performance/PerformanceClient.d.ts +18 -41
  110. package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
  111. package/dist/telemetry/performance/PerformanceClient.js +93 -175
  112. package/dist/telemetry/performance/PerformanceClient.js.map +1 -1
  113. package/dist/telemetry/performance/PerformanceEvent.d.ts +28 -5
  114. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  115. package/dist/telemetry/performance/PerformanceEvent.js +3 -1
  116. package/dist/telemetry/performance/PerformanceEvent.js.map +1 -1
  117. package/dist/telemetry/performance/StubPerformanceClient.js +1 -1
  118. package/dist/telemetry/server/ServerTelemetryManager.js +1 -1
  119. package/dist/url/UrlString.js +1 -1
  120. package/dist/utils/Constants.d.ts +2 -16
  121. package/dist/utils/Constants.d.ts.map +1 -1
  122. package/dist/utils/Constants.js +3 -18
  123. package/dist/utils/Constants.js.map +1 -1
  124. package/dist/utils/ProtocolUtils.js +1 -1
  125. package/dist/utils/StringUtils.js +1 -1
  126. package/dist/utils/TimeUtils.js +1 -1
  127. package/package.json +1 -1
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-common v10.0.0 2023-02-06 */
1
+ /*! @azure/msal-common v12.0.0 2023-04-03 */
2
2
  'use strict';
3
3
  'use strict';
4
4
 
@@ -351,22 +351,6 @@ exports.CredentialType = void 0;
351
351
  CredentialType["ACCESS_TOKEN_WITH_AUTH_SCHEME"] = "AccessToken_With_AuthScheme";
352
352
  CredentialType["REFRESH_TOKEN"] = "RefreshToken";
353
353
  })(exports.CredentialType || (exports.CredentialType = {}));
354
- /**
355
- * Credential Type stored in the cache
356
- */
357
- exports.CacheSchemaType = void 0;
358
- (function (CacheSchemaType) {
359
- CacheSchemaType["ACCOUNT"] = "Account";
360
- CacheSchemaType["CREDENTIAL"] = "Credential";
361
- CacheSchemaType["ID_TOKEN"] = "IdToken";
362
- CacheSchemaType["ACCESS_TOKEN"] = "AccessToken";
363
- CacheSchemaType["REFRESH_TOKEN"] = "RefreshToken";
364
- CacheSchemaType["APP_METADATA"] = "AppMetadata";
365
- CacheSchemaType["TEMPORARY"] = "TempCache";
366
- CacheSchemaType["TELEMETRY"] = "Telemetry";
367
- CacheSchemaType["UNDEFINED"] = "Undefined";
368
- CacheSchemaType["THROTTLING"] = "Throttling";
369
- })(exports.CacheSchemaType || (exports.CacheSchemaType = {}));
370
354
  /**
371
355
  * Combine all cache types
372
356
  */
@@ -486,6 +470,7 @@ var JsonTypes;
486
470
  (function (JsonTypes) {
487
471
  JsonTypes["Jwt"] = "JWT";
488
472
  JsonTypes["Jwk"] = "JWK";
473
+ JsonTypes["Pop"] = "pop";
489
474
  })(JsonTypes || (JsonTypes = {}));
490
475
  var ONE_DAY_IN_MS = 86400000;
491
476
 
@@ -818,6 +803,14 @@ var ClientAuthErrorMessage = {
818
803
  keyIdMissing: {
819
804
  code: "key_id_missing",
820
805
  desc: "A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key."
806
+ },
807
+ noNetworkConnectivity: {
808
+ code: "no_network_connectivity",
809
+ desc: "No network connectivity. Check your internet connection."
810
+ },
811
+ userCanceledError: {
812
+ code: "user_canceled",
813
+ desc: "User canceled the flow."
821
814
  }
822
815
  };
823
816
  /**
@@ -1106,6 +1099,18 @@ var ClientAuthError = /** @class */ (function (_super) {
1106
1099
  ClientAuthError.createKeyIdMissingError = function () {
1107
1100
  return new ClientAuthError(ClientAuthErrorMessage.keyIdMissing.code, ClientAuthErrorMessage.keyIdMissing.desc);
1108
1101
  };
1102
+ /**
1103
+ * Create an error when the client does not have network connectivity
1104
+ */
1105
+ ClientAuthError.createNoNetworkConnectivityError = function () {
1106
+ return new ClientAuthError(ClientAuthErrorMessage.noNetworkConnectivity.code, ClientAuthErrorMessage.noNetworkConnectivity.desc);
1107
+ };
1108
+ /**
1109
+ * Create an error when the user cancels the flow
1110
+ */
1111
+ ClientAuthError.createUserCanceledError = function () {
1112
+ return new ClientAuthError(ClientAuthErrorMessage.userCanceledError.code, ClientAuthErrorMessage.userCanceledError.desc);
1113
+ };
1109
1114
  return ClientAuthError;
1110
1115
  }(AuthError));
1111
1116
 
@@ -1422,7 +1427,7 @@ var Logger = /** @class */ (function () {
1422
1427
 
1423
1428
  /* eslint-disable header/header */
1424
1429
  var name = "@azure/msal-common";
1425
- var version = "10.0.0";
1430
+ var version = "12.0.0";
1426
1431
 
1427
1432
  /*
1428
1433
  * Copyright (c) Microsoft Corporation. All rights reserved.
@@ -1444,178 +1449,6 @@ exports.AzureCloudInstance = void 0;
1444
1449
  AzureCloudInstance["AzureUsGovernment"] = "https://login.microsoftonline.us";
1445
1450
  })(exports.AzureCloudInstance || (exports.AzureCloudInstance = {}));
1446
1451
 
1447
- /*
1448
- * Copyright (c) Microsoft Corporation. All rights reserved.
1449
- * Licensed under the MIT License.
1450
- */
1451
- /**
1452
- * Base type for credentials to be stored in the cache: eg: ACCESS_TOKEN, ID_TOKEN etc
1453
- *
1454
- * Key:Value Schema:
1455
- *
1456
- * Key: <home_account_id*>-<environment>-<credential_type>-<client_id>-<realm*>-<target*>-<requestedClaims*>-<scheme*>
1457
- *
1458
- * Value Schema:
1459
- * {
1460
- * homeAccountId: home account identifier for the auth scheme,
1461
- * environment: entity that issued the token, represented as a full host
1462
- * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
1463
- * clientId: client ID of the application
1464
- * secret: Actual credential as a string
1465
- * familyId: Family ID identifier, usually only used for refresh tokens
1466
- * realm: Full tenant or organizational identifier that the account belongs to
1467
- * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
1468
- * tokenType: Matches the authentication scheme for which the token was issued (i.e. Bearer or pop)
1469
- * requestedClaimsHash: Matches the SHA 256 hash of the claims object included in the token request
1470
- * userAssertionHash: Matches the SHA 256 hash of the obo_assertion for the OBO flow
1471
- * }
1472
- */
1473
- var CredentialEntity = /** @class */ (function () {
1474
- function CredentialEntity() {
1475
- }
1476
- /**
1477
- * Initializes a map with credential {CredentialType} regular expressions.
1478
- */
1479
- CredentialEntity._initRegex = function () {
1480
- var separator = Separators.CACHE_KEY_SEPARATOR;
1481
- CredentialEntity.credentialRegexMap = new Map();
1482
- for (var _i = 0, _a = Object.keys(exports.CredentialType); _i < _a.length; _i++) {
1483
- var credKey = _a[_i];
1484
- var credVal = exports.CredentialType[credKey].toLowerCase();
1485
- try {
1486
- // Verify credential type is preceded by a valid host name (environment) using lookbehind
1487
- CredentialEntity.credentialRegexMap.set(exports.CredentialType[credKey], new RegExp("(?<=" + separator + CredentialEntity.credentialDomainRegex + ")" + separator + credVal + separator));
1488
- }
1489
- catch (err) {
1490
- // Lookbehind is not supported (Safari or older versions of IE) - removing it
1491
- CredentialEntity.credentialRegexMap.set(exports.CredentialType[credKey], new RegExp("" + separator + CredentialEntity.credentialDomainRegex + separator + credVal + separator));
1492
- }
1493
- }
1494
- };
1495
- /**
1496
- * Generate Account Id key component as per the schema: <home_account_id>-<environment>
1497
- */
1498
- CredentialEntity.prototype.generateAccountId = function () {
1499
- return CredentialEntity.generateAccountIdForCacheKey(this.homeAccountId, this.environment);
1500
- };
1501
- /**
1502
- * Generate Credential Id key component as per the schema: <credential_type>-<client_id>-<realm>
1503
- */
1504
- CredentialEntity.prototype.generateCredentialId = function () {
1505
- return CredentialEntity.generateCredentialIdForCacheKey(this.credentialType, this.clientId, this.realm, this.familyId);
1506
- };
1507
- /**
1508
- * Generate target key component as per schema: <target>
1509
- */
1510
- CredentialEntity.prototype.generateTarget = function () {
1511
- return CredentialEntity.generateTargetForCacheKey(this.target);
1512
- };
1513
- /**
1514
- * generates credential key
1515
- */
1516
- CredentialEntity.prototype.generateCredentialKey = function () {
1517
- return CredentialEntity.generateCredentialCacheKey(this.homeAccountId, this.environment, this.credentialType, this.clientId, this.realm, this.target, this.familyId, this.tokenType, this.requestedClaimsHash);
1518
- };
1519
- /**
1520
- * returns the type of the cache (in this case credential)
1521
- */
1522
- CredentialEntity.prototype.generateType = function () {
1523
- switch (this.credentialType) {
1524
- case exports.CredentialType.ID_TOKEN:
1525
- return exports.CacheType.ID_TOKEN;
1526
- case exports.CredentialType.ACCESS_TOKEN:
1527
- case exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME:
1528
- return exports.CacheType.ACCESS_TOKEN;
1529
- case exports.CredentialType.REFRESH_TOKEN:
1530
- return exports.CacheType.REFRESH_TOKEN;
1531
- default: {
1532
- throw ClientAuthError.createUnexpectedCredentialTypeError();
1533
- }
1534
- }
1535
- };
1536
- /**
1537
- * helper function to return `CredentialType`
1538
- * @param key
1539
- */
1540
- CredentialEntity.getCredentialType = function (key) {
1541
- var _a;
1542
- for (var _i = 0, _b = Object.keys(exports.CredentialType); _i < _b.length; _i++) {
1543
- var credKey = _b[_i];
1544
- if ((_a = this.credentialRegexMap.get(exports.CredentialType[credKey])) === null || _a === void 0 ? void 0 : _a.test(key.toLowerCase())) {
1545
- return exports.CredentialType[credKey];
1546
- }
1547
- }
1548
- return Constants.NOT_DEFINED;
1549
- };
1550
- /**
1551
- * generates credential key
1552
- * <home_account_id*>-\<environment>-<credential_type>-<client_id>-<realm\*>-<target\*>-<scheme\*>
1553
- */
1554
- CredentialEntity.generateCredentialCacheKey = function (homeAccountId, environment, credentialType, clientId, realm, target, familyId, tokenType, requestedClaimsHash) {
1555
- var credentialKey = [
1556
- this.generateAccountIdForCacheKey(homeAccountId, environment),
1557
- this.generateCredentialIdForCacheKey(credentialType, clientId, realm, familyId),
1558
- this.generateTargetForCacheKey(target),
1559
- this.generateClaimsHashForCacheKey(requestedClaimsHash),
1560
- this.generateSchemeForCacheKey(tokenType)
1561
- ];
1562
- return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
1563
- };
1564
- /**
1565
- * generates Account Id for keys
1566
- * @param homeAccountId
1567
- * @param environment
1568
- */
1569
- CredentialEntity.generateAccountIdForCacheKey = function (homeAccountId, environment) {
1570
- var accountId = [homeAccountId, environment];
1571
- return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
1572
- };
1573
- /**
1574
- * Generates Credential Id for keys
1575
- * @param credentialType
1576
- * @param realm
1577
- * @param clientId
1578
- * @param familyId
1579
- */
1580
- CredentialEntity.generateCredentialIdForCacheKey = function (credentialType, clientId, realm, familyId) {
1581
- var clientOrFamilyId = credentialType === exports.CredentialType.REFRESH_TOKEN
1582
- ? familyId || clientId
1583
- : clientId;
1584
- var credentialId = [
1585
- credentialType,
1586
- clientOrFamilyId,
1587
- realm || Constants.EMPTY_STRING,
1588
- ];
1589
- return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
1590
- };
1591
- /**
1592
- * Generate target key component as per schema: <target>
1593
- */
1594
- CredentialEntity.generateTargetForCacheKey = function (scopes) {
1595
- return (scopes || Constants.EMPTY_STRING).toLowerCase();
1596
- };
1597
- /**
1598
- * Generate requested claims key component as per schema: <requestedClaims>
1599
- */
1600
- CredentialEntity.generateClaimsHashForCacheKey = function (requestedClaimsHash) {
1601
- return (requestedClaimsHash || Constants.EMPTY_STRING).toLowerCase();
1602
- };
1603
- /**
1604
- * Generate scheme key componenet as per schema: <scheme>
1605
- */
1606
- CredentialEntity.generateSchemeForCacheKey = function (tokenType) {
1607
- /*
1608
- * PoP Tokens and SSH certs include scheme in cache key
1609
- * Cast to lowercase to handle "bearer" from ADFS
1610
- */
1611
- return (tokenType && tokenType.toLowerCase() !== exports.AuthenticationScheme.BEARER.toLowerCase()) ? tokenType.toLowerCase() : Constants.EMPTY_STRING;
1612
- };
1613
- // Match host names like "login.microsoftonline.com", "https://accounts.google.com:4000", https://localhost:5000, etc.
1614
- CredentialEntity.credentialDomainRegex = "(https?:\\/\\/)?((([\\w-]+\\.)*([\\w-]{1,63})(\\.(\\w{2,63})))|(localhost))(\\:[0-9]{4,5})?";
1615
- return CredentialEntity;
1616
- }());
1617
- CredentialEntity._initRegex();
1618
-
1619
1452
  /*
1620
1453
  * Copyright (c) Microsoft Corporation. All rights reserved.
1621
1454
  * Licensed under the MIT License.
@@ -1900,6 +1733,21 @@ var ScopeSet = /** @class */ (function () {
1900
1733
  var inputScopes = scopeString.split(" ");
1901
1734
  return new ScopeSet(inputScopes);
1902
1735
  };
1736
+ /**
1737
+ * Creates the set of scopes to search for in cache lookups
1738
+ * @param inputScopeString
1739
+ * @returns
1740
+ */
1741
+ ScopeSet.createSearchScopes = function (inputScopeString) {
1742
+ var scopeSet = new ScopeSet(inputScopeString);
1743
+ if (!scopeSet.containsOnlyOIDCScopes()) {
1744
+ scopeSet.removeOIDCScopes();
1745
+ }
1746
+ else {
1747
+ scopeSet.removeScope(Constants.OFFLINE_ACCESS_SCOPE);
1748
+ }
1749
+ return scopeSet;
1750
+ };
1903
1751
  /**
1904
1752
  * Used to validate the scopes input parameter requested by the developer.
1905
1753
  * @param {Array<string>} inputScopes - Developer requested permissions. Not all scopes are guaranteed to be included in the access token returned.
@@ -2396,35 +2244,59 @@ var AuthToken = /** @class */ (function () {
2396
2244
  * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
2397
2245
  */
2398
2246
  var CacheManager = /** @class */ (function () {
2399
- function CacheManager(clientId, cryptoImpl) {
2247
+ function CacheManager(clientId, cryptoImpl, logger) {
2400
2248
  this.clientId = clientId;
2401
2249
  this.cryptoImpl = cryptoImpl;
2250
+ this.commonLogger = logger.clone(name, version);
2402
2251
  }
2403
2252
  /**
2404
2253
  * Returns all accounts in cache
2405
2254
  */
2406
2255
  CacheManager.prototype.getAllAccounts = function () {
2407
2256
  var _this = this;
2408
- var currentAccounts = this.getAccountsFilteredBy();
2409
- var accountValues = Object.keys(currentAccounts).map(function (accountKey) { return currentAccounts[accountKey]; });
2410
- var numAccounts = accountValues.length;
2411
- if (numAccounts < 1) {
2257
+ var allAccountKeys = this.getAccountKeys();
2258
+ if (allAccountKeys.length < 1) {
2259
+ return [];
2260
+ }
2261
+ var accountEntities = allAccountKeys.reduce(function (accounts, key) {
2262
+ var entity = _this.getAccount(key);
2263
+ if (!entity) {
2264
+ return accounts;
2265
+ }
2266
+ accounts.push(entity);
2267
+ return accounts;
2268
+ }, []);
2269
+ if (accountEntities.length < 1) {
2412
2270
  return [];
2413
2271
  }
2414
2272
  else {
2415
- var allAccounts = accountValues.map(function (value) {
2416
- var accountEntity = CacheManager.toObject(new AccountEntity(), value);
2417
- var accountInfo = accountEntity.getAccountInfo();
2418
- var idToken = _this.readIdTokenFromCache(_this.clientId, accountInfo);
2419
- if (idToken && !accountInfo.idTokenClaims) {
2420
- accountInfo.idToken = idToken.secret;
2421
- accountInfo.idTokenClaims = new AuthToken(idToken.secret, _this.cryptoImpl).claims;
2422
- }
2423
- return accountInfo;
2273
+ var allAccounts = accountEntities.map(function (accountEntity) {
2274
+ return _this.getAccountInfoFromEntity(accountEntity);
2424
2275
  });
2425
2276
  return allAccounts;
2426
2277
  }
2427
2278
  };
2279
+ /**
2280
+ * Gets accountInfo object based on provided filters
2281
+ */
2282
+ CacheManager.prototype.getAccountInfoFilteredBy = function (accountFilter) {
2283
+ var allAccounts = this.getAccountsFilteredBy(accountFilter);
2284
+ if (allAccounts.length > 0) {
2285
+ return this.getAccountInfoFromEntity(allAccounts[0]);
2286
+ }
2287
+ else {
2288
+ return null;
2289
+ }
2290
+ };
2291
+ CacheManager.prototype.getAccountInfoFromEntity = function (accountEntity) {
2292
+ var accountInfo = accountEntity.getAccountInfo();
2293
+ var idToken = this.getIdToken(accountInfo);
2294
+ if (idToken) {
2295
+ accountInfo.idToken = idToken.secret;
2296
+ accountInfo.idTokenClaims = new AuthToken(idToken.secret, this.cryptoImpl).claims;
2297
+ }
2298
+ return accountInfo;
2299
+ };
2428
2300
  /**
2429
2301
  * saves a cache record
2430
2302
  * @param cacheRecord
@@ -2466,12 +2338,12 @@ var CacheManager = /** @class */ (function () {
2466
2338
  */
2467
2339
  CacheManager.prototype.saveAccessToken = function (credential) {
2468
2340
  return __awaiter(this, void 0, void 0, function () {
2469
- var currentTokenCache, currentScopes, currentAccessTokens, removedAccessTokens_1;
2341
+ var accessTokenFilter, tokenKeys, currentScopes, removedAccessTokens;
2470
2342
  var _this = this;
2471
2343
  return __generator(this, function (_a) {
2472
2344
  switch (_a.label) {
2473
2345
  case 0:
2474
- currentTokenCache = this.getCredentialsFilteredBy({
2346
+ accessTokenFilter = {
2475
2347
  clientId: credential.clientId,
2476
2348
  credentialType: credential.credentialType,
2477
2349
  environment: credential.environment,
@@ -2479,22 +2351,25 @@ var CacheManager = /** @class */ (function () {
2479
2351
  realm: credential.realm,
2480
2352
  tokenType: credential.tokenType,
2481
2353
  requestedClaimsHash: credential.requestedClaimsHash
2482
- });
2354
+ };
2355
+ tokenKeys = this.getTokenKeys();
2483
2356
  currentScopes = ScopeSet.fromString(credential.target);
2484
- currentAccessTokens = Object.keys(currentTokenCache.accessTokens).map(function (key) { return currentTokenCache.accessTokens[key]; });
2485
- if (!currentAccessTokens) return [3 /*break*/, 2];
2486
- removedAccessTokens_1 = [];
2487
- currentAccessTokens.forEach(function (tokenEntity) {
2488
- var tokenScopeSet = ScopeSet.fromString(tokenEntity.target);
2489
- if (tokenScopeSet.intersectingScopeSets(currentScopes)) {
2490
- removedAccessTokens_1.push(_this.removeCredential(tokenEntity));
2357
+ removedAccessTokens = [];
2358
+ tokenKeys.accessToken.forEach(function (key) {
2359
+ if (!_this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) {
2360
+ return;
2361
+ }
2362
+ var tokenEntity = _this.getAccessTokenCredential(key);
2363
+ if (tokenEntity && _this.credentialMatchesFilter(tokenEntity, accessTokenFilter)) {
2364
+ var tokenScopeSet = ScopeSet.fromString(tokenEntity.target);
2365
+ if (tokenScopeSet.intersectingScopeSets(currentScopes)) {
2366
+ removedAccessTokens.push(_this.removeAccessToken(key));
2367
+ }
2491
2368
  }
2492
2369
  });
2493
- return [4 /*yield*/, Promise.all(removedAccessTokens_1)];
2370
+ return [4 /*yield*/, Promise.all(removedAccessTokens)];
2494
2371
  case 1:
2495
2372
  _a.sent();
2496
- _a.label = 2;
2497
- case 2:
2498
2373
  this.setAccessTokenCredential(credential);
2499
2374
  return [2 /*return*/];
2500
2375
  }
@@ -2509,149 +2384,151 @@ var CacheManager = /** @class */ (function () {
2509
2384
  * @param realm
2510
2385
  */
2511
2386
  CacheManager.prototype.getAccountsFilteredBy = function (accountFilter) {
2512
- return this.getAccountsFilteredByInternal(accountFilter ? accountFilter.homeAccountId : Constants.EMPTY_STRING, accountFilter ? accountFilter.environment : Constants.EMPTY_STRING, accountFilter ? accountFilter.realm : Constants.EMPTY_STRING, accountFilter ? accountFilter.nativeAccountId : Constants.EMPTY_STRING);
2513
- };
2514
- /**
2515
- * retrieve accounts matching all provided filters; if no filter is set, get all accounts
2516
- * not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared
2517
- * @param homeAccountId
2518
- * @param environment
2519
- * @param realm
2520
- */
2521
- CacheManager.prototype.getAccountsFilteredByInternal = function (homeAccountId, environment, realm, nativeAccountId) {
2522
2387
  var _this = this;
2523
- var allCacheKeys = this.getKeys();
2524
- var matchingAccounts = {};
2525
- allCacheKeys.forEach(function (cacheKey) {
2388
+ var allAccountKeys = this.getAccountKeys();
2389
+ var matchingAccounts = [];
2390
+ allAccountKeys.forEach(function (cacheKey) {
2391
+ if (!_this.isAccountKey(cacheKey, accountFilter.homeAccountId, accountFilter.realm)) {
2392
+ // Don't parse value if the key doesn't match the account filters
2393
+ return;
2394
+ }
2526
2395
  var entity = _this.getAccount(cacheKey);
2527
2396
  if (!entity) {
2528
2397
  return;
2529
2398
  }
2530
- if (!!homeAccountId && !_this.matchHomeAccountId(entity, homeAccountId)) {
2399
+ if (!!accountFilter.homeAccountId && !_this.matchHomeAccountId(entity, accountFilter.homeAccountId)) {
2531
2400
  return;
2532
2401
  }
2533
- if (!!environment && !_this.matchEnvironment(entity, environment)) {
2402
+ if (!!accountFilter.localAccountId && !_this.matchLocalAccountId(entity, accountFilter.localAccountId)) {
2403
+ return;
2404
+ }
2405
+ if (!!accountFilter.username && !_this.matchUsername(entity, accountFilter.username)) {
2406
+ return;
2407
+ }
2408
+ if (!!accountFilter.environment && !_this.matchEnvironment(entity, accountFilter.environment)) {
2534
2409
  return;
2535
2410
  }
2536
- if (!!realm && !_this.matchRealm(entity, realm)) {
2411
+ if (!!accountFilter.realm && !_this.matchRealm(entity, accountFilter.realm)) {
2537
2412
  return;
2538
2413
  }
2539
- if (!!nativeAccountId && !_this.matchNativeAccountId(entity, nativeAccountId)) {
2414
+ if (!!accountFilter.nativeAccountId && !_this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) {
2540
2415
  return;
2541
2416
  }
2542
- matchingAccounts[cacheKey] = entity;
2417
+ matchingAccounts.push(entity);
2543
2418
  });
2544
2419
  return matchingAccounts;
2545
2420
  };
2546
2421
  /**
2547
- * retrieve credentails matching all provided filters; if no filter is set, get all credentials
2422
+ * Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
2423
+ * @param key
2548
2424
  * @param homeAccountId
2549
- * @param environment
2550
- * @param credentialType
2551
- * @param clientId
2552
- * @param realm
2553
- * @param target
2425
+ * @param tenantId
2426
+ * @returns
2554
2427
  */
2555
- CacheManager.prototype.getCredentialsFilteredBy = function (filter) {
2556
- return this.getCredentialsFilteredByInternal(filter.homeAccountId, filter.environment, filter.credentialType, filter.clientId, filter.familyId, filter.realm, filter.target, filter.userAssertionHash, filter.tokenType, filter.keyId, filter.requestedClaimsHash);
2428
+ CacheManager.prototype.isAccountKey = function (key, homeAccountId, tenantId) {
2429
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
2430
+ // Account cache keys contain 3 items separated by '-' (each item may also contain '-')
2431
+ return false;
2432
+ }
2433
+ if (homeAccountId && !key.toLowerCase().includes(homeAccountId.toLowerCase())) {
2434
+ return false;
2435
+ }
2436
+ if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
2437
+ return false;
2438
+ }
2439
+ // Do not check environment as aliasing can cause false negatives
2440
+ return true;
2557
2441
  };
2558
2442
  /**
2559
- * Support function to help match credentials
2560
- * @param homeAccountId
2561
- * @param environment
2562
- * @param credentialType
2563
- * @param clientId
2564
- * @param realm
2565
- * @param target
2566
- * @param userAssertionHash
2567
- * @param tokenType
2443
+ * Returns true if the given key matches our credential key schema.
2444
+ * @param key
2568
2445
  */
2569
- CacheManager.prototype.getCredentialsFilteredByInternal = function (homeAccountId, environment, credentialType, clientId, familyId, realm, target, userAssertionHash, tokenType, keyId, requestedClaimsHash) {
2570
- var _this = this;
2571
- var allCacheKeys = this.getKeys();
2572
- var matchingCredentials = {
2573
- idTokens: {},
2574
- accessTokens: {},
2575
- refreshTokens: {},
2576
- };
2577
- allCacheKeys.forEach(function (cacheKey) {
2578
- // don't parse any non-credential type cache entities
2579
- var credType = CredentialEntity.getCredentialType(cacheKey);
2580
- if (credType === Constants.NOT_DEFINED) {
2581
- return;
2582
- }
2583
- // Attempt retrieval
2584
- var entity = _this.getSpecificCredential(cacheKey, credType);
2585
- if (!entity) {
2586
- return;
2587
- }
2588
- if (!!userAssertionHash && !_this.matchUserAssertionHash(entity, userAssertionHash)) {
2589
- return;
2590
- }
2591
- /*
2592
- * homeAccountId can undefined, and we want to filter out cached items that have a homeAccountId of ""
2593
- * because we don't want a client_credential request to return a cached token that has a homeAccountId
2594
- */
2595
- if ((typeof homeAccountId === "string") && !_this.matchHomeAccountId(entity, homeAccountId)) {
2596
- return;
2597
- }
2598
- if (!!environment && !_this.matchEnvironment(entity, environment)) {
2599
- return;
2600
- }
2601
- if (!!realm && !_this.matchRealm(entity, realm)) {
2602
- return;
2603
- }
2604
- if (!!credentialType && !_this.matchCredentialType(entity, credentialType)) {
2605
- return;
2606
- }
2607
- if (!!clientId && !_this.matchClientId(entity, clientId)) {
2608
- return;
2609
- }
2610
- if (!!familyId && !_this.matchFamilyId(entity, familyId)) {
2611
- return;
2446
+ CacheManager.prototype.isCredentialKey = function (key) {
2447
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
2448
+ // Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
2449
+ return false;
2450
+ }
2451
+ var lowerCaseKey = key.toLowerCase();
2452
+ // Credential keys must indicate what credential type they represent
2453
+ if (lowerCaseKey.indexOf(exports.CredentialType.ID_TOKEN.toLowerCase()) === -1 &&
2454
+ lowerCaseKey.indexOf(exports.CredentialType.ACCESS_TOKEN.toLowerCase()) === -1 &&
2455
+ lowerCaseKey.indexOf(exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 &&
2456
+ lowerCaseKey.indexOf(exports.CredentialType.REFRESH_TOKEN.toLowerCase()) === -1) {
2457
+ return false;
2458
+ }
2459
+ if (lowerCaseKey.indexOf(exports.CredentialType.REFRESH_TOKEN.toLowerCase()) > -1) {
2460
+ // Refresh tokens must contain the client id or family id
2461
+ var clientIdValidation = "" + exports.CredentialType.REFRESH_TOKEN + Separators.CACHE_KEY_SEPARATOR + this.clientId + Separators.CACHE_KEY_SEPARATOR;
2462
+ var familyIdValidation = "" + exports.CredentialType.REFRESH_TOKEN + Separators.CACHE_KEY_SEPARATOR + THE_FAMILY_ID + Separators.CACHE_KEY_SEPARATOR;
2463
+ if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 && lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) {
2464
+ return false;
2612
2465
  }
2613
- /*
2614
- * idTokens do not have "target", target specific refreshTokens do exist for some types of authentication
2615
- * Resource specific refresh tokens case will be added when the support is deemed necessary
2616
- */
2617
- if (!!target && !_this.matchTarget(entity, target)) {
2618
- return;
2466
+ }
2467
+ else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
2468
+ // Tokens must contain the clientId
2469
+ return false;
2470
+ }
2471
+ return true;
2472
+ };
2473
+ /**
2474
+ * Returns whether or not the given credential entity matches the filter
2475
+ * @param entity
2476
+ * @param filter
2477
+ * @returns
2478
+ */
2479
+ CacheManager.prototype.credentialMatchesFilter = function (entity, filter) {
2480
+ if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) {
2481
+ return false;
2482
+ }
2483
+ if (!!filter.userAssertionHash && !this.matchUserAssertionHash(entity, filter.userAssertionHash)) {
2484
+ return false;
2485
+ }
2486
+ /*
2487
+ * homeAccountId can be undefined, and we want to filter out cached items that have a homeAccountId of ""
2488
+ * because we don't want a client_credential request to return a cached token that has a homeAccountId
2489
+ */
2490
+ if ((typeof filter.homeAccountId === "string") && !this.matchHomeAccountId(entity, filter.homeAccountId)) {
2491
+ return false;
2492
+ }
2493
+ if (!!filter.environment && !this.matchEnvironment(entity, filter.environment)) {
2494
+ return false;
2495
+ }
2496
+ if (!!filter.realm && !this.matchRealm(entity, filter.realm)) {
2497
+ return false;
2498
+ }
2499
+ if (!!filter.credentialType && !this.matchCredentialType(entity, filter.credentialType)) {
2500
+ return false;
2501
+ }
2502
+ if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) {
2503
+ return false;
2504
+ }
2505
+ /*
2506
+ * idTokens do not have "target", target specific refreshTokens do exist for some types of authentication
2507
+ * Resource specific refresh tokens case will be added when the support is deemed necessary
2508
+ */
2509
+ if (!!filter.target && !this.matchTarget(entity, filter.target)) {
2510
+ return false;
2511
+ }
2512
+ // If request OR cached entity has requested Claims Hash, check if they match
2513
+ if (filter.requestedClaimsHash || entity.requestedClaimsHash) {
2514
+ // Don't match if either is undefined or they are different
2515
+ if (entity.requestedClaimsHash !== filter.requestedClaimsHash) {
2516
+ return false;
2619
2517
  }
2620
- // If request OR cached entity has requested Claims Hash, check if they match
2621
- if (requestedClaimsHash || entity.requestedClaimsHash) {
2622
- // Don't match if either is undefined or they are different
2623
- if (entity.requestedClaimsHash !== requestedClaimsHash) {
2624
- return;
2625
- }
2518
+ }
2519
+ // Access Token with Auth Scheme specific matching
2520
+ if (entity.credentialType === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) {
2521
+ if (!!filter.tokenType && !this.matchTokenType(entity, filter.tokenType)) {
2522
+ return false;
2626
2523
  }
2627
- // Access Token with Auth Scheme specific matching
2628
- if (credentialType === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) {
2629
- if (!!tokenType && !_this.matchTokenType(entity, tokenType)) {
2630
- return;
2631
- }
2632
- // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
2633
- if (tokenType === exports.AuthenticationScheme.SSH) {
2634
- if (keyId && !_this.matchKeyId(entity, keyId)) {
2635
- return;
2636
- }
2524
+ // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
2525
+ if (filter.tokenType === exports.AuthenticationScheme.SSH) {
2526
+ if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
2527
+ return false;
2637
2528
  }
2638
2529
  }
2639
- // At this point, the entity matches the request, update cache key if key schema has changed
2640
- var updatedCacheKey = _this.updateCredentialCacheKey(cacheKey, entity);
2641
- switch (credType) {
2642
- case exports.CredentialType.ID_TOKEN:
2643
- matchingCredentials.idTokens[updatedCacheKey] = entity;
2644
- break;
2645
- case exports.CredentialType.ACCESS_TOKEN:
2646
- case exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME:
2647
- matchingCredentials.accessTokens[updatedCacheKey] = entity;
2648
- break;
2649
- case exports.CredentialType.REFRESH_TOKEN:
2650
- matchingCredentials.refreshTokens[updatedCacheKey] = entity;
2651
- break;
2652
- }
2653
- });
2654
- return matchingCredentials;
2530
+ }
2531
+ return true;
2655
2532
  };
2656
2533
  /**
2657
2534
  * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata
@@ -2719,30 +2596,26 @@ var CacheManager = /** @class */ (function () {
2719
2596
  */
2720
2597
  CacheManager.prototype.removeAllAccounts = function () {
2721
2598
  return __awaiter(this, void 0, void 0, function () {
2722
- var allCacheKeys, removedAccounts;
2599
+ var allAccountKeys, removedAccounts;
2723
2600
  var _this = this;
2724
2601
  return __generator(this, function (_a) {
2725
2602
  switch (_a.label) {
2726
2603
  case 0:
2727
- allCacheKeys = this.getKeys();
2604
+ allAccountKeys = this.getAccountKeys();
2728
2605
  removedAccounts = [];
2729
- allCacheKeys.forEach(function (cacheKey) {
2730
- var entity = _this.getAccount(cacheKey);
2731
- if (!entity) {
2732
- return;
2733
- }
2606
+ allAccountKeys.forEach(function (cacheKey) {
2734
2607
  removedAccounts.push(_this.removeAccount(cacheKey));
2735
2608
  });
2736
2609
  return [4 /*yield*/, Promise.all(removedAccounts)];
2737
2610
  case 1:
2738
2611
  _a.sent();
2739
- return [2 /*return*/, true];
2612
+ return [2 /*return*/];
2740
2613
  }
2741
2614
  });
2742
2615
  });
2743
2616
  };
2744
2617
  /**
2745
- * returns a boolean if the given account is removed
2618
+ * Removes the account and related tokens for a given account key
2746
2619
  * @param account
2747
2620
  */
2748
2621
  CacheManager.prototype.removeAccount = function (accountKey) {
@@ -2756,7 +2629,10 @@ var CacheManager = /** @class */ (function () {
2756
2629
  throw ClientAuthError.createNoAccountFoundError();
2757
2630
  }
2758
2631
  return [4 /*yield*/, this.removeAccountContext(account)];
2759
- case 1: return [2 /*return*/, ((_a.sent()) && this.removeItem(accountKey, exports.CacheSchemaType.ACCOUNT))];
2632
+ case 1:
2633
+ _a.sent();
2634
+ this.removeItem(accountKey);
2635
+ return [2 /*return*/];
2760
2636
  }
2761
2637
  });
2762
2638
  });
@@ -2767,29 +2643,33 @@ var CacheManager = /** @class */ (function () {
2767
2643
  */
2768
2644
  CacheManager.prototype.removeAccountContext = function (account) {
2769
2645
  return __awaiter(this, void 0, void 0, function () {
2770
- var allCacheKeys, accountId, removedCredentials;
2646
+ var allTokenKeys, accountId, removedCredentials;
2771
2647
  var _this = this;
2772
2648
  return __generator(this, function (_a) {
2773
2649
  switch (_a.label) {
2774
2650
  case 0:
2775
- allCacheKeys = this.getKeys();
2651
+ allTokenKeys = this.getTokenKeys();
2776
2652
  accountId = account.generateAccountId();
2777
2653
  removedCredentials = [];
2778
- allCacheKeys.forEach(function (cacheKey) {
2779
- // don't parse any non-credential type cache entities
2780
- var credType = CredentialEntity.getCredentialType(cacheKey);
2781
- if (credType === Constants.NOT_DEFINED) {
2782
- return;
2654
+ allTokenKeys.idToken.forEach(function (key) {
2655
+ if (key.indexOf(accountId) === 0) {
2656
+ _this.removeIdToken(key);
2657
+ }
2658
+ });
2659
+ allTokenKeys.accessToken.forEach(function (key) {
2660
+ if (key.indexOf(accountId) === 0) {
2661
+ removedCredentials.push(_this.removeAccessToken(key));
2783
2662
  }
2784
- var cacheEntity = _this.getSpecificCredential(cacheKey, credType);
2785
- if (!!cacheEntity && accountId === cacheEntity.generateAccountId()) {
2786
- removedCredentials.push(_this.removeCredential(cacheEntity));
2663
+ });
2664
+ allTokenKeys.refreshToken.forEach(function (key) {
2665
+ if (key.indexOf(accountId) === 0) {
2666
+ _this.removeRefreshToken(key);
2787
2667
  }
2788
2668
  });
2789
2669
  return [4 /*yield*/, Promise.all(removedCredentials)];
2790
2670
  case 1:
2791
2671
  _a.sent();
2792
- return [2 /*return*/, true];
2672
+ return [2 /*return*/];
2793
2673
  }
2794
2674
  });
2795
2675
  });
@@ -2798,13 +2678,16 @@ var CacheManager = /** @class */ (function () {
2798
2678
  * returns a boolean if the given credential is removed
2799
2679
  * @param credential
2800
2680
  */
2801
- CacheManager.prototype.removeCredential = function (credential) {
2681
+ CacheManager.prototype.removeAccessToken = function (key) {
2802
2682
  return __awaiter(this, void 0, void 0, function () {
2803
- var key, accessTokenWithAuthSchemeEntity, kid;
2683
+ var credential, accessTokenWithAuthSchemeEntity, kid;
2804
2684
  return __generator(this, function (_a) {
2805
2685
  switch (_a.label) {
2806
2686
  case 0:
2807
- key = credential.generateCredentialKey();
2687
+ credential = this.getAccessTokenCredential(key);
2688
+ if (!credential) {
2689
+ return [2 /*return*/];
2690
+ }
2808
2691
  if (!(credential.credentialType.toLowerCase() === exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase())) return [3 /*break*/, 4];
2809
2692
  if (!(credential.tokenType === exports.AuthenticationScheme.POP)) return [3 /*break*/, 4];
2810
2693
  accessTokenWithAuthSchemeEntity = credential;
@@ -2820,7 +2703,7 @@ var CacheManager = /** @class */ (function () {
2820
2703
  case 3:
2821
2704
  _a.sent();
2822
2705
  throw ClientAuthError.createBindingKeyNotRemovedError();
2823
- case 4: return [2 /*return*/, this.removeItem(key, exports.CacheSchemaType.CREDENTIAL)];
2706
+ case 4: return [2 /*return*/, this.removeItem(key)];
2824
2707
  }
2825
2708
  });
2826
2709
  });
@@ -2833,7 +2716,7 @@ var CacheManager = /** @class */ (function () {
2833
2716
  var allCacheKeys = this.getKeys();
2834
2717
  allCacheKeys.forEach(function (cacheKey) {
2835
2718
  if (_this.isAppMetadata(cacheKey)) {
2836
- _this.removeItem(cacheKey, exports.CacheSchemaType.APP_METADATA);
2719
+ _this.removeItem(cacheKey);
2837
2720
  }
2838
2721
  });
2839
2722
  return true;
@@ -2846,12 +2729,13 @@ var CacheManager = /** @class */ (function () {
2846
2729
  * @param environment
2847
2730
  * @param authScheme
2848
2731
  */
2849
- CacheManager.prototype.readCacheRecord = function (account, clientId, request, environment) {
2732
+ CacheManager.prototype.readCacheRecord = function (account, request, environment) {
2733
+ var tokenKeys = this.getTokenKeys();
2850
2734
  var cachedAccount = this.readAccountFromCache(account);
2851
- var cachedIdToken = this.readIdTokenFromCache(clientId, account);
2852
- var cachedAccessToken = this.readAccessTokenFromCache(clientId, account, request);
2853
- var cachedRefreshToken = this.readRefreshTokenFromCache(clientId, account, false);
2854
- var cachedAppMetadata = this.readAppMetadataFromCache(environment, clientId);
2735
+ var cachedIdToken = this.getIdToken(account, tokenKeys);
2736
+ var cachedAccessToken = this.getAccessToken(account, request, tokenKeys);
2737
+ var cachedRefreshToken = this.getRefreshToken(account, false, tokenKeys);
2738
+ var cachedAppMetadata = this.readAppMetadataFromCache(environment);
2855
2739
  if (cachedAccount && cachedIdToken) {
2856
2740
  cachedAccount.idTokenClaims = new AuthToken(cachedIdToken.secret, this.cryptoImpl).claims;
2857
2741
  }
@@ -2871,51 +2755,83 @@ var CacheManager = /** @class */ (function () {
2871
2755
  var accountKey = AccountEntity.generateAccountCacheKey(account);
2872
2756
  return this.getAccount(accountKey);
2873
2757
  };
2874
- /**
2875
- * Retrieve AccountEntity from cache
2876
- * @param nativeAccountId
2877
- * @returns AccountEntity or Null
2878
- */
2879
- CacheManager.prototype.readAccountFromCacheWithNativeAccountId = function (nativeAccountId) {
2880
- // fetch account from memory
2881
- var accountFilter = {
2882
- nativeAccountId: nativeAccountId
2883
- };
2884
- var accountCache = this.getAccountsFilteredBy(accountFilter);
2885
- var accounts = Object.keys(accountCache).map(function (key) { return accountCache[key]; });
2886
- if (accounts.length < 1) {
2887
- return null;
2888
- }
2889
- else if (accounts.length > 1) {
2890
- throw ClientAuthError.createMultipleMatchingAccountsInCacheError();
2891
- }
2892
- return accountCache[0];
2893
- };
2894
2758
  /**
2895
2759
  * Retrieve IdTokenEntity from cache
2896
2760
  * @param clientId
2897
2761
  * @param account
2898
2762
  * @param inputRealm
2899
2763
  */
2900
- CacheManager.prototype.readIdTokenFromCache = function (clientId, account) {
2764
+ CacheManager.prototype.getIdToken = function (account, tokenKeys) {
2765
+ this.commonLogger.trace("CacheManager - getIdToken called");
2901
2766
  var idTokenFilter = {
2902
2767
  homeAccountId: account.homeAccountId,
2903
2768
  environment: account.environment,
2904
2769
  credentialType: exports.CredentialType.ID_TOKEN,
2905
- clientId: clientId,
2770
+ clientId: this.clientId,
2906
2771
  realm: account.tenantId,
2907
2772
  };
2908
- var credentialCache = this.getCredentialsFilteredBy(idTokenFilter);
2909
- var idTokens = Object.keys(credentialCache.idTokens).map(function (key) { return credentialCache.idTokens[key]; });
2773
+ var idTokens = this.getIdTokensByFilter(idTokenFilter, tokenKeys);
2910
2774
  var numIdTokens = idTokens.length;
2911
2775
  if (numIdTokens < 1) {
2776
+ this.commonLogger.info("CacheManager:getIdToken - No token found");
2912
2777
  return null;
2913
2778
  }
2914
2779
  else if (numIdTokens > 1) {
2915
2780
  throw ClientAuthError.createMultipleMatchingTokensInCacheError();
2916
2781
  }
2782
+ this.commonLogger.info("CacheManager:getIdToken - Returning id token");
2917
2783
  return idTokens[0];
2918
2784
  };
2785
+ /**
2786
+ * Gets all idTokens matching the given filter
2787
+ * @param filter
2788
+ * @returns
2789
+ */
2790
+ CacheManager.prototype.getIdTokensByFilter = function (filter, tokenKeys) {
2791
+ var _this = this;
2792
+ var idTokenKeys = tokenKeys && tokenKeys.idToken || this.getTokenKeys().idToken;
2793
+ var idTokens = [];
2794
+ idTokenKeys.forEach(function (key) {
2795
+ if (!_this.idTokenKeyMatchesFilter(key, __assign({ clientId: _this.clientId }, filter))) {
2796
+ return;
2797
+ }
2798
+ var idToken = _this.getIdTokenCredential(key);
2799
+ if (idToken && _this.credentialMatchesFilter(idToken, filter)) {
2800
+ idTokens.push(idToken);
2801
+ }
2802
+ });
2803
+ return idTokens;
2804
+ };
2805
+ /**
2806
+ * Validate the cache key against filter before retrieving and parsing cache value
2807
+ * @param key
2808
+ * @param filter
2809
+ * @returns
2810
+ */
2811
+ CacheManager.prototype.idTokenKeyMatchesFilter = function (inputKey, filter) {
2812
+ var key = inputKey.toLowerCase();
2813
+ if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
2814
+ return false;
2815
+ }
2816
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
2817
+ return false;
2818
+ }
2819
+ return true;
2820
+ };
2821
+ /**
2822
+ * Removes idToken from the cache
2823
+ * @param key
2824
+ */
2825
+ CacheManager.prototype.removeIdToken = function (key) {
2826
+ this.removeItem(key);
2827
+ };
2828
+ /**
2829
+ * Removes refresh token from the cache
2830
+ * @param key
2831
+ */
2832
+ CacheManager.prototype.removeRefreshToken = function (key) {
2833
+ this.removeItem(key);
2834
+ };
2919
2835
  /**
2920
2836
  * Retrieve AccessTokenEntity from cache
2921
2837
  * @param clientId
@@ -2923,8 +2839,10 @@ var CacheManager = /** @class */ (function () {
2923
2839
  * @param scopes
2924
2840
  * @param authScheme
2925
2841
  */
2926
- CacheManager.prototype.readAccessTokenFromCache = function (clientId, account, request) {
2927
- var scopes = new ScopeSet(request.scopes || []);
2842
+ CacheManager.prototype.getAccessToken = function (account, request, tokenKeys) {
2843
+ var _this = this;
2844
+ this.commonLogger.trace("CacheManager - getAccessToken called");
2845
+ var scopes = ScopeSet.createSearchScopes(request.scopes);
2928
2846
  var authScheme = request.authenticationScheme || exports.AuthenticationScheme.BEARER;
2929
2847
  /*
2930
2848
  * Distinguish between Bearer and PoP/SSH token cache types
@@ -2935,55 +2853,156 @@ var CacheManager = /** @class */ (function () {
2935
2853
  homeAccountId: account.homeAccountId,
2936
2854
  environment: account.environment,
2937
2855
  credentialType: credentialType,
2938
- clientId: clientId,
2856
+ clientId: this.clientId,
2939
2857
  realm: account.tenantId,
2940
- target: scopes.printScopesLowerCase(),
2858
+ target: scopes,
2941
2859
  tokenType: authScheme,
2942
2860
  keyId: request.sshKid,
2943
2861
  requestedClaimsHash: request.requestedClaimsHash,
2944
2862
  };
2945
- var credentialCache = this.getCredentialsFilteredBy(accessTokenFilter);
2946
- var accessTokens = Object.keys(credentialCache.accessTokens).map(function (key) { return credentialCache.accessTokens[key]; });
2863
+ var accessTokenKeys = tokenKeys && tokenKeys.accessToken || this.getTokenKeys().accessToken;
2864
+ var accessTokens = [];
2865
+ accessTokenKeys.forEach(function (key) {
2866
+ // Validate key
2867
+ if (_this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) {
2868
+ var accessToken = _this.getAccessTokenCredential(key);
2869
+ // Validate value
2870
+ if (accessToken && _this.credentialMatchesFilter(accessToken, accessTokenFilter)) {
2871
+ accessTokens.push(accessToken);
2872
+ }
2873
+ }
2874
+ });
2947
2875
  var numAccessTokens = accessTokens.length;
2948
2876
  if (numAccessTokens < 1) {
2877
+ this.commonLogger.info("CacheManager:getAccessToken - No token found");
2949
2878
  return null;
2950
2879
  }
2951
2880
  else if (numAccessTokens > 1) {
2952
2881
  throw ClientAuthError.createMultipleMatchingTokensInCacheError();
2953
2882
  }
2883
+ this.commonLogger.info("CacheManager:getAccessToken - Returning access token");
2954
2884
  return accessTokens[0];
2955
2885
  };
2886
+ /**
2887
+ * Validate the cache key against filter before retrieving and parsing cache value
2888
+ * @param key
2889
+ * @param filter
2890
+ * @param keyMustContainAllScopes
2891
+ * @returns
2892
+ */
2893
+ CacheManager.prototype.accessTokenKeyMatchesFilter = function (inputKey, filter, keyMustContainAllScopes) {
2894
+ var key = inputKey.toLowerCase();
2895
+ if (filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
2896
+ return false;
2897
+ }
2898
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
2899
+ return false;
2900
+ }
2901
+ if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) {
2902
+ return false;
2903
+ }
2904
+ if (filter.requestedClaimsHash && key.indexOf(filter.requestedClaimsHash.toLowerCase()) === -1) {
2905
+ return false;
2906
+ }
2907
+ if (filter.target) {
2908
+ var scopes = filter.target.asArray();
2909
+ for (var i = 0; i < scopes.length; i++) {
2910
+ if (keyMustContainAllScopes && !key.includes(scopes[i].toLowerCase())) {
2911
+ // When performing a cache lookup a missing scope would be a cache miss
2912
+ return false;
2913
+ }
2914
+ else if (!keyMustContainAllScopes && key.includes(scopes[i].toLowerCase())) {
2915
+ // When performing a cache write, any token with a subset of requested scopes should be replaced
2916
+ return true;
2917
+ }
2918
+ }
2919
+ }
2920
+ return true;
2921
+ };
2922
+ /**
2923
+ * Gets all access tokens matching the filter
2924
+ * @param filter
2925
+ * @returns
2926
+ */
2927
+ CacheManager.prototype.getAccessTokensByFilter = function (filter) {
2928
+ var _this = this;
2929
+ var tokenKeys = this.getTokenKeys();
2930
+ var accessTokens = [];
2931
+ tokenKeys.accessToken.forEach(function (key) {
2932
+ if (!_this.accessTokenKeyMatchesFilter(key, filter, true)) {
2933
+ return;
2934
+ }
2935
+ var accessToken = _this.getAccessTokenCredential(key);
2936
+ if (accessToken && _this.credentialMatchesFilter(accessToken, filter)) {
2937
+ accessTokens.push(accessToken);
2938
+ }
2939
+ });
2940
+ return accessTokens;
2941
+ };
2956
2942
  /**
2957
2943
  * Helper to retrieve the appropriate refresh token from cache
2958
2944
  * @param clientId
2959
2945
  * @param account
2960
2946
  * @param familyRT
2961
2947
  */
2962
- CacheManager.prototype.readRefreshTokenFromCache = function (clientId, account, familyRT) {
2948
+ CacheManager.prototype.getRefreshToken = function (account, familyRT, tokenKeys) {
2949
+ var _this = this;
2950
+ this.commonLogger.trace("CacheManager - getRefreshToken called");
2963
2951
  var id = familyRT ? THE_FAMILY_ID : undefined;
2964
2952
  var refreshTokenFilter = {
2965
2953
  homeAccountId: account.homeAccountId,
2966
2954
  environment: account.environment,
2967
2955
  credentialType: exports.CredentialType.REFRESH_TOKEN,
2968
- clientId: clientId,
2956
+ clientId: this.clientId,
2969
2957
  familyId: id,
2970
2958
  };
2971
- var credentialCache = this.getCredentialsFilteredBy(refreshTokenFilter);
2972
- var refreshTokens = Object.keys(credentialCache.refreshTokens).map(function (key) { return credentialCache.refreshTokens[key]; });
2959
+ var refreshTokenKeys = tokenKeys && tokenKeys.refreshToken || this.getTokenKeys().refreshToken;
2960
+ var refreshTokens = [];
2961
+ refreshTokenKeys.forEach(function (key) {
2962
+ // Validate key
2963
+ if (_this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) {
2964
+ var refreshToken = _this.getRefreshTokenCredential(key);
2965
+ // Validate value
2966
+ if (refreshToken && _this.credentialMatchesFilter(refreshToken, refreshTokenFilter)) {
2967
+ refreshTokens.push(refreshToken);
2968
+ }
2969
+ }
2970
+ });
2973
2971
  var numRefreshTokens = refreshTokens.length;
2974
2972
  if (numRefreshTokens < 1) {
2973
+ this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found.");
2975
2974
  return null;
2976
2975
  }
2977
2976
  // address the else case after remove functions address environment aliases
2977
+ this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token");
2978
2978
  return refreshTokens[0];
2979
2979
  };
2980
+ /**
2981
+ * Validate the cache key against filter before retrieving and parsing cache value
2982
+ * @param key
2983
+ * @param filter
2984
+ */
2985
+ CacheManager.prototype.refreshTokenKeyMatchesFilter = function (inputKey, filter) {
2986
+ var key = inputKey.toLowerCase();
2987
+ if (filter.familyId && key.indexOf(filter.familyId.toLowerCase()) === -1) {
2988
+ return false;
2989
+ }
2990
+ // If familyId is used, clientId is not in the key
2991
+ if (!filter.familyId && filter.clientId && key.indexOf(filter.clientId.toLowerCase()) === -1) {
2992
+ return false;
2993
+ }
2994
+ if (filter.homeAccountId && key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
2995
+ return false;
2996
+ }
2997
+ return true;
2998
+ };
2980
2999
  /**
2981
3000
  * Retrieve AppMetadataEntity from cache
2982
3001
  */
2983
- CacheManager.prototype.readAppMetadataFromCache = function (environment, clientId) {
3002
+ CacheManager.prototype.readAppMetadataFromCache = function (environment) {
2984
3003
  var appMetadataFilter = {
2985
3004
  environment: environment,
2986
- clientId: clientId,
3005
+ clientId: this.clientId,
2987
3006
  };
2988
3007
  var appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter);
2989
3008
  var appMetadataEntries = Object.keys(appMetadata).map(function (key) { return appMetadata[key]; });
@@ -3001,8 +3020,8 @@ var CacheManager = /** @class */ (function () {
3001
3020
  * @param environment
3002
3021
  * @param clientId
3003
3022
  */
3004
- CacheManager.prototype.isAppMetadataFOCI = function (environment, clientId) {
3005
- var appMetadata = this.readAppMetadataFromCache(environment, clientId);
3023
+ CacheManager.prototype.isAppMetadataFOCI = function (environment) {
3024
+ var appMetadata = this.readAppMetadataFromCache(environment);
3006
3025
  return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID);
3007
3026
  };
3008
3027
  /**
@@ -3013,6 +3032,24 @@ var CacheManager = /** @class */ (function () {
3013
3032
  CacheManager.prototype.matchHomeAccountId = function (entity, homeAccountId) {
3014
3033
  return !!((typeof entity.homeAccountId === "string") && (homeAccountId === entity.homeAccountId));
3015
3034
  };
3035
+ /**
3036
+ * helper to match account ids
3037
+ * @param entity
3038
+ * @param localAccountId
3039
+ * @returns
3040
+ */
3041
+ CacheManager.prototype.matchLocalAccountId = function (entity, localAccountId) {
3042
+ return !!((typeof entity.localAccountId === "string") && (localAccountId === entity.localAccountId));
3043
+ };
3044
+ /**
3045
+ * helper to match usernames
3046
+ * @param entity
3047
+ * @param username
3048
+ * @returns
3049
+ */
3050
+ CacheManager.prototype.matchUsername = function (entity, username) {
3051
+ return !!((typeof entity.username === "string") && (username.toLowerCase() === entity.username.toLowerCase()));
3052
+ };
3016
3053
  /**
3017
3054
  * helper to match assertion
3018
3055
  * @param value
@@ -3085,14 +3122,7 @@ var CacheManager = /** @class */ (function () {
3085
3122
  return false;
3086
3123
  }
3087
3124
  var entityScopeSet = ScopeSet.fromString(entity.target);
3088
- var requestTargetScopeSet = ScopeSet.fromString(target);
3089
- if (!requestTargetScopeSet.containsOnlyOIDCScopes()) {
3090
- requestTargetScopeSet.removeOIDCScopes(); // ignore OIDC scopes
3091
- }
3092
- else {
3093
- requestTargetScopeSet.removeScope(Constants.OFFLINE_ACCESS_SCOPE);
3094
- }
3095
- return entityScopeSet.containsScopeSet(requestTargetScopeSet);
3125
+ return entityScopeSet.containsScopeSet(target);
3096
3126
  };
3097
3127
  /**
3098
3128
  * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise
@@ -3130,27 +3160,6 @@ var CacheManager = /** @class */ (function () {
3130
3160
  CacheManager.prototype.generateAuthorityMetadataCacheKey = function (authority) {
3131
3161
  return AUTHORITY_METADATA_CONSTANTS.CACHE_KEY + "-" + this.clientId + "-" + authority;
3132
3162
  };
3133
- /**
3134
- * Returns the specific credential (IdToken/AccessToken/RefreshToken) from the cache
3135
- * @param key
3136
- * @param credType
3137
- */
3138
- CacheManager.prototype.getSpecificCredential = function (key, credType) {
3139
- switch (credType) {
3140
- case exports.CredentialType.ID_TOKEN: {
3141
- return this.getIdTokenCredential(key);
3142
- }
3143
- case exports.CredentialType.ACCESS_TOKEN:
3144
- case exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME: {
3145
- return this.getAccessTokenCredential(key);
3146
- }
3147
- case exports.CredentialType.REFRESH_TOKEN: {
3148
- return this.getRefreshTokenCredential(key);
3149
- }
3150
- default:
3151
- return null;
3152
- }
3153
- };
3154
3163
  /**
3155
3164
  * Helper to convert serialized data to object
3156
3165
  * @param obj
@@ -3249,6 +3258,14 @@ var DefaultStorageClass = /** @class */ (function (_super) {
3249
3258
  var notImplErr = "Storage interface - getKeys() has not been implemented for the cacheStorage interface.";
3250
3259
  throw AuthError.createUnexpectedError(notImplErr);
3251
3260
  };
3261
+ DefaultStorageClass.prototype.getAccountKeys = function () {
3262
+ var notImplErr = "Storage interface - getAccountKeys() has not been implemented for the cacheStorage interface.";
3263
+ throw AuthError.createUnexpectedError(notImplErr);
3264
+ };
3265
+ DefaultStorageClass.prototype.getTokenKeys = function () {
3266
+ var notImplErr = "Storage interface - getTokenKeys() has not been implemented for the cacheStorage interface.";
3267
+ throw AuthError.createUnexpectedError(notImplErr);
3268
+ };
3252
3269
  DefaultStorageClass.prototype.clear = function () {
3253
3270
  return __awaiter(this, void 0, void 0, function () {
3254
3271
  var notImplErr;
@@ -3337,7 +3354,7 @@ function buildClientConfiguration(_a) {
3337
3354
  authOptions: buildAuthOptions(userAuthOptions),
3338
3355
  systemOptions: __assign(__assign({}, DEFAULT_SYSTEM_OPTIONS), userSystemOptions),
3339
3356
  loggerOptions: loggerOptions,
3340
- storageInterface: storageImplementation || new DefaultStorageClass(userAuthOptions.clientId, DEFAULT_CRYPTO_IMPLEMENTATION),
3357
+ storageInterface: storageImplementation || new DefaultStorageClass(userAuthOptions.clientId, DEFAULT_CRYPTO_IMPLEMENTATION, new Logger(loggerOptions)),
3341
3358
  networkInterface: networkImplementation || DEFAULT_NETWORK_IMPLEMENTATION,
3342
3359
  cryptoInterface: cryptoImplementation || DEFAULT_CRYPTO_IMPLEMENTATION,
3343
3360
  clientCredentials: clientCredentials || DEFAULT_CLIENT_CREDENTIALS,
@@ -3399,7 +3416,7 @@ var ThrottlingUtils = /** @class */ (function () {
3399
3416
  var value = cacheManager.getThrottlingCache(key);
3400
3417
  if (value) {
3401
3418
  if (value.throttleTime < Date.now()) {
3402
- cacheManager.removeItem(key, exports.CacheSchemaType.THROTTLING);
3419
+ cacheManager.removeItem(key);
3403
3420
  return;
3404
3421
  }
3405
3422
  throw new ServerError(((_a = value.errorCodes) === null || _a === void 0 ? void 0 : _a.join(" ")) || Constants.EMPTY_STRING, value.errorMessage, value.subError);
@@ -3463,7 +3480,7 @@ var ThrottlingUtils = /** @class */ (function () {
3463
3480
  sshKid: request.sshKid
3464
3481
  };
3465
3482
  var key = this.generateThrottlingStorageKey(thumbprint);
3466
- return cacheManager.removeItem(key, exports.CacheSchemaType.THROTTLING);
3483
+ cacheManager.removeItem(key);
3467
3484
  };
3468
3485
  return ThrottlingUtils;
3469
3486
  }());
@@ -4090,6 +4107,142 @@ var BaseClient = /** @class */ (function () {
4090
4107
  return BaseClient;
4091
4108
  }());
4092
4109
 
4110
+ /*
4111
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4112
+ * Licensed under the MIT License.
4113
+ */
4114
+ /**
4115
+ * Base type for credentials to be stored in the cache: eg: ACCESS_TOKEN, ID_TOKEN etc
4116
+ *
4117
+ * Key:Value Schema:
4118
+ *
4119
+ * Key: <home_account_id*>-<environment>-<credential_type>-<client_id>-<realm*>-<target*>-<requestedClaims*>-<scheme*>
4120
+ *
4121
+ * Value Schema:
4122
+ * {
4123
+ * homeAccountId: home account identifier for the auth scheme,
4124
+ * environment: entity that issued the token, represented as a full host
4125
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
4126
+ * clientId: client ID of the application
4127
+ * secret: Actual credential as a string
4128
+ * familyId: Family ID identifier, usually only used for refresh tokens
4129
+ * realm: Full tenant or organizational identifier that the account belongs to
4130
+ * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
4131
+ * tokenType: Matches the authentication scheme for which the token was issued (i.e. Bearer or pop)
4132
+ * requestedClaimsHash: Matches the SHA 256 hash of the claims object included in the token request
4133
+ * userAssertionHash: Matches the SHA 256 hash of the obo_assertion for the OBO flow
4134
+ * }
4135
+ */
4136
+ var CredentialEntity = /** @class */ (function () {
4137
+ function CredentialEntity() {
4138
+ }
4139
+ /**
4140
+ * Generate Account Id key component as per the schema: <home_account_id>-<environment>
4141
+ */
4142
+ CredentialEntity.prototype.generateAccountId = function () {
4143
+ return CredentialEntity.generateAccountIdForCacheKey(this.homeAccountId, this.environment);
4144
+ };
4145
+ /**
4146
+ * Generate Credential Id key component as per the schema: <credential_type>-<client_id>-<realm>
4147
+ */
4148
+ CredentialEntity.prototype.generateCredentialId = function () {
4149
+ return CredentialEntity.generateCredentialIdForCacheKey(this.credentialType, this.clientId, this.realm, this.familyId);
4150
+ };
4151
+ /**
4152
+ * Generate target key component as per schema: <target>
4153
+ */
4154
+ CredentialEntity.prototype.generateTarget = function () {
4155
+ return CredentialEntity.generateTargetForCacheKey(this.target);
4156
+ };
4157
+ /**
4158
+ * generates credential key
4159
+ */
4160
+ CredentialEntity.prototype.generateCredentialKey = function () {
4161
+ return CredentialEntity.generateCredentialCacheKey(this.homeAccountId, this.environment, this.credentialType, this.clientId, this.realm, this.target, this.familyId, this.tokenType, this.requestedClaimsHash);
4162
+ };
4163
+ /**
4164
+ * returns the type of the cache (in this case credential)
4165
+ */
4166
+ CredentialEntity.prototype.generateType = function () {
4167
+ switch (this.credentialType) {
4168
+ case exports.CredentialType.ID_TOKEN:
4169
+ return exports.CacheType.ID_TOKEN;
4170
+ case exports.CredentialType.ACCESS_TOKEN:
4171
+ case exports.CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME:
4172
+ return exports.CacheType.ACCESS_TOKEN;
4173
+ case exports.CredentialType.REFRESH_TOKEN:
4174
+ return exports.CacheType.REFRESH_TOKEN;
4175
+ default: {
4176
+ throw ClientAuthError.createUnexpectedCredentialTypeError();
4177
+ }
4178
+ }
4179
+ };
4180
+ /**
4181
+ * generates credential key
4182
+ * <home_account_id*>-\<environment>-<credential_type>-<client_id>-<realm\*>-<target\*>-<scheme\*>
4183
+ */
4184
+ CredentialEntity.generateCredentialCacheKey = function (homeAccountId, environment, credentialType, clientId, realm, target, familyId, tokenType, requestedClaimsHash) {
4185
+ var credentialKey = [
4186
+ this.generateAccountIdForCacheKey(homeAccountId, environment),
4187
+ this.generateCredentialIdForCacheKey(credentialType, clientId, realm, familyId),
4188
+ this.generateTargetForCacheKey(target),
4189
+ this.generateClaimsHashForCacheKey(requestedClaimsHash),
4190
+ this.generateSchemeForCacheKey(tokenType)
4191
+ ];
4192
+ return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
4193
+ };
4194
+ /**
4195
+ * generates Account Id for keys
4196
+ * @param homeAccountId
4197
+ * @param environment
4198
+ */
4199
+ CredentialEntity.generateAccountIdForCacheKey = function (homeAccountId, environment) {
4200
+ var accountId = [homeAccountId, environment];
4201
+ return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
4202
+ };
4203
+ /**
4204
+ * Generates Credential Id for keys
4205
+ * @param credentialType
4206
+ * @param realm
4207
+ * @param clientId
4208
+ * @param familyId
4209
+ */
4210
+ CredentialEntity.generateCredentialIdForCacheKey = function (credentialType, clientId, realm, familyId) {
4211
+ var clientOrFamilyId = credentialType === exports.CredentialType.REFRESH_TOKEN
4212
+ ? familyId || clientId
4213
+ : clientId;
4214
+ var credentialId = [
4215
+ credentialType,
4216
+ clientOrFamilyId,
4217
+ realm || Constants.EMPTY_STRING,
4218
+ ];
4219
+ return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
4220
+ };
4221
+ /**
4222
+ * Generate target key component as per schema: <target>
4223
+ */
4224
+ CredentialEntity.generateTargetForCacheKey = function (scopes) {
4225
+ return (scopes || Constants.EMPTY_STRING).toLowerCase();
4226
+ };
4227
+ /**
4228
+ * Generate requested claims key component as per schema: <requestedClaims>
4229
+ */
4230
+ CredentialEntity.generateClaimsHashForCacheKey = function (requestedClaimsHash) {
4231
+ return (requestedClaimsHash || Constants.EMPTY_STRING).toLowerCase();
4232
+ };
4233
+ /**
4234
+ * Generate scheme key componenet as per schema: <scheme>
4235
+ */
4236
+ CredentialEntity.generateSchemeForCacheKey = function (tokenType) {
4237
+ /*
4238
+ * PoP Tokens and SSH certs include scheme in cache key
4239
+ * Cast to lowercase to handle "bearer" from ADFS
4240
+ */
4241
+ return (tokenType && tokenType.toLowerCase() !== exports.AuthenticationScheme.BEARER.toLowerCase()) ? tokenType.toLowerCase() : Constants.EMPTY_STRING;
4242
+ };
4243
+ return CredentialEntity;
4244
+ }());
4245
+
4093
4246
  /*
4094
4247
  * Copyright (c) Microsoft Corporation. All rights reserved.
4095
4248
  * Licensed under the MIT License.
@@ -4907,6 +5060,7 @@ exports.PerformanceEvents = void 0;
4907
5060
  * Internal API for initializing silent request in SilentCacheClient (msal-browser)
4908
5061
  */
4909
5062
  PerformanceEvents["InitializeSilentRequest"] = "initializeSilentRequest";
5063
+ PerformanceEvents["InitializeClientApplication"] = "initializeClientApplication";
4910
5064
  /**
4911
5065
  * Helper function in SilentIframeClient class (msal-browser).
4912
5066
  */
@@ -4972,6 +5126,7 @@ exports.PerformanceEvents = void 0;
4972
5126
  PerformanceEvents["HandleRedirectPromiseMeasurement"] = "handleRedirectPromiseMeasurement";
4973
5127
  PerformanceEvents["UpdateCloudDiscoveryMetadataMeasurement"] = "updateCloudDiscoveryMetadataMeasurement";
4974
5128
  PerformanceEvents["UsernamePasswordClientAcquireToken"] = "usernamePasswordClientAcquireToken";
5129
+ PerformanceEvents["NativeMessageHandlerHandshake"] = "nativeMessageHandlerHandshake";
4975
5130
  })(exports.PerformanceEvents || (exports.PerformanceEvents = {}));
4976
5131
  /**
4977
5132
  * State of the performance event.
@@ -5337,7 +5492,7 @@ var ResponseHandler = /** @class */ (function () {
5337
5492
  _b.sent();
5338
5493
  _b.label = 7;
5339
5494
  case 7: return [7 /*endfinally*/];
5340
- case 8: return [2 /*return*/, ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, serverTokenResponse.spa_code, serverRequestId)];
5495
+ case 8: return [2 /*return*/, ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, serverTokenResponse, serverRequestId)];
5341
5496
  }
5342
5497
  });
5343
5498
  });
@@ -5423,7 +5578,7 @@ var ResponseHandler = /** @class */ (function () {
5423
5578
  * @param fromTokenCache
5424
5579
  * @param stateString
5425
5580
  */
5426
- ResponseHandler.generateAuthenticationResult = function (cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenObj, requestState, code, requestId) {
5581
+ ResponseHandler.generateAuthenticationResult = function (cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenObj, requestState, serverTokenResponse, requestId) {
5427
5582
  var _a, _b, _c;
5428
5583
  return __awaiter(this, void 0, void 0, function () {
5429
5584
  var accessToken, responseScopes, expiresOn, extExpiresOn, familyId, popTokenGenerator, _d, secret, keyId, uid, tid;
@@ -5459,6 +5614,10 @@ var ResponseHandler = /** @class */ (function () {
5459
5614
  }
5460
5615
  uid = (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.oid) || (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.sub) || Constants.EMPTY_STRING;
5461
5616
  tid = (idTokenObj === null || idTokenObj === void 0 ? void 0 : idTokenObj.claims.tid) || Constants.EMPTY_STRING;
5617
+ // for hybrid + native bridge enablement, send back the native account Id
5618
+ if ((serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_accountid) && !!cacheRecord.account) {
5619
+ cacheRecord.account.nativeAccountId = serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_accountid;
5620
+ }
5462
5621
  return [2 /*return*/, {
5463
5622
  authority: authority.canonicalAuthority,
5464
5623
  uniqueId: uid,
@@ -5478,7 +5637,7 @@ var ResponseHandler = /** @class */ (function () {
5478
5637
  state: requestState ? requestState.userRequestState : Constants.EMPTY_STRING,
5479
5638
  cloudGraphHostName: ((_b = cacheRecord.account) === null || _b === void 0 ? void 0 : _b.cloudGraphHostName) || Constants.EMPTY_STRING,
5480
5639
  msGraphHost: ((_c = cacheRecord.account) === null || _c === void 0 ? void 0 : _c.msGraphHost) || Constants.EMPTY_STRING,
5481
- code: code,
5640
+ code: serverTokenResponse === null || serverTokenResponse === void 0 ? void 0 : serverTokenResponse.spa_code,
5482
5641
  fromNativeBroker: false,
5483
5642
  }];
5484
5643
  }
@@ -6277,7 +6436,7 @@ var RefreshTokenClient = /** @class */ (function (_super) {
6277
6436
  if (!request.account) {
6278
6437
  throw ClientAuthError.createNoAccountInSilentRequestError();
6279
6438
  }
6280
- isFOCI = this.cacheManager.isAppMetadataFOCI(request.account.environment, this.config.authOptions.clientId);
6439
+ isFOCI = this.cacheManager.isAppMetadataFOCI(request.account.environment);
6281
6440
  // if the app is part of the family, retrive a Family refresh token if present and make a refreshTokenRequest
6282
6441
  if (isFOCI) {
6283
6442
  try {
@@ -6316,7 +6475,7 @@ var RefreshTokenClient = /** @class */ (function (_super) {
6316
6475
  (_a = this.performanceClient) === null || _a === void 0 ? void 0 : _a.addQueueMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
6317
6476
  atsMeasurement = (_b = this.performanceClient) === null || _b === void 0 ? void 0 : _b.startMeasurement(exports.PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken, request.correlationId);
6318
6477
  this.logger.verbose("RefreshTokenClientAcquireTokenWithCachedRefreshToken called", request.correlationId);
6319
- refreshToken = this.cacheManager.readRefreshTokenFromCache(this.config.authOptions.clientId, request.account, foci);
6478
+ refreshToken = this.cacheManager.getRefreshToken(request.account, foci);
6320
6479
  if (!refreshToken) {
6321
6480
  atsMeasurement === null || atsMeasurement === void 0 ? void 0 : atsMeasurement.discardMeasurement();
6322
6481
  throw InteractionRequiredAuthError.createNoTokensFoundError();
@@ -6543,7 +6702,6 @@ var ClientCredentialClient = /** @class */ (function (_super) {
6543
6702
  };
6544
6703
  /**
6545
6704
  * Reads access token from the cache
6546
- * TODO: Move this call to cacheManager instead
6547
6705
  */
6548
6706
  ClientCredentialClient.prototype.readAccessTokenFromCache = function () {
6549
6707
  var accessTokenFilter = {
@@ -6552,10 +6710,9 @@ var ClientCredentialClient = /** @class */ (function (_super) {
6552
6710
  credentialType: exports.CredentialType.ACCESS_TOKEN,
6553
6711
  clientId: this.config.authOptions.clientId,
6554
6712
  realm: this.authority.tenant,
6555
- target: this.scopeSet.printScopesLowerCase()
6713
+ target: ScopeSet.createSearchScopes(this.scopeSet.asArray())
6556
6714
  };
6557
- var credentialCache = this.cacheManager.getCredentialsFilteredBy(accessTokenFilter);
6558
- var accessTokens = Object.keys(credentialCache.accessTokens).map(function (key) { return credentialCache.accessTokens[key]; });
6715
+ var accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter);
6559
6716
  if (accessTokens.length < 1) {
6560
6717
  return null;
6561
6718
  }
@@ -6736,7 +6893,7 @@ var OnBehalfOfClient = /** @class */ (function (_super) {
6736
6893
  this.logger.info("OnbehalfofFlow:getCachedAuthenticationResult - Cached access token is expired or will expire within " + this.config.systemOptions.tokenRenewalOffsetSeconds + " seconds.");
6737
6894
  throw ClientAuthError.createRefreshRequiredError();
6738
6895
  }
6739
- cachedIdToken = this.readIdTokenFromCacheForOBO(request, cachedAccessToken.homeAccountId);
6896
+ cachedIdToken = this.readIdTokenFromCacheForOBO(cachedAccessToken.homeAccountId);
6740
6897
  cachedAccount = null;
6741
6898
  if (cachedIdToken) {
6742
6899
  idTokenObject = new AuthToken(cachedIdToken.secret, this.config.cryptoInterface);
@@ -6771,7 +6928,7 @@ var OnBehalfOfClient = /** @class */ (function (_super) {
6771
6928
  * Certain use cases of OBO flow do not expect an idToken in the cache/or from the service
6772
6929
  * @param request
6773
6930
  */
6774
- OnBehalfOfClient.prototype.readIdTokenFromCacheForOBO = function (request, atHomeAccountId) {
6931
+ OnBehalfOfClient.prototype.readIdTokenFromCacheForOBO = function (atHomeAccountId) {
6775
6932
  var idTokenFilter = {
6776
6933
  homeAccountId: atHomeAccountId,
6777
6934
  environment: this.authority.canonicalAuthorityUrlComponents.HostNameAndPort,
@@ -6779,8 +6936,7 @@ var OnBehalfOfClient = /** @class */ (function (_super) {
6779
6936
  clientId: this.config.authOptions.clientId,
6780
6937
  realm: this.authority.tenant
6781
6938
  };
6782
- var credentialCache = this.cacheManager.getCredentialsFilteredBy(idTokenFilter);
6783
- var idTokens = Object.keys(credentialCache.idTokens).map(function (key) { return credentialCache.idTokens[key]; });
6939
+ var idTokens = this.cacheManager.getIdTokensByFilter(idTokenFilter);
6784
6940
  // When acquiring a token on behalf of an application, there might not be an id token in the cache
6785
6941
  if (idTokens.length < 1) {
6786
6942
  return null;
@@ -6803,14 +6959,13 @@ var OnBehalfOfClient = /** @class */ (function (_super) {
6803
6959
  var accessTokenFilter = {
6804
6960
  credentialType: credentialType,
6805
6961
  clientId: clientId,
6806
- target: this.scopeSet.printScopesLowerCase(),
6962
+ target: ScopeSet.createSearchScopes(this.scopeSet.asArray()),
6807
6963
  tokenType: authScheme,
6808
6964
  keyId: request.sshKid,
6809
6965
  requestedClaimsHash: request.requestedClaimsHash,
6810
6966
  userAssertionHash: this.userAssertionHash
6811
6967
  };
6812
- var credentialCache = this.cacheManager.getCredentialsFilteredBy(accessTokenFilter);
6813
- var accessTokens = Object.keys(credentialCache.accessTokens).map(function (key) { return credentialCache.accessTokens[key]; });
6968
+ var accessTokens = this.cacheManager.getAccessTokensByFilter(accessTokenFilter);
6814
6969
  var numAccessTokens = accessTokens.length;
6815
6970
  if (numAccessTokens < 1) {
6816
6971
  return null;
@@ -6959,7 +7114,7 @@ var SilentFlowClient = /** @class */ (function (_super) {
6959
7114
  throw ClientAuthError.createNoAccountInSilentRequestError();
6960
7115
  }
6961
7116
  environment = request.authority || this.authority.getPreferredCache();
6962
- cacheRecord = this.cacheManager.readCacheRecord(request.account, this.config.authOptions.clientId, request, environment);
7117
+ cacheRecord = this.cacheManager.readCacheRecord(request.account, request, environment);
6963
7118
  if (!cacheRecord.accessToken) {
6964
7119
  // Must refresh due to non-existent access_token.
6965
7120
  (_b = this.serverTelemetryManager) === null || _b === void 0 ? void 0 : _b.setCacheOutcome(CacheOutcome.NO_CACHED_ACCESS_TOKEN);
@@ -8323,8 +8478,8 @@ var JoseHeader = /** @class */ (function () {
8323
8478
  throw JoseHeaderError.createMissingAlgError();
8324
8479
  }
8325
8480
  var shrHeader = new JoseHeader({
8326
- // Access Token PoP headers must have type JWT, but the type header can be overriden for special cases
8327
- typ: shrHeaderOptions.typ || JsonTypes.Jwt,
8481
+ // Access Token PoP headers must have type pop, but the type header can be overriden for special cases
8482
+ typ: shrHeaderOptions.typ || JsonTypes.Pop,
8328
8483
  kid: shrHeaderOptions.kid,
8329
8484
  alg: shrHeaderOptions.alg
8330
8485
  });
@@ -8575,11 +8730,8 @@ var PerformanceClient = /** @class */ (function () {
8575
8730
  this.logger = logger;
8576
8731
  this.callbacks = new Map();
8577
8732
  this.eventsByCorrelationId = new Map();
8578
- this.staticFieldsByCorrelationId = new Map();
8579
- this.measurementsById = new Map();
8580
8733
  this.queueMeasurements = new Map();
8581
8734
  this.preQueueTimeByCorrelationId = new Map();
8582
- this.countersByCorrelationId = new Map();
8583
8735
  }
8584
8736
  /**
8585
8737
  * Starts and returns an platform-specific implementation of IPerformanceMeasurement.
@@ -8620,16 +8772,16 @@ var PerformanceClient = /** @class */ (function () {
8620
8772
  * @returns {number}
8621
8773
  */
8622
8774
  PerformanceClient.prototype.getPreQueueTime = function (eventName, correlationId) {
8623
- var preQueueTimesByEvents = this.preQueueTimeByCorrelationId.get(correlationId);
8624
- if (!preQueueTimesByEvents) {
8775
+ var preQueueEvent = this.preQueueTimeByCorrelationId.get(correlationId);
8776
+ if (!preQueueEvent) {
8625
8777
  this.logger.trace("PerformanceClient.getPreQueueTime: no pre-queue times found for correlationId: " + correlationId + ", unable to add queue measurement");
8626
8778
  return;
8627
8779
  }
8628
- else if (!preQueueTimesByEvents.get(eventName)) {
8780
+ else if (preQueueEvent.name !== eventName) {
8629
8781
  this.logger.trace("PerformanceClient.getPreQueueTime: no pre-queue time found for " + eventName + ", unable to add queue measurement");
8630
8782
  return;
8631
8783
  }
8632
- return preQueueTimesByEvents.get(eventName);
8784
+ return preQueueEvent.time;
8633
8785
  };
8634
8786
  /**
8635
8787
  * Calculates the difference between current time and time when function was queued.
@@ -8657,12 +8809,13 @@ var PerformanceClient = /** @class */ (function () {
8657
8809
  /**
8658
8810
  * Adds queue measurement time to QueueMeasurements array for given correlation ID.
8659
8811
  *
8660
- * @param {PerformanceEvents} name
8812
+ * @param {PerformanceEvents} eventName
8661
8813
  * @param {?string} correlationId
8662
- * @param {?number} time
8814
+ * @param {?number} queueTime
8815
+ * @param {?boolean} manuallyCompleted - indicator for manually completed queue measurements
8663
8816
  * @returns
8664
8817
  */
8665
- PerformanceClient.prototype.addQueueMeasurement = function (eventName, correlationId, queueTime) {
8818
+ PerformanceClient.prototype.addQueueMeasurement = function (eventName, correlationId, queueTime, manuallyCompleted) {
8666
8819
  if (!correlationId) {
8667
8820
  this.logger.trace("PerformanceClient.addQueueMeasurement: correlationId not provided for " + eventName + ", cannot add queue measurement");
8668
8821
  return;
@@ -8675,7 +8828,7 @@ var PerformanceClient = /** @class */ (function () {
8675
8828
  this.logger.trace("PerformanceClient.addQueueMeasurement: no queue time provided for " + eventName);
8676
8829
  return;
8677
8830
  }
8678
- var queueMeasurement = { eventName: eventName, queueTime: queueTime };
8831
+ var queueMeasurement = { eventName: eventName, queueTime: queueTime, manuallyCompleted: manuallyCompleted };
8679
8832
  // Adds to existing correlation Id if present in queueMeasurements
8680
8833
  var existingMeasurements = this.queueMeasurements.get(correlationId);
8681
8834
  if (existingMeasurements) {
@@ -8688,6 +8841,8 @@ var PerformanceClient = /** @class */ (function () {
8688
8841
  var measurementArray = [queueMeasurement];
8689
8842
  this.queueMeasurements.set(correlationId, measurementArray);
8690
8843
  }
8844
+ // Delete processed pre-queue event.
8845
+ this.preQueueTimeByCorrelationId.delete(correlationId);
8691
8846
  };
8692
8847
  /**
8693
8848
  * Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
@@ -8706,17 +8861,8 @@ var PerformanceClient = /** @class */ (function () {
8706
8861
  }
8707
8862
  // Duplicate code to address spelling error will be removed at the next major version bump.
8708
8863
  this.logger.trace("PerformanceClient: Performance measurement started for " + measureName, eventCorrelationId);
8709
- var validMeasurement;
8710
- var performanceMeasuremeant = this.startPerformanceMeasuremeant(measureName, eventCorrelationId);
8711
- if (performanceMeasuremeant.startMeasurement) {
8712
- performanceMeasuremeant.startMeasurement();
8713
- validMeasurement = performanceMeasuremeant;
8714
- }
8715
- else {
8716
- var performanceMeasurement = this.startPerformanceMeasurement(measureName, eventCorrelationId);
8717
- performanceMeasurement.startMeasurement();
8718
- validMeasurement = performanceMeasurement;
8719
- }
8864
+ var performanceMeasurement = this.startPerformanceMeasuremeant(measureName, eventCorrelationId);
8865
+ performanceMeasurement.startMeasurement();
8720
8866
  var inProgressEvent = {
8721
8867
  eventId: this.generateId(),
8722
8868
  status: exports.PerformanceEventStatus.InProgress,
@@ -8727,27 +8873,15 @@ var PerformanceClient = /** @class */ (function () {
8727
8873
  name: measureName,
8728
8874
  startTimeMs: Date.now(),
8729
8875
  correlationId: eventCorrelationId,
8730
- };
8731
- // Store in progress events so they can be discarded if not ended properly
8732
- this.cacheEventByCorrelationId(inProgressEvent);
8733
- var staticFields = {
8734
8876
  appName: (_a = this.applicationTelemetry) === null || _a === void 0 ? void 0 : _a.appName,
8735
8877
  appVersion: (_b = this.applicationTelemetry) === null || _b === void 0 ? void 0 : _b.appVersion,
8736
8878
  };
8737
- this.addStaticFields(staticFields, eventCorrelationId);
8738
- this.cacheMeasurement(inProgressEvent, validMeasurement);
8879
+ // Store in progress events so they can be discarded if not ended properly
8880
+ this.cacheEventByCorrelationId(inProgressEvent);
8739
8881
  // Return the event and functions the caller can use to properly end/flush the measurement
8740
8882
  return {
8741
8883
  endMeasurement: function (event) {
8742
- var completedEvent = _this.endMeasurement(__assign(__assign({}, inProgressEvent), event));
8743
- if (completedEvent) {
8744
- // Cache event so that submeasurements can be added downstream
8745
- _this.cacheEventByCorrelationId(completedEvent);
8746
- }
8747
- return completedEvent;
8748
- },
8749
- flushMeasurement: function () {
8750
- return _this.flushMeasurements(inProgressEvent.name, inProgressEvent.correlationId);
8884
+ return _this.endMeasurement(__assign(__assign({}, inProgressEvent), event), performanceMeasurement);
8751
8885
  },
8752
8886
  discardMeasurement: function () {
8753
8887
  return _this.discardMeasurements(inProgressEvent.correlationId);
@@ -8758,40 +8892,66 @@ var PerformanceClient = /** @class */ (function () {
8758
8892
  increment: function (counters) {
8759
8893
  return _this.increment(counters, inProgressEvent.correlationId);
8760
8894
  },
8761
- measurement: validMeasurement,
8895
+ measurement: performanceMeasurement,
8762
8896
  event: inProgressEvent
8763
8897
  };
8764
8898
  };
8765
8899
  /**
8766
8900
  * Stops measuring the performance for an operation. Should only be called directly by PerformanceClient classes,
8767
8901
  * as consumers should instead use the function returned by startMeasurement.
8902
+ * Adds a new field named as "[event name]DurationMs" for sub-measurements, completes and emits an event
8903
+ * otherwise.
8768
8904
  *
8769
8905
  * @param {PerformanceEvent} event
8906
+ * @param {IPerformanceMeasurement} measurement
8770
8907
  * @returns {(PerformanceEvent | null)}
8771
8908
  */
8772
- PerformanceClient.prototype.endMeasurement = function (event) {
8773
- var performanceMeasurement = this.measurementsById.get(event.eventId);
8774
- if (performanceMeasurement) {
8775
- // Immediately delete so that the same event isnt ended twice
8776
- this.measurementsById.delete(event.eventId);
8777
- performanceMeasurement.endMeasurement();
8778
- var durationMs = performanceMeasurement.flushMeasurement();
8779
- // null indicates no measurement was taken (e.g. needed performance APIs not present)
8780
- if (durationMs !== null) {
8781
- this.logger.trace("PerformanceClient: Performance measurement ended for " + event.name + ": " + durationMs + " ms", event.correlationId);
8782
- var completedEvent = __assign(__assign({
8783
- // Allow duration to be overwritten when event ends (e.g. testing), but not status
8784
- durationMs: Math.round(durationMs) }, event), { status: exports.PerformanceEventStatus.Completed });
8785
- return completedEvent;
8786
- }
8787
- else {
8788
- this.logger.trace("PerformanceClient: Performance measurement not taken", event.correlationId);
8789
- }
8909
+ PerformanceClient.prototype.endMeasurement = function (event, measurement) {
8910
+ var _this = this;
8911
+ var _a, _b;
8912
+ var rootEvent = this.eventsByCorrelationId.get(event.correlationId);
8913
+ if (!rootEvent) {
8914
+ this.logger.trace("PerformanceClient: Measurement not found for " + event.eventId, event.correlationId);
8915
+ return null;
8916
+ }
8917
+ var isRoot = event.eventId === rootEvent.eventId;
8918
+ var queueInfo = {
8919
+ totalQueueTime: 0,
8920
+ totalQueueCount: 0,
8921
+ manuallyCompletedCount: 0
8922
+ };
8923
+ if (isRoot) {
8924
+ queueInfo = this.getQueueInfo(event.correlationId);
8925
+ this.discardCache(rootEvent.correlationId);
8790
8926
  }
8791
8927
  else {
8792
- this.logger.trace("PerformanceClient: Measurement not found for " + event.eventId, event.correlationId);
8928
+ (_a = rootEvent.incompleteSubMeasurements) === null || _a === void 0 ? void 0 : _a.delete(event.eventId);
8793
8929
  }
8794
- return null;
8930
+ measurement === null || measurement === void 0 ? void 0 : measurement.endMeasurement();
8931
+ var durationMs = measurement === null || measurement === void 0 ? void 0 : measurement.flushMeasurement();
8932
+ // null indicates no measurement was taken (e.g. needed performance APIs not present)
8933
+ if (!durationMs) {
8934
+ this.logger.trace("PerformanceClient: Performance measurement not taken", rootEvent.correlationId);
8935
+ return null;
8936
+ }
8937
+ this.logger.trace("PerformanceClient: Performance measurement ended for " + event.name + ": " + durationMs + " ms", event.correlationId);
8938
+ // Add sub-measurement attribute to root event.
8939
+ if (!isRoot) {
8940
+ rootEvent[event.name + "DurationMs"] = Math.floor(durationMs);
8941
+ return __assign({}, rootEvent);
8942
+ }
8943
+ var finalEvent = __assign(__assign({}, rootEvent), event);
8944
+ var incompleteSubsCount = 0;
8945
+ // Incomplete sub-measurements are discarded. They are likely an instrumentation bug that should be fixed.
8946
+ (_b = finalEvent.incompleteSubMeasurements) === null || _b === void 0 ? void 0 : _b.forEach(function (subMeasurement) {
8947
+ _this.logger.trace("PerformanceClient: Incomplete submeasurement " + subMeasurement.name + " found for " + event.name, finalEvent.correlationId);
8948
+ incompleteSubsCount++;
8949
+ });
8950
+ finalEvent.incompleteSubMeasurements = undefined;
8951
+ finalEvent = __assign(__assign({}, finalEvent), { durationMs: Math.round(durationMs), queuedTimeMs: queueInfo.totalQueueTime, queuedCount: queueInfo.totalQueueCount, queuedManuallyCompletedCount: queueInfo.manuallyCompletedCount, status: exports.PerformanceEventStatus.Completed, incompleteSubsCount: incompleteSubsCount });
8952
+ this.truncateIntegralFields(finalEvent, this.getIntFields());
8953
+ this.emitEvents([finalEvent], event.correlationId);
8954
+ return finalEvent;
8795
8955
  };
8796
8956
  /**
8797
8957
  * Saves extra information to be emitted when the measurements are flushed
@@ -8799,14 +8959,13 @@ var PerformanceClient = /** @class */ (function () {
8799
8959
  * @param correlationId
8800
8960
  */
8801
8961
  PerformanceClient.prototype.addStaticFields = function (fields, correlationId) {
8802
- var existingStaticFields = this.staticFieldsByCorrelationId.get(correlationId);
8803
- if (existingStaticFields) {
8804
- this.logger.trace("PerformanceClient: Updating static fields");
8805
- this.staticFieldsByCorrelationId.set(correlationId, __assign(__assign({}, existingStaticFields), fields));
8962
+ this.logger.trace("PerformanceClient: Updating static fields");
8963
+ var event = this.eventsByCorrelationId.get(correlationId);
8964
+ if (event) {
8965
+ this.eventsByCorrelationId.set(correlationId, __assign(__assign({}, event), fields));
8806
8966
  }
8807
8967
  else {
8808
- this.logger.trace("PerformanceClient: Adding static fields");
8809
- this.staticFieldsByCorrelationId.set(correlationId, fields);
8968
+ this.logger.trace("PerformanceClient: Event not found for", correlationId);
8810
8969
  }
8811
8970
  };
8812
8971
  /**
@@ -8815,18 +8974,18 @@ var PerformanceClient = /** @class */ (function () {
8815
8974
  * @param correlationId {string} correlation identifier
8816
8975
  */
8817
8976
  PerformanceClient.prototype.increment = function (counters, correlationId) {
8818
- var existing = this.countersByCorrelationId.get(correlationId);
8819
- if (!existing) {
8820
- this.logger.trace("PerformanceClient: Setting counters");
8821
- this.countersByCorrelationId.set(correlationId, __assign({}, counters));
8822
- return;
8823
- }
8824
8977
  this.logger.trace("PerformanceClient: Updating counters");
8825
- for (var counter in counters) {
8826
- if (!existing.hasOwnProperty(counter)) {
8827
- existing[counter] = 0;
8978
+ var event = this.eventsByCorrelationId.get(correlationId);
8979
+ if (event) {
8980
+ for (var counter in counters) {
8981
+ if (!event.hasOwnProperty(counter)) {
8982
+ event[counter] = 0;
8983
+ }
8984
+ event[counter] += counters[counter];
8828
8985
  }
8829
- existing[counter] += counters[counter];
8986
+ }
8987
+ else {
8988
+ this.logger.trace("PerformanceClient: Event not found for", correlationId);
8830
8989
  }
8831
8990
  };
8832
8991
  /**
@@ -8839,117 +8998,35 @@ var PerformanceClient = /** @class */ (function () {
8839
8998
  * @param {PerformanceEvent} event
8840
8999
  */
8841
9000
  PerformanceClient.prototype.cacheEventByCorrelationId = function (event) {
8842
- var existingEvents = this.eventsByCorrelationId.get(event.correlationId);
8843
- if (existingEvents) {
9001
+ var rootEvent = this.eventsByCorrelationId.get(event.correlationId);
9002
+ if (rootEvent) {
8844
9003
  this.logger.trace("PerformanceClient: Performance measurement for " + event.name + " added/updated", event.correlationId);
8845
- existingEvents.set(event.eventId, event);
9004
+ rootEvent.incompleteSubMeasurements = rootEvent.incompleteSubMeasurements || new Map();
9005
+ rootEvent.incompleteSubMeasurements.set(event.eventId, { name: event.name, startTimeMs: event.startTimeMs });
8846
9006
  }
8847
9007
  else {
8848
9008
  this.logger.trace("PerformanceClient: Performance measurement for " + event.name + " started", event.correlationId);
8849
- this.eventsByCorrelationId.set(event.correlationId, new Map().set(event.eventId, event));
9009
+ this.eventsByCorrelationId.set(event.correlationId, __assign({}, event));
8850
9010
  }
8851
9011
  };
8852
- /**
8853
- * Cache measurements by their id.
8854
- *
8855
- * @private
8856
- * @param {PerformanceEvent} event
8857
- * @param {IPerformanceMeasurement} measurement
8858
- */
8859
- PerformanceClient.prototype.cacheMeasurement = function (event, measurement) {
8860
- this.measurementsById.set(event.eventId, measurement);
8861
- };
8862
- /**
8863
- * Gathers and emits performance events for measurements taked for the given top-level API and correlation ID.
8864
- *
8865
- * @param {PerformanceEvents} measureName
8866
- * @param {string} correlationId
8867
- */
8868
- PerformanceClient.prototype.flushMeasurements = function (measureName, correlationId) {
8869
- var _this = this;
8870
- this.logger.trace("PerformanceClient: Performance measurements flushed for " + measureName, correlationId);
8871
- /**
8872
- * Adds all queue time and count measurements for given correlation ID
8873
- * then deletes queue times for given correlation ID from queueMeasurements map.
8874
- */
9012
+ PerformanceClient.prototype.getQueueInfo = function (correlationId) {
8875
9013
  var queueMeasurementForCorrelationId = this.queueMeasurements.get(correlationId);
8876
9014
  if (!queueMeasurementForCorrelationId) {
8877
9015
  this.logger.trace("PerformanceClient: no queue measurements found for for correlationId: " + correlationId);
8878
9016
  }
8879
9017
  var totalQueueTime = 0;
8880
9018
  var totalQueueCount = 0;
9019
+ var manuallyCompletedCount = 0;
8881
9020
  queueMeasurementForCorrelationId === null || queueMeasurementForCorrelationId === void 0 ? void 0 : queueMeasurementForCorrelationId.forEach(function (measurement) {
8882
9021
  totalQueueTime += measurement.queueTime;
8883
9022
  totalQueueCount++;
9023
+ manuallyCompletedCount += measurement.manuallyCompleted ? 1 : 0;
8884
9024
  });
8885
- var eventsForCorrelationId = this.eventsByCorrelationId.get(correlationId);
8886
- var staticFields = this.staticFieldsByCorrelationId.get(correlationId);
8887
- var counters = this.countersByCorrelationId.get(correlationId);
8888
- if (eventsForCorrelationId) {
8889
- this.discardCache(correlationId);
8890
- /*
8891
- * Manually end incomplete submeasurements to ensure there arent orphaned/never ending events.
8892
- * Incomplete submeasurements are likely an instrumentation bug that should be fixed.
8893
- * IE only supports Map.forEach.
8894
- */
8895
- var completedEvents_1 = [];
8896
- var incompleteSubsCount_1 = 0;
8897
- eventsForCorrelationId.forEach(function (event) {
8898
- if (event.name !== measureName && event.status !== exports.PerformanceEventStatus.Completed) {
8899
- _this.logger.trace("PerformanceClient: Incomplete submeasurement " + event.name + " found for " + measureName, correlationId);
8900
- incompleteSubsCount_1++;
8901
- var completedEvent = _this.endMeasurement(event);
8902
- if (completedEvent) {
8903
- completedEvents_1.push(completedEvent);
8904
- }
8905
- }
8906
- completedEvents_1.push(event);
8907
- });
8908
- // Sort events by start time (earliest first)
8909
- var sortedCompletedEvents = completedEvents_1.sort(function (eventA, eventB) { return eventA.startTimeMs - eventB.startTimeMs; });
8910
- // Take completed top level event and add completed submeasurements durations as properties
8911
- var topLevelEvents = sortedCompletedEvents.filter(function (event) { return event.name === measureName && event.status === exports.PerformanceEventStatus.Completed; });
8912
- if (topLevelEvents.length > 0) {
8913
- /*
8914
- * Only take the first top-level event if there are multiple events with the same correlation id.
8915
- * This greatly simplifies logic for submeasurements.
8916
- */
8917
- if (topLevelEvents.length > 1) {
8918
- this.logger.verbose("PerformanceClient: Multiple distinct top-level performance events found, using the first", correlationId);
8919
- }
8920
- var topLevelEvent = topLevelEvents[0];
8921
- this.logger.verbose("PerformanceClient: Measurement found for " + measureName, correlationId);
8922
- // Build event object with top level and sub measurements
8923
- var eventToEmit = sortedCompletedEvents.reduce(function (previous, current) {
8924
- if (current.name !== measureName) {
8925
- _this.logger.trace("PerformanceClient: Complete submeasurement found for " + current.name, correlationId);
8926
- // TODO: Emit additional properties for each subMeasurement
8927
- var subMeasurementName = current.name + "DurationMs";
8928
- /*
8929
- * Some code paths, such as resolving an authority, can occur multiple times.
8930
- * Only take the first measurement, since the second could be read from the cache,
8931
- * or due to the same correlation id being used for two distinct requests.
8932
- */
8933
- if (!previous[subMeasurementName]) {
8934
- previous[subMeasurementName] = current.durationMs;
8935
- }
8936
- else {
8937
- _this.logger.verbose("PerformanceClient: Submeasurement for " + measureName + " already exists for " + current.name + ", ignoring", correlationId);
8938
- }
8939
- }
8940
- return previous;
8941
- }, topLevelEvent);
8942
- var finalEvent = __assign(__assign(__assign(__assign({}, eventToEmit), staticFields), counters), { queuedTimeMs: totalQueueTime, queuedCount: totalQueueCount, incompleteSubsCount: incompleteSubsCount_1 });
8943
- this.truncateIntegralFields(finalEvent, this.getIntFields());
8944
- this.emitEvents([finalEvent], eventToEmit.correlationId);
8945
- }
8946
- else {
8947
- this.logger.verbose("PerformanceClient: No completed top-level measurements found for " + measureName, correlationId);
8948
- }
8949
- }
8950
- else {
8951
- this.logger.verbose("PerformanceClient: No measurements found", correlationId);
8952
- }
9025
+ return {
9026
+ totalQueueTime: totalQueueTime,
9027
+ totalQueueCount: totalQueueCount,
9028
+ manuallyCompletedCount: manuallyCompletedCount
9029
+ };
8953
9030
  };
8954
9031
  /**
8955
9032
  * Removes measurements for a given correlation id.
@@ -8963,14 +9040,10 @@ var PerformanceClient = /** @class */ (function () {
8963
9040
  /**
8964
9041
  * Removes cache for a given correlation id.
8965
9042
  *
8966
- * @param {string} correlation identifier
9043
+ * @param {string} correlationId correlation identifier
8967
9044
  */
8968
9045
  PerformanceClient.prototype.discardCache = function (correlationId) {
8969
9046
  this.discardMeasurements(correlationId);
8970
- this.logger.trace("PerformanceClient: Static fields discarded", correlationId);
8971
- this.staticFieldsByCorrelationId.delete(correlationId);
8972
- this.logger.trace("PerformanceClient: Counters discarded", correlationId);
8973
- this.countersByCorrelationId.delete(correlationId);
8974
9047
  this.logger.trace("PerformanceClient: QueueMeasurements discarded", correlationId);
8975
9048
  this.queueMeasurements.delete(correlationId);
8976
9049
  this.logger.trace("PerformanceClient: Pre-queue times discarded", correlationId);