Browse Source

Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-dms

1570-levenshtein-distance-user-search
lain 4 years ago
parent
commit
af6d01ec93
65 changed files with 447 additions and 155 deletions
  1. +1
    -1
      config/config.exs
  2. +17
    -1
      docs/API/admin_api.md
  3. +31
    -0
      docs/configuration/postgresql.md
  4. +2
    -2
      docs/installation/debian_based_en.md
  5. +2
    -2
      docs/installation/debian_based_jp.md
  6. +1
    -1
      docs/installation/otp_en.md
  7. +21
    -17
      lib/mix/tasks/pleroma/emoji.ex
  8. +1
    -4
      lib/pleroma/activity/queries.ex
  9. +1
    -1
      lib/pleroma/conversation.ex
  10. +1
    -1
      lib/pleroma/emoji/pack.ex
  11. +5
    -13
      lib/pleroma/notification.ex
  12. +62
    -20
      lib/pleroma/plugs/http_security_plug.ex
  13. +18
    -9
      lib/pleroma/user.ex
  14. +20
    -7
      lib/pleroma/web/activity_pub/activity_pub.ex
  15. +7
    -3
      lib/pleroma/web/activity_pub/transmogrifier.ex
  16. +5
    -4
      lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
  17. +1
    -1
      lib/pleroma/web/feed/user_controller.ex
  18. +1
    -1
      lib/pleroma/web/mastodon_api/controllers/account_controller.ex
  19. +2
    -2
      lib/pleroma/web/mastodon_api/controllers/status_controller.ex
  20. +7
    -5
      lib/pleroma/web/mastodon_api/views/account_view.ex
  21. +1
    -1
      lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex
  22. +2
    -0
      lib/pleroma/workers/cron/clear_oauth_token_worker.ex
  23. +2
    -0
      lib/pleroma/workers/cron/digest_emails_worker.ex
  24. +4
    -0
      lib/pleroma/workers/cron/new_users_digest_worker.ex
  25. +2
    -0
      lib/pleroma/workers/cron/purge_expired_activities_worker.ex
  26. +7
    -0
      priv/repo/migrations/20200526144426_add_apps_indexes.exs
  27. +8
    -0
      priv/repo/migrations/20200527104138_change_notification_user_index.exs
  28. +0
    -1
      priv/static/adminfe/chunk-3384.2278f87c.css
  29. +1
    -0
      priv/static/adminfe/chunk-3384.d50ed383.css
  30. +1
    -1
      priv/static/adminfe/chunk-7e30.f2b9674a.css
  31. +1
    -0
      priv/static/adminfe/chunk-e458.6c0703cb.css
  32. +0
    -1
      priv/static/adminfe/chunk-e458.f88bafea.css
  33. +1
    -1
      priv/static/adminfe/index.html
  34. +2
    -0
      priv/static/adminfe/static/js/app.0146039c.js
  35. +1
    -0
      priv/static/adminfe/static/js/app.0146039c.js.map
  36. +0
    -2
      priv/static/adminfe/static/js/app.203f69f8.js
  37. +0
    -1
      priv/static/adminfe/static/js/app.203f69f8.js.map
  38. +0
    -2
      priv/static/adminfe/static/js/chunk-3384.458ffaf1.js
  39. +0
    -1
      priv/static/adminfe/static/js/chunk-3384.458ffaf1.js.map
  40. +2
    -0
      priv/static/adminfe/static/js/chunk-3384.b2ebeeca.js
  41. +1
    -0
      priv/static/adminfe/static/js/chunk-3384.b2ebeeca.js.map
  42. +0
    -2
      priv/static/adminfe/static/js/chunk-4011.67fb1692.js
  43. +0
    -1
      priv/static/adminfe/static/js/chunk-4011.67fb1692.js.map
  44. +2
    -0
      priv/static/adminfe/static/js/chunk-7e30.ec42e302.js
  45. +1
    -0
      priv/static/adminfe/static/js/chunk-7e30.ec42e302.js.map
  46. +0
    -2
      priv/static/adminfe/static/js/chunk-e458.4e5aad44.js
  47. +0
    -1
      priv/static/adminfe/static/js/chunk-e458.4e5aad44.js.map
  48. +2
    -0
      priv/static/adminfe/static/js/chunk-e458.bb460d81.js
  49. +1
    -0
      priv/static/adminfe/static/js/chunk-e458.bb460d81.js.map
  50. +2
    -2
      priv/static/adminfe/static/js/runtime.b08eb412.js
  51. +1
    -1
      priv/static/adminfe/static/js/runtime.b08eb412.js.map
  52. +3
    -0
      test/instance_static/local_pack/files.json
  53. +10
    -0
      test/instance_static/local_pack/manifest.json
  54. +7
    -4
      test/notification_test.exs
  55. +1
    -0
      test/plugs/authentication_plug_test.exs
  56. +1
    -1
      test/plugs/http_security_plug_test.exs
  57. +2
    -1
      test/support/factory.ex
  58. +13
    -0
      test/tasks/emoji_test.exs
  59. +20
    -0
      test/user_test.exs
  60. +30
    -0
      test/web/activity_pub/activity_pub_controller_test.exs
  61. +19
    -14
      test/web/activity_pub/transmogrifier_test.exs
  62. +31
    -4
      test/web/admin_api/controllers/admin_api_controller_test.exs
  63. +25
    -1
      test/web/feed/user_controller_test.exs
  64. +31
    -4
      test/web/mastodon_api/views/account_view_test.exs
  65. +3
    -11
      test/web/media_proxy/media_proxy_test.exs

+ 1
- 1
config/config.exs View File

