Authentication Endpoints
Supabase handles the underlying auth, while our Express API wraps core flows for better control (custom verification emails, rate limiting, onboarding hand-off). These endpoints live in reformer-platform/src/api/auth.js.
POST /api/auth/signup
Create a new account.
- Body
{
"email": "founder@example.com",
"password": "StrongPass123",
"metadata": {
"name": "Founder",
"companyName": "Client Co"
}
}
-
Validations
- Email format check (
isValidEmail) - Password strength (>= 8 chars, mixed case, numeric)
- Rate limited via
userRateLimiter
- Email format check (
-
Behaviour
- Uses Supabase Auth (
createClient) to register user. - Generates short verification token (stored in
verification_tokens) and sends Resend email (/verify?token=...). - Returns Supabase
user+sessionobjects (session null if verification required).
- Uses Supabase Auth (
-
Errors
- 400 for missing/invalid input.
- 409 if email already registered.
POST /api/auth/login
Authenticate user and return Supabase session token.
{
"email": "founder@example.com",
"password": "StrongPass123"
}
- 200:
{ "session": { "access_token": "...", ... }, "user": {...} } - 401: Invalid credentials
- 403: Email not verified (if Supabase denies login)
POST /api/auth/logout
Logs user out by revoking Supabase refresh token. Expects bearer token in Authorization header.
GET /api/auth/me
Returns current user profile if Authorization: Bearer <token> present.
- 200:
{"email":"...","app_metadata":...} - 401: Missing/invalid token
POST /api/auth/forgot-password
Request a password reset email. Sends a recovery link to the user's email address.
- Body
{
"email": "founder@example.com"
}
-
Validations
- Email format check (
isValidEmail) - Rate limited via
userRateLimiter
- Email format check (
-
Behaviour
- Uses Supabase Admin API to generate recovery link (if
SUPABASE_SERVICE_ROLE_KEYavailable) - Falls back to Supabase
resetPasswordForEmailif admin API unavailable - Sends email via Resend API with reset link
- Reset link redirects to:
https://my.reformer.la/reset-password(configurable viaPASSWORD_RESET_REDIRECT_URL)
- Uses Supabase Admin API to generate recovery link (if
-
Response
- 200:
{"success": true, "message": "If an account exists for this email, a reset link has been sent."} - 400: Invalid email format
- 500: Email sending failed
- 200:
-
Email Delivery
- Sent via Resend API (
RESEND_API_KEYrequired) - From:
Reformer <noreply@mail.reformer.la> - Subject: "Reset your Reformer password"
- Link expires in 1 hour (Supabase default)
- Sent via Resend API (
POST /api/auth/reset-password
Reset password using recovery token from email link.
- Body
{
"password": "NewStrongPass123",
"token": "recovery_token_from_email_link"
}
- Headers (Alternative to body token)
Authorization: Bearer <recovery_token>
-
Validations
- Password strength (>= 8 chars, uppercase, lowercase, number)
- Token must be valid Supabase recovery token
- Rate limited via
userRateLimiter
-
Behaviour
- Extracts token from body, Authorization header, or URL hash
- Creates Supabase session with recovery token
- Updates password via
supabase.auth.updateUser() - Falls back to Admin API if direct update fails
- Supports JWT token decoding for admin API fallback
-
Response
- 200:
{"success": true, "message": "Password has been reset successfully"} - 400: Invalid token, expired link, or weak password
- 500: Server error during password update
- 200:
-
Token Format
- Supabase sends recovery tokens in URL hash:
#access_token=xxx&type=recovery&expires_in=3600 - Frontend extracts
access_tokenand sends to this endpoint - Token can be passed in body
tokenfield orAuthorization: Bearerheader
- Supabase sends recovery tokens in URL hash:
-
Frontend Pages
/forgot-password- Request reset link/reset-password- Set new password (extracts token from URL hash)
Environment Variables
Required for Authentication
NEXT_PUBLIC_SUPABASE_URL/SUPABASE_URL- Supabase project URLNEXT_PUBLIC_SUPABASE_ANON_KEY/SUPABASE_ANON_KEY- Supabase anonymous keySUPABASE_SERVICE_ROLE_KEY- Service role key for admin operations (password reset, verification)
Required for Email Delivery
RESEND_API_KEY- Resend API key for sending verification and password reset emails
Optional Configuration
PASSWORD_RESET_REDIRECT_URL- Custom redirect URL for password reset (defaults tohttps://my.reformer.la/reset-password)AUTH_RESET_REDIRECT_URL- Alternative environment variable name for reset redirectNEXT_PUBLIC_MARKETING_SITE_URL- Marketing site URL for redirects
QA / Testing Notes
- E2E flow captured in
docs/operations/e2e-auth.mdx. - Rate limit: Supabase may return
email rate limit exceeded; wait or vary domains. - Use
node scripts/test-e2e-auth.jsonce rate limits reset. - Checkout integration expects verified session token for authenticated calls.
Keep this page updated as auth routes change (Memberstack fallback, magic links, SSO, etc.).***