@ttoss/react-auth-strapi 0.2.0
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/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/esm/index.js +291 -0
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +340 -0
- package/i18n/compiled/en.json +272 -0
- package/i18n/lang/en.json +191 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Terezinha Tech Operations (ttoss)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# @ttoss/react-auth-strapi
|
|
2
|
+
|
|
3
|
+
Pre-configured authentication components for React applications using Strapi CMS backend with [strapi-plugin-refresh-token](https://github.com/redon2/strapi-plugin-refresh-token).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ttoss/react-auth-strapi @ttoss/react-notifications
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { AuthProvider, Auth, useAuth } from '@ttoss/react-auth-strapi';
|
|
15
|
+
import { NotificationProvider } from '@ttoss/react-notifications';
|
|
16
|
+
|
|
17
|
+
// 1. Wrap your app with providers
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<NotificationProvider>
|
|
21
|
+
<AuthProvider apiUrl="https://your-strapi-api.com/api">
|
|
22
|
+
<AuthenticatedApp />
|
|
23
|
+
</AuthProvider>
|
|
24
|
+
</NotificationProvider>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 2. Use the pre-built Auth component
|
|
29
|
+
function LoginPage() {
|
|
30
|
+
return <Auth />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 3. Access authentication state
|
|
34
|
+
function AuthenticatedApp() {
|
|
35
|
+
const { isAuthenticated, user, signOut } = useAuth();
|
|
36
|
+
|
|
37
|
+
if (!isAuthenticated) {
|
|
38
|
+
return <LoginPage />;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<p>Welcome, {user?.email}</p>
|
|
44
|
+
<button onClick={signOut}>Sign Out</button>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- **Zero configuration**: Pre-configured Strapi authentication handlers
|
|
53
|
+
- **Complete auth flows**: Sign in, sign up, forgot password, email confirmation
|
|
54
|
+
- **Token management**: Automatic refresh token handling with secure storage
|
|
55
|
+
- **Error handling**: Built-in notifications for authentication errors
|
|
56
|
+
- **Email verification**: Automatic resend confirmation emails for unverified accounts
|
|
57
|
+
|
|
58
|
+
## Strapi Backend Setup
|
|
59
|
+
|
|
60
|
+
This package requires Strapi with specific plugins and configuration:
|
|
61
|
+
|
|
62
|
+
### Required Strapi Plugins
|
|
63
|
+
|
|
64
|
+
1. **Users & Permissions plugin** (built-in)
|
|
65
|
+
2. **[strapi-plugin-refresh-token](https://github.com/redon2/strapi-plugin-refresh-token)** for token refresh functionality
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install strapi-plugin-refresh-token
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Strapi API Endpoints
|
|
72
|
+
|
|
73
|
+
The package expects these Strapi endpoints to be available:
|
|
74
|
+
|
|
75
|
+
```mermaid
|
|
76
|
+
flowchart LR
|
|
77
|
+
A[Auth Component] --> B[ /auth/local]
|
|
78
|
+
A --> C[ /auth/local/register]
|
|
79
|
+
A --> D[ /auth/forgot-password]
|
|
80
|
+
A --> E[ /auth/send-email-confirmation]
|
|
81
|
+
A --> F[ /auth/local/refresh]
|
|
82
|
+
A --> G[ /users/me]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- `POST /auth/local` - Sign in with email/password
|
|
86
|
+
- `POST /auth/local/register` - User registration
|
|
87
|
+
- `POST /auth/forgot-password` - Request password reset
|
|
88
|
+
- `POST /auth/send-email-confirmation` - Resend email confirmation
|
|
89
|
+
- `POST /auth/local/refresh` - Refresh access token
|
|
90
|
+
- `GET /users/me` - Get current user profile
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
### AuthProvider
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
<AuthProvider
|
|
98
|
+
apiUrl="https://your-strapi-api.com/api" // Your Strapi API base URL
|
|
99
|
+
>
|
|
100
|
+
{children}
|
|
101
|
+
</AuthProvider>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The provider automatically:
|
|
105
|
+
|
|
106
|
+
- Manages refresh tokens in localStorage
|
|
107
|
+
- Handles token refresh on app startup
|
|
108
|
+
- Provides authentication context to child components
|
|
109
|
+
|
|
110
|
+
### Auth Component
|
|
111
|
+
|
|
112
|
+
Pre-configured authentication flow with all handlers implemented:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
<Auth />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The component automatically handles:
|
|
119
|
+
|
|
120
|
+
- **Sign in**: Authenticates with Strapi local strategy
|
|
121
|
+
- **Sign up**: Registers new users and triggers email confirmation
|
|
122
|
+
- **Forgot password**: Initiates password reset flow
|
|
123
|
+
- **Email confirmation**: Manages email verification process
|
|
124
|
+
- **Error notifications**: Shows user-friendly error messages
|
|
125
|
+
|
|
126
|
+
### useAuth Hook
|
|
127
|
+
|
|
128
|
+
Enhanced version of the core useAuth hook with Strapi-specific context:
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
const {
|
|
132
|
+
isAuthenticated, // boolean
|
|
133
|
+
user, // { id: string, email: string, emailVerified?: boolean }
|
|
134
|
+
tokens, // { accessToken: string, refreshToken: string }
|
|
135
|
+
signOut, // () => Promise<void>
|
|
136
|
+
setAuthData, // Update auth state manually
|
|
137
|
+
apiUrl, // Strapi API URL from context
|
|
138
|
+
} = useAuth();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Authentication Flow
|
|
142
|
+
|
|
143
|
+
```mermaid
|
|
144
|
+
sequenceDiagram
|
|
145
|
+
participant U as User
|
|
146
|
+
participant A as Auth Component
|
|
147
|
+
participant S as Strapi API
|
|
148
|
+
participant L as LocalStorage
|
|
149
|
+
|
|
150
|
+
U->>A: Enter credentials
|
|
151
|
+
A->>S: POST /auth/local
|
|
152
|
+
S-->>A: { jwt, refreshToken, user }
|
|
153
|
+
A->>L: Store refreshToken
|
|
154
|
+
A->>A: setAuthData({ user, tokens, isAuthenticated: true })
|
|
155
|
+
|
|
156
|
+
Note over A,L: On app restart
|
|
157
|
+
A->>L: Get stored refreshToken
|
|
158
|
+
A->>S: POST /auth/local/refresh
|
|
159
|
+
S-->>A: { jwt, refreshToken }
|
|
160
|
+
A->>S: GET /users/me (with jwt)
|
|
161
|
+
S-->>A: user data
|
|
162
|
+
A->>A: Restore authentication state
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Error Handling
|
|
166
|
+
|
|
167
|
+
The package integrates with `@ttoss/react-notifications` to display authentication errors:
|
|
168
|
+
|
|
169
|
+
- **Invalid credentials**: "Sign in failed" notification
|
|
170
|
+
- **Unconfirmed email**: Automatically resends confirmation email
|
|
171
|
+
- **Registration errors**: "Sign up failed" with specific error message
|
|
172
|
+
- **Network errors**: Generic error messages for API failures
|
|
173
|
+
|
|
174
|
+
## Token Security
|
|
175
|
+
|
|
176
|
+
### Refresh Token Storage
|
|
177
|
+
|
|
178
|
+
- Refresh tokens are stored in `localStorage` with the key `ttoss-strapi-auth-refresh-token`
|
|
179
|
+
- Access tokens are kept in memory only (React state)
|
|
180
|
+
- Tokens are automatically cleared on sign out or authentication errors
|
|
181
|
+
|
|
182
|
+
### Automatic Token Refresh
|
|
183
|
+
|
|
184
|
+
- On app startup, attempts to refresh tokens if a refresh token exists
|
|
185
|
+
- If refresh fails, user is automatically signed out
|
|
186
|
+
- No manual token management required
|
|
187
|
+
|
|
188
|
+
## Dependencies
|
|
189
|
+
|
|
190
|
+
- `@ttoss/react-auth-core`: Core authentication abstractions
|
|
191
|
+
- `@ttoss/react-notifications`: Error and success notifications
|
|
192
|
+
|
|
193
|
+
## Type Definitions
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
type StrapiUser = {
|
|
197
|
+
id: string;
|
|
198
|
+
email: string;
|
|
199
|
+
emailVerified?: boolean;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
type StrapiTokens = {
|
|
203
|
+
accessToken: string; // JWT from Strapi
|
|
204
|
+
refreshToken: string; // Refresh token from plugin
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
type StrapiAuthResponse = {
|
|
208
|
+
jwt: string;
|
|
209
|
+
refreshToken: string;
|
|
210
|
+
user: {
|
|
211
|
+
id: string;
|
|
212
|
+
email: string;
|
|
213
|
+
confirmed: boolean;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
```
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
|
|
3
|
+
// src/Auth.tsx
|
|
4
|
+
import { Auth as AuthCore, useAuthScreen } from "@ttoss/react-auth-core";
|
|
5
|
+
import { useNotifications } from "@ttoss/react-notifications";
|
|
6
|
+
import * as React2 from "react";
|
|
7
|
+
|
|
8
|
+
// src/AuthProvider.tsx
|
|
9
|
+
import { AuthProvider as AuthProviderCore, useAuth as useAuthCore } from "@ttoss/react-auth-core";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
|
|
12
|
+
// src/storage.ts
|
|
13
|
+
var AUTH_STORAGE_REFRESH_TOKEN_KEY = "ttoss-strapi-auth-refresh-token";
|
|
14
|
+
var isBrowser = typeof window !== "undefined";
|
|
15
|
+
var getLocalStorage = () => {
|
|
16
|
+
try {
|
|
17
|
+
return isBrowser ? window.localStorage : null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var storage = {
|
|
23
|
+
getRefreshToken: () => {
|
|
24
|
+
const ls = getLocalStorage();
|
|
25
|
+
if (!ls) return null;
|
|
26
|
+
try {
|
|
27
|
+
return ls.getItem(AUTH_STORAGE_REFRESH_TOKEN_KEY);
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
setRefreshToken: refreshToken => {
|
|
33
|
+
const ls = getLocalStorage();
|
|
34
|
+
if (!ls) return;
|
|
35
|
+
try {
|
|
36
|
+
ls.setItem(AUTH_STORAGE_REFRESH_TOKEN_KEY, refreshToken);
|
|
37
|
+
} catch {}
|
|
38
|
+
},
|
|
39
|
+
clearRefreshToken: () => {
|
|
40
|
+
const ls = getLocalStorage();
|
|
41
|
+
if (!ls) return;
|
|
42
|
+
try {
|
|
43
|
+
ls.removeItem(AUTH_STORAGE_REFRESH_TOKEN_KEY);
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/AuthProvider.tsx
|
|
49
|
+
import { jsx } from "react/jsx-runtime";
|
|
50
|
+
var AuthContext = React.createContext({
|
|
51
|
+
apiUrl: ""
|
|
52
|
+
});
|
|
53
|
+
var AuthProvider = props => {
|
|
54
|
+
const getAuthData = React.useCallback(async () => {
|
|
55
|
+
try {
|
|
56
|
+
const refreshToken = storage.getRefreshToken();
|
|
57
|
+
if (!refreshToken) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const refreshResponse = await fetch(`${props.apiUrl}/auth/local/refresh`, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json"
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
refreshToken
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
const refreshData = await refreshResponse.json();
|
|
70
|
+
if ("error" in refreshData) {
|
|
71
|
+
storage.clearRefreshToken();
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const meResponse = await fetch(`${props.apiUrl}/users/me`, {
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: `Bearer ${refreshData.jwt}`
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const data = await meResponse.json();
|
|
80
|
+
if (!meResponse.ok) {
|
|
81
|
+
storage.clearRefreshToken();
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
user: {
|
|
86
|
+
id: data.id,
|
|
87
|
+
email: data.email,
|
|
88
|
+
emailVerified: data.confirmed ?? data.emailVerified ?? data.user?.confirmed
|
|
89
|
+
},
|
|
90
|
+
tokens: {
|
|
91
|
+
accessToken: refreshData.jwt,
|
|
92
|
+
refreshToken: refreshData.refreshToken
|
|
93
|
+
},
|
|
94
|
+
isAuthenticated: true
|
|
95
|
+
};
|
|
96
|
+
} catch {
|
|
97
|
+
storage.clearRefreshToken();
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}, [props.apiUrl]);
|
|
101
|
+
const signOut = React.useCallback(async () => {
|
|
102
|
+
storage.clearRefreshToken();
|
|
103
|
+
}, []);
|
|
104
|
+
return /* @__PURE__ */jsx(AuthContext.Provider, {
|
|
105
|
+
value: {
|
|
106
|
+
apiUrl: props.apiUrl
|
|
107
|
+
},
|
|
108
|
+
children: /* @__PURE__ */jsx(AuthProviderCore, {
|
|
109
|
+
getAuthData,
|
|
110
|
+
signOut,
|
|
111
|
+
children: props.children
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
var useAuth = () => {
|
|
116
|
+
const authCore = useAuthCore();
|
|
117
|
+
const {
|
|
118
|
+
apiUrl
|
|
119
|
+
} = React.useContext(AuthContext);
|
|
120
|
+
return {
|
|
121
|
+
apiUrl,
|
|
122
|
+
...authCore
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// src/Auth.tsx
|
|
127
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
128
|
+
var Auth = () => {
|
|
129
|
+
const {
|
|
130
|
+
setAuthData,
|
|
131
|
+
apiUrl
|
|
132
|
+
} = useAuth();
|
|
133
|
+
const {
|
|
134
|
+
screen,
|
|
135
|
+
setScreen
|
|
136
|
+
} = useAuthScreen();
|
|
137
|
+
const {
|
|
138
|
+
addNotification
|
|
139
|
+
} = useNotifications();
|
|
140
|
+
const onSignIn = React2.useCallback(async ({
|
|
141
|
+
email,
|
|
142
|
+
password
|
|
143
|
+
}) => {
|
|
144
|
+
try {
|
|
145
|
+
const response = await fetch(`${apiUrl}/auth/local`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: {
|
|
148
|
+
"Content-Type": "application/json"
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
identifier: email,
|
|
152
|
+
password
|
|
153
|
+
})
|
|
154
|
+
});
|
|
155
|
+
const data = await response.json();
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
const errorMessage = data.error?.message;
|
|
158
|
+
if (errorMessage === "Your account email is not confirmed") {
|
|
159
|
+
const resendResponse = await fetch(`${apiUrl}/auth/send-email-confirmation`, {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: {
|
|
162
|
+
"Content-Type": "application/json"
|
|
163
|
+
},
|
|
164
|
+
body: JSON.stringify({
|
|
165
|
+
email
|
|
166
|
+
})
|
|
167
|
+
});
|
|
168
|
+
if (!resendResponse.ok) {
|
|
169
|
+
const resendData = await resendResponse.json();
|
|
170
|
+
addNotification({
|
|
171
|
+
title: "Resend confirmation email failed",
|
|
172
|
+
message: resendData.error?.message || "An error occurred while resending the confirmation email.",
|
|
173
|
+
type: "error"
|
|
174
|
+
});
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
setScreen({
|
|
178
|
+
value: "confirmSignUpCheckEmail"
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
addNotification({
|
|
183
|
+
title: "Sign in failed",
|
|
184
|
+
message: data.error?.message || "An error occurred during sign in.",
|
|
185
|
+
type: "error"
|
|
186
|
+
});
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
storage.setRefreshToken(data.refreshToken);
|
|
190
|
+
setAuthData({
|
|
191
|
+
user: {
|
|
192
|
+
id: data.user.id,
|
|
193
|
+
email: data.user.email,
|
|
194
|
+
emailVerified: data.user.confirmed
|
|
195
|
+
},
|
|
196
|
+
tokens: {
|
|
197
|
+
accessToken: data.jwt,
|
|
198
|
+
refreshToken: data.refreshToken
|
|
199
|
+
},
|
|
200
|
+
isAuthenticated: true
|
|
201
|
+
});
|
|
202
|
+
} catch {
|
|
203
|
+
addNotification({
|
|
204
|
+
title: "Network Error",
|
|
205
|
+
message: "Unable to connect to the server. Please check your connection.",
|
|
206
|
+
type: "error"
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}, [setAuthData, setScreen, addNotification, apiUrl]);
|
|
210
|
+
const onSignUp = React2.useCallback(async ({
|
|
211
|
+
email,
|
|
212
|
+
password
|
|
213
|
+
}) => {
|
|
214
|
+
try {
|
|
215
|
+
const response = await fetch(`${apiUrl}/auth/local/register`, {
|
|
216
|
+
method: "POST",
|
|
217
|
+
headers: {
|
|
218
|
+
"Content-Type": "application/json"
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify({
|
|
221
|
+
username: email,
|
|
222
|
+
// Assuming username is the same as email
|
|
223
|
+
email,
|
|
224
|
+
password
|
|
225
|
+
})
|
|
226
|
+
});
|
|
227
|
+
const data = await response.json();
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
addNotification({
|
|
230
|
+
title: "Sign up failed",
|
|
231
|
+
message: data.error?.message || "An error occurred during sign up.",
|
|
232
|
+
type: "error"
|
|
233
|
+
});
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
setScreen({
|
|
237
|
+
value: "confirmSignUpCheckEmail"
|
|
238
|
+
});
|
|
239
|
+
} catch {
|
|
240
|
+
addNotification({
|
|
241
|
+
title: "Network Error",
|
|
242
|
+
message: "Unable to connect to the server. Please check your connection.",
|
|
243
|
+
type: "error"
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}, [addNotification, setScreen, apiUrl]);
|
|
247
|
+
const onForgotPassword = React2.useCallback(async ({
|
|
248
|
+
email
|
|
249
|
+
}) => {
|
|
250
|
+
try {
|
|
251
|
+
const response = await fetch(`${apiUrl}/auth/forgot-password`, {
|
|
252
|
+
method: "POST",
|
|
253
|
+
headers: {
|
|
254
|
+
"Content-Type": "application/json"
|
|
255
|
+
},
|
|
256
|
+
body: JSON.stringify({
|
|
257
|
+
email
|
|
258
|
+
})
|
|
259
|
+
});
|
|
260
|
+
const data = await response.json();
|
|
261
|
+
if (!response.ok) {
|
|
262
|
+
addNotification({
|
|
263
|
+
title: "Forgot password failed",
|
|
264
|
+
message: data.error?.message || "An error occurred during forgot password.",
|
|
265
|
+
type: "error"
|
|
266
|
+
});
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
} catch {
|
|
270
|
+
addNotification({
|
|
271
|
+
title: "Network Error",
|
|
272
|
+
message: "Unable to connect to the server. Please check your connection.",
|
|
273
|
+
type: "error"
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}, [addNotification, apiUrl]);
|
|
277
|
+
const onConfirmSignUpCheckEmail = React2.useCallback(async () => {
|
|
278
|
+
setScreen({
|
|
279
|
+
value: "signIn"
|
|
280
|
+
});
|
|
281
|
+
}, [setScreen]);
|
|
282
|
+
return /* @__PURE__ */jsx2(AuthCore, {
|
|
283
|
+
screen,
|
|
284
|
+
setScreen,
|
|
285
|
+
onSignIn,
|
|
286
|
+
onSignUp,
|
|
287
|
+
onForgotPassword,
|
|
288
|
+
onConfirmSignUpCheckEmail
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
export { Auth, AuthProvider, useAuth };
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as _ttoss_react_auth_core from '@ttoss/react-auth-core';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare const Auth: () => react_jsx_runtime.JSX.Element;
|
|
6
|
+
|
|
7
|
+
declare const AuthProvider: (props: React.PropsWithChildren<{
|
|
8
|
+
apiUrl: string;
|
|
9
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare const useAuth: () => {
|
|
11
|
+
signOut?: () => Promise<void>;
|
|
12
|
+
isAuthenticated: boolean;
|
|
13
|
+
user: _ttoss_react_auth_core.AuthUser | null;
|
|
14
|
+
tokens: _ttoss_react_auth_core.AuthTokens | null;
|
|
15
|
+
setAuthData: React.Dispatch<React.SetStateAction<_ttoss_react_auth_core.AuthData>>;
|
|
16
|
+
apiUrl: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { Auth, AuthProvider, useAuth };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as _ttoss_react_auth_core from '@ttoss/react-auth-core';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare const Auth: () => react_jsx_runtime.JSX.Element;
|
|
6
|
+
|
|
7
|
+
declare const AuthProvider: (props: React.PropsWithChildren<{
|
|
8
|
+
apiUrl: string;
|
|
9
|
+
}>) => react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare const useAuth: () => {
|
|
11
|
+
signOut?: () => Promise<void>;
|
|
12
|
+
isAuthenticated: boolean;
|
|
13
|
+
user: _ttoss_react_auth_core.AuthUser | null;
|
|
14
|
+
tokens: _ttoss_react_auth_core.AuthTokens | null;
|
|
15
|
+
setAuthData: React.Dispatch<React.SetStateAction<_ttoss_react_auth_core.AuthData>>;
|
|
16
|
+
apiUrl: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { Auth, AuthProvider, useAuth };
|