@@ -274,7 +274,7 @@ config :pleroma, :markup,
config :pleroma, :frontend_configurations,
pleroma_fe: %{
alwaysShowSubjectInput: true,
background: "/static/aurora_borealis.jpg",
background: "/images/city.jpg",
collapseMessageWithSubject: false,
disableChat: false,
greentext: false,


+ 17
- 1
docs/API/admin_api.md View File

@@ -511,7 +511,23 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- `discoverable`
- `actor_type`

- Response: none (code `200`)
- Response:

```json
{"status": "success"}
```

```json
{"errors":
{"actor_type": "is invalid"},
{"email": "has invalid format"},
...
}
```

```json
{"error": "Unable to update user."}
```

## `GET /api/pleroma/admin/reports`



+ 31
- 0
docs/configuration/postgresql.md View File

@@ -0,0 +1,31 @@
# Optimizing your PostgreSQL performance

Pleroma performance depends to a large extent on good database performance. The default PostgreSQL settings are mostly fine, but often you can get better performance by changing a few settings.

You can use [PGTune](https://pgtune.leopard.in.ua) to get recommendations for your setup. If you do, set the "Number of Connections" field to 20, as Pleroma will only use 10 concurrent connections anyway. If you don't, it will give you advice that might even hurt your performance.

We also recommend not using the "Network Storage" option.

## Example configurations

Here are some configuration suggestions for PostgreSQL 10+.

### 1GB RAM, 1 CPU
```
shared_buffers = 256MB
effective_cache_size = 768MB
maintenance_work_mem = 64MB
work_mem = 13107kB
```

### 2GB RAM, 2 CPU
```
shared_buffers = 512MB
effective_cache_size = 1536MB
maintenance_work_mem = 128MB
work_mem = 26214kB
max_worker_processes = 2
max_parallel_workers_per_gather = 1
max_parallel_workers = 2
```


+ 2
- 2
docs/installation/debian_based_en.md View File

@@ -38,8 +38,8 @@ sudo apt install git build-essential postgresql postgresql-contrib
* Download and add the Erlang repository:

```shell
wget -P /tmp/ https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i /tmp/erlang-solutions_1.0_all.deb
wget -P /tmp/ https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
sudo dpkg -i /tmp/erlang-solutions_2.0_all.deb
```

* Install Elixir and Erlang:


+ 2
- 2
docs/installation/debian_based_jp.md View File

@@ -40,8 +40,8 @@ sudo apt install git build-essential postgresql postgresql-contrib

* Erlangのリポジトリをダウンロードおよびインストールします。
```
wget -P /tmp/ https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i /tmp/erlang-solutions_1.0_all.deb
wget -P /tmp/ https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
sudo dpkg -i /tmp/erlang-solutions_2.0_all.deb
```

* ElixirとErlangをインストールします、


+ 1
- 1
docs/installation/otp_en.md View File

@@ -63,7 +63,7 @@ apt install postgresql-11-rum
```

#### (Optional) Performance configuration
For optimal performance, you may use [PGTune](https://pgtune.leopard.in.ua), don't forget to restart postgresql after editing the configuration
It is encouraged to check [Optimizing your PostgreSQL performance](../configuration/postgresql.md) document, for tips on PostgreSQL tuning.

```sh tab="Alpine"
rc-service postgresql restart


+ 21
- 17
lib/mix/tasks/pleroma/emoji.ex View File

@@ -15,7 +15,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do
{options, [], []} = parse_global_opts(args)

url_or_path = options[:manifest] || default_manifest()
manifest = fetch_manifest(url_or_path)
manifest = fetch_and_decode(url_or_path)

Enum.each(manifest, fn {name, info} ->
to_print = [
@@ -42,12 +42,12 @@ defmodule Mix.Tasks.Pleroma.Emoji do

url_or_path = options[:manifest] || default_manifest()

manifest = fetch_manifest(url_or_path)
manifest = fetch_and_decode(url_or_path)

for pack_name <- pack_names do
if Map.has_key?(manifest, pack_name) do
pack = manifest[pack_name]
src_url = pack["src"]
src = pack["src"]

IO.puts(
IO.ANSI.format([
@@ -57,11 +57,11 @@ defmodule Mix.Tasks.Pleroma.Emoji do
:normal,
" from ",
:underline,
src_url
src
])
)

binary_archive = Tesla.get!(client(), src_url).body
{:ok, binary_archive} = fetch(src)
archive_sha = :crypto.hash(:sha256, binary_archive) |> Base.encode16()

sha_status_text = ["SHA256 of ", :bright, pack_name, :normal, " source file is ", :bright]
@@ -74,8 +74,8 @@ defmodule Mix.Tasks.Pleroma.Emoji do
raise "Bad SHA256 for #{pack_name}"
end

# The url specified in files should be in the same directory
files_url =
# The location specified in files should be in the same directory
files_loc =
url_or_path
|> Path.dirname()
|> Path.join(pack["files"])
@@ -88,11 +88,11 @@ defmodule Mix.Tasks.Pleroma.Emoji do
:normal,
" from ",
:underline,
files_url
files_loc
])
)

files = Tesla.get!(client(), files_url).body |> Jason.decode!()
files = fetch_and_decode(files_loc)

IO.puts(IO.ANSI.format(["Unpacking ", :bright, pack_name]))

@@ -237,16 +237,20 @@ defmodule Mix.Tasks.Pleroma.Emoji do
end
end

defp fetch_manifest(from) do
Jason.decode!(
if String.starts_with?(from, "http") do
Tesla.get!(client(), from).body
else
File.read!(from)
end
)
defp fetch_and_decode(from) do
with {:ok, json} <- fetch(from) do
Jason.decode!(json)
end
end

defp fetch("http" <> _ = from) do
with {:ok, %{body: body}} <- Tesla.get(client(), from) do
{:ok, body}
end
end

defp fetch(path), do: File.read(path)

defp parse_global_opts(args) do
OptionParser.parse(
args,


+ 1
- 4
lib/pleroma/activity/queries.ex View File

@@ -24,10 +24,7 @@ defmodule Pleroma.Activity.Queries do

@spec by_actor(query, String.t()) :: query
def by_actor(query \\ Activity, actor) do
from(
activity in query,
where: fragment("(?)->>'actor' = ?", activity.data, ^actor)
)
from(a in query, where: a.actor == ^actor)
end

@spec by_author(query, User.t()) :: query


+ 1
- 1
lib/pleroma/conversation.ex View File

@@ -63,7 +63,7 @@ defmodule Pleroma.Conversation do
ap_id when is_binary(ap_id) and byte_size(ap_id) > 0 <- object.data["context"] do
{:ok, conversation} = create_for_ap_id(ap_id)

users = User.get_users_from_set(activity.recipients, false)
users = User.get_users_from_set(activity.recipients, local_only: false)

participations =
Enum.map(users, fn user ->


+ 1
- 1
lib/pleroma/emoji/pack.ex View File

@@ -499,7 +499,7 @@ defmodule Pleroma.Emoji.Pack do
if Base.decode16!(sha) == :crypto.hash(:sha256, archive) do
{:ok, archive}
else
{:error, :imvalid_checksum}
{:error, :invalid_checksum}
end
end
end


+ 5
- 13
lib/pleroma/notification.ex View File

@@ -92,8 +92,9 @@ defmodule Pleroma.Notification do
|> join(:left, [n, a], object in Object,
on:
fragment(
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
"(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
object.data,
a.data,
a.data
)
)
@@ -224,18 +225,8 @@ defmodule Pleroma.Notification do
|> Marker.multi_set_last_read_id(user, "notifications")
|> Repo.transaction()

Notification
for_user_query(user)
|> where([n], n.id in ^notification_ids)
|> join(:inner, [n], activity in assoc(n, :activity))
|> join(:left, [n, a], object in Object,
on:
fragment(
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
object.data,
a.data
)
)
|> preload([n, a, o], activity: {a, object: o})
|> Repo.all()
end

@@ -370,7 +361,8 @@ defmodule Pleroma.Notification do
when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact"] do
potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity)

potential_receivers = User.get_users_from_set(potential_receiver_ap_ids, local_only)
potential_receivers =
User.get_users_from_set(potential_receiver_ap_ids, local_only: local_only)

notification_enabled_ap_ids =
potential_receiver_ap_ids


+ 62
- 20
lib/pleroma/plugs/http_security_plug.ex View File

@@ -31,7 +31,7 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
{"x-content-type-options", "nosniff"},
{"referrer-policy", referrer_policy},
{"x-download-options", "noopen"},
{"content-security-policy", csp_string() <> ";"}
{"content-security-policy", csp_string()}
]

if report_uri do
@@ -43,23 +43,46 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
]
}

