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