def handle_incoming(%{"id" => nil}, _options), do: :error
def handle_incoming(%{"id" => ""}, _options), do: :error
# length of https:// = 8, should validate better, but good enough for now.
- def handle_incoming(%{"id" => id}, _options) when not (is_binary(id) and length(id) > 8),
+ def handle_incoming(%{"id" => id}, _options) when is_binary(id) and byte_size(id) < 8,
do: :error
# TODO: validate those with a Ecto scheme
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
options
)
- when objtype in ["Article", "Note", "Video", "Page", "Question", "Answer"] do
+ when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer"] do
actor = Containment.get_actor(data)
data =
})
{:user_locked, true} ->
+ {:ok, _relationship} = FollowingRelationship.update(follower, followed, "pending")
:noop
end
end
end
+ @misskey_reactions %{
+ "like" => "👍",
+ "love" => "❤️",
+ "laugh" => "😆",
+ "hmm" => "🤔",
+ "surprise" => "😮",
+ "congrats" => "🎉",
+ "angry" => "💢",
+ "confused" => "😥",
+ "rip" => "😇",
+ "pudding" => "🍮",
+ "star" => "⭐"
+ }
+
+ @doc "Rewrite misskey likes into EmojiReactions"
+ def handle_incoming(
+ %{
+ "type" => "Like",
+ "_misskey_reaction" => reaction
+ } = data,
+ options
+ ) do
+ data
+ |> Map.put("type", "EmojiReaction")
+ |> Map.put("content", @misskey_reactions[reaction] || reaction)
+ |> handle_incoming(options)
+ end
+
def handle_incoming(
%{"type" => "Like", "object" => object_id, "actor" => _actor, "id" => id} = data,
_options
end
end
+ def handle_incoming(
+ %{
+ "type" => "EmojiReaction",
+ "object" => object_id,
+ "actor" => _actor,
+ "id" => id,
+ "content" => emoji
+ } = data,
+ _options
+ ) do
+ with actor <- Containment.get_actor(data),
+ {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor),
+ {:ok, object} <- get_obj_helper(object_id),
+ {:ok, activity, _object} <-
+ ActivityPub.react_with_emoji(actor, object, emoji, activity_id: id, local: false) do
+ {:ok, activity}
+ else
+ _e -> :error
+ end
+ end
+
def handle_incoming(
%{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data,
_options
update_data =
new_user_data
- |> Map.take([:avatar, :banner, :bio, :name])
+ |> Map.take([:avatar, :banner, :bio, :name, :also_known_as])
|> Map.put(:fields, fields)
|> Map.put(:locked, locked)
|> Map.put(:invisible, invisible)
end
end
+ def handle_incoming(
+ %{
+ "type" => "Undo",
+ "object" => %{"type" => "EmojiReaction", "id" => reaction_activity_id},
+ "actor" => _actor,
+ "id" => id
+ } = data,
+ _options
+ ) do
+ with actor <- Containment.get_actor(data),
+ {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor),
+ {:ok, activity, _} <-
+ ActivityPub.unreact_with_emoji(actor, reaction_activity_id,
+ activity_id: id,
+ local: false
+ ) do
+ {:ok, activity}
+ else
+ _e -> :error
+ end
+ end
+
def handle_incoming(
%{
"type" => "Undo",
end
end
+ def handle_incoming(
+ %{
+ "type" => "Move",
+ "actor" => origin_actor,
+ "object" => origin_actor,
+ "target" => target_actor
+ },
+ _options
+ ) do
+ with %User{} = origin_user <- User.get_cached_by_ap_id(origin_actor),
+ {:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_actor),
+ true <- origin_actor in target_user.also_known_as do
+ ActivityPub.move(origin_user, target_user, false)
+ else
+ _e -> :error
+ end
+ end
+
def handle_incoming(_, _), do: :error
@spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil
Map.put(object, "attachment", attachments)
end
- defp strip_internal_fields(object) do
+ def strip_internal_fields(object) do
object
|> Map.drop(Pleroma.Constants.object_internal_fields())
end