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