summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-06-15 07:57:58 +0000
committerlain <lain@soykaf.club>2020-06-15 12:05:09 +0200
commit43eb4144d601442b0edb7f7e87c2f50d64276e1e (patch)
tree43c28b196fa5ba62bf303dcc512e8cd0128bc526
parent271ea5068f4e3b901cb3f682e132378246daf452 (diff)
parentb15cfc3d365dcfa5f99159fe06e29de6f8aceb4f (diff)
Merge branch 'notifications-filtering' into 'develop'namespace-move-notification
Mastodon API return full result set in notifications See merge request pleroma/pleroma!2552
-rw-r--r--CHANGELOG.md2
-rw-r--r--docs/API/differences_in_mastoapi_responses.md2
-rw-r--r--lib/pleroma/notification.ex21
-rw-r--r--lib/pleroma/user.ex8
-rw-r--r--lib/pleroma/web/mastodon_api/views/notification_view.ex68
-rw-r--r--priv/repo/migrations/20200527163635_delete_notifications_from_invisible_users.exs18
-rw-r--r--test/notification_test.exs8
-rw-r--r--test/web/mastodon_api/controllers/notification_controller_test.exs27
-rw-r--r--test/web/mastodon_api/views/notification_view_test.exs6
9 files changed, 116 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9361fa260..3e2c5c2bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -49,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Filtering of push notifications on activities from blocked domains
- Resolving Peertube accounts with Webfinger
- `blob:` urls not being allowed by connect-src CSP
+- Mastodon API: fix `GET /api/v1/notifications` not returning the full result set
## [Unreleased (patch)]
@@ -179,6 +180,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking:** `/api/pleroma/admin/users/invite_token` now uses `POST`, changed accepted params and returns full invite in json instead of only token string.
- **Breaking** replying to reports is now "report notes", endpoint changed from `POST /api/pleroma/admin/reports/:id/respond` to `POST /api/pleroma/admin/reports/:id/notes`
- Mastodon API: stopped sanitizing display names, field names and subject fields since they are supposed to be treated as plaintext
+- **Breaking** The `move` notifications now have the type `pleroma:move`
- Admin API: Return `total` when querying for reports
- Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`)
- Admin API: Return link alongside with token on password reset
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index be3c802af..a0dc53fe9 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -106,7 +106,7 @@ Has these additional fields under the `pleroma` object:
### Move Notification
-The `type` value is `move`. Has an additional field:
+The `type` value is `pleroma:move`. Has an additional field:
- `target`: new account
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 3386a1933..ea09a0622 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -166,8 +166,16 @@ defmodule Pleroma.Notification do
query
|> join(:left, [n, a], mutated_activity in Pleroma.Activity,
on:
- fragment("?->>'context'", a.data) ==
- fragment("?->>'context'", mutated_activity.data) and
+ fragment(
+ "COALESCE((?->'object')->>'id', ?->>'object')",
+ a.data,
+ a.data
+ ) ==
+ fragment(
+ "COALESCE((?->'object')->>'id', ?->>'object')",
+ mutated_activity.data,
+ mutated_activity.data
+ ) and
fragment("(?->>'type' = 'Like' or ?->>'type' = 'Announce')", a.data, a.data) and
fragment("?->>'type'", mutated_activity.data) == "Create",
as: :mutated_activity
@@ -379,7 +387,7 @@ defmodule Pleroma.Notification do
"favourite"
"Move" ->
- "move"
+ "pleroma:move"
"EmojiReact" ->
"pleroma:emoji_reaction"
@@ -541,6 +549,7 @@ defmodule Pleroma.Notification do
def skip?(%Activity{} = activity, %User{} = user) do
[
:self,
+ :invisible,
:followers,
:follows,
:non_followers,
@@ -557,6 +566,12 @@ defmodule Pleroma.Notification do
activity.data["actor"] == user.ap_id
end
+ def skip?(:invisible, %Activity{} = activity, _) do
+ actor = activity.data["actor"]
+ user = User.get_cached_by_ap_id(actor)
+ User.invisible?(user)
+ end
+
def skip?(
:followers,
%Activity{} = activity,
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index c5c74d132..52ac9052b 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1488,6 +1488,7 @@ defmodule Pleroma.User do
end)
delete_user_activities(user)
+ delete_notifications_from_user_activities(user)
delete_outgoing_pending_follow_requests(user)
@@ -1576,6 +1577,13 @@ defmodule Pleroma.User do
})
end
+ def delete_notifications_from_user_activities(%User{ap_id: ap_id}) do
+ Notification
+ |> join(:inner, [n], activity in assoc(n, :activity))
+ |> where([n, a], fragment("? = ?", a.actor, ^ap_id))
+ |> Repo.delete_all()
+ end
+
def delete_user_activities(%User{ap_id: ap_id} = user) do
ap_id
|> Activity.Queries.by_actor()
diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex
index b11578623..6ace0edfa 100644
--- a/lib/pleroma/web/mastodon_api/views/notification_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex
@@ -46,6 +46,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
activities
|> Enum.filter(&(&1.data["type"] == "Move"))
|> Enum.map(&User.get_cached_by_ap_id(&1.data["target"]))
+ |> Enum.filter(& &1)
actors =
activities
@@ -84,50 +85,45 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
# Note: :relationships contain user mutes (needed for :muted flag in :status)
status_render_opts = %{relationships: opts[:relationships]}
- with %{id: _} = account <-
- AccountView.render(
- "show.json",
- %{user: actor, for: reading_user}
- ) do
- response = %{
- id: to_string(notification.id),
- type: notification.type,
- created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
- account: account,
- pleroma: %{
- is_seen: notification.seen
- }
+ account =
+ AccountView.render(
+ "show.json",
+ %{user: actor, for: reading_user}
+ )
+
+ response = %{
+ id: to_string(notification.id),
+ type: notification.type,
+ created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
+ account: account,
+ pleroma: %{
+ is_seen: notification.seen
}
+ }
- case notification.type do
- "mention" ->
- put_status(response, activity, reading_user, status_render_opts)
+ case notification.type do
+ "mention" ->
+ put_status(response, activity, reading_user, status_render_opts)
- "favourite" ->
- put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
+ "favourite" ->
+ put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
- "reblog" ->
- put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
+ "reblog" ->
+ put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
- "move" ->
- put_target(response, activity, reading_user, %{})
+ "pleroma:move" ->
+ put_target(response, activity, reading_user, %{})
- "pleroma:emoji_reaction" ->
- response
- |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
- |> put_emoji(activity)
+ "pleroma:emoji_reaction" ->
+ response
+ |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
+ |> put_emoji(activity)
- "pleroma:chat_mention" ->
- put_chat_message(response, activity, reading_user, status_render_opts)
+ "pleroma:chat_mention" ->
+ put_chat_message(response, activity, reading_user, status_render_opts)
- type when type in ["follow", "follow_request"] ->
- response
-
- _ ->
- nil
- end
- else
- _ -> nil
+ type when type in ["follow", "follow_request"] ->
+ response
end
end
diff --git a/priv/repo/migrations/20200527163635_delete_notifications_from_invisible_users.exs b/priv/repo/migrations/20200527163635_delete_notifications_from_invisible_users.exs
new file mode 100644
index 000000000..9e95a8111
--- /dev/null
+++ b/priv/repo/migrations/20200527163635_delete_notifications_from_invisible_users.exs
@@ -0,0 +1,18 @@
+defmodule Pleroma.Repo.Migrations.DeleteNotificationsFromInvisibleUsers do
+ use Ecto.Migration
+
+ import Ecto.Query
+ alias Pleroma.Repo
+
+ def up do
+ Pleroma.Notification
+ |> join(:inner, [n], activity in assoc(n, :activity))
+ |> where(
+ [n, a],
+ fragment("? in (SELECT ap_id FROM users WHERE invisible = true)", a.actor)
+ )
+ |> Repo.delete_all()
+ end
+
+ def down, do: :ok
+end
diff --git a/test/notification_test.exs b/test/notification_test.exs
index b9bbdceca..526f43fab 100644
--- a/test/notification_test.exs
+++ b/test/notification_test.exs
@@ -306,6 +306,14 @@ defmodule Pleroma.NotificationTest do
assert {:ok, []} == Notification.create_notifications(status)
end
+
+ test "it disables notifications from people who are invisible" do
+ author = insert(:user, invisible: true)
+ user = insert(:user)
+
+ {:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
+ refute Notification.create_notification(status, user)
+ end
end
describe "follow / follow_request notifications" do
diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs
index 698c99711..70ef0e8b5 100644
--- a/test/web/mastodon_api/controllers/notification_controller_test.exs
+++ b/test/web/mastodon_api/controllers/notification_controller_test.exs
@@ -313,6 +313,33 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert public_activity.id in activity_ids
refute unlisted_activity.id in activity_ids
end
+
+ test "doesn't return less than the requested amount of records when the user's reply is liked" do
+ user = insert(:user)
+ %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
+
+ {:ok, mention} =
+ CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "public"})
+
+ {:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
+
+ {:ok, reply} =
+ CommonAPI.post(other_user, %{
+ status: ".",
+ visibility: "public",
+ in_reply_to_status_id: activity.id
+ })
+
+ {:ok, _favorite} = CommonAPI.favorite(user, reply.id)
+
+ activity_ids =
+ conn
+ |> get("/api/v1/notifications?exclude_visibilities[]=direct&limit=2")
+ |> json_response_and_validate_schema(200)
+ |> Enum.map(& &1["status"]["id"])
+
+ assert [reply.id, mention.id] == activity_ids
+ end
end
test "filters notifications using exclude_types" do
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs
index b2fa5b302..aa1196db0 100644
--- a/test/web/mastodon_api/views/notification_view_test.exs
+++ b/test/web/mastodon_api/views/notification_view_test.exs
@@ -139,9 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], followed, [expected])
User.perform(:delete, follower)
- notification = Notification |> Repo.one() |> Repo.preload(:activity)
-
- test_notifications_rendering([notification], followed, [])
+ refute Repo.one(Notification)
end
@tag capture_log: true
@@ -174,7 +172,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
- type: "move",
+ type: "pleroma:move",
account: AccountView.render("show.json", %{user: old_user, for: follower}),
target: AccountView.render("show.json", %{user: new_user, for: follower}),
created_at: Utils.to_masto_date(notification.inserted_at)