aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 07:01:40 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 07:01:40 -0800
commite31b68197ec16d2805ec14c2bf532a03f4739e92 (patch)
treebcda027df5c020ec6d12073ef1b132a6a14c2a86 /web
parentbd2508211760edbc1bad1d515587d08fd2ec99c9 (diff)
downloadneko-e31b68197ec16d2805ec14c2bf532a03f4739e92.tar.gz
neko-e31b68197ec16d2805ec14c2bf532a03f4739e92.tar.bz2
neko-e31b68197ec16d2805ec14c2bf532a03f4739e92.zip
Implement Frontend Logout with tests
Diffstat (limited to 'web')
-rw-r--r--web/web.go8
-rw-r--r--web/web_test.go26
2 files changed, 34 insertions, 0 deletions
diff --git a/web/web.go b/web/web.go
index ca5e2a2..10e9b2f 100644
--- a/web/web.go
+++ b/web/web.go
@@ -205,9 +205,17 @@ func Serve() {
http.HandleFunc("/login/", loginHandler)
http.HandleFunc("/logout/", logoutHandler)
http.HandleFunc("/api/login", apiLoginHandler)
+ http.HandleFunc("/api/logout", apiLogoutHandler)
http.HandleFunc("/api/auth", apiAuthStatusHandler)
http.HandleFunc("/", AuthWrap(indexHandler))
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(config.Config.Port), nil))
}
+
+func apiLogoutHandler(w http.ResponseWriter, r *http.Request) {
+ c := http.Cookie{Name: AuthCookie, Value: "", Path: "/", MaxAge: -1, HttpOnly: false}
+ http.SetCookie(w, &c)
+ w.Header().Set("Content-Type", "application/json")
+ fmt.Fprintf(w, `{"status":"ok"}`)
+}
diff --git a/web/web_test.go b/web/web_test.go
index a73a6c9..156bbef 100644
--- a/web/web_test.go
+++ b/web/web_test.go
@@ -356,6 +356,32 @@ func TestApiAuthStatusHandlerAuthenticated(t *testing.T) {
if body != `{"status":"ok", "authenticated":true}` {
t.Errorf("Expected authenticated true, got %q", body)
}
+
+ // Test Logout
+ req, _ = http.NewRequest("POST", "/api/logout", nil)
+ rr = httptest.NewRecorder()
+ handler := http.HandlerFunc(apiLogoutHandler)
+ handler.ServeHTTP(rr, req)
+
+ if status := rr.Code; status != http.StatusOK {
+ t.Errorf("logout handler returned wrong status code: got %v want %v",
+ status, http.StatusOK)
+ }
+
+ // Verify cookie is cleared
+ cookies := rr.Result().Cookies()
+ found := false
+ for _, c := range cookies {
+ if c.Name == AuthCookie {
+ found = true
+ if c.MaxAge != -1 {
+ t.Errorf("auth cookie not expired: got MaxAge %v want -1", c.MaxAge)
+ }
+ }
+ }
+ if !found {
+ t.Errorf("auth cookie not found in response")
+ }
}
func TestApiAuthStatusHandlerUnauthenticated(t *testing.T) {