fix(activitypub): accept emoji reactions with a single tag object

Ported from Akkoma 462225880.

Co-authored-by: Oneric <oneric@oneric.stub>
This commit is contained in:
Lain Soykaf 2026-10-31 15:37:41 +04:00
commit 654a41b2c9
No known key found for this signature in database
3 changed files with 31 additions and 1 deletions

View file

@ -0,0 +1 @@
Accept incoming emoji reactions whose tag is a single object instead of an array

View file

@ -57,7 +57,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
|> CommonFixes.fix_actor()
|> CommonFixes.fix_activity_addressing()
data = Map.put_new(data, "tag", [])
data = fix_tag(data)
case Object.normalize(data["object"]) do
%Object{} = object ->
@ -70,6 +70,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
end
end
# JSON-LD compaction turns a single-element array into a bare object
defp fix_tag(%{"tag" => %{} = tag} = data), do: Map.put(data, "tag", [tag])
defp fix_tag(data), do: Map.put_new(data, "tag", [])
defp fix_emoji_qualification(%{"content" => emoji} = data) do
new_emoji = Pleroma.Emoji.fully_qualify_emoji(emoji)

View file

@ -86,6 +86,31 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
)
end
test "it works for incoming custom emoji reactions with a single tag object" do
user = insert(:user)
other_user = insert(:user, local: false)
{:ok, activity} = CommonAPI.post(user, %{status: "hello"})
data =
File.read!("test/fixtures/custom-emoji-reaction.json")
|> Jason.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", other_user.ap_id)
[tag] = data["tag"]
data = Map.put(data, "tag", tag)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["content"] == ":hanapog:"
assert [%{"name" => "hanapog"}] = data["tag"]
object = Object.get_by_ap_id(data["object"])
url = tag["icon"]["url"]
assert match?([["hanapog", _, ^url]], object.data["reactions"])
end
test "it works for incoming unqualified emoji reactions" do
user = insert(:user)
other_user = insert(:user, local: false)