package auth import ( "context" "net/http" "github.com/danielgtaylor/huma/v2" ) type LogoutInput struct { SessionID string `cookie:"nadir_session_id"` } type LogoutOutput struct { SetCookie http.Cookie `header:"Set-Cookie"` Body struct { Status string `json:"status" example:"logged out"` } } // RegisterLogout wires the logout operation. Like login it carries no permission // metadata, so the RBAC middleware lets it through: it deletes whatever session // the cookie names (a no-op for an unknown/expired token) and clears the cookie. func RegisterLogout(api huma.API, sessions *SessionStore, secure bool) { huma.Register(api, huma.Operation{ OperationID: "logout", Method: "POST", Path: "/api/logout", Summary: "End the current session", Description: "Invalidates the session named by the cookie and clears it. " + "Always succeeds, even without a valid session.", Tags: []string{"Authentication"}, }, func(ctx context.Context, in *LogoutInput) (*LogoutOutput, error) { if in.SessionID != "" { if err := sessions.Delete(in.SessionID); err != nil { return nil, huma.Error500InternalServerError("could not end session", err) } } out := &LogoutOutput{ SetCookie: http.Cookie{ Name: "nadir_session_id", Value: "", Path: "/", HttpOnly: true, Secure: secure, SameSite: http.SameSiteStrictMode, MaxAge: -1, // delete the cookie now }, } out.Body.Status = "logged out" return out, nil }) }