Skip to main content
Source: equa-server/modules/auth/src/sessions.ts, authentication.ts, google-auth.ts, modules/api/src/server.ts, magic-link.ts

Authentication

The Equa API uses session-based authentication powered by express-session. After a successful login, the server creates a session and returns a session cookie. This cookie must be included in all subsequent API requests.

How Sessions Work

  1. The client sends credentials to a login endpoint
  2. The server validates credentials and creates a session stored in the database (TypeORM session store)
  3. A Set-Cookie header is returned with the session ID
  4. The client includes this cookie on every subsequent request
  5. The server validates the session on each request and identifies the user

Session Configuration

SettingValueDescription
maxAge604,800,000 ms (7 days)Session expiration time (configurable via API_SESSION_MAX_AGE)
rollingtrueSession expiry resets on each request
resavefalseSession is not re-saved if unmodified
saveUninitializedfalseEmpty sessions are not persisted
sameSitelaxMitigates CSRF by limiting cross-site cookie sends
httpOnlytruePrevents JavaScript access to the session cookie
securetrue in productionCookie only sent over HTTPS
proxytrueTrust the reverse proxy for secure cookies

Login Methods

Email and Password

POST /v1/user/login
{
  "email": "user@example.com",
  "password": "your-password"
}
Returns the authenticated user object and sets the session cookie.

Google OAuth

POST /v1/user/google-auth
{
  "token": "google-oauth-id-token"
}
Accepts a Google OAuth ID token (obtained from Google Sign-In on the client). Creates or links the user account and establishes a session.

Google OAuth Redirect Mode (form POST)

POST /v1/user/google-auth/redirect
Content-Type: application/x-www-form-urlencoded
Used by Google Sign-In redirect/form flows where Google posts credentials as form data instead of JSON. Required form fields:
  • credential: Google OAuth ID token
  • g_csrf_token: CSRF token from the form body
CSRF validation requirements:
  • The g_csrf_token value must be present in both the request body and the g_csrf_token cookie.
  • The two values must match, or the request is rejected.
Behavior:
  • Success: Creates/links the user session and redirects to /login?authenticated=true.
  • Missing credential: Returns 400 with { "message": "Missing credential" }.
  • CSRF mismatch/missing token: Returns 403 with { "message": "CSRF token validation failed" }.
  • Auth failure during verification: Redirects to /login?error=auth_failed.
Magic links provide passwordless email-based authentication.
The magic link module (modules/auth/src/magic-link.ts) implements token generation, verification, and session creation, but dedicated REST endpoints (POST /v1/user/magic-link and POST /v1/user/magic-link/verify) are not currently registered in auth-endpoints.ts. The implementation exists but is not yet wired to the endpoint layer.
The magic link flow (when fully wired) works as follows: Step 1: Request a magic link — Generates a 32-byte hex token (crypto.randomBytes(32).toString('hex')), stores it with a 15-minute expiry, and sends an email to the user. The response is always successful to prevent email enumeration. Step 2: Verify the magic link token — Validates the token (must be unused, not expired), marks it as used, creates a logged-in session, and returns the user object.

Making Authenticated Requests

All API calls from the browser must include credentials so the session cookie is sent:
const response = await fetch('https://api.equa.cc/v1/organization', {
  method: 'GET',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
})

Checking the Current Session

To verify the current session is valid and retrieve the authenticated user:
GET /v1/user/current
Returns the current user object if the session is valid, or an unauthenticated response otherwise.

Debugging Sessions (Development Only)

For local session debugging, use the auth diagnostic endpoint:
GET /v1/auth/diagnostic
This endpoint is available in development and test environments. It is disabled in production (NODE_ENV=production). Example response shape:
{
  "hasSession": true,
  "hasUser": true,
  "userId": "uuid-or-null",
  "sessionIdPrefix": "abcd1234...",
  "hasConnectSidCookie": true,
  "cookieSecure": false,
  "cookieMaxAge": 604799999,
  "timestamp": "2026-02-22T17:45:31.712Z"
}
Use this endpoint to confirm whether a 401/403 is caused by a missing session, expired session, or cookie configuration mismatch.

Logout

POST /v1/user/logout
Destroys the server-side session and clears the session cookie. Requires an active session.

Two-Factor Authentication (2FA)

Equa supports TOTP-based two-factor authentication.
EndpointMethodDescription
GET /v1/user/2faGETGenerate a new 2FA secret/QR code
POST /v1/user/2fa/verifyPOSTVerify a 2FA token
POST /v1/user/2faPOSTEnable 2FA on the account (auth required)

CORS and Cookies

The API server is configured to accept cross-origin requests from the Equa frontend domain. Ensure your requests include:
  • credentials: 'include' on all fetch calls
  • The correct Content-Type header for JSON payloads
  • HTTPS in production (required for secure cookies)