@azure/msal-common 14.0.1 → 14.0.3

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 (295) hide show
  1. package/dist/account/AuthToken.d.ts +14 -17
  2. package/dist/account/AuthToken.d.ts.map +1 -1
  3. package/dist/account/AuthToken.mjs +48 -39
  4. package/dist/account/AuthToken.mjs.map +1 -1
  5. package/dist/account/CcsCredential.mjs +1 -1
  6. package/dist/account/CcsCredential.mjs.map +1 -1
  7. package/dist/account/ClientInfo.d.ts.map +1 -1
  8. package/dist/account/ClientInfo.mjs +3 -4
  9. package/dist/account/ClientInfo.mjs.map +1 -1
  10. package/dist/authority/Authority.d.ts +1 -0
  11. package/dist/authority/Authority.d.ts.map +1 -1
  12. package/dist/authority/Authority.mjs +4 -2
  13. package/dist/authority/Authority.mjs.map +1 -1
  14. package/dist/authority/AuthorityFactory.d.ts +1 -0
  15. package/dist/authority/AuthorityFactory.d.ts.map +1 -1
  16. package/dist/authority/AuthorityFactory.mjs +3 -3
  17. package/dist/authority/AuthorityFactory.mjs.map +1 -1
  18. package/dist/authority/AuthorityMetadata.mjs +1 -1
  19. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  20. package/dist/authority/AuthorityOptions.mjs +1 -1
  21. package/dist/authority/AuthorityOptions.mjs.map +1 -1
  22. package/dist/authority/AuthorityType.mjs +1 -1
  23. package/dist/authority/AuthorityType.mjs.map +1 -1
  24. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  25. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs.map +1 -1
  26. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  27. package/dist/authority/CloudInstanceDiscoveryResponse.mjs.map +1 -1
  28. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  29. package/dist/authority/OpenIdConfigResponse.mjs.map +1 -1
  30. package/dist/authority/ProtocolMode.mjs +1 -1
  31. package/dist/authority/ProtocolMode.mjs.map +1 -1
  32. package/dist/authority/RegionDiscovery.mjs +1 -1
  33. package/dist/authority/RegionDiscovery.mjs.map +1 -1
  34. package/dist/cache/CacheManager.d.ts +2 -0
  35. package/dist/cache/CacheManager.d.ts.map +1 -1
  36. package/dist/cache/CacheManager.mjs +7 -5
  37. package/dist/cache/CacheManager.mjs.map +1 -1
  38. package/dist/cache/entities/AccessTokenEntity.d.ts.map +1 -1
  39. package/dist/cache/entities/AccessTokenEntity.mjs +4 -7
  40. package/dist/cache/entities/AccessTokenEntity.mjs.map +1 -1
  41. package/dist/cache/entities/AccountEntity.d.ts +1 -0
  42. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  43. package/dist/cache/entities/AccountEntity.mjs +3 -4
  44. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  45. package/dist/cache/entities/AppMetadataEntity.mjs +1 -1
  46. package/dist/cache/entities/AppMetadataEntity.mjs.map +1 -1
  47. package/dist/cache/entities/AuthorityMetadataEntity.d.ts +1 -0
  48. package/dist/cache/entities/AuthorityMetadataEntity.d.ts.map +1 -1
  49. package/dist/cache/entities/AuthorityMetadataEntity.mjs +2 -1
  50. package/dist/cache/entities/AuthorityMetadataEntity.mjs.map +1 -1
  51. package/dist/cache/entities/CacheRecord.d.ts +1 -0
  52. package/dist/cache/entities/CacheRecord.d.ts.map +1 -1
  53. package/dist/cache/entities/CacheRecord.mjs +2 -1
  54. package/dist/cache/entities/CacheRecord.mjs.map +1 -1
  55. package/dist/cache/entities/CredentialEntity.mjs +1 -1
  56. package/dist/cache/entities/CredentialEntity.mjs.map +1 -1
  57. package/dist/cache/entities/IdTokenEntity.mjs +1 -1
  58. package/dist/cache/entities/IdTokenEntity.mjs.map +1 -1
  59. package/dist/cache/entities/RefreshTokenEntity.mjs +1 -1
  60. package/dist/cache/entities/RefreshTokenEntity.mjs.map +1 -1
  61. package/dist/cache/entities/ServerTelemetryEntity.mjs +1 -1
  62. package/dist/cache/entities/ServerTelemetryEntity.mjs.map +1 -1
  63. package/dist/cache/entities/ThrottlingEntity.mjs +1 -1
  64. package/dist/cache/entities/ThrottlingEntity.mjs.map +1 -1
  65. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  66. package/dist/cache/persistence/TokenCacheContext.mjs.map +1 -1
  67. package/dist/cache/utils/CacheTypes.d.ts +7 -0
  68. package/dist/cache/utils/CacheTypes.d.ts.map +1 -1
  69. package/dist/client/AuthorizationCodeClient.d.ts +1 -0
  70. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  71. package/dist/client/AuthorizationCodeClient.mjs +11 -39
  72. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  73. package/dist/client/BaseClient.d.ts +2 -1
  74. package/dist/client/BaseClient.d.ts.map +1 -1
  75. package/dist/client/BaseClient.mjs +9 -2
  76. package/dist/client/BaseClient.mjs.map +1 -1
  77. package/dist/client/RefreshTokenClient.d.ts +1 -0
  78. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  79. package/dist/client/RefreshTokenClient.mjs +3 -11
  80. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  81. package/dist/client/SilentFlowClient.d.ts +1 -0
  82. package/dist/client/SilentFlowClient.d.ts.map +1 -1
  83. package/dist/client/SilentFlowClient.mjs +8 -7
  84. package/dist/client/SilentFlowClient.mjs.map +1 -1
  85. package/dist/config/ClientConfiguration.d.ts +2 -0
  86. package/dist/config/ClientConfiguration.d.ts.map +1 -1
  87. package/dist/config/ClientConfiguration.mjs +1 -1
  88. package/dist/config/ClientConfiguration.mjs.map +1 -1
  89. package/dist/crypto/ICrypto.mjs +1 -1
  90. package/dist/crypto/ICrypto.mjs.map +1 -1
  91. package/dist/crypto/JoseHeader.d.ts +1 -0
  92. package/dist/crypto/JoseHeader.d.ts.map +1 -1
  93. package/dist/crypto/JoseHeader.mjs +2 -1
  94. package/dist/crypto/JoseHeader.mjs.map +1 -1
  95. package/dist/crypto/PopTokenGenerator.d.ts +1 -0
  96. package/dist/crypto/PopTokenGenerator.d.ts.map +1 -1
  97. package/dist/crypto/PopTokenGenerator.mjs +2 -1
  98. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  99. package/dist/error/AuthError.mjs +1 -1
  100. package/dist/error/AuthError.mjs.map +1 -1
  101. package/dist/error/ClientAuthError.mjs +1 -1
  102. package/dist/error/ClientAuthError.mjs.map +1 -1
  103. package/dist/error/ClientConfigurationError.mjs +1 -1
  104. package/dist/error/ClientConfigurationError.mjs.map +1 -1
  105. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  106. package/dist/error/InteractionRequiredAuthError.mjs.map +1 -1
  107. package/dist/error/JoseHeaderError.mjs +1 -1
  108. package/dist/error/JoseHeaderError.mjs.map +1 -1
  109. package/dist/error/ServerError.mjs +1 -1
  110. package/dist/error/ServerError.mjs.map +1 -1
  111. package/dist/index.cjs +1926 -1826
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.d.ts +4 -3
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.mjs +5 -3
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/logger/Logger.d.ts.map +1 -1
  118. package/dist/logger/Logger.mjs +2 -12
  119. package/dist/logger/Logger.mjs.map +1 -1
  120. package/dist/network/INetworkModule.mjs +1 -1
  121. package/dist/network/INetworkModule.mjs.map +1 -1
  122. package/dist/network/NetworkManager.d.ts +1 -0
  123. package/dist/network/NetworkManager.d.ts.map +1 -1
  124. package/dist/network/NetworkManager.mjs +2 -1
  125. package/dist/network/NetworkManager.mjs.map +1 -1
  126. package/dist/network/ThrottlingUtils.d.ts +1 -0
  127. package/dist/network/ThrottlingUtils.d.ts.map +1 -1
  128. package/dist/network/ThrottlingUtils.mjs +2 -1
  129. package/dist/network/ThrottlingUtils.mjs.map +1 -1
  130. package/dist/packageMetadata.d.ts +1 -1
  131. package/dist/packageMetadata.mjs +2 -2
  132. package/dist/packageMetadata.mjs.map +1 -1
  133. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  134. package/dist/request/AuthenticationHeaderParser.mjs.map +1 -1
  135. package/dist/request/RequestParameterBuilder.d.ts +1 -0
  136. package/dist/request/RequestParameterBuilder.d.ts.map +1 -1
  137. package/dist/request/RequestParameterBuilder.mjs +7 -7
  138. package/dist/request/RequestParameterBuilder.mjs.map +1 -1
  139. package/dist/request/RequestValidator.d.ts.map +1 -1
  140. package/dist/request/RequestValidator.mjs +4 -6
  141. package/dist/request/RequestValidator.mjs.map +1 -1
  142. package/dist/request/ScopeSet.mjs +4 -4
  143. package/dist/request/ScopeSet.mjs.map +1 -1
  144. package/dist/response/AuthenticationResult.d.ts +3 -1
  145. package/dist/response/AuthenticationResult.d.ts.map +1 -1
  146. package/dist/response/ResponseHandler.d.ts +5 -3
  147. package/dist/response/ResponseHandler.d.ts.map +1 -1
  148. package/dist/response/ResponseHandler.mjs +58 -39
  149. package/dist/response/ResponseHandler.mjs.map +1 -1
  150. package/dist/response/ServerAuthorizationTokenResponse.d.ts +2 -0
  151. package/dist/response/ServerAuthorizationTokenResponse.d.ts.map +1 -1
  152. package/dist/telemetry/performance/IPerformanceClient.d.ts +4 -4
  153. package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
  154. package/dist/telemetry/performance/PerformanceClient.d.ts +2 -2
  155. package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
  156. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  157. package/dist/telemetry/performance/PerformanceClient.mjs.map +1 -1
  158. package/dist/telemetry/performance/PerformanceEvent.d.ts +8 -1
  159. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  160. package/dist/telemetry/performance/PerformanceEvent.mjs +9 -1
  161. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  162. package/dist/telemetry/performance/StubPerformanceClient.d.ts +3 -3
  163. package/dist/telemetry/performance/StubPerformanceClient.d.ts.map +1 -1
  164. package/dist/telemetry/performance/StubPerformanceClient.mjs +23 -3
  165. package/dist/telemetry/performance/StubPerformanceClient.mjs.map +1 -1
  166. package/dist/telemetry/server/ServerTelemetryManager.d.ts +1 -0
  167. package/dist/telemetry/server/ServerTelemetryManager.d.ts.map +1 -1
  168. package/dist/telemetry/server/ServerTelemetryManager.mjs +4 -4
  169. package/dist/telemetry/server/ServerTelemetryManager.mjs.map +1 -1
  170. package/dist/url/UrlString.d.ts.map +1 -1
  171. package/dist/url/UrlString.mjs +10 -12
  172. package/dist/url/UrlString.mjs.map +1 -1
  173. package/dist/utils/Constants.d.ts +10 -0
  174. package/dist/utils/Constants.d.ts.map +1 -1
  175. package/dist/utils/Constants.mjs +11 -2
  176. package/dist/utils/Constants.mjs.map +1 -1
  177. package/dist/utils/FunctionWrappers.d.ts +28 -0
  178. package/dist/utils/FunctionWrappers.d.ts.map +1 -0
  179. package/dist/utils/FunctionWrappers.mjs +90 -0
  180. package/dist/utils/FunctionWrappers.mjs.map +1 -0
  181. package/dist/utils/ProtocolUtils.d.ts.map +1 -1
  182. package/dist/utils/ProtocolUtils.mjs +4 -7
  183. package/dist/utils/ProtocolUtils.mjs.map +1 -1
  184. package/dist/utils/StringUtils.d.ts +0 -13
  185. package/dist/utils/StringUtils.d.ts.map +1 -1
  186. package/dist/utils/StringUtils.mjs +3 -34
  187. package/dist/utils/StringUtils.mjs.map +1 -1
  188. package/dist/utils/TimeUtils.mjs +1 -1
  189. package/dist/utils/TimeUtils.mjs.map +1 -1
  190. package/package.json +6 -4
  191. package/src/account/AccountInfo.ts +44 -0
  192. package/src/account/AuthToken.ts +70 -0
  193. package/src/account/CcsCredential.ts +16 -0
  194. package/src/account/ClientCredentials.ts +20 -0
  195. package/src/account/ClientInfo.ts +64 -0
  196. package/src/account/TokenClaims.ts +70 -0
  197. package/src/authority/Authority.ts +1225 -0
  198. package/src/authority/AuthorityFactory.ts +106 -0
  199. package/src/authority/AuthorityMetadata.ts +953 -0
  200. package/src/authority/AuthorityOptions.ts +40 -0
  201. package/src/authority/AuthorityType.ts +15 -0
  202. package/src/authority/AzureRegion.ts +7 -0
  203. package/src/authority/AzureRegionConfiguration.ts +16 -0
  204. package/src/authority/CloudDiscoveryMetadata.ts +10 -0
  205. package/src/authority/CloudInstanceDiscoveryErrorResponse.ts +26 -0
  206. package/src/authority/CloudInstanceDiscoveryResponse.ts +21 -0
  207. package/src/authority/ImdsOptions.ts +10 -0
  208. package/src/authority/OIDCOptions.ts +14 -0
  209. package/src/authority/OpenIdConfigResponse.ts +24 -0
  210. package/src/authority/ProtocolMode.ts +13 -0
  211. package/src/authority/RegionDiscovery.ts +193 -0
  212. package/src/authority/RegionDiscoveryMetadata.ts +15 -0
  213. package/src/broker/nativeBroker/INativeBrokerPlugin.ts +29 -0
  214. package/src/cache/CacheManager.ts +1619 -0
  215. package/src/cache/entities/AccessTokenEntity.ts +162 -0
  216. package/src/cache/entities/AccountEntity.ts +309 -0
  217. package/src/cache/entities/AppMetadataEntity.ts +91 -0
  218. package/src/cache/entities/AuthorityMetadataEntity.ts +112 -0
  219. package/src/cache/entities/CacheRecord.ts +33 -0
  220. package/src/cache/entities/CredentialEntity.ts +215 -0
  221. package/src/cache/entities/IdTokenEntity.ts +74 -0
  222. package/src/cache/entities/RefreshTokenEntity.ts +78 -0
  223. package/src/cache/entities/ServerTelemetryEntity.ts +38 -0
  224. package/src/cache/entities/ThrottlingEntity.ts +36 -0
  225. package/src/cache/interface/ICacheManager.ts +218 -0
  226. package/src/cache/interface/ICachePlugin.ts +11 -0
  227. package/src/cache/interface/ISerializableTokenCache.ts +9 -0
  228. package/src/cache/persistence/TokenCacheContext.ts +39 -0
  229. package/src/cache/utils/CacheTypes.ts +93 -0
  230. package/src/client/AuthorizationCodeClient.ts +714 -0
  231. package/src/client/BaseClient.ts +205 -0
  232. package/src/client/RefreshTokenClient.ts +442 -0
  233. package/src/client/SilentFlowClient.ts +186 -0
  234. package/src/config/AppTokenProvider.ts +47 -0
  235. package/src/config/ClientConfiguration.ts +287 -0
  236. package/src/crypto/ICrypto.ts +127 -0
  237. package/src/crypto/IGuidGenerator.ts +9 -0
  238. package/src/crypto/JoseHeader.ts +55 -0
  239. package/src/crypto/PopTokenGenerator.ts +155 -0
  240. package/src/crypto/SignedHttpRequest.ts +16 -0
  241. package/src/error/AuthError.ts +85 -0
  242. package/src/error/ClientAuthError.ts +738 -0
  243. package/src/error/ClientConfigurationError.ts +396 -0
  244. package/src/error/InteractionRequiredAuthError.ts +134 -0
  245. package/src/error/JoseHeaderError.ts +52 -0
  246. package/src/error/ServerError.ts +18 -0
  247. package/src/index.ts +215 -0
  248. package/src/logger/Logger.ts +272 -0
  249. package/src/network/INetworkModule.ts +57 -0
  250. package/src/network/NetworkManager.ts +76 -0
  251. package/src/network/RequestThumbprint.ts +22 -0
  252. package/src/network/ThrottlingUtils.ts +156 -0
  253. package/src/packageMetadata.ts +3 -0
  254. package/src/request/AuthenticationHeaderParser.ts +89 -0
  255. package/src/request/BaseAuthRequest.ts +46 -0
  256. package/src/request/CommonAuthorizationCodeRequest.ts +33 -0
  257. package/src/request/CommonAuthorizationUrlRequest.ts +56 -0
  258. package/src/request/CommonClientCredentialRequest.ts +23 -0
  259. package/src/request/CommonDeviceCodeRequest.ts +31 -0
  260. package/src/request/CommonEndSessionRequest.ts +27 -0
  261. package/src/request/CommonOnBehalfOfRequest.ts +19 -0
  262. package/src/request/CommonRefreshTokenRequest.ts +25 -0
  263. package/src/request/CommonSilentFlowRequest.ts +24 -0
  264. package/src/request/CommonUsernamePasswordRequest.ts +23 -0
  265. package/src/request/NativeRequest.ts +25 -0
  266. package/src/request/NativeSignOutRequest.ts +10 -0
  267. package/src/request/RequestParameterBuilder.ts +606 -0
  268. package/src/request/RequestValidator.ts +103 -0
  269. package/src/request/ScopeSet.ts +230 -0
  270. package/src/request/StoreInCache.ts +16 -0
  271. package/src/response/AuthenticationResult.ts +47 -0
  272. package/src/response/AuthorizationCodePayload.ts +18 -0
  273. package/src/response/DeviceCodeResponse.ts +31 -0
  274. package/src/response/ExternalTokenResponse.ts +24 -0
  275. package/src/response/IMDSBadResponse.ts +9 -0
  276. package/src/response/ResponseHandler.ts +614 -0
  277. package/src/response/ServerAuthorizationCodeResponse.ts +33 -0
  278. package/src/response/ServerAuthorizationTokenResponse.ts +54 -0
  279. package/src/telemetry/performance/IPerformanceClient.ts +71 -0
  280. package/src/telemetry/performance/IPerformanceMeasurement.ts +10 -0
  281. package/src/telemetry/performance/PerformanceClient.ts +635 -0
  282. package/src/telemetry/performance/PerformanceEvent.ts +542 -0
  283. package/src/telemetry/performance/StubPerformanceClient.ts +101 -0
  284. package/src/telemetry/server/ServerTelemetryManager.ts +274 -0
  285. package/src/telemetry/server/ServerTelemetryRequest.ts +13 -0
  286. package/src/url/IUri.ts +17 -0
  287. package/src/url/UrlString.ts +363 -0
  288. package/src/utils/Constants.ts +436 -0
  289. package/src/utils/FunctionWrappers.ts +105 -0
  290. package/src/utils/MsalTypes.ts +9 -0
  291. package/src/utils/ProtocolUtils.ts +124 -0
  292. package/src/utils/StringUtils.ts +106 -0
  293. package/src/utils/TimeUtils.ts +51 -0
  294. package/dist/account/DecodedAuthToken.d.ts +0 -9
  295. package/dist/account/DecodedAuthToken.d.ts.map +0 -1
