@azure/msal-common 14.4.1-beta.1 → 14.6.0-alpha.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 (209) hide show
  1. package/dist/account/AccountInfo.d.ts +27 -0
  2. package/dist/account/AccountInfo.d.ts.map +1 -1
  3. package/dist/account/AccountInfo.mjs +64 -0
  4. package/dist/account/AccountInfo.mjs.map +1 -0
  5. package/dist/account/AuthToken.mjs +1 -1
  6. package/dist/account/AuthToken.mjs.map +1 -1
  7. package/dist/account/CcsCredential.mjs +1 -1
  8. package/dist/account/CcsCredential.mjs.map +1 -1
  9. package/dist/account/ClientInfo.d.ts +1 -2
  10. package/dist/account/ClientInfo.d.ts.map +1 -1
  11. package/dist/account/ClientInfo.mjs +3 -3
  12. package/dist/account/ClientInfo.mjs.map +1 -1
  13. package/dist/account/TokenClaims.d.ts +18 -0
  14. package/dist/account/TokenClaims.d.ts.map +1 -1
  15. package/dist/account/TokenClaims.mjs +25 -0
  16. package/dist/account/TokenClaims.mjs.map +1 -0
  17. package/dist/authority/Authority.d.ts +7 -2
  18. package/dist/authority/Authority.d.ts.map +1 -1
  19. package/dist/authority/Authority.mjs +34 -7
  20. package/dist/authority/Authority.mjs.map +1 -1
  21. package/dist/authority/AuthorityFactory.mjs +1 -1
  22. package/dist/authority/AuthorityFactory.mjs.map +1 -1
  23. package/dist/authority/AuthorityMetadata.mjs +1 -1
  24. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  25. package/dist/authority/AuthorityOptions.mjs +1 -1
  26. package/dist/authority/AuthorityOptions.mjs.map +1 -1
  27. package/dist/authority/AuthorityType.mjs +1 -1
  28. package/dist/authority/AuthorityType.mjs.map +1 -1
  29. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  30. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs.map +1 -1
  31. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  32. package/dist/authority/CloudInstanceDiscoveryResponse.mjs.map +1 -1
  33. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  34. package/dist/authority/OpenIdConfigResponse.mjs.map +1 -1
  35. package/dist/authority/ProtocolMode.mjs +1 -1
  36. package/dist/authority/ProtocolMode.mjs.map +1 -1
  37. package/dist/authority/RegionDiscovery.mjs +1 -1
  38. package/dist/authority/RegionDiscovery.mjs.map +1 -1
  39. package/dist/cache/CacheManager.d.ts +50 -27
  40. package/dist/cache/CacheManager.d.ts.map +1 -1
  41. package/dist/cache/CacheManager.mjs +243 -107
  42. package/dist/cache/CacheManager.mjs.map +1 -1
  43. package/dist/cache/entities/AccountEntity.d.ts +9 -4
  44. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  45. package/dist/cache/entities/AccountEntity.mjs +56 -28
  46. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  47. package/dist/cache/entities/AppMetadataEntity.mjs +1 -1
  48. package/dist/cache/entities/AppMetadataEntity.mjs.map +1 -1
  49. package/dist/cache/entities/AuthorityMetadataEntity.mjs +1 -1
  50. package/dist/cache/entities/AuthorityMetadataEntity.mjs.map +1 -1
  51. package/dist/cache/entities/CacheRecord.mjs +1 -1
  52. package/dist/cache/entities/CacheRecord.mjs.map +1 -1
  53. package/dist/cache/entities/ThrottlingEntity.d.ts +2 -8
  54. package/dist/cache/entities/ThrottlingEntity.d.ts.map +1 -1
  55. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  56. package/dist/cache/persistence/TokenCacheContext.mjs.map +1 -1
  57. package/dist/cache/utils/CacheHelpers.d.ts +7 -1
  58. package/dist/cache/utils/CacheHelpers.d.ts.map +1 -1
  59. package/dist/cache/utils/CacheHelpers.mjs +20 -4
  60. package/dist/cache/utils/CacheHelpers.mjs.map +1 -1
  61. package/dist/cache/utils/CacheTypes.d.ts +2 -0
  62. package/dist/cache/utils/CacheTypes.d.ts.map +1 -1
  63. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  64. package/dist/client/AuthorizationCodeClient.mjs +10 -9
  65. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  66. package/dist/client/BaseClient.mjs +1 -1
  67. package/dist/client/BaseClient.mjs.map +1 -1
  68. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  69. package/dist/client/RefreshTokenClient.mjs +25 -11
  70. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  71. package/dist/client/SilentFlowClient.d.ts.map +1 -1
  72. package/dist/client/SilentFlowClient.mjs +20 -9
  73. package/dist/client/SilentFlowClient.mjs.map +1 -1
  74. package/dist/config/ClientConfiguration.d.ts.map +1 -1
  75. package/dist/config/ClientConfiguration.mjs +2 -4
  76. package/dist/config/ClientConfiguration.mjs.map +1 -1
  77. package/dist/constants/AADServerParamKeys.d.ts +53 -0
  78. package/dist/constants/AADServerParamKeys.d.ts.map +1 -0
  79. package/dist/constants/AADServerParamKeys.mjs +61 -0
  80. package/dist/constants/AADServerParamKeys.mjs.map +1 -0
  81. package/dist/crypto/ICrypto.mjs +1 -1
  82. package/dist/crypto/ICrypto.mjs.map +1 -1
  83. package/dist/crypto/JoseHeader.mjs +1 -1
  84. package/dist/crypto/JoseHeader.mjs.map +1 -1
  85. package/dist/crypto/PopTokenGenerator.mjs +2 -2
  86. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  87. package/dist/error/AuthError.mjs +1 -1
  88. package/dist/error/AuthError.mjs.map +1 -1
  89. package/dist/error/AuthErrorCodes.mjs +1 -1
  90. package/dist/error/AuthErrorCodes.mjs.map +1 -1
  91. package/dist/error/ClientAuthError.mjs +1 -1
  92. package/dist/error/ClientAuthError.mjs.map +1 -1
  93. package/dist/error/ClientAuthErrorCodes.mjs +1 -1
  94. package/dist/error/ClientAuthErrorCodes.mjs.map +1 -1
  95. package/dist/error/ClientConfigurationError.mjs +1 -1
  96. package/dist/error/ClientConfigurationError.mjs.map +1 -1
  97. package/dist/error/ClientConfigurationErrorCodes.mjs +1 -1
  98. package/dist/error/ClientConfigurationErrorCodes.mjs.map +1 -1
  99. package/dist/error/InteractionRequiredAuthError.d.ts +4 -0
  100. package/dist/error/InteractionRequiredAuthError.d.ts.map +1 -1
  101. package/dist/error/InteractionRequiredAuthError.mjs +10 -3
  102. package/dist/error/InteractionRequiredAuthError.mjs.map +1 -1
  103. package/dist/error/InteractionRequiredAuthErrorCodes.d.ts +1 -0
  104. package/dist/error/InteractionRequiredAuthErrorCodes.d.ts.map +1 -1
  105. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +4 -3
  106. package/dist/error/InteractionRequiredAuthErrorCodes.mjs.map +1 -1
  107. package/dist/error/JoseHeaderError.mjs +1 -1
  108. package/dist/error/JoseHeaderError.mjs.map +1 -1
  109. package/dist/error/JoseHeaderErrorCodes.mjs +1 -1
  110. package/dist/error/JoseHeaderErrorCodes.mjs.map +1 -1
  111. package/dist/error/ServerError.mjs +1 -1
  112. package/dist/error/ServerError.mjs.map +1 -1
  113. package/dist/index.cjs +797 -416
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.d.ts +5 -4
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.mjs +7 -4
  118. package/dist/index.mjs.map +1 -1
  119. package/dist/logger/Logger.mjs +1 -1
  120. package/dist/logger/Logger.mjs.map +1 -1
  121. package/dist/network/INetworkModule.mjs +1 -1
  122. package/dist/network/INetworkModule.mjs.map +1 -1
  123. package/dist/network/NetworkManager.mjs +1 -1
  124. package/dist/network/NetworkManager.mjs.map +1 -1
  125. package/dist/network/ThrottlingUtils.mjs +1 -1
  126. package/dist/network/ThrottlingUtils.mjs.map +1 -1
  127. package/dist/packageMetadata.d.ts +1 -1
  128. package/dist/packageMetadata.d.ts.map +1 -1
  129. package/dist/packageMetadata.mjs +2 -2
  130. package/dist/packageMetadata.mjs.map +1 -1
  131. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  132. package/dist/request/AuthenticationHeaderParser.mjs.map +1 -1
  133. package/dist/request/CommonRefreshTokenRequest.d.ts +0 -1
  134. package/dist/request/CommonRefreshTokenRequest.d.ts.map +1 -1
  135. package/dist/request/CommonSilentFlowRequest.d.ts +7 -1
  136. package/dist/request/CommonSilentFlowRequest.d.ts.map +1 -1
  137. package/dist/request/RequestParameterBuilder.d.ts.map +1 -1
  138. package/dist/request/RequestParameterBuilder.mjs +46 -45
  139. package/dist/request/RequestParameterBuilder.mjs.map +1 -1
  140. package/dist/request/RequestValidator.mjs +1 -1
  141. package/dist/request/RequestValidator.mjs.map +1 -1
  142. package/dist/request/ScopeSet.mjs +1 -1
  143. package/dist/request/ScopeSet.mjs.map +1 -1
  144. package/dist/response/ResponseHandler.d.ts +3 -1
  145. package/dist/response/ResponseHandler.d.ts.map +1 -1
  146. package/dist/response/ResponseHandler.mjs +56 -20
  147. package/dist/response/ResponseHandler.mjs.map +1 -1
  148. package/dist/response/ServerAuthorizationTokenResponse.d.ts +1 -0
  149. package/dist/response/ServerAuthorizationTokenResponse.d.ts.map +1 -1
  150. package/dist/telemetry/performance/IPerformanceClient.d.ts +6 -0
  151. package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
  152. package/dist/telemetry/performance/PerformanceClient.d.ts +9 -2
  153. package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
  154. package/dist/telemetry/performance/PerformanceClient.mjs +17 -13
  155. package/dist/telemetry/performance/PerformanceClient.mjs.map +1 -1
  156. package/dist/telemetry/performance/PerformanceEvent.mjs +1 -1
  157. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  158. package/dist/telemetry/performance/StubPerformanceClient.d.ts.map +1 -1
  159. package/dist/telemetry/performance/StubPerformanceClient.mjs +1 -1
  160. package/dist/telemetry/performance/StubPerformanceClient.mjs.map +1 -1
  161. package/dist/telemetry/server/ServerTelemetryManager.mjs +1 -1
  162. package/dist/telemetry/server/ServerTelemetryManager.mjs.map +1 -1
  163. package/dist/url/UrlString.mjs +1 -1
  164. package/dist/url/UrlString.mjs.map +1 -1
  165. package/dist/utils/Constants.d.ts +2 -69
  166. package/dist/utils/Constants.d.ts.map +1 -1
  167. package/dist/utils/Constants.mjs +6 -70
  168. package/dist/utils/Constants.mjs.map +1 -1
  169. package/dist/utils/FunctionWrappers.mjs +1 -1
  170. package/dist/utils/FunctionWrappers.mjs.map +1 -1
  171. package/dist/utils/ProtocolUtils.mjs +1 -1
  172. package/dist/utils/ProtocolUtils.mjs.map +1 -1
  173. package/dist/utils/StringUtils.mjs +1 -1
  174. package/dist/utils/StringUtils.mjs.map +1 -1
  175. package/dist/utils/TimeUtils.mjs +1 -1
  176. package/dist/utils/TimeUtils.mjs.map +1 -1
  177. package/dist/utils/UrlUtils.mjs +1 -1
  178. package/dist/utils/UrlUtils.mjs.map +1 -1
  179. package/package.json +93 -92
  180. package/src/account/AccountInfo.ts +96 -0
  181. package/src/account/ClientInfo.ts +2 -3
  182. package/src/account/TokenClaims.ts +28 -0
  183. package/src/authority/Authority.ts +38 -5
  184. package/src/cache/CacheManager.ts +410 -162
  185. package/src/cache/entities/AccountEntity.ts +84 -33
  186. package/src/cache/entities/ThrottlingEntity.ts +2 -24
  187. package/src/cache/utils/CacheHelpers.ts +22 -2
  188. package/src/cache/utils/CacheTypes.ts +11 -0
  189. package/src/client/AuthorizationCodeClient.ts +4 -5
  190. package/src/client/RefreshTokenClient.ts +35 -14
  191. package/src/client/SilentFlowClient.ts +31 -11
  192. package/src/config/ClientConfiguration.ts +4 -4
  193. package/src/constants/AADServerParamKeys.ts +57 -0
  194. package/src/crypto/PopTokenGenerator.ts +1 -1
  195. package/src/error/InteractionRequiredAuthError.ts +12 -2
  196. package/src/error/InteractionRequiredAuthErrorCodes.ts +1 -0
  197. package/src/index.ts +18 -5
  198. package/src/packageMetadata.ts +1 -1
  199. package/src/request/CommonRefreshTokenRequest.ts +0 -1
  200. package/src/request/CommonSilentFlowRequest.ts +7 -1
  201. package/src/request/RequestParameterBuilder.ts +7 -5
  202. package/src/response/ResponseHandler.ts +109 -25
  203. package/src/response/ServerAuthorizationTokenResponse.ts +1 -0
  204. package/src/telemetry/performance/IPerformanceClient.ts +6 -0
  205. package/src/telemetry/performance/PerformanceClient.ts +24 -31
  206. package/src/telemetry/performance/StubPerformanceClient.ts +0 -1
  207. package/src/utils/Constants.ts +4 -72
  208. package/dist/cache/entities/ThrottlingEntity.mjs +0 -30
  209. package/dist/cache/entities/ThrottlingEntity.mjs.map +0 -1
