summaryrefslogtreecommitdiffstats
path: root/internal/handler/websocket
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-13 20:38:59 -0800
committerbndw <ben@bdw.to>2026-02-13 20:38:59 -0800
commitdfa19ff0776be0850ad7b86ca579601431349593 (patch)
treeb56a3af23dda020bd6fd6709a7d1fc3c2d9f625f /internal/handler/websocket
parent89b8948195f24df127b7ae656ab3f60bd1b49ac7 (diff)
feat: implement NIP-09 with hard delete
Implement event deletion (NIP-09) using hard delete approach: - Kind 5 events trigger deletion but are not stored themselves - ProcessDeletion hard deletes referenced events (DELETE FROM events) - Only authors can delete their own events (pubkey verification) - Support multiple event IDs in single deletion request - No deletions table needed (simpler schema) - Added 4 deletion tests covering various scenarios - All 45 tests passing
Diffstat (limited to 'internal/handler/websocket')
-rw-r--r--internal/handler/websocket/handler.go11
1 files changed, 11 insertions, 0 deletions
diff --git a/internal/handler/websocket/handler.go b/internal/handler/websocket/handler.go
index 38d4fa6..224a2f8 100644
--- a/internal/handler/websocket/handler.go
+++ b/internal/handler/websocket/handler.go
@@ -17,6 +17,7 @@ import (
17type EventStore interface { 17type EventStore interface {
18 StoreEvent(context.Context, *storage.EventData) error 18 StoreEvent(context.Context, *storage.EventData) error
19 QueryEvents(context.Context, []*pb.Filter, *storage.QueryOptions) ([]*pb.Event, error) 19 QueryEvents(context.Context, []*pb.Filter, *storage.QueryOptions) ([]*pb.Event, error)
20 ProcessDeletion(context.Context, *pb.Event) error
20} 21}
21 22
22type Handler struct { 23type Handler struct {
@@ -115,6 +116,16 @@ func (h *Handler) handleEvent(ctx context.Context, conn *websocket.Conn, raw []j
115 pbEvent := NostrToPB(&event) 116 pbEvent := NostrToPB(&event)
116 canonicalJSON := event.Serialize() 117 canonicalJSON := event.Serialize()
117 118
119 // Handle deletion events (kind 5) - process but don't store
120 if pbEvent.Kind == 5 {
121 if err := h.store.ProcessDeletion(ctx, pbEvent); err != nil {
122 h.sendOK(ctx, conn, event.ID, false, fmt.Sprintf("deletion failed: %v", err))
123 return nil
124 }
125 h.sendOK(ctx, conn, event.ID, true, "deleted")
126 return nil
127 }
128
118 eventData := &storage.EventData{ 129 eventData := &storage.EventData{
119 Event: pbEvent, 130 Event: pbEvent,
120 CanonicalJSON: canonicalJSON, 131 CanonicalJSON: canonicalJSON,