diff --git a/server/db/mongo/checkDuplicate.go b/server/db/mongo/checkDuplicate.go new file mode 100644 index 0000000..4adf15b --- /dev/null +++ b/server/db/mongo/checkDuplicate.go @@ -0,0 +1,25 @@ +package mongo + +import ( + "context" + "fmt" + nostr "grain/server/types" // Adjust import path as needed + + "go.mongodb.org/mongo-driver/bson" +) + +// CheckDuplicateEvent checks if an event with the same ID already exists in the collection. +func CheckDuplicateEvent(ctx context.Context, evt nostr.Event) (bool, error) { + collection := GetCollection(evt.Kind) + filter := bson.M{"id": evt.ID} + + var existingEvent nostr.Event + err := collection.FindOne(ctx, filter).Decode(&existingEvent) + if err != nil { + if err.Error() == "mongo: no documents in result" { + return false, nil // No duplicate found + } + return false, fmt.Errorf("error checking for duplicate event: %v", err) + } + return true, nil // Duplicate found +} diff --git a/server/handlers/event.go b/server/handlers/event.go index 060e407..59a9ab8 100644 --- a/server/handlers/event.go +++ b/server/handlers/event.go @@ -66,6 +66,19 @@ func HandleEvent(ws *websocket.Conn, message []interface{}) { return } + // Check for duplicate event + isDuplicate, err := mongo.CheckDuplicateEvent(context.TODO(), evt) + if err != nil { + fmt.Printf("Error checking for duplicate event: %v\n", err) + response.SendOK(ws, evt.ID, false, "error: internal server error during duplicate check") + return + } + + if isDuplicate { + response.SendOK(ws, evt.ID, false, "blocked: the database already contains this event") + return + } + // Store the event in MongoDB or other storage mongo.StoreMongoEvent(context.TODO(), evt, ws) fmt.Println("Event processed:", evt.ID) @@ -106,20 +119,20 @@ func validateEventTimestamp(evt nostr.Event) bool { } func handleBlacklistAndWhitelist(ws *websocket.Conn, evt nostr.Event) bool { - // Use the updated CheckBlacklist function - if blacklisted, msg := config.CheckBlacklist(evt.PubKey, evt.Content); blacklisted { - response.SendOK(ws, evt.ID, false, msg) - return false - } + // Use the updated CheckBlacklist function + if blacklisted, msg := config.CheckBlacklist(evt.PubKey, evt.Content); blacklisted { + response.SendOK(ws, evt.ID, false, msg) + return false + } - // Check the whitelist using CheckWhitelist function - isWhitelisted, msg := config.CheckWhitelist(evt) - if !isWhitelisted { - response.SendOK(ws, evt.ID, false, msg) - return false - } + // Check the whitelist using CheckWhitelist function + isWhitelisted, msg := config.CheckWhitelist(evt) + if !isWhitelisted { + response.SendOK(ws, evt.ID, false, msg) + return false + } - return true + return true } func handleRateAndSizeLimits(ws *websocket.Conn, evt nostr.Event, eventSize int) bool {