StudyBoost Docs

Feature: Secure Cookie Authentication with Session Management

Metadata


Overview

Implements secure authentication using HTTP-only cookies, short-lived access tokens, rotating refresh tokens, and database-backed session management for multi-device login. This is the baseline for protected features such as uploads, AI usage, premium access, and user personalization.


Frontend Behavior

  • Dedicated auth pages are the only auth entry points: /login, /signup.
  • Login page accepts email or username plus password.
  • Signup page captures email, username, password, and confirm password (optional first/last name).
  • Auth requests include credentials: 'include' so cookie-based sessions work.
  • Successful login/signup stores auth state in cookies only (no localStorage token usage).
  • Logout clears auth cookies and ends the active session.
  • Unauthenticated access to protected routes/actions redirects to /login?next=<target>.
  • No in-page auth modal fallback in FEAT-31.

Backend Behavior

  • POST /auth/signup — validates payload, hashes password with bcrypt, creates user in users, creates session in auth_sessions, sends email verification token via email_verification_tokens, sets access_token + refresh_token cookies.
  • POST /auth/login — authenticates by identifier (email or username) + password, creates a new session row per login (multi-device support), sets auth cookies.
  • POST /auth/refresh — validates the refresh token from the cookie, rotates the refresh token and updates the session hash, issues a new short-lived access token.
  • POST /auth/logout — clears auth cookies, invalidates the active session in auth_sessions.
  • GET /auth/me — requires authentication, returns the current user profile.
  • POST /auth/verify-email — marks the user email verified when the token is valid.
  • POST /auth/resend-verification — reissues a verification token for unverified users.

Cookie and token policy:

  • access_token: short-lived (default 15 minutes).
  • refresh_token: long-lived (7-30 days, default 30 days).
  • Tokens stored in HTTP-only cookies only (no localStorage).
  • Hosted env: cookie domain shared on .studyboost.com; local dev: host-only cookie domain for localhost compatibility.

Security and guard behavior:

  • Access token validated from cookies; expired access token auto-refreshes via a valid refresh token.
  • Session validation checks auth_sessions on protected routes.
  • Refresh tokens are stored hashed only and rotated on every refresh.
  • Rate limiting enabled on auth endpoints.

Protected routes in this scope: notifications controller endpoints; subscriptions/my-subscription, subscriptions/my-usage, usage mutation debug routes; documents/upload and documents/summarize.


QA Test Scenarios

Scenario IDDescriptionStepsInputExpected Result
FEAT-31-01Signup creates session and cookiesCall POST /auth/signup with valid payloadValid email, username, passwordReturns success, creates users + auth_sessions rows, sets auth cookies
FEAT-31-02Login creates separate device sessionsLogin from two clientsSame valid credentials on two devicesTwo valid auth_sessions rows for the same user
FEAT-31-03Access token allows protected routeCall protected endpoint with valid cookiesValid access_token cookieRequest succeeds
FEAT-31-04Expired access token auto-refreshesUse expired access token with valid refresh token on protected routeExpired access + valid refreshRequest succeeds and cookies are rotated
FEAT-31-05Refresh replay is blockedReuse old refresh token after rotationStale refresh tokenRequest fails with unauthorized
FEAT-31-06Logout invalidates active sessionCall POST /auth/logout then call protected route with old cookiesValid auth cookies then reused cookiesCookies cleared, session removed, protected route returns unauthorized
FEAT-31-07Missing auth cookies are rejectedCall protected route without cookiesNo cookies401 unauthorized response
FEAT-31-08Login throttlingRepeated failed login attempts within throttle windowWrong password repeatedlyRate-limit response after threshold
FEAT-31-09Verify email flowCall verify endpoint with a valid tokenValid verification tokenUser email marked verified; token marked used
FEAT-31-10Subdomain cookie policyTest hosted env cookie settingsHosted env requestCookies include .studyboost.com domain and secure policy

Edge Cases

  • Stolen or replayed refresh token after rotation is rejected.
  • Expired session row while the access token is still present.
  • Missing/invalid cookies on protected endpoints.
  • Unverified email account logging in before verification.
  • CORS origin not in the allow-list for credentialed requests.

Notes

  • Feature flags: None.
  • Dependencies: @nestjs/jwt, @nestjs/throttler, Prisma models (auth_sessions, email_verification_tokens), Mail module.
  • Known limitations: No account lockout or CAPTCHA in this scope.
  • Dependency contract: Future AI/billing/premium/upload protections must reuse FEAT-31 cookie/session guards and include FEAT-level auth QA scenarios.

OAuth and Reset Integration

OAuth callbacks (Google in FEAT-105) resolve/link the user account, then issue auth cookies through the same createSessionForUser pipeline used by email/password login. Password reset completion in FEAT-105 revokes every row in auth_sessions for the affected user after writing the new password hash, enforcing global sign-out across devices.


Related Docs

  • Features contract: /docs/features
  • QA requirements: /docs/features/qa-requirements
  • Database schema: /docs/database-schema
  • Core systems: /docs/core-systems
  • Implementation-level source of truth: docs/features/FEAT-31-secure-cookie-auth-session-management.md