commit d802abd847c6b52b945a90acdc5e26935f8859f8
from: Oliver Lowe <o@olowe.co>
date: Tue Mar 12 03:20:23 2024 UTC

apub: unmarshal direct To recipients into Mastodon et al. Mentions

This seems clear enough. In the regular email world we want direct
recipients to be signalled in some way of our message. Recipients
merely copied in (CC'd) don't need to be alerted but still get the
message.

commit - 2469f6646d48415c8f7f947815762863adbf3133
commit + d802abd847c6b52b945a90acdc5e26935f8859f8
blob - b51d6126a1a803d43253f2f12cb04b127470f2f9
blob + 394107211718e1725e4598c31f9e1b2d8b3fb3bf
--- apub.go
+++ apub.go
@@ -54,6 +54,7 @@ type Activity struct {
 	} `json:"source,omitempty"`
 	PublicKey *PublicKey      `json:"publicKey,omitempty"`
 	Audience  string          `json:"audience,omitempty"`
+	Href      string          `json:"href,omitempty"`
 	Tag       []Activity      `json:"tag,omitempty"`
 	Object    json.RawMessage `json:"object,omitempty"`
 }
blob - 0b3cec10190214ec99aa7a32c1992548fdb94c62
blob + bed76fae19b3fa04905356980c77324b465eb3ae
--- mail.go
+++ mail.go
@@ -92,6 +92,7 @@ func UnmarshalMail(msg *mail.Message) (*Activity, erro
 	}
 
 	var wto, wcc []string
+	var tags []Activity
 	if msg.Header.Get("To") != "" {
 		to, err := msg.Header.AddressList("To")
 		// ignore missing To line. Some ActivityPub servers only have the
@@ -104,7 +105,10 @@ func UnmarshalMail(msg *mail.Message) (*Activity, erro
 			return nil, fmt.Errorf("webfinger To addresses: %w", err)
 		}
 		wto = make([]string, len(actors))
+		tags = make([]Activity, len(actors))
 		for i, a := range actors {
+			addr := strings.Trim(to[i].Address, "<>")
+			tags[i] = Activity{Type: "Mention", Href: a.ID, Name: "@" + addr}
 			wto[i] = a.ID
 		}
 	}
@@ -139,6 +143,7 @@ func UnmarshalMail(msg *mail.Message) (*Activity, erro
 		Content:      strings.TrimSpace(buf.String()),
 		InReplyTo:    strings.Trim(msg.Header.Get("In-Reply-To"), "<>"),
 		Published:    &date,
+		Tag:          tags,
 	}, nil
 }
 
blob - 719f8db1b08a80ce3600fde0a0a856af9267803f
blob + 61bf051284c44bab0c9c0ee8b84609ae5bcdff77
--- mail_test.go
+++ mail_test.go
@@ -26,7 +26,7 @@ func TestMailAddress(t *testing.T) {
 		{
 			"testdata/actor/lemmy.json",
 			"<Spotlight7573@lemmy.world>",
-			"<@>", // empty mail.Address
+			"<@>", // zero mail.Address
 		},
 	}
 	for _, tt := range tests {
@@ -94,7 +94,15 @@ func TestUnmarshalMail(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping network calls to unmarshal mail message to Activity")
 	}
-	if _, err := UnmarshalMail(msg); err != nil {
+	a, err := UnmarshalMail(msg)
+	if err != nil {
 		t.Fatal(err)
 	}
+	if len(a.Tag) != 1 {
+		t.Fatalf("wanted 1 tag in unmarshalled activity, got %d", len(a.Tag))
+	}
+	want := "@henfredemars@infosec.pub"
+	if a.Tag[0].Name != want {
+		t.Errorf("wanted tag name %s, got %s", want, a.Tag[0].Name)
+	}
 }