@aws-amplify/auth 5.0.2-unstable.3 → 5.0.2-unstable.7

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.d.ts CHANGED
@@ -16,6 +16,8 @@ export declare class AuthClass {
16
16
  private oAuthFlowInProgress;
17
17
  private pendingSignIn;
18
18
  private autoSignInInitiated;
19
+ private inflightSessionPromise;
20
+ private inflightSessionPromiseCounter;
19
21
  Credentials: import("@aws-amplify/core").CredentialsClass;
20
22
  /**
21
23
  * Initialize Auth with AWS configurations
@@ -199,6 +201,7 @@ export declare class AuthClass {
199
201
  * @return - A promise resolves to session object if success
200
202
  */
201
203
  currentSession(): Promise<CognitoUserSession>;
204
+ private _userSession;
202
205
  /**
203
206
  * Get the corresponding user session
204
207
  * @param {Object} user - The CognitoUser object
package/lib/Auth.js CHANGED
@@ -40,6 +40,8 @@ var AuthClass = /** @class */ (function () {
40
40
  this.user = null;
41
41
  this.oAuthFlowInProgress = false;
42
42
  this.autoSignInInitiated = false;
43
+ this.inflightSessionPromise = null;
44
+ this.inflightSessionPromiseCounter = 0;
43
45
  this.Credentials = core_1.Credentials;
44
46
  this.wrapRefreshSessionCallback = function (callback) {
45
47
  var wrapped = function (error, data) {
@@ -1376,10 +1378,10 @@ var AuthClass = /** @class */ (function () {
1376
1378
  return new Promise(function (res, rej) {
1377
1379
  _this._storageSync
1378
1380
  .then(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1379
- var user, clientMetadata;
1381
+ var user, session, bypassCache, clientMetadata, _a, scope, err_1;
1380
1382
  var _this = this;
1381
- return tslib_1.__generator(this, function (_a) {
1382
- switch (_a.label) {
1383
+ return tslib_1.__generator(this, function (_b) {
1384
+ switch (_b.label) {
1383
1385
  case 0:
1384
1386
  if (!this.isOAuthInProgress()) return [3 /*break*/, 2];
1385
1387
  logger.debug('OAuth signIn in progress, waiting for resolution...');
@@ -1403,8 +1405,8 @@ var AuthClass = /** @class */ (function () {
1403
1405
  }
1404
1406
  })];
1405
1407
  case 1:
1406
- _a.sent();
1407
- _a.label = 2;
1408
+ _b.sent();
1409
+ _b.label = 2;
1408
1410
  case 2:
1409
1411
  user = this.userPool.getCurrentUser();
1410
1412
  if (!user) {
@@ -1412,96 +1414,77 @@ var AuthClass = /** @class */ (function () {
1412
1414
  rej('No current user');
1413
1415
  return [2 /*return*/];
1414
1416
  }
1417
+ _b.label = 3;
1418
+ case 3:
1419
+ _b.trys.push([3, 7, , 8]);
1420
+ return [4 /*yield*/, this._userSession(user)];
1421
+ case 4:
1422
+ session = _b.sent();
1423
+ bypassCache = params ? params.bypassCache : false;
1424
+ if (!bypassCache) return [3 /*break*/, 6];
1425
+ return [4 /*yield*/, this.Credentials.clear()];
1426
+ case 5:
1427
+ _b.sent();
1428
+ _b.label = 6;
1429
+ case 6:
1415
1430
  clientMetadata = this._config.clientMetadata;
1416
- // refresh the session if the session expired.
1417
- user.getSession(function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1418
- var cleanUpError_5, bypassCache, clientMetadata, _a, scope;
1419
- var _this = this;
1420
- return tslib_1.__generator(this, function (_b) {
1421
- switch (_b.label) {
1422
- case 0:
1423
- if (!err) return [3 /*break*/, 5];
1424
- logger.debug('Failed to get the user session', err);
1425
- if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1426
- _b.label = 1;
1427
- case 1:
1428
- _b.trys.push([1, 3, , 4]);
1429
- return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1430
- case 2:
1431
- _b.sent();
1432
- return [3 /*break*/, 4];
1433
- case 3:
1434
- cleanUpError_5 = _b.sent();
1435
- rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_5.message));
1436
- return [2 /*return*/];
1437
- case 4:
1438
- rej(err);
1439
- return [2 /*return*/];
1440
- case 5:
1441
- bypassCache = params ? params.bypassCache : false;
1442
- if (!bypassCache) return [3 /*break*/, 7];
1443
- return [4 /*yield*/, this.Credentials.clear()];
1444
- case 6:
1445
- _b.sent();
1446
- _b.label = 7;
1447
- case 7:
1448
- clientMetadata = this._config.clientMetadata;
1449
- _a = session.getAccessToken().decodePayload().scope, scope = _a === void 0 ? '' : _a;
1450
- if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
1451
- user.getUserData(function (err, data) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1452
- var cleanUpError_6, preferredMFA, attributeList, i, attribute, userAttribute, attributes;
1453
- return tslib_1.__generator(this, function (_a) {
1454
- switch (_a.label) {
1455
- case 0:
1456
- if (!err) return [3 /*break*/, 7];
1457
- logger.debug('getting user data failed', err);
1458
- if (!this.isSessionInvalid(err)) return [3 /*break*/, 5];
1459
- _a.label = 1;
1460
- case 1:
1461
- _a.trys.push([1, 3, , 4]);
1462
- return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1463
- case 2:
1464
- _a.sent();
1465
- return [3 /*break*/, 4];
1466
- case 3:
1467
- cleanUpError_6 = _a.sent();
1468
- rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_6.message));
1469
- return [2 /*return*/];
1470
- case 4:
1471
- rej(err);
1472
- return [3 /*break*/, 6];
1473
- case 5:
1474
- res(user);
1475
- _a.label = 6;
1476
- case 6: return [2 /*return*/];
1477
- case 7:
1478
- preferredMFA = data.PreferredMfaSetting || 'NOMFA';
1479
- attributeList = [];
1480
- for (i = 0; i < data.UserAttributes.length; i++) {
1481
- attribute = {
1482
- Name: data.UserAttributes[i].Name,
1483
- Value: data.UserAttributes[i].Value,
1484
- };
1485
- userAttribute = new amazon_cognito_identity_js_1.CognitoUserAttribute(attribute);
1486
- attributeList.push(userAttribute);
1487
- }
1488
- attributes = this.attributesToObject(attributeList);
1489
- Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA });
1490
- return [2 /*return*/, res(user)];
1491
- }
1492
- });
1493
- }); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
1494
- }
1495
- else {
1496
- logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
1497
- "is not in the scopes of the access token");
1431
+ _a = session.getAccessToken().decodePayload().scope, scope = _a === void 0 ? '' : _a;
1432
+ if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
1433
+ user.getUserData(function (err, data) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1434
+ var cleanUpError_5, preferredMFA, attributeList, i, attribute, userAttribute, attributes;
1435
+ return tslib_1.__generator(this, function (_a) {
1436
+ switch (_a.label) {
1437
+ case 0:
1438
+ if (!err) return [3 /*break*/, 7];
1439
+ logger.debug('getting user data failed', err);
1440
+ if (!this.isSessionInvalid(err)) return [3 /*break*/, 5];
1441
+ _a.label = 1;
1442
+ case 1:
1443
+ _a.trys.push([1, 3, , 4]);
1444
+ return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1445
+ case 2:
1446
+ _a.sent();
1447
+ return [3 /*break*/, 4];
1448
+ case 3:
1449
+ cleanUpError_5 = _a.sent();
1450
+ rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_5.message));
1451
+ return [2 /*return*/];
1452
+ case 4:
1453
+ rej(err);
1454
+ return [3 /*break*/, 6];
1455
+ case 5:
1456
+ res(user);
1457
+ _a.label = 6;
1458
+ case 6: return [2 /*return*/];
1459
+ case 7:
1460
+ preferredMFA = data.PreferredMfaSetting || 'NOMFA';
1461
+ attributeList = [];
1462
+ for (i = 0; i < data.UserAttributes.length; i++) {
1463
+ attribute = {
1464
+ Name: data.UserAttributes[i].Name,
1465
+ Value: data.UserAttributes[i].Value,
1466
+ };
1467
+ userAttribute = new amazon_cognito_identity_js_1.CognitoUserAttribute(attribute);
1468
+ attributeList.push(userAttribute);
1469
+ }
1470
+ attributes = this.attributesToObject(attributeList);
1471
+ Object.assign(user, { attributes: attributes, preferredMFA: preferredMFA });
1498
1472
  return [2 /*return*/, res(user)];
1499
- }
1500
- return [2 /*return*/];
1501
- }
1502
- });
1503
- }); }, { clientMetadata: clientMetadata });
1504
- return [2 /*return*/];
1473
+ }
1474
+ });
1475
+ }); }, { bypassCache: bypassCache, clientMetadata: clientMetadata });
1476
+ }
1477
+ else {
1478
+ logger.debug("Unable to get the user data because the " + USER_ADMIN_SCOPE + " " +
1479
+ "is not in the scopes of the access token");
1480
+ return [2 /*return*/, res(user)];
1481
+ }
1482
+ return [3 /*break*/, 8];
1483
+ case 7:
1484
+ err_1 = _b.sent();
1485
+ rej(err_1);
1486
+ return [3 /*break*/, 8];
1487
+ case 8: return [2 /*return*/];
1505
1488
  }
