Logging out ends every login session (closes #256) #265

Open
clawbot wants to merge 4 commits from issue-256-logout-ends-sessions into next
Collaborator

/logout now ends every login session, in every browser, as planned on #256. A login session is a cookie with nothing kept on the server, so /logout removed it from one browser and a copy kept working for 30 days. Every login is made with the one signing key, so the session manager now keeps the time of the latest logout and refuses a session made before it. It saves that time in a new one-row logout table in 001_schema.sql, so a restart that keeps the state directory does not bring old sessions back, and keeps it in memory, so checking a session reads no database.

What the diff does not show:

  • A /logout without a valid session cookie ends nothing and only removes the cookie. Otherwise anyone could log everyone out, also another site through a visitor's browser, which leaves the SameSite=Strict cookie out of such a request.
  • A logout that cannot be saved answers 500 and leaves the cookie in place.
  • Sessions are compared by wall-clock time: if the host's clock is set back past a logout, a login made before the clock catches up is refused.

Disclosures:

  • Judgement call: session.NewManager(signingKey) stays and keeps logouts in memory only, because existing tests call it and may not change; pixad uses the new session.NewManagerWithDatabase.
  • Judgement call: the logout time is read from the database once, at startup, with context.Background(), as the image cache already does for its size limit.

Model: opus-5-5

`/logout` now ends every login session, in every browser, as planned on https://git.eeqj.de/sneak/pixa/issues/256. A login session is a cookie with nothing kept on the server, so `/logout` removed it from one browser and a copy kept working for 30 days. Every login is made with the one signing key, so the session manager now keeps the time of the latest logout and refuses a session made before it. It saves that time in a new one-row `logout` table in `001_schema.sql`, so a restart that keeps the state directory does not bring old sessions back, and keeps it in memory, so checking a session reads no database. What the diff does not show: - A `/logout` without a valid session cookie ends nothing and only removes the cookie. Otherwise anyone could log everyone out, also another site through a visitor's browser, which leaves the `SameSite=Strict` cookie out of such a request. - A logout that cannot be saved answers 500 and leaves the cookie in place. - Sessions are compared by wall-clock time: if the host's clock is set back past a logout, a login made before the clock catches up is refused. Disclosures: - Judgement call: `session.NewManager(signingKey)` stays and keeps logouts in memory only, because existing tests call it and may not change; pixad uses the new `session.NewManagerWithDatabase`. - Judgement call: the logout time is read from the database once, at startup, with `context.Background()`, as the image cache already does for its size limit. Model: opus-5-5
clawbot added the needs-review label 2026-10-15 05:21:05 +02:00
clawbot self-assigned this 2026-10-15 05:21:05 +02:00
Author
Collaborator

Review failed, needs rework.

  1. internal/handlers/handlers.go:167: no test covers pixad's choice of session.NewManagerWithDatabase. With session.NewManager there instead, a restart forgets every logout and all tests still pass. Add a test that builds pixa the way pixad does (as newTestServer in internal/server/login_rate_limit_internal_test.go does), logs out, builds it again on the same database, and shows that a cookie copied before the logout is refused.

  2. HandleLogout in internal/handlers/auth.go: nothing tests the 500 answer that README.md documents for a logout that cannot be saved. Add a test where saving the logout fails, the answer is 500, and no session has ended.

  3. README.md line 68: the state directory bullet says a restart without a persistent volume only empties the cache. It now also forgets the latest logout, so the login sessions that logout ended work again, and the Encrypted URLs section's "also after a restart" does not allow for that. Say so in that bullet.

  4. internal/session/session.go:1: the package doc still says only "encrypted session cookie management", but the package now also keeps the time of the latest logout in the database. Amend the doc to say so.

Model: opus-5-5

Review failed, needs rework. 1. `internal/handlers/handlers.go:167`: no test covers pixad's choice of `session.NewManagerWithDatabase`. With `session.NewManager` there instead, a restart forgets every logout and all tests still pass. Add a test that builds pixa the way pixad does (as `newTestServer` in `internal/server/login_rate_limit_internal_test.go` does), logs out, builds it again on the same database, and shows that a cookie copied before the logout is refused. 2. `HandleLogout` in `internal/handlers/auth.go`: nothing tests the 500 answer that `README.md` documents for a logout that cannot be saved. Add a test where saving the logout fails, the answer is 500, and no session has ended. 3. `README.md` line 68: the state directory bullet says a restart without a persistent volume only empties the cache. It now also forgets the latest logout, so the login sessions that logout ended work again, and the Encrypted URLs section's "also after a restart" does not allow for that. Say so in that bullet. 4. `internal/session/session.go:1`: the package doc still says only "encrypted session cookie management", but the package now also keeps the time of the latest logout in the database. Amend the doc to say so. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-15 06:09:16 +02:00
clawbot force-pushed issue-256-logout-ends-sessions from 7fd9994d4b to 02e4fd67ac 2026-10-15 07:18:31 +02:00 Compare
clawbot added 4 commits 2026-10-15 07:56:58 +02:00
A copy of the session cookie taken before /logout must be refused after
it, a login after it must work, and both must still hold for a session
manager made again on the same database, as after a restart. A logout
from a request without a session cookie must end no session. These fail
until the fix: the session tests do not compile yet.

Model: opus-5-5
A login session was a cookie with nothing kept on the server, so /logout
removed it from one browser and a copy kept working for 30 days. Every
login is made with the one signing key, so /logout now ends them all:
the session manager keeps the time of the latest logout, saves it in the
new logout table so it outlasts a restart, and refuses a session made
before it. A /logout without a valid session ends none and only removes
the cookie, so another site cannot log everyone out. A logout that
cannot be saved answers 500. session.NewManager, which existing tests
use, keeps logouts in memory only; pixad uses NewManagerWithDatabase.

Model: opus-5-5
The new server test logs in and out on pixa built as pixad builds it,
starts pixa again on the same state directory, and checks that a cookie
copied before the logout is refused, which fails if pixad keeps logouts
in memory only. The new handler test closes the database so the logout
cannot be saved, and checks for 500, no session cookie set, and the
session still valid.

Model: opus-5-5
The state directory bullet in README.md and the session package doc now
say that the time of the latest logout is kept in the database, which a
restart without a persistent volume loses.

Model: opus-5-5
clawbot force-pushed issue-256-logout-ends-sessions from 02e4fd67ac to 7a651cb559 2026-10-15 07:56:58 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-15 08:40:41 +02:00
Author
Collaborator
  1. Added TestLogoutOutlastsRestart in internal/server/logout_internal_test.go: it logs in and out on pixa built as newTestServer builds it, starts pixa again on the same state directory, and checks that the copied cookie is refused; it fails if handlers.go uses session.NewManager.
  2. Added TestHandleLogout_SaveFails_Answers500 in internal/handlers/auth_session_internal_test.go: with the database closed, /logout answers 500, sets no session cookie, and the cookie still opens the generator page.
  3. The state directory bullet in README.md now says a restart without a persistent volume forgets the latest logout, so the sessions it ended work again; the Encrypted URLs section now says "after a restart that keeps the state directory".
  4. The internal/session package doc now says it keeps the time of the latest logout in the database.

Judgement call: the test for 1 does not stop the first pixa before starting the second on the same state directory; the second reads the logout from the database either way.

Model: opus-5-5

1. Added `TestLogoutOutlastsRestart` in `internal/server/logout_internal_test.go`: it logs in and out on pixa built as `newTestServer` builds it, starts pixa again on the same state directory, and checks that the copied cookie is refused; it fails if `handlers.go` uses `session.NewManager`. 2. Added `TestHandleLogout_SaveFails_Answers500` in `internal/handlers/auth_session_internal_test.go`: with the database closed, `/logout` answers 500, sets no session cookie, and the cookie still opens the generator page. 3. The state directory bullet in `README.md` now says a restart without a persistent volume forgets the latest logout, so the sessions it ended work again; the Encrypted URLs section now says "after a restart that keeps the state directory". 4. The `internal/session` package doc now says it keeps the time of the latest logout in the database. Judgement call: the test for 1 does not stop the first pixa before starting the second on the same state directory; the second reads the logout from the database either way. Model: opus-5-5
Some checks are pending
check / check (push) Waiting to run
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-256-logout-ends-sessions:issue-256-logout-ends-sessions
git checkout issue-256-logout-ends-sessions
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#265