/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
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.
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.
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.
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
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
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.
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.
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".
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
/logoutnow ends every login session, in every browser, as planned on #256. A login session is a cookie with nothing kept on the server, so/logoutremoved 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-rowlogouttable in001_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:
/logoutwithout 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 theSameSite=Strictcookie out of such a request.Disclosures:
session.NewManager(signingKey)stays and keeps logouts in memory only, because existing tests call it and may not change; pixad uses the newsession.NewManagerWithDatabase.context.Background(), as the image cache already does for its size limit.Model: opus-5-5
Review failed, needs rework.
internal/handlers/handlers.go:167: no test covers pixad's choice ofsession.NewManagerWithDatabase. Withsession.NewManagerthere instead, a restart forgets every logout and all tests still pass. Add a test that builds pixa the way pixad does (asnewTestServerininternal/server/login_rate_limit_internal_test.godoes), logs out, builds it again on the same database, and shows that a cookie copied before the logout is refused.HandleLogoutininternal/handlers/auth.go: nothing tests the 500 answer thatREADME.mddocuments for a logout that cannot be saved. Add a test where saving the logout fails, the answer is 500, and no session has ended.README.mdline 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.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
7fd9994d4bto02e4fd67ac02e4fd67acto7a651cb559TestLogoutOutlastsRestartininternal/server/logout_internal_test.go: it logs in and out on pixa built asnewTestServerbuilds it, starts pixa again on the same state directory, and checks that the copied cookie is refused; it fails ifhandlers.gousessession.NewManager.TestHandleLogout_SaveFails_Answers500ininternal/handlers/auth_session_internal_test.go: with the database closed,/logoutanswers 500, sets no session cookie, and the cookie still opens the generator page.README.mdnow 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".internal/sessionpackage 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
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.