summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-15 10:22:32 -0800
committerbndw <ben@bdw.to>2026-02-15 10:22:32 -0800
commite26729f658739b368073b558eb909af137609dfa (patch)
tree3e574bf390235d16af78d1c902d1c349f4400ca8
parent16a38f97183e4cbaf95c510c85d61f5a45873f4b (diff)
feat: track auth rejections with specific 'unauthorized' status
Auth failures (pubkey not in allowlist) are now tracked with status 'unauthorized' instead of generic 'error' in metrics. This allows monitoring of auth rejections separately from other errors. Metrics will now show: - muxstr_relay_requests_total{status="unauthorized"} - auth failures - muxstr_relay_requests_total{status="unauthenticated"} - no auth yet - muxstr_relay_requests_total{status="error"} - other errors - muxstr_relay_requests_total{status="rate_limited"} - rate limited - muxstr_relay_requests_total{status="ok"} - success Added test assertion to verify metrics tracking.
-rw-r--r--internal/handler/websocket/handler.go4
-rw-r--r--internal/handler/websocket/handler_test.go7
2 files changed, 9 insertions, 2 deletions
diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go
index a23dd60..de71926 100644
--- a/internal/handler/websocket/handler.go
+++ b/internal/handler/websocket/handler.go
@@ -265,7 +265,7 @@ func (h *Handler) handleEvent(ctx context.Context, conn *websocket.Conn, raw []j
265 } 265 }
266 266
267 if err := h.requireAuth(ctx, conn, true, state); err != nil { 267 if err := h.requireAuth(ctx, conn, true, state); err != nil {
268 status = "error" 268 status = "unauthorized"
269 h.sendOK(ctx, conn, event.ID, false, err.Error()) 269 h.sendOK(ctx, conn, event.ID, false, err.Error())
270 return nil 270 return nil
271 } 271 }
@@ -371,7 +371,7 @@ func (h *Handler) handleReq(ctx context.Context, conn *websocket.Conn, raw []jso
371 } 371 }
372 372
373 if err := h.requireAuth(ctx, conn, false, state); err != nil { 373 if err := h.requireAuth(ctx, conn, false, state); err != nil {
374 status = "error" 374 status = "unauthorized"
375 return err 375 return err
376 } 376 }
377 377
diff --git a/internal/handler/websocket/handler_test.go b/internal/handler/websocket/handler_test.go
index 9f02510..9982aea 100644
--- a/internal/handler/websocket/handler_test.go
+++ b/internal/handler/websocket/handler_test.go
@@ -368,6 +368,13 @@ func TestAuthNotInAllowlist(t *testing.T) {
368 t.Errorf("Expected OK false for unauthorized pubkey, got false: %v", msg3[3]) 368 t.Errorf("Expected OK false for unauthorized pubkey, got false: %v", msg3[3])
369 } 369 }
370 t.Logf("Unauthorized pubkey correctly rejected: %v", msg3[3]) 370 t.Logf("Unauthorized pubkey correctly rejected: %v", msg3[3])
371
372 // Verify metrics tracked the unauthorized request
373 unauthorizedCount := ts.metrics.getRequestCount("EVENT", "unauthorized")
374 if unauthorizedCount == 0 {
375 t.Errorf("Expected unauthorized requests to be tracked in metrics, got 0")
376 }
377 t.Logf("Metrics: %d unauthorized requests tracked", unauthorizedCount)
371} 378}
372 379
373// TestRateLimitByIP verifies that rate limiting works by IP 380// TestRateLimitByIP verifies that rate limiting works by IP