@azure/msal-common 14.0.0-alpha.1 → 14.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +62 -62
  3. package/dist/account/AccountInfo.d.ts +31 -31
  4. package/dist/account/AuthToken.d.ts +20 -20
  5. package/dist/account/AuthToken.js +48 -48
  6. package/dist/account/CcsCredential.d.ts +9 -8
  7. package/dist/account/CcsCredential.d.ts.map +1 -1
  8. package/dist/account/CcsCredential.js +9 -10
  9. package/dist/account/CcsCredential.js.map +1 -1
  10. package/dist/account/ClientCredentials.d.ts +14 -14
  11. package/dist/account/ClientInfo.d.ts +19 -19
  12. package/dist/account/ClientInfo.js +37 -37
  13. package/dist/account/DecodedAuthToken.d.ts +8 -8
  14. package/dist/account/TokenClaims.d.ts +65 -65
  15. package/dist/authority/Authority.d.ts +228 -215
  16. package/dist/authority/Authority.d.ts.map +1 -1
  17. package/dist/authority/Authority.js +716 -682
  18. package/dist/authority/Authority.js.map +1 -1
  19. package/dist/authority/AuthorityFactory.d.ts +30 -30
  20. package/dist/authority/AuthorityFactory.js +47 -47
  21. package/dist/authority/AuthorityMetadata.d.ts +622 -622
  22. package/dist/authority/AuthorityMetadata.js +876 -876
  23. package/dist/authority/AuthorityOptions.d.ts +19 -18
  24. package/dist/authority/AuthorityOptions.d.ts.map +1 -1
  25. package/dist/authority/AuthorityOptions.js +19 -20
  26. package/dist/authority/AuthorityOptions.js.map +1 -1
  27. package/dist/authority/AuthorityType.d.ts +10 -9
  28. package/dist/authority/AuthorityType.d.ts.map +1 -1
  29. package/dist/authority/AuthorityType.js +14 -15
  30. package/dist/authority/AuthorityType.js.map +1 -1
  31. package/dist/authority/AzureRegion.d.ts +1 -1
  32. package/dist/authority/AzureRegionConfiguration.d.ts +5 -5
  33. package/dist/authority/CloudDiscoveryMetadata.d.ts +5 -5
  34. package/dist/authority/CloudInstanceDiscoveryErrorResponse.d.ts +13 -13
  35. package/dist/authority/CloudInstanceDiscoveryErrorResponse.js +8 -8
  36. package/dist/authority/CloudInstanceDiscoveryResponse.d.ts +9 -9
  37. package/dist/authority/CloudInstanceDiscoveryResponse.js +8 -8
  38. package/dist/authority/ImdsOptions.d.ts +5 -5
  39. package/dist/authority/OpenIdConfigResponse.d.ts +11 -11
  40. package/dist/authority/OpenIdConfigResponse.js +10 -10
  41. package/dist/authority/ProtocolMode.d.ts +8 -7
  42. package/dist/authority/ProtocolMode.d.ts.map +1 -1
  43. package/dist/authority/ProtocolMode.js +12 -13
  44. package/dist/authority/ProtocolMode.js.map +1 -1
  45. package/dist/authority/RegionDiscovery.d.ts +30 -30
  46. package/dist/authority/RegionDiscovery.js +108 -108
  47. package/dist/authority/RegionDiscoveryMetadata.d.ts +6 -6
  48. package/dist/broker/nativeBroker/INativeBrokerPlugin.d.ts +15 -15
  49. package/dist/cache/CacheManager.d.ts +443 -443
  50. package/dist/cache/CacheManager.js +1011 -1011
  51. package/dist/cache/entities/AccessTokenEntity.d.ts +56 -56
  52. package/dist/cache/entities/AccessTokenEntity.js +111 -111
  53. package/dist/cache/entities/AccountEntity.d.ts +99 -99
  54. package/dist/cache/entities/AccountEntity.js +248 -248
  55. package/dist/cache/entities/AppMetadataEntity.d.ts +39 -39
  56. package/dist/cache/entities/AppMetadataEntity.js +66 -66
  57. package/dist/cache/entities/AuthorityMetadataEntity.d.ts +47 -47
  58. package/dist/cache/entities/AuthorityMetadataEntity.js +77 -77
  59. package/dist/cache/entities/CacheRecord.d.ts +13 -13
  60. package/dist/cache/entities/CacheRecord.js +13 -13
  61. package/dist/cache/entities/CredentialEntity.d.ts +88 -88
  62. package/dist/cache/entities/CredentialEntity.js +136 -136
  63. package/dist/cache/entities/IdTokenEntity.d.ts +34 -34
  64. package/dist/cache/entities/IdTokenEntity.js +56 -56
  65. package/dist/cache/entities/RefreshTokenEntity.d.ts +36 -36
  66. package/dist/cache/entities/RefreshTokenEntity.js +59 -59
  67. package/dist/cache/entities/ServerTelemetryEntity.d.ts +12 -12
  68. package/dist/cache/entities/ServerTelemetryEntity.js +27 -27
  69. package/dist/cache/entities/ThrottlingEntity.d.ts +13 -13
  70. package/dist/cache/entities/ThrottlingEntity.js +23 -23
  71. package/dist/cache/interface/ICacheManager.d.ts +165 -165
  72. package/dist/cache/interface/ICachePlugin.d.ts +5 -5
  73. package/dist/cache/interface/ISerializableTokenCache.d.ts +4 -4
  74. package/dist/cache/persistence/TokenCacheContext.d.ts +23 -23
  75. package/dist/cache/persistence/TokenCacheContext.js +25 -25
  76. package/dist/cache/utils/CacheTypes.d.ts +62 -62
  77. package/dist/client/AuthorizationCodeClient.d.ts +71 -71
  78. package/dist/client/AuthorizationCodeClient.js +433 -433
  79. package/dist/client/BaseClient.d.ts +50 -50
  80. package/dist/client/BaseClient.js +92 -92
  81. package/dist/client/RefreshTokenClient.d.ts +34 -34
  82. package/dist/client/RefreshTokenClient.js +239 -239
  83. package/dist/client/SilentFlowClient.d.ts +24 -24
  84. package/dist/client/SilentFlowClient.js +94 -94
  85. package/dist/config/AppTokenProvider.d.ts +38 -38
  86. package/dist/config/ClientConfiguration.d.ts +133 -133
  87. package/dist/config/ClientConfiguration.js +88 -88
  88. package/dist/crypto/ICrypto.d.ts +62 -62
  89. package/dist/crypto/ICrypto.js +42 -42
  90. package/dist/crypto/IGuidGenerator.d.ts +4 -4
  91. package/dist/crypto/JoseHeader.d.ts +21 -21
  92. package/dist/crypto/JoseHeader.js +36 -36
  93. package/dist/crypto/PopTokenGenerator.d.ts +58 -57
  94. package/dist/crypto/PopTokenGenerator.d.ts.map +1 -1
  95. package/dist/crypto/PopTokenGenerator.js +82 -83
  96. package/dist/crypto/PopTokenGenerator.js.map +1 -1
  97. package/dist/crypto/SignedHttpRequest.d.ts +11 -11
  98. package/dist/error/AuthError.d.ts +47 -47
  99. package/dist/error/AuthError.js +51 -51
  100. package/dist/error/ClientAuthError.d.ts +412 -412
  101. package/dist/error/ClientAuthError.js +519 -519
  102. package/dist/error/ClientConfigurationError.d.ts +206 -198
  103. package/dist/error/ClientConfigurationError.d.ts.map +1 -1
  104. package/dist/error/ClientConfigurationError.js +259 -249
  105. package/dist/error/ClientConfigurationError.js.map +1 -1
  106. package/dist/error/InteractionRequiredAuthError.d.ts +59 -59
  107. package/dist/error/InteractionRequiredAuthError.js +78 -78
  108. package/dist/error/JoseHeaderError.d.ts +28 -28
  109. package/dist/error/JoseHeaderError.js +39 -39
  110. package/dist/error/ServerError.d.ts +7 -7
  111. package/dist/error/ServerError.js +14 -14
  112. package/dist/index.cjs.js +8826 -8813
  113. package/dist/index.cjs.js.map +1 -1
  114. package/dist/index.d.ts +93 -93
  115. package/dist/index.js +1 -1
  116. package/dist/logger/Logger.d.ts +95 -95
  117. package/dist/logger/Logger.js +197 -197
  118. package/dist/network/INetworkModule.d.ts +29 -29
  119. package/dist/network/INetworkModule.js +14 -14
  120. package/dist/network/NetworkManager.d.ts +32 -32
  121. package/dist/network/NetworkManager.js +33 -33
  122. package/dist/network/RequestThumbprint.d.ts +16 -16
  123. package/dist/network/ThrottlingUtils.d.ts +41 -41
  124. package/dist/network/ThrottlingUtils.js +94 -94
  125. package/dist/packageMetadata.d.ts +2 -2
  126. package/dist/packageMetadata.d.ts.map +1 -1
  127. package/dist/packageMetadata.js +4 -4
  128. package/dist/request/AuthenticationHeaderParser.d.ts +19 -19
  129. package/dist/request/AuthenticationHeaderParser.js +55 -55
  130. package/dist/request/BaseAuthRequest.d.ts +37 -37
  131. package/dist/request/CommonAuthorizationCodeRequest.d.ts +27 -27
  132. package/dist/request/CommonAuthorizationUrlRequest.d.ts +50 -50
  133. package/dist/request/CommonClientCredentialRequest.d.ts +17 -17
  134. package/dist/request/CommonDeviceCodeRequest.d.ts +21 -21
  135. package/dist/request/CommonEndSessionRequest.d.ts +21 -21
  136. package/dist/request/CommonOnBehalfOfRequest.d.ts +13 -13
  137. package/dist/request/CommonRefreshTokenRequest.d.ts +19 -19
  138. package/dist/request/CommonSilentFlowRequest.d.ts +18 -18
  139. package/dist/request/CommonUsernamePasswordRequest.d.ts +17 -17
  140. package/dist/request/NativeRequest.d.ts +19 -19
  141. package/dist/request/NativeSignOutRequest.d.ts +5 -5
  142. package/dist/request/RequestParameterBuilder.d.ts +216 -216
  143. package/dist/request/RequestParameterBuilder.js +374 -374
  144. package/dist/request/RequestValidator.d.ts +33 -33
  145. package/dist/request/RequestValidator.js +82 -83
  146. package/dist/request/RequestValidator.js.map +1 -1
  147. package/dist/request/ScopeSet.d.ts +88 -88
  148. package/dist/request/ScopeSet.js +197 -197
  149. package/dist/response/AuthenticationResult.d.ts +39 -39
  150. package/dist/response/AuthorizationCodePayload.d.ts +13 -13
  151. package/dist/response/DeviceCodeResponse.d.ts +25 -25
  152. package/dist/response/ExternalTokenResponse.d.ts +15 -15
  153. package/dist/response/IMDSBadResponse.d.ts +4 -4
  154. package/dist/response/ResponseHandler.d.ts +72 -72
  155. package/dist/response/ResponseHandler.js +300 -300
  156. package/dist/response/ServerAuthorizationCodeResponse.d.ts +25 -25
  157. package/dist/response/ServerAuthorizationTokenResponse.d.ts +44 -44
  158. package/dist/telemetry/performance/IPerformanceClient.d.ts +42 -42
  159. package/dist/telemetry/performance/IPerformanceMeasurement.d.ts +5 -5
  160. package/dist/telemetry/performance/PerformanceClient.d.ts +189 -189
  161. package/dist/telemetry/performance/PerformanceClient.js +406 -406
  162. package/dist/telemetry/performance/PerformanceEvent.d.ts +441 -439
  163. package/dist/telemetry/performance/PerformanceEvent.d.ts.map +1 -1
  164. package/dist/telemetry/performance/PerformanceEvent.js +225 -227
  165. package/dist/telemetry/performance/PerformanceEvent.js.map +1 -1
  166. package/dist/telemetry/performance/StubPerformanceClient.d.ts +15 -19
  167. package/dist/telemetry/performance/StubPerformanceClient.d.ts.map +1 -1
  168. package/dist/telemetry/performance/StubPerformanceClient.js +22 -36
  169. package/dist/telemetry/performance/StubPerformanceClient.js.map +1 -1
  170. package/dist/telemetry/server/ServerTelemetryManager.d.ts +65 -65
  171. package/dist/telemetry/server/ServerTelemetryManager.js +196 -196
  172. package/dist/telemetry/server/ServerTelemetryRequest.d.ts +8 -8
  173. package/dist/url/IUri.d.ts +12 -12
  174. package/dist/url/UrlString.d.ts +70 -70
  175. package/dist/url/UrlString.js +242 -242
  176. package/dist/utils/Constants.d.ts +345 -331
  177. package/dist/utils/Constants.d.ts.map +1 -1
  178. package/dist/utils/Constants.js +353 -373
  179. package/dist/utils/Constants.js.map +1 -1
  180. package/dist/utils/MsalTypes.d.ts +6 -6
  181. package/dist/utils/ProtocolUtils.d.ts +42 -42
  182. package/dist/utils/ProtocolUtils.js +71 -71
  183. package/dist/utils/StringUtils.d.ts +53 -53
  184. package/dist/utils/StringUtils.js +124 -124
  185. package/dist/utils/TimeUtils.d.ts +27 -27
  186. package/dist/utils/TimeUtils.js +45 -45
  187. package/package.json +86 -79
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-common v14.0.0-alpha.1 2023-05-08 */
1
+ /*! @azure/msal-common v14.0.0-beta.0 2023-06-19 */
2
2
  'use strict';