1506
1489
  });
1507
1490
  }); })
@@ -1611,50 +1594,79 @@ var AuthClass = /** @class */ (function () {
1611
1594
  });
1612
1595
  });
1613
1596
  };
1597
+ AuthClass.prototype._userSession = function (user) {
1598
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1599
+ var clientMetadata, userSession;
1600
+ var _this = this;
1601
+ return tslib_1.__generator(this, function (_a) {
1602
+ switch (_a.label) {
1603
+ case 0:
1604
+ if (!user) {
1605
+ logger.debug('the user is null');
1606
+ return [2 /*return*/, this.rejectAuthError(Auth_1.AuthErrorTypes.NoUserSession)];
1607
+ }
1608
+ clientMetadata = this._config.clientMetadata;
1609
+ // Debouncing the concurrent userSession calls by caching the promise.
1610
+ // This solution assumes users will always call this function with the same CognitoUser instance.
1611
+ if (this.inflightSessionPromiseCounter === 0) {
1612
+ this.inflightSessionPromise = new Promise(function (res, rej) {
1613
+ user.getSession(function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1614
+ var cleanUpError_6;
1615
+ return tslib_1.__generator(this, function (_a) {
1616
+ switch (_a.label) {
1617
+ case 0:
1618
+ if (!err) return [3 /*break*/, 5];
1619
+ logger.debug('Failed to get the session from user', user);
1620
+ if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1621
+ _a.label = 1;
1622
+ case 1:
1623
+ _a.trys.push([1, 3, , 4]);
1624
+ return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1625
+ case 2:
1626
+ _a.sent();
1627
+ return [3 /*break*/, 4];
1628
+ case 3:
1629
+ cleanUpError_6 = _a.sent();
1630
+ rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_6.message));
1631
+ return [2 /*return*/];
1632
+ case 4:
1633
+ rej(err);
1634
+ return [2 /*return*/];
1635
+ case 5:
1636
+ logger.debug('Succeed to get the user session', session);
1637
+ res(session);
1638
+ return [2 /*return*/];
1639
+ }
1640
+ });
1641
+ }); }, { clientMetadata: clientMetadata });
1642
+ });
1643
+ }
1644
+ this.inflightSessionPromiseCounter++;
1645
+ _a.label = 1;
1646
+ case 1:
1647
+ _a.trys.push([1, , 3, 4]);
1648
+ return [4 /*yield*/, this.inflightSessionPromise];
1649
+ case 2:
1650
+ userSession = _a.sent();
1651
+ // Set private member. Avoid user.setSignInUserSession() to prevent excessive localstorage refresh.
1652
+ // @ts-ignore
1653
+ user.signInUserSession = userSession;
1654
+ return [2 /*return*/, userSession];
1655
+ case 3:
1656
+ this.inflightSessionPromiseCounter--;
1657
+ return [7 /*endfinally*/];
1658
+ case 4: return [2 /*return*/];
1659
+ }
1660
+ });
1661
+ });
1662
+ };
1614
1663
  /**
1615
1664
  * Get the corresponding user session
1616
1665
  * @param {Object} user - The CognitoUser object
1617
1666
  * @return - A promise resolves to the session
1618
1667
  */
