feat: persistent session + logout button + auto-redirect for authenticated users

- Logout button added to dashboard and event page headers
- Landing page checks for valid session cookie → auto-redirects to dashboard
- Session cookie persists 24h — closing and reopening browser keeps login
This commit is contained in:
Claus Lohmar 2026-06-05 11:24:05 +00:00
parent aa07ff3c50
commit ce2efd9be7
3 changed files with 13 additions and 1 deletions

View file

@ -48,8 +48,16 @@ type AuthHandler struct {
// LandingPage renders the landing page with the email input form for OTP login.
// It parses templates/index.html and executes it with no template data.
func (h *AuthHandler) LandingPage(w http.ResponseWriter, r *http.Request) {
tmpl := getTemplate("index.html")
// If the user already has a valid session, redirect to the dashboard.
if cookie, err := r.Cookie("session_token"); err == nil && cookie.Value != "" {
if _, ok := h.Sessions.Get(cookie.Value); ok {
w.Header().Set("HX-Redirect", "/dashboard")
w.WriteHeader(http.StatusOK)
return
}
}
tmpl := getTemplate("index.html")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := tmpl.Execute(w, nil); err != nil {
log.Printf("ERROR [%s] handlers: LandingPage execute template: %v", time.Now().Format(time.RFC3339), err)

View file

@ -15,6 +15,8 @@
<div class="app-shell">
<header class="app-header">
<h1 class="app-title"><img src="/static/favicon.svg" width="24" height="24" alt="" style="vertical-align: middle; margin-right: 0.5rem;">ReceiptNext</h1>
<button class="btn btn-secondary btn-sm" style="font-size: 0.75rem;"
hx-post="/logout" hx-target="body" hx-push-url="true">Logout</button>
</header>
<main class="main-content">

View file

@ -17,6 +17,8 @@
<a href="/dashboard" class="btn btn-secondary btn-sm"
hx-get="/dashboard" hx-target="body" hx-push-url="true">&larr; Events</a>
<h1 class="app-title" style="font-size: 1.1rem;">{{.Event.Name}}</h1>
<button class="btn btn-secondary btn-sm" style="font-size: 0.75rem;"
hx-post="/logout" hx-target="body" hx-push-url="true">Logout</button>
</header>
<main class="main-content">