feat(webui): implement logout process

This commit is contained in:
Julien Dessaux 2025-01-13 10:11:20 +01:00
parent aef0b00fb9
commit 1292d189cf
Signed by: adyxax
GPG key ID: F92E51B86E07177E
5 changed files with 52 additions and 10 deletions

View file

@ -27,6 +27,14 @@ func (db *DB) CreateSession(account *model.Account) (string, error) {
return sessionId.String(), nil return sessionId.String(), nil
} }
func (db *DB) DeleteSession(session *model.Session) error {
_, err := db.Exec(`DELETE FROM sessions WHERE id = ?`, session.Id)
if err != nil {
return fmt.Errorf("failed to delete session %s: %w", session.Id, err)
}
return nil
}
func (db *DB) LoadSessionById(id string) (*model.Session, error) { func (db *DB) LoadSessionById(id string) (*model.Session, error) {
session := model.Session{ session := model.Session{
Id: id, Id: id,

View file

@ -0,0 +1,5 @@
{{ define "main" }}
<article>
<p>Logout successful</p>
</article>
{{ end }}

24
pkg/webui/logout.go Normal file
View file

@ -0,0 +1,24 @@
package webui
import (
"html/template"
"net/http"
"git.adyxax.org/adyxax/tfstated/pkg/database"
"git.adyxax.org/adyxax/tfstated/pkg/model"
)
var logoutTemplate = template.Must(template.ParseFS(htmlFS, "html/base.html", "html/logout.html"))
func handleLogoutGET(db *database.DB) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value(model.SessionContextKey{})
err := db.DeleteSession(session.(*model.Session))
if err != nil {
errorResponse(w, http.StatusInternalServerError, err)
return
}
unsetSesssionCookie(w)
render(w, logoutTemplate, http.StatusOK, nil)
})
}

View file

@ -15,6 +15,7 @@ func addRoutes(
mux.Handle("GET /healthz", handleHealthz()) mux.Handle("GET /healthz", handleHealthz())
mux.Handle("GET /login", session(handleLoginGET())) mux.Handle("GET /login", session(handleLoginGET()))
mux.Handle("POST /login", session(handleLoginPOST(db))) mux.Handle("POST /login", session(handleLoginPOST(db)))
mux.Handle("GET /logout", session(requireLogin(handleLogoutGET(db))))
mux.Handle("GET /static/", cache(http.FileServer(http.FS(staticFS)))) mux.Handle("GET /static/", cache(http.FileServer(http.FS(staticFS))))
mux.Handle("GET /", session(requireLogin(handleIndexGET()))) mux.Handle("GET /", session(requireLogin(handleIndexGET())))
} }

View file

@ -22,16 +22,7 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler {
} }
if err == nil { if err == nil {
if len(cookie.Value) != 36 { if len(cookie.Value) != 36 {
http.SetCookie(w, &http.Cookie{ unsetSesssionCookie(w)
Name: cookieName,
Value: "",
Quoted: false,
Path: "/",
MaxAge: 0, // remove invalid cookie
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Secure: true,
})
} else { } else {
session, err := db.LoadSessionById(cookie.Value) session, err := db.LoadSessionById(cookie.Value)
if err != nil { if err != nil {
@ -53,3 +44,16 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler {
}) })
} }
} }
func unsetSesssionCookie(w http.ResponseWriter) {
http.SetCookie(w, &http.Cookie{
Name: cookieName,
Value: "",
Quoted: false,
Path: "/",
MaxAge: 0, // remove invalid cookie
HttpOnly: true,
SameSite: http.SameSiteStrictMode,
Secure: true,
})
}