@azure/msal-common 14.1.0 → 14.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/account/AuthToken.mjs +1 -1
  2. package/dist/account/CcsCredential.mjs +1 -1
  3. package/dist/account/ClientInfo.mjs +1 -1
  4. package/dist/authority/Authority.d.ts +25 -11
  5. package/dist/authority/Authority.d.ts.map +1 -1
  6. package/dist/authority/Authority.mjs +122 -71
  7. package/dist/authority/Authority.mjs.map +1 -1
  8. package/dist/authority/AuthorityFactory.d.ts.map +1 -1
  9. package/dist/authority/AuthorityFactory.mjs +3 -3
  10. package/dist/authority/AuthorityMetadata.d.ts +23 -0
  11. package/dist/authority/AuthorityMetadata.d.ts.map +1 -1
  12. package/dist/authority/AuthorityMetadata.mjs +58 -2
  13. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  14. package/dist/authority/AuthorityOptions.d.ts +6 -0
  15. package/dist/authority/AuthorityOptions.d.ts.map +1 -1
  16. package/dist/authority/AuthorityOptions.mjs +1 -1
  17. package/dist/authority/AuthorityOptions.mjs.map +1 -1
  18. package/dist/authority/AuthorityType.mjs +1 -1
  19. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  20. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  21. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  22. package/dist/authority/ProtocolMode.mjs +1 -1
  23. package/dist/authority/RegionDiscovery.mjs +1 -1
  24. package/dist/cache/CacheManager.d.ts +17 -1
  25. package/dist/cache/CacheManager.d.ts.map +1 -1
  26. package/dist/cache/CacheManager.mjs +72 -35
  27. package/dist/cache/CacheManager.mjs.map +1 -1
  28. package/dist/cache/entities/AccessTokenEntity.mjs +1 -1
  29. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  30. package/dist/cache/entities/AccountEntity.mjs +1 -3
  31. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  32. package/dist/cache/entities/AppMetadataEntity.mjs +1 -1
  33. package/dist/cache/entities/AuthorityMetadataEntity.mjs +1 -1
  34. package/dist/cache/entities/CacheRecord.mjs +1 -1
  35. package/dist/cache/entities/CredentialEntity.mjs +1 -1
  36. package/dist/cache/entities/IdTokenEntity.mjs +1 -1
  37. package/dist/cache/entities/RefreshTokenEntity.mjs +1 -1
  38. package/dist/cache/entities/ServerTelemetryEntity.mjs +1 -1
  39. package/dist/cache/entities/ThrottlingEntity.mjs +1 -1
  40. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  41. package/dist/cache/utils/CacheTypes.d.ts +1 -0
  42. package/dist/cache/utils/CacheTypes.d.ts.map +1 -1
  43. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  44. package/dist/client/AuthorizationCodeClient.mjs +2 -2
  45. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  46. package/dist/client/BaseClient.d.ts +1 -1
  47. package/dist/client/BaseClient.d.ts.map +1 -1
  48. package/dist/client/BaseClient.mjs +5 -4
  49. package/dist/client/BaseClient.mjs.map +1 -1
  50. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  51. package/dist/client/RefreshTokenClient.mjs +4 -4
  52. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  53. package/dist/client/SilentFlowClient.d.ts +1 -0
  54. package/dist/client/SilentFlowClient.d.ts.map +1 -1
  55. package/dist/client/SilentFlowClient.mjs +20 -27
  56. package/dist/client/SilentFlowClient.mjs.map +1 -1
  57. package/dist/config/ClientConfiguration.mjs +1 -1
  58. package/dist/crypto/ICrypto.mjs +1 -1
  59. package/dist/crypto/JoseHeader.mjs +1 -1
  60. package/dist/crypto/PopTokenGenerator.mjs +1 -1
  61. package/dist/error/AuthError.mjs +1 -1
  62. package/dist/error/AuthErrorCodes.mjs +1 -1
  63. package/dist/error/ClientAuthError.d.ts +5 -0
  64. package/dist/error/ClientAuthError.d.ts.map +1 -1
  65. package/dist/error/ClientAuthError.mjs +7 -2
  66. package/dist/error/ClientAuthError.mjs.map +1 -1
  67. package/dist/error/ClientAuthErrorCodes.d.ts +1 -0
  68. package/dist/error/ClientAuthErrorCodes.d.ts.map +1 -1
  69. package/dist/error/ClientAuthErrorCodes.mjs +3 -2
  70. package/dist/error/ClientAuthErrorCodes.mjs.map +1 -1
  71. package/dist/error/ClientConfigurationError.mjs +1 -1
  72. package/dist/error/ClientConfigurationErrorCodes.mjs +1 -1
  73. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  74. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +1 -1
  75. package/dist/error/JoseHeaderError.mjs +1 -1
  76. package/dist/error/JoseHeaderErrorCodes.mjs +1 -1
  77. package/dist/error/ServerError.mjs +1 -1
  78. package/dist/index.cjs +4455 -4301
  79. package/dist/index.cjs.map +1 -1
  80. package/dist/index.d.ts +2 -2
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.mjs +2 -2
  83. package/dist/logger/Logger.mjs +1 -1
  84. package/dist/network/INetworkModule.mjs +1 -1
  85. package/dist/network/NetworkManager.mjs +1 -1
  86. package/dist/network/ThrottlingUtils.mjs +1 -1
  87. package/dist/packageMetadata.d.ts +1 -1
  88. package/dist/packageMetadata.mjs +2 -2
  89. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  90. package/dist/request/RequestParameterBuilder.mjs +1 -1
  91. package/dist/request/RequestValidator.mjs +1 -1
  92. package/dist/request/ScopeSet.mjs +1 -1
  93. package/dist/response/ResponseHandler.d.ts.map +1 -1
  94. package/dist/response/ResponseHandler.mjs +8 -4
  95. package/dist/response/ResponseHandler.mjs.map +1 -1
  96. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  97. package/dist/telemetry/performance/PerformanceEvent.d.ts +17 -1
  98. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  99. package/dist/telemetry/performance/PerformanceEvent.mjs +9 -2
  100. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  101. package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
  102. package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
  103. package/dist/url/UrlString.mjs +1 -1
  104. package/dist/utils/Constants.mjs +1 -1
  105. package/dist/utils/FunctionWrappers.mjs +1 -1
  106. package/dist/utils/ProtocolUtils.mjs +1 -1
  107. package/dist/utils/StringUtils.mjs +1 -1
  108. package/dist/utils/TimeUtils.mjs +1 -1
  109. package/package.json +1 -1
  110. package/src/authority/Authority.ts +207 -127
  111. package/src/authority/AuthorityFactory.ts +4 -4
  112. package/src/authority/AuthorityMetadata.ts +87 -0
  113. package/src/authority/AuthorityOptions.ts +9 -0
  114. package/src/cache/CacheManager.ts +115 -52
  115. package/src/cache/entities/AccountEntity.ts +0 -3
  116. package/src/cache/utils/CacheTypes.ts +1 -0
  117. package/src/client/AuthorizationCodeClient.ts +9 -2
  118. package/src/client/BaseClient.ts +9 -6
  119. package/src/client/RefreshTokenClient.ts +17 -7
  120. package/src/client/SilentFlowClient.ts +49 -49
  121. package/src/error/ClientAuthError.ts +8 -0
  122. package/src/error/ClientAuthErrorCodes.ts +1 -0
  123. package/src/index.ts +6 -1
  124. package/src/packageMetadata.ts +1 -1
  125. package/src/response/ResponseHandler.ts +9 -3
  126. package/src/telemetry/performance/PerformanceEvent.ts +24 -2
