Personas prove what goes to relays; the server says what it reads
FEP-521a and FEP-8b32. Every persona has an Ed25519 key of its own (Avatar.SigningKey; migration 014 gives the earlier ones theirs), named in its actor's assertionMethod as a Multikey, the terms defined in the actor's own context. A persona's activity going to a relay carries an eddsa-jcs-2022 proof (JSON canonicalised by RFC 8785, Jcs), so what Activity-Relay forwards reaches Mastodon, which verifies it with its own code. Nothing else carries one: Mitra takes a proof over the HTTP signature and refuses one by a key it has not read, without reading the actor again. Received: an actor's own Multikeys are kept, and a forwarded activity whose proof one of them verifies is taken as it came instead of being read again from its origin. Discovery: WebFinger for the server's origin links its instance actor (FEP-d556), NodeInfo links it as the application actor (FEP-2677), and actors name RFC 9421 under implements (FEP-844e). Checked live: relay 16 (Activity-Relay's forward of alice's post reaches Mastodon), Mitra, GoToSocial and Mastodon unchanged (165 in all). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
c47b6e5533
commit
9ab87b2779
22 files changed
+702
-30
No files matched your search
@@ -38,6 +38,31 @@ namespace PrivaPub.Tests.Http
|
||||
static string Link(JsonObject document, string rel) =>
|
||||
document["links"]!.AsArray().Single(l => l!["rel"]!.GetValue<string>() == rel)!["href"]!.GetValue<string>();
|
||||
|
||||
// FEP-d556, FEP-2677 and FEP-844e: the server's own actor is found from its origin and from NodeInfo, and says what
|
||||
// the server reads that its documents do not show
|
||||
[Fact]
|
||||
public async Task The_server_actor_is_found_from_the_origin_and_nodeinfo_and_tells_what_it_implements()
|
||||
{
|
||||
var instance = $"{Base}/peasants/privapub";
|
||||
foreach (var resource in new[] { Base, Base + "/" })
|
||||
{
|
||||
var found = await WebFinger(resource);
|
||||
Assert.Equal(HttpStatusCode.OK, found.Status);
|
||||
Assert.Equal(resource, found.Json["subject"]!.GetValue<string>());
|
||||
Assert.Equal(instance, Link(found.Json, "https://www.w3.org/ns/activitystreams#Service"));
|
||||
}
|
||||
var nodeinfo = await _client.Fetch("/.well-known/nodeinfo", "application/json");
|
||||
Assert.Equal(instance, Link(nodeinfo.Json, "https://www.w3.org/ns/activitystreams#Application"));
|
||||
|
||||
var actor = (await _client.Fetch("/peasants/privapub")).Json;
|
||||
Assert.Contains(actor["implements"]!.AsArray(), i => i!["href"]!.GetValue<string>() == "https://datatracker.ietf.org/doc/html/rfc9421");
|
||||
var persona = await _host.Persona(await _host.SignUp(), "generated");
|
||||
var personaActor = (await _client.Fetch($"/peasants/{persona.UserName}")).Json;
|
||||
Assert.Equal("Application", personaActor["generator"]!["type"]!.GetValue<string>());
|
||||
Assert.Contains(personaActor["generator"]!["implements"]!.AsArray(), i => i!["href"]!.GetValue<string>() == "https://datatracker.ietf.org/doc/html/rfc9421");
|
||||
Assert.StartsWith("z6Mk", personaActor["assertionMethod"]![0]!["publicKeyMultibase"]!.GetValue<string>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WebFinger_finds_a_persona_by_acct_and_by_actor_uri()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user