@ttoss/react-auth 1.7.23 → 1.7.25

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/README.md CHANGED
@@ -17,7 +17,7 @@ This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908
17
17
  ### Install
18
18
 
19
19
  ```shell
20
- $ yarn add @ttoss/auth @ttoss/react-notifications
20
+ $ yarn add @ttoss/auth @ttoss/react-notifications aws-amplify
21
21
  ```
22
22
 
23
23
  ## Examples of use
@@ -25,32 +25,58 @@ $ yarn add @ttoss/auth @ttoss/react-notifications
25
25
  ### Amplify config
26
26
 
27
27
  ```ts
28
- import Amplify from 'aws-amplify';
29
-
30
- Amplify.configure({
31
- Auth: {
32
- // REQUIRED only for Federated Authentication - Amazon Cognito Identity Pool ID
33
- identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
34
-
35
- // REQUIRED - Amazon Cognito Region
36
- region: 'XX-XXXX-X',
37
-
38
- // OPTIONAL - Amazon Cognito Federated Identity Pool Region
39
- // Required only if it's different from Amazon Cognito Region
40
- identityPoolRegion: 'XX-XXXX-X',
28
+ import { Amplify, type ResourcesConfig } from 'aws-amplify';
29
+ import {
30
+ CookieStorage,
31
+ KeyValueStorageInterface,
32
+ defaultStorage,
33
+ sessionStorage,
34
+ } from 'aws-amplify/utils';
35
+ import { cognitoUserPoolsTokenProvider } from 'aws-amplify/auth/cognito';
36
+
37
+ const authConfig: ResourcesConfig['Auth'] = {
38
+ Cognito: {
39
+ // REQUIRED Amazon Cognito User Pool Client ID (26-char alphanumeric string)
40
+ userPoolClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
41
41
 
42
42
  // OPTIONAL - Amazon Cognito User Pool ID
43
43
  userPoolId: 'XX-XXXX-X_abcd1234',
44
44
 
45
- // OPTIONAL - Amazon Cognito Web Client ID (26-char alphanumeric string)
46
- userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
45
+ loginWith: {
46
+ // OPTIONAL - Hosted UI configuration
47
+ oauth: {
48
+ domain: 'your_cognito_domain',
49
+ scopes: [
50
+ 'phone',
51
+ 'email',
52
+ 'profile',
53
+ 'openid',
54
+ 'aws.cognito.signin.user.admin',
55
+ ],
56
+ redirectSignIn: ['http://localhost:3000/'],
57
+ redirectSignOut: ['http://localhost:3000/'],
58
+ responseType: 'code', // or 'token', note that REFRESH token will only be generated when the responseType is code
59
+ },
60
+ },
61
+ },
62
+ };
47
63
 
48
- // OPTIONAL - Enforce user authentication prior to accessing AWS resources or not
49
- mandatorySignIn: false,
64
+ Amplify.configure({
65
+ Auth: authConfig,
66
+ });
50
67
 
68
+ // Browser Local Storage
69
+ // In Amplify the localStorage is the default storage mechanism. It saves the tokens in the browser's localStorage.
70
+ // This local storage will persist across browser sessions and tabs. You can explicitly set to this storage by calling:
71
+ cognitoUserPoolsTokenProvider.setKeyValueStorage(defaultStorage);
72
+
73
+ // Cookie Storage
74
+ // CookieStorage saves the tokens in the browser's Cookies. The cookies will persist across browser sessions and tabs.
75
+ // You can explicitly set to this storage by calling:
76
+ cognitoUserPoolsTokenProvider.setKeyValueStorage(
77
+ new CookieStorage(
51
78
  // OPTIONAL - Configuration for cookie storage
52
- // Note: if the secure flag is set to true, then the cookie transmission requires a secure protocol
53
- cookieStorage: {
79
+ {
54
80
  // REQUIRED - Cookie domain (only required if cookieStorage is provided)
55
81
  domain: '.yourdomain.com',
56
82
  // OPTIONAL - Cookie path
@@ -58,37 +84,41 @@ Amplify.configure({
58
84
  // OPTIONAL - Cookie expiration in days
59
85
  expires: 365,
60
86
  // OPTIONAL - See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
61
- sameSite: 'strict' | 'lax',
87
+ sameSite: 'strict' | 'lax' | 'none',
62
88
  // OPTIONAL - Cookie secure flag
63
89
  // Either true or false, indicating if the cookie transmission requires a secure protocol (https).
64
90
  secure: true,
65
- },
91
+ }
92
+ )
93
+ );
66
94
 
67
- // OPTIONAL - customized storage object
68
- storage: MyStorage,
69
-
70
- // OPTIONAL - Manually set the authentication flow type. Default is 'USER_SRP_AUTH'
71
- authenticationFlowType: 'USER_PASSWORD_AUTH',
72
-
73
- // OPTIONAL - Manually set key value pairs that can be passed to Cognito Lambda Triggers
74
- clientMetadata: { myCustomKey: 'myCustomValue' },
75
-
76
- // OPTIONAL - Hosted UI configuration
77
- oauth: {
78
- domain: 'your_cognito_domain',
79
- scope: [
80
- 'phone',
81
- 'email',
82
- 'profile',
83
- 'openid',
84
- 'aws.cognito.signin.user.admin',
85
- ],
86
- redirectSignIn: 'http://localhost:3000/',
87
- redirectSignOut: 'http://localhost:3000/',
88
- responseType: 'code', // or 'token', note that REFRESH token will only be generated when the responseType is code
89
- },
90
- },
91
- });
95
+ // Browser Session Storage
96
+ // sessionStorage saves the tokens in the browser's sessionStorage and these tokens will clear when a tab is closed.
97
+ // The benefit to this storage mechanism is that the session only lasts as long as the browser is open and you
98
+ // can sign out users when they close the tab. You can update to this storage by calling:
99
+ cognitoUserPoolsTokenProvider.setKeyValueStorage(sessionStorage);
100
+
101
+ // Custom Storage
102
+ // You can implement your own custom storage mechanism by creating a class that implements the storage interface.
103
+ // Here is an example that uses memory storage:
104
+
105
+ class MyCustomStorage implements KeyValueStorageInterface {
106
+ storageObject: Record<string, string> = {};
107
+ async setItem(key: string, value: string): Promise<void> {
108
+ this.storageObject[key] = value;
109
+ }
110
+ async getItem(key: string): Promise<string | null> {
111
+ return this.storageObject[key];
112
+ }
113
+ async removeItem(key: string): Promise<void> {
114
+ delete this.storageObject[key];
115
+ }
116
+ async clear(): Promise<void> {
117
+ this.storageObject = {};
118
+ }
119
+ }
120
+
121
+ cognitoUserPoolsTokenProvider.setKeyValueStorage(new MyCustomStorage());
92
122
  ```
