UNPKG

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