Files
xamxam/docs
Pontoporeia 554ba3ee8d fix(admin): stop logging out active long-form work; raise idle timeout to 4h
The admin idle timeout (30 min) was refreshed only by navigations and HTMX
requests. During long encoding sessions on an open form there are none, so
an actively-typing admin was logged out mid-work after ~30-45 min.

Add an activity-driven keepalive:
- /admin/session-keepalive.php: 204 when authenticated (refreshes
  admin_last_activity via AdminAuth::isAuthenticated()), 401 otherwise.
- admin-session-keepalive.js: marks activity only on real user input
  (pointer/keyboard/input/scroll/wheel/touch/focus) and pings at most once
  per 5 min while the tab is visible. A genuinely idle tab never pings, so
  the idle timeout still applies.

Raise the idle window 30 min -> 4 h: for a single-/few-admin back-office
whose main workflow is data entry, 30 min still kicked admins who stepped
away mid-form. With the keepalive in place, 4 h means "no interaction at
all", not "no navigation". Absolute timeout stays 12 h.

Also fix session ID rotation, which never fired: it used
`$absolute % IDLE_TIMEOUT_SECONDS === 0`, i.e. required a request to land
exactly on a multiple of the interval relative to login time. Replaced with
an explicit admin_last_rotation timestamp and a ROTATION_INTERVAL_SECONDS
(30 min) constant decoupled from the idle timeout, so raising the idle
window does not widen the fixation/replay window.

Refactor AdminAuth::enforceSessionTimeout() to return bool instead of
redirecting/exiting, so the keepalive endpoint can report 401 cleanly
rather than letting fetch follow a redirect to the login page.

Smoke test (just smoke-session-keepalive) covers activity refresh, 2 h idle
accepted, rotation firing, idle rejection+destruction, and unauthenticated
rejection. Docs updated.
2026-09-18 16:26:49 +02:00
..

Documentation index

docs/ holds current reference documentation describing how the system actually works today. Everything else — proposals, plans, incident reports, analyses, original requirements, one-off helpers — is in archive/.

Note on naming: XAMXAM was previously Post-ERG (code once organised under posterg-website/, apps/, front-backend/, /var/www/posterg/). Historical docs may reference the old layout; the live paths are now app/, app/public/, app/storage/xamxam.db, just dev, PHPUnit, and /var/www/xamxam/ on the server.

Reference docs

Doc Contents
development.md Dev workflow, structure, builds, testing, linting
environment.md Runtime stack, PHP/nginx/DB/Node requirements, server specs
deployment.md Server setup, deploy, backups, rollback
database.md SQLite schema, migrations, tables, common ops
search.md /search and /repertoire behaviour
export.md CSV / DB / files export + full restore procedure
nextcloud-sync.md Off-site SQLite snapshot sync to Nextcloud WebDAV
import.md CSV import format + behaviour
security.md Current security posture
file-uploads.md Upload surfaces, types, storage layout
CSS.md CSS architecture + build

Archive

Non-documentation material (proposals, plans, incident reports, analyses, requirements, one-off helpers) is preserved read-only in archive/ for context. It is not maintained.

  • nginx/docs/ — nginx config, security headers, deployment, HTACCESS→nginx
  • app/storage/README.md — DB quick-reference (schema link)
  • app/public/admin/README.md — admin panel structure

Maintenance guidance: when updating code, update the matching reference doc above. Do not move analysis/proposals into docs/ — put them in archive/.