1619
1668
  AuthClass.prototype.userSession = function (user) {
1620
- var _this = this;
1621
- if (!user) {
1622
- logger.debug('the user is null');
1623
- return this.rejectAuthError(Auth_1.AuthErrorTypes.NoUserSession);
1624
- }
1625
- var clientMetadata = this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1626
- return new Promise(function (res, rej) {
1627
- logger.debug('Getting the session from this user:', user);
1628
- user.getSession(function (err, session) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1629
- var cleanUpError_7;
1630
- return tslib_1.__generator(this, function (_a) {
1631
- switch (_a.label) {
1632
- case 0:
1633
- if (!err) return [3 /*break*/, 5];
1634
- logger.debug('Failed to get the session from user', user);
1635
- if (!this.isSessionInvalid(err)) return [3 /*break*/, 4];
1636
- _a.label = 1;
1637
- case 1:
1638
- _a.trys.push([1, 3, , 4]);
1639
- return [4 /*yield*/, this.cleanUpInvalidSession(user)];
1640
- case 2:
1641
- _a.sent();
1642
- return [3 /*break*/, 4];
1643
- case 3:
1644
- cleanUpError_7 = _a.sent();
1645
- rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_7.message));
1646
- return [2 /*return*/];
1647
- case 4:
1648
- rej(err);
1649
- return [2 /*return*/];
1650
- case 5:
1651
- logger.debug('Succeed to get the user session', session);
1652
- res(session);
1653
- return [2 /*return*/];
1654
- }
1655
- });
1656
- }); }, { clientMetadata: clientMetadata });
1657
- });
1669
+ return this._userSession(user);
1658
1670
  };
