Skip to main content

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
  • 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 + session objects (session null if verification required).
  • 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
  • Behaviour

    • Uses Supabase Admin API to generate recovery link (if SUPABASE_SERVICE_ROLE_KEY available)
    • Falls back to Supabase resetPasswordForEmail if admin API unavailable
    • Sends email via Resend API with reset link
    • Reset link redirects to: https://my.reformer.la/reset-password (configurable via PASSWORD_RESET_REDIRECT_URL)
  • 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
  • Email Delivery

    • Sent via Resend API (RESEND_API_KEY required)
    • From: Reformer <noreply@mail.reformer.la>
    • Subject: "Reset your Reformer password"
    • Link expires in 1 hour (Supabase default)

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
  • Token Format

    • Supabase sends recovery tokens in URL hash: #access_token=xxx&type=recovery&expires_in=3600
    • Frontend extracts access_token and sends to this endpoint
    • Token can be passed in body token field or Authorization: Bearer header
  • 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 URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY / SUPABASE_ANON_KEY - Supabase anonymous key
  • SUPABASE_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 to https://my.reformer.la/reset-password)
  • AUTH_RESET_REDIRECT_URL - Alternative environment variable name for reset redirect
  • NEXT_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.js once 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.).***