diff options
| author | bndw <ben@bdw.to> | 2026-02-13 20:38:59 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-13 20:38:59 -0800 |
| commit | dfa19ff0776be0850ad7b86ca579601431349593 (patch) | |
| tree | b56a3af23dda020bd6fd6709a7d1fc3c2d9f625f /internal/handler/websocket | |
| parent | 89b8948195f24df127b7ae656ab3f60bd1b49ac7 (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.go | 11 |
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 ( | |||
| 17 | type EventStore interface { | 17 | type 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 | ||
| 22 | type Handler struct { | 23 | type 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, |
