fix: Phase 1 - security & stability patches
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

- AuthMiddleware now requires auth on /v1/* routes (returns 401)
- WebSocket origin check configurable via WSAllowedOrigin
- Removed debug fmt.Printf leaks (config, ollama, server)
- Registry access protected by sync.RWMutex (race condition fix)
- Session cleanup goroutine runs every 15 min
- RevokeSession returns error instead of silent no-op
This commit is contained in:
2026-04-26 14:45:22 -04:00
parent da074f52b4
commit 8a8d8d1477
13 changed files with 448 additions and 105 deletions
+23 -5
View File
@@ -79,7 +79,7 @@ func (m *SessionManager) createSignedToken(sessionID, username, displayName, rol
}
payloadB64 := base64.RawURLEncoding.EncodeToString(payloadJSON)
h := hmac.New(sha256.New, m.secret)
h.Write(payloadJSON)
signature := h.Sum(nil)
@@ -133,23 +133,41 @@ func (m *SessionManager) ValidateSession(token string) (*Session, string, error)
return &session, "", nil
}
func (m *SessionManager) RevokeSession(token string) {
func (m *SessionManager) RevokeSession(token string) error {
parts := strings.Split(token, ".")
if len(parts) != 2 {
return
return fmt.Errorf("invalid token format")
}
payloadJSON, err := base64.RawURLEncoding.DecodeString(parts[0])
if err != nil {
return
return fmt.Errorf("failed to decode payload: %w", err)
}
var payload sessionPayload
if err := json.Unmarshal(payloadJSON, &payload); err != nil {
return
return fmt.Errorf("failed to parse payload: %w", err)
}
m.mu.Lock()
delete(m.sessions, payload.SessionID)
m.mu.Unlock()
return nil
}
// StartCleanup runs a background goroutine that removes expired sessions every 15 minutes.
func (m *SessionManager) StartCleanup() {
go func() {
ticker := time.NewTicker(15 * time.Minute)
for range ticker.C {
m.mu.Lock()
now := time.Now()
for id, s := range m.sessions {
if now.After(s.ExpiresAt) {
delete(m.sessions, id)
}
}
m.mu.Unlock()
}
}()
}