@azure/msal-common 14.4.0 → 14.4.1-beta.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 (199) hide show
  1. package/dist/account/AccountInfo.d.ts +31 -31
  2. package/dist/account/AuthToken.d.ts +17 -17
  3. package/dist/account/AuthToken.mjs +58 -58
  4. package/dist/account/CcsCredential.d.ts +9 -9
  5. package/dist/account/CcsCredential.mjs +8 -8
  6. package/dist/account/ClientCredentials.d.ts +14 -14
  7. package/dist/account/ClientInfo.d.ts +19 -19
  8. package/dist/account/ClientInfo.mjs +37 -37
  9. package/dist/account/TokenClaims.d.ts +65 -65
  10. package/dist/authority/Authority.d.ts +249 -249
  11. package/dist/authority/Authority.mjs +788 -788
  12. package/dist/authority/AuthorityFactory.d.ts +31 -31
  13. package/dist/authority/AuthorityFactory.mjs +47 -47
  14. package/dist/authority/AuthorityMetadata.d.ts +503 -503
  15. package/dist/authority/AuthorityMetadata.mjs +603 -603
  16. package/dist/authority/AuthorityOptions.d.ts +27 -27
  17. package/dist/authority/AuthorityOptions.mjs +18 -18
  18. package/dist/authority/AuthorityType.d.ts +10 -10
  19. package/dist/authority/AuthorityType.mjs +13 -13
  20. package/dist/authority/AzureRegion.d.ts +1 -1
  21. package/dist/authority/AzureRegionConfiguration.d.ts +5 -5
  22. package/dist/authority/CloudDiscoveryMetadata.d.ts +5 -5
  23. package/dist/authority/CloudInstanceDiscoveryErrorResponse.d.ts +13 -13
  24. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +8 -8
  25. package/dist/authority/CloudInstanceDiscoveryResponse.d.ts +9 -9
  26. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +8 -8
  27. package/dist/authority/ImdsOptions.d.ts +5 -5
  28. package/dist/authority/OIDCOptions.d.ts +8 -8
  29. package/dist/authority/OpenIdConfigResponse.d.ts +11 -11
  30. package/dist/authority/OpenIdConfigResponse.mjs +10 -10
  31. package/dist/authority/ProtocolMode.d.ts +8 -8
  32. package/dist/authority/ProtocolMode.mjs +11 -11
  33. package/dist/authority/RegionDiscovery.d.ts +32 -32
  34. package/dist/authority/RegionDiscovery.mjs +106 -106
  35. package/dist/authority/RegionDiscoveryMetadata.d.ts +6 -6
  36. package/dist/broker/nativeBroker/INativeBrokerPlugin.d.ts +15 -15
  37. package/dist/cache/CacheManager.d.ts +485 -485
  38. package/dist/cache/CacheManager.mjs +1102 -1102
  39. package/dist/cache/entities/AccessTokenEntity.d.ts +25 -25
  40. package/dist/cache/entities/AccountEntity.d.ts +101 -101
  41. package/dist/cache/entities/AccountEntity.mjs +218 -218
  42. package/dist/cache/entities/AppMetadataEntity.d.ts +39 -39
  43. package/dist/cache/entities/AppMetadataEntity.mjs +66 -66
  44. package/dist/cache/entities/AuthorityMetadataEntity.d.ts +48 -48
  45. package/dist/cache/entities/AuthorityMetadataEntity.mjs +78 -78
  46. package/dist/cache/entities/CacheRecord.d.ts +14 -14
  47. package/dist/cache/entities/CacheRecord.mjs +14 -14
  48. package/dist/cache/entities/CredentialEntity.d.ts +30 -30
  49. package/dist/cache/entities/IdTokenEntity.d.ts +8 -8
  50. package/dist/cache/entities/RefreshTokenEntity.d.ts +7 -5
  51. package/dist/cache/entities/RefreshTokenEntity.d.ts.map +1 -1
  52. package/dist/cache/entities/ServerTelemetryEntity.d.ts +5 -5
  53. package/dist/cache/entities/ThrottlingEntity.d.ts +13 -13
  54. package/dist/cache/entities/ThrottlingEntity.mjs +23 -23
  55. package/dist/cache/interface/ICacheManager.d.ts +166 -166
  56. package/dist/cache/interface/ICachePlugin.d.ts +5 -5
  57. package/dist/cache/interface/ISerializableTokenCache.d.ts +4 -4
  58. package/dist/cache/persistence/TokenCacheContext.d.ts +23 -23
  59. package/dist/cache/persistence/TokenCacheContext.mjs +25 -25
  60. package/dist/cache/utils/CacheHelpers.d.ts +64 -64
  61. package/dist/cache/utils/CacheHelpers.d.ts.map +1 -1
  62. package/dist/cache/utils/CacheHelpers.mjs +234 -231
  63. package/dist/cache/utils/CacheHelpers.mjs.map +1 -1
  64. package/dist/cache/utils/CacheTypes.d.ts +67 -67
  65. package/dist/client/AuthorizationCodeClient.d.ts +74 -74
  66. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  67. package/dist/client/AuthorizationCodeClient.mjs +402 -402
  68. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  69. package/dist/client/BaseClient.d.ts +51 -51
  70. package/dist/client/BaseClient.mjs +100 -100
  71. package/dist/client/RefreshTokenClient.d.ts +35 -35
  72. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  73. package/dist/client/RefreshTokenClient.mjs +193 -187
  74. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  75. package/dist/client/SilentFlowClient.d.ts +27 -27
  76. package/dist/client/SilentFlowClient.mjs +118 -118
  77. package/dist/config/AppTokenProvider.d.ts +38 -38
  78. package/dist/config/ClientConfiguration.d.ts +150 -150
  79. package/dist/config/ClientConfiguration.mjs +97 -97
  80. package/dist/crypto/ICrypto.d.ts +58 -58
  81. package/dist/crypto/ICrypto.mjs +30 -30
  82. package/dist/crypto/IGuidGenerator.d.ts +4 -4
  83. package/dist/crypto/JoseHeader.d.ts +22 -22
  84. package/dist/crypto/JoseHeader.mjs +37 -37
  85. package/dist/crypto/PopTokenGenerator.d.ts +60 -60
  86. package/dist/crypto/PopTokenGenerator.mjs +82 -82
  87. package/dist/crypto/SignedHttpRequest.d.ts +15 -15
  88. package/dist/error/AuthError.d.ts +44 -44
  89. package/dist/error/AuthError.mjs +46 -46
  90. package/dist/error/AuthErrorCodes.d.ts +5 -5
  91. package/dist/error/AuthErrorCodes.mjs +9 -9
  92. package/dist/error/ClientAuthError.d.ts +237 -237
  93. package/dist/error/ClientAuthError.mjs +249 -249
  94. package/dist/error/ClientAuthErrorCodes.d.ts +44 -44
  95. package/dist/error/ClientAuthErrorCodes.mjs +48 -48
  96. package/dist/error/ClientConfigurationError.d.ts +128 -128
  97. package/dist/error/ClientConfigurationError.mjs +135 -135
  98. package/dist/error/ClientConfigurationErrorCodes.d.ts +22 -22
  99. package/dist/error/ClientConfigurationErrorCodes.mjs +26 -26
  100. package/dist/error/InteractionRequiredAuthError.d.ts +57 -57
  101. package/dist/error/InteractionRequiredAuthError.d.ts.map +1 -1
  102. package/dist/error/InteractionRequiredAuthError.mjs +78 -77
  103. package/dist/error/InteractionRequiredAuthError.mjs.map +1 -1
  104. package/dist/error/InteractionRequiredAuthErrorCodes.d.ts +6 -5
  105. package/dist/error/InteractionRequiredAuthErrorCodes.d.ts.map +1 -1
  106. package/dist/error/InteractionRequiredAuthErrorCodes.mjs +13 -12
  107. package/dist/error/InteractionRequiredAuthErrorCodes.mjs.map +1 -1
  108. package/dist/error/JoseHeaderError.d.ts +15 -15
  109. package/dist/error/JoseHeaderError.mjs +22 -22
  110. package/dist/error/JoseHeaderErrorCodes.d.ts +2 -2
  111. package/dist/error/JoseHeaderErrorCodes.mjs +6 -6
  112. package/dist/error/ServerError.d.ts +7 -7
  113. package/dist/error/ServerError.mjs +14 -14
  114. package/dist/index.cjs +8289 -8277
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.ts +98 -98
  117. package/dist/index.mjs +1 -1
  118. package/dist/logger/Logger.d.ts +95 -95
  119. package/dist/logger/Logger.mjs +188 -188
  120. package/dist/network/INetworkModule.d.ts +29 -29
  121. package/dist/network/INetworkModule.mjs +12 -12
  122. package/dist/network/NetworkManager.d.ts +33 -33
  123. package/dist/network/NetworkManager.mjs +34 -34
  124. package/dist/network/RequestThumbprint.d.ts +18 -18
  125. package/dist/network/ThrottlingUtils.d.ts +42 -42
  126. package/dist/network/ThrottlingUtils.mjs +95 -95
  127. package/dist/packageMetadata.d.ts +2 -2
  128. package/dist/packageMetadata.mjs +3 -3
  129. package/dist/request/AuthenticationHeaderParser.d.ts +19 -19
  130. package/dist/request/AuthenticationHeaderParser.mjs +55 -55
  131. package/dist/request/BaseAuthRequest.d.ts +43 -43
  132. package/dist/request/CommonAuthorizationCodeRequest.d.ts +27 -27
  133. package/dist/request/CommonAuthorizationUrlRequest.d.ts +50 -50
  134. package/dist/request/CommonClientCredentialRequest.d.ts +17 -17
  135. package/dist/request/CommonDeviceCodeRequest.d.ts +21 -21
  136. package/dist/request/CommonEndSessionRequest.d.ts +21 -21
  137. package/dist/request/CommonOnBehalfOfRequest.d.ts +13 -13
  138. package/dist/request/CommonRefreshTokenRequest.d.ts +23 -22
  139. package/dist/request/CommonRefreshTokenRequest.d.ts.map +1 -1
  140. package/dist/request/CommonSilentFlowRequest.d.ts +21 -20
  141. package/dist/request/CommonSilentFlowRequest.d.ts.map +1 -1
  142. package/dist/request/CommonUsernamePasswordRequest.d.ts +17 -17
  143. package/dist/request/NativeRequest.d.ts +19 -19
  144. package/dist/request/NativeSignOutRequest.d.ts +5 -5
  145. package/dist/request/RequestParameterBuilder.d.ts +217 -217
  146. package/dist/request/RequestParameterBuilder.mjs +381 -381
  147. package/dist/request/RequestValidator.d.ts +33 -33
  148. package/dist/request/RequestValidator.mjs +81 -81
  149. package/dist/request/ScopeSet.d.ts +88 -88
  150. package/dist/request/ScopeSet.mjs +197 -197
  151. package/dist/request/StoreInCache.d.ts +8 -8
  152. package/dist/response/AuthenticationResult.d.ts +41 -41
  153. package/dist/response/AuthorizationCodePayload.d.ts +13 -13
  154. package/dist/response/DeviceCodeResponse.d.ts +25 -25
  155. package/dist/response/ExternalTokenResponse.d.ts +15 -15
  156. package/dist/response/IMDSBadResponse.d.ts +4 -4
  157. package/dist/response/ResponseHandler.d.ts +67 -67
  158. package/dist/response/ResponseHandler.d.ts.map +1 -1
  159. package/dist/response/ResponseHandler.mjs +312 -312
  160. package/dist/response/ResponseHandler.mjs.map +1 -1
  161. package/dist/response/ServerAuthorizationCodeResponse.d.ts +25 -25
  162. package/dist/response/ServerAuthorizationTokenResponse.d.ts +46 -46
  163. package/dist/telemetry/performance/IPerformanceClient.d.ts +51 -51
  164. package/dist/telemetry/performance/IPerformanceMeasurement.d.ts +5 -5
  165. package/dist/telemetry/performance/PerformanceClient.d.ts +191 -191
  166. package/dist/telemetry/performance/PerformanceClient.mjs +409 -409
  167. package/dist/telemetry/performance/PerformanceEvent.d.ts +464 -464
  168. package/dist/telemetry/performance/PerformanceEvent.mjs +253 -253
  169. package/dist/telemetry/performance/StubPerformanceClient.d.ts +24 -24
  170. package/dist/telemetry/performance/StubPerformanceClient.mjs +76 -76
  171. package/dist/telemetry/server/ServerTelemetryManager.d.ts +66 -66
  172. package/dist/telemetry/server/ServerTelemetryManager.mjs +201 -201
  173. package/dist/telemetry/server/ServerTelemetryRequest.d.ts +8 -8
  174. package/dist/url/IUri.d.ts +12 -12
  175. package/dist/url/UrlString.d.ts +48 -48
  176. package/dist/url/UrlString.mjs +161 -161
  177. package/dist/utils/Constants.d.ts +365 -365
  178. package/dist/utils/Constants.mjs +375 -375
  179. package/dist/utils/FunctionWrappers.d.ts +27 -27
  180. package/dist/utils/FunctionWrappers.mjs +84 -84
  181. package/dist/utils/MsalTypes.d.ts +6 -6
  182. package/dist/utils/ProtocolUtils.d.ts +42 -42
  183. package/dist/utils/ProtocolUtils.mjs +69 -69
  184. package/dist/utils/StringUtils.d.ts +40 -40
  185. package/dist/utils/StringUtils.mjs +95 -95
  186. package/dist/utils/TimeUtils.d.ts +27 -27
  187. package/dist/utils/TimeUtils.mjs +45 -45
  188. package/dist/utils/UrlUtils.d.ts +10 -10
  189. package/dist/utils/UrlUtils.mjs +44 -44
  190. package/package.json +92 -92
  191. package/src/cache/entities/RefreshTokenEntity.ts +3 -1
  192. package/src/cache/utils/CacheHelpers.ts +6 -1
  193. package/src/client/AuthorizationCodeClient.ts +2 -1
  194. package/src/client/RefreshTokenClient.ts +13 -1
  195. package/src/error/InteractionRequiredAuthError.ts +2 -0
  196. package/src/error/InteractionRequiredAuthErrorCodes.ts +1 -0
  197. package/src/request/CommonRefreshTokenRequest.ts +1 -0
  198. package/src/request/CommonSilentFlowRequest.ts +1 -0
  199. package/src/response/ResponseHandler.ts +8 -4
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-common v14.4.0 2023-11-07 */
1
+ /*! @azure/msal-common v14.4.1-beta.0 2023-11-14 */
2
2
  'use strict';