@@ -3,18 +3,25 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { Separators, CacheAccountType, Constants } from "../../utils/Constants";
6
+ import { CacheAccountType, Separators } from "../../utils/Constants";
7
7
  import { Authority } from "../../authority/Authority";
8
8
  import { ICrypto } from "../../crypto/ICrypto";
9
- import { buildClientInfo } from "../../account/ClientInfo";
10
- import { AccountInfo } from "../../account/AccountInfo";
9
+ import { ClientInfo, buildClientInfo } from "../../account/ClientInfo";
10
+ import {
11
+ AccountInfo,
12
+ TenantProfile,
13
+ buildTenantProfileFromIdTokenClaims,
14
+ } from "../../account/AccountInfo";
11
15
  import {
12
16
  createClientAuthError,
13
17
  ClientAuthErrorCodes,
14
18
  } from "../../error/ClientAuthError";
15
19
  import { AuthorityType } from "../../authority/AuthorityType";
16
20
  import { Logger } from "../../logger/Logger";
17
- import { TokenClaims } from "../../account/TokenClaims";
21
+ import {
22
+ TokenClaims,
23
+ getTenantIdFromIdTokenClaims,
24
+ } from "../../account/TokenClaims";
18
25
  import { ProtocolMode } from "../../authority/ProtocolMode";
