diff --git a/khatru/policies/reactions.go b/khatru/policies/reactions.go new file mode 100644 index 0000000..d4828cd --- /dev/null +++ b/khatru/policies/reactions.go @@ -0,0 +1,33 @@ +package policies + +import ( + "fiatjaf.com/nostr" + "fiatjaf.com/nostr/eventstore" +) + +// UniqueReactionsWrapper ensures that only the latest reaction or poll response from an author to an event is kept. +// When a new reaction (kind 7) or poll response (kind 1018) is received, it deletes any previous ones from the same author to the same event. +type UniqueReactionsWrapper struct { + eventstore.Store +} + +func (w *UniqueReactionsWrapper) SaveEvent(event nostr.Event) error { + // check if it's a reaction or poll response + if event.Kind == 7 || event.Kind == 1018 { + // find the referenced event ID + ref := event.Tags.Find("e") + if ref != nil { + // query for existing events of same kind from same author referencing the same event and delete them + for old := range w.Store.QueryEvents(nostr.Filter{ + Authors: []nostr.PubKey{event.PubKey}, + Kinds: []nostr.Kind{event.Kind}, + Tags: nostr.TagMap{"e": []string{ref[1]}}, + }, 1_000) { + w.Store.DeleteEvent(old.ID) + } + } + } + + // Save the new event + return w.Store.SaveEvent(event) +} diff --git a/khatru/policies/schema_validation.go b/khatru/policies/schema_validation.go new file mode 100644 index 0000000..d51a0ff --- /dev/null +++ b/khatru/policies/schema_validation.go @@ -0,0 +1,18 @@ +package policies + +import ( + "context" + + "fiatjaf.com/nostr" + "fiatjaf.com/nostr/schema" +) + +func ValidateAgainstSchema(ctx context.Context, evt nostr.Event) (bool, string) { + v := schema.NewDefaultValidator() + v.FailOnUnknown = true + err := v.ValidateEvent(evt) + if err != nil { + return true, err.Error() + } + return false, "" +} diff --git a/schema/schema.go b/schema/schema.go index ef8757c..45b036b 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -53,6 +53,10 @@ func NewValidator(schemaData string) Validator { return Validator{Schema: schema} } +func NewDefaultValidator() Validator { + return NewValidator(string(schemaFile)) +} + var ( ErrUnknownContent = fmt.Errorf("unknown content") ErrUnknownKind = fmt.Errorf("unknown kind")