3
3
  import { Separators, CredentialType, AuthenticationScheme, THE_FAMILY_ID, APP_METADATA, AUTHORITY_METADATA_CONSTANTS } from '../utils/Constants.mjs';
4
4
  import { generateCredentialKey } from './utils/CacheHelpers.mjs';
@@ -10,1107 +10,1107 @@ import { name, version } from '../packageMetadata.mjs';
10
10
  import { getAliasesFromStaticSources } from '../authority/AuthorityMetadata.mjs';
11
11
  import { invalidCacheRecord, bindingKeyNotRemoved, multipleMatchingAppMetadata, methodNotImplemented } from '../error/ClientAuthErrorCodes.mjs';
12
12
 
13
- /*
14
- * Copyright (c) Microsoft Corporation. All rights reserved.
15
- * Licensed under the MIT License.
16
- */
17
- /**
18
- * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
19
- * @internal
20
- */
21
- class CacheManager {
22
- constructor(clientId, cryptoImpl, logger, staticAuthorityOptions) {
23
- this.clientId = clientId;
24
- this.cryptoImpl = cryptoImpl;
25
- this.commonLogger = logger.clone(name, version);
26
- this.staticAuthorityOptions = staticAuthorityOptions;
27
- }
28
- /**
29
- * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
30
- * @param accountFilter - (Optional) filter to narrow down the accounts returned
31
- * @returns Array of AccountInfo objects in cache
32
- */
33
- getAllAccounts(accountFilter) {
34
- const validAccounts = [];
35
- this.getAccountsFilteredBy(accountFilter || {}).forEach((accountEntity) => {
36
- const accountInfo = this.getAccountInfoFromEntity(accountEntity, accountFilter);
37
- if (accountInfo) {
38
- validAccounts.push(accountInfo);
39
- }
40
- });
41
- return validAccounts;
42
- }
43
- /**
44
- * Gets accountInfo object based on provided filters
45
- */
46
- getAccountInfoFilteredBy(accountFilter) {
47
- const allAccounts = this.getAllAccounts(accountFilter);
48
- if (allAccounts.length > 1) {
49
- // If one or more accounts are found, further filter to the first account that has an ID token
50
- return allAccounts.filter((account) => {
51
- return !!account.idTokenClaims;
52
- })[0];
53
- }
54
- else if (allAccounts.length === 1) {
55
- // If only one account is found, return it regardless of whether a matching ID token was found
56
- return allAccounts[0];
57
- }
58
- else {
59
- return null;
60
- }
61
- }
62
- /**
63
- * Returns a single matching
64
- * @param accountFilter
65
- * @returns
66
- */
67
- getBaseAccountInfo(accountFilter) {
68
- const accountEntities = this.getAccountsFilteredBy(accountFilter);
69
- if (accountEntities.length > 0) {
70
- return accountEntities[0].getAccountInfo();
71
- }
72
- else {
73
- return null;
74
- }
75
- }
76
- getAccountInfoFromEntity(accountEntity, accountFilter) {
77
- const accountInfo = accountEntity.getAccountInfo();
78
- const idToken = this.getIdToken(accountInfo);
79
- if (idToken) {
80
- const idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode);
81
- if (this.idTokenClaimsMatchAccountFilter(idTokenClaims, accountFilter)) {
82
- accountInfo.idToken = idToken.secret;
83
- accountInfo.idTokenClaims = idTokenClaims;
84
- return accountInfo;
85
- }
86
- }
87
- return accountInfo;
88
- }
89
- idTokenClaimsMatchAccountFilter(idTokenClaims, accountFilter) {
90
- if (accountFilter) {
91
- if (!!accountFilter.loginHint &&
92
- !this.matchLoginHint(idTokenClaims, accountFilter.loginHint)) {
93
- return false;
94
- }
95
- if (!!accountFilter.sid &&
96
- !this.matchSid(idTokenClaims, accountFilter.sid)) {
97
- return false;
98
- }
99
- }
100
- return true;
101
- }
102
- /**
103
- * saves a cache record
104
- * @param cacheRecord
105
- */
106
- async saveCacheRecord(cacheRecord, storeInCache) {
107
- if (!cacheRecord) {
108
- throw createClientAuthError(invalidCacheRecord);
109
- }
110
- if (!!cacheRecord.account) {
111
- this.setAccount(cacheRecord.account);
112
- }
113
- if (!!cacheRecord.idToken && storeInCache?.idToken !== false) {
114
- this.setIdTokenCredential(cacheRecord.idToken);
115
- }
116
- if (!!cacheRecord.accessToken && storeInCache?.accessToken !== false) {
117
- await this.saveAccessToken(cacheRecord.accessToken);
118
- }
119
- if (!!cacheRecord.refreshToken &&
120
- storeInCache?.refreshToken !== false) {
121
- this.setRefreshTokenCredential(cacheRecord.refreshToken);
122
- }
123
- if (!!cacheRecord.appMetadata) {
124
- this.setAppMetadata(cacheRecord.appMetadata);
125
- }
126
- }
127
- /**
128
- * saves access token credential
129
- * @param credential
130
- */
131
- async saveAccessToken(credential) {
132
- const accessTokenFilter = {
133
- clientId: credential.clientId,
134
- credentialType: credential.credentialType,
135
- environment: credential.environment,
136
- homeAccountId: credential.homeAccountId,
137
- realm: credential.realm,
138
- tokenType: credential.tokenType,
139
- requestedClaimsHash: credential.requestedClaimsHash,
140
- };
141
- const tokenKeys = this.getTokenKeys();
142
- const currentScopes = ScopeSet.fromString(credential.target);
143
- const removedAccessTokens = [];
144
- tokenKeys.accessToken.forEach((key) => {
145
- if (!this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) {
146
- return;
147
- }
148
- const tokenEntity = this.getAccessTokenCredential(key);
149
- if (tokenEntity &&
150
- this.credentialMatchesFilter(tokenEntity, accessTokenFilter)) {
151
- const tokenScopeSet = ScopeSet.fromString(tokenEntity.target);
152
- if (tokenScopeSet.intersectingScopeSets(currentScopes)) {
153
- removedAccessTokens.push(this.removeAccessToken(key));
154
- }
155
- }
156
- });
157
- await Promise.all(removedAccessTokens);
158
- this.setAccessTokenCredential(credential);
159
- }
160
- /**
161
- * Retrieve accounts matching all provided filters; if no filter is set, get all accounts
162
- * Not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared
163
- * @param accountFilter - An object containing Account properties to filter by
164
- */
165
- getAccountsFilteredBy(accountFilter) {
166
- const allAccountKeys = this.getAccountKeys();
167
- const matchingAccounts = [];
168
- allAccountKeys.forEach((cacheKey) => {
169
- if (!this.isAccountKey(cacheKey, accountFilter.homeAccountId, accountFilter.tenantId)) {
170
- // Don't parse value if the key doesn't match the account filters
171
- return;
172
- }
173
- const entity = this.getAccount(cacheKey);
174
- if (!entity) {
175
- return;
176
- }
177
- if (!!accountFilter.homeAccountId &&
178
- !this.matchHomeAccountId(entity, accountFilter.homeAccountId)) {
179
- return;
180
- }
181
- if (!!accountFilter.localAccountId &&
182
- !this.matchLocalAccountId(entity, accountFilter.localAccountId)) {
183
- return;
184
- }
185
- if (!!accountFilter.username &&
186
- !this.matchUsername(entity, accountFilter.username)) {
187
- return;
188
- }
189
- if (!!accountFilter.environment &&
190
- !this.matchEnvironment(entity, accountFilter.environment)) {
191
- return;
192
- }
193
- if (!!accountFilter.realm &&
194
- !this.matchRealm(entity, accountFilter.realm)) {
195
- return;
196
- }
197
- // tenantId is another name for realm
198
- if (!!accountFilter.tenantId &&
199
- !this.matchRealm(entity, accountFilter.tenantId)) {
200
- return;
201
- }
202
- if (!!accountFilter.nativeAccountId &&
203
- !this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) {
204
- return;
205
- }
206
- if (!!accountFilter.authorityType &&
207
- !this.matchAuthorityType(entity, accountFilter.authorityType)) {
208
- return;
209
- }
210
- if (!!accountFilter.name &&
211
- !this.matchName(entity, accountFilter.name)) {
212
- return;
213
- }
214
- matchingAccounts.push(entity);
215
- });
216
- return matchingAccounts;
217
- }
218
- /**
219
- * Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
220
- * @param key
221
- * @param homeAccountId
222
- * @param tenantId
223
- * @returns
224
- */
225
- isAccountKey(key, homeAccountId, tenantId) {
226
- if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
227
- // Account cache keys contain 3 items separated by '-' (each item may also contain '-')
228
- return false;
229
- }
230
- if (homeAccountId &&
231
- !key.toLowerCase().includes(homeAccountId.toLowerCase())) {
232
- return false;
233
- }
234
- if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
235
- return false;
236
- }
237
- // Do not check environment as aliasing can cause false negatives
238
- return true;
239
- }
240
- /**
241
- * Returns true if the given key matches our credential key schema.
242
- * @param key
243
- */
244
- isCredentialKey(key) {
245
- if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
246
- // Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
247
- return false;
248
- }
249
- const lowerCaseKey = key.toLowerCase();
250
- // Credential keys must indicate what credential type they represent
251
- if (lowerCaseKey.indexOf(CredentialType.ID_TOKEN.toLowerCase()) ===
252
- -1 &&
253
- lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) ===
254
- -1 &&
255
- lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 &&
256
- lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) ===
257
- -1) {
258
- return false;
259
- }
260
- if (lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) >
261
- -1) {
262
- // Refresh tokens must contain the client id or family id
263
- const clientIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${this.clientId}${Separators.CACHE_KEY_SEPARATOR}`;
264
- const familyIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${THE_FAMILY_ID}${Separators.CACHE_KEY_SEPARATOR}`;
265
- if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 &&
266
- lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) {
267
- return false;
268
- }
269
- }
270
- else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
271
- // Tokens must contain the clientId
272
- return false;
273
- }
274
- return true;
275
- }
276
- /**
277
- * Returns whether or not the given credential entity matches the filter
278
- * @param entity
279
- * @param filter
280
- * @returns
281
- */
282
- credentialMatchesFilter(entity, filter) {
283
- if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) {
284
- return false;
285
- }
286
- if (!!filter.userAssertionHash &&
287
- !this.matchUserAssertionHash(entity, filter.userAssertionHash)) {
288
- return false;
289
- }
290
- /*
291
- * homeAccountId can be undefined, and we want to filter out cached items that have a homeAccountId of ""
292
- * because we don't want a client_credential request to return a cached token that has a homeAccountId
293
- */
294
- if (typeof filter.homeAccountId === "string" &&
295
- !this.matchHomeAccountId(entity, filter.homeAccountId)) {
296
- return false;
297
- }
298
- if (!!filter.environment &&
299
- !this.matchEnvironment(entity, filter.environment)) {
300
- return false;
301
- }
302
- if (!!filter.realm && !this.matchRealm(entity, filter.realm)) {
303
- return false;
304
- }
305
- if (!!filter.credentialType &&
306
- !this.matchCredentialType(entity, filter.credentialType)) {
307
- return false;
308
- }
309
- if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) {
310
- return false;
311
- }
312
- /*
313
- * idTokens do not have "target", target specific refreshTokens do exist for some types of authentication
314
- * Resource specific refresh tokens case will be added when the support is deemed necessary
315
- */
316
- if (!!filter.target && !this.matchTarget(entity, filter.target)) {
317
- return false;
318
- }
319
- // If request OR cached entity has requested Claims Hash, check if they match
320
- if (filter.requestedClaimsHash || entity.requestedClaimsHash) {
321
- // Don't match if either is undefined or they are different
322
- if (entity.requestedClaimsHash !== filter.requestedClaimsHash) {
323
- return false;
324
- }
325
- }
326
- // Access Token with Auth Scheme specific matching
327
- if (entity.credentialType ===
328
- CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) {
329
- if (!!filter.tokenType &&
330
- !this.matchTokenType(entity, filter.tokenType)) {
331
- return false;
332
- }
333
- // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
334
- if (filter.tokenType === AuthenticationScheme.SSH) {
335
- if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
336
- return false;
337
- }
338
- }
339
- }
340
- return true;
341
- }
342
- /**
343
- * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata
344
- * @param filter
345
- */
346
- getAppMetadataFilteredBy(filter) {
347
- return this.getAppMetadataFilteredByInternal(filter.environment, filter.clientId);
348
- }
349
- /**
350
- * Support function to help match appMetadata
351
- * @param environment
352
- * @param clientId
353
- */
354
- getAppMetadataFilteredByInternal(environment, clientId) {
355
- const allCacheKeys = this.getKeys();
356
- const matchingAppMetadata = {};
357
- allCacheKeys.forEach((cacheKey) => {
358
- // don't parse any non-appMetadata type cache entities
359
- if (!this.isAppMetadata(cacheKey)) {
360
- return;
361
- }
362
- // Attempt retrieval
363
- const entity = this.getAppMetadata(cacheKey);
364
- if (!entity) {
365
- return;
366
- }
367
- if (!!environment && !this.matchEnvironment(entity, environment)) {
368
- return;
369
- }
370
- if (!!clientId && !this.matchClientId(entity, clientId)) {
371
- return;
372
- }
373
- matchingAppMetadata[cacheKey] = entity;
374
- });
375
- return matchingAppMetadata;
376
- }
377
- /**
378
- * retrieve authorityMetadata that contains a matching alias
379
- * @param filter
380
- */
381
- getAuthorityMetadataByAlias(host) {
382
- const allCacheKeys = this.getAuthorityMetadataKeys();
383
- let matchedEntity = null;
384
- allCacheKeys.forEach((cacheKey) => {
385
- // don't parse any non-authorityMetadata type cache entities
386
- if (!this.isAuthorityMetadata(cacheKey) ||
387
- cacheKey.indexOf(this.clientId) === -1) {
388
- return;
389
- }
390
- // Attempt retrieval
391
- const entity = this.getAuthorityMetadata(cacheKey);
392
- if (!entity) {
393
- return;
394
- }
395
- if (entity.aliases.indexOf(host) === -1) {
396
- return;
397
- }
398
- matchedEntity = entity;
399
- });
400
- return matchedEntity;
401
- }
402
- /**
403
- * Removes all accounts and related tokens from cache.
404
- */
405
- async removeAllAccounts() {
406
- const allAccountKeys = this.getAccountKeys();
407
- const removedAccounts = [];
408
- allAccountKeys.forEach((cacheKey) => {
409
- removedAccounts.push(this.removeAccount(cacheKey));
410
- });
411
- await Promise.all(removedAccounts);
412
- }
413
- /**
414
- * Removes the account and related tokens for a given account key
415
- * @param account
416
- */
417
- async removeAccount(accountKey) {
418
- const account = this.getAccount(accountKey);
419
- if (!account) {
420
- return;
421
- }
422
- await this.removeAccountContext(account);
423
- this.removeItem(accountKey);
424
- }
425
- /**
426
- * Removes credentials associated with the provided account
427
- * @param account
428
- */
429
- async removeAccountContext(account) {
430
- const allTokenKeys = this.getTokenKeys();
431
- const accountId = account.generateAccountId();
432
- const removedCredentials = [];
433
- allTokenKeys.idToken.forEach((key) => {
434
- if (key.indexOf(accountId) === 0) {
435
- this.removeIdToken(key);
436
- }
437
- });
438
- allTokenKeys.accessToken.forEach((key) => {
439
- if (key.indexOf(accountId) === 0) {
440
- removedCredentials.push(this.removeAccessToken(key));
441
- }
442
- });
443
- allTokenKeys.refreshToken.forEach((key) => {
444
- if (key.indexOf(accountId) === 0) {
445
- this.removeRefreshToken(key);
446
- }
447
- });
448
- await Promise.all(removedCredentials);
449
- }
450
- /**
451
- * returns a boolean if the given credential is removed
452
- * @param credential
453
- */
454
- async removeAccessToken(key) {
455
- const credential = this.getAccessTokenCredential(key);
456
- if (!credential) {
457
- return;
458
- }
459
- // Remove Token Binding Key from key store for PoP Tokens Credentials
460
- if (credential.credentialType.toLowerCase() ===
461
- CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) {
462
- if (credential.tokenType === AuthenticationScheme.POP) {
463
- const accessTokenWithAuthSchemeEntity = credential;
464
- const kid = accessTokenWithAuthSchemeEntity.keyId;
465
- if (kid) {
466
- try {
467
- await this.cryptoImpl.removeTokenBindingKey(kid);
468
- }
469
- catch (error) {
470
- throw createClientAuthError(bindingKeyNotRemoved);
471
- }
472
- }
473
- }
474
- }
475
- return this.removeItem(key);
476
- }
477
- /**
478
- * Removes all app metadata objects from cache.
479
- */
480
- removeAppMetadata() {
481
- const allCacheKeys = this.getKeys();
482
- allCacheKeys.forEach((cacheKey) => {
483
- if (this.isAppMetadata(cacheKey)) {
484
- this.removeItem(cacheKey);
485
- }
486
- });
487
- return true;
488
- }
489
- /**
490
- * Retrieve the cached credentials into a cacherecord
491
- * @param account {AccountInfo}
492
- * @param request {BaseAuthRequest}
493
- * @param environment {string}
494
- * @param performanceClient {?IPerformanceClient}
495
- * @param correlationId {?string}
496
- */
497
- readCacheRecord(account, request, environment, performanceClient, correlationId) {
498
- const tokenKeys = this.getTokenKeys();
499
- const cachedAccount = this.readAccountFromCache(account);
500
- const cachedIdToken = this.getIdToken(account, tokenKeys, performanceClient, correlationId);
501
- const cachedAccessToken = this.getAccessToken(account, request, tokenKeys, performanceClient, correlationId);
502
- const cachedRefreshToken = this.getRefreshToken(account, false, tokenKeys, performanceClient, correlationId);
503
- const cachedAppMetadata = this.readAppMetadataFromCache(environment);
504
- if (cachedAccount && cachedIdToken) {
505
- cachedAccount.idTokenClaims = extractTokenClaims(cachedIdToken.secret, this.cryptoImpl.base64Decode);
506
- }
507
- return {
508
- account: cachedAccount,
509
- idToken: cachedIdToken,
510
- accessToken: cachedAccessToken,
511
- refreshToken: cachedRefreshToken,
512
- appMetadata: cachedAppMetadata,
513
- };
514
- }
515
- /**
516
- * Retrieve AccountEntity from cache
517
- * @param account
518
- */
519
- readAccountFromCache(account) {
520
- const accountKey = AccountEntity.generateAccountCacheKey(account);
521
- return this.getAccount(accountKey);
522
- }
523
- /**
524
- * Retrieve IdTokenEntity from cache
525
- * @param account {AccountInfo}
526
- * @param tokenKeys {?TokenKeys}
527
- * @param performanceClient {?IPerformanceClient}
528
- * @param correlationId {?string}
529
- */
530
- getIdToken(account, tokenKeys, performanceClient, correlationId) {
531
- this.commonLogger.trace("CacheManager - getIdToken called");
532
- const idTokenFilter = {
533
- homeAccountId: account.homeAccountId,
534
- environment: account.environment,
535
- credentialType: CredentialType.ID_TOKEN,
536
- clientId: this.clientId,
537
- realm: account.tenantId,
538
- };
539
- const idTokens = this.getIdTokensByFilter(idTokenFilter, tokenKeys);
540
- const numIdTokens = idTokens.length;
541
- if (numIdTokens < 1) {
542
- this.commonLogger.info("CacheManager:getIdToken - No token found");
543
- return null;
544
- }
545
- else if (numIdTokens > 1) {
546
- this.commonLogger.info("CacheManager:getIdToken - Multiple id tokens found, clearing them");
547
- idTokens.forEach((idToken) => {
548
- this.removeIdToken(generateCredentialKey(idToken));
549
- });
550
- if (performanceClient && correlationId) {
551
- performanceClient.addFields({ multiMatchedID: idTokens.length }, correlationId);
552
- }
553
- return null;
554
- }
555
- this.commonLogger.info("CacheManager:getIdToken - Returning id token");
556
- return idTokens[0];
557
- }
558
- /**
559
- * Gets all idTokens matching the given filter
560
- * @param filter
561
- * @returns
562
- */
563
- getIdTokensByFilter(filter, tokenKeys) {
564
- const idTokenKeys = (tokenKeys && tokenKeys.idToken) || this.getTokenKeys().idToken;
565
- const idTokens = [];
566
- idTokenKeys.forEach((key) => {
567
- if (!this.idTokenKeyMatchesFilter(key, {
568
- clientId: this.clientId,
569
- ...filter,
570
- })) {
571
- return;
572
- }
573
- const idToken = this.getIdTokenCredential(key);
574
- if (idToken && this.credentialMatchesFilter(idToken, filter)) {
575
- idTokens.push(idToken);
576
- }
577
- });
578
- return idTokens;
579
- }
580
- /**
581
- * Validate the cache key against filter before retrieving and parsing cache value
582
- * @param key
583
- * @param filter
584
- * @returns
585
- */
586
- idTokenKeyMatchesFilter(inputKey, filter) {
587
- const key = inputKey.toLowerCase();
588
- if (filter.clientId &&
589
- key.indexOf(filter.clientId.toLowerCase()) === -1) {
590
- return false;
591
- }
592
- if (filter.homeAccountId &&
593
- key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
594
- return false;
595
- }
596
- return true;
597
- }
598
- /**
599
- * Removes idToken from the cache
600
- * @param key
601
- */
602
- removeIdToken(key) {
603
- this.removeItem(key);
604
- }
605
- /**
606
- * Removes refresh token from the cache
607
- * @param key
608
- */
609
- removeRefreshToken(key) {
610
- this.removeItem(key);
611
- }
612
- /**
613
- * Retrieve AccessTokenEntity from cache
614
- * @param account {AccountInfo}
615
- * @param request {BaseAuthRequest}
616
- * @param tokenKeys {?TokenKeys}
617
- * @param performanceClient {?IPerformanceClient}
618
- * @param correlationId {?string}
619
- */
620
- getAccessToken(account, request, tokenKeys, performanceClient, correlationId) {
621
- this.commonLogger.trace("CacheManager - getAccessToken called");
622
- const scopes = ScopeSet.createSearchScopes(request.scopes);
623
- const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER;
624
- /*
625
- * Distinguish between Bearer and PoP/SSH token cache types
626
- * Cast to lowercase to handle "bearer" from ADFS
627
- */
628
- const credentialType = authScheme &&
629
- authScheme.toLowerCase() !==
630
- AuthenticationScheme.BEARER.toLowerCase()
631
- ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME
632
- : CredentialType.ACCESS_TOKEN;
633
- const accessTokenFilter = {
634
- homeAccountId: account.homeAccountId,
635
- environment: account.environment,
636
- credentialType: credentialType,
637
- clientId: this.clientId,
638
- realm: account.tenantId,
639
- target: scopes,
640
- tokenType: authScheme,
641
- keyId: request.sshKid,
642
- requestedClaimsHash: request.requestedClaimsHash,
643
- };
644
- const accessTokenKeys = (tokenKeys && tokenKeys.accessToken) ||
645
- this.getTokenKeys().accessToken;
646
- const accessTokens = [];
647
- accessTokenKeys.forEach((key) => {
648
- // Validate key
649
- if (this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) {
650
- const accessToken = this.getAccessTokenCredential(key);
651
- // Validate value
652
- if (accessToken &&
653
- this.credentialMatchesFilter(accessToken, accessTokenFilter)) {
654
- accessTokens.push(accessToken);
655
- }
656
- }
657
- });
658
- const numAccessTokens = accessTokens.length;
659
- if (numAccessTokens < 1) {
660
- this.commonLogger.info("CacheManager:getAccessToken - No token found");
661
- return null;
662
- }
663
- else if (numAccessTokens > 1) {
664
- this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them");
665
- accessTokens.forEach((accessToken) => {
666
- void this.removeAccessToken(generateCredentialKey(accessToken));
667
- });
668
- if (performanceClient && correlationId) {
669
- performanceClient.addFields({ multiMatchedAT: accessTokens.length }, correlationId);
670
- }
671
- return null;
672
- }
673
- this.commonLogger.info("CacheManager:getAccessToken - Returning access token");
674
- return accessTokens[0];
675
- }
676
- /**
677
- * Validate the cache key against filter before retrieving and parsing cache value
678
- * @param key
679
- * @param filter
680
- * @param keyMustContainAllScopes
681
- * @returns
682
- */
683
- accessTokenKeyMatchesFilter(inputKey, filter, keyMustContainAllScopes) {
684
- const key = inputKey.toLowerCase();
685
- if (filter.clientId &&
686
- key.indexOf(filter.clientId.toLowerCase()) === -1) {
687
- return false;
688
- }
689
- if (filter.homeAccountId &&
690
- key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
691
- return false;
692
- }
693
- if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) {
694
- return false;
695
- }
696
- if (filter.requestedClaimsHash &&
697
- key.indexOf(filter.requestedClaimsHash.toLowerCase()) === -1) {
698
- return false;
699
- }
700
- if (filter.target) {
701
- const scopes = filter.target.asArray();
702
- for (let i = 0; i < scopes.length; i++) {
703
- if (keyMustContainAllScopes &&
704
- !key.includes(scopes[i].toLowerCase())) {
705
- // When performing a cache lookup a missing scope would be a cache miss
706
- return false;
707
- }
708
- else if (!keyMustContainAllScopes &&
709
- key.includes(scopes[i].toLowerCase())) {
710
- // When performing a cache write, any token with a subset of requested scopes should be replaced
711
- return true;
712
- }
713
- }
714
- }
715
- return true;
716
- }
717
- /**
718
- * Gets all access tokens matching the filter
719
- * @param filter
720
- * @returns
721
- */
722
- getAccessTokensByFilter(filter) {
723
- const tokenKeys = this.getTokenKeys();
724
- const accessTokens = [];
725
- tokenKeys.accessToken.forEach((key) => {
726
- if (!this.accessTokenKeyMatchesFilter(key, filter, true)) {
727
- return;
728
- }
729
- const accessToken = this.getAccessTokenCredential(key);
730
- if (accessToken &&
731
- this.credentialMatchesFilter(accessToken, filter)) {
732
- accessTokens.push(accessToken);
733
- }
734
- });
735
- return accessTokens;
736
- }
737
- /**
738
- * Helper to retrieve the appropriate refresh token from cache
739
- * @param account {AccountInfo}
740
- * @param familyRT {boolean}
741
- * @param tokenKeys {?TokenKeys}
742
- * @param performanceClient {?IPerformanceClient}
743
- * @param correlationId {?string}
744
- */
745
- getRefreshToken(account, familyRT, tokenKeys, performanceClient, correlationId) {
746
- this.commonLogger.trace("CacheManager - getRefreshToken called");
747
- const id = familyRT ? THE_FAMILY_ID : undefined;
748
- const refreshTokenFilter = {
749
- homeAccountId: account.homeAccountId,
750
- environment: account.environment,
751
- credentialType: CredentialType.REFRESH_TOKEN,
752
- clientId: this.clientId,
753
- familyId: id,
754
- };
755
- const refreshTokenKeys = (tokenKeys && tokenKeys.refreshToken) ||
756
- this.getTokenKeys().refreshToken;
757
- const refreshTokens = [];
758
- refreshTokenKeys.forEach((key) => {
759
- // Validate key
760
- if (this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) {
761
- const refreshToken = this.getRefreshTokenCredential(key);
762
- // Validate value
763
- if (refreshToken &&
764
- this.credentialMatchesFilter(refreshToken, refreshTokenFilter)) {
765
- refreshTokens.push(refreshToken);
766
- }
767
- }
768
- });
769
- const numRefreshTokens = refreshTokens.length;
770
- if (numRefreshTokens < 1) {
771
- this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found.");
772
- return null;
773
- }
774
- // address the else case after remove functions address environment aliases
775
- if (numRefreshTokens > 1 && performanceClient && correlationId) {
776
- performanceClient.addFields({ multiMatchedRT: numRefreshTokens }, correlationId);
777
- }
778
- this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token");
779
- return refreshTokens[0];
780
- }
781
- /**
782
- * Validate the cache key against filter before retrieving and parsing cache value
783
- * @param key
784
- * @param filter
785
- */
786
- refreshTokenKeyMatchesFilter(inputKey, filter) {
787
- const key = inputKey.toLowerCase();
788
- if (filter.familyId &&
789
- key.indexOf(filter.familyId.toLowerCase()) === -1) {
790
- return false;
791
- }
792
- // If familyId is used, clientId is not in the key
793
- if (!filter.familyId &&
794
- filter.clientId &&
795
- key.indexOf(filter.clientId.toLowerCase()) === -1) {
796
- return false;
797
- }
798
- if (filter.homeAccountId &&
799
- key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
800
- return false;
801
- }
802
- return true;
803
- }
804
- /**
805
- * Retrieve AppMetadataEntity from cache
806
- */
807
- readAppMetadataFromCache(environment) {
808
- const appMetadataFilter = {
809
- environment,
810
- clientId: this.clientId,
811
- };
812
- const appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter);
813
- const appMetadataEntries = Object.keys(appMetadata).map((key) => appMetadata[key]);
814
- const numAppMetadata = appMetadataEntries.length;
815
- if (numAppMetadata < 1) {
816
- return null;
817
- }
818
- else if (numAppMetadata > 1) {
819
- throw createClientAuthError(multipleMatchingAppMetadata);
820
- }
821
- return appMetadataEntries[0];
822
- }
823
- /**
824
- * Return the family_id value associated with FOCI
825
- * @param environment
826
- * @param clientId
827
- */
828
- isAppMetadataFOCI(environment) {
829
- const appMetadata = this.readAppMetadataFromCache(environment);
830
- return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID);
831
- }
832
- /**
833
- * helper to match account ids
834
- * @param value
835
- * @param homeAccountId
836
- */
837
- matchHomeAccountId(entity, homeAccountId) {
838
- return !!(typeof entity.homeAccountId === "string" &&
839
- homeAccountId === entity.homeAccountId);
840
- }
841
- /**
842
- * helper to match account ids
843
- * @param entity
844
- * @param localAccountId
845
- * @returns
846
- */
847
- matchLocalAccountId(entity, localAccountId) {
848
- return !!(typeof entity.localAccountId === "string" &&
849
- localAccountId === entity.localAccountId);
850
- }
851
- /**
852
- * helper to match usernames
853
- * @param entity
854
- * @param username
855
- * @returns
856
- */
857
- matchUsername(entity, username) {
858
- return !!(typeof entity.username === "string" &&
859
- username.toLowerCase() === entity.username.toLowerCase());
860
- }
861
- /**
862
- * helper to match names
863
- * @param entity
864
- * @param name
865
- * @returns true if the downcased name properties are present and match in the filter and the entity
866
- */
867
- matchName(entity, name) {
868
- return !!(name.toLowerCase() === entity.name?.toLowerCase());
869
- }
870
- /**
871
- * helper to match assertion
872
- * @param value
873
- * @param oboAssertion
874
- */
875
- matchUserAssertionHash(entity, userAssertionHash) {
876
- return !!(entity.userAssertionHash &&
877
- userAssertionHash === entity.userAssertionHash);
878
- }
879
- /**
880
- * helper to match environment
881
- * @param value
882
- * @param environment
883
- */
884
- matchEnvironment(entity, environment) {
885
- // Check static authority options first for cases where authority metadata has not been resolved and cached yet
886
- if (this.staticAuthorityOptions) {
887
- const staticAliases = getAliasesFromStaticSources(this.staticAuthorityOptions, this.commonLogger);
888
- if (staticAliases.includes(environment) &&
889
- staticAliases.includes(entity.environment)) {
890
- return true;
891
- }
892
- }
893
- // Query metadata cache if no static authority configuration has aliases that match enviroment
894
- const cloudMetadata = this.getAuthorityMetadataByAlias(environment);
895
- if (cloudMetadata &&
896
- cloudMetadata.aliases.indexOf(entity.environment) > -1) {
897
- return true;
898
- }
899
- return false;
900
- }
901
- /**
902
- * helper to match credential type
903
- * @param entity
904
- * @param credentialType
905
- */
906
- matchCredentialType(entity, credentialType) {
907
- return (entity.credentialType &&
908
- credentialType.toLowerCase() === entity.credentialType.toLowerCase());
909
- }
910
- /**
911
- * helper to match client ids
912
- * @param entity
913
- * @param clientId
914
- */
915
- matchClientId(entity, clientId) {
916
- return !!(entity.clientId && clientId === entity.clientId);
917
- }
918
- /**
919
- * helper to match family ids
920
- * @param entity
921
- * @param familyId
922
- */
923
- matchFamilyId(entity, familyId) {
924
- return !!(entity.familyId && familyId === entity.familyId);
925
- }
926
- /**
927
- * helper to match realm
928
- * @param entity
929
- * @param realm
930
- */
931
- matchRealm(entity, realm) {
932
- return !!(entity.realm && realm === entity.realm);
933
- }
934
- /**
935
- * helper to match nativeAccountId
936
- * @param entity
937
- * @param nativeAccountId
938
- * @returns boolean indicating the match result
939
- */
940
- matchNativeAccountId(entity, nativeAccountId) {
941
- return !!(entity.nativeAccountId && nativeAccountId === entity.nativeAccountId);
942
- }
943
- /**
944
- * helper to match loginHint which can be either:
945
- * 1. login_hint ID token claim
946
- * 2. username in cached account object
947
- * 3. upn in ID token claims
948
- * @param entity
949
- * @param loginHint
950
- * @returns
951
- */
952
- matchLoginHint(idTokenClaims, loginHint) {
953
- if (idTokenClaims?.login_hint === loginHint) {
954
- return true;
955
- }
956
- if (idTokenClaims.preferred_username === loginHint) {
957
- return true;
958
- }
959
- if (idTokenClaims?.upn === loginHint) {
960
- return true;
961
- }
962
- return false;
963
- }
964
- /**
965
- * Helper to match sid
966
- * @param idTokenClaims
967
- * @param sid
968
- * @returns true if the sid claim is present and matches the filter
969
- */
970
- matchSid(idTokenClaims, sid) {
971
- return !!(idTokenClaims?.sid && idTokenClaims.sid === sid);
972
- }
973
- matchAuthorityType(entity, authorityType) {
974
- return !!(entity.authorityType &&
975
- authorityType.toLowerCase() === entity.authorityType.toLowerCase());
976
- }
977
- /**
978
- * Returns true if the target scopes are a subset of the current entity's scopes, false otherwise.
979
- * @param entity
980
- * @param target
981
- */
982
- matchTarget(entity, target) {
983
- const isNotAccessTokenCredential = entity.credentialType !== CredentialType.ACCESS_TOKEN &&
984
- entity.credentialType !==
985
- CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
986
- if (isNotAccessTokenCredential || !entity.target) {
987
- return false;
988
- }
989
- const entityScopeSet = ScopeSet.fromString(entity.target);
990
- return entityScopeSet.containsScopeSet(target);
991
- }
992
- /**
993
- * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise
994
- * @param entity
995
- * @param tokenType
996
- */
997
- matchTokenType(entity, tokenType) {
998
- return !!(entity.tokenType && entity.tokenType === tokenType);
999
- }
1000
- /**
1001
- * Returns true if the credential's keyId matches the one in the request, false otherwise
1002
- * @param entity
1003
- * @param tokenType
1004
- */
1005
- matchKeyId(entity, keyId) {
1006
- return !!(entity.keyId && entity.keyId === keyId);
1007
- }
1008
- /**
1009
- * returns if a given cache entity is of the type appmetadata
1010
- * @param key
1011
- */
1012
- isAppMetadata(key) {
1013
- return key.indexOf(APP_METADATA) !== -1;
1014
- }
1015
- /**
1016
- * returns if a given cache entity is of the type authoritymetadata
1017
- * @param key
1018
- */
1019
- isAuthorityMetadata(key) {
1020
- return key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) !== -1;
1021
- }
1022
- /**
1023
- * returns cache key used for cloud instance metadata
1024
- */
1025
- generateAuthorityMetadataCacheKey(authority) {
1026
- return `${AUTHORITY_METADATA_CONSTANTS.CACHE_KEY}-${this.clientId}-${authority}`;
1027
- }
1028
- /**
1029
- * Helper to convert serialized data to object
1030
- * @param obj
1031
- * @param json
1032
- */
1033
- static toObject(obj, json) {
1034
- for (const propertyName in json) {
1035
- obj[propertyName] = json[propertyName];
1036
- }
1037
- return obj;
1038
- }
1039
- }
1040
- /** @internal */
1041
- class DefaultStorageClass extends CacheManager {
1042
- setAccount() {
1043
- throw createClientAuthError(methodNotImplemented);
1044
- }
1045
- getAccount() {
1046
- throw createClientAuthError(methodNotImplemented);
1047
- }
1048
- setIdTokenCredential() {
1049
- throw createClientAuthError(methodNotImplemented);
1050
- }
1051
- getIdTokenCredential() {
1052
- throw createClientAuthError(methodNotImplemented);
1053
- }
1054
- setAccessTokenCredential() {
1055
- throw createClientAuthError(methodNotImplemented);
1056
- }
1057
- getAccessTokenCredential() {
1058
- throw createClientAuthError(methodNotImplemented);
1059
- }
1060
- setRefreshTokenCredential() {
1061
- throw createClientAuthError(methodNotImplemented);
1062
- }
1063
- getRefreshTokenCredential() {
1064
- throw createClientAuthError(methodNotImplemented);
1065
- }
1066
- setAppMetadata() {
1067
- throw createClientAuthError(methodNotImplemented);
1068
- }
1069
- getAppMetadata() {
1070
- throw createClientAuthError(methodNotImplemented);
1071
- }
1072
- setServerTelemetry() {
1073
- throw createClientAuthError(methodNotImplemented);
1074
- }
1075
- getServerTelemetry() {
1076
- throw createClientAuthError(methodNotImplemented);
1077
- }
1078
- setAuthorityMetadata() {
1079
- throw createClientAuthError(methodNotImplemented);
1080
- }
1081
- getAuthorityMetadata() {
1082
- throw createClientAuthError(methodNotImplemented);
1083
- }
1084
- getAuthorityMetadataKeys() {
1085
- throw createClientAuthError(methodNotImplemented);
1086
- }
1087
- setThrottlingCache() {
1088
- throw createClientAuthError(methodNotImplemented);
1089
- }
1090
- getThrottlingCache() {
1091
- throw createClientAuthError(methodNotImplemented);
1092
- }
1093
- removeItem() {
1094
- throw createClientAuthError(methodNotImplemented);
1095
- }
1096
- containsKey() {
1097
- throw createClientAuthError(methodNotImplemented);
1098
- }
1099
- getKeys() {
1100
- throw createClientAuthError(methodNotImplemented);
1101
- }
1102
- getAccountKeys() {
1103
- throw createClientAuthError(methodNotImplemented);
1104
- }
1105
- getTokenKeys() {
1106
- throw createClientAuthError(methodNotImplemented);
1107
- }
1108
- async clear() {
1109
- throw createClientAuthError(methodNotImplemented);
1110
- }
1111
- updateCredentialCacheKey() {
1112
- throw createClientAuthError(methodNotImplemented);
1113
- }
13
+ /*
14
+ * Copyright (c) Microsoft Corporation. All rights reserved.
15
+ * Licensed under the MIT License.
16
+ */
17
+ /**
18
+ * Interface class which implement cache storage functions used by MSAL to perform validity checks, and store tokens.
19
+ * @internal
20
+ */
21
+ class CacheManager {
22
+ constructor(clientId, cryptoImpl, logger, staticAuthorityOptions) {
23
+ this.clientId = clientId;
24
+ this.cryptoImpl = cryptoImpl;
25
+ this.commonLogger = logger.clone(name, version);
26
+ this.staticAuthorityOptions = staticAuthorityOptions;
27
+ }
28
+ /**
29
+ * Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
30
+ * @param accountFilter - (Optional) filter to narrow down the accounts returned
31
+ * @returns Array of AccountInfo objects in cache
32
+ */
33
+ getAllAccounts(accountFilter) {
34
+ const validAccounts = [];
35
+ this.getAccountsFilteredBy(accountFilter || {}).forEach((accountEntity) => {
36
+ const accountInfo = this.getAccountInfoFromEntity(accountEntity, accountFilter);
37
+ if (accountInfo) {
38
+ validAccounts.push(accountInfo);
39
+ }
40
+ });
41
+ return validAccounts;
42
+ }
43
+ /**
44
+ * Gets accountInfo object based on provided filters
45
+ */
46
+ getAccountInfoFilteredBy(accountFilter) {
47
+ const allAccounts = this.getAllAccounts(accountFilter);
48
+ if (allAccounts.length > 1) {
49
+ // If one or more accounts are found, further filter to the first account that has an ID token
50
+ return allAccounts.filter((account) => {
51
+ return !!account.idTokenClaims;
52
+ })[0];
53
+ }
54
+ else if (allAccounts.length === 1) {
55
+ // If only one account is found, return it regardless of whether a matching ID token was found
56
+ return allAccounts[0];
57
+ }
58
+ else {
59
+ return null;
60
+ }
61
+ }
62
+ /**
63
+ * Returns a single matching
64
+ * @param accountFilter
65
+ * @returns
66
+ */
67
+ getBaseAccountInfo(accountFilter) {
68
+ const accountEntities = this.getAccountsFilteredBy(accountFilter);
69
+ if (accountEntities.length > 0) {
70
+ return accountEntities[0].getAccountInfo();
71
+ }
72
+ else {
73
+ return null;
74
+ }
75
+ }
76
+ getAccountInfoFromEntity(accountEntity, accountFilter) {
77
+ const accountInfo = accountEntity.getAccountInfo();
78
+ const idToken = this.getIdToken(accountInfo);
79
+ if (idToken) {
80
+ const idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode);
81
+ if (this.idTokenClaimsMatchAccountFilter(idTokenClaims, accountFilter)) {
82
+ accountInfo.idToken = idToken.secret;
83
+ accountInfo.idTokenClaims = idTokenClaims;
84
+ return accountInfo;
85
+ }
86
+ }
87
+ return accountInfo;
88
+ }
89
+ idTokenClaimsMatchAccountFilter(idTokenClaims, accountFilter) {
90
+ if (accountFilter) {
91
+ if (!!accountFilter.loginHint &&
92
+ !this.matchLoginHint(idTokenClaims, accountFilter.loginHint)) {
93
+ return false;
94
+ }
95
+ if (!!accountFilter.sid &&
96
+ !this.matchSid(idTokenClaims, accountFilter.sid)) {
97
+ return false;
98
+ }
99
+ }
100
+ return true;
101
+ }
102
+ /**
103
+ * saves a cache record
104
+ * @param cacheRecord
105
+ */
106
+ async saveCacheRecord(cacheRecord, storeInCache) {
107
+ if (!cacheRecord) {
108
+ throw createClientAuthError(invalidCacheRecord);
109
+ }
110
+ if (!!cacheRecord.account) {
111
+ this.setAccount(cacheRecord.account);
112
+ }
113
+ if (!!cacheRecord.idToken && storeInCache?.idToken !== false) {
114
+ this.setIdTokenCredential(cacheRecord.idToken);
115
+ }
116
+ if (!!cacheRecord.accessToken && storeInCache?.accessToken !== false) {
117
+ await this.saveAccessToken(cacheRecord.accessToken);
118
+ }
119
+ if (!!cacheRecord.refreshToken &&
120
+ storeInCache?.refreshToken !== false) {
121
+ this.setRefreshTokenCredential(cacheRecord.refreshToken);
122
+ }
123
+ if (!!cacheRecord.appMetadata) {
124
+ this.setAppMetadata(cacheRecord.appMetadata);
125
+ }
126
+ }
127
+ /**
128
+ * saves access token credential
129
+ * @param credential
130
+ */
131
+ async saveAccessToken(credential) {
132
+ const accessTokenFilter = {
133
+ clientId: credential.clientId,
134
+ credentialType: credential.credentialType,
135
+ environment: credential.environment,
136
+ homeAccountId: credential.homeAccountId,
137
+ realm: credential.realm,
138
+ tokenType: credential.tokenType,
139
+ requestedClaimsHash: credential.requestedClaimsHash,
140
+ };
141
+ const tokenKeys = this.getTokenKeys();
142
+ const currentScopes = ScopeSet.fromString(credential.target);
143
+ const removedAccessTokens = [];
144
+ tokenKeys.accessToken.forEach((key) => {
145
+ if (!this.accessTokenKeyMatchesFilter(key, accessTokenFilter, false)) {
146
+ return;
147
+ }
148
+ const tokenEntity = this.getAccessTokenCredential(key);
149
+ if (tokenEntity &&
150
+ this.credentialMatchesFilter(tokenEntity, accessTokenFilter)) {
151
+ const tokenScopeSet = ScopeSet.fromString(tokenEntity.target);
152
+ if (tokenScopeSet.intersectingScopeSets(currentScopes)) {
153
+ removedAccessTokens.push(this.removeAccessToken(key));
154
+ }
155
+ }
156
+ });
157
+ await Promise.all(removedAccessTokens);
158
+ this.setAccessTokenCredential(credential);
159
+ }
160
+ /**
161
+ * Retrieve accounts matching all provided filters; if no filter is set, get all accounts
162
+ * Not checking for casing as keys are all generated in lower case, remember to convert to lower case if object properties are compared
163
+ * @param accountFilter - An object containing Account properties to filter by
164
+ */
165
+ getAccountsFilteredBy(accountFilter) {
166
+ const allAccountKeys = this.getAccountKeys();
167
+ const matchingAccounts = [];
168
+ allAccountKeys.forEach((cacheKey) => {
169
+ if (!this.isAccountKey(cacheKey, accountFilter.homeAccountId, accountFilter.tenantId)) {
170
+ // Don't parse value if the key doesn't match the account filters
171
+ return;
172
+ }
173
+ const entity = this.getAccount(cacheKey);
174
+ if (!entity) {
175
+ return;
176
+ }
177
+ if (!!accountFilter.homeAccountId &&
178
+ !this.matchHomeAccountId(entity, accountFilter.homeAccountId)) {
179
+ return;
180
+ }
181
+ if (!!accountFilter.localAccountId &&
182
+ !this.matchLocalAccountId(entity, accountFilter.localAccountId)) {
183
+ return;
184
+ }
185
+ if (!!accountFilter.username &&
186
+ !this.matchUsername(entity, accountFilter.username)) {
187
+ return;
188
+ }
189
+ if (!!accountFilter.environment &&
190
+ !this.matchEnvironment(entity, accountFilter.environment)) {
191
+ return;
192
+ }
193
+ if (!!accountFilter.realm &&
194
+ !this.matchRealm(entity, accountFilter.realm)) {
195
+ return;
196
+ }
197
+ // tenantId is another name for realm
198
+ if (!!accountFilter.tenantId &&
199
+ !this.matchRealm(entity, accountFilter.tenantId)) {
200
+ return;
201
+ }
202
+ if (!!accountFilter.nativeAccountId &&
203
+ !this.matchNativeAccountId(entity, accountFilter.nativeAccountId)) {
204
+ return;
205
+ }
206
+ if (!!accountFilter.authorityType &&
207
+ !this.matchAuthorityType(entity, accountFilter.authorityType)) {
208
+ return;
209
+ }
210
+ if (!!accountFilter.name &&
211
+ !this.matchName(entity, accountFilter.name)) {
212
+ return;
213
+ }
214
+ matchingAccounts.push(entity);
215
+ });
216
+ return matchingAccounts;
217
+ }
218
+ /**
219
+ * Returns true if the given key matches our account key schema. Also matches homeAccountId and/or tenantId if provided
220
+ * @param key
221
+ * @param homeAccountId
222
+ * @param tenantId
223
+ * @returns
224
+ */
225
+ isAccountKey(key, homeAccountId, tenantId) {
226
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 3) {
227
+ // Account cache keys contain 3 items separated by '-' (each item may also contain '-')
228
+ return false;
229
+ }
230
+ if (homeAccountId &&
231
+ !key.toLowerCase().includes(homeAccountId.toLowerCase())) {
232
+ return false;
233
+ }
234
+ if (tenantId && !key.toLowerCase().includes(tenantId.toLowerCase())) {
235
+ return false;
236
+ }
237
+ // Do not check environment as aliasing can cause false negatives
238
+ return true;
239
+ }
240
+ /**
241
+ * Returns true if the given key matches our credential key schema.
242
+ * @param key
243
+ */
244
+ isCredentialKey(key) {
245
+ if (key.split(Separators.CACHE_KEY_SEPARATOR).length < 6) {
246
+ // Credential cache keys contain 6 items separated by '-' (each item may also contain '-')
247
+ return false;
248
+ }
249
+ const lowerCaseKey = key.toLowerCase();
250
+ // Credential keys must indicate what credential type they represent
251
+ if (lowerCaseKey.indexOf(CredentialType.ID_TOKEN.toLowerCase()) ===
252
+ -1 &&
253
+ lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN.toLowerCase()) ===
254
+ -1 &&
255
+ lowerCaseKey.indexOf(CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) === -1 &&
256
+ lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) ===
257
+ -1) {
258
+ return false;
259
+ }
260
+ if (lowerCaseKey.indexOf(CredentialType.REFRESH_TOKEN.toLowerCase()) >
261
+ -1) {
262
+ // Refresh tokens must contain the client id or family id
263
+ const clientIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${this.clientId}${Separators.CACHE_KEY_SEPARATOR}`;
264
+ const familyIdValidation = `${CredentialType.REFRESH_TOKEN}${Separators.CACHE_KEY_SEPARATOR}${THE_FAMILY_ID}${Separators.CACHE_KEY_SEPARATOR}`;
265
+ if (lowerCaseKey.indexOf(clientIdValidation.toLowerCase()) === -1 &&
266
+ lowerCaseKey.indexOf(familyIdValidation.toLowerCase()) === -1) {
267
+ return false;
268
+ }
269
+ }
270
+ else if (lowerCaseKey.indexOf(this.clientId.toLowerCase()) === -1) {
271
+ // Tokens must contain the clientId
272
+ return false;
273
+ }
274
+ return true;
275
+ }
276
+ /**
277
+ * Returns whether or not the given credential entity matches the filter
278
+ * @param entity
279
+ * @param filter
280
+ * @returns
281
+ */
282
+ credentialMatchesFilter(entity, filter) {
283
+ if (!!filter.clientId && !this.matchClientId(entity, filter.clientId)) {
284
+ return false;
285
+ }
286
+ if (!!filter.userAssertionHash &&
287
+ !this.matchUserAssertionHash(entity, filter.userAssertionHash)) {
288
+ return false;
289
+ }
290
+ /*
291
+ * homeAccountId can be undefined, and we want to filter out cached items that have a homeAccountId of ""
292
+ * because we don't want a client_credential request to return a cached token that has a homeAccountId
293
+ */
294
+ if (typeof filter.homeAccountId === "string" &&
295
+ !this.matchHomeAccountId(entity, filter.homeAccountId)) {
296
+ return false;
297
+ }
298
+ if (!!filter.environment &&
299
+ !this.matchEnvironment(entity, filter.environment)) {
300
+ return false;
301
+ }
302
+ if (!!filter.realm && !this.matchRealm(entity, filter.realm)) {
303
+ return false;
304
+ }
305
+ if (!!filter.credentialType &&
306
+ !this.matchCredentialType(entity, filter.credentialType)) {
307
+ return false;
308
+ }
309
+ if (!!filter.familyId && !this.matchFamilyId(entity, filter.familyId)) {
310
+ return false;
311
+ }
312
+ /*
313
+ * idTokens do not have "target", target specific refreshTokens do exist for some types of authentication
314
+ * Resource specific refresh tokens case will be added when the support is deemed necessary
315
+ */
316
+ if (!!filter.target && !this.matchTarget(entity, filter.target)) {
317
+ return false;
318
+ }
319
+ // If request OR cached entity has requested Claims Hash, check if they match
320
+ if (filter.requestedClaimsHash || entity.requestedClaimsHash) {
321
+ // Don't match if either is undefined or they are different
322
+ if (entity.requestedClaimsHash !== filter.requestedClaimsHash) {
323
+ return false;
324
+ }
325
+ }
326
+ // Access Token with Auth Scheme specific matching
327
+ if (entity.credentialType ===
328
+ CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME) {
329
+ if (!!filter.tokenType &&
330
+ !this.matchTokenType(entity, filter.tokenType)) {
331
+ return false;
332
+ }
333
+ // KeyId (sshKid) in request must match cached SSH certificate keyId because SSH cert is bound to a specific key
334
+ if (filter.tokenType === AuthenticationScheme.SSH) {
335
+ if (filter.keyId && !this.matchKeyId(entity, filter.keyId)) {
336
+ return false;
337
+ }
338
+ }
339
+ }
340
+ return true;
341
+ }
342
+ /**
343
+ * retrieve appMetadata matching all provided filters; if no filter is set, get all appMetadata
344
+ * @param filter
345
+ */
346
+ getAppMetadataFilteredBy(filter) {
347
+ return this.getAppMetadataFilteredByInternal(filter.environment, filter.clientId);
348
+ }
349
+ /**
350
+ * Support function to help match appMetadata
351
+ * @param environment
352
+ * @param clientId
353
+ */
354
+ getAppMetadataFilteredByInternal(environment, clientId) {
355
+ const allCacheKeys = this.getKeys();
356
+ const matchingAppMetadata = {};
357
+ allCacheKeys.forEach((cacheKey) => {
358
+ // don't parse any non-appMetadata type cache entities
359
+ if (!this.isAppMetadata(cacheKey)) {
360
+ return;
361
+ }
362
+ // Attempt retrieval
363
+ const entity = this.getAppMetadata(cacheKey);
364
+ if (!entity) {
365
+ return;
366
+ }
367
+ if (!!environment && !this.matchEnvironment(entity, environment)) {
368
+ return;
369
+ }
370
+ if (!!clientId && !this.matchClientId(entity, clientId)) {
371
+ return;
372
+ }
373
+ matchingAppMetadata[cacheKey] = entity;
374
+ });
375
+ return matchingAppMetadata;
376
+ }
377
+ /**
378
+ * retrieve authorityMetadata that contains a matching alias
379
+ * @param filter
380
+ */
381
+ getAuthorityMetadataByAlias(host) {
382
+ const allCacheKeys = this.getAuthorityMetadataKeys();
383
+ let matchedEntity = null;
384
+ allCacheKeys.forEach((cacheKey) => {
385
+ // don't parse any non-authorityMetadata type cache entities
386
+ if (!this.isAuthorityMetadata(cacheKey) ||
387
+ cacheKey.indexOf(this.clientId) === -1) {
388
+ return;
389
+ }
390
+ // Attempt retrieval
391
+ const entity = this.getAuthorityMetadata(cacheKey);
392
+ if (!entity) {
393
+ return;
394
+ }
395
+ if (entity.aliases.indexOf(host) === -1) {
396
+ return;
397
+ }
398
+ matchedEntity = entity;
399
+ });
400
+ return matchedEntity;
401
+ }
402
+ /**
403
+ * Removes all accounts and related tokens from cache.
404
+ */
405
+ async removeAllAccounts() {
406
+ const allAccountKeys = this.getAccountKeys();
407
+ const removedAccounts = [];
408
+ allAccountKeys.forEach((cacheKey) => {
409
+ removedAccounts.push(this.removeAccount(cacheKey));
410
+ });
411
+ await Promise.all(removedAccounts);
412
+ }
413
+ /**
414
+ * Removes the account and related tokens for a given account key
415
+ * @param account
416
+ */
417
+ async removeAccount(accountKey) {
418
+ const account = this.getAccount(accountKey);
419
+ if (!account) {
420
+ return;
421
+ }
422
+ await this.removeAccountContext(account);
423
+ this.removeItem(accountKey);
424
+ }
425
+ /**
426
+ * Removes credentials associated with the provided account
427
+ * @param account
428
+ */
429
+ async removeAccountContext(account) {
430
+ const allTokenKeys = this.getTokenKeys();
431
+ const accountId = account.generateAccountId();
432
+ const removedCredentials = [];
433
+ allTokenKeys.idToken.forEach((key) => {
434
+ if (key.indexOf(accountId) === 0) {
435
+ this.removeIdToken(key);
436
+ }
437
+ });
438
+ allTokenKeys.accessToken.forEach((key) => {
439
+ if (key.indexOf(accountId) === 0) {
440
+ removedCredentials.push(this.removeAccessToken(key));
441
+ }
442
+ });
443
+ allTokenKeys.refreshToken.forEach((key) => {
444
+ if (key.indexOf(accountId) === 0) {
445
+ this.removeRefreshToken(key);
446
+ }
447
+ });
448
+ await Promise.all(removedCredentials);
449
+ }
450
+ /**
451
+ * returns a boolean if the given credential is removed
452
+ * @param credential
453
+ */
454
+ async removeAccessToken(key) {
455
+ const credential = this.getAccessTokenCredential(key);
456
+ if (!credential) {
457
+ return;
458
+ }
459
+ // Remove Token Binding Key from key store for PoP Tokens Credentials
460
+ if (credential.credentialType.toLowerCase() ===
461
+ CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME.toLowerCase()) {
462
+ if (credential.tokenType === AuthenticationScheme.POP) {
463
+ const accessTokenWithAuthSchemeEntity = credential;
464
+ const kid = accessTokenWithAuthSchemeEntity.keyId;
465
+ if (kid) {
466
+ try {
467
+ await this.cryptoImpl.removeTokenBindingKey(kid);
468
+ }
469
+ catch (error) {
470
+ throw createClientAuthError(bindingKeyNotRemoved);
471
+ }
472
+ }
473
+ }
474
+ }
475
+ return this.removeItem(key);
476
+ }
477
+ /**
478
+ * Removes all app metadata objects from cache.
479
+ */
480
+ removeAppMetadata() {
481
+ const allCacheKeys = this.getKeys();
482
+ allCacheKeys.forEach((cacheKey) => {
483
+ if (this.isAppMetadata(cacheKey)) {
484
+ this.removeItem(cacheKey);
485
+ }
486
+ });
487
+ return true;
488
+ }
489
+ /**
490
+ * Retrieve the cached credentials into a cacherecord
491
+ * @param account {AccountInfo}
492
+ * @param request {BaseAuthRequest}
493
+ * @param environment {string}
494
+ * @param performanceClient {?IPerformanceClient}
495
+ * @param correlationId {?string}
496
+ */
497
+ readCacheRecord(account, request, environment, performanceClient, correlationId) {
498
+ const tokenKeys = this.getTokenKeys();
499
+ const cachedAccount = this.readAccountFromCache(account);
500
+ const cachedIdToken = this.getIdToken(account, tokenKeys, performanceClient, correlationId);
501
+ const cachedAccessToken = this.getAccessToken(account, request, tokenKeys, performanceClient, correlationId);
502
+ const cachedRefreshToken = this.getRefreshToken(account, false, tokenKeys, performanceClient, correlationId);
503
+ const cachedAppMetadata = this.readAppMetadataFromCache(environment);
504
+ if (cachedAccount && cachedIdToken) {
505
+ cachedAccount.idTokenClaims = extractTokenClaims(cachedIdToken.secret, this.cryptoImpl.base64Decode);
506
+ }
507
+ return {
508
+ account: cachedAccount,
509
+ idToken: cachedIdToken,
510
+ accessToken: cachedAccessToken,
511
+ refreshToken: cachedRefreshToken,
512
+ appMetadata: cachedAppMetadata,
513
+ };
514
+ }
515
+ /**
516
+ * Retrieve AccountEntity from cache
517
+ * @param account
518
+ */
519
+ readAccountFromCache(account) {
520
+ const accountKey = AccountEntity.generateAccountCacheKey(account);
521
+ return this.getAccount(accountKey);
522
+ }
523
+ /**
524
+ * Retrieve IdTokenEntity from cache
525
+ * @param account {AccountInfo}
526
+ * @param tokenKeys {?TokenKeys}
527
+ * @param performanceClient {?IPerformanceClient}
528
+ * @param correlationId {?string}
529
+ */
530
+ getIdToken(account, tokenKeys, performanceClient, correlationId) {
531
+ this.commonLogger.trace("CacheManager - getIdToken called");
532
+ const idTokenFilter = {
533
+ homeAccountId: account.homeAccountId,
534
+ environment: account.environment,
535
+ credentialType: CredentialType.ID_TOKEN,
536
+ clientId: this.clientId,
537
+ realm: account.tenantId,
538
+ };
539
+ const idTokens = this.getIdTokensByFilter(idTokenFilter, tokenKeys);
540
+ const numIdTokens = idTokens.length;
541
+ if (numIdTokens < 1) {
542
+ this.commonLogger.info("CacheManager:getIdToken - No token found");
543
+ return null;
544
+ }
545
+ else if (numIdTokens > 1) {
546
+ this.commonLogger.info("CacheManager:getIdToken - Multiple id tokens found, clearing them");
547
+ idTokens.forEach((idToken) => {
548
+ this.removeIdToken(generateCredentialKey(idToken));
549
+ });
550
+ if (performanceClient && correlationId) {
551
+ performanceClient.addFields({ multiMatchedID: idTokens.length }, correlationId);
552
+ }
553
+ return null;
554
+ }
555
+ this.commonLogger.info("CacheManager:getIdToken - Returning id token");
556
+ return idTokens[0];
557
+ }
558
+ /**
559
+ * Gets all idTokens matching the given filter
560
+ * @param filter
561
+ * @returns
562
+ */
563
+ getIdTokensByFilter(filter, tokenKeys) {
564
+ const idTokenKeys = (tokenKeys && tokenKeys.idToken) || this.getTokenKeys().idToken;
565
+ const idTokens = [];
566
+ idTokenKeys.forEach((key) => {
567
+ if (!this.idTokenKeyMatchesFilter(key, {
568
+ clientId: this.clientId,
569
+ ...filter,
570
+ })) {
571
+ return;
572
+ }
573
+ const idToken = this.getIdTokenCredential(key);
574
+ if (idToken && this.credentialMatchesFilter(idToken, filter)) {
575
+ idTokens.push(idToken);
576
+ }
577
+ });
578
+ return idTokens;
579
+ }
580
+ /**
581
+ * Validate the cache key against filter before retrieving and parsing cache value
582
+ * @param key
583
+ * @param filter
584
+ * @returns
585
+ */
586
+ idTokenKeyMatchesFilter(inputKey, filter) {
587
+ const key = inputKey.toLowerCase();
588
+ if (filter.clientId &&
589
+ key.indexOf(filter.clientId.toLowerCase()) === -1) {
590
+ return false;
591
+ }
592
+ if (filter.homeAccountId &&
593
+ key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
594
+ return false;
595
+ }
596
+ return true;
597
+ }
598
+ /**
599
+ * Removes idToken from the cache
600
+ * @param key
601
+ */
602
+ removeIdToken(key) {
603
+ this.removeItem(key);
604
+ }
605
+ /**
606
+ * Removes refresh token from the cache
607
+ * @param key
608
+ */
609
+ removeRefreshToken(key) {
610
+ this.removeItem(key);
611
+ }
612
+ /**
613
+ * Retrieve AccessTokenEntity from cache
614
+ * @param account {AccountInfo}
615
+ * @param request {BaseAuthRequest}
616
+ * @param tokenKeys {?TokenKeys}
617
+ * @param performanceClient {?IPerformanceClient}
618
+ * @param correlationId {?string}
619
+ */
620
+ getAccessToken(account, request, tokenKeys, performanceClient, correlationId) {
621
+ this.commonLogger.trace("CacheManager - getAccessToken called");
622
+ const scopes = ScopeSet.createSearchScopes(request.scopes);
623
+ const authScheme = request.authenticationScheme || AuthenticationScheme.BEARER;
624
+ /*
625
+ * Distinguish between Bearer and PoP/SSH token cache types
626
+ * Cast to lowercase to handle "bearer" from ADFS
627
+ */
628
+ const credentialType = authScheme &&
629
+ authScheme.toLowerCase() !==
630
+ AuthenticationScheme.BEARER.toLowerCase()
631
+ ? CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME
632
+ : CredentialType.ACCESS_TOKEN;
633
+ const accessTokenFilter = {
634
+ homeAccountId: account.homeAccountId,
635
+ environment: account.environment,
636
+ credentialType: credentialType,
637
+ clientId: this.clientId,
638
+ realm: account.tenantId,
639
+ target: scopes,
640
+ tokenType: authScheme,
641
+ keyId: request.sshKid,
642
+ requestedClaimsHash: request.requestedClaimsHash,
643
+ };
644
+ const accessTokenKeys = (tokenKeys && tokenKeys.accessToken) ||
645
+ this.getTokenKeys().accessToken;
646
+ const accessTokens = [];
647
+ accessTokenKeys.forEach((key) => {
648
+ // Validate key
649
+ if (this.accessTokenKeyMatchesFilter(key, accessTokenFilter, true)) {
650
+ const accessToken = this.getAccessTokenCredential(key);
651
+ // Validate value
652
+ if (accessToken &&
653
+ this.credentialMatchesFilter(accessToken, accessTokenFilter)) {
654
+ accessTokens.push(accessToken);
655
+ }
656
+ }
657
+ });
658
+ const numAccessTokens = accessTokens.length;
659
+ if (numAccessTokens < 1) {
660
+ this.commonLogger.info("CacheManager:getAccessToken - No token found");
661
+ return null;
662
+ }
663
+ else if (numAccessTokens > 1) {
664
+ this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them");
665
+ accessTokens.forEach((accessToken) => {
666
+ void this.removeAccessToken(generateCredentialKey(accessToken));
667
+ });
668
+ if (performanceClient && correlationId) {
669
+ performanceClient.addFields({ multiMatchedAT: accessTokens.length }, correlationId);
670
+ }
671
+ return null;
672
+ }
673
+ this.commonLogger.info("CacheManager:getAccessToken - Returning access token");
674
+ return accessTokens[0];
675
+ }
676
+ /**
677
+ * Validate the cache key against filter before retrieving and parsing cache value
678
+ * @param key
679
+ * @param filter
680
+ * @param keyMustContainAllScopes
681
+ * @returns
682
+ */
683
+ accessTokenKeyMatchesFilter(inputKey, filter, keyMustContainAllScopes) {
684
+ const key = inputKey.toLowerCase();
685
+ if (filter.clientId &&
686
+ key.indexOf(filter.clientId.toLowerCase()) === -1) {
687
+ return false;
688
+ }
689
+ if (filter.homeAccountId &&
690
+ key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
691
+ return false;
692
+ }
693
+ if (filter.realm && key.indexOf(filter.realm.toLowerCase()) === -1) {
694
+ return false;
695
+ }
696
+ if (filter.requestedClaimsHash &&
697
+ key.indexOf(filter.requestedClaimsHash.toLowerCase()) === -1) {
698
+ return false;
699
+ }
700
+ if (filter.target) {
701
+ const scopes = filter.target.asArray();
702
+ for (let i = 0; i < scopes.length; i++) {
703
+ if (keyMustContainAllScopes &&
704
+ !key.includes(scopes[i].toLowerCase())) {
705
+ // When performing a cache lookup a missing scope would be a cache miss
706
+ return false;
707
+ }
708
+ else if (!keyMustContainAllScopes &&
709
+ key.includes(scopes[i].toLowerCase())) {
710
+ // When performing a cache write, any token with a subset of requested scopes should be replaced
711
+ return true;
712
+ }
713
+ }
714
+ }
715
+ return true;
716
+ }
717
+ /**
718
+ * Gets all access tokens matching the filter
719
+ * @param filter
720
+ * @returns
721
+ */
722
+ getAccessTokensByFilter(filter) {
723
+ const tokenKeys = this.getTokenKeys();
724
+ const accessTokens = [];
725
+ tokenKeys.accessToken.forEach((key) => {
726
+ if (!this.accessTokenKeyMatchesFilter(key, filter, true)) {
727
+ return;
728
+ }
729
+ const accessToken = this.getAccessTokenCredential(key);
730
+ if (accessToken &&
731
+ this.credentialMatchesFilter(accessToken, filter)) {
732
+ accessTokens.push(accessToken);
733
+ }
734
+ });
735
+ return accessTokens;
736
+ }
737
+ /**
738
+ * Helper to retrieve the appropriate refresh token from cache
739
+ * @param account {AccountInfo}
740
+ * @param familyRT {boolean}
741
+ * @param tokenKeys {?TokenKeys}
742
+ * @param performanceClient {?IPerformanceClient}
743
+ * @param correlationId {?string}
744
+ */
745
+ getRefreshToken(account, familyRT, tokenKeys, performanceClient, correlationId) {
746
+ this.commonLogger.trace("CacheManager - getRefreshToken called");
747
+ const id = familyRT ? THE_FAMILY_ID : undefined;
748
+ const refreshTokenFilter = {
749
+ homeAccountId: account.homeAccountId,
750
+ environment: account.environment,
751
+ credentialType: CredentialType.REFRESH_TOKEN,
752
+ clientId: this.clientId,
753
+ familyId: id,
754
+ };
755
+ const refreshTokenKeys = (tokenKeys && tokenKeys.refreshToken) ||
756
+ this.getTokenKeys().refreshToken;
757
+ const refreshTokens = [];
758
+ refreshTokenKeys.forEach((key) => {
759
+ // Validate key
760
+ if (this.refreshTokenKeyMatchesFilter(key, refreshTokenFilter)) {
761
+ const refreshToken = this.getRefreshTokenCredential(key);
762
+ // Validate value
763
+ if (refreshToken &&
764
+ this.credentialMatchesFilter(refreshToken, refreshTokenFilter)) {
765
+ refreshTokens.push(refreshToken);
766
+ }
767
+ }
768
+ });
769
+ const numRefreshTokens = refreshTokens.length;
770
+ if (numRefreshTokens < 1) {
771
+ this.commonLogger.info("CacheManager:getRefreshToken - No refresh token found.");
772
+ return null;
773
+ }
774
+ // address the else case after remove functions address environment aliases
775
+ if (numRefreshTokens > 1 && performanceClient && correlationId) {
776
+ performanceClient.addFields({ multiMatchedRT: numRefreshTokens }, correlationId);
777
+ }
778
+ this.commonLogger.info("CacheManager:getRefreshToken - returning refresh token");
779
+ return refreshTokens[0];
780
+ }
781
+ /**
782
+ * Validate the cache key against filter before retrieving and parsing cache value
783
+ * @param key
784
+ * @param filter
785
+ */
786
+ refreshTokenKeyMatchesFilter(inputKey, filter) {
787
+ const key = inputKey.toLowerCase();
788
+ if (filter.familyId &&
789
+ key.indexOf(filter.familyId.toLowerCase()) === -1) {
790
+ return false;
791
+ }
792
+ // If familyId is used, clientId is not in the key
793
+ if (!filter.familyId &&
794
+ filter.clientId &&
795
+ key.indexOf(filter.clientId.toLowerCase()) === -1) {
796
+ return false;
797
+ }
798
+ if (filter.homeAccountId &&
799
+ key.indexOf(filter.homeAccountId.toLowerCase()) === -1) {
800
+ return false;
801
+ }
802
+ return true;
803
+ }
804
+ /**
805
+ * Retrieve AppMetadataEntity from cache
806
+ */
807
+ readAppMetadataFromCache(environment) {
808
+ const appMetadataFilter = {
809
+ environment,
810
+ clientId: this.clientId,
811
+ };
812
+ const appMetadata = this.getAppMetadataFilteredBy(appMetadataFilter);
813
+ const appMetadataEntries = Object.keys(appMetadata).map((key) => appMetadata[key]);
814
+ const numAppMetadata = appMetadataEntries.length;
815
+ if (numAppMetadata < 1) {
816
+ return null;
817
+ }
818
+ else if (numAppMetadata > 1) {
819
+ throw createClientAuthError(multipleMatchingAppMetadata);
820
+ }
821
+ return appMetadataEntries[0];
822
+ }
823
+ /**
824
+ * Return the family_id value associated with FOCI
825
+ * @param environment
826
+ * @param clientId
827
+ */
828
+ isAppMetadataFOCI(environment) {
829
+ const appMetadata = this.readAppMetadataFromCache(environment);
830
+ return !!(appMetadata && appMetadata.familyId === THE_FAMILY_ID);
831
+ }
832
+ /**
833
+ * helper to match account ids
834
+ * @param value
835
+ * @param homeAccountId
836
+ */
837
+ matchHomeAccountId(entity, homeAccountId) {
838
+ return !!(typeof entity.homeAccountId === "string" &&
839
+ homeAccountId === entity.homeAccountId);
840
+ }
841
+ /**
842
+ * helper to match account ids
843
+ * @param entity
844
+ * @param localAccountId
845
+ * @returns
846
+ */
847
+ matchLocalAccountId(entity, localAccountId) {
848
+ return !!(typeof entity.localAccountId === "string" &&
849
+ localAccountId === entity.localAccountId);
850
+ }
851
+ /**
852
+ * helper to match usernames
853
+ * @param entity
854
+ * @param username
855
+ * @returns
856
+ */
857
+ matchUsername(entity, username) {
858
+ return !!(typeof entity.username === "string" &&
859
+ username.toLowerCase() === entity.username.toLowerCase());
860
+ }
861
+ /**
862
+ * helper to match names
863
+ * @param entity
864
+ * @param name
865
+ * @returns true if the downcased name properties are present and match in the filter and the entity
866
+ */
867
+ matchName(entity, name) {
868
+ return !!(name.toLowerCase() === entity.name?.toLowerCase());
869
+ }
870
+ /**
871
+ * helper to match assertion
872
+ * @param value
873
+ * @param oboAssertion
874
+ */
875
+ matchUserAssertionHash(entity, userAssertionHash) {
876
+ return !!(entity.userAssertionHash &&
877
+ userAssertionHash === entity.userAssertionHash);
878
+ }
879
+ /**
880
+ * helper to match environment
881
+ * @param value
882
+ * @param environment
883
+ */
884
+ matchEnvironment(entity, environment) {
885
+ // Check static authority options first for cases where authority metadata has not been resolved and cached yet
886
+ if (this.staticAuthorityOptions) {
887
+ const staticAliases = getAliasesFromStaticSources(this.staticAuthorityOptions, this.commonLogger);
888
+ if (staticAliases.includes(environment) &&
889
+ staticAliases.includes(entity.environment)) {
890
+ return true;
891
+ }
892
+ }
893
+ // Query metadata cache if no static authority configuration has aliases that match enviroment
894
+ const cloudMetadata = this.getAuthorityMetadataByAlias(environment);
895
+ if (cloudMetadata &&
896
+ cloudMetadata.aliases.indexOf(entity.environment) > -1) {
897
+ return true;
898
+ }
899
+ return false;
900
+ }
901
+ /**
902
+ * helper to match credential type
903
+ * @param entity
904
+ * @param credentialType
905
+ */
906
+ matchCredentialType(entity, credentialType) {
907
+ return (entity.credentialType &&
908
+ credentialType.toLowerCase() === entity.credentialType.toLowerCase());
909
+ }
910
+ /**
911
+ * helper to match client ids
912
+ * @param entity
913
+ * @param clientId
914
+ */
915
+ matchClientId(entity, clientId) {
916
+ return !!(entity.clientId && clientId === entity.clientId);
917
+ }
918
+ /**
919
+ * helper to match family ids
920
+ * @param entity
921
+ * @param familyId
922
+ */
923
+ matchFamilyId(entity, familyId) {
924
+ return !!(entity.familyId && familyId === entity.familyId);
925
+ }
926
+ /**
927
+ * helper to match realm
928
+ * @param entity
929
+ * @param realm
930
+ */
931
+ matchRealm(entity, realm) {
932
+ return !!(entity.realm && realm === entity.realm);
933
+ }
934
+ /**
935
+ * helper to match nativeAccountId
936
+ * @param entity
937
+ * @param nativeAccountId
938
+ * @returns boolean indicating the match result
939
+ */
940
+ matchNativeAccountId(entity, nativeAccountId) {
941
+ return !!(entity.nativeAccountId && nativeAccountId === entity.nativeAccountId);
942
+ }
943
+ /**
944
+ * helper to match loginHint which can be either:
945
+ * 1. login_hint ID token claim
946
+ * 2. username in cached account object
947
+ * 3. upn in ID token claims
948
+ * @param entity
949
+ * @param loginHint
950
+ * @returns
951
+ */
952
+ matchLoginHint(idTokenClaims, loginHint) {
953
+ if (idTokenClaims?.login_hint === loginHint) {
954
+ return true;
955
+ }
956
+ if (idTokenClaims.preferred_username === loginHint) {
957
+ return true;
958
+ }
959
+ if (idTokenClaims?.upn === loginHint) {
960
+ return true;
961
+ }
962
+ return false;
963
+ }
964
+ /**
965
+ * Helper to match sid
966
+ * @param idTokenClaims
967
+ * @param sid
968
+ * @returns true if the sid claim is present and matches the filter
969
+ */
970
+ matchSid(idTokenClaims, sid) {
971
+ return !!(idTokenClaims?.sid && idTokenClaims.sid === sid);
972
+ }
973
+ matchAuthorityType(entity, authorityType) {
974
+ return !!(entity.authorityType &&
975
+ authorityType.toLowerCase() === entity.authorityType.toLowerCase());
976
+ }
977
+ /**
978
+ * Returns true if the target scopes are a subset of the current entity's scopes, false otherwise.
979
+ * @param entity
980
+ * @param target
981
+ */
982
+ matchTarget(entity, target) {
983
+ const isNotAccessTokenCredential = entity.credentialType !== CredentialType.ACCESS_TOKEN &&
984
+ entity.credentialType !==
985
+ CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
986
+ if (isNotAccessTokenCredential || !entity.target) {
987
+ return false;
988
+ }
989
+ const entityScopeSet = ScopeSet.fromString(entity.target);
990
+ return entityScopeSet.containsScopeSet(target);
991
+ }
992
+ /**
993
+ * Returns true if the credential's tokenType or Authentication Scheme matches the one in the request, false otherwise
994
+ * @param entity
995
+ * @param tokenType
996
+ */
997
+ matchTokenType(entity, tokenType) {
998
+ return !!(entity.tokenType && entity.tokenType === tokenType);
999
+ }
1000
+ /**
1001
+ * Returns true if the credential's keyId matches the one in the request, false otherwise
1002
+ * @param entity
1003
+ * @param tokenType
1004
+ */
1005
+ matchKeyId(entity, keyId) {
1006
+ return !!(entity.keyId && entity.keyId === keyId);
1007
+ }
1008
+ /**
1009
+ * returns if a given cache entity is of the type appmetadata
1010
+ * @param key
1011
+ */
1012
+ isAppMetadata(key) {
1013
+ return key.indexOf(APP_METADATA) !== -1;
1014
+ }
1015
+ /**
1016
+ * returns if a given cache entity is of the type authoritymetadata
1017
+ * @param key
1018
+ */
1019
+ isAuthorityMetadata(key) {
1020
+ return key.indexOf(AUTHORITY_METADATA_CONSTANTS.CACHE_KEY) !== -1;
1021
+ }
1022
+ /**
1023
+ * returns cache key used for cloud instance metadata
1024
+ */
1025
+ generateAuthorityMetadataCacheKey(authority) {
1026
+ return `${AUTHORITY_METADATA_CONSTANTS.CACHE_KEY}-${this.clientId}-${authority}`;
1027
+ }
1028
+ /**
1029
+ * Helper to convert serialized data to object
1030
+ * @param obj
1031
+ * @param json
1032
+ */
1033
+ static toObject(obj, json) {
1034
+ for (const propertyName in json) {
1035
+ obj[propertyName] = json[propertyName];
1036
+ }
1037
+ return obj;
1038
+ }
1039
+ }
1040
+ /** @internal */
1041
+ class DefaultStorageClass extends CacheManager {
1042
+ setAccount() {
1043
+ throw createClientAuthError(methodNotImplemented);
1044
+ }
1045
+ getAccount() {
1046
+ throw createClientAuthError(methodNotImplemented);
1047
+ }
1048
+ setIdTokenCredential() {
1049
+ throw createClientAuthError(methodNotImplemented);
1050
+ }
1051
+ getIdTokenCredential() {
1052
+ throw createClientAuthError(methodNotImplemented);
1053
+ }
1054
+ setAccessTokenCredential() {
1055
+ throw createClientAuthError(methodNotImplemented);
1056
+ }
1057
+ getAccessTokenCredential() {
1058
+ throw createClientAuthError(methodNotImplemented);
1059
+ }
1060
+ setRefreshTokenCredential() {
1061
+ throw createClientAuthError(methodNotImplemented);
1062
+ }
1063
+ getRefreshTokenCredential() {
1064
+ throw createClientAuthError(methodNotImplemented);
1065
+ }
1066
+ setAppMetadata() {
1067
+ throw createClientAuthError(methodNotImplemented);
1068
+ }
1069
+ getAppMetadata() {
1070
+ throw createClientAuthError(methodNotImplemented);
1071
+ }
1072
+ setServerTelemetry() {
1073
+ throw createClientAuthError(methodNotImplemented);
1074
+ }
1075
+ getServerTelemetry() {
1076
+ throw createClientAuthError(methodNotImplemented);
1077
+ }
1078
+ setAuthorityMetadata() {
1079
+ throw createClientAuthError(methodNotImplemented);
1080
+ }
1081
+ getAuthorityMetadata() {
1082
+ throw createClientAuthError(methodNotImplemented);
1083
+ }
1084
+ getAuthorityMetadataKeys() {
1085
+ throw createClientAuthError(methodNotImplemented);
1086
+ }
1087
+ setThrottlingCache() {
1088
+ throw createClientAuthError(methodNotImplemented);
1089
+ }
1090
+ getThrottlingCache() {
1091
+ throw createClientAuthError(methodNotImplemented);
1092
+ }
1093
+ removeItem() {
1094
+ throw createClientAuthError(methodNotImplemented);
1095
+ }
1096
+ containsKey() {
1097
+ throw createClientAuthError(methodNotImplemented);
1098
+ }
1099
+ getKeys() {
1100
+ throw createClientAuthError(methodNotImplemented);
1101
+ }
1102
+ getAccountKeys() {
1103
+ throw createClientAuthError(methodNotImplemented);
1104
+ }
1105
+ getTokenKeys() {
1106
+ throw createClientAuthError(methodNotImplemented);
1107
+ }
1108
+ async clear() {
1109
+ throw createClientAuthError(methodNotImplemented);
1110
+ }
1111
+ updateCredentialCacheKey() {
1112
+ throw createClientAuthError(methodNotImplemented);
1113
+ }
1114
1114
  }
1115
1115
 
1116
1116
  export { CacheManager, DefaultStorageClass };