diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 9ed54fa6e..55985d310 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -118,7 +118,7 @@ defp normalise_addressing_public_list(%{} = map, [field | fields]) do Map.put(map, field, new_fval) else - map + Map.put(map, field, []) end normalise_addressing_public_list(map, fields) @@ -208,6 +208,19 @@ def fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object, options) def fix_in_reply_to(object, _options), do: object + # Pleroma sends unlisted posts without addressing public scope in the enclosing activity + # but we only use the ativity for access perm cheks, see: + # https://git.pleroma.social/pleroma/pleroma/-/issues/3323 + defp fix_create_visibility(%{"type" => "Create", "object" => %{} = object} = activity) do + activity + |> Map.put("to", object["to"]) + |> Map.put("cc", object["cc"]) + |> Map.put("bto", object["bto"]) + |> Map.put("bcc", object["bcc"]) + end + + defp fix_create_visibility(activity), do: activity + def fix_quote_url(object, options \\ []) def fix_quote_url(%{"quoteUri" => quote_url} = object, options) @@ -513,6 +526,7 @@ defp handle_incoming_normalised( ) when objtype in ~w{Question Answer Audio Video Event Article Note Page} do fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1) + data = fix_create_visibility(data) object = data["object"] diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index 234a48990..e9271ce9a 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -17,6 +17,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do import Mock import Pleroma.Factory + require Pleroma.Constants + setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok @@ -276,6 +278,32 @@ test "it ensures that address fields become lists" do refute is_nil(data["cc"]) end + test "it fixes Pleroma unlisted" do + # https://git.pleroma.social/pleroma/pleroma/-/issues/3323 + user1 = insert(:user) + user2 = insert(:user) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Jason.decode!() + |> Map.put("actor", user1.ap_id) + |> Map.put("cc", []) + |> Map.put("to", [user2.ap_id, user1.follower_address]) + + object = + data["object"] + |> Map.put("attributedTo", user1.ap_id) + |> Map.put("cc", [Pleroma.Constants.as_public()]) + |> Map.put("to", [user2.ap_id, user1.follower_address]) + |> Map.put("id", user1.ap_id <> "/activities/12345678") + + data = Map.put(data, "object", object) + + {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data) + + assert "unlisted" == Pleroma.Web.ActivityPub.Visibility.get_visibility(activity) + end + test "it strips internal likes" do data = File.read!("test/fixtures/mastodon-post-activity.json")