@aws-amplify/auth 5.6.4-user-agent-backup.c6dfb36.0 → 5.6.4

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