headers ++ [{"reply-to", Jason.encode!(report_group)}]
[{"reply-to", Jason.encode!(report_group)} | headers]
else
headers
end
end

static_csp_rules = [
"default-src 'none'",
"base-uri 'self'",
"frame-ancestors 'none'",
"style-src 'self' 'unsafe-inline'",
"font-src 'self'",
"manifest-src 'self'"
]

@csp_start [Enum.join(static_csp_rules, ";") <> ";"]

defp csp_string do
scheme = Config.get([Pleroma.Web.Endpoint, :url])[:scheme]
static_url = Pleroma.Web.Endpoint.static_url()
websocket_url = Pleroma.Web.Endpoint.websocket_url()
report_uri = Config.get([:http_security, :report_uri])

connect_src = "connect-src 'self' #{static_url} #{websocket_url}"
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"

{img_src, media_src} =
if Config.get([:media_proxy, :enabled]) &&
!Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do
sources = get_proxy_and_attachment_sources()
{[img_src, sources], [media_src, sources]}
else
{img_src, media_src}
end

connect_src = ["connect-src 'self' ", static_url, ?\s, websocket_url]

connect_src =
if Pleroma.Config.get(:env) == :dev do
connect_src <> " http://localhost:3035/"
[connect_src, " http://localhost:3035/"]
else
connect_src
end
@@ -71,27 +94,46 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
"script-src 'self'"
end

main_part = [
"default-src 'none'",
"base-uri 'self'",
"frame-ancestors 'none'",
"img-src 'self' data: blob: https:",
"media-src 'self' https:",
"style-src 'self' 'unsafe-inline'",
"font-src 'self'",
"manifest-src 'self'",
connect_src,
script_src
]
report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"]
insecure = if scheme == "https", do: "upgrade-insecure-requests"

@csp_start
|> add_csp_param(img_src)
|> add_csp_param(media_src)
|> add_csp_param(connect_src)
|> add_csp_param(script_src)
|> add_csp_param(insecure)
|> add_csp_param(report)
|> :erlang.iolist_to_binary()
end

defp get_proxy_and_attachment_sources do
media_proxy_whitelist =
Enum.reduce(Config.get([:media_proxy, :whitelist]), [], fn host, acc ->
add_source(acc, host)
end)

report = if report_uri, do: ["report-uri #{report_uri}; report-to csp-endpoint"], else: []
upload_base_url =
if Config.get([Pleroma.Upload, :base_url]),
do: URI.parse(Config.get([Pleroma.Upload, :base_url])).host

insecure = if scheme == "https", do: ["upgrade-insecure-requests"], else: []
s3_endpoint =
if Config.get([Pleroma.Upload, :uploader]) == Pleroma.Uploaders.S3,
do: URI.parse(Config.get([Pleroma.Uploaders.S3, :public_endpoint])).host

(main_part ++ report ++ insecure)
|> Enum.join("; ")
[]
|> add_source(upload_base_url)
|> add_source(s3_endpoint)
|> add_source(media_proxy_whitelist)
end

defp add_source(iodata, nil), do: iodata
defp add_source(iodata, source), do: [[?\s, source] | iodata]

defp add_csp_param(csp_iodata, nil), do: csp_iodata

defp add_csp_param(csp_iodata, param), do: [[param, ?;] | csp_iodata]

