From 6eee5e1c4208ce8ab2ad2d6f3856a038f017a353 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Tue, 7 Apr 2026 08:30:00 +0200 Subject: [PATCH] reject protected events, so long as we do not implement AUTH --- lib/gc_index_relay/nostr.ex | 3 ++- lib/gc_index_relay/nostr/validator.ex | 15 +++++++++++ test/gc_index_relay/nostr/validator_test.exs | 28 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/gc_index_relay/nostr.ex b/lib/gc_index_relay/nostr.ex index 3cea006..2685cb0 100644 --- a/lib/gc_index_relay/nostr.ex +++ b/lib/gc_index_relay/nostr.ex @@ -57,7 +57,8 @@ defmodule GcIndexRelay.Nostr do """ def create_event(event) when is_struct(event, PubEvent) do with {:ok, event} <- Validator.validate_id(event), - {:ok, event} <- Validator.validate_signature(event) do + {:ok, event} <- Validator.validate_signature(event), + {:ok, event} <- Validator.validate_not_protected(event) do db_event = PubEvent.to_db(event) tags_as_maps = Enum.map(db_event.tags, &Map.from_struct/1) attrs = db_event |> Map.from_struct() |> Map.put(:tags, tags_as_maps) diff --git a/lib/gc_index_relay/nostr/validator.ex b/lib/gc_index_relay/nostr/validator.ex index 8155856..2a73ead 100644 --- a/lib/gc_index_relay/nostr/validator.ex +++ b/lib/gc_index_relay/nostr/validator.ex @@ -58,6 +58,21 @@ defmodule GcIndexRelay.Nostr.Validator do event.id == computed_id end + @doc """ + Rejects protected events per [NIP-70](https://github.com/nostr-protocol/nips/blob/master/70.md). + + An event containing the `["-"]` tag is considered protected and may only be + published by its author after completing the NIP-42 AUTH flow. Since this relay + does not implement NIP-42, protected events are rejected outright. + """ + def validate_not_protected(event) when is_struct(event, PubEvent) do + if Enum.member?(event.tags, ["-"]) do + {:error, "auth-required: this event may only be published by its author"} + else + {:ok, event} + end + end + @doc """ Validates a Nostr event signature per [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md). """ diff --git a/test/gc_index_relay/nostr/validator_test.exs b/test/gc_index_relay/nostr/validator_test.exs index 5b850fd..a05bb70 100644 --- a/test/gc_index_relay/nostr/validator_test.exs +++ b/test/gc_index_relay/nostr/validator_test.exs @@ -139,6 +139,34 @@ defmodule GcIndexRelay.Nostr.ValidatorTest do end end + describe "validate_not_protected/1" do + test "returns {:ok, event} for a normal event with no tags" do + event = valid_pub_event_fixture() + + assert {:ok, ^event} = Validator.validate_not_protected(event) + end + + test "returns {:ok, event} for an event with other tags but no protection tag" do + event = valid_pub_event_fixture(tags: [["e", "abc123"], ["p", "def456"]]) + + assert {:ok, ^event} = Validator.validate_not_protected(event) + end + + test "returns {:error, message} for an event with the [\"-\"] protection tag" do + event = valid_pub_event_fixture(tags: [["-"]]) + + assert {:error, message} = Validator.validate_not_protected(event) + assert message =~ "auth-required" + end + + test "returns {:error, message} when [\"-\"] is mixed with other tags" do + event = valid_pub_event_fixture(tags: [["e", "abc123"], ["-"], ["p", "def456"]]) + + assert {:error, message} = Validator.validate_not_protected(event) + assert message =~ "auth-required" + end + end + describe "static reference test" do test "validates against known-good pre-computed event" do event = static_valid_pub_event()