@aws-amplify/auth
Version:
Auth category of aws-amplify
1,157 lines • 64.9 kB
JavaScript
"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