@azure/msal-common 14.14.0 → 14.14.2

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