diff options
| author | bndw <ben@bdw.to> | 2026-02-15 10:26:10 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-15 10:26:10 -0800 |
| commit | 57bc300fe26812aad568c8119f04d92e94c9ab14 (patch) | |
| tree | 2ec71cfc86b4a950f5435c3b8a0e5b0b4f847773 /internal/handler/websocket | |
| parent | a6ee0e3f268f9a847bf8a19159cf291021a0f38e (diff) | |
fix: record AUTH attempt metrics in WebSocket handler
Add RecordAuthAttempt calls to handleAuth so successful and failed
AUTH attempts are tracked in metrics. This fixes the dashboard
'Challenges' counter which was always showing 0.
The deferred call ensures both success and failure cases are recorded:
- success=true when AUTH completes successfully
- success=false when AUTH fails (invalid signature, wrong challenge, etc.)
Updated MetricsRecorder interface and mock to include RecordAuthAttempt.
Diffstat (limited to 'internal/handler/websocket')
| -rw-r--r-- | internal/handler/websocket/handler.go | 9 | ||||
| -rw-r--r-- | internal/handler/websocket/handler_test.go | 1 |
2 files changed, 10 insertions, 0 deletions
diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go index de71926..dfe7b9e 100644 --- a/internal/handler/websocket/handler.go +++ b/internal/handler/websocket/handler.go | |||
| @@ -33,6 +33,7 @@ type MetricsRecorder interface { | |||
| 33 | DecrementSubscriptions() | 33 | DecrementSubscriptions() |
| 34 | SetActiveSubscriptions(count int) | 34 | SetActiveSubscriptions(count int) |
| 35 | RecordRequest(method, status string, duration float64) | 35 | RecordRequest(method, status string, duration float64) |
| 36 | RecordAuthAttempt(success bool) | ||
| 36 | RecordBlockedEvent(kind int32) | 37 | RecordBlockedEvent(kind int32) |
| 37 | } | 38 | } |
| 38 | 39 | ||
| @@ -522,6 +523,13 @@ func (h *Handler) sendAuthChallenge(ctx context.Context, conn *websocket.Conn, c | |||
| 522 | } | 523 | } |
| 523 | 524 | ||
| 524 | func (h *Handler) handleAuth(ctx context.Context, conn *websocket.Conn, raw []json.RawMessage, state *connState) error { | 525 | func (h *Handler) handleAuth(ctx context.Context, conn *websocket.Conn, raw []json.RawMessage, state *connState) error { |
| 526 | success := false | ||
| 527 | defer func() { | ||
| 528 | if h.metrics != nil { | ||
| 529 | h.metrics.RecordAuthAttempt(success) | ||
| 530 | } | ||
| 531 | }() | ||
| 532 | |||
| 525 | if len(raw) != 2 { | 533 | if len(raw) != 2 { |
| 526 | return fmt.Errorf("AUTH expects 2 elements") | 534 | return fmt.Errorf("AUTH expects 2 elements") |
| 527 | } | 535 | } |
| @@ -560,6 +568,7 @@ func (h *Handler) handleAuth(ctx context.Context, conn *websocket.Conn, raw []js | |||
| 560 | state.authenticatedPubkey = authEvent.PubKey | 568 | state.authenticatedPubkey = authEvent.PubKey |
| 561 | log.Printf("WebSocket client authenticated: %s", authEvent.PubKey[:16]) | 569 | log.Printf("WebSocket client authenticated: %s", authEvent.PubKey[:16]) |
| 562 | 570 | ||
| 571 | success = true | ||
| 563 | // Don't send OK for AUTH - it's not an EVENT | 572 | // Don't send OK for AUTH - it's not an EVENT |
| 564 | return nil | 573 | return nil |
| 565 | } | 574 | } |
diff --git a/internal/handler/websocket/handler_test.go b/internal/handler/websocket/handler_test.go index 9982aea..10405b2 100644 --- a/internal/handler/websocket/handler_test.go +++ b/internal/handler/websocket/handler_test.go | |||
| @@ -97,6 +97,7 @@ func (m *mockMetrics) RecordRequest(method, status string, duration float64) { | |||
| 97 | key := fmt.Sprintf("%s:%s", method, status) | 97 | key := fmt.Sprintf("%s:%s", method, status) |
| 98 | m.requests[key]++ | 98 | m.requests[key]++ |
| 99 | } | 99 | } |
| 100 | func (m *mockMetrics) RecordAuthAttempt(success bool) {} | ||
| 100 | func (m *mockMetrics) RecordBlockedEvent(kind int32) { | 101 | func (m *mockMetrics) RecordBlockedEvent(kind int32) { |
| 101 | m.mu.Lock() | 102 | m.mu.Lock() |
| 102 | defer m.mu.Unlock() | 103 | defer m.mu.Unlock() |
