@azure/msal-common 15.12.0 → 15.13.1
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 +3 -0
- package/dist/account/AccountInfo.d.ts.map +1 -1
- package/dist/account/AccountInfo.mjs +1 -1
- package/dist/account/AccountInfo.mjs.map +1 -1
- package/dist/account/AuthToken.d.ts +6 -0
- package/dist/account/AuthToken.d.ts.map +1 -1
- package/dist/account/AuthToken.mjs +22 -2
- package/dist/account/AuthToken.mjs.map +1 -1
- package/dist/account/CcsCredential.mjs +1 -1
- package/dist/account/ClientInfo.d.ts +5 -1
- package/dist/account/ClientInfo.d.ts.map +1 -1
- package/dist/account/ClientInfo.mjs +1 -1
- package/dist/account/ClientInfo.mjs.map +1 -1
- package/dist/account/TokenClaims.d.ts +4 -0
- package/dist/account/TokenClaims.d.ts.map +1 -1
- package/dist/account/TokenClaims.mjs +1 -1
- package/dist/account/TokenClaims.mjs.map +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 +7 -6
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.mjs +13 -11
- package/dist/cache/CacheManager.mjs.map +1 -1
- package/dist/cache/entities/AccountEntity.d.ts +4 -3
- package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
- package/dist/cache/entities/AccountEntity.mjs +18 -12
- package/dist/cache/entities/AccountEntity.mjs.map +1 -1
- package/dist/cache/interface/ICacheManager.d.ts +16 -5
- package/dist/cache/interface/ICacheManager.d.ts.map +1 -1
- package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
- package/dist/cache/utils/CacheHelpers.mjs +1 -1
- package/dist/client/AuthorizationCodeClient.mjs +1 -1
- package/dist/client/BaseClient.mjs +1 -1
- package/dist/client/RefreshTokenClient.mjs +1 -1
- package/dist/client/SilentFlowClient.mjs +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.mjs +2 -2
- package/dist/protocol/Authorize.mjs +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 +5 -5
- package/dist/response/ResponseHandler.mjs.map +1 -1
- package/dist/telemetry/performance/IPerformanceClient.d.ts +2 -1
- package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
- package/dist/telemetry/performance/PerformanceClient.d.ts +4 -1
- package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
- package/dist/telemetry/performance/PerformanceClient.mjs +23 -5
- package/dist/telemetry/performance/PerformanceClient.mjs.map +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 +1 -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.mjs +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.mjs +1 -1
- package/dist/utils/UrlUtils.mjs +1 -1
- package/lib/index-browser.cjs +23 -5
- package/lib/index-browser.cjs.map +1 -1
- package/lib/{index-node-C8h2xZEM.js → index-node-DhUjlPuB.js} +406 -378
- package/lib/index-node-DhUjlPuB.js.map +1 -0
- package/lib/index-node.cjs +2 -2
- package/lib/index.cjs +2 -2
- package/lib/types/account/AccountInfo.d.ts +3 -0
- package/lib/types/account/AccountInfo.d.ts.map +1 -1
- package/lib/types/account/AuthToken.d.ts +6 -0
- package/lib/types/account/AuthToken.d.ts.map +1 -1
- package/lib/types/account/ClientInfo.d.ts +5 -1
- package/lib/types/account/ClientInfo.d.ts.map +1 -1
- package/lib/types/account/TokenClaims.d.ts +4 -0
- package/lib/types/account/TokenClaims.d.ts.map +1 -1
- package/lib/types/cache/CacheManager.d.ts +7 -6
- package/lib/types/cache/CacheManager.d.ts.map +1 -1
- package/lib/types/cache/entities/AccountEntity.d.ts +4 -3
- package/lib/types/cache/entities/AccountEntity.d.ts.map +1 -1
- package/lib/types/cache/interface/ICacheManager.d.ts +16 -5
- package/lib/types/cache/interface/ICacheManager.d.ts.map +1 -1
- package/lib/types/packageMetadata.d.ts +1 -1
- package/lib/types/response/ResponseHandler.d.ts.map +1 -1
- package/lib/types/telemetry/performance/IPerformanceClient.d.ts +2 -1
- package/lib/types/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
- package/lib/types/telemetry/performance/PerformanceClient.d.ts +4 -1
- package/lib/types/telemetry/performance/PerformanceClient.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/package.json +1 -1
- package/src/account/AccountInfo.ts +5 -0
- package/src/account/AuthToken.ts +23 -0
- package/src/account/ClientInfo.ts +5 -1
- package/src/account/TokenClaims.ts +4 -0
- package/src/cache/CacheManager.ts +23 -13
- package/src/cache/entities/AccountEntity.ts +20 -12
- package/src/cache/interface/ICacheManager.ts +23 -4
- package/src/packageMetadata.ts +1 -1
- package/src/response/ResponseHandler.ts +8 -3
- package/src/telemetry/performance/IPerformanceClient.ts +3 -1
- package/src/telemetry/performance/PerformanceClient.ts +29 -3
- package/src/telemetry/performance/PerformanceEvent.ts +4 -0
- package/lib/index-node-C8h2xZEM.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @azure/msal-common v15.
|
|
1
|
+
/*! @azure/msal-common v15.13.1 2025-10-29 */
|
|
2
2
|
'use strict';
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
@@ -754,6 +754,26 @@ function extractTokenClaims(encodedToken, base64Decode) {
|
|
|
754
754
|
throw createClientAuthError(tokenParsingError);
|
|
755
755
|
}
|
|
756
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Check if the signin_state claim contains "kmsi"
|
|
759
|
+
* @param idTokenClaims
|
|
760
|
+
* @returns
|
|
761
|
+
*/
|
|
762
|
+
function isKmsi(idTokenClaims) {
|
|
763
|
+
if (!idTokenClaims.signin_state) {
|
|
764
|
+
return false;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Signin_state claim known values:
|
|
768
|
+
* dvc_mngd - device is managed
|
|
769
|
+
* dvc_dmjd - device is domain joined
|
|
770
|
+
* kmsi - user opted to "keep me signed in"
|
|
771
|
+
* inknownntwk - Request made inside a known network. Don't use this, use CAE instead.
|
|
772
|
+
*/
|
|
773
|
+
const kmsiClaims = ["kmsi", "dvc_dmjd"]; // There are some cases where kmsi may not be returned but persistent storage is still OK - allow dvc_dmjd as well
|
|
774
|
+
const kmsi = idTokenClaims.signin_state.some((value) => kmsiClaims.includes(value.trim().toLowerCase()));
|
|
775
|
+
return kmsi;
|
|
776
|
+
}
|
|
757
777
|
/**
|
|
758
778
|
* decode a JWT
|
|
759
779
|
*
|
|
@@ -796,7 +816,8 @@ var AuthToken = /*#__PURE__*/Object.freeze({
|
|
|
796
816
|
__proto__: null,
|
|
797
817
|
checkMaxAge: checkMaxAge,
|
|
798
818
|
extractTokenClaims: extractTokenClaims,
|
|
799
|
-
getJWSPayload: getJWSPayload
|
|
819
|
+
getJWSPayload: getJWSPayload,
|
|
820
|
+
isKmsi: isKmsi
|
|
800
821
|
});
|
|
801
822
|
|
|
802
823
|
/*
|
|
@@ -3905,7 +3926,7 @@ class Logger {
|
|
|
3905
3926
|
|
|
3906
3927
|
/* eslint-disable header/header */
|
|
3907
3928
|
const name = "@azure/msal-common";
|
|
3908
|
-
const version = "15.
|
|
3929
|
+
const version = "15.13.1";
|
|
3909
3930
|
|
|
3910
3931
|
/*
|
|
3911
3932
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4100,6 +4121,44 @@ class ScopeSet {
|
|
|
4100
4121
|
}
|
|
4101
4122
|
}
|
|
4102
4123
|
|
|
4124
|
+
/*
|
|
4125
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4126
|
+
* Licensed under the MIT License.
|
|
4127
|
+
*/
|
|
4128
|
+
/**
|
|
4129
|
+
* Function to build a client info object from server clientInfo string
|
|
4130
|
+
* @param rawClientInfo
|
|
4131
|
+
* @param crypto
|
|
4132
|
+
*/
|
|
4133
|
+
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
4134
|
+
if (!rawClientInfo) {
|
|
4135
|
+
throw createClientAuthError(clientInfoEmptyError);
|
|
4136
|
+
}
|
|
4137
|
+
try {
|
|
4138
|
+
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
4139
|
+
return JSON.parse(decodedClientInfo);
|
|
4140
|
+
}
|
|
4141
|
+
catch (e) {
|
|
4142
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
/**
|
|
4146
|
+
* Function to build a client info object from cached homeAccountId string
|
|
4147
|
+
* @param homeAccountId
|
|
4148
|
+
*/
|
|
4149
|
+
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
4150
|
+
if (!homeAccountId) {
|
|
4151
|
+
throw createClientAuthError(clientInfoDecodingError);
|
|
4152
|
+
}
|
|
4153
|
+
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
4154
|
+
return {
|
|
4155
|
+
uid: clientInfoParts[0],
|
|
4156
|
+
utid: clientInfoParts.length < 2
|
|
4157
|
+
? Constants.EMPTY_STRING
|
|
4158
|
+
: clientInfoParts[1],
|
|
4159
|
+
};
|
|
4160
|
+
}
|
|
4161
|
+
|
|
4103
4162
|
/*
|
|
4104
4163
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4105
4164
|
* Licensed under the MIT License.
|
|
@@ -4185,56 +4244,21 @@ function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenC
|
|
|
4185
4244
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4186
4245
|
* Licensed under the MIT License.
|
|
4187
4246
|
*/
|
|
4188
|
-
const cacheQuotaExceeded = "cache_quota_exceeded";
|
|
4189
|
-
const cacheErrorUnknown = "cache_error_unknown";
|
|
4190
|
-
|
|
4191
|
-
var CacheErrorCodes = /*#__PURE__*/Object.freeze({
|
|
4192
|
-
__proto__: null,
|
|
4193
|
-
cacheErrorUnknown: cacheErrorUnknown,
|
|
4194
|
-
cacheQuotaExceeded: cacheQuotaExceeded
|
|
4195
|
-
});
|
|
4196
|
-
|
|
4197
|
-
/*
|
|
4198
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4199
|
-
* Licensed under the MIT License.
|
|
4200
|
-
*/
|
|
4201
|
-
const CacheErrorMessages = {
|
|
4202
|
-
[cacheQuotaExceeded]: "Exceeded cache storage capacity.",
|
|
4203
|
-
[cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
|
|
4204
|
-
};
|
|
4205
|
-
/**
|
|
4206
|
-
* Error thrown when there is an error with the cache
|
|
4207
|
-
*/
|
|
4208
|
-
class CacheError extends AuthError {
|
|
4209
|
-
constructor(errorCode, errorMessage) {
|
|
4210
|
-
const message = errorMessage ||
|
|
4211
|
-
(CacheErrorMessages[errorCode]
|
|
4212
|
-
? CacheErrorMessages[errorCode]
|
|
4213
|
-
: CacheErrorMessages[cacheErrorUnknown]);
|
|
4214
|
-
super(`${errorCode}: ${message}`);
|
|
4215
|
-
Object.setPrototypeOf(this, CacheError.prototype);
|
|
4216
|
-
this.name = "CacheError";
|
|
4217
|
-
this.errorCode = errorCode;
|
|
4218
|
-
this.errorMessage = message;
|
|
4219
|
-
}
|
|
4220
|
-
}
|
|
4221
4247
|
/**
|
|
4222
|
-
*
|
|
4223
|
-
*
|
|
4248
|
+
* Gets tenantId from available ID token claims to set as credential realm with the following precedence:
|
|
4249
|
+
* 1. tid - if the token is acquired from an Azure AD tenant tid will be present
|
|
4250
|
+
* 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
|
|
4251
|
+
* 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
|
|
4252
|
+
* Downcased to match the realm case-insensitive comparison requirements
|
|
4253
|
+
* @param idTokenClaims
|
|
4224
4254
|
* @returns
|
|
4225
4255
|
*/
|
|
4226
|
-
function
|
|
4227
|
-
if (
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
if (e.name === "QuotaExceededError" ||
|
|
4231
|
-
e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
|
|
4232
|
-
e.message.includes("exceeded the quota")) {
|
|
4233
|
-
return new CacheError(cacheQuotaExceeded);
|
|
4234
|
-
}
|
|
4235
|
-
else {
|
|
4236
|
-
return new CacheError(e.name, e.message);
|
|
4256
|
+
function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
4257
|
+
if (idTokenClaims) {
|
|
4258
|
+
const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
|
|
4259
|
+
return tenantId || null;
|
|
4237
4260
|
}
|
|
4261
|
+
return null;
|
|
4238
4262
|
}
|
|
4239
4263
|
|
|
4240
4264
|
/*
|
|
@@ -4242,69 +4266,344 @@ function createCacheError(e) {
|
|
|
4242
4266
|
* Licensed under the MIT License.
|
|
4243
4267
|
*/
|
|
4244
4268
|
/**
|
|
4245
|
-
*
|
|
4269
|
+
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
|
|
4270
|
+
*
|
|
4271
|
+
* Key : Value Schema
|
|
4272
|
+
*
|
|
4273
|
+
* Key: <home_account_id>-<environment>-<realm*>
|
|
4274
|
+
*
|
|
4275
|
+
* Value Schema:
|
|
4276
|
+
* {
|
|
4277
|
+
* homeAccountId: home account identifier for the auth scheme,
|
|
4278
|
+
* environment: entity that issued the token, represented as a full host
|
|
4279
|
+
* realm: Full tenant or organizational identifier that the account belongs to
|
|
4280
|
+
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
4281
|
+
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
4282
|
+
* authorityType: Accounts authority type as a string
|
|
4283
|
+
* name: Full name for the account, including given name and family name,
|
|
4284
|
+
* lastModificationTime: last time this entity was modified in the cache
|
|
4285
|
+
* lastModificationApp:
|
|
4286
|
+
* nativeAccountId: Account identifier on the native device
|
|
4287
|
+
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
4288
|
+
* }
|
|
4246
4289
|
* @internal
|
|
4247
4290
|
*/
|
|
4248
|
-
class
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4291
|
+
class AccountEntity {
|
|
4292
|
+
/**
|
|
4293
|
+
* Returns the AccountInfo interface for this account.
|
|
4294
|
+
*/
|
|
4295
|
+
static getAccountInfo(accountEntity) {
|
|
4296
|
+
return {
|
|
4297
|
+
homeAccountId: accountEntity.homeAccountId,
|
|
4298
|
+
environment: accountEntity.environment,
|
|
4299
|
+
tenantId: accountEntity.realm,
|
|
4300
|
+
username: accountEntity.username,
|
|
4301
|
+
localAccountId: accountEntity.localAccountId,
|
|
4302
|
+
loginHint: accountEntity.loginHint,
|
|
4303
|
+
name: accountEntity.name,
|
|
4304
|
+
nativeAccountId: accountEntity.nativeAccountId,
|
|
4305
|
+
authorityType: accountEntity.authorityType,
|
|
4306
|
+
// Deserialize tenant profiles array into a Map
|
|
4307
|
+
tenantProfiles: new Map((accountEntity.tenantProfiles || []).map((tenantProfile) => {
|
|
4308
|
+
return [tenantProfile.tenantId, tenantProfile];
|
|
4309
|
+
})),
|
|
4310
|
+
dataBoundary: accountEntity.dataBoundary,
|
|
4311
|
+
};
|
|
4255
4312
|
}
|
|
4256
4313
|
/**
|
|
4257
|
-
* Returns
|
|
4258
|
-
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
4259
|
-
* @returns Array of AccountInfo objects in cache
|
|
4314
|
+
* Returns true if the account entity is in single tenant format (outdated), false otherwise
|
|
4260
4315
|
*/
|
|
4261
|
-
|
|
4262
|
-
return this.
|
|
4316
|
+
isSingleTenant() {
|
|
4317
|
+
return !this.tenantProfiles;
|
|
4263
4318
|
}
|
|
4264
4319
|
/**
|
|
4265
|
-
*
|
|
4320
|
+
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
4321
|
+
* @param accountDetails
|
|
4266
4322
|
*/
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
return null;
|
|
4323
|
+
static createAccount(accountDetails, authority, base64Decode) {
|
|
4324
|
+
const account = new AccountEntity();
|
|
4325
|
+
if (authority.authorityType === AuthorityType.Adfs) {
|
|
4326
|
+
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
4272
4327
|
}
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
// If one or more accounts are found, prioritize accounts that have an ID token
|
|
4276
|
-
const sortedAccounts = allAccounts.sort((account) => {
|
|
4277
|
-
return account.idTokenClaims ? -1 : 1;
|
|
4278
|
-
});
|
|
4279
|
-
return sortedAccounts[0];
|
|
4328
|
+
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
4329
|
+
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
4280
4330
|
}
|
|
4281
|
-
else
|
|
4282
|
-
|
|
4283
|
-
|
|
4331
|
+
else {
|
|
4332
|
+
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
4333
|
+
}
|
|
4334
|
+
let clientInfo;
|
|
4335
|
+
if (accountDetails.clientInfo && base64Decode) {
|
|
4336
|
+
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
|
|
4337
|
+
if (clientInfo.xms_tdbr) {
|
|
4338
|
+
account.dataBoundary =
|
|
4339
|
+
clientInfo.xms_tdbr === "EU" ? "EU" : "None";
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
account.clientInfo = accountDetails.clientInfo;
|
|
4343
|
+
account.homeAccountId = accountDetails.homeAccountId;
|
|
4344
|
+
account.nativeAccountId = accountDetails.nativeAccountId;
|
|
4345
|
+
const env = accountDetails.environment ||
|
|
4346
|
+
(authority && authority.getPreferredCache());
|
|
4347
|
+
if (!env) {
|
|
4348
|
+
throw createClientAuthError(invalidCacheEnvironment);
|
|
4349
|
+
}
|
|
4350
|
+
account.environment = env;
|
|
4351
|
+
// non AAD scenarios can have empty realm
|
|
4352
|
+
account.realm =
|
|
4353
|
+
clientInfo?.utid ||
|
|
4354
|
+
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
4355
|
+
"";
|
|
4356
|
+
// How do you account for MSA CID here?
|
|
4357
|
+
account.localAccountId =
|
|
4358
|
+
clientInfo?.uid ||
|
|
4359
|
+
accountDetails.idTokenClaims?.oid ||
|
|
4360
|
+
accountDetails.idTokenClaims?.sub ||
|
|
4361
|
+
"";
|
|
4362
|
+
/*
|
|
4363
|
+
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
4364
|
+
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
4365
|
+
* policy is configured to return more than 1 email.
|
|
4366
|
+
*/
|
|
4367
|
+
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
4368
|
+
accountDetails.idTokenClaims?.upn;
|
|
4369
|
+
const email = accountDetails.idTokenClaims?.emails
|
|
4370
|
+
? accountDetails.idTokenClaims.emails[0]
|
|
4371
|
+
: null;
|
|
4372
|
+
account.username = preferredUsername || email || "";
|
|
4373
|
+
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
4374
|
+
account.name = accountDetails.idTokenClaims?.name || "";
|
|
4375
|
+
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
4376
|
+
account.msGraphHost = accountDetails.msGraphHost;
|
|
4377
|
+
if (accountDetails.tenantProfiles) {
|
|
4378
|
+
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
4284
4379
|
}
|
|
4285
4380
|
else {
|
|
4286
|
-
|
|
4381
|
+
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
4382
|
+
account.tenantProfiles = [tenantProfile];
|
|
4287
4383
|
}
|
|
4384
|
+
return account;
|
|
4288
4385
|
}
|
|
4289
4386
|
/**
|
|
4290
|
-
*
|
|
4291
|
-
* @param
|
|
4387
|
+
* Creates an AccountEntity object from AccountInfo
|
|
4388
|
+
* @param accountInfo
|
|
4389
|
+
* @param cloudGraphHostName
|
|
4390
|
+
* @param msGraphHost
|
|
4292
4391
|
* @returns
|
|
4293
4392
|
*/
|
|
4294
|
-
|
|
4295
|
-
const
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4393
|
+
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
|
|
4394
|
+
const account = new AccountEntity();
|
|
4395
|
+
account.authorityType =
|
|
4396
|
+
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
4397
|
+
account.homeAccountId = accountInfo.homeAccountId;
|
|
4398
|
+
account.localAccountId = accountInfo.localAccountId;
|
|
4399
|
+
account.nativeAccountId = accountInfo.nativeAccountId;
|
|
4400
|
+
account.realm = accountInfo.tenantId;
|
|
4401
|
+
account.environment = accountInfo.environment;
|
|
4402
|
+
account.username = accountInfo.username;
|
|
4403
|
+
account.name = accountInfo.name;
|
|
4404
|
+
account.loginHint = accountInfo.loginHint;
|
|
4405
|
+
account.cloudGraphHostName = cloudGraphHostName;
|
|
4406
|
+
account.msGraphHost = msGraphHost;
|
|
4407
|
+
// Serialize tenant profiles map into an array
|
|
4408
|
+
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
|
|
4409
|
+
account.dataBoundary = accountInfo.dataBoundary;
|
|
4410
|
+
return account;
|
|
4302
4411
|
}
|
|
4303
4412
|
/**
|
|
4304
|
-
*
|
|
4305
|
-
*
|
|
4306
|
-
* @param
|
|
4307
|
-
|
|
4413
|
+
* Generate HomeAccountId from server response
|
|
4414
|
+
* @param serverClientInfo
|
|
4415
|
+
* @param authType
|
|
4416
|
+
*/
|
|
4417
|
+
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
|
|
4418
|
+
// since ADFS/DSTS do not have tid and does not set client_info
|
|
4419
|
+
if (!(authType === AuthorityType.Adfs ||
|
|
4420
|
+
authType === AuthorityType.Dsts)) {
|
|
4421
|
+
// for cases where there is clientInfo
|
|
4422
|
+
if (serverClientInfo) {
|
|
4423
|
+
try {
|
|
4424
|
+
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
|
|
4425
|
+
if (clientInfo.uid && clientInfo.utid) {
|
|
4426
|
+
return `${clientInfo.uid}.${clientInfo.utid}`;
|
|
4427
|
+
}
|
|
4428
|
+
}
|
|
4429
|
+
catch (e) { }
|
|
4430
|
+
}
|
|
4431
|
+
logger.warning("No client info in response");
|
|
4432
|
+
}
|
|
4433
|
+
// default to "sub" claim
|
|
4434
|
+
return idTokenClaims?.sub || "";
|
|
4435
|
+
}
|
|
4436
|
+
/**
|
|
4437
|
+
* Validates an entity: checks for all expected params
|
|
4438
|
+
* @param entity
|
|
4439
|
+
*/
|
|
4440
|
+
static isAccountEntity(entity) {
|
|
4441
|
+
if (!entity) {
|
|
4442
|
+
return false;
|
|
4443
|
+
}
|
|
4444
|
+
return (entity.hasOwnProperty("homeAccountId") &&
|
|
4445
|
+
entity.hasOwnProperty("environment") &&
|
|
4446
|
+
entity.hasOwnProperty("realm") &&
|
|
4447
|
+
entity.hasOwnProperty("localAccountId") &&
|
|
4448
|
+
entity.hasOwnProperty("username") &&
|
|
4449
|
+
entity.hasOwnProperty("authorityType"));
|
|
4450
|
+
}
|
|
4451
|
+
/**
|
|
4452
|
+
* Helper function to determine whether 2 accountInfo objects represent the same account
|
|
4453
|
+
* @param accountA
|
|
4454
|
+
* @param accountB
|
|
4455
|
+
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
4456
|
+
*/
|
|
4457
|
+
static accountInfoIsEqual(accountA, accountB, compareClaims) {
|
|
4458
|
+
if (!accountA || !accountB) {
|
|
4459
|
+
return false;
|
|
4460
|
+
}
|
|
4461
|
+
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
|
|
4462
|
+
if (compareClaims) {
|
|
4463
|
+
const accountAClaims = (accountA.idTokenClaims ||
|
|
4464
|
+
{});
|
|
4465
|
+
const accountBClaims = (accountB.idTokenClaims ||
|
|
4466
|
+
{});
|
|
4467
|
+
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
4468
|
+
claimsMatch =
|
|
4469
|
+
accountAClaims.iat === accountBClaims.iat &&
|
|
4470
|
+
accountAClaims.nonce === accountBClaims.nonce;
|
|
4471
|
+
}
|
|
4472
|
+
return (accountA.homeAccountId === accountB.homeAccountId &&
|
|
4473
|
+
accountA.localAccountId === accountB.localAccountId &&
|
|
4474
|
+
accountA.username === accountB.username &&
|
|
4475
|
+
accountA.tenantId === accountB.tenantId &&
|
|
4476
|
+
accountA.loginHint === accountB.loginHint &&
|
|
4477
|
+
accountA.environment === accountB.environment &&
|
|
4478
|
+
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
4479
|
+
claimsMatch);
|
|
4480
|
+
}
|
|
4481
|
+
}
|
|
4482
|
+
|
|
4483
|
+
/*
|
|
4484
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4485
|
+
* Licensed under the MIT License.
|
|
4486
|
+
*/
|
|
4487
|
+
const cacheQuotaExceeded = "cache_quota_exceeded";
|
|
4488
|
+
const cacheErrorUnknown = "cache_error_unknown";
|
|
4489
|
+
|
|
4490
|
+
var CacheErrorCodes = /*#__PURE__*/Object.freeze({
|
|
4491
|
+
__proto__: null,
|
|
4492
|
+
cacheErrorUnknown: cacheErrorUnknown,
|
|
4493
|
+
cacheQuotaExceeded: cacheQuotaExceeded
|
|
4494
|
+
});
|
|
4495
|
+
|
|
4496
|
+
/*
|
|
4497
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4498
|
+
* Licensed under the MIT License.
|
|
4499
|
+
*/
|
|
4500
|
+
const CacheErrorMessages = {
|
|
4501
|
+
[cacheQuotaExceeded]: "Exceeded cache storage capacity.",
|
|
4502
|
+
[cacheErrorUnknown]: "Unexpected error occurred when using cache storage.",
|
|
4503
|
+
};
|
|
4504
|
+
/**
|
|
4505
|
+
* Error thrown when there is an error with the cache
|
|
4506
|
+
*/
|
|
4507
|
+
class CacheError extends AuthError {
|
|
4508
|
+
constructor(errorCode, errorMessage) {
|
|
4509
|
+
const message = errorMessage ||
|
|
4510
|
+
(CacheErrorMessages[errorCode]
|
|
4511
|
+
? CacheErrorMessages[errorCode]
|
|
4512
|
+
: CacheErrorMessages[cacheErrorUnknown]);
|
|
4513
|
+
super(`${errorCode}: ${message}`);
|
|
4514
|
+
Object.setPrototypeOf(this, CacheError.prototype);
|
|
4515
|
+
this.name = "CacheError";
|
|
4516
|
+
this.errorCode = errorCode;
|
|
4517
|
+
this.errorMessage = message;
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
/**
|
|
4521
|
+
* Helper function to wrap browser errors in a CacheError object
|
|
4522
|
+
* @param e
|
|
4523
|
+
* @returns
|
|
4524
|
+
*/
|
|
4525
|
+
function createCacheError(e) {
|
|
4526
|
+
if (!(e instanceof Error)) {
|
|
4527
|
+
return new CacheError(cacheErrorUnknown);
|
|
4528
|
+
}
|
|
4529
|
+
if (e.name === "QuotaExceededError" ||
|
|
4530
|
+
e.name === "NS_ERROR_DOM_QUOTA_REACHED" ||
|
|
4531
|
+
e.message.includes("exceeded the quota")) {
|
|
4532
|
+
return new CacheError(cacheQuotaExceeded);
|
|
4533
|
+
}
|
|
4534
|
+
else {
|
|
4535
|
+
return new CacheError(e.name, e.message);
|
|
4536
|
+
}
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4539
|
+
/*
|
|
4540
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4541
|
+
* Licensed under the MIT License.
|
|
4542
|
+
*/
|
|
4543
|
+
/**
|
|
4544
|
+
* Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
|
|
4545
|
+
* @internal
|
|
4546
|
+
*/
|
|
4547
|
+
class CacheManager {
|
|
4548
|
+
constructor(clientId, cryptoImpl, logger, performanceClient, staticAuthorityOptions) {
|
|
4549
|
+
this.clientId = clientId;
|
|
4550
|
+
this.cryptoImpl = cryptoImpl;
|
|
4551
|
+
this.commonLogger = logger.clone(name, version);
|
|
4552
|
+
this.staticAuthorityOptions = staticAuthorityOptions;
|
|
4553
|
+
this.performanceClient = performanceClient;
|
|
4554
|
+
}
|
|
4555
|
+
/**
|
|
4556
|
+
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
4557
|
+
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
4558
|
+
* @returns Array of AccountInfo objects in cache
|
|
4559
|
+
*/
|
|
4560
|
+
getAllAccounts(accountFilter, correlationId) {
|
|
4561
|
+
return this.buildTenantProfiles(this.getAccountsFilteredBy(accountFilter, correlationId), correlationId, accountFilter);
|
|
4562
|
+
}
|
|
4563
|
+
/**
|
|
4564
|
+
* Gets first tenanted AccountInfo object found based on provided filters
|
|
4565
|
+
*/
|
|
4566
|
+
getAccountInfoFilteredBy(accountFilter, correlationId) {
|
|
4567
|
+
if (Object.keys(accountFilter).length === 0 ||
|
|
4568
|
+
Object.values(accountFilter).every((value) => !value)) {
|
|
4569
|
+
this.commonLogger.warning("getAccountInfoFilteredBy: Account filter is empty or invalid, returning null");
|
|
4570
|
+
return null;
|
|
4571
|
+
}
|
|
4572
|
+
const allAccounts = this.getAllAccounts(accountFilter, correlationId);
|
|
4573
|
+
if (allAccounts.length > 1) {
|
|
4574
|
+
// If one or more accounts are found, prioritize accounts that have an ID token
|
|
4575
|
+
const sortedAccounts = allAccounts.sort((account) => {
|
|
4576
|
+
return account.idTokenClaims ? -1 : 1;
|
|
4577
|
+
});
|
|
4578
|
+
return sortedAccounts[0];
|
|
4579
|
+
}
|
|
4580
|
+
else if (allAccounts.length === 1) {
|
|
4581
|
+
// If only one account is found, return it regardless of whether a matching ID token was found
|
|
4582
|
+
return allAccounts[0];
|
|
4583
|
+
}
|
|
4584
|
+
else {
|
|
4585
|
+
return null;
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
/**
|
|
4589
|
+
* Returns a single matching
|
|
4590
|
+
* @param accountFilter
|
|
4591
|
+
* @returns
|
|
4592
|
+
*/
|
|
4593
|
+
getBaseAccountInfo(accountFilter, correlationId) {
|
|
4594
|
+
const accountEntities = this.getAccountsFilteredBy(accountFilter, correlationId);
|
|
4595
|
+
if (accountEntities.length > 0) {
|
|
4596
|
+
return AccountEntity.getAccountInfo(accountEntities[0]);
|
|
4597
|
+
}
|
|
4598
|
+
else {
|
|
4599
|
+
return null;
|
|
4600
|
+
}
|
|
4601
|
+
}
|
|
4602
|
+
/**
|
|
4603
|
+
* Matches filtered account entities with cached ID tokens that match the tenant profile-specific account filters
|
|
4604
|
+
* and builds the account info objects from the matching ID token's claims
|
|
4605
|
+
* @param cachedAccounts
|
|
4606
|
+
* @param accountFilter
|
|
4308
4607
|
* @returns Array of AccountInfo objects that match account and tenant profile filters
|
|
4309
4608
|
*/
|
|
4310
4609
|
buildTenantProfiles(cachedAccounts, correlationId, accountFilter) {
|
|
@@ -4333,7 +4632,7 @@ class CacheManager {
|
|
|
4333
4632
|
return tenantedAccountInfo;
|
|
4334
4633
|
}
|
|
4335
4634
|
getTenantProfilesFromAccountEntity(accountEntity, correlationId, targetTenantId, tenantProfileFilter) {
|
|
4336
|
-
const accountInfo =
|
|
4635
|
+
const accountInfo = AccountEntity.getAccountInfo(accountEntity);
|
|
4337
4636
|
let searchTenantProfiles = accountInfo.tenantProfiles || new Map();
|
|
4338
4637
|
const tokenKeys = this.getTokenKeys();
|
|
4339
4638
|
// If a tenant ID was provided, only return the tenant profile for that tenant ID if it exists
|
|
@@ -4403,27 +4702,28 @@ class CacheManager {
|
|
|
4403
4702
|
/**
|
|
4404
4703
|
* saves a cache record
|
|
4405
4704
|
* @param cacheRecord {CacheRecord}
|
|
4406
|
-
* @param storeInCache {?StoreInCache}
|
|
4407
4705
|
* @param correlationId {?string} correlation id
|
|
4706
|
+
* @param kmsi - Keep Me Signed In
|
|
4707
|
+
* @param storeInCache {?StoreInCache}
|
|
4408
4708
|
*/
|
|
4409
|
-
async saveCacheRecord(cacheRecord, correlationId, storeInCache) {
|
|
4709
|
+
async saveCacheRecord(cacheRecord, correlationId, kmsi, storeInCache) {
|
|
4410
4710
|
if (!cacheRecord) {
|
|
4411
4711
|
throw createClientAuthError(invalidCacheRecord);
|
|
4412
4712
|
}
|
|
4413
4713
|
try {
|
|
4414
4714
|
if (!!cacheRecord.account) {
|
|
4415
|
-
await this.setAccount(cacheRecord.account, correlationId);
|
|
4715
|
+
await this.setAccount(cacheRecord.account, correlationId, kmsi);
|
|
4416
4716
|
}
|
|
4417
4717
|
if (!!cacheRecord.idToken && storeInCache?.idToken !== false) {
|
|
4418
|
-
await this.setIdTokenCredential(cacheRecord.idToken, correlationId);
|
|
4718
|
+
await this.setIdTokenCredential(cacheRecord.idToken, correlationId, kmsi);
|
|
4419
4719
|
}
|
|
4420
4720
|
if (!!cacheRecord.accessToken &&
|
|
4421
4721
|
storeInCache?.accessToken !== false) {
|
|
4422
|
-
await this.saveAccessToken(cacheRecord.accessToken, correlationId);
|
|
4722
|
+
await this.saveAccessToken(cacheRecord.accessToken, correlationId, kmsi);
|
|
4423
4723
|
}
|
|
4424
4724
|
if (!!cacheRecord.refreshToken &&
|
|
4425
4725
|
storeInCache?.refreshToken !== false) {
|
|
4426
|
-
await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId);
|
|
4726
|
+
await this.setRefreshTokenCredential(cacheRecord.refreshToken, correlationId, kmsi);
|
|
4427
4727
|
}
|
|
4428
4728
|
if (!!cacheRecord.appMetadata) {
|
|
4429
4729
|
this.setAppMetadata(cacheRecord.appMetadata, correlationId);
|
|
@@ -4443,7 +4743,7 @@ class CacheManager {
|
|
|
4443
4743
|
* saves access token credential
|
|
4444
4744
|
* @param credential
|
|
4445
4745
|
*/
|
|
4446
|
-
async saveAccessToken(credential, correlationId) {
|
|
4746
|
+
async saveAccessToken(credential, correlationId, kmsi) {
|
|
4447
4747
|
const accessTokenFilter = {
|
|
4448
4748
|
clientId: credential.clientId,
|
|
4449
4749
|
credentialType: credential.credentialType,
|
|
@@ -4468,7 +4768,7 @@ class CacheManager {
|
|
|
4468
4768
|
}
|
|
4469
4769
|
}
|
|
4470
4770
|
});
|
|
4471
|
-
await this.setAccessTokenCredential(credential, correlationId);
|
|
4771
|
+
await this.setAccessTokenCredential(credential, correlationId, kmsi);
|
|
4472
4772
|
}
|
|
4473
4773
|
/**
|
|
4474
4774
|
* Retrieve account entities matching all provided tenant-agnostic filters; if no filter is set, get all account entities in the cache
|
|
@@ -5528,44 +5828,6 @@ const CcsCredentialType = {
|
|
|
5528
5828
|
UPN: "UPN",
|
|
5529
5829
|
};
|
|
5530
5830
|
|
|
5531
|
-
/*
|
|
5532
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5533
|
-
* Licensed under the MIT License.
|
|
5534
|
-
*/
|
|
5535
|
-
/**
|
|
5536
|
-
* Function to build a client info object from server clientInfo string
|
|
5537
|
-
* @param rawClientInfo
|
|
5538
|
-
* @param crypto
|
|
5539
|
-
*/
|
|
5540
|
-
function buildClientInfo(rawClientInfo, base64Decode) {
|
|
5541
|
-
if (!rawClientInfo) {
|
|
5542
|
-
throw createClientAuthError(clientInfoEmptyError);
|
|
5543
|
-
}
|
|
5544
|
-
try {
|
|
5545
|
-
const decodedClientInfo = base64Decode(rawClientInfo);
|
|
5546
|
-
return JSON.parse(decodedClientInfo);
|
|
5547
|
-
}
|
|
5548
|
-
catch (e) {
|
|
5549
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
5550
|
-
}
|
|
5551
|
-
}
|
|
5552
|
-
/**
|
|
5553
|
-
* Function to build a client info object from cached homeAccountId string
|
|
5554
|
-
* @param homeAccountId
|
|
5555
|
-
*/
|
|
5556
|
-
function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
5557
|
-
if (!homeAccountId) {
|
|
5558
|
-
throw createClientAuthError(clientInfoDecodingError);
|
|
5559
|
-
}
|
|
5560
|
-
const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
|
|
5561
|
-
return {
|
|
5562
|
-
uid: clientInfoParts[0],
|
|
5563
|
-
utid: clientInfoParts.length < 2
|
|
5564
|
-
? Constants.EMPTY_STRING
|
|
5565
|
-
: clientInfoParts[1],
|
|
5566
|
-
};
|
|
5567
|
-
}
|
|
5568
|
-
|
|
5569
5831
|
/*
|
|
5570
5832
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5571
5833
|
* Licensed under the MIT License.
|
|
@@ -6326,240 +6588,6 @@ class BaseClient {
|
|
|
6326
6588
|
}
|
|
6327
6589
|
}
|
|
6328
6590
|
|
|
6329
|
-
/*
|
|
6330
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6331
|
-
* Licensed under the MIT License.
|
|
6332
|
-
*/
|
|
6333
|
-
/**
|
|
6334
|
-
* Gets tenantId from available ID token claims to set as credential realm with the following precedence:
|
|
6335
|
-
* 1. tid - if the token is acquired from an Azure AD tenant tid will be present
|
|
6336
|
-
* 2. tfp - if the token is acquired from a modern B2C tenant tfp should be present
|
|
6337
|
-
* 3. acr - if the token is acquired from a legacy B2C tenant acr should be present
|
|
6338
|
-
* Downcased to match the realm case-insensitive comparison requirements
|
|
6339
|
-
* @param idTokenClaims
|
|
6340
|
-
* @returns
|
|
6341
|
-
*/
|
|
6342
|
-
function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
6343
|
-
if (idTokenClaims) {
|
|
6344
|
-
const tenantId = idTokenClaims.tid || idTokenClaims.tfp || idTokenClaims.acr;
|
|
6345
|
-
return tenantId || null;
|
|
6346
|
-
}
|
|
6347
|
-
return null;
|
|
6348
|
-
}
|
|
6349
|
-
|
|
6350
|
-
/*
|
|
6351
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6352
|
-
* Licensed under the MIT License.
|
|
6353
|
-
*/
|
|
6354
|
-
/**
|
|
6355
|
-
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs).
|
|
6356
|
-
*
|
|
6357
|
-
* Key : Value Schema
|
|
6358
|
-
*
|
|
6359
|
-
* Key: <home_account_id>-<environment>-<realm*>
|
|
6360
|
-
*
|
|
6361
|
-
* Value Schema:
|
|
6362
|
-
* {
|
|
6363
|
-
* homeAccountId: home account identifier for the auth scheme,
|
|
6364
|
-
* environment: entity that issued the token, represented as a full host
|
|
6365
|
-
* realm: Full tenant or organizational identifier that the account belongs to
|
|
6366
|
-
* localAccountId: Original tenant-specific accountID, usually used for legacy cases
|
|
6367
|
-
* username: primary username that represents the user, usually corresponds to preferred_username in the v2 endpt
|
|
6368
|
-
* authorityType: Accounts authority type as a string
|
|
6369
|
-
* name: Full name for the account, including given name and family name,
|
|
6370
|
-
* lastModificationTime: last time this entity was modified in the cache
|
|
6371
|
-
* lastModificationApp:
|
|
6372
|
-
* nativeAccountId: Account identifier on the native device
|
|
6373
|
-
* tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
|
|
6374
|
-
* }
|
|
6375
|
-
* @internal
|
|
6376
|
-
*/
|
|
6377
|
-
class AccountEntity {
|
|
6378
|
-
/**
|
|
6379
|
-
* Returns the AccountInfo interface for this account.
|
|
6380
|
-
*/
|
|
6381
|
-
getAccountInfo() {
|
|
6382
|
-
return {
|
|
6383
|
-
homeAccountId: this.homeAccountId,
|
|
6384
|
-
environment: this.environment,
|
|
6385
|
-
tenantId: this.realm,
|
|
6386
|
-
username: this.username,
|
|
6387
|
-
localAccountId: this.localAccountId,
|
|
6388
|
-
loginHint: this.loginHint,
|
|
6389
|
-
name: this.name,
|
|
6390
|
-
nativeAccountId: this.nativeAccountId,
|
|
6391
|
-
authorityType: this.authorityType,
|
|
6392
|
-
// Deserialize tenant profiles array into a Map
|
|
6393
|
-
tenantProfiles: new Map((this.tenantProfiles || []).map((tenantProfile) => {
|
|
6394
|
-
return [tenantProfile.tenantId, tenantProfile];
|
|
6395
|
-
})),
|
|
6396
|
-
};
|
|
6397
|
-
}
|
|
6398
|
-
/**
|
|
6399
|
-
* Returns true if the account entity is in single tenant format (outdated), false otherwise
|
|
6400
|
-
*/
|
|
6401
|
-
isSingleTenant() {
|
|
6402
|
-
return !this.tenantProfiles;
|
|
6403
|
-
}
|
|
6404
|
-
/**
|
|
6405
|
-
* Build Account cache from IdToken, clientInfo and authority/policy. Associated with AAD.
|
|
6406
|
-
* @param accountDetails
|
|
6407
|
-
*/
|
|
6408
|
-
static createAccount(accountDetails, authority, base64Decode) {
|
|
6409
|
-
const account = new AccountEntity();
|
|
6410
|
-
if (authority.authorityType === AuthorityType.Adfs) {
|
|
6411
|
-
account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
|
|
6412
|
-
}
|
|
6413
|
-
else if (authority.protocolMode === ProtocolMode.OIDC) {
|
|
6414
|
-
account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
6415
|
-
}
|
|
6416
|
-
else {
|
|
6417
|
-
account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
|
|
6418
|
-
}
|
|
6419
|
-
let clientInfo;
|
|
6420
|
-
if (accountDetails.clientInfo && base64Decode) {
|
|
6421
|
-
clientInfo = buildClientInfo(accountDetails.clientInfo, base64Decode);
|
|
6422
|
-
}
|
|
6423
|
-
account.clientInfo = accountDetails.clientInfo;
|
|
6424
|
-
account.homeAccountId = accountDetails.homeAccountId;
|
|
6425
|
-
account.nativeAccountId = accountDetails.nativeAccountId;
|
|
6426
|
-
const env = accountDetails.environment ||
|
|
6427
|
-
(authority && authority.getPreferredCache());
|
|
6428
|
-
if (!env) {
|
|
6429
|
-
throw createClientAuthError(invalidCacheEnvironment);
|
|
6430
|
-
}
|
|
6431
|
-
account.environment = env;
|
|
6432
|
-
// non AAD scenarios can have empty realm
|
|
6433
|
-
account.realm =
|
|
6434
|
-
clientInfo?.utid ||
|
|
6435
|
-
getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
|
|
6436
|
-
"";
|
|
6437
|
-
// How do you account for MSA CID here?
|
|
6438
|
-
account.localAccountId =
|
|
6439
|
-
clientInfo?.uid ||
|
|
6440
|
-
accountDetails.idTokenClaims?.oid ||
|
|
6441
|
-
accountDetails.idTokenClaims?.sub ||
|
|
6442
|
-
"";
|
|
6443
|
-
/*
|
|
6444
|
-
* In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
|
|
6445
|
-
* In most cases it will contain a single email. This field should not be relied upon if a custom
|
|
6446
|
-
* policy is configured to return more than 1 email.
|
|
6447
|
-
*/
|
|
6448
|
-
const preferredUsername = accountDetails.idTokenClaims?.preferred_username ||
|
|
6449
|
-
accountDetails.idTokenClaims?.upn;
|
|
6450
|
-
const email = accountDetails.idTokenClaims?.emails
|
|
6451
|
-
? accountDetails.idTokenClaims.emails[0]
|
|
6452
|
-
: null;
|
|
6453
|
-
account.username = preferredUsername || email || "";
|
|
6454
|
-
account.loginHint = accountDetails.idTokenClaims?.login_hint;
|
|
6455
|
-
account.name = accountDetails.idTokenClaims?.name || "";
|
|
6456
|
-
account.cloudGraphHostName = accountDetails.cloudGraphHostName;
|
|
6457
|
-
account.msGraphHost = accountDetails.msGraphHost;
|
|
6458
|
-
if (accountDetails.tenantProfiles) {
|
|
6459
|
-
account.tenantProfiles = accountDetails.tenantProfiles;
|
|
6460
|
-
}
|
|
6461
|
-
else {
|
|
6462
|
-
const tenantProfile = buildTenantProfile(accountDetails.homeAccountId, account.localAccountId, account.realm, accountDetails.idTokenClaims);
|
|
6463
|
-
account.tenantProfiles = [tenantProfile];
|
|
6464
|
-
}
|
|
6465
|
-
return account;
|
|
6466
|
-
}
|
|
6467
|
-
/**
|
|
6468
|
-
* Creates an AccountEntity object from AccountInfo
|
|
6469
|
-
* @param accountInfo
|
|
6470
|
-
* @param cloudGraphHostName
|
|
6471
|
-
* @param msGraphHost
|
|
6472
|
-
* @returns
|
|
6473
|
-
*/
|
|
6474
|
-
static createFromAccountInfo(accountInfo, cloudGraphHostName, msGraphHost) {
|
|
6475
|
-
const account = new AccountEntity();
|
|
6476
|
-
account.authorityType =
|
|
6477
|
-
accountInfo.authorityType || CacheAccountType.GENERIC_ACCOUNT_TYPE;
|
|
6478
|
-
account.homeAccountId = accountInfo.homeAccountId;
|
|
6479
|
-
account.localAccountId = accountInfo.localAccountId;
|
|
6480
|
-
account.nativeAccountId = accountInfo.nativeAccountId;
|
|
6481
|
-
account.realm = accountInfo.tenantId;
|
|
6482
|
-
account.environment = accountInfo.environment;
|
|
6483
|
-
account.username = accountInfo.username;
|
|
6484
|
-
account.name = accountInfo.name;
|
|
6485
|
-
account.loginHint = accountInfo.loginHint;
|
|
6486
|
-
account.cloudGraphHostName = cloudGraphHostName;
|
|
6487
|
-
account.msGraphHost = msGraphHost;
|
|
6488
|
-
// Serialize tenant profiles map into an array
|
|
6489
|
-
account.tenantProfiles = Array.from(accountInfo.tenantProfiles?.values() || []);
|
|
6490
|
-
return account;
|
|
6491
|
-
}
|
|
6492
|
-
/**
|
|
6493
|
-
* Generate HomeAccountId from server response
|
|
6494
|
-
* @param serverClientInfo
|
|
6495
|
-
* @param authType
|
|
6496
|
-
*/
|
|
6497
|
-
static generateHomeAccountId(serverClientInfo, authType, logger, cryptoObj, idTokenClaims) {
|
|
6498
|
-
// since ADFS/DSTS do not have tid and does not set client_info
|
|
6499
|
-
if (!(authType === AuthorityType.Adfs ||
|
|
6500
|
-
authType === AuthorityType.Dsts)) {
|
|
6501
|
-
// for cases where there is clientInfo
|
|
6502
|
-
if (serverClientInfo) {
|
|
6503
|
-
try {
|
|
6504
|
-
const clientInfo = buildClientInfo(serverClientInfo, cryptoObj.base64Decode);
|
|
6505
|
-
if (clientInfo.uid && clientInfo.utid) {
|
|
6506
|
-
return `${clientInfo.uid}.${clientInfo.utid}`;
|
|
6507
|
-
}
|
|
6508
|
-
}
|
|
6509
|
-
catch (e) { }
|
|
6510
|
-
}
|
|
6511
|
-
logger.warning("No client info in response");
|
|
6512
|
-
}
|
|
6513
|
-
// default to "sub" claim
|
|
6514
|
-
return idTokenClaims?.sub || "";
|
|
6515
|
-
}
|
|
6516
|
-
/**
|
|
6517
|
-
* Validates an entity: checks for all expected params
|
|
6518
|
-
* @param entity
|
|
6519
|
-
*/
|
|
6520
|
-
static isAccountEntity(entity) {
|
|
6521
|
-
if (!entity) {
|
|
6522
|
-
return false;
|
|
6523
|
-
}
|
|
6524
|
-
return (entity.hasOwnProperty("homeAccountId") &&
|
|
6525
|
-
entity.hasOwnProperty("environment") &&
|
|
6526
|
-
entity.hasOwnProperty("realm") &&
|
|
6527
|
-
entity.hasOwnProperty("localAccountId") &&
|
|
6528
|
-
entity.hasOwnProperty("username") &&
|
|
6529
|
-
entity.hasOwnProperty("authorityType"));
|
|
6530
|
-
}
|
|
6531
|
-
/**
|
|
6532
|
-
* Helper function to determine whether 2 accountInfo objects represent the same account
|
|
6533
|
-
* @param accountA
|
|
6534
|
-
* @param accountB
|
|
6535
|
-
* @param compareClaims - If set to true idTokenClaims will also be compared to determine account equality
|
|
6536
|
-
*/
|
|
6537
|
-
static accountInfoIsEqual(accountA, accountB, compareClaims) {
|
|
6538
|
-
if (!accountA || !accountB) {
|
|
6539
|
-
return false;
|
|
6540
|
-
}
|
|
6541
|
-
let claimsMatch = true; // default to true so as to not fail comparison below if compareClaims: false
|
|
6542
|
-
if (compareClaims) {
|
|
6543
|
-
const accountAClaims = (accountA.idTokenClaims ||
|
|
6544
|
-
{});
|
|
6545
|
-
const accountBClaims = (accountB.idTokenClaims ||
|
|
6546
|
-
{});
|
|
6547
|
-
// issued at timestamp and nonce are expected to change each time a new id token is acquired
|
|
6548
|
-
claimsMatch =
|
|
6549
|
-
accountAClaims.iat === accountBClaims.iat &&
|
|
6550
|
-
accountAClaims.nonce === accountBClaims.nonce;
|
|
6551
|
-
}
|
|
6552
|
-
return (accountA.homeAccountId === accountB.homeAccountId &&
|
|
6553
|
-
accountA.localAccountId === accountB.localAccountId &&
|
|
6554
|
-
accountA.username === accountB.username &&
|
|
6555
|
-
accountA.tenantId === accountB.tenantId &&
|
|
6556
|
-
accountA.loginHint === accountB.loginHint &&
|
|
6557
|
-
accountA.environment === accountB.environment &&
|
|
6558
|
-
accountA.nativeAccountId === accountB.nativeAccountId &&
|
|
6559
|
-
claimsMatch);
|
|
6560
|
-
}
|
|
6561
|
-
}
|
|
6562
|
-
|
|
6563
6591
|
/*
|
|
6564
6592
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6565
6593
|
* Licensed under the MIT License.
|
|
@@ -6961,14 +6989,14 @@ class ResponseHandler {
|
|
|
6961
6989
|
if (handlingRefreshTokenResponse &&
|
|
6962
6990
|
!forceCacheRefreshTokenResponse &&
|
|
6963
6991
|
cacheRecord.account) {
|
|
6964
|
-
const key = this.cacheStorage.generateAccountKey(cacheRecord.account
|
|
6992
|
+
const key = this.cacheStorage.generateAccountKey(AccountEntity.getAccountInfo(cacheRecord.account));
|
|
6965
6993
|
const account = this.cacheStorage.getAccount(key, request.correlationId);
|
|
6966
6994
|
if (!account) {
|
|
6967
6995
|
this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
|
|
6968
6996
|
return await ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, undefined, serverRequestId);
|
|
6969
6997
|
}
|
|
6970
6998
|
}
|
|
6971
|
-
await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, request.storeInCache);
|
|
6999
|
+
await this.cacheStorage.saveCacheRecord(cacheRecord, request.correlationId, isKmsi(idTokenClaims || {}), request.storeInCache);
|
|
6972
7000
|
}
|
|
6973
7001
|
finally {
|
|
6974
7002
|
if (this.persistencePlugin &&
|
|
@@ -7115,7 +7143,7 @@ class ResponseHandler {
|
|
|
7115
7143
|
serverTokenResponse?.spa_accountid;
|
|
7116
7144
|
}
|
|
7117
7145
|
const accountInfo = cacheRecord.account
|
|
7118
|
-
? updateAccountTenantProfileData(cacheRecord.account
|
|
7146
|
+
? updateAccountTenantProfileData(AccountEntity.getAccountInfo(cacheRecord.account), undefined, // tenantProfile optional
|
|
7119
7147
|
idTokenClaims, cacheRecord.idToken?.secret)
|
|
7120
7148
|
: null;
|
|
7121
7149
|
return {
|
|
@@ -8402,4 +8430,4 @@ exports.invokeAsync = invokeAsync;
|
|
|
8402
8430
|
exports.tenantIdMatchesHomeTenant = tenantIdMatchesHomeTenant;
|
|
8403
8431
|
exports.updateAccountTenantProfileData = updateAccountTenantProfileData;
|
|
8404
8432
|
exports.version = version;
|
|
8405
|
-
//# sourceMappingURL=index-node-
|
|
8433
|
+
//# sourceMappingURL=index-node-DhUjlPuB.js.map
|