Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85823427
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/changelog.d/mention-notify-access.security b/changelog.d/mention-notify-access.security
new file mode 100644
index 000000000..2f1830079
--- /dev/null
+++ b/changelog.d/mention-notify-access.security
@@ -0,0 +1 @@
+Do not notify tagged users who cannot see the post
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 255803c14..b66e0ace6 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -435,13 +435,56 @@ defmodule Pleroma.Web.CommonAPI.Utils do
%{}
end
- tagged_mentions = maybe_extract_mentions(object_data)
+ tagged_mentions =
+ maybe_extract_mentions(object_data)
+ |> filter_tags_to_qualified(activity)
recipients ++ tagged_mentions
end
def maybe_notify_mentioned_recipients(recipients, _), do: recipients
+ # Filter tagged mentions to ensure they can actually access the status
+ defp filter_tags_to_qualified(tagged_mentions, %Activity{
+ recipients: recipients,
+ data: data,
+ actor: actor
+ }) do
+ recipients =
+ if recipients && recipients != [],
+ do: recipients,
+ else:
+ (data["to"] || []) ++ (data["cc"] || []) ++ (data["bto"] || []) ++ (data["bcc"] || [])
+
+ cond do
+ recipients == [] ->
+ []
+
+ Pleroma.Constants.as_public() in recipients ->
+ tagged_mentions
+
+ true ->
+ author = User.get_cached_by_ap_id(actor)
+ to_followers = match?(%User{}, author) and author.follower_address in recipients
+
+ Enum.filter(tagged_mentions, fn tagged ->
+ cond do
+ tagged in recipients ->
+ true
+
+ to_followers ->
+ case User.get_cached_by_ap_id(tagged) do
+ %User{} = tagged_user -> User.following?(tagged_user, author)
+ _ -> false
+ end
+
+ true ->
+ false
+ end
+ end)
+ end
+ end
+
def maybe_notify_followers(recipients, %Activity{data: %{"type" => "Move"}} = activity) do
with %User{} = user <- User.get_cached_by_ap_id(activity.actor) do
user
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index 1ff014a8d..091b9affc 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.NotificationTest do
import Pleroma.Factory
+ require Pleroma.Constants
+
alias Pleroma.FollowingRelationship
alias Pleroma.Notification
alias Pleroma.Object
@@ -628,6 +630,102 @@ defmodule Pleroma.NotificationTest do
assert other_user in enabled_receivers
end
+ defp incoming_note_tagging(author, to, tagged_ap_ids) do
+ tags = Enum.map(tagged_ap_ids, &%{"type" => "Mention", "href" => &1, "name" => &1})
+
+ {:ok, activity} =
+ Transmogrifier.handle_incoming(%{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "type" => "Create",
+ "to" => to,
+ "actor" => author.ap_id,
+ "object" => %{
+ "type" => "Note",
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
+ "to" => to,
+ "content" => "tagged",
+ "tag" => tags,
+ "attributedTo" => author.ap_id
+ }
+ })
+
+ activity
+ end
+
+ defp notified_ap_ids(activity),
+ do: activity |> Notification.get_notified_from_activity() |> Enum.map(& &1.ap_id)
+
+ test "it does not notify tagged users who cannot see a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ refute tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it notifies tagged followers of a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+ {:ok, _, _} = Pleroma.User.follow(tagged, author)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ assert tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it does not notify tagged users who are not addressed by a direct message" do
+ author = insert(:user)
+ addressed = insert(:user)
+ tagged = insert(:user)
+
+ activity = incoming_note_tagging(author, [addressed.ap_id], [tagged.ap_id])
+ receivers = notified_ap_ids(activity)
+
+ assert addressed.ap_id in receivers
+ refute tagged.ap_id in receivers
+ end
+
+ test "it notifies tagged users of a public post even if they are not addressed" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ activity =
+ incoming_note_tagging(author, [Pleroma.Constants.as_public()], [tagged.ap_id])
+
+ assert tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it does not notify tagged users with a pending follow request" do
+ author = insert(:user, is_locked: true)
+ tagged = insert(:user)
+ {:ok, _, _, _} = CommonAPI.follow(author, tagged)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ refute tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it ignores tags of unknown users in a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ follower = insert(:user)
+ {:ok, _, _} = Pleroma.User.follow(follower, author)
+
+ activity =
+ incoming_note_tagging(author, [author.follower_address], [
+ "https://unknown.example/users/nobody",
+ tagged.ap_id,
+ follower.ap_id
+ ])
+
+ receivers = notified_ap_ids(activity)
+
+ refute tagged.ap_id in receivers
+ assert follower.ap_id in receivers
+ end
+
test "it does not send notifications to users who are only cc in new messages" do
user = insert(:user)
other_user = insert(:user)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Oct 29, 5:38 AM (9 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1797593
Default Alt Text
(5 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline