Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-2
This commit is contained in:
commit
1aa8aa7d7f
|
@ -62,19 +62,21 @@ unit-testing:
|
|||
- mix ecto.migrate
|
||||
- mix coveralls --preload-modules
|
||||
|
||||
federated-testing:
|
||||
stage: test
|
||||
cache: *testing_cache_policy
|
||||
services:
|
||||
- name: minibikini/postgres-with-rum:12
|
||||
alias: postgres
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
script:
|
||||
- mix deps.get
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- epmd -daemon
|
||||
- mix test --trace --only federated
|
||||
# Removed to fix CI issue. In this early state it wasn't adding much value anyway.
|
||||
# TODO Fix and reinstate federated testing
|
||||
# federated-testing:
|
||||
# stage: test
|
||||
# cache: *testing_cache_policy
|
||||
# services:
|
||||
# - name: minibikini/postgres-with-rum:12
|
||||
# alias: postgres
|
||||
# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
# script:
|
||||
# - mix deps.get
|
||||
# - mix ecto.create
|
||||
# - mix ecto.migrate
|
||||
# - epmd -daemon
|
||||
# - mix test --trace --only federated
|
||||
|
||||
unit-testing-rum:
|
||||
stage: test
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
### Precheck
|
||||
|
||||
* For support use https://git.pleroma.social/pleroma/pleroma-support or [community channels](https://git.pleroma.social/pleroma/pleroma#community-channels).
|
||||
* Please do a quick search to ensure no similar bug has been reported before. If the bug has not been addressed after 2 weeks, it's fine to bump it.
|
||||
* Try to ensure that the bug is actually related to the Pleroma backend. For example, if a bug happens in Pleroma-FE but not in Mastodon-FE or mobile clients, it's likely that the bug should be filed in [Pleroma-FE](https://git.pleroma.social/pleroma/pleroma-fe/issues/new) repository.
|
||||
-->
|
||||
|
||||
### Environment
|
||||
|
||||
* Installation type:
|
||||
- [ ] OTP
|
||||
- [ ] From source
|
||||
* Pleroma version (could be found in the "Version" tab of settings in Pleroma-FE):
|
||||
* Elixir version (`elixir -v` for from source installations, N/A for OTP):
|
||||
* Operating system:
|
||||
* PostgreSQL version (`postgres -V`):
|
||||
|
||||
|
||||
### Bug description
|
|
@ -0,0 +1,5 @@
|
|||
### Release checklist
|
||||
* [ ] Bump version in `mix.exs`
|
||||
* [ ] Compile a changelog
|
||||
* [ ] Create an MR with an announcement to pleroma.social
|
||||
* [ ] Tag the release
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -7,6 +7,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Changed
|
||||
- **Breaking:** BBCode and Markdown formatters will no longer return any `\n` and only use `<br/>` for newlines
|
||||
|
||||
### Removed
|
||||
- **Breaking:** removed `with_move` parameter from notifications timeline.
|
||||
|
||||
### Added
|
||||
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
|
||||
<details>
|
||||
<summary>API Changes</summary>
|
||||
- Mastodon API: Support for `include_types` in `/api/v1/notifications`.
|
||||
</details>
|
||||
|
||||
## [2.0.0] - 2019-03-08
|
||||
### Security
|
||||
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
||||
|
|
|
@ -117,7 +117,7 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields:
|
|||
Accepts additional parameters:
|
||||
|
||||
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
|
||||
- `with_move`: boolean, when set to `true` will include Move notifications. `false` by default.
|
||||
- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`.
|
||||
|
||||
## POST `/api/v1/statuses`
|
||||
|
||||
|
|
|
@ -138,7 +138,8 @@ config :pleroma, :mrf_user_allowlist,
|
|||
```
|
||||
|
||||
#### :mrf_object_age
|
||||
* `threshold`: Required age (in seconds) of a post before actions are taken.
|
||||
* `threshold`: Required time offset (in seconds) compared to your server clock of an incoming post before actions are taken.
|
||||
e.g., A value of 900 results in any post with a timestamp older than 15 minutes will be acted upon.
|
||||
* `actions`: A list of actions to apply to the post:
|
||||
* `:delist` removes the post from public timelines
|
||||
* `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines
|
||||
|
|
|
@ -77,7 +77,6 @@ def for_user_query(user, opts \\ %{}) do
|
|||
|> exclude_notification_muted(user, exclude_notification_muted_opts)
|
||||
|> exclude_blocked(user, exclude_blocked_opts)
|
||||
|> exclude_visibility(opts)
|
||||
|> exclude_move(opts)
|
||||
end
|
||||
|
||||
defp exclude_blocked(query, user, opts) do
|
||||
|
@ -107,14 +106,6 @@ defp exclude_notification_muted(query, user, opts) do
|
|||
|> where([n, a, o, tm], is_nil(tm.user_id))
|
||||
end
|
||||
|
||||
defp exclude_move(query, %{with_move: true}) do
|
||||
query
|
||||
end
|
||||
|
||||
defp exclude_move(query, _opts) do
|
||||
where(query, [n, a], fragment("?->>'type' != 'Move'", a.data))
|
||||
end
|
||||
|
||||
@valid_visibilities ~w[direct unlisted public private]
|
||||
|
||||
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
||||
|
|
|
@ -55,6 +55,7 @@ def get_notifications(user, params \\ %{}) do
|
|||
|
||||
user
|
||||
|> Notification.for_user_query(options)
|
||||
|> restrict(:include_types, options)
|
||||
|> restrict(:exclude_types, options)
|
||||
|> restrict(:account_ap_id, options)
|
||||
|> Pagination.fetch_paginated(params)
|
||||
|
@ -69,10 +70,10 @@ def get_scheduled_activities(user, params \\ %{}) do
|
|||
defp cast_params(params) do
|
||||
param_types = %{
|
||||
exclude_types: {:array, :string},
|
||||
include_types: {:array, :string},
|
||||
exclude_visibilities: {:array, :string},
|
||||
reblogs: :boolean,
|
||||
with_muted: :boolean,
|
||||
with_move: :boolean,
|
||||
account_ap_id: :string
|
||||
}
|
||||
|
||||
|
@ -80,14 +81,16 @@ defp cast_params(params) do
|
|||
changeset.changes
|
||||
end
|
||||
|
||||
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
||||
ap_types =
|
||||
mastodon_types
|
||||
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
||||
|> Enum.filter(& &1)
|
||||
defp restrict(query, :include_types, %{include_types: mastodon_types = [_ | _]}) do
|
||||
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||
|
||||
query
|
||||
|> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||
where(query, [q, a], fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||
end
|
||||
|
||||
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
||||
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||
|
||||
where(query, [q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||
end
|
||||
|
||||
defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
||||
|
@ -95,4 +98,10 @@ defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
|||
end
|
||||
|
||||
defp restrict(query, _, _), do: query
|
||||
|
||||
defp convert_and_filter_mastodon_types(types) do
|
||||
types
|
||||
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
||||
|> Enum.filter(& &1)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,6 +60,7 @@ def raw_nodeinfo do
|
|||
"pleroma_explicit_addressing",
|
||||
"shareable_emoji_packs",
|
||||
"multifetch",
|
||||
"pleroma:api/v1/notifications:include_types_filter",
|
||||
if Config.get([:media_proxy, :enabled]) do
|
||||
"media_proxy"
|
||||
end,
|
||||
|
|
|
@ -667,7 +667,13 @@ test "move activity generates a notification" do
|
|||
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert [] = Notification.for_user(follower)
|
||||
assert [
|
||||
%{
|
||||
activity: %{
|
||||
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
||||
}
|
||||
}
|
||||
] = Notification.for_user(follower)
|
||||
|
||||
assert [
|
||||
%{
|
||||
|
@ -675,17 +681,7 @@ test "move activity generates a notification" do
|
|||
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
||||
}
|
||||
}
|
||||
] = Notification.for_user(follower, %{with_move: true})
|
||||
|
||||
assert [] = Notification.for_user(other_follower)
|
||||
|
||||
assert [
|
||||
%{
|
||||
activity: %{
|
||||
data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
|
||||
}
|
||||
}
|
||||
] = Notification.for_user(other_follower, %{with_move: true})
|
||||
] = Notification.for_user(other_follower)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1955,11 +1955,9 @@ test "create" do
|
|||
|
||||
activity = %Activity{activity | object: nil}
|
||||
|
||||
assert [%Notification{activity: ^activity}] =
|
||||
Notification.for_user(follower, %{with_move: true})
|
||||
assert [%Notification{activity: ^activity}] = Notification.for_user(follower)
|
||||
|
||||
assert [%Notification{activity: ^activity}] =
|
||||
Notification.for_user(follower_move_opted_out, %{with_move: true})
|
||||
assert [%Notification{activity: ^activity}] = Notification.for_user(follower_move_opted_out)
|
||||
end
|
||||
|
||||
test "old user must be in the new user's `also_known_as` list" do
|
||||
|
|
|
@ -304,6 +304,51 @@ test "filters notifications using exclude_types" do
|
|||
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||
end
|
||||
|
||||
test "filters notifications using include_types" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
|
||||
{:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user)
|
||||
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
mention_notification_id = get_notification_id_by_activity(mention_activity)
|
||||
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
|
||||
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
|
||||
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["follow"]})
|
||||
|
||||
assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["mention"]})
|
||||
|
||||
assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["favourite"]})
|
||||
|
||||
assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["reblog"]})
|
||||
|
||||
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||
|
||||
result = conn |> get("/api/v1/notifications") |> json_response(200)
|
||||
|
||||
assert length(result) == 4
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/notifications", %{
|
||||
include_types: ["follow", "mention", "favourite", "reblog"]
|
||||
})
|
||||
|> json_response(200)
|
||||
|
||||
assert length(result) == 4
|
||||
end
|
||||
|
||||
test "destroy multiple" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
@ -407,7 +452,7 @@ test "see notifications after muting user with notifications and with_muted para
|
|||
assert length(json_response(conn, 200)) == 1
|
||||
end
|
||||
|
||||
test "see move notifications with `with_move` parameter" do
|
||||
test "see move notifications" do
|
||||
old_user = insert(:user)
|
||||
new_user = insert(:user, also_known_as: [old_user.ap_id])
|
||||
%{user: follower, conn: conn} = oauth_access(["read:notifications"])
|
||||
|
@ -416,11 +461,7 @@ test "see move notifications with `with_move` parameter" do
|
|||
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
||||
Pleroma.Tests.ObanHelpers.perform_all()
|
||||
|
||||
ret_conn = get(conn, "/api/v1/notifications")
|
||||
|
||||
assert json_response(ret_conn, 200) == []
|
||||
|
||||
conn = get(conn, "/api/v1/notifications", %{"with_move" => "true"})
|
||||
conn = get(conn, "/api/v1/notifications")
|
||||
|
||||
assert length(json_response(conn, 200)) == 1
|
||||
end
|
||||
|
|
|
@ -120,7 +120,7 @@ test "Move notification" do
|
|||
old_user = refresh_record(old_user)
|
||||
new_user = refresh_record(new_user)
|
||||
|
||||
[notification] = Notification.for_user(follower, %{with_move: true})
|
||||
[notification] = Notification.for_user(follower)
|
||||
|
||||
expected = %{
|
||||
id: to_string(notification.id),
|
||||
|
|
Loading…
Reference in New Issue