1659
1671
  /**
1660
1672
  * Get authenticated credentials of current user.
@@ -1798,7 +1810,7 @@ var AuthClass = /** @class */ (function () {
1798
1810
  // we must validate the user as an authenticated user by using getSession
1799
1811
  var clientMetadata = _this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1800
1812
  user.getSession(function (err, result) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1801
- var cleanUpError_8;
1813
+ var cleanUpError_7;
1802
1814
  var _this = this;
1803
1815
  return tslib_1.__generator(this, function (_a) {
1804
1816
  switch (_a.label) {
@@ -1814,8 +1826,8 @@ var AuthClass = /** @class */ (function () {
1814
1826
  _a.sent();
1815
1827
  return [3 /*break*/, 4];
1816
1828
  case 3:
1817
- cleanUpError_8 = _a.sent();
1818
- rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_8.message));
1829
+ cleanUpError_7 = _a.sent();
1830
+ rej(new Error("Session is invalid due to: " + err.message + " and failed to clean up invalid session: " + cleanUpError_7.message));
1819
1831
  return [2 /*return*/];
1820
1832
  case 4: return [2 /*return*/, rej(err)];
1821
1833
  case 5:
@@ -2039,7 +2051,7 @@ var AuthClass = /** @class */ (function () {
2039
2051
  */
2040
2052
  AuthClass.prototype.currentUserInfo = function () {
2041
2053
  return tslib_1.__awaiter(this, void 0, void 0, function () {
2042
- var source, user, attributes, userAttrs, credentials, e_12, info, err_1, user;
2054
+ var source, user, attributes, userAttrs, credentials, e_12, info, err_2, user;
2043
2055
  return tslib_1.__generator(this, function (_a) {
2044
2056
  switch (_a.label) {
2045
2057
  case 0:
@@ -2080,8 +2092,8 @@ var AuthClass = /** @class */ (function () {
2080
2092
  };
2081
2093
  return [2 /*return*/, info];
2082
2094
  case 8:
2083
- err_1 = _a.sent();
2084
- logger.error('currentUserInfo error', err_1);
2095
+ err_2 = _a.sent();
2096
+ logger.error('currentUserInfo error', err_2);
2085
2097
  return [2 /*return*/, {}];
2086
2098
  case 9:
2087
2099
  if (source === 'federated') {
@@ -2162,7 +2174,7 @@ var AuthClass = /** @class */ (function () {
2162
2174
  */
2163
2175
  AuthClass.prototype._handleAuthResponse = function (URL) {
2164
2176
  return tslib_1.__awaiter(this, void 0, void 0, function () {
2165
- var currentUrl, hasCodeOrError, hasTokenOrError, _a, accessToken, idToken, refreshToken, state, session, credentials, isCustomStateIncluded, currentUser, customState, err_2;
2177
+ var currentUrl, hasCodeOrError, hasTokenOrError, _a, accessToken, idToken, refreshToken, state, session, credentials, isCustomStateIncluded, currentUser, customState, err_3;
2166
2178
  return tslib_1.__generator(this, function (_b) {
2167
2179
  switch (_b.label) {
2168
2180
  case 0:
@@ -2235,16 +2247,16 @@ var AuthClass = /** @class */ (function () {
2235
2247
  //#endregion
2236
2248
  return [2 /*return*/, credentials];
2237
2249
  case 6:
2238
- err_2 = _b.sent();
2239
- logger.debug('Error in cognito hosted auth response', err_2);
2250
+ err_3 = _b.sent();
2251
+ logger.debug('Error in cognito hosted auth response', err_3);
2240
2252
  // Just like a successful handling of `?code`, replace the window history to "dispose" of the `code`.
2241
2253
  // Otherwise, reloading the page will throw errors as the `code` has already been spent.
2242
2254
  if (window && typeof window.history !== 'undefined') {
2243
2255
  window.history.replaceState({}, null, this._config.oauth.redirectSignIn);
2244
2256
  }
2245
- dispatchAuthEvent('signIn_failure', err_2, "The OAuth response flow failed");
2246
- dispatchAuthEvent('cognitoHostedUI_failure', err_2, "A failure occurred when returning to the Cognito Hosted UI");
2247
- dispatchAuthEvent('customState_failure', err_2, "A failure occurred when returning state");
2257
+ dispatchAuthEvent('signIn_failure', err_3, "The OAuth response flow failed");
2258
+ dispatchAuthEvent('cognitoHostedUI_failure', err_3, "A failure occurred when returning to the Cognito Hosted UI");
2259
+ dispatchAuthEvent('customState_failure', err_3, "A failure occurred when returning state");
2248
2260
  return [3 /*break*/, 7];
2249
2261
  case 7: return [3 /*break*/, 9];
2250
2262
  case 8: