diff --git a/.fdignore b/.fdignore index ba077a4..10fabaa 100644 --- a/.fdignore +++ b/.fdignore @@ -1 +1,3 @@ bin +data +media diff --git a/cmd/relay/main.go b/cmd/relay/main.go index 0ed3bbc..6603b78 100644 --- a/cmd/relay/main.go +++ b/cmd/relay/main.go @@ -34,7 +34,7 @@ func main() { } go func() { - fmt.Printf("running on :%s\n", port) + log.Printf("running on :%s\n", port) if err := srv.ListenAndServe(); err != http.ErrServerClosed { log.Printf("HTTP server error: %v\n", err) } @@ -44,7 +44,7 @@ func main() { <-shutdown - fmt.Println("\nShutting down gracefully...") + log.Println("\nShutting down gracefully...") shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second) defer shutdownCancel() diff --git a/zooid/events.go b/zooid/events.go index 8ef019b..023c0a5 100644 --- a/zooid/events.go +++ b/zooid/events.go @@ -338,12 +338,24 @@ func (events *EventStore) CountEvents(filter nostr.Filter) (uint32, error) { // Non-eventstore methods -func (events *EventStore) SignAndSaveEvent(event nostr.Event, broadcast bool) error { +func (events *EventStore) StoreEvent(event nostr.Event) error { + if event.Kind.IsRegular() { + if err := events.SaveEvent(event); err != nil && err != eventstore.ErrDupEvent { + return err + } + + return nil + } + + return events.ReplaceEvent(event) +} + +func (events *EventStore) SignAndStoreEvent(event nostr.Event, broadcast bool) error { if err := events.Config.Sign(&event); err != nil { return err } - if err := events.SaveEvent(event); err != nil { + if err := events.StoreEvent(event); err != nil { return err } @@ -385,7 +397,7 @@ func (events *EventStore) GetOrCreateMemberList() nostr.Event { } return nostr.Event{ - Kind: nostr.KindApplicationSpecificData, + Kind: RELAY_MEMBERS, CreatedAt: nostr.Now(), Tags: nostr.Tags{ []string{"-"}, diff --git a/zooid/groups.go b/zooid/groups.go index 8320773..345340f 100644 --- a/zooid/groups.go +++ b/zooid/groups.go @@ -44,7 +44,7 @@ func (g *GroupStore) AddMember(h string, pubkey nostr.PubKey) error { }, } - return g.Events.SignAndSaveEvent(event, true) + return g.Events.SignAndStoreEvent(event, true) } func (g *GroupStore) RemoveMember(h string, pubkey nostr.PubKey) error { @@ -57,7 +57,7 @@ func (g *GroupStore) RemoveMember(h string, pubkey nostr.PubKey) error { }, } - return g.Events.SignAndSaveEvent(event, true) + return g.Events.SignAndStoreEvent(event, true) } func (g *GroupStore) SetMetadataFromEvent(event nostr.Event) error { @@ -77,7 +77,7 @@ func (g *GroupStore) SetMetadataFromEvent(event nostr.Event) error { Tags: tags, } - return g.Events.SignAndSaveEvent(metadataEvent, true) + return g.Events.SignAndStoreEvent(metadataEvent, true) } func (g *GroupStore) DeleteGroup(h string) { diff --git a/zooid/instance.go b/zooid/instance.go index 91c2995..690d3e5 100644 --- a/zooid/instance.go +++ b/zooid/instance.go @@ -93,10 +93,11 @@ func MakeInstance(filename string) (*Instance, error) { instance.Relay.StoreEvent = instance.StoreEvent instance.Relay.ReplaceEvent = instance.ReplaceEvent instance.Relay.DeleteEvent = instance.DeleteEvent - instance.Relay.OnEvent = instance.OnEvent - instance.Relay.OnEventSaved = instance.OnEventSaved instance.Relay.OnRequest = instance.OnRequest instance.Relay.QueryStored = instance.QueryStored + instance.Relay.OnEvent = instance.OnEvent + instance.Relay.OnEventSaved = instance.OnEventSaved + instance.Relay.OnEphemeralEvent = instance.OnEphemeralEvent // Todo: when there's a new version of khatru // instance.Relay.StartExpirationManager() @@ -181,10 +182,6 @@ func (instance *Instance) IsInternalEvent(event nostr.Event) bool { } func (instance *Instance) IsReadOnlyEvent(event nostr.Event) bool { - if instance.IsInternalEvent(event) { - return true - } - readOnlyEventKinds := []nostr.Kind{ RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER, @@ -222,7 +219,7 @@ func (instance *Instance) GenerateInviteEvent(pubkey nostr.PubKey) nostr.Event { }, } - if err := instance.Events.SignAndSaveEvent(event, false); err != nil { + if err := instance.Events.SignAndStoreEvent(event, false); err != nil { log.Printf("Failed to sign invite event: %v", err) } @@ -240,7 +237,7 @@ func (instance *Instance) PreventBroadcast(ws *khatru.WebSocket, event nostr.Eve } func (instance *Instance) StoreEvent(ctx context.Context, event nostr.Event) error { - return instance.Events.SaveEvent(event) + return instance.Events.StoreEvent(event) } func (instance *Instance) ReplaceEvent(ctx context.Context, event nostr.Event) error { @@ -285,6 +282,10 @@ func (instance *Instance) QueryStored(ctx context.Context, filter nostr.Filter) } for event := range instance.Events.QueryEvents(filter, 1000) { + if instance.IsInternalEvent(event) { + continue + } + if instance.IsWriteOnlyEvent(event) { continue } @@ -336,6 +337,10 @@ func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (rejec return true, "restricted: you are not a member of this relay" } + if instance.IsInternalEvent(event) { + return true, "invalid: this event's kind is not accepted" + } + if instance.IsReadOnlyEvent(event) { return true, "invalid: this event's kind is not accepted" } @@ -402,14 +407,6 @@ func (instance *Instance) OnEvent(ctx context.Context, event nostr.Event) (rejec } func (instance *Instance) OnEventSaved(ctx context.Context, event nostr.Event) { - if event.Kind == RELAY_JOIN { - instance.Management.AllowPubkey(event.PubKey) - } - - if event.Kind == RELAY_LEAVE { - instance.Management.BanPubkey(event.PubKey, "exited relay") - } - if event.Kind == nostr.KindSimpleGroupJoinRequest && instance.Config.Groups.AutoJoin { h := GetGroupIDFromEvent(event) meta := instance.Groups.GetMetadata(h) @@ -431,3 +428,13 @@ func (instance *Instance) OnEventSaved(ctx context.Context, event nostr.Event) { instance.Groups.DeleteGroup(GetGroupIDFromEvent(event)) } } + +func (instance *Instance) OnEphemeralEvent(ctx context.Context, event nostr.Event) { + if event.Kind == RELAY_JOIN { + instance.Management.AllowPubkey(event.PubKey) + } + + if event.Kind == RELAY_LEAVE { + instance.Management.BanPubkey(event.PubKey, "exited relay") + } +} diff --git a/zooid/management.go b/zooid/management.go index 9f6e795..6c097f7 100644 --- a/zooid/management.go +++ b/zooid/management.go @@ -48,7 +48,7 @@ func (m *ManagementStore) BanEvent(id nostr.ID, reason string) error { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_EVENTS) event.Tags = append(event.Tags, nostr.Tag{"event", id.Hex(), reason}) - return m.Events.SignAndSaveEvent(event, false) + return m.Events.SignAndStoreEvent(event, false) } func (m *ManagementStore) AllowEvent(id nostr.ID, reason string) error { @@ -57,7 +57,7 @@ func (m *ManagementStore) AllowEvent(id nostr.ID, reason string) error { return t[1] == id.Hex() }) - return m.Events.SignAndSaveEvent(event, false) + return m.Events.SignAndStoreEvent(event, false) } func (m *ManagementStore) EventIsBanned(id nostr.ID) bool { @@ -73,7 +73,7 @@ func (m *ManagementStore) GetBannedPubkeyItems() []nip86.PubKeyReason { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_PUBKEYS) items := make([]nip86.PubKeyReason, 0) - for tag := range event.Tags.FindAll("pubkey") { + for tag := range event.Tags.FindAll("banned") { items = append(items, nip86.PubKeyReason{ PubKey: nostr.MustPubKeyFromHex(tag[1]), Reason: tag[2], @@ -86,10 +86,10 @@ func (m *ManagementStore) GetBannedPubkeyItems() []nip86.PubKeyReason { func (m *ManagementStore) AddBannedPubkey(pubkey nostr.PubKey, reason string) error { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_PUBKEYS) - if event.Tags.FindWithValue("pubkey", pubkey.Hex()) == nil { - event.Tags = append(event.Tags, nostr.Tag{"pubkey", pubkey.Hex(), reason}) + if event.Tags.FindWithValue("banned", pubkey.Hex()) == nil { + event.Tags = append(event.Tags, nostr.Tag{"banned", pubkey.Hex(), reason}) - if err := m.Events.SignAndSaveEvent(event, false); err != nil { + if err := m.Events.SignAndStoreEvent(event, false); err != nil { return err } } @@ -100,12 +100,12 @@ func (m *ManagementStore) AddBannedPubkey(pubkey nostr.PubKey, reason string) er func (m *ManagementStore) RemoveBannedPubkey(pubkey nostr.PubKey) error { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_PUBKEYS) - if event.Tags.FindWithValue("pubkey", pubkey.Hex()) != nil { + if event.Tags.FindWithValue("banned", pubkey.Hex()) != nil { event.Tags = Filter(event.Tags, func(t nostr.Tag) bool { - return t[1] != pubkey.Hex() + return len(t) >= 2 && t[1] != pubkey.Hex() }) - if err := m.Events.SignAndSaveEvent(event, false); err != nil { + if err := m.Events.SignAndStoreEvent(event, false); err != nil { return err } } @@ -115,7 +115,7 @@ func (m *ManagementStore) RemoveBannedPubkey(pubkey nostr.PubKey) error { func (m *ManagementStore) PubkeyIsBanned(pubkey nostr.PubKey) bool { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_PUBKEYS) - tag := event.Tags.FindWithValue("pubkey", pubkey.Hex()) + tag := event.Tags.FindWithValue("banned", pubkey.Hex()) return tag != nil } @@ -152,13 +152,13 @@ func (m *ManagementStore) AddMember(pubkey nostr.PubKey) error { }, } - if err := m.Events.SignAndSaveEvent(addMemberEvent, true); err != nil { + if err := m.Events.SignAndStoreEvent(addMemberEvent, true); err != nil { return err } - membersEvent.Tags = append(membersEvent.Tags, nostr.Tag{"pubkey", pubkey.Hex()}) + membersEvent.Tags = append(membersEvent.Tags, nostr.Tag{"member", pubkey.Hex()}) - if err := m.Events.SignAndSaveEvent(membersEvent, true); err != nil { + if err := m.Events.SignAndStoreEvent(membersEvent, true); err != nil { return err } } @@ -179,15 +179,15 @@ func (m *ManagementStore) RemoveMember(pubkey nostr.PubKey) error { }, } - if err := m.Events.SignAndSaveEvent(removeMemberEvent, true); err != nil { + if err := m.Events.SignAndStoreEvent(removeMemberEvent, true); err != nil { return err } membersEvent.Tags = Filter(membersEvent.Tags, func(t nostr.Tag) bool { - return t[1] != pubkey.Hex() + return len(t) >= 2 && t[1] != pubkey.Hex() }) - if err := m.Events.SignAndSaveEvent(membersEvent, true); err != nil { + if err := m.Events.SignAndStoreEvent(membersEvent, true); err != nil { return err }