@azure/msal-common 14.0.2 → 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 (269) 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.mjs +1 -1
  11. package/dist/authority/Authority.mjs.map +1 -1
  12. package/dist/authority/AuthorityFactory.d.ts.map +1 -1
  13. package/dist/authority/AuthorityFactory.mjs +2 -3
  14. package/dist/authority/AuthorityFactory.mjs.map +1 -1
  15. package/dist/authority/AuthorityMetadata.mjs +1 -1
  16. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  17. package/dist/authority/AuthorityOptions.mjs +1 -1
  18. package/dist/authority/AuthorityOptions.mjs.map +1 -1
  19. package/dist/authority/AuthorityType.mjs +1 -1
  20. package/dist/authority/AuthorityType.mjs.map +1 -1
  21. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  22. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs.map +1 -1
  23. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  24. package/dist/authority/CloudInstanceDiscoveryResponse.mjs.map +1 -1
  25. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  26. package/dist/authority/OpenIdConfigResponse.mjs.map +1 -1
  27. package/dist/authority/ProtocolMode.mjs +1 -1
  28. package/dist/authority/ProtocolMode.mjs.map +1 -1
  29. package/dist/authority/RegionDiscovery.mjs +1 -1
  30. package/dist/authority/RegionDiscovery.mjs.map +1 -1
  31. package/dist/cache/CacheManager.d.ts.map +1 -1
  32. package/dist/cache/CacheManager.mjs +5 -5
  33. package/dist/cache/CacheManager.mjs.map +1 -1
  34. package/dist/cache/entities/AccessTokenEntity.d.ts.map +1 -1
  35. package/dist/cache/entities/AccessTokenEntity.mjs +4 -7
  36. package/dist/cache/entities/AccessTokenEntity.mjs.map +1 -1
  37. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  38. package/dist/cache/entities/AccountEntity.mjs +2 -4
  39. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  40. package/dist/cache/entities/AppMetadataEntity.mjs +1 -1
  41. package/dist/cache/entities/AppMetadataEntity.mjs.map +1 -1
  42. package/dist/cache/entities/AuthorityMetadataEntity.mjs +1 -1
  43. package/dist/cache/entities/AuthorityMetadataEntity.mjs.map +1 -1
  44. package/dist/cache/entities/CacheRecord.mjs +1 -1
  45. package/dist/cache/entities/CacheRecord.mjs.map +1 -1
  46. package/dist/cache/entities/CredentialEntity.mjs +1 -1
  47. package/dist/cache/entities/CredentialEntity.mjs.map +1 -1
  48. package/dist/cache/entities/IdTokenEntity.mjs +1 -1
  49. package/dist/cache/entities/IdTokenEntity.mjs.map +1 -1
  50. package/dist/cache/entities/RefreshTokenEntity.mjs +1 -1
  51. package/dist/cache/entities/RefreshTokenEntity.mjs.map +1 -1
  52. package/dist/cache/entities/ServerTelemetryEntity.mjs +1 -1
  53. package/dist/cache/entities/ServerTelemetryEntity.mjs.map +1 -1
  54. package/dist/cache/entities/ThrottlingEntity.mjs +1 -1
  55. package/dist/cache/entities/ThrottlingEntity.mjs.map +1 -1
  56. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  57. package/dist/cache/persistence/TokenCacheContext.mjs.map +1 -1
  58. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  59. package/dist/client/AuthorizationCodeClient.mjs +10 -39
  60. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  61. package/dist/client/BaseClient.d.ts +1 -1
  62. package/dist/client/BaseClient.d.ts.map +1 -1
  63. package/dist/client/BaseClient.mjs +8 -2
  64. package/dist/client/BaseClient.mjs.map +1 -1
  65. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  66. package/dist/client/RefreshTokenClient.mjs +2 -11
  67. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  68. package/dist/client/SilentFlowClient.d.ts.map +1 -1
  69. package/dist/client/SilentFlowClient.mjs +7 -7
  70. package/dist/client/SilentFlowClient.mjs.map +1 -1
  71. package/dist/config/ClientConfiguration.mjs +1 -1
  72. package/dist/config/ClientConfiguration.mjs.map +1 -1
  73. package/dist/crypto/ICrypto.mjs +1 -1
  74. package/dist/crypto/ICrypto.mjs.map +1 -1
  75. package/dist/crypto/JoseHeader.mjs +1 -1
  76. package/dist/crypto/JoseHeader.mjs.map +1 -1
  77. package/dist/crypto/PopTokenGenerator.mjs +1 -1
  78. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  79. package/dist/error/AuthError.mjs +1 -1
  80. package/dist/error/AuthError.mjs.map +1 -1
  81. package/dist/error/ClientAuthError.mjs +1 -1
  82. package/dist/error/ClientAuthError.mjs.map +1 -1
  83. package/dist/error/ClientConfigurationError.mjs +1 -1
  84. package/dist/error/ClientConfigurationError.mjs.map +1 -1
  85. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  86. package/dist/error/InteractionRequiredAuthError.mjs.map +1 -1
  87. package/dist/error/JoseHeaderError.mjs +1 -1
  88. package/dist/error/JoseHeaderError.mjs.map +1 -1
  89. package/dist/error/ServerError.mjs +1 -1
  90. package/dist/error/ServerError.mjs.map +1 -1
  91. package/dist/index.cjs +1641 -1560
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.ts +3 -3
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.mjs +5 -3
  96. package/dist/index.mjs.map +1 -1
  97. package/dist/logger/Logger.d.ts.map +1 -1
  98. package/dist/logger/Logger.mjs +2 -12
  99. package/dist/logger/Logger.mjs.map +1 -1
  100. package/dist/network/INetworkModule.mjs +1 -1
  101. package/dist/network/INetworkModule.mjs.map +1 -1
  102. package/dist/network/NetworkManager.mjs +1 -1
  103. package/dist/network/NetworkManager.mjs.map +1 -1
  104. package/dist/network/ThrottlingUtils.mjs +1 -1
  105. package/dist/network/ThrottlingUtils.mjs.map +1 -1
  106. package/dist/packageMetadata.d.ts +1 -1
  107. package/dist/packageMetadata.mjs +2 -2
  108. package/dist/packageMetadata.mjs.map +1 -1
  109. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  110. package/dist/request/AuthenticationHeaderParser.mjs.map +1 -1
  111. package/dist/request/RequestParameterBuilder.d.ts.map +1 -1
  112. package/dist/request/RequestParameterBuilder.mjs +6 -7
  113. package/dist/request/RequestParameterBuilder.mjs.map +1 -1
  114. package/dist/request/RequestValidator.d.ts.map +1 -1
  115. package/dist/request/RequestValidator.mjs +4 -6
  116. package/dist/request/RequestValidator.mjs.map +1 -1
  117. package/dist/request/ScopeSet.mjs +4 -4
  118. package/dist/request/ScopeSet.mjs.map +1 -1
  119. package/dist/response/AuthenticationResult.d.ts +3 -1
  120. package/dist/response/AuthenticationResult.d.ts.map +1 -1
  121. package/dist/response/ResponseHandler.d.ts +4 -3
  122. package/dist/response/ResponseHandler.d.ts.map +1 -1
  123. package/dist/response/ResponseHandler.mjs +57 -39
  124. package/dist/response/ResponseHandler.mjs.map +1 -1
  125. package/dist/response/ServerAuthorizationTokenResponse.d.ts +2 -0
  126. package/dist/response/ServerAuthorizationTokenResponse.d.ts.map +1 -1
  127. package/dist/telemetry/performance/IPerformanceClient.d.ts +4 -4
  128. package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
  129. package/dist/telemetry/performance/PerformanceClient.d.ts +2 -2
  130. package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
  131. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  132. package/dist/telemetry/performance/PerformanceClient.mjs.map +1 -1
  133. package/dist/telemetry/performance/PerformanceEvent.d.ts +8 -1
  134. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  135. package/dist/telemetry/performance/PerformanceEvent.mjs +9 -1
  136. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  137. package/dist/telemetry/performance/StubPerformanceClient.d.ts +3 -3
  138. package/dist/telemetry/performance/StubPerformanceClient.d.ts.map +1 -1
  139. package/dist/telemetry/performance/StubPerformanceClient.mjs +23 -3
  140. package/dist/telemetry/performance/StubPerformanceClient.mjs.map +1 -1
  141. package/dist/telemetry/server/ServerTelemetryManager.d.ts.map +1 -1
  142. package/dist/telemetry/server/ServerTelemetryManager.mjs +3 -4
  143. package/dist/telemetry/server/ServerTelemetryManager.mjs.map +1 -1
  144. package/dist/url/UrlString.d.ts.map +1 -1
  145. package/dist/url/UrlString.mjs +10 -12
  146. package/dist/url/UrlString.mjs.map +1 -1
  147. package/dist/utils/Constants.d.ts +10 -0
  148. package/dist/utils/Constants.d.ts.map +1 -1
  149. package/dist/utils/Constants.mjs +11 -2
  150. package/dist/utils/Constants.mjs.map +1 -1
  151. package/dist/utils/FunctionWrappers.d.ts +28 -0
  152. package/dist/utils/FunctionWrappers.d.ts.map +1 -0
  153. package/dist/utils/FunctionWrappers.mjs +90 -0
  154. package/dist/utils/FunctionWrappers.mjs.map +1 -0
  155. package/dist/utils/ProtocolUtils.d.ts.map +1 -1
  156. package/dist/utils/ProtocolUtils.mjs +4 -7
  157. package/dist/utils/ProtocolUtils.mjs.map +1 -1
  158. package/dist/utils/StringUtils.d.ts +0 -13
  159. package/dist/utils/StringUtils.d.ts.map +1 -1
  160. package/dist/utils/StringUtils.mjs +3 -34
  161. package/dist/utils/StringUtils.mjs.map +1 -1
  162. package/dist/utils/TimeUtils.mjs +1 -1
  163. package/dist/utils/TimeUtils.mjs.map +1 -1
  164. package/package.json +6 -4
  165. package/src/account/AccountInfo.ts +44 -0
  166. package/src/account/AuthToken.ts +70 -0
  167. package/src/account/CcsCredential.ts +16 -0
  168. package/src/account/ClientCredentials.ts +20 -0
  169. package/src/account/ClientInfo.ts +64 -0
  170. package/src/account/TokenClaims.ts +70 -0
  171. package/src/authority/Authority.ts +1225 -0
  172. package/src/authority/AuthorityFactory.ts +106 -0
  173. package/src/authority/AuthorityMetadata.ts +953 -0
  174. package/src/authority/AuthorityOptions.ts +40 -0
  175. package/src/authority/AuthorityType.ts +15 -0
  176. package/src/authority/AzureRegion.ts +7 -0
  177. package/src/authority/AzureRegionConfiguration.ts +16 -0
  178. package/src/authority/CloudDiscoveryMetadata.ts +10 -0
  179. package/src/authority/CloudInstanceDiscoveryErrorResponse.ts +26 -0
  180. package/src/authority/CloudInstanceDiscoveryResponse.ts +21 -0
  181. package/src/authority/ImdsOptions.ts +10 -0
  182. package/src/authority/OIDCOptions.ts +14 -0
  183. package/src/authority/OpenIdConfigResponse.ts +24 -0
  184. package/src/authority/ProtocolMode.ts +13 -0
  185. package/src/authority/RegionDiscovery.ts +193 -0
  186. package/src/authority/RegionDiscoveryMetadata.ts +15 -0
  187. package/src/broker/nativeBroker/INativeBrokerPlugin.ts +29 -0
  188. package/src/cache/CacheManager.ts +1619 -0
  189. package/src/cache/entities/AccessTokenEntity.ts +162 -0
  190. package/src/cache/entities/AccountEntity.ts +309 -0
  191. package/src/cache/entities/AppMetadataEntity.ts +91 -0
  192. package/src/cache/entities/AuthorityMetadataEntity.ts +112 -0
  193. package/src/cache/entities/CacheRecord.ts +33 -0
  194. package/src/cache/entities/CredentialEntity.ts +215 -0
  195. package/src/cache/entities/IdTokenEntity.ts +74 -0
  196. package/src/cache/entities/RefreshTokenEntity.ts +78 -0
  197. package/src/cache/entities/ServerTelemetryEntity.ts +38 -0
  198. package/src/cache/entities/ThrottlingEntity.ts +36 -0
  199. package/src/cache/interface/ICacheManager.ts +218 -0
  200. package/src/cache/interface/ICachePlugin.ts +11 -0
  201. package/src/cache/interface/ISerializableTokenCache.ts +9 -0
  202. package/src/cache/persistence/TokenCacheContext.ts +39 -0
  203. package/src/cache/utils/CacheTypes.ts +93 -0
  204. package/src/client/AuthorizationCodeClient.ts +714 -0
  205. package/src/client/BaseClient.ts +205 -0
  206. package/src/client/RefreshTokenClient.ts +442 -0
  207. package/src/client/SilentFlowClient.ts +186 -0
  208. package/src/config/AppTokenProvider.ts +47 -0
  209. package/src/config/ClientConfiguration.ts +287 -0
  210. package/src/crypto/ICrypto.ts +127 -0
  211. package/src/crypto/IGuidGenerator.ts +9 -0
  212. package/src/crypto/JoseHeader.ts +55 -0
  213. package/src/crypto/PopTokenGenerator.ts +155 -0
  214. package/src/crypto/SignedHttpRequest.ts +16 -0
  215. package/src/error/AuthError.ts +85 -0
  216. package/src/error/ClientAuthError.ts +738 -0
  217. package/src/error/ClientConfigurationError.ts +396 -0
  218. package/src/error/InteractionRequiredAuthError.ts +134 -0
  219. package/src/error/JoseHeaderError.ts +52 -0
  220. package/src/error/ServerError.ts +18 -0
  221. package/src/index.ts +215 -0
  222. package/src/logger/Logger.ts +272 -0
  223. package/src/network/INetworkModule.ts +57 -0
  224. package/src/network/NetworkManager.ts +76 -0
  225. package/src/network/RequestThumbprint.ts +22 -0
  226. package/src/network/ThrottlingUtils.ts +156 -0
  227. package/src/packageMetadata.ts +3 -0
  228. package/src/request/AuthenticationHeaderParser.ts +89 -0
  229. package/src/request/BaseAuthRequest.ts +46 -0
  230. package/src/request/CommonAuthorizationCodeRequest.ts +33 -0
  231. package/src/request/CommonAuthorizationUrlRequest.ts +56 -0
  232. package/src/request/CommonClientCredentialRequest.ts +23 -0
  233. package/src/request/CommonDeviceCodeRequest.ts +31 -0
  234. package/src/request/CommonEndSessionRequest.ts +27 -0
  235. package/src/request/CommonOnBehalfOfRequest.ts +19 -0
  236. package/src/request/CommonRefreshTokenRequest.ts +25 -0
  237. package/src/request/CommonSilentFlowRequest.ts +24 -0
  238. package/src/request/CommonUsernamePasswordRequest.ts +23 -0
  239. package/src/request/NativeRequest.ts +25 -0
  240. package/src/request/NativeSignOutRequest.ts +10 -0
  241. package/src/request/RequestParameterBuilder.ts +606 -0
  242. package/src/request/RequestValidator.ts +103 -0
  243. package/src/request/ScopeSet.ts +230 -0
  244. package/src/request/StoreInCache.ts +16 -0
  245. package/src/response/AuthenticationResult.ts +47 -0
  246. package/src/response/AuthorizationCodePayload.ts +18 -0
  247. package/src/response/DeviceCodeResponse.ts +31 -0
  248. package/src/response/ExternalTokenResponse.ts +24 -0
  249. package/src/response/IMDSBadResponse.ts +9 -0
  250. package/src/response/ResponseHandler.ts +614 -0
  251. package/src/response/ServerAuthorizationCodeResponse.ts +33 -0
  252. package/src/response/ServerAuthorizationTokenResponse.ts +54 -0
  253. package/src/telemetry/performance/IPerformanceClient.ts +71 -0
  254. package/src/telemetry/performance/IPerformanceMeasurement.ts +10 -0
  255. package/src/telemetry/performance/PerformanceClient.ts +635 -0
  256. package/src/telemetry/performance/PerformanceEvent.ts +542 -0
  257. package/src/telemetry/performance/StubPerformanceClient.ts +101 -0
  258. package/src/telemetry/server/ServerTelemetryManager.ts +274 -0
  259. package/src/telemetry/server/ServerTelemetryRequest.ts +13 -0
  260. package/src/url/IUri.ts +17 -0
  261. package/src/url/UrlString.ts +363 -0
  262. package/src/utils/Constants.ts +436 -0
  263. package/src/utils/FunctionWrappers.ts +105 -0
  264. package/src/utils/MsalTypes.ts +9 -0
  265. package/src/utils/ProtocolUtils.ts +124 -0
  266. package/src/utils/StringUtils.ts +106 -0
  267. package/src/utils/TimeUtils.ts +51 -0
  268. package/dist/account/DecodedAuthToken.d.ts +0 -9
  269. package/dist/account/DecodedAuthToken.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-common v14.0.2 2023-08-18 */
1
+ /*! @azure/msal-common v14.0.3 2023-09-05 */
2
2
  'use strict';
3
3
  'use strict';
4
4
 
@@ -65,6 +65,15 @@ const Constants = {
65
65
  SHR_NONCE_VALIDITY: 240,
66
66
  INVALID_INSTANCE: "invalid_instance",
67
67
  };
68
+ const HttpStatus = {
69
+ SUCCESS_RANGE_START: 200,
70
+ SUCCESS_RANGE_END: 299,
71
+ REDIRECT: 302,
72
+ CLIENT_ERROR_RANGE_START: 400,
73
+ CLIENT_ERROR_RANGE_END: 499,
74
+ SERVER_ERROR_RANGE_START: 500,
75
+ SERVER_ERROR_RANGE_END: 599,
76
+ };
68
77
  const OIDC_DEFAULT_SCOPES = [
69
78
  Constants.OPENID_SCOPE,
70
79
  Constants.PROFILE_SCOPE,
@@ -457,6 +466,218 @@ const DEFAULT_CRYPTO_IMPLEMENTATION = {
457
466
  },
458
467
  };
459
468
 