def warn_if_disabled do
unless Config.get([:http_security, :enabled]) do
Logger.warn("


+ 18
- 9
lib/pleroma/user.ex View File

@@ -538,9 +538,10 @@ defmodule Pleroma.User do
|> delete_change(:also_known_as)
|> unique_constraint(:email)
|> validate_format(:email, @email_regex)
|> validate_inclusion(:actor_type, ["Person", "Service"])
end

@spec update_as_admin(%User{}, map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
@spec update_as_admin(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()}
def update_as_admin(user, params) do
params = Map.put(params, "password_confirmation", params["password"])
changeset = update_as_admin_changeset(user, params)
@@ -561,7 +562,7 @@ defmodule Pleroma.User do
|> put_change(:password_reset_pending, false)
end

@spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
@spec reset_password(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()}
def reset_password(%User{} = user, params) do
reset_password(user, user, params)
end
@@ -1208,8 +1209,9 @@ defmodule Pleroma.User do

def increment_unread_conversation_count(_, user), do: {:ok, user}

@spec get_users_from_set([String.t()], boolean()) :: [User.t()]
def get_users_from_set(ap_ids, local_only \\ true) do
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
def get_users_from_set(ap_ids, opts \\ []) do
local_only = Keyword.get(opts, :local_only, true)
criteria = %{ap_id: ap_ids, deactivated: false}
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria

@@ -1618,12 +1620,19 @@ defmodule Pleroma.User do
def fetch_by_ap_id(ap_id), do: ActivityPub.make_user_from_ap_id(ap_id)

def get_or_fetch_by_ap_id(ap_id) do
user = get_cached_by_ap_id(ap_id)
cached_user = get_cached_by_ap_id(ap_id)

if !is_nil(user) and !needs_update?(user) do
{:ok, user}
else
fetch_by_ap_id(ap_id)
maybe_fetched_user = needs_update?(cached_user) && fetch_by_ap_id(ap_id)

case {cached_user, maybe_fetched_user} do
{_, {:ok, %User{} = user}} ->
{:ok, user}

{%User{} = user, _} ->
{:ok, user}

_ ->
{:error, :not_found}
end
end



+ 20
- 7
lib/pleroma/web/activity_pub/activity_pub.ex View File

@@ -545,14 +545,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Repo.one()
end

@spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
@spec fetch_public_or_unlisted_activities(map(), Pagination.type()) :: [Activity.t()]
def fetch_public_or_unlisted_activities(opts \\ %{}, pagination \\ :keyset) do
opts = Map.drop(opts, ["user"])

[Constants.as_public()]
|> fetch_activities_query(opts)
|> restrict_unlisted()
|> Pagination.fetch_paginated(opts, pagination)
query = fetch_activities_query([Constants.as_public()], opts)

query =
if opts["restrict_unlisted"] do
restrict_unlisted(query)
else
query
end

Pagination.fetch_paginated(query, opts, pagination)
end

@spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
opts
|> Map.put("restrict_unlisted", true)
|> fetch_public_or_unlisted_activities(pagination)
end

@valid_visibilities ~w[direct unlisted public private]
@@ -1165,7 +1178,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Activity.with_joined_object()
|> Object.with_joined_activity()
|> select([_like, object, activity], %{activity | object: object})
|> order_by([like, _, _], desc: like.id)
|> order_by([like, _, _], desc_nulls_last: like.id)
|> Pagination.fetch_paginated(
Map.merge(params, %{"skip_order" => true}),
pagination,


+ 7
- 3
lib/pleroma/web/activity_pub/transmogrifier.ex View File

@@ -1055,10 +1055,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
Map.put(object, "tag", tags)
end

# TODO These should be added on our side on insertion, it doesn't make much
# sense to regenerate these all the time
def add_mention_tags(object) do
{enabled_receivers, disabled_receivers} = Utils.get_notified_from_object(object)
potential_receivers = enabled_receivers ++ disabled_receivers
mentions = Enum.map(potential_receivers, &build_mention_tag/1)
to = object["to"] || []
cc = object["cc"] || []
mentioned = User.get_users_from_set(to ++ cc, local_only: false)

mentions = Enum.map(mentioned, &build_mention_tag/1)

tags = object["tag"] || []
Map.put(object, "tag", tags ++ mentions)


+ 5
- 4
lib/pleroma/web/admin_api/controllers/admin_api_controller.ex View File

@@ -693,7 +693,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
%{assigns: %{user: admin}} = conn,
%{"nickname" => nickname} = params
) do
with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
with {_, %User{} = user} <- {:user, User.get_cached_by_nickname(nickname)},
{:ok, _user} <-
User.update_as_admin(user, params) do
ModerationLog.insert_log(%{
@@ -715,11 +715,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
json(conn, %{status: "success"})
else
{:error, changeset} ->
{_, {error, _}} = Enum.at(changeset.errors, 0)
json(conn, %{error: "New password #{error}."})
errors = Map.new(changeset.errors, fn {key, {error, _}} -> {key, error} end)

json(conn, %{errors: errors})

_ ->
json(conn, %{error: "Unable to change password."})
json(conn, %{error: "Unable to update user."})
end
end



+ 1
- 1
lib/pleroma/web/feed/user_controller.ex View File

@@ -56,7 +56,7 @@ defmodule Pleroma.Web.Feed.UserController do
"actor_id" => user.ap_id
}
|> put_if_exist("max_id", params["max_id"])
|> ActivityPub.fetch_public_activities()
|> ActivityPub.fetch_public_or_unlisted_activities()

conn
|> put_resp_content_type("application/#{format}+xml")


+ 1
- 1
lib/pleroma/web/mastodon_api/controllers/account_controller.ex View File

@@ -81,7 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do

plug(
RateLimiter,
[name: :relation_id_action, params: ["id", "uri"]] when action in @relationship_actions
[name: :relation_id_action, params: [:id, :uri]] when action in @relationship_actions
)

plug(RateLimiter, [name: :relations_actions] when action in @relationship_actions)


+ 2
- 2
lib/pleroma/web/mastodon_api/controllers/status_controller.ex View File

@@ -84,13 +84,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do

plug(
RateLimiter,
[name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: ["id"]]
[name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: [:id]]
when action in ~w(reblog unreblog)a
)

plug(
RateLimiter,
[name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: ["id"]]
[name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: [:id]]
when action in ~w(favourite unfavourite)a
)



+ 7
- 5
lib/pleroma/web/mastodon_api/views/account_view.ex View File

@@ -182,12 +182,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
bot = user.actor_type in ["Application", "Service"]

emojis =
Enum.map(user.emoji, fn {shortcode, url} ->
Enum.map(user.emoji, fn {shortcode, raw_url} ->
url = MediaProxy.url(raw_url)

%{
"shortcode" => shortcode,
"url" => url,
"static_url" => url,
"visible_in_picker" => false
shortcode: shortcode,
url: url,
static_url: url,
visible_in_picker: false
}
end)



+ 1
- 1
lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex View File

@@ -106,7 +106,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
|> put_status(:internal_server_error)
|> json(%{error: "The requested instance does not support sharing emoji packs"})

{:error, :imvalid_checksum} ->
{:error, :invalid_checksum} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "SHA256 for the pack doesn't match the one sent by the server"})


+ 2
- 0
lib/pleroma/workers/cron/clear_oauth_token_worker.ex View File

@@ -16,6 +16,8 @@ defmodule Pleroma.Workers.Cron.ClearOauthTokenWorker do
def perform(_opts, _job) do
if Config.get([:oauth2, :clean_expired_tokens], false) do
Token.delete_expired_tokens()
else
:ok
end
end
end

+ 2
- 0
lib/pleroma/workers/cron/digest_emails_worker.ex View File

@@ -37,6 +37,8 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorker do
)
|> Repo.all()
|> send_emails
else
:ok
end
end



+ 4
- 0
lib/pleroma/workers/cron/new_users_digest_worker.ex View File

@@ -55,7 +55,11 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorker do
|> Repo.all()
|> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
|> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
else
:ok
end
else
:ok
end
end
end

+ 2
- 0
lib/pleroma/workers/cron/purge_expired_activities_worker.ex View File

@@ -23,6 +23,8 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker do
def perform(_opts, _job) do
if Config.get([ActivityExpiration, :enabled]) do
Enum.each(ActivityExpiration.due_expirations(@interval), &delete_activity/1)
else
:ok
end
end



+ 7
- 0
priv/repo/migrations/20200526144426_add_apps_indexes.exs View File

@@ -0,0 +1,7 @@
defmodule Pleroma.Repo.Migrations.AddAppsIndexes do
use Ecto.Migration

def change do
create(index(:apps, [:client_id, :client_secret]))
end
end

+ 8
- 0
priv/repo/migrations/20200527104138_change_notification_user_index.exs View File

@@ -0,0 +1,8 @@
defmodule Pleroma.Repo.Migrations.ChangeNotificationUserIndex do
use Ecto.Migration

def change do
drop_if_exists(index(:notifications, [:user_id]))
create_if_not_exists(index(:notifications, [:user_id, "id desc nulls last"]))
end
end

+ 0
- 1
priv/static/adminfe/chunk-3384.2278f87c.css
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/chunk-3384.d50ed383.css
File diff suppressed because it is too large
View File


priv/static/adminfe/chunk-7e30.f2b9674a.css
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/chunk-e458.6c0703cb.css View File

@@ -0,0 +1 @@
.status-card{margin-bottom:10px}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-checkbox{margin-right:7px}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media only screen and (max-width:480px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.statuses-container{padding:0 15px}.statuses-container h1{margin:10px 0 15px}.statuses-container .status-container{margin:0 0 10px}.statuses-header-container .el-button.is-plain:focus,.statuses-header-container .el-button.is-plain:hover{border-color:#dcdfe6;color:#606266;cursor:default}.checkbox-container{margin-bottom:15px}.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 0 15px}.reboot-button{padding:10px;margin:0;width:145px}.select-instance{width:396px}.statuses-header,.statuses-header-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.statuses-pagination{padding:15px 0;text-align:center}@media only screen and (max-width:480px){.checkbox-container{margin-bottom:10px}.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:10px 0}.select-field{width:100%;margin-bottom:5px}.select-instance{width:100%}.statuses-header-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.statuses-header-container .el-button-group{width:100%}.statuses-header-container .el-button{padding:10px 6.5px;width:50%}.statuses-header-container .el-button-group>.el-button:first-child{border-bottom-left-radius:0}.statuses-header-container .el-button-group>.el-button:not(:first-child):not(:last-child).private-button{border-top-right-radius:4px}.statuses-header-container .el-button-group>.el-button:not(:first-child):not(:last-child).public-button{border-bottom-left-radius:4px;border-top:#fff}.statuses-header-container .el-button-group>.el-button:last-child{border-top-right-radius:0;border-top:#fff}.statuses-header-container .reboot-button{margin:10px 0 0}}

+ 0
- 1
priv/static/adminfe/chunk-e458.f88bafea.css View File

@@ -1 +0,0 @@
.status-card{margin-bottom:10px}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-checkbox{margin-right:7px}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media only screen and (max-width:480px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.statuses-container{padding:0 15px}.statuses-container h1{margin:10px 0 15px}.statuses-container .status-container{margin:0 0 10px}.checkbox-container{margin-bottom:15px}.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 0 15px}.reboot-button{padding:10px;margin:0;width:145px}.select-instance{width:396px}.statuses-header,.statuses-header-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.statuses-pagination{padding:15px 0;text-align:center}@media only screen and (max-width:480px){.checkbox-container{margin-bottom:10px}.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:10px 0}.select-field{width:100%;margin-bottom:5px}.select-instance{width:100%}.statuses-header-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.statuses-header-container .el-button{padding:10px 6.5px}.statuses-header-container .reboot-button{margin:10px 0 0}}

+ 1
- 1
priv/static/adminfe/index.html View File

@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.686b5876.css rel=stylesheet><link href=app.796ca6d4.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.1b4f6ce0.js></script><script type=text/javascript src=static/js/chunk-elementUI.fba0efec.js></script><script type=text/javascript src=static/js/chunk-libs.b8c453ab.js></script><script type=text/javascript src=static/js/app.203f69f8.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.686b5876.css rel=stylesheet><link href=app.796ca6d4.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.b08eb412.js></script><script type=text/javascript src=static/js/chunk-elementUI.fba0efec.js></script><script type=text/javascript src=static/js/chunk-libs.b8c453ab.js></script><script type=text/javascript src=static/js/app.0146039c.js></script></body></html>

+ 2
- 0
priv/static/adminfe/static/js/app.0146039c.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/static/js/app.0146039c.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/adminfe/static/js/app.203f69f8.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/adminfe/static/js/app.203f69f8.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/adminfe/static/js/chunk-3384.458ffaf1.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/adminfe/static/js/chunk-3384.458ffaf1.js.map
File diff suppressed because it is too large
View File


+ 2
- 0
priv/static/adminfe/static/js/chunk-3384.b2ebeeca.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/static/js/chunk-3384.b2ebeeca.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/adminfe/static/js/chunk-4011.67fb1692.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/adminfe/static/js/chunk-4011.67fb1692.js.map
File diff suppressed because it is too large
View File


+ 2
- 0
priv/static/adminfe/static/js/chunk-7e30.ec42e302.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/static/js/chunk-7e30.ec42e302.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/adminfe/static/js/chunk-e458.4e5aad44.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/adminfe/static/js/chunk-e458.4e5aad44.js.map
File diff suppressed because it is too large
View File


+ 2
- 0
priv/static/adminfe/static/js/chunk-e458.bb460d81.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/adminfe/static/js/chunk-e458.bb460d81.js.map
File diff suppressed because it is too large
View File


priv/static/adminfe/static/js/runtime.1b4f6ce0.js → priv/static/adminfe/static/js/runtime.b08eb412.js View File

@@ -1,2 +1,2 @@
!function(e){function n(n){for(var r,c,a=n[0],f=n[1],h=n[2],i=0,l=[];i<a.length;i++)c=a[i],u[c]&&l.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);for(d&&d(n);l.length;)l.shift()();return o.push.apply(o,h||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[];c[e]?n.push(c[e]):0!==c[e]&&{"chunk-6b68":1,"chunk-d38a":1,"chunk-0558":1,"chunk-0778":1,"chunk-3384":1,"chunk-6e81":1,"chunk-4011":1,"chunk-970d":1,"chunk-22d2":1,"chunk-e458":1,"chunk-7637":1,"chunk-0961":1}[e]&&n.push(c[e]=new Promise(function(n,t){for(var r=({}[e]||e)+"."+{"7zzA":"31d6cfe0",JEtC:"31d6cfe0",ZhIB:"31d6cfe0","chunk-6b68":"0cc00484","chunk-d38a":"cabdc22e","chunk-0558":"af0d89cd","chunk-0778":"d9e7180a","chunk-3384":"2278f87c","chunk-6e81":"0e80d020","chunk-7f9e":"31d6cfe0","chunk-4011":"c4799067","chunk-df62":"31d6cfe0","chunk-970d":"f59cca8c","chunk-22d2":"813009b9","chunk-e458":"f88bafea","chunk-7637":"941c4edb",oAJy:"31d6cfe0","chunk-0961":"d3692214","chunk-16d0":"31d6cfe0"}[e]+".css",c=a.p+r,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(i=u[o]).getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(f===r||f===c))return n()}var h=document.getElementsByTagName("style");for(o=0;o<h.length;o++){var i;if((f=(i=h[o]).getAttribute("data-href"))===r||f===c)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var r=n&&n.target&&n.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.request=r,t(u)},d.href=c,document.getElementsByTagName("head")[0].appendChild(d)}).then(function(){c[e]=0}));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var r=new Promise(function(n,r){t=u[e]=[n,r]});n.push(t[2]=r);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{"7zzA":"e1ae1c94",JEtC:"f9ba4594",ZhIB:"861df339","chunk-6b68":"fbc0f684","chunk-d38a":"a851004a","chunk-0558":"75954137","chunk-0778":"b17650df","chunk-3384":"458ffaf1","chunk-6e81":"3733ace2","chunk-7f9e":"c49aa694","chunk-4011":"67fb1692","chunk-df62":"6c5105a6","chunk-970d":"2457e066","chunk-22d2":"a0cf7976","chunk-e458":"4e5aad44","chunk-7637":"8f5fb36e",oAJy:"840fb1c2","chunk-0961":"ef33e81b","chunk-16d0":"6ce78978"}[e]+".js"}(e),o=function(n){f.onerror=f.onload=null,clearTimeout(h);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var h=setTimeout(function(){o({type:"timeout",target:f})},12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],h=f.push.bind(f);f.push=n,f=f.slice();for(var i=0;i<f.length;i++)n(f[i]);var d=h;t()}([]);
//# sourceMappingURL=runtime.1b4f6ce0.js.map
!function(e){function n(n){for(var r,c,a=n[0],f=n[1],h=n[2],i=0,l=[];i<a.length;i++)c=a[i],u[c]&&l.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);for(d&&d(n);l.length;)l.shift()();return o.push.apply(o,h||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[];c[e]?n.push(c[e]):0!==c[e]&&{"chunk-6b68":1,"chunk-d38a":1,"chunk-0558":1,"chunk-0778":1,"chunk-3384":1,"chunk-6e81":1,"chunk-7e30":1,"chunk-e458":1,"chunk-970d":1,"chunk-22d2":1,"chunk-7637":1,"chunk-0961":1}[e]&&n.push(c[e]=new Promise(function(n,t){for(var r=({}[e]||e)+"."+{"7zzA":"31d6cfe0",JEtC:"31d6cfe0",ZhIB:"31d6cfe0","chunk-6b68":"0cc00484","chunk-d38a":"cabdc22e","chunk-0558":"af0d89cd","chunk-0778":"d9e7180a","chunk-3384":"d50ed383","chunk-6e81":"0e80d020","chunk-7f9e":"31d6cfe0","chunk-7e30":"f2b9674a","chunk-df62":"31d6cfe0","chunk-e458":"6c0703cb","chunk-970d":"f59cca8c","chunk-22d2":"813009b9","chunk-7637":"941c4edb",oAJy:"31d6cfe0","chunk-0961":"d3692214","chunk-16d0":"31d6cfe0"}[e]+".css",c=a.p+r,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(i=u[o]).getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(f===r||f===c))return n()}var h=document.getElementsByTagName("style");for(o=0;o<h.length;o++){var i;if((f=(i=h[o]).getAttribute("data-href"))===r||f===c)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var r=n&&n.target&&n.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.request=r,t(u)},d.href=c,document.getElementsByTagName("head")[0].appendChild(d)}).then(function(){c[e]=0}));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var r=new Promise(function(n,r){t=u[e]=[n,r]});n.push(t[2]=r);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{"7zzA":"e1ae1c94",JEtC:"f9ba4594",ZhIB:"861df339","chunk-6b68":"fbc0f684","chunk-d38a":"a851004a","chunk-0558":"75954137","chunk-0778":"b17650df","chunk-3384":"b2ebeeca","chunk-6e81":"3733ace2","chunk-7f9e":"c49aa694","chunk-7e30":"ec42e302","chunk-df62":"6c5105a6","chunk-e458":"bb460d81","chunk-970d":"2457e066","chunk-22d2":"a0cf7976","chunk-7637":"8f5fb36e",oAJy:"840fb1c2","chunk-0961":"ef33e81b","chunk-16d0":"6ce78978"}[e]+".js"}(e),o=function(n){f.onerror=f.onload=null,clearTimeout(h);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var h=setTimeout(function(){o({type:"timeout",target:f})},12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],h=f.push.bind(f);f.push=n,f=f.slice();for(var i=0;i<f.length;i++)n(f[i]);var d=h;t()}([]);
//# sourceMappingURL=runtime.b08eb412.js.map

priv/static/adminfe/static/js/runtime.b08eb412.js.map
File diff suppressed because it is too large
View File


+ 3
- 0
test/instance_static/local_pack/files.json View File

@@ -0,0 +1,3 @@
{
"blank": "blank.png"
}

+ 10
- 0
test/instance_static/local_pack/manifest.json View File

@@ -0,0 +1,10 @@
{
"local": {
"src_sha256": "384025A1AC6314473863A11AC7AB38A12C01B851A3F82359B89B4D4211D3291D",
"src": "test/fixtures/emoji/packs/blank.png.zip",
"license": "Apache 2.0",
"homepage": "https://example.com",
"files": "files.json",
"description": "Some local pack"
}
}

+ 7
- 4
test/notification_test.exs View File

@@ -454,8 +454,7 @@ defmodule Pleroma.NotificationTest do
status: "hey again @#{other_user.nickname}!"
})

