@azure/msal-common 15.9.0 → 15.11.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.
- package/dist/account/AccountInfo.d.ts +2 -1
- package/dist/account/AccountInfo.d.ts.map +1 -1
- package/dist/account/AccountInfo.mjs +5 -2
- package/dist/account/AccountInfo.mjs.map +1 -1
- package/dist/account/AuthToken.mjs +1 -1
- package/dist/account/CcsCredential.mjs +1 -1
- package/dist/account/ClientInfo.mjs +1 -1
- package/dist/account/TokenClaims.mjs +1 -1
- package/dist/authority/Authority.mjs +1 -1
- package/dist/authority/AuthorityFactory.mjs +1 -1
- package/dist/authority/AuthorityMetadata.mjs +1 -1
- package/dist/authority/AuthorityOptions.mjs +1 -1
- package/dist/authority/AuthorityType.mjs +1 -1
- package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
- package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
- package/dist/authority/OpenIdConfigResponse.mjs +1 -1
- package/dist/authority/ProtocolMode.mjs +1 -1
- package/dist/authority/RegionDiscovery.mjs +1 -1
- package/dist/cache/CacheManager.d.ts +15 -20
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.mjs +37 -97
- package/dist/cache/CacheManager.mjs.map +1 -1
- package/dist/cache/entities/AccountEntity.d.ts +2 -14
- package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
- package/dist/cache/entities/AccountEntity.mjs +6 -34
- package/dist/cache/entities/AccountEntity.mjs.map +1 -1
- package/dist/cache/entities/CredentialEntity.d.ts +1 -1
- package/dist/cache/entities/CredentialEntity.d.ts.map +1 -1
- package/dist/cache/interface/ICacheManager.d.ts +2 -10
- package/dist/cache/interface/ICacheManager.d.ts.map +1 -1
- package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
- package/dist/cache/utils/CacheHelpers.d.ts +4 -13
- package/dist/cache/utils/CacheHelpers.d.ts.map +1 -1
- package/dist/cache/utils/CacheHelpers.mjs +6 -71
- package/dist/cache/utils/CacheHelpers.mjs.map +1 -1
- package/dist/client/AuthorizationCodeClient.mjs +1 -1
- package/dist/client/BaseClient.mjs +1 -1
- package/dist/client/RefreshTokenClient.d.ts.map +1 -1
- package/dist/client/RefreshTokenClient.mjs +2 -3
- package/dist/client/RefreshTokenClient.mjs.map +1 -1
- package/dist/client/SilentFlowClient.mjs +2 -2
- package/dist/client/SilentFlowClient.mjs.map +1 -1
- package/dist/config/ClientConfiguration.mjs +1 -1
- package/dist/constants/AADServerParamKeys.mjs +1 -1
- package/dist/crypto/ICrypto.mjs +1 -1
- package/dist/crypto/JoseHeader.mjs +1 -1
- package/dist/crypto/PopTokenGenerator.mjs +1 -1
- package/dist/error/AuthError.mjs +1 -1
- package/dist/error/AuthErrorCodes.mjs +1 -1
- package/dist/error/CacheError.mjs +1 -1
- package/dist/error/CacheErrorCodes.mjs +1 -1
- package/dist/error/ClientAuthError.mjs +1 -1
- package/dist/error/ClientAuthErrorCodes.mjs +1 -1
- package/dist/error/ClientConfigurationError.mjs +1 -1
- package/dist/error/ClientConfigurationErrorCodes.mjs +1 -1
- package/dist/error/InteractionRequiredAuthError.mjs +1 -1
- package/dist/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
- package/dist/error/JoseHeaderError.mjs +1 -1
- package/dist/error/JoseHeaderErrorCodes.mjs +1 -1
- package/dist/error/NetworkError.mjs +1 -1
- package/dist/error/ServerError.mjs +1 -1
- package/dist/index-browser.mjs +1 -1
- package/dist/index-node.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/logger/Logger.mjs +1 -1
- package/dist/network/INetworkModule.mjs +1 -1
- package/dist/network/RequestThumbprint.mjs +1 -1
- package/dist/network/ThrottlingUtils.mjs +1 -1
- package/dist/packageMetadata.d.ts +1 -1
- package/dist/packageMetadata.d.ts.map +1 -1
- package/dist/packageMetadata.mjs +2 -2
- package/dist/protocol/Authorize.mjs +2 -2
- package/dist/protocol/Authorize.mjs.map +1 -1
- package/dist/request/AuthenticationHeaderParser.mjs +1 -1
- package/dist/request/RequestParameterBuilder.mjs +1 -1
- package/dist/request/ScopeSet.mjs +1 -1
- package/dist/response/ResponseHandler.d.ts.map +1 -1
- package/dist/response/ResponseHandler.mjs +3 -3
- package/dist/response/ResponseHandler.mjs.map +1 -1
- package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
- package/dist/telemetry/performance/PerformanceEvent.d.ts +3 -0
- package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
- package/dist/telemetry/performance/PerformanceEvent.mjs +11 -1
- package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
- package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
- package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
- package/dist/url/UrlString.mjs +1 -1
- package/dist/utils/ClientAssertionUtils.mjs +1 -1
- package/dist/utils/Constants.d.ts +0 -1
- package/dist/utils/Constants.d.ts.map +1 -1
- package/dist/utils/Constants.mjs +1 -3
- package/dist/utils/Constants.mjs.map +1 -1
- package/dist/utils/FunctionWrappers.mjs +1 -1
- package/dist/utils/ProtocolUtils.mjs +1 -1
- package/dist/utils/StringUtils.mjs +1 -1
- package/dist/utils/TimeUtils.d.ts +7 -0
- package/dist/utils/TimeUtils.d.ts.map +1 -1
- package/dist/utils/TimeUtils.mjs +12 -2
- package/dist/utils/TimeUtils.mjs.map +1 -1
- package/dist/utils/UrlUtils.mjs +1 -1
- package/lib/index-browser.cjs +2 -2
- package/lib/{index-node-C5c-lcoe.js → index-node-CtW_2rqJ.js} +465 -595
- package/lib/index-node-CtW_2rqJ.js.map +1 -0
- package/lib/index-node.cjs +2 -2
- package/lib/index.cjs +2 -2
- package/lib/types/account/AccountInfo.d.ts +2 -1
- package/lib/types/account/AccountInfo.d.ts.map +1 -1
- package/lib/types/cache/CacheManager.d.ts +15 -20
- package/lib/types/cache/CacheManager.d.ts.map +1 -1
- package/lib/types/cache/entities/AccountEntity.d.ts +2 -14
- package/lib/types/cache/entities/AccountEntity.d.ts.map +1 -1
- package/lib/types/cache/entities/CredentialEntity.d.ts +1 -1
- package/lib/types/cache/entities/CredentialEntity.d.ts.map +1 -1
- package/lib/types/cache/interface/ICacheManager.d.ts +2 -10
- package/lib/types/cache/interface/ICacheManager.d.ts.map +1 -1
- package/lib/types/cache/utils/CacheHelpers.d.ts +4 -13
- package/lib/types/cache/utils/CacheHelpers.d.ts.map +1 -1
- package/lib/types/client/RefreshTokenClient.d.ts.map +1 -1
- package/lib/types/packageMetadata.d.ts +1 -1
- package/lib/types/packageMetadata.d.ts.map +1 -1
- package/lib/types/response/ResponseHandler.d.ts.map +1 -1
- package/lib/types/telemetry/performance/PerformanceEvent.d.ts +3 -0
- package/lib/types/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
- package/lib/types/utils/Constants.d.ts +0 -1
- package/lib/types/utils/Constants.d.ts.map +1 -1
- package/lib/types/utils/TimeUtils.d.ts +7 -0
- package/lib/types/utils/TimeUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/account/AccountInfo.ts +16 -2
- package/src/cache/CacheManager.ts +59 -125
- package/src/cache/entities/AccountEntity.ts +7 -38
- package/src/cache/entities/CredentialEntity.ts +1 -1
- package/src/cache/interface/ICacheManager.ts +2 -15
- package/src/cache/utils/CacheHelpers.ts +11 -83
- package/src/client/RefreshTokenClient.ts +1 -2
- package/src/client/SilentFlowClient.ts +2 -2
- package/src/packageMetadata.ts +1 -1
- package/src/protocol/Authorize.ts +1 -1
- package/src/response/ResponseHandler.ts +3 -1
- package/src/telemetry/performance/PerformanceEvent.ts +16 -0
- package/src/utils/Constants.ts +0 -2
- package/src/utils/TimeUtils.ts +15 -0
- package/lib/index-node-C5c-lcoe.js.map +0 -1
|
@@ -19,10 +19,8 @@ import {
|
|
|
19
19
|
THE_FAMILY_ID,
|
|
20
20
|
AUTHORITY_METADATA_CONSTANTS,
|
|
21
21
|
AuthenticationScheme,
|
|
22
|
-
Separators,
|
|
23
22
|
} from "../utils/Constants.js";
|
|
24
23
|
import { CredentialEntity } from "./entities/CredentialEntity.js";
|
|
25
|
-
import { generateCredentialKey } from "./utils/CacheHelpers.js";
|
|
26
24
|
import { ScopeSet } from "../request/ScopeSet.js";
|
|
27
25
|
import { AccountEntity } from "./entities/AccountEntity.js";
|
|
28
26
|
import { AccessTokenEntity } from "./entities/AccessTokenEntity.js";
|
|
@@ -252,6 +250,18 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
252
250
|
*/
|
|
253
251
|
abstract getTokenKeys(): TokenKeys;
|
|
254
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Returns credential cache key from the entity
|
|
255
|
+
* @param credential
|
|
256
|
+
*/
|
|
257
|
+
abstract generateCredentialKey(credential: CredentialEntity): string;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Returns the account cache key from the account info
|
|
261
|
+
* @param account
|
|
262
|
+
*/
|
|
263
|
+
abstract generateAccountKey(account: AccountInfo): string;
|
|
264
|
+
|
|
255
265
|
/**
|
|
256
266
|
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
257
267
|
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
@@ -275,6 +285,15 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
275
285
|
accountFilter: AccountFilter,
|
|
276
286
|
correlationId: string
|
|
277
287
|
): AccountInfo | null {
|
|
288
|
+
if (
|
|
289
|
+
Object.keys(accountFilter).length === 0 ||
|
|
290
|
+
Object.values(accountFilter).every((value) => !value)
|
|
291
|
+
) {
|
|
292
|
+
this.commonLogger.warning(
|
|
293
|
+
"getAccountInfoFilteredBy: Account filter is empty or invalid, returning null"
|
|
294
|
+
);
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
278
297
|
const allAccounts = this.getAllAccounts(accountFilter, correlationId);
|
|
279
298
|
if (allAccounts.length > 1) {
|
|
280
299
|
// If one or more accounts are found, prioritize accounts that have an ID token
|
|
@@ -635,11 +654,6 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
635
654
|
const allAccountKeys = this.getAccountKeys();
|
|
636
655
|
const matchingAccounts: AccountEntity[] = [];
|
|
637
656
|
allAccountKeys.forEach((cacheKey) => {
|
|
638
|
-
if (!this.isAccountKey(cacheKey, accountFilter.homeAccountId)) {
|
|
639
|
-
// Don't parse value if the key doesn't match the account filters
|
|
640
|
-
return;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
657
|
const entity: AccountEntity | null = this.getAccount(
|
|
644
658
|
cacheKey,
|
|
645
659
|
correlationId
|
|
@@ -722,86 +736,6 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
722
736
|
return matchingAccounts;
|
|
723
737
|
}
|
|
724
738
|
|
|
725
|
-
/**
|
|
726
|
-
* Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
|
|
727
|
-
* @param key
|
|
728
|
-
* @param homeAccountId
|
|
729
|
-
* @param tenantId
|
|
730
|
-
* @returns
|
|
731
|
-
*/
|
|
732
|
-
isAccountKey(
|
|
733
|
-
key: string,
|
|
734
|
-
homeAccountId?: string,
|
|
735
|
-
tenantId?: string
|
|
736
|
-
): boolean {
|
|
737
|
-
if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
|
|
738
|
-
// Account cache keys contain 3 items separated by '-' (each item may also contain '-')
|
|
739
|
-
return false;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
if (
|
|
743
|
-
homeAccountId &&
|
|
744
|
-
!key.toLowerCase().includes(homeAccountId.toLowerCase())
|
|
745
|
-
) {
|
|
746
|
-
return false;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
|
|
750
|
-
return false;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
// Do not check environment as aliasing can cause false negatives
|
|
754
|
-
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
/**
|
|
759
|
-
* Returns true if the given key matches our credential key schema.
|
|
760
|
-
* @param key
|
|
761
|
-
*/
|
|
762
|
-
isCredentialKey(key: string): boolean {
|
|
763
|
-
if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
|
|
764
|
-
// Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
const lowerCaseKey = key.toLowerCase();
|
|
769
|
-
// Credential keys must indicate what credential type they represent
|
|
770
|
-
if (
|
|
771
|
-
lowerCaseKey.indexOf(CredentialType.ID_TOKEN.toLowerCase()) ===
|
|
772
|
-
-1 &&
|
|
773
|
-
lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) ===
|
|
774
|
-
-1 &&
|
|
775
|
-
lowerCaseKey.indexOf(
|
|
776
|
-
CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()
|
|
777
|
-
) === -1 &&
|
|
778
|
-
lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) ===
|
|
779
|
-
-1
|
|
780
|
-
) {
|
|
781
|
-
return false;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (
|
|
785
|
-
lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) >
|
|
786
|
-
-1
|
|
787
|
-
) {
|
|
788
|
-
// Refresh tokens must contain the client id or family id
|
|
789
|
-
const clientIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${this.clientId}${Separators.CACHE_KEY_SEPARATOR}`;
|
|
790
|
-
const familyIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${THE_FAMILY_ID}${Separators.CACHE_KEY_SEPARATOR}`;
|
|
791
|
-
if (
|
|
792
|
-
lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 &&
|
|
793
|
-
lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1
|
|
794
|
-
) {
|
|
795
|
-
return false;
|
|
796
|
-
}
|
|
797
|
-
} else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
|
|
798
|
-
// Tokens must contain the clientId
|
|
799
|
-
return false;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
return true;
|
|
803
|
-
}
|
|
804
|
-
|
|
805
739
|
/**
|
|
806
740
|
* Returns whether or not the given credential entity matches the filter
|
|
807
741
|
* @param entity
|
|
@@ -974,10 +908,9 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
974
908
|
* Removes all accounts and related tokens from cache.
|
|
975
909
|
*/
|
|
976
910
|
removeAllAccounts(correlationId: string): void {
|
|
977
|
-
const
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
this.removeAccount(cacheKey, correlationId);
|
|
911
|
+
const accounts = this.getAllAccounts({}, correlationId);
|
|
912
|
+
accounts.forEach((account) => {
|
|
913
|
+
this.removeAccount(account, correlationId);
|
|
981
914
|
});
|
|
982
915
|
}
|
|
983
916
|
|
|
@@ -985,39 +918,47 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
985
918
|
* Removes the account and related tokens for a given account key
|
|
986
919
|
* @param account
|
|
987
920
|
*/
|
|
988
|
-
removeAccount(
|
|
989
|
-
const account = this.getAccount(accountKey, correlationId);
|
|
990
|
-
if (!account) {
|
|
991
|
-
return;
|
|
992
|
-
}
|
|
921
|
+
removeAccount(account: AccountInfo, correlationId: string): void {
|
|
993
922
|
this.removeAccountContext(account, correlationId);
|
|
994
|
-
this.
|
|
923
|
+
const accountKeys = this.getAccountKeys();
|
|
924
|
+
const keyFilter = (key: string): boolean => {
|
|
925
|
+
return (
|
|
926
|
+
key.includes(account.homeAccountId) &&
|
|
927
|
+
key.includes(account.environment)
|
|
928
|
+
);
|
|
929
|
+
};
|
|
930
|
+
accountKeys.filter(keyFilter).forEach((key) => {
|
|
931
|
+
this.removeItem(key, correlationId);
|
|
932
|
+
this.performanceClient.incrementFields(
|
|
933
|
+
{ accountsRemoved: 1 },
|
|
934
|
+
correlationId
|
|
935
|
+
);
|
|
936
|
+
});
|
|
995
937
|
}
|
|
996
938
|
|
|
997
939
|
/**
|
|
998
940
|
* Removes credentials associated with the provided account
|
|
999
941
|
* @param account
|
|
1000
942
|
*/
|
|
1001
|
-
removeAccountContext(account:
|
|
943
|
+
removeAccountContext(account: AccountInfo, correlationId: string): void {
|
|
1002
944
|
const allTokenKeys = this.getTokenKeys();
|
|
1003
|
-
const
|
|
945
|
+
const keyFilter = (key: string): boolean => {
|
|
946
|
+
return (
|
|
947
|
+
key.includes(account.homeAccountId) &&
|
|
948
|
+
key.includes(account.environment)
|
|
949
|
+
);
|
|
950
|
+
};
|
|
1004
951
|
|
|
1005
|
-
allTokenKeys.idToken.forEach((key) => {
|
|
1006
|
-
|
|
1007
|
-
this.removeIdToken(key, correlationId);
|
|
1008
|
-
}
|
|
952
|
+
allTokenKeys.idToken.filter(keyFilter).forEach((key) => {
|
|
953
|
+
this.removeIdToken(key, correlationId);
|
|
1009
954
|
});
|
|
1010
955
|
|
|
1011
|
-
allTokenKeys.accessToken.forEach((key) => {
|
|
1012
|
-
|
|
1013
|
-
this.removeAccessToken(key, correlationId);
|
|
1014
|
-
}
|
|
956
|
+
allTokenKeys.accessToken.filter(keyFilter).forEach((key) => {
|
|
957
|
+
this.removeAccessToken(key, correlationId);
|
|
1015
958
|
});
|
|
1016
959
|
|
|
1017
|
-
allTokenKeys.refreshToken.forEach((key) => {
|
|
1018
|
-
|
|
1019
|
-
this.removeRefreshToken(key, correlationId);
|
|
1020
|
-
}
|
|
960
|
+
allTokenKeys.refreshToken.filter(keyFilter).forEach((key) => {
|
|
961
|
+
this.removeRefreshToken(key, correlationId);
|
|
1021
962
|
});
|
|
1022
963
|
}
|
|
1023
964
|
|
|
@@ -1075,19 +1016,6 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
1075
1016
|
return true;
|
|
1076
1017
|
}
|
|
1077
1018
|
|
|
1078
|
-
/**
|
|
1079
|
-
* Retrieve AccountEntity from cache
|
|
1080
|
-
* @param account
|
|
1081
|
-
*/
|
|
1082
|
-
readAccountFromCache(
|
|
1083
|
-
account: AccountInfo,
|
|
1084
|
-
correlationId: string
|
|
1085
|
-
): AccountEntity | null {
|
|
1086
|
-
const accountKey: string =
|
|
1087
|
-
AccountEntity.generateAccountCacheKey(account);
|
|
1088
|
-
return this.getAccount(accountKey, correlationId);
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
1019
|
/**
|
|
1092
1020
|
* Retrieve IdTokenEntity from cache
|
|
1093
1021
|
* @param account {AccountInfo}
|
|
@@ -1335,7 +1263,7 @@ export abstract class CacheManager implements ICacheManager {
|
|
|
1335
1263
|
);
|
|
1336
1264
|
accessTokens.forEach((accessToken) => {
|
|
1337
1265
|
this.removeAccessToken(
|
|
1338
|
-
generateCredentialKey(accessToken),
|
|
1266
|
+
this.generateCredentialKey(accessToken),
|
|
1339
1267
|
correlationId
|
|
1340
1268
|
);
|
|
1341
1269
|
});
|
|
@@ -1958,4 +1886,10 @@ export class DefaultStorageClass extends CacheManager {
|
|
|
1958
1886
|
getTokenKeys(): TokenKeys {
|
|
1959
1887
|
throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented);
|
|
1960
1888
|
}
|
|
1889
|
+
generateCredentialKey(): string {
|
|
1890
|
+
throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented);
|
|
1891
|
+
}
|
|
1892
|
+
generateAccountKey(): string {
|
|
1893
|
+
throw createClientAuthError(ClientAuthErrorCodes.methodNotImplemented);
|
|
1894
|
+
}
|
|
1961
1895
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { CacheAccountType
|
|
6
|
+
import { CacheAccountType } from "../../utils/Constants.js";
|
|
7
7
|
import type { Authority } from "../../authority/Authority.js";
|
|
8
8
|
import { ICrypto } from "../../crypto/ICrypto.js";
|
|
9
9
|
import { ClientInfo, buildClientInfo } from "../../account/ClientInfo.js";
|
|
@@ -54,6 +54,7 @@ export class AccountEntity {
|
|
|
54
54
|
localAccountId: string;
|
|
55
55
|
username: string;
|
|
56
56
|
authorityType: string;
|
|
57
|
+
loginHint?: string;
|
|
57
58
|
clientInfo?: string;
|
|
58
59
|
name?: string;
|
|
59
60
|
lastModificationTime?: string;
|
|
@@ -62,28 +63,7 @@ export class AccountEntity {
|
|
|
62
63
|
msGraphHost?: string;
|
|
63
64
|
nativeAccountId?: string;
|
|
64
65
|
tenantProfiles?: Array<TenantProfile>;
|
|
65
|
-
lastUpdatedAt
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
|
|
69
|
-
*/
|
|
70
|
-
generateAccountId(): string {
|
|
71
|
-
const accountId: Array<string> = [this.homeAccountId, this.environment];
|
|
72
|
-
return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
|
|
77
|
-
*/
|
|
78
|
-
generateAccountKey(): string {
|
|
79
|
-
return AccountEntity.generateAccountCacheKey({
|
|
80
|
-
homeAccountId: this.homeAccountId,
|
|
81
|
-
environment: this.environment,
|
|
82
|
-
tenantId: this.realm,
|
|
83
|
-
username: this.username,
|
|
84
|
-
localAccountId: this.localAccountId,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
66
|
+
lastUpdatedAt: string;
|
|
87
67
|
|
|
88
68
|
/**
|
|
89
69
|
* Returns the AccountInfo interface for this account.
|
|
@@ -95,6 +75,7 @@ export class AccountEntity {
|
|
|
95
75
|
tenantId: this.realm,
|
|
96
76
|
username: this.username,
|
|
97
77
|
localAccountId: this.localAccountId,
|
|
78
|
+
loginHint: this.loginHint,
|
|
98
79
|
name: this.name,
|
|
99
80
|
nativeAccountId: this.nativeAccountId,
|
|
100
81
|
authorityType: this.authorityType,
|
|
@@ -114,21 +95,6 @@ export class AccountEntity {
|
|
|
114
95
|
return !this.tenantProfiles;
|
|
115
96
|
}
|
|
116
97
|
|
|
117
|
-
/**
|
|
118
|
-
* Generates account key from interface
|
|
119
|
-
* @param accountInterface
|
|
120
|
-
*/
|
|
121
|
-
static generateAccountCacheKey(accountInterface: AccountInfo): string {
|
|
122
|
-
const homeTenantId = accountInterface.homeAccountId.split(".")[1];
|
|
123
|
-
const accountKey = [
|
|
124
|
-
accountInterface.homeAccountId,
|
|
125
|
-
accountInterface.environment || "",
|
|
126
|
-
homeTenantId || accountInterface.tenantId || "",
|
|
127
|
-
];
|
|
128
|
-
|
|
129
|
-
return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
98
|
/**
|
|
133
99
|
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
134
100
|
* @param accountDetails
|
|
@@ -207,6 +173,7 @@ export class AccountEntity {
|
|
|
207
173
|
: null;
|
|
208
174
|
|
|
209
175
|
account.username = preferredUsername || email || "";
|
|
176
|
+
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
210
177
|
account.name = accountDetails.idTokenClaims?.name || "";
|
|
211
178
|
|
|
212
179
|
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
@@ -252,6 +219,7 @@ export class AccountEntity {
|
|
|
252
219
|
|
|
253
220
|
account.username = accountInfo.username;
|
|
254
221
|
account.name = accountInfo.name;
|
|
222
|
+
account.loginHint = accountInfo.loginHint;
|
|
255
223
|
|
|
256
224
|
account.cloudGraphHostName = cloudGraphHostName;
|
|
257
225
|
account.msGraphHost = msGraphHost;
|
|
@@ -353,6 +321,7 @@ export class AccountEntity {
|
|
|
353
321
|
accountA.localAccountId === accountB.localAccountId &&
|
|
354
322
|
accountA.username === accountB.username &&
|
|
355
323
|
accountA.tenantId === accountB.tenantId &&
|
|
324
|
+
accountA.loginHint === accountB.loginHint &&
|
|
356
325
|
accountA.environment === accountB.environment &&
|
|
357
326
|
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
358
327
|
claimsMatch
|
|
@@ -29,19 +29,6 @@ export interface ICacheManager {
|
|
|
29
29
|
*/
|
|
30
30
|
setAccount(account: AccountEntity, correlationId: string): Promise<void>;
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
|
|
34
|
-
* @param key
|
|
35
|
-
* @param homeAccountId
|
|
36
|
-
* @param tenantId
|
|
37
|
-
* @returns
|
|
38
|
-
*/
|
|
39
|
-
isAccountKey(
|
|
40
|
-
key: string,
|
|
41
|
-
homeAccountId?: string,
|
|
42
|
-
tenantId?: string
|
|
43
|
-
): boolean;
|
|
44
|
-
|
|
45
32
|
/**
|
|
46
33
|
* fetch the idToken entity from the platform cache
|
|
47
34
|
* @param idTokenKey
|
|
@@ -221,13 +208,13 @@ export interface ICacheManager {
|
|
|
221
208
|
* returns a boolean if the given account is removed
|
|
222
209
|
* @param account
|
|
223
210
|
*/
|
|
224
|
-
removeAccount(
|
|
211
|
+
removeAccount(account: AccountInfo, correlationId: string): void;
|
|
225
212
|
|
|
226
213
|
/**
|
|
227
214
|
* returns a boolean if the given account is removed
|
|
228
215
|
* @param account
|
|
229
216
|
*/
|
|
230
|
-
removeAccountContext(account:
|
|
217
|
+
removeAccountContext(account: AccountInfo, correlationId: string): void;
|
|
231
218
|
|
|
232
219
|
/**
|
|
233
220
|
* @param key
|
|
@@ -28,28 +28,6 @@ import { CredentialEntity } from "../entities/CredentialEntity.js";
|
|
|
28
28
|
import { IdTokenEntity } from "../entities/IdTokenEntity.js";
|
|
29
29
|
import { RefreshTokenEntity } from "../entities/RefreshTokenEntity.js";
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
* Cache Key: <home_account_id>-<environment>-<credential_type>-<client_id or familyId>-<realm>-<scopes>-<claims hash>-<scheme>
|
|
33
|
-
* IdToken Example: uid.utid-login.microsoftonline.com-idtoken-app_client_id-contoso.com
|
|
34
|
-
* AccessToken Example: uid.utid-login.microsoftonline.com-accesstoken-app_client_id-contoso.com-scope1 scope2--pop
|
|
35
|
-
* RefreshToken Example: uid.utid-login.microsoftonline.com-refreshtoken-1-contoso.com
|
|
36
|
-
* @param credentialEntity
|
|
37
|
-
* @returns
|
|
38
|
-
*/
|
|
39
|
-
export function generateCredentialKey(
|
|
40
|
-
credentialEntity: CredentialEntity
|
|
41
|
-
): string {
|
|
42
|
-
const credentialKey = [
|
|
43
|
-
generateAccountId(credentialEntity),
|
|
44
|
-
generateCredentialId(credentialEntity),
|
|
45
|
-
generateTarget(credentialEntity),
|
|
46
|
-
generateClaimsHash(credentialEntity),
|
|
47
|
-
generateScheme(credentialEntity),
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
31
|
/**
|
|
54
32
|
* Create IdTokenEntity
|
|
55
33
|
* @param homeAccountId
|
|
@@ -71,6 +49,7 @@ export function createIdTokenEntity(
|
|
|
71
49
|
clientId: clientId,
|
|
72
50
|
secret: idToken,
|
|
73
51
|
realm: tenantId,
|
|
52
|
+
lastUpdatedAt: Date.now().toString(), // Set the last updated time to now
|
|
74
53
|
};
|
|
75
54
|
|
|
76
55
|
return idTokenEntity;
|
|
@@ -116,6 +95,7 @@ export function createAccessTokenEntity(
|
|
|
116
95
|
realm: tenantId,
|
|
117
96
|
target: scopes,
|
|
118
97
|
tokenType: tokenType || AuthenticationScheme.BEARER,
|
|
98
|
+
lastUpdatedAt: Date.now().toString(), // Set the last updated time to now
|
|
119
99
|
};
|
|
120
100
|
|
|
121
101
|
if (userAssertionHash) {
|
|
@@ -184,6 +164,7 @@ export function createRefreshTokenEntity(
|
|
|
184
164
|
environment: environment,
|
|
185
165
|
clientId: clientId,
|
|
186
166
|
secret: refreshToken,
|
|
167
|
+
lastUpdatedAt: Date.now().toString(),
|
|
187
168
|
};
|
|
188
169
|
|
|
189
170
|
if (userAssertionHash) {
|
|
@@ -201,7 +182,7 @@ export function createRefreshTokenEntity(
|
|
|
201
182
|
return rtEntity;
|
|
202
183
|
}
|
|
203
184
|
|
|
204
|
-
export function isCredentialEntity(entity: object):
|
|
185
|
+
export function isCredentialEntity(entity: object): entity is CredentialEntity {
|
|
205
186
|
return (
|
|
206
187
|
entity.hasOwnProperty("homeAccountId") &&
|
|
207
188
|
entity.hasOwnProperty("environment") &&
|
|
@@ -215,7 +196,9 @@ export function isCredentialEntity(entity: object): boolean {
|
|
|
215
196
|
* Validates an entity: checks for all expected params
|
|
216
197
|
* @param entity
|
|
217
198
|
*/
|
|
218
|
-
export function isAccessTokenEntity(
|
|
199
|
+
export function isAccessTokenEntity(
|
|
200
|
+
entity: object
|
|
201
|
+
): entity is AccessTokenEntity {
|
|
219
202
|
if (!entity) {
|
|
220
203
|
return false;
|
|
221
204
|
}
|
|
@@ -234,7 +217,7 @@ export function isAccessTokenEntity(entity: object): boolean {
|
|
|
234
217
|
* Validates an entity: checks for all expected params
|
|
235
218
|
* @param entity
|
|
236
219
|
*/
|
|
237
|
-
export function isIdTokenEntity(entity: object):
|
|
220
|
+
export function isIdTokenEntity(entity: object): entity is IdTokenEntity {
|
|
238
221
|
if (!entity) {
|
|
239
222
|
return false;
|
|
240
223
|
}
|
|
@@ -250,7 +233,9 @@ export function isIdTokenEntity(entity: object): boolean {
|
|
|
250
233
|
* Validates an entity: checks for all expected params
|
|
251
234
|
* @param entity
|
|
252
235
|
*/
|
|
253
|
-
export function isRefreshTokenEntity(
|
|
236
|
+
export function isRefreshTokenEntity(
|
|
237
|
+
entity: object
|
|
238
|
+
): entity is RefreshTokenEntity {
|
|
254
239
|
if (!entity) {
|
|
255
240
|
return false;
|
|
256
241
|
}
|
|
@@ -261,63 +246,6 @@ export function isRefreshTokenEntity(entity: object): boolean {
|
|
|
261
246
|
);
|
|
262
247
|
}
|
|
263
248
|
|
|
264
|
-
/**
|
|
265
|
-
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
|
|
266
|
-
*/
|
|
267
|
-
function generateAccountId(credentialEntity: CredentialEntity): string {
|
|
268
|
-
const accountId: Array<string> = [
|
|
269
|
-
credentialEntity.homeAccountId,
|
|
270
|
-
credentialEntity.environment,
|
|
271
|
-
];
|
|
272
|
-
return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Generate Credential Id key component as per the schema: <credential_type>-<client_id>-<realm>
|
|
277
|
-
*/
|
|
278
|
-
function generateCredentialId(credentialEntity: CredentialEntity): string {
|
|
279
|
-
const clientOrFamilyId =
|
|
280
|
-
credentialEntity.credentialType === CredentialType.REFRESH_TOKEN
|
|
281
|
-
? credentialEntity.familyId || credentialEntity.clientId
|
|
282
|
-
: credentialEntity.clientId;
|
|
283
|
-
const credentialId: Array<string> = [
|
|
284
|
-
credentialEntity.credentialType,
|
|
285
|
-
clientOrFamilyId,
|
|
286
|
-
credentialEntity.realm || "",
|
|
287
|
-
];
|
|
288
|
-
|
|
289
|
-
return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Generate target key component as per schema: <target>
|
|
294
|
-
*/
|
|
295
|
-
function generateTarget(credentialEntity: CredentialEntity): string {
|
|
296
|
-
return (credentialEntity.target || "").toLowerCase();
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Generate requested claims key component as per schema: <requestedClaims>
|
|
301
|
-
*/
|
|
302
|
-
function generateClaimsHash(credentialEntity: CredentialEntity): string {
|
|
303
|
-
return (credentialEntity.requestedClaimsHash || "").toLowerCase();
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Generate scheme key componenet as per schema: <scheme>
|
|
308
|
-
*/
|
|
309
|
-
function generateScheme(credentialEntity: CredentialEntity): string {
|
|
310
|
-
/*
|
|
311
|
-
* PoP Tokens and SSH certs include scheme in cache key
|
|
312
|
-
* Cast to lowercase to handle "bearer" from ADFS
|
|
313
|
-
*/
|
|
314
|
-
return credentialEntity.tokenType &&
|
|
315
|
-
credentialEntity.tokenType.toLowerCase() !==
|
|
316
|
-
AuthenticationScheme.BEARER.toLowerCase()
|
|
317
|
-
? credentialEntity.tokenType.toLowerCase()
|
|
318
|
-
: "";
|
|
319
|
-
}
|
|
320
|
-
|
|
321
249
|
/**
|
|
322
250
|
* validates if a given cache entry is "Telemetry", parses <key,value>
|
|
323
251
|
* @param key
|
|
@@ -47,7 +47,6 @@ import {
|
|
|
47
47
|
import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent.js";
|
|
48
48
|
import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient.js";
|
|
49
49
|
import { invoke, invokeAsync } from "../utils/FunctionWrappers.js";
|
|
50
|
-
import { generateCredentialKey } from "../cache/utils/CacheHelpers.js";
|
|
51
50
|
import { ClientAssertion } from "../account/ClientCredentials.js";
|
|
52
51
|
import { getClientAssertion } from "../utils/ClientAssertionUtils.js";
|
|
53
52
|
import { getRequestThumbprint } from "../network/RequestThumbprint.js";
|
|
@@ -273,7 +272,7 @@ export class RefreshTokenClient extends BaseClient {
|
|
|
273
272
|
"acquireTokenWithRefreshToken: bad refresh token, removing from cache"
|
|
274
273
|
);
|
|
275
274
|
const badRefreshTokenKey =
|
|
276
|
-
generateCredentialKey(refreshToken);
|
|
275
|
+
this.cacheManager.generateCredentialKey(refreshToken);
|
|
277
276
|
this.cacheManager.removeRefreshToken(
|
|
278
277
|
badRefreshTokenKey,
|
|
279
278
|
request.correlationId
|
|
@@ -115,8 +115,8 @@ export class SilentFlowClient extends BaseClient {
|
|
|
115
115
|
const environment =
|
|
116
116
|
request.authority || this.authority.getPreferredCache();
|
|
117
117
|
const cacheRecord: CacheRecord = {
|
|
118
|
-
account: this.cacheManager.
|
|
119
|
-
request.account,
|
|
118
|
+
account: this.cacheManager.getAccount(
|
|
119
|
+
this.cacheManager.generateAccountKey(request.account),
|
|
120
120
|
request.correlationId
|
|
121
121
|
),
|
|
122
122
|
accessToken: cachedAccessToken,
|
package/src/packageMetadata.ts
CHANGED
|
@@ -411,5 +411,5 @@ function extractAccountSid(account: AccountInfo): string | null {
|
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
function extractLoginHint(account: AccountInfo): string | null {
|
|
414
|
-
return account.idTokenClaims?.login_hint || null;
|
|
414
|
+
return account.loginHint || account.idTokenClaims?.login_hint || null;
|
|
415
415
|
}
|
|
@@ -278,7 +278,9 @@ export class ResponseHandler {
|
|
|
278
278
|
!forceCacheRefreshTokenResponse &&
|
|
279
279
|
cacheRecord.account
|
|
280
280
|
) {
|
|
281
|
-
const key =
|
|
281
|
+
const key = this.cacheStorage.generateAccountKey(
|
|
282
|
+
cacheRecord.account.getAccountInfo()
|
|
283
|
+
);
|
|
282
284
|
const account = this.cacheStorage.getAccount(
|
|
283
285
|
key,
|
|
284
286
|
request.correlationId
|
|
@@ -859,6 +859,10 @@ export type PerformanceEvent = {
|
|
|
859
859
|
// Event context as JSON string
|
|
860
860
|
context?: string;
|
|
861
861
|
|
|
862
|
+
// Cache Data
|
|
863
|
+
cacheLocation?: string;
|
|
864
|
+
cacheRetentionDays?: number;
|
|
865
|
+
|
|
862
866
|
// Number of tokens in the cache to be reported when cache quota is exceeded
|
|
863
867
|
cacheRtCount?: number;
|
|
864
868
|
cacheIdCount?: number;
|
|
@@ -898,6 +902,8 @@ export type PerformanceEvent = {
|
|
|
898
902
|
msalInstanceCount?: number;
|
|
899
903
|
// Number of MSAL JS instances using the same client id in the frame
|
|
900
904
|
sameClientIdInstanceCount?: number;
|
|
905
|
+
|
|
906
|
+
navigateCallbackResult?: boolean;
|
|
901
907
|
};
|
|
902
908
|
|
|
903
909
|
export type PerformanceEventContext = {
|
|
@@ -927,4 +933,14 @@ export const IntFields: ReadonlySet<string> = new Set([
|
|
|
927
933
|
"multiMatchedRT",
|
|
928
934
|
"unencryptedCacheCount",
|
|
929
935
|
"encryptedCacheExpiredCount",
|
|
936
|
+
"oldAccountCount",
|
|
937
|
+
"oldAccessCount",
|
|
938
|
+
"oldIdCount",
|
|
939
|
+
"oldRefreshCount",
|
|
940
|
+
"currAccountCount",
|
|
941
|
+
"currAccessCount",
|
|
942
|
+
"currIdCount",
|
|
943
|
+
"currRefreshCount",
|
|
944
|
+
"expiredCacheRemovedCount",
|
|
945
|
+
"upgradedCacheCount",
|
|
930
946
|
]);
|
package/src/utils/Constants.ts
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
export const Constants = {
|
|
7
7
|
LIBRARY_NAME: "MSAL.JS",
|
|
8
8
|
SKU: "msal.js.common",
|
|
9
|
-
// Prefix for all library cache entries
|
|
10
|
-
CACHE_PREFIX: "msal",
|
|
11
9
|
// default authority
|
|
12
10
|
DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/",
|
|
13
11
|
DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com",
|
package/src/utils/TimeUtils.ts
CHANGED
|
@@ -48,6 +48,21 @@ export function isTokenExpired(expiresOn: string, offset: number): boolean {
|
|
|
48
48
|
return offsetCurrentTimeSec > expirationSec;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a cache entry is expired based on the last updated time and cache retention days.
|
|
53
|
+
* @param lastUpdatedAt
|
|
54
|
+
* @param cacheRetentionDays
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
export function isCacheExpired(
|
|
58
|
+
lastUpdatedAt: string,
|
|
59
|
+
cacheRetentionDays: number
|
|
60
|
+
): boolean {
|
|
61
|
+
const cacheExpirationTimestamp =
|
|
62
|
+
Number(lastUpdatedAt) + cacheRetentionDays * 24 * 60 * 60 * 1000;
|
|
63
|
+
return Date.now() > cacheExpirationTimestamp;
|
|
64
|
+
}
|
|
65
|
+
|
|
51
66
|
/**
|
|
52
67
|
* If the current time is earlier than the time that a token was cached at, we must discard the token
|
|
53
68
|
* i.e. The system clock was turned back after acquiring the cached token
|