Merge branch 'develop' into feature/admin-api-list-statuses-for-a-given-instance
This commit is contained in:
commit
fd24467b92
32 changed files with 411 additions and 59 deletions
|
@ -5,7 +5,6 @@ CC-BY-SA-4.0
|
|||
COPYING
|
||||
*file
|
||||
elixir_buildpack.config
|
||||
docs/
|
||||
test/
|
||||
|
||||
# Required to get version
|
||||
|
|
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- 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
|
||||
- Admin API: Support authentication via `x-admin-token` HTTP header
|
||||
- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`)
|
||||
- Mastodon API: `pleroma.thread_muted` to the Status entity
|
||||
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message
|
||||
|
@ -42,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Static Frontend: Add the ability to render user profiles and notices server-side without requiring JS app.
|
||||
- Mix task to re-count statuses for all users (`mix pleroma.count_statuses`)
|
||||
- Support for `X-Forwarded-For` and similar HTTP headers which used by reverse proxies to pass a real user IP address to the backend. Must not be enabled unless your instance is behind at least one reverse proxy (such as Nginx, Apache HTTPD or Varnish Cache).
|
||||
- MRF: New module which handles incoming posts based on their age. By default, all incoming posts that are older than 2 days will be unlisted and not shown to their followers.
|
||||
<details>
|
||||
<summary>API Changes</summary>
|
||||
|
||||
|
@ -80,6 +82,41 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Mastodon API: Inability to get some local users by nickname in `/api/v1/accounts/:id_or_nickname`
|
||||
</details>
|
||||
|
||||
## [1.1.6] - 2019-11-19
|
||||
### Fixed
|
||||
- Not being able to log into to third party apps when the browser is logged into mastofe
|
||||
- Email confirmation not being required even when enabled
|
||||
- Mastodon API: conversations API crashing when one status is malformed
|
||||
|
||||
### Bundled Pleroma-FE Changes
|
||||
#### Added
|
||||
- About page
|
||||
- Meme arrows
|
||||
|
||||
#### Fixed
|
||||
- Image modal not closing unless clicked outside of image
|
||||
- Attachment upload spinner not being centered
|
||||
- Showing follow counters being 0 when they are actually hidden
|
||||
|
||||
## [1.1.5] - 2019-11-09
|
||||
### Fixed
|
||||
- Polls having different numbers in timelines/notifications/poll api endpoints due to cache desyncronization
|
||||
- Pleroma API: OAuth token endpoint not being found when ".json" suffix is appended
|
||||
|
||||
### Changed
|
||||
- Frontend bundle updated to [044c9ad0](https://git.pleroma.social/pleroma/pleroma-fe/commit/044c9ad0562af059dd961d50961a3880fca9c642)
|
||||
|
||||
## [1.1.4] - 2019-11-01
|
||||
### Fixed
|
||||
- Added a migration that fills up empty user.info fields to prevent breakage after previous unsafe migrations.
|
||||
- Failure to migrate from pre-1.0.0 versions
|
||||
- Mastodon API: Notification stream not including follow notifications
|
||||
|
||||
## [1.1.3] - 2019-10-25
|
||||
### Fixed
|
||||
- Blocked users showing up in notifications collapsed as if they were muted
|
||||
- `pleroma_ctl` not working on Debian's default shell
|
||||
|
||||
## [1.1.2] - 2019-10-18
|
||||
### Fixed
|
||||
- `pleroma_ctl` trying to connect to a running instance when generating the config, which of course doesn't exist.
|
||||
|
|
|
@ -381,6 +381,10 @@
|
|||
accept: [],
|
||||
reject: []
|
||||
|
||||
config :pleroma, :mrf_object_age,
|
||||
threshold: 172_800,
|
||||
actions: [:delist, :strip_followers]
|
||||
|
||||
config :pleroma, :rich_media,
|
||||
enabled: true,
|
||||
ignore_hosts: [],
|
||||
|
|
|
@ -235,14 +235,6 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
|||
}
|
||||
```
|
||||
|
||||
## DEPRECATED `PATCH /api/pleroma/admin/users/:nickname/activation_status`
|
||||
|
||||
### Active or deactivate a user
|
||||
|
||||
- Params:
|
||||
- `nickname`
|
||||
- `status` BOOLEAN field, false value means deactivation.
|
||||
|
||||
## `GET /api/pleroma/admin/users/:nickname_or_id`
|
||||
|
||||
### Retrive the details of a user
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
Every command should be ran with a prefix, in case of OTP releases it is `./bin/pleroma_ctl database` and in case of source installs it's `mix pleroma.database`.
|
||||
|
||||
!!! danger
|
||||
These mix tasks can take a long time to complete. Many of them were written to address specific database issues that happened because of bugs in migrations or other specific scenarios. Do not run these tasks "just in case" if everything is fine your instance.
|
||||
|
||||
## Replace embedded objects with their references
|
||||
|
||||
Replaces embedded objects with references to them in the `objects` table. Only needs to be ran once if the instance was created before Pleroma 1.0.5. The reason why this is not a migration is because it could significantly increase the database size after being ran, however after this `VACUUM FULL` will be able to reclaim about 20% (really depends on what is in the database, your mileage may vary) of the db size before the migration.
|
||||
|
|
|
@ -41,6 +41,7 @@ You shouldn't edit the base config directly to avoid breakages and merge conflic
|
|||
* `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`: Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed.
|
||||
* `Pleroma.Web.ActivityPub.MRF.MentionPolicy`: Drops posts mentioning configurable users. (See [`:mrf_mention`](#mrf_mention)).
|
||||
* `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)).
|
||||
* `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)).
|
||||
* `public`: Makes the client API in authentificated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network.
|
||||
* `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send.
|
||||
* `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``.
|
||||
|
@ -137,6 +138,13 @@ config :pleroma, :mrf_user_allowlist,
|
|||
"example.org": ["https://example.org/users/admin"]
|
||||
```
|
||||
|
||||
#### :mrf_object_age
|
||||
* `threshold`: Required age (in seconds) of a post before actions are taken.
|
||||
* `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
|
||||
* `:reject` rejects the message entirely
|
||||
|
||||
### :activitypub
|
||||
* ``unfollow_blocked``: Whether blocks result in people getting unfollowed
|
||||
* ``outgoing_blocks``: Whether to federate blocks to other instances
|
||||
|
@ -648,7 +656,7 @@ Feel free to adjust the priv_dir and port number. Then you will have to create t
|
|||
|
||||
### :admin_token
|
||||
|
||||
Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter. Example:
|
||||
Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter or `x-admin-token` HTTP header. Example:
|
||||
|
||||
```elixir
|
||||
config :pleroma, :admin_token, "somerandomtoken"
|
||||
|
@ -656,8 +664,14 @@ config :pleroma, :admin_token, "somerandomtoken"
|
|||
|
||||
You can then do
|
||||
|
||||
```sh
|
||||
curl "http://localhost:4000/api/pleroma/admin/invite_token?admin_token=somerandomtoken"
|
||||
```shell
|
||||
curl "http://localhost:4000/api/pleroma/admin/users/invites?admin_token=somerandomtoken"
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```shell
|
||||
curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites"
|
||||
```
|
||||
|
||||
### :auth
|
||||
|
|
|
@ -16,14 +16,28 @@ def secret_token do
|
|||
|
||||
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
|
||||
|
||||
def call(%{params: %{"admin_token" => admin_token}} = conn, _) do
|
||||
if secret_token() && admin_token == secret_token() do
|
||||
conn
|
||||
|> assign(:user, %User{is_admin: true})
|
||||
def call(conn, _) do
|
||||
if secret_token() do
|
||||
authenticate(conn)
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, _), do: conn
|
||||
def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do
|
||||
if admin_token == secret_token() do
|
||||
assign(conn, :user, %User{is_admin: true})
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate(conn) do
|
||||
token = secret_token()
|
||||
|
||||
case get_req_header(conn, "x-admin-token") do
|
||||
[^token] -> assign(conn, :user, %User{is_admin: true})
|
||||
_ -> conn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -71,7 +71,7 @@ defp fetch_user_and_token(token) do
|
|||
)
|
||||
|
||||
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
|
||||
with %Token{user: %{deactivated: false} = user} = token_record <- Repo.one(query) do
|
||||
with %Token{user: user} = token_record <- Repo.one(query) do
|
||||
{:ok, user, token_record}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,9 +10,13 @@ def init(options) do
|
|||
options
|
||||
end
|
||||
|
||||
def call(%{assigns: %{user: %User{deactivated: true}}} = conn, _) do
|
||||
conn
|
||||
|> assign(:user, nil)
|
||||
def call(%{assigns: %{user: %User{} = user}} = conn, _) do
|
||||
if User.auth_active?(user) do
|
||||
conn
|
||||
else
|
||||
conn
|
||||
|> assign(:user, nil)
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, _) do
|
||||
|
|
|
@ -124,6 +124,9 @@ defmodule Pleroma.User do
|
|||
timestamps()
|
||||
end
|
||||
|
||||
@doc "Returns if the user should be allowed to authenticate"
|
||||
def auth_active?(%User{deactivated: true}), do: false
|
||||
|
||||
def auth_active?(%User{confirmation_pending: true}),
|
||||
do: !Pleroma.Config.get([:instance, :account_activation_required])
|
||||
|
||||
|
|
101
lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
Normal file
101
lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
Normal file
|
@ -0,0 +1,101 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
@moduledoc "Filter activities depending on their age"
|
||||
@behaviour MRF
|
||||
|
||||
defp check_date(%{"published" => published} = message) do
|
||||
with %DateTime{} = now <- DateTime.utc_now(),
|
||||
{:ok, %DateTime{} = then, _} <- DateTime.from_iso8601(published),
|
||||
max_ttl <- Config.get([:mrf_object_age, :threshold]),
|
||||
{:ttl, false} <- {:ttl, DateTime.diff(now, then) > max_ttl} do
|
||||
{:ok, message}
|
||||
else
|
||||
{:ttl, true} ->
|
||||
{:reject, nil}
|
||||
|
||||
e ->
|
||||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_reject(message, actions) do
|
||||
if :reject in actions do
|
||||
{:reject, nil}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_delist(message, actions) do
|
||||
if :delist in actions do
|
||||
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
|
||||
to = List.delete(message["to"], Pleroma.Constants.as_public()) ++ [user.follower_address]
|
||||
cc = List.delete(message["cc"], user.follower_address) ++ [Pleroma.Constants.as_public()]
|
||||
|
||||
message =
|
||||
message
|
||||
|> Map.put("to", to)
|
||||
|> Map.put("cc", cc)
|
||||
|
||||
{:ok, message}
|
||||
else
|
||||
# Unhandleable error: somebody is messing around, just drop the message.
|
||||
_e ->
|
||||
{:reject, nil}
|
||||
end
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_strip_followers(message, actions) do
|
||||
if :strip_followers in actions do
|
||||
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
|
||||
to = List.delete(message["to"], user.follower_address)
|
||||
cc = List.delete(message["cc"], user.follower_address)
|
||||
|
||||
message =
|
||||
message
|
||||
|> Map.put("to", to)
|
||||
|> Map.put("cc", cc)
|
||||
|
||||
{:ok, message}
|
||||
else
|
||||
# Unhandleable error: somebody is messing around, just drop the message.
|
||||
_e ->
|
||||
{:reject, nil}
|
||||
end
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "published" => _} = message) do
|
||||
with actions <- Config.get([:mrf_object_age, :actions]),
|
||||
{:reject, _} <- check_date(message),
|
||||
{:ok, message} <- check_reject(message, actions),
|
||||
{:ok, message} <- check_delist(message, actions),
|
||||
{:ok, message} <- check_strip_followers(message, actions) do
|
||||
{:ok, message}
|
||||
else
|
||||
# check_date() is allowed to short-circuit the pipeline
|
||||
e -> e
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(message), do: {:ok, message}
|
||||
|
||||
@impl true
|
||||
def describe, do: {:ok, %{}}
|
||||
end
|
|
@ -120,6 +120,12 @@ def raw_nodeinfo do
|
|||
banner: Config.get([:instance, :banner_upload_limit]),
|
||||
background: Config.get([:instance, :background_upload_limit])
|
||||
},
|
||||
fieldsLimits: %{
|
||||
maxFields: Config.get([:instance, :max_account_fields]),
|
||||
maxRemoteFields: Config.get([:instance, :max_remote_account_fields]),
|
||||
nameLength: Config.get([:instance, :account_field_name_length]),
|
||||
valueLength: Config.get([:instance, :account_field_value_length])
|
||||
},
|
||||
accountActivationRequired: Config.get([:instance, :account_activation_required], false),
|
||||
invitesEnabled: Config.get([:instance, :invites_enabled], false),
|
||||
mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false),
|
||||
|
|
|
@ -13,6 +13,7 @@ defmodule Pleroma.Web.Router do
|
|||
pipeline :oauth do
|
||||
plug(:fetch_session)
|
||||
plug(Pleroma.Plugs.OAuthPlug)
|
||||
plug(Pleroma.Plugs.UserEnabledPlug)
|
||||
end
|
||||
|
||||
pipeline :api do
|
||||
|
|
4
mix.lock
4
mix.lock
|
@ -35,8 +35,8 @@
|
|||
"ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"ex_syslogger": {:git, "https://github.com/slashmili/ex_syslogger.git", "f3963399047af17e038897c69e20d552e6899e1d", [tag: "1.4.0"]},
|
||||
"excoveralls": {:hex, :excoveralls, "0.11.2", "0c6f2c8db7683b0caa9d490fb8125709c54580b4255ffa7ad35f3264b075a643", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"fast_html": {:hex, :fast_html, "0.99.3", "e7ce6245fed0635f4719a31cc409091ed17b2091165a4a1cffbf2ceac77abbf4", [:make, :mix], [], "hexpm"},
|
||||
"fast_sanitize": {:hex, :fast_sanitize, "0.1.3", "e89a743b1679c344abdfcf79778d1499fbc599eca2d8a8cdfaf9ff520986fb72", [:mix], [{:fast_html, "~> 0.99", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"fast_html": {:hex, :fast_html, "0.99.4", "d80812664f0429607e1d880fba0ef04da87a2e4fa596701bcaae17953535695c", [:make, :mix], [], "hexpm"},
|
||||
"fast_sanitize": {:hex, :fast_sanitize, "0.1.4", "6c2e7203ca2f8275527a3021ba6e9d5d4ee213a47dc214a97c128737c9e56df1", [:mix], [{:fast_html, "~> 0.99", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"floki": {:hex, :floki, "0.23.0", "956ab6dba828c96e732454809fb0bd8d43ce0979b75f34de6322e73d4c917829", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm"},
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.fd71461124f3eb029b1b.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.5c3fab032deb5f2793cb.js></script><script type=text/javascript src=/static/js/app.105d64a8fcdd6724ccde.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.fd71461124f3eb029b1b.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.76db8e4cdf29decd5cab.js></script><script type=text/javascript src=/static/js/app.d20ca27d22d74eb7bce0.js></script></body></html>
|
|
@ -1,2 +1,2 @@
|
|||
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{1012:function(t,e,i){"use strict";i.r(e);var n=i(1013),c=i.n(n);for(var r in n)"default"!==r&&function(t){i.d(e,t,function(){return n[t]})}(r);var a=i(1016),s=i(0);var o=function(t){i(1014)},u=Object(s.a)(c.a,a.a,a.b,!1,o,null,null);e.default=u.exports},1013:function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=c(i(348));function c(t){return t&&t.__esModule?t:{default:t}}var r={components:{TabSwitcher:c(i(205)).default},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,c=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var r=new File([t],e,{mimetype:"image/png"}),a=new FormData;a.append("file",r),n.default.uploadMedia({store:c,formData:a}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}};e.default=r},1014:function(t,e,i){var n=i(1015);"string"==typeof n&&(n=[[t.i,n,""]]),n.locals&&(t.exports=n.locals);(0,i(2).default)("cc6cdea4",n,!0,{})},1015:function(t,e,i){(t.exports=i(1)(!1)).push([t.i,".sticker-picker{width:100%;position:relative}.sticker-picker .tab-switcher{position:absolute;top:0;bottom:0;left:0;right:0}.sticker-picker .sticker-picker-content .sticker{display:inline-block;width:20%;height:20%}.sticker-picker .sticker-picker-content .sticker img{width:100%}.sticker-picker .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--link,#d8a070))}",""])},1016:function(t,e,i){"use strict";i.d(e,"a",function(){return n}),i.d(e,"b",function(){return c});var n=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(n){return i("div",{key:n,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+n,e.meta.title)}}},[i("img",{attrs:{src:e.path+n}})])}),0)}),0)],1)},c=[]}}]);
|
||||
//# sourceMappingURL=2.73375b727cef616c59b4.js.map
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{1023:function(t,e,i){"use strict";i.r(e);var n=i(1024),c=i.n(n);for(var r in n)"default"!==r&&function(t){i.d(e,t,function(){return n[t]})}(r);var a=i(1027),s=i(0);var o=function(t){i(1025)},u=Object(s.a)(c.a,a.a,a.b,!1,o,null,null);e.default=u.exports},1024:function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=c(i(352));function c(t){return t&&t.__esModule?t:{default:t}}var r={components:{TabSwitcher:c(i(207)).default},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,c=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var r=new File([t],e,{mimetype:"image/png"}),a=new FormData;a.append("file",r),n.default.uploadMedia({store:c,formData:a}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}};e.default=r},1025:function(t,e,i){var n=i(1026);"string"==typeof n&&(n=[[t.i,n,""]]),n.locals&&(t.exports=n.locals);(0,i(2).default)("cc6cdea4",n,!0,{})},1026:function(t,e,i){(t.exports=i(1)(!1)).push([t.i,".sticker-picker{width:100%;position:relative}.sticker-picker .tab-switcher{position:absolute;top:0;bottom:0;left:0;right:0}.sticker-picker .sticker-picker-content .sticker{display:inline-block;width:20%;height:20%}.sticker-picker .sticker-picker-content .sticker img{width:100%}.sticker-picker .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--link,#d8a070))}",""])},1027:function(t,e,i){"use strict";i.d(e,"a",function(){return n}),i.d(e,"b",function(){return c});var n=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(n){return i("div",{key:n,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+n,e.meta.title)}}},[i("img",{attrs:{src:e.path+n}})])}),0)}),0)],1)},c=[]}}]);
|
||||
//# sourceMappingURL=2.c96b30ae9f2d3f46f0ad.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
priv/static/static/js/app.d20ca27d22d74eb7bce0.js
Normal file
2
priv/static/static/js/app.d20ca27d22d74eb7bce0.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/app.d20ca27d22d74eb7bce0.js.map
Normal file
1
priv/static/static/js/app.d20ca27d22d74eb7bce0.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
var serviceWorkerOption = {"assets":["/static/img/nsfw.74818f9.png","/static/css/app.fd71461124f3eb029b1b.css","/static/js/app.105d64a8fcdd6724ccde.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.5c3fab032deb5f2793cb.js","/static/js/2.73375b727cef616c59b4.js"]};
|
||||
var serviceWorkerOption = {"assets":["/static/img/nsfw.74818f9.png","/static/css/app.fd71461124f3eb029b1b.css","/static/js/app.d20ca27d22d74eb7bce0.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.76db8e4cdf29decd5cab.js","/static/js/2.c96b30ae9f2d3f46f0ad.js"]};
|
||||
|
||||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=0)}([function(e,n,t){"use strict";var r,o=t(1),i=(r=o)&&r.__esModule?r:{default:r};function a(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){return"window"===e.type})})}self.addEventListener("push",function(e){e.data&&e.waitUntil(i.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications}).then(function(n){return n&&a().then(function(n){var t=e.data.json();if(0===n.length)return self.registration.showNotification(t.title,t)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(a().then(function(e){for(var n=0;n<e.length;n++){var t=e[n];if("/"===t.url&&"focus"in t)return t.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,n){
|
||||
/*!
|
||||
|
|
|
@ -22,21 +22,39 @@ test "does nothing if a user is assigned", %{conn: conn} do
|
|||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "with secret set and given in the 'admin_token' parameter, it assigns an admin user", %{
|
||||
conn: conn
|
||||
} do
|
||||
Pleroma.Config.put(:admin_token, "password123")
|
||||
describe "when secret set it assigns an admin user" do
|
||||
test "with `admin_token` query parameter", %{conn: conn} do
|
||||
Pleroma.Config.put(:admin_token, "password123")
|
||||
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "wrong_password"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "wrong_password"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
refute conn.assigns[:user]
|
||||
refute conn.assigns[:user]
|
||||
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "password123"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "password123"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:user].is_admin
|
||||
assert conn.assigns[:user].is_admin
|
||||
end
|
||||
|
||||
test "with `x-admin-token` HTTP header", %{conn: conn} do
|
||||
Pleroma.Config.put(:admin_token, "☕️")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("x-admin-token", "🥛")
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
refute conn.assigns[:user]
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("x-admin-token", "☕️")
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:user].is_admin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,23 @@ test "doesn't do anything if the user isn't set", %{conn: conn} do
|
|||
assert ret_conn == conn
|
||||
end
|
||||
|
||||
test "with a user that's not confirmed and a config requiring confirmation, it removes that user",
|
||||
%{conn: conn} do
|
||||
old = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
|
||||
user = insert(:user, confirmation_pending: true)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> UserEnabledPlug.call(%{})
|
||||
|
||||
assert conn.assigns.user == nil
|
||||
|
||||
Pleroma.Config.put([:instance, :account_activation_required], old)
|
||||
end
|
||||
|
||||
test "with a user that is deactivated, it removes that user", %{conn: conn} do
|
||||
user = insert(:user, deactivated: true)
|
||||
|
||||
|
|
|
@ -1195,6 +1195,13 @@ test "auth_active?/1 works correctly" do
|
|||
refute User.auth_active?(local_user)
|
||||
assert User.auth_active?(confirmed_user)
|
||||
assert User.auth_active?(remote_user)
|
||||
|
||||
# also shows unactive for deactivated users
|
||||
|
||||
deactivated_but_confirmed =
|
||||
insert(:user, local: true, confirmation_pending: false, deactivated: true)
|
||||
|
||||
refute User.auth_active?(deactivated_but_confirmed)
|
||||
end
|
||||
|
||||
describe "superuser?/1" do
|
||||
|
|
105
test/web/activity_pub/mrf/object_age_policy_test.exs
Normal file
105
test/web/activity_pub/mrf/object_age_policy_test.exs
Normal file
|
@ -0,0 +1,105 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy
|
||||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
|
||||
clear_config([:mrf_object_age]) do
|
||||
Config.put(:mrf_object_age,
|
||||
threshold: 172_800,
|
||||
actions: [:delist, :strip_followers]
|
||||
)
|
||||
end
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "with reject action" do
|
||||
test "it rejects an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:reject, _} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with delist action" do
|
||||
test "it delists an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, data} = ObjectAgePolicy.filter(data)
|
||||
|
||||
assert Visibility.get_visibility(%{data: data}) == "unlisted"
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with strip_followers action" do
|
||||
test "it strips followers collections from an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, data} = ObjectAgePolicy.filter(data)
|
||||
|
||||
refute user.follower_address in data["to"]
|
||||
refute user.follower_address in data["cc"]
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.Web.MastodonAPI.FilterView
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
|
|
|
@ -61,6 +61,33 @@ test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do
|
|||
assert Pleroma.Application.repository() == result["software"]["repository"]
|
||||
end
|
||||
|
||||
test "returns fieldsLimits field", %{conn: conn} do
|
||||
max_account_fields = Pleroma.Config.get([:instance, :max_account_fields])
|
||||
max_remote_account_fields = Pleroma.Config.get([:instance, :max_remote_account_fields])
|
||||
account_field_name_length = Pleroma.Config.get([:instance, :account_field_name_length])
|
||||
account_field_value_length = Pleroma.Config.get([:instance, :account_field_value_length])
|
||||
|
||||
Pleroma.Config.put([:instance, :max_account_fields], 10)
|
||||
Pleroma.Config.put([:instance, :max_remote_account_fields], 15)
|
||||
Pleroma.Config.put([:instance, :account_field_name_length], 255)
|
||||
Pleroma.Config.put([:instance, :account_field_value_length], 2048)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/nodeinfo/2.1.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["metadata"]["fieldsLimits"]["maxFields"] == 10
|
||||
assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15
|
||||
assert response["metadata"]["fieldsLimits"]["nameLength"] == 255
|
||||
assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048
|
||||
|
||||
Pleroma.Config.put([:instance, :max_account_fields], max_account_fields)
|
||||
Pleroma.Config.put([:instance, :max_remote_account_fields], max_remote_account_fields)
|
||||
Pleroma.Config.put([:instance, :account_field_name_length], account_field_name_length)
|
||||
Pleroma.Config.put([:instance, :account_field_value_length], account_field_value_length)
|
||||
end
|
||||
|
||||
test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
|
||||
option = Pleroma.Config.get([:instance, :safe_dm_mentions])
|
||||
Pleroma.Config.put([:instance, :safe_dm_mentions], true)
|
||||
|
|
Loading…
Reference in a new issue