diff --git a/src/auth/session.go b/src/auth/session.go index fb8e130..4a9c9e4 100644 --- a/src/auth/session.go +++ b/src/auth/session.go @@ -64,6 +64,17 @@ func CreateSession(ctx context.Context, conn *pgxpool.Pool, username string) (*m return &session, nil } +// Deletes a session by id. If no session with that id exists, no +// error is returned. +func DeleteSession(ctx context.Context, conn *pgxpool.Pool, id string) error { + _, err := conn.Exec(ctx, "DELETE FROM sessions WHERE id = $1", id) + if err != nil { + return oops.New(err, "failed to delete session") + } + + return nil +} + func NewSessionCookie(session *models.Session) *http.Cookie { return &http.Cookie{ Name: SessionCookieName, @@ -77,3 +88,9 @@ func NewSessionCookie(session *models.Session) *http.Cookie { SameSite: http.SameSiteDefaultMode, } } + +var DeleteSessionCookie = &http.Cookie{ + Name: SessionCookieName, + Domain: config.Config.Auth.CookieDomain, + MaxAge: -1, +} diff --git a/src/templates/src/include/header.html b/src/templates/src/include/header.html index d4c295e..83677be 100644 --- a/src/templates/src/include/header.html +++ b/src/templates/src/include/header.html @@ -6,7 +6,7 @@ Admin {{ end }} {{ .User.Username }} - Logout + Logout {{ else }} Register Log in diff --git a/src/website/routes.go b/src/website/routes.go index 4201fd6..be500ca 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -38,6 +38,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { mainRoutes.GET("/assets/project.css", routes.ProjectCSS) routes.POST("/login", routes.Login) + routes.GET("/logout", routes.Logout) routes.ServeFiles("/public/*filepath", http.Dir("public")) @@ -197,6 +198,20 @@ func (s *websiteRoutes) Login(c *RequestContext, p httprouter.Params) { } } +func (s *websiteRoutes) Logout(c *RequestContext, p httprouter.Params) { + sessionCookie, err := c.Req.Cookie(auth.SessionCookieName) + if err == nil { + // clear the session from the db immediately, no expiration + err := auth.DeleteSession(c.Context(), s.conn, sessionCookie.Value) + if err != nil { + logging.Error().Err(err).Msg("failed to delete session on logout") + } + } + + c.SetCookie(auth.DeleteSessionCookie) + c.Redirect("/", http.StatusSeeOther) // TODO: Redirect to the page the user was currently on, or if not authorized to view that page, immediately to the home page. +} + func ErrorLoggingWrapper(h HMNHandler) HMNHandler { return func(c *RequestContext, p httprouter.Params) { h(c, p)