UNPKG

11.9 kBJavaScriptView Raw
1/*
2 * Copyright (c) Microsoft Corporation. All rights reserved.
3 * Licensed under the MIT License.
4 */
5import { __spreadArrays } from "tslib";
6import { CryptoUtils } from "./utils/CryptoUtils";
7import { SSOTypes, Constants, PromptState, ResponseTypes } from "./utils/Constants";
8import { ScopeSet } from "./ScopeSet";
9import { version as libraryVersion } from "./packageMetadata";
10/**
11 * Nonce: OIDC Nonce definition: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
12 * State: OAuth Spec: https://tools.ietf.org/html/rfc6749#section-10.12
13 * @hidden
14 */
15var ServerRequestParameters = /** @class */ (function () {
16 /**
17 * Constructor
18 * @param authority
19 * @param clientId
20 * @param scope
21 * @param responseType
22 * @param redirectUri
23 * @param state
24 */
25 function ServerRequestParameters(authority, clientId, responseType, redirectUri, scopes, state, correlationId) {
26 this.authorityInstance = authority;
27 this.clientId = clientId;
28 this.nonce = CryptoUtils.createNewGuid();
29 // set scope to clientId if null
30 this.scopes = scopes ? __spreadArrays(scopes) : Constants.oidcScopes;
31 this.scopes = ScopeSet.trimScopes(this.scopes);
32 // set state (already set at top level)
33 this.state = state;
34 // set correlationId
35 this.correlationId = correlationId;
36 // telemetry information
37 this.xClientSku = "MSAL.JS";
38 this.xClientVer = libraryVersion;
39 this.responseType = responseType;
40 this.redirectUri = redirectUri;
41 }
42 Object.defineProperty(ServerRequestParameters.prototype, "authority", {
43 get: function () {
44 return this.authorityInstance ? this.authorityInstance.CanonicalAuthority : null;
45 },
46 enumerable: false,
47 configurable: true
48 });
49 /**
50 * @hidden
51 * @ignore
52 *
53 * Utility to populate QueryParameters and ExtraQueryParameters to ServerRequestParamerers
54 * @param request
55 * @param serverAuthenticationRequest
56 */
57 ServerRequestParameters.prototype.populateQueryParams = function (account, request, adalIdTokenObject, silentCall) {
58 var queryParameters = {};
59 if (request) {
60 // add the prompt parameter to serverRequestParameters if passed
61 if (request.prompt) {
62 this.promptValue = request.prompt;
63 }
64 // Add claims challenge to serverRequestParameters if passed
65 if (request.claimsRequest) {
66 this.claimsValue = request.claimsRequest;
67 }
68 // if the developer provides one of these, give preference to developer choice
69 if (ServerRequestParameters.isSSOParam(request)) {
70 queryParameters = this.constructUnifiedCacheQueryParameter(request, null);
71 }
72 }
73 if (adalIdTokenObject) {
74 queryParameters = this.constructUnifiedCacheQueryParameter(null, adalIdTokenObject);
75 }
76 /*
77 * adds sid/login_hint if not populated
78 * this.logger.verbose("Calling addHint parameters");
79 */
80 queryParameters = this.addHintParameters(account, queryParameters);
81 // sanity check for developer passed extraQueryParameters
82 var eQParams = request ? request.extraQueryParameters : null;
83 // Populate the extraQueryParameters to be sent to the server
84 this.queryParameters = ServerRequestParameters.generateQueryParametersString(queryParameters);
85 this.extraQueryParameters = ServerRequestParameters.generateQueryParametersString(eQParams, silentCall);
86 };
87 // #region QueryParam helpers
88 /**
89 * Constructs extraQueryParameters to be sent to the server for the AuthenticationParameters set by the developer
90 * in any login() or acquireToken() calls
91 * @param idTokenObject
92 * @param extraQueryParameters
93 * @param sid
94 * @param loginHint
95 */
96 // TODO: check how this behaves when domain_hint only is sent in extraparameters and idToken has no upn.
97 ServerRequestParameters.prototype.constructUnifiedCacheQueryParameter = function (request, idTokenObject) {
98 var _a;
99 // preference order: account > sid > login_hint
100 var ssoType;
101 var ssoData;
102 var serverReqParam = {};
103 // if account info is passed, account.login_hint claim > account.sid > account.username
104 if (request) {
105 if (request.account) {
106 var account = request.account;
107 if ((_a = account.idTokenClaims) === null || _a === void 0 ? void 0 : _a.login_hint) {
108 ssoType = SSOTypes.LOGIN_HINT;
109 ssoData = account.idTokenClaims.login_hint;
110 }
111 else if (account.sid) {
112 ssoType = SSOTypes.SID;
113 ssoData = account.sid;
114 }
115 else if (account.userName) {
116 ssoType = SSOTypes.LOGIN_HINT;
117 ssoData = account.userName;
118 }
119 }
120 // sid from request
121 else if (request.sid) {
122 ssoType = SSOTypes.SID;
123 ssoData = request.sid;
124 }
125 // loginHint from request
126 else if (request.loginHint) {
127 ssoType = SSOTypes.LOGIN_HINT;
128 ssoData = request.loginHint;
129 }
130 }
131 // adalIdToken retrieved from cache
132 else if (idTokenObject) {
133 if (idTokenObject.hasOwnProperty(Constants.upn)) {
134 ssoType = SSOTypes.ID_TOKEN;
135 ssoData = idTokenObject["upn"];
136 }
137 }
138 serverReqParam = this.addSSOParameter(ssoType, ssoData);
139 return serverReqParam;
140 };
141 /**
142 * @hidden
143 *
144 * Adds login_hint to authorization URL which is used to pre-fill the username field of sign in page for the user if known ahead of time
145 * domain_hint if added skips the email based discovery process of the user - only supported for interactive calls in implicit_flow
146 * domain_req utid received as part of the clientInfo
147 * login_req uid received as part of clientInfo
148 * Also does a sanity check for extraQueryParameters passed by the user to ensure no repeat queryParameters
149 *
150 * @param {@link Account} account - Account for which the token is requested
151 * @param queryparams
152 * @param {@link ServerRequestParameters}
153 * @ignore
154 */
155 ServerRequestParameters.prototype.addHintParameters = function (account, params) {
156 var _a, _b;
157 /*
158 * This is a final check for all queryParams added so far; preference order: sid > login_hint
159 * sid cannot be passed along with login_hint or domain_hint, hence we check both are not populated yet in queryParameters
160 */
161 var qParams = params;
162 if (account) {
163 if (!qParams[SSOTypes.SID] && !qParams[SSOTypes.LOGIN_HINT]) {
164 if ((_a = account.idTokenClaims) === null || _a === void 0 ? void 0 : _a.login_hint) {
165 // Use login_hint claim if available over sid or email/upn
166 qParams = this.addSSOParameter(SSOTypes.LOGIN_HINT, (_b = account.idTokenClaims) === null || _b === void 0 ? void 0 : _b.login_hint, qParams);
167 }
168 else if (account.sid && this.promptValue === PromptState.NONE) {
169 // sid - populate only if login_hint is not already populated and the account has sid
170 qParams = this.addSSOParameter(SSOTypes.SID, account.sid, qParams);
171 }
172 else if (account.userName) {
173 // Add username/upn as loginHint if nothing else available
174 qParams = this.addSSOParameter(SSOTypes.LOGIN_HINT, account.userName, qParams);
175 }
176 }
177 }
178 return qParams;
179 };
180 /**
181 * Add SID to extraQueryParameters
182 * @param sid
183 */
184 ServerRequestParameters.prototype.addSSOParameter = function (ssoType, ssoData, params) {
185 var ssoParam = params || {};
186 if (!ssoData) {
187 return ssoParam;
188 }
189 switch (ssoType) {
190 case SSOTypes.SID: {
191 ssoParam[SSOTypes.SID] = ssoData;
192 break;
193 }
194 case SSOTypes.ID_TOKEN: {
195 ssoParam[SSOTypes.LOGIN_HINT] = ssoData;
196 break;
197 }
198 case SSOTypes.LOGIN_HINT: {
199 ssoParam[SSOTypes.LOGIN_HINT] = ssoData;
200 break;
201 }
202 }
203 return ssoParam;
204 };
205 /**
206 * Utility to generate a QueryParameterString from a Key-Value mapping of extraQueryParameters passed
207 * @param extraQueryParameters
208 */
209 ServerRequestParameters.generateQueryParametersString = function (queryParameters, silentCall) {
210 var paramsString = null;
211 if (queryParameters) {
212 Object.keys(queryParameters).forEach(function (key) {
213 // sid cannot be passed along with login_hint or domain_hint
214 if (key === Constants.domain_hint && (silentCall || queryParameters[SSOTypes.SID])) {
215 return;
216 }
217 if (!paramsString) {
218 paramsString = key + "=" + encodeURIComponent(queryParameters[key]);
219 }
220 else {
221 paramsString += "&" + key + "=" + encodeURIComponent(queryParameters[key]);
222 }
223 });
224 }
225 return paramsString;
226 };
227 // #endregion
228 /**
229 * Check to see if there are SSO params set in the Request
230 * @param request
231 */
232 ServerRequestParameters.isSSOParam = function (request) {
233 return !!(request && (request.account || request.sid || request.loginHint));
234 };
235 /**
236 * Returns the correct response_type string attribute for an acquireToken request configuration
237 * @param accountsMatch boolean: Determines whether the account in the request matches the cached account
238 * @param scopes Array<string>: AuthenticationRequest scopes configuration
239 * @param loginScopesOnly boolean: True if the scopes array ONLY contains the clientId or any combination of OIDC scopes, without resource scopes
240 */
241 ServerRequestParameters.determineResponseType = function (accountsMatch, scopes) {
242 // Supports getting an id_token by sending in clientId as only scope or OIDC scopes as only scopes
243 if (ScopeSet.onlyContainsOidcScopes(scopes)) {
244 return ResponseTypes.id_token;
245 }
246 // If accounts match, check if OIDC scopes are included, otherwise return id_token_token
247 return (accountsMatch) ? this.responseTypeForMatchingAccounts(scopes) : ResponseTypes.id_token_token;
248 };
249 /**
250 * Returns the correct response_type string attribute for an acquireToken request configuration that contains an
251 * account that matches the account in the MSAL cache.
252 * @param scopes Array<string>: AuthenticationRequest scopes configuration
253 */
254 ServerRequestParameters.responseTypeForMatchingAccounts = function (scopes) {
255 // Opt-into also requesting an ID token by sending in 'openid', 'profile' or both along with resource scopes when login is not necessary.
256 return (ScopeSet.containsAnyOidcScopes(scopes)) ? ResponseTypes.id_token_token : ResponseTypes.token;
257 };
258 return ServerRequestParameters;
259}());
260export { ServerRequestParameters };
261//# sourceMappingURL=ServerRequestParameters.js.map
\No newline at end of file