469
+ /*
470
+ * Copyright (c) Microsoft Corporation. All rights reserved.
471
+ * Licensed under the MIT License.
472
+ */
473
+ /**
474
+ * Log message level.
475
+ */
476
+ exports.LogLevel = void 0;
477
+ (function (LogLevel) {
478
+ LogLevel[LogLevel["Error"] = 0] = "Error";
479
+ LogLevel[LogLevel["Warning"] = 1] = "Warning";
480
+ LogLevel[LogLevel["Info"] = 2] = "Info";
481
+ LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
482
+ LogLevel[LogLevel["Trace"] = 4] = "Trace";
483
+ })(exports.LogLevel || (exports.LogLevel = {}));
484
+ /**
485
+ * Class which facilitates logging of messages to a specific place.
486
+ */
487
+ class Logger {
488
+ constructor(loggerOptions, packageName, packageVersion) {
489
+ // Current log level, defaults to info.
490
+ this.level = exports.LogLevel.Info;
491
+ const defaultLoggerCallback = () => {
492
+ return;
493
+ };
494
+ const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
495
+ this.localCallback =
496
+ setLoggerOptions.loggerCallback || defaultLoggerCallback;
497
+ this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
498
+ this.level =
499
+ typeof setLoggerOptions.logLevel === "number"
500
+ ? setLoggerOptions.logLevel
501
+ : exports.LogLevel.Info;
502
+ this.correlationId =
503
+ setLoggerOptions.correlationId || Constants.EMPTY_STRING;
504
+ this.packageName = packageName || Constants.EMPTY_STRING;
505
+ this.packageVersion = packageVersion || Constants.EMPTY_STRING;
506
+ }
507
+ static createDefaultLoggerOptions() {
508
+ return {
509
+ loggerCallback: () => {
510
+ // allow users to not set loggerCallback
511
+ },
512
+ piiLoggingEnabled: false,
513
+ logLevel: exports.LogLevel.Info,
514
+ };
515
+ }
516
+ /**
517
+ * Create new Logger with existing configurations.
518
+ */
519
+ clone(packageName, packageVersion, correlationId) {
520
+ return new Logger({
521
+ loggerCallback: this.localCallback,
522
+ piiLoggingEnabled: this.piiLoggingEnabled,
523
+ logLevel: this.level,
524
+ correlationId: correlationId || this.correlationId,
525
+ }, packageName, packageVersion);
526
+ }
527
+ /**
528
+ * Log message with required options.
529
+ */
530
+ logMessage(logMessage, options) {
531
+ if (options.logLevel > this.level ||
532
+ (!this.piiLoggingEnabled && options.containsPii)) {
533
+ return;
534
+ }
535
+ const timestamp = new Date().toUTCString();
536
+ // Add correlationId to logs if set, correlationId provided on log messages take precedence
537
+ const logHeader = `[${timestamp}] : [${options.correlationId || this.correlationId || ""}]`;
538
+ const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${exports.LogLevel[options.logLevel]} - ${logMessage}`;
539
+ // debug(`msal:${LogLevel[options.logLevel]}${options.containsPii ? "-Pii": Constants.EMPTY_STRING}${options.context ? `:${options.context}` : Constants.EMPTY_STRING}`)(logMessage);
540
+ this.executeCallback(options.logLevel, log, options.containsPii || false);
541
+ }
542
+ /**
543
+ * Execute callback with message.
544
+ */
545
+ executeCallback(level, message, containsPii) {
546
+ if (this.localCallback) {
547
+ this.localCallback(level, message, containsPii);
548
+ }
549
+ }
550
+ /**
551
+ * Logs error messages.
552
+ */
553
+ error(message, correlationId) {
554
+ this.logMessage(message, {
555
+ logLevel: exports.LogLevel.Error,
556
+ containsPii: false,
557
+ correlationId: correlationId || Constants.EMPTY_STRING,
558
+ });
559
+ }
560
+ /**
561
+ * Logs error messages with PII.
562
+ */
563
+ errorPii(message, correlationId) {
564
+ this.logMessage(message, {
565
+ logLevel: exports.LogLevel.Error,
566
+ containsPii: true,
567
+ correlationId: correlationId || Constants.EMPTY_STRING,
568
+ });
569
+ }
570
+ /**
571
+ * Logs warning messages.
572
+ */
573
+ warning(message, correlationId) {
574
+ this.logMessage(message, {
575
+ logLevel: exports.LogLevel.Warning,
576
+ containsPii: false,
577
+ correlationId: correlationId || Constants.EMPTY_STRING,
578
+ });
579
+ }
580
+ /**
581
+ * Logs warning messages with PII.
582
+ */
583
+ warningPii(message, correlationId) {
584
+ this.logMessage(message, {
585
+ logLevel: exports.LogLevel.Warning,
586
+ containsPii: true,
587
+ correlationId: correlationId || Constants.EMPTY_STRING,
588
+ });
589
+ }
590
+ /**
591
+ * Logs info messages.
592
+ */
593
+ info(message, correlationId) {
594
+ this.logMessage(message, {
595
+ logLevel: exports.LogLevel.Info,
596
+ containsPii: false,
597
+ correlationId: correlationId || Constants.EMPTY_STRING,
598
+ });
599
+ }
600
+ /**
601
+ * Logs info messages with PII.
602
+ */
603
+ infoPii(message, correlationId) {
604
+ this.logMessage(message, {
605
+ logLevel: exports.LogLevel.Info,
606
+ containsPii: true,
607
+ correlationId: correlationId || Constants.EMPTY_STRING,
608
+ });
609
+ }
610
+ /**
611
+ * Logs verbose messages.
612
+ */
613
+ verbose(message, correlationId) {
614
+ this.logMessage(message, {
615
+ logLevel: exports.LogLevel.Verbose,
616
+ containsPii: false,
617
+ correlationId: correlationId || Constants.EMPTY_STRING,
618
+ });
619
+ }
620
+ /**
621
+ * Logs verbose messages with PII.
622
+ */
623
+ verbosePii(message, correlationId) {
624
+ this.logMessage(message, {
625
+ logLevel: exports.LogLevel.Verbose,
626
+ containsPii: true,
627
+ correlationId: correlationId || Constants.EMPTY_STRING,
628
+ });
629
+ }
630
+ /**
631
+ * Logs trace messages.
632
+ */
633
+ trace(message, correlationId) {
634
+ this.logMessage(message, {
635
+ logLevel: exports.LogLevel.Trace,
636
+ containsPii: false,
637
+ correlationId: correlationId || Constants.EMPTY_STRING,
638
+ });
639
+ }
640
+ /**
641
+ * Logs trace messages with PII.
642
+ */
643
+ tracePii(message, correlationId) {
644
+ this.logMessage(message, {
645
+ logLevel: exports.LogLevel.Trace,
646
+ containsPii: true,
647
+ correlationId: correlationId || Constants.EMPTY_STRING,
648
+ });
649
+ }
650
+ /**
651
+ * Returns whether PII Logging is enabled or not.
652
+ */
653
+ isPiiLoggingEnabled() {
654
+ return this.piiLoggingEnabled || false;
655
+ }
656
+ }
657
+
658
+ /* eslint-disable header/header */
659
+ const name = "@azure/msal-common";
660
+ const version = "14.0.3";
661
+
662
+ /*
663
+ * Copyright (c) Microsoft Corporation. All rights reserved.
664
+ * Licensed under the MIT License.
665
+ */
666
+ const AzureCloudInstance = {
667
+ // AzureCloudInstance is not specified.
668
+ None: "none",
669
+ // Microsoft Azure public cloud
670
+ AzurePublic: "https://login.microsoftonline.com",
671
+ // Microsoft PPE
672
+ AzurePpe: "https://login.windows-ppe.net",
673
+ // Microsoft Chinese national/regional cloud
674
+ AzureChina: "https://login.chinacloudapi.cn",
675
+ // Microsoft German national/regional cloud ("Black Forest")
676
+ AzureGermany: "https://login.microsoftonline.de",
677
+ // US Government cloud
678
+ AzureUsGovernment: "https://login.microsoftonline.us",
679
+ };
680
+
460
681
  /*
461
682
  * Copyright (c) Microsoft Corporation. All rights reserved.
462
683
  * Licensed under the MIT License.
@@ -982,765 +1203,515 @@ class ClientAuthError extends AuthError {
982
1203
  * Licensed under the MIT License.
983
1204
  */
984
1205
  /**
985
- * @hidden
1206
+ * ClientConfigurationErrorMessage class containing string constants used by error codes and messages.
986
1207
  */
987
- class StringUtils {
988
- /**
989
- * decode a JWT
990
- *
991
- * @param authToken
992
- */
993
- static decodeAuthToken(authToken) {
994
- if (StringUtils.isEmpty(authToken)) {
995
- throw ClientAuthError.createTokenNullOrEmptyError(authToken);
996
- }
997
- const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/;
998
- const matches = tokenPartsRegex.exec(authToken);
999
- if (!matches || matches.length < 4) {
1000
- throw ClientAuthError.createTokenParsingError(`Given token is malformed: ${JSON.stringify(authToken)}`);
1001
- }
1002
- const crackedToken = {
1003
- header: matches[1],
1004
- JWSPayload: matches[2],
1005
- JWSSig: matches[3],
1006
- };
1007
- return crackedToken;
1008
- }
1009
- /**
1010
- * Check if a string is empty.
1011
- *
1012
- * @param str
1013
- */
1014
- static isEmpty(str) {
1015
- return typeof str === "undefined" || !str || 0 === str.length;
1016
- }
1017
- /**
1018
- * Check if stringified object is empty
1019
- * @param strObj
1020
- */
1021
- static isEmptyObj(strObj) {
1022
- if (strObj && !StringUtils.isEmpty(strObj)) {
1023
- try {
1024
- const obj = JSON.parse(strObj);
1025
- return Object.keys(obj).length === 0;
1026
- }
1027
- catch (e) { }
1028
- }
1029
- return true;
1030
- }
1031
- static startsWith(str, search) {
1032
- return str.indexOf(search) === 0;
1033
- }
1034
- static endsWith(str, search) {
1035
- return (str.length >= search.length &&
1036
- str.lastIndexOf(search) === str.length - search.length);
1037
- }
1038
- /**
1039
- * Parses string into an object.
1040
- *
1041
- * @param query
1042
- */
1043
- static queryStringToObject(query) {
1044
- const obj = {};
1045
- const params = query.split("&");
1046
- const decode = (s) => decodeURIComponent(s.replace(/\+/g, " "));
1047
- params.forEach((pair) => {
1048
- if (pair.trim()) {
1049
- const [key, value] = pair.split(/=(.+)/g, 2); // Split on the first occurence of the '=' character
1050
- if (key && value) {
1051
- obj[decode(key)] = decode(value);
1052
- }
1053
- }
1054
- });
1055
- return obj;
1208
+ const ClientConfigurationErrorMessage = {
1209
+ redirectUriNotSet: {
1210
+ code: "redirect_uri_empty",
1211
+ desc: "A redirect URI is required for all calls, and none has been set.",
1212
+ },
1213
+ postLogoutUriNotSet: {
1214
+ code: "post_logout_uri_empty",
1215
+ desc: "A post logout redirect has not been set.",
1216
+ },
1217
+ claimsRequestParsingError: {
1218
+ code: "claims_request_parsing_error",
1219
+ desc: "Could not parse the given claims request object.",
1220
+ },
1221
+ authorityUriInsecure: {
1222
+ code: "authority_uri_insecure",
1223
+ desc: "Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options",
1224
+ },
1225
+ urlParseError: {
1226
+ code: "url_parse_error",
1227
+ desc: "URL could not be parsed into appropriate segments.",
1228
+ },
1229
+ urlEmptyError: {
1230
+ code: "empty_url_error",
1231
+ desc: "URL was empty or null.",
1232
+ },
1233
+ emptyScopesError: {
1234
+ code: "empty_input_scopes_error",
1235
+ desc: "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.",
1236
+ },
1237
+ nonArrayScopesError: {
1238
+ code: "nonarray_input_scopes_error",
1239
+ desc: "Scopes cannot be passed as non-array.",
1240
+ },
1241
+ clientIdSingleScopeError: {
1242
+ code: "clientid_input_scopes_error",
1243
+ desc: "Client ID can only be provided as a single scope.",
1244
+ },
1245
+ invalidPrompt: {
1246
+ code: "invalid_prompt_value",
1247
+ desc: "Supported prompt values are 'login', 'select_account', 'consent', 'create', 'none' and 'no_session'. Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest",
1248
+ },
1249
+ invalidClaimsRequest: {
1250
+ code: "invalid_claims",
1251
+ desc: "Given claims parameter must be a stringified JSON object.",
1252
+ },
1253
+ tokenRequestEmptyError: {
1254
+ code: "token_request_empty",
1255
+ desc: "Token request was empty and not found in cache.",
1256
+ },
1257
+ logoutRequestEmptyError: {
1258
+ code: "logout_request_empty",
1259
+ desc: "The logout request was null or undefined.",
1260
+ },
1261
+ invalidCodeChallengeMethod: {
1262
+ code: "invalid_code_challenge_method",
1263
+ desc: 'code_challenge_method passed is invalid. Valid values are "plain" and "S256".',
1264
+ },
1265
+ invalidCodeChallengeParams: {
1266
+ code: "pkce_params_missing",
1267
+ desc: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request",
1268
+ },
1269
+ invalidCloudDiscoveryMetadata: {
1270
+ code: "invalid_cloud_discovery_metadata",
1271
+ desc: "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields",
1272
+ },
1273
+ invalidAuthorityMetadata: {
1274
+ code: "invalid_authority_metadata",
1275
+ desc: "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields.",
1276
+ },
1277
+ untrustedAuthority: {
1278
+ code: "untrusted_authority",
1279
+ desc: "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.",
1280
+ },
1281
+ invalidAzureCloudInstance: {
1282
+ code: "invalid_azure_cloud_instance",
1283
+ desc: "Invalid AzureCloudInstance provided. Please refer MSAL JS docs: aks.ms/msaljs/azure_cloud_instance for valid values",
1284
+ },
1285
+ missingSshJwk: {
1286
+ code: "missing_ssh_jwk",
1287
+ desc: "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme.",
1288
+ },
1289
+ missingSshKid: {
1290
+ code: "missing_ssh_kid",
1291
+ desc: "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme.",
1292
+ },
1293
+ missingNonceAuthenticationHeader: {
1294
+ code: "missing_nonce_authentication_header",
1295
+ desc: "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce.",
1296
+ },
1297
+ invalidAuthenticationHeader: {
1298
+ code: "invalid_authentication_header",
1299
+ desc: "Invalid authentication header provided",
1300
+ },
1301
+ cannotSetOIDCOptions: {
1302
+ code: "cannot_set_OIDCOptions",
1303
+ desc: "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.",
1304
+ },
1305
+ cannotAllowNativeBroker: {
1306
+ code: "cannot_allow_native_broker",
1307
+ desc: "Cannot set allowNativeBroker parameter to true when not in AAD protocol mode.",
1308
+ },
1309
+ authorityMismatch: {
1310
+ code: "authority_mismatch",
1311
+ desc: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority.",
1312
+ },
1313
+ };
1314
+ /**
1315
+ * Error thrown when there is an error in configuration of the MSAL.js library.
1316
+ */
1317
+ class ClientConfigurationError extends ClientAuthError {
1318
+ constructor(errorCode, errorMessage) {
1319
+ super(errorCode, errorMessage);
1320
+ this.name = "ClientConfigurationError";
1321
+ Object.setPrototypeOf(this, ClientConfigurationError.prototype);
1056
1322
  }
1057
1323
  /**
1058
- * Trims entries in an array.
1059
- *
1060
- * @param arr
1324
+ * Creates an error thrown when the redirect uri is empty (not set by caller)
1061
1325
  */
1062
- static trimArrayEntries(arr) {
1063
- return arr.map((entry) => entry.trim());
1326
+ static createRedirectUriEmptyError() {
1327
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.redirectUriNotSet.code, ClientConfigurationErrorMessage.redirectUriNotSet.desc);
1064
1328
  }
1065
1329
  /**
1066
- * Removes empty strings from array
1067
- * @param arr
1330
+ * Creates an error thrown when the post-logout redirect uri is empty (not set by caller)
1068
1331
  */
1069
- static removeEmptyStringsFromArray(arr) {
1070
- return arr.filter((entry) => {
1071
- return !StringUtils.isEmpty(entry);
1072
- });
1332
+ static createPostLogoutRedirectUriEmptyError() {
1333
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.postLogoutUriNotSet.code, ClientConfigurationErrorMessage.postLogoutUriNotSet.desc);
1073
1334
  }
1074
1335
  /**
1075
- * Attempts to parse a string into JSON
1076
- * @param str
1336
+ * Creates an error thrown when the claims request could not be successfully parsed
1077
1337
  */
1078
- static jsonParseHelper(str) {
1079
- try {
1080
- return JSON.parse(str);
1081
- }
1082
- catch (e) {
1083
- return null;
1084
- }
1338
+ static createClaimsRequestParsingError(claimsRequestParseError) {
1339
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.claimsRequestParsingError.code, `${ClientConfigurationErrorMessage.claimsRequestParsingError.desc} Given value: ${claimsRequestParseError}`);
1085
1340
  }
1086
1341
  /**
1087
- * Tests if a given string matches a given pattern, with support for wildcards and queries.
1088
- * @param pattern Wildcard pattern to string match. Supports "*" for wildcards and "?" for queries
1089
- * @param input String to match against
1342
+ * Creates an error thrown if authority uri is given an insecure protocol.
1343
+ * @param urlString
1090
1344
  */
1091
- static matchPattern(pattern, input) {
1092
- /**
1093
- * Wildcard support: https://stackoverflow.com/a/3117248/4888559
1094
- * Queries: replaces "?" in string with escaped "\?" for regex test
1095
- */
1096
- // eslint-disable-next-line security/detect-non-literal-regexp
1097
- const regex = new RegExp(pattern
1098
- .replace(/\\/g, "\\\\")
1099
- .replace(/\*/g, "[^ ]*")
1100
- .replace(/\?/g, "\\?"));
1101
- return regex.test(input);
1102
- }
1103
- }
1104
-
1105
- /*
1106
- * Copyright (c) Microsoft Corporation. All rights reserved.
1107
- * Licensed under the MIT License.
1108
- */
1109
- /**
1110
- * Log message level.
1111
- */
1112
- exports.LogLevel = void 0;
1113
- (function (LogLevel) {
1114
- LogLevel[LogLevel["Error"] = 0] = "Error";
1115
- LogLevel[LogLevel["Warning"] = 1] = "Warning";
1116
- LogLevel[LogLevel["Info"] = 2] = "Info";
1117
- LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
1118
- LogLevel[LogLevel["Trace"] = 4] = "Trace";
1119
- })(exports.LogLevel || (exports.LogLevel = {}));
1120
- /**
1121
- * Class which facilitates logging of messages to a specific place.
1122
- */
1123
- class Logger {
1124
- constructor(loggerOptions, packageName, packageVersion) {
1125
- // Current log level, defaults to info.
1126
- this.level = exports.LogLevel.Info;
1127
- const defaultLoggerCallback = () => {
1128
- return;
1129
- };
1130
- const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
1131
- this.localCallback =
1132
- setLoggerOptions.loggerCallback || defaultLoggerCallback;
1133
- this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
1134
- this.level =
1135
- typeof setLoggerOptions.logLevel === "number"
1136
- ? setLoggerOptions.logLevel
1137
- : exports.LogLevel.Info;
1138
- this.correlationId =
1139
- setLoggerOptions.correlationId || Constants.EMPTY_STRING;
1140
- this.packageName = packageName || Constants.EMPTY_STRING;
1141
- this.packageVersion = packageVersion || Constants.EMPTY_STRING;
1345
+ static createInsecureAuthorityUriError(urlString) {
1346
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityUriInsecure.code, `${ClientConfigurationErrorMessage.authorityUriInsecure.desc} Given URI: ${urlString}`);
1142
1347
  }
1143
- static createDefaultLoggerOptions() {
1144
- return {
1145
- loggerCallback: () => {
1146
- // allow users to not set loggerCallback
1147
- },
1148
- piiLoggingEnabled: false,
1149
- logLevel: exports.LogLevel.Info,
1150
- };
1348
+ /**
1349
+ * Creates an error thrown if URL string does not parse into separate segments.
1350
+ * @param urlString
1351
+ */
1352
+ static createUrlParseError(urlParseError) {
1353
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.urlParseError.code, `${ClientConfigurationErrorMessage.urlParseError.desc} Given Error: ${urlParseError}`);
1151
1354
  }
1152
1355
  /**
1153
- * Create new Logger with existing configurations.
1356
+ * Creates an error thrown if URL string is empty or null.
1357
+ * @param urlString
1154
1358
  */
1155
- clone(packageName, packageVersion, correlationId) {
1156
- return new Logger({
1157
- loggerCallback: this.localCallback,
1158
- piiLoggingEnabled: this.piiLoggingEnabled,
1159
- logLevel: this.level,
1160
- correlationId: correlationId || this.correlationId,
1161
- }, packageName, packageVersion);
1359
+ static createUrlEmptyError() {
1360
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.urlEmptyError.code, ClientConfigurationErrorMessage.urlEmptyError.desc);
1162
1361
  }
1163
1362
  /**
1164
- * Log message with required options.
1363
+ * Error thrown when scopes are empty.
1364
+ * @param scopesValue
1165
1365
  */
1166
- logMessage(logMessage, options) {
1167
- if (options.logLevel > this.level ||
1168
- (!this.piiLoggingEnabled && options.containsPii)) {
1169
- return;
1170
- }
1171
- const timestamp = new Date().toUTCString();
1172
- // Add correlationId to logs if set, correlationId provided on log messages take precedence
1173
- let logHeader;
1174
- if (!StringUtils.isEmpty(options.correlationId)) {
1175
- logHeader = `[${timestamp}] : [${options.correlationId}]`;
1176
- }
1177
- else if (!StringUtils.isEmpty(this.correlationId)) {
1178
- logHeader = `[${timestamp}] : [${this.correlationId}]`;
1179
- }
1180
- else {
1181
- logHeader = `[${timestamp}]`;
1182
- }
1183
- const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${exports.LogLevel[options.logLevel]} - ${logMessage}`;
1184
- // debug(`msal:${LogLevel[options.logLevel]}${options.containsPii ? "-Pii": Constants.EMPTY_STRING}${options.context ? `:${options.context}` : Constants.EMPTY_STRING}`)(logMessage);
1185
- this.executeCallback(options.logLevel, log, options.containsPii || false);
1366
+ static createEmptyScopesArrayError() {
1367
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.emptyScopesError.code, `${ClientConfigurationErrorMessage.emptyScopesError.desc}`);
1186
1368
  }
1187
1369
  /**
1188
- * Execute callback with message.
1370
+ * Error thrown when client id scope is not provided as single scope.
1371
+ * @param inputScopes
1189
1372
  */
1190
- executeCallback(level, message, containsPii) {
1191
- if (this.localCallback) {
1192
- this.localCallback(level, message, containsPii);
1193
- }
1373
+ static createClientIdSingleScopeError(inputScopes) {
1374
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.clientIdSingleScopeError.code, `${ClientConfigurationErrorMessage.clientIdSingleScopeError.desc} Given Scopes: ${inputScopes}`);
1194
1375
  }
1195
1376
  /**
1196
- * Logs error messages.
1377
+ * Error thrown when prompt is not an allowed type.
1378
+ * @param promptValue
1197
1379
  */
1198
- error(message, correlationId) {
1199
- this.logMessage(message, {
1200
- logLevel: exports.LogLevel.Error,
1201
- containsPii: false,
1202
- correlationId: correlationId || Constants.EMPTY_STRING,
1203
- });
1380
+ static createInvalidPromptError(promptValue) {
1381
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidPrompt.code, `${ClientConfigurationErrorMessage.invalidPrompt.desc} Given value: ${promptValue}`);
1204
1382
  }
1205
1383
  /**
1206
- * Logs error messages with PII.
1384
+ * Creates error thrown when claims parameter is not a stringified JSON object
1207
1385
  */
1208
- errorPii(message, correlationId) {
1209
- this.logMessage(message, {
1210
- logLevel: exports.LogLevel.Error,
1211
- containsPii: true,
1212
- correlationId: correlationId || Constants.EMPTY_STRING,
1213
- });
1386
+ static createInvalidClaimsRequestError() {
1387
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidClaimsRequest.code, ClientConfigurationErrorMessage.invalidClaimsRequest.desc);
1214
1388
  }
1215
1389
  /**
1216
- * Logs warning messages.
1390
+ * Throws error when token request is empty and nothing cached in storage.
1217
1391
  */
1218
- warning(message, correlationId) {
1219
- this.logMessage(message, {
1220
- logLevel: exports.LogLevel.Warning,
1221
- containsPii: false,
1222
- correlationId: correlationId || Constants.EMPTY_STRING,
1223
- });
1392
+ static createEmptyLogoutRequestError() {
1393
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.logoutRequestEmptyError.code, ClientConfigurationErrorMessage.logoutRequestEmptyError.desc);
1224
1394
  }
1225
1395
  /**
1226
- * Logs warning messages with PII.
1396
+ * Throws error when token request is empty and nothing cached in storage.
1227
1397
  */
1228
- warningPii(message, correlationId) {
1229
- this.logMessage(message, {
1230
- logLevel: exports.LogLevel.Warning,
1231
- containsPii: true,
1232
- correlationId: correlationId || Constants.EMPTY_STRING,
1233
- });
1398
+ static createEmptyTokenRequestError() {
1399
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.tokenRequestEmptyError.code, ClientConfigurationErrorMessage.tokenRequestEmptyError.desc);
1234
1400
  }
1235
1401
  /**
1236
- * Logs info messages.
1402
+ * Throws error when an invalid code_challenge_method is passed by the user
1237
1403
  */
1238
- info(message, correlationId) {
1239
- this.logMessage(message, {
1240
- logLevel: exports.LogLevel.Info,
1241
- containsPii: false,
1242
- correlationId: correlationId || Constants.EMPTY_STRING,
1243
- });
1404
+ static createInvalidCodeChallengeMethodError() {
1405
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeMethod.code, ClientConfigurationErrorMessage.invalidCodeChallengeMethod.desc);
1244
1406
  }
1245
1407
  /**
1246
- * Logs info messages with PII.
1408
+ * Throws error when both params: code_challenge and code_challenge_method are not passed together
1247
1409
  */
1248
- infoPii(message, correlationId) {
1249
- this.logMessage(message, {
1250
- logLevel: exports.LogLevel.Info,
1251
- containsPii: true,
1252
- correlationId: correlationId || Constants.EMPTY_STRING,
1253
- });
1410
+ static createInvalidCodeChallengeParamsError() {
1411
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeParams.code, ClientConfigurationErrorMessage.invalidCodeChallengeParams.desc);
1254
1412
  }
1255
1413
  /**
1256
- * Logs verbose messages.
1414
+ * Throws an error when the user passes invalid cloudDiscoveryMetadata
1257
1415
  */
1258
- verbose(message, correlationId) {
1259
- this.logMessage(message, {
1260
- logLevel: exports.LogLevel.Verbose,
1261
- containsPii: false,
1262
- correlationId: correlationId || Constants.EMPTY_STRING,
1263
- });
1416
+ static createInvalidCloudDiscoveryMetadataError() {
1417
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.code, ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.desc);
1264
1418
  }
1265
1419
  /**
1266
- * Logs verbose messages with PII.
1420
+ * Throws an error when the user passes invalid cloudDiscoveryMetadata
1267
1421
  */
1268
- verbosePii(message, correlationId) {
1269
- this.logMessage(message, {
1270
- logLevel: exports.LogLevel.Verbose,
1271
- containsPii: true,
1272
- correlationId: correlationId || Constants.EMPTY_STRING,
1273
- });
1422
+ static createInvalidAuthorityMetadataError() {
1423
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthorityMetadata.code, ClientConfigurationErrorMessage.invalidAuthorityMetadata.desc);
1274
1424
  }
1275
1425
  /**
1276
- * Logs trace messages.
1426
+ * Throws error when provided authority is not a member of the trusted host list
1277
1427
  */
1278
- trace(message, correlationId) {
1279
- this.logMessage(message, {
1280
- logLevel: exports.LogLevel.Trace,
1281
- containsPii: false,
1282
- correlationId: correlationId || Constants.EMPTY_STRING,
1283
- });
1428
+ static createUntrustedAuthorityError() {
1429
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.untrustedAuthority.code, ClientConfigurationErrorMessage.untrustedAuthority.desc);
1284
1430
  }
1285
1431
  /**
1286
- * Logs trace messages with PII.
1432
+ * Throws error when the AzureCloudInstance is set to an invalid value
1287
1433
  */
1288
- tracePii(message, correlationId) {
1289
- this.logMessage(message, {
1290
- logLevel: exports.LogLevel.Trace,
1291
- containsPii: true,
1292
- correlationId: correlationId || Constants.EMPTY_STRING,
1293
- });
1434
+ static createInvalidAzureCloudInstanceError() {
1435
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAzureCloudInstance.code, ClientConfigurationErrorMessage.invalidAzureCloudInstance.desc);
1294
1436
  }
1295
1437
  /**
1296
- * Returns whether PII Logging is enabled or not.
1438
+ * Throws an error when the authentication scheme is set to SSH but the SSH public key is omitted from the request
1297
1439
  */
1298
- isPiiLoggingEnabled() {
1299
- return this.piiLoggingEnabled || false;
1440
+ static createMissingSshJwkError() {
1441
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshJwk.code, ClientConfigurationErrorMessage.missingSshJwk.desc);
1442
+ }
1443
+ /**
1444
+ * Throws an error when the authentication scheme is set to SSH but the SSH public key ID is omitted from the request
1445
+ */
1446
+ static createMissingSshKidError() {
1447
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshKid.code, ClientConfigurationErrorMessage.missingSshKid.desc);
1448
+ }
1449
+ /**
1450
+ * Throws error when provided headers don't contain a header that a server nonce can be extracted from
1451
+ */
1452
+ static createMissingNonceAuthenticationHeadersError() {
1453
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.code, ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.desc);
1454
+ }
1455
+ /**
1456
+ * Throws error when a provided header is invalid in any way
1457
+ */
1458
+ static createInvalidAuthenticationHeaderError(invalidHeaderName, details) {
1459
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthenticationHeader.code, `${ClientConfigurationErrorMessage.invalidAuthenticationHeader.desc}. Invalid header: ${invalidHeaderName}. Details: ${details}`);
1460
+ }
1461
+ /**
1462
+ * Throws error when provided non-default OIDCOptions when not in OIDC protocol mode
1463
+ */
1464
+ static createCannotSetOIDCOptionsError() {
1465
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.cannotSetOIDCOptions.code, ClientConfigurationErrorMessage.cannotSetOIDCOptions.desc);
1466
+ }
1467
+ /**
1468
+ * Throws error when allowNativeBroker is set to true when not in AAD protocol mode
1469
+ */
1470
+ static createCannotAllowNativeBrokerError() {
1471
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.cannotAllowNativeBroker.code, ClientConfigurationErrorMessage.cannotAllowNativeBroker.desc);
1472
+ }
1473
+ /**
1474
+ * Create an error when the authority provided in request does not match authority provided in account or MSAL.js configuration.
1475
+ */
1476
+ static createAuthorityMismatchError() {
1477
+ return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityMismatch.code, ClientConfigurationErrorMessage.authorityMismatch.desc);
1300
1478
  }
