@azure/msal-common 14.0.1 → 14.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/dist/account/AuthToken.d.ts +14 -17
  2. package/dist/account/AuthToken.d.ts.map +1 -1
  3. package/dist/account/AuthToken.mjs +48 -39
  4. package/dist/account/AuthToken.mjs.map +1 -1
  5. package/dist/account/CcsCredential.mjs +1 -1
  6. package/dist/account/CcsCredential.mjs.map +1 -1
  7. package/dist/account/ClientInfo.d.ts.map +1 -1
  8. package/dist/account/ClientInfo.mjs +3 -4
  9. package/dist/account/ClientInfo.mjs.map +1 -1
  10. package/dist/authority/Authority.d.ts +1 -0
  11. package/dist/authority/Authority.d.ts.map +1 -1
  12. package/dist/authority/Authority.mjs +4 -2
  13. package/dist/authority/Authority.mjs.map +1 -1
  14. package/dist/authority/AuthorityFactory.d.ts +1 -0
  15. package/dist/authority/AuthorityFactory.d.ts.map +1 -1
  16. package/dist/authority/AuthorityFactory.mjs +3 -3
  17. package/dist/authority/AuthorityFactory.mjs.map +1 -1
  18. package/dist/authority/AuthorityMetadata.mjs +1 -1
  19. package/dist/authority/AuthorityMetadata.mjs.map +1 -1
  20. package/dist/authority/AuthorityOptions.mjs +1 -1
  21. package/dist/authority/AuthorityOptions.mjs.map +1 -1
  22. package/dist/authority/AuthorityType.mjs +1 -1
  23. package/dist/authority/AuthorityType.mjs.map +1 -1
  24. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs +1 -1
  25. package/dist/authority/CloudInstanceDiscoveryErrorResponse.mjs.map +1 -1
  26. package/dist/authority/CloudInstanceDiscoveryResponse.mjs +1 -1
  27. package/dist/authority/CloudInstanceDiscoveryResponse.mjs.map +1 -1
  28. package/dist/authority/OpenIdConfigResponse.mjs +1 -1
  29. package/dist/authority/OpenIdConfigResponse.mjs.map +1 -1
  30. package/dist/authority/ProtocolMode.mjs +1 -1
  31. package/dist/authority/ProtocolMode.mjs.map +1 -1
  32. package/dist/authority/RegionDiscovery.mjs +1 -1
  33. package/dist/authority/RegionDiscovery.mjs.map +1 -1
  34. package/dist/cache/CacheManager.d.ts +2 -0
  35. package/dist/cache/CacheManager.d.ts.map +1 -1
  36. package/dist/cache/CacheManager.mjs +7 -5
  37. package/dist/cache/CacheManager.mjs.map +1 -1
  38. package/dist/cache/entities/AccessTokenEntity.d.ts.map +1 -1
  39. package/dist/cache/entities/AccessTokenEntity.mjs +4 -7
  40. package/dist/cache/entities/AccessTokenEntity.mjs.map +1 -1
  41. package/dist/cache/entities/AccountEntity.d.ts +1 -0
  42. package/dist/cache/entities/AccountEntity.d.ts.map +1 -1
  43. package/dist/cache/entities/AccountEntity.mjs +3 -4
  44. package/dist/cache/entities/AccountEntity.mjs.map +1 -1
  45. package/dist/cache/entities/AppMetadataEntity.mjs +1 -1
  46. package/dist/cache/entities/AppMetadataEntity.mjs.map +1 -1
  47. package/dist/cache/entities/AuthorityMetadataEntity.d.ts +1 -0
  48. package/dist/cache/entities/AuthorityMetadataEntity.d.ts.map +1 -1
  49. package/dist/cache/entities/AuthorityMetadataEntity.mjs +2 -1
  50. package/dist/cache/entities/AuthorityMetadataEntity.mjs.map +1 -1
  51. package/dist/cache/entities/CacheRecord.d.ts +1 -0
  52. package/dist/cache/entities/CacheRecord.d.ts.map +1 -1
  53. package/dist/cache/entities/CacheRecord.mjs +2 -1
  54. package/dist/cache/entities/CacheRecord.mjs.map +1 -1
  55. package/dist/cache/entities/CredentialEntity.mjs +1 -1
  56. package/dist/cache/entities/CredentialEntity.mjs.map +1 -1
  57. package/dist/cache/entities/IdTokenEntity.mjs +1 -1
  58. package/dist/cache/entities/IdTokenEntity.mjs.map +1 -1
  59. package/dist/cache/entities/RefreshTokenEntity.mjs +1 -1
  60. package/dist/cache/entities/RefreshTokenEntity.mjs.map +1 -1
  61. package/dist/cache/entities/ServerTelemetryEntity.mjs +1 -1
  62. package/dist/cache/entities/ServerTelemetryEntity.mjs.map +1 -1
  63. package/dist/cache/entities/ThrottlingEntity.mjs +1 -1
  64. package/dist/cache/entities/ThrottlingEntity.mjs.map +1 -1
  65. package/dist/cache/persistence/TokenCacheContext.mjs +1 -1
  66. package/dist/cache/persistence/TokenCacheContext.mjs.map +1 -1
  67. package/dist/cache/utils/CacheTypes.d.ts +7 -0
  68. package/dist/cache/utils/CacheTypes.d.ts.map +1 -1
  69. package/dist/client/AuthorizationCodeClient.d.ts +1 -0
  70. package/dist/client/AuthorizationCodeClient.d.ts.map +1 -1
  71. package/dist/client/AuthorizationCodeClient.mjs +11 -39
  72. package/dist/client/AuthorizationCodeClient.mjs.map +1 -1
  73. package/dist/client/BaseClient.d.ts +2 -1
  74. package/dist/client/BaseClient.d.ts.map +1 -1
  75. package/dist/client/BaseClient.mjs +9 -2
  76. package/dist/client/BaseClient.mjs.map +1 -1
  77. package/dist/client/RefreshTokenClient.d.ts +1 -0
  78. package/dist/client/RefreshTokenClient.d.ts.map +1 -1
  79. package/dist/client/RefreshTokenClient.mjs +3 -11
  80. package/dist/client/RefreshTokenClient.mjs.map +1 -1
  81. package/dist/client/SilentFlowClient.d.ts +1 -0
  82. package/dist/client/SilentFlowClient.d.ts.map +1 -1
  83. package/dist/client/SilentFlowClient.mjs +8 -7
  84. package/dist/client/SilentFlowClient.mjs.map +1 -1
  85. package/dist/config/ClientConfiguration.d.ts +2 -0
  86. package/dist/config/ClientConfiguration.d.ts.map +1 -1
  87. package/dist/config/ClientConfiguration.mjs +1 -1
  88. package/dist/config/ClientConfiguration.mjs.map +1 -1
  89. package/dist/crypto/ICrypto.mjs +1 -1
  90. package/dist/crypto/ICrypto.mjs.map +1 -1
  91. package/dist/crypto/JoseHeader.d.ts +1 -0
  92. package/dist/crypto/JoseHeader.d.ts.map +1 -1
  93. package/dist/crypto/JoseHeader.mjs +2 -1
  94. package/dist/crypto/JoseHeader.mjs.map +1 -1
  95. package/dist/crypto/PopTokenGenerator.d.ts +1 -0
  96. package/dist/crypto/PopTokenGenerator.d.ts.map +1 -1
  97. package/dist/crypto/PopTokenGenerator.mjs +2 -1
  98. package/dist/crypto/PopTokenGenerator.mjs.map +1 -1
  99. package/dist/error/AuthError.mjs +1 -1
  100. package/dist/error/AuthError.mjs.map +1 -1
  101. package/dist/error/ClientAuthError.mjs +1 -1
  102. package/dist/error/ClientAuthError.mjs.map +1 -1
  103. package/dist/error/ClientConfigurationError.mjs +1 -1
  104. package/dist/error/ClientConfigurationError.mjs.map +1 -1
  105. package/dist/error/InteractionRequiredAuthError.mjs +1 -1
  106. package/dist/error/InteractionRequiredAuthError.mjs.map +1 -1
  107. package/dist/error/JoseHeaderError.mjs +1 -1
  108. package/dist/error/JoseHeaderError.mjs.map +1 -1
  109. package/dist/error/ServerError.mjs +1 -1
  110. package/dist/error/ServerError.mjs.map +1 -1
  111. package/dist/index.cjs +1926 -1826
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.d.ts +4 -3
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.mjs +5 -3
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/logger/Logger.d.ts.map +1 -1
  118. package/dist/logger/Logger.mjs +2 -12
  119. package/dist/logger/Logger.mjs.map +1 -1
  120. package/dist/network/INetworkModule.mjs +1 -1
  121. package/dist/network/INetworkModule.mjs.map +1 -1
  122. package/dist/network/NetworkManager.d.ts +1 -0
  123. package/dist/network/NetworkManager.d.ts.map +1 -1
  124. package/dist/network/NetworkManager.mjs +2 -1
  125. package/dist/network/NetworkManager.mjs.map +1 -1
  126. package/dist/network/ThrottlingUtils.d.ts +1 -0
  127. package/dist/network/ThrottlingUtils.d.ts.map +1 -1
  128. package/dist/network/ThrottlingUtils.mjs +2 -1
  129. package/dist/network/ThrottlingUtils.mjs.map +1 -1
  130. package/dist/packageMetadata.d.ts +1 -1
  131. package/dist/packageMetadata.mjs +2 -2
  132. package/dist/packageMetadata.mjs.map +1 -1
  133. package/dist/request/AuthenticationHeaderParser.mjs +1 -1
  134. package/dist/request/AuthenticationHeaderParser.mjs.map +1 -1
  135. package/dist/request/RequestParameterBuilder.d.ts +1 -0
  136. package/dist/request/RequestParameterBuilder.d.ts.map +1 -1
  137. package/dist/request/RequestParameterBuilder.mjs +7 -7
  138. package/dist/request/RequestParameterBuilder.mjs.map +1 -1
  139. package/dist/request/RequestValidator.d.ts.map +1 -1
  140. package/dist/request/RequestValidator.mjs +4 -6
  141. package/dist/request/RequestValidator.mjs.map +1 -1
  142. package/dist/request/ScopeSet.mjs +4 -4
  143. package/dist/request/ScopeSet.mjs.map +1 -1
  144. package/dist/response/AuthenticationResult.d.ts +3 -1
  145. package/dist/response/AuthenticationResult.d.ts.map +1 -1
  146. package/dist/response/ResponseHandler.d.ts +5 -3
  147. package/dist/response/ResponseHandler.d.ts.map +1 -1
  148. package/dist/response/ResponseHandler.mjs +58 -39
  149. package/dist/response/ResponseHandler.mjs.map +1 -1
  150. package/dist/response/ServerAuthorizationTokenResponse.d.ts +2 -0
  151. package/dist/response/ServerAuthorizationTokenResponse.d.ts.map +1 -1
  152. package/dist/telemetry/performance/IPerformanceClient.d.ts +4 -4
  153. package/dist/telemetry/performance/IPerformanceClient.d.ts.map +1 -1
  154. package/dist/telemetry/performance/PerformanceClient.d.ts +2 -2
  155. package/dist/telemetry/performance/PerformanceClient.d.ts.map +1 -1
  156. package/dist/telemetry/performance/PerformanceClient.mjs +1 -1
  157. package/dist/telemetry/performance/PerformanceClient.mjs.map +1 -1
  158. package/dist/telemetry/performance/PerformanceEvent.d.ts +8 -1
  159. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  160. package/dist/telemetry/performance/PerformanceEvent.mjs +9 -1
  161. package/dist/telemetry/performance/PerformanceEvent.mjs.map +1 -1
  162. package/dist/telemetry/performance/StubPerformanceClient.d.ts +3 -3
  163. package/dist/telemetry/performance/StubPerformanceClient.d.ts.map +1 -1
  164. package/dist/telemetry/performance/StubPerformanceClient.mjs +23 -3
  165. package/dist/telemetry/performance/StubPerformanceClient.mjs.map +1 -1
  166. package/dist/telemetry/server/ServerTelemetryManager.d.ts +1 -0
  167. package/dist/telemetry/server/ServerTelemetryManager.d.ts.map +1 -1
  168. package/dist/telemetry/server/ServerTelemetryManager.mjs +4 -4
  169. package/dist/telemetry/server/ServerTelemetryManager.mjs.map +1 -1
  170. package/dist/url/UrlString.d.ts.map +1 -1
  171. package/dist/url/UrlString.mjs +10 -12
  172. package/dist/url/UrlString.mjs.map +1 -1
  173. package/dist/utils/Constants.d.ts +10 -0
  174. package/dist/utils/Constants.d.ts.map +1 -1
  175. package/dist/utils/Constants.mjs +11 -2
  176. package/dist/utils/Constants.mjs.map +1 -1
  177. package/dist/utils/FunctionWrappers.d.ts +28 -0
  178. package/dist/utils/FunctionWrappers.d.ts.map +1 -0
  179. package/dist/utils/FunctionWrappers.mjs +90 -0
  180. package/dist/utils/FunctionWrappers.mjs.map +1 -0
  181. package/dist/utils/ProtocolUtils.d.ts.map +1 -1
  182. package/dist/utils/ProtocolUtils.mjs +4 -7
  183. package/dist/utils/ProtocolUtils.mjs.map +1 -1
  184. package/dist/utils/StringUtils.d.ts +0 -13
  185. package/dist/utils/StringUtils.d.ts.map +1 -1
  186. package/dist/utils/StringUtils.mjs +3 -34
  187. package/dist/utils/StringUtils.mjs.map +1 -1
  188. package/dist/utils/TimeUtils.mjs +1 -1
  189. package/dist/utils/TimeUtils.mjs.map +1 -1
  190. package/package.json +6 -4
  191. package/src/account/AccountInfo.ts +44 -0
  192. package/src/account/AuthToken.ts +70 -0
  193. package/src/account/CcsCredential.ts +16 -0
  194. package/src/account/ClientCredentials.ts +20 -0
  195. package/src/account/ClientInfo.ts +64 -0
  196. package/src/account/TokenClaims.ts +70 -0
  197. package/src/authority/Authority.ts +1225 -0
  198. package/src/authority/AuthorityFactory.ts +106 -0
  199. package/src/authority/AuthorityMetadata.ts +953 -0
  200. package/src/authority/AuthorityOptions.ts +40 -0
  201. package/src/authority/AuthorityType.ts +15 -0
  202. package/src/authority/AzureRegion.ts +7 -0
  203. package/src/authority/AzureRegionConfiguration.ts +16 -0
  204. package/src/authority/CloudDiscoveryMetadata.ts +10 -0
  205. package/src/authority/CloudInstanceDiscoveryErrorResponse.ts +26 -0
  206. package/src/authority/CloudInstanceDiscoveryResponse.ts +21 -0
  207. package/src/authority/ImdsOptions.ts +10 -0
  208. package/src/authority/OIDCOptions.ts +14 -0
  209. package/src/authority/OpenIdConfigResponse.ts +24 -0
  210. package/src/authority/ProtocolMode.ts +13 -0
  211. package/src/authority/RegionDiscovery.ts +193 -0
  212. package/src/authority/RegionDiscoveryMetadata.ts +15 -0
  213. package/src/broker/nativeBroker/INativeBrokerPlugin.ts +29 -0
  214. package/src/cache/CacheManager.ts +1619 -0
  215. package/src/cache/entities/AccessTokenEntity.ts +162 -0
  216. package/src/cache/entities/AccountEntity.ts +309 -0
  217. package/src/cache/entities/AppMetadataEntity.ts +91 -0
  218. package/src/cache/entities/AuthorityMetadataEntity.ts +112 -0
  219. package/src/cache/entities/CacheRecord.ts +33 -0
  220. package/src/cache/entities/CredentialEntity.ts +215 -0
  221. package/src/cache/entities/IdTokenEntity.ts +74 -0
  222. package/src/cache/entities/RefreshTokenEntity.ts +78 -0
  223. package/src/cache/entities/ServerTelemetryEntity.ts +38 -0
  224. package/src/cache/entities/ThrottlingEntity.ts +36 -0
  225. package/src/cache/interface/ICacheManager.ts +218 -0
  226. package/src/cache/interface/ICachePlugin.ts +11 -0
  227. package/src/cache/interface/ISerializableTokenCache.ts +9 -0
  228. package/src/cache/persistence/TokenCacheContext.ts +39 -0
  229. package/src/cache/utils/CacheTypes.ts +93 -0
  230. package/src/client/AuthorizationCodeClient.ts +714 -0
  231. package/src/client/BaseClient.ts +205 -0
  232. package/src/client/RefreshTokenClient.ts +442 -0
  233. package/src/client/SilentFlowClient.ts +186 -0
  234. package/src/config/AppTokenProvider.ts +47 -0
  235. package/src/config/ClientConfiguration.ts +287 -0
  236. package/src/crypto/ICrypto.ts +127 -0
  237. package/src/crypto/IGuidGenerator.ts +9 -0
  238. package/src/crypto/JoseHeader.ts +55 -0
  239. package/src/crypto/PopTokenGenerator.ts +155 -0
  240. package/src/crypto/SignedHttpRequest.ts +16 -0
  241. package/src/error/AuthError.ts +85 -0
  242. package/src/error/ClientAuthError.ts +738 -0
  243. package/src/error/ClientConfigurationError.ts +396 -0
  244. package/src/error/InteractionRequiredAuthError.ts +134 -0
  245. package/src/error/JoseHeaderError.ts +52 -0
  246. package/src/error/ServerError.ts +18 -0
  247. package/src/index.ts +215 -0
  248. package/src/logger/Logger.ts +272 -0
  249. package/src/network/INetworkModule.ts +57 -0
  250. package/src/network/NetworkManager.ts +76 -0
  251. package/src/network/RequestThumbprint.ts +22 -0
  252. package/src/network/ThrottlingUtils.ts +156 -0
  253. package/src/packageMetadata.ts +3 -0
  254. package/src/request/AuthenticationHeaderParser.ts +89 -0
  255. package/src/request/BaseAuthRequest.ts +46 -0
  256. package/src/request/CommonAuthorizationCodeRequest.ts +33 -0
  257. package/src/request/CommonAuthorizationUrlRequest.ts +56 -0
  258. package/src/request/CommonClientCredentialRequest.ts +23 -0
  259. package/src/request/CommonDeviceCodeRequest.ts +31 -0
  260. package/src/request/CommonEndSessionRequest.ts +27 -0
  261. package/src/request/CommonOnBehalfOfRequest.ts +19 -0
  262. package/src/request/CommonRefreshTokenRequest.ts +25 -0
  263. package/src/request/CommonSilentFlowRequest.ts +24 -0
  264. package/src/request/CommonUsernamePasswordRequest.ts +23 -0
  265. package/src/request/NativeRequest.ts +25 -0
  266. package/src/request/NativeSignOutRequest.ts +10 -0
  267. package/src/request/RequestParameterBuilder.ts +606 -0
  268. package/src/request/RequestValidator.ts +103 -0
  269. package/src/request/ScopeSet.ts +230 -0
  270. package/src/request/StoreInCache.ts +16 -0
  271. package/src/response/AuthenticationResult.ts +47 -0
  272. package/src/response/AuthorizationCodePayload.ts +18 -0
  273. package/src/response/DeviceCodeResponse.ts +31 -0
  274. package/src/response/ExternalTokenResponse.ts +24 -0
  275. package/src/response/IMDSBadResponse.ts +9 -0
  276. package/src/response/ResponseHandler.ts +614 -0
  277. package/src/response/ServerAuthorizationCodeResponse.ts +33 -0
  278. package/src/response/ServerAuthorizationTokenResponse.ts +54 -0
  279. package/src/telemetry/performance/IPerformanceClient.ts +71 -0
  280. package/src/telemetry/performance/IPerformanceMeasurement.ts +10 -0
  281. package/src/telemetry/performance/PerformanceClient.ts +635 -0
  282. package/src/telemetry/performance/PerformanceEvent.ts +542 -0
  283. package/src/telemetry/performance/StubPerformanceClient.ts +101 -0
  284. package/src/telemetry/server/ServerTelemetryManager.ts +274 -0
  285. package/src/telemetry/server/ServerTelemetryRequest.ts +13 -0
  286. package/src/url/IUri.ts +17 -0
  287. package/src/url/UrlString.ts +363 -0
  288. package/src/utils/Constants.ts +436 -0
  289. package/src/utils/FunctionWrappers.ts +105 -0
  290. package/src/utils/MsalTypes.ts +9 -0
  291. package/src/utils/ProtocolUtils.ts +124 -0
  292. package/src/utils/StringUtils.ts +106 -0
  293. package/src/utils/TimeUtils.ts +51 -0
  294. package/dist/account/DecodedAuthToken.d.ts +0 -9
  295. package/dist/account/DecodedAuthToken.d.ts.map +0 -1
