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
+15 -3
View File
@@ -195,11 +195,23 @@ func (a *Authenticator) setCookie(w http.ResponseWriter, name, value string, ttl
}
func (a *Authenticator) clearCookie(w http.ResponseWriter, name string) {
http.SetCookie(w, &http.Cookie{
// A cookie delete only lands when its Domain matches the one the cookie was
// set with. The session cookie's scope has changed over Pete's life: host-only
// before the games site, then widened to the parent domain so news and games
// could share one login. A browser may still hold it under the older scope, and
// a clear under only the current scope leaves the other in place — a stranded
// cookie that keeps someone signed in with a session logout can't reach. So
// clear both: always host-only, plus the parent domain when one is configured.
base := http.Cookie{
Name: name, Value: "", Path: "/", MaxAge: -1,
Domain: a.cookieDomain(name),
HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode,
})
}
http.SetCookie(w, &base) // host-only (no Domain attribute)
if d := a.cookieDomain(name); d != "" {
scoped := base
scoped.Domain = d
http.SetCookie(w, &scoped) // parent-domain scope
}
}
// oauthFor returns the OAuth config to use for this request. The configured