@azure/msal-common 15.8.1 → 15.10.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 +32 -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.d.ts +10 -0
- package/dist/error/ClientConfigurationError.d.ts.map +1 -1
- package/dist/error/ClientConfigurationError.mjs +12 -2
- package/dist/error/ClientConfigurationError.mjs.map +1 -1
- package/dist/error/ClientConfigurationErrorCodes.d.ts +2 -0
- package/dist/error/ClientConfigurationErrorCodes.d.ts.map +1 -1
- package/dist/error/ClientConfigurationErrorCodes.mjs +5 -3
- package/dist/error/ClientConfigurationErrorCodes.mjs.map +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/exports-common.d.ts +1 -1
- package/dist/exports-common.d.ts.map +1 -1
- package/dist/index-browser.mjs +2 -2
- package/dist/index-node.mjs +2 -2
- package/dist/index.mjs +2 -2
- 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/BaseAuthRequest.d.ts +5 -1
- package/dist/request/BaseAuthRequest.d.ts.map +1 -1
- package/dist/request/RequestParameterBuilder.d.ts +6 -0
- package/dist/request/RequestParameterBuilder.d.ts.map +1 -1
- package/dist/request/RequestParameterBuilder.mjs +14 -2
- package/dist/request/RequestParameterBuilder.mjs.map +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 +2 -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 +5 -1
- package/dist/utils/Constants.d.ts.map +1 -1
- package/dist/utils/Constants.mjs +6 -4
- 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 +3 -2
- package/lib/index-browser.cjs.map +1 -1
- package/lib/{index-node-BCM1mkg5.js → index-node-Dy4fVJGl.js} +496 -599
- package/lib/index-node-Dy4fVJGl.js.map +1 -0
- package/lib/index-node.cjs +3 -2
- package/lib/index-node.cjs.map +1 -1
- package/lib/index.cjs +3 -2
- package/lib/index.cjs.map +1 -1
- 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/error/ClientConfigurationError.d.ts +10 -0
- package/lib/types/error/ClientConfigurationError.d.ts.map +1 -1
- package/lib/types/error/ClientConfigurationErrorCodes.d.ts +2 -0
- package/lib/types/error/ClientConfigurationErrorCodes.d.ts.map +1 -1
- package/lib/types/exports-common.d.ts +1 -1
- package/lib/types/exports-common.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/request/BaseAuthRequest.d.ts +5 -1
- package/lib/types/request/BaseAuthRequest.d.ts.map +1 -1
- package/lib/types/request/RequestParameterBuilder.d.ts +6 -0
- package/lib/types/request/RequestParameterBuilder.d.ts.map +1 -1
- package/lib/types/response/ResponseHandler.d.ts.map +1 -1
- package/lib/types/telemetry/performance/PerformanceEvent.d.ts +2 -0
- package/lib/types/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
- package/lib/types/utils/Constants.d.ts +5 -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 +50 -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/error/ClientConfigurationError.ts +16 -0
- package/src/error/ClientConfigurationErrorCodes.ts +3 -0
- package/src/exports-common.ts +1 -0
- package/src/packageMetadata.ts +1 -1
- package/src/protocol/Authorize.ts +1 -1
- package/src/request/BaseAuthRequest.ts +5 -1
- package/src/request/RequestParameterBuilder.ts +16 -0
- package/src/response/ResponseHandler.ts +3 -1
- package/src/telemetry/performance/PerformanceEvent.ts +14 -0
- package/src/utils/Constants.ts +6 -2
- package/src/utils/TimeUtils.ts +15 -0
- package/lib/index-node-BCM1mkg5.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @azure/msal-common v15.
|
|
1
|
+
/*! @azure/msal-common v15.10.0 2025-08-05 */
|
|
2
2
|
'use strict';
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
const Constants = {
|
|
10
10
|
LIBRARY_NAME: "MSAL.JS",
|
|
11
11
|
SKU: "msal.js.common",
|
|
12
|
-
// Prefix for all library cache entries
|
|
13
|
-
CACHE_PREFIX: "msal",
|
|
14
12
|
// default authority
|
|
15
13
|
DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/",
|
|
16
14
|
DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com",
|
|
@@ -81,6 +79,10 @@ const HttpStatus = {
|
|
|
81
79
|
SERVER_ERROR_RANGE_END: 599,
|
|
82
80
|
MULTI_SIDED_ERROR: 600,
|
|
83
81
|
};
|
|
82
|
+
const HttpMethod = {
|
|
83
|
+
GET: "GET",
|
|
84
|
+
POST: "POST",
|
|
85
|
+
};
|
|
84
86
|
const OIDC_DEFAULT_SCOPES = [
|
|
85
87
|
Constants.OPENID_SCOPE,
|
|
86
88
|
Constants.PROFILE_SCOPE,
|
|
@@ -846,7 +848,9 @@ const missingNonceAuthenticationHeader = "missing_nonce_authentication_header";
|
|
|
846
848
|
const invalidAuthenticationHeader = "invalid_authentication_header";
|
|
847
849
|
const cannotSetOIDCOptions = "cannot_set_OIDCOptions";
|
|
848
850
|
const cannotAllowPlatformBroker = "cannot_allow_platform_broker";
|
|
849
|
-
const authorityMismatch = "authority_mismatch";
|
|
851
|
+
const authorityMismatch = "authority_mismatch";
|
|
852
|
+
const invalidRequestMethodForEAR = "invalid_request_method_for_EAR";
|
|
853
|
+
const invalidAuthorizePostBodyParameters = "invalid_authorize_post_body_parameters";
|
|
850
854
|
|
|
851
855
|
var ClientConfigurationErrorCodes = /*#__PURE__*/Object.freeze({
|
|
852
856
|
__proto__: null,
|
|
@@ -858,9 +862,11 @@ var ClientConfigurationErrorCodes = /*#__PURE__*/Object.freeze({
|
|
|
858
862
|
emptyInputScopesError: emptyInputScopesError,
|
|
859
863
|
invalidAuthenticationHeader: invalidAuthenticationHeader,
|
|
860
864
|
invalidAuthorityMetadata: invalidAuthorityMetadata,
|
|
865
|
+
invalidAuthorizePostBodyParameters: invalidAuthorizePostBodyParameters,
|
|
861
866
|
invalidClaims: invalidClaims,
|
|
862
867
|
invalidCloudDiscoveryMetadata: invalidCloudDiscoveryMetadata,
|
|
863
868
|
invalidCodeChallengeMethod: invalidCodeChallengeMethod,
|
|
869
|
+
invalidRequestMethodForEAR: invalidRequestMethodForEAR,
|
|
864
870
|
logoutRequestEmpty: logoutRequestEmpty,
|
|
865
871
|
missingNonceAuthenticationHeader: missingNonceAuthenticationHeader,
|
|
866
872
|
missingSshJwk: missingSshJwk,
|
|
@@ -899,6 +905,8 @@ const ClientConfigurationErrorMessages = {
|
|
|
899
905
|
[cannotSetOIDCOptions]: "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.",
|
|
900
906
|
[cannotAllowPlatformBroker]: "Cannot set allowPlatformBroker parameter to true when not in AAD protocol mode.",
|
|
901
907
|
[authorityMismatch]: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority.",
|
|
908
|
+
[invalidAuthorizePostBodyParameters]: "Invalid authorize post body parameters provided. If you are using authorizePostBodyParameters, the request method must be POST. Please check the request method and parameters.",
|
|
909
|
+
[invalidRequestMethodForEAR]: "Invalid request method for EAR protocol mode. The request method cannot be GET when using EAR protocol mode. Please change the request method to POST.",
|
|
902
910
|
};
|
|
903
911
|
/**
|
|
904
912
|
* ClientConfigurationErrorMessage class containing string constants used by error codes and messages.
|
|
@@ -989,6 +997,14 @@ const ClientConfigurationErrorMessage = {
|
|
|
989
997
|
code: authorityMismatch,
|
|
990
998
|
desc: ClientConfigurationErrorMessages[authorityMismatch],
|
|
991
999
|
},
|
|
1000
|
+
invalidAuthorizePostBodyParameters: {
|
|
1001
|
+
code: invalidAuthorizePostBodyParameters,
|
|
1002
|
+
desc: ClientConfigurationErrorMessages[invalidAuthorizePostBodyParameters],
|
|
1003
|
+
},
|
|
1004
|
+
invalidRequestMethodForEAR: {
|
|
1005
|
+
code: invalidRequestMethodForEAR,
|
|
1006
|
+
desc: ClientConfigurationErrorMessages[invalidRequestMethodForEAR],
|
|
1007
|
+
},
|
|
992
1008
|
};
|
|
993
1009
|
/**
|
|
994
1010
|
* Error thrown when there is an error in configuration of the MSAL.js library.
|
|
@@ -2039,6 +2055,16 @@ const IntFields = new Set([
|
|
|
2039
2055
|
"multiMatchedRT",
|
|
2040
2056
|
"unencryptedCacheCount",
|
|
2041
2057
|
"encryptedCacheExpiredCount",
|
|
2058
|
+
"oldAccountCount",
|
|
2059
|
+
"oldAccessCount",
|
|
2060
|
+
"oldIdCount",
|
|
2061
|
+
"oldRefreshCount",
|
|
2062
|
+
"currAccountCount",
|
|
2063
|
+
"currAccessCount",
|
|
2064
|
+
"currIdCount",
|
|
2065
|
+
"currRefreshCount",
|
|
2066
|
+
"expiredCacheRemovedCount",
|
|
2067
|
+
"upgradedCacheCount",
|
|
2042
2068
|
]);
|
|
2043
2069
|
|
|
2044
2070
|
/*
|
|
@@ -2283,6 +2309,16 @@ function isTokenExpired(expiresOn, offset) {
|
|
|
2283
2309
|
// If current time + offset is greater than token expiration time, then token is expired.
|
|
2284
2310
|
return offsetCurrentTimeSec > expirationSec;
|
|
2285
2311
|
}
|
|
2312
|
+
/**
|
|
2313
|
+
* Checks if a cache entry is expired based on the last updated time and cache retention days.
|
|
2314
|
+
* @param lastUpdatedAt
|
|
2315
|
+
* @param cacheRetentionDays
|
|
2316
|
+
* @returns
|
|
2317
|
+
*/
|
|
2318
|
+
function isCacheExpired(lastUpdatedAt, cacheRetentionDays) {
|
|
2319
|
+
const cacheExpirationTimestamp = Number(lastUpdatedAt) + cacheRetentionDays * 24 * 60 * 60 * 1000;
|
|
2320
|
+
return Date.now() > cacheExpirationTimestamp;
|
|
2321
|
+
}
|
|
2286
2322
|
/**
|
|
2287
2323
|
* If the current time is earlier than the time that a token was cached at, we must discard the token
|
|
2288
2324
|
* i.e. The system clock was turned back after acquiring the cached token
|
|
@@ -2305,6 +2341,7 @@ function delay(t, value) {
|
|
|
2305
2341
|
var TimeUtils = /*#__PURE__*/Object.freeze({
|
|
2306
2342
|
__proto__: null,
|
|
2307
2343
|
delay: delay,
|
|
2344
|
+
isCacheExpired: isCacheExpired,
|
|
2308
2345
|
isTokenExpired: isTokenExpired,
|
|
2309
2346
|
nowSeconds: nowSeconds,
|
|
2310
2347
|
toDateFromSeconds: toDateFromSeconds,
|
|
@@ -2316,24 +2353,6 @@ var TimeUtils = /*#__PURE__*/Object.freeze({
|
|
|
2316
2353
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2317
2354
|
* Licensed under the MIT License.
|
|
2318
2355
|
*/
|
|
2319
|
-
/**
|
|
2320
|
-
* Cache Key: <home_account_id>-<environment>-<credential_type>-<client_id or familyId>-<realm>-<scopes>-<claims hash>-<scheme>
|
|
2321
|
-
* IdToken Example: uid.utid-login.microsoftonline.com-idtoken-app_client_id-contoso.com
|
|
2322
|
-
* AccessToken Example: uid.utid-login.microsoftonline.com-accesstoken-app_client_id-contoso.com-scope1 scope2--pop
|
|
2323
|
-
* RefreshToken Example: uid.utid-login.microsoftonline.com-refreshtoken-1-contoso.com
|
|
2324
|
-
* @param credentialEntity
|
|
2325
|
-
* @returns
|
|
2326
|
-
*/
|
|
2327
|
-
function generateCredentialKey(credentialEntity) {
|
|
2328
|
-
const credentialKey = [
|
|
2329
|
-
generateAccountId(credentialEntity),
|
|
2330
|
-
generateCredentialId(credentialEntity),
|
|
2331
|
-
generateTarget(credentialEntity),
|
|
2332
|
-
generateClaimsHash(credentialEntity),
|
|
2333
|
-
generateScheme(credentialEntity),
|
|
2334
|
-
];
|
|
2335
|
-
return credentialKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
2336
|
-
}
|
|
2337
2356
|
/**
|
|
2338
2357
|
* Create IdTokenEntity
|
|
2339
2358
|
* @param homeAccountId
|
|
@@ -2349,6 +2368,7 @@ function createIdTokenEntity(homeAccountId, environment, idToken, clientId, tena
|
|
|
2349
2368
|
clientId: clientId,
|
|
2350
2369
|
secret: idToken,
|
|
2351
2370
|
realm: tenantId,
|
|
2371
|
+
lastUpdatedAt: Date.now().toString(), // Set the last updated time to now
|
|
2352
2372
|
};
|
|
2353
2373
|
return idTokenEntity;
|
|
2354
2374
|
}
|
|
@@ -2376,6 +2396,7 @@ function createAccessTokenEntity(homeAccountId, environment, accessToken, client
|
|
|
2376
2396
|
realm: tenantId,
|
|
2377
2397
|
target: scopes,
|
|
2378
2398
|
tokenType: tokenType || AuthenticationScheme.BEARER,
|
|
2399
|
+
lastUpdatedAt: Date.now().toString(), // Set the last updated time to now
|
|
2379
2400
|
};
|
|
2380
2401
|
if (userAssertionHash) {
|
|
2381
2402
|
atEntity.userAssertionHash = userAssertionHash;
|
|
@@ -2423,6 +2444,7 @@ function createRefreshTokenEntity(homeAccountId, environment, refreshToken, clie
|
|
|
2423
2444
|
environment: environment,
|
|
2424
2445
|
clientId: clientId,
|
|
2425
2446
|
secret: refreshToken,
|
|
2447
|
+
lastUpdatedAt: Date.now().toString(),
|
|
2426
2448
|
};
|
|
2427
2449
|
if (userAssertionHash) {
|
|
2428
2450
|
rtEntity.userAssertionHash = userAssertionHash;
|
|
@@ -2480,56 +2502,6 @@ function isRefreshTokenEntity(entity) {
|
|
|
2480
2502
|
return (isCredentialEntity(entity) &&
|
|
2481
2503
|
entity["credentialType"] === CredentialType.REFRESH_TOKEN);
|
|
2482
2504
|
}
|
|
2483
|
-
/**
|
|
2484
|
-
* Generate Account Id key component as per the schema: <home_account_id>-<environment>
|
|
2485
|
-
*/
|
|
2486
|
-
function generateAccountId(credentialEntity) {
|
|
2487
|
-
const accountId = [
|
|
2488
|
-
credentialEntity.homeAccountId,
|
|
2489
|
-
credentialEntity.environment,
|
|
2490
|
-
];
|
|
2491
|
-
return accountId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
2492
|
-
}
|
|
2493
|
-
/**
|
|
2494
|
-
* Generate Credential Id key component as per the schema: <credential_type>-<client_id>-<realm>
|
|
2495
|
-
*/
|
|
2496
|
-
function generateCredentialId(credentialEntity) {
|
|
2497
|
-
const clientOrFamilyId = credentialEntity.credentialType === CredentialType.REFRESH_TOKEN
|
|
2498
|
-
? credentialEntity.familyId || credentialEntity.clientId
|
|
2499
|
-
: credentialEntity.clientId;
|
|
2500
|
-
const credentialId = [
|
|
2501
|
-
credentialEntity.credentialType,
|
|
2502
|
-
clientOrFamilyId,
|
|
2503
|
-
credentialEntity.realm || "",
|
|
2504
|
-
];
|
|
2505
|
-
return credentialId.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
2506
|
-
}
|
|
2507
|
-
/**
|
|
2508
|
-
* Generate target key component as per schema: <target>
|
|
2509
|
-
*/
|
|
2510
|
-
function generateTarget(credentialEntity) {
|
|
2511
|
-
return (credentialEntity.target || "").toLowerCase();
|
|
2512
|
-
}
|
|
2513
|
-
/**
|
|
2514
|
-
* Generate requested claims key component as per schema: <requestedClaims>
|
|
2515
|
-
*/
|
|
2516
|
-
function generateClaimsHash(credentialEntity) {
|
|
2517
|
-
return (credentialEntity.requestedClaimsHash || "").toLowerCase();
|
|
2518
|
-
}
|
|
2519
|
-
/**
|
|
2520
|
-
* Generate scheme key componenet as per schema: <scheme>
|
|
2521
|
-
*/
|
|
2522
|
-
function generateScheme(credentialEntity) {
|
|
2523
|
-
/*
|
|
2524
|
-
* PoP Tokens and SSH certs include scheme in cache key
|
|
2525
|
-
* Cast to lowercase to handle "bearer" from ADFS
|
|
2526
|
-
*/
|
|
2527
|
-
return credentialEntity.tokenType &&
|
|
2528
|
-
credentialEntity.tokenType.toLowerCase() !==
|
|
2529
|
-
AuthenticationScheme.BEARER.toLowerCase()
|
|
2530
|
-
? credentialEntity.tokenType.toLowerCase()
|
|
2531
|
-
: "";
|
|
2532
|
-
}
|
|
2533
2505
|
/**
|
|
2534
2506
|
* validates if a given cache entry is "Telemetry", parses <key,value>
|
|
2535
2507
|
* @param key
|
|
@@ -2644,7 +2616,6 @@ var CacheHelpers = /*#__PURE__*/Object.freeze({
|
|
|
2644
2616
|
createRefreshTokenEntity: createRefreshTokenEntity,
|
|
2645
2617
|
generateAppMetadataKey: generateAppMetadataKey,
|
|
2646
2618
|
generateAuthorityMetadataExpiresAt: generateAuthorityMetadataExpiresAt,
|
|
2647
|
-
generateCredentialKey: generateCredentialKey,
|
|
2648
2619
|
isAccessTokenEntity: isAccessTokenEntity,
|
|
2649
2620
|
isAppMetadataEntity: isAppMetadataEntity,
|
|
2650
2621
|
isAuthorityMetadataEntity: isAuthorityMetadataEntity,
|
|
@@ -3882,7 +3853,7 @@ class Logger {
|
|
|
3882
3853
|
|
|
3883
3854
|
/* eslint-disable header/header */
|
|
3884
3855
|
const name = "@azure/msal-common";
|
|
3885
|
-
const version = "15.
|
|
3856
|
+
const version = "15.10.0";
|
|
3886
3857
|
|
|
3887
3858
|
/*
|
|
3888
3859
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4073,44 +4044,6 @@ class ScopeSet {
|
|
|
4073
4044
|
}
|
|
4074
4045
|
}
|
|
4075
4046
|
|
|
4076
|
-
/*
|
|
4077
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4078
|
-
* Licensed under the MIT License.
|
|
4079
|
-
*/
|
|
4080
|
-
/**
|
|
4081
|
-
* Function to build a client info object from server clientInfo string
|
|
4082
|
-
* @param rawClientInfo
|
|
4083
|
-
* @param crypto
|
|
4084
|
-
*/
|
|
4085
|
-
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
4086
|
-
if (!rawClientInfo) {
|
|
4087
|
-
throw createClientAuthError(clientInfoEmptyError);
|
|
4088
|
-
}
|
|
4089
|
-
try {
|
|
4090
|
-
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
4091
|
-
return JSON.parse(decodedClientInfo);
|
|
4092
|
-
}
|
|
4093
|
-
catch (e) {
|
|
4094
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
4095
|
-
}
|
|
4096
|
-
}
|
|
4097
|
-
/**
|
|
4098
|
-
* Function to build a client info object from cached homeAccountId string
|
|
4099
|
-
* @param homeAccountId
|
|
4100
|
-
*/
|
|
4101
|
-
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
4102
|
-
if (!homeAccountId) {
|
|
4103
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
4104
|
-
}
|
|
4105
|
-
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
4106
|
-
return {
|
|
4107
|
-
uid: clientInfoParts[0],
|
|
4108
|
-
utid: clientInfoParts.length < 2
|
|
4109
|
-
? Constants.EMPTY_STRING
|
|
4110
|
-
: clientInfoParts[1],
|
|
4111
|
-
};
|
|
4112
|
-
}
|
|
4113
|
-
|
|
4114
4047
|
/*
|
|
4115
4048
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4116
4049
|
* Licensed under the MIT License.
|
|
@@ -4136,7 +4069,7 @@ function tenantIdMatchesHomeTenant(tenantId, homeAccountId) {
|
|
|
4136
4069
|
*/
|
|
4137
4070
|
function buildTenantProfile(homeAccountId, localAccountId, tenantId, idTokenClaims) {
|
|
4138
4071
|
if (idTokenClaims) {
|
|
4139
|
-
const { oid, sub, tid, name, tfp, acr } = idTokenClaims;
|
|
4072
|
+
const { oid, sub, tid, name, tfp, acr, preferred_username, upn, login_hint, } = idTokenClaims;
|
|
4140
4073
|
/**
|
|
4141
4074
|
* Since there is no way to determine if the authority is AAD or B2C, we exhaust all the possible claims that can serve as tenant ID with the following precedence:
|
|
4142
4075
|
* tid - TenantID claim that identifies the tenant that issued the token in AAD. Expected in all AAD ID tokens, not present in B2C ID Tokens.
|
|
@@ -4148,6 +4081,8 @@ function buildTenantProfile(homeAccountId, localAccountId, tenantId, idTokenClai
|
|
|
4148
4081
|
tenantId: tenantId,
|
|
4149
4082
|
localAccountId: oid || sub || "",
|
|
4150
4083
|
name: name,
|
|
4084
|
+
username: preferred_username || upn || "",
|
|
4085
|
+
loginHint: login_hint,
|
|
4151
4086
|
isHomeTenant: tenantIdMatchesHomeTenant(tenantId, homeAccountId),
|
|
4152
4087
|
};
|
|
4153
4088
|
}
|
|
@@ -4155,6 +4090,7 @@ function buildTenantProfile(homeAccountId, localAccountId, tenantId, idTokenClai
|
|
|
4155
4090
|
return {
|
|
4156
4091
|
tenantId,
|
|
4157
4092
|
localAccountId,
|
|
4093
|
+
username: "",
|
|
4158
4094
|
isHomeTenant: tenantIdMatchesHomeTenant(tenantId, homeAccountId),
|
|
4159
4095
|
};
|
|
4160
4096
|
}
|
|
@@ -4193,21 +4129,56 @@ function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenC
|
|
|
4193
4129
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4194
4130
|
* Licensed under the MIT License.
|
|
4195
4131
|
*/
|
|
4132
|
+
const cacheQuotaExceeded = "cache_quota_exceeded";
|
|
4133
|
+
const cacheErrorUnknown = "cache_error_unknown";
|
|
4134
|
+
|
|
4135
|
+
var CacheErrorCodes = /*#__PURE__*/Object.freeze({
|
|
4136
|
+
__proto__: null,
|
|
4137
|
+
cacheErrorUnknown: cacheErrorUnknown,
|
|
4138
|
+
cacheQuotaExceeded: cacheQuotaExceeded
|
|
4139
|
+
});
|
|
4140
|
+
|
|
4141
|
+
/*
|
|
4142
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4143
|
+
* Licensed under the MIT License.
|
|
4144
|
+
*/
|
|
4145
|
+
const CacheErrorMessages = {
|
|
4146
|
+
[cacheQuotaExceeded]: "Exceeded cache storage capacity.",
|
|
4147
|
+
[cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
|
|
4148
|
+
};
|
|
4196
4149
|
/**
|
|
4197
|
-
*
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4150
|
+
* Error thrown when there is an error with the cache
|
|
4151
|
+
*/
|
|
4152
|
+
class CacheError extends AuthError {
|
|
4153
|
+
constructor(errorCode, errorMessage) {
|
|
4154
|
+
const message = errorMessage ||
|
|
4155
|
+
(CacheErrorMessages[errorCode]
|
|
4156
|
+
? CacheErrorMessages[errorCode]
|
|
4157
|
+
: CacheErrorMessages[cacheErrorUnknown]);
|
|
4158
|
+
super(`${errorCode}: ${message}`);
|
|
4159
|
+
Object.setPrototypeOf(this, CacheError.prototype);
|
|
4160
|
+
this.name = "CacheError";
|
|
4161
|
+
this.errorCode = errorCode;
|
|
4162
|
+
this.errorMessage = message;
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
4165
|
+
/**
|
|
4166
|
+
* Helper function to wrap browser errors in a CacheError object
|
|
4167
|
+
* @param e
|
|
4203
4168
|
* @returns
|
|
4204
4169
|
*/
|
|
4205
|
-
function
|
|
4206
|
-
if (
|
|
4207
|
-
|
|
4208
|
-
|
|
4170
|
+
function createCacheError(e) {
|
|
4171
|
+
if (!(e instanceof Error)) {
|
|
4172
|
+
return new CacheError(cacheErrorUnknown);
|
|
4173
|
+
}
|
|
4174
|
+
if (e.name === "QuotaExceededError" ||
|
|
4175
|
+
e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
|
|
4176
|
+
e.message.includes("exceeded the quota")) {
|
|
4177
|
+
return new CacheError(cacheQuotaExceeded);
|
|
4178
|
+
}
|
|
4179
|
+
else {
|
|
4180
|
+
return new CacheError(e.name, e.message);
|
|
4209
4181
|
}
|
|
4210
|
-
return null;
|
|
4211
4182
|
}
|
|
4212
4183
|
|
|
4213
4184
|
/*
|
|
@@ -4215,383 +4186,86 @@ function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
|
4215
4186
|
* Licensed under the MIT License.
|
|
4216
4187
|
*/
|
|
4217
4188
|
/**
|
|
4218
|
-
*
|
|
4219
|
-
*
|
|
4220
|
-
* Key : Value Schema
|
|
4221
|
-
*
|
|
4222
|
-
* Key: <home_account_id>-<environment>-<realm*>
|
|
4223
|
-
*
|
|
4224
|
-
* Value Schema:
|
|
4225
|
-
* {
|
|
4226
|
-
* homeAccountId: home account identifier for the auth scheme,
|
|
4227
|
-
* environment: entity that issued the token, represented as a full host
|
|
4228
|
-
* realm: Full tenant or organizational identifier that the account belongs to
|
|
4229
|
-
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
4230
|
-
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
4231
|
-
* authorityType: Accounts authority type as a string
|
|
4232
|
-
* name: Full name for the account, including given name and family name,
|
|
4233
|
-
* lastModificationTime: last time this entity was modified in the cache
|
|
4234
|
-
* lastModificationApp:
|
|
4235
|
-
* nativeAccountId: Account identifier on the native device
|
|
4236
|
-
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
4237
|
-
* }
|
|
4189
|
+
* Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
|
|
4238
4190
|
* @internal
|
|
4239
4191
|
*/
|
|
4240
|
-
class
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4192
|
+
class CacheManager {
|
|
4193
|
+
constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) {
|
|
4194
|
+
this.clientId = clientId;
|
|
4195
|
+
this.cryptoImpl = cryptoImpl;
|
|
4196
|
+
this.commonLogger = logger.clone(name, version);
|
|
4197
|
+
this.staticAuthorityOptions = staticAuthorityOptions;
|
|
4198
|
+
this.performanceClient = performanceClient;
|
|
4247
4199
|
}
|
|
4248
4200
|
/**
|
|
4249
|
-
*
|
|
4201
|
+
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
4202
|
+
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
4203
|
+
* @returns Array of AccountInfo objects in cache
|
|
4250
4204
|
*/
|
|
4251
|
-
|
|
4252
|
-
return
|
|
4253
|
-
homeAccountId: this.homeAccountId,
|
|
4254
|
-
environment: this.environment,
|
|
4255
|
-
tenantId: this.realm,
|
|
4256
|
-
username: this.username,
|
|
4257
|
-
localAccountId: this.localAccountId,
|
|
4258
|
-
});
|
|
4205
|
+
getAllAccounts(accountFilter, correlationId) {
|
|
4206
|
+
return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter);
|
|
4259
4207
|
}
|
|
4260
4208
|
/**
|
|
4261
|
-
*
|
|
4209
|
+
* Gets first tenanted AccountInfo object found based on provided filters
|
|
4262
4210
|
*/
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
//
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4211
|
+
getAccountInfoFilteredBy(accountFilter, correlationId) {
|
|
4212
|
+
const allAccounts = this.getAllAccounts(accountFilter, correlationId);
|
|
4213
|
+
if (allAccounts.length > 1) {
|
|
4214
|
+
// If one or more accounts are found, prioritize accounts that have an ID token
|
|
4215
|
+
const sortedAccounts = allAccounts.sort((account) => {
|
|
4216
|
+
return account.idTokenClaims ? -1 : 1;
|
|
4217
|
+
});
|
|
4218
|
+
return sortedAccounts[0];
|
|
4219
|
+
}
|
|
4220
|
+
else if (allAccounts.length === 1) {
|
|
4221
|
+
// If only one account is found, return it regardless of whether a matching ID token was found
|
|
4222
|
+
return allAccounts[0];
|
|
4223
|
+
}
|
|
4224
|
+
else {
|
|
4225
|
+
return null;
|
|
4226
|
+
}
|
|
4278
4227
|
}
|
|
4279
4228
|
/**
|
|
4280
|
-
* Returns
|
|
4229
|
+
* Returns a single matching
|
|
4230
|
+
* @param accountFilter
|
|
4231
|
+
* @returns
|
|
4281
4232
|
*/
|
|
4282
|
-
|
|
4283
|
-
|
|
4233
|
+
getBaseAccountInfo(accountFilter, correlationId) {
|
|
4234
|
+
const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
|
|
4235
|
+
if (accountEntities.length > 0) {
|
|
4236
|
+
return accountEntities[0].getAccountInfo();
|
|
4237
|
+
}
|
|
4238
|
+
else {
|
|
4239
|
+
return null;
|
|
4240
|
+
}
|
|
4284
4241
|
}
|
|
4285
4242
|
/**
|
|
4286
|
-
*
|
|
4287
|
-
*
|
|
4243
|
+
* Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
|
|
4244
|
+
* and builds the account info objects from the matching ID token's claims
|
|
4245
|
+
* @param cachedAccounts
|
|
4246
|
+
* @param accountFilter
|
|
4247
|
+
* @returns Array of AccountInfo objects that match account and tenant profile filters
|
|
4288
4248
|
*/
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
accountInterface.environment || "",
|
|
4294
|
-
homeTenantId || accountInterface.tenantId || "",
|
|
4295
|
-
];
|
|
4296
|
-
return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
|
|
4249
|
+
buildTenantProfiles(cachedAccounts, correlationId, accountFilter) {
|
|
4250
|
+
return cachedAccounts.flatMap((accountEntity) => {
|
|
4251
|
+
return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter);
|
|
4252
|
+
});
|
|
4297
4253
|
}
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
4306
|
-
}
|
|
4307
|
-
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
4308
|
-
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
4309
|
-
}
|
|
4310
|
-
else {
|
|
4311
|
-
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
4254
|
+
getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) {
|
|
4255
|
+
let tenantedAccountInfo = null;
|
|
4256
|
+
let idTokenClaims;
|
|
4257
|
+
if (tenantProfileFilter) {
|
|
4258
|
+
if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) {
|
|
4259
|
+
return null;
|
|
4260
|
+
}
|
|
4312
4261
|
}
|
|
4313
|
-
|
|
4314
|
-
if (
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
const env = accountDetails.environment ||
|
|
4321
|
-
(authority && authority.getPreferredCache());
|
|
4322
|
-
if (!env) {
|
|
4323
|
-
throw createClientAuthError(invalidCacheEnvironment);
|
|
4324
|
-
}
|
|
4325
|
-
account.environment = env;
|
|
4326
|
-
// non AAD scenarios can have empty realm
|
|
4327
|
-
account.realm =
|
|
4328
|
-
clientInfo?.utid ||
|
|
4329
|
-
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
4330
|
-
"";
|
|
4331
|
-
// How do you account for MSA CID here?
|
|
4332
|
-
account.localAccountId =
|
|
4333
|
-
clientInfo?.uid ||
|
|
4334
|
-
accountDetails.idTokenClaims?.oid ||
|
|
4335
|
-
accountDetails.idTokenClaims?.sub ||
|
|
4336
|
-
"";
|
|
4337
|
-
/*
|
|
4338
|
-
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
4339
|
-
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
4340
|
-
* policy is configured to return more than 1 email.
|
|
4341
|
-
*/
|
|
4342
|
-
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
4343
|
-
accountDetails.idTokenClaims?.upn;
|
|
4344
|
-
const email = accountDetails.idTokenClaims?.emails
|
|
4345
|
-
? accountDetails.idTokenClaims.emails[0]
|
|
4346
|
-
: null;
|
|
4347
|
-
account.username = preferredUsername || email || "";
|
|
4348
|
-
account.name = accountDetails.idTokenClaims?.name || "";
|
|
4349
|
-
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
4350
|
-
account.msGraphHost = accountDetails.msGraphHost;
|
|
4351
|
-
if (accountDetails.tenantProfiles) {
|
|
4352
|
-
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
4353
|
-
}
|
|
4354
|
-
else {
|
|
4355
|
-
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
4356
|
-
account.tenantProfiles = [tenantProfile];
|
|
4357
|
-
}
|
|
4358
|
-
return account;
|
|
4359
|
-
}
|
|
4360
|
-
/**
|
|
4361
|
-
* Creates an AccountEntity object from AccountInfo
|
|
4362
|
-
* @param accountInfo
|
|
4363
|
-
* @param cloudGraphHostName
|
|
4364
|
-
* @param msGraphHost
|
|
4365
|
-
* @returns
|
|
4366
|
-
*/
|
|
4367
|
-
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
|
|
4368
|
-
const account = new AccountEntity();
|
|
4369
|
-
account.authorityType =
|
|
4370
|
-
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
4371
|
-
account.homeAccountId = accountInfo.homeAccountId;
|
|
4372
|
-
account.localAccountId = accountInfo.localAccountId;
|
|
4373
|
-
account.nativeAccountId = accountInfo.nativeAccountId;
|
|
4374
|
-
account.realm = accountInfo.tenantId;
|
|
4375
|
-
account.environment = accountInfo.environment;
|
|
4376
|
-
account.username = accountInfo.username;
|
|
4377
|
-
account.name = accountInfo.name;
|
|
4378
|
-
account.cloudGraphHostName = cloudGraphHostName;
|
|
4379
|
-
account.msGraphHost = msGraphHost;
|
|
4380
|
-
// Serialize tenant profiles map into an array
|
|
4381
|
-
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
|
|
4382
|
-
return account;
|
|
4383
|
-
}
|
|
4384
|
-
/**
|
|
4385
|
-
* Generate HomeAccountId from server response
|
|
4386
|
-
* @param serverClientInfo
|
|
4387
|
-
* @param authType
|
|
4388
|
-
*/
|
|
4389
|
-
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
|
|
4390
|
-
// since ADFS/DSTS do not have tid and does not set client_info
|
|
4391
|
-
if (!(authType === AuthorityType.Adfs ||
|
|
4392
|
-
authType === AuthorityType.Dsts)) {
|
|
4393
|
-
// for cases where there is clientInfo
|
|
4394
|
-
if (serverClientInfo) {
|
|
4395
|
-
try {
|
|
4396
|
-
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
|
|
4397
|
-
if (clientInfo.uid && clientInfo.utid) {
|
|
4398
|
-
return `${clientInfo.uid}.${clientInfo.utid}`;
|
|
4399
|
-
}
|
|
4400
|
-
}
|
|
4401
|
-
catch (e) { }
|
|
4402
|
-
}
|
|
4403
|
-
logger.warning("No client info in response");
|
|
4404
|
-
}
|
|
4405
|
-
// default to "sub" claim
|
|
4406
|
-
return idTokenClaims?.sub || "";
|
|
4407
|
-
}
|
|
4408
|
-
/**
|
|
4409
|
-
* Validates an entity: checks for all expected params
|
|
4410
|
-
* @param entity
|
|
4411
|
-
*/
|
|
4412
|
-
static isAccountEntity(entity) {
|
|
4413
|
-
if (!entity) {
|
|
4414
|
-
return false;
|
|
4415
|
-
}
|
|
4416
|
-
return (entity.hasOwnProperty("homeAccountId") &&
|
|
4417
|
-
entity.hasOwnProperty("environment") &&
|
|
4418
|
-
entity.hasOwnProperty("realm") &&
|
|
4419
|
-
entity.hasOwnProperty("localAccountId") &&
|
|
4420
|
-
entity.hasOwnProperty("username") &&
|
|
4421
|
-
entity.hasOwnProperty("authorityType"));
|
|
4422
|
-
}
|
|
4423
|
-
/**
|
|
4424
|
-
* Helper function to determine whether 2 accountInfo objects represent the same account
|
|
4425
|
-
* @param accountA
|
|
4426
|
-
* @param accountB
|
|
4427
|
-
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
4428
|
-
*/
|
|
4429
|
-
static accountInfoIsEqual(accountA, accountB, compareClaims) {
|
|
4430
|
-
if (!accountA || !accountB) {
|
|
4431
|
-
return false;
|
|
4432
|
-
}
|
|
4433
|
-
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
|
|
4434
|
-
if (compareClaims) {
|
|
4435
|
-
const accountAClaims = (accountA.idTokenClaims ||
|
|
4436
|
-
{});
|
|
4437
|
-
const accountBClaims = (accountB.idTokenClaims ||
|
|
4438
|
-
{});
|
|
4439
|
-
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
4440
|
-
claimsMatch =
|
|
4441
|
-
accountAClaims.iat === accountBClaims.iat &&
|
|
4442
|
-
accountAClaims.nonce === accountBClaims.nonce;
|
|
4443
|
-
}
|
|
4444
|
-
return (accountA.homeAccountId === accountB.homeAccountId &&
|
|
4445
|
-
accountA.localAccountId === accountB.localAccountId &&
|
|
4446
|
-
accountA.username === accountB.username &&
|
|
4447
|
-
accountA.tenantId === accountB.tenantId &&
|
|
4448
|
-
accountA.environment === accountB.environment &&
|
|
4449
|
-
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
4450
|
-
claimsMatch);
|
|
4451
|
-
}
|
|
4452
|
-
}
|
|
4453
|
-
|
|
4454
|
-
/*
|
|
4455
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4456
|
-
* Licensed under the MIT License.
|
|
4457
|
-
*/
|
|
4458
|
-
const cacheQuotaExceeded = "cache_quota_exceeded";
|
|
4459
|
-
const cacheErrorUnknown = "cache_error_unknown";
|
|
4460
|
-
|
|
4461
|
-
var CacheErrorCodes = /*#__PURE__*/Object.freeze({
|
|
4462
|
-
__proto__: null,
|
|
4463
|
-
cacheErrorUnknown: cacheErrorUnknown,
|
|
4464
|
-
cacheQuotaExceeded: cacheQuotaExceeded
|
|
4465
|
-
});
|
|
4466
|
-
|
|
4467
|
-
/*
|
|
4468
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4469
|
-
* Licensed under the MIT License.
|
|
4470
|
-
*/
|
|
4471
|
-
const CacheErrorMessages = {
|
|
4472
|
-
[cacheQuotaExceeded]: "Exceeded cache storage capacity.",
|
|
4473
|
-
[cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
|
|
4474
|
-
};
|
|
4475
|
-
/**
|
|
4476
|
-
* Error thrown when there is an error with the cache
|
|
4477
|
-
*/
|
|
4478
|
-
class CacheError extends AuthError {
|
|
4479
|
-
constructor(errorCode, errorMessage) {
|
|
4480
|
-
const message = errorMessage ||
|
|
4481
|
-
(CacheErrorMessages[errorCode]
|
|
4482
|
-
? CacheErrorMessages[errorCode]
|
|
4483
|
-
: CacheErrorMessages[cacheErrorUnknown]);
|
|
4484
|
-
super(`${errorCode}: ${message}`);
|
|
4485
|
-
Object.setPrototypeOf(this, CacheError.prototype);
|
|
4486
|
-
this.name = "CacheError";
|
|
4487
|
-
this.errorCode = errorCode;
|
|
4488
|
-
this.errorMessage = message;
|
|
4489
|
-
}
|
|
4490
|
-
}
|
|
4491
|
-
/**
|
|
4492
|
-
* Helper function to wrap browser errors in a CacheError object
|
|
4493
|
-
* @param e
|
|
4494
|
-
* @returns
|
|
4495
|
-
*/
|
|
4496
|
-
function createCacheError(e) {
|
|
4497
|
-
if (!(e instanceof Error)) {
|
|
4498
|
-
return new CacheError(cacheErrorUnknown);
|
|
4499
|
-
}
|
|
4500
|
-
if (e.name === "QuotaExceededError" ||
|
|
4501
|
-
e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
|
|
4502
|
-
e.message.includes("exceeded the quota")) {
|
|
4503
|
-
return new CacheError(cacheQuotaExceeded);
|
|
4504
|
-
}
|
|
4505
|
-
else {
|
|
4506
|
-
return new CacheError(e.name, e.message);
|
|
4507
|
-
}
|
|
4508
|
-
}
|
|
4509
|
-
|
|
4510
|
-
/*
|
|
4511
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4512
|
-
* Licensed under the MIT License.
|
|
4513
|
-
*/
|
|
4514
|
-
/**
|
|
4515
|
-
* Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
|
|
4516
|
-
* @internal
|
|
4517
|
-
*/
|
|
4518
|
-
class CacheManager {
|
|
4519
|
-
constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) {
|
|
4520
|
-
this.clientId = clientId;
|
|
4521
|
-
this.cryptoImpl = cryptoImpl;
|
|
4522
|
-
this.commonLogger = logger.clone(name, version);
|
|
4523
|
-
this.staticAuthorityOptions = staticAuthorityOptions;
|
|
4524
|
-
this.performanceClient = performanceClient;
|
|
4525
|
-
}
|
|
4526
|
-
/**
|
|
4527
|
-
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
4528
|
-
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
4529
|
-
* @returns Array of AccountInfo objects in cache
|
|
4530
|
-
*/
|
|
4531
|
-
getAllAccounts(accountFilter, correlationId) {
|
|
4532
|
-
return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter);
|
|
4533
|
-
}
|
|
4534
|
-
/**
|
|
4535
|
-
* Gets first tenanted AccountInfo object found based on provided filters
|
|
4536
|
-
*/
|
|
4537
|
-
getAccountInfoFilteredBy(accountFilter, correlationId) {
|
|
4538
|
-
const allAccounts = this.getAllAccounts(accountFilter, correlationId);
|
|
4539
|
-
if (allAccounts.length > 1) {
|
|
4540
|
-
// If one or more accounts are found, prioritize accounts that have an ID token
|
|
4541
|
-
const sortedAccounts = allAccounts.sort((account) => {
|
|
4542
|
-
return account.idTokenClaims ? -1 : 1;
|
|
4543
|
-
});
|
|
4544
|
-
return sortedAccounts[0];
|
|
4545
|
-
}
|
|
4546
|
-
else if (allAccounts.length === 1) {
|
|
4547
|
-
// If only one account is found, return it regardless of whether a matching ID token was found
|
|
4548
|
-
return allAccounts[0];
|
|
4549
|
-
}
|
|
4550
|
-
else {
|
|
4551
|
-
return null;
|
|
4552
|
-
}
|
|
4553
|
-
}
|
|
4554
|
-
/**
|
|
4555
|
-
* Returns a single matching
|
|
4556
|
-
* @param accountFilter
|
|
4557
|
-
* @returns
|
|
4558
|
-
*/
|
|
4559
|
-
getBaseAccountInfo(accountFilter, correlationId) {
|
|
4560
|
-
const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
|
|
4561
|
-
if (accountEntities.length > 0) {
|
|
4562
|
-
return accountEntities[0].getAccountInfo();
|
|
4563
|
-
}
|
|
4564
|
-
else {
|
|
4565
|
-
return null;
|
|
4566
|
-
}
|
|
4567
|
-
}
|
|
4568
|
-
/**
|
|
4569
|
-
* Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
|
|
4570
|
-
* and builds the account info objects from the matching ID token's claims
|
|
4571
|
-
* @param cachedAccounts
|
|
4572
|
-
* @param accountFilter
|
|
4573
|
-
* @returns Array of AccountInfo objects that match account and tenant profile filters
|
|
4574
|
-
*/
|
|
4575
|
-
buildTenantProfiles(cachedAccounts, correlationId, accountFilter) {
|
|
4576
|
-
return cachedAccounts.flatMap((accountEntity) => {
|
|
4577
|
-
return this.getTenantProfilesFromAccountEntity(accountEntity, correlationId, accountFilter?.tenantId, accountFilter);
|
|
4578
|
-
});
|
|
4579
|
-
}
|
|
4580
|
-
getTenantedAccountInfoByFilter(accountInfo, tokenKeys, tenantProfile, correlationId, tenantProfileFilter) {
|
|
4581
|
-
let tenantedAccountInfo = null;
|
|
4582
|
-
let idTokenClaims;
|
|
4583
|
-
if (tenantProfileFilter) {
|
|
4584
|
-
if (!this.tenantProfileMatchesFilter(tenantProfile, tenantProfileFilter)) {
|
|
4585
|
-
return null;
|
|
4586
|
-
}
|
|
4587
|
-
}
|
|
4588
|
-
const idToken = this.getIdToken(accountInfo, correlationId, tokenKeys, tenantProfile.tenantId);
|
|
4589
|
-
if (idToken) {
|
|
4590
|
-
idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode);
|
|
4591
|
-
if (!this.idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter)) {
|
|
4592
|
-
// ID token sourced claims don't match so this tenant profile is not a match
|
|
4593
|
-
return null;
|
|
4594
|
-
}
|
|
4262
|
+
const idToken = this.getIdToken(accountInfo, correlationId, tokenKeys, tenantProfile.tenantId);
|
|
4263
|
+
if (idToken) {
|
|
4264
|
+
idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode);
|
|
4265
|
+
if (!this.idTokenClaimsMatchTenantProfileFilter(idTokenClaims, tenantProfileFilter)) {
|
|
4266
|
+
// ID token sourced claims don't match so this tenant profile is not a match
|
|
4267
|
+
return null;
|
|
4268
|
+
}
|
|
4595
4269
|
}
|
|
4596
4270
|
// Expand tenant profile into account info based on matching tenant profile and if available matching ID token claims
|
|
4597
4271
|
tenantedAccountInfo = updateAccountTenantProfileData(accountInfo, tenantProfile, idTokenClaims, idToken?.secret);
|
|
@@ -4744,10 +4418,6 @@ class CacheManager {
|
|
|
4744
4418
|
const allAccountKeys = this.getAccountKeys();
|
|
4745
4419
|
const matchingAccounts = [];
|
|
4746
4420
|
allAccountKeys.forEach((cacheKey) => {
|
|
4747
|
-
if (!this.isAccountKey(cacheKey, accountFilter.homeAccountId)) {
|
|
4748
|
-
// Don't parse value if the key doesn't match the account filters
|
|
4749
|
-
return;
|
|
4750
|
-
}
|
|
4751
4421
|
const entity = this.getAccount(cacheKey, correlationId);
|
|
4752
4422
|
// Match base account fields
|
|
4753
4423
|
if (!entity) {
|
|
@@ -4793,64 +4463,6 @@ class CacheManager {
|
|
|
4793
4463
|
});
|
|
4794
4464
|
return matchingAccounts;
|
|
4795
4465
|
}
|
|
4796
|
-
/**
|
|
4797
|
-
* Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
|
|
4798
|
-
* @param key
|
|
4799
|
-
* @param homeAccountId
|
|
4800
|
-
* @param tenantId
|
|
4801
|
-
* @returns
|
|
4802
|
-
*/
|
|
4803
|
-
isAccountKey(key, homeAccountId, tenantId) {
|
|
4804
|
-
if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
|
|
4805
|
-
// Account cache keys contain 3 items separated by '-' (each item may also contain '-')
|
|
4806
|
-
return false;
|
|
4807
|
-
}
|
|
4808
|
-
if (homeAccountId &&
|
|
4809
|
-
!key.toLowerCase().includes(homeAccountId.toLowerCase())) {
|
|
4810
|
-
return false;
|
|
4811
|
-
}
|
|
4812
|
-
if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
|
|
4813
|
-
return false;
|
|
4814
|
-
}
|
|
4815
|
-
// Do not check environment as aliasing can cause false negatives
|
|
4816
|
-
return true;
|
|
4817
|
-
}
|
|
4818
|
-
/**
|
|
4819
|
-
* Returns true if the given key matches our credential key schema.
|
|
4820
|
-
* @param key
|
|
4821
|
-
*/
|
|
4822
|
-
isCredentialKey(key) {
|
|
4823
|
-
if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
|
|
4824
|
-
// Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
|
|
4825
|
-
return false;
|
|
4826
|
-
}
|
|
4827
|
-
const lowerCaseKey = key.toLowerCase();
|
|
4828
|
-
// Credential keys must indicate what credential type they represent
|
|
4829
|
-
if (lowerCaseKey.indexOf(CredentialType.ID_TOKEN.toLowerCase()) ===
|
|
4830
|
-
-1 &&
|
|
4831
|
-
lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) ===
|
|
4832
|
-
-1 &&
|
|
4833
|
-
lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 &&
|
|
4834
|
-
lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) ===
|
|
4835
|
-
-1) {
|
|
4836
|
-
return false;
|
|
4837
|
-
}
|
|
4838
|
-
if (lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) >
|
|
4839
|
-
-1) {
|
|
4840
|
-
// Refresh tokens must contain the client id or family id
|
|
4841
|
-
const clientIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${this.clientId}${Separators.CACHE_KEY_SEPARATOR}`;
|
|
4842
|
-
const familyIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${THE_FAMILY_ID}${Separators.CACHE_KEY_SEPARATOR}`;
|
|
4843
|
-
if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 &&
|
|
4844
|
-
lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) {
|
|
4845
|
-
return false;
|
|
4846
|
-
}
|
|
4847
|
-
}
|
|
4848
|
-
else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
|
|
4849
|
-
// Tokens must contain the clientId
|
|
4850
|
-
return false;
|
|
4851
|
-
}
|
|
4852
|
-
return true;
|
|
4853
|
-
}
|
|
4854
4466
|
/**
|
|
4855
4467
|
* Returns whether or not the given credential entity matches the filter
|
|
4856
4468
|
* @param entity
|
|
@@ -4975,22 +4587,26 @@ class CacheManager {
|
|
|
4975
4587
|
* Removes all accounts and related tokens from cache.
|
|
4976
4588
|
*/
|
|
4977
4589
|
removeAllAccounts(correlationId) {
|
|
4978
|
-
const
|
|
4979
|
-
|
|
4980
|
-
this.removeAccount(
|
|
4590
|
+
const accounts = this.getAllAccounts({}, correlationId);
|
|
4591
|
+
accounts.forEach((account) => {
|
|
4592
|
+
this.removeAccount(account, correlationId);
|
|
4981
4593
|
});
|
|
4982
4594
|
}
|
|
4983
4595
|
/**
|
|
4984
4596
|
* Removes the account and related tokens for a given account key
|
|
4985
4597
|
* @param account
|
|
4986
4598
|
*/
|
|
4987
|
-
removeAccount(
|
|
4988
|
-
const account = this.getAccount(accountKey, correlationId);
|
|
4989
|
-
if (!account) {
|
|
4990
|
-
return;
|
|
4991
|
-
}
|
|
4599
|
+
removeAccount(account, correlationId) {
|
|
4992
4600
|
this.removeAccountContext(account, correlationId);
|
|
4993
|
-
this.
|
|
4601
|
+
const accountKeys = this.getAccountKeys();
|
|
4602
|
+
const keyFilter = (key) => {
|
|
4603
|
+
return (key.includes(account.homeAccountId) &&
|
|
4604
|
+
key.includes(account.environment));
|
|
4605
|
+
};
|
|
4606
|
+
accountKeys.filter(keyFilter).forEach((key) => {
|
|
4607
|
+
this.removeItem(key, correlationId);
|
|
4608
|
+
this.performanceClient.incrementFields({ accountsRemoved: 1 }, correlationId);
|
|
4609
|
+
});
|
|
4994
4610
|
}
|
|
4995
4611
|
/**
|
|
4996
4612
|
* Removes credentials associated with the provided account
|
|
@@ -4998,21 +4614,18 @@ class CacheManager {
|
|
|
4998
4614
|
*/
|
|
4999
4615
|
removeAccountContext(account, correlationId) {
|
|
5000
4616
|
const allTokenKeys = this.getTokenKeys();
|
|
5001
|
-
const
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
4617
|
+
const keyFilter = (key) => {
|
|
4618
|
+
return (key.includes(account.homeAccountId) &&
|
|
4619
|
+
key.includes(account.environment));
|
|
4620
|
+
};
|
|
4621
|
+
allTokenKeys.idToken.filter(keyFilter).forEach((key) => {
|
|
4622
|
+
this.removeIdToken(key, correlationId);
|
|
5006
4623
|
});
|
|
5007
|
-
allTokenKeys.accessToken.forEach((key) => {
|
|
5008
|
-
|
|
5009
|
-
this.removeAccessToken(key, correlationId);
|
|
5010
|
-
}
|
|
4624
|
+
allTokenKeys.accessToken.filter(keyFilter).forEach((key) => {
|
|
4625
|
+
this.removeAccessToken(key, correlationId);
|
|
5011
4626
|
});
|
|
5012
|
-
allTokenKeys.refreshToken.forEach((key) => {
|
|
5013
|
-
|
|
5014
|
-
this.removeRefreshToken(key, correlationId);
|
|
5015
|
-
}
|
|
4627
|
+
allTokenKeys.refreshToken.filter(keyFilter).forEach((key) => {
|
|
4628
|
+
this.removeRefreshToken(key, correlationId);
|
|
5016
4629
|
});
|
|
5017
4630
|
}
|
|
5018
4631
|
/**
|
|
@@ -5052,14 +4665,6 @@ class CacheManager {
|
|
|
5052
4665
|
});
|
|
5053
4666
|
return true;
|
|
5054
4667
|
}
|
|
5055
|
-
/**
|
|
5056
|
-
* Retrieve AccountEntity from cache
|
|
5057
|
-
* @param account
|
|
5058
|
-
*/
|
|
5059
|
-
readAccountFromCache(account, correlationId) {
|
|
5060
|
-
const accountKey = AccountEntity.generateAccountCacheKey(account);
|
|
5061
|
-
return this.getAccount(accountKey, correlationId);
|
|
5062
|
-
}
|
|
5063
4668
|
/**
|
|
5064
4669
|
* Retrieve IdTokenEntity from cache
|
|
5065
4670
|
* @param account {AccountInfo}
|
|
@@ -5229,7 +4834,7 @@ class CacheManager {
|
|
|
5229
4834
|
else if (numAccessTokens > 1) {
|
|
5230
4835
|
this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them", correlationId);
|
|
5231
4836
|
accessTokens.forEach((accessToken) => {
|
|
5232
|
-
this.removeAccessToken(generateCredentialKey(accessToken), correlationId);
|
|
4837
|
+
this.removeAccessToken(this.generateCredentialKey(accessToken), correlationId);
|
|
5233
4838
|
});
|
|
5234
4839
|
this.performanceClient.addFields({ multiMatchedAT: accessTokens.length }, correlationId);
|
|
5235
4840
|
return null;
|
|
@@ -5670,6 +5275,12 @@ class DefaultStorageClass extends CacheManager {
|
|
|
5670
5275
|
getTokenKeys() {
|
|
5671
5276
|
throw createClientAuthError(methodNotImplemented);
|
|
5672
5277
|
}
|
|
5278
|
+
generateCredentialKey() {
|
|
5279
|
+
throw createClientAuthError(methodNotImplemented);
|
|
5280
|
+
}
|
|
5281
|
+
generateAccountKey() {
|
|
5282
|
+
throw createClientAuthError(methodNotImplemented);
|
|
5283
|
+
}
|
|
5673
5284
|
}
|
|
5674
5285
|
|
|
5675
5286
|
/*
|
|
@@ -5838,24 +5449,62 @@ function buildAuthOptions(authOptions) {
|
|
|
5838
5449
|
encodeExtraQueryParams: false,
|
|
5839
5450
|
...authOptions,
|
|
5840
5451
|
};
|
|
5841
|
-
}
|
|
5842
|
-
/**
|
|
5843
|
-
* Returns true if config has protocolMode set to ProtocolMode.OIDC, false otherwise
|
|
5844
|
-
* @param ClientConfiguration
|
|
5845
|
-
*/
|
|
5846
|
-
function isOidcProtocolMode(config) {
|
|
5847
|
-
return (config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC);
|
|
5452
|
+
}
|
|
5453
|
+
/**
|
|
5454
|
+
* Returns true if config has protocolMode set to ProtocolMode.OIDC, false otherwise
|
|
5455
|
+
* @param ClientConfiguration
|
|
5456
|
+
*/
|
|
5457
|
+
function isOidcProtocolMode(config) {
|
|
5458
|
+
return (config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC);
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
/*
|
|
5462
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5463
|
+
* Licensed under the MIT License.
|
|
5464
|
+
*/
|
|
5465
|
+
const CcsCredentialType = {
|
|
5466
|
+
HOME_ACCOUNT_ID: "home_account_id",
|
|
5467
|
+
UPN: "UPN",
|
|
5468
|
+
};
|
|
5469
|
+
|
|
5470
|
+
/*
|
|
5471
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5472
|
+
* Licensed under the MIT License.
|
|
5473
|
+
*/
|
|
5474
|
+
/**
|
|
5475
|
+
* Function to build a client info object from server clientInfo string
|
|
5476
|
+
* @param rawClientInfo
|
|
5477
|
+
* @param crypto
|
|
5478
|
+
*/
|
|
5479
|
+
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
5480
|
+
if (!rawClientInfo) {
|
|
5481
|
+
throw createClientAuthError(clientInfoEmptyError);
|
|
5482
|
+
}
|
|
5483
|
+
try {
|
|
5484
|
+
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
5485
|
+
return JSON.parse(decodedClientInfo);
|
|
5486
|
+
}
|
|
5487
|
+
catch (e) {
|
|
5488
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
/**
|
|
5492
|
+
* Function to build a client info object from cached homeAccountId string
|
|
5493
|
+
* @param homeAccountId
|
|
5494
|
+
*/
|
|
5495
|
+
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
5496
|
+
if (!homeAccountId) {
|
|
5497
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
5498
|
+
}
|
|
5499
|
+
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
5500
|
+
return {
|
|
5501
|
+
uid: clientInfoParts[0],
|
|
5502
|
+
utid: clientInfoParts.length < 2
|
|
5503
|
+
? Constants.EMPTY_STRING
|
|
5504
|
+
: clientInfoParts[1],
|
|
5505
|
+
};
|
|
5848
5506
|
}
|
|
5849
5507
|
|
|
5850
|
-
/*
|
|
5851
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5852
|
-
* Licensed under the MIT License.
|
|
5853
|
-
*/
|
|
5854
|
-
const CcsCredentialType = {
|
|
5855
|
-
HOME_ACCOUNT_ID: "home_account_id",
|
|
5856
|
-
UPN: "UPN",
|
|
5857
|
-
};
|
|
5858
|
-
|
|
5859
5508
|
/*
|
|
5860
5509
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5861
5510
|
* Licensed under the MIT License.
|
|
@@ -6255,6 +5904,18 @@ function addEARParameters(parameters, jwk) {
|
|
|
6255
5904
|
// ear_jwe_crypto will always have value: {"alg":"dir","enc":"A256GCM"} so we can hardcode this
|
|
6256
5905
|
const jweCryptoB64Encoded = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0";
|
|
6257
5906
|
parameters.set(EAR_JWE_CRYPTO, jweCryptoB64Encoded);
|
|
5907
|
+
}
|
|
5908
|
+
/**
|
|
5909
|
+
* Adds authorize body parameters to the request parameters
|
|
5910
|
+
* @param parameters
|
|
5911
|
+
* @param bodyParameters
|
|
5912
|
+
*/
|
|
5913
|
+
function addPostBodyParameters(parameters, bodyParameters) {
|
|
5914
|
+
Object.entries(bodyParameters).forEach(([key, value]) => {
|
|
5915
|
+
if (value) {
|
|
5916
|
+
parameters.set(key, value);
|
|
5917
|
+
}
|
|
5918
|
+
});
|
|
6258
5919
|
}
|
|
6259
5920
|
|
|
6260
5921
|
var RequestParameterBuilder = /*#__PURE__*/Object.freeze({
|
|
@@ -6289,6 +5950,7 @@ var RequestParameterBuilder = /*#__PURE__*/Object.freeze({
|
|
|
6289
5950
|
addOboAssertion: addOboAssertion,
|
|
6290
5951
|
addPassword: addPassword,
|
|
6291
5952
|
addPopToken: addPopToken,
|
|
5953
|
+
addPostBodyParameters: addPostBodyParameters,
|
|
6292
5954
|
addPostLogoutRedirectUri: addPostLogoutRedirectUri,
|
|
6293
5955
|
addPrompt: addPrompt,
|
|
6294
5956
|
addRedirectUri: addRedirectUri,
|
|
@@ -6603,6 +6265,240 @@ class BaseClient {
|
|
|
6603
6265
|
}
|
|
6604
6266
|
}
|
|
6605
6267
|
|
|
6268
|
+
/*
|
|
6269
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6270
|
+
* Licensed under the MIT License.
|
|
6271
|
+
*/
|
|
6272
|
+
/**
|
|
6273
|
+
* Gets tenantId from available ID token claims to set as credential realm with the following precedence:
|
|
6274
|
+
* 1. tid - if the token is acquired from an Azure AD tenant tid will be present
|
|
6275
|
+
* 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
|
|
6276
|
+
* 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
|
|
6277
|
+
* Downcased to match the realm case-insensitive comparison requirements
|
|
6278
|
+
* @param idTokenClaims
|
|
6279
|
+
* @returns
|
|
6280
|
+
*/
|
|
6281
|
+
function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
6282
|
+
if (idTokenClaims) {
|
|
6283
|
+
const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
|
|
6284
|
+
return tenantId || null;
|
|
6285
|
+
}
|
|
6286
|
+
return null;
|
|
6287
|
+
}
|
|
6288
|
+
|
|
6289
|
+
/*
|
|
6290
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6291
|
+
* Licensed under the MIT License.
|
|
6292
|
+
*/
|
|
6293
|
+
/**
|
|
6294
|
+
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
|
|
6295
|
+
*
|
|
6296
|
+
* Key : Value Schema
|
|
6297
|
+
*
|
|
6298
|
+
* Key: <home_account_id>-<environment>-<realm*>
|
|
6299
|
+
*
|
|
6300
|
+
* Value Schema:
|
|
6301
|
+
* {
|
|
6302
|
+
* homeAccountId: home account identifier for the auth scheme,
|
|
6303
|
+
* environment: entity that issued the token, represented as a full host
|
|
6304
|
+
* realm: Full tenant or organizational identifier that the account belongs to
|
|
6305
|
+
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
6306
|
+
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
6307
|
+
* authorityType: Accounts authority type as a string
|
|
6308
|
+
* name: Full name for the account, including given name and family name,
|
|
6309
|
+
* lastModificationTime: last time this entity was modified in the cache
|
|
6310
|
+
* lastModificationApp:
|
|
6311
|
+
* nativeAccountId: Account identifier on the native device
|
|
6312
|
+
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
6313
|
+
* }
|
|
6314
|
+
* @internal
|
|
6315
|
+
*/
|
|
6316
|
+
class AccountEntity {
|
|
6317
|
+
/**
|
|
6318
|
+
* Returns the AccountInfo interface for this account.
|
|
6319
|
+
*/
|
|
6320
|
+
getAccountInfo() {
|
|
6321
|
+
return {
|
|
6322
|
+
homeAccountId: this.homeAccountId,
|
|
6323
|
+
environment: this.environment,
|
|
6324
|
+
tenantId: this.realm,
|
|
6325
|
+
username: this.username,
|
|
6326
|
+
localAccountId: this.localAccountId,
|
|
6327
|
+
loginHint: this.loginHint,
|
|
6328
|
+
name: this.name,
|
|
6329
|
+
nativeAccountId: this.nativeAccountId,
|
|
6330
|
+
authorityType: this.authorityType,
|
|
6331
|
+
// Deserialize tenant profiles array into a Map
|
|
6332
|
+
tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => {
|
|
6333
|
+
return [tenantProfile.tenantId, tenantProfile];
|
|
6334
|
+
})),
|
|
6335
|
+
};
|
|
6336
|
+
}
|
|
6337
|
+
/**
|
|
6338
|
+
* Returns true if the account entity is in single tenant format (outdated), false otherwise
|
|
6339
|
+
*/
|
|
6340
|
+
isSingleTenant() {
|
|
6341
|
+
return !this.tenantProfiles;
|
|
6342
|
+
}
|
|
6343
|
+
/**
|
|
6344
|
+
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
6345
|
+
* @param accountDetails
|
|
6346
|
+
*/
|
|
6347
|
+
static createAccount(accountDetails, authority, base64Decode) {
|
|
6348
|
+
const account = new AccountEntity();
|
|
6349
|
+
if (authority.authorityType === AuthorityType.Adfs) {
|
|
6350
|
+
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
6351
|
+
}
|
|
6352
|
+
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
6353
|
+
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
6354
|
+
}
|
|
6355
|
+
else {
|
|
6356
|
+
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
6357
|
+
}
|
|
6358
|
+
let clientInfo;
|
|
6359
|
+
if (accountDetails.clientInfo && base64Decode) {
|
|
6360
|
+
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
|
|
6361
|
+
}
|
|
6362
|
+
account.clientInfo = accountDetails.clientInfo;
|
|
6363
|
+
account.homeAccountId = accountDetails.homeAccountId;
|
|
6364
|
+
account.nativeAccountId = accountDetails.nativeAccountId;
|
|
6365
|
+
const env = accountDetails.environment ||
|
|
6366
|
+
(authority && authority.getPreferredCache());
|
|
6367
|
+
if (!env) {
|
|
6368
|
+
throw createClientAuthError(invalidCacheEnvironment);
|
|
6369
|
+
}
|
|
6370
|
+
account.environment = env;
|
|
6371
|
+
// non AAD scenarios can have empty realm
|
|
6372
|
+
account.realm =
|
|
6373
|
+
clientInfo?.utid ||
|
|
6374
|
+
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
6375
|
+
"";
|
|
6376
|
+
// How do you account for MSA CID here?
|
|
6377
|
+
account.localAccountId =
|
|
6378
|
+
clientInfo?.uid ||
|
|
6379
|
+
accountDetails.idTokenClaims?.oid ||
|
|
6380
|
+
accountDetails.idTokenClaims?.sub ||
|
|
6381
|
+
"";
|
|
6382
|
+
/*
|
|
6383
|
+
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
6384
|
+
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
6385
|
+
* policy is configured to return more than 1 email.
|
|
6386
|
+
*/
|
|
6387
|
+
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
6388
|
+
accountDetails.idTokenClaims?.upn;
|
|
6389
|
+
const email = accountDetails.idTokenClaims?.emails
|
|
6390
|
+
? accountDetails.idTokenClaims.emails[0]
|
|
6391
|
+
: null;
|
|
6392
|
+
account.username = preferredUsername || email || "";
|
|
6393
|
+
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
6394
|
+
account.name = accountDetails.idTokenClaims?.name || "";
|
|
6395
|
+
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
6396
|
+
account.msGraphHost = accountDetails.msGraphHost;
|
|
6397
|
+
if (accountDetails.tenantProfiles) {
|
|
6398
|
+
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
6399
|
+
}
|
|
6400
|
+
else {
|
|
6401
|
+
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
6402
|
+
account.tenantProfiles = [tenantProfile];
|
|
6403
|
+
}
|
|
6404
|
+
return account;
|
|
6405
|
+
}
|
|
6406
|
+
/**
|
|
6407
|
+
* Creates an AccountEntity object from AccountInfo
|
|
6408
|
+
* @param accountInfo
|
|
6409
|
+
* @param cloudGraphHostName
|
|
6410
|
+
* @param msGraphHost
|
|
6411
|
+
* @returns
|
|
6412
|
+
*/
|
|
6413
|
+
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
|
|
6414
|
+
const account = new AccountEntity();
|
|
6415
|
+
account.authorityType =
|
|
6416
|
+
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
6417
|
+
account.homeAccountId = accountInfo.homeAccountId;
|
|
6418
|
+
account.localAccountId = accountInfo.localAccountId;
|
|
6419
|
+
account.nativeAccountId = accountInfo.nativeAccountId;
|
|
6420
|
+
account.realm = accountInfo.tenantId;
|
|
6421
|
+
account.environment = accountInfo.environment;
|
|
6422
|
+
account.username = accountInfo.username;
|
|
6423
|
+
account.name = accountInfo.name;
|
|
6424
|
+
account.loginHint = accountInfo.loginHint;
|
|
6425
|
+
account.cloudGraphHostName = cloudGraphHostName;
|
|
6426
|
+
account.msGraphHost = msGraphHost;
|
|
6427
|
+
// Serialize tenant profiles map into an array
|
|
6428
|
+
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
|
|
6429
|
+
return account;
|
|
6430
|
+
}
|
|
6431
|
+
/**
|
|
6432
|
+
* Generate HomeAccountId from server response
|
|
6433
|
+
* @param serverClientInfo
|
|
6434
|
+
* @param authType
|
|
6435
|
+
*/
|
|
6436
|
+
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
|
|
6437
|
+
// since ADFS/DSTS do not have tid and does not set client_info
|
|
6438
|
+
if (!(authType === AuthorityType.Adfs ||
|
|
6439
|
+
authType === AuthorityType.Dsts)) {
|
|
6440
|
+
// for cases where there is clientInfo
|
|
6441
|
+
if (serverClientInfo) {
|
|
6442
|
+
try {
|
|
6443
|
+
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
|
|
6444
|
+
if (clientInfo.uid && clientInfo.utid) {
|
|
6445
|
+
return `${clientInfo.uid}.${clientInfo.utid}`;
|
|
6446
|
+
}
|
|
6447
|
+
}
|
|
6448
|
+
catch (e) { }
|
|
6449
|
+
}
|
|
6450
|
+
logger.warning("No client info in response");
|
|
6451
|
+
}
|
|
6452
|
+
// default to "sub" claim
|
|
6453
|
+
return idTokenClaims?.sub || "";
|
|
6454
|
+
}
|
|
6455
|
+
/**
|
|
6456
|
+
* Validates an entity: checks for all expected params
|
|
6457
|
+
* @param entity
|
|
6458
|
+
*/
|
|
6459
|
+
static isAccountEntity(entity) {
|
|
6460
|
+
if (!entity) {
|
|
6461
|
+
return false;
|
|
6462
|
+
}
|
|
6463
|
+
return (entity.hasOwnProperty("homeAccountId") &&
|
|
6464
|
+
entity.hasOwnProperty("environment") &&
|
|
6465
|
+
entity.hasOwnProperty("realm") &&
|
|
6466
|
+
entity.hasOwnProperty("localAccountId") &&
|
|
6467
|
+
entity.hasOwnProperty("username") &&
|
|
6468
|
+
entity.hasOwnProperty("authorityType"));
|
|
6469
|
+
}
|
|
6470
|
+
/**
|
|
6471
|
+
* Helper function to determine whether 2 accountInfo objects represent the same account
|
|
6472
|
+
* @param accountA
|
|
6473
|
+
* @param accountB
|
|
6474
|
+
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
6475
|
+
*/
|
|
6476
|
+
static accountInfoIsEqual(accountA, accountB, compareClaims) {
|
|
6477
|
+
if (!accountA || !accountB) {
|
|
6478
|
+
return false;
|
|
6479
|
+
}
|
|
6480
|
+
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
|
|
6481
|
+
if (compareClaims) {
|
|
6482
|
+
const accountAClaims = (accountA.idTokenClaims ||
|
|
6483
|
+
{});
|
|
6484
|
+
const accountBClaims = (accountB.idTokenClaims ||
|
|
6485
|
+
{});
|
|
6486
|
+
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
6487
|
+
claimsMatch =
|
|
6488
|
+
accountAClaims.iat === accountBClaims.iat &&
|
|
6489
|
+
accountAClaims.nonce === accountBClaims.nonce;
|
|
6490
|
+
}
|
|
6491
|
+
return (accountA.homeAccountId === accountB.homeAccountId &&
|
|
6492
|
+
accountA.localAccountId === accountB.localAccountId &&
|
|
6493
|
+
accountA.username === accountB.username &&
|
|
6494
|
+
accountA.tenantId === accountB.tenantId &&
|
|
6495
|
+
accountA.loginHint === accountB.loginHint &&
|
|
6496
|
+
accountA.environment === accountB.environment &&
|
|
6497
|
+
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
6498
|
+
claimsMatch);
|
|
6499
|
+
}
|
|
6500
|
+
}
|
|
6501
|
+
|
|
6606
6502
|
/*
|
|
6607
6503
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6608
6504
|
* Licensed under the MIT License.
|
|
@@ -7004,7 +6900,7 @@ class ResponseHandler {
|
|
|
7004
6900
|
if (handlingRefreshTokenResponse &&
|
|
7005
6901
|
!forceCacheRefreshTokenResponse &&
|
|
7006
6902
|
cacheRecord.account) {
|
|
7007
|
-
const key = cacheRecord.account.
|
|
6903
|
+
const key = this.cacheStorage.generateAccountKey(cacheRecord.account.getAccountInfo());
|
|
7008
6904
|
const account = this.cacheStorage.getAccount(key, request.correlationId);
|
|
7009
6905
|
if (!account) {
|
|
7010
6906
|
this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
|
|
@@ -7578,7 +7474,7 @@ class RefreshTokenClient extends BaseClient {
|
|
|
7578
7474
|
if (e.subError === badToken) {
|
|
7579
7475
|
// Remove bad refresh token from cache
|
|
7580
7476
|
this.logger.verbose("acquireTokenWithRefreshToken: bad refresh token, removing from cache");
|
|
7581
|
-
const badRefreshTokenKey = generateCredentialKey(refreshToken);
|
|
7477
|
+
const badRefreshTokenKey = this.cacheManager.generateCredentialKey(refreshToken);
|
|
7582
7478
|
this.cacheManager.removeRefreshToken(badRefreshTokenKey, request.correlationId);
|
|
7583
7479
|
}
|
|
7584
7480
|
}
|
|
@@ -7735,7 +7631,7 @@ class SilentFlowClient extends BaseClient {
|
|
|
7735
7631
|
}
|
|
7736
7632
|
const environment = request.authority || this.authority.getPreferredCache();
|
|
7737
7633
|
const cacheRecord = {
|
|
7738
|
-
account: this.cacheManager.
|
|
7634
|
+
account: this.cacheManager.getAccount(this.cacheManager.generateAccountKey(request.account), request.correlationId),
|
|
7739
7635
|
accessToken: cachedAccessToken,
|
|
7740
7636
|
idToken: this.cacheManager.getIdToken(request.account, request.correlationId, tokenKeys, requestTenantId, this.performanceClient),
|
|
7741
7637
|
refreshToken: null,
|
|
@@ -8013,7 +7909,7 @@ function extractAccountSid(account) {
|
|
|
8013
7909
|
return account.idTokenClaims?.sid || null;
|
|
8014
7910
|
}
|
|
8015
7911
|
function extractLoginHint(account) {
|
|
8016
|
-
return account.idTokenClaims?.login_hint || null;
|
|
7912
|
+
return account.loginHint || account.idTokenClaims?.login_hint || null;
|
|
8017
7913
|
}
|
|
8018
7914
|
|
|
8019
7915
|
var Authorize = /*#__PURE__*/Object.freeze({
|
|
@@ -8384,6 +8280,7 @@ exports.EncodingTypes = EncodingTypes;
|
|
|
8384
8280
|
exports.Errors = Errors;
|
|
8385
8281
|
exports.GrantType = GrantType;
|
|
8386
8282
|
exports.HeaderNames = HeaderNames;
|
|
8283
|
+
exports.HttpMethod = HttpMethod;
|
|
8387
8284
|
exports.HttpStatus = HttpStatus;
|
|
8388
8285
|
exports.IntFields = IntFields;
|
|
8389
8286
|
exports.InteractionRequiredAuthError = InteractionRequiredAuthError;
|
|
@@ -8444,4 +8341,4 @@ exports.invokeAsync = invokeAsync;
|
|
|
8444
8341
|
exports.tenantIdMatchesHomeTenant = tenantIdMatchesHomeTenant;
|
|
8445
8342
|
exports.updateAccountTenantProfileData = updateAccountTenantProfileData;
|
|
8446
8343
|
exports.version = version;
|
|
8447
|
-
//# sourceMappingURL=index-node-
|
|
8344
|
+
//# sourceMappingURL=index-node-Dy4fVJGl.js.map
|