3
3
  import { BaseClient } from './BaseClient.js';
4
4
  import { RequestParameterBuilder } from '../request/RequestParameterBuilder.js';
@@ -15,438 +15,438 @@ import { ClientConfigurationError } from '../error/ClientConfigurationError.js';
15
15
  import { RequestValidator } from '../request/RequestValidator.js';
16
16
  import { PerformanceEvents } from '../telemetry/performance/PerformanceEvent.js';
17
17
 
18
- /*
19
- * Copyright (c) Microsoft Corporation. All rights reserved.
20
- * Licensed under the MIT License.
21
- */
22
- /**
23
- * Oauth2.0 Authorization Code client
24
- */
25
- class AuthorizationCodeClient extends BaseClient {
26
- constructor(configuration, performanceClient) {
27
- super(configuration, performanceClient);
28
- // Flag to indicate if client is for hybrid spa auth code redemption
29
- this.includeRedirectUri = true;
30
- }
31
- /**
32
- * Creates the URL of the authorization request letting the user input credentials and consent to the
33
- * application. The URL target the /authorize endpoint of the authority configured in the
34
- * application object.
35
- *
36
- * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI
37
- * sent in the request and should contain an authorization code, which can then be used to acquire tokens via
38
- * acquireToken(AuthorizationCodeRequest)
39
- * @param request
40
- */
41
- async getAuthCodeUrl(request) {
42
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.GetAuthCodeUrl, request.correlationId);
43
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
44
- const queryString = await this.createAuthCodeUrlQueryString(request);
45
- return UrlString.appendQueryString(this.authority.authorizationEndpoint, queryString);
46
- }
47
- /**
48
- * API to acquire a token in exchange of 'authorization_code` acquired by the user in the first leg of the
49
- * authorization_code_grant
50
- * @param request
51
- */
52
- async acquireToken(request, authCodePayload) {
53
- if (!request || !request.code) {
54
- throw ClientAuthError.createTokenRequestCannotBeMadeError();
55
- }
56
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientAcquireToken, request.correlationId);
57
- const atsMeasurement = this.performanceClient?.startMeasurement(
58
- // @ts-ignore
59
- "AuthCodeClientAcquireToken", request.correlationId);
60
- this.logger.info("in acquireToken call in auth-code client");
61
- const reqTimestamp = TimeUtils.nowSeconds();
62
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
63
- const response = await this.executeTokenRequest(this.authority, request);
64
- // Retrieve requestId from response headers
65
- const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID];
66
- const httpVerAuthority = response.headers?.[HeaderNames.X_MS_HTTP_VERSION];
67
- if (httpVerAuthority) {
68
- atsMeasurement?.addStaticFields({
69
- httpVerAuthority,
70
- });
71
- }
72
- const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin, this.performanceClient);
73
- // Validate response. This function throws a server error if an error is returned by the server.
74
- responseHandler.validateTokenResponse(response.body);
75
- this.performanceClient?.setPreQueueTime(PerformanceEvents.HandleServerTokenResponse, request.correlationId);
76
- return responseHandler
77
- .handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, authCodePayload, undefined, undefined, undefined, requestId)
78
- .then((result) => {
79
- atsMeasurement?.endMeasurement({
80
- success: true,
81
- });
82
- return result;
83
- })
84
- .catch((error) => {
85
- this.logger.verbose("Error in fetching token in ACC", request.correlationId);
86
- atsMeasurement?.endMeasurement({
87
- errorCode: error.errorCode,
88
- subErrorCode: error.subError,
89
- success: false,
90
- });
91
- throw error;
92
- });
93
- }
94
- /**
95
- * Handles the hash fragment response from public client code request. Returns a code response used by
96
- * the client to exchange for a token in acquireToken.
97
- * @param hashFragment
98
- */
99
- handleFragmentResponse(hashFragment, cachedState) {
100
- // Handle responses.
101
- const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, null, null);
102
- // Deserialize hash fragment response parameters.
103
- const hashUrlString = new UrlString(hashFragment);
104
- // Deserialize hash fragment response parameters.
105
- const serverParams = UrlString.getDeserializedHash(hashUrlString.getHash());
106
- // Get code response
107
- responseHandler.validateServerAuthorizationCodeResponse(serverParams, cachedState, this.cryptoUtils);
108
- // throw when there is no auth code in the response
109
- if (!serverParams.code) {
110
- throw ClientAuthError.createNoAuthCodeInServerResponseError();
111
- }
112
- return {
113
- ...serverParams,
114
- // Code param is optional in ServerAuthorizationCodeResponse but required in AuthorizationCodePaylod
115
- code: serverParams.code,
116
- };
117
- }
118
- /**
119
- * Used to log out the current user, and redirect the user to the postLogoutRedirectUri.
120
- * Default behaviour is to redirect the user to `window.location.href`.
121
- * @param authorityUri
122
- */
123
- getLogoutUri(logoutRequest) {
124
- // Throw error if logoutRequest is null/undefined
125
- if (!logoutRequest) {
126
- throw ClientConfigurationError.createEmptyLogoutRequestError();
127
- }
128
- const queryString = this.createLogoutUrlQueryString(logoutRequest);
129
- // Construct logout URI
130
- return UrlString.appendQueryString(this.authority.endSessionEndpoint, queryString);
131
- }
132
- /**
133
- * Executes POST request to token endpoint
134
- * @param authority
135
- * @param request
136
- */
137
- async executeTokenRequest(authority, request) {
138
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
139
- this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
140
- const queryParametersString = this.createTokenQueryParameters(request);
141
- const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
142
- const requestBody = await this.createTokenRequestBody(request);
143
- let ccsCredential = undefined;
144
- if (request.clientInfo) {
145
- try {
146
- const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
147
- ccsCredential = {
148
- credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
149
- type: CcsCredentialType.HOME_ACCOUNT_ID,
150
- };
151
- }
152
- catch (e) {
153
- this.logger.verbose("Could not parse client info for CCS Header: " + e);
154
- }
155
- }
156
- const headers = this.createTokenRequestHeaders(ccsCredential || request.ccsCredential);
157
- const thumbprint = {
158
- clientId: this.config.authOptions.clientId,
159
- authority: authority.canonicalAuthority,
160
- scopes: request.scopes,
161
- claims: request.claims,
162
- authenticationScheme: request.authenticationScheme,
163
- resourceRequestMethod: request.resourceRequestMethod,
164
- resourceRequestUri: request.resourceRequestUri,
165
- shrClaims: request.shrClaims,
166
- sshKid: request.sshKid,
167
- };
168
- return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint);
169
- }
170
- /**
171
- * Generates a map for all the params to be sent to the service
172
- * @param request
173
- */
174
- async createTokenRequestBody(request) {
175
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
176
- const parameterBuilder = new RequestParameterBuilder();
177
- parameterBuilder.addClientId(this.config.authOptions.clientId);
178
- /*
179
- * For hybrid spa flow, there will be a code but no verifier
180
- * In this scenario, don't include redirect uri as auth code will not be bound to redirect URI
181
- */
182
- if (!this.includeRedirectUri) {
183
- // Just validate
184
- RequestValidator.validateRedirectUri(request.redirectUri);
185
- }
186
- else {
187
- // Validate and include redirect uri
188
- parameterBuilder.addRedirectUri(request.redirectUri);
189
- }
190
- // Add scope array, parameter builder will add default scopes and dedupe
191
- parameterBuilder.addScopes(request.scopes);
192
- // add code: user set, not validated
193
- parameterBuilder.addAuthorizationCode(request.code);
194
- // Add library metadata
195
- parameterBuilder.addLibraryInfo(this.config.libraryInfo);
196
- parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
197
- parameterBuilder.addThrottling();
198
- if (this.serverTelemetryManager) {
199
- parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
200
- }
201
- // add code_verifier if passed
202
- if (request.codeVerifier) {
203
- parameterBuilder.addCodeVerifier(request.codeVerifier);
204
- }
205
- if (this.config.clientCredentials.clientSecret) {
206
- parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
207
- }
208
- if (this.config.clientCredentials.clientAssertion) {
209
- const clientAssertion = this.config.clientCredentials.clientAssertion;
210
- parameterBuilder.addClientAssertion(clientAssertion.assertion);
211
- parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
212
- }
213
- parameterBuilder.addGrantType(GrantType.AUTHORIZATION_CODE_GRANT);
214
- parameterBuilder.addClientInfo();
215
- if (request.authenticationScheme === AuthenticationScheme.POP) {
216
- const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient);
217
- this.performanceClient?.setPreQueueTime(PerformanceEvents.PopTokenGenerateCnf, request.correlationId);
218
- const reqCnfData = await popTokenGenerator.generateCnf(request);
219
- // SPA PoP requires full Base64Url encoded req_cnf string (unhashed)
220
- parameterBuilder.addPopToken(reqCnfData.reqCnfString);
221
- }
222
- else if (request.authenticationScheme === AuthenticationScheme.SSH) {
223
- if (request.sshJwk) {
224
- parameterBuilder.addSshJwk(request.sshJwk);
225
- }
226
- else {
227
- throw ClientConfigurationError.createMissingSshJwkError();
228
- }
229
- }
230
- const correlationId = request.correlationId ||
231
- this.config.cryptoInterface.createNewGuid();
232
- parameterBuilder.addCorrelationId(correlationId);
233
- if (!StringUtils.isEmptyObj(request.claims) ||
234
- (this.config.authOptions.clientCapabilities &&
235
- this.config.authOptions.clientCapabilities.length > 0)) {
236
- parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
237
- }
238
- let ccsCred = undefined;
239
- if (request.clientInfo) {
240
- try {
241
- const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
242
- ccsCred = {
243
- credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
244
- type: CcsCredentialType.HOME_ACCOUNT_ID,
245
- };
246
- }
247
- catch (e) {
248
- this.logger.verbose("Could not parse client info for CCS Header: " + e);
249
- }
250
- }
251
- else {
252
- ccsCred = request.ccsCredential;
253
- }
254
- // Adds these as parameters in the request instead of headers to prevent CORS preflight request
255
- if (this.config.systemOptions.preventCorsPreflight && ccsCred) {
256
- switch (ccsCred.type) {
257
- case CcsCredentialType.HOME_ACCOUNT_ID:
258
- try {
259
- const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
260
- parameterBuilder.addCcsOid(clientInfo);
261
- }
262
- catch (e) {
263
- this.logger.verbose("Could not parse home account ID for CCS Header: " +
264
- e);
265
- }
266
- break;
267
- case CcsCredentialType.UPN:
268
- parameterBuilder.addCcsUpn(ccsCred.credential);
269
- break;
270
- }
271
- }
272
- if (request.tokenBodyParameters) {
273
- parameterBuilder.addExtraQueryParameters(request.tokenBodyParameters);
274
- }
275
- // Add hybrid spa parameters if not already provided
276
- if (request.enableSpaAuthorizationCode &&
277
- (!request.tokenBodyParameters ||
278
- !request.tokenBodyParameters[AADServerParamKeys.RETURN_SPA_CODE])) {
279
- parameterBuilder.addExtraQueryParameters({
280
- [AADServerParamKeys.RETURN_SPA_CODE]: "1",
281
- });
282
- }
283
- return parameterBuilder.createQueryString();
284
- }
285
- /**
286
- * This API validates the `AuthorizationCodeUrlRequest` and creates a URL
287
- * @param request
288
- */
289
- async createAuthCodeUrlQueryString(request) {
290
- this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
291
- const parameterBuilder = new RequestParameterBuilder();
292
- parameterBuilder.addClientId(this.config.authOptions.clientId);
293
- const requestScopes = [
294
- ...(request.scopes || []),
295
- ...(request.extraScopesToConsent || []),
296
- ];
297
- parameterBuilder.addScopes(requestScopes);
298
- // validate the redirectUri (to be a non null value)
299
- parameterBuilder.addRedirectUri(request.redirectUri);
300
- // generate the correlationId if not set by the user and add
301
- const correlationId = request.correlationId ||
302
- this.config.cryptoInterface.createNewGuid();
303
- parameterBuilder.addCorrelationId(correlationId);
304
- // add response_mode. If not passed in it defaults to query.
305
- parameterBuilder.addResponseMode(request.responseMode);
306
- // add response_type = code
307
- parameterBuilder.addResponseTypeCode();
308
- // add library info parameters
309
- parameterBuilder.addLibraryInfo(this.config.libraryInfo);
310
- parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
311
- // add client_info=1
312
- parameterBuilder.addClientInfo();
313
- if (request.codeChallenge && request.codeChallengeMethod) {
314
- parameterBuilder.addCodeChallengeParams(request.codeChallenge, request.codeChallengeMethod);
315
- }
316
- if (request.prompt) {
317
- parameterBuilder.addPrompt(request.prompt);
318
- }
319
- if (request.domainHint) {
320
- parameterBuilder.addDomainHint(request.domainHint);
321
- }
322
- // Add sid or loginHint with preference for login_hint claim (in request) -> sid -> loginHint (upn/email) -> username of AccountInfo object
323
- if (request.prompt !== PromptValue.SELECT_ACCOUNT) {
324
- // AAD will throw if prompt=select_account is passed with an account hint
325
- if (request.sid && request.prompt === PromptValue.NONE) {
326
- // SessionID is only used in silent calls
327
- this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from request");
328
- parameterBuilder.addSid(request.sid);
329
- }
330
- else if (request.account) {
331
- const accountSid = this.extractAccountSid(request.account);
332
- const accountLoginHintClaim = this.extractLoginHint(request.account);
333
- // If login_hint claim is present, use it over sid/username
334
- if (accountLoginHintClaim) {
335
- this.logger.verbose("createAuthCodeUrlQueryString: login_hint claim present on account");
336
- parameterBuilder.addLoginHint(accountLoginHintClaim);
337
- try {
338
- const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
339
- parameterBuilder.addCcsOid(clientInfo);
340
- }
341
- catch (e) {
342
- this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
343
- }
344
- }
345
- else if (accountSid && request.prompt === PromptValue.NONE) {
346
- /*
347
- * If account and loginHint are provided, we will check account first for sid before adding loginHint
348
- * SessionId is only used in silent calls
349
- */
350
- this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from account");
351
- parameterBuilder.addSid(accountSid);
352
- try {
353
- const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
354
- parameterBuilder.addCcsOid(clientInfo);
355
- }
356
- catch (e) {
357
- this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
358
- }
359
- }
360
- else if (request.loginHint) {
361
- this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from request");
362
- parameterBuilder.addLoginHint(request.loginHint);
363
- parameterBuilder.addCcsUpn(request.loginHint);
364
- }
365
- else if (request.account.username) {
366
- // Fallback to account username if provided
367
- this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from account");
368
- parameterBuilder.addLoginHint(request.account.username);
369
- try {
370
- const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
371
- parameterBuilder.addCcsOid(clientInfo);
372
- }
373
- catch (e) {
374
- this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
375
- }
376
- }
377
- }
378
- else if (request.loginHint) {
379
- this.logger.verbose("createAuthCodeUrlQueryString: No account, adding login_hint from request");
380
- parameterBuilder.addLoginHint(request.loginHint);
381
- parameterBuilder.addCcsUpn(request.loginHint);
382
- }
383
- }
384
- else {
385
- this.logger.verbose("createAuthCodeUrlQueryString: Prompt is select_account, ignoring account hints");
386
- }
387
- if (request.nonce) {
388
- parameterBuilder.addNonce(request.nonce);
389
- }
390
- if (request.state) {
391
- parameterBuilder.addState(request.state);
392
- }
393
- if (!StringUtils.isEmpty(request.claims) ||
394
- (this.config.authOptions.clientCapabilities &&
395
- this.config.authOptions.clientCapabilities.length > 0)) {
396
- parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
397
- }
398
- if (request.extraQueryParameters) {
399
- parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
400
- }
401
- if (request.nativeBroker) {
402
- // signal ests that this is a WAM call
403
- parameterBuilder.addNativeBroker();
404
- // pass the req_cnf for POP
405
- if (request.authenticationScheme === AuthenticationScheme.POP) {
406
- const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils);
407
- // to reduce the URL length, it is recommended to send the hash of the req_cnf instead of the whole string
408
- const reqCnfData = await popTokenGenerator.generateCnf(request);
409
- parameterBuilder.addPopToken(reqCnfData.reqCnfHash);
410
- }
411
- }
412
- return parameterBuilder.createQueryString();
413
- }
414
- /**
415
- * This API validates the `EndSessionRequest` and creates a URL
416
- * @param request
417
- */
418
- createLogoutUrlQueryString(request) {
419
- const parameterBuilder = new RequestParameterBuilder();
420
- if (request.postLogoutRedirectUri) {
421
- parameterBuilder.addPostLogoutRedirectUri(request.postLogoutRedirectUri);
422
- }
423
- if (request.correlationId) {
424
- parameterBuilder.addCorrelationId(request.correlationId);
425
- }
426
- if (request.idTokenHint) {
427
- parameterBuilder.addIdTokenHint(request.idTokenHint);
428
- }
429
- if (request.state) {
430
- parameterBuilder.addState(request.state);
431
- }
432
- if (request.logoutHint) {
433
- parameterBuilder.addLogoutHint(request.logoutHint);
434
- }
435
- if (request.extraQueryParameters) {
436
- parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
437
- }
438
- return parameterBuilder.createQueryString();
439
- }
440
- /**
441
- * Helper to get sid from account. Returns null if idTokenClaims are not present or sid is not present.
442
- * @param account
443
- */
444
- extractAccountSid(account) {
445
- return account.idTokenClaims?.sid || null;
446
- }
447
- extractLoginHint(account) {
448
- return account.idTokenClaims?.login_hint || null;
449
- }
18
+ /*
19
+ * Copyright (c) Microsoft Corporation. All rights reserved.
20
+ * Licensed under the MIT License.
21
+ */
22
+ /**
23
+ * Oauth2.0 Authorization Code client
24
+ */
25
+ class AuthorizationCodeClient extends BaseClient {
26
+ constructor(configuration, performanceClient) {
27
+ super(configuration, performanceClient);
28
+ // Flag to indicate if client is for hybrid spa auth code redemption
29
+ this.includeRedirectUri = true;
30
+ }
31
+ /**
32
+ * Creates the URL of the authorization request letting the user input credentials and consent to the
33
+ * application. The URL target the /authorize endpoint of the authority configured in the
34
+ * application object.
35
+ *
36
+ * Once the user inputs their credentials and consents, the authority will send a response to the redirect URI
37
+ * sent in the request and should contain an authorization code, which can then be used to acquire tokens via
38
+ * acquireToken(AuthorizationCodeRequest)
39
+ * @param request
40
+ */
41
+ async getAuthCodeUrl(request) {
42
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.GetAuthCodeUrl, request.correlationId);
43
+ this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
44
+ const queryString = await this.createAuthCodeUrlQueryString(request);
45
+ return UrlString.appendQueryString(this.authority.authorizationEndpoint, queryString);
46
+ }
47
+ /**
48
+ * API to acquire a token in exchange of 'authorization_code` acquired by the user in the first leg of the
49
+ * authorization_code_grant
50
+ * @param request
51
+ */
52
+ async acquireToken(request, authCodePayload) {
53
+ if (!request || !request.code) {
54
+ throw ClientAuthError.createTokenRequestCannotBeMadeError();
55
+ }
56
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientAcquireToken, request.correlationId);
57
+ const atsMeasurement = this.performanceClient?.startMeasurement(
58
+ // @ts-ignore
59
+ "AuthCodeClientAcquireToken", request.correlationId);
60
+ this.logger.info("in acquireToken call in auth-code client");
61
+ const reqTimestamp = TimeUtils.nowSeconds();
62
+ this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
63
+ const response = await this.executeTokenRequest(this.authority, request);
64
+ // Retrieve requestId from response headers
65
+ const requestId = response.headers?.[HeaderNames.X_MS_REQUEST_ID];
66
+ const httpVerAuthority = response.headers?.[HeaderNames.X_MS_HTTP_VERSION];
67
+ if (httpVerAuthority) {
68
+ atsMeasurement?.addStaticFields({
69
+ httpVerAuthority,
70
+ });
71
+ }
72
+ const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, this.config.serializableCache, this.config.persistencePlugin, this.performanceClient);
73
+ // Validate response. This function throws a server error if an error is returned by the server.
74
+ responseHandler.validateTokenResponse(response.body);
75
+ this.performanceClient?.setPreQueueTime(PerformanceEvents.HandleServerTokenResponse, request.correlationId);
76
+ return responseHandler
77
+ .handleServerTokenResponse(response.body, this.authority, reqTimestamp, request, authCodePayload, undefined, undefined, undefined, requestId)
78
+ .then((result) => {
79
+ atsMeasurement?.endMeasurement({
80
+ success: true,
81
+ });
82
+ return result;
83
+ })
84
+ .catch((error) => {
85
+ this.logger.verbose("Error in fetching token in ACC", request.correlationId);
86
+ atsMeasurement?.endMeasurement({
87
+ errorCode: error.errorCode,
88
+ subErrorCode: error.subError,
89
+ success: false,
90
+ });
91
+ throw error;
92
+ });
93
+ }
94
+ /**
95
+ * Handles the hash fragment response from public client code request. Returns a code response used by
96
+ * the client to exchange for a token in acquireToken.
97
+ * @param hashFragment
98
+ */
99
+ handleFragmentResponse(hashFragment, cachedState) {
100
+ // Handle responses.
101
+ const responseHandler = new ResponseHandler(this.config.authOptions.clientId, this.cacheManager, this.cryptoUtils, this.logger, null, null);
102
+ // Deserialize hash fragment response parameters.
103
+ const hashUrlString = new UrlString(hashFragment);
104
+ // Deserialize hash fragment response parameters.
105
+ const serverParams = UrlString.getDeserializedHash(hashUrlString.getHash());
106
+ // Get code response
107
+ responseHandler.validateServerAuthorizationCodeResponse(serverParams, cachedState, this.cryptoUtils);
108
+ // throw when there is no auth code in the response
109
+ if (!serverParams.code) {
110
+ throw ClientAuthError.createNoAuthCodeInServerResponseError();
111
+ }
112
+ return {
113
+ ...serverParams,
114
+ // Code param is optional in ServerAuthorizationCodeResponse but required in AuthorizationCodePaylod
115
+ code: serverParams.code,
116
+ };
117
+ }
118
+ /**
119
+ * Used to log out the current user, and redirect the user to the postLogoutRedirectUri.
120
+ * Default behaviour is to redirect the user to `window.location.href`.
121
+ * @param authorityUri
122
+ */
123
+ getLogoutUri(logoutRequest) {
124
+ // Throw error if logoutRequest is null/undefined
125
+ if (!logoutRequest) {
126
+ throw ClientConfigurationError.createEmptyLogoutRequestError();
127
+ }
128
+ const queryString = this.createLogoutUrlQueryString(logoutRequest);
129
+ // Construct logout URI
130
+ return UrlString.appendQueryString(this.authority.endSessionEndpoint, queryString);
131
+ }
132
+ /**
133
+ * Executes POST request to token endpoint
134
+ * @param authority
135
+ * @param request
136
+ */
137
+ async executeTokenRequest(authority, request) {
138
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientExecuteTokenRequest, request.correlationId);
139
+ this.performanceClient?.setPreQueueTime(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
140
+ const queryParametersString = this.createTokenQueryParameters(request);
141
+ const endpoint = UrlString.appendQueryString(authority.tokenEndpoint, queryParametersString);
142
+ const requestBody = await this.createTokenRequestBody(request);
143
+ let ccsCredential = undefined;
144
+ if (request.clientInfo) {
145
+ try {
146
+ const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
147
+ ccsCredential = {
148
+ credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
149
+ type: CcsCredentialType.HOME_ACCOUNT_ID,
150
+ };
151
+ }
152
+ catch (e) {
153
+ this.logger.verbose("Could not parse client info for CCS Header: " + e);
154
+ }
155
+ }
156
+ const headers = this.createTokenRequestHeaders(ccsCredential || request.ccsCredential);
157
+ const thumbprint = {
158
+ clientId: this.config.authOptions.clientId,
159
+ authority: authority.canonicalAuthority,
160
+ scopes: request.scopes,
161
+ claims: request.claims,
162
+ authenticationScheme: request.authenticationScheme,
163
+ resourceRequestMethod: request.resourceRequestMethod,
164
+ resourceRequestUri: request.resourceRequestUri,
165
+ shrClaims: request.shrClaims,
166
+ sshKid: request.sshKid,
167
+ };
168
+ return this.executePostToTokenEndpoint(endpoint, requestBody, headers, thumbprint);
169
+ }
170
+ /**
171
+ * Generates a map for all the params to be sent to the service
172
+ * @param request
173
+ */
174
+ async createTokenRequestBody(request) {
175
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateTokenRequestBody, request.correlationId);
176
+ const parameterBuilder = new RequestParameterBuilder();
177
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
178
+ /*
179
+ * For hybrid spa flow, there will be a code but no verifier
180
+ * In this scenario, don't include redirect uri as auth code will not be bound to redirect URI
181
+ */
182
+ if (!this.includeRedirectUri) {
183
+ // Just validate
184
+ RequestValidator.validateRedirectUri(request.redirectUri);
185
+ }
186
+ else {
187
+ // Validate and include redirect uri
188
+ parameterBuilder.addRedirectUri(request.redirectUri);
189
+ }
190
+ // Add scope array, parameter builder will add default scopes and dedupe
191
+ parameterBuilder.addScopes(request.scopes);
192
+ // add code: user set, not validated
193
+ parameterBuilder.addAuthorizationCode(request.code);
194
+ // Add library metadata
195
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
196
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
197
+ parameterBuilder.addThrottling();
198
+ if (this.serverTelemetryManager) {
199
+ parameterBuilder.addServerTelemetry(this.serverTelemetryManager);
200
+ }
201
+ // add code_verifier if passed
202
+ if (request.codeVerifier) {
203
+ parameterBuilder.addCodeVerifier(request.codeVerifier);
204
+ }
205
+ if (this.config.clientCredentials.clientSecret) {
206
+ parameterBuilder.addClientSecret(this.config.clientCredentials.clientSecret);
207
+ }
208
+ if (this.config.clientCredentials.clientAssertion) {
209
+ const clientAssertion = this.config.clientCredentials.clientAssertion;
210
+ parameterBuilder.addClientAssertion(clientAssertion.assertion);
211
+ parameterBuilder.addClientAssertionType(clientAssertion.assertionType);
212
+ }
213
+ parameterBuilder.addGrantType(GrantType.AUTHORIZATION_CODE_GRANT);
214
+ parameterBuilder.addClientInfo();
215
+ if (request.authenticationScheme === AuthenticationScheme.POP) {
216
+ const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils, this.performanceClient);
217
+ this.performanceClient?.setPreQueueTime(PerformanceEvents.PopTokenGenerateCnf, request.correlationId);
218
+ const reqCnfData = await popTokenGenerator.generateCnf(request);
219
+ // SPA PoP requires full Base64Url encoded req_cnf string (unhashed)
220
+ parameterBuilder.addPopToken(reqCnfData.reqCnfString);
221
+ }
222
+ else if (request.authenticationScheme === AuthenticationScheme.SSH) {
223
+ if (request.sshJwk) {
224
+ parameterBuilder.addSshJwk(request.sshJwk);
225
+ }
226
+ else {
227
+ throw ClientConfigurationError.createMissingSshJwkError();
228
+ }
229
+ }
230
+ const correlationId = request.correlationId ||
231
+ this.config.cryptoInterface.createNewGuid();
232
+ parameterBuilder.addCorrelationId(correlationId);
233
+ if (!StringUtils.isEmptyObj(request.claims) ||
234
+ (this.config.authOptions.clientCapabilities &&
235
+ this.config.authOptions.clientCapabilities.length > 0)) {
236
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
237
+ }
238
+ let ccsCred = undefined;
239
+ if (request.clientInfo) {
240
+ try {
241
+ const clientInfo = buildClientInfo(request.clientInfo, this.cryptoUtils);
242
+ ccsCred = {
243
+ credential: `${clientInfo.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfo.utid}`,
244
+ type: CcsCredentialType.HOME_ACCOUNT_ID,
245
+ };
246
+ }
247
+ catch (e) {
248
+ this.logger.verbose("Could not parse client info for CCS Header: " + e);
249
+ }
250
+ }
251
+ else {
252
+ ccsCred = request.ccsCredential;
253
+ }
254
+ // Adds these as parameters in the request instead of headers to prevent CORS preflight request
255
+ if (this.config.systemOptions.preventCorsPreflight && ccsCred) {
256
+ switch (ccsCred.type) {
257
+ case CcsCredentialType.HOME_ACCOUNT_ID:
258
+ try {
259
+ const clientInfo = buildClientInfoFromHomeAccountId(ccsCred.credential);
260
+ parameterBuilder.addCcsOid(clientInfo);
261
+ }
262
+ catch (e) {
263
+ this.logger.verbose("Could not parse home account ID for CCS Header: " +
264
+ e);
265
+ }
266
+ break;
267
+ case CcsCredentialType.UPN:
268
+ parameterBuilder.addCcsUpn(ccsCred.credential);
269
+ break;
270
+ }
271
+ }
272
+ if (request.tokenBodyParameters) {
273
+ parameterBuilder.addExtraQueryParameters(request.tokenBodyParameters);
274
+ }
275
+ // Add hybrid spa parameters if not already provided
276
+ if (request.enableSpaAuthorizationCode &&
277
+ (!request.tokenBodyParameters ||
278
+ !request.tokenBodyParameters[AADServerParamKeys.RETURN_SPA_CODE])) {
279
+ parameterBuilder.addExtraQueryParameters({
280
+ [AADServerParamKeys.RETURN_SPA_CODE]: "1",
281
+ });
282
+ }
283
+ return parameterBuilder.createQueryString();
284
+ }
285
+ /**
286
+ * This API validates the `AuthorizationCodeUrlRequest` and creates a URL
287
+ * @param request
288
+ */
289
+ async createAuthCodeUrlQueryString(request) {
290
+ this.performanceClient?.addQueueMeasurement(PerformanceEvents.AuthClientCreateQueryString, request.correlationId);
291
+ const parameterBuilder = new RequestParameterBuilder();
292
+ parameterBuilder.addClientId(this.config.authOptions.clientId);
293
+ const requestScopes = [
294
+ ...(request.scopes || []),
295
+ ...(request.extraScopesToConsent || []),
296
+ ];
297
+ parameterBuilder.addScopes(requestScopes);
298
+ // validate the redirectUri (to be a non null value)
299
+ parameterBuilder.addRedirectUri(request.redirectUri);
300
+ // generate the correlationId if not set by the user and add
301
+ const correlationId = request.correlationId ||
302
+ this.config.cryptoInterface.createNewGuid();
303
+ parameterBuilder.addCorrelationId(correlationId);
304
+ // add response_mode. If not passed in it defaults to query.
305
+ parameterBuilder.addResponseMode(request.responseMode);
306
+ // add response_type = code
307
+ parameterBuilder.addResponseTypeCode();
308
+ // add library info parameters
309
+ parameterBuilder.addLibraryInfo(this.config.libraryInfo);
310
+ parameterBuilder.addApplicationTelemetry(this.config.telemetry.application);
311
+ // add client_info=1
312
+ parameterBuilder.addClientInfo();
313
+ if (request.codeChallenge && request.codeChallengeMethod) {
314
+ parameterBuilder.addCodeChallengeParams(request.codeChallenge, request.codeChallengeMethod);
315
+ }
316
+ if (request.prompt) {
317
+ parameterBuilder.addPrompt(request.prompt);
318
+ }
319
+ if (request.domainHint) {
320
+ parameterBuilder.addDomainHint(request.domainHint);
321
+ }
322
+ // Add sid or loginHint with preference for login_hint claim (in request) -> sid -> loginHint (upn/email) -> username of AccountInfo object
323
+ if (request.prompt !== PromptValue.SELECT_ACCOUNT) {
324
+ // AAD will throw if prompt=select_account is passed with an account hint
325
+ if (request.sid && request.prompt === PromptValue.NONE) {
326
+ // SessionID is only used in silent calls
327
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from request");
328
+ parameterBuilder.addSid(request.sid);
329
+ }
330
+ else if (request.account) {
331
+ const accountSid = this.extractAccountSid(request.account);
332
+ const accountLoginHintClaim = this.extractLoginHint(request.account);
333
+ // If login_hint claim is present, use it over sid/username
334
+ if (accountLoginHintClaim) {
335
+ this.logger.verbose("createAuthCodeUrlQueryString: login_hint claim present on account");
336
+ parameterBuilder.addLoginHint(accountLoginHintClaim);
337
+ try {
338
+ const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
339
+ parameterBuilder.addCcsOid(clientInfo);
340
+ }
341
+ catch (e) {
342
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
343
+ }
344
+ }
345
+ else if (accountSid && request.prompt === PromptValue.NONE) {
346
+ /*
347
+ * If account and loginHint are provided, we will check account first for sid before adding loginHint
348
+ * SessionId is only used in silent calls
349
+ */
350
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is none, adding sid from account");
351
+ parameterBuilder.addSid(accountSid);
352
+ try {
353
+ const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
354
+ parameterBuilder.addCcsOid(clientInfo);
355
+ }
356
+ catch (e) {
357
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
358
+ }
359
+ }
360
+ else if (request.loginHint) {
361
+ this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from request");
362
+ parameterBuilder.addLoginHint(request.loginHint);
363
+ parameterBuilder.addCcsUpn(request.loginHint);
364
+ }
365
+ else if (request.account.username) {
366
+ // Fallback to account username if provided
367
+ this.logger.verbose("createAuthCodeUrlQueryString: Adding login_hint from account");
368
+ parameterBuilder.addLoginHint(request.account.username);
369
+ try {
370
+ const clientInfo = buildClientInfoFromHomeAccountId(request.account.homeAccountId);
371
+ parameterBuilder.addCcsOid(clientInfo);
372
+ }
373
+ catch (e) {
374
+ this.logger.verbose("createAuthCodeUrlQueryString: Could not parse home account ID for CCS Header");
375
+ }
376
+ }
377
+ }
378
+ else if (request.loginHint) {
379
+ this.logger.verbose("createAuthCodeUrlQueryString: No account, adding login_hint from request");
380
+ parameterBuilder.addLoginHint(request.loginHint);
381
+ parameterBuilder.addCcsUpn(request.loginHint);
382
+ }
383
+ }
384
+ else {
385
+ this.logger.verbose("createAuthCodeUrlQueryString: Prompt is select_account, ignoring account hints");
386
+ }
387
+ if (request.nonce) {
388
+ parameterBuilder.addNonce(request.nonce);
389
+ }
390
+ if (request.state) {
391
+ parameterBuilder.addState(request.state);
392
+ }
393
+ if (!StringUtils.isEmpty(request.claims) ||
394
+ (this.config.authOptions.clientCapabilities &&
395
+ this.config.authOptions.clientCapabilities.length > 0)) {
396
+ parameterBuilder.addClaims(request.claims, this.config.authOptions.clientCapabilities);
397
+ }
398
+ if (request.extraQueryParameters) {
399
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
400
+ }
401
+ if (request.nativeBroker) {
402
+ // signal ests that this is a WAM call
403
+ parameterBuilder.addNativeBroker();
404
+ // pass the req_cnf for POP
405
+ if (request.authenticationScheme === AuthenticationScheme.POP) {
406
+ const popTokenGenerator = new PopTokenGenerator(this.cryptoUtils);
407
+ // to reduce the URL length, it is recommended to send the hash of the req_cnf instead of the whole string
408
+ const reqCnfData = await popTokenGenerator.generateCnf(request);
409
+ parameterBuilder.addPopToken(reqCnfData.reqCnfHash);
410
+ }
411
+ }
412
+ return parameterBuilder.createQueryString();
413
+ }
414
+ /**
415
+ * This API validates the `EndSessionRequest` and creates a URL
416
+ * @param request
417
+ */
418
+ createLogoutUrlQueryString(request) {
419
+ const parameterBuilder = new RequestParameterBuilder();
420
+ if (request.postLogoutRedirectUri) {
421
+ parameterBuilder.addPostLogoutRedirectUri(request.postLogoutRedirectUri);
422
+ }
423
+ if (request.correlationId) {
424
+ parameterBuilder.addCorrelationId(request.correlationId);
425
+ }
426
+ if (request.idTokenHint) {
427
+ parameterBuilder.addIdTokenHint(request.idTokenHint);
428
+ }
429
+ if (request.state) {
430
+ parameterBuilder.addState(request.state);
431
+ }
432
+ if (request.logoutHint) {
433
+ parameterBuilder.addLogoutHint(request.logoutHint);
434
+ }
435
+ if (request.extraQueryParameters) {
436
+ parameterBuilder.addExtraQueryParameters(request.extraQueryParameters);
437
+ }
438
+ return parameterBuilder.createQueryString();
439
+ }
440
+ /**
441
+ * Helper to get sid from account. Returns null if idTokenClaims are not present or sid is not present.
442
+ * @param account
443
+ */
444
+ extractAccountSid(account) {
445
+ return account.idTokenClaims?.sid || null;
446
+ }
447
+ extractLoginHint(account) {
448
+ return account.idTokenClaims?.login_hint || null;
449
+ }
450
450
  }
451
451
 
452
452
  export { AuthorizationCodeClient };