@@ -42,6 +42,12 @@ import { BaseAuthRequest } from "../request/BaseAuthRequest";
42
42
  import { Logger } from "../logger/Logger";
43
43
  import { name, version } from "../packageMetadata";
44
44
  import { StoreInCache } from "../request/StoreInCache";
45
+ import {
46
+ getAliasesFromConfigMetadata,
47
+ getHardcodedAliasesForCanonicalAuthority,
48
+ } from "../authority/AuthorityMetadata";
49
+ import { StaticAuthorityOptions } from "../authority/AuthorityOptions";
50
+ import { TokenClaims } from "../account/TokenClaims";
45
51
 
46
52
  /**
47
53
  * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
@@ -52,11 +58,18 @@ export abstract class CacheManager implements ICacheManager {
52
58
  protected cryptoImpl: ICrypto;
53
59
  // Instance of logger for functions defined in the msal-common layer
54
60
  private commonLogger: Logger;
55
-
56
- constructor(clientId: string, cryptoImpl: ICrypto, logger: Logger) {
61
+ private staticAuthorityOptions?: StaticAuthorityOptions;
62
+
63
+ constructor(
64
+ clientId: string,
65
+ cryptoImpl: ICrypto,
66
+ logger: Logger,
67
+ staticAuthorityOptions?: StaticAuthorityOptions
68
+ ) {
57
69
  this.clientId = clientId;
58
70
  this.cryptoImpl = cryptoImpl;
59
71
  this.commonLogger = logger.clone(name, version);
72
+ this.staticAuthorityOptions = staticAuthorityOptions;
60
73
  }
61
74
 
62
75
  /**
@@ -226,67 +239,93 @@ export abstract class CacheManager implements ICacheManager {
226
239
  * @returns Array of AccountInfo objects in cache
227
240
  */