19
26
 
20
27
  /**
@@ -35,8 +42,8 @@ import { ProtocolMode } from "../../authority/ProtocolMode";
35
42
  * name: Full name for the account, including given name and family name,
36
43
  * lastModificationTime: last time this entity was modified in the cache
37
44
  * lastModificationApp:
38
- * idTokenClaims: Object containing claims parsed from ID token
39
45
  * nativeAccountId: Account identifier on the native device
46
+ * tenantProfiles: Array of tenant profile objects for each tenant that the account has authenticated with in the browser
40
47
  * }
41
48
  * @internal
42
49
  */
@@ -53,8 +60,8 @@ export class AccountEntity {
53
60
  lastModificationApp?: string;
54
61
  cloudGraphHostName?: string;
55
62
  msGraphHost?: string;
56
- idTokenClaims?: TokenClaims;
57
63
  nativeAccountId?: string;
64
+ tenantProfiles?: Array<TenantProfile>;
58
65
 
59
66
  /**
60
67
  * Generate Account Id key component as per the schema: <home_account_id>-<environment>
@@ -88,21 +95,34 @@ export class AccountEntity {
88
95
  username: this.username,
89
96
  localAccountId: this.localAccountId,
90
97
  name: this.name,
91
- idTokenClaims: this.idTokenClaims,
92
98
  nativeAccountId: this.nativeAccountId,
93
99
  authorityType: this.authorityType,
100
+ // Deserialize tenant profiles array into a Map
101
+ tenantProfiles: new Map(
102
+ (this.tenantProfiles || []).map((tenantProfile) => {
103
+ return [tenantProfile.tenantId, tenantProfile];
104
+ })
105
+ ),
94
106
  };
95
107
  }
96
108
 
109
+ /**
110
+ * Returns true if the account entity is in single tenant format (outdated), false otherwise
111
+ */
112
+ isSingleTenant(): boolean {
113
+ return !this.tenantProfiles;
114
+ }
115
+
97
116
  /**
98
117
  * Generates account key from interface
99
118
  * @param accountInterface
100
119
  */
101
120
  static generateAccountCacheKey(accountInterface: AccountInfo): string {
121
+ const homeTenantId = accountInterface.homeAccountId.split(".")[1];
102
122
  const accountKey = [
103
123
  accountInterface.homeAccountId,
104
- accountInterface.environment || Constants.EMPTY_STRING,
105
- accountInterface.tenantId || Constants.EMPTY_STRING,
124
+ accountInterface.environment || "",
125
+ homeTenantId || accountInterface.tenantId || "",
106
126
  ];
107
127
 
108
128
  return accountKey.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
@@ -121,8 +141,10 @@ export class AccountEntity {
121
141
  msGraphHost?: string;
122
142
  environment?: string;
123
143
  nativeAccountId?: string;
144
+ tenantProfiles?: Array<TenantProfile>;
124
145
  },
125
- authority: Authority
146
+ authority: Authority,
147
+ base64Decode?: (input: string) => string
126
148
  ): AccountEntity {
127
149
  const account: AccountEntity = new AccountEntity();
128
150
 
@@ -134,6 +156,15 @@ export class AccountEntity {
134
156
  account.authorityType = CacheAccountType.GENERIC_ACCOUNT_TYPE;
135
157
  }
136
158
 
159
+ let clientInfo: ClientInfo | undefined;
160
+
161
+ if (accountDetails.clientInfo && base64Decode) {
162
+ clientInfo = buildClientInfo(
163
+ accountDetails.clientInfo,
164
+ base64Decode
165
+ );
166
+ }
167
+
137
168
  account.clientInfo = accountDetails.clientInfo;
138
169
  account.homeAccountId = accountDetails.homeAccountId;
139
170
  account.nativeAccountId = accountDetails.nativeAccountId;
@@ -151,13 +182,16 @@ export class AccountEntity {
151
182
  account.environment = env;
152
183
  // non AAD scenarios can have empty realm
153
184
  account.realm =
154
- accountDetails.idTokenClaims.tid || Constants.EMPTY_STRING;
185
+ clientInfo?.utid ||
186
+ getTenantIdFromIdTokenClaims(accountDetails.idTokenClaims) ||
187
+ "";
155
188
 
156
189
  // How do you account for MSA CID here?
157
190
  account.localAccountId =
191
+ clientInfo?.uid ||
158
192
  accountDetails.idTokenClaims.oid ||
159
193
  accountDetails.idTokenClaims.sub ||
160
- Constants.EMPTY_STRING;
194
+ "";
161
195
 
162
196
  /*
163
197
  * In B2C scenarios the emails claim is used instead of preferred_username and it is an array.
@@ -171,12 +205,26 @@ export class AccountEntity {
171
205
  ? accountDetails.idTokenClaims.emails[0]
172
206
  : null;
173
207
 
174
- account.username = preferredUsername || email || Constants.EMPTY_STRING;
208
+ account.username = preferredUsername || email || "";
175
209
  account.name = accountDetails.idTokenClaims.name;
176
210
 
177
211
  account.cloudGraphHostName = accountDetails.cloudGraphHostName;
178
212
  account.msGraphHost = accountDetails.msGraphHost;
179
213
 
214
+ if (accountDetails.tenantProfiles) {
215
+ account.tenantProfiles = accountDetails.tenantProfiles;
216
+ } else {
217
+ const tenantProfiles = [];
218
+ if (accountDetails.idTokenClaims) {
219
+ const tenantProfile = buildTenantProfileFromIdTokenClaims(
220
+ accountDetails.homeAccountId,
221
+ accountDetails.idTokenClaims
222
+ );
223
+ tenantProfiles.push(tenantProfile);
224
+ }
225
+ account.tenantProfiles = tenantProfiles;
226
+ }
227
+
180
228
  return account;
181
229
  }
182
230
 
@@ -208,6 +256,10 @@ export class AccountEntity {
208
256
 
209
257
  account.cloudGraphHostName = cloudGraphHostName;
210
258
  account.msGraphHost = msGraphHost;
259
+ // Serialize tenant profiles map into an array
260
+ account.tenantProfiles = Array.from(
261
+ accountInfo.tenantProfiles?.values() || []
262
+ );
211
263
 
212
264
  return account;
213
265
  }
@@ -224,31 +276,30 @@ export class AccountEntity {
224
276
  cryptoObj: ICrypto,
225
277
  idTokenClaims?: TokenClaims
226
278
  ): string {
227
- const accountId = idTokenClaims?.sub
228
- ? idTokenClaims.sub
229
- : Constants.EMPTY_STRING;
230
-
231
- // since ADFS does not have tid and does not set client_info
279
+ // since ADFS/DSTS do not have tid and does not set client_info
232
280
  if (
233
- authType === AuthorityType.Adfs ||
234
- authType === AuthorityType.Dsts
281
+ !(
282
+ authType === AuthorityType.Adfs ||
283
+ authType === AuthorityType.Dsts
284
+ )
235
285
  ) {
236
- return accountId;
237
- }
238
-
239
- // for cases where there is clientInfo
240
- if (serverClientInfo) {
241
- try {
242
- const clientInfo = buildClientInfo(serverClientInfo, cryptoObj);
243
- if (clientInfo.uid && clientInfo.utid) {
244
- return `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`;
245
- }
246
- } catch (e) {}
286
+ // for cases where there is clientInfo
287
+ if (serverClientInfo) {
288
+ try {
289
+ const clientInfo = buildClientInfo(
290
+ serverClientInfo,
291
+ cryptoObj.base64Decode
292
+ );
293
+ if (clientInfo.uid && clientInfo.utid) {
294
+ return `${clientInfo.uid}.${clientInfo.utid}`;
295
+ }
296
+ } catch (e) {}
297
+ }
298
+ logger.warning("No client info in response");
247
299
  }
248
300
 
249
301
  // default to "sub" claim
250
- logger.verbose("No client info in response");
251
- return accountId;
302
+ return idTokenClaims?.sub || "";
252
303
  }
253
304
 
254
305
  /**
@@ -3,9 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ThrottlingConstants } from "../../utils/Constants";
7
-
8
- export class ThrottlingEntity {
6
+ export type ThrottlingEntity = {
9
7
  // Unix-time value representing the expiration of the throttle
10
8
  throttleTime: number;
11
9
  // Information provided by the server
@@ -13,24 +11,4 @@ export class ThrottlingEntity {
13
11
  errorCodes?: Array<string>;
14
12
  errorMessage?: string;
15
13
  subError?: string;
16
-
17
- /**
18
- * validates if a given cache entry is "Throttling", parses <key,value>
19
- * @param key
20
- * @param entity
21
- */
22
- static isThrottlingEntity(key: string, entity?: object): boolean {
23
- let validateKey: boolean = false;
24
- if (key) {
25
- validateKey =
26
- key.indexOf(ThrottlingConstants.THROTTLING_PREFIX) === 0;
27
- }
28
-
29
- let validateEntity: boolean = true;
30
- if (entity) {
31
- validateEntity = entity.hasOwnProperty("throttleTime");
32
- }
33
-
34
- return validateKey && validateEntity;
35
- }
36
- }
14
+ };
@@ -14,6 +14,7 @@ import {
14
14
  CredentialType,
15
15
  SERVER_TELEM_CONSTANTS,
16
16
  Separators,
17
+ ThrottlingConstants,
17
18
  } from "../../utils/Constants";
18
19
  import { TimeUtils } from "../../utils/TimeUtils";
19
20
  import { AccessTokenEntity } from "../entities/AccessTokenEntity";
@@ -169,7 +170,7 @@ export function createRefreshTokenEntity(
169
170
  clientId: string,
170
171
  familyId?: string,
171
172
  userAssertionHash?: string,
172
- expiresOn?: string
173
+ expiresOn?: number
173
174
  ): RefreshTokenEntity {
174
175
  const rtEntity: RefreshTokenEntity = {
175
176
  credentialType: CredentialType.REFRESH_TOKEN,
@@ -188,7 +189,7 @@ export function createRefreshTokenEntity(
188
189
  }
189
190
 
190
191
  if (expiresOn) {
191
- rtEntity.expiresOn = expiresOn;
192
+ rtEntity.expiresOn = expiresOn.toString();
192
193
  }
193
194
 
194
195
  return rtEntity;
@@ -330,3 +331,22 @@ export function isServerTelemetryEntity(key: string, entity?: object): boolean {
330
331
 
331
332
  return validateKey && validateEntity;
332
333
  }
334
+
335
+ /**
336
+ * validates if a given cache entry is "Throttling", parses <key,value>
337
+ * @param key
338
+ * @param entity
339
+ */
340
+ export function isThrottlingEntity(key: string, entity?: object): boolean {
341
+ let validateKey: boolean = false;
342
+ if (key) {
343
+ validateKey = key.indexOf(ThrottlingConstants.THROTTLING_PREFIX) === 0;
344
+ }
345
+
346
+ let validateEntity: boolean = true;
347
+ if (entity) {
348
+ validateEntity = entity.hasOwnProperty("throttleTime");
349
+ }
350
+
351
+ return validateKey && validateEntity;
352
+ }
@@ -60,8 +60,19 @@ export type AccountFilter = Omit<
60
60
  realm?: string;
61
61
  loginHint?: string;
62
62
  sid?: string;
63
+ isHomeTenant?: boolean;
63
64
  };
64
65
 
66
+ export type TenantProfileFilter = Pick<
67
+ AccountFilter,
68
+ | "localAccountId"
69
+ | "loginHint"
70
+ | "name"
71
+ | "sid"
72
+ | "isHomeTenant"
73
+ | "username"
74
+ >;
75
+
65
76
  /**
66
77
  * Credential: <home_account_id*>-<environment>-<credential_type>-<client_id>-<realm*>-<target*>-<scheme*>
67
78
  */
@@ -13,9 +13,9 @@ import {
13
13
  AuthenticationScheme,
14
14
  PromptValue,
15
15
  Separators,
16
- AADServerParamKeys,
17
16
  HeaderNames,
18
17
  } from "../utils/Constants";
18
+ import * as AADServerParamKeys from "../constants/AADServerParamKeys";
19
19
  import {
20
20
  ClientConfiguration,
21
21
  isOidcProtocolMode,
@@ -161,8 +161,7 @@ export class AuthorizationCodeClient extends BaseClient {
161
161
  undefined,
162
162
  undefined,
163
163
  undefined,
164
- requestId,
165
- (TimeUtils.nowSeconds() + 24 * 60 * 60).toString()
164
+ requestId
166
165
  );
167
166
  }
168
167
 
@@ -255,7 +254,7 @@ export class AuthorizationCodeClient extends BaseClient {
255
254
  try {
256
255
  const clientInfo = buildClientInfo(
257
256
  request.clientInfo,
258
- this.cryptoUtils
257
+ this.cryptoUtils.base64Decode
259
258
  );
260
259
  ccsCredential = {
261
260
  credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
@@ -422,7 +421,7 @@ export class AuthorizationCodeClient extends BaseClient {
422
421
  try {
423
422
  const clientInfo = buildClientInfo(
424
423
  request.clientInfo,
425
- this.cryptoUtils
424
+ this.cryptoUtils.base64Decode
426
425
  );
427
426
  ccsCred = {
428
427
  credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
@@ -17,8 +17,8 @@ import {
17
17
  AuthenticationScheme,
18
18
  Errors,
19
19
  HeaderNames,
20
- AADServerParamKeys,
21
20
  } from "../utils/Constants";
21
+ import * as AADServerParamKeys from "../constants/AADServerParamKeys";
22
22
  import { ResponseHandler } from "../response/ResponseHandler";
23
23
  import { AuthenticationResult } from "../response/AuthenticationResult";
24
24
  import { PopTokenGenerator } from "../crypto/PopTokenGenerator";
@@ -47,6 +47,10 @@ import {
47
47
  import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
48
48
  import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient";
49
49
  import { invoke, invokeAsync } from "../utils/FunctionWrappers";
50
+ import { generateCredentialKey } from "../cache/utils/CacheHelpers";
51
+
52
+ const DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS = 300; // 5 Minutes
53
+
50
54
  /**
51
55
  * OAuth2.0 refresh token client
52
56
  * @internal
@@ -102,8 +106,7 @@ export class RefreshTokenClient extends BaseClient {
102
106
  undefined,
103
107
  true,
104
108
  request.forceCache,
105
- requestId,
106
- request.expiresOn
109
+ requestId
107
110
  );
108
111
  }
109
112
 
@@ -141,7 +144,7 @@ export class RefreshTokenClient extends BaseClient {
141
144
  // if the app is part of the family, retrive a Family refresh token if present and make a refreshTokenRequest
142
145
  if (isFOCI) {
143
146
  try {
144
- return invokeAsync(
147
+ return await invokeAsync(
145
148
  this.acquireTokenWithCachedRefreshToken.bind(this),
146
149
  PerformanceEvents.RefreshTokenClientAcquireTokenWithCachedRefreshToken,
147
150
  this.logger,
@@ -218,9 +221,12 @@ export class RefreshTokenClient extends BaseClient {
218
221
  }
219
222
 
220
223
  if (
221
- request.enableRTExpiryCheck &&
222
224
  refreshToken.expiresOn &&
223
- Number(refreshToken.expiresOn) < TimeUtils.nowSeconds() + 5 * 60
225
+ TimeUtils.isTokenExpired(
226
+ refreshToken.expiresOn,
227
+ request.refreshTokenExpirationOffsetSeconds ||
228
+ DEFAULT_REFRESH_TOKEN_EXPIRATION_OFFSET_SECONDS
229
+ )
224
230
  ) {
225
231
  throw createInteractionRequiredAuthError(
226
232
  InteractionRequiredAuthErrorCodes.refreshTokenExpired
@@ -237,16 +243,31 @@ export class RefreshTokenClient extends BaseClient {
237
243
  credential: request.account.homeAccountId,
238
244
  type: CcsCredentialType.HOME_ACCOUNT_ID,
239
245
  },
240
- expiresOn: refreshToken.expiresOn,
241
246
  };
242
247
 
243
- return invokeAsync(
244
- this.acquireToken.bind(this),
245
- PerformanceEvents.RefreshTokenClientAcquireToken,
246
- this.logger,
247
- this.performanceClient,
248
- request.correlationId
249
- )(refreshTokenRequest);
248
+ try {
249
+ return await invokeAsync(
250
+ this.acquireToken.bind(this),
251
+ PerformanceEvents.RefreshTokenClientAcquireToken,
252
+ this.logger,
253
+ this.performanceClient,
254
+ request.correlationId
255
+ )(refreshTokenRequest);
256
+ } catch (e) {
257
+ if (
258
+ e instanceof InteractionRequiredAuthError &&
259
+ e.subError === InteractionRequiredAuthErrorCodes.badToken
260
+ ) {
261
+ // Remove bad refresh token from cache
262
+ this.logger.verbose(
263
+ "acquireTokenWithRefreshToken: bad refresh token, removing from cache"
264
+ );
265
+ const badRefreshTokenKey = generateCredentialKey(refreshToken);
266
+ this.cacheManager.removeRefreshToken(badRefreshTokenKey);
267
+ }
268
+
269
+ throw e;
270
+ }
250
271
  }
251
272
 
252
273
  /**
@@ -23,6 +23,7 @@ import { checkMaxAge, extractTokenClaims } from "../account/AuthToken";
23
23
  import { TokenClaims } from "../account/TokenClaims";
24
24
  import { PerformanceEvents } from "../telemetry/performance/PerformanceEvent";
25
25
  import { invokeAsync } from "../utils/FunctionWrappers";
26
+ import { getTenantFromAuthorityString } from "../authority/Authority";
26
27
 
27
28
  /** @internal */
28
29
  export class SilentFlowClient extends BaseClient {
@@ -118,18 +119,20 @@ export class SilentFlowClient extends BaseClient {
118
119
  );
119
120
  }
120
121
 
121
- const environment =
122
- request.authority || this.authority.getPreferredCache();
123
-
124
- const cacheRecord = this.cacheManager.readCacheRecord(
122
+ const requestTenantId =
123
+ request.account.tenantId ||
124
+ getTenantFromAuthorityString(request.authority);
125
+ const tokenKeys = this.cacheManager.getTokenKeys();
126
+ const cachedAccessToken = this.cacheManager.getAccessToken(
125
127
  request.account,
126
128
  request,
127
- environment,
129
+ tokenKeys,
130
+ requestTenantId,
128
131
  this.performanceClient,
129
132
  request.correlationId
130
133
  );
131
134
 
132
- if (!cacheRecord.accessToken) {
135
+ if (!cachedAccessToken) {
133
136
  // must refresh due to non-existent access_token
134
137
  this.setCacheOutcome(
135
138
  CacheOutcome.NO_CACHED_ACCESS_TOKEN,
@@ -139,9 +142,9 @@ export class SilentFlowClient extends BaseClient {
139
142
  ClientAuthErrorCodes.tokenRefreshRequired
140
143
  );
141
144
  } else if (
142
- TimeUtils.wasClockTurnedBack(cacheRecord.accessToken.cachedAt) ||
145
+ TimeUtils.wasClockTurnedBack(cachedAccessToken.cachedAt) ||
143
146
  TimeUtils.isTokenExpired(
144
- cacheRecord.accessToken.expiresOn,
147
+ cachedAccessToken.expiresOn,
145
148
  this.config.systemOptions.tokenRenewalOffsetSeconds
146
149
  )
147
150
  ) {
@@ -154,8 +157,8 @@ export class SilentFlowClient extends BaseClient {
154
157
  ClientAuthErrorCodes.tokenRefreshRequired
155
158
  );
156
159
  } else if (
157
- cacheRecord.accessToken.refreshOn &&
158
- TimeUtils.isTokenExpired(cacheRecord.accessToken.refreshOn, 0)
160
+ cachedAccessToken.refreshOn &&
161
+ TimeUtils.isTokenExpired(cachedAccessToken.refreshOn, 0)
159
162
  ) {
160
163
  // must refresh (in the background) due to the refresh_in value
161
164
  lastCacheOutcome = CacheOutcome.PROACTIVELY_REFRESHED;
@@ -163,6 +166,23 @@ export class SilentFlowClient extends BaseClient {
163
166
  // don't throw ClientAuthError.createRefreshRequiredError(), return cached token instead
164
167
  }
165
168
 
169
+ const environment =
170
+ request.authority || this.authority.getPreferredCache();
171
+ const cacheRecord: CacheRecord = {
172
+ account: this.cacheManager.readAccountFromCache(request.account),
173
+ accessToken: cachedAccessToken,
174
+ idToken: this.cacheManager.getIdToken(
175
+ request.account,
176
+ tokenKeys,
177
+ requestTenantId,
178
+ this.performanceClient,
179
+ request.correlationId
180
+ ),
181
+ refreshToken: null,
182
+ appMetadata:
183
+ this.cacheManager.readAppMetadataFromCache(environment),
184
+ };
185
+
166
186
  this.setCacheOutcome(lastCacheOutcome, request.correlationId);
167
187
 
168
188
  if (this.config.serverTelemetryManager) {
@@ -231,7 +251,7 @@ export class SilentFlowClient extends BaseClient {
231
251
  checkMaxAge(authTime, request.maxAge);
232
252
  }
233
253
 
234
- return await ResponseHandler.generateAuthenticationResult(
254
+ return ResponseHandler.generateAuthenticationResult(
235
255
  this.cryptoUtils,
236
256
  this.authority,
237
257
  cacheRecord,
@@ -6,7 +6,10 @@
6
6
  import { INetworkModule } from "../network/INetworkModule";
7
7
  import { DEFAULT_CRYPTO_IMPLEMENTATION, ICrypto } from "../crypto/ICrypto";
8
8
  import { ILoggerCallback, Logger, LogLevel } from "../logger/Logger";
9
- import { Constants } from "../utils/Constants";
9
+ import {
10
+ Constants,
11
+ DEFAULT_TOKEN_RENEWAL_OFFSET_SEC,
12
+ } from "../utils/Constants";
10
13
  import { version } from "../packageMetadata";
11
14
  import { Authority } from "../authority/Authority";
12
15
  import { AzureCloudInstance } from "../authority/AuthorityOptions";
@@ -21,9 +24,6 @@ import {
21
24
  createClientAuthError,
22
25
  } from "../error/ClientAuthError";
23
26
 
24
- // Token renewal offset default in seconds
25
- const DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
26
-
27
27
  /**
28
28
  * Use the configuration object to configure MSAL Modules and initialize the base interfaces for MSAL.
29
29
  *
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export const CLIENT_ID = "client_id";
7
+ export const REDIRECT_URI = "redirect_uri";
8
+ export const RESPONSE_TYPE = "response_type";
9
+ export const RESPONSE_MODE = "response_mode";
10
+ export const GRANT_TYPE = "grant_type";
11
+ export const CLAIMS = "claims";
12
+ export const SCOPE = "scope";
13
+ export const ERROR = "error";
14
+ export const ERROR_DESCRIPTION = "error_description";
15
+ export const ACCESS_TOKEN = "access_token";
16
+ export const ID_TOKEN = "id_token";
17
+ export const REFRESH_TOKEN = "refresh_token";
18
+ export const EXPIRES_IN = "expires_in";
19
+ export const REFRESH_TOKEN_EXPIRES_IN = "refresh_token_expires_in";
20
+ export const STATE = "state";
21
+ export const NONCE = "nonce";
22
+ export const PROMPT = "prompt";
23
+ export const SESSION_STATE = "session_state";
24
+ export const CLIENT_INFO = "client_info";
25
+ export const CODE = "code";
26
+ export const CODE_CHALLENGE = "code_challenge";
27
+ export const CODE_CHALLENGE_METHOD = "code_challenge_method";
28
+ export const CODE_VERIFIER = "code_verifier";
29
+ export const CLIENT_REQUEST_ID = "client-request-id";
30
+ export const X_CLIENT_SKU = "x-client-SKU";
31
+ export const X_CLIENT_VER = "x-client-VER";
32
+ export const X_CLIENT_OS = "x-client-OS";
33
+ export const X_CLIENT_CPU = "x-client-CPU";
34
+ export const X_CLIENT_CURR_TELEM = "x-client-current-telemetry";
35
+ export const X_CLIENT_LAST_TELEM = "x-client-last-telemetry";
36
+ export const X_MS_LIB_CAPABILITY = "x-ms-lib-capability";
37
+ export const X_APP_NAME = "x-app-name";
38
+ export const X_APP_VER = "x-app-ver";
39
+ export const POST_LOGOUT_URI = "post_logout_redirect_uri";
40
+ export const ID_TOKEN_HINT = "id_token_hint";
41
+ export const DEVICE_CODE = "device_code";
42
+ export const CLIENT_SECRET = "client_secret";
43
+ export const CLIENT_ASSERTION = "client_assertion";
44
+ export const CLIENT_ASSERTION_TYPE = "client_assertion_type";
45
+ export const TOKEN_TYPE = "token_type";
46
+ export const REQ_CNF = "req_cnf";
47
+ export const OBO_ASSERTION = "assertion";
48
+ export const REQUESTED_TOKEN_USE = "requested_token_use";
49
+ export const ON_BEHALF_OF = "on_behalf_of";
50
+ export const FOCI = "foci";
51
+ export const CCS_HEADER = "X-AnchorMailbox";
52
+ export const RETURN_SPA_CODE = "return_spa_code";
53
+ export const NATIVE_BROKER = "nativebroker";
54
+ export const LOGOUT_HINT = "logout_hint";
55
+ export const SID = "sid";
56
+ export const LOGIN_HINT = "login_hint";
57
+ export const DOMAIN_HINT = "domain_hint";
@@ -140,7 +140,7 @@ export class PopTokenGenerator {
140
140
  ? new UrlString(resourceRequestUri)
141
141
  : undefined;
142
142
  const resourceUrlComponents = resourceUrlString?.getUrlComponents();
143
- return await this.cryptoUtils.signJwt(
143
+ return this.cryptoUtils.signJwt(
144
144
  {
145
145
  at: payload,
146
146
  ts: TimeUtils.nowSeconds(),