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