228
241
  getAllAccounts(accountFilter?: AccountFilter): AccountInfo[] {
229
- if (accountFilter) {
230
- return this.getAccountsFilteredBy(accountFilter).map(
231
- (accountEntity) => {
232
- return accountEntity.getAccountInfo();
233
- }
234
- );
235
- }
236
-
237
- const allAccountKeys = this.getAccountKeys();
238
- if (allAccountKeys.length < 1) {
239
- return [];
240
- }
241
-
242
- const accountEntities: AccountEntity[] = allAccountKeys.reduce(
243
- (accounts: AccountEntity[], key: string) => {
244
- const entity: AccountEntity | null = this.getAccount(key);
245
-
246
- if (!entity) {
247
- return accounts;
242
+ const validAccounts: AccountInfo[] = [];
243
+ this.getAccountsFilteredBy(accountFilter || {}).forEach(
244
+ (accountEntity: AccountEntity) => {
245
+ const accountInfo = this.getAccountInfoFromEntity(
246
+ accountEntity,
247
+ accountFilter
248
+ );
249
+ if (accountInfo) {
250
+ validAccounts.push(accountInfo);
248
251
  }
249
- accounts.push(entity);
250
- return accounts;
251
- },
252
- []
253
- );
254
-
255
- const allAccounts = accountEntities.map<AccountInfo>(
256
- (accountEntity) => {
257
- return this.getAccountInfoFromEntity(accountEntity);
258
252
  }
259
253
  );
260
- return allAccounts;
254
+ return validAccounts;
261
255
  }
262
256
 
263
257
  /**
264
258
  * Gets accountInfo object based on provided filters
265
259
  */
266
260
  getAccountInfoFilteredBy(accountFilter: AccountFilter): AccountInfo | null {
267
- const allAccounts = this.getAccountsFilteredBy(accountFilter);
261
+ const allAccounts = this.getAllAccounts(accountFilter);
268
262
  if (allAccounts.length > 0) {
269
- return this.getAccountInfoFromEntity(allAccounts[0]);
263
+ return allAccounts[0];
264
+ } else {
265
+ return null;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Returns a single matching
271
+ * @param accountFilter
272
+ * @returns
273
+ */
274
+ getBaseAccountInfo(accountFilter: AccountFilter): AccountInfo | null {
275
+ const accountEntities = this.getAccountsFilteredBy(accountFilter);
276
+ if (accountEntities.length > 0) {
277
+ return accountEntities[0].getAccountInfo();
270
278
  } else {
271
279
  return null;
272
280
  }
273
281
  }
274
282
 
275
283
  private getAccountInfoFromEntity(
276
- accountEntity: AccountEntity
277
- ): AccountInfo {
284
+ accountEntity: AccountEntity,
285
+ accountFilter?: AccountFilter
286
+ ): AccountInfo | null {
278
287
  const accountInfo = accountEntity.getAccountInfo();
279
288
  const idToken = this.getIdToken(accountInfo);
280
289
  if (idToken) {
281
- accountInfo.idToken = idToken.secret;
282
- accountInfo.idTokenClaims = extractTokenClaims(
290
+ const idTokenClaims = extractTokenClaims(
283
291
  idToken.secret,
284
292
  this.cryptoImpl.base64Decode
285
293
  );
294
+
295
+ if (
296
+ this.idTokenClaimsMatchAccountFilter(
297
+ idTokenClaims,
298
+ accountFilter
299
+ )
300
+ ) {
301
+ accountInfo.idToken = idToken.secret;
302
+ accountInfo.idTokenClaims = idTokenClaims;
303
+ return accountInfo;
304
+ }
286
305
  }
287
- return accountInfo;
306
+ return null;
288
307
  }
289
308
 
309
+ private idTokenClaimsMatchAccountFilter(
310
+ idTokenClaims: TokenClaims,
311
+ accountFilter?: AccountFilter
312
+ ): boolean {
313
+ if (accountFilter) {
314
+ if (
315
+ !!accountFilter.loginHint &&
316
+ !this.matchLoginHint(idTokenClaims, accountFilter.loginHint)
317
+ ) {
318
+ return false;
319
+ }
320
+ if (
321
+ !!accountFilter.sid &&
322
+ !this.matchSid(idTokenClaims, accountFilter.sid)
323
+ ) {
324
+ return false;
325
+ }
326
+ }
327
+ return true;
328
+ }
290
329
  /**
291
330
  * saves a cache record
292
331
  * @param cacheRecord
@@ -377,7 +416,6 @@ export abstract class CacheManager implements ICacheManager {
377
416
  getAccountsFilteredBy(accountFilter: AccountFilter): AccountEntity[] {
378
417
  const allAccountKeys = this.getAccountKeys();
379
418
  const matchingAccounts: AccountEntity[] = [];
380
-
381
419
  allAccountKeys.forEach((cacheKey) => {
382
420
  if (
383
421
  !this.isAccountKey(
@@ -449,13 +487,6 @@ export abstract class CacheManager implements ICacheManager {
449
487
  return;
450
488
  }
451
489
 
452
- if (
453
- !!accountFilter.loginHint &&
454
- !this.matchLoginHint(entity, accountFilter.loginHint)
455
- ) {
456
- return;
457
- }
458
-
459
490
  if (
460
491
  !!accountFilter.authorityType &&
461
492
  !this.matchAuthorityType(entity, accountFilter.authorityType)
@@ -957,7 +988,6 @@ export abstract class CacheManager implements ICacheManager {
957
988
  ) {
958
989
  return;
959
990
  }
960
-
961
991
  const idToken = this.getIdTokenCredential(key);
962
992
  if (idToken && this.credentialMatchesFilter(idToken, filter)) {
963
993
  idTokens.push(idToken);
@@ -1391,6 +1421,27 @@ export abstract class CacheManager implements ICacheManager {
1391
1421
  entity: AccountEntity | CredentialEntity | AppMetadataEntity,
1392
1422
  environment: string
1393
1423
  ): boolean {
1424
+ // Check static authority options first for cases where authority metadata has not been resolved and cached yet
1425
+ if (this.staticAuthorityOptions) {
1426
+ const staticAliases =
1427
+ getAliasesFromConfigMetadata(
1428
+ this.staticAuthorityOptions.canonicalAuthority,
1429
+ this.staticAuthorityOptions.cloudDiscoveryMetadata
1430
+ ) ||
1431
+ getHardcodedAliasesForCanonicalAuthority(
1432
+ this.staticAuthorityOptions.canonicalAuthority
1433
+ ) ||
1434
+ this.staticAuthorityOptions.knownAuthorities;
1435
+ if (
1436
+ staticAliases &&
1437
+ staticAliases.includes(environment) &&
1438
+ staticAliases.includes(entity.environment)
1439
+ ) {
1440
+ return true;
1441
+ }
1442
+ }
1443
+
1444
+ // Query metadata cache if no static authority configuration has aliases that match enviroment
1394
1445
  const cloudMetadata = this.getAuthorityMetadataByAlias(environment);
1395
1446
  if (
1396
1447
  cloudMetadata &&
@@ -1398,7 +1449,6 @@ export abstract class CacheManager implements ICacheManager {
1398
1449
  ) {
1399
1450
  return true;
1400
1451
  }
1401
-
1402
1452
  return false;
1403
1453
  }
1404
1454
 
@@ -1477,22 +1527,35 @@ export abstract class CacheManager implements ICacheManager {
1477
1527
  * @param loginHint
1478
1528
  * @returns
1479
1529
  */
1480
- private matchLoginHint(entity: AccountEntity, loginHint: string): boolean {
1481
- if (entity.idTokenClaims?.login_hint === loginHint) {
1530
+ private matchLoginHint(
1531
+ idTokenClaims: TokenClaims,
1532
+ loginHint: string
1533
+ ): boolean {
1534
+ if (idTokenClaims?.login_hint === loginHint) {
1482
1535
  return true;
1483
1536
  }
1484
1537
 
1485
- if (entity.username === loginHint) {
1538
+ if (idTokenClaims.preferred_username === loginHint) {
1486
1539
  return true;
1487
1540
  }
1488
1541
 
1489
- if (entity.idTokenClaims?.upn === loginHint) {
1542
+ if (idTokenClaims?.upn === loginHint) {
1490
1543
  return true;
1491
1544
  }
1492
1545
 
1493
1546
  return false;
1494
1547
  }
1495
1548
 
1549
+ /**
1550
+ * Helper to match sid
1551
+ * @param idTokenClaims
1552
+ * @param sid
1553
+ * @returns true if the sid claim is present and matches the filter
1554
+ */
1555
+ private matchSid(idTokenClaims: TokenClaims, sid: string): boolean {
1556
+ return !!(idTokenClaims?.sid && idTokenClaims.sid === sid);
1557
+ }
1558
+
1496
1559
  private matchAuthorityType(
1497
1560
  entity: AccountEntity,
1498
1561
  authorityType: string
@@ -153,8 +153,6 @@ export class AccountEntity {
153
153
  account.realm =
154
154
  accountDetails.idTokenClaims.tid || Constants.EMPTY_STRING;
155
155
 
156
- account.idTokenClaims = accountDetails.idTokenClaims;
157
-
158
156
  // How do you account for MSA CID here?
159
157
  account.localAccountId =
160
158
  accountDetails.idTokenClaims.oid ||
@@ -207,7 +205,6 @@ export class AccountEntity {
207
205
 
208
206
  account.username = accountInfo.username;
209
207
  account.name = accountInfo.name;
210
- account.idTokenClaims = accountInfo.idTokenClaims;
211
208
 
212
209
  account.cloudGraphHostName = cloudGraphHostName;
213
210
  account.msGraphHost = msGraphHost;
@@ -59,6 +59,7 @@ export type AccountFilter = Omit<
59
59
  > & {
60
60
  realm?: string;
61
61
  loginHint?: string;
62
+ sid?: string;
62
63
  };
63
64
 
64
65
  /**
@@ -297,11 +297,18 @@ export class AuthorizationCodeClient extends BaseClient {
297
297
 
298
298
  return invokeAsync(
299
299
  this.executePostToTokenEndpoint.bind(this),
300
- PerformanceEvents.BaseClientExecutePostToTokenEndpoint,
300
+ PerformanceEvents.AuthorizationCodeClientExecutePostToTokenEndpoint,
301
301
  this.logger,
302
302
  this.performanceClient,
303
303
  request.correlationId
304
- )(endpoint, requestBody, headers, thumbprint, request.correlationId);
304
+ )(
305
+ endpoint,
306
+ requestBody,
307
+ headers,
308
+ thumbprint,
309
+ request.correlationId,
310
+ PerformanceEvents.AuthorizationCodeClientExecutePostToTokenEndpoint
311
+ );
305
312
  }
306
313
 
307
314
  /**
@@ -28,7 +28,6 @@ import { buildClientInfoFromHomeAccountId } from "../account/ClientInfo";
28
28
  import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient";
29
29
  import { RequestParameterBuilder } from "../request/RequestParameterBuilder";
30
30
  import { BaseAuthRequest } from "../request/BaseAuthRequest";
31
- import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
32
31
 
33
32
  /**
34
33
  * Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
@@ -144,12 +143,16 @@ export abstract class BaseClient {
144
143
  queryString: string,
145
144
  headers: Record<string, string>,
146
145
  thumbprint: RequestThumbprint,
147
- correlationId: string
146
+ correlationId: string,
147
+ queuedEvent?: string
148
148
  ): Promise<NetworkResponse<ServerAuthorizationTokenResponse>> {
149
- this.performanceClient?.addQueueMeasurement(
150
- PerformanceEvents.BaseClientExecutePostToTokenEndpoint,
151
- correlationId
152
- );
149
+ if (queuedEvent) {
150
+ this.performanceClient?.addQueueMeasurement(
151
+ queuedEvent,
152
+ correlationId
153
+ );
154
+ }
155
+
153
156
  const response =
154
157
  await this.networkManager.sendPostRequest<ServerAuthorizationTokenResponse>(
155
158
  thumbprint,
@@ -46,7 +46,7 @@ import {
46
46
  } from "../error/InteractionRequiredAuthError";
47
47
  import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
48
48
  import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient";
49
- import { invokeAsync } from "../utils/FunctionWrappers";
49
+ import { invoke, invokeAsync } from "../utils/FunctionWrappers";
50
50
  /**
51
51
  * OAuth2.0 refresh token client
52
52
  * @internal
@@ -196,10 +196,13 @@ export class RefreshTokenClient extends BaseClient {
196
196
  );
197
197
 
198
198
  // fetches family RT or application RT based on FOCI value
199
- const refreshToken = this.cacheManager.getRefreshToken(
200
- request.account,
201
- foci
202
- );
199
+ const refreshToken = invoke(
200
+ this.cacheManager.getRefreshToken.bind(this.cacheManager),
201
+ PerformanceEvents.CacheManagerGetRefreshToken,
202
+ this.logger,
203
+ this.performanceClient,
204
+ request.correlationId
205
+ )(request.account, foci);
203
206
 
204
207
  if (!refreshToken) {
205
208
  throw createInteractionRequiredAuthError(
@@ -274,11 +277,18 @@ export class RefreshTokenClient extends BaseClient {
274
277
 
275
278
  return invokeAsync(
276
279
  this.executePostToTokenEndpoint.bind(this),
277
- PerformanceEvents.BaseClientExecutePostToTokenEndpoint,
280
+ PerformanceEvents.RefreshTokenClientExecutePostToTokenEndpoint,
278
281
  this.logger,
279
282
  this.performanceClient,
280
283
  request.correlationId
281
- )(endpoint, requestBody, headers, thumbprint, request.correlationId);
284
+ )(
285
+ endpoint,
286
+ requestBody,
287
+ headers,
288
+ thumbprint,
289
+ request.correlationId,
290
+ PerformanceEvents.RefreshTokenClientExecutePostToTokenEndpoint
291
+ );
282
292
  }
283
293
 
284
294
  /**
@@ -14,10 +14,6 @@ import {
14
14
  ClientAuthErrorCodes,
15
15
  createClientAuthError,
16
16
  } from "../error/ClientAuthError";
17
- import {
18
- createClientConfigurationError,
19
- ClientConfigurationErrorCodes,
20
- } from "../error/ClientConfigurationError";
21
17
  import { ResponseHandler } from "../response/ResponseHandler";
22
18
  import { CacheRecord } from "../cache/entities/CacheRecord";
23
19
  import { CacheOutcome } from "../utils/Constants";
@@ -25,6 +21,8 @@ import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient"
25
21
  import { StringUtils } from "../utils/StringUtils";
26
22
  import { checkMaxAge, extractTokenClaims } from "../account/AuthToken";
27
23
  import { TokenClaims } from "../account/TokenClaims";
24
+ import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
25
+ import { invokeAsync } from "../utils/FunctionWrappers";
28
26
 
29
27
  /** @internal */
30
28
  export class SilentFlowClient extends BaseClient {
@@ -92,35 +90,21 @@ export class SilentFlowClient extends BaseClient {
92
90
  async acquireCachedToken(
93
91
  request: CommonSilentFlowRequest
94
92
  ): Promise<[AuthenticationResult, CacheOutcome]> {
93
+ this.performanceClient?.addQueueMeasurement(
94
+ PerformanceEvents.SilentFlowClientAcquireCachedToken,
95
+ request.correlationId
96
+ );
95
97
  let lastCacheOutcome: CacheOutcome = CacheOutcome.NOT_APPLICABLE;
96
98
 
97
- // Cannot renew token if no request object is given.
98
- if (!request) {
99
- throw createClientConfigurationError(
100
- ClientConfigurationErrorCodes.tokenRequestEmpty
101
- );
102
- }
103
-
104
- if (request.forceRefresh) {
105
- // Must refresh due to present force_refresh flag.
106
- lastCacheOutcome = CacheOutcome.FORCE_REFRESH_OR_CLAIMS;
107
- this.serverTelemetryManager?.setCacheOutcome(
108
- CacheOutcome.FORCE_REFRESH_OR_CLAIMS
109
- );
110
- this.logger.info(
111
- "SilentFlowClient:acquireCachedToken - Skipping cache because forceRefresh is true."
112
- );
113
- throw createClientAuthError(
114
- ClientAuthErrorCodes.tokenRefreshRequired
115
- );
116
- } else if (
117
- !this.config.cacheOptions.claimsBasedCachingEnabled &&
118
- !StringUtils.isEmptyObj(request.claims)
99
+ if (
100
+ request.forceRefresh ||
101
+ (!this.config.cacheOptions.claimsBasedCachingEnabled &&
102
+ !StringUtils.isEmptyObj(request.claims))
119
103
  ) {
120
- lastCacheOutcome = CacheOutcome.FORCE_REFRESH_OR_CLAIMS;
121
- // Must refresh due to request parameters.
122
- this.logger.info(
123
- "SilentFlowClient:acquireCachedToken - Skipping cache because claims-based caching is disabled and claims were requested."
104
+ // Must refresh due to present force_refresh flag.
105
+ this.setCacheOutcome(
106
+ CacheOutcome.FORCE_REFRESH_OR_CLAIMS,
107
+ request.correlationId
124
108
  );
125
109
  throw createClientAuthError(
126
110
  ClientAuthErrorCodes.tokenRefreshRequired
@@ -145,12 +129,9 @@ export class SilentFlowClient extends BaseClient {
145
129
 
146
130
  if (!cacheRecord.accessToken) {
147
131
  // must refresh due to non-existent access_token
148
- lastCacheOutcome = CacheOutcome.NO_CACHED_ACCESS_TOKEN;
149
- this.serverTelemetryManager?.setCacheOutcome(
150
- CacheOutcome.NO_CACHED_ACCESS_TOKEN
151
- );
152
- this.logger.info(
153
- "SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties."
132
+ this.setCacheOutcome(
133
+ CacheOutcome.NO_CACHED_ACCESS_TOKEN,
134
+ request.correlationId
154
135
  );
155
136
  throw createClientAuthError(
156
137
  ClientAuthErrorCodes.tokenRefreshRequired
@@ -163,12 +144,9 @@ export class SilentFlowClient extends BaseClient {
163
144
  )
164
145
  ) {
165
146
  // must refresh due to the expires_in value
166
- lastCacheOutcome = CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED;
167
- this.serverTelemetryManager?.setCacheOutcome(
168
- CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED
169
- );
170
- this.logger.info(
171
- `SilentFlowClient:acquireCachedToken - Cached access token is expired or will expire within ${this.config.systemOptions.tokenRenewalOffsetSeconds} seconds.`
147
+ this.setCacheOutcome(
148
+ CacheOutcome.CACHED_ACCESS_TOKEN_EXPIRED,
149
+ request.correlationId
172
150
  );
173
151
  throw createClientAuthError(
174
152
  ClientAuthErrorCodes.tokenRefreshRequired
@@ -179,26 +157,44 @@ export class SilentFlowClient extends BaseClient {
179
157
  ) {
180
158
  // must refresh (in the background) due to the refresh_in value
181
159
  lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED;
182
- this.serverTelemetryManager?.setCacheOutcome(
183
- CacheOutcome.PROACTIVELY_REFRESHED
184
- );
185
- this.logger.info(
186
- "SilentFlowClient:acquireCachedToken - Cached access token's refreshOn property has been exceeded'."
187
- );
188
160
 
189
161
  // don't throw ClientAuthError.createRefreshRequiredError(), return cached token instead
190
162
  }
191
163
 
164
+ this.setCacheOutcome(lastCacheOutcome, request.correlationId);
165
+
192
166
  if (this.config.serverTelemetryManager) {
193
167
  this.config.serverTelemetryManager.incrementCacheHits();
194
168
  }
195
169
 
196
170
  return [
197
- await this.generateResultFromCacheRecord(cacheRecord, request),
171
+ await invokeAsync(
172
+ this.generateResultFromCacheRecord.bind(this),
173
+ PerformanceEvents.SilentFlowClientGenerateResultFromCacheRecord,
174
+ this.logger,
175
+ this.performanceClient,
176
+ request.correlationId
177
+ )(cacheRecord, request),
198
178
  lastCacheOutcome,
199
179
  ];
200
180
  }
201
181
 
182
+ private setCacheOutcome(
183
+ cacheOutcome: CacheOutcome,
184
+ correlationId: string
185
+ ): void {
186
+ this.serverTelemetryManager?.setCacheOutcome(cacheOutcome);
187
+ this.performanceClient?.addFields(
188
+ {
189
+ cacheOutcome: cacheOutcome,
190
+ },
191
+ correlationId
192
+ );
193
+ this.logger.info(
194
+ `Token refresh is required due to cache outcome: ${cacheOutcome}`
195
+ );
196
+ }
197
+
202
198
  /**
203
199
  * Helper function to build response object from the CacheRecord
204
200
  * @param cacheRecord
@@ -207,6 +203,10 @@ export class SilentFlowClient extends BaseClient {
207
203
  cacheRecord: CacheRecord,
208
204
  request: CommonSilentFlowRequest
209
205
  ): Promise<AuthenticationResult> {
206
+ this.performanceClient?.addQueueMeasurement(
207
+ PerformanceEvents.SilentFlowClientGenerateResultFromCacheRecord,
208
+ request.correlationId
209
+ );
210
210
  let idTokenClaims: TokenClaims | undefined;
211
211
  if (cacheRecord.idToken) {
212
212
  idTokenClaims = extractTokenClaims(
@@ -89,6 +89,8 @@ export const ClientAuthErrorMessages = {
89
89
  "A tenant id - not common, organizations, or consumers - must be specified when using the client_credentials flow.",
90
90
  [ClientAuthErrorCodes.methodNotImplemented]:
91
91
  "This method has not been implemented",
92
+ [ClientAuthErrorCodes.nestedAppAuthBridgeDisabled]:
93
+ "The nested app auth bridge is disabled",
92
94
  };
93
95
 
94
96
  /**
@@ -306,6 +308,12 @@ export const ClientAuthErrorMessage = {
306
308
  ClientAuthErrorCodes.missingTenantIdError
307
309
  ],
308
310
  },
311
+ nestedAppAuthBridgeDisabled: {
312
+ code: ClientAuthErrorCodes.nestedAppAuthBridgeDisabled,
313
+ desc: ClientAuthErrorMessages[
314
+ ClientAuthErrorCodes.nestedAppAuthBridgeDisabled
315
+ ],
316
+ },
309
317
  };
310
318
 
311
319
  /**
@@ -49,3 +49,4 @@ export const noNetworkConnectivity = "no_network_connectivity";
49
49
  export const userCanceled = "user_canceled";
50
50
  export const missingTenantIdError = "missing_tenant_id_error";
51
51
  export const methodNotImplemented = "method_not_implemented";
52
+ export const nestedAppAuthBridgeDisabled = "nested_app_auth_bridge_disabled";
package/src/index.ts CHANGED
@@ -39,10 +39,15 @@ export {
39
39
  buildClientInfoFromHomeAccountId,
40
40
  } from "./account/ClientInfo";
41
41
  // Authority
42
- export { Authority } from "./authority/Authority";
42
+ export {
43
+ Authority,
44
+ formatAuthorityUri,
45
+ buildStaticAuthorityOptions,
46
+ } from "./authority/Authority";
43
47
  export {
44
48
  AuthorityOptions,
45
49
  AzureCloudInstance,
50
+ StaticAuthorityOptions,
46
51
  } from "./authority/AuthorityOptions";
47
52
  export { AuthorityFactory } from "./authority/AuthorityFactory";
48
53
  export { AuthorityType } from "./authority/AuthorityType";
@@ -1,3 +1,3 @@
1
1
  /* eslint-disable header/header */
2
2
  export const name = "@azure/msal-common";
3
- export const version = "14.1.0";
3
+ export const version = "14.2.0";
@@ -44,6 +44,7 @@ import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient"
44
44
  import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
45
45
  import { checkMaxAge, extractTokenClaims } from "../account/AuthToken";
46
46
  import { TokenClaims } from "../account/TokenClaims";
47
+ import { AccountInfo } from "../account/AccountInfo";
47
48
 
48
49
  /**
49
50
  * Class that handles response parsing.
@@ -599,14 +600,19 @@ export class ResponseHandler {
599
600
  serverTokenResponse?.spa_accountid;
600
601
  }
601
602
 
603
+ const accountInfo: AccountInfo | null = cacheRecord.account
604
+ ? {
605
+ ...cacheRecord.account.getAccountInfo(),
606
+ idTokenClaims,
607
+ }
608
+ : null;
609
+
602
610
  return {
603
611
  authority: authority.canonicalAuthority,
604
612
  uniqueId: uid,
605
613
  tenantId: tid,
606
614
  scopes: responseScopes,
607
- account: cacheRecord.account
608
- ? cacheRecord.account.getAccountInfo()
609
- : null,
615
+ account: accountInfo,
610
616
  idToken: cacheRecord?.idToken?.secret || "",
611
617
  idTokenClaims: idTokenClaims || {},
612
618
  accessToken: accessToken,