[n2, n1] = notifs = Notification.for_user(other_user)
assert length(notifs) == 2
[n2, n1] = Notification.for_user(other_user)

assert n2.id > n1.id

@@ -464,7 +463,9 @@ defmodule Pleroma.NotificationTest do
status: "hey yet again @#{other_user.nickname}!"
})

Notification.set_read_up_to(other_user, n2.id)
[_, read_notification] = Notification.set_read_up_to(other_user, n2.id)

assert read_notification.activity.object

[n3, n2, n1] = Notification.for_user(other_user)

@@ -972,7 +973,9 @@ defmodule Pleroma.NotificationTest do

{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})

assert length(Notification.for_user(user)) == 1
[notification] = Notification.for_user(user)

assert notification.activity.object
end

test "it doesn't return notifications for muted user with notifications" do


+ 1
- 0
test/plugs/authentication_plug_test.exs View File

@@ -68,6 +68,7 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
assert "$pbkdf2" <> _ = user.password_hash
end

@tag :skip_on_mac
test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
user =
insert(:user,


+ 1
- 1
test/plugs/http_security_plug_test.exs View File

@@ -67,7 +67,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do

[csp] = Conn.get_resp_header(conn, "content-security-policy")

assert csp =~ ~r|report-uri https://endpoint.com; report-to csp-endpoint;|
assert csp =~ ~r|report-uri https://endpoint.com;report-to csp-endpoint;|

[reply_to] = Conn.get_resp_header(conn, "reply-to")



+ 2
- 1
test/support/factory.ex View File

@@ -34,7 +34,8 @@ defmodule Pleroma.Factory do
last_digest_emailed_at: NaiveDateTime.utc_now(),
last_refreshed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{},
multi_factor_authentication_settings: %Pleroma.MFA.Settings{}
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
ap_enabled: true
}

