- Shipped
- August 3, 2026 at 4:04 AM UTC
- Author
- kamo
- Commit
- 6c003d8
A session left open on an unattended workstation stayed usable indefinitely. This terminates it after 15 minutes of no interaction, with a 60-second warning so nobody is dumped mid-task. The timing rules live in app/lib/idleTimeout.ts as a pure controller (unit tested with fake timers); the component is only an input layer. Three decisions worth knowing about: - Only pointer, key, wheel, scroll, touch and visibility events count as presence. Websocket frames, polling and timers do not — kamo-internal screens refresh themselves constantly, and treating that as a human at the desk would make the control decorative. - Presence is measured across the whole origin, because the control's subject is an unattended machine, not an unattended tab. Work in one tab keeps its siblings alive; when every tab goes quiet they expire together, so no arrangement of tabs leaves a usable session on an abandoned screen. - The end of a session is announced across tabs. The *** id lives in each tab's sessionStorage over one shared Redis session, so a sibling that is never told keeps showing an authenticated workspace over a session that no longer exists. Both the automatic logoff and the ordinary /logout page now broadcast. Termination goes through the existing /logout page — SecurityService logout, Redis key deletion, cookie clearing, forward to kamo-login — because clearing client state alone leaves the server session alive and is not a logoff. Copy shipped ahead of this in kamo-translation-dictionary (c39dfb9).