UNPKG

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