You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> You can customize the cookie behavior by passing `cookieOptions` to the `TOTPStrategy` instance. Check [Customization](https://github.com/dev-xo/remix-auth-totp/blob/main/docs/customization.md) to learn more.
136
+
> You can customize the cookie behavior by passing a `cookieOptions` property to the `TOTPStrategy` instance. Check [Customization](https://github.com/dev-xo/remix-auth-totp/blob/main/docs/customization.md) to learn more.
137
137
138
-
### 2: Implementing the Strategy Logic.
138
+
### 2: Implementing Strategy Logic
139
139
140
140
The Strategy Instance requires the following method: `sendTOTP`.
141
141
@@ -154,11 +154,12 @@ authenticator.use(
154
154
)
155
155
```
156
156
157
-
### 3. Creating and Storing the User.
157
+
### 3. Handling User Creation
158
158
159
159
The Strategy returns a `verify` method that allows handling our own logic. This includes creating the user, updating the session, etc.<br />
160
160
161
-
When using Cloudflare D1, you may want to perform the lookup in `action` or `loader` after committing the session, by passing the `context` binding to a `findOrCreateUserByEmail` function.
161
+
> [!TIP]
162
+
> When using Cloudflare D1, consider performing user lookups in the `action` or `loader` functions after committing the session. You can pass the `context` binding to a `findOrCreateUserByEmail` function to handle database operations.
162
163
163
164
This should return the user data that will be stored in Session.
164
165
@@ -171,11 +172,9 @@ authenticator.use(
171
172
},
172
173
async ({ email }) => {
173
174
// Get user from database.
174
-
let user =awaitdb.user.findFirst({
175
-
where: { email },
176
-
})
175
+
let user =awaitdb.user.findFirst({ where: { email } })
177
176
178
-
// Create a new user if it doesn't exist.
177
+
// Create a new user (if it doesn't exist).
179
178
if (!user) {
180
179
user=awaitdb.user.create({
181
180
data: { email },
@@ -204,8 +203,17 @@ authenticator.use(
204
203
205
204
Last but not least, we need to create the routes for the authentication flow.
206
205
206
+
We'll require the following routes:
207
+
208
+
-`login.tsx` - Handles the login form submission.
209
+
-`verify.tsx` - Handles the TOTP verification form submission.
210
+
-`logout.tsx` - Handles the logout.
211
+
-`dashboard.tsx` - Handles the authenticated route (optional).
212
+
207
213
### `login.tsx`
208
214
215
+
This route is used to handle the login form submission.
216
+
209
217
```tsx
210
218
// app/routes/login.tsx
211
219
import { redirect } from'react-router'
@@ -271,6 +279,8 @@ export default function Login() {
271
279
272
280
### `verify.tsx`
273
281
282
+
This route is used to handle the TOTP verification form submission.
283
+
274
284
For the verify route, we are leveraging `@mjackson/headers` to parse the cookie. Created by Michael Jackson, the CO-Founder of Remix/React Router.
275
285
276
286
```tsx
@@ -389,8 +399,32 @@ export default function Verify() {
389
399
}
390
400
```
391
401
402
+
### `logout.tsx`
403
+
404
+
This route is used to destroy the session and redirect to the login page.
0 commit comments