@@ -0,0 +1,274 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ SERVER_TELEM_CONSTANTS,
8
+ Separators,
9
+ CacheOutcome,
10
+ Constants,
11
+ RegionDiscoverySources,
12
+ RegionDiscoveryOutcomes,
13
+ } from "../../utils/Constants";
14
+ import { CacheManager } from "../../cache/CacheManager";
15
+ import { AuthError } from "../../error/AuthError";
16
+ import { ServerTelemetryRequest } from "./ServerTelemetryRequest";
17
+ import { ServerTelemetryEntity } from "../../cache/entities/ServerTelemetryEntity";
18
+ import { RegionDiscoveryMetadata } from "../../authority/RegionDiscoveryMetadata";
19
+
20
+ /** @internal */
21
+ export class ServerTelemetryManager {
22
+ private cacheManager: CacheManager;
23
+ private apiId: number;
24
+ private correlationId: string;
25
+ private telemetryCacheKey: string;
26
+ private wrapperSKU: String;
27
+ private wrapperVer: String;
28
+ private regionUsed: string | undefined;
29
+ private regionSource: RegionDiscoverySources | undefined;
30
+ private regionOutcome: RegionDiscoveryOutcomes | undefined;
31
+ private cacheOutcome: CacheOutcome = CacheOutcome.NO_CACHE_HIT;
32
+
33
+ constructor(
34
+ telemetryRequest: ServerTelemetryRequest,
35
+ cacheManager: CacheManager
36
+ ) {
37
+ this.cacheManager = cacheManager;
38
+ this.apiId = telemetryRequest.apiId;
39
+ this.correlationId = telemetryRequest.correlationId;
40
+ this.wrapperSKU = telemetryRequest.wrapperSKU || Constants.EMPTY_STRING;
41
+ this.wrapperVer = telemetryRequest.wrapperVer || Constants.EMPTY_STRING;
42
+
43
+ this.telemetryCacheKey =
44
+ SERVER_TELEM_CONSTANTS.CACHE_KEY +
45
+ Separators.CACHE_KEY_SEPARATOR +
46
+ telemetryRequest.clientId;
47
+ }
48
+
49
+ /**
50
+ * API to add MSER Telemetry to request
51
+ */
52
+ generateCurrentRequestHeaderValue(): string {
53
+ const request = `${this.apiId}${SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR}${this.cacheOutcome}`;
54
+ const platformFields = [this.wrapperSKU, this.wrapperVer].join(
55
+ SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR
56
+ );
57
+ const regionDiscoveryFields = this.getRegionDiscoveryFields();
58
+ const requestWithRegionDiscoveryFields = [
59
+ request,
60
+ regionDiscoveryFields,
61
+ ].join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
62
+
63
+ return [
64
+ SERVER_TELEM_CONSTANTS.SCHEMA_VERSION,
65
+ requestWithRegionDiscoveryFields,
66
+ platformFields,
67
+ ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
68
+ }
69
+
70
+ /**
71
+ * API to add MSER Telemetry for the last failed request
72
+ */
73
+ generateLastRequestHeaderValue(): string {
74
+ const lastRequests = this.getLastRequests();
75
+
76
+ const maxErrors = ServerTelemetryManager.maxErrorsToSend(lastRequests);
77
+ const failedRequests = lastRequests.failedRequests
78
+ .slice(0, 2 * maxErrors)
79
+ .join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
80
+ const errors = lastRequests.errors
81
+ .slice(0, maxErrors)
82
+ .join(SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR);
83
+ const errorCount = lastRequests.errors.length;
84
+
85
+ // Indicate whether this header contains all data or partial data
86
+ const overflow =
87
+ maxErrors < errorCount
88
+ ? SERVER_TELEM_CONSTANTS.OVERFLOW_TRUE
89
+ : SERVER_TELEM_CONSTANTS.OVERFLOW_FALSE;
90
+ const platformFields = [errorCount, overflow].join(
91
+ SERVER_TELEM_CONSTANTS.VALUE_SEPARATOR
92
+ );
93
+
94
+ return [
95
+ SERVER_TELEM_CONSTANTS.SCHEMA_VERSION,
96
+ lastRequests.cacheHits,
97
+ failedRequests,
98
+ errors,
99
+ platformFields,
100
+ ].join(SERVER_TELEM_CONSTANTS.CATEGORY_SEPARATOR);
101
+ }
102
+
103
+ /**
104
+ * API to cache token failures for MSER data capture
105
+ * @param error
106
+ */
107
+ cacheFailedRequest(error: unknown): void {
108
+ const lastRequests = this.getLastRequests();
109
+ if (
110
+ lastRequests.errors.length >=
111
+ SERVER_TELEM_CONSTANTS.MAX_CACHED_ERRORS
112
+ ) {
113
+ // Remove a cached error to make room, first in first out
114
+ lastRequests.failedRequests.shift(); // apiId
115
+ lastRequests.failedRequests.shift(); // correlationId
116
+ lastRequests.errors.shift();
117
+ }
118
+
119
+ lastRequests.failedRequests.push(this.apiId, this.correlationId);
120
+
121
+ if (error instanceof Error && !!error && error.toString()) {
122
+ if (error instanceof AuthError) {
123
+ if (error.subError) {
124
+ lastRequests.errors.push(error.subError);
125
+ } else if (error.errorCode) {
126
+ lastRequests.errors.push(error.errorCode);
127
+ } else {
128
+ lastRequests.errors.push(error.toString());
129
+ }
130
+ } else {
131
+ lastRequests.errors.push(error.toString());
132
+ }
133
+ } else {
134
+ lastRequests.errors.push(SERVER_TELEM_CONSTANTS.UNKNOWN_ERROR);
135
+ }
136
+
137
+ this.cacheManager.setServerTelemetry(
138
+ this.telemetryCacheKey,
139
+ lastRequests
140
+ );
141
+
142
+ return;
143
+ }
144
+
145
+ /**
146
+ * Update server telemetry cache entry by incrementing cache hit counter
147
+ */
148
+ incrementCacheHits(): number {
149
+ const lastRequests = this.getLastRequests();
150
+ lastRequests.cacheHits += 1;
151
+
152
+ this.cacheManager.setServerTelemetry(
153
+ this.telemetryCacheKey,
154
+ lastRequests
155
+ );
156
+ return lastRequests.cacheHits;
157
+ }
158
+
159
+ /**
160
+ * Get the server telemetry entity from cache or initialize a new one
161
+ */
162
+ getLastRequests(): ServerTelemetryEntity {
163
+ const initialValue: ServerTelemetryEntity = new ServerTelemetryEntity();
164
+ const lastRequests = this.cacheManager.getServerTelemetry(
165
+ this.telemetryCacheKey
166
+ ) as ServerTelemetryEntity;
167
+
168
+ return lastRequests || initialValue;
169
+ }
170
+
171
+ /**
172
+ * Remove server telemetry cache entry
173
+ */
174
+ clearTelemetryCache(): void {
175
+ const lastRequests = this.getLastRequests();
176
+ const numErrorsFlushed =
177
+ ServerTelemetryManager.maxErrorsToSend(lastRequests);
178
+ const errorCount = lastRequests.errors.length;
179
+ if (numErrorsFlushed === errorCount) {
180
+ // All errors were sent on last request, clear Telemetry cache
181
+ this.cacheManager.removeItem(this.telemetryCacheKey);
182
+ } else {
183
+ // Partial data was flushed to server, construct a new telemetry cache item with errors that were not flushed
184
+ const serverTelemEntity = new ServerTelemetryEntity();
185
+ serverTelemEntity.failedRequests =
186
+ lastRequests.failedRequests.slice(numErrorsFlushed * 2); // failedRequests contains 2 items for each error
187
+ serverTelemEntity.errors =
188
+ lastRequests.errors.slice(numErrorsFlushed);
189
+
190
+ this.cacheManager.setServerTelemetry(
191
+ this.telemetryCacheKey,
192
+ serverTelemEntity
193
+ );
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Returns the maximum number of errors that can be flushed to the server in the next network request
199
+ * @param serverTelemetryEntity
200
+ */
201
+ static maxErrorsToSend(
202
+ serverTelemetryEntity: ServerTelemetryEntity
203
+ ): number {
204
+ let i;
205
+ let maxErrors = 0;
206
+ let dataSize = 0;
207
+ const errorCount = serverTelemetryEntity.errors.length;
208
+ for (i = 0; i < errorCount; i++) {
209
+ // failedRequests parameter contains pairs of apiId and correlationId, multiply index by 2 to preserve pairs
210
+ const apiId =
211
+ serverTelemetryEntity.failedRequests[2 * i] ||
212
+ Constants.EMPTY_STRING;
213
+ const correlationId =
214
+ serverTelemetryEntity.failedRequests[2 * i + 1] ||
215
+ Constants.EMPTY_STRING;
216
+ const errorCode =
217
+ serverTelemetryEntity.errors[i] || Constants.EMPTY_STRING;
218
+
219
+ // Count number of characters that would be added to header, each character is 1 byte. Add 3 at the end to account for separators
220
+ dataSize +=
221
+ apiId.toString().length +
222
+ correlationId.toString().length +
223
+ errorCode.length +
224
+ 3;
225
+
226
+ if (dataSize < SERVER_TELEM_CONSTANTS.MAX_LAST_HEADER_BYTES) {
227
+ // Adding this entry to the header would still keep header size below the limit
228
+ maxErrors += 1;
229
+ } else {
230
+ break;
231
+ }
232
+ }
233
+
234
+ return maxErrors;
235
+ }
236
+
237
+ /**
238
+ * Get the region discovery fields
239
+ *
240
+ * @returns string
241
+ */
242
+ getRegionDiscoveryFields(): string {
243
+ const regionDiscoveryFields: string[] = [];
244
+
245
+ regionDiscoveryFields.push(this.regionUsed || Constants.EMPTY_STRING);
246
+ regionDiscoveryFields.push(this.regionSource || Constants.EMPTY_STRING);
247
+ regionDiscoveryFields.push(
248
+ this.regionOutcome || Constants.EMPTY_STRING
249
+ );
250
+
251
+ return regionDiscoveryFields.join(",");
252
+ }
253
+
254
+ /**
255
+ * Update the region discovery metadata
256
+ *
257
+ * @param regionDiscoveryMetadata
258
+ * @returns void
259
+ */
260
+ updateRegionDiscoveryMetadata(
261
+ regionDiscoveryMetadata: RegionDiscoveryMetadata
262
+ ): void {
263
+ this.regionUsed = regionDiscoveryMetadata.region_used;
264
+ this.regionSource = regionDiscoveryMetadata.region_source;
265
+ this.regionOutcome = regionDiscoveryMetadata.region_outcome;
266
+ }
267
+
268
+ /**
269
+ * Set cache outcome
270
+ */
271
+ setCacheOutcome(cacheOutcome: CacheOutcome): void {
272
+ this.cacheOutcome = cacheOutcome;
273
+ }
274
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type ServerTelemetryRequest = {
7
+ clientId: string;
8
+ apiId: number;
9
+ correlationId: string;
10
+ forceRefresh?: boolean;
11
+ wrapperSKU?: string;
12
+ wrapperVer?: string;
13
+ };
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Interface which describes URI components.
8
+ */
9
+ export interface IUri {
10
+ Protocol: string;
11
+ HostNameAndPort: string;
12
+ AbsolutePath: string;
13
+ Search: string;
14
+ Hash: string;
15
+ PathSegments: string[];
16
+ QueryString: string;
17
+ }
@@ -0,0 +1,363 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ServerAuthorizationCodeResponse } from "../response/ServerAuthorizationCodeResponse";
7
+ import { ClientConfigurationError } from "../error/ClientConfigurationError";
8
+ import { ClientAuthError } from "../error/ClientAuthError";
9
+ import { StringUtils } from "../utils/StringUtils";
10
+ import { IUri } from "./IUri";
11
+ import {
12
+ AADAuthorityConstants,
13
+ Constants,
14
+ ServerResponseType,
15
+ } from "../utils/Constants";
16
+
17
+ /**
18
+ * Url object class which can perform various transformations on url strings.
19
+ */
20
+ export class UrlString {
21
+ // internal url string field
22
+ private _urlString: string;
23
+ public get urlString(): string {
24
+ return this._urlString;
25
+ }
26
+
27
+ constructor(url: string) {
28
+ this._urlString = url;
29
+ if (!this._urlString) {
30
+ // Throws error if url is empty
31
+ throw ClientConfigurationError.createUrlEmptyError();
32
+ }
33
+
34
+ if (!this.getHash()) {
35
+ this._urlString = UrlString.canonicalizeUri(url);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Ensure urls are lower case and end with a / character.
41
+ * @param url
42
+ */
43
+ static canonicalizeUri(url: string): string {
44
+ if (url) {
45
+ let lowerCaseUrl = url.toLowerCase();
46
+
47
+ if (StringUtils.endsWith(lowerCaseUrl, "?")) {
48
+ lowerCaseUrl = lowerCaseUrl.slice(0, -1);
49
+ } else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
50
+ lowerCaseUrl = lowerCaseUrl.slice(0, -2);
51
+ }
52
+
53
+ if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
54
+ lowerCaseUrl += "/";
55
+ }
56
+
57
+ return lowerCaseUrl;
58
+ }
59
+
60
+ return url;
61
+ }
62
+
63
+ /**
64
+ * Throws if urlString passed is not a valid authority URI string.
65
+ */
66
+ validateAsUri(): void {
67
+ // Attempts to parse url for uri components
68
+ let components;
69
+ try {
70
+ components = this.getUrlComponents();
71
+ } catch (e) {
72
+ throw ClientConfigurationError.createUrlParseError(e as string);
73
+ }
74
+
75
+ // Throw error if URI or path segments are not parseable.
76
+ if (!components.HostNameAndPort || !components.PathSegments) {
77
+ throw ClientConfigurationError.createUrlParseError(
78
+ `Given url string: ${this.urlString}`
79
+ );
80
+ }
81
+
82
+ // Throw error if uri is insecure.
83
+ if (
84
+ !components.Protocol ||
85
+ components.Protocol.toLowerCase() !== "https:"
86
+ ) {
87
+ throw ClientConfigurationError.createInsecureAuthorityUriError(
88
+ this.urlString
89
+ );
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Given a url and a query string return the url with provided query string appended
95
+ * @param url
96
+ * @param queryString
97
+ */
98
+ static appendQueryString(url: string, queryString: string): string {
99
+ if (!queryString) {
100
+ return url;
101
+ }
102
+
103
+ return url.indexOf("?") < 0
104
+ ? `${url}?${queryString}`
105
+ : `${url}&${queryString}`;
106
+ }
107
+
108
+ /**
109
+ * Returns a url with the hash removed
110
+ * @param url
111
+ */
112
+ static removeHashFromUrl(url: string): string {
113
+ return UrlString.canonicalizeUri(url.split("#")[0]);
114
+ }
115
+
116
+ /**
117
+ * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
118
+ * @param href The url
119
+ * @param tenantId The tenant id to replace
120
+ */
121
+ replaceTenantPath(tenantId: string): UrlString {
122
+ const urlObject = this.getUrlComponents();
123
+ const pathArray = urlObject.PathSegments;
124
+ if (
125
+ tenantId &&
126
+ pathArray.length !== 0 &&
127
+ (pathArray[0] === AADAuthorityConstants.COMMON ||
128
+ pathArray[0] === AADAuthorityConstants.ORGANIZATIONS)
129
+ ) {
130
+ pathArray[0] = tenantId;
131
+ }
132
+ return UrlString.constructAuthorityUriFromObject(urlObject);
133
+ }
134
+
135
+ /**
136
+ * Returns the anchor part(#) of the URL
137
+ */
138
+ getHash(): string {
139
+ return UrlString.parseHash(this.urlString);
140
+ }
141
+
142
+ /**
143
+ * Parses out the components from a url string.
144
+ * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
145
+ */
146
+ getUrlComponents(): IUri {
147
+ // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
148
+ const regEx = RegExp(
149
+ "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"
150
+ );
151
+
152
+ // If url string does not match regEx, we throw an error
153
+ const match = this.urlString.match(regEx);
154
+ if (!match) {
155
+ throw ClientConfigurationError.createUrlParseError(
156
+ `Given url string: ${this.urlString}`
157
+ );
158
+ }
159
+
160
+ // Url component object
161
+ const urlComponents = {
162
+ Protocol: match[1],
163
+ HostNameAndPort: match[4],
164
+ AbsolutePath: match[5],
165
+ QueryString: match[7],
166
+ } as IUri;
167
+
168
+ let pathSegments = urlComponents.AbsolutePath.split("/");
169
+ pathSegments = pathSegments.filter((val) => val && val.length > 0); // remove empty elements
170
+ urlComponents.PathSegments = pathSegments;
171
+
172
+ if (
173
+ urlComponents.QueryString &&
174
+ urlComponents.QueryString.endsWith("/")
175
+ ) {
176
+ urlComponents.QueryString = urlComponents.QueryString.substring(
177
+ 0,
178
+ urlComponents.QueryString.length - 1
179
+ );
180
+ }
181
+ return urlComponents;
182
+ }
183
+
184
+ static getDomainFromUrl(url: string): string {
185
+ const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
186
+
187
+ const match = url.match(regEx);
188
+
189
+ if (!match) {
190
+ throw ClientConfigurationError.createUrlParseError(
191
+ `Given url string: ${url}`
192
+ );
193
+ }
194
+
195
+ return match[2];
196
+ }
197
+
198
+ static getAbsoluteUrl(relativeUrl: string, baseUrl: string): string {
199
+ if (relativeUrl[0] === Constants.FORWARD_SLASH) {
200
+ const url = new UrlString(baseUrl);
201
+ const baseComponents = url.getUrlComponents();
202
+
203
+ return (
204
+ baseComponents.Protocol +
205
+ "//" +
206
+ baseComponents.HostNameAndPort +
207
+ relativeUrl
208
+ );
209
+ }
210
+
211
+ return relativeUrl;
212
+ }
213
+
214
+ /**
215
+ * Parses hash string from given string. Returns empty string if no hash symbol is found.
216
+ * @param hashString
217
+ */
218
+ static parseHash(hashString: string): string {
219
+ const hashIndex1 = hashString.indexOf("#");
220
+ const hashIndex2 = hashString.indexOf("#/");
221
+ if (hashIndex2 > -1) {
222
+ return hashString.substring(hashIndex2 + 2);
223
+ } else if (hashIndex1 > -1) {
224
+ return hashString.substring(hashIndex1 + 1);
225
+ }
226
+ return Constants.EMPTY_STRING;
227
+ }
228
+
229
+ /**
230
+ * Parses query string from given string. Returns empty string if no query symbol is found.
231
+ * @param queryString
232
+ */
233
+ static parseQueryString(queryString: string): string {
234
+ const queryIndex1 = queryString.indexOf("?");
235
+ const queryIndex2 = queryString.indexOf("/?");
236
+ if (queryIndex2 > -1) {
237
+ return queryString.substring(queryIndex2 + 2);
238
+ } else if (queryIndex1 > -1) {
239
+ return queryString.substring(queryIndex1 + 1);
240
+ }
241
+ return Constants.EMPTY_STRING;
242
+ }
243
+
244
+ /**
245
+ * Parses query server response string from given string.
246
+ * Extract hash between '?code=' and '#' if trailing '# is present.
247
+ * Returns empty string if no query symbol is found.
248
+ * @param queryString
249
+ */
250
+ static parseQueryServerResponse(queryString: string): string {
251
+ const queryIndex1 = queryString.indexOf("?code");
252
+ const queryIndex2 = queryString.indexOf("/?code");
253
+ const hashIndex = queryString.indexOf("#");
254
+ if (queryIndex2 > -1 && hashIndex > -1) {
255
+ return queryString.substring(queryIndex2 + 2, hashIndex);
256
+ } else if (queryIndex2 > -1) {
257
+ return queryString.substring(queryIndex2 + 2);
258
+ } else if (queryIndex1 > -1 && hashIndex > -1) {
259
+ return queryString.substring(queryIndex1 + 1, hashIndex);
260
+ } else if (queryIndex1 > -1) {
261
+ return queryString.substring(queryIndex1 + 1);
262
+ }
263
+ return Constants.EMPTY_STRING;
264
+ }
265
+
266
+ static constructAuthorityUriFromObject(urlObject: IUri): UrlString {
267
+ return new UrlString(
268
+ urlObject.Protocol +
269
+ "//" +
270
+ urlObject.HostNameAndPort +
271
+ "/" +
272
+ urlObject.PathSegments.join("/")
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Returns URL hash as server auth code response object.
278
+ */
279
+ static getDeserializedHash(hash: string): ServerAuthorizationCodeResponse {
280
+ // Check if given hash is empty
281
+ if (!hash) {
282
+ return {};
283
+ }
284
+ // Strip the # symbol if present
285
+ const parsedHash = UrlString.parseHash(hash);
286
+ // If # symbol was not present, above will return empty string, so give original hash value
287
+ const deserializedHash: ServerAuthorizationCodeResponse =
288
+ StringUtils.queryStringToObject<ServerAuthorizationCodeResponse>(
289
+ parsedHash || hash
290
+ );
291
+ // Check if deserialization didn't work
292
+ if (!deserializedHash) {
293
+ throw ClientAuthError.createHashNotDeserializedError(
294
+ JSON.stringify(deserializedHash)
295
+ );
296
+ }
297
+ return deserializedHash;
298
+ }
299
+
300
+ /**
301
+ * Returns URL query string as server auth code response object.
302
+ */
303
+ static getDeserializedQueryString(
304
+ query: string
305
+ ): ServerAuthorizationCodeResponse {
306
+ // Check if given query is empty
307
+ if (!query) {
308
+ return {};
309
+ }
310
+ // Strip the ? symbol if present
311
+ const parsedQueryString = UrlString.parseQueryString(query);
312
+ // If ? symbol was not present, above will return empty string, so give original query value
313
+ const deserializedQueryString: ServerAuthorizationCodeResponse =
314
+ StringUtils.queryStringToObject<ServerAuthorizationCodeResponse>(
315
+ parsedQueryString || query
316
+ );
317
+ // Check if deserialization didn't work
318
+ if (!deserializedQueryString) {
319
+ throw ClientAuthError.createHashNotDeserializedError(
320
+ JSON.stringify(deserializedQueryString)
321
+ );
322
+ }
323
+ return deserializedQueryString;
324
+ }
325
+ /**
326
+ * Returns either deserialized query string or deserialized hash, depending on the serverResponseType
327
+ * as a server auth code response object.
328
+ */
329
+ static getDeserializedCodeResponse(
330
+ serverResponseType: ServerResponseType | undefined,
331
+ hashFragment: string
332
+ ): ServerAuthorizationCodeResponse {
333
+ const hashUrlString = new UrlString(hashFragment);
334
+ let serverParams: ServerAuthorizationCodeResponse;
335
+ if (serverResponseType === ServerResponseType.QUERY) {
336
+ serverParams = UrlString.getDeserializedQueryString(hashFragment);
337
+ } else {
338
+ serverParams = UrlString.getDeserializedHash(
339
+ hashUrlString.getHash()
340
+ );
341
+ }
342
+ return serverParams;
343
+ }
344
+
345
+ /**
346
+ * Check if the hash of the URL string contains known properties
347
+ */
348
+ static hashContainsKnownProperties(hash: string): boolean {
349
+ if (!hash || hash.indexOf("=") < 0) {
350
+ // Hash doesn't contain key/value pairs
351
+ return false;
352
+ }
353
+
354
+ const parameters: ServerAuthorizationCodeResponse =
355
+ UrlString.getDeserializedHash(hash);
356
+ return !!(
357
+ parameters.code ||
358
+ parameters.error_description ||
359
+ parameters.error ||
360
+ parameters.state
361
+ );
362
+ }
363
+ }