UNPKG

@aws-amplify/auth

Version:

Auth category of aws-amplify

1,157 lines • 64.9 kB
"use strict"; /* * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { 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; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var types_1 = require("./types"); var core_1 = require("@aws-amplify/core"); var amazon_cognito_identity_js_1 = require("amazon-cognito-identity-js"); var amazon_cognito_auth_js_1 = require("amazon-cognito-auth-js"); var logger = new core_1.ConsoleLogger('AuthClass'); var dispatchAuthEvent = function (event, data) { core_1.Hub.dispatch('auth', { event: event, data: data }, 'Auth'); }; /** * Provide authentication steps */ var AuthClass = /** @class */ (function () { /** * Initialize Auth with AWS configurations * @param {Object} config - Configuration of the Auth */ function AuthClass(config) { this.userPool = null; this._cognitoAuthClient = null; this.user = null; this._gettingCredPromise = null; this.configure(config); this.currentUserCredentials = this.currentUserCredentials.bind(this); if (core_1.AWS.config) { core_1.AWS.config.update({ customUserAgent: core_1.Constants.userAgent }); } else { logger.warn('No AWS.config'); } } AuthClass.prototype.getModuleName = function () { return 'Auth'; }; AuthClass.prototype.configure = function (config) { var _this = this; if (!config) return this._config || {}; logger.debug('configure Auth'); var conf = Object.assign({}, this._config, core_1.Parser.parseMobilehubConfig(config).Auth, config); this._config = conf; 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, storage = _a.storage, identityPoolRegion = _a.identityPoolRegion; if (!this._config.storage) { // backward compatbility if (cookieStorage) this._storage = new amazon_cognito_identity_js_1.CookieStorage(cookieStorage); else { this._storage = new core_1.StorageHelper().getStorage(); } } else { this._storage = this._config.storage; } this._storageSync = Promise.resolve(); if (typeof this._storage['sync'] === 'function') { this._storageSync = this._storage['sync'](); } if (userPoolId) { var userPoolData = { UserPoolId: userPoolId, ClientId: userPoolWebClientId, }; userPoolData.Storage = this._storage; this.userPool = new amazon_cognito_identity_js_1.CognitoUserPool(userPoolData); } core_1.Credentials.configure({ mandatorySignIn: mandatorySignIn, region: identityPoolRegion || region, userPoolId: userPoolId, identityPoolId: identityPoolId, refreshHandlers: refreshHandlers, storage: this._storage }); // initiailize cognitoauth client if hosted ui options provided // to keep backward compatibility: var cognitoHostedUIConfig = oauth ? (oauth['domain'] ? oauth : oauth.awsCognito) : undefined; if (cognitoHostedUIConfig) { var that_1 = this; var cognitoAuthParams = Object.assign({ ClientId: userPoolWebClientId, UserPoolId: userPoolId, AppWebDomain: cognitoHostedUIConfig['domain'], TokenScopesArray: cognitoHostedUIConfig['scope'], RedirectUriSignIn: cognitoHostedUIConfig['redirectSignIn'], RedirectUriSignOut: cognitoHostedUIConfig['redirectSignOut'], ResponseType: cognitoHostedUIConfig['responseType'], Storage: this._storage }, cognitoHostedUIConfig['options']); logger.debug('cognito auth params', cognitoAuthParams); this._cognitoAuthClient = new amazon_cognito_auth_js_1.CognitoAuth(cognitoAuthParams); this._cognitoAuthClient.userhandler = { // user signed in onSuccess: function (result) { that_1.user = that_1.userPool.getCurrentUser(); logger.debug("Cognito Hosted authentication result", result); that_1.currentSession().then(function (session) { return __awaiter(_this, void 0, void 0, function () { var cred, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, 4, 5]); return [4 /*yield*/, core_1.Credentials.clear()]; case 1: _a.sent(); return [4 /*yield*/, core_1.Credentials.set(session, 'session')]; case 2: cred = _a.sent(); logger.debug('sign in succefully with', cred); return [3 /*break*/, 5]; case 3: e_1 = _a.sent(); logger.debug('sign in without aws credentials', e_1); return [3 /*break*/, 5]; case 4: dispatchAuthEvent('signIn', that_1.user); dispatchAuthEvent('cognitoHostedUI', that_1.user); return [7 /*endfinally*/]; case 5: return [2 /*return*/]; } }); }); }); }, onFailure: function (err) { logger.debug("Error in cognito hosted auth response", err); dispatchAuthEvent('signIn_failure', err); dispatchAuthEvent('cognitoHostedUI_failure', err); } }; // if not logged in, try to parse the url. this.currentAuthenticatedUser().then(function () { logger.debug('user already logged in'); }).catch(function (e) { logger.debug('not logged in, try to parse the url'); if (!core_1.JS.browserOrNode().isBrowser || !window.location) { logger.debug('not in the browser'); return; } var curUrl = window.location.href; try { _this._cognitoAuthClient.parseCognitoWebResponse(curUrl); } catch (err) { logger.debug('something wrong when parsing the url', err); dispatchAuthEvent('parsingUrl_failure', null); } }); } dispatchAuthEvent('configured', null); return this._config; }; /** * Sign up with username, password and other attrbutes like phone, email * @param {String | object} params - The user attirbutes used for signin * @param {String[]} restOfAttrs - for the backward compatability * @return - A promise resolves callback data if success */ AuthClass.prototype.signUp = function (params) { var _this = this; var restOfAttrs = []; for (var _i = 1; _i < arguments.length; _i++) { restOfAttrs[_i - 1] = arguments[_i]; } if (!this.userPool) { return Promise.reject('No userPool'); } var username = null; var password = null; var attributes = []; var validationData = null; if (params && typeof params === 'string') { username = params; password = restOfAttrs ? restOfAttrs[0] : null; var email = restOfAttrs ? restOfAttrs[1] : null; var phone_number = restOfAttrs ? restOfAttrs[2] : null; if (email) attributes.push({ Name: 'email', Value: email }); if (phone_number) attributes.push({ Name: 'phone_number', Value: phone_number }); } else if (params && typeof params === 'object') { username = params['username']; password = params['password']; var attrs_1 = params['attributes']; if (attrs_1) { Object.keys(attrs_1).map(function (key) { var ele = { Name: key, Value: attrs_1[key] }; attributes.push(ele); }); } validationData = params['validationData'] || null; } else { return Promise.reject('The first parameter should either be non-null string or object'); } if (!username) { return Promise.reject('Username cannot be empty'); } if (!password) { return Promise.reject('Password cannot be empty'); } logger.debug('signUp attrs:', attributes); logger.debug('signUp validation data:', validationData); return new Promise(function (resolve, reject) { _this.userPool.signUp(username, password, attributes, validationData, function (err, data) { if (err) { dispatchAuthEvent('signUp_failure', err); reject(err); } else { dispatchAuthEvent('signUp', data); resolve(data); } }); }); }; /** * Send the verfication code to confirm sign up * @param {String} username - The username to be confirmed * @param {String} code - The verification code * @param {ConfirmSignUpOptions} options - other options for confirm signup * @return - A promise resolves callback data if success */ AuthClass.prototype.confirmSignUp = function (username, code, options) { if (!this.userPool) { return Promise.reject('No userPool'); } if (!username) { return Promise.reject('Username cannot be empty'); } if (!code) { return Promise.reject('Code cannot be empty'); } var user = this.createCognitoUser(username); var forceAliasCreation = options && typeof options.forceAliasCreation === 'boolean' ? options.forceAliasCreation : true; return new Promise(function (resolve, reject) { user.confirmRegistration(code, forceAliasCreation, function (err, data) { if (err) { reject(err); } else { resolve(data); } }); }); }; /** * Resend the verification code * @param {String} username - The username to be confirmed * @return - A promise resolves data if success */ AuthClass.prototype.resendSignUp = function (username) { if (!this.userPool) { return Promise.reject('No userPool'); } if (!username) { return Promise.reject('Username cannot be empty'); } var user = this.createCognitoUser(username); return new Promise(function (resolve, reject) { user.resendConfirmationCode(function (err, data) { if (err) { reject(err); } else { resolve(data); } }); }); }; /** * Sign in * @param {String | SignInOpts} usernameOrSignInOpts - The username to be signed in or the sign in options * @param {String} password - The password of the username * @return - A promise resolves the CognitoUser */ AuthClass.prototype.signIn = function (usernameOrSignInOpts, pw) { if (!this.userPool) { return Promise.reject('No userPool'); } var username = null; var password = null; var validationData = {}; // for backward compatibility if (typeof usernameOrSignInOpts === 'string') { username = usernameOrSignInOpts; password = pw; } else if (types_1.isUsernamePasswordOpts(usernameOrSignInOpts)) { if (typeof pw !== 'undefined') { logger.warn('The password should be defined under the first parameter object!'); } username = usernameOrSignInOpts.username; password = usernameOrSignInOpts.password; validationData = usernameOrSignInOpts.validationData; } else { return Promise.reject(new Error('The username should either be a string or one of the sign in types')); } if (!username) { return Promise.reject('Username cannot be empty'); } var authDetails = new amazon_cognito_identity_js_1.AuthenticationDetails({ Username: username, Password: password, ValidationData: validationData }); if (password) { return this.signInWithPassword(authDetails); } else { return this.signInWithoutPassword(authDetails); } }; /** * Return an object with the authentication callbacks * @param {CognitoUser} user - the cognito user object * @param {} resolve - function called when resolving the current step * @param {} reject - function called when rejecting the current step * @return - an object with the callback methods for user authentication */ AuthClass.prototype.authCallbacks = function (user, resolve, reject) { var _this = this; var that = this; return { onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () { var cred, e_2; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.debug(session); delete (user['challengeName']); delete (user['challengeParam']); _a.label = 1; case 1: _a.trys.push([1, 4, 5, 6]); return [4 /*yield*/, core_1.Credentials.clear()]; case 2: _a.sent(); return [4 /*yield*/, core_1.Credentials.set(session, 'session')]; case 3: cred = _a.sent(); logger.debug('succeed to get cognito credentials', cred); return [3 /*break*/, 6]; case 4: e_2 = _a.sent(); logger.debug('cannot get cognito credentials', e_2); return [3 /*break*/, 6]; case 5: that.user = user; dispatchAuthEvent('signIn', user); resolve(user); return [7 /*endfinally*/]; case 6: return [2 /*return*/]; } }); }); }, onFailure: function (err) { logger.debug('signIn failure', err); dispatchAuthEvent('signIn_failure', err); reject(err); }, customChallenge: function (challengeParam) { logger.debug('signIn custom challenge answer required'); user['challengeName'] = 'CUSTOM_CHALLENGE'; user['challengeParam'] = challengeParam; resolve(user); }, mfaRequired: function (challengeName, challengeParam) { logger.debug('signIn MFA required'); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); }, mfaSetup: function (challengeName, challengeParam) { logger.debug('signIn mfa setup', challengeName); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); }, newPasswordRequired: function (userAttributes, requiredAttributes) { logger.debug('signIn new password'); user['challengeName'] = 'NEW_PASSWORD_REQUIRED'; user['challengeParam'] = { userAttributes: userAttributes, requiredAttributes: requiredAttributes }; resolve(user); }, totpRequired: function (challengeName, challengeParam) { logger.debug('signIn totpRequired'); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); }, selectMFAType: function (challengeName, challengeParam) { logger.debug('signIn selectMFAType', challengeName); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); } }; }; /** * Sign in with a password * @private * @param {AuthenticationDetails} authDetails - the user sign in data * @return - A promise resolves the CognitoUser object if success or mfa required */ AuthClass.prototype.signInWithPassword = function (authDetails) { var _this = this; var user = this.createCognitoUser(authDetails.getUsername()); return new Promise(function (resolve, reject) { user.authenticateUser(authDetails, _this.authCallbacks(user, resolve, reject)); }); }; /** * Sign in without a password * @private * @param {AuthenticationDetails} authDetails - the user sign in data * @return - A promise resolves the CognitoUser object if success or mfa required */ AuthClass.prototype.signInWithoutPassword = function (authDetails) { var _this = this; var user = this.createCognitoUser(authDetails.getUsername()); user.setAuthenticationFlowType('CUSTOM_AUTH'); return new Promise(function (resolve, reject) { user.initiateAuth(authDetails, _this.authCallbacks(user, resolve, reject)); }); }; /** * get user current preferred mfa option * this method doesn't work with totp, we need to deprecate it. * @deprecated * @param {CognitoUser} user - the current user * @return - A promise resolves the current preferred mfa option if success */ AuthClass.prototype.getMFAOptions = function (user) { return new Promise(function (res, rej) { user.getMFAOptions(function (err, mfaOptions) { if (err) { logger.debug('get MFA Options failed', err); rej(err); return; } logger.debug('get MFA options success', mfaOptions); res(mfaOptions); return; }); }); }; /** * get preferred mfa method * @param {CognitoUser} user - the current cognito user */ AuthClass.prototype.getPreferredMFA = function (user) { var that = this; return new Promise(function (res, rej) { user.getUserData(function (err, data) { if (err) { logger.debug('getting preferred mfa failed', err); rej(err); return; } var mfaType = that._getMfaTypeFromUserData(data); if (!mfaType) { rej('invalid MFA Type'); return; } else { res(mfaType); return; } }); }); }; AuthClass.prototype._getMfaTypeFromUserData = function (data) { var ret = null; var preferredMFA = data.PreferredMfaSetting; // if the user has used Auth.setPreferredMFA() to setup the mfa type // then the "PreferredMfaSetting" would exist in the response if (preferredMFA) { ret = preferredMFA; } else { // if mfaList exists but empty, then its noMFA var mfaList = data.UserMFASettingList; if (!mfaList) { // if SMS was enabled by using Auth.enableSMS(), // the response would contain MFAOptions // as for now Cognito only supports for SMS, so we will say it is 'SMS_MFA' // if it does not exist, then it should be NOMFA var MFAOptions = data.MFAOptions; if (MFAOptions) { ret = 'SMS_MFA'; } else { ret = 'NOMFA'; } } else if (mfaList.length === 0) { ret = 'NOMFA'; } else { logger.debug('invalid case for getPreferredMFA', data); } } return ret; }; AuthClass.prototype._getUserData = function (user) { return new Promise(function (res, rej) { user.getUserData(function (err, data) { if (err) { logger.debug('getting user data failed', err); rej(err); return; } else { res(data); return; } }); }); }; /** * set preferred MFA method * @param {CognitoUser} user - the current Cognito user * @param {string} mfaMethod - preferred mfa method * @return - A promise resolve if success */ AuthClass.prototype.setPreferredMFA = function (user, mfaMethod) { return __awaiter(this, void 0, void 0, function () { var userData, smsMfaSettings, totpMfaSettings, _a, mfaList, currentMFAType, that; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this._getUserData(user)]; case 1: userData = _b.sent(); smsMfaSettings = null; totpMfaSettings = null; _a = mfaMethod; switch (_a) { case 'TOTP' || 'SOFTWARE_TOKEN_MFA': return [3 /*break*/, 2]; case 'SMS' || 'SMS_MFA': return [3 /*break*/, 3]; case 'NOMFA': return [3 /*break*/, 4]; } return [3 /*break*/, 6]; case 2: totpMfaSettings = { PreferredMfa: true, Enabled: true }; return [3 /*break*/, 7]; case 3: smsMfaSettings = { PreferredMfa: true, Enabled: true }; return [3 /*break*/, 7]; case 4: mfaList = userData['UserMFASettingList']; return [4 /*yield*/, this._getMfaTypeFromUserData(userData)]; case 5: currentMFAType = _b.sent(); if (currentMFAType === 'NOMFA') { return [2 /*return*/, Promise.resolve('No change for mfa type')]; } else if (currentMFAType === 'SMS_MFA') { smsMfaSettings = { PreferredMfa: false, Enabled: false }; } else if (currentMFAType === 'SOFTWARE_TOKEN_MFA') { totpMfaSettings = { PreferredMfa: false, Enabled: false }; } else { return [2 /*return*/, Promise.reject('invalid MFA type')]; } // if there is a UserMFASettingList in the response // we need to disable every mfa type in that list if (mfaList && mfaList.length !== 0) { // to disable SMS or TOTP if exists in that list mfaList.forEach(function (mfaType) { if (mfaType === 'SMS_MFA') { smsMfaSettings = { PreferredMfa: false, Enabled: false }; } else if (mfaType === 'SOFTWARE_TOKEN_MFA') { totpMfaSettings = { PreferredMfa: false, Enabled: false }; } }); } return [3 /*break*/, 7]; case 6: logger.debug('no validmfa method provided'); return [2 /*return*/, Promise.reject('no validmfa method provided')]; case 7: that = this; return [2 /*return*/, new Promise(function (res, rej) { user.setUserMfaPreference(smsMfaSettings, totpMfaSettings, function (err, result) { if (err) { logger.debug('Set user mfa preference error', err); return rej(err); } logger.debug('Set user mfa success', result); return res(result); }); })]; } }); }); }; /** * diable SMS * @deprecated * @param {CognitoUser} user - the current user * @return - A promise resolves is success */ AuthClass.prototype.disableSMS = function (user) { return new Promise(function (res, rej) { user.disableMFA(function (err, data) { if (err) { logger.debug('disable mfa failed', err); rej(err); return; } logger.debug('disable mfa succeed', data); res(data); return; }); }); }; /** * enable SMS * @deprecated * @param {CognitoUser} user - the current user * @return - A promise resolves is success */ AuthClass.prototype.enableSMS = function (user) { return new Promise(function (res, rej) { user.enableMFA(function (err, data) { if (err) { logger.debug('enable mfa failed', err); rej(err); return; } logger.debug('enable mfa succeed', data); res(data); return; }); }); }; /** * Setup TOTP * @param {CognitoUser} user - the current user * @return - A promise resolves with the secret code if success */ AuthClass.prototype.setupTOTP = function (user) { return new Promise(function (res, rej) { user.associateSoftwareToken({ onFailure: function (err) { logger.debug('associateSoftwareToken failed', err); rej(err); return; }, associateSecretCode: function (secretCode) { logger.debug('associateSoftwareToken sucess', secretCode); res(secretCode); return; } }); }); }; /** * verify TOTP setup * @param {CognitoUser} user - the current user * @param {string} challengeAnswer - challenge answer * @return - A promise resolves is success */ AuthClass.prototype.verifyTotpToken = function (user, challengeAnswer) { logger.debug('verfication totp token', user, challengeAnswer); return new Promise(function (res, rej) { user.verifySoftwareToken(challengeAnswer, 'My TOTP device', { onFailure: function (err) { logger.debug('verifyTotpToken failed', err); rej(err); return; }, onSuccess: function (data) { logger.debug('verifyTotpToken success', data); res(data); return; } }); }); }; /** * Send MFA code to confirm sign in * @param {Object} user - The CognitoUser object * @param {String} code - The confirmation code */ AuthClass.prototype.confirmSignIn = function (user, code, mfaType) { var _this = this; if (!code) { return Promise.reject('Code cannot be empty'); } var that = this; return new Promise(function (resolve, reject) { user.sendMFACode(code, { onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () { var cred, e_3; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.debug(session); _a.label = 1; case 1: _a.trys.push([1, 4, 5, 6]); return [4 /*yield*/, core_1.Credentials.clear()]; case 2: _a.sent(); return [4 /*yield*/, core_1.Credentials.set(session, 'session')]; case 3: cred = _a.sent(); logger.debug('succeed to get cognito credentials', cred); return [3 /*break*/, 6]; case 4: e_3 = _a.sent(); logger.debug('cannot get cognito credentials', e_3); return [3 /*break*/, 6]; case 5: that.user = user; dispatchAuthEvent('signIn', user); resolve(user); return [7 /*endfinally*/]; case 6: return [2 /*return*/]; } }); }); }, onFailure: function (err) { logger.debug('confirm signIn failure', err); reject(err); } }, mfaType); }); }; AuthClass.prototype.completeNewPassword = function (user, password, requiredAttributes) { var _this = this; if (!password) { return Promise.reject('Password cannot be empty'); } var that = this; return new Promise(function (resolve, reject) { user.completeNewPasswordChallenge(password, requiredAttributes, { onSuccess: function (session) { return __awaiter(_this, void 0, void 0, function () { var cred, e_4; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.debug(session); _a.label = 1; case 1: _a.trys.push([1, 4, 5, 6]); return [4 /*yield*/, core_1.Credentials.clear()]; case 2: _a.sent(); return [4 /*yield*/, core_1.Credentials.set(session, 'session')]; case 3: cred = _a.sent(); logger.debug('succeed to get cognito credentials', cred); return [3 /*break*/, 6]; case 4: e_4 = _a.sent(); logger.debug('cannot get cognito credentials', e_4); return [3 /*break*/, 6]; case 5: that.user = user; dispatchAuthEvent('signIn', user); resolve(user); return [7 /*endfinally*/]; case 6: return [2 /*return*/]; } }); }); }, onFailure: function (err) { logger.debug('completeNewPassword failure', err); dispatchAuthEvent('completeNewPassword_failure', err); reject(err); }, mfaRequired: function (challengeName, challengeParam) { logger.debug('signIn MFA required'); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); }, mfaSetup: function (challengeName, challengeParam) { logger.debug('signIn mfa setup', challengeName); user['challengeName'] = challengeName; user['challengeParam'] = challengeParam; resolve(user); } }); }); }; /** * Send the answer to a custom challenge * @param {CognitoUser} user - The CognitoUser object * @param {String} challengeResponses - The confirmation code */ AuthClass.prototype.sendCustomChallengeAnswer = function (user, challengeResponses) { var _this = this; if (!this.userPool) { return Promise.reject('No userPool'); } if (!challengeResponses) { return Promise.reject('Challenge response cannot be empty'); } var that = this; return new Promise(function (resolve, reject) { user.sendCustomChallengeAnswer(challengeResponses, _this.authCallbacks(user, resolve, reject)); }); }; /** * Update an authenticated users' attributes * @param {CognitoUser} - The currently logged in user object * @return {Promise} **/ AuthClass.prototype.updateUserAttributes = function (user, attributes) { var attributeList = []; var that = this; return new Promise(function (resolve, reject) { that.userSession(user).then(function (session) { for (var key in attributes) { if (key !== 'sub' && key.indexOf('_verified') < 0) { var attr = { 'Name': key, 'Value': attributes[key] }; attributeList.push(attr); } } user.updateAttributes(attributeList, function (err, result) { if (err) { return reject(err); } else { return resolve(result); } }); }); }); }; /** * Return user attributes * @param {Object} user - The CognitoUser object * @return - A promise resolves to user attributes if success */ AuthClass.prototype.userAttributes = function (user) { var _this = this; return new Promise(function (resolve, reject) { _this.userSession(user).then(function (session) { user.getUserAttributes(function (err, attributes) { if (err) { reject(err); } else { resolve(attributes); } }); }); }); }; AuthClass.prototype.verifiedContact = function (user) { var that = this; return this.userAttributes(user) .then(function (attributes) { var attrs = that.attributesToObject(attributes); var unverified = {}; var verified = {}; if (attrs['email']) { if (attrs['email_verified']) { verified['email'] = attrs['email']; } else { unverified['email'] = attrs['email']; } } if (attrs['phone_number']) { if (attrs['phone_number_verified']) { verified['phone_number'] = attrs['phone_number']; } else { unverified['phone_number'] = attrs['phone_number']; } } return { verified: verified, unverified: unverified }; }); }; /** * Get current authenticated user * @return - A promise resolves to curret authenticated CognitoUser if success */ AuthClass.prototype.currentUserPoolUser = function (params) { var _this = this; if (!this.userPool) { return Promise.reject('No userPool'); } var that = this; return new Promise(function (res, rej) { _this._storageSync.then(function () { var user = that.userPool.getCurrentUser(); if (!user) { logger.debug('Failed to get user from user pool'); rej('No current user'); return; } // refresh the session if the session expired. user.getSession(function (err, session) { if (err) { logger.debug('Failed to get the user session', err); rej(err); return; } // get user data from Cognito var bypassCache = params ? params.bypassCache : false; user.getUserData(function (err, data) { if (err) { logger.debug('getting user data failed', err); // Make sure the user is still valid if (err.message === 'User is disabled' || err.message === 'User does not exist.') { rej(err); } else { // the error may also be thrown when lack of permissions to get user info etc // in that case we just bypass the error res(user); } return; } var preferredMFA = data.PreferredMfaSetting || 'NOMFA'; var attributeList = []; for (var i = 0; i < data.UserAttributes.length; i++) { var attribute = { Name: data.UserAttributes[i].Name, Value: data.UserAttributes[i].Value, }; var userAttribute = new amazon_cognito_identity_js_1.CognitoUserAttribute(attribute); attributeList.push(userAttribute); } var attributes = that.attributesToObject(attributeList); Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA }); return res(user); }, { bypassCache: bypassCache }); }); }).catch(function (e) { logger.debug('Failed to sync cache info into memory', e); return rej(e); }); }); }; /** * Get current authenticated user * @param {CurrentUserOpts} - options for getting the current user * @return - A promise resolves to curret authenticated CognitoUser if success */ AuthClass.prototype.currentAuthenticatedUser = function (params) { return __awaiter(this, void 0, void 0, function () { var federatedUser, user, e_5; return __generator(this, function (_a) { switch (_a.label) { case 0: logger.debug('getting current authenticted user'); federatedUser = null; try { federatedUser = JSON.parse(this._storage.getItem('aws-amplify-federatedInfo')).user; } catch (e) { logger.debug('cannot load federated user from auth storage'); } if (!federatedUser) return [3 /*break*/, 1]; this.user = federatedUser; logger.debug('get current authenticated federated user', this.user); return [2 /*return*/, this.user]; case 1: logger.debug('get current authenticated userpool user'); user = null; _a.label = 2; case 2: _a.trys.push([2, 4, , 5]); return [4 /*yield*/, this.currentUserPoolUser(params)]; case 3: user = _a.sent(); return [3 /*break*/, 5]; case 4: e_5 = _a.sent(); logger.debug('The user is not authenticated by the error', e_5); throw ('not authenticated'); case 5: this.user = user; return [2 /*return*/, this.user]; } }); }); }; /** * Get current user's session * @return - A promise resolves to session object if success */ AuthClass.prototype.currentSession = function () { var that = this; logger.debug('Getting current session'); if (!this.userPool) { return Promise.reject('No userPool'); } return new Promise(function (res, rej) { that.currentUserPoolUser().then(function (user) { that.userSession(user).then(function (session) { res(session); return; }).catch(function (e) { logger.debug('Failed to get the current session', e); rej(e); return; }); }).catch(function (e) { logger.debug('Failed to get the current user', e); rej(e); return; }); }); }; /** * Get the corresponding user session * @param {Object} user - The CognitoUser object * @return - A promise resolves to the session */ AuthClass.prototype.userSession = function (user) { if (!user) { logger.debug('the user is null'); return Promise.reject('Failed to get the session because the user is empty'); } return new Promise(function (resolve, reject) { logger.debug('Getting the session from this user:', user); user.getSession(function (err, session) { if (err) { logger.debug('Failed to get the session from user', user); reject(err); return; } else { logger.debug('Succeed to get the user session', session); resolve(session); return; } }); }); }; /** * Get authenticated credentials of current user. * @return - A promise resolves to be current user's credentials */ AuthClass.prototype.currentUserCredentials = function () { var that = this; logger.debug('Getting current user credentials'); // first to check whether there is federation info in the auth storage var federatedInfo = null; try { federatedInfo = JSON.parse(this._storage.getItem('aws-amplify-federatedInfo')); } catch (e) { logger.debug('failed to get or parse item aws-amplify-federatedInfo', e); } if (federatedInfo) { // refresh the jwt token here if necessary return core_1.Credentials.refreshFederatedToken(federatedInfo); } else { return this.currentSession() .then(function (session) { logger.debug('getting session success', session); return core_1.Credentials.set(session, 'session'); }).catch(function (error) { logger.debug('getting session failed', error); return core_1.Credentials.set(null, 'guest'); }); } }; AuthClass.prototype.currentCredentials = function () { logger.debug('getting current credntials'); return core_1.Credentials.get(); }; /** * Initiate an attribute confirmation request * @param {Object} user - The CognitoUser * @param {Object} attr - The attributes to be verified * @return - A promise resolves to callback data if s