@aws-amplify/auth
Version:
Auth category of aws-amplify
1,134 lines • 77.1 kB
JavaScript
"use strict";
/*
* Copyright 2017-2019 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 url_1 = require("url");
var OAuth_1 = require("./OAuth/OAuth");
var urlListener_1 = require("./urlListener");
var logger = new core_1.ConsoleLogger('AuthClass');
var USER_ADMIN_SCOPE = 'aws.cognito.signin.user.admin';
var AMPLIFY_SYMBOL = ((typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') ?
Symbol.for('amplify_default') : '@@amplify_default');
var dispatchAuthEvent = function (event, data, message) {
core_1.Hub.dispatch('auth', { event: event, data: data, message: message }, 'Auth', AMPLIFY_SYMBOL);
};
var CognitoHostedUIIdentityProvider;
(function (CognitoHostedUIIdentityProvider) {
CognitoHostedUIIdentityProvider["Cognito"] = "COGNITO";
CognitoHostedUIIdentityProvider["Google"] = "Google";
CognitoHostedUIIdentityProvider["Facebook"] = "Facebook";
CognitoHostedUIIdentityProvider["Amazon"] = "LoginWithAmazon";
})(CognitoHostedUIIdentityProvider = exports.CognitoHostedUIIdentityProvider || (exports.CognitoHostedUIIdentityProvider = {}));
/**
* Provide authentication steps
*/
var AuthClass = /** @class */ (function () {
/**
* Initialize Auth with AWS configurations
* @param {Object} config - Configuration of the Auth
*/
function AuthClass(config) {
var _this = this;
this.userPool = null;
this.user = 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');
}
core_1.Hub.listen('auth', function (_a) {
var payload = _a.payload;
var event = payload.event;
switch (event) {
case 'signIn':
_this._storage.setItem('amplify-signin-with-hostedUI', 'false');
break;
case 'signOut':
_this._storage.removeItem('amplify-signin-with-hostedUI');
break;
case 'cognitoHostedUI':
_this._storage.setItem('amplify-signin-with-hostedUI', 'true');
break;
}
});
}
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, 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 {
if (core_1.JS.isEmpty(this._config.storage)) {
logger.error('The storage in the Auth config can not be empty!');
throw new Error('Empty storage object');
}
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 ? (types_1.isCognitoHostedOpts(this._config.oauth)
? oauth : oauth.awsCognito)
: undefined;
if (cognitoHostedUIConfig) {
var cognitoAuthParams = Object.assign({
cognitoClientId: userPoolWebClientId,
UserPoolId: userPoolId,
domain: cognitoHostedUIConfig['domain'],
scopes: cognitoHostedUIConfig['scope'],
redirectSignIn: cognitoHostedUIConfig['redirectSignIn'],
redirectSignOut: cognitoHostedUIConfig['redirectSignOut'],
responseType: cognitoHostedUIConfig['responseType'],
Storage: this._storage,
urlOpener: cognitoHostedUIConfig['urlOpener']
}, cognitoHostedUIConfig['options']);
this._oAuthHandler = new OAuth_1.default({
scopes: cognitoAuthParams.scopes,
config: cognitoAuthParams,
cognitoClientId: cognitoAuthParams.cognitoClientId
});
// **NOTE** - Remove this in a future major release as it is a breaking change
urlListener_1.default(function (_a) {
var url = _a.url;
_this._handleAuthResponse(url);
});
}
dispatchAuthEvent('configured', null, "The Auth category has been configured successfully");
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, username + " failed to signup");
reject(err);
}
else {
dispatchAuthEvent('signUp', data, username + " has signed up successfully");
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_1, currentUser, 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, 9]);
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*/, 9];
case 4:
e_1 = _a.sent();
logger.debug('cannot get cognito credentials', e_1);
return [3 /*break*/, 9];
case 5:
_a.trys.push([5, 7, , 8]);
return [4 /*yield*/, this.currentUserPoolUser()];
case 6:
currentUser = _a.sent();
that.user = currentUser;
dispatchAuthEvent('signIn', currentUser, "A user " + user.getUsername() + " has been signed in");
resolve(currentUser);
return [3 /*break*/, 8];
case 7:
e_2 = _a.sent();
logger.error('Failed to get the signed in user', e_2);
reject(e_2);
return [3 /*break*/, 8];
case 8: return [7 /*endfinally*/];
case 9: return [2 /*return*/];
}
});
}); },
onFailure: function (err) {
logger.debug('signIn failure', err);
dispatchAuthEvent('signIn_failure', err, user.getUsername() + " failed to signin");
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
* @param {GetPreferredMFAOpts} params - options for getting the current user preferred MFA
*/
AuthClass.prototype.getPreferredMFA = function (user, params) {
var that = this;
return new Promise(function (res, rej) {
var bypassCache = params ? params.bypassCache : false;
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;
}
}, { bypassCache: bypassCache });
});
};
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, params) {
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;
}
}, params);
});
};
/**
* 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, { bypassCache: true })];
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);
logger.debug('Caching the latest user data into local');
// cache the latest result into user data
user.getUserData(function (err, data) {
if (err) {
logger.debug('getting user data failed', err);
return rej(err);
}
else {
return res(result);
}
}, { bypassCache: true });
});
})];
}
});
});
};
/**
* 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, user + " has signed in");
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, user + " has signed in");
resolve(user);
return [7 /*endfinally*/];
case 6: return [2 /*return*/];
}
});
}); },
onFailure: function (err) {
logger.debug('completeNewPassword failure', err);
dispatchAuthEvent('completeNewPassword_failure', err, _this.user + " failed to complete the new password flow");
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 current 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;
// validate the token's scope fisrt before calling this function
var _a = session.getAccessToken().decodePayload().scope, scope = _a === void 0 ? '' : _a;
if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
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 });
}
else {
logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
"is not in the scopes of the access token");
return res(user);
}
});
}).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 current authenticated CognitoUser if success
*/
AuthClass.prototype.currentAuthenticatedUser = function (params) {
return __awaiter(this, void 0, void 0, function () {
var federatedUser, e_5, user, e_6;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
logger.debug('getting current authenticted user');
federatedUser = null;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this._storageSync];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
e_5 = _a.sent();
logger.debug('Failed to sync cache info into memory', e_5);
throw e_5;
case 4:
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*/, 5];
this.user = federatedUser;
logger.debug('get current authenticated federated user', this.user);
return [2 /*return*/, this.user];
case 5:
logger.debug('get current authenticated userpool user');
user = null;
_a.label = 6;
case 6:
_a.trys.push([6, 8, , 9]);
return [4 /*yield*/, this.currentUserPoolUser(params)];
case 7:
user = _a.sent();
return [3 /*break*/, 9];
case 8:
e_6 = _a.sent();
if (e_6 === 'No userPool') {
logger.error('Cannot get the current user because the user pool is missing. ' +
'Please make sure the Auth module is configured with a valid Cognito User Pool ID');
}
logger.debug('The user is not authenticated by the error', e_6);
throw ('not authenticated');
case 9:
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 ne