<%= label f, :code, "Recovery code" %>
- <%= text_input f, :code %>
+ <%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, spellcheck: false] %>
<%= hidden_input f, :mfa_token, value: @mfa_token %>
<%= hidden_input f, :state, value: @state %>
<%= hidden_input f, :redirect_uri, value: @redirect_uri %>
diff --git a/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex b/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex
index af6e546b0..af85777eb 100644
--- a/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex
+++ b/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex
@@ -10,7 +10,7 @@
<%= form_for @conn, mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
<%= label f, :code, "Authentication code" %>
- <%= text_input f, :code %>
+ <%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %>
<%= hidden_input f, :mfa_token, value: @mfa_token %>
<%= hidden_input f, :state, value: @state %>
<%= hidden_input f, :redirect_uri, value: @redirect_uri %>
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 5cfb385ac..2294d9d0d 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -19,6 +19,7 @@ def register_user(params, opts \\ []) do
|> Map.put(:nickname, params[:username])
|> Map.put(:name, Map.get(params, :fullname, params[:username]))
|> Map.put(:password_confirmation, params[:password])
+ |> Map.put(:registration_reason, params[:reason])
if Pleroma.Config.get([:instance, :registrations_open]) do
create_user(params, opts)
@@ -44,6 +45,7 @@ defp create_user(params, opts) do
case User.register(changeset) do
{:ok, user} ->
+ maybe_notify_admins(user)
{:ok, user}
{:error, changeset} ->
@@ -56,6 +58,18 @@ defp create_user(params, opts) do
end
end
+ defp maybe_notify_admins(%User{} = account) do
+ if Pleroma.Config.get([:instance, :account_approval_required]) do
+ User.all_superusers()
+ |> Enum.filter(fn user -> not is_nil(user.email) end)
+ |> Enum.each(fn superuser ->
+ superuser
+ |> Pleroma.Emails.AdminEmail.new_unapproved_registration(account)
+ |> Pleroma.Emails.Mailer.deliver_async()
+ end)
+ end
+ end
+
def password_reset(nickname_or_email) do
with true <- is_binary(nickname_or_email),
%User{local: true, email: email} = user when is_binary(email) <-
diff --git a/lib/pleroma/web/views/masto_fe_view.ex b/lib/pleroma/web/views/masto_fe_view.ex
index f739dacb6..b1669d198 100644
--- a/lib/pleroma/web/views/masto_fe_view.ex
+++ b/lib/pleroma/web/views/masto_fe_view.ex
@@ -9,36 +9,6 @@ defmodule Pleroma.Web.MastoFEView do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.CustomEmojiView
- @default_settings %{
- onboarded: true,
- home: %{
- shows: %{
- reblog: true,
- reply: true
- }
- },
- notifications: %{
- alerts: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
- },
- shows: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
- },
- sounds: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
- }
- }
- }
-
def initial_state(token, user, custom_emojis) do
limit = Config.get([:instance, :limit])
@@ -86,7 +56,7 @@ def initial_state(token, user, custom_emojis) do
"video\/mp4"
]
},
- settings: user.mastofe_settings || @default_settings,
+ settings: user.mastofe_settings || %{},
push_subscription: nil,
accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)},
custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis),
diff --git a/mix.exs b/mix.exs
index 52b4cf268..aab833c5e 100644
--- a/mix.exs
+++ b/mix.exs
@@ -114,64 +114,52 @@ defp oauth_deps do
# Type `mix help deps` for examples and options.
defp deps do
[
- {:phoenix, "~> 1.4.8"},
+ {:phoenix, "~> 1.4.17"},
{:tzdata, "~> 1.0.3"},
- {:plug_cowboy, "~> 2.0"},
+ {:plug_cowboy, "~> 2.3"},
{:phoenix_pubsub, "~> 1.1"},
{:phoenix_ecto, "~> 4.0"},
{:ecto_enum, "~> 1.4"},
{:ecto_sql, "~> 3.4.4"},
- {:postgrex, ">= 0.13.5"},
+ {:postgrex, ">= 0.15.5"},
{:oban, "~> 2.0.0"},
- {:gettext, "~> 0.15"},
- {:pbkdf2_elixir, "~> 1.0"},
- {:bcrypt_elixir, "~> 2.0"},
+ {:gettext, "~> 0.18"},
+ {:pbkdf2_elixir, "~> 1.2"},
+ {:bcrypt_elixir, "~> 2.2"},
{:trailing_format_plug, "~> 0.0.7"},
{:fast_sanitize, "~> 0.1"},
{:html_entities, "~> 0.5", override: true},
- {:phoenix_html, "~> 2.10"},
- {:calendar, "~> 0.17.4"},
+ {:phoenix_html, "~> 2.14"},
+ {:calendar, "~> 1.0"},
{:cachex, "~> 3.2"},
{:poison, "~> 3.0", override: true},
- # {:tesla, "~> 1.3", override: true},
{:tesla,
github: "teamon/tesla", ref: "af3707078b10793f6a534938e56b963aff82fe3c", override: true},
{:castore, "~> 0.1"},
- {:cowlib, "~> 2.8", override: true},
+ {:cowlib, "~> 2.9", override: true},
{:gun,
github: "ninenines/gun", ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327", override: true},
- {:jason, "~> 1.0"},
- {:mogrify, "~> 0.6.1"},
+ {:jason, "~> 1.2"},
+ {:mogrify, "~> 0.7.4"},
{:ex_aws, "~> 2.1"},
{:ex_aws_s3, "~> 2.0"},
{:sweet_xml, "~> 0.6.6"},
- {:earmark, "~> 1.3"},
+ {:earmark, "1.4.3"},
{:bbcode_pleroma, "~> 0.2.0"},
- {:ex_machina, "~> 2.3", only: :test},
- {:credo, "~> 1.1.0", only: [:dev, :test], runtime: false},
- {:mock, "~> 0.3.3", only: :test},
{:crypt,
- git: "https://github.com/msantos/crypt", ref: "f63a705f92c26955977ee62a313012e309a4d77a"},
- {:cors_plug, "~> 1.5"},
- {:ex_doc, "~> 0.21", only: :dev, runtime: false},
- {:web_push_encryption, "~> 0.2.1"},
- {:swoosh,
- git: "https://github.com/swoosh/swoosh",
- ref: "c96e0ca8a00d8f211ec1f042a4626b09f249caa5",
- override: true},
- {:phoenix_swoosh, "~> 0.2"},
+ git: "https://github.com/msantos/crypt.git",
+ ref: "f63a705f92c26955977ee62a313012e309a4d77a"},
+ {:cors_plug, "~> 2.0"},
+ {:web_push_encryption, "~> 0.3"},
+ {:swoosh, "~> 1.0"},
+ {:phoenix_swoosh, "~> 0.3"},
{:gen_smtp, "~> 0.13"},
- {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test},
{:ex_syslogger, "~> 1.4"},
- {:floki, "~> 0.25"},
- {:timex, "~> 3.5"},
+ {:floki, "~> 0.27"},
+ {:timex, "~> 3.6"},
{:ueberauth, "~> 0.4"},
- {:auto_linker,
- git: "https://git.pleroma.social/pleroma/auto_linker.git",
- ref: "95e8188490e97505c56636c1379ffdf036c1fdde"},
- {:http_signatures,
- git: "https://git.pleroma.social/pleroma/http_signatures.git",
- ref: "293d77bb6f4a67ac8bde1428735c3b42f22cbb30"},
+ {:linkify, "~> 0.2.0"},
+ {:http_signatures, "~> 0.1.0"},
{:telemetry, "~> 0.3"},
{:poolboy, "~> 1.5"},
{:prometheus, "~> 4.6"},
@@ -183,26 +171,33 @@ defp deps do
{:quack, "~> 0.1.1"},
{:joken, "~> 2.0"},
{:benchee, "~> 1.0"},
- {:pot, "~> 0.10.2"},
+ {:pot, "~> 0.11"},
{:esshd, "~> 0.1.0", runtime: Application.get_env(:esshd, :enabled, false)},
{:ex_const, "~> 0.2"},
{:plug_static_index_html, "~> 1.0.0"},
- {:excoveralls, "~> 0.12.1", only: :test},
{:flake_id, "~> 0.1.0"},
{:concurrent_limiter,
- git: "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter",
- ref: "8eee96c6ba39b9286ec44c51c52d9f2758951365"},
+ git: "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git",
+ ref: "55e92f84b4ed531bd487952a71040a9c69dc2807"},
{:remote_ip,
git: "https://git.pleroma.social/pleroma/remote_ip.git",
ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"},
{:captcha,
git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git",
ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"},
- {:mox, "~> 0.5", only: :test},
{:restarter, path: "./restarter"},
{:open_api_spex,
git: "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git",
- ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"}
+ ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"},
+
+ ## dev & test
+ {:ex_doc, "~> 0.22", only: :dev, runtime: false},
+ {:ex_machina, "~> 2.4", only: :test},
+ {:credo, "~> 1.4", only: [:dev, :test], runtime: false},
+ {:mock, "~> 0.3.5", only: :test},
+ {:excoveralls, "~> 0.13.1", only: :test},
+ {:mox, "~> 0.5", only: :test},
+ {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test}
] ++ oauth_deps()
end
@@ -219,7 +214,8 @@ defp aliases do
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"],
- docs: ["pleroma.docs", "docs"]
+ docs: ["pleroma.docs", "docs"],
+ analyze: ["credo --strict --only=warnings,todo,fixme,consistency,readability"]
]
end
@@ -233,10 +229,10 @@ defp aliases do
defp version(version) do
identifier_filter = ~r/[^0-9a-z\-]+/i
- {_cmdgit, cmdgit_err} = System.cmd("sh", ["-c", "command -v git"])
+ git_available? = match?({_output, 0}, System.cmd("sh", ["-c", "command -v git"]))
git_pre_release =
- if cmdgit_err == 0 do
+ if git_available? do
{tag, tag_err} =
System.cmd("git", ["describe", "--tags", "--abbrev=0"], stderr_to_stdout: true)
@@ -262,7 +258,7 @@ defp version(version) do
# Branch name as pre-release version component, denoted with a dot
branch_name =
- with 0 <- cmdgit_err,
+ with true <- git_available?,
{branch_name, 0} <- System.cmd("git", ["rev-parse", "--abbrev-ref", "HEAD"]),
branch_name <- String.trim(branch_name),
branch_name <- System.get_env("PLEROMA_BUILD_BRANCH") || branch_name,
diff --git a/mix.lock b/mix.lock
index 8dd37a40f..55c3c59c6 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,6 +1,5 @@
%{
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"},
- "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]},
"base62": {:hex, :base62, "1.2.1", "4866763e08555a7b3917064e9eef9194c41667276c51b59de2bc42c6ea65f806", [:mix], [{:custom_base, "~> 0.2.1", [hex: :custom_base, repo: "hexpm", optional: false]}], "hexpm", "3b29948de2013d3f93aa898c884a9dff847e7aec75d9d6d8c1dc4c61c2716c42"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"bbcode": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/bbcode.git", "f2d267675e9a7e1ad1ea9beb4cc23382762b66c2", [ref: "v0.2.0"]},
@@ -9,25 +8,26 @@
"benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"cachex": {:hex, :cachex, "3.2.0", "a596476c781b0646e6cb5cd9751af2e2974c3e0d5498a8cab71807618b74fe2f", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "aef93694067a43697ae0531727e097754a9e992a1e7946296f5969d6dd9ac986"},
- "calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "738d0e17a93c2ccfe4ddc707bdc8e672e9074c8569498483feb1c4530fb91b2b"},
+ "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"},
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]},
- "castore": {:hex, :castore, "0.1.5", "591c763a637af2cc468a72f006878584bc6c306f8d111ef8ba1d4c10e0684010", [:mix], [], "hexpm", "6db356b2bc6cc22561e051ff545c20ad064af57647e436650aa24d7d06cd941a"},
+ "castore": {:hex, :castore, "0.1.7", "1ca19eee705cde48c9e809e37fdd0730510752cc397745e550f6065a56a701e9", [:mix], [], "hexpm", "a2ae2c13d40e9c308387f1aceb14786dca019ebc2a11484fb2a9f797ea0aa0d8"},
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"},
- "concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter", "8eee96c6ba39b9286ec44c51c52d9f2758951365", [ref: "8eee96c6ba39b9286ec44c51c52d9f2758951365"]},
+ "concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "55e92f84b4ed531bd487952a71040a9c69dc2807", [ref: "55e92f84b4ed531bd487952a71040a9c69dc2807"]},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
- "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9af027d20dc12dd0c4345a6b87247e0c62965871feea0bfecf9764648b02cc69"},
- "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"},
- "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
- "credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0bbd3222607ccaaac5c0340f7f525c627ae4d7aee6c8c8c108922620c5b6446"},
+ "cors_plug": {:hex, :cors_plug, "2.0.2", "2b46083af45e4bc79632bd951550509395935d3e7973275b2b743bd63cc942ce", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f0d0e13f71c51fd4ef8b2c7e051388e4dfb267522a83a22392c856de7e46465f"},
+ "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
+ "cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
+ "credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
- "crypt": {:git, "https://github.com/msantos/crypt", "f63a705f92c26955977ee62a313012e309a4d77a", [ref: "f63a705f92c26955977ee62a313012e309a4d77a"]},
+ "crypt": {:git, "https://github.com/msantos/crypt.git", "f63a705f92c26955977ee62a313012e309a4d77a", [ref: "f63a705f92c26955977ee62a313012e309a4d77a"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
+ "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"},
"ecto": {:hex, :ecto, "3.4.5", "2bcd262f57b2c888b0bd7f7a28c8a48aa11dc1a2c6a858e45dd8f8426d504265", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8c6d1d4d524559e9b7a062f0498e2c206122552d63eacff0a6567ffe7a8e8691"},
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
"ecto_sql": {:hex, :ecto_sql, "3.4.5", "30161f81b167d561a9a2df4329c10ae05ff36eca7ccc84628f2c8b9fa1e43323", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "31990c6a3579b36a3c0841d34a94c275e727de8b84f58509da5f1b2032c98ac2"},
@@ -35,27 +35,27 @@
"esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"},
"eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"},
"ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"},
- "ex_aws": {:hex, :ex_aws, "2.1.1", "1e4de2106cfbf4e837de41be41cd15813eabc722315e388f0d6bb3732cec47cd", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "06b6fde12b33bb6d65d5d3493e903ba5a56d57a72350c15285a4298338089e10"},
+ "ex_aws": {:hex, :ex_aws, "2.1.3", "26b6f036f0127548706aade4a509978fc7c26bd5334b004fba9bfe2687a525df", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "0bdbe2aed9f326922fc5a6a80417e32f0c895f4b3b2b0b9676ebf23dd16c5da4"},
"ex_aws_s3": {:hex, :ex_aws_s3, "2.0.2", "c0258bbdfea55de4f98f0b2f0ca61fe402cc696f573815134beb1866e778f47b", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "0569f5b211b1a3b12b705fe2a9d0e237eb1360b9d76298028df2346cad13097a"},
"ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"},
- "ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"},
- "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", "b84f6af156264530b312a8ab98ac6088f6b77ae5fe2058305c81434aa01fbaf9"},
+ "ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"},
+ "ex_machina": {:hex, :ex_machina, "2.4.0", "09a34c5d371bfb5f78399029194a8ff67aff340ebe8ba19040181af35315eabb", [: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", "a20bc9ddc721b33ea913b93666c5d0bdca5cbad7a67540784ae277228832d72c"},
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
- "excoveralls": {:hex, :excoveralls, "0.12.2", "a513defac45c59e310ac42fcf2b8ae96f1f85746410f30b1ff2b710a4b6cd44b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "151c476331d49b45601ffc45f43cb3a8beb396b02a34e3777fea0ad34ae57d89"},
+ "excoveralls": {:hex, :excoveralls, "0.13.1", "b9f1697f7c9e0cfe15d1a1d737fb169c398803ffcbc57e672aa007e9fd42864c", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b4bb550e045def1b4d531a37fb766cbbe1307f7628bf8f0414168b3f52021cce"},
"fast_html": {:hex, :fast_html, "1.0.3", "2cc0d4b68496266a1530e0c852cafeaede0bd10cfdee26fda50dc696c203162f", [:make, :mix], [], "hexpm", "ab3d782b639d3c4655fbaec0f9d032c91f8cab8dd791ac7469c2381bc7c32f85"},
"fast_sanitize": {:hex, :fast_sanitize, "0.1.7", "2a7cd8734c88a2de6de55022104f8a3b87f1fdbe8bbf131d9049764b53d50d0d", [:mix], [{:fast_html, "~> 1.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f39fe8ea08fbac17487c30bf09b7d9f3e12472e51fb07a88ffeb8fd17da8ab67"},
"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", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"},
- "floki": {:hex, :floki, "0.25.0", "b1c9ddf5f32a3a90b43b76f3386ca054325dc2478af020e87b5111c19f2284ac", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "631f4e627c46d5ecd347df5a2accdaf0621c77c3693c5b75a8ad58e84c61f242"},
+ "floki": {:hex, :floki, "0.27.0", "6b29a14283f1e2e8fad824bc930eaa9477c462022075df6bea8f0ad811c13599", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "583b8c13697c37179f1f82443bcc7ad2f76fbc0bf4c186606eebd658f7f2631b"},
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
"gen_stage": {:hex, :gen_stage, "0.14.3", "d0c66f1c87faa301c1a85a809a3ee9097a4264b2edf7644bf5c123237ef732bf", [:mix], [], "hexpm"},
"gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"},
- "gettext": {:hex, :gettext, "0.17.4", "f13088e1ec10ce01665cf25f5ff779e7df3f2dc71b37084976cf89d1aa124d5c", [:mix], [], "hexpm", "3c75b5ea8288e2ee7ea503ff9e30dfe4d07ad3c054576a6e60040e79a801e14d"},
+ "gettext": {:hex, :gettext, "0.18.0", "406d6b9e0e3278162c2ae1de0a60270452c553536772167e2d701f028116f870", [:mix], [], "hexpm", "c3f850be6367ebe1a08616c2158affe4a23231c70391050bf359d5f92f66a571"},
"gun": {:git, "https://github.com/ninenines/gun.git", "921c47146b2d9567eac7e9a4d2ccc60fffd4f327", [ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327"]},
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
- "http_signatures": {:git, "https://git.pleroma.social/pleroma/http_signatures.git", "293d77bb6f4a67ac8bde1428735c3b42f22cbb30", [ref: "293d77bb6f4a67ac8bde1428735c3b42f22cbb30"]},
- "httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "aa2c74bd271af34239a3948779612f87df2422c2fdcfdbcec28d9c105f0773fe"},
+ "http_signatures": {:hex, :http_signatures, "0.1.0", "4e4b501a936dbf4cb5222597038a89ea10781776770d2e185849fa829686b34c", [:mix], [], "hexpm", "f8a7b3731e3fd17d38fa6e343fcad7b03d6874a3b0a108c8568a71ed9c2cf824"},
+ "httpoison": {:hex, :httpoison, "1.7.0", "abba7d086233c2d8574726227b6c2c4f6e53c4deae7fe5f6de531162ce9929a0", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "975cc87c845a103d3d1ea1ccfd68a2700c211a434d8428b10c323dc95dc5b980"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"},
@@ -63,36 +63,37 @@
"jose": {:hex, :jose, "1.10.1", "16d8e460dae7203c6d1efa3f277e25b5af8b659febfc2f2eb4bacf87f128b80a", [:mix, :rebar3], [], "hexpm", "3c7ddc8a9394b92891db7c2771da94bf819834a1a4c92e30857b7d582e2f8257"},
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
"libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
- "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
- "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
+ "linkify": {:hex, :linkify, "0.2.0", "2518bbbea21d2caa9d372424e1ad845b640c6630e2d016f1bd1f518f9ebcca28", [:mix], [], "hexpm", "b8ca8a68b79e30b7938d6c996085f3db14939f29538a59ca5101988bb7f917f6"},
+ "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
+ "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
- "mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "e6d886252f1a41f4ba06ecf2b4c8d38760b34b1c08a11c28f7397b2e03995964"},
- "mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm", "3bc928d817974fa10cc11e6c89b9a9361e37e96dbbf3d868c41094ec05745dcd"},
- "mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm", "052346cf322311c49a0f22789f3698eea030eec09b8c47367f0686ef2634ae14"},
+ "mock": {:hex, :mock, "0.3.5", "feb81f52b8dcf0a0d65001d2fec459f6b6a8c22562d94a965862f6cc066b5431", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "6fae404799408300f863550392635d8f7e3da6b71abdd5c393faf41b131c8728"},
+ "mogrify": {:hex, :mogrify, "0.7.4", "9b2496dde44b1ce12676f85d7dc531900939e6367bc537c7243a1b089435b32d", [:mix], [], "hexpm", "50d79e337fba6bc95bfbef918058c90f50b17eed9537771e61d4619488f099c3"},
+ "mox": {:hex, :mox, "0.5.2", "55a0a5ba9ccc671518d068c8dddd20eeb436909ea79d1799e2209df7eaa98b6c", [:mix], [], "hexpm", "df4310628cd628ee181df93f50ddfd07be3e5ecc30232d3b6aadf30bdfe6092b"},
"myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
- "nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
+ "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
"oban": {:hex, :oban, "2.0.0", "e6ce70d94dd46815ec0882a1ffb7356df9a9d5b8a40a64ce5c2536617a447379", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cf574813bd048b98a698aa587c21367d2e06842d4e1b1993dcd6a696e9e633bd"},
"open_api_spex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", "f296ac0924ba3cf79c7a588c4c252889df4c2edd", [ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"]},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
- "phoenix": {:hex, :phoenix, "1.4.13", "67271ad69b51f3719354604f4a3f968f83aa61c19199343656c9caee057ff3b8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ab765a0feddb81fc62e2116c827b5f068df85159c162bee760745276ad7ddc1b"},
+ "phoenix": {:hex, :phoenix, "1.4.17", "1b1bd4cff7cfc87c94deaa7d60dd8c22e04368ab95499483c50640ef3bd838d8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a8e5d7a3d76d452bb5fb86e8b7bd115f737e4f8efe202a463d4aeb4a5809611"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"},
- "phoenix_html": {:hex, :phoenix_html, "2.14.0", "d8c6bc28acc8e65f8ea0080ee05aa13d912c8758699283b8d3427b655aabe284", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "b0bb30eda478a06dbfbe96728061a93833db3861a49ccb516f839ecb08493fbb"},
+ "phoenix_html": {:hex, :phoenix_html, "2.14.2", "b8a3899a72050f3f48a36430da507dd99caf0ac2d06c77529b1646964f3d563e", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "58061c8dfd25da5df1ea0ca47c972f161beb6c875cd293917045b92ffe1bf617"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
- "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.2.0", "a7e0b32077cd6d2323ae15198839b05d9caddfa20663fd85787479e81f89520e", [:mix], [{:phoenix, "~> 1.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.2", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 0.1", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "ebf1bfa7b3c1c850c04929afe02e2e0d7ab135e0706332c865de03e761676b1f"},
- "plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "9902eda2c52ada2a096434682e99a2493f5d06a94d6ac6bcfff9805f952350f1"},
- "plug_cowboy": {:hex, :plug_cowboy, "2.1.2", "8b0addb5908c5238fac38e442e81b6fcd32788eaa03246b4d55d147c47c5805e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "7d722581ce865a237e14da6d946f92704101740a256bd13ec91e63c0b122fc70"},
+ "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.0", "2acfa0db038a7649e0a4614eee970e6ed9a39d191ccd79a03583b51d0da98165", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "b8bbae4b59a676de6b8bd8675eda37bc8b4424812ae429d6fdcb2b039e00003b"},
+ "plug": {:hex, :plug, "1.10.3", "c9cebe917637d8db0e759039cc106adca069874e1a9034fd6e3fdd427fd3c283", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "01f9037a2a1de1d633b5a881101e6a444bcabb1d386ca1e00bb273a1f1d9d939"},
+ "plug_cowboy": {:hex, :plug_cowboy, "2.3.0", "149a50e05cb73c12aad6506a371cd75750c0b19a32f81866e1a323dda9e0e99d", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bc595a1870cef13f9c1e03df56d96804db7f702175e4ccacdb8fc75c02a7b97e"},
"plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.15.5", "aec40306a622d459b01bff890fa42f1430dac61593b122754144ad9033a2152f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ed90c81e1525f65a2ba2279dbcebf030d6d13328daa2f8088b9661eb9143af7f"},
- "pot": {:hex, :pot, "0.10.2", "9895c83bcff8cd22d9f5bc79dfc88a188176b261b618ad70d93faf5c5ca36e67", [:rebar3], [], "hexpm", "ac589a8e296b7802681e93cd0a436faec117ea63e9916709c628df31e17e91e2"},
+ "pot": {:hex, :pot, "0.11.0", "61bad869a94534739dd4614a25a619bc5c47b9970e9a0ea5bef4628036fc7a16", [:rebar3], [], "hexpm", "57ee6ee6bdeb639661ffafb9acefe3c8f966e45394de6a766813bb9e1be4e54b"},
"prometheus": {:hex, :prometheus, "4.6.0", "20510f381db1ccab818b4cf2fac5fa6ab5cc91bc364a154399901c001465f46f", [:mix, :rebar3], [], "hexpm", "4905fd2992f8038eccd7aa0cd22f40637ed618c0bed1f75c05aacec15b7545de"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"},
"prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm", "9fd13404a48437e044b288b41f76e64acd9735fb8b0e3809f494811dfa66d0fb"},
@@ -100,21 +101,21 @@
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},
"quack": {:hex, :quack, "0.1.1", "cca7b4da1a233757fdb44b3334fce80c94785b3ad5a602053b7a002b5a8967bf", [:mix], [{:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2.0", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "d736bfa7444112eb840027bb887832a0e403a4a3437f48028c3b29a2dbbd2543"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
- "recon": {:hex, :recon, "2.5.0", "2f7fcbec2c35034bade2f9717f77059dc54eb4e929a3049ca7ba6775c0bd66cd", [:mix, :rebar3], [], "hexpm", "72f3840fedd94f06315c523f6cecf5b4827233bed7ae3fe135b2a0ebeab5e196"},
+ "recon": {:hex, :recon, "2.5.1", "430ffa60685ac1efdfb1fe4c97b8767c92d0d92e6e7c3e8621559ba77598678a", [:mix, :rebar3], [], "hexpm", "5721c6b6d50122d8f68cccac712caa1231f97894bab779eff5ff0f886cb44648"},
"remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]},
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"},
- "swoosh": {:git, "https://github.com/swoosh/swoosh", "c96e0ca8a00d8f211ec1f042a4626b09f249caa5", [ref: "c96e0ca8a00d8f211ec1f042a4626b09f249caa5"]},
+ "swoosh": {:hex, :swoosh, "1.0.0", "c547cfc83f30e12d5d1fdcb623d7de2c2e29a5becfc68bf8f42ba4d23d2c2756", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "b3b08e463f876cb6167f7168e9ad99a069a724e124bcee61847e0e1ed13f4a0d"},
"syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
"tesla": {:git, "https://github.com/teamon/tesla.git", "af3707078b10793f6a534938e56b963aff82fe3c", [ref: "af3707078b10793f6a534938e56b963aff82fe3c"]},
- "timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "f354efb2400dd7a80fd9eb6c8419068c4f632da4ac47f3d8822d6e33f08bc852"},
+ "timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"},
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
"tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"},
- "ueberauth": {:hex, :ueberauth, "0.6.2", "25a31111249d60bad8b65438b2306a4dc91f3208faa62f5a8c33e8713989b2e8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "db9fbfb5ac707bc4f85a297758406340bf0358b4af737a88113c1a9eee120ac7"},
+ "ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
- "web_push_encryption": {:hex, :web_push_encryption, "0.2.3", "a0ceab85a805a30852f143d22d71c434046fbdbafbc7292e7887cec500826a80", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "9315c8f37c108835cf3f8e9157d7a9b8f420a34f402d1b1620a31aed5b93ecdf"},
+ "web_push_encryption": {:hex, :web_push_encryption, "0.3.0", "598b5135e696fd1404dc8d0d7c0fa2c027244a4e5d5e5a98ba267f14fdeaabc8", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "f10bdd1afe527ede694749fb77a2f22f146a51b054c7fa541c9fd920fba7c875"},
"websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
}
diff --git a/priv/repo/migrations/20200712234852_add_approval_fields_to_users.exs b/priv/repo/migrations/20200712234852_add_approval_fields_to_users.exs
new file mode 100644
index 000000000..43f741a5b
--- /dev/null
+++ b/priv/repo/migrations/20200712234852_add_approval_fields_to_users.exs
@@ -0,0 +1,10 @@
+defmodule Pleroma.Repo.Migrations.AddApprovalFieldsToUsers do
+ use Ecto.Migration
+
+ def change do
+ alter table(:users) do
+ add(:approval_pending, :boolean)
+ add(:registration_reason, :text)
+ end
+ end
+end
diff --git a/priv/repo/migrations/20200716195806_autolinker_to_linkify.exs b/priv/repo/migrations/20200716195806_autolinker_to_linkify.exs
new file mode 100644
index 000000000..570acba84
--- /dev/null
+++ b/priv/repo/migrations/20200716195806_autolinker_to_linkify.exs
@@ -0,0 +1,36 @@
+defmodule Pleroma.Repo.Migrations.AutolinkerToLinkify do
+ use Ecto.Migration
+ alias Pleroma.ConfigDB
+
+ @autolinker_path %{group: :auto_linker, key: :opts}
+ @linkify_path %{group: :pleroma, key: Pleroma.Formatter}
+
+ @compat_opts [:class, :rel, :new_window, :truncate, :strip_prefix, :extra]
+
+ def change do
+ with {:ok, {old, new}} <- maybe_get_params() do
+ move_config(old, new)
+ end
+ end
+
+ defp move_config(%{} = old, %{} = new) do
+ {:ok, _} = ConfigDB.update_or_create(new)
+ {:ok, _} = ConfigDB.delete(old)
+ :ok
+ end
+
+ defp maybe_get_params() do
+ with %ConfigDB{value: opts} <- ConfigDB.get_by_params(@autolinker_path),
+ opts <- transform_opts(opts),
+ %{} = linkify_params <- Map.put(@linkify_path, :value, opts) do
+ {:ok, {@autolinker_path, linkify_params}}
+ end
+ end
+
+ def transform_opts(opts) when is_list(opts) do
+ opts
+ |> Enum.into(%{})
+ |> Map.take(@compat_opts)
+ |> Map.to_list()
+ end
+end
diff --git a/priv/repo/migrations/20200722185515_fix_malformed_formatter_config.exs b/priv/repo/migrations/20200722185515_fix_malformed_formatter_config.exs
new file mode 100644
index 000000000..77b760825
--- /dev/null
+++ b/priv/repo/migrations/20200722185515_fix_malformed_formatter_config.exs
@@ -0,0 +1,26 @@
+defmodule Pleroma.Repo.Migrations.FixMalformedFormatterConfig do
+ use Ecto.Migration
+ alias Pleroma.ConfigDB
+
+ @config_path %{group: :pleroma, key: Pleroma.Formatter}
+
+ def change do
+ with %ConfigDB{value: %{} = opts} <- ConfigDB.get_by_params(@config_path),
+ fixed_opts <- Map.to_list(opts) do
+ fix_config(fixed_opts)
+ else
+ _ -> :skipped
+ end
+ end
+
+ defp fix_config(fixed_opts) when is_list(fixed_opts) do
+ {:ok, _} =
+ ConfigDB.update_or_create(%{
+ group: :pleroma,
+ key: Pleroma.Formatter,
+ value: fixed_opts
+ })
+
+ :ok
+ end
+end
diff --git a/priv/repo/migrations/20200724133313_move_welcome_settings.exs b/priv/repo/migrations/20200724133313_move_welcome_settings.exs
new file mode 100644
index 000000000..323a8fcee
--- /dev/null
+++ b/priv/repo/migrations/20200724133313_move_welcome_settings.exs
@@ -0,0 +1,94 @@
+defmodule Pleroma.Repo.Migrations.MoveWelcomeSettings do
+ use Ecto.Migration
+
+ alias Pleroma.ConfigDB
+
+ @old_keys [:welcome_user_nickname, :welcome_message]
+
+ def up do
+ with {:ok, config, {keep_values, move_values}} <- get_old_values() do
+ insert_welcome_settings(move_values)
+ update_instance_config(config, keep_values)
+ end
+ end
+
+ def down do
+ with {:ok, welcome_config, revert_values} <- get_revert_values() do
+ revert_instance_config(revert_values)
+ Pleroma.Repo.delete(welcome_config)
+ end
+ end
+
+ defp insert_welcome_settings([_ | _] = values) do
+ unless String.trim(values[:welcome_message]) == "" do
+ config_values = [
+ direct_message: %{
+ enabled: true,
+ sender_nickname: values[:welcome_user_nickname],
+ message: values[:welcome_message]
+ },
+ email: %{
+ enabled: false,
+ sender: nil,
+ subject: "Welcome to <%= instance_name %>",
+ html: "Welcome to <%= instance_name %>",
+ text: "Welcome to <%= instance_name %>"
+ }
+ ]
+
+ {:ok, _} =
+ %ConfigDB{}
+ |> ConfigDB.changeset(%{group: :pleroma, key: :welcome, value: config_values})
+ |> Pleroma.Repo.insert()
+ end
+
+ :ok
+ end
+
+ defp insert_welcome_settings(_), do: :noop
+
+ defp revert_instance_config(%{} = revert_values) do
+ values = [
+ welcome_user_nickname: revert_values[:sender_nickname],
+ welcome_message: revert_values[:message]
+ ]
+
+ ConfigDB.update_or_create(%{group: :pleroma, key: :instance, value: values})
+ end
+
+ defp revert_instance_config(_), do: :noop
+
+ defp update_instance_config(config, values) do
+ {:ok, _} =
+ config
+ |> ConfigDB.changeset(%{value: values})
+ |> Pleroma.Repo.update()
+
+ :ok
+ end
+
+ defp get_revert_values do
+ config = ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+
+ cond do
+ is_nil(config) -> {:noop, nil, nil}
+ true -> {:ok, config, config.value[:direct_message]}
+ end
+ end
+
+ defp get_old_values do
+ config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+
+ cond do
+ is_nil(config) ->
+ {:noop, config, {}}
+
+ is_binary(config.value[:welcome_message]) ->
+ {:ok, config,
+ {Keyword.drop(config.value, @old_keys), Keyword.take(config.value, @old_keys)}}
+
+ true ->
+ {:ok, config, {Keyword.drop(config.value, @old_keys), []}}
+ end
+ end
+end
diff --git a/priv/repo/migrations/20200802170532_fix_legacy_tags.exs b/priv/repo/migrations/20200802170532_fix_legacy_tags.exs
new file mode 100644
index 000000000..f7274b44e
--- /dev/null
+++ b/priv/repo/migrations/20200802170532_fix_legacy_tags.exs
@@ -0,0 +1,37 @@
+# Fix legacy tags set by AdminFE that don't align with TagPolicy MRF
+
+defmodule Pleroma.Repo.Migrations.FixLegacyTags do
+ use Ecto.Migration
+ alias Pleroma.Repo
+ alias Pleroma.User
+ import Ecto.Query
+
+ @old_new_map %{
+ "force_nsfw" => "mrf_tag:media-force-nsfw",
+ "strip_media" => "mrf_tag:media-strip",
+ "force_unlisted" => "mrf_tag:force-unlisted",
+ "sandbox" => "mrf_tag:sandbox",
+ "disable_remote_subscription" => "mrf_tag:disable-remote-subscription",
+ "disable_any_subscription" => "mrf_tag:disable-any-subscription"
+ }
+
+ def change do
+ legacy_tags = Map.keys(@old_new_map)
+
+ from(u in User, where: fragment("? && ?", u.tags, ^legacy_tags))
+ |> Repo.all()
+ |> Enum.each(fn user ->
+ fix_tags_changeset(user)
+ |> Repo.update()
+ end)
+ end
+
+ defp fix_tags_changeset(%User{tags: tags} = user) do
+ new_tags =
+ Enum.map(tags, fn tag ->
+ Map.get(@old_new_map, tag, tag)
+ end)
+
+ Ecto.Changeset.change(user, tags: new_tags)
+ end
+end
diff --git a/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
new file mode 100644
index 000000000..389935f0d
--- /dev/null
+++ b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
@@ -0,0 +1,19 @@
+defmodule Pleroma.Repo.Migrations.RemoveNonlocalExpirations do
+ use Ecto.Migration
+
+ def up do
+ statement = """
+ DELETE FROM
+ activity_expirations A USING activities B
+ WHERE
+ A.activity_id = B.id
+ AND B.local = false;
+ """
+
+ execute(statement)
+ end
+
+ def down do
+ :ok
+ end
+end
diff --git a/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
new file mode 100644
index 000000000..83de18096
--- /dev/null
+++ b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.AddUniqueIndexToAppClientId do
+ use Ecto.Migration
+
+ def change do
+ create(unique_index(:apps, [:client_id]))
+ end
+end
diff --git a/test/application_requirements_test.exs b/test/application_requirements_test.exs
index 481cdfd73..21d24ddd0 100644
--- a/test/application_requirements_test.exs
+++ b/test/application_requirements_test.exs
@@ -9,6 +9,56 @@ defmodule Pleroma.ApplicationRequirementsTest do
alias Pleroma.Repo
+ describe "check_welcome_message_config!/1" do
+ setup do: clear_config([:welcome])
+ setup do: clear_config([Pleroma.Emails.Mailer])
+
+ test "raises if welcome email enabled but mail disabled" do
+ Pleroma.Config.put([:welcome, :email, :enabled], true)
+ Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
+
+ assert_raise Pleroma.ApplicationRequirements.VerifyError, "The mail disabled.", fn ->
+ capture_log(&Pleroma.ApplicationRequirements.verify!/0)
+ end
+ end
+ end
+
+ describe "check_confirmation_accounts!" do
+ setup_with_mocks([
+ {Pleroma.ApplicationRequirements, [:passthrough],
+ [
+ check_migrations_applied!: fn _ -> :ok end
+ ]}
+ ]) do
+ :ok
+ end
+
+ setup do: clear_config([:instance, :account_activation_required])
+
+ test "raises if account confirmation is required but mailer isn't enable" do
+ Pleroma.Config.put([:instance, :account_activation_required], true)
+ Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
+
+ assert_raise Pleroma.ApplicationRequirements.VerifyError,
+ "Account activation enabled, but Mailer is disabled. Cannot send confirmation emails.",
+ fn ->
+ capture_log(&Pleroma.ApplicationRequirements.verify!/0)
+ end
+ end
+
+ test "doesn't do anything if account confirmation is disabled" do
+ Pleroma.Config.put([:instance, :account_activation_required], false)
+ Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
+ assert Pleroma.ApplicationRequirements.verify!() == :ok
+ end
+
+ test "doesn't do anything if account confirmation is required and mailer is enabled" do
+ Pleroma.Config.put([:instance, :account_activation_required], true)
+ Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], true)
+ assert Pleroma.ApplicationRequirements.verify!() == :ok
+ end
+ end
+
describe "check_rum!" do
setup_with_mocks([
{Pleroma.ApplicationRequirements, [:passthrough],
diff --git a/test/captcha_test.exs b/test/captcha_test.exs
index 1ab9019ab..1b9f4a12f 100644
--- a/test/captcha_test.exs
+++ b/test/captcha_test.exs
@@ -41,7 +41,8 @@ test "new and validate" do
answer_data: answer,
token: ^token,
url: ^url,
- type: :kocaptcha
+ type: :kocaptcha,
+ seconds_valid: 300
} = new
assert Kocaptcha.validate(token, "7oEy8c", answer) == :ok
@@ -56,7 +57,8 @@ test "new and validate" do
answer_data: answer,
token: token,
type: :native,
- url: "data:image/png;base64," <> _
+ url: "data:image/png;base64," <> _,
+ seconds_valid: 300
} = new
assert is_binary(answer)
diff --git a/test/config_test.exs b/test/config_test.exs
index a46ab4302..1556e4237 100644
--- a/test/config_test.exs
+++ b/test/config_test.exs
@@ -28,6 +28,34 @@ test "get/1 with a list of keys" do
assert Pleroma.Config.get([:azerty, :uiop], true) == true
end
+ describe "nil values" do
+ setup do
+ Pleroma.Config.put(:lorem, nil)
+ Pleroma.Config.put(:ipsum, %{dolor: [sit: nil]})
+ Pleroma.Config.put(:dolor, sit: %{amet: nil})
+
+ on_exit(fn -> Enum.each(~w(lorem ipsum dolor)a, &Pleroma.Config.delete/1) end)
+ end
+
+ test "get/1 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem) == nil
+ end
+
+ test "get/2 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem, true) == nil
+ end
+
+ test "get/1 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit]) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet]) == nil
+ end
+
+ test "get/2 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit], true) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet], true) == nil
+ end
+ end
+
test "get/1 when value is false" do
Pleroma.Config.put([:instance, :false_test], false)
Pleroma.Config.put([:instance, :nested], [])
@@ -89,5 +117,23 @@ test "delete/2 with a list of keys" do
Pleroma.Config.put([:delete_me, :delete_me], hello: "world", world: "Hello")
Pleroma.Config.delete([:delete_me, :delete_me, :world])
assert Pleroma.Config.get([:delete_me, :delete_me]) == [hello: "world"]
+
+ assert Pleroma.Config.delete([:this_key_does_not_exist])
+ assert Pleroma.Config.delete([:non, :existing, :key])
+ end
+
+ test "fetch/1" do
+ Pleroma.Config.put([:lorem], :ipsum)
+ Pleroma.Config.put([:ipsum], dolor: :sit)
+
+ assert Pleroma.Config.fetch([:lorem]) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch(:lorem) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch([:ipsum, :dolor]) == {:ok, :sit}
+ assert Pleroma.Config.fetch([:lorem, :ipsum]) == :error
+ assert Pleroma.Config.fetch([:loremipsum]) == :error
+ assert Pleroma.Config.fetch(:loremipsum) == :error
+
+ Pleroma.Config.delete([:lorem])
+ Pleroma.Config.delete([:ipsum])
end
end
diff --git a/test/emails/admin_email_test.exs b/test/emails/admin_email_test.exs
index 9082ae5a7..e24231e27 100644
--- a/test/emails/admin_email_test.exs
+++ b/test/emails/admin_email_test.exs
@@ -46,4 +46,24 @@ test "it works when the reporter is a remote user without email" do
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}
end
+
+ test "new unapproved registration email" do
+ config = Pleroma.Config.get(:instance)
+ to_user = insert(:user)
+ account = insert(:user, registration_reason: "Plz let me in")
+
+ res = AdminEmail.new_unapproved_registration(to_user, account)
+
+ account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
+
+ assert res.to == [{to_user.name, to_user.email}]
+ assert res.from == {config[:name], config[:notify_email]}
+ assert res.subject == "New account up for review on #{config[:name]} (@#{account.nickname})"
+
+ assert res.html_body == """
+
New account for review: @#{account.nickname}
+
Plz let me in
+
Visit AdminFE
+ """
+ end
end
diff --git a/test/emails/mailer_test.exs b/test/emails/mailer_test.exs
index e6e34cba8..3da45056b 100644
--- a/test/emails/mailer_test.exs
+++ b/test/emails/mailer_test.exs
@@ -19,6 +19,7 @@ defmodule Pleroma.Emails.MailerTest do
test "not send email when mailer is disabled" do
Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false)
Mailer.deliver(@email)
+ :timer.sleep(100)
refute_email_sent(
from: {"Pleroma", "noreply@example.com"},
@@ -30,6 +31,7 @@ test "not send email when mailer is disabled" do
test "send email" do
Mailer.deliver(@email)
+ :timer.sleep(100)
assert_email_sent(
from: {"Pleroma", "noreply@example.com"},
@@ -41,6 +43,7 @@ test "send email" do
test "perform" do
Mailer.perform(:deliver_async, @email, [])
+ :timer.sleep(100)
assert_email_sent(
from: {"Pleroma", "noreply@example.com"},
diff --git a/test/fixtures/mastodon-question-activity.json b/test/fixtures/mastodon-question-activity.json
index ac329c7d5..3648b9f90 100644
--- a/test/fixtures/mastodon-question-activity.json
+++ b/test/fixtures/mastodon-question-activity.json
@@ -49,7 +49,6 @@
"en": "
Why is Tenshi eating a corndog so cute?
"
},
"endTime": "2019-05-11T09:03:36Z",
- "closed": "2019-05-11T09:03:36Z",
"attachment": [],
"tag": [],
"replies": {
diff --git a/test/fixtures/tesla_mock/poll_attachment.json b/test/fixtures/tesla_mock/poll_attachment.json
new file mode 100644
index 000000000..92e822dc8
--- /dev/null
+++ b/test/fixtures/tesla_mock/poll_attachment.json
@@ -0,0 +1,99 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://patch.cx/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "actor": "https://patch.cx/users/rin",
+ "anyOf": [],
+ "attachment": [
+ {
+ "mediaType": "image/jpeg",
+ "name": "screenshot_mpv:Totoro@01:18:44.345.jpg",
+ "type": "Document",
+ "url": "https://shitposter.club/media/3bb4c4d402f8fdcc7f80963c3d7cf6f10f936897fd374922ade33199d2f86d87.jpg?name=screenshot_mpv%3ATotoro%4001%3A18%3A44.345.jpg"
+ }
+ ],
+ "attributedTo": "https://patch.cx/users/rin",
+ "cc": [
+ "https://patch.cx/users/rin/followers"
+ ],
+ "closed": "2020-06-19T23:22:02.754678Z",
+ "content": "
@rinpatch ",
+ "closed": "2019-09-19T00:32:36.785333",
+ "content": "can you vote on this poll?",
+ "id": "https://patch.cx/objects/tesla_mock/poll_attachment",
+ "oneOf": [
+ {
+ "name": "a",
+ "replies": {
+ "totalItems": 0,
+ "type": "Collection"
+ },
+ "type": "Note"
+ },
+ {
+ "name": "A",
+ "replies": {
+ "totalItems": 0,
+ "type": "Collection"
+ },
+ "type": "Note"
+ },
+ {
+ "name": "Aa",
+ "replies": {
+ "totalItems": 0,
+ "type": "Collection"
+ },
+ "type": "Note"
+ },
+ {
+ "name": "AA",
+ "replies": {
+ "totalItems": 0,
+ "type": "Collection"
+ },
+ "type": "Note"
+ },
+ {
+ "name": "AAa",
+ "replies": {
+ "totalItems": 1,
+ "type": "Collection"
+ },
+ "type": "Note"
+ },
+ {
+ "name": "AAA",
+ "replies": {
+ "totalItems": 3,
+ "type": "Collection"
+ },
+ "type": "Note"
+ }
+ ],
+ "published": "2020-06-19T23:12:02.786113Z",
+ "sensitive": false,
+ "summary": "",
+ "tag": [
+ {
+ "href": "https://mastodon.sdf.org/users/rinpatch",
+ "name": "@rinpatch@mastodon.sdf.org",
+ "type": "Mention"
+ }
+ ],
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public",
+ "https://mastodon.sdf.org/users/rinpatch"
+ ],
+ "type": "Question",
+ "voters": [
+ "https://shitposter.club/users/moonman",
+ "https://skippers-bin.com/users/7v1w1r8ce6",
+ "https://mastodon.sdf.org/users/rinpatch",
+ "https://mastodon.social/users/emelie"
+ ]
+}
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index bef5a2c28..f066bd50a 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -10,6 +10,7 @@ defmodule Pleroma.FormatterTest do
import Pleroma.Factory
setup_all do
+ clear_config(Pleroma.Formatter)
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
@@ -255,6 +256,36 @@ test "it can parse mentions and return the relevant users" do
assert {_text, ^expected_mentions, []} = Formatter.linkify(text)
end
+
+ test "it parses URL containing local mention" do
+ _user = insert(:user, %{nickname: "lain"})
+
+ text = "https://example.com/@lain"
+
+ expected = ~S(
https://example.com/@lain )
+
+ assert {^expected, [], []} = Formatter.linkify(text)
+ end
+
+ test "it correctly parses angry face D:< with mention" do
+ lain =
+ insert(:user, %{
+ nickname: "lain@lain.com",
+ ap_id: "https://lain.com/users/lain",
+ id: "9qrWmR0cKniB0YU0TA"
+ })
+
+ text = "@lain@lain.com D:<"
+
+ expected_text =
+ ~S(
@lain D:<)
+
+ expected_mentions = [
+ {"@lain@lain.com", lain}
+ ]
+
+ assert {^expected_text, ^expected_mentions, []} = Formatter.linkify(text)
+ end
end
describe ".parse_tags" do
diff --git a/test/migrations/20200716195806_autolinker_to_linkify_test.exs b/test/migrations/20200716195806_autolinker_to_linkify_test.exs
new file mode 100644
index 000000000..250d11c61
--- /dev/null
+++ b/test/migrations/20200716195806_autolinker_to_linkify_test.exs
@@ -0,0 +1,68 @@
+defmodule Pleroma.Repo.Migrations.AutolinkerToLinkifyTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+ alias Pleroma.ConfigDB
+
+ setup do: clear_config(Pleroma.Formatter)
+ setup_all do: require_migration("20200716195806_autolinker_to_linkify")
+
+ test "change/0 converts auto_linker opts for Pleroma.Formatter", %{migration: migration} do
+ autolinker_opts = [
+ extra: true,
+ validate_tld: true,
+ class: false,
+ strip_prefix: false,
+ new_window: false,
+ rel: "testing"
+ ]
+
+ insert(:config, group: :auto_linker, key: :opts, value: autolinker_opts)
+
+ migration.change()
+
+ assert nil == ConfigDB.get_by_params(%{group: :auto_linker, key: :opts})
+
+ %{value: new_opts} = ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Formatter})
+
+ assert new_opts == [
+ class: false,
+ extra: true,
+ new_window: false,
+ rel: "testing",
+ strip_prefix: false
+ ]
+
+ Pleroma.Config.put(Pleroma.Formatter, new_opts)
+ assert new_opts == Pleroma.Config.get(Pleroma.Formatter)
+
+ {text, _mentions, []} =
+ Pleroma.Formatter.linkify(
+ "https://www.businessinsider.com/walmart-will-close-stores-on-thanksgiving-ending-black-friday-tradition-2020-7\n\nOmg will COVID finally end Black Friday???"
+ )
+
+ assert text ==
+ "
https://www.businessinsider.com/walmart-will-close-stores-on-thanksgiving-ending-black-friday-tradition-2020-7 \n\nOmg will COVID finally end Black Friday???"
+ end
+
+ test "transform_opts/1 returns a list of compatible opts", %{migration: migration} do
+ old_opts = [
+ extra: true,
+ validate_tld: true,
+ class: false,
+ strip_prefix: false,
+ new_window: false,
+ rel: "qqq"
+ ]
+
+ expected_opts = [
+ class: false,
+ extra: true,
+ new_window: false,
+ rel: "qqq",
+ strip_prefix: false
+ ]
+
+ assert migration.transform_opts(old_opts) == expected_opts
+ end
+end
diff --git a/test/migrations/20200722185515_fix_malformed_formatter_config_test.exs b/test/migrations/20200722185515_fix_malformed_formatter_config_test.exs
new file mode 100644
index 000000000..d3490478e
--- /dev/null
+++ b/test/migrations/20200722185515_fix_malformed_formatter_config_test.exs
@@ -0,0 +1,66 @@
+defmodule Pleroma.Repo.Migrations.FixMalformedFormatterConfigTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+ alias Pleroma.ConfigDB
+
+ setup do: clear_config(Pleroma.Formatter)
+ setup_all do: require_migration("20200722185515_fix_malformed_formatter_config")
+
+ test "change/0 converts a map into a list", %{migration: migration} do
+ incorrect_opts = %{
+ class: false,
+ extra: true,
+ new_window: false,
+ rel: "F",
+ strip_prefix: false
+ }
+
+ insert(:config, group: :pleroma, key: Pleroma.Formatter, value: incorrect_opts)
+
+ assert :ok == migration.change()
+
+ %{value: new_opts} = ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Formatter})
+
+ assert new_opts == [
+ class: false,
+ extra: true,
+ new_window: false,
+ rel: "F",
+ strip_prefix: false
+ ]
+
+ Pleroma.Config.put(Pleroma.Formatter, new_opts)
+ assert new_opts == Pleroma.Config.get(Pleroma.Formatter)
+
+ {text, _mentions, []} =
+ Pleroma.Formatter.linkify(
+ "https://www.businessinsider.com/walmart-will-close-stores-on-thanksgiving-ending-black-friday-tradition-2020-7\n\nOmg will COVID finally end Black Friday???"
+ )
+
+ assert text ==
+ "
https://www.businessinsider.com/walmart-will-close-stores-on-thanksgiving-ending-black-friday-tradition-2020-7 \n\nOmg will COVID finally end Black Friday???"
+ end
+
+ test "change/0 skips if Pleroma.Formatter config is already a list", %{migration: migration} do
+ opts = [
+ class: false,
+ extra: true,
+ new_window: false,
+ rel: "ugc",
+ strip_prefix: false
+ ]
+
+ insert(:config, group: :pleroma, key: Pleroma.Formatter, value: opts)
+
+ assert :skipped == migration.change()
+
+ %{value: new_opts} = ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Formatter})
+
+ assert new_opts == opts
+ end
+
+ test "change/0 skips if Pleroma.Formatter is empty", %{migration: migration} do
+ assert :skipped == migration.change()
+ end
+end
diff --git a/test/migrations/20200724133313_move_welcome_settings_test.exs b/test/migrations/20200724133313_move_welcome_settings_test.exs
new file mode 100644
index 000000000..739f24547
--- /dev/null
+++ b/test/migrations/20200724133313_move_welcome_settings_test.exs
@@ -0,0 +1,140 @@
+defmodule Pleroma.Repo.Migrations.MoveWelcomeSettingsTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+ alias Pleroma.ConfigDB
+
+ setup_all do: require_migration("20200724133313_move_welcome_settings")
+
+ describe "up/0" do
+ test "converts welcome settings", %{migration: migration} do
+ insert(:config,
+ group: :pleroma,
+ key: :instance,
+ value: [
+ welcome_message: "Test message",
+ welcome_user_nickname: "jimm",
+ name: "Pleroma"
+ ]
+ )
+
+ migration.up()
+ instance_config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+ welcome_config = ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+
+ assert instance_config.value == [name: "Pleroma"]
+
+ assert welcome_config.value == [
+ direct_message: %{
+ enabled: true,
+ message: "Test message",
+ sender_nickname: "jimm"
+ },
+ email: %{
+ enabled: false,
+ html: "Welcome to <%= instance_name %>",
+ sender: nil,
+ subject: "Welcome to <%= instance_name %>",
+ text: "Welcome to <%= instance_name %>"
+ }
+ ]
+ end
+
+ test "does nothing when message empty", %{migration: migration} do
+ insert(:config,
+ group: :pleroma,
+ key: :instance,
+ value: [
+ welcome_message: "",
+ welcome_user_nickname: "jimm",
+ name: "Pleroma"
+ ]
+ )
+
+ migration.up()
+ instance_config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+ refute ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+ assert instance_config.value == [name: "Pleroma"]
+ end
+
+ test "does nothing when welcome_message not set", %{migration: migration} do
+ insert(:config,
+ group: :pleroma,
+ key: :instance,
+ value: [welcome_user_nickname: "jimm", name: "Pleroma"]
+ )
+
+ migration.up()
+ instance_config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+ refute ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+ assert instance_config.value == [name: "Pleroma"]
+ end
+ end
+
+ describe "down/0" do
+ test "revert new settings to old when instance setting not exists", %{migration: migration} do
+ insert(:config,
+ group: :pleroma,
+ key: :welcome,
+ value: [
+ direct_message: %{
+ enabled: true,
+ message: "Test message",
+ sender_nickname: "jimm"
+ },
+ email: %{
+ enabled: false,
+ html: "Welcome to <%= instance_name %>",
+ sender: nil,
+ subject: "Welcome to <%= instance_name %>",
+ text: "Welcome to <%= instance_name %>"
+ }
+ ]
+ )
+
+ migration.down()
+
+ refute ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+ instance_config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+
+ assert instance_config.value == [
+ welcome_user_nickname: "jimm",
+ welcome_message: "Test message"
+ ]
+ end
+
+ test "revert new settings to old when instance setting exists", %{migration: migration} do
+ insert(:config, group: :pleroma, key: :instance, value: [name: "Pleroma App"])
+
+ insert(:config,
+ group: :pleroma,
+ key: :welcome,
+ value: [
+ direct_message: %{
+ enabled: true,
+ message: "Test message",
+ sender_nickname: "jimm"
+ },
+ email: %{
+ enabled: false,
+ html: "Welcome to <%= instance_name %>",
+ sender: nil,
+ subject: "Welcome to <%= instance_name %>",
+ text: "Welcome to <%= instance_name %>"
+ }
+ ]
+ )
+
+ migration.down()
+
+ refute ConfigDB.get_by_params(%{group: :pleroma, key: :welcome})
+ instance_config = ConfigDB.get_by_params(%{group: :pleroma, key: :instance})
+
+ assert instance_config.value == [
+ name: "Pleroma App",
+ welcome_user_nickname: "jimm",
+ welcome_message: "Test message"
+ ]
+ end
+ end
+end
diff --git a/test/migrations/20200802170532_fix_legacy_tags_test.exs b/test/migrations/20200802170532_fix_legacy_tags_test.exs
new file mode 100644
index 000000000..3b4dee407
--- /dev/null
+++ b/test/migrations/20200802170532_fix_legacy_tags_test.exs
@@ -0,0 +1,24 @@
+defmodule Pleroma.Repo.Migrations.FixLegacyTagsTest do
+ alias Pleroma.User
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+
+ setup_all do: require_migration("20200802170532_fix_legacy_tags")
+
+ test "change/0 converts legacy user tags into correct values", %{migration: migration} do
+ user = insert(:user, tags: ["force_nsfw", "force_unlisted", "verified"])
+ user2 = insert(:user)
+
+ assert :ok == migration.change()
+
+ fixed_user = User.get_by_id(user.id)
+ fixed_user2 = User.get_by_id(user2.id)
+
+ assert fixed_user.tags == ["mrf_tag:media-force-nsfw", "mrf_tag:force-unlisted", "verified"]
+ assert fixed_user2.tags == []
+
+ # user2 should not have been updated
+ assert fixed_user2.updated_at == fixed_user2.inserted_at
+ end
+end
diff --git a/test/object/fetcher_test.exs b/test/object/fetcher_test.exs
index d9098ea1b..16cfa7f5c 100644
--- a/test/object/fetcher_test.exs
+++ b/test/object/fetcher_test.exs
@@ -177,6 +177,13 @@ test "handle HTTP 404 response" do
"https://mastodon.example.org/users/userisgone404"
)
end
+
+ test "it can fetch pleroma polls with attachments" do
+ {:ok, object} =
+ Fetcher.fetch_object_from_id("https://patch.cx/objects/tesla_mock/poll_attachment")
+
+ assert object
+ end
end
describe "pruning" do
diff --git a/test/pagination_test.exs b/test/pagination_test.exs
index 9165427ae..e526f23e8 100644
--- a/test/pagination_test.exs
+++ b/test/pagination_test.exs
@@ -54,6 +54,20 @@ test "paginates by min_id & limit", %{notes: notes} do
assert length(paginated) == 1
end
+
+ test "handles id gracefully", %{notes: notes} do
+ id = Enum.at(notes, 1).id |> Integer.to_string()
+
+ paginated =
+ Pagination.fetch_paginated(Object, %{
+ id: "9s99Hq44Cnv8PKBwWG",
+ max_id: id,
+ limit: 20,
+ offset: 0
+ })
+
+ assert length(paginated) == 1
+ end
end
describe "offset" do
diff --git a/test/plugs/frontend_static_test.exs b/test/plugs/frontend_static_test.exs
new file mode 100644
index 000000000..d11d91d78
--- /dev/null
+++ b/test/plugs/frontend_static_test.exs
@@ -0,0 +1,30 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.FrontendStaticPlugTest do
+ use Pleroma.Web.ConnCase
+
+ @dir "test/tmp/instance_static"
+
+ setup do
+ File.mkdir_p!(@dir)
+ on_exit(fn -> File.rm_rf(@dir) end)
+ end
+
+ setup do: clear_config([:instance, :static_dir], @dir)
+
+ test "overrides existing static files", %{conn: conn} do
+ name = "pelmora"
+ ref = "uguu"
+
+ clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
+ path = "#{@dir}/frontends/#{name}/#{ref}"
+
+ File.mkdir_p!(path)
+ File.write!("#{path}/index.html", "from frontend plug")
+
+ index = get(conn, "/")
+ assert html_response(index, 200) == "from frontend plug"
+ end
+end
diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs
index be2613ad0..d42ba817e 100644
--- a/test/plugs/instance_static_test.exs
+++ b/test/plugs/instance_static_test.exs
@@ -2,7 +2,7 @@
# Copyright © 2017-2020 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
-defmodule Pleroma.Web.RuntimeStaticPlugTest do
+defmodule Pleroma.Web.InstanceStaticPlugTest do
use Pleroma.Web.ConnCase
@dir "test/tmp/instance_static"
@@ -24,6 +24,28 @@ test "overrides index" do
assert html_response(index, 200) == "hello world"
end
+ test "also overrides frontend files", %{conn: conn} do
+ name = "pelmora"
+ ref = "uguu"
+
+ clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
+
+ bundled_index = get(conn, "/")
+ refute html_response(bundled_index, 200) == "from frontend plug"
+
+ path = "#{@dir}/frontends/#{name}/#{ref}"
+ File.mkdir_p!(path)
+ File.write!("#{path}/index.html", "from frontend plug")
+
+ index = get(conn, "/")
+ assert html_response(index, 200) == "from frontend plug"
+
+ File.write!(@dir <> "/index.html", "from instance static")
+
+ index = get(conn, "/")
+ assert html_response(index, 200) == "from instance static"
+ end
+
test "overrides any file in static/static" do
bundled_index = get(build_conn(), "/static/terms-of-service.html")
diff --git a/test/report_note_test.exs b/test/report_note_test.exs
new file mode 100644
index 000000000..25c1d6a61
--- /dev/null
+++ b/test/report_note_test.exs
@@ -0,0 +1,16 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.ReportNoteTest do
+ alias Pleroma.ReportNote
+ use Pleroma.DataCase
+ import Pleroma.Factory
+
+ test "create/3" do
+ user = insert(:user)
+ report = insert(:report_activity)
+ assert {:ok, note} = ReportNote.create(user.id, report.id, "naughty boy")
+ assert note.content == "naughty boy"
+ end
+end
diff --git a/test/support/captcha_mock.ex b/test/support/captcha_mock.ex
index 7b0c1d5af..2ed2ba3b4 100644
--- a/test/support/captcha_mock.ex
+++ b/test/support/captcha_mock.ex
@@ -16,7 +16,8 @@ def new,
type: :mock,
token: "afa1815e14e29355e6c8f6b143a39fa2",
answer_data: @solution,
- url: "https://example.org/captcha.png"
+ url: "https://example.org/captcha.png",
+ seconds_valid: 300
}
@impl Service
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 635d83650..486eda8da 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -297,6 +297,30 @@ def follow_activity_factory do
}
end
+ def report_activity_factory(attrs \\ %{}) do
+ user = attrs[:user] || insert(:user)
+ activity = attrs[:activity] || insert(:note_activity)
+ state = attrs[:state] || "open"
+
+ data = %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "actor" => user.ap_id,
+ "type" => "Flag",
+ "object" => [activity.actor, activity.data["id"]],
+ "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
+ "to" => [],
+ "cc" => [activity.actor],
+ "context" => activity.data["context"],
+ "state" => state
+ }
+
+ %Pleroma.Activity{
+ data: data,
+ actor: data["actor"],
+ recipients: data["to"] ++ data["cc"]
+ }
+ end
+
def oauth_app_factory do
%Pleroma.Web.OAuth.App{
client_name: sequence(:client_name, &"Some client #{&1}"),
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index 26281b45e..ecd4b1e18 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -17,9 +17,19 @@ defmacro clear_config(config_path) do
defmacro clear_config(config_path, do: yield) do
quote do
- initial_setting = Config.get(unquote(config_path))
+ initial_setting = Config.fetch(unquote(config_path))
unquote(yield)
- on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+
+ on_exit(fn ->
+ case initial_setting do
+ :error ->
+ Config.delete(unquote(config_path))
+
+ {:ok, value} ->
+ Config.put(unquote(config_path), value)
+ end
+ end)
+
:ok
end
end
@@ -32,6 +42,11 @@ defmacro clear_config(config_path, temp_setting) do
end
end
+ def require_migration(migration_name) do
+ [{module, _}] = Code.require_file("#{migration_name}.exs", "priv/repo/migrations")
+ {:ok, %{migration: module}}
+ end
+
defmacro __using__(_opts) do
quote do
import Pleroma.Tests.Helpers,
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index 19a202654..eeeba7880 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -82,6 +82,14 @@ def get("https://mastodon.sdf.org/users/rinpatch", _, _, _) do
}}
end
+ def get("https://patch.cx/objects/tesla_mock/poll_attachment", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/tesla_mock/poll_attachment.json")
+ }}
+ end
+
def get(
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/emelie",
_,
diff --git a/test/tasks/app_test.exs b/test/tasks/app_test.exs
index b8f03566d..71a84ac8e 100644
--- a/test/tasks/app_test.exs
+++ b/test/tasks/app_test.exs
@@ -50,13 +50,13 @@ test "with errors" do
defp assert_app(name, redirect, scopes) do
app = Repo.get_by(Pleroma.Web.OAuth.App, client_name: name)
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "#{name} successfully created:"
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "App client_id: #{app.client_id}"
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "App client_secret: #{app.client_secret}"
assert app.scopes == scopes
diff --git a/test/tasks/config_test.exs b/test/tasks/config_test.exs
index 71f36c0e3..fb12e7fb3 100644
--- a/test/tasks/config_test.exs
+++ b/test/tasks/config_test.exs
@@ -129,8 +129,6 @@ test "load a settings with large values and pass to file", %{temp_file: temp_fil
autofollowed_nicknames: [],
max_pinned_statuses: 1,
attachment_links: false,
- welcome_user_nickname: nil,
- welcome_message: nil,
max_report_comment_size: 1000,
safe_dm_mentions: false,
healthcheck: false,
@@ -172,7 +170,7 @@ test "load a settings with large values and pass to file", %{temp_file: temp_fil
end
assert file ==
- "#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
+ "#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
end
end
end
diff --git a/test/tasks/release_env_test.exs b/test/tasks/release_env_test.exs
new file mode 100644
index 000000000..519f1eba9
--- /dev/null
+++ b/test/tasks/release_env_test.exs
@@ -0,0 +1,30 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Mix.Tasks.Pleroma.ReleaseEnvTest do
+ use ExUnit.Case
+ import ExUnit.CaptureIO, only: [capture_io: 1]
+
+ @path "config/pleroma.test.env"
+
+ def do_clean do
+ if File.exists?(@path) do
+ File.rm_rf(@path)
+ end
+ end
+
+ setup do
+ do_clean()
+ on_exit(fn -> do_clean() end)
+ :ok
+ end
+
+ test "generate pleroma.env" do
+ assert capture_io(fn ->
+ Mix.Tasks.Pleroma.ReleaseEnv.run(["gen", "--path", @path, "--force"])
+ end) =~ "The file generated"
+
+ assert File.read!(@path) =~ "RELEASE_COOKIE="
+ end
+end
diff --git a/test/upload/filter/anonymize_filename_test.exs b/test/upload/filter/anonymize_filename_test.exs
index 2d5c580f1..adff70f57 100644
--- a/test/upload/filter/anonymize_filename_test.exs
+++ b/test/upload/filter/anonymize_filename_test.exs
@@ -9,6 +9,8 @@ defmodule Pleroma.Upload.Filter.AnonymizeFilenameTest do
alias Pleroma.Upload
setup do
+ File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
+
upload_file = %Upload{
name: "an… image.jpg",
content_type: "image/jpg",
diff --git a/test/upload/filter/exiftool_test.exs b/test/upload/filter/exiftool_test.exs
index a1b7e46cd..8ed7d650b 100644
--- a/test/upload/filter/exiftool_test.exs
+++ b/test/upload/filter/exiftool_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.Upload.Filter.ExiftoolTest do
alias Pleroma.Upload.Filter
test "apply exiftool filter" do
+ assert Pleroma.Utils.command_available?("exiftool")
+
File.cp!(
"test/fixtures/DSCN0010.jpg",
"test/fixtures/DSCN0010_tmp.jpg"
diff --git a/test/uploaders/local_test.exs b/test/uploaders/local_test.exs
index ae2cfef94..18122ff6c 100644
--- a/test/uploaders/local_test.exs
+++ b/test/uploaders/local_test.exs
@@ -14,6 +14,7 @@ test "it returns path to local folder for files" do
describe "put_file/1" do
test "put file to local folder" do
+ File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
file_path = "local_upload/files/image.jpg"
file = %Pleroma.Upload{
@@ -32,6 +33,7 @@ test "put file to local folder" do
describe "delete_file/1" do
test "deletes local file" do
+ File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
file_path = "local_upload/files/image.jpg"
file = %Pleroma.Upload{
diff --git a/test/user/welcome_chat_massage_test.exs b/test/user/welcome_chat_massage_test.exs
new file mode 100644
index 000000000..fe26d6e4d
--- /dev/null
+++ b/test/user/welcome_chat_massage_test.exs
@@ -0,0 +1,35 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.WelcomeChatMessageTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Config
+ alias Pleroma.User.WelcomeChatMessage
+
+ import Pleroma.Factory
+
+ setup do: clear_config([:welcome])
+
+ describe "post_message/1" do
+ test "send a chat welcome message" do
+ welcome_user = insert(:user, name: "mewmew")
+ user = insert(:user)
+
+ Config.put([:welcome, :chat_message, :enabled], true)
+ Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
+
+ Config.put(
+ [:welcome, :chat_message, :message],
+ "Hello, welcome to Blob/Cat!"
+ )
+
+ {:ok, %Pleroma.Activity{} = activity} = WelcomeChatMessage.post_message(user)
+
+ assert user.ap_id in activity.recipients
+ assert Pleroma.Object.normalize(activity).data["type"] == "ChatMessage"
+ assert Pleroma.Object.normalize(activity).data["content"] == "Hello, welcome to Blob/Cat!"
+ end
+ end
+end
diff --git a/test/user/welcome_email_test.exs b/test/user/welcome_email_test.exs
new file mode 100644
index 000000000..d005d11b2
--- /dev/null
+++ b/test/user/welcome_email_test.exs
@@ -0,0 +1,61 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.WelcomeEmailTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Config
+ alias Pleroma.Tests.ObanHelpers
+ alias Pleroma.User.WelcomeEmail
+
+ import Pleroma.Factory
+ import Swoosh.TestAssertions
+
+ setup do: clear_config([:welcome])
+
+ describe "send_email/1" do
+ test "send a welcome email" do
+ user = insert(:user, name: "Jimm")
+
+ Config.put([:welcome, :email, :enabled], true)
+ Config.put([:welcome, :email, :sender], "welcome@pleroma.app")
+
+ Config.put(
+ [:welcome, :email, :subject],
+ "Hello, welcome to pleroma: <%= instance_name %>"
+ )
+
+ Config.put(
+ [:welcome, :email, :html],
+ "
Hello <%= user.name %>. Welcome to <%= instance_name %>
"
+ )
+
+ instance_name = Config.get([:instance, :name])
+
+ {:ok, _job} = WelcomeEmail.send_email(user)
+
+ ObanHelpers.perform_all()
+
+ assert_email_sent(
+ from: {instance_name, "welcome@pleroma.app"},
+ to: {user.name, user.email},
+ subject: "Hello, welcome to pleroma: #{instance_name}",
+ html_body: "
Hello #{user.name}. Welcome to #{instance_name}
"
+ )
+
+ Config.put([:welcome, :email, :sender], {"Pleroma App", "welcome@pleroma.app"})
+
+ {:ok, _job} = WelcomeEmail.send_email(user)
+
+ ObanHelpers.perform_all()
+
+ assert_email_sent(
+ from: {"Pleroma App", "welcome@pleroma.app"},
+ to: {user.name, user.email},
+ subject: "Hello, welcome to pleroma: #{instance_name}",
+ html_body: "
Hello #{user.name}. Welcome to #{instance_name}
"
+ )
+ end
+ end
+end
diff --git a/test/user/welcome_message_test.exs b/test/user/welcome_message_test.exs
new file mode 100644
index 000000000..3cd6f5cb7
--- /dev/null
+++ b/test/user/welcome_message_test.exs
@@ -0,0 +1,34 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.WelcomeMessageTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Config
+ alias Pleroma.User.WelcomeMessage
+
+ import Pleroma.Factory
+
+ setup do: clear_config([:welcome])
+
+ describe "post_message/1" do
+ test "send a direct welcome message" do
+ welcome_user = insert(:user)
+ user = insert(:user, name: "Jimm")
+
+ Config.put([:welcome, :direct_message, :enabled], true)
+ Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
+
+ Config.put(
+ [:welcome, :direct_message, :message],
+ "Hello. Welcome to Pleroma"
+ )
+
+ {:ok, %Pleroma.Activity{} = activity} = WelcomeMessage.post_message(user)
+ assert user.ap_id in activity.recipients
+ assert activity.data["directMessage"] == true
+ assert Pleroma.Object.normalize(activity).data["content"] =~ "Hello. Welcome to Pleroma"
+ end
+ end
+end
diff --git a/test/user_test.exs b/test/user_test.exs
index 29855b9cd..941e48408 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -17,6 +17,7 @@ defmodule Pleroma.UserTest do
import Pleroma.Factory
import ExUnit.CaptureLog
+ import Swoosh.TestAssertions
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@@ -385,9 +386,10 @@ test "fetches correct profile for nickname beginning with number" do
password_confirmation: "test",
email: "email@example.com"
}
+
setup do: clear_config([:instance, :autofollowed_nicknames])
- setup do: clear_config([:instance, :welcome_message])
- setup do: clear_config([:instance, :welcome_user_nickname])
+ setup do: clear_config([:welcome])
+ setup do: clear_config([:instance, :account_activation_required])
test "it autofollows accounts that are set for it" do
user = insert(:user)
@@ -408,20 +410,68 @@ test "it autofollows accounts that are set for it" do
test "it sends a welcome message if it is set" do
welcome_user = insert(:user)
-
- Pleroma.Config.put([:instance, :welcome_user_nickname], welcome_user.nickname)
- Pleroma.Config.put([:instance, :welcome_message], "Hello, this is a cool site")
+ Pleroma.Config.put([:welcome, :direct_message, :enabled], true)
+ Pleroma.Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
+ Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a direct message")
cng = User.register_changeset(%User{}, @full_user_data)
{:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
activity = Repo.one(Pleroma.Activity)
assert registered_user.ap_id in activity.recipients
- assert Object.normalize(activity).data["content"] =~ "cool site"
+ assert Object.normalize(activity).data["content"] =~ "direct message"
assert activity.actor == welcome_user.ap_id
end
- setup do: clear_config([:instance, :account_activation_required])
+ test "it sends a welcome chat message if it is set" do
+ welcome_user = insert(:user)
+ Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
+ Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
+ Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
+
+ cng = User.register_changeset(%User{}, @full_user_data)
+ {:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
+
+ activity = Repo.one(Pleroma.Activity)
+ assert registered_user.ap_id in activity.recipients
+ assert Object.normalize(activity).data["content"] =~ "chat message"
+ assert activity.actor == welcome_user.ap_id
+ end
+
+ test "it sends a welcome email message if it is set" do
+ welcome_user = insert(:user)
+ Pleroma.Config.put([:welcome, :email, :enabled], true)
+ Pleroma.Config.put([:welcome, :email, :sender], welcome_user.email)
+
+ Pleroma.Config.put(
+ [:welcome, :email, :subject],
+ "Hello, welcome to cool site: <%= instance_name %>"
+ )
+
+ instance_name = Pleroma.Config.get([:instance, :name])
+
+ cng = User.register_changeset(%User{}, @full_user_data)
+ {:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
+
+ assert_email_sent(
+ from: {instance_name, welcome_user.email},
+ to: {registered_user.name, registered_user.email},
+ subject: "Hello, welcome to cool site: #{instance_name}",
+ html_body: "Welcome to #{instance_name}"
+ )
+ end
+
+ test "it sends a confirm email" do
+ Pleroma.Config.put([:instance, :account_activation_required], true)
+
+ cng = User.register_changeset(%User{}, @full_user_data)
+ {:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
+ assert_email_sent(Pleroma.Emails.UserEmail.account_confirmation_email(registered_user))
+ end
test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
Pleroma.Config.put([:instance, :account_activation_required], true)
@@ -463,6 +513,29 @@ test "it restricts certain nicknames" do
refute changeset.valid?
end
+ test "it blocks blacklisted email domains" do
+ clear_config([User, :email_blacklist], ["trolling.world"])
+
+ # Block with match
+ params = Map.put(@full_user_data, :email, "troll@trolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ refute changeset.valid?
+
+ # Block with subdomain match
+ params = Map.put(@full_user_data, :email, "troll@gnomes.trolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ refute changeset.valid?
+
+ # Pass with different domains that are similar
+ params = Map.put(@full_user_data, :email, "troll@gnomestrolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ assert changeset.valid?
+
+ params = Map.put(@full_user_data, :email, "troll@trolling.world.us")
+ changeset = User.register_changeset(%User{}, params)
+ assert changeset.valid?
+ end
+
test "it sets the password_hash and ap_id" do
changeset = User.register_changeset(%User{}, @full_user_data)
@@ -473,6 +546,24 @@ test "it sets the password_hash and ap_id" do
assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
end
+
+ test "it sets the 'accepts_chat_messages' set to true" do
+ changeset = User.register_changeset(%User{}, @full_user_data)
+ assert changeset.valid?
+
+ {:ok, user} = Repo.insert(changeset)
+
+ assert user.accepts_chat_messages
+ end
+
+ test "it creates a confirmed user" do
+ changeset = User.register_changeset(%User{}, @full_user_data)
+ assert changeset.valid?
+
+ {:ok, user} = Repo.insert(changeset)
+
+ refute user.confirmation_pending
+ end
end
describe "user registration, with :account_activation_required" do
@@ -486,15 +577,6 @@ test "it sets the password_hash and ap_id" do
}
setup do: clear_config([:instance, :account_activation_required], true)
- test "it sets the 'accepts_chat_messages' set to true" do
- changeset = User.register_changeset(%User{}, @full_user_data)
- assert changeset.valid?
-
- {:ok, user} = Repo.insert(changeset)
-
- assert user.accepts_chat_messages
- end
-
test "it creates unconfirmed user" do
changeset = User.register_changeset(%User{}, @full_user_data)
assert changeset.valid?
@@ -516,6 +598,46 @@ test "it creates confirmed user if :confirmed option is given" do
end
end
+ describe "user registration, with :account_approval_required" do
+ @full_user_data %{
+ bio: "A guy",
+ name: "my name",
+ nickname: "nick",
+ password: "test",
+ password_confirmation: "test",
+ email: "email@example.com",
+ registration_reason: "I'm a cool guy :)"
+ }
+ setup do: clear_config([:instance, :account_approval_required], true)
+
+ test "it creates unapproved user" do
+ changeset = User.register_changeset(%User{}, @full_user_data)
+ assert changeset.valid?
+
+ {:ok, user} = Repo.insert(changeset)
+
+ assert user.approval_pending
+ assert user.registration_reason == "I'm a cool guy :)"
+ end
+
+ test "it restricts length of registration reason" do
+ reason_limit = Pleroma.Config.get([:instance, :registration_reason_length])
+
+ assert is_integer(reason_limit)
+
+ params =
+ @full_user_data
+ |> Map.put(
+ :registration_reason,
+ "Quia et nesciunt dolores numquam ipsam nisi sapiente soluta. Ullam repudiandae nisi quam porro officiis officiis ad. Consequatur animi velit ex quia. Odit voluptatem perferendis quia ut nisi. Dignissimos sit soluta atque aliquid dolorem ut dolorum ut. Labore voluptates iste iusto amet voluptatum earum. Ad fugit illum nam eos ut nemo. Pariatur ea fuga non aspernatur. Dignissimos debitis officia corporis est nisi ab et. Atque itaque alias eius voluptas minus. Accusamus numquam tempore occaecati in."
+ )
+
+ changeset = User.register_changeset(%User{}, params)
+
+ refute changeset.valid?
+ end
+ end
+
describe "get_or_fetch/1" do
test "gets an existing user by nickname" do
user = insert(:user)
@@ -1181,6 +1303,31 @@ test "hide a user's statuses from timelines and notifications" do
end
end
+ describe "approve" do
+ test "approves a user" do
+ user = insert(:user, approval_pending: true)
+ assert true == user.approval_pending
+ {:ok, user} = User.approve(user)
+ assert false == user.approval_pending
+ end
+
+ test "approves a list of users" do
+ unapproved_users = [
+ insert(:user, approval_pending: true),
+ insert(:user, approval_pending: true),
+ insert(:user, approval_pending: true)
+ ]
+
+ {:ok, users} = User.approve(unapproved_users)
+
+ assert Enum.count(users) == 3
+
+ Enum.each(users, fn user ->
+ assert false == user.approval_pending
+ end)
+ end
+ end
+
describe "delete" do
setup do
{:ok, user} = insert(:user) |> User.set_cache()
@@ -1268,6 +1415,17 @@ test "deactivates user when activation is not required", %{user: user} do
end
end
+ test "delete/1 when approval is pending deletes the user" do
+ user = insert(:user, approval_pending: true)
+ {:ok, user: user}
+
+ {:ok, job} = User.delete(user)
+ {:ok, _} = ObanHelpers.perform(job)
+
+ refute User.get_cached_by_id(user.id)
+ refute User.get_by_id(user.id)
+ end
+
test "get_public_key_for_ap_id fetches a user that's not in the db" do
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
end
@@ -1342,6 +1500,14 @@ test "returns :deactivated for deactivated user" do
user = insert(:user, local: true, confirmation_pending: false, deactivated: true)
assert User.account_status(user) == :deactivated
end
+
+ test "returns :approval_pending for unapproved user" do
+ user = insert(:user, local: true, approval_pending: true)
+ assert User.account_status(user) == :approval_pending
+
+ user = insert(:user, local: true, confirmation_pending: true, approval_pending: true)
+ assert User.account_status(user) == :approval_pending
+ end
end
describe "superuser?/1" do
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index f3951462f..d6eab7337 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -1179,7 +1179,8 @@ test "it can create a Flag activity",
"id" => activity_ap_id,
"content" => content,
"published" => activity_with_object.object.data["published"],
- "actor" => AccountView.render("show.json", %{user: target_account})
+ "actor" =>
+ AccountView.render("show.json", %{user: target_account, skip_visibility_check: true})
}
assert %Activity{
diff --git a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
index 8babf49e7..f25cf8b12 100644
--- a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
+++ b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
@@ -7,11 +7,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
@id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
+ @local_actor Pleroma.Web.Endpoint.url() <> "/users/cofe"
test "adds `expires_at` property" do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"object" => %{"type" => "Note"}
})
@@ -25,6 +27,7 @@ test "keeps existing `expires_at` if it less than the config setting" do
assert {:ok, %{"type" => "Create", "expires_at" => ^expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"expires_at" => expires_at,
"object" => %{"type" => "Note"}
@@ -37,6 +40,7 @@ test "overwrites existing `expires_at` if it greater than the config setting" do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"expires_at" => too_distant_future,
"object" => %{"type" => "Note"}
@@ -49,6 +53,7 @@ test "ignores remote activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Create",
"object" => %{"type" => "Note"}
})
@@ -60,6 +65,7 @@ test "ignores non-Create/Note activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Follow"
})
@@ -68,6 +74,7 @@ test "ignores non-Create/Note activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Create",
"object" => %{"type" => "Cofe"}
})
diff --git a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/web/activity_pub/mrf/ensure_re_prepended_test.exs
index 38ddec5bb..9a283f27d 100644
--- a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs
+++ b/test/web/activity_pub/mrf/ensure_re_prepended_test.exs
@@ -78,5 +78,15 @@ test "it skip if parent and child summary isn't equal" do
assert {:ok, res} = EnsureRePrepended.filter(message)
assert res == message
end
+
+ test "it skips if the object is only a reference" do
+ message = %{
+ "type" => "Create",
+ "object" => "somereference"
+ }
+
+ assert {:ok, res} = EnsureRePrepended.filter(message)
+ assert res == message
+ end
end
end
diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs
index b0fb753bd..cf6acc9a2 100644
--- a/test/web/activity_pub/mrf/object_age_policy_test.exs
+++ b/test/web/activity_pub/mrf/object_age_policy_test.exs
@@ -38,6 +38,17 @@ defp get_new_message do
end
describe "with reject action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:reject])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ assert match?({:reject, _}, ObjectAgePolicy.filter(data))
+ end
+
test "it rejects an old post" do
Config.put([:mrf_object_age, :actions], [:reject])
@@ -56,6 +67,21 @@ test "it allows a new post" do
end
describe "with delist action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:delist])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ {: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 delists an old post" do
Config.put([:mrf_object_age, :actions], [:delist])
@@ -80,6 +106,22 @@ test "it allows a new post" do
end
describe "with strip_followers action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:strip_followers])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ {: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 strips followers collections from an old post" do
Config.put([:mrf_object_age, :actions], [:strip_followers])
diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs
index e842d8d8d..d7dde62c4 100644
--- a/test/web/activity_pub/mrf/simple_policy_test.exs
+++ b/test/web/activity_pub/mrf/simple_policy_test.exs
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
import Pleroma.Factory
alias Pleroma.Config
alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
+ alias Pleroma.Web.CommonAPI
setup do:
clear_config(:mrf_simple,
@@ -15,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
federated_timeline_removal: [],
report_removal: [],
reject: [],
+ followers_only: [],
accept: [],
avatar_removal: [],
banner_removal: [],
@@ -261,6 +263,64 @@ test "actor has a matching host" do
end
end
+ describe "when :followers_only" do
+ test "is empty" do
+ Config.put([:mrf_simple, :followers_only], [])
+ {_, ftl_message} = build_ftl_actor_and_message()
+ local_message = build_local_message()
+
+ assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
+ assert SimplePolicy.filter(local_message) == {:ok, local_message}
+ end
+
+ test "has a matching host" do
+ actor = insert(:user)
+ following_user = insert(:user)
+ non_following_user = insert(:user)
+
+ {:ok, _, _, _} = CommonAPI.follow(following_user, actor)
+
+ activity = %{
+ "actor" => actor.ap_id,
+ "to" => [
+ "https://www.w3.org/ns/activitystreams#Public",
+ following_user.ap_id,
+ non_following_user.ap_id
+ ],
+ "cc" => [actor.follower_address, "http://foo.bar/qux"]
+ }
+
+ dm_activity = %{
+ "actor" => actor.ap_id,
+ "to" => [
+ following_user.ap_id,
+ non_following_user.ap_id
+ ],
+ "cc" => []
+ }
+
+ actor_domain =
+ activity
+ |> Map.fetch!("actor")
+ |> URI.parse()
+ |> Map.fetch!(:host)
+
+ Config.put([:mrf_simple, :followers_only], [actor_domain])
+
+ assert {:ok, new_activity} = SimplePolicy.filter(activity)
+ assert actor.follower_address in new_activity["cc"]
+ assert following_user.ap_id in new_activity["to"]
+ refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["to"]
+ refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["cc"]
+ refute non_following_user.ap_id in new_activity["to"]
+ refute non_following_user.ap_id in new_activity["cc"]
+
+ assert {:ok, new_dm_activity} = SimplePolicy.filter(dm_activity)
+ assert new_dm_activity["to"] == [following_user.ap_id]
+ assert new_dm_activity["cc"] == []
+ end
+ end
+
describe "when :accept" do
test "is empty" do
Config.put([:mrf_simple, :accept], [])
diff --git a/test/web/activity_pub/object_validators/delete_validation_test.exs b/test/web/activity_pub/object_validators/delete_validation_test.exs
index 42cd18298..02683b899 100644
--- a/test/web/activity_pub/object_validators/delete_validation_test.exs
+++ b/test/web/activity_pub/object_validators/delete_validation_test.exs
@@ -87,7 +87,7 @@ test "it's invalid if the actor of the object and the actor of delete are from d
{:error, cng} = ObjectValidator.validate(invalid_other_actor, [])
- assert {:actor, {"is not allowed to delete object", []}} in cng.errors
+ assert {:actor, {"is not allowed to modify object", []}} in cng.errors
end
test "it's valid if the actor of the object is a local superuser",
diff --git a/test/web/activity_pub/pipeline_test.exs b/test/web/activity_pub/pipeline_test.exs
index 8deb64501..f2a231eaf 100644
--- a/test/web/activity_pub/pipeline_test.exs
+++ b/test/web/activity_pub/pipeline_test.exs
@@ -14,6 +14,51 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
:ok
end
+ test "when given an `object_data` in meta, Federation will receive a the original activity with the `object` field set to this embedded object" do
+ activity = insert(:note_activity)
+ object = %{"id" => "1", "type" => "Love"}
+ meta = [local: true, object_data: object]
+
+ activity_with_object = %{activity | data: Map.put(activity.data, "object", object)}
+
+ with_mocks([
+ {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
+ {
+ Pleroma.Web.ActivityPub.MRF,
+ [],
+ [filter: fn o -> {:ok, o} end]
+ },
+ {
+ Pleroma.Web.ActivityPub.ActivityPub,
+ [],
+ [persist: fn o, m -> {:ok, o, m} end]
+ },
+ {
+ Pleroma.Web.ActivityPub.SideEffects,
+ [],
+ [
+ handle: fn o, m -> {:ok, o, m} end,
+ handle_after_transaction: fn m -> m end
+ ]
+ },
+ {
+ Pleroma.Web.Federator,
+ [],
+ [publish: fn _o -> :ok end]
+ }
+ ]) do
+ assert {:ok, ^activity, ^meta} =
+ Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
+
+ assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
+ assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
+ assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
+ assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
+ refute called(Pleroma.Web.Federator.publish(activity))
+ assert_called(Pleroma.Web.Federator.publish(activity_with_object))
+ end
+ end
+
test "it goes through validation, filtering, persisting, side effects and federation for local activities" do
activity = insert(:note_activity)
meta = [local: true]
diff --git a/test/web/activity_pub/side_effects_test.exs b/test/web/activity_pub/side_effects_test.exs
index 2649b060a..4a08eb7ee 100644
--- a/test/web/activity_pub/side_effects_test.exs
+++ b/test/web/activity_pub/side_effects_test.exs
@@ -312,8 +312,12 @@ test "when activation is required", %{delete: delete, user: user} do
}
end
- test "deletes the original block", %{block_undo: block_undo, block: block} do
- {:ok, _block_undo, _} = SideEffects.handle(block_undo)
+ test "deletes the original block", %{
+ block_undo: block_undo,
+ block: block
+ } do
+ {:ok, _block_undo, _meta} = SideEffects.handle(block_undo)
+
refute Activity.get_by_id(block.id)
end
diff --git a/test/web/activity_pub/transmogrifier/answer_handling_test.exs b/test/web/activity_pub/transmogrifier/answer_handling_test.exs
new file mode 100644
index 000000000..0f6605c3f
--- /dev/null
+++ b/test/web/activity_pub/transmogrifier/answer_handling_test.exs
@@ -0,0 +1,78 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.Web.ActivityPub.Transmogrifier
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+
+ setup_all do
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ :ok
+ end
+
+ test "incoming, rewrites Note to Answer and increments vote counters" do
+ user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "suya...",
+ poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
+ })
+
+ object = Object.normalize(activity)
+
+ data =
+ File.read!("test/fixtures/mastodon-vote.json")
+ |> Poison.decode!()
+ |> Kernel.put_in(["to"], user.ap_id)
+ |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
+ |> Kernel.put_in(["object", "to"], user.ap_id)
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+ answer_object = Object.normalize(activity)
+ assert answer_object.data["type"] == "Answer"
+ assert answer_object.data["inReplyTo"] == object.data["id"]
+
+ new_object = Object.get_by_ap_id(object.data["id"])
+ assert new_object.data["replies_count"] == object.data["replies_count"]
+
+ assert Enum.any?(
+ new_object.data["oneOf"],
+ fn
+ %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
+ _ -> false
+ end
+ )
+ end
+
+ test "outgoing, rewrites Answer to Note" do
+ user = insert(:user)
+
+ {:ok, poll_activity} =
+ CommonAPI.post(user, %{
+ status: "suya...",
+ poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
+ })
+
+ poll_object = Object.normalize(poll_activity)
+ # TODO: Replace with CommonAPI vote creation when implemented
+ data =
+ File.read!("test/fixtures/mastodon-vote.json")
+ |> Poison.decode!()
+ |> Kernel.put_in(["to"], user.ap_id)
+ |> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
+ |> Kernel.put_in(["object", "to"], user.ap_id)
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+ {:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
+
+ assert data["object"]["type"] == "Note"
+ end
+end
diff --git a/test/web/activity_pub/transmogrifier/chat_message_test.exs b/test/web/activity_pub/transmogrifier/chat_message_test.exs
index d6736dc3e..31274c067 100644
--- a/test/web/activity_pub/transmogrifier/chat_message_test.exs
+++ b/test/web/activity_pub/transmogrifier/chat_message_test.exs
@@ -124,6 +124,24 @@ test "it fetches the actor if they aren't in our system" do
{:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data)
end
+ test "it doesn't work for deactivated users" do
+ data =
+ File.read!("test/fixtures/create-chat-message.json")
+ |> Poison.decode!()
+
+ _author =
+ insert(:user,
+ ap_id: data["actor"],
+ local: false,
+ last_refreshed_at: DateTime.utc_now(),
+ deactivated: true
+ )
+
+ _recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
+
+ assert {:error, _} = Transmogrifier.handle_incoming(data)
+ end
+
test "it inserts it and creates a chat" do
data =
File.read!("test/fixtures/create-chat-message.json")
diff --git a/test/web/activity_pub/transmogrifier/question_handling_test.exs b/test/web/activity_pub/transmogrifier/question_handling_test.exs
new file mode 100644
index 000000000..9fb965d7f
--- /dev/null
+++ b/test/web/activity_pub/transmogrifier/question_handling_test.exs
@@ -0,0 +1,123 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.Web.ActivityPub.Transmogrifier
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+
+ setup_all do
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ :ok
+ end
+
+ test "Mastodon Question activity" do
+ data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+ object = Object.normalize(activity, false)
+
+ assert object.data["closed"] == "2019-05-11T09:03:36Z"
+
+ assert object.data["context"] == activity.data["context"]
+
+ assert object.data["context"] ==
+ "tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation"
+
+ assert object.data["context_id"]
+
+ assert object.data["anyOf"] == []
+
+ assert Enum.sort(object.data["oneOf"]) ==
+ Enum.sort([
+ %{
+ "name" => "25 char limit is dumb",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"},
+ "type" => "Note"
+ },
+ %{
+ "name" => "Dunno",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"},
+ "type" => "Note"
+ },
+ %{
+ "name" => "Everyone knows that!",
+ "replies" => %{"totalItems" => 1, "type" => "Collection"},
+ "type" => "Note"
+ },
+ %{
+ "name" => "I can't even fit a funny",
+ "replies" => %{"totalItems" => 1, "type" => "Collection"},
+ "type" => "Note"
+ }
+ ])
+
+ user = insert(:user)
+
+ {:ok, reply_activity} = CommonAPI.post(user, %{status: "hewwo", in_reply_to_id: activity.id})
+
+ reply_object = Object.normalize(reply_activity, false)
+
+ assert reply_object.data["context"] == object.data["context"]
+ assert reply_object.data["context_id"] == object.data["context_id"]
+ end
+
+ test "Mastodon Question activity with HTML tags in plaintext" do
+ options = [
+ %{
+ "type" => "Note",
+ "name" => "
",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"}
+ },
+ %{
+ "type" => "Note",
+ "name" => "
",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"}
+ },
+ %{
+ "type" => "Note",
+ "name" => "
",
+ "replies" => %{"totalItems" => 1, "type" => "Collection"}
+ },
+ %{
+ "type" => "Note",
+ "name" => "
",
+ "replies" => %{"totalItems" => 1, "type" => "Collection"}
+ }
+ ]
+
+ data =
+ File.read!("test/fixtures/mastodon-question-activity.json")
+ |> Poison.decode!()
+ |> Kernel.put_in(["object", "oneOf"], options)
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+ object = Object.normalize(activity, false)
+
+ assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
+ end
+
+ test "returns an error if received a second time" do
+ data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
+
+ assert {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+ assert {:error, {:validate_object, {:error, _}}} = Transmogrifier.handle_incoming(data)
+ end
+
+ test "accepts a Question with no content" do
+ data =
+ File.read!("test/fixtures/mastodon-question-activity.json")
+ |> Poison.decode!()
+ |> Kernel.put_in(["object", "content"], "")
+
+ assert {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
+ end
+end
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 248b410c6..6dd9a3fec 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -160,7 +160,15 @@ test "it does not crash if the object in inReplyTo can't be fetched" do
assert capture_log(fn ->
{:ok, _returned_activity} = Transmogrifier.handle_incoming(data)
- end) =~ "[error] Couldn't fetch \"https://404.site/whatever\", error: nil"
+ end) =~ "[warn] Couldn't fetch \"https://404.site/whatever\", error: nil"
+ end
+
+ test "it does not work for deactivated users" do
+ data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
+
+ insert(:user, ap_id: data["actor"], deactivated: true)
+
+ assert {:error, _} = Transmogrifier.handle_incoming(data)
end
test "it works for incoming notices" do
@@ -217,23 +225,6 @@ test "it works for incoming notices with hashtags" do
assert Enum.at(object.data["tag"], 2) == "moo"
end
- test "it works for incoming questions" do
- data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
- object = Object.normalize(activity)
-
- assert Enum.all?(object.data["oneOf"], fn choice ->
- choice["name"] in [
- "Dunno",
- "Everyone knows that!",
- "25 char limit is dumb",
- "I can't even fit a funny"
- ]
- end)
- end
-
test "it works for incoming listens" do
data = %{
"@context" => "https://www.w3.org/ns/activitystreams",
@@ -263,38 +254,6 @@ test "it works for incoming listens" do
assert object.data["length"] == 180_000
end
- test "it rewrites Note votes to Answers and increments vote counters on question activities" do
- user = insert(:user)
-
- {:ok, activity} =
- CommonAPI.post(user, %{
- status: "suya...",
- poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
- })
-
- object = Object.normalize(activity)
-
- data =
- File.read!("test/fixtures/mastodon-vote.json")
- |> Poison.decode!()
- |> Kernel.put_in(["to"], user.ap_id)
- |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
- |> Kernel.put_in(["object", "to"], user.ap_id)
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
- answer_object = Object.normalize(activity)
- assert answer_object.data["type"] == "Answer"
- object = Object.get_by_ap_id(object.data["id"])
-
- assert Enum.any?(
- object.data["oneOf"],
- fn
- %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
- _ -> false
- end
- )
- end
-
test "it works for incoming notices with contentMap" do
data =
File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
@@ -669,7 +628,8 @@ test "it remaps video URLs as attachments if necessary" do
%{
"href" =>
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
- "mediaType" => "video/mp4"
+ "mediaType" => "video/mp4",
+ "type" => "Link"
}
]
}
@@ -688,7 +648,8 @@ test "it remaps video URLs as attachments if necessary" do
%{
"href" =>
"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4",
- "mediaType" => "video/mp4"
+ "mediaType" => "video/mp4",
+ "type" => "Link"
}
]
}
@@ -710,7 +671,7 @@ test "it accepts Flag activities" do
"id" => activity.data["id"],
"content" => "test post",
"published" => object.data["published"],
- "actor" => AccountView.render("show.json", %{user: user})
+ "actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true})
}
message = %{
@@ -1261,30 +1222,6 @@ test "successfully reserializes a message with AS2 objects in IR" do
end
end
- test "Rewrites Answers to Notes" do
- user = insert(:user)
-
- {:ok, poll_activity} =
- CommonAPI.post(user, %{
- status: "suya...",
- poll: %{options: ["suya", "suya.", "suya.."], expires_in: 10}
- })
-
- poll_object = Object.normalize(poll_activity)
- # TODO: Replace with CommonAPI vote creation when implemented
- data =
- File.read!("test/fixtures/mastodon-vote.json")
- |> Poison.decode!()
- |> Kernel.put_in(["to"], user.ap_id)
- |> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
- |> Kernel.put_in(["object", "to"], user.ap_id)
-
- {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
- {:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
-
- assert data["object"]["type"] == "Note"
- end
-
describe "fix_explicit_addressing" do
setup do
user = insert(:user)
@@ -1532,8 +1469,13 @@ test "returns modified object when attachment is map" do
"attachment" => [
%{
"mediaType" => "video/mp4",
+ "type" => "Document",
"url" => [
- %{"href" => "https://peertube.moe/stat-480.mp4", "mediaType" => "video/mp4"}
+ %{
+ "href" => "https://peertube.moe/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
]
}
]
@@ -1550,14 +1492,24 @@ test "returns modified object when attachment is list" do
"attachment" => [
%{
"mediaType" => "video/mp4",
+ "type" => "Document",
"url" => [
- %{"href" => "https://pe.er/stat-480.mp4", "mediaType" => "video/mp4"}
+ %{
+ "href" => "https://pe.er/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
]
},
%{
"mediaType" => "video/mp4",
+ "type" => "Document",
"url" => [
- %{"href" => "https://pe.er/stat-480.mp4", "mediaType" => "video/mp4"}
+ %{
+ "href" => "https://pe.er/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
]
}
]
diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs
index 361dc5a41..d50213545 100644
--- a/test/web/activity_pub/utils_test.exs
+++ b/test/web/activity_pub/utils_test.exs
@@ -482,7 +482,8 @@ test "returns map with Flag object" do
"id" => activity_ap_id,
"content" => content,
"published" => activity.object.data["published"],
- "actor" => AccountView.render("show.json", %{user: target_account})
+ "actor" =>
+ AccountView.render("show.json", %{user: target_account, skip_visibility_check: true})
}
assert %{
diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs
index da91cd552..b5d5bd8c7 100644
--- a/test/web/admin_api/controllers/admin_api_controller_test.exs
+++ b/test/web/admin_api/controllers/admin_api_controller_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
import ExUnit.CaptureLog
import Mock
import Pleroma.Factory
+ import Swoosh.TestAssertions
alias Pleroma.Activity
alias Pleroma.Config
@@ -348,7 +349,9 @@ test "Show", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
assert expected == json_response(conn, 200)
@@ -612,6 +615,8 @@ test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do
describe "GET /api/pleroma/admin/users" do
test "renders users array for the first page", %{conn: conn, admin: admin} do
user = insert(:user, local: false, tags: ["foo", "bar"])
+ user2 = insert(:user, approval_pending: true, registration_reason: "I'm a chill dude")
+
conn = get(conn, "/api/pleroma/admin/users?page=1")
users =
@@ -626,7 +631,9 @@ test "renders users array for the first page", %{conn: conn, admin: admin} do
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false,
- "url" => admin.ap_id
+ "approval_pending" => false,
+ "url" => admin.ap_id,
+ "registration_reason" => nil
},
%{
"deactivated" => user.deactivated,
@@ -638,13 +645,29 @@ test "renders users array for the first page", %{conn: conn, admin: admin} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
+ },
+ %{
+ "deactivated" => user2.deactivated,
+ "id" => user2.id,
+ "nickname" => user2.nickname,
+ "roles" => %{"admin" => false, "moderator" => false},
+ "local" => true,
+ "tags" => [],
+ "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
+ "display_name" => HTML.strip_tags(user2.name || user2.nickname),
+ "confirmation_pending" => false,
+ "approval_pending" => true,
+ "url" => user2.ap_id,
+ "registration_reason" => "I'm a chill dude"
}
]
|> Enum.sort_by(& &1["nickname"])
assert json_response(conn, 200) == %{
- "count" => 2,
+ "count" => 3,
"page_size" => 50,
"users" => users
}
@@ -711,7 +734,9 @@ test "regular search", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -737,7 +762,9 @@ test "search by domain", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -763,7 +790,9 @@ test "search by full nickname", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -789,7 +818,9 @@ test "search by display name", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -815,7 +846,9 @@ test "search by email", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -841,7 +874,9 @@ test "regular search with page size", %{conn: conn} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -862,7 +897,9 @@ test "regular search with page size", %{conn: conn} do
"avatar" => User.avatar_url(user2) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user2.name || user2.nickname),
"confirmation_pending" => false,
- "url" => user2.ap_id
+ "approval_pending" => false,
+ "url" => user2.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -895,7 +932,9 @@ test "only local users" do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -921,7 +960,9 @@ test "only local users with no query", %{conn: conn, admin: old_admin} do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
},
%{
"deactivated" => admin.deactivated,
@@ -933,7 +974,9 @@ test "only local users with no query", %{conn: conn, admin: old_admin} do
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false,
- "url" => admin.ap_id
+ "approval_pending" => false,
+ "url" => admin.ap_id,
+ "registration_reason" => nil
},
%{
"deactivated" => false,
@@ -945,7 +988,9 @@ test "only local users with no query", %{conn: conn, admin: old_admin} do
"avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname),
"confirmation_pending" => false,
- "url" => old_admin.ap_id
+ "approval_pending" => false,
+ "url" => old_admin.ap_id,
+ "registration_reason" => nil
}
]
|> Enum.sort_by(& &1["nickname"])
@@ -957,6 +1002,44 @@ test "only local users with no query", %{conn: conn, admin: old_admin} do
}
end
+ test "only unapproved users", %{conn: conn} do
+ user =
+ insert(:user,
+ nickname: "sadboy",
+ approval_pending: true,
+ registration_reason: "Plz let me in!"
+ )
+
+ insert(:user, nickname: "happyboy", approval_pending: false)
+
+ conn = get(conn, "/api/pleroma/admin/users?filters=need_approval")
+
+ users =
+ [
+ %{
+ "deactivated" => user.deactivated,
+ "id" => user.id,
+ "nickname" => user.nickname,
+ "roles" => %{"admin" => false, "moderator" => false},
+ "local" => true,
+ "tags" => [],
+ "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+ "display_name" => HTML.strip_tags(user.name || user.nickname),
+ "confirmation_pending" => false,
+ "approval_pending" => true,
+ "url" => user.ap_id,
+ "registration_reason" => "Plz let me in!"
+ }
+ ]
+ |> Enum.sort_by(& &1["nickname"])
+
+ assert json_response(conn, 200) == %{
+ "count" => 1,
+ "page_size" => 50,
+ "users" => users
+ }
+ end
+
test "load only admins", %{conn: conn, admin: admin} do
second_admin = insert(:user, is_admin: true)
insert(:user)
@@ -976,7 +1059,9 @@ test "load only admins", %{conn: conn, admin: admin} do
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false,
- "url" => admin.ap_id
+ "approval_pending" => false,
+ "url" => admin.ap_id,
+ "registration_reason" => nil
},
%{
"deactivated" => false,
@@ -988,7 +1073,9 @@ test "load only admins", %{conn: conn, admin: admin} do
"avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname),
"confirmation_pending" => false,
- "url" => second_admin.ap_id
+ "approval_pending" => false,
+ "url" => second_admin.ap_id,
+ "registration_reason" => nil
}
]
|> Enum.sort_by(& &1["nickname"])
@@ -1021,7 +1108,9 @@ test "load only moderators", %{conn: conn} do
"avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(moderator.name || moderator.nickname),
"confirmation_pending" => false,
- "url" => moderator.ap_id
+ "approval_pending" => false,
+ "url" => moderator.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -1047,7 +1136,9 @@ test "load users with tags list", %{conn: conn} do
"avatar" => User.avatar_url(user1) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user1.name || user1.nickname),
"confirmation_pending" => false,
- "url" => user1.ap_id
+ "approval_pending" => false,
+ "url" => user1.ap_id,
+ "registration_reason" => nil
},
%{
"deactivated" => false,
@@ -1059,7 +1150,9 @@ test "load users with tags list", %{conn: conn} do
"avatar" => User.avatar_url(user2) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user2.name || user2.nickname),
"confirmation_pending" => false,
- "url" => user2.ap_id
+ "approval_pending" => false,
+ "url" => user2.ap_id,
+ "registration_reason" => nil
}
]
|> Enum.sort_by(& &1["nickname"])
@@ -1099,7 +1192,9 @@ test "it works with multiple filters" do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -1124,7 +1219,9 @@ test "it omits relay user", %{admin: admin, conn: conn} do
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false,
- "url" => admin.ap_id
+ "approval_pending" => false,
+ "url" => admin.ap_id,
+ "registration_reason" => nil
}
]
}
@@ -1171,6 +1268,26 @@ test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
"@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
end
+ test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do
+ user_one = insert(:user, approval_pending: true)
+ user_two = insert(:user, approval_pending: true)
+
+ conn =
+ patch(
+ conn,
+ "/api/pleroma/admin/users/approve",
+ %{nicknames: [user_one.nickname, user_two.nickname]}
+ )
+
+ response = json_response(conn, 200)
+ assert Enum.map(response["users"], & &1["approval_pending"]) == [false, false]
+
+ log_entry = Repo.one(ModerationLog)
+
+ assert ModerationLog.get_log_entry_message(log_entry) ==
+ "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
+ end
+
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
user = insert(:user)
@@ -1187,7 +1304,9 @@ test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admi
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false,
- "url" => user.ap_id
+ "approval_pending" => false,
+ "url" => user.ap_id,
+ "registration_reason" => nil
}
log_entry = Repo.one(ModerationLog)
@@ -1731,6 +1850,9 @@ test "it resend emails for two users", %{conn: conn, admin: admin} do
"@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{
second_user.nickname
}"
+
+ ObanHelpers.perform_all()
+ assert_email_sent(Pleroma.Emails.UserEmail.account_confirmation_email(first_user))
end
end
diff --git a/test/web/admin_api/controllers/report_controller_test.exs b/test/web/admin_api/controllers/report_controller_test.exs
index f30dc8956..57946e6bb 100644
--- a/test/web/admin_api/controllers/report_controller_test.exs
+++ b/test/web/admin_api/controllers/report_controller_test.exs
@@ -204,7 +204,7 @@ test "updates state of multiple reports", %{
test "returns empty response when no reports created", %{conn: conn} do
response =
conn
- |> get("/api/pleroma/admin/reports")
+ |> get(report_path(conn, :index))
|> json_response_and_validate_schema(:ok)
assert Enum.empty?(response["reports"])
@@ -224,7 +224,7 @@ test "returns reports", %{conn: conn} do
response =
conn
- |> get("/api/pleroma/admin/reports")
+ |> get(report_path(conn, :index))
|> json_response_and_validate_schema(:ok)
[report] = response["reports"]
@@ -256,7 +256,7 @@ test "returns reports with specified state", %{conn: conn} do
response =
conn
- |> get("/api/pleroma/admin/reports?state=open")
+ |> get(report_path(conn, :index, %{state: "open"}))
|> json_response_and_validate_schema(:ok)
assert [open_report] = response["reports"]
@@ -268,7 +268,7 @@ test "returns reports with specified state", %{conn: conn} do
response =
conn
- |> get("/api/pleroma/admin/reports?state=closed")
+ |> get(report_path(conn, :index, %{state: "closed"}))
|> json_response_and_validate_schema(:ok)
assert [closed_report] = response["reports"]
@@ -280,9 +280,7 @@ test "returns reports with specified state", %{conn: conn} do
assert %{"total" => 0, "reports" => []} ==
conn
- |> get("/api/pleroma/admin/reports?state=resolved", %{
- "" => ""
- })
+ |> get(report_path(conn, :index, %{state: "resolved"}))
|> json_response_and_validate_schema(:ok)
end
diff --git a/test/web/admin_api/search_test.exs b/test/web/admin_api/search_test.exs
index e0e3d4153..b974cedd5 100644
--- a/test/web/admin_api/search_test.exs
+++ b/test/web/admin_api/search_test.exs
@@ -166,5 +166,16 @@ test "it returns user by email" do
assert total == 3
assert count == 1
end
+
+ test "it returns unapproved user" do
+ unapproved = insert(:user, approval_pending: true)
+ insert(:user)
+ insert(:user)
+
+ {:ok, _results, total} = Search.user()
+ {:ok, [^unapproved], count} = Search.user(%{need_approval: true})
+ assert total == 3
+ assert count == 1
+ end
end
end
diff --git a/test/web/admin_api/views/report_view_test.exs b/test/web/admin_api/views/report_view_test.exs
index f00b0afb2..5a02292be 100644
--- a/test/web/admin_api/views/report_view_test.exs
+++ b/test/web/admin_api/views/report_view_test.exs
@@ -4,11 +4,14 @@
defmodule Pleroma.Web.AdminAPI.ReportViewTest do
use Pleroma.DataCase
+
import Pleroma.Factory
+
+ alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.AdminAPI.ReportView
alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MastodonAPI.StatusView
test "renders a report" do
@@ -21,13 +24,16 @@ test "renders a report" do
content: nil,
actor:
Map.merge(
- AccountView.render("show.json", %{user: user}),
- Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
+ MastodonAPI.AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
+ AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
- AccountView.render("show.json", %{user: other_user}),
- Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
+ MastodonAPI.AccountView.render("show.json", %{
+ user: other_user,
+ skip_visibility_check: true
+ }),
+ AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [],
notes: [],
@@ -56,13 +62,16 @@ test "includes reported statuses" do
content: nil,
actor:
Map.merge(
- AccountView.render("show.json", %{user: user}),
- Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
+ MastodonAPI.AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
+ AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
- AccountView.render("show.json", %{user: other_user}),
- Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
+ MastodonAPI.AccountView.render("show.json", %{
+ user: other_user,
+ skip_visibility_check: true
+ }),
+ AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [StatusView.render("show.json", %{activity: activity})],
state: "open",
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 7e11fede3..4ba6232dc 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -458,6 +458,11 @@ test "it adds emoji in the object" do
end
describe "posting" do
+ test "deactivated users can't post" do
+ user = insert(:user, deactivated: true)
+ assert {:error, _} = CommonAPI.post(user, %{status: "ye"})
+ end
+
test "it supports explicit addressing" do
user = insert(:user)
user_two = insert(:user)
@@ -624,14 +629,27 @@ test "unreacting to a status with an emoji" do
user = insert(:user)
other_user = insert(:user)
- {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
- {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
+ clear_config([:instance, :federating], true)
- {:ok, unreaction} = CommonAPI.unreact_with_emoji(activity.id, user, "👍")
+ with_mock Pleroma.Web.Federator,
+ publish: fn _ -> nil end do
+ {:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
+ {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
- assert unreaction.data["type"] == "Undo"
- assert unreaction.data["object"] == reaction.data["id"]
- assert unreaction.local
+ {:ok, unreaction} = CommonAPI.unreact_with_emoji(activity.id, user, "👍")
+
+ assert unreaction.data["type"] == "Undo"
+ assert unreaction.data["object"] == reaction.data["id"]
+ assert unreaction.local
+
+ # On federation, it contains the undone (and deleted) object
+ unreaction_with_object = %{
+ unreaction
+ | data: Map.put(unreaction.data, "object", reaction.data)
+ }
+
+ assert called(Pleroma.Web.Federator.publish(unreaction_with_object))
+ end
end
test "repeating a status" do
diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs
index fa2ed1ea5..0d2a61967 100644
--- a/test/web/feed/user_controller_test.exs
+++ b/test/web/feed/user_controller_test.exs
@@ -181,6 +181,17 @@ test "returns feed with public and unlisted activities", %{conn: conn} do
assert activity_titles == ['public', 'unlisted']
end
+
+ test "returns 404 when the user is remote", %{conn: conn} do
+ user = insert(:user, local: false)
+
+ {:ok, _} = CommonAPI.post(user, %{status: "test"})
+
+ assert conn
+ |> put_req_header("accept", "application/atom+xml")
+ |> get(user_feed_path(conn, :feed, user.nickname))
+ |> response(404)
+ end
end
# Note: see ActivityPubControllerTest for JSON format tests
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
index 9c7b5e9b2..17a1e7d66 100644
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/web/mastodon_api/controllers/account_controller_test.exs
@@ -5,7 +5,6 @@
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
use Pleroma.Web.ConnCase
- alias Pleroma.Config
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -16,8 +15,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
import Pleroma.Factory
describe "account fetching" do
- setup do: clear_config([:instance, :limit_to_local_content])
-
test "works by id" do
%User{id: user_id} = insert(:user)
@@ -42,7 +39,7 @@ test "works by nickname" do
end
test "works by nickname for remote users" do
- Config.put([:instance, :limit_to_local_content], false)
+ clear_config([:instance, :limit_to_local_content], false)
user = insert(:user, nickname: "user@example.com", local: false)
@@ -53,7 +50,7 @@ test "works by nickname for remote users" do
end
test "respects limit_to_local_content == :all for remote user nicknames" do
- Config.put([:instance, :limit_to_local_content], :all)
+ clear_config([:instance, :limit_to_local_content], :all)
user = insert(:user, nickname: "user@example.com", local: false)
@@ -63,7 +60,7 @@ test "respects limit_to_local_content == :all for remote user nicknames" do
end
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
- Config.put([:instance, :limit_to_local_content], :unauthenticated)
+ clear_config([:instance, :limit_to_local_content], :unauthenticated)
user = insert(:user, nickname: "user@example.com", local: false)
reading_user = insert(:user)
@@ -583,6 +580,15 @@ test "getting followers, pagination", %{user: user, conn: conn} do
|> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3_id}")
|> json_response_and_validate_schema(200)
+ assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] =
+ conn
+ |> get(
+ "/api/v1/accounts/#{user.id}/followers?id=#{user.id}&limit=20&max_id=#{
+ follower3_id
+ }"
+ )
+ |> json_response_and_validate_schema(200)
+
res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3_id}")
assert [%{"id" => ^follower2_id}] = json_response_and_validate_schema(res_conn, 200)
@@ -654,6 +660,16 @@ test "getting following, pagination", %{user: user, conn: conn} do
assert id2 == following2.id
assert id1 == following1.id
+ res_conn =
+ get(
+ conn,
+ "/api/v1/accounts/#{user.id}/following?id=#{user.id}&limit=20&max_id=#{following3.id}"
+ )
+
+ assert [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200)
+ assert id2 == following2.id
+ assert id1 == following1.id
+
res_conn =
get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
@@ -884,9 +900,93 @@ test "blocking / unblocking a user" do
[valid_params: valid_params]
end
- setup do: clear_config([:instance, :account_activation_required])
+ test "registers and logs in without :account_activation_required / :account_approval_required",
+ %{conn: conn} do
+ clear_config([:instance, :account_activation_required], false)
+ clear_config([:instance, :account_approval_required], false)
+
+ conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/apps", %{
+ client_name: "client_name",
+ redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
+ scopes: "read, write, follow"
+ })
+
+ assert %{
+ "client_id" => client_id,
+ "client_secret" => client_secret,
+ "id" => _,
+ "name" => "client_name",
+ "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
+ "vapid_key" => _,
+ "website" => nil
+ } = json_response_and_validate_schema(conn, 200)
+
+ conn =
+ post(conn, "/oauth/token", %{
+ grant_type: "client_credentials",
+ client_id: client_id,
+ client_secret: client_secret
+ })
+
+ assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
+ json_response(conn, 200)
+
+ assert token
+ token_from_db = Repo.get_by(Token, token: token)
+ assert token_from_db
+ assert refresh
+ assert scope == "read write follow"
+
+ clear_config([User, :email_blacklist], ["example.org"])
+
+ params = %{
+ username: "lain",
+ email: "lain@example.org",
+ password: "PlzDontHackLain",
+ bio: "Test Bio",
+ agreement: true
+ }
+
+ conn =
+ build_conn()
+ |> put_req_header("content-type", "multipart/form-data")
+ |> put_req_header("authorization", "Bearer " <> token)
+ |> post("/api/v1/accounts", params)
+
+ assert %{"error" => "{\"email\":[\"Invalid email\"]}"} =
+ json_response_and_validate_schema(conn, 400)
+
+ Pleroma.Config.put([User, :email_blacklist], [])
+
+ conn =
+ build_conn()
+ |> put_req_header("content-type", "multipart/form-data")
+ |> put_req_header("authorization", "Bearer " <> token)
+ |> post("/api/v1/accounts", params)
+
+ %{
+ "access_token" => token,
+ "created_at" => _created_at,
+ "scope" => ^scope,
+ "token_type" => "Bearer"
+ } = json_response_and_validate_schema(conn, 200)
+
+ token_from_db = Repo.get_by(Token, token: token)
+ assert token_from_db
+ user = Repo.preload(token_from_db, :user).user
+
+ assert user
+ refute user.confirmation_pending
+ refute user.approval_pending
+ end
+
+ test "registers but does not log in with :account_activation_required", %{conn: conn} do
+ clear_config([:instance, :account_activation_required], true)
+ clear_config([:instance, :account_approval_required], false)
- test "Account registration via Application", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
@@ -934,19 +1034,76 @@ test "Account registration via Application", %{conn: conn} do
agreement: true
})
- %{
- "access_token" => token,
- "created_at" => _created_at,
- "scope" => ^scope,
- "token_type" => "Bearer"
- } = json_response_and_validate_schema(conn, 200)
+ response = json_response_and_validate_schema(conn, 200)
+ assert %{"identifier" => "missing_confirmed_email"} = response
+ refute response["access_token"]
+ refute response["token_type"]
+ user = Repo.get_by(User, email: "lain@example.org")
+ assert user.confirmation_pending
+ end
+
+ test "registers but does not log in with :account_approval_required", %{conn: conn} do
+ clear_config([:instance, :account_approval_required], true)
+ clear_config([:instance, :account_activation_required], false)
+
+ conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/apps", %{
+ client_name: "client_name",
+ redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
+ scopes: "read, write, follow"
+ })
+
+ assert %{
+ "client_id" => client_id,
+ "client_secret" => client_secret,
+ "id" => _,
+ "name" => "client_name",
+ "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
+ "vapid_key" => _,
+ "website" => nil
+ } = json_response_and_validate_schema(conn, 200)
+
+ conn =
+ post(conn, "/oauth/token", %{
+ grant_type: "client_credentials",
+ client_id: client_id,
+ client_secret: client_secret
+ })
+
+ assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
+ json_response(conn, 200)
+
+ assert token
token_from_db = Repo.get_by(Token, token: token)
assert token_from_db
- token_from_db = Repo.preload(token_from_db, :user)
- assert token_from_db.user
+ assert refresh
+ assert scope == "read write follow"
- assert token_from_db.user.confirmation_pending
+ conn =
+ build_conn()
+ |> put_req_header("content-type", "multipart/form-data")
+ |> put_req_header("authorization", "Bearer " <> token)
+ |> post("/api/v1/accounts", %{
+ username: "lain",
+ email: "lain@example.org",
+ password: "PlzDontHackLain",
+ bio: "Test Bio",
+ agreement: true,
+ reason: "I'm a cool dude, bro"
+ })
+
+ response = json_response_and_validate_schema(conn, 200)
+ assert %{"identifier" => "awaiting_approval"} = response
+ refute response["access_token"]
+ refute response["token_type"]
+
+ user = Repo.get_by(User, email: "lain@example.org")
+
+ assert user.approval_pending
+ assert user.registration_reason == "I'm a cool dude, bro"
end
test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
@@ -1000,11 +1157,9 @@ test "returns bad_request if missing required params", %{
end)
end
- setup do: clear_config([:instance, :account_activation_required])
-
test "returns bad_request if missing email params when :account_activation_required is enabled",
%{conn: conn, valid_params: valid_params} do
- Pleroma.Config.put([:instance, :account_activation_required], true)
+ clear_config([:instance, :account_activation_required], true)
app_token = insert(:oauth_token, user: nil)
@@ -1169,8 +1324,6 @@ test "respects rate limit setting", %{conn: conn} do
assert token_from_db
token_from_db = Repo.preload(token_from_db, :user)
assert token_from_db.user
-
- assert token_from_db.user.confirmation_pending
end
conn =
diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
index 01a24afcf..664654500 100644
--- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs
+++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
@@ -32,6 +32,38 @@ test "blocking / unblocking a domain" do
refute User.blocks?(user, other_user)
end
+ test "blocking a domain via query params" do
+ %{user: user, conn: conn} = oauth_access(["write:blocks"])
+ other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
+
+ ret_conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/domain_blocks?domain=dogwhistle.zone")
+
+ assert %{} == json_response_and_validate_schema(ret_conn, 200)
+ user = User.get_cached_by_ap_id(user.ap_id)
+ assert User.blocks?(user, other_user)
+ end
+
+ test "unblocking a domain via query params" do
+ %{user: user, conn: conn} = oauth_access(["write:blocks"])
+ other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
+
+ User.block_domain(user, "dogwhistle.zone")
+ user = refresh_record(user)
+ assert User.blocks?(user, other_user)
+
+ ret_conn =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> delete("/api/v1/domain_blocks?domain=dogwhistle.zone")
+
+ assert %{} == json_response_and_validate_schema(ret_conn, 200)
+ user = User.get_cached_by_ap_id(user.ap_id)
+ refute User.blocks?(user, other_user)
+ end
+
test "getting a list of domain blocks" do
%{user: user, conn: conn} = oauth_access(["read:blocks"])
diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs
index f29547d13..0d426ec34 100644
--- a/test/web/mastodon_api/controllers/filter_controller_test.exs
+++ b/test/web/mastodon_api/controllers/filter_controller_test.exs
@@ -64,11 +64,13 @@ test "fetching a list of filters" do
test "get a filter" do
%{user: user, conn: conn} = oauth_access(["read:filters"])
+ # check whole_word false
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
- context: ["home"]
+ context: ["home"],
+ whole_word: false
}
{:ok, filter} = Pleroma.Filter.create(query)
@@ -76,6 +78,25 @@ test "get a filter" do
conn = get(conn, "/api/v1/filters/#{filter.filter_id}")
assert response = json_response_and_validate_schema(conn, 200)
+ assert response["whole_word"] == false
+
+ # check whole_word true
+ %{user: user, conn: conn} = oauth_access(["read:filters"])
+
+ query = %Pleroma.Filter{
+ user_id: user.id,
+ filter_id: 3,
+ phrase: "knight",
+ context: ["home"],
+ whole_word: true
+ }
+
+ {:ok, filter} = Pleroma.Filter.create(query)
+
+ conn = get(conn, "/api/v1/filters/#{filter.filter_id}")
+
+ assert response = json_response_and_validate_schema(conn, 200)
+ assert response["whole_word"] == true
end
test "update a filter" do
@@ -86,7 +107,8 @@ test "update a filter" do
filter_id: 2,
phrase: "knight",
context: ["home"],
- hide: true
+ hide: true,
+ whole_word: true
}
{:ok, _filter} = Pleroma.Filter.create(query)
@@ -108,6 +130,7 @@ test "update a filter" do
assert response["phrase"] == new.phrase
assert response["context"] == new.context
assert response["irreversible"] == true
+ assert response["whole_word"] == true
end
test "delete a filter" do
diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs
index cc880d82c..6a9ccd979 100644
--- a/test/web/mastodon_api/controllers/instance_controller_test.exs
+++ b/test/web/mastodon_api/controllers/instance_controller_test.exs
@@ -27,6 +27,7 @@ test "get instance information", %{conn: conn} do
"thumbnail" => _,
"languages" => _,
"registrations" => _,
+ "approval_required" => _,
"poll_limits" => _,
"upload_limit" => _,
"avatar_upload_limit" => _,
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs
index d34f300da..5955d8334 100644
--- a/test/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/web/mastodon_api/controllers/status_controller_test.exs
@@ -1432,6 +1432,20 @@ test "requires authentication for private posts", %{user: user} do
[%{"id" => id}] = response
assert id == other_user.id
end
+
+ test "returns empty array when :show_reactions is disabled", %{conn: conn, activity: activity} do
+ clear_config([:instance, :show_reactions], false)
+
+ other_user = insert(:user)
+ {:ok, _} = CommonAPI.favorite(other_user, activity.id)
+
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response_and_validate_schema(:ok)
+
+ assert Enum.empty?(response)
+ end
end
describe "GET /api/v1/statuses/:id/reblogged_by" do
diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs
index c08be37d4..0c5a38bf6 100644
--- a/test/web/mastodon_api/mastodon_api_test.exs
+++ b/test/web/mastodon_api/mastodon_api_test.exs
@@ -17,8 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
test "returns error when followed user is deactivated" do
follower = insert(:user)
user = insert(:user, local: true, deactivated: true)
- {:error, error} = MastodonAPI.follow(follower, user)
- assert error == :rejected
+ assert {:error, _error} = MastodonAPI.follow(follower, user)
end
test "following for user" do
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs
index 4a0512e68..a55b5a06e 100644
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ b/test/web/mastodon_api/views/account_view_test.exs
@@ -97,7 +97,7 @@ test "Represent a user account" do
}
}
- assert expected == AccountView.render("show.json", %{user: user})
+ assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
test "Favicon is nil when :instances_favicons is disabled" do
@@ -110,11 +110,12 @@ test "Favicon is nil when :instances_favicons is disabled" do
favicon:
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png"
}
- } = AccountView.render("show.json", %{user: user})
+ } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
Config.put([:instances_favicons, :enabled], false)
- assert %{pleroma: %{favicon: nil}} = AccountView.render("show.json", %{user: user})
+ assert %{pleroma: %{favicon: nil}} =
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
test "Represent the user account for the account owner" do
@@ -192,7 +193,7 @@ test "Represent a Service(bot) account" do
}
}
- assert expected == AccountView.render("show.json", %{user: user})
+ assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
test "Represent a Funkwhale channel" do
@@ -201,7 +202,9 @@ test "Represent a Funkwhale channel" do
"https://channels.tests.funkwhale.audio/federation/actors/compositions"
)
- assert represented = AccountView.render("show.json", %{user: user})
+ assert represented =
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})
+
assert represented.acct == "compositions@channels.tests.funkwhale.audio"
assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
end
@@ -226,6 +229,23 @@ test "Represent a smaller mention" do
assert expected == AccountView.render("mention.json", %{user: user})
end
+ test "demands :for or :skip_visibility_check option for account rendering" do
+ clear_config([:restrict_unauthenticated, :profiles, :local], false)
+
+ user = insert(:user)
+ user_id = user.id
+
+ assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: nil})
+ assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: user})
+
+ assert %{id: ^user_id} =
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})
+
+ assert_raise RuntimeError, ~r/:skip_visibility_check or :for option is required/, fn ->
+ AccountView.render("show.json", %{user: user})
+ end
+ end
+
describe "relationship" do
defp test_relationship_rendering(user, other_user, expected_result) do
opts = %{user: user, target: other_user, relationships: nil}
@@ -339,7 +359,7 @@ test "returns the settings store if the requesting user is the represented user
assert result.pleroma.settings_store == %{:fe => "test"}
- result = AccountView.render("show.json", %{user: user, with_pleroma_settings: true})
+ result = AccountView.render("show.json", %{user: user, for: nil, with_pleroma_settings: true})
assert result.pleroma[:settings_store] == nil
result = AccountView.render("show.json", %{user: user, for: user})
@@ -348,13 +368,13 @@ test "returns the settings store if the requesting user is the represented user
test "doesn't sanitize display names" do
user = insert(:user, name: "
username ")
- result = AccountView.render("show.json", %{user: user})
+ result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
assert result.display_name == "
username "
end
test "never display nil user follow counts" do
user = insert(:user, following_count: 0, follower_count: 0)
- result = AccountView.render("show.json", %{user: user})
+ result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
assert result.following_count == 0
assert result.followers_count == 0
@@ -378,7 +398,7 @@ test "shows when follows/followers stats are hidden and sets follow/follower cou
followers_count: 0,
following_count: 0,
pleroma: %{hide_follows_count: true, hide_followers_count: true}
- } = AccountView.render("show.json", %{user: user})
+ } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
test "shows when follows/followers are hidden" do
@@ -391,7 +411,7 @@ test "shows when follows/followers are hidden" do
followers_count: 1,
following_count: 1,
pleroma: %{hide_follows: true, hide_followers: true}
- } = AccountView.render("show.json", %{user: user})
+ } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
end
test "shows actual follower/following count to the account owner" do
@@ -534,7 +554,7 @@ test "uses mediaproxy urls when it's enabled" do
emoji: %{"joker_smile" => "https://evil.website/society.png"}
)
- AccountView.render("show.json", %{user: user})
+ AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|> Enum.all?(fn
{key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
String.starts_with?(url, Pleroma.Web.base_url())
diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/web/mastodon_api/views/poll_view_test.exs
index 76672f36c..b7e2f17ef 100644
--- a/test/web/mastodon_api/views/poll_view_test.exs
+++ b/test/web/mastodon_api/views/poll_view_test.exs
@@ -135,4 +135,33 @@ test "does not crash on polls with no end date" do
assert result[:expires_at] == nil
assert result[:expired] == false
end
+
+ test "doesn't strips HTML tags" do
+ user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ status: "What's with the smug face?",
+ poll: %{
+ options: [
+ "
",
+ "
",
+ "
",
+ "
"
+ ],
+ expires_in: 20
+ }
+ })
+
+ object = Object.normalize(activity)
+
+ assert %{
+ options: [
+ %{title: "
", votes_count: 0},
+ %{title: "
", votes_count: 0},
+ %{title: "
", votes_count: 0},
+ %{title: "
", votes_count: 0}
+ ]
+ } = PollView.render("show.json", %{object: object})
+ end
end
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
index fa26b3129..8703d5ba7 100644
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ b/test/web/mastodon_api/views/status_view_test.exs
@@ -56,6 +56,23 @@ test "has an emoji reaction list" do
]
end
+ test "works correctly with badly formatted emojis" do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{status: "yo"})
+
+ activity
+ |> Object.normalize(false)
+ |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
+
+ activity = Activity.get_by_id(activity.id)
+
+ status = StatusView.render("show.json", activity: activity, for: user)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "☕", count: 1, me: true}
+ ]
+ end
+
test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
user = insert(:user)
@@ -177,7 +194,7 @@ test "a note activity" do
id: to_string(note.id),
uri: object_data["id"],
url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
- account: AccountView.render("show.json", %{user: user}),
+ account: AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
card: nil,
diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs
index 899af648e..993a490e0 100644
--- a/test/web/oauth/app_test.exs
+++ b/test/web/oauth/app_test.exs
@@ -29,5 +29,16 @@ test "gets exist app and updates scopes" do
assert exist_app.id == app.id
assert exist_app.scopes == ["read", "write", "follow", "push"]
end
+
+ test "has unique client_id" do
+ insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop")
+
+ error =
+ catch_error(insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop"))
+
+ assert %Ecto.ConstraintError{} = error
+ assert error.constraint == "apps_client_id_index"
+ assert error.type == :unique
+ end
end
end
diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs
index 011642c08..63b1c0eb8 100644
--- a/test/web/oauth/ldap_authorization_test.exs
+++ b/test/web/oauth/ldap_authorization_test.exs
@@ -7,7 +7,6 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
alias Pleroma.Repo
alias Pleroma.Web.OAuth.Token
import Pleroma.Factory
- import ExUnit.CaptureLog
import Mock
@skip if !Code.ensure_loaded?(:eldap), do: :skip
@@ -72,9 +71,7 @@ test "creates a new user after successful LDAP authorization" do
equalityMatch: fn _type, _value -> :ok end,
wholeSubtree: fn -> :ok end,
search: fn _connection, _options ->
- {:ok,
- {:eldap_search_result, [{:eldap_entry, '', [{'mail', [to_charlist(user.email)]}]}],
- []}}
+ {:ok, {:eldap_search_result, [{:eldap_entry, '', []}], []}}
end,
close: fn _connection ->
send(self(), :close_connection)
@@ -101,50 +98,6 @@ test "creates a new user after successful LDAP authorization" do
end
end
- @tag @skip
- test "falls back to the default authorization when LDAP is unavailable" do
- password = "testpassword"
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password))
- app = insert(:oauth_app, scopes: ["read", "write"])
-
- host = Pleroma.Config.get([:ldap, :host]) |> to_charlist
- port = Pleroma.Config.get([:ldap, :port])
-
- with_mocks [
- {:eldap, [],
- [
- open: fn [^host], [{:port, ^port}, {:ssl, false} | _] -> {:error, 'connect failed'} end,
- simple_bind: fn _connection, _dn, ^password -> :ok end,
- close: fn _connection ->
- send(self(), :close_connection)
- :ok
- end
- ]}
- ] do
- log =
- capture_log(fn ->
- conn =
- build_conn()
- |> post("/oauth/token", %{
- "grant_type" => "password",
- "username" => user.nickname,
- "password" => password,
- "client_id" => app.client_id,
- "client_secret" => app.client_secret
- })
-
- assert %{"access_token" => token} = json_response(conn, 200)
-
- token = Repo.get_by(Token, token: token)
-
- assert token.user_id == user.id
- end)
-
- assert log =~ "Could not open LDAP connection: 'connect failed'"
- refute_received :close_connection
- end
- end
-
@tag @skip
test "disallow authorization for wrong LDAP credentials" do
password = "testpassword"
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index d389e4ce0..1200126b8 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -19,7 +19,10 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
key: "_test",
signing_salt: "cooldude"
]
- setup do: clear_config([:instance, :account_activation_required])
+ setup do
+ clear_config([:instance, :account_activation_required])
+ clear_config([:instance, :account_approval_required])
+ end
describe "in OAuth consumer mode, " do
setup do
@@ -995,6 +998,30 @@ test "rejects token exchange for user with confirmation_pending set to true" do
}
end
+ test "rejects token exchange for valid credentials belonging to an unapproved user" do
+ password = "testpassword"
+
+ user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt(password), approval_pending: true)
+
+ refute Pleroma.User.account_status(user) == :active
+
+ app = insert(:oauth_app)
+
+ conn =
+ build_conn()
+ |> post("/oauth/token", %{
+ "grant_type" => "password",
+ "username" => user.nickname,
+ "password" => password,
+ "client_id" => app.client_id,
+ "client_secret" => app.client_secret
+ })
+
+ assert resp = json_response(conn, 403)
+ assert %{"error" => _} = resp
+ refute Map.has_key?(resp, "access_token")
+ end
+
test "rejects an invalid authorization code" do
app = insert(:oauth_app)
diff --git a/test/web/pleroma_api/controllers/chat_controller_test.exs b/test/web/pleroma_api/controllers/chat_controller_test.exs
index 82e16741d..d71e80d03 100644
--- a/test/web/pleroma_api/controllers/chat_controller_test.exs
+++ b/test/web/pleroma_api/controllers/chat_controller_test.exs
@@ -332,5 +332,27 @@ test "it return a list of chats the current user is participating in, in descend
chat_1.id |> to_string()
]
end
+
+ test "it is not affected by :restrict_unauthenticated setting (issue #1973)", %{
+ conn: conn,
+ user: user
+ } do
+ clear_config([:restrict_unauthenticated, :profiles, :local], true)
+ clear_config([:restrict_unauthenticated, :profiles, :remote], true)
+
+ user2 = insert(:user)
+ user3 = insert(:user, local: false)
+
+ {:ok, _chat_12} = Chat.get_or_create(user.id, user2.ap_id)
+ {:ok, _chat_13} = Chat.get_or_create(user.id, user3.ap_id)
+
+ result =
+ conn
+ |> get("/api/v1/pleroma/chats")
+ |> json_response_and_validate_schema(200)
+
+ account_ids = Enum.map(result, &get_in(&1, ["account", "id"]))
+ assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id])
+ end
end
end
diff --git a/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs b/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs
index df58a5eb6..e113bb15f 100644
--- a/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs
+++ b/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs
@@ -14,6 +14,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
)
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
+ setup do: clear_config([:instance, :public], true)
+
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
@@ -27,6 +29,11 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
{:ok, %{admin_conn: admin_conn}}
end
+ test "GET /api/pleroma/emoji/packs when :public: false", %{conn: conn} do
+ Config.put([:instance, :public], false)
+ conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
+ end
+
test "GET /api/pleroma/emoji/packs", %{conn: conn} do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
diff --git a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
index e1bb5ebfe..3deab30d1 100644
--- a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
+++ b/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
@@ -106,6 +106,23 @@ test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
result
end
+ test "GET /api/v1/pleroma/statuses/:id/reactions with :show_reactions disabled", %{conn: conn} do
+ clear_config([:instance, :show_reactions], false)
+
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
+ {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
+
+ result =
+ conn
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
+ |> json_response_and_validate_schema(200)
+
+ assert result == []
+ end
+
test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
diff --git a/test/web/pleroma_api/views/chat/message_reference_view_test.exs b/test/web/pleroma_api/views/chat/message_reference_view_test.exs
index e5b165255..40dbae3cd 100644
--- a/test/web/pleroma_api/views/chat/message_reference_view_test.exs
+++ b/test/web/pleroma_api/views/chat/message_reference_view_test.exs
@@ -43,7 +43,17 @@ test "it displays a chat message" do
assert chat_message[:unread] == false
assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
- {:ok, activity} = CommonAPI.post_chat_message(recipient, user, "gkgkgk", media_id: upload.id)
+ clear_config([:rich_media, :enabled], true)
+
+ Tesla.Mock.mock(fn
+ %{url: "https://example.com/ogp"} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
+ end)
+
+ {:ok, activity} =
+ CommonAPI.post_chat_message(recipient, user, "gkgkgk https://example.com/ogp",
+ media_id: upload.id
+ )
object = Object.normalize(activity)
@@ -52,10 +62,11 @@ test "it displays a chat message" do
chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
assert chat_message_two[:id] == cm_ref.id
- assert chat_message_two[:content] == "gkgkgk"
+ assert chat_message_two[:content] == object.data["content"]
assert chat_message_two[:account_id] == recipient.id
assert chat_message_two[:chat_id] == chat_message[:chat_id]
assert chat_message_two[:attachment]
assert chat_message_two[:unread] == true
+ assert chat_message_two[:card]
end
end
diff --git a/test/web/pleroma_api/views/chat_view_test.exs b/test/web/pleroma_api/views/chat_view_test.exs
index 14eecb1bd..02484b705 100644
--- a/test/web/pleroma_api/views/chat_view_test.exs
+++ b/test/web/pleroma_api/views/chat_view_test.exs
@@ -26,7 +26,8 @@ test "it represents a chat" do
assert represented_chat == %{
id: "#{chat.id}",
- account: AccountView.render("show.json", user: recipient),
+ account:
+ AccountView.render("show.json", user: recipient, skip_visibility_check: true),
unread: 0,
last_message: nil,
updated_at: Utils.to_masto_date(chat.updated_at)
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index 368533292..20a45cb6f 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -4,11 +4,11 @@
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
+ import Pleroma.Factory
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.UserInviteToken
- alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.TwitterAPI.TwitterAPI
setup_all do
@@ -27,13 +27,10 @@ test "it registers a new user and returns the user." do
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("lain")
-
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
+ assert user == User.get_cached_by_nickname("lain")
end
- test "it registers a new user with empty string in bio and returns the user." do
+ test "it registers a new user with empty string in bio and returns the user" do
data = %{
:username => "lain",
:email => "lain@wired.jp",
@@ -45,10 +42,7 @@ test "it registers a new user with empty string in bio and returns the user." do
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("lain")
-
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
+ assert user == User.get_cached_by_nickname("lain")
end
test "it sends confirmation email if :account_activation_required is specified in instance config" do
@@ -85,6 +79,42 @@ test "it sends confirmation email if :account_activation_required is specified i
)
end
+ test "it sends an admin email if :account_approval_required is specified in instance config" do
+ admin = insert(:user, is_admin: true)
+ setting = Pleroma.Config.get([:instance, :account_approval_required])
+
+ unless setting do
+ Pleroma.Config.put([:instance, :account_approval_required], true)
+ on_exit(fn -> Pleroma.Config.put([:instance, :account_approval_required], setting) end)
+ end
+
+ data = %{
+ :username => "lain",
+ :email => "lain@wired.jp",
+ :fullname => "lain iwakura",
+ :bio => "",
+ :password => "bear",
+ :confirm => "bear",
+ :reason => "I love anime"
+ }
+
+ {:ok, user} = TwitterAPI.register_user(data)
+ ObanHelpers.perform_all()
+
+ assert user.approval_pending
+
+ email = Pleroma.Emails.AdminEmail.new_unapproved_registration(admin, user)
+
+ notify_email = Pleroma.Config.get([:instance, :notify_email])
+ instance_name = Pleroma.Config.get([:instance, :name])
+
+ Swoosh.TestAssertions.assert_email_sent(
+ from: {instance_name, notify_email},
+ to: {admin.name, admin.email},
+ html_body: email.html_body
+ )
+ end
+
test "it registers a new user and parses mentions in the bio" do
data1 = %{
:username => "john",
@@ -134,13 +164,10 @@ test "returns user on success" do
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("vinny")
+ assert user == User.get_cached_by_nickname("vinny")
+
invite = Repo.get_by(UserInviteToken, token: invite.token)
-
assert invite.used == true
-
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
end
test "returns error on invalid token" do
@@ -197,10 +224,8 @@ test "returns error on expired token" do
check_fn = fn invite ->
data = Map.put(data, :token, invite.token)
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("vinny")
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
+ assert user == User.get_cached_by_nickname("vinny")
end
{:ok, data: data, check_fn: check_fn}
@@ -260,14 +285,11 @@ test "returns user on success, after him registration fails" do
}
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("vinny")
+ assert user == User.get_cached_by_nickname("vinny")
+
invite = Repo.get_by(UserInviteToken, token: invite.token)
-
assert invite.used == true
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
-
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
@@ -302,13 +324,10 @@ test "returns user on success" do
}
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("vinny")
+ assert user == User.get_cached_by_nickname("vinny")
+
invite = Repo.get_by(UserInviteToken, token: invite.token)
-
refute invite.used
-
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
end
test "error after max uses" do
@@ -327,13 +346,11 @@ test "error after max uses" do
}
{:ok, user} = TwitterAPI.register_user(data)
- fetched_user = User.get_cached_by_nickname("vinny")
+ assert user == User.get_cached_by_nickname("vinny")
+
invite = Repo.get_by(UserInviteToken, token: invite.token)
assert invite.used == true
- assert AccountView.render("show.json", %{user: user}) ==
- AccountView.render("show.json", %{user: fetched_user})
-
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",