AP ingest: accept Emoji icon variants

This commit is contained in:
Lain Soykaf 2026-01-17 01:33:21 +04:00
commit 9912a9f603
6 changed files with 246 additions and 8 deletions

View file

@ -59,12 +59,29 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
end
def changeset(struct, %{"type" => "Emoji"} = data) do
data = Map.put(data, "name", String.trim(data["name"], ":"))
data =
data
|> Map.put("name", String.trim(data["name"], ":"))
|> normalize_emoji_icon()
struct
|> cast(data, [:type, :name, :updated, :id])
|> cast_embed(:icon, with: &icon_changeset/2)
|> validate_required([:type, :name, :icon])
case data["icon"] do
%{"url" => url} when is_binary(url) ->
if valid_http_url?(url) do
struct
|> cast(data, [:type, :name, :updated, :id])
|> cast_embed(:icon, with: &icon_changeset/2)
|> validate_required([:type, :name, :icon])
else
struct
|> cast(data, [])
|> Map.put(:action, :ignore)
end
_ ->
struct
|> cast(data, [])
|> Map.put(:action, :ignore)
end
end
def changeset(struct, %{"type" => "Link"} = data) do
@ -101,6 +118,41 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
defp infer_type(data), do: data
defp normalize_emoji_icon(%{"icon" => icon} = data) when is_binary(icon) do
Map.put(data, "icon", %{"type" => "Image", "url" => icon})
end
defp normalize_emoji_icon(%{"icon" => icon} = data) when is_map(icon) do
case extract_icon_url(icon) do
url when is_binary(url) -> Map.put(data, "icon", %{"type" => "Image", "url" => url})
_ -> Map.delete(data, "icon")
end
end
defp normalize_emoji_icon(data), do: data
defp extract_icon_url(%{"url" => url}) when is_binary(url), do: url
defp extract_icon_url(%{"url" => %{"href" => href}}) when is_binary(href), do: href
defp extract_icon_url(%{"url" => [first | _]}) do
cond do
is_binary(first) -> first
is_map(first) -> first["href"]
true -> nil
end
end
defp extract_icon_url(%{"href" => href}) when is_binary(href), do: href
defp extract_icon_url(_), do: nil
defp valid_http_url?(url) when is_binary(url) do
match?({:ok, _}, ObjectValidators.Uri.cast(url))
end
defp valid_http_url?(_), do: false
def icon_changeset(struct, data) do
struct
|> cast(data, [:type, :url])

View file

@ -386,6 +386,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_url(object), do: object
defp emoji_icon_url(icon) when is_binary(icon), do: icon
defp emoji_icon_url(%{"url" => url}) when is_binary(url), do: url
defp emoji_icon_url(%{"url" => %{"href" => href}}) when is_binary(href), do: href
defp emoji_icon_url(%{"url" => [first | _]}) do
cond do
is_binary(first) -> first
is_map(first) -> first["href"] || first["url"] || first["id"]
true -> nil
end
end
defp emoji_icon_url(%{"href" => href}) when is_binary(href), do: href
defp emoji_icon_url(_), do: nil
def fix_emoji(%{"tag" => tags} = object) when is_list(tags) do
emoji =
tags
@ -393,7 +411,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> Enum.reduce(%{}, fn data, mapping ->
name = String.trim(data["name"], ":")
Map.put(mapping, name, data["icon"]["url"])
case emoji_icon_url(data["icon"]) do
url when is_binary(url) -> Map.put(mapping, name, url)
_ -> mapping
end
end)
Map.put(object, "emoji", emoji)
@ -401,9 +422,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_emoji(%{"tag" => %{"type" => "Emoji"} = tag} = object) do
name = String.trim(tag["name"], ":")
emoji = %{name => tag["icon"]["url"]}
Map.put(object, "emoji", emoji)
with url when is_binary(url) <- emoji_icon_url(tag["icon"]) do
Map.put(object, "emoji", %{name => url})
else
_ -> object
end
end
def fix_emoji(object), do: object