From 0abb475d2a0a3b4cd670e710591e2cf4c58e9dc0 Mon Sep 17 00:00:00 2001 From: highperfocused Date: Sun, 4 Jan 2026 16:56:17 +0100 Subject: [PATCH] nip17-RejectNonAuthenticatedGiftWrapQueries --- main.go | 17 +---------------- nip17.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 nip17.go diff --git a/main.go b/main.go index ce61490..cd26fc8 100644 --- a/main.go +++ b/main.go @@ -119,22 +119,7 @@ func main() { // }, // ) - // // you can request auth by rejecting an event or a request with the prefix "auth-required: " - // relay.RejectFilter = append(relay.RejectFilter, - // // built-in policies - // policies.NoComplexFilters, - - // // define your own policies - // func(ctx context.Context, filter nostr.Filter) (reject bool, msg string) { - // if pubkey := khatru.GetAuthed(ctx); pubkey != "" { - // log.Printf("request from %s\n", pubkey) - // return false, "" - // } - // return true, "auth-required: only authenticated users can read from this relay" - // // (this will cause an AUTH message to be sent and then a CLOSED message such that clients can - // // authenticate and then request again) - // }, - // ) + relay.RejectFilter = append(relay.RejectFilter, RejectNonAuthenticatedGiftWrapQueries) // management endpoints relay.ManagementAPI.RejectAPICall = append(relay.ManagementAPI.RejectAPICall, diff --git a/nip17.go b/nip17.go new file mode 100644 index 0000000..1a85158 --- /dev/null +++ b/nip17.go @@ -0,0 +1,57 @@ +package main + +import ( + "context" + + "github.com/fiatjaf/khatru" + "github.com/nbd-wtf/go-nostr" +) + +// RejectNonAuthenticatedGiftWrapQueries implements NIP-17 metadata protection +// by requiring authentication for kind 1059 (gift wrap) queries and restricting +// results to only show events intended for the authenticated user. +func RejectNonAuthenticatedGiftWrapQueries(ctx context.Context, filter nostr.Filter) (reject bool, msg string) { + // Check if filter includes kind 1059 (gift wrap events) + isGiftWrapQuery := false + for _, kind := range filter.Kinds { + if kind == 1059 { + isGiftWrapQuery = true + break + } + } + + if !isGiftWrapQuery { + return false, "" // not a gift wrap query, allow + } + + // Require authentication for gift wrap queries + pubkey := khatru.GetAuthed(ctx) + if pubkey == "" { + return true, "auth-required: authentication required to query direct messages" + } + + // Only allow querying gift wraps addressed to the authenticated user + // Check if the filter already restricts by recipient pubkey + hasRecipientFilter := false + for _, tag := range filter.Tags { + if len(tag) > 0 && tag[0] == "p" { + // Check if authenticated user is in the p tags + for i := 1; i < len(tag); i++ { + if tag[i] == pubkey { + hasRecipientFilter = true + break + } + } + } + } + + if !hasRecipientFilter { + // Force the filter to only include events where the authenticated user is the recipient + if filter.Tags == nil { + filter.Tags = make(nostr.TagMap) + } + filter.Tags["p"] = []string{pubkey} + } + + return false, "" +}