User Story
As an authenticated user, I want my login session to persist across page reloads, so that I don't have to log in every time I refresh the page.
Parent Epic
EPIC-01: Authentication & User Management (#1)
Priority
Must Have
Dependencies
Acceptance Criteria
- A Fastify plugin manages session creation, validation, and expiration
- Sessions are stored server-side (in SQLite) with a session token sent to the client as an HTTP-only, Secure, SameSite=Strict cookie
- A
sessions table exists with columns: id (TEXT PRIMARY KEY), user_id (TEXT NOT NULL, FK to users), expires_at (TEXT NOT NULL), created_at (TEXT NOT NULL)
- Sessions expire after a configurable duration (default: 7 days)
- Expired sessions are cleaned up periodically (e.g., on a timer or on each request)
- A
GET /api/auth/me endpoint returns the current user's profile if authenticated, or 401 if not
- A
POST /api/auth/logout endpoint destroys the current session and clears the cookie
- A Fastify preHandler hook protects all
/api/* routes (except /api/auth/setup and /api/auth/login) — returns 401 for unauthenticated requests
Notes
- The session token should be cryptographically random (e.g., 256-bit)
- The cookie must use
HttpOnly, Secure, and SameSite=Strict flags for security
- The
Secure flag may need to be configurable for local development (HTTP without TLS)
- Session cleanup can be lazy (on request) or active (interval timer) — implementation decision for backend developer
- The auth preHandler hook is the gatekeeper for the entire API surface
User Story
As an authenticated user, I want my login session to persist across page reloads, so that I don't have to log in every time I refresh the page.
Parent Epic
EPIC-01: Authentication & User Management (#1)
Priority
Must Have
Dependencies
Acceptance Criteria
sessionstable exists with columns:id(TEXT PRIMARY KEY),user_id(TEXT NOT NULL, FK to users),expires_at(TEXT NOT NULL),created_at(TEXT NOT NULL)GET /api/auth/meendpoint returns the current user's profile if authenticated, or 401 if notPOST /api/auth/logoutendpoint destroys the current session and clears the cookie/api/*routes (except/api/auth/setupand/api/auth/login) — returns 401 for unauthenticated requestsNotes
HttpOnly,Secure, andSameSite=Strictflags for securitySecureflag may need to be configurable for local development (HTTP without TLS)