auth: clear session cookie under both host-only and parent-domain scope

Logout emitted a single Set-Cookie scoped to the configured cookie domain
(parodia.dev). A browser holding the session under the older host-only scope
(news.parodia.dev, from before the cookie domain widened for the games site)
was never cleared, so logout looked like a no-op and stranded the user on a
stale session logout couldn't reach. Clear both scopes.

Also surface the who-page owner unlock's previously-silent misses: a genuine
lookup/decode error, and a signed-in session that carries no username. Both
used to fail with err discarded and no log, making a stuck owner undiagnosable.
This commit is contained in:
prosolis
2026-07-17 18:57:01 -07:00
parent 9d9cfd9f9a
commit 1159e64505
3 changed files with 77 additions and 4 deletions
+12 -1
View File
@@ -221,7 +221,18 @@ func (s *Server) handleAdventureWho(w http.ResponseWriter, r *http.Request) {
// reversing the token, so no visitor can unlock another player's self extras.
if s.auth != nil {
if u := s.auth.userFromRequest(r); u != nil {
if self, ok, err := storage.PlayerDetailByOwner(buyerLocalpart(u), token); err == nil && ok {
// A signed-in visitor viewing someone else's page legitimately fails the
// ownership join (ok=false), so that alone is not worth a log. Two other
// misses are: a genuine lookup/decode error, and a session that carries no
// username (minted before the game economy existed) — for the latter the
// join can never match because buyerLocalpart is empty. Both used to fail
// silently here; surface them so a stuck owner is diagnosable.
lp := buyerLocalpart(u)
if lp == "" {
slog.Warn("who: signed-in session has no username; owner unlock skipped", "sub", u.Sub)
} else if self, ok, err := storage.PlayerDetailByOwner(lp, token); err != nil {
slog.Error("who: owner detail lookup failed", "localpart", lp, "token", token, "err", err)
} else if ok {
page.HasSelf = true
page.Self = self
page.Worn = itemRows(self.Equipped, "worn")