AP ingest: normalize inReplyTo shapes

This commit is contained in:
Lain Soykaf 2026-01-16 23:57:01 +04:00
commit bff67650e1
8 changed files with 245 additions and 12 deletions

View file

@ -41,22 +41,34 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
def fix_object_defaults(data) do
data = Maps.filter_empty_values(data)
in_reply_to_id = in_reply_to_id(data["inReplyTo"])
context =
Utils.maybe_create_context(
data["context"] || data["conversation"] || data["inReplyTo"] || data["id"]
data["context"] || data["conversation"] || in_reply_to_id || data["id"]
)
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"])
data = Map.put(data, "context", context)
data
|> Map.put("context", context)
|> cast_and_filter_recipients("to", follower_collection)
|> cast_and_filter_recipients("cc", follower_collection)
|> cast_and_filter_recipients("bto", follower_collection)
|> cast_and_filter_recipients("bcc", follower_collection)
|> Transmogrifier.fix_implicit_addressing(follower_collection)
with attributed_to when is_binary(attributed_to) <- data["attributedTo"],
%User{follower_address: follower_collection} <- User.get_cached_by_ap_id(attributed_to) do
data
|> cast_and_filter_recipients("to", follower_collection)
|> cast_and_filter_recipients("cc", follower_collection)
|> cast_and_filter_recipients("bto", follower_collection)
|> cast_and_filter_recipients("bcc", follower_collection)
|> Transmogrifier.fix_implicit_addressing(follower_collection)
else
_ -> data
end
end
defp in_reply_to_id(in_reply_to) when is_binary(in_reply_to), do: in_reply_to
defp in_reply_to_id(%{"id" => in_reply_to}) when is_binary(in_reply_to), do: in_reply_to
defp in_reply_to_id(%{"href" => in_reply_to}) when is_binary(in_reply_to), do: in_reply_to
defp in_reply_to_id([in_reply_to | _]), do: in_reply_to_id(in_reply_to)
defp in_reply_to_id(_), do: nil
def fix_activity_addressing(activity) do
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(activity["actor"])

View file

@ -201,9 +201,29 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object, options)
when not is_nil(in_reply_to) do
in_reply_to_id = prepare_in_reply_to(in_reply_to)
object =
cond do
is_list(in_reply_to) ->
if not_empty_string(in_reply_to_id) do
Map.put(object, "inReplyTo", in_reply_to_id)
else
Map.delete(object, "inReplyTo")
end
is_map(in_reply_to) and is_nil(in_reply_to["id"]) and is_binary(in_reply_to["href"]) ->
Map.put(object, "inReplyTo", in_reply_to["href"])
is_map(in_reply_to) and is_nil(in_reply_to["id"]) and is_nil(in_reply_to["href"]) ->
Map.delete(object, "inReplyTo")
true ->
object
end
depth = (options[:depth] || 0) + 1
if Federator.allowed_thread_distance?(depth) do
if not_empty_string(in_reply_to_id) and Federator.allowed_thread_distance?(depth) do
with {:ok, replied_object} <- get_obj_helper(in_reply_to_id, options),
%Activity{} <- Activity.get_create_by_object_ap_id(replied_object.data["id"]) do
object
@ -249,9 +269,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
is_map(in_reply_to) && is_bitstring(in_reply_to["id"]) ->
in_reply_to["id"]
is_map(in_reply_to) && is_bitstring(in_reply_to["href"]) ->
in_reply_to["href"]
is_list(in_reply_to) && is_bitstring(Enum.at(in_reply_to, 0)) ->
Enum.at(in_reply_to, 0)
is_list(in_reply_to) && is_map(Enum.at(in_reply_to, 0)) ->
in_reply_to
|> Enum.at(0)
|> prepare_in_reply_to()
true ->
""
end