Skip to main content

SPEC 001 — Authentication


1. Feature Purpose

Authentication gates every action in the Equa platform. It provides three sign-in methods (password, Google OAuth, magic link), enforces email verification before access, supports optional two-factor authentication, and maintains rolling server-side sessions. Authorization is layered on top via RBAC with per-site read/write permission checks.

2. Current State (Verified)

2.1 Password Login

2.2 Google OAuth

2.4 Sessions

2.5 Authorization (RBAC)

2.6 Auth Form Fields (Frontend)

The login and registration forms use react-final-form with custom field components that render plain <input type="text">, not <input type="email">. This is intentional — the login field accepts either a username or an email address, so type="email" would reject valid usernames. Testing implication: E2E selectors must target input[name="usernameOrEmail"] / input[name="email"], never input[type="email"]. Tests using type="email" selectors silently time out (30s) because the locator never matches. See PR #515 for the full test locator fix. Source: equa-web/src/modules/auth/pages/login.tsx, equa-web/src/modules/auth/pages/register.tsx, e2e/regression-fixed-issues.spec.ts (PR #515, 2026-04-02).

2.7 Gateway Token Sync (URL Query Params)

The Equa frontend participates in the equabot gateway’s tokenized-URL pattern. When a user lands on the app with ?equabotToken=<token> or ?gatewayToken=<token> in the query string, storage.ts reads the token and auto-persists it to localStorage under the gateway-token key. Why it exists: Before PR #512, a client/server token desync could leave the dashboard unable to reach the gateway even though the user was authenticated. The URL-param handoff lets the gateway hand a fresh token directly to the browser via the landing URL, eliminating the desync class of bug (EQUAStart#502). Source: equa-web/src/modules/equabot-settings/services/storage.ts, storage.test.ts (PR #512 Workstream A, 2026-04-01; lint follow-up in PR #513).

3. Data Model

Users

Sessions

TempPasswords

EmailVerifications

Onetimecodes


4. API Endpoints


5. Frontend Components

Frontend Session Handling

  • Cookies sent with credentials: 'include' on every fetch.
  • 401 responses trigger automatic logout and redirect to login.
  • Current user loaded from GET /api/v1/user/current.

6. Business Rules

  1. Email verification required — Users cannot access protected routes until emailVerified = true.
  2. Rolling sessions — Every authenticated request refreshes the session expiry (rolling: true), so active users stay logged in as long as they make a request within every 42-minute window.
  3. Anti-enumeration on magic linkssendMagicLink() always returns success, even for unknown emails, to prevent email harvesting.
  4. Secure cookies — The secure flag is set automatically when SSL is detected, preventing cookie transmission over plain HTTP.
  5. Google auto-registration — First-time Google OAuth users are created automatically; email is pre-verified from Google’s claim.
  6. RBAC enforcementrequirePermissions() middleware runs before every protected endpoint; canWriteSite() and canReadSite() gate organization-level access.
  7. Password hashing — bcryptjs with 10 salt rounds; raw passwords are never stored or logged.
  8. Magic link expiry — Tokens expire after 15 minutes; cleanupExpiredMagicLinks() removes stale rows.

7. Acceptance Criteria

  • User can register with email + password and receive a verification email
  • User cannot access protected routes until email is verified
  • User can log in with verified email + correct password
  • User can enable and verify TOTP two-factor authentication
  • User can sign in with Google OAuth and is auto-registered on first use
  • User can request a magic link and log in via the emailed token
  • Magic link tokens expire after 15 minutes
  • Session persists for up to 42 minutes with rolling refresh
  • 401 response on frontend triggers automatic logout
  • RBAC guards block unauthorized access to organization resources
  • Anti-enumeration: magic link request returns success for non-existent emails

8. Risks