Logo

Command Palette

Search for a command to run...

Authentication

How OTP, Magic Link, and session-based auth work across the RocketX platform.

Centralized Auth Architecture

All authentication logic lives in the Express backend. Next.js is a pure consumer — no auth logic runs in Next.js middleware or server actions.

  • OTP + Magic Link: Both are dispatched simultaneously to the user's email via Resend (or Nodemailer SMTP fallback).
  • Password reset: Time-limited token flow via email.
  • Session cookie: On successful login the API sets a secure, HttpOnly better-auth.session_token cookie.

The Proxy Rewrite

next.config.ts rewrites /api/* to the Express server so the browser always talks to one origin and cookies are scoped correctly:

// apps/web/next.config.ts
async rewrites() {
  return [
    { source: "/api/:path*", destination: "https://api.rocketx.market/:path*" },
  ];
}

Session Verification

The requireAuth Express middleware reads the auth-token JWT cookie (signed with ENCRYPTION_KEY) and attaches req.user to every authenticated request. The Next.js AuthGuard fetches /api/v1/auth/session to hydrate the Zustand auth store on the client.

GitHub OAuth (Developer Feature)

Connecting GitHub to the Developer Portal uses a stateful OAuth flow:

  1. GET /v1/developer/github/connect — signs a short-lived HS256 state JWT containing { userId, purpose: "github-connect", returnTo } and redirects to GitHub App installation.
  2. GitHub redirects back to GET /v1/developer/github/callback — this route is public (registered before requireAuth). It verifies the state JWT, exchanges the installation ID, saves it to the user's record, then redirects to returnTo.

Cookie Domain Strategy

Because auth uses HttpOnly cookies, UI and API must share a cookie domain:

EnvironmentCookie domain
Local devlocalhost (browser handles automatically)
Production.yourdomain.com (set AUTH_DOMAIN=.yourdomain.com in API env)

In production, both app.yourdomain.com and api.yourdomain.com must sit under .yourdomain.com.