khatru: fix policy that requires nostr-prefix references.

This commit is contained in:
fiatjaf
2025-09-15 08:27:29 -03:00
parent e8456dab70
commit 805003b39b
4 changed files with 51 additions and 26 deletions

5
go.mod
View File

@@ -40,7 +40,7 @@ require (
gopkg.in/yaml.v3 v3.0.1
)
require github.com/dgraph-io/ristretto v0.2.0
require github.com/dgraph-io/ristretto/v2 v2.3.0
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
@@ -64,8 +64,6 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
github.com/dgraph-io/ristretto/v2 v2.3.0 // indirect
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
@@ -80,7 +78,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect

4
go.sum
View File

@@ -110,8 +110,6 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgraph-io/ristretto/v2 v2.3.0 h1:qTQ38m7oIyd4GAed/QkUZyPFNMnvVWyazGXRwvOt5zk=
github.com/dgraph-io/ristretto/v2 v2.3.0/go.mod h1:gpoRV3VzrEY1a9dWAYV6T1U7YzfgttXdd/ZzL1s9OZM=
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
@@ -311,8 +309,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -10,7 +10,9 @@ import (
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/nip19"
"fiatjaf.com/nostr/nip27"
"fiatjaf.com/nostr/nip70"
"fiatjaf.com/nostr/sdk"
)
// PreventTooManyIndexableTags returns a function that can be used as a RejectFilter that will reject
@@ -114,26 +116,31 @@ func OnlyAllowNIP70ProtectedEvents(ctx context.Context, event nostr.Event) (reje
return true, "blocked: we only accept events protected with the nip70 \"-\" tag"
}
var nostrReferencesPrefix = regexp.MustCompile(`\b(nevent1|npub1|nprofile1|note1)\w*\b`)
func RejectUnprefixedNostrReferences(ctx context.Context, event nostr.Event) (bool, string) {
pattern := `\b(nevent1|npub1|nprofile1|note1)\w*\b`
re, err := regexp.Compile(pattern)
if err != nil {
// if regex error, allow
return false, ""
}
matches := re.FindAllStringIndex(event.Content, -1)
for _, match := range matches {
start := match[0]
end := match[1]
ref := event.Content[start:end]
_, _, err := nip19.Decode(ref)
if err != nil {
// invalid reference, ignore and allow
continue
}
if start < 6 || event.Content[start-6:start] != "nostr:" {
return true, "references must be prefixed with \"nostr:\""
content := sdk.GetMainContent(event)
// only do it for stuff that wasn't parsed as blocks already
// (since those are already good references or URLs)
for block := range nip27.Parse(content) {
if block.Pointer == nil {
matches := nostrReferencesPrefix.FindAllStringIndex(block.Text, -1)
for _, match := range matches {
start := match[0]
end := match[1]
ref := block.Text[start:end]
_, _, err := nip19.Decode(ref)
if err != nil {
// invalid reference, ignore and allow
// (it's probably someone saying something like "oh, write something like npub1foo...")
continue
}
return true, "references must be prefixed with \"nostr:\""
}
}
}
return false, ""
}

View File

@@ -4,6 +4,9 @@ import (
"math"
"strings"
"testing"
"fiatjaf.com/nostr"
"github.com/tidwall/gjson"
)
// IsVirtualRelay returns true if the given normalized relay URL shouldn't be considered for outbox-model calculations.
@@ -44,3 +47,25 @@ func PerQueryLimitInBatch(totalFilterLimit int, numberOfQueries int) int {
),
)
}
// GetMainContent returns the user-provided text of the event. This is often the "content", but sometimes,
// like on kind:9802 highlights' "comment" tag, it's on a tag.
// for many other events it is nowhere, as the event doesn't contain any user-provided free text.
// (incomplete)
func GetMainContent(event nostr.Event) string {
switch event.Kind {
case 9802:
// for highlights, check if the comment is in the desired language
// only check the quote language if there is no comment
if tag := event.Tags.Find("comment"); tag != nil && len(tag[1]) > 0 {
return tag[1]
}
return ""
case 0:
return gjson.Get(event.Content, "about").Str
case 443, 27235, 22242, 1059, 13:
return ""
default:
return event.Content
}
}