Session Management and Timeout Policy¶
This document describes the current session model used by the SetTimes admin experience.
Current Session Architecture¶
SetTimes uses server-side sessions stored in D1, managed by a direct session manager in functions/utils/auth.js. (The Lucia dependency was removed in PR #290; the table is still named lucia_sessions for historical/compatibility reasons.)
- Server-side session store:
lucia_sessions - Session cookie:
__Host-session_tokenin production,session_tokenin local development - CSRF cookie:
csrf_tokenfor the double-submit CSRF pattern - Client-side persistence: localStorage stores display-only user fields such as email, name, and role. It does not store the session secret.
The session identifier remains in an HttpOnly cookie and is not available to JavaScript.
Key implementation references:
functions/utils/auth.jsfunctions/api/admin/_middleware.jsfunctions/api/admin/me.jsfrontend/src/utils/adminApi.jsfrontend/src/admin/hooks/useAdminAuthSession.js
Timeout Policy¶
The timeout model is server-driven.
Admin sessions¶
- Idle timeout: 15 minutes
- Absolute maximum lifetime: 8 hours
Non-admin authenticated sessions¶
- Idle timeout: 30 minutes
- Absolute maximum lifetime: 30 days
The middleware checks both limits on every authenticated /api/admin/* request. If either limit is exceeded, the server invalidates the session and clears the session cookie.
Client Behavior¶
The admin frontend checks the current session via GET /api/admin/me.
- A valid response refreshes the local UI state and updates session-timing headers.
- A
401response is treated as a real authentication failure and logs the user out. - A temporary
5xx, parse failure, or network problem is treated as a transient verification failure and should not immediately sign out a user who already has valid local admin state.
This distinction exists to avoid losing in-progress admin work during temporary Cloudflare, D1, or connectivity faults.
Idle Warning and Logout UX¶
The admin UI displays a warning dialog shortly before enforced logout.
- Warning lead time: 5 minutes before the current server-reported expiry window
- Warning actions:
Stay signed inorLog out - If the user is logged out for inactivity, the login screen shows:
You were signed out due to inactivity. Please sign in again.
Stay signed in triggers a fresh session verification. If that verification fails transiently, the UI keeps the existing admin state instead of treating the failure as an immediate logout.
Session Security Properties¶
- Session cookies are HttpOnly
- Production cookies use the
__Host-prefix andSameSite=Strict - CSRF protection uses a double-submit token cookie plus
X-CSRF-Token - Session expiry enforcement happens server-side, not only in the browser
- The session metadata returned to the browser excludes raw session identifiers
Session-Related Endpoints¶
These routes are currently used for authenticated self-service inside the admin portal namespace:
GET /api/admin/me: returns authenticated user info and safe session expiry metadataGET /api/admin/sessions: returns safe session metadata for the current user without raw session IDsDELETE /api/admin/sessions: revokes a specific session when an opaquerevocationTokenis supplied; raw session IDs are never exposed to the clientPOST /api/admin/sessions/revoke-all: revokes all other sessions and rotates the current sessionGET /api/admin/trusted-devices: lists trusted devices for the current userDELETE /api/admin/trusted-devices: revokes a trusted device
Operational Notes¶
- Temporary server or network failures should be investigated as availability problems, not assumed to be session expiry.
- Session cleanup for expired rows is handled by the maintenance cleanup flow against
lucia_sessions. - If an account is deactivated, subsequent authenticated requests fail even if the cookie is still present.
Testing Guidance¶
Useful checks when changing session behavior:
- Verify that
GET /api/admin/mereturns safe session metadata only. - Verify that
GET /api/admin/sessionsdoes not expose rawlucia_sessions.idvalues. - Verify that transient
5xxfailures during session verification do not immediately sign out an already authenticated admin. - Verify that real
401responses still clear admin state and redirect to login. - Verify that idle warning timing matches server-provided expiry headers.
Related Docs¶
docs/ADMIN_HANDBOOK.mddocs/TROUBLESHOOTING.mdSECURITY.md