1301
1479
  }
1302
1480
 
1303
- /* eslint-disable header/header */
1304
- const name = "@azure/msal-common";
1305
- const version = "14.0.2";
1306
-
1307
1481
  /*
1308
1482
  * Copyright (c) Microsoft Corporation. All rights reserved.
1309
1483
  * Licensed under the MIT License.
1310
1484
  */
1311
- const AzureCloudInstance = {
1312
- // AzureCloudInstance is not specified.
1313
- None: "none",
1314
- // Microsoft Azure public cloud
1315
- AzurePublic: "https://login.microsoftonline.com",
1316
- // Microsoft PPE
1317
- AzurePpe: "https://login.windows-ppe.net",
1318
- // Microsoft Chinese national/regional cloud
1319
- AzureChina: "https://login.chinacloudapi.cn",
1320
- // Microsoft German national/regional cloud ("Black Forest")
1321
- AzureGermany: "https://login.microsoftonline.de",
1322
- // US Government cloud
1323
- AzureUsGovernment: "https://login.microsoftonline.us",
1324
- };
1485
+ /**
1486
+ * @hidden
1487
+ */
1488
+ class StringUtils {
1489
+ /**
1490
+ * Check if stringified object is empty
1491
+ * @param strObj
1492
+ */
1493
+ static isEmptyObj(strObj) {
1494
+ if (strObj) {
1495
+ try {
1496
+ const obj = JSON.parse(strObj);
1497
+ return Object.keys(obj).length === 0;
1498
+ }
1499
+ catch (e) { }
1500
+ }
1501
+ return true;
1502
+ }
1503
+ static startsWith(str, search) {
1504
+ return str.indexOf(search) === 0;
1505
+ }
1506
+ static endsWith(str, search) {
1507
+ return (str.length >= search.length &&
1508
+ str.lastIndexOf(search) === str.length - search.length);
1509
+ }
1510
+ /**
1511
+ * Parses string into an object.
1512
+ *
1513
+ * @param query
1514
+ */
1515
+ static queryStringToObject(query) {
1516
+ const obj = {};
1517
+ const params = query.split("&");
1518
+ const decode = (s) => decodeURIComponent(s.replace(/\+/g, " "));
1519
+ params.forEach((pair) => {
1520
+ if (pair.trim()) {
1521
+ const [key, value] = pair.split(/=(.+)/g, 2); // Split on the first occurence of the '=' character
1522
+ if (key && value) {
1523
+ obj[decode(key)] = decode(value);
1524
+ }
1525
+ }
1526
+ });
1527
+ return obj;
1528
+ }
1529
+ /**
1530
+ * Trims entries in an array.
1531
+ *
1532
+ * @param arr
1533
+ */
1534
+ static trimArrayEntries(arr) {
1535
+ return arr.map((entry) => entry.trim());
1536
+ }
1537
+ /**
1538
+ * Removes empty strings from array
1539
+ * @param arr
1540
+ */
1541
+ static removeEmptyStringsFromArray(arr) {
1542
+ return arr.filter((entry) => {
1543
+ return !!entry;
1544
+ });
1545
+ }
1546
+ /**
1547
+ * Attempts to parse a string into JSON
1548
+ * @param str
1549
+ */
1550
+ static jsonParseHelper(str) {
1551
+ try {
1552
+ return JSON.parse(str);
1553
+ }
1554
+ catch (e) {
1555
+ return null;
1556
+ }
1557
+ }
1558
+ /**
1559
+ * Tests if a given string matches a given pattern, with support for wildcards and queries.
1560
+ * @param pattern Wildcard pattern to string match. Supports "*" for wildcards and "?" for queries
1561
+ * @param input String to match against
1562
+ */
1563
+ static matchPattern(pattern, input) {
1564
+ /**
1565
+ * Wildcard support: https://stackoverflow.com/a/3117248/4888559
1566
+ * Queries: replaces "?" in string with escaped "\?" for regex test
1567
+ */
1568
+ // eslint-disable-next-line security/detect-non-literal-regexp
1569
+ const regex = new RegExp(pattern
1570
+ .replace(/\\/g, "\\\\")
1571
+ .replace(/\*/g, "[^ ]*")
1572
+ .replace(/\?/g, "\\?"));
1573
+ return regex.test(input);
1574
+ }
1575
+ }
1325
1576
 
1326
1577
  /*
1327
1578
  * Copyright (c) Microsoft Corporation. All rights reserved.
1328
1579
  * Licensed under the MIT License.
1329
1580
  */
1330
1581
  /**
1331
- * ClientConfigurationErrorMessage class containing string constants used by error codes and messages.
1332
- */
1333
- const ClientConfigurationErrorMessage = {
1334
- redirectUriNotSet: {
1335
- code: "redirect_uri_empty",
1336
- desc: "A redirect URI is required for all calls, and none has been set.",
1337
- },
1338
- postLogoutUriNotSet: {
1339
- code: "post_logout_uri_empty",
1340
- desc: "A post logout redirect has not been set.",
1341
- },
1342
- claimsRequestParsingError: {
1343
- code: "claims_request_parsing_error",
1344
- desc: "Could not parse the given claims request object.",
1345
- },
1346
- authorityUriInsecure: {
1347
- code: "authority_uri_insecure",
1348
- desc: "Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options",
1349
- },
1350
- urlParseError: {
1351
- code: "url_parse_error",
1352
- desc: "URL could not be parsed into appropriate segments.",
1353
- },
1354
- urlEmptyError: {
1355
- code: "empty_url_error",
1356
- desc: "URL was empty or null.",
1357
- },
1358
- emptyScopesError: {
1359
- code: "empty_input_scopes_error",
1360
- desc: "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.",
1361
- },
1362
- nonArrayScopesError: {
1363
- code: "nonarray_input_scopes_error",
1364
- desc: "Scopes cannot be passed as non-array.",
1365
- },
1366
- clientIdSingleScopeError: {
1367
- code: "clientid_input_scopes_error",
1368
- desc: "Client ID can only be provided as a single scope.",
1369
- },
1370
- invalidPrompt: {
1371
- code: "invalid_prompt_value",
1372
- desc: "Supported prompt values are 'login', 'select_account', 'consent', 'create', 'none' and 'no_session'. Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest",
1373
- },
1374
- invalidClaimsRequest: {
1375
- code: "invalid_claims",
1376
- desc: "Given claims parameter must be a stringified JSON object.",
1377
- },
1378
- tokenRequestEmptyError: {
1379
- code: "token_request_empty",
1380
- desc: "Token request was empty and not found in cache.",
1381
- },
1382
- logoutRequestEmptyError: {
1383
- code: "logout_request_empty",
1384
- desc: "The logout request was null or undefined.",
1385
- },
1386
- invalidCodeChallengeMethod: {
1387
- code: "invalid_code_challenge_method",
1388
- desc: 'code_challenge_method passed is invalid. Valid values are "plain" and "S256".',
1389
- },
1390
- invalidCodeChallengeParams: {
1391
- code: "pkce_params_missing",
1392
- desc: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request",
1393
- },
1394
- invalidCloudDiscoveryMetadata: {
1395
- code: "invalid_cloud_discovery_metadata",
1396
- desc: "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields",
1397
- },
1398
- invalidAuthorityMetadata: {
1399
- code: "invalid_authority_metadata",
1400
- desc: "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields.",
1401
- },
1402
- untrustedAuthority: {
1403
- code: "untrusted_authority",
1404
- desc: "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.",
1405
- },
1406
- invalidAzureCloudInstance: {
1407
- code: "invalid_azure_cloud_instance",
1408
- desc: "Invalid AzureCloudInstance provided. Please refer MSAL JS docs: aks.ms/msaljs/azure_cloud_instance for valid values",
1409
- },
1410
- missingSshJwk: {
1411
- code: "missing_ssh_jwk",
1412
- desc: "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme.",
1413
- },
1414
- missingSshKid: {
1415
- code: "missing_ssh_kid",
1416
- desc: "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme.",
1417
- },
1418
- missingNonceAuthenticationHeader: {
1419
- code: "missing_nonce_authentication_header",
1420
- desc: "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce.",
1421
- },
1422
- invalidAuthenticationHeader: {
1423
- code: "invalid_authentication_header",
1424
- desc: "Invalid authentication header provided",
1425
- },
1426
- cannotSetOIDCOptions: {
1427
- code: "cannot_set_OIDCOptions",
1428
- desc: "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.",
1429
- },
1430
- cannotAllowNativeBroker: {
1431
- code: "cannot_allow_native_broker",
1432
- desc: "Cannot set allowNativeBroker parameter to true when not in AAD protocol mode.",
1433
- },
1434
- authorityMismatch: {
1435
- code: "authority_mismatch",
1436
- desc: "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority.",
1437
- },
1438
- };
1439
- /**
1440
- * Error thrown when there is an error in configuration of the MSAL.js library.
1582
+ * The ScopeSet class creates a set of scopes. Scopes are case-insensitive, unique values, so the Set object in JS makes
1583
+ * the most sense to implement for this class. All scopes are trimmed and converted to lower case strings in intersection and union functions
1584
+ * to ensure uniqueness of strings.
1441
1585
  */
