Spaces:
Running
Running
Redirect confirmed email users to sign in
Browse files- README.md +2 -2
- src/server.ts +2 -4
README.md
CHANGED
|
@@ -74,7 +74,7 @@ Brevo is configured as Supabase Auth's SMTP provider; the Express API does not s
|
|
| 74 |
<p><a href="https://sporalizer.pages.dev/api/auth/confirm?token_hash={{ .TokenHash }}">Confirm email</a></p>
|
| 75 |
```
|
| 76 |
|
| 77 |
-
Set **Site URL** to the frontend origin. Allow the frontend callback URLs listed above. The Pages proxy forwards confirmation to the backend, which verifies the one-time token and
|
| 78 |
|
| 79 |
Brevo credentials stay in Supabase SMTP settings and are not added to the browser or committed to `.env`.
|
| 80 |
|
|
@@ -84,7 +84,7 @@ Brevo credentials stay in Supabase SMTP settings and are not added to the browse
|
|
| 84 |
- `POST /api/auth/login` β `{ email, password }`.
|
| 85 |
- `GET /api/auth/google?redirect=/labs` β starts Google OAuth.
|
| 86 |
- `GET /api/auth/callback` β exchanges the Supabase code and sets HttpOnly cookies.
|
| 87 |
-
- `GET /api/auth/confirm?token_hash=...` β verifies the signup email and
|
| 88 |
- `GET /api/auth/me` β verifies the session and refreshes it when necessary.
|
| 89 |
- `POST /api/auth/logout` β clears the session cookies.
|
| 90 |
- `GET /api/auth/profile` and `PATCH /api/auth/profile` β read and update the signed-in user's profile.
|
|
|
|
| 74 |
<p><a href="https://sporalizer.pages.dev/api/auth/confirm?token_hash={{ .TokenHash }}">Confirm email</a></p>
|
| 75 |
```
|
| 76 |
|
| 77 |
+
Set **Site URL** to the frontend origin. Allow the frontend callback URLs listed above. The Pages proxy forwards confirmation to the backend, which verifies the one-time token and redirects to `/login?verified=1`; the user then signs in with their email and password. Existing email links using the Space origin should be replaced by newly issued emails.
|
| 78 |
|
| 79 |
Brevo credentials stay in Supabase SMTP settings and are not added to the browser or committed to `.env`.
|
| 80 |
|
|
|
|
| 84 |
- `POST /api/auth/login` β `{ email, password }`.
|
| 85 |
- `GET /api/auth/google?redirect=/labs` β starts Google OAuth.
|
| 86 |
- `GET /api/auth/callback` β exchanges the Supabase code and sets HttpOnly cookies.
|
| 87 |
+
- `GET /api/auth/confirm?token_hash=...` β verifies the signup email and redirects to the login page with a confirmation message.
|
| 88 |
- `GET /api/auth/me` β verifies the session and refreshes it when necessary.
|
| 89 |
- `POST /api/auth/logout` β clears the session cookies.
|
| 90 |
- `GET /api/auth/profile` and `PATCH /api/auth/profile` β read and update the signed-in user's profile.
|
src/server.ts
CHANGED
|
@@ -444,8 +444,7 @@ app.get("/api/auth/callback", async (req, res, next) => {
|
|
| 444 |
});
|
| 445 |
|
| 446 |
// Supabase confirmation emails can use {{ .TokenHash }} to deliver the one-time
|
| 447 |
-
// token directly to this server.
|
| 448 |
-
// cookie session used by password and Google sign-in.
|
| 449 |
app.get("/api/auth/confirm", async (req, res, next) => {
|
| 450 |
try {
|
| 451 |
const tokenHash = typeof req.query.token_hash === "string" ? req.query.token_hash : "";
|
|
@@ -455,8 +454,7 @@ app.get("/api/auth/confirm", async (req, res, next) => {
|
|
| 455 |
if (error || !data.user || !data.session) return res.redirect(`${env.FRONTEND_URL}/login?error=email_confirmation_failed`);
|
| 456 |
|
| 457 |
await syncProfile(data.user);
|
| 458 |
-
|
| 459 |
-
return res.redirect(`${env.FRONTEND_URL}/labs`);
|
| 460 |
} catch (error) { next(error); }
|
| 461 |
});
|
| 462 |
|
|
|
|
| 444 |
});
|
| 445 |
|
| 446 |
// Supabase confirmation emails can use {{ .TokenHash }} to deliver the one-time
|
| 447 |
+
// token directly to this server. Verify the email, then ask the user to sign in.
|
|
|
|
| 448 |
app.get("/api/auth/confirm", async (req, res, next) => {
|
| 449 |
try {
|
| 450 |
const tokenHash = typeof req.query.token_hash === "string" ? req.query.token_hash : "";
|
|
|
|
| 454 |
if (error || !data.user || !data.session) return res.redirect(`${env.FRONTEND_URL}/login?error=email_confirmation_failed`);
|
| 455 |
|
| 456 |
await syncProfile(data.user);
|
| 457 |
+
return res.redirect(`${env.FRONTEND_URL}/login?verified=1`);
|
|
|
|
| 458 |
} catch (error) { next(error); }
|
| 459 |
});
|
| 460 |
|