@@ -0,0 +1,436 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export const Constants = {
7
+ LIBRARY_NAME: "MSAL.JS",
8
+ SKU: "msal.js.common",
9
+ // Prefix for all library cache entries
10
+ CACHE_PREFIX: "msal",
11
+ // default authority
12
+ DEFAULT_AUTHORITY: "https://login.microsoftonline.com/common/",
13
+ DEFAULT_AUTHORITY_HOST: "login.microsoftonline.com",
14
+ DEFAULT_COMMON_TENANT: "common",
15
+ // ADFS String
16
+ ADFS: "adfs",
17
+ DSTS: "dstsv2",
18
+ // Default AAD Instance Discovery Endpoint
19
+ AAD_INSTANCE_DISCOVERY_ENDPT:
20
+ "https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=",
21
+ // CIAM URL
22
+ CIAM_AUTH_URL: ".ciamlogin.com",
23
+ AAD_TENANT_DOMAIN_SUFFIX: ".onmicrosoft.com",
24
+ // Resource delimiter - used for certain cache entries
25
+ RESOURCE_DELIM: "|",
26
+ // Placeholder for non-existent account ids/objects
27
+ NO_ACCOUNT: "NO_ACCOUNT",
28
+ // Claims
29
+ CLAIMS: "claims",
30
+ // Consumer UTID
31
+ CONSUMER_UTID: "9188040d-6c67-4c5b-b112-36a304b66dad",
32
+ // Default scopes
33
+ OPENID_SCOPE: "openid",
34
+ PROFILE_SCOPE: "profile",
35
+ OFFLINE_ACCESS_SCOPE: "offline_access",
36
+ EMAIL_SCOPE: "email",
37
+ // Default response type for authorization code flow
38
+ CODE_RESPONSE_TYPE: "code",
39
+ CODE_GRANT_TYPE: "authorization_code",
40
+ RT_GRANT_TYPE: "refresh_token",
41
+ FRAGMENT_RESPONSE_MODE: "fragment",
42
+ S256_CODE_CHALLENGE_METHOD: "S256",
43
+ URL_FORM_CONTENT_TYPE: "application/x-www-form-urlencoded;charset=utf-8",
44
+ AUTHORIZATION_PENDING: "authorization_pending",
45
+ NOT_DEFINED: "not_defined",
46
+ EMPTY_STRING: "",
47
+ NOT_APPLICABLE: "N/A",
48
+ FORWARD_SLASH: "/",
49
+ IMDS_ENDPOINT: "http://169.254.169.254/metadata/instance/compute/location",
50
+ IMDS_VERSION: "2020-06-01",
51
+ IMDS_TIMEOUT: 2000,
52
+ AZURE_REGION_AUTO_DISCOVER_FLAG: "TryAutoDetect",
53
+ REGIONAL_AUTH_PUBLIC_CLOUD_SUFFIX: "login.microsoft.com",
54
+ REGIONAL_AUTH_NON_MSI_QUERY_STRING: "allowestsrnonmsi=true",
55
+ KNOWN_PUBLIC_CLOUDS: [
56
+ "login.microsoftonline.com",
57
+ "login.windows.net",
58
+ "login.microsoft.com",
59
+ "sts.windows.net",
60
+ ],
61
+ TOKEN_RESPONSE_TYPE: "token",
62
+ ID_TOKEN_RESPONSE_TYPE: "id_token",
63
+ SHR_NONCE_VALIDITY: 240,
64
+ INVALID_INSTANCE: "invalid_instance",
65
+ };
66
+
67
+ export const HttpStatus = {
68
+ SUCCESS_RANGE_START: 200,
69
+ SUCCESS_RANGE_END: 299,
70
+ REDIRECT: 302,
71
+ CLIENT_ERROR_RANGE_START: 400,
72
+ CLIENT_ERROR_RANGE_END: 499,
73
+ SERVER_ERROR_RANGE_START: 500,
74
+ SERVER_ERROR_RANGE_END: 599,
75
+ } as const;
76
+ export type HttpStatus = (typeof HttpStatus)[keyof typeof HttpStatus];
77
+
78
+ export const OIDC_DEFAULT_SCOPES = [
79
+ Constants.OPENID_SCOPE,
80
+ Constants.PROFILE_SCOPE,
81
+ Constants.OFFLINE_ACCESS_SCOPE,
82
+ ];
83
+
84
+ export const OIDC_SCOPES = [...OIDC_DEFAULT_SCOPES, Constants.EMAIL_SCOPE];
85
+
86
+ /**
87
+ * Request header names
88
+ */
89
+ export const HeaderNames = {
90
+ CONTENT_TYPE: "Content-Type",
91
+ RETRY_AFTER: "Retry-After",
92
+ CCS_HEADER: "X-AnchorMailbox",
93
+ WWWAuthenticate: "WWW-Authenticate",
94
+ AuthenticationInfo: "Authentication-Info",
95
+ X_MS_REQUEST_ID: "x-ms-request-id",
96
+ X_MS_HTTP_VERSION: "x-ms-httpver",
97
+ } as const;
98
+ export type HeaderNames = (typeof HeaderNames)[keyof typeof HeaderNames];
99
+
100
+ /**
101
+ * Persistent cache keys MSAL which stay while user is logged in.
102
+ */
103
+ export const PersistentCacheKeys = {
104
+ ID_TOKEN: "idtoken",
105
+ CLIENT_INFO: "client.info",
106
+ ADAL_ID_TOKEN: "adal.idtoken",
107
+ ERROR: "error",
108
+ ERROR_DESC: "error.description",
109
+ ACTIVE_ACCOUNT: "active-account", // Legacy active-account cache key, use new key instead
110
+ ACTIVE_ACCOUNT_FILTERS: "active-account-filters", // new cache entry for active_account for a more robust version for browser
111
+ } as const;
112
+ export type PersistentCacheKeys =
113
+ (typeof PersistentCacheKeys)[keyof typeof PersistentCacheKeys];
114
+
115
+ /**
116
+ * String constants related to AAD Authority
117
+ */
118
+ export const AADAuthorityConstants = {
119
+ COMMON: "common",
120
+ ORGANIZATIONS: "organizations",
121
+ CONSUMERS: "consumers",
122
+ } as const;
123
+ export type AADAuthorityConstants =
124
+ (typeof AADAuthorityConstants)[keyof typeof AADAuthorityConstants];
125
+
126
+ /**
127
+ * Keys in the hashParams sent by AAD Server
128
+ */
129
+ export const AADServerParamKeys = {
130
+ CLIENT_ID: "client_id",
131
+ REDIRECT_URI: "redirect_uri",
132
+ RESPONSE_TYPE: "response_type",
133
+ RESPONSE_MODE: "response_mode",
134
+ GRANT_TYPE: "grant_type",
135
+ CLAIMS: "claims",
136
+ SCOPE: "scope",
137
+ ERROR: "error",
138
+ ERROR_DESCRIPTION: "error_description",
139
+ ACCESS_TOKEN: "access_token",
140
+ ID_TOKEN: "id_token",
141
+ REFRESH_TOKEN: "refresh_token",
142
+ EXPIRES_IN: "expires_in",
143
+ STATE: "state",
144
+ NONCE: "nonce",
145
+ PROMPT: "prompt",
146
+ SESSION_STATE: "session_state",
147
+ CLIENT_INFO: "client_info",
148
+ CODE: "code",
149
+ CODE_CHALLENGE: "code_challenge",
150
+ CODE_CHALLENGE_METHOD: "code_challenge_method",
151
+ CODE_VERIFIER: "code_verifier",
152
+ CLIENT_REQUEST_ID: "client-request-id",
153
+ X_CLIENT_SKU: "x-client-SKU",
154
+ X_CLIENT_VER: "x-client-VER",
155
+ X_CLIENT_OS: "x-client-OS",
156
+ X_CLIENT_CPU: "x-client-CPU",
157
+ X_CLIENT_CURR_TELEM: "x-client-current-telemetry",
158
+ X_CLIENT_LAST_TELEM: "x-client-last-telemetry",
159
+ X_MS_LIB_CAPABILITY: "x-ms-lib-capability",
160
+ X_APP_NAME: "x-app-name",
161
+ X_APP_VER: "x-app-ver",
162
+ POST_LOGOUT_URI: "post_logout_redirect_uri",
163
+ ID_TOKEN_HINT: "id_token_hint",
164
+ DEVICE_CODE: "device_code",
165
+ CLIENT_SECRET: "client_secret",
166
+ CLIENT_ASSERTION: "client_assertion",
167
+ CLIENT_ASSERTION_TYPE: "client_assertion_type",
168
+ TOKEN_TYPE: "token_type",
169
+ REQ_CNF: "req_cnf",
170
+ OBO_ASSERTION: "assertion",
171
+ REQUESTED_TOKEN_USE: "requested_token_use",
172
+ ON_BEHALF_OF: "on_behalf_of",
173
+ FOCI: "foci",
174
+ CCS_HEADER: "X-AnchorMailbox",
175
+ RETURN_SPA_CODE: "return_spa_code",
176
+ NATIVE_BROKER: "nativebroker",
177
+ LOGOUT_HINT: "logout_hint",
178
+ } as const;
179
+ export type AADServerParamKeys =
180
+ (typeof AADServerParamKeys)[keyof typeof AADServerParamKeys];
181
+
182
+ /**
183
+ * Claims request keys
184
+ */
185
+ export const ClaimsRequestKeys = {
186
+ ACCESS_TOKEN: "access_token",
187
+ XMS_CC: "xms_cc",
188
+ } as const;
189
+ export type ClaimsRequestKeys =
190
+ (typeof ClaimsRequestKeys)[keyof typeof ClaimsRequestKeys];
191
+
192
+ /**
193
+ * we considered making this "enum" in the request instead of string, however it looks like the allowed list of
194
+ * prompt values kept changing over past couple of years. There are some undocumented prompt values for some
195
+ * internal partners too, hence the choice of generic "string" type instead of the "enum"
196
+ */
197
+ export const PromptValue = {
198
+ LOGIN: "login",
199
+ SELECT_ACCOUNT: "select_account",
200
+ CONSENT: "consent",
201
+ NONE: "none",
202
+ CREATE: "create",
203
+ NO_SESSION: "no_session",
204
+ };
205
+
206
+ /**
207
+ * SSO Types - generated to populate hints
208
+ */
209
+ export const SSOTypes = {
210
+ ACCOUNT: "account",
211
+ SID: "sid",
212
+ LOGIN_HINT: "login_hint",
213
+ ID_TOKEN: "id_token",
214
+ DOMAIN_HINT: "domain_hint",
215
+ ORGANIZATIONS: "organizations",
216
+ CONSUMERS: "consumers",
217
+ ACCOUNT_ID: "accountIdentifier",
218
+ HOMEACCOUNT_ID: "homeAccountIdentifier",
219
+ } as const;
220
+ export type SSOTypes = (typeof SSOTypes)[keyof typeof SSOTypes];
221
+
222
+ /**
223
+ * allowed values for codeVerifier
224
+ */
225
+ export const CodeChallengeMethodValues = {
226
+ PLAIN: "plain",
227
+ S256: "S256",
228
+ };
229
+
230
+ /**
231
+ * allowed values for server response type
232
+ */
233
+ export const ServerResponseType = {
234
+ QUERY: "query",
235
+ FRAGMENT: "fragment",
236
+ } as const;
237
+ export type ServerResponseType =
238
+ (typeof ServerResponseType)[keyof typeof ServerResponseType];
239
+
240
+ /**
241
+ * allowed values for response_mode
242
+ */
243
+ export const ResponseMode = {
244
+ ...ServerResponseType,
245
+ FORM_POST: "form_post",
246
+ } as const;
247
+ export type ResponseMode = (typeof ResponseMode)[keyof typeof ResponseMode];
248
+
249
+ /**
250
+ * allowed grant_type
251
+ */
252
+ export const GrantType = {
253
+ IMPLICIT_GRANT: "implicit",
254
+ AUTHORIZATION_CODE_GRANT: "authorization_code",
255
+ CLIENT_CREDENTIALS_GRANT: "client_credentials",
256
+ RESOURCE_OWNER_PASSWORD_GRANT: "password",
257
+ REFRESH_TOKEN_GRANT: "refresh_token",
258
+ DEVICE_CODE_GRANT: "device_code",
259
+ JWT_BEARER: "urn:ietf:params:oauth:grant-type:jwt-bearer",
260
+ } as const;
261
+ export type GrantType = (typeof GrantType)[keyof typeof GrantType];
262
+
263
+ /**
264
+ * Account types in Cache
265
+ */
266
+ export const CacheAccountType = {
267
+ MSSTS_ACCOUNT_TYPE: "MSSTS",
268
+ ADFS_ACCOUNT_TYPE: "ADFS",
269
+ MSAV1_ACCOUNT_TYPE: "MSA",
270
+ GENERIC_ACCOUNT_TYPE: "Generic", // NTLM, Kerberos, FBA, Basic etc
271
+ } as const;
272
+ export type CacheAccountType =
273
+ (typeof CacheAccountType)[keyof typeof CacheAccountType];
274
+
275
+ /**
276
+ * Separators used in cache
277
+ */
278
+ export const Separators = {
279
+ CACHE_KEY_SEPARATOR: "-",
280
+ CLIENT_INFO_SEPARATOR: ".",
281
+ } as const;
282
+ export type Separators = (typeof Separators)[keyof typeof Separators];
283
+
284
+ /**
285
+ * Credential Type stored in the cache
286
+ */
287
+ export const CredentialType = {
288
+ ID_TOKEN: "IdToken",
289
+ ACCESS_TOKEN: "AccessToken",
290
+ ACCESS_TOKEN_WITH_AUTH_SCHEME: "AccessToken_With_AuthScheme",
291
+ REFRESH_TOKEN: "RefreshToken",
292
+ } as const;
293
+ export type CredentialType =
294
+ (typeof CredentialType)[keyof typeof CredentialType];
295
+
296
+ /**
297
+ * Combine all cache types
298
+ */
299
+ export const CacheType = {
300
+ ADFS: 1001,
301
+ MSA: 1002,
302
+ MSSTS: 1003,
303
+ GENERIC: 1004,
304
+ ACCESS_TOKEN: 2001,
305
+ REFRESH_TOKEN: 2002,
306
+ ID_TOKEN: 2003,
307
+ APP_METADATA: 3001,
308
+ UNDEFINED: 9999,
309
+ } as const;
310
+ export type CacheType = (typeof CacheType)[keyof typeof CacheType];
311
+
312
+ /**
313
+ * More Cache related constants
314
+ */
315
+ export const APP_METADATA = "appmetadata";
316
+ export const CLIENT_INFO = "client_info";
317
+ export const THE_FAMILY_ID = "1";
318
+
319
+ export const AUTHORITY_METADATA_CONSTANTS = {
320
+ CACHE_KEY: "authority-metadata",
321
+ REFRESH_TIME_SECONDS: 3600 * 24, // 24 Hours
322
+ };
323
+
324
+ export const AuthorityMetadataSource = {
325
+ CONFIG: "config",
326
+ CACHE: "cache",
327
+ NETWORK: "network",
328
+ HARDCODED_VALUES: "hardcoded_values",
329
+ } as const;
330
+ export type AuthorityMetadataSource =
331
+ (typeof AuthorityMetadataSource)[keyof typeof AuthorityMetadataSource];
332
+
333
+ export const SERVER_TELEM_CONSTANTS = {
334
+ SCHEMA_VERSION: 5,
335
+ MAX_CUR_HEADER_BYTES: 80, // ESTS limit is 100B, set to 80 to provide a 20B buffer
336
+ MAX_LAST_HEADER_BYTES: 330, // ESTS limit is 350B, set to 330 to provide a 20B buffer,
337
+ MAX_CACHED_ERRORS: 50, // Limit the number of errors that can be stored to prevent uncontrolled size gains
338
+ CACHE_KEY: "server-telemetry",
339
+ CATEGORY_SEPARATOR: "|",
340
+ VALUE_SEPARATOR: ",",
341
+ OVERFLOW_TRUE: "1",
342
+ OVERFLOW_FALSE: "0",
343
+ UNKNOWN_ERROR: "unknown_error",
344
+ };
345
+
346
+ /**
347
+ * Type of the authentication request
348
+ */
349
+ export const AuthenticationScheme = {
350
+ BEARER: "Bearer",
351
+ POP: "pop",
352
+ SSH: "ssh-cert",
353
+ } as const;
354
+ export type AuthenticationScheme =
355
+ (typeof AuthenticationScheme)[keyof typeof AuthenticationScheme];
356
+
357
+ /**
358
+ * Constants related to throttling
359
+ */
360
+ export const ThrottlingConstants = {
361
+ // Default time to throttle RequestThumbprint in seconds
362
+ DEFAULT_THROTTLE_TIME_SECONDS: 60,
363
+ // Default maximum time to throttle in seconds, overrides what the server sends back
364
+ DEFAULT_MAX_THROTTLE_TIME_SECONDS: 3600,
365
+ // Prefix for storing throttling entries
366
+ THROTTLING_PREFIX: "throttling",
367
+ // Value assigned to the x-ms-lib-capability header to indicate to the server the library supports throttling
368
+ X_MS_LIB_CAPABILITY_VALUE: "retry-after, h429",
369
+ };
370
+
371
+ export const Errors = {
372
+ INVALID_GRANT_ERROR: "invalid_grant",
373
+ CLIENT_MISMATCH_ERROR: "client_mismatch",
374
+ };
375
+
376
+ /**
377
+ * Password grant parameters
378
+ */
379
+ export const PasswordGrantConstants = {
380
+ username: "username",
381
+ password: "password",
382
+ } as const;
383
+ export type PasswordGrantConstants =
384
+ (typeof PasswordGrantConstants)[keyof typeof PasswordGrantConstants];
385
+
386
+ /**
387
+ * Response codes
388
+ */
389
+ export const ResponseCodes = {
390
+ httpSuccess: 200,
391
+ httpBadRequest: 400,
392
+ } as const;
393
+ export type ResponseCodes = (typeof ResponseCodes)[keyof typeof ResponseCodes];
394
+
395
+ /**
396
+ * Region Discovery Sources
397
+ */
398
+ export const RegionDiscoverySources = {
399
+ FAILED_AUTO_DETECTION: "1",
400
+ INTERNAL_CACHE: "2",
401
+ ENVIRONMENT_VARIABLE: "3",
402
+ IMDS: "4",
403
+ } as const;
404
+ export type RegionDiscoverySources =
405
+ (typeof RegionDiscoverySources)[keyof typeof RegionDiscoverySources];
406
+
407
+ /**
408
+ * Region Discovery Outcomes
409
+ */
410
+ export const RegionDiscoveryOutcomes = {
411
+ CONFIGURED_MATCHES_DETECTED: "1",
412
+ CONFIGURED_NO_AUTO_DETECTION: "2",
413
+ CONFIGURED_NOT_DETECTED: "3",
414
+ AUTO_DETECTION_REQUESTED_SUCCESSFUL: "4",
415
+ AUTO_DETECTION_REQUESTED_FAILED: "5",
416
+ } as const;
417
+ export type RegionDiscoveryOutcomes =
418
+ (typeof RegionDiscoveryOutcomes)[keyof typeof RegionDiscoveryOutcomes];
419
+
420
+ export const CacheOutcome = {
421
+ NO_CACHE_HIT: "0",
422
+ FORCE_REFRESH: "1",
423
+ NO_CACHED_ACCESS_TOKEN: "2",
424
+ CACHED_ACCESS_TOKEN_EXPIRED: "3",
425
+ REFRESH_CACHED_ACCESS_TOKEN: "4",
426
+ } as const;
427
+ export type CacheOutcome = (typeof CacheOutcome)[keyof typeof CacheOutcome];
428
+
429
+ export const JsonTypes = {
430
+ Jwt: "JWT",
431
+ Jwk: "JWK",
432
+ Pop: "pop",
433
+ } as const;
434
+ export type JsonTypes = (typeof JsonTypes)[keyof typeof JsonTypes];
435
+
436
+ export const ONE_DAY_IN_MS = 86400000;
@@ -0,0 +1,105 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { Logger } from "../logger/Logger";
7
+ import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient";
8
+
9
+ /**
10
+ * Wraps a function with a performance measurement.
11
+ * Usage: invoke(functionToCall, performanceClient, "EventName", "correlationId")(...argsToPassToFunction)
12
+ * @param callback
13
+ * @param eventName
14
+ * @param logger
15
+ * @param telemetryClient
16
+ * @param correlationId
17
+ * @returns
18
+ * @internal
19
+ */
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ export const invoke = <T extends Array<any>, U>(
22
+ callback: (...args: T) => U,
23
+ eventName: string,
24
+ logger: Logger,
25
+ telemetryClient?: IPerformanceClient,
26
+ correlationId?: string
27
+ ) => {
28
+ return (...args: T): U => {
29
+ logger.trace(`Executing function ${eventName}`);
30
+ const inProgressEvent = telemetryClient?.startMeasurement(
31
+ eventName,
32
+ correlationId
33
+ );
34
+ telemetryClient?.setPreQueueTime(eventName, correlationId);
35
+ try {
36
+ const result = callback(...args);
37
+ inProgressEvent?.end({
38
+ success: true,
39
+ });
40
+ logger.trace(`Returning result from ${eventName}`);
41
+ return result;
42
+ } catch (e) {
43
+ logger.trace(`Error occurred in ${eventName}`);
44
+ try {
45
+ logger.trace(JSON.stringify(e));
46
+ } catch (e) {
47
+ logger.trace("Unable to print error message.");
48
+ }
49
+ inProgressEvent?.end({
50
+ success: false,
51
+ });
52
+ throw e;
53
+ }
54
+ };
55
+ };
56
+
57
+ /**
58
+ * Wraps an async function with a performance measurement.
59
+ * Usage: invokeAsync(functionToCall, performanceClient, "EventName", "correlationId")(...argsToPassToFunction)
60
+ * @param callback
61
+ * @param eventName
62
+ * @param logger
63
+ * @param telemetryClient
64
+ * @param correlationId
65
+ * @returns
66
+ * @internal
67
+ *
68
+ */
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ export const invokeAsync = <T extends Array<any>, U>(
71
+ callback: (...args: T) => Promise<U>,
72
+ eventName: string,
73
+ logger: Logger,
74
+ telemetryClient?: IPerformanceClient,
75
+ correlationId?: string
76
+ ) => {
77
+ return (...args: T): Promise<U> => {
78
+ logger.trace(`Executing function ${eventName}`);
79
+ const inProgressEvent = telemetryClient?.startMeasurement(
80
+ eventName,
81
+ correlationId
82
+ );
83
+ telemetryClient?.setPreQueueTime(eventName, correlationId);
84
+ return callback(...args)
85
+ .then((response) => {
86
+ logger.trace(`Returning result from ${eventName}`);
87
+ inProgressEvent?.end({
88
+ success: true,
89
+ });
90
+ return response;
91
+ })
92
+ .catch((e) => {
93
+ logger.trace(`Error occurred in ${eventName}`);
94
+ try {
95
+ logger.trace(JSON.stringify(e));
96
+ } catch (e) {
97
+ logger.trace("Unable to print error message.");
98
+ }
99
+ inProgressEvent?.end({
100
+ success: false,
101
+ });
102
+ throw e;
103
+ });
104
+ };
105
+ };
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Key-Value type to support queryParams, extraQueryParams and claims
8
+ */
9
+ export type StringDict = { [key: string]: string };
@@ -0,0 +1,124 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { Constants } from "./Constants";
7
+ import { ICrypto } from "../crypto/ICrypto";
8
+ import { ClientAuthError } from "../error/ClientAuthError";
9
+
10
+ /**
11
+ * Type which defines the object that is stringified, encoded and sent in the state value.
12
+ * Contains the following:
13
+ * - id - unique identifier for this request
14
+ * - ts - timestamp for the time the request was made. Used to ensure that token expiration is not calculated incorrectly.
15
+ * - platformState - string value sent from the platform.
16
+ */
17
+ export type LibraryStateObject = {
18
+ id: string;
19
+ meta?: Record<string, string>;
20
+ };
21
+
22
+ /**
23
+ * Type which defines the stringified and encoded object sent to the service in the authorize request.
24
+ */
25
+ export type RequestStateObject = {
26
+ userRequestState: string;
27
+ libraryState: LibraryStateObject;
28
+ };
29
+
30
+ /**
31
+ * Class which provides helpers for OAuth 2.0 protocol specific values
32
+ */
33
+ export class ProtocolUtils {
34
+ /**
35
+ * Appends user state with random guid, or returns random guid.
36
+ * @param userState
37
+ * @param randomGuid
38
+ */
39
+ static setRequestState(
40
+ cryptoObj: ICrypto,
41
+ userState?: string,
42
+ meta?: Record<string, string>
43
+ ): string {
44
+ const libraryState = ProtocolUtils.generateLibraryState(
45
+ cryptoObj,
46
+ meta
47
+ );
48
+ return userState
49
+ ? `${libraryState}${Constants.RESOURCE_DELIM}${userState}`
50
+ : libraryState;
51
+ }
52
+
53
+ /**
54
+ * Generates the state value used by the common library.
55
+ * @param randomGuid
56
+ * @param cryptoObj
57
+ */
58
+ static generateLibraryState(
59
+ cryptoObj: ICrypto,
60
+ meta?: Record<string, string>
61
+ ): string {
62
+ if (!cryptoObj) {
63
+ throw ClientAuthError.createNoCryptoObjectError(
64
+ "generateLibraryState"
65
+ );
66
+ }
67
+
68
+ // Create a state object containing a unique id and the timestamp of the request creation
69
+ const stateObj: LibraryStateObject = {
70
+ id: cryptoObj.createNewGuid(),
71
+ };
72
+
73
+ if (meta) {
74
+ stateObj.meta = meta;
75
+ }
76
+
77
+ const stateString = JSON.stringify(stateObj);
78
+
79
+ return cryptoObj.base64Encode(stateString);
80
+ }
81
+
82
+ /**
83
+ * Parses the state into the RequestStateObject, which contains the LibraryState info and the state passed by the user.
84
+ * @param state
85
+ * @param cryptoObj
86
+ */
87
+ static parseRequestState(
88
+ cryptoObj: ICrypto,
89
+ state: string
90
+ ): RequestStateObject {
91
+ if (!cryptoObj) {
92
+ throw ClientAuthError.createNoCryptoObjectError(
93
+ "parseRequestState"
94
+ );
95
+ }
96
+
97
+ if (!state) {
98
+ throw ClientAuthError.createInvalidStateError(
99
+ state,
100
+ "Null, undefined or empty state"
101
+ );
102
+ }
103
+
104
+ try {
105
+ // Split the state between library state and user passed state and decode them separately
106
+ const splitState = state.split(Constants.RESOURCE_DELIM);
107
+ const libraryState = splitState[0];
108
+ const userState =
109
+ splitState.length > 1
110
+ ? splitState.slice(1).join(Constants.RESOURCE_DELIM)
111
+ : Constants.EMPTY_STRING;
112
+ const libraryStateString = cryptoObj.base64Decode(libraryState);
113
+ const libraryStateObj = JSON.parse(
114
+ libraryStateString
115
+ ) as LibraryStateObject;
116
+ return {
117
+ userRequestState: userState || Constants.EMPTY_STRING,
118
+ libraryState: libraryStateObj,
119
+ };
120
+ } catch (e) {
121
+ throw ClientAuthError.createInvalidStateError(state, e as string);
122
+ }
123
+ }
124
+ }