1442
- class ClientConfigurationError extends ClientAuthError {
1443
- constructor(errorCode, errorMessage) {
1444
- super(errorCode, errorMessage);
1445
- this.name = "ClientConfigurationError";
1446
- Object.setPrototypeOf(this, ClientConfigurationError.prototype);
1447
- }
1448
- /**
1449
- * Creates an error thrown when the redirect uri is empty (not set by caller)
1450
- */
1451
- static createRedirectUriEmptyError() {
1452
- return new ClientConfigurationError(ClientConfigurationErrorMessage.redirectUriNotSet.code, ClientConfigurationErrorMessage.redirectUriNotSet.desc);
1586
+ class ScopeSet {
1587
+ constructor(inputScopes) {
1588
+ // Filter empty string and null/undefined array items
1589
+ const scopeArr = inputScopes
1590
+ ? StringUtils.trimArrayEntries([...inputScopes])
1591
+ : [];
1592
+ const filteredInput = scopeArr
1593
+ ? StringUtils.removeEmptyStringsFromArray(scopeArr)
1594
+ : [];
1595
+ // Validate and filter scopes (validate function throws if validation fails)
1596
+ this.validateInputScopes(filteredInput);
1597
+ this.scopes = new Set(); // Iterator in constructor not supported by IE11
1598
+ filteredInput.forEach((scope) => this.scopes.add(scope));
1453
1599
  }
1454
1600
  /**
1455
- * Creates an error thrown when the post-logout redirect uri is empty (not set by caller)
1601
+ * Factory method to create ScopeSet from space-delimited string
1602
+ * @param inputScopeString
1603
+ * @param appClientId
1604
+ * @param scopesRequired
1456
1605
  */
1457
- static createPostLogoutRedirectUriEmptyError() {
1458
- return new ClientConfigurationError(ClientConfigurationErrorMessage.postLogoutUriNotSet.code, ClientConfigurationErrorMessage.postLogoutUriNotSet.desc);
1606
+ static fromString(inputScopeString) {
1607
+ const scopeString = inputScopeString || Constants.EMPTY_STRING;
1608
+ const inputScopes = scopeString.split(" ");
1609
+ return new ScopeSet(inputScopes);
1459
1610
  }
1460
1611
  /**
1461
- * Creates an error thrown when the claims request could not be successfully parsed
1612
+ * Creates the set of scopes to search for in cache lookups
1613
+ * @param inputScopeString
1614
+ * @returns
1462
1615
  */
1463
- static createClaimsRequestParsingError(claimsRequestParseError) {
1464
- return new ClientConfigurationError(ClientConfigurationErrorMessage.claimsRequestParsingError.code, `${ClientConfigurationErrorMessage.claimsRequestParsingError.desc} Given value: ${claimsRequestParseError}`);
1616
+ static createSearchScopes(inputScopeString) {
1617
+ const scopeSet = new ScopeSet(inputScopeString);
1618
+ if (!scopeSet.containsOnlyOIDCScopes()) {
1619
+ scopeSet.removeOIDCScopes();
1620
+ }
1621
+ else {
1622
+ scopeSet.removeScope(Constants.OFFLINE_ACCESS_SCOPE);
1623
+ }
1624
+ return scopeSet;
1465
1625
  }
1466
1626
  /**
1467
- * Creates an error thrown if authority uri is given an insecure protocol.
1468
- * @param urlString
1627
+ * Used to validate the scopes input parameter requested by the developer.
1628
+ * @param {Array<string>} inputScopes - Developer requested permissions. Not all scopes are guaranteed to be included in the access token returned.
1629
+ * @param {boolean} scopesRequired - Boolean indicating whether the scopes array is required or not
1469
1630
  */
1470
- static createInsecureAuthorityUriError(urlString) {
1471
- return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityUriInsecure.code, `${ClientConfigurationErrorMessage.authorityUriInsecure.desc} Given URI: ${urlString}`);
1631
+ validateInputScopes(inputScopes) {
1632
+ // Check if scopes are required but not given or is an empty array
1633
+ if (!inputScopes || inputScopes.length < 1) {
1634
+ throw ClientConfigurationError.createEmptyScopesArrayError();
1635
+ }
1472
1636
  }
1473
1637
  /**
1474
- * Creates an error thrown if URL string does not parse into separate segments.
1475
- * @param urlString
1638
+ * Check if a given scope is present in this set of scopes.
1639
+ * @param scope
1476
1640
  */
1477
- static createUrlParseError(urlParseError) {
1478
- return new ClientConfigurationError(ClientConfigurationErrorMessage.urlParseError.code, `${ClientConfigurationErrorMessage.urlParseError.desc} Given Error: ${urlParseError}`);
1641
+ containsScope(scope) {
1642
+ const lowerCaseScopes = this.printScopesLowerCase().split(" ");
1643
+ const lowerCaseScopesSet = new ScopeSet(lowerCaseScopes);
1644
+ // compare lowercase scopes
1645
+ return scope
1646
+ ? lowerCaseScopesSet.scopes.has(scope.toLowerCase())
1647
+ : false;
1479
1648
  }
1480
1649
  /**
1481
- * Creates an error thrown if URL string is empty or null.
1482
- * @param urlString
1650
+ * Check if a set of scopes is present in this set of scopes.
1651
+ * @param scopeSet
1483
1652
  */
1484
- static createUrlEmptyError() {
1485
- return new ClientConfigurationError(ClientConfigurationErrorMessage.urlEmptyError.code, ClientConfigurationErrorMessage.urlEmptyError.desc);
1653
+ containsScopeSet(scopeSet) {
1654
+ if (!scopeSet || scopeSet.scopes.size <= 0) {
1655
+ return false;
1656
+ }
1657
+ return (this.scopes.size >= scopeSet.scopes.size &&
1658
+ scopeSet.asArray().every((scope) => this.containsScope(scope)));
1486
1659
  }
1487
1660
  /**
1488
- * Error thrown when scopes are empty.
1489
- * @param scopesValue
1661
+ * Check if set of scopes contains only the defaults
1490
1662
  */
1491
- static createEmptyScopesArrayError() {
1492
- return new ClientConfigurationError(ClientConfigurationErrorMessage.emptyScopesError.code, `${ClientConfigurationErrorMessage.emptyScopesError.desc}`);
1663
+ containsOnlyOIDCScopes() {
1664
+ let defaultScopeCount = 0;
1665
+ OIDC_SCOPES.forEach((defaultScope) => {
1666
+ if (this.containsScope(defaultScope)) {
1667
+ defaultScopeCount += 1;
1668
+ }
1669
+ });
1670
+ return this.scopes.size === defaultScopeCount;
1493
1671
  }
1494
1672
  /**
1495
- * Error thrown when client id scope is not provided as single scope.
1496
- * @param inputScopes
1673
+ * Appends single scope if passed
1674
+ * @param newScope
1497
1675
  */
1498
- static createClientIdSingleScopeError(inputScopes) {
1499
- return new ClientConfigurationError(ClientConfigurationErrorMessage.clientIdSingleScopeError.code, `${ClientConfigurationErrorMessage.clientIdSingleScopeError.desc} Given Scopes: ${inputScopes}`);
1676
+ appendScope(newScope) {
1677
+ if (newScope) {
1678
+ this.scopes.add(newScope.trim());
1679
+ }
1500
1680
  }
1501
1681
  /**
1502
- * Error thrown when prompt is not an allowed type.
1503
- * @param promptValue
1682
+ * Appends multiple scopes if passed
1683
+ * @param newScopes
1504
1684
  */
1505
- static createInvalidPromptError(promptValue) {
1506
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidPrompt.code, `${ClientConfigurationErrorMessage.invalidPrompt.desc} Given value: ${promptValue}`);
1685
+ appendScopes(newScopes) {
1686
+ try {
1687
+ newScopes.forEach((newScope) => this.appendScope(newScope));
1688
+ }
1689
+ catch (e) {
1690
+ throw ClientAuthError.createAppendScopeSetError(e);
1691
+ }
1507
1692
  }
1508
1693
  /**
1509
- * Creates error thrown when claims parameter is not a stringified JSON object
1694
+ * Removes element from set of scopes.
1695
+ * @param scope
1510
1696
  */
1511
- static createInvalidClaimsRequestError() {
1512
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidClaimsRequest.code, ClientConfigurationErrorMessage.invalidClaimsRequest.desc);
1697
+ removeScope(scope) {
1698
+ if (!scope) {
1699
+ throw ClientAuthError.createRemoveEmptyScopeFromSetError(scope);
1700
+ }
1701
+ this.scopes.delete(scope.trim());
1513
1702
  }
1514
1703
  /**
1515
- * Throws error when token request is empty and nothing cached in storage.
1704
+ * Removes default scopes from set of scopes
1705
+ * Primarily used to prevent cache misses if the default scopes are not returned from the server
1516
1706
  */
1517
- static createEmptyLogoutRequestError() {
1518
- return new ClientConfigurationError(ClientConfigurationErrorMessage.logoutRequestEmptyError.code, ClientConfigurationErrorMessage.logoutRequestEmptyError.desc);
1707
+ removeOIDCScopes() {
1708
+ OIDC_SCOPES.forEach((defaultScope) => {
1709
+ this.scopes.delete(defaultScope);
1710
+ });
1519
1711
  }
1520
1712
  /**
1521
- * Throws error when token request is empty and nothing cached in storage.
1522
- */
1523
- static createEmptyTokenRequestError() {
1524
- return new ClientConfigurationError(ClientConfigurationErrorMessage.tokenRequestEmptyError.code, ClientConfigurationErrorMessage.tokenRequestEmptyError.desc);
1525
- }
1526
- /**
1527
- * Throws error when an invalid code_challenge_method is passed by the user
1528
- */
1529
- static createInvalidCodeChallengeMethodError() {
1530
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeMethod.code, ClientConfigurationErrorMessage.invalidCodeChallengeMethod.desc);
1531
- }
1532
- /**
1533
- * Throws error when both params: code_challenge and code_challenge_method are not passed together
1534
- */
1535
- static createInvalidCodeChallengeParamsError() {
1536
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCodeChallengeParams.code, ClientConfigurationErrorMessage.invalidCodeChallengeParams.desc);
1537
- }
1538
- /**
1539
- * Throws an error when the user passes invalid cloudDiscoveryMetadata
1540
- */
1541
- static createInvalidCloudDiscoveryMetadataError() {
1542
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.code, ClientConfigurationErrorMessage.invalidCloudDiscoveryMetadata.desc);
1543
- }
1544
- /**
1545
- * Throws an error when the user passes invalid cloudDiscoveryMetadata
1546
- */
1547
- static createInvalidAuthorityMetadataError() {
1548
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthorityMetadata.code, ClientConfigurationErrorMessage.invalidAuthorityMetadata.desc);
1549
- }
1550
- /**
1551
- * Throws error when provided authority is not a member of the trusted host list
1552
- */
1553
- static createUntrustedAuthorityError() {
1554
- return new ClientConfigurationError(ClientConfigurationErrorMessage.untrustedAuthority.code, ClientConfigurationErrorMessage.untrustedAuthority.desc);
1555
- }
1556
- /**
1557
- * Throws error when the AzureCloudInstance is set to an invalid value
1558
- */
1559
- static createInvalidAzureCloudInstanceError() {
1560
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAzureCloudInstance.code, ClientConfigurationErrorMessage.invalidAzureCloudInstance.desc);
1561
- }
1562
- /**
1563
- * Throws an error when the authentication scheme is set to SSH but the SSH public key is omitted from the request
1564
- */
1565
- static createMissingSshJwkError() {
1566
- return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshJwk.code, ClientConfigurationErrorMessage.missingSshJwk.desc);
1567
- }
1568
- /**
1569
- * Throws an error when the authentication scheme is set to SSH but the SSH public key ID is omitted from the request
1570
- */
1571
- static createMissingSshKidError() {
1572
- return new ClientConfigurationError(ClientConfigurationErrorMessage.missingSshKid.code, ClientConfigurationErrorMessage.missingSshKid.desc);
1573
- }
1574
- /**
1575
- * Throws error when provided headers don't contain a header that a server nonce can be extracted from
1576
- */
1577
- static createMissingNonceAuthenticationHeadersError() {
1578
- return new ClientConfigurationError(ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.code, ClientConfigurationErrorMessage.missingNonceAuthenticationHeader.desc);
1579
- }
1580
- /**
1581
- * Throws error when a provided header is invalid in any way
1582
- */
1583
- static createInvalidAuthenticationHeaderError(invalidHeaderName, details) {
1584
- return new ClientConfigurationError(ClientConfigurationErrorMessage.invalidAuthenticationHeader.code, `${ClientConfigurationErrorMessage.invalidAuthenticationHeader.desc}. Invalid header: ${invalidHeaderName}. Details: ${details}`);
1585
- }
1586
- /**
1587
- * Throws error when provided non-default OIDCOptions when not in OIDC protocol mode
1588
- */
1589
- static createCannotSetOIDCOptionsError() {
1590
- return new ClientConfigurationError(ClientConfigurationErrorMessage.cannotSetOIDCOptions.code, ClientConfigurationErrorMessage.cannotSetOIDCOptions.desc);
1591
- }
1592
- /**
1593
- * Throws error when allowNativeBroker is set to true when not in AAD protocol mode
1594
- */
1595
- static createCannotAllowNativeBrokerError() {
1596
- return new ClientConfigurationError(ClientConfigurationErrorMessage.cannotAllowNativeBroker.code, ClientConfigurationErrorMessage.cannotAllowNativeBroker.desc);
1597
- }
1598
- /**
1599
- * Create an error when the authority provided in request does not match authority provided in account or MSAL.js configuration.
1600
- */
1601
- static createAuthorityMismatchError() {
1602
- return new ClientConfigurationError(ClientConfigurationErrorMessage.authorityMismatch.code, ClientConfigurationErrorMessage.authorityMismatch.desc);
1603
- }
1604
- }
1605
-
1606
- /*
1607
- * Copyright (c) Microsoft Corporation. All rights reserved.
1608
- * Licensed under the MIT License.
1609
- */
1610
- /**
1611
- * The ScopeSet class creates a set of scopes. Scopes are case-insensitive, unique values, so the Set object in JS makes
1612
- * the most sense to implement for this class. All scopes are trimmed and converted to lower case strings in intersection and union functions
1613
- * to ensure uniqueness of strings.
1614
- */
1615
- class ScopeSet {
1616
- constructor(inputScopes) {
1617
- // Filter empty string and null/undefined array items
1618
- const scopeArr = inputScopes
1619
- ? StringUtils.trimArrayEntries([...inputScopes])
1620
- : [];
1621
- const filteredInput = scopeArr
1622
- ? StringUtils.removeEmptyStringsFromArray(scopeArr)
1623
- : [];
1624
- // Validate and filter scopes (validate function throws if validation fails)
1625
- this.validateInputScopes(filteredInput);
1626
- this.scopes = new Set(); // Iterator in constructor not supported by IE11
1627
- filteredInput.forEach((scope) => this.scopes.add(scope));
1628
- }
1629
- /**
1630
- * Factory method to create ScopeSet from space-delimited string
1631
- * @param inputScopeString
1632
- * @param appClientId
1633
- * @param scopesRequired
1634
- */
1635
- static fromString(inputScopeString) {
1636
- const scopeString = inputScopeString || Constants.EMPTY_STRING;
1637
- const inputScopes = scopeString.split(" ");
1638
- return new ScopeSet(inputScopes);
1639
- }
1640
- /**
1641
- * Creates the set of scopes to search for in cache lookups
1642
- * @param inputScopeString
1643
- * @returns
1644
- */
1645
- static createSearchScopes(inputScopeString) {
1646
- const scopeSet = new ScopeSet(inputScopeString);
1647
- if (!scopeSet.containsOnlyOIDCScopes()) {
1648
- scopeSet.removeOIDCScopes();
1649
- }
1650
- else {
1651
- scopeSet.removeScope(Constants.OFFLINE_ACCESS_SCOPE);
1652
- }
1653
- return scopeSet;
1654
- }
1655
- /**
1656
- * Used to validate the scopes input parameter requested by the developer.
1657
- * @param {Array<string>} inputScopes - Developer requested permissions. Not all scopes are guaranteed to be included in the access token returned.
1658
- * @param {boolean} scopesRequired - Boolean indicating whether the scopes array is required or not
1659
- */
1660
- validateInputScopes(inputScopes) {
1661
- // Check if scopes are required but not given or is an empty array
1662
- if (!inputScopes || inputScopes.length < 1) {
1663
- throw ClientConfigurationError.createEmptyScopesArrayError();
1664
- }
1665
- }
1666
- /**
1667
- * Check if a given scope is present in this set of scopes.
1668
- * @param scope
1669
- */
1670
- containsScope(scope) {
1671
- const lowerCaseScopes = this.printScopesLowerCase().split(" ");
1672
- const lowerCaseScopesSet = new ScopeSet(lowerCaseScopes);
1673
- // compare lowercase scopes
1674
- return !StringUtils.isEmpty(scope)
1675
- ? lowerCaseScopesSet.scopes.has(scope.toLowerCase())
1676
- : false;
1677
- }
1678
- /**
1679
- * Check if a set of scopes is present in this set of scopes.
1680
- * @param scopeSet
1681
- */
1682
- containsScopeSet(scopeSet) {
1683
- if (!scopeSet || scopeSet.scopes.size <= 0) {
1684
- return false;
1685
- }
1686
- return (this.scopes.size >= scopeSet.scopes.size &&
1687
- scopeSet.asArray().every((scope) => this.containsScope(scope)));
1688
- }
1689
- /**
1690
- * Check if set of scopes contains only the defaults
1691
- */
1692
- containsOnlyOIDCScopes() {
1693
- let defaultScopeCount = 0;
1694
- OIDC_SCOPES.forEach((defaultScope) => {
1695
- if (this.containsScope(defaultScope)) {
1696
- defaultScopeCount += 1;
1697
- }
1698
- });
1699
- return this.scopes.size === defaultScopeCount;
1700
- }
1701
- /**
1702
- * Appends single scope if passed
1703
- * @param newScope
1704
- */
1705
- appendScope(newScope) {
1706
- if (!StringUtils.isEmpty(newScope)) {
1707
- this.scopes.add(newScope.trim());
1708
- }
1709
- }
1710
- /**
1711
- * Appends multiple scopes if passed
1712
- * @param newScopes
1713
- */
1714
- appendScopes(newScopes) {
1715
- try {
1716
- newScopes.forEach((newScope) => this.appendScope(newScope));
1717
- }
1718
- catch (e) {
1719
- throw ClientAuthError.createAppendScopeSetError(e);
1720
- }
1721
- }
1722
- /**
1723
- * Removes element from set of scopes.
1724
- * @param scope
1725
- */
1726
- removeScope(scope) {
1727
- if (StringUtils.isEmpty(scope)) {
1728
- throw ClientAuthError.createRemoveEmptyScopeFromSetError(scope);
1729
- }
1730
- this.scopes.delete(scope.trim());
1731
- }
1732
- /**
1733
- * Removes default scopes from set of scopes
1734
- * Primarily used to prevent cache misses if the default scopes are not returned from the server
1735
- */
1736
- removeOIDCScopes() {
1737
- OIDC_SCOPES.forEach((defaultScope) => {
1738
- this.scopes.delete(defaultScope);
1739
- });
1740
- }
1741
- /**
1742
- * Combines an array of scopes with the current set of scopes.
1743
- * @param otherScopes
1713
+ * Combines an array of scopes with the current set of scopes.
1714
+ * @param otherScopes
1744
1715
  */
1745
1716
  unionScopeSets(otherScopes) {
1746
1717
  if (!otherScopes) {
@@ -1811,7 +1782,7 @@ class ScopeSet {
1811
1782
  * @param crypto
1812
1783
  */
1813
1784
  function buildClientInfo(rawClientInfo, crypto) {
1814
- if (StringUtils.isEmpty(rawClientInfo)) {
1785
+ if (!rawClientInfo) {
1815
1786
  throw ClientAuthError.createClientInfoEmptyError();
1816
1787
  }
1817
1788
  try {
@@ -1827,7 +1798,7 @@ function buildClientInfo(rawClientInfo, crypto) {
1827
1798
  * @param homeAccountId
1828
1799
  */
1829
1800
  function buildClientInfoFromHomeAccountId(homeAccountId) {
1830
- if (StringUtils.isEmpty(homeAccountId)) {
1801
+ if (!homeAccountId) {
1831
1802
  throw ClientAuthError.createClientInfoDecodingError("Home account ID was empty.");
1832
1803
  }
1833
1804
  const clientInfoParts = homeAccountId.split(Separators.CLIENT_INFO_SEPARATOR, 2);
@@ -2030,8 +2001,7 @@ class AccountEntity {
2030
2001
  if (serverClientInfo) {
2031
2002
  try {
2032
2003
  const clientInfo = buildClientInfo(serverClientInfo, cryptoObj);
2033
- if (!StringUtils.isEmpty(clientInfo.uid) &&
2034
- !StringUtils.isEmpty(clientInfo.utid)) {
2004
+ if (clientInfo.uid && clientInfo.utid) {
2035
2005
  return `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`;
2036
2006
  }
2037
2007
  }
@@ -2092,50 +2062,67 @@ class AccountEntity {
2092
2062
  * Licensed under the MIT License.
2093
2063
  */
2094
2064
  /**
2095
- * JWT Token representation class. Parses token string and generates claims object.
2065
+ * Extract token by decoding the rawToken
2066
+ *
2067
+ * @param encodedToken
2096
2068
  */
2097
- class AuthToken {
2098
- constructor(rawToken, crypto) {
2099
- if (StringUtils.isEmpty(rawToken)) {
2100
- throw ClientAuthError.createTokenNullOrEmptyError(rawToken);
2101
- }
2102
- this.rawToken = rawToken;
2103
- this.claims = AuthToken.extractTokenClaims(rawToken, crypto);
2069
+ function extractTokenClaims(encodedToken, base64Decode) {
2070
+ const jswPayload = getJWSPayload(encodedToken);
2071
+ // token will be decoded to get the username
2072
+ try {
2073
+ // base64Decode() should throw an error if there is an issue
2074
+ const base64Decoded = base64Decode(jswPayload);
2075
+ return JSON.parse(base64Decoded);
2104
2076
  }
2105
- /**
2106
- * Extract token by decoding the rawToken
2107
- *
2108
- * @param encodedToken
2109
- */
2110
- static extractTokenClaims(encodedToken, crypto) {
2111
- const decodedToken = StringUtils.decodeAuthToken(encodedToken);
2112
- // token will be decoded to get the username
2113
- try {
2114
- const base64TokenPayload = decodedToken.JWSPayload;
2115
- // base64Decode() should throw an error if there is an issue
2116
- const base64Decoded = crypto.base64Decode(base64TokenPayload);
2117
- return JSON.parse(base64Decoded);
2118
- }
2119
- catch (err) {
2120
- throw ClientAuthError.createTokenParsingError(err);
2121
- }
2077
+ catch (err) {
2078
+ throw ClientAuthError.createTokenParsingError(err);
2079
+ }
2080
+ }
2081
+ /**
2082
+ * decode a JWT
2083
+ *
2084
+ * @param authToken
2085
+ */
2086
+ function getJWSPayload(authToken) {
2087
+ if (!authToken) {
2088
+ throw ClientAuthError.createTokenNullOrEmptyError(authToken);
2089
+ }
2090
+ const tokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/;
2091
+ const matches = tokenPartsRegex.exec(authToken);
2092
+ if (!matches || matches.length < 4) {
2093
+ throw ClientAuthError.createTokenParsingError(`Given token is malformed: ${JSON.stringify(authToken)}`);
2122
2094
  }
2123
2095
  /**
2124
- * Determine if the token's max_age has transpired
2096
+ * const crackedToken = {
2097
+ * header: matches[1],
2098
+ * JWSPayload: matches[2],
2099
+ * JWSSig: matches[3],
2100
+ * };
2125
2101
  */
2126
- static checkMaxAge(authTime, maxAge) {
2127
- /*
2128
- * per https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
2129
- * To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access,
2130
- * provide a value of 0 for the max_age parameter and the AS will force a fresh login.
2131
- */
2132
- const fiveMinuteSkew = 300000; // five minutes in milliseconds
2133
- if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) {
2134
- throw ClientAuthError.createMaxAgeTranspiredError();
2135
- }
2102
+ return matches[2];
2103
+ }
2104
+ /**
2105
+ * Determine if the token's max_age has transpired
2106
+ */
2107
+ function checkMaxAge(authTime, maxAge) {
2108
+ /*
2109
+ * per https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
2110
+ * To force an immediate re-authentication: If an app requires that a user re-authenticate prior to access,
2111
+ * provide a value of 0 for the max_age parameter and the AS will force a fresh login.
2112
+ */
2113
+ const fiveMinuteSkew = 300000; // five minutes in milliseconds
2114
+ if (maxAge === 0 || Date.now() - fiveMinuteSkew > authTime + maxAge) {
2115
+ throw ClientAuthError.createMaxAgeTranspiredError();
2136
2116
  }
2137
2117
  }
2138
2118
 
2119
+ var AuthToken = /*#__PURE__*/Object.freeze({
2120
+ __proto__: null,
2121
+ checkMaxAge: checkMaxAge,
2122
+ extractTokenClaims: extractTokenClaims,
2123
+ getJWSPayload: getJWSPayload
2124
+ });
2125
+
2139
2126
  /*
2140
2127
  * Copyright (c) Microsoft Corporation. All rights reserved.
2141
2128
  * Licensed under the MIT License.
@@ -2193,7 +2180,7 @@ class CacheManager {
2193
2180
  const idToken = this.getIdToken(accountInfo);
2194
2181
  if (idToken) {
2195
2182
  accountInfo.idToken = idToken.secret;
2196
- accountInfo.idTokenClaims = new AuthToken(idToken.secret, this.cryptoImpl).claims;
2183
+ accountInfo.idTokenClaims = extractTokenClaims(idToken.secret, this.cryptoImpl.base64Decode);
2197
2184
  }
2198
2185
  return accountInfo;
2199
2186
  }
@@ -2589,7 +2576,7 @@ class CacheManager {
2589
2576
  const cachedRefreshToken = this.getRefreshToken(account, false, tokenKeys);
2590
2577
  const cachedAppMetadata = this.readAppMetadataFromCache(environment);
2591
2578
  if (cachedAccount && cachedIdToken) {
2592
- cachedAccount.idTokenClaims = new AuthToken(cachedIdToken.secret, this.cryptoImpl).claims;
2579
+ cachedAccount.idTokenClaims = extractTokenClaims(cachedIdToken.secret, this.cryptoImpl.base64Decode);
2593
2580
  }
2594
2581
  return {
2595
2582
  account: cachedAccount,
@@ -2745,7 +2732,7 @@ class CacheManager {
2745
2732
  else if (numAccessTokens > 1) {
2746
2733
  this.commonLogger.info("CacheManager:getAccessToken - Multiple access tokens found, clearing them");
2747
2734
  accessTokens.forEach((accessToken) => {
2748
- this.removeAccessToken(accessToken.generateCredentialKey());
2735
+ void this.removeAccessToken(accessToken.generateCredentialKey());
2749
2736
  });
2750
2737
  return null;
2751
2738
  }
@@ -3427,7 +3414,7 @@ class RequestValidator {
3427
3414
  * @param redirectUri
3428
3415
  */
3429
3416
  static validateRedirectUri(redirectUri) {
3430
- if (StringUtils.isEmpty(redirectUri)) {
3417
+ if (!redirectUri) {
3431
3418
  throw ClientConfigurationError.createRedirectUriEmptyError();
3432
3419
  }
3433
3420
  }
@@ -3458,8 +3445,7 @@ class RequestValidator {
3458
3445
  * @param codeChallengeMethod
3459
3446
  */
3460
3447
  static validateCodeChallengeParams(codeChallenge, codeChallengeMethod) {
3461
- if (StringUtils.isEmpty(codeChallenge) ||
3462
- StringUtils.isEmpty(codeChallengeMethod)) {
3448
+ if (!codeChallenge || !codeChallengeMethod) {
3463
3449
  throw ClientConfigurationError.createInvalidCodeChallengeParamsError();
3464
3450
  }
3465
3451
  else {
@@ -3487,7 +3473,7 @@ class RequestValidator {
3487
3473
  return {};
3488
3474
  }
3489
3475
  // Remove any query parameters already included in SSO params
3490
- queryParams.forEach((value, key) => {
3476
+ queryParams.forEach((_value, key) => {
3491
3477
  if (eQParams[key]) {
3492
3478
  delete eQParams[key];
3493
3479
  }
@@ -3670,7 +3656,7 @@ class RequestParameterBuilder {
3670
3656
  * @param state
3671
3657
  */
3672
3658
  addState(state) {
3673
- if (!StringUtils.isEmpty(state)) {
3659
+ if (state) {
3674
3660
  this.parameters.set(AADServerParamKeys.STATE, encodeURIComponent(state));
3675
3661
  }
3676
3662
  }
@@ -3737,7 +3723,7 @@ class RequestParameterBuilder {
3737
3723
  * @param clientAssertion
3738
3724
  */
3739
3725
  addClientAssertion(clientAssertion) {
3740
- if (!StringUtils.isEmpty(clientAssertion)) {
3726
+ if (clientAssertion) {
3741
3727
  this.parameters.set(AADServerParamKeys.CLIENT_ASSERTION, encodeURIComponent(clientAssertion));
3742
3728
  }
3743
3729
  }
@@ -3746,7 +3732,7 @@ class RequestParameterBuilder {
3746
3732
  * @param clientAssertionType
3747
3733
  */
3748
3734
  addClientAssertionType(clientAssertionType) {
3749
- if (!StringUtils.isEmpty(clientAssertionType)) {
3735
+ if (clientAssertionType) {
3750
3736
  this.parameters.set(AADServerParamKeys.CLIENT_ASSERTION_TYPE, encodeURIComponent(clientAssertionType));
3751
3737
  }
3752
3738
  }
@@ -3833,7 +3819,7 @@ class RequestParameterBuilder {
3833
3819
  * @param cnfString
3834
3820
  */
3835
3821
  addPopToken(cnfString) {
3836
- if (!StringUtils.isEmpty(cnfString)) {
3822
+ if (cnfString) {
3837
3823
  this.parameters.set(AADServerParamKeys.TOKEN_TYPE, AuthenticationScheme.POP);
3838
3824
  this.parameters.set(AADServerParamKeys.REQ_CNF, encodeURIComponent(cnfString));
3839
3825
  }
@@ -3842,7 +3828,7 @@ class RequestParameterBuilder {
3842
3828
  * add SSH JWK and key ID to query params
3843
3829
  */
3844
3830
  addSshJwk(sshJwkString) {
3845
- if (!StringUtils.isEmpty(sshJwkString)) {
3831
+ if (sshJwkString) {
3846
3832
  this.parameters.set(AADServerParamKeys.TOKEN_TYPE, AuthenticationScheme.SSH);
3847
3833
  this.parameters.set(AADServerParamKeys.REQ_CNF, encodeURIComponent(sshJwkString));
3848
3834
  }
@@ -3884,18 +3870,253 @@ class RequestParameterBuilder {
3884
3870
  * Licensed under the MIT License.
3885
3871
  */
3886
3872
  /**
3887
- * Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
3888
- * @internal
3873
+ * Enumeration of operations that are instrumented by have their performance measured by the PerformanceClient.
3874
+ *
3875
+ * @export
3876
+ * @enum {number}
3889
3877
  */
3890
- class BaseClient {
3891
- constructor(configuration, performanceClient) {
3892
- // Set the configuration
3893
- this.config = buildClientConfiguration(configuration);
3894
- // Initialize the logger
3895
- this.logger = new Logger(this.config.loggerOptions, name, version);
3896
- // Initialize crypto
3897
- this.cryptoUtils = this.config.cryptoInterface;
3898
- // Initialize storage interface
3878
+ const PerformanceEvents = {
3879
+ /**
3880
+ * acquireTokenByCode API (msal-browser and msal-node).
3881
+ * Used to acquire tokens by trading an authorization code against the token endpoint.
3882
+ */
3883
+ AcquireTokenByCode: "acquireTokenByCode",
3884
+ /**
3885
+ * acquireTokenByRefreshToken API (msal-browser and msal-node).
3886
+ * Used to renew an access token using a refresh token against the token endpoint.
3887
+ */
3888
+ AcquireTokenByRefreshToken: "acquireTokenByRefreshToken",
3889
+ /**
3890
+ * acquireTokenSilent API (msal-browser and msal-node).
3891
+ * Used to silently acquire a new access token (from the cache or the network).
3892
+ */
3893
+ AcquireTokenSilent: "acquireTokenSilent",
3894
+ /**
3895
+ * acquireTokenSilentAsync (msal-browser).
3896
+ * Internal API for acquireTokenSilent.
3897
+ */
3898
+ AcquireTokenSilentAsync: "acquireTokenSilentAsync",
3899
+ /**
3900
+ * acquireTokenPopup (msal-browser).
3901
+ * Used to acquire a new access token interactively through pop ups
3902
+ */
3903
+ AcquireTokenPopup: "acquireTokenPopup",
3904
+ /**
3905
+ * getPublicKeyThumbprint API in CryptoOpts class (msal-browser).
3906
+ * Used to generate a public/private keypair and generate a public key thumbprint for pop requests.
3907
+ */
3908
+ CryptoOptsGetPublicKeyThumbprint: "cryptoOptsGetPublicKeyThumbprint",
3909
+ /**
3910
+ * signJwt API in CryptoOpts class (msal-browser).
3911
+ * Used to signed a pop token.
3912
+ */
3913
+ CryptoOptsSignJwt: "cryptoOptsSignJwt",
3914
+ /**
3915
+ * acquireToken API in the SilentCacheClient class (msal-browser).
3916
+ * Used to read access tokens from the cache.
3917
+ */
3918
+ SilentCacheClientAcquireToken: "silentCacheClientAcquireToken",
3919
+ /**
3920
+ * acquireToken API in the SilentIframeClient class (msal-browser).
3921
+ * Used to acquire a new set of tokens from the authorize endpoint in a hidden iframe.
3922
+ */
3923
+ SilentIframeClientAcquireToken: "silentIframeClientAcquireToken",
3924
+ /**
3925
+ * acquireToken API in SilentRereshClient (msal-browser).
3926
+ * Used to acquire a new set of tokens from the token endpoint using a refresh token.
3927
+ */
3928
+ SilentRefreshClientAcquireToken: "silentRefreshClientAcquireToken",
3929
+ /**
3930
+ * ssoSilent API (msal-browser).
3931
+ * Used to silently acquire an authorization code and set of tokens using a hidden iframe.
3932
+ */
3933
+ SsoSilent: "ssoSilent",
3934
+ /**
3935
+ * getDiscoveredAuthority API in StandardInteractionClient class (msal-browser).
3936
+ * Used to load authority metadata for a request.
3937
+ */
3938
+ StandardInteractionClientGetDiscoveredAuthority: "standardInteractionClientGetDiscoveredAuthority",
3939
+ /**
3940
+ * acquireToken APIs in msal-browser.
3941
+ * Used to make an /authorize endpoint call with native brokering enabled.
3942
+ */
3943
+ FetchAccountIdWithNativeBroker: "fetchAccountIdWithNativeBroker",
3944
+ /**
3945
+ * acquireToken API in NativeInteractionClient class (msal-browser).
3946
+ * Used to acquire a token from Native component when native brokering is enabled.
3947
+ */
3948
+ NativeInteractionClientAcquireToken: "nativeInteractionClientAcquireToken",
3949
+ /**
3950
+ * Time spent creating default headers for requests to token endpoint
3951
+ */
3952
+ BaseClientCreateTokenRequestHeaders: "baseClientCreateTokenRequestHeaders",
3953
+ /**
3954
+ * Time spent sending/waiting for the response of a request to the token endpoint
3955
+ */
3956
+ BaseClientExecutePostToTokenEndpoint: "baseClientExecutePostToTokenEndpoint",
3957
+ /**
3958
+ * Used to measure the time taken for completing embedded-broker handshake (PW-Broker).
3959
+ */
3960
+ BrokerHandhshake: "brokerHandshake",
3961
+ /**
3962
+ * acquireTokenByRefreshToken API in BrokerClientApplication (PW-Broker) .
3963
+ */
3964
+ AcquireTokenByRefreshTokenInBroker: "acquireTokenByRefreshTokenInBroker",
3965
+ /**
3966
+ * Time taken for token acquisition by broker
3967
+ */
3968
+ AcquireTokenByBroker: "acquireTokenByBroker",
3969
+ /**
3970
+ * Time spent on the network for refresh token acquisition
3971
+ */
3972
+ RefreshTokenClientExecuteTokenRequest: "refreshTokenClientExecuteTokenRequest",
3973
+ /**
3974
+ * Time taken for acquiring refresh token , records RT size
3975
+ */
3976
+ RefreshTokenClientAcquireToken: "refreshTokenClientAcquireToken",
3977
+ /**
3978
+ * Time taken for acquiring cached refresh token
3979
+ */
3980
+ RefreshTokenClientAcquireTokenWithCachedRefreshToken: "refreshTokenClientAcquireTokenWithCachedRefreshToken",
3981
+ /**
3982
+ * acquireTokenByRefreshToken API in RefreshTokenClient (msal-common).
3983
+ */
3984
+ RefreshTokenClientAcquireTokenByRefreshToken: "refreshTokenClientAcquireTokenByRefreshToken",
3985
+ /**
3986
+ * Helper function to create token request body in RefreshTokenClient (msal-common).
3987
+ */
3988
+ RefreshTokenClientCreateTokenRequestBody: "refreshTokenClientCreateTokenRequestBody",
3989
+ /**
3990
+ * acquireTokenFromCache (msal-browser).
3991
+ * Internal API for acquiring token from cache
3992
+ */
3993
+ AcquireTokenFromCache: "acquireTokenFromCache",
3994
+ /**
3995
+ * acquireTokenBySilentIframe (msal-browser).
3996
+ * Internal API for acquiring token by silent Iframe
3997
+ */
3998
+ AcquireTokenBySilentIframe: "acquireTokenBySilentIframe",
3999
+ /**
4000
+ * Internal API for initializing base request in BaseInteractionClient (msal-browser)
4001
+ */
4002
+ InitializeBaseRequest: "initializeBaseRequest",
4003
+ /**
4004
+ * Internal API for initializing silent request in SilentCacheClient (msal-browser)
4005
+ */
4006
+ InitializeSilentRequest: "initializeSilentRequest",
4007
+ InitializeClientApplication: "initializeClientApplication",
4008
+ /**
4009
+ * Helper function in SilentIframeClient class (msal-browser).
4010
+ */
4011
+ SilentIframeClientTokenHelper: "silentIframeClientTokenHelper",
4012
+ /**
4013
+ * SilentHandler
4014
+ */
4015
+ SilentHandlerInitiateAuthRequest: "silentHandlerInitiateAuthRequest",
4016
+ SilentHandlerMonitorIframeForHash: "silentHandlerMonitorIframeForHash",
4017
+ SilentHandlerLoadFrame: "silentHandlerLoadFrame",
4018
+ /**
4019
+ * Helper functions in StandardInteractionClient class (msal-browser)
4020
+ */
4021
+ StandardInteractionClientCreateAuthCodeClient: "standardInteractionClientCreateAuthCodeClient",
4022
+ StandardInteractionClientGetClientConfiguration: "standardInteractionClientGetClientConfiguration",
4023
+ StandardInteractionClientInitializeAuthorizationRequest: "standardInteractionClientInitializeAuthorizationRequest",
4024
+ StandardInteractionClientInitializeAuthorizationCodeRequest: "standardInteractionClientInitializeAuthorizationCodeRequest",
4025
+ /**
4026
+ * getAuthCodeUrl API (msal-browser and msal-node).
4027
+ */
4028
+ GetAuthCodeUrl: "getAuthCodeUrl",
4029
+ /**
4030
+ * Functions from InteractionHandler (msal-browser)
4031
+ */
4032
+ HandleCodeResponseFromServer: "handleCodeResponseFromServer",
4033
+ HandleCodeResponseFromHash: "handleCodeResponseFromHash",
4034
+ UpdateTokenEndpointAuthority: "updateTokenEndpointAuthority",
4035
+ /**
4036
+ * APIs in Authorization Code Client (msal-common)
4037
+ */
4038
+ AuthClientAcquireToken: "authClientAcquireToken",
4039
+ AuthClientExecuteTokenRequest: "authClientExecuteTokenRequest",
4040
+ AuthClientCreateTokenRequestBody: "authClientCreateTokenRequestBody",
4041
+ AuthClientCreateQueryString: "authClientCreateQueryString",
4042
+ /**
4043
+ * Generate functions in PopTokenGenerator (msal-common)
4044
+ */
4045
+ PopTokenGenerateCnf: "popTokenGenerateCnf",
4046
+ PopTokenGenerateKid: "popTokenGenerateKid",
4047
+ /**
4048
+ * handleServerTokenResponse API in ResponseHandler (msal-common)
4049
+ */
4050
+ HandleServerTokenResponse: "handleServerTokenResponse",
4051
+ /**
4052
+ * Authority functions
4053
+ */
4054
+ AuthorityFactoryCreateDiscoveredInstance: "authorityFactoryCreateDiscoveredInstance",
4055
+ AuthorityResolveEndpointsAsync: "authorityResolveEndpointsAsync",
4056
+ AuthorityGetCloudDiscoveryMetadataFromNetwork: "authorityGetCloudDiscoveryMetadataFromNetwork",
4057
+ AuthorityUpdateCloudDiscoveryMetadata: "authorityUpdateCloudDiscoveryMetadata",
4058
+ AuthorityGetEndpointMetadataFromNetwork: "authorityGetEndpointMetadataFromNetwork",
4059
+ AuthorityUpdateEndpointMetadata: "authorityUpdateEndpointMetadata",
4060
+ AuthorityUpdateMetadataWithRegionalInformation: "authorityUpdateMetadataWithRegionalInformation",
4061
+ /**
4062
+ * Region Discovery functions
4063
+ */
4064
+ RegionDiscoveryDetectRegion: "regionDiscoveryDetectRegion",
4065
+ RegionDiscoveryGetRegionFromIMDS: "regionDiscoveryGetRegionFromIMDS",
4066
+ RegionDiscoveryGetCurrentVersion: "regionDiscoveryGetCurrentVersion",
4067
+ AcquireTokenByCodeAsync: "acquireTokenByCodeAsync",
4068
+ GetEndpointMetadataFromNetwork: "getEndpointMetadataFromNetwork",
4069
+ GetCloudDiscoveryMetadataFromNetworkMeasurement: "getCloudDiscoveryMetadataFromNetworkMeasurement",
4070
+ HandleRedirectPromiseMeasurement: "handleRedirectPromiseMeasurement",
4071
+ UpdateCloudDiscoveryMetadataMeasurement: "updateCloudDiscoveryMetadataMeasurement",
4072
+ UsernamePasswordClientAcquireToken: "usernamePasswordClientAcquireToken",
4073
+ NativeMessageHandlerHandshake: "nativeMessageHandlerHandshake",
4074
+ NativeGenerateAuthResult: "nativeGenerateAuthResult",
4075
+ /**
4076
+ * Cache operations
4077
+ */
4078
+ ClearTokensAndKeysWithClaims: "clearTokensAndKeysWithClaims",
4079
+ };
4080
+ /**
4081
+ * State of the performance event.
4082
+ *
4083
+ * @export
4084
+ * @enum {number}
4085
+ */
4086
+ const PerformanceEventStatus = {
4087
+ NotStarted: 0,
4088
+ InProgress: 1,
4089
+ Completed: 2,
4090
+ };
4091
+ const IntFields = new Set([
4092
+ "accessTokenSize",
4093
+ "durationMs",
4094
+ "idTokenSize",
4095
+ "matsSilentStatus",
4096
+ "matsHttpStatus",
4097
+ "refreshTokenSize",
4098
+ "queuedTimeMs",
4099
+ "startTimeMs",
4100
+ "status",
4101
+ ]);
4102
+
4103
+ /*
4104
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4105
+ * Licensed under the MIT License.
4106
+ */
4107
+ /**
4108
+ * Base application class which will construct requests to send to and handle responses from the Microsoft STS using the authorization code flow.
4109
+ * @internal
4110
+ */
4111
+ class BaseClient {
4112
+ constructor(configuration, performanceClient) {
4113
+ // Set the configuration
4114
+ this.config = buildClientConfiguration(configuration);
4115
+ // Initialize the logger
4116
+ this.logger = new Logger(this.config.loggerOptions, name, version);
4117
+ // Initialize crypto
4118
+ this.cryptoUtils = this.config.cryptoInterface;
4119
+ // Initialize storage interface
3899
4120
  this.cacheManager = this.config.storageInterface;
3900
4121
  // Set the network interface
3901
4122
  this.networkClient = this.config.networkInterface;
@@ -3940,8 +4161,13 @@ class BaseClient {
3940
4161
  * @param headers
3941
4162
  * @param thumbprint
3942
4163
  */
3943
- async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint) {
4164
+ async executePostToTokenEndpoint(tokenEndpoint, queryString, headers, thumbprint, correlationId) {
4165
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.BaseClientCreateTokenRequestHeaders, correlationId);
3944
4166
  const response = await this.networkManager.sendPostRequest(thumbprint, tokenEndpoint, { body: queryString, headers: headers });
4167
+ this.performanceClient?.addFields({
4168
+ refreshTokenSize: response.body.refresh_token?.length || 0,
4169
+ httpVerToken: response.headers?.[HeaderNames.X_MS_HTTP_VERSION] || "",
4170
+ }, correlationId);
3945
4171
  if (this.config.serverTelemetryManager &&
3946
4172
  response.status < 500 &&
3947
4173
  response.status !== 429) {
@@ -4253,583 +4479,73 @@ class AccessTokenEntity extends CredentialEntity {
4253
4479
  * @param expiresOn
4254
4480
  * @param extExpiresOn
4255
4481
  */
4256
- static createAccessTokenEntity(homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, cryptoUtils, refreshOn, tokenType, userAssertionHash, keyId, requestedClaims, requestedClaimsHash) {
4257
- const atEntity = new AccessTokenEntity();
4258
- atEntity.homeAccountId = homeAccountId;
4259
- atEntity.credentialType = CredentialType.ACCESS_TOKEN;
4260
- atEntity.secret = accessToken;
4261
- const currentTime = TimeUtils.nowSeconds();
4262
- atEntity.cachedAt = currentTime.toString();
4263
- /*
4264
- * Token expiry time.
4265
- * This value should be  calculated based on the current UTC time measured locally and the value  expires_in Represented as a string in JSON.
4266
- */
4267
- atEntity.expiresOn = expiresOn.toString();
4268
- atEntity.extendedExpiresOn = extExpiresOn.toString();
4269
- if (refreshOn) {
4270
- atEntity.refreshOn = refreshOn.toString();
4271
- }
4272
- atEntity.environment = environment;
4273
- atEntity.clientId = clientId;
4274
- atEntity.realm = tenantId;
4275
- atEntity.target = scopes;
4276
- atEntity.userAssertionHash = userAssertionHash;
4277
- atEntity.tokenType = StringUtils.isEmpty(tokenType)
4278
- ? AuthenticationScheme.BEARER
4279
- : tokenType;
4280
- if (requestedClaims) {
4281
- atEntity.requestedClaims = requestedClaims;
4282
- atEntity.requestedClaimsHash = requestedClaimsHash;
4283
- }
4284
- /*
4285
- * Create Access Token With Auth Scheme instead of regular access token
4286
- * Cast to lower to handle "bearer" from ADFS
4287
- */
4288
- if (atEntity.tokenType?.toLowerCase() !==
4289
- AuthenticationScheme.BEARER.toLowerCase()) {
4290
- atEntity.credentialType =
4291
- CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
4292
- switch (atEntity.tokenType) {
4293
- case AuthenticationScheme.POP:
4294
- // Make sure keyId is present and add it to credential
4295
- const tokenClaims = AuthToken.extractTokenClaims(accessToken, cryptoUtils);
4296
- if (!tokenClaims?.cnf?.kid) {
4297
- throw ClientAuthError.createTokenClaimsRequiredError();
4298
- }
4299
- atEntity.keyId = tokenClaims.cnf.kid;
4300
- break;
4301
- case AuthenticationScheme.SSH:
4302
- atEntity.keyId = keyId;
4303
- }
4304
- }
4305
- return atEntity;
4306
- }
4307
- /**
4308
- * Validates an entity: checks for all expected params
4309
- * @param entity
4310
- */
4311
- static isAccessTokenEntity(entity) {
4312
- if (!entity) {
4313
- return false;
4314
- }
4315
- return (entity.hasOwnProperty("homeAccountId") &&
4316
- entity.hasOwnProperty("environment") &&
4317
- entity.hasOwnProperty("credentialType") &&
4318
- entity.hasOwnProperty("realm") &&
4319
- entity.hasOwnProperty("clientId") &&
4320
- entity.hasOwnProperty("secret") &&
4321
- entity.hasOwnProperty("target") &&
4322
- (entity["credentialType"] === CredentialType.ACCESS_TOKEN ||
4323
- entity["credentialType"] ===
4324
- CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME));
4325
- }
4326
- }
4327
-
4328
- /*
4329
- * Copyright (c) Microsoft Corporation. All rights reserved.
4330
- * Licensed under the MIT License.
4331
- */
4332
- /**
4333
- * REFRESH_TOKEN Cache
4334
- *
4335
- * Key:Value Schema:
4336
- *
4337
- * Key Example: uid.utid-login.microsoftonline.com-refreshtoken-clientId--
4338
- *
4339
- * Value:
4340
- * {
4341
- * homeAccountId: home account identifier for the auth scheme,
4342
- * environment: entity that issued the token, represented as a full host
4343
- * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
4344
- * clientId: client ID of the application
4345
- * secret: Actual credential as a string
4346
- * familyId: Family ID identifier, '1' represents Microsoft Family
4347
- * realm: Full tenant or organizational identifier that the account belongs to
4348
- * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
4349
- * }
4350
- */
4351
- class RefreshTokenEntity extends CredentialEntity {
4352
- /**
4353
- * Create RefreshTokenEntity
4354
- * @param homeAccountId
4355
- * @param authenticationResult
4356
- * @param clientId
4357
- * @param authority
4358
- */
4359
- static createRefreshTokenEntity(homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash) {
4360
- const rtEntity = new RefreshTokenEntity();
4361
- rtEntity.clientId = clientId;
4362
- rtEntity.credentialType = CredentialType.REFRESH_TOKEN;
4363
- rtEntity.environment = environment;
4364
- rtEntity.homeAccountId = homeAccountId;
4365
- rtEntity.secret = refreshToken;
4366
- rtEntity.userAssertionHash = userAssertionHash;
4367
- if (familyId)
4368
- rtEntity.familyId = familyId;
4369
- return rtEntity;
4370
- }
4371
- /**
4372
- * Validates an entity: checks for all expected params
4373
- * @param entity
4374
- */
4375
- static isRefreshTokenEntity(entity) {
4376
- if (!entity) {
4377
- return false;
4378
- }
4379
- return (entity.hasOwnProperty("homeAccountId") &&
4380
- entity.hasOwnProperty("environment") &&
4381
- entity.hasOwnProperty("credentialType") &&
4382
- entity.hasOwnProperty("clientId") &&
4383
- entity.hasOwnProperty("secret") &&
4384
- entity["credentialType"] === CredentialType.REFRESH_TOKEN);
4385
- }
4386
- }
4387
-
4388
- /*
4389
- * Copyright (c) Microsoft Corporation. All rights reserved.
4390
- * Licensed under the MIT License.
4391
- */
4392
- /**
4393
- * InteractionRequiredServerErrorMessage contains string constants used by error codes and messages returned by the server indicating interaction is required
4394
- */
4395
- const InteractionRequiredServerErrorMessage = [
4396
- "interaction_required",
4397
- "consent_required",
4398
- "login_required",
4399
- ];
4400
- const InteractionRequiredAuthSubErrorMessage = [
4401
- "message_only",
4402
- "additional_action",
4403
- "basic_action",
4404
- "user_password_expired",
4405
- "consent_required",
4406
- ];
4407
- /**
4408
- * Interaction required errors defined by the SDK
4409
- */
4410
- const InteractionRequiredAuthErrorMessage = {
4411
- noTokensFoundError: {
4412
- code: "no_tokens_found",
4413
- desc: "No refresh token found in the cache. Please sign-in.",
4414
- },
4415
- native_account_unavailable: {
4416
- code: "native_account_unavailable",
4417
- desc: "The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API.",
4418
- },
4419
- };
4420
- /**
4421
- * Error thrown when user interaction is required.
4422
- */
4423
- class InteractionRequiredAuthError extends AuthError {
4424
- constructor(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims) {
4425
- super(errorCode, errorMessage, subError);
4426
- Object.setPrototypeOf(this, InteractionRequiredAuthError.prototype);
4427
- this.timestamp = timestamp || Constants.EMPTY_STRING;
4428
- this.traceId = traceId || Constants.EMPTY_STRING;
4429
- this.correlationId = correlationId || Constants.EMPTY_STRING;
4430
- this.claims = claims || Constants.EMPTY_STRING;
4431
- this.name = "InteractionRequiredAuthError";
4432
- }
4433
- /**
4434
- * Helper function used to determine if an error thrown by the server requires interaction to resolve
4435
- * @param errorCode
4436
- * @param errorString
4437
- * @param subError
4438
- */
4439
- static isInteractionRequiredError(errorCode, errorString, subError) {
4440
- const isInteractionRequiredErrorCode = !!errorCode &&
4441
- InteractionRequiredServerErrorMessage.indexOf(errorCode) > -1;
4442
- const isInteractionRequiredSubError = !!subError &&
4443
- InteractionRequiredAuthSubErrorMessage.indexOf(subError) > -1;
4444
- const isInteractionRequiredErrorDesc = !!errorString &&
4445
- InteractionRequiredServerErrorMessage.some((irErrorCode) => {
4446
- return errorString.indexOf(irErrorCode) > -1;
4447
- });
4448
- return (isInteractionRequiredErrorCode ||
4449
- isInteractionRequiredErrorDesc ||
4450
- isInteractionRequiredSubError);
4451
- }
4452
- /**
4453
- * Creates an error thrown when the authorization code required for a token request is null or empty.
4454
- */
4455
- static createNoTokensFoundError() {
4456
- return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.noTokensFoundError.code, InteractionRequiredAuthErrorMessage.noTokensFoundError.desc);
4457
- }
4458
- /**
4459
- * Creates an error thrown when the native broker returns ACCOUNT_UNAVAILABLE status, indicating that the account was removed and interactive sign-in is required
4460
- * @returns
4461
- */
4462
- static createNativeAccountUnavailableError() {
4463
- return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.native_account_unavailable.code, InteractionRequiredAuthErrorMessage.native_account_unavailable.desc);
4464
- }
4465
- }
4466
-
4467
- /*
4468
- * Copyright (c) Microsoft Corporation. All rights reserved.
4469
- * Licensed under the MIT License.
4470
- */
4471
- /** @internal */
4472
- class CacheRecord {
4473
- constructor(accountEntity, idTokenEntity, accessTokenEntity, refreshTokenEntity, appMetadataEntity) {
4474
- this.account = accountEntity || null;
4475
- this.idToken = idTokenEntity || null;
4476
- this.accessToken = accessTokenEntity || null;
4477
- this.refreshToken = refreshTokenEntity || null;
4478
- this.appMetadata = appMetadataEntity || null;
4479
- }
4480
- }
4481
-
4482
- /*
4483
- * Copyright (c) Microsoft Corporation. All rights reserved.
4484
- * Licensed under the MIT License.
4485
- */
4486
- /**
4487
- * Class which provides helpers for OAuth 2.0 protocol specific values
4488
- */
4489
- class ProtocolUtils {
4490
- /**
4491
- * Appends user state with random guid, or returns random guid.
4492
- * @param userState
4493
- * @param randomGuid
4494
- */
4495
- static setRequestState(cryptoObj, userState, meta) {
4496
- const libraryState = ProtocolUtils.generateLibraryState(cryptoObj, meta);
4497
- return !StringUtils.isEmpty(userState)
4498
- ? `${libraryState}${Constants.RESOURCE_DELIM}${userState}`
4499
- : libraryState;
4500
- }
4501
- /**
4502
- * Generates the state value used by the common library.
4503
- * @param randomGuid
4504
- * @param cryptoObj
4505
- */
4506
- static generateLibraryState(cryptoObj, meta) {
4507
- if (!cryptoObj) {
4508
- throw ClientAuthError.createNoCryptoObjectError("generateLibraryState");
4509
- }
4510
- // Create a state object containing a unique id and the timestamp of the request creation
4511
- const stateObj = {
4512
- id: cryptoObj.createNewGuid(),
4513
- };
4514
- if (meta) {
4515
- stateObj.meta = meta;
4516
- }
4517
- const stateString = JSON.stringify(stateObj);
4518
- return cryptoObj.base64Encode(stateString);
4519
- }
4520
- /**
4521
- * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
4522
- * @param state
4523
- * @param cryptoObj
4524
- */
4525
- static parseRequestState(cryptoObj, state) {
4526
- if (!cryptoObj) {
4527
- throw ClientAuthError.createNoCryptoObjectError("parseRequestState");
4528
- }
4529
- if (StringUtils.isEmpty(state)) {
4530
- throw ClientAuthError.createInvalidStateError(state, "Null, undefined or empty state");
4531
- }
4532
- try {
4533
- // Split the state between library state and user passed state and decode them separately
4534
- const splitState = state.split(Constants.RESOURCE_DELIM);
4535
- const libraryState = splitState[0];
4536
- const userState = splitState.length > 1
4537
- ? splitState.slice(1).join(Constants.RESOURCE_DELIM)
4538
- : Constants.EMPTY_STRING;
4539
- const libraryStateString = cryptoObj.base64Decode(libraryState);
4540
- const libraryStateObj = JSON.parse(libraryStateString);
4541
- return {
4542
- userRequestState: !StringUtils.isEmpty(userState)
4543
- ? userState
4544
- : Constants.EMPTY_STRING,
4545
- libraryState: libraryStateObj,
4546
- };
4547
- }
4548
- catch (e) {
4549
- throw ClientAuthError.createInvalidStateError(state, e);
4550
- }
4551
- }
4552
- }
4553
-
4554
- /*
4555
- * Copyright (c) Microsoft Corporation. All rights reserved.
4556
- * Licensed under the MIT License.
4557
- */
4558
- /**
4559
- * Url object class which can perform various transformations on url strings.
4560
- */
4561
- class UrlString {
4562
- get urlString() {
4563
- return this._urlString;
4564
- }
4565
- constructor(url) {
4566
- this._urlString = url;
4567
- if (StringUtils.isEmpty(this._urlString)) {
4568
- // Throws error if url is empty
4569
- throw ClientConfigurationError.createUrlEmptyError();
4570
- }
4571
- if (StringUtils.isEmpty(this.getHash())) {
4572
- this._urlString = UrlString.canonicalizeUri(url);
4573
- }
4574
- }
4575
- /**
4576
- * Ensure urls are lower case and end with a / character.
4577
- * @param url
4578
- */
4579
- static canonicalizeUri(url) {
4580
- if (url) {
4581
- let lowerCaseUrl = url.toLowerCase();
4582
- if (StringUtils.endsWith(lowerCaseUrl, "?")) {
4583
- lowerCaseUrl = lowerCaseUrl.slice(0, -1);
4584
- }
4585
- else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
4586
- lowerCaseUrl = lowerCaseUrl.slice(0, -2);
4587
- }
4588
- if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
4589
- lowerCaseUrl += "/";
4590
- }
4591
- return lowerCaseUrl;
4592
- }
4593
- return url;
4594
- }
4595
- /**
4596
- * Throws if urlString passed is not a valid authority URI string.
4597
- */
4598
- validateAsUri() {
4599
- // Attempts to parse url for uri components
4600
- let components;
4601
- try {
4602
- components = this.getUrlComponents();
4603
- }
4604
- catch (e) {
4605
- throw ClientConfigurationError.createUrlParseError(e);
4606
- }
4607
- // Throw error if URI or path segments are not parseable.
4608
- if (!components.HostNameAndPort || !components.PathSegments) {
4609
- throw ClientConfigurationError.createUrlParseError(`Given url string: ${this.urlString}`);
4610
- }
4611
- // Throw error if uri is insecure.
4612
- if (!components.Protocol ||
4613
- components.Protocol.toLowerCase() !== "https:") {
4614
- throw ClientConfigurationError.createInsecureAuthorityUriError(this.urlString);
4615
- }
4616
- }
4617
- /**
4618
- * Given a url and a query string return the url with provided query string appended
4619
- * @param url
4620
- * @param queryString
4621
- */
4622
- static appendQueryString(url, queryString) {
4623
- if (StringUtils.isEmpty(queryString)) {
4624
- return url;
4625
- }
4626
- return url.indexOf("?") < 0
4627
- ? `${url}?${queryString}`
4628
- : `${url}&${queryString}`;
4629
- }
4630
- /**
4631
- * Returns a url with the hash removed
4632
- * @param url
4633
- */
4634
- static removeHashFromUrl(url) {
4635
- return UrlString.canonicalizeUri(url.split("#")[0]);
4636
- }
4637
- /**
4638
- * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
4639
- * @param href The url
4640
- * @param tenantId The tenant id to replace
4641
- */
4642
- replaceTenantPath(tenantId) {
4643
- const urlObject = this.getUrlComponents();
4644
- const pathArray = urlObject.PathSegments;
4645
- if (tenantId &&
4646
- pathArray.length !== 0 &&
4647
- (pathArray[0] === AADAuthorityConstants.COMMON ||
4648
- pathArray[0] === AADAuthorityConstants.ORGANIZATIONS)) {
4649
- pathArray[0] = tenantId;
4650
- }
4651
- return UrlString.constructAuthorityUriFromObject(urlObject);
4652
- }
4653
- /**
4654
- * Returns the anchor part(#) of the URL
4655
- */
4656
- getHash() {
4657
- return UrlString.parseHash(this.urlString);
4658
- }
4659
- /**
4660
- * Parses out the components from a url string.
4661
- * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
4662
- */
4663
- getUrlComponents() {
4664
- // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
4665
- const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
4666
- // If url string does not match regEx, we throw an error
4667
- const match = this.urlString.match(regEx);
4668
- if (!match) {
4669
- throw ClientConfigurationError.createUrlParseError(`Given url string: ${this.urlString}`);
4670
- }
4671
- // Url component object
4672
- const urlComponents = {
4673
- Protocol: match[1],
4674
- HostNameAndPort: match[4],
4675
- AbsolutePath: match[5],
4676
- QueryString: match[7],
4677
- };
4678
- let pathSegments = urlComponents.AbsolutePath.split("/");
4679
- pathSegments = pathSegments.filter((val) => val && val.length > 0); // remove empty elements
4680
- urlComponents.PathSegments = pathSegments;
4681
- if (!StringUtils.isEmpty(urlComponents.QueryString) &&
4682
- urlComponents.QueryString.endsWith("/")) {
4683
- urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1);
4684
- }
4685
- return urlComponents;
4686
- }
4687
- static getDomainFromUrl(url) {
4688
- const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
4689
- const match = url.match(regEx);
4690
- if (!match) {
4691
- throw ClientConfigurationError.createUrlParseError(`Given url string: ${url}`);
4692
- }
4693
- return match[2];
4694
- }
4695
- static getAbsoluteUrl(relativeUrl, baseUrl) {
4696
- if (relativeUrl[0] === Constants.FORWARD_SLASH) {
4697
- const url = new UrlString(baseUrl);
4698
- const baseComponents = url.getUrlComponents();
4699
- return (baseComponents.Protocol +
4700
- "//" +
4701
- baseComponents.HostNameAndPort +
4702
- relativeUrl);
4703
- }
4704
- return relativeUrl;
4705
- }
4706
- /**
4707
- * Parses hash string from given string. Returns empty string if no hash symbol is found.
4708
- * @param hashString
4709
- */
4710
- static parseHash(hashString) {
4711
- const hashIndex1 = hashString.indexOf("#");
4712
- const hashIndex2 = hashString.indexOf("#/");
4713
- if (hashIndex2 > -1) {
4714
- return hashString.substring(hashIndex2 + 2);
4715
- }
4716
- else if (hashIndex1 > -1) {
4717
- return hashString.substring(hashIndex1 + 1);
4718
- }
4719
- return Constants.EMPTY_STRING;
4720
- }
4721
- /**
4722
- * Parses query string from given string. Returns empty string if no query symbol is found.
4723
- * @param queryString
4724
- */
4725
- static parseQueryString(queryString) {
4726
- const queryIndex1 = queryString.indexOf("?");
4727
- const queryIndex2 = queryString.indexOf("/?");
4728
- if (queryIndex2 > -1) {
4729
- return queryString.substring(queryIndex2 + 2);
4730
- }
4731
- else if (queryIndex1 > -1) {
4732
- return queryString.substring(queryIndex1 + 1);
4733
- }
4734
- return Constants.EMPTY_STRING;
4735
- }
4736
- /**
4737
- * Parses query server response string from given string.
4738
- * Extract hash between '?code=' and '#' if trailing '# is present.
4739
- * Returns empty string if no query symbol is found.
4740
- * @param queryString
4741
- */
4742
- static parseQueryServerResponse(queryString) {
4743
- const queryIndex1 = queryString.indexOf("?code");
4744
- const queryIndex2 = queryString.indexOf("/?code");
4745
- const hashIndex = queryString.indexOf("#");
4746
- if (queryIndex2 > -1 && hashIndex > -1) {
4747
- return queryString.substring(queryIndex2 + 2, hashIndex);
4748
- }
4749
- else if (queryIndex2 > -1) {
4750
- return queryString.substring(queryIndex2 + 2);
4751
- }
4752
- else if (queryIndex1 > -1 && hashIndex > -1) {
4753
- return queryString.substring(queryIndex1 + 1, hashIndex);
4754
- }
4755
- else if (queryIndex1 > -1) {
4756
- return queryString.substring(queryIndex1 + 1);
4757
- }
4758
- return Constants.EMPTY_STRING;
4759
- }
4760
- static constructAuthorityUriFromObject(urlObject) {
4761
- return new UrlString(urlObject.Protocol +
4762
- "//" +
4763
- urlObject.HostNameAndPort +
4764
- "/" +
4765
- urlObject.PathSegments.join("/"));
4766
- }
4767
- /**
4768
- * Returns URL hash as server auth code response object.
4769
- */
4770
- static getDeserializedHash(hash) {
4771
- // Check if given hash is empty
4772
- if (StringUtils.isEmpty(hash)) {
4773
- return {};
4774
- }
4775
- // Strip the # symbol if present
4776
- const parsedHash = UrlString.parseHash(hash);
4777
- // If # symbol was not present, above will return empty string, so give original hash value
4778
- const deserializedHash = StringUtils.queryStringToObject(StringUtils.isEmpty(parsedHash) ? hash : parsedHash);
4779
- // Check if deserialization didn't work
4780
- if (!deserializedHash) {
4781
- throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedHash));
4782
- }
4783
- return deserializedHash;
4784
- }
4785
- /**
4786
- * Returns URL query string as server auth code response object.
4787
- */
4788
- static getDeserializedQueryString(query) {
4789
- // Check if given query is empty
4790
- if (StringUtils.isEmpty(query)) {
4791
- return {};
4792
- }
4793
- // Strip the ? symbol if present
4794
- const parsedQueryString = UrlString.parseQueryString(query);
4795
- // If ? symbol was not present, above will return empty string, so give original query value
4796
- const deserializedQueryString = StringUtils.queryStringToObject(StringUtils.isEmpty(parsedQueryString)
4797
- ? query
4798
- : parsedQueryString);
4799
- // Check if deserialization didn't work
4800
- if (!deserializedQueryString) {
4801
- throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedQueryString));
4802
- }
4803
- return deserializedQueryString;
4804
- }
4805
- /**
4806
- * Returns either deserialized query string or deserialized hash, depending on the serverResponseType
4807
- * as a server auth code response object.
4808
- */
4809
- static getDeserializedCodeResponse(serverResponseType, hashFragment) {
4810
- const hashUrlString = new UrlString(hashFragment);
4811
- let serverParams;
4812
- if (serverResponseType === ServerResponseType.QUERY) {
4813
- serverParams = UrlString.getDeserializedQueryString(hashFragment);
4482
+ static createAccessTokenEntity(homeAccountId, environment, accessToken, clientId, tenantId, scopes, expiresOn, extExpiresOn, cryptoUtils, refreshOn, tokenType, userAssertionHash, keyId, requestedClaims, requestedClaimsHash) {
4483
+ const atEntity = new AccessTokenEntity();
4484
+ atEntity.homeAccountId = homeAccountId;
4485
+ atEntity.credentialType = CredentialType.ACCESS_TOKEN;
4486
+ atEntity.secret = accessToken;
4487
+ const currentTime = TimeUtils.nowSeconds();
4488
+ atEntity.cachedAt = currentTime.toString();
4489
+ /*
4490
+ * Token expiry time.
4491
+ * This value should be  calculated based on the current UTC time measured locally and the value  expires_in Represented as a string in JSON.
4492
+ */
4493
+ atEntity.expiresOn = expiresOn.toString();
4494
+ atEntity.extendedExpiresOn = extExpiresOn.toString();
4495
+ if (refreshOn) {
4496
+ atEntity.refreshOn = refreshOn.toString();
4814
4497
  }
4815
- else {
4816
- serverParams = UrlString.getDeserializedHash(hashUrlString.getHash());
4498
+ atEntity.environment = environment;
4499
+ atEntity.clientId = clientId;
4500
+ atEntity.realm = tenantId;
4501
+ atEntity.target = scopes;
4502
+ atEntity.userAssertionHash = userAssertionHash;
4503
+ atEntity.tokenType = tokenType || AuthenticationScheme.BEARER;
4504
+ if (requestedClaims) {
4505
+ atEntity.requestedClaims = requestedClaims;
4506
+ atEntity.requestedClaimsHash = requestedClaimsHash;
4817
4507
  }
4818
- return serverParams;
4508
+ /*
4509
+ * Create Access Token With Auth Scheme instead of regular access token
4510
+ * Cast to lower to handle "bearer" from ADFS
4511
+ */
4512
+ if (atEntity.tokenType?.toLowerCase() !==
4513
+ AuthenticationScheme.BEARER.toLowerCase()) {
4514
+ atEntity.credentialType =
4515
+ CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME;
4516
+ switch (atEntity.tokenType) {
4517
+ case AuthenticationScheme.POP:
4518
+ // Make sure keyId is present and add it to credential
4519
+ const tokenClaims = extractTokenClaims(accessToken, cryptoUtils.base64Decode);
4520
+ if (!tokenClaims?.cnf?.kid) {
4521
+ throw ClientAuthError.createTokenClaimsRequiredError();
4522
+ }
4523
+ atEntity.keyId = tokenClaims.cnf.kid;
4524
+ break;
4525
+ case AuthenticationScheme.SSH:
4526
+ atEntity.keyId = keyId;
4527
+ }
4528
+ }
4529
+ return atEntity;
4819
4530
  }
4820
4531
  /**
4821
- * Check if the hash of the URL string contains known properties
4532
+ * Validates an entity: checks for all expected params
4533
+ * @param entity
4822
4534
  */
4823
- static hashContainsKnownProperties(hash) {
4824
- if (StringUtils.isEmpty(hash) || hash.indexOf("=") < 0) {
4825
- // Hash doesn't contain key/value pairs
4535
+ static isAccessTokenEntity(entity) {
4536
+ if (!entity) {
4826
4537
  return false;
4827
4538
  }
4828
- const parameters = UrlString.getDeserializedHash(hash);
4829
- return !!(parameters.code ||
4830
- parameters.error_description ||
4831
- parameters.error ||
4832
- parameters.state);
4539
+ return (entity.hasOwnProperty("homeAccountId") &&
4540
+ entity.hasOwnProperty("environment") &&
4541
+ entity.hasOwnProperty("credentialType") &&
4542
+ entity.hasOwnProperty("realm") &&
4543
+ entity.hasOwnProperty("clientId") &&
4544
+ entity.hasOwnProperty("secret") &&
4545
+ entity.hasOwnProperty("target") &&
4546
+ (entity["credentialType"] === CredentialType.ACCESS_TOKEN ||
4547
+ entity["credentialType"] ===
4548
+ CredentialType.ACCESS_TOKEN_WITH_AUTH_SCHEME));
4833
4549
  }
4834
4550
  }
4835
4551
 
@@ -4838,227 +4554,504 @@ class UrlString {
4838
4554
  * Licensed under the MIT License.
4839
4555
  */
4840
4556
  /**
4841
- * Enumeration of operations that are instrumented by have their performance measured by the PerformanceClient.
4557
+ * REFRESH_TOKEN Cache
4842
4558
  *
4843
- * @export
4844
- * @enum {number}
4559
+ * Key:Value Schema:
4560
+ *
4561
+ * Key Example: uid.utid-login.microsoftonline.com-refreshtoken-clientId--
4562
+ *
4563
+ * Value:
4564
+ * {
4565
+ * homeAccountId: home account identifier for the auth scheme,
4566
+ * environment: entity that issued the token, represented as a full host
4567
+ * credentialType: Type of credential as a string, can be one of the following: RefreshToken, AccessToken, IdToken, Password, Cookie, Certificate, Other
4568
+ * clientId: client ID of the application
4569
+ * secret: Actual credential as a string
4570
+ * familyId: Family ID identifier, '1' represents Microsoft Family
4571
+ * realm: Full tenant or organizational identifier that the account belongs to
4572
+ * target: Permissions that are included in the token, or for refresh tokens, the resource identifier.
4573
+ * }
4845
4574
  */
4846
- const PerformanceEvents = {
4847
- /**
4848
- * acquireTokenByCode API (msal-browser and msal-node).
4849
- * Used to acquire tokens by trading an authorization code against the token endpoint.
4850
- */
4851
- AcquireTokenByCode: "acquireTokenByCode",
4852
- /**
4853
- * acquireTokenByRefreshToken API (msal-browser and msal-node).
4854
- * Used to renew an access token using a refresh token against the token endpoint.
4855
- */
4856
- AcquireTokenByRefreshToken: "acquireTokenByRefreshToken",
4857
- /**
4858
- * acquireTokenSilent API (msal-browser and msal-node).
4859
- * Used to silently acquire a new access token (from the cache or the network).
4860
- */
4861
- AcquireTokenSilent: "acquireTokenSilent",
4862
- /**
4863
- * acquireTokenSilentAsync (msal-browser).
4864
- * Internal API for acquireTokenSilent.
4865
- */
4866
- AcquireTokenSilentAsync: "acquireTokenSilentAsync",
4867
- /**
4868
- * acquireTokenPopup (msal-browser).
4869
- * Used to acquire a new access token interactively through pop ups
4870
- */
4871
- AcquireTokenPopup: "acquireTokenPopup",
4872
- /**
4873
- * getPublicKeyThumbprint API in CryptoOpts class (msal-browser).
4874
- * Used to generate a public/private keypair and generate a public key thumbprint for pop requests.
4875
- */
4876
- CryptoOptsGetPublicKeyThumbprint: "cryptoOptsGetPublicKeyThumbprint",
4877
- /**
4878
- * signJwt API in CryptoOpts class (msal-browser).
4879
- * Used to signed a pop token.
4880
- */
4881
- CryptoOptsSignJwt: "cryptoOptsSignJwt",
4882
- /**
4883
- * acquireToken API in the SilentCacheClient class (msal-browser).
4884
- * Used to read access tokens from the cache.
4885
- */
4886
- SilentCacheClientAcquireToken: "silentCacheClientAcquireToken",
4887
- /**
4888
- * acquireToken API in the SilentIframeClient class (msal-browser).
4889
- * Used to acquire a new set of tokens from the authorize endpoint in a hidden iframe.
4890
- */
4891
- SilentIframeClientAcquireToken: "silentIframeClientAcquireToken",
4892
- /**
4893
- * acquireToken API in SilentRereshClient (msal-browser).
4894
- * Used to acquire a new set of tokens from the token endpoint using a refresh token.
4895
- */
4896
- SilentRefreshClientAcquireToken: "silentRefreshClientAcquireToken",
4897
- /**
4898
- * ssoSilent API (msal-browser).
4899
- * Used to silently acquire an authorization code and set of tokens using a hidden iframe.
4900
- */
4901
- SsoSilent: "ssoSilent",
4902
- /**
4903
- * getDiscoveredAuthority API in StandardInteractionClient class (msal-browser).
4904
- * Used to load authority metadata for a request.
4905
- */
4906
- StandardInteractionClientGetDiscoveredAuthority: "standardInteractionClientGetDiscoveredAuthority",
4907
- /**
4908
- * acquireToken APIs in msal-browser.
4909
- * Used to make an /authorize endpoint call with native brokering enabled.
4910
- */
4911
- FetchAccountIdWithNativeBroker: "fetchAccountIdWithNativeBroker",
4912
- /**
4913
- * acquireToken API in NativeInteractionClient class (msal-browser).
4914
- * Used to acquire a token from Native component when native brokering is enabled.
4915
- */
4916
- NativeInteractionClientAcquireToken: "nativeInteractionClientAcquireToken",
4917
- /**
4918
- * Time spent creating default headers for requests to token endpoint
4919
- */
4920
- BaseClientCreateTokenRequestHeaders: "baseClientCreateTokenRequestHeaders",
4575
+ class RefreshTokenEntity extends CredentialEntity {
4921
4576
  /**
4922
- * Used to measure the time taken for completing embedded-broker handshake (PW-Broker).
4577
+ * Create RefreshTokenEntity
4578
+ * @param homeAccountId
4579
+ * @param authenticationResult
4580
+ * @param clientId
4581
+ * @param authority
4923
4582
  */
4924
- BrokerHandhshake: "brokerHandshake",
4583
+ static createRefreshTokenEntity(homeAccountId, environment, refreshToken, clientId, familyId, userAssertionHash) {
4584
+ const rtEntity = new RefreshTokenEntity();
4585
+ rtEntity.clientId = clientId;
4586
+ rtEntity.credentialType = CredentialType.REFRESH_TOKEN;
4587
+ rtEntity.environment = environment;
4588
+ rtEntity.homeAccountId = homeAccountId;
4589
+ rtEntity.secret = refreshToken;
4590
+ rtEntity.userAssertionHash = userAssertionHash;
4591
+ if (familyId)
4592
+ rtEntity.familyId = familyId;
4593
+ return rtEntity;
4594
+ }
4925
4595
  /**
4926
- * acquireTokenByRefreshToken API in BrokerClientApplication (PW-Broker) .
4596
+ * Validates an entity: checks for all expected params
4597
+ * @param entity
4927
4598
  */
4928
- AcquireTokenByRefreshTokenInBroker: "acquireTokenByRefreshTokenInBroker",
4599
+ static isRefreshTokenEntity(entity) {
4600
+ if (!entity) {
4601
+ return false;
4602
+ }
4603
+ return (entity.hasOwnProperty("homeAccountId") &&
4604
+ entity.hasOwnProperty("environment") &&
4605
+ entity.hasOwnProperty("credentialType") &&
4606
+ entity.hasOwnProperty("clientId") &&
4607
+ entity.hasOwnProperty("secret") &&
4608
+ entity["credentialType"] === CredentialType.REFRESH_TOKEN);
4609
+ }
4610
+ }
4611
+
4612
+ /*
4613
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4614
+ * Licensed under the MIT License.
4615
+ */
4616
+ /**
4617
+ * InteractionRequiredServerErrorMessage contains string constants used by error codes and messages returned by the server indicating interaction is required
4618
+ */
4619
+ const InteractionRequiredServerErrorMessage = [
4620
+ "interaction_required",
4621
+ "consent_required",
4622
+ "login_required",
4623
+ ];
4624
+ const InteractionRequiredAuthSubErrorMessage = [
4625
+ "message_only",
4626
+ "additional_action",
4627
+ "basic_action",
4628
+ "user_password_expired",
4629
+ "consent_required",
4630
+ ];
4631
+ /**
4632
+ * Interaction required errors defined by the SDK
4633
+ */
4634
+ const InteractionRequiredAuthErrorMessage = {
4635
+ noTokensFoundError: {
4636
+ code: "no_tokens_found",
4637
+ desc: "No refresh token found in the cache. Please sign-in.",
4638
+ },
4639
+ native_account_unavailable: {
4640
+ code: "native_account_unavailable",
4641
+ desc: "The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API.",
4642
+ },
4643
+ };
4644
+ /**
4645
+ * Error thrown when user interaction is required.
4646
+ */
4647
+ class InteractionRequiredAuthError extends AuthError {
4648
+ constructor(errorCode, errorMessage, subError, timestamp, traceId, correlationId, claims) {
4649
+ super(errorCode, errorMessage, subError);
4650
+ Object.setPrototypeOf(this, InteractionRequiredAuthError.prototype);
4651
+ this.timestamp = timestamp || Constants.EMPTY_STRING;
4652
+ this.traceId = traceId || Constants.EMPTY_STRING;
4653
+ this.correlationId = correlationId || Constants.EMPTY_STRING;
4654
+ this.claims = claims || Constants.EMPTY_STRING;
4655
+ this.name = "InteractionRequiredAuthError";
4656
+ }
4929
4657
  /**
4930
- * Time taken for token acquisition by broker
4658
+ * Helper function used to determine if an error thrown by the server requires interaction to resolve
4659
+ * @param errorCode
4660
+ * @param errorString
4661
+ * @param subError
4931
4662
  */
4932
- AcquireTokenByBroker: "acquireTokenByBroker",
4663
+ static isInteractionRequiredError(errorCode, errorString, subError) {
4664
+ const isInteractionRequiredErrorCode = !!errorCode &&
4665
+ InteractionRequiredServerErrorMessage.indexOf(errorCode) > -1;
4666
+ const isInteractionRequiredSubError = !!subError &&
4667
+ InteractionRequiredAuthSubErrorMessage.indexOf(subError) > -1;
4668
+ const isInteractionRequiredErrorDesc = !!errorString &&
4669
+ InteractionRequiredServerErrorMessage.some((irErrorCode) => {
4670
+ return errorString.indexOf(irErrorCode) > -1;
4671
+ });
4672
+ return (isInteractionRequiredErrorCode ||
4673
+ isInteractionRequiredErrorDesc ||
4674
+ isInteractionRequiredSubError);
4675
+ }
4933
4676
  /**
4934
- * Time spent on the network for refresh token acquisition
4677
+ * Creates an error thrown when the authorization code required for a token request is null or empty.
4935
4678
  */
4936
- RefreshTokenClientExecuteTokenRequest: "refreshTokenClientExecuteTokenRequest",
4679
+ static createNoTokensFoundError() {
4680
+ return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.noTokensFoundError.code, InteractionRequiredAuthErrorMessage.noTokensFoundError.desc);
4681
+ }
4937
4682
  /**
4938
- * Time taken for acquiring refresh token , records RT size
4683
+ * Creates an error thrown when the native broker returns ACCOUNT_UNAVAILABLE status, indicating that the account was removed and interactive sign-in is required
4684
+ * @returns
4939
4685
  */
4940
- RefreshTokenClientAcquireToken: "refreshTokenClientAcquireToken",
4686
+ static createNativeAccountUnavailableError() {
4687
+ return new InteractionRequiredAuthError(InteractionRequiredAuthErrorMessage.native_account_unavailable.code, InteractionRequiredAuthErrorMessage.native_account_unavailable.desc);
4688
+ }
4689
+ }
4690
+
4691
+ /*
4692
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4693
+ * Licensed under the MIT License.
4694
+ */
4695
+ /** @internal */
4696
+ class CacheRecord {
4697
+ constructor(accountEntity, idTokenEntity, accessTokenEntity, refreshTokenEntity, appMetadataEntity) {
4698
+ this.account = accountEntity || null;
4699
+ this.idToken = idTokenEntity || null;
4700
+ this.accessToken = accessTokenEntity || null;
4701
+ this.refreshToken = refreshTokenEntity || null;
4702
+ this.appMetadata = appMetadataEntity || null;
4703
+ }
4704
+ }
4705
+
4706
+ /*
4707
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4708
+ * Licensed under the MIT License.
4709
+ */
4710
+ /**
4711
+ * Class which provides helpers for OAuth 2.0 protocol specific values
4712
+ */
4713
+ class ProtocolUtils {
4941
4714
  /**
4942
- * Time taken for acquiring cached refresh token
4715
+ * Appends user state with random guid, or returns random guid.
4716
+ * @param userState
4717
+ * @param randomGuid
4943
4718
  */
4944
- RefreshTokenClientAcquireTokenWithCachedRefreshToken: "refreshTokenClientAcquireTokenWithCachedRefreshToken",
4719
+ static setRequestState(cryptoObj, userState, meta) {
4720
+ const libraryState = ProtocolUtils.generateLibraryState(cryptoObj, meta);
4721
+ return userState
4722
+ ? `${libraryState}${Constants.RESOURCE_DELIM}${userState}`
4723
+ : libraryState;
4724
+ }
4945
4725
  /**
4946
- * acquireTokenByRefreshToken API in RefreshTokenClient (msal-common).
4726
+ * Generates the state value used by the common library.
4727
+ * @param randomGuid
4728
+ * @param cryptoObj
4947
4729
  */
4948
- RefreshTokenClientAcquireTokenByRefreshToken: "refreshTokenClientAcquireTokenByRefreshToken",
4730
+ static generateLibraryState(cryptoObj, meta) {
4731
+ if (!cryptoObj) {
4732
+ throw ClientAuthError.createNoCryptoObjectError("generateLibraryState");
4733
+ }
4734
+ // Create a state object containing a unique id and the timestamp of the request creation
4735
+ const stateObj = {
4736
+ id: cryptoObj.createNewGuid(),
4737
+ };
4738
+ if (meta) {
4739
+ stateObj.meta = meta;
4740
+ }
4741
+ const stateString = JSON.stringify(stateObj);
4742
+ return cryptoObj.base64Encode(stateString);
4743
+ }
4949
4744
  /**
4950
- * Helper function to create token request body in RefreshTokenClient (msal-common).
4745
+ * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
4746
+ * @param state
4747
+ * @param cryptoObj
4951
4748
  */
4952
- RefreshTokenClientCreateTokenRequestBody: "refreshTokenClientCreateTokenRequestBody",
4749
+ static parseRequestState(cryptoObj, state) {
4750
+ if (!cryptoObj) {
4751
+ throw ClientAuthError.createNoCryptoObjectError("parseRequestState");
4752
+ }
4753
+ if (!state) {
4754
+ throw ClientAuthError.createInvalidStateError(state, "Null, undefined or empty state");
4755
+ }
4756
+ try {
4757
+ // Split the state between library state and user passed state and decode them separately
4758
+ const splitState = state.split(Constants.RESOURCE_DELIM);
4759
+ const libraryState = splitState[0];
4760
+ const userState = splitState.length > 1
4761
+ ? splitState.slice(1).join(Constants.RESOURCE_DELIM)
4762
+ : Constants.EMPTY_STRING;
4763
+ const libraryStateString = cryptoObj.base64Decode(libraryState);
4764
+ const libraryStateObj = JSON.parse(libraryStateString);
4765
+ return {
4766
+ userRequestState: userState || Constants.EMPTY_STRING,
4767
+ libraryState: libraryStateObj,
4768
+ };
4769
+ }
4770
+ catch (e) {
4771
+ throw ClientAuthError.createInvalidStateError(state, e);
4772
+ }
4773
+ }
4774
+ }
4775
+
4776
+ /*
4777
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4778
+ * Licensed under the MIT License.
4779
+ */
4780
+ /**
4781
+ * Url object class which can perform various transformations on url strings.
4782
+ */
4783
+ class UrlString {
4784
+ get urlString() {
4785
+ return this._urlString;
4786
+ }
4787
+ constructor(url) {
4788
+ this._urlString = url;
4789
+ if (!this._urlString) {
4790
+ // Throws error if url is empty
4791
+ throw ClientConfigurationError.createUrlEmptyError();
4792
+ }
4793
+ if (!this.getHash()) {
4794
+ this._urlString = UrlString.canonicalizeUri(url);
4795
+ }
4796
+ }
4953
4797
  /**
4954
- * acquireTokenFromCache (msal-browser).
4955
- * Internal API for acquiring token from cache
4798
+ * Ensure urls are lower case and end with a / character.
4799
+ * @param url
4956
4800
  */
4957
- AcquireTokenFromCache: "acquireTokenFromCache",
4801
+ static canonicalizeUri(url) {
4802
+ if (url) {
4803
+ let lowerCaseUrl = url.toLowerCase();
4804
+ if (StringUtils.endsWith(lowerCaseUrl, "?")) {
4805
+ lowerCaseUrl = lowerCaseUrl.slice(0, -1);
4806
+ }
4807
+ else if (StringUtils.endsWith(lowerCaseUrl, "?/")) {
4808
+ lowerCaseUrl = lowerCaseUrl.slice(0, -2);
4809
+ }
4810
+ if (!StringUtils.endsWith(lowerCaseUrl, "/")) {
4811
+ lowerCaseUrl += "/";
4812
+ }
4813
+ return lowerCaseUrl;
4814
+ }
4815
+ return url;
4816
+ }
4958
4817
  /**
4959
- * acquireTokenBySilentIframe (msal-browser).
4960
- * Internal API for acquiring token by silent Iframe
4818
+ * Throws if urlString passed is not a valid authority URI string.
4961
4819
  */
4962
- AcquireTokenBySilentIframe: "acquireTokenBySilentIframe",
4820
+ validateAsUri() {
4821
+ // Attempts to parse url for uri components
4822
+ let components;
4823
+ try {
4824
+ components = this.getUrlComponents();
4825
+ }
4826
+ catch (e) {
4827
+ throw ClientConfigurationError.createUrlParseError(e);
4828
+ }
4829
+ // Throw error if URI or path segments are not parseable.
4830
+ if (!components.HostNameAndPort || !components.PathSegments) {
4831
+ throw ClientConfigurationError.createUrlParseError(`Given url string: ${this.urlString}`);
4832
+ }
4833
+ // Throw error if uri is insecure.
4834
+ if (!components.Protocol ||
4835
+ components.Protocol.toLowerCase() !== "https:") {
4836
+ throw ClientConfigurationError.createInsecureAuthorityUriError(this.urlString);
4837
+ }
4838
+ }
4963
4839
  /**
4964
- * Internal API for initializing base request in BaseInteractionClient (msal-browser)
4840
+ * Given a url and a query string return the url with provided query string appended
4841
+ * @param url
4842
+ * @param queryString
4965
4843
  */
4966
- InitializeBaseRequest: "initializeBaseRequest",
4844
+ static appendQueryString(url, queryString) {
4845
+ if (!queryString) {
4846
+ return url;
4847
+ }
4848
+ return url.indexOf("?") < 0
4849
+ ? `${url}?${queryString}`
4850
+ : `${url}&${queryString}`;
4851
+ }
4967
4852
  /**
4968
- * Internal API for initializing silent request in SilentCacheClient (msal-browser)
4853
+ * Returns a url with the hash removed
4854
+ * @param url
4969
4855
  */
4970
- InitializeSilentRequest: "initializeSilentRequest",
4971
- InitializeClientApplication: "initializeClientApplication",
4856
+ static removeHashFromUrl(url) {
4857
+ return UrlString.canonicalizeUri(url.split("#")[0]);
4858
+ }
4972
4859
  /**
4973
- * Helper function in SilentIframeClient class (msal-browser).
4860
+ * Given a url like https://a:b/common/d?e=f#g, and a tenantId, returns https://a:b/tenantId/d
4861
+ * @param href The url
4862
+ * @param tenantId The tenant id to replace
4974
4863
  */
4975
- SilentIframeClientTokenHelper: "silentIframeClientTokenHelper",
4864
+ replaceTenantPath(tenantId) {
4865
+ const urlObject = this.getUrlComponents();
4866
+ const pathArray = urlObject.PathSegments;
4867
+ if (tenantId &&
4868
+ pathArray.length !== 0 &&
4869
+ (pathArray[0] === AADAuthorityConstants.COMMON ||
4870
+ pathArray[0] === AADAuthorityConstants.ORGANIZATIONS)) {
4871
+ pathArray[0] = tenantId;
4872
+ }
4873
+ return UrlString.constructAuthorityUriFromObject(urlObject);
4874
+ }
4976
4875
  /**
4977
- * SilentHandler
4876
+ * Returns the anchor part(#) of the URL
4978
4877
  */
4979
- SilentHandlerInitiateAuthRequest: "silentHandlerInitiateAuthRequest",
4980
- SilentHandlerMonitorIframeForHash: "silentHandlerMonitorIframeForHash",
4981
- SilentHandlerLoadFrame: "silentHandlerLoadFrame",
4878
+ getHash() {
4879
+ return UrlString.parseHash(this.urlString);
4880
+ }
4982
4881
  /**
4983
- * Helper functions in StandardInteractionClient class (msal-browser)
4882
+ * Parses out the components from a url string.
4883
+ * @returns An object with the various components. Please cache this value insted of calling this multiple times on the same url.
4984
4884
  */
4985
- StandardInteractionClientCreateAuthCodeClient: "standardInteractionClientCreateAuthCodeClient",
4986
- StandardInteractionClientGetClientConfiguration: "standardInteractionClientGetClientConfiguration",
4987
- StandardInteractionClientInitializeAuthorizationRequest: "standardInteractionClientInitializeAuthorizationRequest",
4988
- StandardInteractionClientInitializeAuthorizationCodeRequest: "standardInteractionClientInitializeAuthorizationCodeRequest",
4885
+ getUrlComponents() {
4886
+ // https://gist.github.com/curtisz/11139b2cfcaef4a261e0
4887
+ const regEx = RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
4888
+ // If url string does not match regEx, we throw an error
4889
+ const match = this.urlString.match(regEx);
4890
+ if (!match) {
4891
+ throw ClientConfigurationError.createUrlParseError(`Given url string: ${this.urlString}`);
4892
+ }
4893
+ // Url component object
4894
+ const urlComponents = {
4895
+ Protocol: match[1],
4896
+ HostNameAndPort: match[4],
4897
+ AbsolutePath: match[5],
4898
+ QueryString: match[7],
4899
+ };
4900
+ let pathSegments = urlComponents.AbsolutePath.split("/");
4901
+ pathSegments = pathSegments.filter((val) => val && val.length > 0); // remove empty elements
4902
+ urlComponents.PathSegments = pathSegments;
4903
+ if (urlComponents.QueryString &&
4904
+ urlComponents.QueryString.endsWith("/")) {
4905
+ urlComponents.QueryString = urlComponents.QueryString.substring(0, urlComponents.QueryString.length - 1);
4906
+ }
4907
+ return urlComponents;
4908
+ }
4909
+ static getDomainFromUrl(url) {
4910
+ const regEx = RegExp("^([^:/?#]+://)?([^/?#]*)");
4911
+ const match = url.match(regEx);
4912
+ if (!match) {
4913
+ throw ClientConfigurationError.createUrlParseError(`Given url string: ${url}`);
4914
+ }
4915
+ return match[2];
4916
+ }
4917
+ static getAbsoluteUrl(relativeUrl, baseUrl) {
4918
+ if (relativeUrl[0] === Constants.FORWARD_SLASH) {
4919
+ const url = new UrlString(baseUrl);
4920
+ const baseComponents = url.getUrlComponents();
4921
+ return (baseComponents.Protocol +
4922
+ "//" +
4923
+ baseComponents.HostNameAndPort +
4924
+ relativeUrl);
4925
+ }
4926
+ return relativeUrl;
4927
+ }
4989
4928
  /**
4990
- * getAuthCodeUrl API (msal-browser and msal-node).
4929
+ * Parses hash string from given string. Returns empty string if no hash symbol is found.
4930
+ * @param hashString
4991
4931
  */
4992
- GetAuthCodeUrl: "getAuthCodeUrl",
4932
+ static parseHash(hashString) {
4933
+ const hashIndex1 = hashString.indexOf("#");
4934
+ const hashIndex2 = hashString.indexOf("#/");
4935
+ if (hashIndex2 > -1) {
4936
+ return hashString.substring(hashIndex2 + 2);
4937
+ }
4938
+ else if (hashIndex1 > -1) {
4939
+ return hashString.substring(hashIndex1 + 1);
4940
+ }
4941
+ return Constants.EMPTY_STRING;
4942
+ }
4993
4943
  /**
4994
- * Functions from InteractionHandler (msal-browser)
4944
+ * Parses query string from given string. Returns empty string if no query symbol is found.
4945
+ * @param queryString
4995
4946
  */
4996
- HandleCodeResponseFromServer: "handleCodeResponseFromServer",
4997
- HandleCodeResponseFromHash: "handleCodeResponseFromHash",
4998
- UpdateTokenEndpointAuthority: "updateTokenEndpointAuthority",
4947
+ static parseQueryString(queryString) {
4948
+ const queryIndex1 = queryString.indexOf("?");
4949
+ const queryIndex2 = queryString.indexOf("/?");
4950
+ if (queryIndex2 > -1) {
4951
+ return queryString.substring(queryIndex2 + 2);
4952
+ }
4953
+ else if (queryIndex1 > -1) {
4954
+ return queryString.substring(queryIndex1 + 1);
4955
+ }
4956
+ return Constants.EMPTY_STRING;
4957
+ }
4999
4958
  /**
5000
- * APIs in Authorization Code Client (msal-common)
4959
+ * Parses query server response string from given string.
4960
+ * Extract hash between '?code=' and '#' if trailing '# is present.
4961
+ * Returns empty string if no query symbol is found.
4962
+ * @param queryString
5001
4963
  */
5002
- AuthClientAcquireToken: "authClientAcquireToken",
5003
- AuthClientExecuteTokenRequest: "authClientExecuteTokenRequest",
5004
- AuthClientCreateTokenRequestBody: "authClientCreateTokenRequestBody",
5005
- AuthClientCreateQueryString: "authClientCreateQueryString",
4964
+ static parseQueryServerResponse(queryString) {
4965
+ const queryIndex1 = queryString.indexOf("?code");
4966
+ const queryIndex2 = queryString.indexOf("/?code");
4967
+ const hashIndex = queryString.indexOf("#");
4968
+ if (queryIndex2 > -1 && hashIndex > -1) {
4969
+ return queryString.substring(queryIndex2 + 2, hashIndex);
4970
+ }
4971
+ else if (queryIndex2 > -1) {
4972
+ return queryString.substring(queryIndex2 + 2);
4973
+ }
4974
+ else if (queryIndex1 > -1 && hashIndex > -1) {
4975
+ return queryString.substring(queryIndex1 + 1, hashIndex);
4976
+ }
4977
+ else if (queryIndex1 > -1) {
4978
+ return queryString.substring(queryIndex1 + 1);
4979
+ }
4980
+ return Constants.EMPTY_STRING;
4981
+ }
4982
+ static constructAuthorityUriFromObject(urlObject) {
4983
+ return new UrlString(urlObject.Protocol +
4984
+ "//" +
4985
+ urlObject.HostNameAndPort +
4986
+ "/" +
4987
+ urlObject.PathSegments.join("/"));
4988
+ }
5006
4989
  /**
5007
- * Generate functions in PopTokenGenerator (msal-common)
4990
+ * Returns URL hash as server auth code response object.
5008
4991
  */
5009
- PopTokenGenerateCnf: "popTokenGenerateCnf",
5010
- PopTokenGenerateKid: "popTokenGenerateKid",
4992
+ static getDeserializedHash(hash) {
4993
+ // Check if given hash is empty
4994
+ if (!hash) {
4995
+ return {};
4996
+ }
4997
+ // Strip the # symbol if present
4998
+ const parsedHash = UrlString.parseHash(hash);
4999
+ // If # symbol was not present, above will return empty string, so give original hash value
5000
+ const deserializedHash = StringUtils.queryStringToObject(parsedHash || hash);
5001
+ // Check if deserialization didn't work
5002
+ if (!deserializedHash) {
5003
+ throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedHash));
5004
+ }
5005
+ return deserializedHash;
5006
+ }
5011
5007
  /**
5012
- * handleServerTokenResponse API in ResponseHandler (msal-common)
5008
+ * Returns URL query string as server auth code response object.
5013
5009
  */
5014
- HandleServerTokenResponse: "handleServerTokenResponse",
5010
+ static getDeserializedQueryString(query) {
5011
+ // Check if given query is empty
5012
+ if (!query) {
5013
+ return {};
5014
+ }
5015
+ // Strip the ? symbol if present
5016
+ const parsedQueryString = UrlString.parseQueryString(query);
5017
+ // If ? symbol was not present, above will return empty string, so give original query value
5018
+ const deserializedQueryString = StringUtils.queryStringToObject(parsedQueryString || query);
5019
+ // Check if deserialization didn't work
5020
+ if (!deserializedQueryString) {
5021
+ throw ClientAuthError.createHashNotDeserializedError(JSON.stringify(deserializedQueryString));
5022
+ }
5023
+ return deserializedQueryString;
5024
+ }
5015
5025
  /**
5016
- * Authority functions
5026
+ * Returns either deserialized query string or deserialized hash, depending on the serverResponseType
5027
+ * as a server auth code response object.
5017
5028
  */
5018
- AuthorityFactoryCreateDiscoveredInstance: "authorityFactoryCreateDiscoveredInstance",
5019
- AuthorityResolveEndpointsAsync: "authorityResolveEndpointsAsync",
5020
- AuthorityGetCloudDiscoveryMetadataFromNetwork: "authorityGetCloudDiscoveryMetadataFromNetwork",
5021
- AuthorityUpdateCloudDiscoveryMetadata: "authorityUpdateCloudDiscoveryMetadata",
5022
- AuthorityGetEndpointMetadataFromNetwork: "authorityGetEndpointMetadataFromNetwork",
5023
- AuthorityUpdateEndpointMetadata: "authorityUpdateEndpointMetadata",
5024
- AuthorityUpdateMetadataWithRegionalInformation: "authorityUpdateMetadataWithRegionalInformation",
5029
+ static getDeserializedCodeResponse(serverResponseType, hashFragment) {
5030
+ const hashUrlString = new UrlString(hashFragment);
5031
+ let serverParams;
5032
+ if (serverResponseType === ServerResponseType.QUERY) {
5033
+ serverParams = UrlString.getDeserializedQueryString(hashFragment);
5034
+ }
5035
+ else {
5036
+ serverParams = UrlString.getDeserializedHash(hashUrlString.getHash());
5037
+ }
5038
+ return serverParams;
5039
+ }
5025
5040
  /**
5026
- * Region Discovery functions
5041
+ * Check if the hash of the URL string contains known properties
5027
5042
  */
5028
- RegionDiscoveryDetectRegion: "regionDiscoveryDetectRegion",
5029
- RegionDiscoveryGetRegionFromIMDS: "regionDiscoveryGetRegionFromIMDS",
5030
- RegionDiscoveryGetCurrentVersion: "regionDiscoveryGetCurrentVersion",
5031
- AcquireTokenByCodeAsync: "acquireTokenByCodeAsync",
5032
- GetEndpointMetadataFromNetwork: "getEndpointMetadataFromNetwork",
5033
- GetCloudDiscoveryMetadataFromNetworkMeasurement: "getCloudDiscoveryMetadataFromNetworkMeasurement",
5034
- HandleRedirectPromiseMeasurement: "handleRedirectPromiseMeasurement",
5035
- UpdateCloudDiscoveryMetadataMeasurement: "updateCloudDiscoveryMetadataMeasurement",
5036
- UsernamePasswordClientAcquireToken: "usernamePasswordClientAcquireToken",
5037
- NativeMessageHandlerHandshake: "nativeMessageHandlerHandshake",
5038
- NativeGenerateAuthResult: "nativeGenerateAuthResult",
5039
- };
5040
- /**
5041
- * State of the performance event.
5042
- *
5043
- * @export
5044
- * @enum {number}
5045
- */
5046
- const PerformanceEventStatus = {
5047
- NotStarted: 0,
5048
- InProgress: 1,
5049
- Completed: 2,
5050
- };
5051
- const IntFields = new Set([
5052
- "accessTokenSize",
5053
- "durationMs",
5054
- "idTokenSize",
5055
- "matsSilentStatus",
5056
- "matsHttpStatus",
5057
- "refreshTokenSize",
5058
- "queuedTimeMs",
5059
- "startTimeMs",
5060
- "status",
5061
- ]);
5043
+ static hashContainsKnownProperties(hash) {
5044
+ if (!hash || hash.indexOf("=") < 0) {
5045
+ // Hash doesn't contain key/value pairs
5046
+ return false;
5047
+ }
5048
+ const parameters = UrlString.getDeserializedHash(hash);
5049
+ return !!(parameters.code ||
5050
+ parameters.error_description ||
5051
+ parameters.error ||
5052
+ parameters.state);
5053
+ }
5054
+ }
5062
5055
 
5063
5056
  /*
5064
5057
  * Copyright (c) Microsoft Corporation. All rights reserved.
@@ -5300,17 +5293,37 @@ class ResponseHandler {
5300
5293
  /**
5301
5294
  * Function which validates server authorization token response.
5302
5295
  * @param serverResponse
5296
+ * @param refreshAccessToken
5303
5297
  */
5304
- validateTokenResponse(serverResponse) {
5298
+ validateTokenResponse(serverResponse, refreshAccessToken) {
5305
5299
  // Check for error
5306
5300
  if (serverResponse.error ||
5307
5301
  serverResponse.error_description ||
5308
5302
  serverResponse.suberror) {
5303
+ const errString = `${serverResponse.error_codes} - [${serverResponse.timestamp}]: ${serverResponse.error_description} - Correlation ID: ${serverResponse.correlation_id} - Trace ID: ${serverResponse.trace_id}`;
5304
+ const serverError = new ServerError(serverResponse.error, errString, serverResponse.suberror);
5305
+ // check if 500 error
5306
+ if (refreshAccessToken &&
5307
+ serverResponse.status &&
5308
+ serverResponse.status >= HttpStatus.SERVER_ERROR_RANGE_START &&
5309
+ serverResponse.status <= HttpStatus.SERVER_ERROR_RANGE_END) {
5310
+ this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently unavailable and the access token is unable to be refreshed.\n${serverError}`);
5311
+ // don't throw an exception, but alert the user via a log that the token was unable to be refreshed
5312
+ return;
5313
+ // check if 400 error
5314
+ }
5315
+ else if (refreshAccessToken &&
5316
+ serverResponse.status &&
5317
+ serverResponse.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&
5318
+ serverResponse.status <= HttpStatus.CLIENT_ERROR_RANGE_END) {
5319
+ this.logger.warning(`executeTokenRequest:validateTokenResponse - AAD is currently available but is unable to refresh the access token.\n${serverError}`);
5320
+ // don't throw an exception, but alert the user via a log that the token was unable to be refreshed
5321
+ return;
5322
+ }
5309
5323
  if (InteractionRequiredAuthError.isInteractionRequiredError(serverResponse.error, serverResponse.error_description, serverResponse.suberror)) {
5310
5324
  throw new InteractionRequiredAuthError(serverResponse.error, serverResponse.error_description, serverResponse.suberror, serverResponse.timestamp || Constants.EMPTY_STRING, serverResponse.trace_id || Constants.EMPTY_STRING, serverResponse.correlation_id || Constants.EMPTY_STRING, serverResponse.claims || Constants.EMPTY_STRING);
5311
5325
  }
5312
- const errString = `${serverResponse.error_codes} - [${serverResponse.timestamp}]: ${serverResponse.error_description} - Correlation ID: ${serverResponse.correlation_id} - Trace ID: ${serverResponse.trace_id}`;
5313
- throw new ServerError(serverResponse.error, errString, serverResponse.suberror);
5326
+ throw serverError;
5314
5327
  }
5315
5328
  }
5316
5329
  /**
@@ -5321,27 +5334,26 @@ class ResponseHandler {
5321
5334
  async handleServerTokenResponse(serverTokenResponse, authority, reqTimestamp, request, authCodePayload, userAssertionHash, handlingRefreshTokenResponse, forceCacheRefreshTokenResponse, serverRequestId) {
5322
5335
  this.performanceClient?.addQueueMeasurement(PerformanceEvents.HandleServerTokenResponse, serverTokenResponse.correlation_id);
5323
5336
  // create an idToken object (not entity)
5324
- let idTokenObj;
5337
+ let idTokenClaims;
5325
5338
  if (serverTokenResponse.id_token) {
5326
- idTokenObj = new AuthToken(serverTokenResponse.id_token || Constants.EMPTY_STRING, this.cryptoObj);
5339
+ idTokenClaims = extractTokenClaims(serverTokenResponse.id_token || Constants.EMPTY_STRING, this.cryptoObj.base64Decode);
5327
5340
  // token nonce check (TODO: Add a warning if no nonce is given?)
5328
- if (authCodePayload &&
5329
- !StringUtils.isEmpty(authCodePayload.nonce)) {
5330
- if (idTokenObj.claims.nonce !== authCodePayload.nonce) {
5341
+ if (authCodePayload && authCodePayload.nonce) {
5342
+ if (idTokenClaims.nonce !== authCodePayload.nonce) {
5331
5343
  throw ClientAuthError.createNonceMismatchError();
5332
5344
  }
5333
5345
  }
5334
5346
  // token max_age check
5335
5347
  if (request.maxAge || request.maxAge === 0) {
5336
- const authTime = idTokenObj.claims.auth_time;
5348
+ const authTime = idTokenClaims.auth_time;
5337
5349
  if (!authTime) {
5338
5350
  throw ClientAuthError.createAuthTimeNotFoundError();
5339
5351
  }
5340
- AuthToken.checkMaxAge(authTime, request.maxAge);
5352
+ checkMaxAge(authTime, request.maxAge);
5341
5353
  }
5342
5354
  }
5343
5355
  // generate homeAccountId
5344
- this.homeAccountIdentifier = AccountEntity.generateHomeAccountId(serverTokenResponse.client_info || Constants.EMPTY_STRING, authority.authorityType, this.logger, this.cryptoObj, idTokenObj?.claims);
5356
+ this.homeAccountIdentifier = AccountEntity.generateHomeAccountId(serverTokenResponse.client_info || Constants.EMPTY_STRING, authority.authorityType, this.logger, this.cryptoObj, idTokenClaims);
5345
5357
  // save the response tokens
5346
5358
  let requestStateObj;
5347
5359
  if (!!authCodePayload && !!authCodePayload.state) {
@@ -5350,7 +5362,7 @@ class ResponseHandler {
5350
5362
  // Add keyId from request to serverTokenResponse if defined
5351
5363
  serverTokenResponse.key_id =
5352
5364
  serverTokenResponse.key_id || request.sshKid || undefined;
5353
- const cacheRecord = this.generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenObj, userAssertionHash, authCodePayload);
5365
+ const cacheRecord = this.generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload);
5354
5366
  let cacheContext;
5355
5367
  try {
5356
5368
  if (this.persistencePlugin && this.serializableCache) {
@@ -5371,7 +5383,7 @@ class ResponseHandler {
5371
5383
  const account = this.cacheStorage.getAccount(key);
5372
5384
  if (!account) {
5373
5385
  this.logger.warning("Account used to refresh tokens not in persistence, refreshed tokens will not be stored in the cache");
5374
- return ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, undefined, serverRequestId);
5386
+ return ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, undefined, serverRequestId);
5375
5387
  }
5376
5388
  }
5377
5389
  await this.cacheStorage.saveCacheRecord(cacheRecord, request.storeInCache);
@@ -5384,7 +5396,7 @@ class ResponseHandler {
5384
5396
  await this.persistencePlugin.afterCacheAccess(cacheContext);
5385
5397
  }
5386
5398
  }
5387
- return ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenObj, requestStateObj, serverTokenResponse, serverRequestId);
5399
+ return ResponseHandler.generateAuthenticationResult(this.cryptoObj, authority, cacheRecord, false, request, idTokenClaims, requestStateObj, serverTokenResponse, serverRequestId);
5388
5400
  }
5389
5401
  /**
5390
5402
  * Generates CacheRecord
@@ -5392,20 +5404,19 @@ class ResponseHandler {
5392
5404
  * @param idTokenObj
5393
5405
  * @param authority
5394
5406
  */
5395
- generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenObj, userAssertionHash, authCodePayload) {
5407
+ generateCacheRecord(serverTokenResponse, authority, reqTimestamp, request, idTokenClaims, userAssertionHash, authCodePayload) {
5396
5408
  const env = authority.getPreferredCache();
5397
- if (StringUtils.isEmpty(env)) {
5409
+ if (!env) {
5398
5410
  throw ClientAuthError.createInvalidCacheEnvironmentError();
5399
5411
  }
5400
5412
  // IdToken: non AAD scenarios can have empty realm
5401
5413
  let cachedIdToken;
5402
5414
  let cachedAccount;
5403
- if (!StringUtils.isEmpty(serverTokenResponse.id_token) &&
5404
- !!idTokenObj) {
5405
- cachedIdToken = IdTokenEntity.createIdTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.id_token || Constants.EMPTY_STRING, this.clientId, idTokenObj.claims.tid || Constants.EMPTY_STRING);
5415
+ if (serverTokenResponse.id_token && !!idTokenClaims) {
5416
+ cachedIdToken = IdTokenEntity.createIdTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.id_token, this.clientId, idTokenClaims.tid || "");
5406
5417
  cachedAccount = AccountEntity.createAccount({
5407
5418
  homeAccountId: this.homeAccountIdentifier,
5408
- idTokenClaims: idTokenObj.claims,
5419
+ idTokenClaims: idTokenClaims,
5409
5420
  clientInfo: serverTokenResponse.client_info,
5410
5421
  cloudGraphHostName: authCodePayload?.cloud_graph_host_name,
5411
5422
  msGraphHost: authCodePayload?.msgraph_host,
@@ -5413,7 +5424,7 @@ class ResponseHandler {
5413
5424
  }
5414
5425
  // AccessToken
5415
5426
  let cachedAccessToken = null;
5416
- if (!StringUtils.isEmpty(serverTokenResponse.access_token)) {
5427
+ if (serverTokenResponse.access_token) {
5417
5428
  // If scopes not returned in server response, use request scopes
5418
5429
  const responseScopes = serverTokenResponse.scope
5419
5430
  ? ScopeSet.fromString(serverTokenResponse.scope)
@@ -5437,18 +5448,16 @@ class ResponseHandler {
5437
5448
  ? reqTimestamp + refreshIn
5438
5449
  : undefined;
5439
5450
  // non AAD scenarios can have empty realm
5440
- cachedAccessToken = AccessTokenEntity.createAccessTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.access_token || Constants.EMPTY_STRING, this.clientId, idTokenObj
5441
- ? idTokenObj.claims.tid || Constants.EMPTY_STRING
5442
- : authority.tenant, responseScopes.printScopes(), tokenExpirationSeconds, extendedTokenExpirationSeconds, this.cryptoObj, refreshOnSeconds, serverTokenResponse.token_type, userAssertionHash, serverTokenResponse.key_id, request.claims, request.requestedClaimsHash);
5451
+ cachedAccessToken = AccessTokenEntity.createAccessTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.access_token || Constants.EMPTY_STRING, this.clientId, idTokenClaims?.tid || authority.tenant, responseScopes.printScopes(), tokenExpirationSeconds, extendedTokenExpirationSeconds, this.cryptoObj, refreshOnSeconds, serverTokenResponse.token_type, userAssertionHash, serverTokenResponse.key_id, request.claims, request.requestedClaimsHash);
5443
5452
  }
5444
5453
  // refreshToken
5445
5454
  let cachedRefreshToken = null;
5446
- if (!StringUtils.isEmpty(serverTokenResponse.refresh_token)) {
5455
+ if (serverTokenResponse.refresh_token) {
5447
5456
  cachedRefreshToken = RefreshTokenEntity.createRefreshTokenEntity(this.homeAccountIdentifier, env, serverTokenResponse.refresh_token || Constants.EMPTY_STRING, this.clientId, serverTokenResponse.foci, userAssertionHash);
5448
5457
  }
5449
5458
  // appMetadata
5450
5459
  let cachedAppMetadata = null;
5451
- if (!StringUtils.isEmpty(serverTokenResponse.foci)) {
5460
+ if (serverTokenResponse.foci) {
5452
5461
  cachedAppMetadata = AppMetadataEntity.createAppMetadataEntity(this.clientId, env, serverTokenResponse.foci);
5453
5462
  }
5454
5463
  return new CacheRecord(cachedAccount, cachedIdToken, cachedAccessToken, cachedRefreshToken, cachedAppMetadata);
@@ -5463,11 +5472,12 @@ class ResponseHandler {
5463
5472
  * @param fromTokenCache
5464
5473
  * @param stateString
5465
5474
  */
5466
- static async generateAuthenticationResult(cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenObj, requestState, serverTokenResponse, requestId) {
5475
+ static async generateAuthenticationResult(cryptoObj, authority, cacheRecord, fromTokenCache, request, idTokenClaims, requestState, serverTokenResponse, requestId) {
5467
5476
  let accessToken = Constants.EMPTY_STRING;
5468
5477
  let responseScopes = [];
5469
5478
  let expiresOn = null;
5470
5479
  let extExpiresOn;
5480
+ let refreshOn;
5471
5481
  let familyId = Constants.EMPTY_STRING;
5472
5482
  if (cacheRecord.accessToken) {
5473
5483
  if (cacheRecord.accessToken.tokenType === AuthenticationScheme.POP) {
@@ -5484,17 +5494,18 @@ class ResponseHandler {
5484
5494
  responseScopes = ScopeSet.fromString(cacheRecord.accessToken.target).asArray();
5485
5495
  expiresOn = new Date(Number(cacheRecord.accessToken.expiresOn) * 1000);
5486
5496
  extExpiresOn = new Date(Number(cacheRecord.accessToken.extendedExpiresOn) * 1000);
5497
+ if (cacheRecord.accessToken.refreshOn) {
5498
+ refreshOn = new Date(Number(cacheRecord.accessToken.refreshOn) * 1000);
5499
+ }
5487
5500
  }
5488
5501
  if (cacheRecord.appMetadata) {
5489
5502
  familyId =
5490
5503
  cacheRecord.appMetadata.familyId === THE_FAMILY_ID
5491
5504
  ? THE_FAMILY_ID
5492
- : Constants.EMPTY_STRING;
5505
+ : "";
5493
5506
  }
5494
- const uid = idTokenObj?.claims.oid ||
5495
- idTokenObj?.claims.sub ||
5496
- Constants.EMPTY_STRING;
5497
- const tid = idTokenObj?.claims.tid || Constants.EMPTY_STRING;
5507
+ const uid = idTokenClaims?.oid || idTokenClaims?.sub || "";
5508
+ const tid = idTokenClaims?.tid || "";
5498
5509
  // for hybrid + native bridge enablement, send back the native account Id
5499
5510
  if (serverTokenResponse?.spa_accountid && !!cacheRecord.account) {
5500
5511
  cacheRecord.account.nativeAccountId =
@@ -5508,14 +5519,15 @@ class ResponseHandler {
5508
5519
  account: cacheRecord.account
5509
5520
  ? cacheRecord.account.getAccountInfo()
5510
5521
  : null,
5511
- idToken: idTokenObj ? idTokenObj.rawToken : Constants.EMPTY_STRING,
5512
- idTokenClaims: idTokenObj ? idTokenObj.claims : {},
5522
+ idToken: cacheRecord?.idToken?.secret || "",
5523
+ idTokenClaims: idTokenClaims || {},
5513
5524
  accessToken: accessToken,
5514
5525
  fromCache: fromTokenCache,
5515
5526
  expiresOn: expiresOn,
5527
+ extExpiresOn: extExpiresOn,
5528
+ refreshOn: refreshOn,
5516
5529
  correlationId: request.correlationId,
5517
5530
  requestId: requestId || Constants.EMPTY_STRING,
5518
- extExpiresOn: extExpiresOn,
5519
5531
  familyId: familyId,
5520
5532
  tokenType: cacheRecord.accessToken?.tokenType || Constants.EMPTY_STRING,
5521
5533
  state: requestState
@@ -5530,6 +5542,92 @@ class ResponseHandler {
5530
5542
  }
5531
5543
  }
5532
5544
 
5545
+ /*
5546
+ * Copyright (c) Microsoft Corporation. All rights reserved.
5547
+ * Licensed under the MIT License.
5548
+ */
5549
+ /**
5550
+ * Wraps a function with a performance measurement.
5551
+ * Usage: invoke(functionToCall, performanceClient, "EventName", "correlationId")(...argsToPassToFunction)
5552
+ * @param callback
5553
+ * @param eventName
5554
+ * @param logger
5555
+ * @param telemetryClient
5556
+ * @param correlationId
5557
+ * @returns
5558
+ * @internal
5559
+ */
5560
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5561
+ const invoke = (callback, eventName, logger, telemetryClient, correlationId) => {
5562
+ return (...args) => {
5563
+ logger.trace(`Executing function ${eventName}`);
5564
+ const inProgressEvent = telemetryClient?.startMeasurement(eventName, correlationId);
5565
+ telemetryClient?.setPreQueueTime(eventName, correlationId);
5566
+ try {
5567
+ const result = callback(...args);
5568
+ inProgressEvent?.end({
5569
+ success: true,
5570
+ });
5571
+ logger.trace(`Returning result from ${eventName}`);
5572
+ return result;
5573
+ }
5574
+ catch (e) {
5575
+ logger.trace(`Error occurred in ${eventName}`);
5576
+ try {
5577
+ logger.trace(JSON.stringify(e));
5578
+ }
5579
+ catch (e) {
5580
+ logger.trace("Unable to print error message.");
5581
+ }
5582
+ inProgressEvent?.end({
5583
+ success: false,
5584
+ });
5585
+ throw e;
5586
+ }
5587
+ };
5588
+ };
5589
+ /**
5590
+ * Wraps an async function with a performance measurement.
5591
+ * Usage: invokeAsync(functionToCall, performanceClient, "EventName", "correlationId")(...argsToPassToFunction)
5592
+ * @param callback
5593
+ * @param eventName
5594
+ * @param logger
5595
+ * @param telemetryClient
5596
+ * @param correlationId
5597
+ * @returns
5598
+ * @internal
5599
+ *
5600
+ */
5601
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5602
+ const invokeAsync = (callback, eventName, logger, telemetryClient, correlationId) => {
5603
+ return (...args) => {
5604
+ logger.trace(`Executing function ${eventName}`);
5605
+ const inProgressEvent = telemetryClient?.startMeasurement(eventName, correlationId);
5606
+ telemetryClient?.setPreQueueTime(eventName, correlationId);
5607
+ return callback(...args)
5608
+ .then((response) => {
5609
+ logger.trace(`Returning result from ${eventName}`);
5610
+ inProgressEvent?.end({
5611
+ success: true,
5612
+ });
5613
+ return response;
5614
+ })
5615
+ .catch((e) => {
5616
+ logger.trace(`Error occurred in ${eventName}`);
5617
+ try {
5618
+ logger.trace(JSON.stringify(e));
5619
+ }
5620
+ catch (e) {
5621
+ logger.trace("Unable to print error message.");
5622
+ }
5623
+ inProgressEvent?.end({
5624
+ success: false,
5625
+ });
5626
+ throw e;
5627
+ });
5628
+ };
5629
+ };
5630
+
5533
5631
  /*
5534
5632
  * Copyright (c) Microsoft Corporation. All rights reserved.
5535
5633
  * Licensed under the MIT License.
@@ -5558,8 +5656,7 @@ class AuthorizationCodeClient extends BaseClient {
5558
5656
  */
5559
5657
  async getAuthCodeUrl(request) {
5560
5658
  this.performanceClient?.addQueueMeasurement(PerformanceEvents.GetAuthCodeUrl, request.correlationId);
5561
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
5562
- const queryString = await this.createAuthCodeUrlQueryString(request);
5659
+ const queryString = await invokeAsync(this.createAuthCodeUrlQueryString.bind(this), PerformanceEvents.AuthClientCreateQueryString, this.logger, this.performanceClient, request.correlationId)(request);
5563
5660
  return UrlString.appendQueryString(this.authority.authorizationEndpoint, queryString);
5564
5661
  }
5565
5662
  /**
@@ -5568,46 +5665,18 @@ class AuthorizationCodeClient extends BaseClient {
5568
5665
  * @param request
5569
5666
  */
5570
5667
  async acquireToken(request, authCodePayload) {
5571
- if (!request || !request.code) {
5668
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientAcquireToken, request.correlationId);
5669
+ if (!request.code) {
5572
5670
  throw ClientAuthError.createTokenRequestCannotBeMadeError();
5573
5671
  }
5574
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientAcquireToken, request.correlationId);
5575
- const atsMeasurement = this.performanceClient?.startMeasurement(
5576
- // @ts-ignore
5577
- "AuthCodeClientAcquireToken", request.correlationId);
5578
- this.logger.info("in acquireToken call in auth-code client");
5579
5672
  const reqTimestamp = TimeUtils.nowSeconds();
5580
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
5581
- const response = await this.executeTokenRequest(this.authority, request);
5673
+ const response = await invokeAsync(this.executeTokenRequest.bind(this), PerformanceEvents.AuthClientExecuteTokenRequest, this.logger, this.performanceClient, request.correlationId)(this.authority, request);
5582
5674
  // Retrieve requestId from response headers
5583
5675
  const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID];
5584
- const httpVerAuthority = response.headers?.[HeaderNames.X_MS_HTTP_VERSION];
5585
- if (httpVerAuthority) {
5586
- atsMeasurement?.add({
5587
- httpVerAuthority,
5588
- });
5589
- }
5590
5676
  const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin, this.performanceClient);
5591
5677
  // Validate response. This function throws a server error if an error is returned by the server.
5592
5678
  responseHandler.validateTokenResponse(response.body);
5593
- this.performanceClient?.setPreQueueTime(PerformanceEvents.HandleServerTokenResponse, request.correlationId);
5594
- return responseHandler
5595
- .handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, authCodePayload, undefined, undefined, undefined, requestId)
5596
- .then((result) => {
5597
- atsMeasurement?.end({
5598
- success: true,
5599
- });
5600
- return result;
5601
- })
5602
- .catch((error) => {
5603
- this.logger.verbose("Error in fetching token in ACC", request.correlationId);
5604
- atsMeasurement?.end({
5605
- errorCode: error.errorCode,
5606
- subErrorCode: error.subError,
5607
- success: false,
5608
- });
5609
- throw error;
5610
- });
5679
+ return invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, this.logger, this.performanceClient, request.correlationId)(response.body, this.authority, reqTimestamp, request, authCodePayload, undefined, undefined, undefined, requestId);
5611
5680
  }
5612
5681
  /**
5613
5682
  * Handles the hash fragment response from public client code request. Returns a code response used by
@@ -5652,10 +5721,9 @@ class AuthorizationCodeClient extends BaseClient {
5652
5721
  */
5653
5722
  async executeTokenRequest(authority, request) {
5654
5723
  this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
5655
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
5656
5724
  const queryParametersString = this.createTokenQueryParameters(request);
5657
5725
  const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
5658
- const requestBody = await this.createTokenRequestBody(request);
5726
+ const requestBody = await invokeAsync(this.createTokenRequestBody.bind(this), PerformanceEvents.AuthClientCreateTokenRequestBody, this.logger, this.performanceClient, request.correlationId)(request);
5659
5727
  let ccsCredential = undefined;
5660
5728
  if (request.clientInfo) {
5661
5729
  try {
@@ -5681,7 +5749,7 @@ class AuthorizationCodeClient extends BaseClient {
5681
5749
  shrClaims: request.shrClaims,
5682
5750
  sshKid: request.sshKid,
5683
5751
  };
5684
- return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint);
5752
+ return invokeAsync(this.executePostToTokenEndpoint.bind(this), PerformanceEvents.BaseClientExecutePostToTokenEndpoint, this.logger, this.performanceClient, request.correlationId)(endpoint, requestBody, headers, thumbprint, request.correlationId);
5685
5753
  }
5686
5754
  /**
5687
5755
  * Generates a map for all the params to be sent to the service
@@ -5910,7 +5978,7 @@ class AuthorizationCodeClient extends BaseClient {
5910
5978
  if (request.state) {
5911
5979
  parameterBuilder.addState(request.state);
5912
5980
  }
5913
- if (!StringUtils.isEmpty(request.claims) ||
5981
+ if (request.claims ||
5914
5982
  (this.config.authOptions.clientCapabilities &&
5915
5983
  this.config.authOptions.clientCapabilities.length > 0)) {
5916
5984
  parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
@@ -5988,15 +6056,6 @@ class RefreshTokenClient extends BaseClient {
5988
6056
  const reqTimestamp = TimeUtils.nowSeconds();
5989
6057
  this.performanceClient?.setPreQueueTime(PerformanceEvents.RefreshTokenClientExecuteTokenRequest, request.correlationId);
5990
6058
  const response = await this.executeTokenRequest(request, this.authority);
5991
- const httpVerToken = response.headers?.[HeaderNames.X_MS_HTTP_VERSION];
5992
- atsMeasurement?.add({
5993
- refreshTokenSize: response.body.refresh_token?.length || 0,
5994
- });
5995
- if (httpVerToken) {
5996
- atsMeasurement?.add({
5997
- httpVerToken,
5998
- });
5999
- }
6000
6059
  // Retrieve requestId from response headers
6001
6060
  const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID];
6002
6061
  const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin);
@@ -6119,7 +6178,7 @@ class RefreshTokenClient extends BaseClient {
6119
6178
  shrClaims: request.shrClaims,
6120
6179
  sshKid: request.sshKid,
6121
6180
  };
6122
- return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint)
6181
+ return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint, request.correlationId)
6123
6182
  .then((result) => {
6124
6183
  acquireTokenMeasurement?.end({
6125
6184
  success: true,
@@ -6296,19 +6355,19 @@ class SilentFlowClient extends BaseClient {
6296
6355
  * @param cacheRecord
6297
6356
  */
6298
6357
  async generateResultFromCacheRecord(cacheRecord, request) {
6299
- let idTokenObj;
6358
+ let idTokenClaims;
6300
6359
  if (cacheRecord.idToken) {
6301
- idTokenObj = new AuthToken(cacheRecord.idToken.secret, this.config.cryptoInterface);
6360
+ idTokenClaims = extractTokenClaims(cacheRecord.idToken.secret, this.config.cryptoInterface.base64Decode);
6302
6361
  }
6303
6362
  // token max_age check
6304
6363
  if (request.maxAge || request.maxAge === 0) {
6305
- const authTime = idTokenObj?.claims.auth_time;
6364
+ const authTime = idTokenClaims?.auth_time;
6306
6365
  if (!authTime) {
6307
6366
  throw ClientAuthError.createAuthTimeNotFoundError();
6308
6367
  }
6309
- AuthToken.checkMaxAge(authTime, request.maxAge);
6368
+ checkMaxAge(authTime, request.maxAge);
6310
6369
  }
6311
- return await ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, cacheRecord, true, request, idTokenObj);
6370
+ return await ResponseHandler.generateAuthenticationResult(this.cryptoUtils, this.authority, cacheRecord, true, request, idTokenClaims);
6312
6371
  }
6313
6372
  }
6314
6373
 
@@ -8220,7 +8279,7 @@ class AuthorityFactory {
8220
8279
  */
8221
8280
  static createInstance(authorityUrl, networkInterface, cacheManager, authorityOptions, logger, performanceClient, correlationId) {
8222
8281
  // Throw error if authority url is empty
8223
- if (StringUtils.isEmpty(authorityUrl)) {
8282
+ if (!authorityUrl) {
8224
8283
  throw ClientConfigurationError.createUrlEmptyError();
8225
8284
  }
8226
8285
  return new Authority(authorityUrl, networkInterface, cacheManager, authorityOptions, logger, performanceClient, correlationId);
@@ -8505,10 +8564,10 @@ class ServerTelemetryManager {
8505
8564
  lastRequests.failedRequests.push(this.apiId, this.correlationId);
8506
8565
  if (error instanceof Error && !!error && error.toString()) {
8507
8566
  if (error instanceof AuthError) {
8508
- if (!StringUtils.isEmpty(error.subError)) {
8567
+ if (error.subError) {
8509
8568
  lastRequests.errors.push(error.subError);
8510
8569
  }
8511
- else if (!StringUtils.isEmpty(error.errorCode)) {
8570
+ else if (error.errorCode) {
8512
8571
  lastRequests.errors.push(error.errorCode);
8513
8572
  }
8514
8573
  else {
@@ -9050,10 +9109,30 @@ class StubPerformanceMeasurement {
9050
9109
  return null;
9051
9110
  }
9052
9111
  }
9053
- class StubPerformanceClient extends PerformanceClient {
9112
+ class StubPerformanceClient {
9054
9113
  generateId() {
9055
9114
  return "callback-id";
9056
9115
  }
9116
+ startMeasurement(measureName, correlationId) {
9117
+ return {
9118
+ end: () => null,
9119
+ discard: () => { },
9120
+ add: () => { },
9121
+ increment: () => { },
9122
+ event: {
9123
+ eventId: this.generateId(),
9124
+ status: PerformanceEventStatus.InProgress,
9125
+ authority: "",
9126
+ libraryName: "",
9127
+ libraryVersion: "",
9128
+ clientId: "",
9129
+ name: measureName,
9130
+ startTimeMs: Date.now(),
9131
+ correlationId: correlationId || "",
9132
+ },
9133
+ measurement: new StubPerformanceMeasurement(),
9134
+ };
9135
+ }
9057
9136
  startPerformanceMeasurement() {
9058
9137
  return new StubPerformanceMeasurement();
9059
9138
  }
@@ -9130,7 +9209,7 @@ exports.DefaultStorageClass = DefaultStorageClass;
9130
9209
  exports.Errors = Errors;
9131
9210
  exports.GrantType = GrantType;
9132
9211
  exports.HeaderNames = HeaderNames;
9133
- exports.IdToken = AuthToken;
9212
+ exports.HttpStatus = HttpStatus;
9134
9213
  exports.IdTokenEntity = IdTokenEntity;
9135
9214
  exports.IntFields = IntFields;
9136
9215
  exports.InteractionRequiredAuthError = InteractionRequiredAuthError;
@@ -9173,5 +9252,7 @@ exports.TokenCacheContext = TokenCacheContext;
9173
9252
  exports.UrlString = UrlString;
9174
9253
  exports.buildClientInfo = buildClientInfo;
9175
9254
  exports.buildClientInfoFromHomeAccountId = buildClientInfoFromHomeAccountId;
9255
+ exports.invoke = invoke;
9256
+ exports.invokeAsync = invokeAsync;
9176
9257
  exports.version = version;
9177
9258
  //# sourceMappingURL=index.cjs.map