From 583a3834f925e55275d69ab98dc5e30a5210428f Mon Sep 17 00:00:00 2001 From: sagitchu Date: Thu, 14 May 2026 01:24:03 +0800 Subject: [PATCH] fix: expire websocket admin sessions --- go-backend/internal/ws/server.go | 3 +++ go-backend/internal/ws/server_test.go | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/go-backend/internal/ws/server.go b/go-backend/internal/ws/server.go index abb84bb..82d5b2b 100644 --- a/go-backend/internal/ws/server.go +++ b/go-backend/internal/ws/server.go @@ -642,6 +642,9 @@ func (s *Server) validateAdminSession(userID int64, claims auth.Claims) bool { if s == nil { return false } + if claims.Exp <= time.Now().Unix() { + return false + } if s.getUserAuthState == nil { return true } diff --git a/go-backend/internal/ws/server_test.go b/go-backend/internal/ws/server_test.go index 51f902b..b1322ad 100644 --- a/go-backend/internal/ws/server_test.go +++ b/go-backend/internal/ws/server_test.go @@ -86,3 +86,25 @@ func TestValidateAdminSessionRejectsAuthStateChanges(t *testing.T) { }) } } + +func TestValidateAdminSessionRejectsExpiredToken(t *testing.T) { + secret := "unit-test-secret" + token, err := auth.GenerateToken(1, "admin_user", 0, secret) + if err != nil { + t.Fatalf("generate token: %v", err) + } + claims, err := auth.ParseClaims(token, secret) + if err != nil { + t.Fatalf("parse claims: %v", err) + } + claims.Exp = 1 + + server := NewServer(nil, secret) + server.SetUserAuthStateLookup(func(userID int64) (*auth.UserAuthState, error) { + return &auth.UserAuthState{ID: userID, RoleID: 0, Status: 1, PasswordChangedAt: 0}, nil + }) + + if ok := server.validateAdminSession(1, claims); ok { + t.Fatal("expected expired token to be rejected") + } +}