UNPKG

120 kBJavaScriptView Raw
1/*
2 * Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5 * the License. A copy of the License is located at
6 *
7 * http://aws.amazon.com/apache2.0/
8 *
9 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11 * and limitations under the License.
12 */
13var __assign = (this && this.__assign) || function () {
14 __assign = Object.assign || function(t) {
15 for (var s, i = 1, n = arguments.length; i < n; i++) {
16 s = arguments[i];
17 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
18 t[p] = s[p];
19 }
20 return t;
21 };
22 return __assign.apply(this, arguments);
23};
24var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
25 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26 return new (P || (P = Promise))(function (resolve, reject) {
27 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30 step((generator = generator.apply(thisArg, _arguments || [])).next());
31 });
32};
33var __generator = (this && this.__generator) || function (thisArg, body) {
34 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
35 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
36 function verb(n) { return function (v) { return step([n, v]); }; }
37 function step(op) {
38 if (f) throw new TypeError("Generator is already executing.");
39 while (_) try {
40 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
41 if (y = 0, t) op = [op[0] & 2, t.value];
42 switch (op[0]) {
43 case 0: case 1: t = op; break;
44 case 4: _.label++; return { value: op[1], done: false };
45 case 5: _.label++; y = op[1]; op = [0]; continue;
46 case 7: op = _.ops.pop(); _.trys.pop(); continue;
47 default:
48 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
49 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
50 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
51 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
52 if (t[2]) _.ops.pop();
53 _.trys.pop(); continue;
54 }
55 op = body.call(thisArg, _);
56 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
57 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
58 }
59};
60var __read = (this && this.__read) || function (o, n) {
61 var m = typeof Symbol === "function" && o[Symbol.iterator];
62 if (!m) return o;
63 var i = m.call(o), r, ar = [], e;
64 try {
65 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
66 }
67 catch (error) { e = { error: error }; }
68 finally {
69 try {
70 if (r && !r.done && (m = i["return"])) m.call(i);
71 }
72 finally { if (e) throw e.error; }
73 }
74 return ar;
75};
76import { isUsernamePasswordOpts, isCognitoHostedOpts, isFederatedSignInOptions, isFederatedSignInOptionsCustom, hasCustomState, } from './types';
77import { Amplify, ConsoleLogger as Logger, Credentials, Hub, StorageHelper, Parser, JS, UniversalStorage, urlSafeDecode, } from '@aws-amplify/core';
78import { CookieStorage, CognitoUserPool, AuthenticationDetails, CognitoUser, CognitoUserSession, CognitoUserAttribute, CognitoIdToken, CognitoRefreshToken, CognitoAccessToken, } from 'amazon-cognito-identity-js';
79import { parse } from 'url';
80import OAuth from './OAuth/OAuth';
81import { default as urlListener } from './urlListener';
82import { AuthError, NoUserPoolError } from './Errors';
83import { AuthErrorTypes, CognitoHostedUIIdentityProvider, } from './types/Auth';
84var logger = new Logger('AuthClass');
85var USER_ADMIN_SCOPE = 'aws.cognito.signin.user.admin';
86// 10 sec, following this guide https://www.nngroup.com/articles/response-times-3-important-limits/
87var OAUTH_FLOW_MS_TIMEOUT = 10 * 1000;
88var AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'
89 ? Symbol.for('amplify_default')
90 : '@@amplify_default');
91var dispatchAuthEvent = function (event, data, message) {
92 Hub.dispatch('auth', { event: event, data: data, message: message }, 'Auth', AMPLIFY_SYMBOL);
93};
94// Cognito Documentation for max device
95// tslint:disable-next-line:max-line-length
96// https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListDevices.html#API_ListDevices_RequestSyntax
97var MAX_DEVICES = 60;
98/**
99 * Provide authentication steps
100 */
101var AuthClass = /** @class */ (function () {
102 /**
103 * Initialize Auth with AWS configurations
104 * @param {Object} config - Configuration of the Auth
105 */
106 function AuthClass(config) {
107 var _this = this;
108 this.userPool = null;
109 this.user = null;
110 this.oAuthFlowInProgress = false;
111 this.Credentials = Credentials;
112 this.wrapRefreshSessionCallback = function (callback) {
113 var wrapped = function (error, data) {
114 if (data) {
115 dispatchAuthEvent('tokenRefresh', undefined, "New token retrieved");
116 }
117 else {
118 dispatchAuthEvent('tokenRefresh_failure', error, "Failed to retrieve new token");
119 }
120 return callback(error, data);
121 };
122 return wrapped;
123 }; // prettier-ignore
124 this.configure(config);
125 this.currentCredentials = this.currentCredentials.bind(this);
126 this.currentUserCredentials = this.currentUserCredentials.bind(this);
127 Hub.listen('auth', function (_a) {
128 var payload = _a.payload;
129 var event = payload.event;
130 switch (event) {
131 case 'signIn':
132 _this._storage.setItem('amplify-signin-with-hostedUI', 'false');
133 break;
134 case 'signOut':
135 _this._storage.removeItem('amplify-signin-with-hostedUI');
136 break;
137 case 'cognitoHostedUI':
138 _this._storage.setItem('amplify-signin-with-hostedUI', 'true');
139 break;
140 }
141 });
142 }
143 AuthClass.prototype.getModuleName = function () {
144 return 'Auth';
145 };
146 AuthClass.prototype.configure = function (config) {
147 var _this = this;
148 if (!config)
149 return this._config || {};
150 logger.debug('configure Auth');
151 var conf = Object.assign({}, this._config, Parser.parseMobilehubConfig(config).Auth, config);
152 this._config = conf;
153 var _a = this._config, userPoolId = _a.userPoolId, userPoolWebClientId = _a.userPoolWebClientId, cookieStorage = _a.cookieStorage, oauth = _a.oauth, region = _a.region, identityPoolId = _a.identityPoolId, mandatorySignIn = _a.mandatorySignIn, refreshHandlers = _a.refreshHandlers, identityPoolRegion = _a.identityPoolRegion, clientMetadata = _a.clientMetadata, endpoint = _a.endpoint;
154 if (!this._config.storage) {
155 // backward compatability
156 if (cookieStorage)
157 this._storage = new CookieStorage(cookieStorage);
158 else {
159 this._storage = config.ssr
160 ? new UniversalStorage()
161 : new StorageHelper().getStorage();
162 }
163 }
164 else {
165 if (!this._isValidAuthStorage(this._config.storage)) {
166 logger.error('The storage in the Auth config is not valid!');
167 throw new Error('Empty storage object');
168 }
169 this._storage = this._config.storage;
170 }
171 this._storageSync = Promise.resolve();
172 if (typeof this._storage['sync'] === 'function') {
173 this._storageSync = this._storage['sync']();
174 }
175 if (userPoolId) {
176 var userPoolData = {
177 UserPoolId: userPoolId,
178 ClientId: userPoolWebClientId,
179 endpoint: endpoint,
180 };
181 userPoolData.Storage = this._storage;
182 this.userPool = new CognitoUserPool(userPoolData, this.wrapRefreshSessionCallback);
183 }
184 this.Credentials.configure({
185 mandatorySignIn: mandatorySignIn,
186 region: identityPoolRegion || region,
187 userPoolId: userPoolId,
188 identityPoolId: identityPoolId,
189 refreshHandlers: refreshHandlers,
190 storage: this._storage,
191 });
192 // initialize cognitoauth client if hosted ui options provided
193 // to keep backward compatibility:
194 var cognitoHostedUIConfig = oauth
195 ? isCognitoHostedOpts(this._config.oauth)
196 ? oauth
197 : oauth.awsCognito
198 : undefined;
199 if (cognitoHostedUIConfig) {
200 var cognitoAuthParams = Object.assign({
201 cognitoClientId: userPoolWebClientId,
202 UserPoolId: userPoolId,
203 domain: cognitoHostedUIConfig['domain'],
204 scopes: cognitoHostedUIConfig['scope'],
205 redirectSignIn: cognitoHostedUIConfig['redirectSignIn'],
206 redirectSignOut: cognitoHostedUIConfig['redirectSignOut'],
207 responseType: cognitoHostedUIConfig['responseType'],
208 Storage: this._storage,
209 urlOpener: cognitoHostedUIConfig['urlOpener'],
210 clientMetadata: clientMetadata,
211 }, cognitoHostedUIConfig['options']);
212 this._oAuthHandler = new OAuth({
213 scopes: cognitoAuthParams.scopes,
214 config: cognitoAuthParams,
215 cognitoClientId: cognitoAuthParams.cognitoClientId,
216 });
217 // **NOTE** - Remove this in a future major release as it is a breaking change
218 // Prevents _handleAuthResponse from being called multiple times in Expo
219 // See https://github.com/aws-amplify/amplify-js/issues/4388
220 var usedResponseUrls_1 = {};
221 urlListener(function (_a) {
222 var url = _a.url;
223 if (usedResponseUrls_1[url]) {
224 return;
225 }
226 usedResponseUrls_1[url] = true;
227 _this._handleAuthResponse(url);
228 });
229 }
230 dispatchAuthEvent('configured', null, "The Auth category has been configured successfully");
231 return this._config;
232 };
233 /**
234 * Sign up with username, password and other attributes like phone, email
235 * @param {String | object} params - The user attributes used for signin
236 * @param {String[]} restOfAttrs - for the backward compatability
237 * @return - A promise resolves callback data if success
238 */
239 AuthClass.prototype.signUp = function (params) {
240 var _this = this;
241 var restOfAttrs = [];
242 for (var _i = 1; _i < arguments.length; _i++) {
243 restOfAttrs[_i - 1] = arguments[_i];
244 }
245 if (!this.userPool) {
246 return this.rejectNoUserPool();
247 }
248 var username = null;
249 var password = null;
250 var attributes = [];
251 var validationData = null;
252 var clientMetadata;
253 if (params && typeof params === 'string') {
254 username = params;
255 password = restOfAttrs ? restOfAttrs[0] : null;
256 var email = restOfAttrs ? restOfAttrs[1] : null;
257 var phone_number = restOfAttrs ? restOfAttrs[2] : null;
258 if (email)
259 attributes.push(new CognitoUserAttribute({ Name: 'email', Value: email }));
260 if (phone_number)
261 attributes.push(new CognitoUserAttribute({
262 Name: 'phone_number',
263 Value: phone_number,
264 }));
265 }
266 else if (params && typeof params === 'object') {
267 username = params['username'];
268 password = params['password'];
269 if (params && params.clientMetadata) {
270 clientMetadata = params.clientMetadata;
271 }
272 else if (this._config.clientMetadata) {
273 clientMetadata = this._config.clientMetadata;
274 }
275 var attrs_1 = params['attributes'];
276 if (attrs_1) {
277 Object.keys(attrs_1).map(function (key) {
278 attributes.push(new CognitoUserAttribute({ Name: key, Value: attrs_1[key] }));
279 });
280 }
281 var validationDataObject_1 = params['validationData'];
282 if (validationDataObject_1) {
283 validationData = [];
284 Object.keys(validationDataObject_1).map(function (key) {
285 validationData.push(new CognitoUserAttribute({
286 Name: key,
287 Value: validationDataObject_1[key],
288 }));
289 });
290 }
291 }
292 else {
293 return this.rejectAuthError(AuthErrorTypes.SignUpError);
294 }
295 if (!username) {
296 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
297 }
298 if (!password) {
299 return this.rejectAuthError(AuthErrorTypes.EmptyPassword);
300 }
301 logger.debug('signUp attrs:', attributes);
302 logger.debug('signUp validation data:', validationData);
303 return new Promise(function (resolve, reject) {
304 _this.userPool.signUp(username, password, attributes, validationData, function (err, data) {
305 if (err) {
306 dispatchAuthEvent('signUp_failure', err, username + " failed to signup");
307 reject(err);
308 }
309 else {
310 dispatchAuthEvent('signUp', data, username + " has signed up successfully");
311 resolve(data);
312 }
313 }, clientMetadata);
314 });
315 };
316 /**
317 * Send the verification code to confirm sign up
318 * @param {String} username - The username to be confirmed
319 * @param {String} code - The verification code
320 * @param {ConfirmSignUpOptions} options - other options for confirm signup
321 * @return - A promise resolves callback data if success
322 */
323 AuthClass.prototype.confirmSignUp = function (username, code, options) {
324 if (!this.userPool) {
325 return this.rejectNoUserPool();
326 }
327 if (!username) {
328 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
329 }
330 if (!code) {
331 return this.rejectAuthError(AuthErrorTypes.EmptyCode);
332 }
333 var user = this.createCognitoUser(username);
334 var forceAliasCreation = options && typeof options.forceAliasCreation === 'boolean'
335 ? options.forceAliasCreation
336 : true;
337 var clientMetadata;
338 if (options && options.clientMetadata) {
339 clientMetadata = options.clientMetadata;
340 }
341 else if (this._config.clientMetadata) {
342 clientMetadata = this._config.clientMetadata;
343 }
344 return new Promise(function (resolve, reject) {
345 user.confirmRegistration(code, forceAliasCreation, function (err, data) {
346 if (err) {
347 reject(err);
348 }
349 else {
350 resolve(data);
351 }
352 }, clientMetadata);
353 });
354 };
355 /**
356 * Resend the verification code
357 * @param {String} username - The username to be confirmed
358 * @param {ClientMetadata} clientMetadata - Metadata to be passed to Cognito Lambda triggers
359 * @return - A promise resolves code delivery details if successful
360 */
361 AuthClass.prototype.resendSignUp = function (username, clientMetadata) {
362 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
363 if (!this.userPool) {
364 return this.rejectNoUserPool();
365 }
366 if (!username) {
367 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
368 }
369 var user = this.createCognitoUser(username);
370 return new Promise(function (resolve, reject) {
371 user.resendConfirmationCode(function (err, data) {
372 if (err) {
373 reject(err);
374 }
375 else {
376 resolve(data);
377 }
378 }, clientMetadata);
379 });
380 };
381 /**
382 * Sign in
383 * @param {String | SignInOpts} usernameOrSignInOpts - The username to be signed in or the sign in options
384 * @param {String} password - The password of the username
385 * @return - A promise resolves the CognitoUser
386 */
387 AuthClass.prototype.signIn = function (usernameOrSignInOpts, pw, clientMetadata) {
388 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
389 if (!this.userPool) {
390 return this.rejectNoUserPool();
391 }
392 var username = null;
393 var password = null;
394 var validationData = {};
395 // for backward compatibility
396 if (typeof usernameOrSignInOpts === 'string') {
397 username = usernameOrSignInOpts;
398 password = pw;
399 }
400 else if (isUsernamePasswordOpts(usernameOrSignInOpts)) {
401 if (typeof pw !== 'undefined') {
402 logger.warn('The password should be defined under the first parameter object!');
403 }
404 username = usernameOrSignInOpts.username;
405 password = usernameOrSignInOpts.password;
406 validationData = usernameOrSignInOpts.validationData;
407 }
408 else {
409 return this.rejectAuthError(AuthErrorTypes.InvalidUsername);
410 }
411 if (!username) {
412 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
413 }
414 var authDetails = new AuthenticationDetails({
415 Username: username,
416 Password: password,
417 ValidationData: validationData,
418 ClientMetadata: clientMetadata,
419 });
420 if (password) {
421 return this.signInWithPassword(authDetails);
422 }
423 else {
424 return this.signInWithoutPassword(authDetails);
425 }
426 };
427 /**
428 * Return an object with the authentication callbacks
429 * @param {CognitoUser} user - the cognito user object
430 * @param {} resolve - function called when resolving the current step
431 * @param {} reject - function called when rejecting the current step
432 * @return - an object with the callback methods for user authentication
433 */
434 AuthClass.prototype.authCallbacks = function (user, resolve, reject) {
435 var _this = this;
436 var that = this;
437 return {
438 onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () {
439 var cred, e_1, currentUser, e_2;
440 return __generator(this, function (_a) {
441 switch (_a.label) {
442 case 0:
443 logger.debug(session);
444 delete user['challengeName'];
445 delete user['challengeParam'];
446 _a.label = 1;
447 case 1:
448 _a.trys.push([1, 4, 5, 9]);
449 return [4 /*yield*/, this.Credentials.clear()];
450 case 2:
451 _a.sent();
452 return [4 /*yield*/, this.Credentials.set(session, 'session')];
453 case 3:
454 cred = _a.sent();
455 logger.debug('succeed to get cognito credentials', cred);
456 return [3 /*break*/, 9];
457 case 4:
458 e_1 = _a.sent();
459 logger.debug('cannot get cognito credentials', e_1);
460 return [3 /*break*/, 9];
461 case 5:
462 _a.trys.push([5, 7, , 8]);
463 return [4 /*yield*/, this.currentUserPoolUser()];
464 case 6:
465 currentUser = _a.sent();
466 that.user = currentUser;
467 dispatchAuthEvent('signIn', currentUser, "A user " + user.getUsername() + " has been signed in");
468 resolve(currentUser);
469 return [3 /*break*/, 8];
470 case 7:
471 e_2 = _a.sent();
472 logger.error('Failed to get the signed in user', e_2);
473 reject(e_2);
474 return [3 /*break*/, 8];
475 case 8: return [7 /*endfinally*/];
476 case 9: return [2 /*return*/];
477 }
478 });
479 }); },
480 onFailure: function (err) {
481 logger.debug('signIn failure', err);
482 dispatchAuthEvent('signIn_failure', err, user.getUsername() + " failed to signin");
483 reject(err);
484 },
485 customChallenge: function (challengeParam) {
486 logger.debug('signIn custom challenge answer required');
487 user['challengeName'] = 'CUSTOM_CHALLENGE';
488 user['challengeParam'] = challengeParam;
489 resolve(user);
490 },
491 mfaRequired: function (challengeName, challengeParam) {
492 logger.debug('signIn MFA required');
493 user['challengeName'] = challengeName;
494 user['challengeParam'] = challengeParam;
495 resolve(user);
496 },
497 mfaSetup: function (challengeName, challengeParam) {
498 logger.debug('signIn mfa setup', challengeName);
499 user['challengeName'] = challengeName;
500 user['challengeParam'] = challengeParam;
501 resolve(user);
502 },
503 newPasswordRequired: function (userAttributes, requiredAttributes) {
504 logger.debug('signIn new password');
505 user['challengeName'] = 'NEW_PASSWORD_REQUIRED';
506 user['challengeParam'] = {
507 userAttributes: userAttributes,
508 requiredAttributes: requiredAttributes,
509 };
510 resolve(user);
511 },
512 totpRequired: function (challengeName, challengeParam) {
513 logger.debug('signIn totpRequired');
514 user['challengeName'] = challengeName;
515 user['challengeParam'] = challengeParam;
516 resolve(user);
517 },
518 selectMFAType: function (challengeName, challengeParam) {
519 logger.debug('signIn selectMFAType', challengeName);
520 user['challengeName'] = challengeName;
521 user['challengeParam'] = challengeParam;
522 resolve(user);
523 },
524 };
525 };
526 /**
527 * Sign in with a password
528 * @private
529 * @param {AuthenticationDetails} authDetails - the user sign in data
530 * @return - A promise resolves the CognitoUser object if success or mfa required
531 */
532 AuthClass.prototype.signInWithPassword = function (authDetails) {
533 var _this = this;
534 if (this.pendingSignIn) {
535 throw new Error('Pending sign-in attempt already in progress');
536 }
537 var user = this.createCognitoUser(authDetails.getUsername());
538 this.pendingSignIn = new Promise(function (resolve, reject) {
539 user.authenticateUser(authDetails, _this.authCallbacks(user, function (value) {
540 _this.pendingSignIn = null;
541 resolve(value);
542 }, function (error) {
543 _this.pendingSignIn = null;
544 reject(error);
545 }));
546 });
547 return this.pendingSignIn;
548 };
549 /**
550 * Sign in without a password
551 * @private
552 * @param {AuthenticationDetails} authDetails - the user sign in data
553 * @return - A promise resolves the CognitoUser object if success or mfa required
554 */
555 AuthClass.prototype.signInWithoutPassword = function (authDetails) {
556 var _this = this;
557 var user = this.createCognitoUser(authDetails.getUsername());
558 user.setAuthenticationFlowType('CUSTOM_AUTH');
559 return new Promise(function (resolve, reject) {
560 user.initiateAuth(authDetails, _this.authCallbacks(user, resolve, reject));
561 });
562 };
563 /**
564 * This was previously used by an authenticated user to get MFAOptions,
565 * but no longer returns a meaningful response. Refer to the documentation for
566 * how to setup and use MFA: https://docs.amplify.aws/lib/auth/mfa/q/platform/js
567 * @deprecated
568 * @param {CognitoUser} user - the current user
569 * @return - A promise resolves the current preferred mfa option if success
570 */
571 AuthClass.prototype.getMFAOptions = function (user) {
572 return new Promise(function (res, rej) {
573 user.getMFAOptions(function (err, mfaOptions) {
574 if (err) {
575 logger.debug('get MFA Options failed', err);
576 rej(err);
577 return;
578 }
579 logger.debug('get MFA options success', mfaOptions);
580 res(mfaOptions);
581 return;
582 });
583 });
584 };
585 /**
586 * get preferred mfa method
587 * @param {CognitoUser} user - the current cognito user
588 * @param {GetPreferredMFAOpts} params - options for getting the current user preferred MFA
589 */
590 AuthClass.prototype.getPreferredMFA = function (user, params) {
591 var _this = this;
592 var that = this;
593 return new Promise(function (res, rej) {
594 var clientMetadata = _this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
595 var bypassCache = params ? params.bypassCache : false;
596 user.getUserData(function (err, data) { return __awaiter(_this, void 0, void 0, function () {
597 var cleanUpError_1, mfaType;
598 return __generator(this, function (_a) {
599 switch (_a.label) {
600 case 0:
601 if (!err) return [3 /*break*/, 5];
602 logger.debug('getting preferred mfa failed', err);
603 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
604 _a.label = 1;
605 case 1:
606 _a.trys.push([1, 3, , 4]);
607 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
608 case 2:
609 _a.sent();
610 return [3 /*break*/, 4];
611 case 3:
612 cleanUpError_1 = _a.sent();
613 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_1.message));
614 return [2 /*return*/];
615 case 4:
616 rej(err);
617 return [2 /*return*/];
618 case 5:
619 mfaType = that._getMfaTypeFromUserData(data);
620 if (!mfaType) {
621 rej('invalid MFA Type');
622 return [2 /*return*/];
623 }
624 else {
625 res(mfaType);
626 return [2 /*return*/];
627 }
628 return [2 /*return*/];
629 }
630 });
631 }); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
632 });
633 };
634 AuthClass.prototype._getMfaTypeFromUserData = function (data) {
635 var ret = null;
636 var preferredMFA = data.PreferredMfaSetting;
637 // if the user has used Auth.setPreferredMFA() to setup the mfa type
638 // then the "PreferredMfaSetting" would exist in the response
639 if (preferredMFA) {
640 ret = preferredMFA;
641 }
642 else {
643 // if mfaList exists but empty, then its noMFA
644 var mfaList = data.UserMFASettingList;
645 if (!mfaList) {
646 // if SMS was enabled by using Auth.enableSMS(),
647 // the response would contain MFAOptions
648 // as for now Cognito only supports for SMS, so we will say it is 'SMS_MFA'
649 // if it does not exist, then it should be NOMFA
650 var MFAOptions = data.MFAOptions;
651 if (MFAOptions) {
652 ret = 'SMS_MFA';
653 }
654 else {
655 ret = 'NOMFA';
656 }
657 }
658 else if (mfaList.length === 0) {
659 ret = 'NOMFA';
660 }
661 else {
662 logger.debug('invalid case for getPreferredMFA', data);
663 }
664 }
665 return ret;
666 };
667 AuthClass.prototype._getUserData = function (user, params) {
668 var _this = this;
669 return new Promise(function (res, rej) {
670 user.getUserData(function (err, data) { return __awaiter(_this, void 0, void 0, function () {
671 var cleanUpError_2;
672 return __generator(this, function (_a) {
673 switch (_a.label) {
674 case 0:
675 if (!err) return [3 /*break*/, 5];
676 logger.debug('getting user data failed', err);
677 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
678 _a.label = 1;
679 case 1:
680 _a.trys.push([1, 3, , 4]);
681 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
682 case 2:
683 _a.sent();
684 return [3 /*break*/, 4];
685 case 3:
686 cleanUpError_2 = _a.sent();
687 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_2.message));
688 return [2 /*return*/];
689 case 4:
690 rej(err);
691 return [2 /*return*/];
692 case 5:
693 res(data);
694 _a.label = 6;
695 case 6: return [2 /*return*/];
696 }
697 });
698 }); }, params);
699 });
700 };
701 /**
702 * set preferred MFA method
703 * @param {CognitoUser} user - the current Cognito user
704 * @param {string} mfaMethod - preferred mfa method
705 * @return - A promise resolve if success
706 */
707 AuthClass.prototype.setPreferredMFA = function (user, mfaMethod) {
708 return __awaiter(this, void 0, void 0, function () {
709 var clientMetadata, userData, smsMfaSettings, totpMfaSettings, _a, mfaList, currentMFAType, that;
710 var _this = this;
711 return __generator(this, function (_b) {
712 switch (_b.label) {
713 case 0:
714 clientMetadata = this._config.clientMetadata;
715 return [4 /*yield*/, this._getUserData(user, {
716 bypassCache: true,
717 clientMetadata: clientMetadata,
718 })];
719 case 1:
720 userData = _b.sent();
721 smsMfaSettings = null;
722 totpMfaSettings = null;
723 _a = mfaMethod;
724 switch (_a) {
725 case 'TOTP': return [3 /*break*/, 2];
726 case 'SOFTWARE_TOKEN_MFA': return [3 /*break*/, 2];
727 case 'SMS': return [3 /*break*/, 3];
728 case 'SMS_MFA': return [3 /*break*/, 3];
729 case 'NOMFA': return [3 /*break*/, 4];
730 }
731 return [3 /*break*/, 6];
732 case 2:
733 totpMfaSettings = {
734 PreferredMfa: true,
735 Enabled: true,
736 };
737 return [3 /*break*/, 7];
738 case 3:
739 smsMfaSettings = {
740 PreferredMfa: true,
741 Enabled: true,
742 };
743 return [3 /*break*/, 7];
744 case 4:
745 mfaList = userData['UserMFASettingList'];
746 return [4 /*yield*/, this._getMfaTypeFromUserData(userData)];
747 case 5:
748 currentMFAType = _b.sent();
749 if (currentMFAType === 'NOMFA') {
750 return [2 /*return*/, Promise.resolve('No change for mfa type')];
751 }
752 else if (currentMFAType === 'SMS_MFA') {
753 smsMfaSettings = {
754 PreferredMfa: false,
755 Enabled: false,
756 };
757 }
758 else if (currentMFAType === 'SOFTWARE_TOKEN_MFA') {
759 totpMfaSettings = {
760 PreferredMfa: false,
761 Enabled: false,
762 };
763 }
764 else {
765 return [2 /*return*/, this.rejectAuthError(AuthErrorTypes.InvalidMFA)];
766 }
767 // if there is a UserMFASettingList in the response
768 // we need to disable every mfa type in that list
769 if (mfaList && mfaList.length !== 0) {
770 // to disable SMS or TOTP if exists in that list
771 mfaList.forEach(function (mfaType) {
772 if (mfaType === 'SMS_MFA') {
773 smsMfaSettings = {
774 PreferredMfa: false,
775 Enabled: false,
776 };
777 }
778 else if (mfaType === 'SOFTWARE_TOKEN_MFA') {
779 totpMfaSettings = {
780 PreferredMfa: false,
781 Enabled: false,
782 };
783 }
784 });
785 }
786 return [3 /*break*/, 7];
787 case 6:
788 logger.debug('no validmfa method provided');
789 return [2 /*return*/, this.rejectAuthError(AuthErrorTypes.NoMFA)];
790 case 7:
791 that = this;
792 return [2 /*return*/, new Promise(function (res, rej) {
793 user.setUserMfaPreference(smsMfaSettings, totpMfaSettings, function (err, result) {
794 if (err) {
795 logger.debug('Set user mfa preference error', err);
796 return rej(err);
797 }
798 logger.debug('Set user mfa success', result);
799 logger.debug('Caching the latest user data into local');
800 // cache the latest result into user data
801 user.getUserData(function (err, data) { return __awaiter(_this, void 0, void 0, function () {
802 var cleanUpError_3;
803 return __generator(this, function (_a) {
804 switch (_a.label) {
805 case 0:
806 if (!err) return [3 /*break*/, 5];
807 logger.debug('getting user data failed', err);
808 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
809 _a.label = 1;
810 case 1:
811 _a.trys.push([1, 3, , 4]);
812 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
813 case 2:
814 _a.sent();
815 return [3 /*break*/, 4];
816 case 3:
817 cleanUpError_3 = _a.sent();
818 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_3.message));
819 return [2 /*return*/];
820 case 4: return [2 /*return*/, rej(err)];
821 case 5: return [2 /*return*/, res(result)];
822 }
823 });
824 }); }, {
825 bypassCache: true,
826 clientMetadata: clientMetadata,
827 });
828 });
829 })];
830 }
831 });
832 });
833 };
834 /**
835 * disable SMS
836 * @deprecated
837 * @param {CognitoUser} user - the current user
838 * @return - A promise resolves is success
839 */
840 AuthClass.prototype.disableSMS = function (user) {
841 return new Promise(function (res, rej) {
842 user.disableMFA(function (err, data) {
843 if (err) {
844 logger.debug('disable mfa failed', err);
845 rej(err);
846 return;
847 }
848 logger.debug('disable mfa succeed', data);
849 res(data);
850 return;
851 });
852 });
853 };
854 /**
855 * enable SMS
856 * @deprecated
857 * @param {CognitoUser} user - the current user
858 * @return - A promise resolves is success
859 */
860 AuthClass.prototype.enableSMS = function (user) {
861 return new Promise(function (res, rej) {
862 user.enableMFA(function (err, data) {
863 if (err) {
864 logger.debug('enable mfa failed', err);
865 rej(err);
866 return;
867 }
868 logger.debug('enable mfa succeed', data);
869 res(data);
870 return;
871 });
872 });
873 };
874 /**
875 * Setup TOTP
876 * @param {CognitoUser} user - the current user
877 * @return - A promise resolves with the secret code if success
878 */
879 AuthClass.prototype.setupTOTP = function (user) {
880 return new Promise(function (res, rej) {
881 user.associateSoftwareToken({
882 onFailure: function (err) {
883 logger.debug('associateSoftwareToken failed', err);
884 rej(err);
885 return;
886 },
887 associateSecretCode: function (secretCode) {
888 logger.debug('associateSoftwareToken sucess', secretCode);
889 res(secretCode);
890 return;
891 },
892 });
893 });
894 };
895 /**
896 * verify TOTP setup
897 * @param {CognitoUser} user - the current user
898 * @param {string} challengeAnswer - challenge answer
899 * @return - A promise resolves is success
900 */
901 AuthClass.prototype.verifyTotpToken = function (user, challengeAnswer) {
902 logger.debug('verification totp token', user, challengeAnswer);
903 return new Promise(function (res, rej) {
904 user.verifySoftwareToken(challengeAnswer, 'My TOTP device', {
905 onFailure: function (err) {
906 logger.debug('verifyTotpToken failed', err);
907 rej(err);
908 return;
909 },
910 onSuccess: function (data) {
911 dispatchAuthEvent('signIn', user, "A user " + user.getUsername() + " has been signed in");
912 logger.debug('verifyTotpToken success', data);
913 res(data);
914 return;
915 },
916 });
917 });
918 };
919 /**
920 * Send MFA code to confirm sign in
921 * @param {Object} user - The CognitoUser object
922 * @param {String} code - The confirmation code
923 */
924 AuthClass.prototype.confirmSignIn = function (user, code, mfaType, clientMetadata) {
925 var _this = this;
926 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
927 if (!code) {
928 return this.rejectAuthError(AuthErrorTypes.EmptyCode);
929 }
930 var that = this;
931 return new Promise(function (resolve, reject) {
932 user.sendMFACode(code, {
933 onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () {
934 var cred, e_3;
935 return __generator(this, function (_a) {
936 switch (_a.label) {
937 case 0:
938 logger.debug(session);
939 _a.label = 1;
940 case 1:
941 _a.trys.push([1, 4, 5, 6]);
942 return [4 /*yield*/, this.Credentials.clear()];
943 case 2:
944 _a.sent();
945 return [4 /*yield*/, this.Credentials.set(session, 'session')];
946 case 3:
947 cred = _a.sent();
948 logger.debug('succeed to get cognito credentials', cred);
949 return [3 /*break*/, 6];
950 case 4:
951 e_3 = _a.sent();
952 logger.debug('cannot get cognito credentials', e_3);
953 return [3 /*break*/, 6];
954 case 5:
955 that.user = user;
956 dispatchAuthEvent('signIn', user, "A user " + user.getUsername() + " has been signed in");
957 resolve(user);
958 return [7 /*endfinally*/];
959 case 6: return [2 /*return*/];
960 }
961 });
962 }); },
963 onFailure: function (err) {
964 logger.debug('confirm signIn failure', err);
965 reject(err);
966 },
967 }, mfaType, clientMetadata);
968 });
969 };
970 AuthClass.prototype.completeNewPassword = function (user, password, requiredAttributes, clientMetadata) {
971 var _this = this;
972 if (requiredAttributes === void 0) { requiredAttributes = {}; }
973 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
974 if (!password) {
975 return this.rejectAuthError(AuthErrorTypes.EmptyPassword);
976 }
977 var that = this;
978 return new Promise(function (resolve, reject) {
979 user.completeNewPasswordChallenge(password, requiredAttributes, {
980 onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () {
981 var cred, e_4;
982 return __generator(this, function (_a) {
983 switch (_a.label) {
984 case 0:
985 logger.debug(session);
986 _a.label = 1;
987 case 1:
988 _a.trys.push([1, 4, 5, 6]);
989 return [4 /*yield*/, this.Credentials.clear()];
990 case 2:
991 _a.sent();
992 return [4 /*yield*/, this.Credentials.set(session, 'session')];
993 case 3:
994 cred = _a.sent();
995 logger.debug('succeed to get cognito credentials', cred);
996 return [3 /*break*/, 6];
997 case 4:
998 e_4 = _a.sent();
999 logger.debug('cannot get cognito credentials', e_4);
1000 return [3 /*break*/, 6];
1001 case 5:
1002 that.user = user;
1003 dispatchAuthEvent('signIn', user, "A user " + user.getUsername() + " has been signed in");
1004 resolve(user);
1005 return [7 /*endfinally*/];
1006 case 6: return [2 /*return*/];
1007 }
1008 });
1009 }); },
1010 onFailure: function (err) {
1011 logger.debug('completeNewPassword failure', err);
1012 dispatchAuthEvent('completeNewPassword_failure', err, _this.user + " failed to complete the new password flow");
1013 reject(err);
1014 },
1015 mfaRequired: function (challengeName, challengeParam) {
1016 logger.debug('signIn MFA required');
1017 user['challengeName'] = challengeName;
1018 user['challengeParam'] = challengeParam;
1019 resolve(user);
1020 },
1021 mfaSetup: function (challengeName, challengeParam) {
1022 logger.debug('signIn mfa setup', challengeName);
1023 user['challengeName'] = challengeName;
1024 user['challengeParam'] = challengeParam;
1025 resolve(user);
1026 },
1027 totpRequired: function (challengeName, challengeParam) {
1028 logger.debug('signIn mfa setup', challengeName);
1029 user['challengeName'] = challengeName;
1030 user['challengeParam'] = challengeParam;
1031 resolve(user);
1032 },
1033 }, clientMetadata);
1034 });
1035 };
1036 /**
1037 * Send the answer to a custom challenge
1038 * @param {CognitoUser} user - The CognitoUser object
1039 * @param {String} challengeResponses - The confirmation code
1040 */
1041 AuthClass.prototype.sendCustomChallengeAnswer = function (user, challengeResponses, clientMetadata) {
1042 var _this = this;
1043 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1044 if (!this.userPool) {
1045 return this.rejectNoUserPool();
1046 }
1047 if (!challengeResponses) {
1048 return this.rejectAuthError(AuthErrorTypes.EmptyChallengeResponse);
1049 }
1050 var that = this;
1051 return new Promise(function (resolve, reject) {
1052 user.sendCustomChallengeAnswer(challengeResponses, _this.authCallbacks(user, resolve, reject), clientMetadata);
1053 });
1054 };
1055 /**
1056 * Delete an authenticated users' attributes
1057 * @param {CognitoUser} - The currently logged in user object
1058 * @return {Promise}
1059 **/
1060 AuthClass.prototype.deleteUserAttributes = function (user, attributeNames) {
1061 var that = this;
1062 return new Promise(function (resolve, reject) {
1063 that.userSession(user).then(function (session) {
1064 user.deleteAttributes(attributeNames, function (err, result) {
1065 if (err) {
1066 return reject(err);
1067 }
1068 else {
1069 return resolve(result);
1070 }
1071 });
1072 });
1073 });
1074 };
1075 /**
1076 * Delete the current authenticated user
1077 * @return {Promise}
1078 **/
1079 // TODO: Check return type void
1080 AuthClass.prototype.deleteUser = function () {
1081 return __awaiter(this, void 0, void 0, function () {
1082 var e_5, isSignedInHostedUI;
1083 var _this = this;
1084 return __generator(this, function (_a) {
1085 switch (_a.label) {
1086 case 0:
1087 _a.trys.push([0, 2, , 3]);
1088 return [4 /*yield*/, this._storageSync];
1089 case 1:
1090 _a.sent();
1091 return [3 /*break*/, 3];
1092 case 2:
1093 e_5 = _a.sent();
1094 logger.debug('Failed to sync cache info into memory', e_5);
1095 throw new Error(e_5);
1096 case 3:
1097 isSignedInHostedUI = this._oAuthHandler &&
1098 this._storage.getItem('amplify-signin-with-hostedUI') === 'true';
1099 return [2 /*return*/, new Promise(function (res, rej) { return __awaiter(_this, void 0, void 0, function () {
1100 var user_1;
1101 var _this = this;
1102 return __generator(this, function (_a) {
1103 if (this.userPool) {
1104 user_1 = this.userPool.getCurrentUser();
1105 if (!user_1) {
1106 logger.debug('Failed to get user from user pool');
1107 return [2 /*return*/, rej(new Error('No current user.'))];
1108 }
1109 else {
1110 user_1.getSession(function (err, session) { return __awaiter(_this, void 0, void 0, function () {
1111 var cleanUpError_4;
1112 var _this = this;
1113 return __generator(this, function (_a) {
1114 switch (_a.label) {
1115 case 0:
1116 if (!err) return [3 /*break*/, 5];
1117 logger.debug('Failed to get the user session', err);
1118 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1119 _a.label = 1;
1120 case 1:
1121 _a.trys.push([1, 3, , 4]);
1122 return [4 /*yield*/, this.cleanUpInvalidSession(user_1)];
1123 case 2:
1124 _a.sent();
1125 return [3 /*break*/, 4];
1126 case 3:
1127 cleanUpError_4 = _a.sent();
1128 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_4.message));
1129 return [2 /*return*/];
1130 case 4: return [2 /*return*/, rej(err)];
1131 case 5:
1132 user_1.deleteUser(function (err, result) {
1133 if (err) {
1134 rej(err);
1135 }
1136 else {
1137 dispatchAuthEvent('userDeleted', result, 'The authenticated user has been deleted.');
1138 user_1.signOut();
1139 _this.user = null;
1140 try {
1141 _this.cleanCachedItems(); // clean aws credentials
1142 }
1143 catch (e) {
1144 // TODO: change to rejects in refactor
1145 logger.debug('failed to clear cached items');
1146 }
1147 if (isSignedInHostedUI) {
1148 _this.oAuthSignOutRedirect(res, rej);
1149 }
1150 else {
1151 dispatchAuthEvent('signOut', _this.user, "A user has been signed out");
1152 res(result);
1153 }
1154 }
1155 });
1156 _a.label = 6;
1157 case 6: return [2 /*return*/];
1158 }
1159 });
1160 }); });
1161 }
1162 }
1163 else {
1164 logger.debug('no Congito User pool');
1165 rej(new Error('Cognito User pool does not exist'));
1166 }
1167 return [2 /*return*/];
1168 });
1169 }); })];
1170 }
1171 });
1172 });
1173 };
1174 /**
1175 * Update an authenticated users' attributes
1176 * @param {CognitoUser} - The currently logged in user object
1177 * @return {Promise}
1178 **/
1179 AuthClass.prototype.updateUserAttributes = function (user, attributes, clientMetadata) {
1180 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1181 var attributeList = [];
1182 var that = this;
1183 return new Promise(function (resolve, reject) {
1184 that.userSession(user).then(function (session) {
1185 for (var key in attributes) {
1186 if (key !== 'sub' && key.indexOf('_verified') < 0) {
1187 var attr = {
1188 Name: key,
1189 Value: attributes[key],
1190 };
1191 attributeList.push(attr);
1192 }
1193 }
1194 user.updateAttributes(attributeList, function (err, result) {
1195 if (err) {
1196 return reject(err);
1197 }
1198 else {
1199 return resolve(result);
1200 }
1201 }, clientMetadata);
1202 });
1203 });
1204 };
1205 /**
1206 * Return user attributes
1207 * @param {Object} user - The CognitoUser object
1208 * @return - A promise resolves to user attributes if success
1209 */
1210 AuthClass.prototype.userAttributes = function (user) {
1211 var _this = this;
1212 return new Promise(function (resolve, reject) {
1213 _this.userSession(user).then(function (session) {
1214 user.getUserAttributes(function (err, attributes) {
1215 if (err) {
1216 reject(err);
1217 }
1218 else {
1219 resolve(attributes);
1220 }
1221 });
1222 });
1223 });
1224 };
1225 AuthClass.prototype.verifiedContact = function (user) {
1226 var that = this;
1227 return this.userAttributes(user).then(function (attributes) {
1228 var attrs = that.attributesToObject(attributes);
1229 var unverified = {};
1230 var verified = {};
1231 if (attrs['email']) {
1232 if (attrs['email_verified']) {
1233 verified['email'] = attrs['email'];
1234 }
1235 else {
1236 unverified['email'] = attrs['email'];
1237 }
1238 }
1239 if (attrs['phone_number']) {
1240 if (attrs['phone_number_verified']) {
1241 verified['phone_number'] = attrs['phone_number'];
1242 }
1243 else {
1244 unverified['phone_number'] = attrs['phone_number'];
1245 }
1246 }
1247 return {
1248 verified: verified,
1249 unverified: unverified,
1250 };
1251 });
1252 };
1253 AuthClass.prototype.isErrorWithMessage = function (err) {
1254 return (typeof err === 'object' &&
1255 Object.prototype.hasOwnProperty.call(err, 'message'));
1256 };
1257 // Session revoked by another app
1258 AuthClass.prototype.isTokenRevokedError = function (err) {
1259 return (this.isErrorWithMessage(err) &&
1260 err.message === 'Access Token has been revoked');
1261 };
1262 AuthClass.prototype.isRefreshTokenRevokedError = function (err) {
1263 return (this.isErrorWithMessage(err) &&
1264 err.message === 'Refresh Token has been revoked');
1265 };
1266 AuthClass.prototype.isUserDisabledError = function (err) {
1267 return this.isErrorWithMessage(err) && err.message === 'User is disabled.';
1268 };
1269 AuthClass.prototype.isUserDoesNotExistError = function (err) {
1270 return (this.isErrorWithMessage(err) && err.message === 'User does not exist.');
1271 };
1272 AuthClass.prototype.isRefreshTokenExpiredError = function (err) {
1273 return (this.isErrorWithMessage(err) &&
1274 err.message === 'Refresh Token has expired');
1275 };
1276 AuthClass.prototype.isSignedInHostedUI = function () {
1277 return (this._oAuthHandler &&
1278 this._storage.getItem('amplify-signin-with-hostedUI') === 'true');
1279 };
1280 AuthClass.prototype.isSessionInvalid = function (err) {
1281 return (this.isUserDisabledError(err) ||
1282 this.isUserDoesNotExistError(err) ||
1283 this.isTokenRevokedError(err) ||
1284 this.isRefreshTokenRevokedError(err) ||
1285 this.isRefreshTokenExpiredError(err));
1286 };
1287 AuthClass.prototype.cleanUpInvalidSession = function (user) {
1288 return __awaiter(this, void 0, void 0, function () {
1289 var e_6;
1290 var _this = this;
1291 return __generator(this, function (_a) {
1292 switch (_a.label) {
1293 case 0:
1294 user.signOut();
1295 this.user = null;
1296 _a.label = 1;
1297 case 1:
1298 _a.trys.push([1, 3, , 4]);
1299 return [4 /*yield*/, this.cleanCachedItems()];
1300 case 2:
1301 _a.sent(); // clean aws credentials
1302 return [3 /*break*/, 4];
1303 case 3:
1304 e_6 = _a.sent();
1305 logger.debug('failed to clear cached items');
1306 return [3 /*break*/, 4];
1307 case 4:
1308 if (this.isSignedInHostedUI()) {
1309 return [2 /*return*/, new Promise(function (res, rej) {
1310 _this.oAuthSignOutRedirect(res, rej);
1311 })];
1312 }
1313 else {
1314 dispatchAuthEvent('signOut', this.user, "A user has been signed out");
1315 }
1316 return [2 /*return*/];
1317 }
1318 });
1319 });
1320 };
1321 /**
1322 * Get current authenticated user
1323 * @return - A promise resolves to current authenticated CognitoUser if success
1324 */
1325 AuthClass.prototype.currentUserPoolUser = function (params) {
1326 var _this = this;
1327 if (!this.userPool) {
1328 return this.rejectNoUserPool();
1329 }
1330 return new Promise(function (res, rej) {
1331 _this._storageSync
1332 .then(function () { return __awaiter(_this, void 0, void 0, function () {
1333 var user, clientMetadata;
1334 var _this = this;
1335 return __generator(this, function (_a) {
1336 switch (_a.label) {
1337 case 0:
1338 if (!this.isOAuthInProgress()) return [3 /*break*/, 2];
1339 logger.debug('OAuth signIn in progress, waiting for resolution...');
1340 return [4 /*yield*/, new Promise(function (res) {
1341 var timeoutId = setTimeout(function () {
1342 logger.debug('OAuth signIn in progress timeout');
1343 Hub.remove('auth', hostedUISignCallback);
1344 res();
1345 }, OAUTH_FLOW_MS_TIMEOUT);
1346 Hub.listen('auth', hostedUISignCallback);
1347 function hostedUISignCallback(_a) {
1348 var payload = _a.payload;
1349 var event = payload.event;
1350 if (event === 'cognitoHostedUI' ||
1351 event === 'cognitoHostedUI_failure') {
1352 logger.debug("OAuth signIn resolved: " + event);
1353 clearTimeout(timeoutId);
1354 Hub.remove('auth', hostedUISignCallback);
1355 res();
1356 }
1357 }
1358 })];
1359 case 1:
1360 _a.sent();
1361 _a.label = 2;
1362 case 2:
1363 user = this.userPool.getCurrentUser();
1364 if (!user) {
1365 logger.debug('Failed to get user from user pool');
1366 rej('No current user');
1367 return [2 /*return*/];
1368 }
1369 clientMetadata = this._config.clientMetadata;
1370 // refresh the session if the session expired.
1371 user.getSession(function (err, session) { return __awaiter(_this, void 0, void 0, function () {
1372 var cleanUpError_5, bypassCache, clientMetadata, _a, scope;
1373 var _this = this;
1374 return __generator(this, function (_b) {
1375 switch (_b.label) {
1376 case 0:
1377 if (!err) return [3 /*break*/, 5];
1378 logger.debug('Failed to get the user session', err);
1379 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1380 _b.label = 1;
1381 case 1:
1382 _b.trys.push([1, 3, , 4]);
1383 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1384 case 2:
1385 _b.sent();
1386 return [3 /*break*/, 4];
1387 case 3:
1388 cleanUpError_5 = _b.sent();
1389 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_5.message));
1390 return [2 /*return*/];
1391 case 4:
1392 rej(err);
1393 return [2 /*return*/];
1394 case 5:
1395 bypassCache = params ? params.bypassCache : false;
1396 if (!bypassCache) return [3 /*break*/, 7];
1397 return [4 /*yield*/, this.Credentials.clear()];
1398 case 6:
1399 _b.sent();
1400 _b.label = 7;
1401 case 7:
1402 clientMetadata = this._config.clientMetadata;
1403 _a = session.getAccessToken().decodePayload().scope, scope = _a === void 0 ? '' : _a;
1404 if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
1405 user.getUserData(function (err, data) { return __awaiter(_this, void 0, void 0, function () {
1406 var cleanUpError_6, preferredMFA, attributeList, i, attribute, userAttribute, attributes;
1407 return __generator(this, function (_a) {
1408 switch (_a.label) {
1409 case 0:
1410 if (!err) return [3 /*break*/, 7];
1411 logger.debug('getting user data failed', err);
1412 if (!this.isSessionInvalid(err)) return [3 /*break*/, 5];
1413 _a.label = 1;
1414 case 1:
1415 _a.trys.push([1, 3, , 4]);
1416 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1417 case 2:
1418 _a.sent();
1419 return [3 /*break*/, 4];
1420 case 3:
1421 cleanUpError_6 = _a.sent();
1422 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_6.message));
1423 return [2 /*return*/];
1424 case 4:
1425 rej(err);
1426 return [3 /*break*/, 6];
1427 case 5:
1428 res(user);
1429 _a.label = 6;
1430 case 6: return [2 /*return*/];
1431 case 7:
1432 preferredMFA = data.PreferredMfaSetting || 'NOMFA';
1433 attributeList = [];
1434 for (i = 0; i < data.UserAttributes.length; i++) {
1435 attribute = {
1436 Name: data.UserAttributes[i].Name,
1437 Value: data.UserAttributes[i].Value,
1438 };
1439 userAttribute = new CognitoUserAttribute(attribute);
1440 attributeList.push(userAttribute);
1441 }
1442 attributes = this.attributesToObject(attributeList);
1443 Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA });
1444 return [2 /*return*/, res(user)];
1445 }
1446 });
1447 }); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
1448 }
1449 else {
1450 logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
1451 "is not in the scopes of the access token");
1452 return [2 /*return*/, res(user)];
1453 }
1454 return [2 /*return*/];
1455 }
1456 });
1457 }); }, { clientMetadata: clientMetadata });
1458 return [2 /*return*/];
1459 }
1460 });
1461 }); })
1462 .catch(function (e) {
1463 logger.debug('Failed to sync cache info into memory', e);
1464 return rej(e);
1465 });
1466 });
1467 };
1468 AuthClass.prototype.isOAuthInProgress = function () {
1469 return this.oAuthFlowInProgress;
1470 };
1471 /**
1472 * Get current authenticated user
1473 * @param {CurrentUserOpts} - options for getting the current user
1474 * @return - A promise resolves to current authenticated CognitoUser if success
1475 */
1476 AuthClass.prototype.currentAuthenticatedUser = function (params) {
1477 return __awaiter(this, void 0, void 0, function () {
1478 var federatedUser, e_7, federatedInfo, user, e_8;
1479 return __generator(this, function (_a) {
1480 switch (_a.label) {
1481 case 0:
1482 logger.debug('getting current authenticated user');
1483 federatedUser = null;
1484 _a.label = 1;
1485 case 1:
1486 _a.trys.push([1, 3, , 4]);
1487 return [4 /*yield*/, this._storageSync];
1488 case 2:
1489 _a.sent();
1490 return [3 /*break*/, 4];
1491 case 3:
1492 e_7 = _a.sent();
1493 logger.debug('Failed to sync cache info into memory', e_7);
1494 throw e_7;
1495 case 4:
1496 try {
1497 federatedInfo = JSON.parse(this._storage.getItem('aws-amplify-federatedInfo'));
1498 if (federatedInfo) {
1499 federatedUser = __assign(__assign({}, federatedInfo.user), { token: federatedInfo.token });
1500 }
1501 }
1502 catch (e) {
1503 logger.debug('cannot load federated user from auth storage');
1504 }
1505 if (!federatedUser) return [3 /*break*/, 5];
1506 this.user = federatedUser;
1507 logger.debug('get current authenticated federated user', this.user);
1508 return [2 /*return*/, this.user];
1509 case 5:
1510 logger.debug('get current authenticated userpool user');
1511 user = null;
1512 _a.label = 6;
1513 case 6:
1514 _a.trys.push([6, 8, , 9]);
1515 return [4 /*yield*/, this.currentUserPoolUser(params)];
1516 case 7:
1517 user = _a.sent();
1518 return [3 /*break*/, 9];
1519 case 8:
1520 e_8 = _a.sent();
1521 if (e_8 === 'No userPool') {
1522 logger.error('Cannot get the current user because the user pool is missing. ' +
1523 'Please make sure the Auth module is configured with a valid Cognito User Pool ID');
1524 }
1525 logger.debug('The user is not authenticated by the error', e_8);
1526 return [2 /*return*/, Promise.reject('The user is not authenticated')];
1527 case 9:
1528 this.user = user;
1529 return [2 /*return*/, this.user];
1530 }
1531 });
1532 });
1533 };
1534 /**
1535 * Get current user's session
1536 * @return - A promise resolves to session object if success
1537 */
1538 AuthClass.prototype.currentSession = function () {
1539 var that = this;
1540 logger.debug('Getting current session');
1541 // Purposely not calling the reject method here because we don't need a console error
1542 if (!this.userPool) {
1543 return this.rejectNoUserPool();
1544 }
1545 return new Promise(function (res, rej) {
1546 that
1547 .currentUserPoolUser()
1548 .then(function (user) {
1549 that
1550 .userSession(user)
1551 .then(function (session) {
1552 res(session);
1553 return;
1554 })
1555 .catch(function (e) {
1556 logger.debug('Failed to get the current session', e);
1557 rej(e);
1558 return;
1559 });
1560 })
1561 .catch(function (e) {
1562 logger.debug('Failed to get the current user', e);
1563 rej(e);
1564 return;
1565 });
1566 });
1567 };
1568 /**
1569 * Get the corresponding user session
1570 * @param {Object} user - The CognitoUser object
1571 * @return - A promise resolves to the session
1572 */
1573 AuthClass.prototype.userSession = function (user) {
1574 var _this = this;
1575 if (!user) {
1576 logger.debug('the user is null');
1577 return this.rejectAuthError(AuthErrorTypes.NoUserSession);
1578 }
1579 var clientMetadata = this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1580 return new Promise(function (res, rej) {
1581 logger.debug('Getting the session from this user:', user);
1582 user.getSession(function (err, session) { return __awaiter(_this, void 0, void 0, function () {
1583 var cleanUpError_7;
1584 return __generator(this, function (_a) {
1585 switch (_a.label) {
1586 case 0:
1587 if (!err) return [3 /*break*/, 5];
1588 logger.debug('Failed to get the session from user', user);
1589 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1590 _a.label = 1;
1591 case 1:
1592 _a.trys.push([1, 3, , 4]);
1593 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1594 case 2:
1595 _a.sent();
1596 return [3 /*break*/, 4];
1597 case 3:
1598 cleanUpError_7 = _a.sent();
1599 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_7.message));
1600 return [2 /*return*/];
1601 case 4:
1602 rej(err);
1603 return [2 /*return*/];
1604 case 5:
1605 logger.debug('Succeed to get the user session', session);
1606 res(session);
1607 return [2 /*return*/];
1608 }
1609 });
1610 }); }, { clientMetadata: clientMetadata });
1611 });
1612 };
1613 /**
1614 * Get authenticated credentials of current user.
1615 * @return - A promise resolves to be current user's credentials
1616 */
1617 AuthClass.prototype.currentUserCredentials = function () {
1618 return __awaiter(this, void 0, void 0, function () {
1619 var e_9, federatedInfo;
1620 var _this = this;
1621 return __generator(this, function (_a) {
1622 switch (_a.label) {
1623 case 0:
1624 logger.debug('Getting current user credentials');
1625 _a.label = 1;
1626 case 1:
1627 _a.trys.push([1, 3, , 4]);
1628 return [4 /*yield*/, this._storageSync];
1629 case 2:
1630 _a.sent();
1631 return [3 /*break*/, 4];
1632 case 3:
1633 e_9 = _a.sent();
1634 logger.debug('Failed to sync cache info into memory', e_9);
1635 throw e_9;
1636 case 4:
1637 federatedInfo = null;
1638 try {
1639 federatedInfo = JSON.parse(this._storage.getItem('aws-amplify-federatedInfo'));
1640 }
1641 catch (e) {
1642 logger.debug('failed to get or parse item aws-amplify-federatedInfo', e);
1643 }
1644 if (federatedInfo) {
1645 // refresh the jwt token here if necessary
1646 return [2 /*return*/, this.Credentials.refreshFederatedToken(federatedInfo)];
1647 }
1648 else {
1649 return [2 /*return*/, this.currentSession()
1650 .then(function (session) {
1651 logger.debug('getting session success', session);
1652 return _this.Credentials.set(session, 'session');
1653 })
1654 .catch(function () {
1655 logger.debug('getting guest credentials');
1656 return _this.Credentials.set(null, 'guest');
1657 })];
1658 }
1659 return [2 /*return*/];
1660 }
1661 });
1662 });
1663 };
1664 AuthClass.prototype.currentCredentials = function () {
1665 logger.debug('getting current credentials');
1666 return this.Credentials.get();
1667 };
1668 /**
1669 * Initiate an attribute confirmation request
1670 * @param {Object} user - The CognitoUser
1671 * @param {Object} attr - The attributes to be verified
1672 * @return - A promise resolves to callback data if success
1673 */
1674 AuthClass.prototype.verifyUserAttribute = function (user, attr, clientMetadata) {
1675 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1676 return new Promise(function (resolve, reject) {
1677 user.getAttributeVerificationCode(attr, {
1678 onSuccess: function (success) {
1679 return resolve(success);
1680 },
1681 onFailure: function (err) {
1682 return reject(err);
1683 },
1684 }, clientMetadata);
1685 });
1686 };
1687 /**
1688 * Confirm an attribute using a confirmation code
1689 * @param {Object} user - The CognitoUser
1690 * @param {Object} attr - The attribute to be verified
1691 * @param {String} code - The confirmation code
1692 * @return - A promise resolves to callback data if success
1693 */
1694 AuthClass.prototype.verifyUserAttributeSubmit = function (user, attr, code) {
1695 if (!code) {
1696 return this.rejectAuthError(AuthErrorTypes.EmptyCode);
1697 }
1698 return new Promise(function (resolve, reject) {
1699 user.verifyAttribute(attr, code, {
1700 onSuccess: function (data) {
1701 resolve(data);
1702 return;
1703 },
1704 onFailure: function (err) {
1705 reject(err);
1706 return;
1707 },
1708 });
1709 });
1710 };
1711 AuthClass.prototype.verifyCurrentUserAttribute = function (attr) {
1712 var that = this;
1713 return that
1714 .currentUserPoolUser()
1715 .then(function (user) { return that.verifyUserAttribute(user, attr); });
1716 };
1717 /**
1718 * Confirm current user's attribute using a confirmation code
1719 * @param {Object} attr - The attribute to be verified
1720 * @param {String} code - The confirmation code
1721 * @return - A promise resolves to callback data if success
1722 */
1723 AuthClass.prototype.verifyCurrentUserAttributeSubmit = function (attr, code) {
1724 var that = this;
1725 return that
1726 .currentUserPoolUser()
1727 .then(function (user) { return that.verifyUserAttributeSubmit(user, attr, code); });
1728 };
1729 AuthClass.prototype.cognitoIdentitySignOut = function (opts, user) {
1730 return __awaiter(this, void 0, void 0, function () {
1731 var e_10, isSignedInHostedUI;
1732 var _this = this;
1733 return __generator(this, function (_a) {
1734 switch (_a.label) {
1735 case 0:
1736 _a.trys.push([0, 2, , 3]);
1737 return [4 /*yield*/, this._storageSync];
1738 case 1:
1739 _a.sent();
1740 return [3 /*break*/, 3];
1741 case 2:
1742 e_10 = _a.sent();
1743 logger.debug('Failed to sync cache info into memory', e_10);
1744 throw e_10;
1745 case 3:
1746 isSignedInHostedUI = this._oAuthHandler &&
1747 this._storage.getItem('amplify-signin-with-hostedUI') === 'true';
1748 return [2 /*return*/, new Promise(function (res, rej) {
1749 if (opts && opts.global) {
1750 logger.debug('user global sign out', user);
1751 // in order to use global signout
1752 // we must validate the user as an authenticated user by using getSession
1753 var clientMetadata = _this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1754 user.getSession(function (err, result) { return __awaiter(_this, void 0, void 0, function () {
1755 var cleanUpError_8;
1756 var _this = this;
1757 return __generator(this, function (_a) {
1758 switch (_a.label) {
1759 case 0:
1760 if (!err) return [3 /*break*/, 5];
1761 logger.debug('failed to get the user session', err);
1762 if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1763 _a.label = 1;
1764 case 1:
1765 _a.trys.push([1, 3, , 4]);
1766 return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1767 case 2:
1768 _a.sent();
1769 return [3 /*break*/, 4];
1770 case 3:
1771 cleanUpError_8 = _a.sent();
1772 rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_8.message));
1773 return [2 /*return*/];
1774 case 4: return [2 /*return*/, rej(err)];
1775 case 5:
1776 user.globalSignOut({
1777 onSuccess: function (data) {
1778 logger.debug('global sign out success');
1779 if (isSignedInHostedUI) {
1780 _this.oAuthSignOutRedirect(res, rej);
1781 }
1782 else {
1783 return res();
1784 }
1785 },
1786 onFailure: function (err) {
1787 logger.debug('global sign out failed', err);
1788 return rej(err);
1789 },
1790 });
1791 return [2 /*return*/];
1792 }
1793 });
1794 }); }, { clientMetadata: clientMetadata });
1795 }
1796 else {
1797 logger.debug('user sign out', user);
1798 user.signOut(function () {
1799 if (isSignedInHostedUI) {
1800 _this.oAuthSignOutRedirect(res, rej);
1801 }
1802 else {
1803 return res();
1804 }
1805 });
1806 }
1807 })];
1808 }
1809 });
1810 });
1811 };
1812 AuthClass.prototype.oAuthSignOutRedirect = function (resolve, reject) {
1813 var isBrowser = JS.browserOrNode().isBrowser;
1814 if (isBrowser) {
1815 this.oAuthSignOutRedirectOrReject(reject);
1816 }
1817 else {
1818 this.oAuthSignOutAndResolve(resolve);
1819 }
1820 };
1821 AuthClass.prototype.oAuthSignOutAndResolve = function (resolve) {
1822 this._oAuthHandler.signOut();
1823 resolve();
1824 };
1825 AuthClass.prototype.oAuthSignOutRedirectOrReject = function (reject) {
1826 this._oAuthHandler.signOut(); // this method redirects url
1827 // App should be redirected to another url otherwise it will reject
1828 setTimeout(function () { return reject(Error('Signout timeout fail')); }, 3000);
1829 };
1830 /**
1831 * Sign out method
1832 * @
1833 * @return - A promise resolved if success
1834 */
1835 AuthClass.prototype.signOut = function (opts) {
1836 return __awaiter(this, void 0, void 0, function () {
1837 var e_11, user;
1838 return __generator(this, function (_a) {
1839 switch (_a.label) {
1840 case 0:
1841 _a.trys.push([0, 2, , 3]);
1842 return [4 /*yield*/, this.cleanCachedItems()];
1843 case 1:
1844 _a.sent();
1845 return [3 /*break*/, 3];
1846 case 2:
1847 e_11 = _a.sent();
1848 logger.debug('failed to clear cached items');
1849 return [3 /*break*/, 3];
1850 case 3:
1851 if (!this.userPool) return [3 /*break*/, 7];
1852 user = this.userPool.getCurrentUser();
1853 if (!user) return [3 /*break*/, 5];
1854 return [4 /*yield*/, this.cognitoIdentitySignOut(opts, user)];
1855 case 4:
1856 _a.sent();
1857 return [3 /*break*/, 6];
1858 case 5:
1859 logger.debug('no current Cognito user');
1860 _a.label = 6;
1861 case 6: return [3 /*break*/, 8];
1862 case 7:
1863 logger.debug('no Cognito User pool');
1864 _a.label = 8;
1865 case 8:
1866 /**
1867 * Note for future refactor - no reliable way to get username with
1868 * Cognito User Pools vs Identity when federating with Social Providers
1869 * This is why we need a well structured session object that can be inspected
1870 * and information passed back in the message below for Hub dispatch
1871 */
1872 dispatchAuthEvent('signOut', this.user, "A user has been signed out");
1873 this.user = null;
1874 return [2 /*return*/];
1875 }
1876 });
1877 });
1878 };
1879 AuthClass.prototype.cleanCachedItems = function () {
1880 return __awaiter(this, void 0, void 0, function () {
1881 return __generator(this, function (_a) {
1882 switch (_a.label) {
1883 case 0:
1884 // clear cognito cached item
1885 return [4 /*yield*/, this.Credentials.clear()];
1886 case 1:
1887 // clear cognito cached item
1888 _a.sent();
1889 return [2 /*return*/];
1890 }
1891 });
1892 });
1893 };
1894 /**
1895 * Change a password for an authenticated user
1896 * @param {Object} user - The CognitoUser object
1897 * @param {String} oldPassword - the current password
1898 * @param {String} newPassword - the requested new password
1899 * @return - A promise resolves if success
1900 */
1901 AuthClass.prototype.changePassword = function (user, oldPassword, newPassword, clientMetadata) {
1902 var _this = this;
1903 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1904 return new Promise(function (resolve, reject) {
1905 _this.userSession(user).then(function (session) {
1906 user.changePassword(oldPassword, newPassword, function (err, data) {
1907 if (err) {
1908 logger.debug('change password failure', err);
1909 return reject(err);
1910 }
1911 else {
1912 return resolve(data);
1913 }
1914 }, clientMetadata);
1915 });
1916 });
1917 };
1918 /**
1919 * Initiate a forgot password request
1920 * @param {String} username - the username to change password
1921 * @return - A promise resolves if success
1922 */
1923 AuthClass.prototype.forgotPassword = function (username, clientMetadata) {
1924 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1925 if (!this.userPool) {
1926 return this.rejectNoUserPool();
1927 }
1928 if (!username) {
1929 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
1930 }
1931 var user = this.createCognitoUser(username);
1932 return new Promise(function (resolve, reject) {
1933 user.forgotPassword({
1934 onSuccess: function () {
1935 resolve();
1936 return;
1937 },
1938 onFailure: function (err) {
1939 logger.debug('forgot password failure', err);
1940 dispatchAuthEvent('forgotPassword_failure', err, username + " forgotPassword failed");
1941 reject(err);
1942 return;
1943 },
1944 inputVerificationCode: function (data) {
1945 dispatchAuthEvent('forgotPassword', user, username + " has initiated forgot password flow");
1946 resolve(data);
1947 return;
1948 },
1949 }, clientMetadata);
1950 });
1951 };
1952 /**
1953 * Confirm a new password using a confirmation Code
1954 * @param {String} username - The username
1955 * @param {String} code - The confirmation code
1956 * @param {String} password - The new password
1957 * @return - A promise that resolves if success
1958 */
1959 AuthClass.prototype.forgotPasswordSubmit = function (username, code, password, clientMetadata) {
1960 if (clientMetadata === void 0) { clientMetadata = this._config.clientMetadata; }
1961 if (!this.userPool) {
1962 return this.rejectNoUserPool();
1963 }
1964 if (!username) {
1965 return this.rejectAuthError(AuthErrorTypes.EmptyUsername);
1966 }
1967 if (!code) {
1968 return this.rejectAuthError(AuthErrorTypes.EmptyCode);
1969 }
1970 if (!password) {
1971 return this.rejectAuthError(AuthErrorTypes.EmptyPassword);
1972 }
1973 var user = this.createCognitoUser(username);
1974 return new Promise(function (resolve, reject) {
1975 user.confirmPassword(code, password, {
1976 onSuccess: function (success) {
1977 dispatchAuthEvent('forgotPasswordSubmit', user, username + " forgotPasswordSubmit successful");
1978 resolve(success);
1979 return;
1980 },
1981 onFailure: function (err) {
1982 dispatchAuthEvent('forgotPasswordSubmit_failure', err, username + " forgotPasswordSubmit failed");
1983 reject(err);
1984 return;
1985 },
1986 }, clientMetadata);
1987 });
1988 };
1989 /**
1990 * Get user information
1991 * @async
1992 * @return {Object }- current User's information
1993 */
1994 AuthClass.prototype.currentUserInfo = function () {
1995 return __awaiter(this, void 0, void 0, function () {
1996 var source, user, attributes, userAttrs, credentials, e_12, info, err_1, user;
1997 return __generator(this, function (_a) {
1998 switch (_a.label) {
1999 case 0:
2000 source = this.Credentials.getCredSource();
2001 if (!(!source || source === 'aws' || source === 'userPool')) return [3 /*break*/, 9];
2002 return [4 /*yield*/, this.currentUserPoolUser().catch(function (err) {
2003 return logger.error(err);
2004 })];
2005 case 1:
2006 user = _a.sent();
2007 if (!user) {
2008 return [2 /*return*/, null];
2009 }
2010 _a.label = 2;
2011 case 2:
2012 _a.trys.push([2, 8, , 9]);
2013 return [4 /*yield*/, this.userAttributes(user)];
2014 case 3:
2015 attributes = _a.sent();
2016 userAttrs = this.attributesToObject(attributes);
2017 credentials = null;
2018 _a.label = 4;
2019 case 4:
2020 _a.trys.push([4, 6, , 7]);
2021 return [4 /*yield*/, this.currentCredentials()];
2022 case 5:
2023 credentials = _a.sent();
2024 return [3 /*break*/, 7];
2025 case 6:
2026 e_12 = _a.sent();
2027 logger.debug('Failed to retrieve credentials while getting current user info', e_12);
2028 return [3 /*break*/, 7];
2029 case 7:
2030 info = {
2031 id: credentials ? credentials.identityId : undefined,
2032 username: user.getUsername(),
2033 attributes: userAttrs,
2034 };
2035 return [2 /*return*/, info];
2036 case 8:
2037 err_1 = _a.sent();
2038 logger.error('currentUserInfo error', err_1);
2039 return [2 /*return*/, {}];
2040 case 9:
2041 if (source === 'federated') {
2042 user = this.user;
2043 return [2 /*return*/, user ? user : {}];
2044 }
2045 return [2 /*return*/];
2046 }
2047 });
2048 });
2049 };
2050 AuthClass.prototype.federatedSignIn = function (providerOrOptions, response, user) {
2051 return __awaiter(this, void 0, void 0, function () {
2052 var options, provider, customState, client_id, redirect_uri, provider, loggedInUser, token, identity_id, expires_at, credentials, currentUser;
2053 return __generator(this, function (_a) {
2054 switch (_a.label) {
2055 case 0:
2056 if (!this._config.identityPoolId && !this._config.userPoolId) {
2057 throw new Error("Federation requires either a User Pool or Identity Pool in config");
2058 }
2059 // Ensure backwards compatability
2060 if (typeof providerOrOptions === 'undefined') {
2061 if (this._config.identityPoolId && !this._config.userPoolId) {
2062 throw new Error("Federation with Identity Pools requires tokens passed as arguments");
2063 }
2064 }
2065 if (!(isFederatedSignInOptions(providerOrOptions) ||
2066 isFederatedSignInOptionsCustom(providerOrOptions) ||
2067 hasCustomState(providerOrOptions) ||
2068 typeof providerOrOptions === 'undefined')) return [3 /*break*/, 1];
2069 options = providerOrOptions || {
2070 provider: CognitoHostedUIIdentityProvider.Cognito,
2071 };
2072 provider = isFederatedSignInOptions(options)
2073 ? options.provider
2074 : options.customProvider;
2075 customState = isFederatedSignInOptions(options)
2076 ? options.customState
2077 : options.customState;
2078 if (this._config.userPoolId) {
2079 client_id = isCognitoHostedOpts(this._config.oauth)
2080 ? this._config.userPoolWebClientId
2081 : this._config.oauth.clientID;
2082 redirect_uri = isCognitoHostedOpts(this._config.oauth)
2083 ? this._config.oauth.redirectSignIn
2084 : this._config.oauth.redirectUri;
2085 this._oAuthHandler.oauthSignIn(this._config.oauth.responseType, this._config.oauth.domain, redirect_uri, client_id, provider, customState);
2086 }
2087 return [3 /*break*/, 4];
2088 case 1:
2089 provider = providerOrOptions;
2090 // To check if the user is already logged in
2091 try {
2092 loggedInUser = JSON.stringify(JSON.parse(this._storage.getItem('aws-amplify-federatedInfo')).user);
2093 if (loggedInUser) {
2094 logger.warn("There is already a signed in user: " + loggedInUser + " in your app.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tYou should not call Auth.federatedSignIn method again as it may cause unexpected behavior.");
2095 }
2096 }
2097 catch (e) { }
2098 token = response.token, identity_id = response.identity_id, expires_at = response.expires_at;
2099 return [4 /*yield*/, this.Credentials.set({ provider: provider, token: token, identity_id: identity_id, user: user, expires_at: expires_at }, 'federation')];
2100 case 2:
2101 credentials = _a.sent();
2102 return [4 /*yield*/, this.currentAuthenticatedUser()];
2103 case 3:
2104 currentUser = _a.sent();
2105 dispatchAuthEvent('signIn', currentUser, "A user " + currentUser.username + " has been signed in");
2106 logger.debug('federated sign in credentials', credentials);
2107 return [2 /*return*/, credentials];
2108 case 4: return [2 /*return*/];
2109 }
2110 });
2111 });
2112 };
2113 /**
2114 * Used to complete the OAuth flow with or without the Cognito Hosted UI
2115 * @param {String} URL - optional parameter for customers to pass in the response URL
2116 */
2117 AuthClass.prototype._handleAuthResponse = function (URL) {
2118 return __awaiter(this, void 0, void 0, function () {
2119 var currentUrl, hasCodeOrError, hasTokenOrError, _a, accessToken, idToken, refreshToken, state, session, credentials, isCustomStateIncluded, currentUser, customState, err_2;
2120 return __generator(this, function (_b) {
2121 switch (_b.label) {
2122 case 0:
2123 if (this.oAuthFlowInProgress) {
2124 logger.debug("Skipping URL " + URL + " current flow in progress");
2125 return [2 /*return*/];
2126 }
2127 _b.label = 1;
2128 case 1:
2129 _b.trys.push([1, , 8, 9]);
2130 this.oAuthFlowInProgress = true;
2131 if (!this._config.userPoolId) {
2132 throw new Error("OAuth responses require a User Pool defined in config");
2133 }
2134 dispatchAuthEvent('parsingCallbackUrl', { url: URL }, "The callback url is being parsed");
2135 currentUrl = URL || (JS.browserOrNode().isBrowser ? window.location.href : '');
2136 hasCodeOrError = !!(parse(currentUrl).query || '')
2137 .split('&')
2138 .map(function (entry) { return entry.split('='); })
2139 .find(function (_a) {
2140 var _b = __read(_a, 1), k = _b[0];
2141 return k === 'code' || k === 'error';
2142 });
2143 hasTokenOrError = !!(parse(currentUrl).hash || '#')
2144 .substr(1)
2145 .split('&')
2146 .map(function (entry) { return entry.split('='); })
2147 .find(function (_a) {
2148 var _b = __read(_a, 1), k = _b[0];
2149 return k === 'access_token' || k === 'error';
2150 });
2151 if (!(hasCodeOrError || hasTokenOrError)) return [3 /*break*/, 7];
2152 this._storage.setItem('amplify-redirected-from-hosted-ui', 'true');
2153 _b.label = 2;
2154 case 2:
2155 _b.trys.push([2, 6, , 7]);
2156 return [4 /*yield*/, this._oAuthHandler.handleAuthResponse(currentUrl)];
2157 case 3:
2158 _a = _b.sent(), accessToken = _a.accessToken, idToken = _a.idToken, refreshToken = _a.refreshToken, state = _a.state;
2159 session = new CognitoUserSession({
2160 IdToken: new CognitoIdToken({ IdToken: idToken }),
2161 RefreshToken: new CognitoRefreshToken({
2162 RefreshToken: refreshToken,
2163 }),
2164 AccessToken: new CognitoAccessToken({
2165 AccessToken: accessToken,
2166 }),
2167 });
2168 credentials = void 0;
2169 if (!this._config.identityPoolId) return [3 /*break*/, 5];
2170 return [4 /*yield*/, this.Credentials.set(session, 'session')];
2171 case 4:
2172 credentials = _b.sent();
2173 logger.debug('AWS credentials', credentials);
2174 _b.label = 5;
2175 case 5:
2176 isCustomStateIncluded = /-/.test(state);
2177 currentUser = this.createCognitoUser(session.getIdToken().decodePayload()['cognito:username']);
2178 // This calls cacheTokens() in Cognito SDK
2179 currentUser.setSignInUserSession(session);
2180 if (window && typeof window.history !== 'undefined') {
2181 window.history.replaceState({}, null, this._config.oauth.redirectSignIn);
2182 }
2183 dispatchAuthEvent('signIn', currentUser, "A user " + currentUser.getUsername() + " has been signed in");
2184 dispatchAuthEvent('cognitoHostedUI', currentUser, "A user " + currentUser.getUsername() + " has been signed in via Cognito Hosted UI");
2185 if (isCustomStateIncluded) {
2186 customState = state.split('-').splice(1).join('-');
2187 dispatchAuthEvent('customOAuthState', urlSafeDecode(customState), "State for user " + currentUser.getUsername());
2188 }
2189 //#endregion
2190 return [2 /*return*/, credentials];
2191 case 6:
2192 err_2 = _b.sent();
2193 logger.debug('Error in cognito hosted auth response', err_2);
2194 // Just like a successful handling of `?code`, replace the window history to "dispose" of the `code`.
2195 // Otherwise, reloading the page will throw errors as the `code` has already been spent.
2196 if (window && typeof window.history !== 'undefined') {
2197 window.history.replaceState({}, null, this._config.oauth.redirectSignIn);
2198 }
2199 dispatchAuthEvent('signIn_failure', err_2, "The OAuth response flow failed");
2200 dispatchAuthEvent('cognitoHostedUI_failure', err_2, "A failure occurred when returning to the Cognito Hosted UI");
2201 dispatchAuthEvent('customState_failure', err_2, "A failure occurred when returning state");
2202 return [3 /*break*/, 7];
2203 case 7: return [3 /*break*/, 9];
2204 case 8:
2205 this.oAuthFlowInProgress = false;
2206 return [7 /*endfinally*/];
2207 case 9: return [2 /*return*/];
2208 }
2209 });
2210 });
2211 };
2212 /**
2213 * Compact version of credentials
2214 * @param {Object} credentials
2215 * @return {Object} - Credentials
2216 */
2217 AuthClass.prototype.essentialCredentials = function (credentials) {
2218 return {
2219 accessKeyId: credentials.accessKeyId,
2220 sessionToken: credentials.sessionToken,
2221 secretAccessKey: credentials.secretAccessKey,
2222 identityId: credentials.identityId,
2223 authenticated: credentials.authenticated,
2224 };
2225 };
2226 AuthClass.prototype.attributesToObject = function (attributes) {
2227 var _this = this;
2228 var obj = {};
2229 if (attributes) {
2230 attributes.map(function (attribute) {
2231 if (attribute.Name === 'email_verified' ||
2232 attribute.Name === 'phone_number_verified') {
2233 obj[attribute.Name] =
2234 _this.isTruthyString(attribute.Value) || attribute.Value === true;
2235 }
2236 else {
2237 obj[attribute.Name] = attribute.Value;
2238 }
2239 });
2240 }
2241 return obj;
2242 };
2243 AuthClass.prototype.isTruthyString = function (value) {
2244 return (typeof value.toLowerCase === 'function' && value.toLowerCase() === 'true');
2245 };
2246 AuthClass.prototype.createCognitoUser = function (username) {
2247 var userData = {
2248 Username: username,
2249 Pool: this.userPool,
2250 };
2251 userData.Storage = this._storage;
2252 var authenticationFlowType = this._config.authenticationFlowType;
2253 var user = new CognitoUser(userData);
2254 if (authenticationFlowType) {
2255 user.setAuthenticationFlowType(authenticationFlowType);
2256 }
2257 return user;
2258 };
2259 AuthClass.prototype._isValidAuthStorage = function (obj) {
2260 // We need to check if the obj has the functions of Storage
2261 return (!!obj &&
2262 typeof obj.getItem === 'function' &&
2263 typeof obj.setItem === 'function' &&
2264 typeof obj.removeItem === 'function' &&
2265 typeof obj.clear === 'function');
2266 };
2267 AuthClass.prototype.noUserPoolErrorHandler = function (config) {
2268 if (config) {
2269 if (!config.userPoolId || !config.identityPoolId) {
2270 return AuthErrorTypes.MissingAuthConfig;
2271 }
2272 }
2273 return AuthErrorTypes.NoConfig;
2274 };
2275 AuthClass.prototype.rejectAuthError = function (type) {
2276 return Promise.reject(new AuthError(type));
2277 };
2278 AuthClass.prototype.rejectNoUserPool = function () {
2279 var type = this.noUserPoolErrorHandler(this._config);
2280 return Promise.reject(new NoUserPoolError(type));
2281 };
2282 AuthClass.prototype.rememberDevice = function () {
2283 return __awaiter(this, void 0, void 0, function () {
2284 var currUser, error_1;
2285 return __generator(this, function (_a) {
2286 switch (_a.label) {
2287 case 0:
2288 _a.trys.push([0, 2, , 3]);
2289 return [4 /*yield*/, this.currentUserPoolUser()];
2290 case 1:
2291 currUser = _a.sent();
2292 return [3 /*break*/, 3];
2293 case 2:
2294 error_1 = _a.sent();
2295 logger.debug('The user is not authenticated by the error', error_1);
2296 return [2 /*return*/, Promise.reject('The user is not authenticated')];
2297 case 3:
2298 currUser.getCachedDeviceKeyAndPassword();
2299 return [2 /*return*/, new Promise(function (res, rej) {
2300 currUser.setDeviceStatusRemembered({
2301 onSuccess: function (data) {
2302 res(data);
2303 },
2304 onFailure: function (err) {
2305 if (err.code === 'InvalidParameterException') {
2306 rej(new AuthError(AuthErrorTypes.DeviceConfig));
2307 }
2308 else if (err.code === 'NetworkError') {
2309 rej(new AuthError(AuthErrorTypes.NetworkError));
2310 }
2311 else {
2312 rej(err);
2313 }
2314 },
2315 });
2316 })];
2317 }
2318 });
2319 });
2320 };
2321 AuthClass.prototype.forgetDevice = function () {
2322 return __awaiter(this, void 0, void 0, function () {
2323 var currUser, error_2;
2324 return __generator(this, function (_a) {
2325 switch (_a.label) {
2326 case 0:
2327 _a.trys.push([0, 2, , 3]);
2328 return [4 /*yield*/, this.currentUserPoolUser()];
2329 case 1:
2330 currUser = _a.sent();
2331 return [3 /*break*/, 3];
2332 case 2:
2333 error_2 = _a.sent();
2334 logger.debug('The user is not authenticated by the error', error_2);
2335 return [2 /*return*/, Promise.reject('The user is not authenticated')];
2336 case 3:
2337 currUser.getCachedDeviceKeyAndPassword();
2338 return [2 /*return*/, new Promise(function (res, rej) {
2339 currUser.forgetDevice({
2340 onSuccess: function (data) {
2341 res(data);
2342 },
2343 onFailure: function (err) {
2344 if (err.code === 'InvalidParameterException') {
2345 rej(new AuthError(AuthErrorTypes.DeviceConfig));
2346 }
2347 else if (err.code === 'NetworkError') {
2348 rej(new AuthError(AuthErrorTypes.NetworkError));
2349 }
2350 else {
2351 rej(err);
2352 }
2353 },
2354 });
2355 })];
2356 }
2357 });
2358 });
2359 };
2360 AuthClass.prototype.fetchDevices = function () {
2361 return __awaiter(this, void 0, void 0, function () {
2362 var currUser, error_3;
2363 return __generator(this, function (_a) {
2364 switch (_a.label) {
2365 case 0:
2366 _a.trys.push([0, 2, , 3]);
2367 return [4 /*yield*/, this.currentUserPoolUser()];
2368 case 1:
2369 currUser = _a.sent();
2370 return [3 /*break*/, 3];
2371 case 2:
2372 error_3 = _a.sent();
2373 logger.debug('The user is not authenticated by the error', error_3);
2374 throw new Error('The user is not authenticated');
2375 case 3:
2376 currUser.getCachedDeviceKeyAndPassword();
2377 return [2 /*return*/, new Promise(function (res, rej) {
2378 var cb = {
2379 onSuccess: function (data) {
2380 var deviceList = data.Devices.map(function (device) {
2381 var deviceName = device.DeviceAttributes.find(function (_a) {
2382 var Name = _a.Name;
2383 return Name === 'device_name';
2384 }) || {};
2385 var deviceInfo = {
2386 id: device.DeviceKey,
2387 name: deviceName.Value,
2388 };
2389 return deviceInfo;
2390 });
2391 res(deviceList);
2392 },
2393 onFailure: function (err) {
2394 if (err.code === 'InvalidParameterException') {
2395 rej(new AuthError(AuthErrorTypes.DeviceConfig));
2396 }
2397 else if (err.code === 'NetworkError') {
2398 rej(new AuthError(AuthErrorTypes.NetworkError));
2399 }
2400 else {
2401 rej(err);
2402 }
2403 },
2404 };
2405 currUser.listDevices(MAX_DEVICES, null, cb);
2406 })];
2407 }
2408 });
2409 });
2410 };
2411 return AuthClass;
2412}());
2413export { AuthClass };
2414export var Auth = new AuthClass(null);
2415Amplify.register(Auth);
2416//# sourceMappingURL=Auth.js.map
\No newline at end of file