93
123
 
94
124
  ### PrivateRoute component
package/dist/esm/index.js CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  // src/AuthProvider.tsx
4
4
  import * as React from "react";
5
- import { Auth, Hub } from "aws-amplify";
5
+ import { Hub } from "aws-amplify/utils";
6
+ import { signOut as awsSignOut, fetchAuthSession, fetchUserAttributes, getCurrentUser } from "aws-amplify/auth";
6
7
  import { jsx } from "react/jsx-runtime";
7
8
  var signOut = () => {
8
- return Auth.signOut();
9
+ return awsSignOut();
9
10
  };
10
11
  var AuthContext = /*#__PURE__*/React.createContext({
11
12
  signOut,
@@ -27,24 +28,29 @@ var AuthProvider = ({
27
28
  });
28
29
  React.useEffect(() => {
29
30
  const updateUser = () => {
30
- Auth.currentAuthenticatedUser().then(({
31
- attributes,
32
- signInUserSession
31
+ getCurrentUser().then(async ({
32
+ userId,
33
+ username
33
34
  }) => {
35
+ const session = await fetchAuthSession();
36
+ const idToken = session.tokens?.idToken?.toString();
37
+ const accessToken = session.tokens?.accessToken.toString();
38
+ const user2 = await fetchUserAttributes();
34
39
  setAuthState({
35
40
  user: {
36
- id: attributes.sub,
37
- email: attributes.email,
38
- emailVerified: attributes["email_verified"]
41
+ id: userId,
42
+ email: username,
43
+ emailVerified: user2.email_verified ?? ""
39
44
  },
40
45
  tokens: {
41
- idToken: signInUserSession.idToken.jwtToken,
42
- accessToken: signInUserSession.accessToken.jwtToken,
43
- refreshToken: signInUserSession.refreshToken.token
46
+ idToken: idToken ?? "",
47
+ accessToken: accessToken ?? "",
48
+ refreshToken: ""
44
49
  },
45
50
  isAuthenticated: true
46
51
  });
47
- }).catch(() => {
52
+ }).catch(e => {
53
+ console.error(e);
48
54
  setAuthState({
49
55
  user: null,
50
56
  tokens: null,
@@ -77,7 +83,6 @@ var useAuth = () => {
77
83
 
78
84
  // src/Auth.tsx
79
85
  import * as React6 from "react";
80
- import { Auth as AmplifyAuth } from "aws-amplify";
81
86
 
82
87
  // src/AuthCard.tsx
83
88
  import * as React2 from "react";
@@ -1124,6 +1129,7 @@ var AuthSignUp = ({
1124
1129
 
1125
1130
  // src/Auth.tsx
1126
1131
  import { assign, createMachine } from "xstate";
1132
+ import { confirmResetPassword, confirmSignUp, resendSignUpCode, resetPassword, signIn, signUp } from "aws-amplify/auth";
1127
1133
  import { useMachine } from "@xstate/react";
1128
1134
  import { useNotifications as useNotifications4 } from "@ttoss/react-notifications";
1129
1135
  import { jsx as jsx9 } from "react/jsx-runtime";
@@ -1217,11 +1223,16 @@ var AuthLogic = () => {
1217
1223
  }) => {
1218
1224
  try {
1219
1225
  setLoading(true);
1220
- await AmplifyAuth.signIn(email, password);
1226
+ await signIn({
1227
+ username: email,
1228
+ password
1229
+ });
1221
1230
  } catch (error) {
1222
1231
  switch (error.code) {
1223
1232
  case "UserNotConfirmedException":
1224
- await AmplifyAuth.resendSignUp(email);
1233
+ await resendSignUpCode({
1234
+ username: email
1235
+ });
1225
1236
  send({
1226
1237
  type: "SIGN_UP_RESEND_CONFIRMATION",
1227
1238
  email
@@ -1243,11 +1254,13 @@ var AuthLogic = () => {
1243
1254
  }) => {
1244
1255
  try {
1245
1256
  setLoading(true);
1246
- await AmplifyAuth.signUp({
1257
+ await signUp({
1247
1258
  username: email,
1248
1259
  password,
1249
- attributes: {
1250
- email
1260
+ options: {
1261
+ userAttributes: {
1262
+ email
1263
+ }
1251
1264
  }
1252
1265
  });
1253
1266
  send({
@@ -1269,7 +1282,10 @@ var AuthLogic = () => {
1269
1282
  }) => {
1270
1283
  try {
1271
1284
  setLoading(true);
1272
- await AmplifyAuth.confirmSignUp(email, code);
1285
+ await confirmSignUp({
1286
+ confirmationCode: code,
1287
+ username: email
1288
+ });
1273
1289
  send({
1274
1290
  type: "SIGN_UP_CONFIRMED",
1275
1291
  email
@@ -1293,7 +1309,9 @@ var AuthLogic = () => {
1293
1309
  }) => {
1294
1310
  try {
1295
1311
  setLoading(true);
1296
- await AmplifyAuth.forgotPassword(email);
1312
+ await resetPassword({
1313
+ username: email
1314
+ });
1297
1315
  send({
1298
1316
  type: "FORGOT_PASSWORD_RESET_PASSWORD",
1299
1317
  email
@@ -1314,7 +1332,11 @@ var AuthLogic = () => {
1314
1332
  }) => {
1315
1333
  try {
1316
1334
  setLoading(true);
1317
- await AmplifyAuth.forgotPasswordSubmit(email, code, newPassword);
1335
+ await confirmResetPassword({
1336
+ confirmationCode: code,
1337
+ username: email,
1338
+ newPassword
1339
+ });
1318
1340
  send({
1319
1341
  type: "FORGOT_PASSWORD_CONFIRMED",
1320
1342
  email
@@ -1372,7 +1394,7 @@ var AuthLogic = () => {
1372
1394
  }
1373
1395
  });
1374
1396
  };
1375
- var Auth2 = ({
1397
+ var Auth = ({
1376
1398
  logo,
1377
1399
  fullScreen = true
1378
1400
  }) => {
@@ -1389,4 +1411,4 @@ var Auth2 = ({
1389
1411
  }
1390
1412
  return withLogoNode;
1391
1413
  };
1392
- export { Auth2 as Auth, AuthProvider, useAuth };
1414
+ export { Auth, AuthProvider, useAuth };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/react-auth",
3
- "version": "1.7.23",
3
+ "version": "1.7.25",
4
4
  "description": "ttoss authentication module for React apps.",
5
5
  "author": "ttoss",
6
6
  "contributors": [
@@ -30,23 +30,23 @@
30
30
  "@ttoss/forms": "^0.21.9"
31
31
  },
32
32
  "peerDependencies": {
33
- "aws-amplify": "^5.0.0",
33
+ "aws-amplify": "^6.0.0",
34
34
  "react": ">=16.8.0",
35
- "@ttoss/react-notifications": "^1.24.23",
35
+ "@ttoss/react-notifications": "^1.24.24",
36
36
  "@ttoss/react-i18n": "^1.25.8",
37
37
  "@ttoss/ui": "^4.0.7"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@jest/globals": "^29.7.0",
41
41
  "@types/react": "^18.2.39",
42
- "aws-amplify": "^5.3.11",
42
+ "aws-amplify": "^6.0.12",
43
43
  "jest": "^29.7.0",
44
44
  "tsup": "^8.0.1",
45
45
  "@ttoss/cloud-auth": "^0.12.0",
46
46
  "@ttoss/config": "^1.31.4",
47
47
  "@ttoss/i18n-cli": "^0.7.5",
48
48
  "@ttoss/react-i18n": "^1.25.8",
49
- "@ttoss/react-notifications": "^1.24.23",
49
+ "@ttoss/react-notifications": "^1.24.24",
50
50
  "@ttoss/test-utils": "^2.0.4",
51
51
  "@ttoss/ui": "^4.0.7"
52
52
  },
package/src/Auth.tsx CHANGED
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { Auth as AmplifyAuth } from 'aws-amplify';
3
2
  import { AuthConfirmSignUp } from './AuthConfirmSignUp';
4
3
  import { AuthForgotPassword } from './AuthForgotPassword';
5
4
  import { AuthForgotPasswordResetPassword } from './AuthForgotPasswordResetPassword';
@@ -8,6 +7,14 @@ import { AuthSignIn } from './AuthSignIn';
8
7
  import { AuthSignUp } from './AuthSignUp';
9
8
  import { LogoContextProps, LogoProvider } from './AuthCard';
10
9
  import { assign, createMachine } from 'xstate';
10
+ import {
11
+ confirmResetPassword,
12
+ confirmSignUp,
13
+ resendSignUpCode,
14
+ resetPassword,
15
+ signIn,
16
+ signUp,
17
+ } from 'aws-amplify/auth';
11
18
  import { useAuth } from './AuthProvider';
12
19
  import { useMachine } from '@xstate/react';
13
20
  import { useNotifications } from '@ttoss/react-notifications';
@@ -136,13 +143,13 @@ const AuthLogic = () => {
136
143
  async ({ email, password }) => {
137
144
  try {
138
145
  setLoading(true);
139
- await AmplifyAuth.signIn(email, password);
146
+ await signIn({ username: email, password });
140
147
  // toast('Signed In');
141
148
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
149
  } catch (error: any) {
143
150
  switch (error.code) {
144
151
  case 'UserNotConfirmedException':
145
- await AmplifyAuth.resendSignUp(email);
152
+ await resendSignUpCode({ username: email });
146
153
  send({ type: 'SIGN_UP_RESEND_CONFIRMATION', email });
147
154
  break;
148
155
  default:
@@ -160,10 +167,14 @@ const AuthLogic = () => {
160
167
  async ({ email, password }) => {
161
168
  try {
162
169
  setLoading(true);
163
- await AmplifyAuth.signUp({
170
+ await signUp({
164
171
  username: email,
165
172
  password,
166
- attributes: { email },
173
+ options: {
174
+ userAttributes: {
175
+ email,
176
+ },
177
+ },
167
178
  });
168
179
  // toast('Signed Up');
169
180
  send({ type: 'SIGN_UP_CONFIRM', email });
@@ -182,7 +193,7 @@ const AuthLogic = () => {
182
193
  async ({ email, code }) => {
183
194
  try {
184
195
  setLoading(true);
185
- await AmplifyAuth.confirmSignUp(email, code);
196
+ await confirmSignUp({ confirmationCode: code, username: email });
186
197
  // toast('Confirmed Signed In');
187
198
  send({ type: 'SIGN_UP_CONFIRMED', email });
188
199
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -204,7 +215,7 @@ const AuthLogic = () => {
204
215
  async ({ email }) => {
205
216
  try {
206
217
  setLoading(true);
207
- await AmplifyAuth.forgotPassword(email);
218
+ await resetPassword({ username: email });
208
219
  // toast('Forgot Password');
209
220
  send({ type: 'FORGOT_PASSWORD_RESET_PASSWORD', email });
210
221
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -223,7 +234,11 @@ const AuthLogic = () => {
223
234
  async ({ email, code, newPassword }) => {
224
235
  try {
225
236
  setLoading(true);
226
- await AmplifyAuth.forgotPasswordSubmit(email, code, newPassword);
237
+ await confirmResetPassword({
238
+ confirmationCode: code,
239
+ username: email,
240
+ newPassword,
241
+ });
227
242
  // toast('Forgot Password Reset Password');
228
243
  send({ type: 'FORGOT_PASSWORD_CONFIRMED', email });
229
244
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1,5 +1,11 @@
1
1
  import * as React from 'react';
2
- import { Auth, Hub } from 'aws-amplify';
2
+ import { Hub } from 'aws-amplify/utils';
3
+ import {
4
+ signOut as awsSignOut,
5
+ fetchAuthSession,
6
+ fetchUserAttributes,
7
+ getCurrentUser,
8
+ } from 'aws-amplify/auth';
3
9
 
4
10
  type User = {
5
11
  id: string;
@@ -14,10 +20,11 @@ type Tokens = {
14
20
  } | null;
15
21
 
16
22
  const signOut = () => {
17
- return Auth.signOut();
23
+ return awsSignOut();
18
24
  };
19
25
 
20
26
  const AuthContext = React.createContext<{
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
28
  signOut: () => Promise<any>;
22
29
  isAuthenticated: boolean;
23
30
  user: User;
@@ -42,23 +49,31 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
42
49
 
43
50
  React.useEffect(() => {
44
51
  const updateUser = () => {
45
- Auth.currentAuthenticatedUser()
46
- .then(({ attributes, signInUserSession }) => {
52
+ getCurrentUser()
53
+ .then(async ({ userId, username }) => {
54
+ const session = await fetchAuthSession();
55
+ const idToken = session.tokens?.idToken?.toString();
56
+ const accessToken = session.tokens?.accessToken.toString();
57
+
58
+ const user = await fetchUserAttributes();
59
+
47
60
  setAuthState({
48
61
  user: {
49
- id: attributes.sub,
50
- email: attributes.email,
51
- emailVerified: attributes['email_verified'],
62
+ id: userId,
63
+ email: username,
64
+ emailVerified: user.email_verified ?? '',
52
65
  },
53
66
  tokens: {
54
- idToken: signInUserSession.idToken.jwtToken,
55
- accessToken: signInUserSession.accessToken.jwtToken,
56
- refreshToken: signInUserSession.refreshToken.token,
67
+ idToken: idToken ?? '',
68
+ accessToken: accessToken ?? '',
69
+ refreshToken: '',
57
70
  },
58
71
  isAuthenticated: true,
59
72
  });
60
73
  })
61
- .catch(() => {
74
+ .catch((e) => {
75
+ // eslint-disable-next-line no-console
76
+ console.error(e);
62
77
  setAuthState({
63
78
  user: null,
64
79
  tokens: null,