@aws-amplify/auth 4.4.3-cloud-logging.7 → 4.4.3-cloud-logging.8

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/src/Auth.ts CHANGED
@@ -700,9 +700,21 @@ export class AuthClass {
700
700
 
701
701
  const bypassCache = params ? params.bypassCache : false;
702
702
  user.getUserData(
703
- (err, data) => {
703
+ async (err, data) => {
704
704
  if (err) {
705
705
  logger.debug('getting preferred mfa failed', err);
706
+ if (this.isSessionInvalid(err)) {
707
+ try {
708
+ await this.cleanUpInvalidSession(user);
709
+ } catch (cleanUpError) {
710
+ rej(
711
+ new Error(
712
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
713
+ )
714
+ );
715
+ return;
716
+ }
717
+ }
706
718
  rej(err);
707
719
  return;
708
720
  }
@@ -753,14 +765,25 @@ export class AuthClass {
753
765
 
754
766
  private _getUserData(user, params) {
755
767
  return new Promise((res, rej) => {
756
- user.getUserData((err, data) => {
768
+ user.getUserData(async (err, data) => {
757
769
  if (err) {
758
770
  logger.debug('getting user data failed', err);
771
+ if (this.isSessionInvalid(err)) {
772
+ try {
773
+ await this.cleanUpInvalidSession(user);
774
+ } catch (cleanUpError) {
775
+ rej(
776
+ new Error(
777
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
778
+ )
779
+ );
780
+ return;
781
+ }
782
+ }
759
783
  rej(err);
760
784
  return;
761
785
  } else {
762
786
  res(data);
763
- return;
764
787
  }
765
788
  }, params);
766
789
  });
@@ -856,9 +879,21 @@ export class AuthClass {
856
879
  logger.debug('Caching the latest user data into local');
857
880
  // cache the latest result into user data
858
881
  user.getUserData(
859
- (err, data) => {
882
+ async (err, data) => {
860
883
  if (err) {
861
884
  logger.debug('getting user data failed', err);
885
+ if (this.isSessionInvalid(err)) {
886
+ try {
887
+ await this.cleanUpInvalidSession(user);
888
+ } catch (cleanUpError) {
889
+ rej(
890
+ new Error(
891
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
892
+ )
893
+ );
894
+ return;
895
+ }
896
+ }
862
897
  return rej(err);
863
898
  } else {
864
899
  return res(result);
@@ -1165,6 +1200,18 @@ export class AuthClass {
1165
1200
  user.getSession(async (err, session) => {
1166
1201
  if (err) {
1167
1202
  logger.debug('Failed to get the user session', err);
1203
+ if (this.isSessionInvalid(err)) {
1204
+ try {
1205
+ await this.cleanUpInvalidSession(user);
1206
+ } catch (cleanUpError) {
1207
+ rej(
1208
+ new Error(
1209
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
1210
+ )
1211
+ );
1212
+ return;
1213
+ }
1214
+ }
1168
1215
  return rej(err);
1169
1216
  } else {
1170
1217
  user.deleteUser((err, result: string) => {
@@ -1292,6 +1339,89 @@ export class AuthClass {
1292
1339
  });
1293
1340
  }
1294
1341
 
1342
+ private isErrorWithMessage(err: any): err is { message: string } {
1343
+ return (
1344
+ typeof err === 'object' &&
1345
+ Object.prototype.hasOwnProperty.call(err, 'message')
1346
+ );
1347
+ }
1348
+
1349
+ // Session revoked by another app
1350
+ private isTokenRevokedError(
1351
+ err: any
1352
+ ): err is { message: 'Access Token has been revoked' } {
1353
+ return (
1354
+ this.isErrorWithMessage(err) &&
1355
+ err.message === 'Access Token has been revoked'
1356
+ );
1357
+ }
1358
+
1359
+ private isRefreshTokenRevokedError(
1360
+ err: any
1361
+ ): err is { message: 'Refresh Token has been revoked' } {
1362
+ return (
1363
+ this.isErrorWithMessage(err) &&
1364
+ err.message === 'Refresh Token has been revoked'
1365
+ );
1366
+ }
1367
+
1368
+ private isUserDisabledError(
1369
+ err: any
1370
+ ): err is { message: 'User is disabled.' } {
1371
+ return this.isErrorWithMessage(err) && err.message === 'User is disabled.';
1372
+ }
1373
+
1374
+ private isUserDoesNotExistError(
1375
+ err: any
1376
+ ): err is { message: 'User does not exist.' } {
1377
+ return (
1378
+ this.isErrorWithMessage(err) && err.message === 'User does not exist.'
1379
+ );
1380
+ }
1381
+
1382
+ private isRefreshTokenExpiredError(
1383
+ err: any
1384
+ ): err is { message: 'Refresh Token has expired' } {
1385
+ return (
1386
+ this.isErrorWithMessage(err) &&
1387
+ err.message === 'Refresh Token has expired'
1388
+ );
1389
+ }
1390
+
1391
+ private isSignedInHostedUI() {
1392
+ return (
1393
+ this._oAuthHandler &&
1394
+ this._storage.getItem('amplify-signin-with-hostedUI') === 'true'
1395
+ );
1396
+ }
1397
+
1398
+ private isSessionInvalid(err: any) {
1399
+ return (
1400
+ this.isUserDisabledError(err) ||
1401
+ this.isUserDoesNotExistError(err) ||
1402
+ this.isTokenRevokedError(err) ||
1403
+ this.isRefreshTokenRevokedError(err) ||
1404
+ this.isRefreshTokenExpiredError(err)
1405
+ );
1406
+ }
1407
+
1408
+ private async cleanUpInvalidSession(user: CognitoUser) {
1409
+ user.signOut();
1410
+ this.user = null;
1411
+ try {
1412
+ await this.cleanCachedItems(); // clean aws credentials
1413
+ } catch (e) {
1414
+ logger.debug('failed to clear cached items');
1415
+ }
1416
+ if (this.isSignedInHostedUI()) {
1417
+ return new Promise((res, rej) => {
1418
+ this.oAuthSignOutRedirect(res, rej);
1419
+ });
1420
+ } else {
1421
+ dispatchAuthEvent('signOut', this.user, `A user has been signed out`);
1422
+ }
1423
+ }
1424
+
1295
1425
  /**
1296
1426
  * Get current authenticated user
1297
1427
  * @return - A promise resolves to current authenticated CognitoUser if success
@@ -1353,6 +1483,18 @@ export class AuthClass {
1353
1483
  async (err, session) => {
1354
1484
  if (err) {
1355
1485
  logger.debug('Failed to get the user session', err);
1486
+ if (this.isSessionInvalid(err)) {
1487
+ try {
1488
+ await this.cleanUpInvalidSession(user);
1489
+ } catch (cleanUpError) {
1490
+ rej(
1491
+ new Error(
1492
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
1493
+ )
1494
+ );
1495
+ return;
1496
+ }
1497
+ }
1356
1498
  rej(err);
1357
1499
  return;
1358
1500
  }
@@ -1370,19 +1512,22 @@ export class AuthClass {
1370
1512
  const { scope = '' } = session.getAccessToken().decodePayload();
1371
1513
  if (scope.split(' ').includes(USER_ADMIN_SCOPE)) {
1372
1514
  user.getUserData(
1373
- (err, data) => {
1515
+ async (err, data) => {
1374
1516
  if (err) {
1375
1517
  logger.debug('getting user data failed', err);
1376
- // Make sure the user is still valid
1377
- if (
1378
- err.message === 'User is disabled.' ||
1379
- err.message === 'User does not exist.' ||
1380
- err.message === 'Access Token has been revoked' // Session revoked by another app
1381
- ) {
1518
+ if (this.isSessionInvalid(err)) {
1519
+ try {
1520
+ await this.cleanUpInvalidSession(user);
1521
+ } catch (cleanUpError) {
1522
+ rej(
1523
+ new Error(
1524
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
1525
+ )
1526
+ );
1527
+ return;
1528
+ }
1382
1529
  rej(err);
1383
1530
  } else {
1384
- // the error may also be thrown when lack of permissions to get user info etc
1385
- // in that case we just bypass the error
1386
1531
  res(user);
1387
1532
  }
1388
1533
  return;
@@ -1491,7 +1636,7 @@ export class AuthClass {
1491
1636
  logger.debug('Getting current session');
1492
1637
  // Purposely not calling the reject method here because we don't need a console error
1493
1638
  if (!this.userPool) {
1494
- return Promise.reject();
1639
+ return this.rejectNoUserPool();
1495
1640
  }
1496
1641
 
1497
1642
  return new Promise((res, rej) => {
@@ -1530,17 +1675,29 @@ export class AuthClass {
1530
1675
  }
1531
1676
  const clientMetadata = this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1532
1677
 
1533
- return new Promise((resolve, reject) => {
1678
+ return new Promise((res, rej) => {
1534
1679
  logger.debug('Getting the session from this user:', user);
1535
1680
  user.getSession(
1536
- (err, session) => {
1681
+ async (err, session) => {
1537
1682
  if (err) {
1538
1683
  logger.debug('Failed to get the session from user', user);
1539
- reject(err);
1684
+ if (this.isSessionInvalid(err)) {
1685
+ try {
1686
+ await this.cleanUpInvalidSession(user);
1687
+ } catch (cleanUpError) {
1688
+ rej(
1689
+ new Error(
1690
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
1691
+ )
1692
+ );
1693
+ return;
1694
+ }
1695
+ }
1696
+ rej(err);
1540
1697
  return;
1541
1698
  } else {
1542
1699
  logger.debug('Succeed to get the user session', session);
1543
- resolve(session);
1700
+ res(session);
1544
1701
  return;
1545
1702
  }
1546
1703
  },
@@ -1582,8 +1739,8 @@ export class AuthClass {
1582
1739
  logger.debug('getting session success', session);
1583
1740
  return this.Credentials.set(session, 'session');
1584
1741
  })
1585
- .catch(error => {
1586
- logger.debug('getting session failed', error);
1742
+ .catch(() => {
1743
+ logger.debug('getting guest credentials');
1587
1744
  return this.Credentials.set(null, 'guest');
1588
1745
  });
1589
1746
  }
@@ -1697,9 +1854,21 @@ export class AuthClass {
1697
1854
  const clientMetadata = this._config.clientMetadata; // TODO: verify behavior if this is override during signIn
1698
1855
 
1699
1856
  user.getSession(
1700
- (err, result) => {
1857
+ async (err, result) => {
1701
1858
  if (err) {
1702
1859
  logger.debug('failed to get the user session', err);
1860
+ if (this.isSessionInvalid(err)) {
1861
+ try {
1862
+ await this.cleanUpInvalidSession(user);
1863
+ } catch (cleanUpError) {
1864
+ rej(
1865
+ new Error(
1866
+ `Session is invalid due to: ${err.message} and failed to clean up invalid session: ${cleanUpError.message}`
1867
+ )
1868
+ );
1869
+ return;
1870
+ }
1871
+ }
1703
1872
  return rej(err);
1704
1873
  }
1705
1874
  user.globalSignOut({
@@ -1754,7 +1923,7 @@ export class AuthClass {
1754
1923
  this._oAuthHandler.signOut(); // this method redirects url
1755
1924
 
1756
1925
  // App should be redirected to another url otherwise it will reject
1757
- setTimeout(() => reject('Signout timeout fail'), 3000);
1926
+ setTimeout(() => reject(Error('Signout timeout fail')), 3000);
1758
1927
  }
1759
1928
 
1760
1929
  /**
@@ -1777,7 +1946,7 @@ export class AuthClass {
1777
1946
  logger.debug('no current Cognito user');
1778
1947
  }
1779
1948
  } else {
1780
- logger.debug('no Congito User pool');
1949
+ logger.debug('no Cognito User pool');
1781
1950
  }
1782
1951
 
1783
1952
  /**
@@ -2139,7 +2308,7 @@ export class AuthClass {
2139
2308
  logger.debug('AWS credentials', credentials);
2140
2309
  }
2141
2310
 
2142
- /*
2311
+ /*
2143
2312
  Prior to the request we do sign the custom state along with the state we set. This check will verify
2144
2313
  if there is a dash indicated when setting custom state from the request. If a dash is contained
2145
2314
  then there is custom state present on the state string.
package/src/index.ts CHANGED
@@ -1,35 +1,40 @@
1
- /*
2
- * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5
- * the License. A copy of the License is located at
6
- *
7
- * http://aws.amazon.com/apache2.0/
8
- *
9
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11
- * and limitations under the License.
12
- */
13
-
14
- import { Auth } from './Auth';
15
- import { CognitoHostedUIIdentityProvider, SignUpParams } from './types/Auth';
16
- import {
17
- CognitoUser,
18
- CookieStorage,
19
- appendToCognitoUserAgent,
20
- } from 'amazon-cognito-identity-js';
21
- import { AuthErrorStrings } from './common/AuthErrorStrings';
22
-
23
- /**
24
- * @deprecated use named import
25
- */
26
- export default Auth;
27
- export {
28
- Auth,
29
- CognitoUser,
30
- CookieStorage,
31
- CognitoHostedUIIdentityProvider,
32
- SignUpParams,
33
- appendToCognitoUserAgent,
34
- AuthErrorStrings,
35
- };
1
+ /*
2
+ * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5
+ * the License. A copy of the License is located at
6
+ *
7
+ * http://aws.amazon.com/apache2.0/
8
+ *
9
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11
+ * and limitations under the License.
12
+ */
13
+
14
+ import { Auth } from './Auth';
15
+ import {
16
+ CognitoHostedUIIdentityProvider,
17
+ SignUpParams,
18
+ GRAPHQL_AUTH_MODE,
19
+ } from './types/Auth';
20
+ import {
21
+ CognitoUser,
22
+ CookieStorage,
23
+ appendToCognitoUserAgent,
24
+ } from 'amazon-cognito-identity-js';
25
+ import { AuthErrorStrings } from './common/AuthErrorStrings';
26
+
27
+ /**
28
+ * @deprecated use named import
29
+ */
30
+ export default Auth;
31
+ export {
32
+ Auth,
33
+ CognitoUser,
34
+ CookieStorage,
35
+ CognitoHostedUIIdentityProvider,
36
+ SignUpParams,
37
+ appendToCognitoUserAgent,
38
+ AuthErrorStrings,
39
+ GRAPHQL_AUTH_MODE,
40
+ };
package/src/types/Auth.ts CHANGED
@@ -227,3 +227,11 @@ export interface IAuthDevice {
227
227
  id: string;
228
228
  name: string;
229
229
  }
230
+
231
+ export enum GRAPHQL_AUTH_MODE {
232
+ API_KEY = 'API_KEY',
233
+ AWS_IAM = 'AWS_IAM',
234
+ OPENID_CONNECT = 'OPENID_CONNECT',
235
+ AMAZON_COGNITO_USER_POOLS = 'AMAZON_COGNITO_USER_POOLS',
236
+ AWS_LAMBDA = 'AWS_LAMBDA',
237
+ }