diff --git a/changelog.d/context-local-only.fix b/changelog.d/context-local-only.fix new file mode 100644 index 000000000..5a1d10f3a --- /dev/null +++ b/changelog.d/context-local-only.fix @@ -0,0 +1 @@ +Show local-only replies in status context to local users who don't follow the replier diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index f6c74bdac..03f8447bb 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -466,21 +466,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def fetch_activities_for_context_query(context, opts) do - public = [Constants.as_public()] + user = opts[:user] recipients = - if opts[:user], - do: [opts[:user].ap_id | User.following(opts[:user])] ++ public, - else: public + cond do + user && user.local -> + [Constants.as_public(), as_local_public(), user.ap_id | User.following(user)] + + user -> + [Constants.as_public(), user.ap_id | User.following(user)] + + true -> + [Constants.as_public()] + end from(activity in Activity) |> maybe_preload_objects(opts) |> maybe_preload_bookmarks(opts) |> maybe_set_thread_muted_field(opts) - |> restrict_unauthenticated(opts[:user]) + |> restrict_unauthenticated(user) |> restrict_blocked(opts) |> restrict_blockers_visibility(opts) - |> restrict_recipients(recipients, opts[:user]) + |> restrict_recipients(recipients, user) |> restrict_filtered(opts) |> where( [activity], diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index bc859df48..6574f82f8 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -3093,6 +3093,30 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } = response end + test "context shows local-only replies to local users only" do + poster = insert(:user) + replier = insert(:user) + %{conn: conn} = oauth_access(["read:statuses"]) + %{conn: remote_conn} = oauth_access(["read:statuses"], user: insert(:user, local: false)) + + {:ok, %{id: id1}} = CommonAPI.post(poster, %{status: "1"}) + + {:ok, %{id: id2}} = + CommonAPI.post(replier, %{status: "2", visibility: "local", in_reply_to_status_id: id1}) + + assert %{"descendants" => [%{"id" => ^id2}]} = + conn + |> get("/api/v1/statuses/#{id1}/context") + |> json_response_and_validate_schema(:ok) + + for conn <- [build_conn(), remote_conn] do + assert %{"descendants" => []} = + conn + |> get("/api/v1/statuses/#{id1}/context") + |> json_response_and_validate_schema(:ok) + end + end + test "context doesn't leak priv posts" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) stranger = insert(:user)