forked from AkkomaGang/akkoma
Merge branch 'bugfix/muted-user-notif-streaming' into 'develop'
Bugfix: muted/blocked user notification streaming Closes #1105 See merge request pleroma/pleroma!1461
This commit is contained in:
commit
7271b2a954
3 changed files with 68 additions and 11 deletions
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
|
- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
|
||||||
- Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity
|
- Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity
|
||||||
- Mastodon API: Add `account_id`, `type`, `offset`, and `limit` to search API (`/api/v1/search` and `/api/v2/search`)
|
- Mastodon API: Add `account_id`, `type`, `offset`, and `limit` to search API (`/api/v1/search` and `/api/v2/search`)
|
||||||
|
- Mastodon API, streaming: Fix filtering of notifications based on blocks/mutes/thread mutes
|
||||||
- ActivityPub C2S: follower/following collection pages being inaccessible even when authentifucated if `hide_followers`/ `hide_follows` was set
|
- ActivityPub C2S: follower/following collection pages being inaccessible even when authentifucated if `hide_followers`/ `hide_follows` was set
|
||||||
- Existing user id not being preserved on insert conflict
|
- Existing user id not being preserved on insert conflict
|
||||||
- Rich Media: Parser failing when no TTL can be found by image TTL setters
|
- Rich Media: Parser failing when no TTL can be found by image TTL setters
|
||||||
|
|
|
@ -13,6 +13,7 @@ defmodule Pleroma.Web.Streamer do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.MastodonAPI.NotificationView
|
alias Pleroma.Web.MastodonAPI.NotificationView
|
||||||
|
|
||||||
@keepalive_interval :timer.seconds(30)
|
@keepalive_interval :timer.seconds(30)
|
||||||
|
@ -118,10 +119,14 @@ def handle_cast(
|
||||||
topics
|
topics
|
||||||
|> Map.get("#{topic}:#{item.user_id}", [])
|
|> Map.get("#{topic}:#{item.user_id}", [])
|
||||||
|> Enum.each(fn socket ->
|
|> Enum.each(fn socket ->
|
||||||
send(
|
with %User{} = user <- User.get_cached_by_ap_id(socket.assigns[:user].ap_id),
|
||||||
socket.transport_pid,
|
true <- should_send?(user, item),
|
||||||
{:text, represent_notification(socket.assigns[:user], item)}
|
false <- CommonAPI.thread_muted?(user, item.activity) do
|
||||||
)
|
send(
|
||||||
|
socket.transport_pid,
|
||||||
|
{:text, represent_notification(socket.assigns[:user], item)}
|
||||||
|
)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{:noreply, topics}
|
{:noreply, topics}
|
||||||
|
@ -225,19 +230,32 @@ defp represent_notification(%User{} = user, %Notification{} = notify) do
|
||||||
|> Jason.encode!()
|
|> Jason.encode!()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp should_send?(%User{} = user, %Activity{} = item) do
|
||||||
|
blocks = user.info.blocks || []
|
||||||
|
mutes = user.info.mutes || []
|
||||||
|
reblog_mutes = user.info.muted_reblogs || []
|
||||||
|
|
||||||
|
with parent when not is_nil(parent) <- Object.normalize(item),
|
||||||
|
true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)),
|
||||||
|
true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)),
|
||||||
|
true <- thread_containment(item, user) do
|
||||||
|
true
|
||||||
|
else
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp should_send?(%User{} = user, %Notification{activity: activity}) do
|
||||||
|
should_send?(user, activity)
|
||||||
|
end
|
||||||
|
|
||||||
def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = item) do
|
def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = item) do
|
||||||
Enum.each(topics[topic] || [], fn socket ->
|
Enum.each(topics[topic] || [], fn socket ->
|
||||||
# Get the current user so we have up-to-date blocks etc.
|
# Get the current user so we have up-to-date blocks etc.
|
||||||
if socket.assigns[:user] do
|
if socket.assigns[:user] do
|
||||||
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
||||||
blocks = user.info.blocks || []
|
|
||||||
mutes = user.info.mutes || []
|
|
||||||
reblog_mutes = user.info.muted_reblogs || []
|
|
||||||
|
|
||||||
with parent when not is_nil(parent) <- Object.normalize(item),
|
if should_send?(user, item) do
|
||||||
true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)),
|
|
||||||
true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)),
|
|
||||||
true <- thread_containment(item, user) do
|
|
||||||
send(socket.transport_pid, {:text, represent_update(item, user)})
|
send(socket.transport_pid, {:text, represent_update(item, user)})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -65,6 +65,44 @@ test "it sends notify to in the 'user:notification' stream", %{user: user, notif
|
||||||
Streamer.stream("user:notification", notify)
|
Streamer.stream("user:notification", notify)
|
||||||
Task.await(task)
|
Task.await(task)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{
|
||||||
|
user: user
|
||||||
|
} do
|
||||||
|
blocked = insert(:user)
|
||||||
|
{:ok, user} = User.block(user, blocked)
|
||||||
|
|
||||||
|
task = Task.async(fn -> refute_receive {:text, _}, 4_000 end)
|
||||||
|
|
||||||
|
Streamer.add_socket(
|
||||||
|
"user:notification",
|
||||||
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => ":("})
|
||||||
|
{:ok, notif, _} = CommonAPI.favorite(activity.id, blocked)
|
||||||
|
|
||||||
|
Streamer.stream("user:notification", notif)
|
||||||
|
Task.await(task)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it doesn't send notify to the 'user:notification' stream when a thread is muted", %{
|
||||||
|
user: user
|
||||||
|
} do
|
||||||
|
user2 = insert(:user)
|
||||||
|
task = Task.async(fn -> refute_receive {:text, _}, 4_000 end)
|
||||||
|
|
||||||
|
Streamer.add_socket(
|
||||||
|
"user:notification",
|
||||||
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
|
||||||
|
{:ok, activity} = CommonAPI.add_mute(user, activity)
|
||||||
|
{:ok, notif, _} = CommonAPI.favorite(activity.id, user2)
|
||||||
|
Streamer.stream("user:notification", notif)
|
||||||
|
Task.await(task)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it sends to public" do
|
test "it sends to public" do
|
||||||
|
|
Loading…
Reference in a new issue