%{


+ 13
- 0
test/tasks/emoji_test.exs View File

@@ -73,6 +73,19 @@ defmodule Mix.Tasks.Pleroma.EmojiTest do
on_exit(fn -> File.rm_rf!("test/instance_static/emoji/finmoji") end)
end

test "install local emoji pack" do
assert capture_io(fn ->
Emoji.run([
"get-packs",
"local",
"--manifest",
"test/instance_static/local_pack/manifest.json"
])
end) =~ "Writing pack.json for"

on_exit(fn -> File.rm_rf!("test/instance_static/emoji/local") end)
end

test "pack not found" do
mock(fn
%{


+ 20
- 0
test/user_test.exs View File

@@ -586,6 +586,26 @@ defmodule Pleroma.UserTest do

refute user.last_refreshed_at == orig_user.last_refreshed_at
end

@tag capture_log: true
test "it returns the old user if stale, but unfetchable" do
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)

orig_user =
insert(
:user,
local: false,
nickname: "admin@mastodon.example.org",
ap_id: "http://mastodon.example.org/users/raymoo",
last_refreshed_at: a_week_ago
)

assert orig_user.last_refreshed_at == a_week_ago

{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/raymoo")

assert user.last_refreshed_at == orig_user.last_refreshed_at
end
end

test "returns an ap_id for a user" do


+ 30
- 0
test/web/activity_pub/activity_pub_controller_test.exs View File

@@ -451,6 +451,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert Activity.get_by_ap_id(data["id"])
end

@tag capture_log: true
test "it inserts an incoming activity into the database" <>
"even if we can't fetch the user but have it in our db",
%{conn: conn} do
user =
insert(:user,
ap_id: "https://mastodon.example.org/users/raymoo",
ap_enabled: true,
local: false,
last_refreshed_at: nil
)

data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("actor", user.ap_id)
|> put_in(["object", "attridbutedTo"], user.ap_id)

conn =
conn
|> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json")
|> post("/inbox", data)

assert "ok" == json_response(conn, 200)

ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end

test "it clears `unreachable` federation status of the sender", %{conn: conn} do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()



+ 19
- 14
test/web/activity_pub/transmogrifier_test.exs View File

@@ -1094,23 +1094,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} =
CommonAPI.post(user, %{status: "hey, @#{other_user.nickname}, how are ya? #2hu"})

{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
object = modified["object"]
with_mock Pleroma.Notification,
get_notified_from_activity: fn _, _ -> [] end do
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)

expected_mention = %{
"href" => other_user.ap_id,
"name" => "@#{other_user.nickname}",
"type" => "Mention"
}
object = modified["object"]

expected_tag = %{
"href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
"type" => "Hashtag",
"name" => "#2hu"
}
expected_mention = %{
"href" => other_user.ap_id,
"name" => "@#{other_user.nickname}",
"type" => "Mention"
}

assert Enum.member?(object["tag"], expected_tag)
assert Enum.member?(object["tag"], expected_mention)
expected_tag = %{
"href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
"type" => "Hashtag",
"name" => "#2hu"
}

refute called(Pleroma.Notification.get_notified_from_activity(:_, :_))
assert Enum.member?(object["tag"], expected_tag)
assert Enum.member?(object["tag"], expected_mention)
end
end

test "it adds the sensitive property" do


+ 31
- 4
test/web/admin_api/controllers/admin_api_controller_test.exs View File

@@ -3191,8 +3191,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end

describe "PATCH /users/:nickname/credentials" do
test "changes password and email", %{conn: conn, admin: admin} do
setup do
user = insert(:user)
[user: user]
end

test "changes password and email", %{conn: conn, admin: admin, user: user} do
assert user.password_reset_pending == false

conn =
@@ -3222,9 +3226,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"@#{admin.nickname} forced password reset for users: @#{user.nickname}"
end

test "returns 403 if requested by a non-admin" do
user = insert(:user)

test "returns 403 if requested by a non-admin", %{user: user} do
conn =
build_conn()
|> assign(:user, user)
@@ -3236,6 +3238,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do

assert json_response(conn, :forbidden)
end

test "changes actor type from permitted list", %{conn: conn, user: user} do
assert user.actor_type == "Person"

assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
"actor_type" => "Service"
})
|> json_response(200) == %{"status" => "success"}

