Add signature verification and lossless event tag storage
This commit is contained in:
@@ -15,6 +15,7 @@ defmodule Parrhesia.ConfigTest do
|
||||
assert Parrhesia.Config.get([:policies, :marmot_media_max_imeta_tags_per_event]) == 8
|
||||
assert Parrhesia.Config.get([:policies, :marmot_media_reject_mip04_v1]) == true
|
||||
assert Parrhesia.Config.get([:policies, :marmot_push_max_trigger_age_seconds]) == 120
|
||||
assert Parrhesia.Config.get([:features, :verify_event_signatures]) == false
|
||||
assert Parrhesia.Config.get([:features, :nip_50_search]) == true
|
||||
assert Parrhesia.Config.get([:features, :marmot_push_notifications]) == false
|
||||
end
|
||||
|
||||
63
test/parrhesia/protocol/event_validator_signature_test.exs
Normal file
63
test/parrhesia/protocol/event_validator_signature_test.exs
Normal file
@@ -0,0 +1,63 @@
|
||||
defmodule Parrhesia.Protocol.EventValidatorSignatureTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Parrhesia.Protocol.EventValidator
|
||||
|
||||
test "accepts valid Schnorr signatures when verification is enabled" do
|
||||
previous_features = Application.get_env(:parrhesia, :features, [])
|
||||
|
||||
Application.put_env(
|
||||
:parrhesia,
|
||||
:features,
|
||||
Keyword.put(previous_features, :verify_event_signatures, true)
|
||||
)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:parrhesia, :features, previous_features)
|
||||
end)
|
||||
|
||||
event = signed_event()
|
||||
|
||||
assert :ok = EventValidator.validate(event)
|
||||
end
|
||||
|
||||
test "rejects invalid Schnorr signatures when verification is enabled" do
|
||||
previous_features = Application.get_env(:parrhesia, :features, [])
|
||||
|
||||
Application.put_env(
|
||||
:parrhesia,
|
||||
:features,
|
||||
Keyword.put(previous_features, :verify_event_signatures, true)
|
||||
)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:parrhesia, :features, previous_features)
|
||||
end)
|
||||
|
||||
event =
|
||||
signed_event()
|
||||
|> Map.put("sig", String.duplicate("0", 128))
|
||||
|
||||
assert {:error, :invalid_signature} = EventValidator.validate(event)
|
||||
end
|
||||
|
||||
defp signed_event do
|
||||
{seckey, pubkey} = Secp256k1.keypair(:xonly)
|
||||
|
||||
event = %{
|
||||
"pubkey" => Base.encode16(pubkey, case: :lower),
|
||||
"created_at" => System.system_time(:second),
|
||||
"kind" => 1,
|
||||
"tags" => [["e", String.duplicate("a", 64), "wss://relay.example", "reply"]],
|
||||
"content" => "signed"
|
||||
}
|
||||
|
||||
id = EventValidator.compute_id(event)
|
||||
{:ok, id_bin} = Base.decode16(id, case: :lower)
|
||||
sig = Secp256k1.schnorr_sign(id_bin, seckey)
|
||||
|
||||
event
|
||||
|> Map.put("id", id)
|
||||
|> Map.put("sig", Base.encode16(sig, case: :lower))
|
||||
end
|
||||
end
|
||||
@@ -11,6 +11,24 @@ defmodule Parrhesia.Storage.Adapters.Postgres.EventsLifecycleTest do
|
||||
:ok
|
||||
end
|
||||
|
||||
test "event tags round-trip without truncation" do
|
||||
tagged_event =
|
||||
event(%{
|
||||
"kind" => 1,
|
||||
"tags" => [
|
||||
["e", String.duplicate("a", 64), "wss://relay.example", "reply"],
|
||||
["-"],
|
||||
["p", String.duplicate("b", 64), "wss://hint.example"]
|
||||
],
|
||||
"content" => "tag-roundtrip"
|
||||
})
|
||||
|
||||
assert {:ok, _event} = Events.put_event(%{}, tagged_event)
|
||||
assert {:ok, persisted_tagged_event} = Events.get_event(%{}, tagged_event["id"])
|
||||
|
||||
assert persisted_tagged_event["tags"] == tagged_event["tags"]
|
||||
end
|
||||
|
||||
test "delete_by_request tombstones owned target events" do
|
||||
target = event(%{"kind" => 1, "content" => "target"})
|
||||
assert {:ok, _event} = Events.put_event(%{}, target)
|
||||
|
||||
Reference in New Issue
Block a user