aboutsummaryrefslogtreecommitdiffstats
path: root/internal/handler
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-03-07 18:34:25 -0800
committerbndw <ben@bdw.to>2026-03-07 18:34:25 -0800
commit4522797a0cf378cc44485ed77a01dee9643b6ebe (patch)
treefaa7a1970885635df0cc49cbc4a1aef6fcbea5fa /internal/handler
parent5195d8031b7930069ba5441a6cd1e7a59c21c546 (diff)
Make allowed event kinds configurable
Replaces hardcoded kind allowlist in isAllowedKind with a configurable allowed_kinds list in relay config. Empty list allows all kinds. Default matches previous hardcoded list. Wired through SetAllowedKinds on the handler.
Diffstat (limited to 'internal/handler')
-rw-r--r--internal/handler/websocket/handler.go68
1 files changed, 27 insertions, 41 deletions
diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go
index b11171d..c64f3f9 100644
--- a/internal/handler/websocket/handler.go
+++ b/internal/handler/websocket/handler.go
@@ -64,14 +64,15 @@ type connState struct {
64} 64}
65 65
66type Handler struct { 66type Handler struct {
67 store EventStore 67 store EventStore
68 auth AuthStore 68 auth AuthStore
69 subs *subscription.Manager 69 subs *subscription.Manager
70 metrics MetricsRecorder 70 metrics MetricsRecorder
71 limiter RateLimiter 71 limiter RateLimiter
72 authConfig *AuthConfig 72 authConfig *AuthConfig
73 relayConfig *RelayInfoConfig 73 relayConfig *RelayInfoConfig
74 indexData IndexData 74 indexData IndexData
75 allowedKinds map[int32]bool // nil = allow all
75} 76}
76 77
77func NewHandler(store EventStore, subs *subscription.Manager) *Handler { 78func NewHandler(store EventStore, subs *subscription.Manager) *Handler {
@@ -81,6 +82,17 @@ func NewHandler(store EventStore, subs *subscription.Manager) *Handler {
81 } 82 }
82} 83}
83 84
85func (h *Handler) SetAllowedKinds(kinds []int32) {
86 if len(kinds) == 0 {
87 h.allowedKinds = nil // nil = allow all
88 return
89 }
90 h.allowedKinds = make(map[int32]bool, len(kinds))
91 for _, k := range kinds {
92 h.allowedKinds[k] = true
93 }
94}
95
84func (h *Handler) SetMetrics(m MetricsRecorder) { 96func (h *Handler) SetMetrics(m MetricsRecorder) {
85 h.metrics = m 97 h.metrics = m
86} 98}
@@ -325,8 +337,8 @@ func (h *Handler) handleEvent(ctx context.Context, conn *websocket.Conn, raw []j
325 pbEvent := NostrToPB(&event) 337 pbEvent := NostrToPB(&event)
326 canonicalJSON := event.Serialize() 338 canonicalJSON := event.Serialize()
327 339
328 // Reject non-core protocol kinds (spam, ephemeral, chat) 340 // Reject kinds not in the allowed list
329 if !isAllowedKind(pbEvent.Kind) { 341 if !h.isAllowedKind(pbEvent.Kind) {
330 status = "ok" 342 status = "ok"
331 if h.metrics != nil { 343 if h.metrics != nil {
332 h.metrics.RecordBlockedEvent(pbEvent.Kind) 344 h.metrics.RecordBlockedEvent(pbEvent.Kind)
@@ -623,37 +635,11 @@ func getClientIP(r *http.Request) string {
623 return r.RemoteAddr 635 return r.RemoteAddr
624} 636}
625 637
626// isAllowedKind returns true if the event kind is a core Nostr protocol kind. 638// isAllowedKind returns true if the event kind is permitted by the relay config.
627// Rejects spam, ephemeral events, live chat, and other non-essential kinds. 639// If no allowed kinds are configured, all kinds are accepted.
628func isAllowedKind(kind int32) bool { 640func (h *Handler) isAllowedKind(kind int32) bool {
629 // Core protocol kinds (NIP-01, NIP-02, etc.) 641 if h.allowedKinds == nil {
630 switch kind {
631 case 0: // Metadata/profile
632 return true
633 case 1: // Short text note
634 return true
635 case 3: // Contacts/following
636 return true
637 case 4: // Encrypted DM
638 return true
639 case 5: // Event deletion (handled separately)
640 return true 642 return true
641 case 6: // Repost
642 return true
643 case 7: // Reaction
644 return true
645 case 9735: // Zap
646 return true
647 case 10000, 10001, 10002: // Mute lists, pin lists (NIP-51)
648 return true
649 case 10050: // Relay list metadata
650 return true
651 case 30023: // Long-form content (NIP-23)
652 return true
653 case 30078: // Application-specific data (NIP-78)
654 return true
655 default:
656 // Reject everything else (chat, ephemeral, spam)
657 return false
658 } 643 }
644 return h.allowedKinds[kind]
659} 645}