updated_user = User.get_by_id(user.id)

assert updated_user.actor_type == "Service"

assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
"actor_type" => "Application"
})
|> json_response(200) == %{"errors" => %{"actor_type" => "is invalid"}}
end

test "update non existing user", %{conn: conn} do
assert patch(conn, "/api/pleroma/admin/users/non-existing/credentials", %{
"password" => "new_password"
})
|> json_response(200) == %{"error" => "Unable to update user."}
end
end

describe "PATCH /users/:nickname/force_password_reset" do


+ 25
- 1
test/web/feed/user_controller_test.exs View File

@@ -11,13 +11,14 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
alias Pleroma.Config
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI

setup do: clear_config([:instance, :federating], true)

describe "feed" do
setup do: clear_config([:feed])

test "gets a feed", %{conn: conn} do
test "gets an atom feed", %{conn: conn} do
Config.put(
[:feed, :post_title],
%{max_length: 10, omission: "..."}
@@ -157,6 +158,29 @@ defmodule Pleroma.Web.Feed.UserControllerTest do

assert response(conn, 404)
end

test "returns feed with public and unlisted activities", %{conn: conn} do
user = insert(:user)

{:ok, _} = CommonAPI.post(user, %{status: "public", visibility: "public"})
{:ok, _} = CommonAPI.post(user, %{status: "direct", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: "unlisted", visibility: "unlisted"})
{:ok, _} = CommonAPI.post(user, %{status: "private", visibility: "private"})

resp =
conn
|> put_req_header("accept", "application/atom+xml")
|> get(user_feed_path(conn, :feed, user.nickname))
|> response(200)

activity_titles =
resp
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
|> Enum.sort()

assert activity_titles == ['public', 'unlisted']
end
end

# Note: see ActivityPubControllerTest for JSON format tests


+ 31
- 4
test/web/mastodon_api/views/account_view_test.exs View File

@@ -54,10 +54,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
header_static: "http://localhost:4001/images/banner.png",
emojis: [
%{
"static_url" => "/file.png",
"url" => "/file.png",
"shortcode" => "karjalanpiirakka",
"visible_in_picker" => false
static_url: "/file.png",
url: "/file.png",
shortcode: "karjalanpiirakka",
visible_in_picker: false
}
],
fields: [],
@@ -493,4 +493,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
AccountView.render("show.json", %{user: user, for: user})
end
end

test "uses mediaproxy urls when it's enabled" do
clear_config([:media_proxy, :enabled], true)

user =
insert(:user,
avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
banner: %{"url" => [%{"href" => "https://evil.website/banner.png"}]},
emoji: %{"joker_smile" => "https://evil.website/society.png"}
)

AccountView.render("show.json", %{user: user})
|> Enum.all?(fn
{key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
String.starts_with?(url, Pleroma.Web.base_url())

{:emojis, emojis} ->
Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
String.starts_with?(url, Pleroma.Web.base_url()) &&
String.starts_with?(static_url, Pleroma.Web.base_url())
end)

_ ->
true
end)
|> assert()
end
end

+ 3
- 11
test/web/media_proxy/media_proxy_test.exs View File

@@ -124,15 +124,7 @@ defmodule Pleroma.Web.MediaProxyTest do
end

test "uses the configured base_url" do
base_url = Pleroma.Config.get([:media_proxy, :base_url])

if base_url do
on_exit(fn ->
Pleroma.Config.put([:media_proxy, :base_url], base_url)
end)
end

Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social")
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")

url = "https://pleroma.soykaf.com/static/logo.png"
encoded = url(url)
@@ -213,8 +205,8 @@ defmodule Pleroma.Web.MediaProxyTest do
end

test "does not change whitelisted urls" do
Pleroma.Config.put([:media_proxy, :whitelist], ["mycdn.akamai.com"])
Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social")
clear_config([:media_proxy, :whitelist], ["mycdn.akamai.com"])
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")

media_url = "https://mycdn.akamai.com"



Loading…
Cancel
Save