summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--benchmarks/load_testing/fetcher.ex21
-rw-r--r--config/config.exs2
-rw-r--r--config/description.exs198
-rw-r--r--docs/configuration/cheatsheet.md15
-rwxr-xr-xinstallation/init.d/pleroma48
-rw-r--r--lib/mix/tasks/pleroma/benchmark.ex3
-rw-r--r--lib/mix/tasks/pleroma/digest.ex7
-rw-r--r--lib/pleroma/bbs/authenticator.ex3
-rw-r--r--lib/pleroma/config/config_db.ex11
-rw-r--r--lib/pleroma/constants.ex3
-rw-r--r--lib/pleroma/docs/json.ex1
-rw-r--r--lib/pleroma/plugs/authentication_plug.ex7
-rw-r--r--lib/pleroma/upload.ex2
-rw-r--r--lib/pleroma/user_relationship.ex43
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex53
-rw-r--r--lib/pleroma/web/admin_api/views/account_view.ex9
-rw-r--r--lib/pleroma/web/admin_api/views/report_view.ex13
-rw-r--r--lib/pleroma/web/admin_api/views/status_view.ex17
-rw-r--r--lib/pleroma/web/api_spec/helpers.ex14
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex66
-rw-r--r--lib/pleroma/web/api_spec/operations/app_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/filter_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/marker_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/media_operation.ex132
-rw-r--r--lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex187
-rw-r--r--lib/pleroma/web/api_spec/operations/report_operation.ex3
-rw-r--r--lib/pleroma/web/api_spec/operations/search_operation.ex9
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex34
-rw-r--r--lib/pleroma/web/api_spec/operations/subscription_operation.ex54
-rw-r--r--lib/pleroma/web/api_spec/operations/timeline_operation.ex16
-rw-r--r--lib/pleroma/web/api_spec/schemas/attachment.ex2
-rw-r--r--lib/pleroma/web/auth/totp_authenticator.ex3
-rw-r--r--lib/pleroma/web/chat_channel.ex1
-rw-r--r--lib/pleroma/web/common_api/common_api.ex13
-rw-r--r--lib/pleroma/web/controller_helper.ex21
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex23
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/media_controller.ex43
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/notification_controller.ex5
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/search_controller.ex16
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex13
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex17
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex9
-rw-r--r--lib/pleroma/web/mastodon_api/views/notification_view.ex23
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex12
-rw-r--r--lib/pleroma/web/mongooseim/mongoose_im_controller.ex3
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/account_controller.ex31
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex17
-rw-r--r--lib/pleroma/web/router.ex3
-rw-r--r--mix.exs1
-rw-r--r--mix.lock2
-rw-r--r--priv/gettext/fr/LC_MESSAGES/errors.po164
-rw-r--r--priv/gettext/pl/LC_MESSAGES/errors.po587
-rw-r--r--priv/static/static/config.json31
-rw-r--r--test/config/config_db_test.exs8
-rw-r--r--test/plugs/authentication_plug_test.exs7
-rw-r--r--test/web/activity_pub/activity_pub_test.exs2
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs85
-rw-r--r--test/web/common_api/common_api_test.exs12
-rw-r--r--test/web/mastodon_api/controllers/media_controller_test.exs66
-rw-r--r--test/web/mastodon_api/controllers/notification_controller_test.exs4
-rw-r--r--test/web/mastodon_api/controllers/status_controller_test.exs2
-rw-r--r--test/web/mastodon_api/controllers/timeline_controller_test.exs70
-rw-r--r--test/web/mastodon_api/views/account_view_test.exs76
-rw-r--r--test/web/mastodon_api/views/notification_view_test.exs6
-rw-r--r--test/web/mastodon_api/views/status_view_test.exs16
-rw-r--r--test/web/pleroma_api/controllers/account_controller_test.exs107
67 files changed, 1879 insertions, 612 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b7fb603d..feda41320 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
- NodeInfo: `pleroma_emoji_reactions` to the `features` list.
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
+- Configuration: Add `:database_config_whitelist` setting to whitelist settings which can be configured from AdminFE.
- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma won’t start. For hackney OTP update is not required.
- Mix task to create trusted OAuth App.
- Notifications: Added `follow_request` notification type.
diff --git a/benchmarks/load_testing/fetcher.ex b/benchmarks/load_testing/fetcher.ex
index 12c30f6f5..0de4924bc 100644
--- a/benchmarks/load_testing/fetcher.ex
+++ b/benchmarks/load_testing/fetcher.ex
@@ -387,56 +387,47 @@ defmodule Pleroma.LoadTesting.Fetcher do
favourites = ActivityPub.fetch_favourites(user)
- output_relationships =
- !!Pleroma.Config.get([:extensions, :output_relationships_in_statuses_by_default])
-
Benchee.run(
%{
"Rendering home timeline" => fn ->
StatusView.render("index.json", %{
activities: home_activities,
for: user,
- as: :activity,
- skip_relationships: !output_relationships
+ as: :activity
})
end,
"Rendering direct timeline" => fn ->
StatusView.render("index.json", %{
activities: direct_activities,
for: user,
- as: :activity,
- skip_relationships: !output_relationships
+ as: :activity
})
end,
"Rendering public timeline" => fn ->
StatusView.render("index.json", %{
activities: public_activities,
for: user,
- as: :activity,
- skip_relationships: !output_relationships
+ as: :activity
})
end,
"Rendering tag timeline" => fn ->
StatusView.render("index.json", %{
activities: tag_activities,
for: user,
- as: :activity,
- skip_relationships: !output_relationships
+ as: :activity
})
end,
"Rendering notifications" => fn ->
Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{
notifications: notifications,
- for: user,
- skip_relationships: !output_relationships
+ for: user
})
end,
"Rendering favourites timeline" => fn ->
StatusView.render("index.json", %{
activities: favourites,
for: user,
- as: :activity,
- skip_relationships: !output_relationships
+ as: :activity
})
end
},
diff --git a/config/config.exs b/config/config.exs
index e703c1632..c51884f3a 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -251,8 +251,6 @@ config :pleroma, :instance,
]
]
-config :pleroma, :extensions, output_relationships_in_statuses_by_default: true
-
config :pleroma, :feed,
post_title: %{
max_length: 100,
diff --git a/config/description.exs b/config/description.exs
index 36ec3d40a..a800d7823 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -1105,38 +1105,40 @@ config :pleroma, :config_description, [
description: "Settings for Pleroma FE",
suggestions: [
%{
- theme: "pleroma-dark",
- logo: "/static/logo.png",
- background: "/images/city.jpg",
- redirectRootNoLogin: "/main/all",
- redirectRootLogin: "/main/friends",
- showInstanceSpecificPanel: true,
- scopeOptionsEnabled: false,
- formattingOptionsEnabled: false,
+ alwaysShowSubjectInput: true,
+ background: "/static/aurora_borealis.jpg",
collapseMessageWithSubject: false,
+ disableChat: false,
+ greentext: false,
+ hideFilteredStatuses: false,
+ hideMutedPosts: false,
hidePostStats: false,
+ hideSitename: false,
hideUserStats: false,
+ loginMethod: "password",
+ logo: "/static/logo.png",
+ logoMargin: ".1em",
+ logoMask: true,
+ minimalScopesMode: false,
+ noAttachmentLinks: false,
+ nsfwCensorImage: "",
+ postContentType: "text/plain",
+ redirectRootLogin: "/main/friends",
+ redirectRootNoLogin: "/main/all",
scopeCopy: true,
+ showFeaturesPanel: true,
+ showInstanceSpecificPanel: false,
subjectLineBehavior: "email",
- alwaysShowSubjectInput: true,
- logoMask: false,
- logoMargin: ".1em",
- stickers: false,
- enableEmojiPicker: false
+ theme: "pleroma-dark",
+ webPushNotifications: false
}
],
children: [
%{
- key: :theme,
- type: :string,
- description: "Which theme to use, they are defined in styles.json",
- suggestions: ["pleroma-dark"]
- },
- %{
- key: :logo,
- type: :string,
- description: "URL of the logo, defaults to Pleroma's logo",
- suggestions: ["/static/logo.png"]
+ key: :alwaysShowSubjectInput,
+ label: "Always show subject input",
+ type: :boolean,
+ description: "When disabled, auto-hide the subject field if it's empty"
},
%{
key: :background,
@@ -1146,46 +1148,35 @@ config :pleroma, :config_description, [
suggestions: ["/images/city.jpg"]
},
%{
- key: :redirectRootNoLogin,
- label: "Redirect root no login",
- type: :string,
- description:
- "Relative URL which indicates where to redirect when a user isn't logged in",
- suggestions: ["/main/all"]
- },
- %{
- key: :redirectRootLogin,
- label: "Redirect root login",
- type: :string,
+ key: :collapseMessageWithSubject,
+ label: "Collapse message with subject",
+ type: :boolean,
description:
- "Relative URL which indicates where to redirect when a user is logged in",
- suggestions: ["/main/friends"]
+ "When a message has a subject (aka Content Warning), collapse it by default"
},
%{
- key: :showInstanceSpecificPanel,
- label: "Show instance specific panel",
+ key: :disableChat,
+ label: "PleromaFE Chat",
type: :boolean,
- description: "Whenether to show the instance's specific panel"
+ description: "Disables PleromaFE Chat component"
},
%{
- key: :scopeOptionsEnabled,
- label: "Scope options enabled",
+ key: :greentext,
+ label: "Greentext",
type: :boolean,
- description: "Enable setting a notice visibility and subject/CW when posting"
+ description: "Enables green text on lines prefixed with the > character."
},
%{
- key: :formattingOptionsEnabled,
- label: "Formatting options enabled",
+ key: :hideFilteredStatuses,
+ label: "Hide Filtered Statuses",
type: :boolean,
- description:
- "Enable setting a formatting different than plain-text (ie. HTML, Markdown) when posting, relates to `:instance`, `allowed_post_formats`"
+ description: "Hides filtered statuses from timelines."
},
%{
- key: :collapseMessageWithSubject,
- label: "Collapse message with subject",
+ key: :hideMutedPosts,
+ label: "Hide Muted Posts",
type: :boolean,
- description:
- "When a message has a subject (aka Content Warning), collapse it by default"
+ description: "Hides muted statuses from timelines."
},
%{
key: :hidePostStats,
@@ -1194,6 +1185,12 @@ config :pleroma, :config_description, [
description: "Hide notices statistics (repeats, favorites, ...)"
},
%{
+ key: :hideSitename,
+ label: "Hide Sitename",
+ type: :boolean,
+ description: "Hides instance name from PleromaFE banner."
+ },
+ %{
key: :hideUserStats,
label: "Hide user stats",
type: :boolean,
@@ -1201,26 +1198,19 @@ config :pleroma, :config_description, [
"Hide profile statistics (posts, posts per day, followers, followings, ...)"
},
%{
- key: :scopeCopy,
- label: "Scope copy",
- type: :boolean,
- description: "Copy the scope (private/unlisted/public) in replies to posts by default"
- },
- %{
- key: :subjectLineBehavior,
- label: "Subject line behavior",
+ key: :logo,
type: :string,
- description: "Allows changing the default behaviour of subject lines in replies.
- `email`: copy and preprend re:, as in email,
- `masto`: copy verbatim, as in Mastodon,
- `noop`: don't copy the subject.",
- suggestions: ["email", "masto", "noop"]
+ description: "URL of the logo, defaults to Pleroma's logo",
+ suggestions: ["/static/logo.png"]
},
%{
- key: :alwaysShowSubjectInput,
- label: "Always show subject input",
- type: :boolean,
- description: "When disabled, auto-hide the subject field if it's empty"
+ key: :logoMargin,
+ label: "Logo margin",
+ type: :string,
+ description:
+ "Allows you to adjust vertical margins between logo boundary and navbar borders. " <>
+ "The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout.",
+ suggestions: [".1em"]
},
%{
key: :logoMask,
@@ -1231,24 +1221,78 @@ config :pleroma, :config_description, [
"If you want a colorful logo you must disable logoMask."
},
%{
- key: :logoMargin,
- label: "Logo margin",
+ key: :minimalScopesMode,
+ label: "Minimal scopes mode",
+ type: :boolean,
+ description:
+ "Limit scope selection to Direct, User default, and Scope of post replying to. " <>
+ "Also prevents replying to a DM with a public post from PleromaFE."
+ },
+ %{
+ key: :nsfwCensorImage,
+ label: "NSFW Censor Image",
type: :string,
description:
- "Allows you to adjust vertical margins between logo boundary and navbar borders. " <>
- "The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout.",
- suggestions: [".1em"]
+ "URL of the image to use for hiding NSFW media attachments in the timeline.",
+ suggestions: ["/static/img/nsfw.png"]
+ },
+ %{
+ key: :postContentType,
+ label: "Post Content Type",
+ type: {:dropdown, :atom},
+ description: "Default post formatting option.",
+ suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode"]
+ },
+ %{
+ key: :redirectRootNoLogin,
+ label: "Redirect root no login",
+ type: :string,
+ description:
+ "Relative URL which indicates where to redirect when a user isn't logged in",
+ suggestions: ["/main/all"]
},
%{
- key: :stickers,
+ key: :redirectRootLogin,
+ label: "Redirect root login",
+ type: :string,
+ description:
+ "Relative URL which indicates where to redirect when a user is logged in",
+ suggestions: ["/main/friends"]
+ },
+ %{
+ key: :scopeCopy,
+ label: "Scope copy",
+ type: :boolean,
+ description: "Copy the scope (private/unlisted/public) in replies to posts by default"
+ },
+ %{
+ key: :showFeaturesPanel,
+ label: "Show instance features panel",
type: :boolean,
- description: "Enables stickers."
+ description:
+ "Enables panel displaying functionality of the instance on the About page."
},
%{
- key: :enableEmojiPicker,
- label: "Emoji picker",
+ key: :showInstanceSpecificPanel,
+ label: "Show instance specific panel",
type: :boolean,
- description: "Enables emoji picker."
+ description: "Whether to show the instance's custom panel"
+ },
+ %{
+ key: :subjectLineBehavior,
+ label: "Subject line behavior",
+ type: :string,
+ description: "Allows changing the default behaviour of subject lines in replies.
+ `email`: copy and preprend re:, as in email,
+ `masto`: copy verbatim, as in Mastodon,
+ `noop`: don't copy the subject.",
+ suggestions: ["email", "masto", "noop"]
+ },
+ %{
+ key: :theme,
+ type: :string,
+ description: "Which theme to use. Available themes are defined in styles.json",
+ suggestions: ["pleroma-dark"]
}
]
},
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 707d7fdbd..1078c4e87 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -911,6 +911,21 @@ config :auto_linker,
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
+## :database_config_whitelist
+
+List of valid configuration sections which are allowed to be configured from the
+database. Settings stored in the database before the whitelist is configured are
+still applied, so it is suggested to only use the whitelist on instances that
+have not migrated the config to the database.
+
+Example:
+```elixir
+config :pleroma, :database_config_whitelist, [
+ {:pleroma, :instance},
+ {:pleroma, Pleroma.Web.Metadata},
+ {:auto_linker}
+]
+```
### Multi-factor authentication - :two_factor_authentication
* `totp` - a list containing TOTP configuration
diff --git a/installation/init.d/pleroma b/installation/init.d/pleroma
index ed50bb551..384536f7e 100755
--- a/installation/init.d/pleroma
+++ b/installation/init.d/pleroma
@@ -1,21 +1,45 @@
#!/sbin/openrc-run
-
-# Requires OpenRC >= 0.35
-directory=/opt/pleroma
-
-command=/usr/bin/mix
-command_args="phx.server"
+supervisor=supervise-daemon
command_user=pleroma:pleroma
command_background=1
-
-export PORT=4000
-export MIX_ENV=prod
-
# Ask process to terminate within 30 seconds, otherwise kill it
retry="SIGTERM/30/SIGKILL/5"
-
pidfile="/var/run/pleroma.pid"
+directory=/opt/pleroma
+healthcheck_delay=60
+healthcheck_timer=30
+
+: ${pleroma_port:-4000}
+
+# Needs OpenRC >= 0.42
+#respawn_max=0
+#respawn_delay=5
+
+# put pleroma_console=YES in /etc/conf.d/pleroma if you want to be able to
+# connect to pleroma via an elixir console
+if yesno "${pleroma_console}"; then
+ command=elixir
+ command_args="--name pleroma@127.0.0.1 --erl '-kernel inet_dist_listen_min 9001 inet_dist_listen_max 9001 inet_dist_use_interface {127,0,0,1}' -S mix phx.server"
+
+ start_post() {
+ einfo "You can get a console by using this command as pleroma's user:"
+ einfo "iex --name console@127.0.0.1 --remsh pleroma@127.0.0.1"
+ }
+else
+ command=/usr/bin/mix
+ command_args="phx.server"
+fi
+
+export MIX_ENV=prod
depend() {
- need nginx postgresql
+ need nginx postgresql
+}
+
+healthcheck() {
+ # put pleroma_health=YES in /etc/conf.d/pleroma if you want healthchecking
+ # and make sure you have curl installed
+ yesno "$pleroma_health" || return 0
+
+ curl -q "localhost:${pleroma_port}/api/pleroma/healthcheck"
}
diff --git a/lib/mix/tasks/pleroma/benchmark.ex b/lib/mix/tasks/pleroma/benchmark.ex
index 6ab7fe8ef..dd2b9c8f2 100644
--- a/lib/mix/tasks/pleroma/benchmark.ex
+++ b/lib/mix/tasks/pleroma/benchmark.ex
@@ -67,8 +67,7 @@ defmodule Mix.Tasks.Pleroma.Benchmark do
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
activities: activities,
for: user,
- as: :activity,
- skip_relationships: true
+ as: :activity
})
end
},
diff --git a/lib/mix/tasks/pleroma/digest.ex b/lib/mix/tasks/pleroma/digest.ex
index 7d09e70c5..3595f912d 100644
--- a/lib/mix/tasks/pleroma/digest.ex
+++ b/lib/mix/tasks/pleroma/digest.ex
@@ -1,5 +1,6 @@
defmodule Mix.Tasks.Pleroma.Digest do
use Mix.Task
+ import Mix.Pleroma
@shortdoc "Manages digest emails"
@moduledoc File.read!("docs/administration/CLI_tasks/digest.md")
@@ -22,12 +23,10 @@ defmodule Mix.Tasks.Pleroma.Digest do
with %Swoosh.Email{} = email <- Pleroma.Emails.UserEmail.digest_email(patched_user) do
{:ok, _} = Pleroma.Emails.Mailer.deliver(email)
- Mix.shell().info("Digest email have been sent to #{nickname} (#{user.email})")
+ shell_info("Digest email have been sent to #{nickname} (#{user.email})")
else
_ ->
- Mix.shell().info(
- "Cound't find any mentions for #{nickname} since #{last_digest_emailed_at}"
- )
+ shell_info("Cound't find any mentions for #{nickname} since #{last_digest_emailed_at}")
end
end
end
diff --git a/lib/pleroma/bbs/authenticator.ex b/lib/pleroma/bbs/authenticator.ex
index d4494b003..815de7002 100644
--- a/lib/pleroma/bbs/authenticator.ex
+++ b/lib/pleroma/bbs/authenticator.ex
@@ -4,6 +4,7 @@
defmodule Pleroma.BBS.Authenticator do
use Sshd.PasswordAuthenticator
+ alias Pleroma.Plugs.AuthenticationPlug
alias Pleroma.User
def authenticate(username, password) do
@@ -11,7 +12,7 @@ defmodule Pleroma.BBS.Authenticator do
password = to_string(password)
with %User{} = user <- User.get_by_nickname(username) do
- Pbkdf2.verify_pass(password, user.password_hash)
+ AuthenticationPlug.checkpw(password, user.password_hash)
else
_e -> false
end
diff --git a/lib/pleroma/config/config_db.ex b/lib/pleroma/config/config_db.ex
index 4097ee5b7..2b43d4c36 100644
--- a/lib/pleroma/config/config_db.ex
+++ b/lib/pleroma/config/config_db.ex
@@ -278,6 +278,8 @@ defmodule Pleroma.ConfigDB do
}
end
+ defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]}
+
defp do_convert(entity) when is_tuple(entity) do
value =
entity
@@ -321,6 +323,15 @@ defmodule Pleroma.ConfigDB do
{:proxy_url, {do_transform_string(type), parse_host(host), port}}
end
+ defp do_transform(%{"tuple" => [":partial_chain", entity]}) do
+ {partial_chain, []} =
+ entity
+ |> String.replace(~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "")
+ |> Code.eval_string()
+
+ {:partial_chain, partial_chain}
+ end
+
defp do_transform(%{"tuple" => entity}) do
Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end)
end
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index 3a9eec5ea..06174f624 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -17,7 +17,8 @@ defmodule Pleroma.Constants do
"announcement_count",
"emoji",
"context_id",
- "deleted_activity_id"
+ "deleted_activity_id",
+ "pleroma_internal"
]
)
diff --git a/lib/pleroma/docs/json.ex b/lib/pleroma/docs/json.ex
index 74f8b2615..d1cf1f487 100644
--- a/lib/pleroma/docs/json.ex
+++ b/lib/pleroma/docs/json.ex
@@ -18,7 +18,6 @@ defmodule Pleroma.Docs.JSON do
with config <- Pleroma.Config.Loader.read("config/description.exs") do
config[:pleroma][:config_description]
|> Pleroma.Docs.Generator.convert_to_strings()
- |> Jason.encode!()
end
end
end
diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex
index ae4a235bd..2cdf6c951 100644
--- a/lib/pleroma/plugs/authentication_plug.ex
+++ b/lib/pleroma/plugs/authentication_plug.ex
@@ -16,6 +16,11 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
:crypt.crypt(password, password_hash) == password_hash
end
+ def checkpw(password, "$2" <> _ = password_hash) do
+ # Handle bcrypt passwords for Mastodon migration
+ Bcrypt.verify_pass(password, password_hash)
+ end
+
def checkpw(password, "$pbkdf2" <> _ = password_hash) do
Pbkdf2.verify_pass(password, password_hash)
end
@@ -36,7 +41,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
} = conn,
_
) do
- if Pbkdf2.verify_pass(password, password_hash) do
+ if checkpw(password, password_hash) do
conn
|> assign(:user, auth_user)
|> OAuthScopesPlug.skip_plug()
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
index 762d813d9..1be1a3a5b 100644
--- a/lib/pleroma/upload.ex
+++ b/lib/pleroma/upload.ex
@@ -134,7 +134,7 @@ defmodule Pleroma.Upload do
end
end
- defp prepare_upload(%{"img" => "data:image/" <> image_data}, opts) do
+ defp prepare_upload(%{img: "data:image/" <> image_data}, opts) do
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
data = Base.decode64!(parsed["data"], ignore: :whitespace)
hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data)))
diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex
index 235ad427c..6dfdd2860 100644
--- a/lib/pleroma/user_relationship.ex
+++ b/lib/pleroma/user_relationship.ex
@@ -87,6 +87,22 @@ defmodule Pleroma.UserRelationship do
source_to_target_rel_types \\ nil,
target_to_source_rel_types \\ nil
)
+
+ def dictionary(
+ _source_users,
+ _target_users,
+ [] = _source_to_target_rel_types,
+ [] = _target_to_source_rel_types
+ ) do
+ []
+ end
+
+ def dictionary(
+ source_users,
+ target_users,
+ source_to_target_rel_types,
+ target_to_source_rel_types
+ )
when is_list(source_users) and is_list(target_users) do
source_user_ids = User.binary_id(source_users)
target_user_ids = User.binary_id(target_users)
@@ -138,11 +154,16 @@ defmodule Pleroma.UserRelationship do
def view_relationships_option(%User{} = reading_user, actors, opts) do
{source_to_target_rel_types, target_to_source_rel_types} =
- if opts[:source_mutes_only] do
- # This option is used for rendering statuses (FE needs `muted` flag for each one anyways)
- {[:mute], []}
- else
- {[:block, :mute, :notification_mute, :reblog_mute], [:block, :inverse_subscription]}
+ case opts[:subset] do
+ :source_mutes ->
+ # Used for statuses rendering (FE needs `muted` flag for each status when statuses load)
+ {[:mute], []}
+
+ nil ->
+ {[:block, :mute, :notification_mute, :reblog_mute], [:block, :inverse_subscription]}
+
+ unknown ->
+ raise "Unsupported :subset option value: #{inspect(unknown)}"
end
user_relationships =
@@ -153,7 +174,17 @@ defmodule Pleroma.UserRelationship do
target_to_source_rel_types
)
- following_relationships = FollowingRelationship.all_between_user_sets([reading_user], actors)
+ following_relationships =
+ case opts[:subset] do
+ :source_mutes ->
+ []
+
+ nil ->
+ FollowingRelationship.all_between_user_sets([reading_user], actors)
+
+ unknown ->
+ raise "Unsupported :subset option value: #{inspect(unknown)}"
+ end
%{user_relationships: user_relationships, following_relationships: following_relationships}
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 9821173d0..647ceb3ba 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.ActivityPub.Pipeline
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.AdminAPI.ConfigView
alias Pleroma.Web.AdminAPI.ModerationLogView
@@ -30,14 +31,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.AdminAPI.Search
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MastodonAPI.AppView
- alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.OAuth.App
alias Pleroma.Web.Router
require Logger
- @descriptions_json Pleroma.Docs.JSON.compile()
+ @descriptions Pleroma.Docs.JSON.compile()
@users_page_size 50
plug(
@@ -280,8 +281,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
})
conn
- |> put_view(Pleroma.Web.AdminAPI.StatusView)
- |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
+ |> put_view(AdminAPI.StatusView)
+ |> render("index.json", %{activities: activities, as: :activity})
end
def list_user_statuses(conn, %{"nickname" => nickname} = params) do
@@ -299,8 +300,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
})
conn
- |> put_view(StatusView)
- |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
+ |> put_view(MastodonAPI.StatusView)
+ |> render("index.json", %{activities: activities, as: :activity})
else
_ -> {:error, :not_found}
end
@@ -829,14 +830,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
})
conn
- |> put_view(Pleroma.Web.AdminAPI.StatusView)
- |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
+ |> put_view(AdminAPI.StatusView)
+ |> render("index.json", %{activities: activities, as: :activity})
end
def status_show(conn, %{"id" => id}) do
with %Activity{} = activity <- Activity.get_by_id(id) do
conn
- |> put_view(StatusView)
+ |> put_view(MastodonAPI.StatusView)
|> render("show.json", %{activity: activity})
else
_ -> errors(conn, {:error, :not_found})
@@ -861,7 +862,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
})
conn
- |> put_view(StatusView)
+ |> put_view(MastodonAPI.StatusView)
|> render("show.json", %{activity: activity})
end
end
@@ -897,9 +898,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
def config_descriptions(conn, _params) do
- conn
- |> Plug.Conn.put_resp_content_type("application/json")
- |> Plug.Conn.send_resp(200, @descriptions_json)
+ descriptions = Enum.filter(@descriptions, &whitelisted_config?/1)
+
+ json(conn, descriptions)
end
def config_show(conn, %{"only_db" => true}) do
@@ -954,7 +955,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
def config_update(conn, %{"configs" => configs}) do
with :ok <- configurable_from_database(conn) do
{_errors, results} =
- Enum.map(configs, fn
+ configs
+ |> Enum.filter(&whitelisted_config?/1)
+ |> Enum.map(fn
%{"group" => group, "key" => key, "delete" => true} = params ->
ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
@@ -1016,6 +1019,28 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end
+ defp whitelisted_config?(group, key) do
+ if whitelisted_configs = Config.get(:database_config_whitelist) do
+ Enum.any?(whitelisted_configs, fn
+ {whitelisted_group} ->
+ group == inspect(whitelisted_group)
+
+ {whitelisted_group, whitelisted_key} ->
+ group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
+ end)
+ else
+ true
+ end
+ end
+
+ defp whitelisted_config?(%{"group" => group, "key" => key}) do
+ whitelisted_config?(group, key)
+ end
+
+ defp whitelisted_config?(%{:group => group} = config) do
+ whitelisted_config?(group, config[:key])
+ end
+
def reload_emoji(conn, _params) do
Pleroma.Emoji.reload()
diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex
index a16a3ebf0..46dadb5ee 100644
--- a/lib/pleroma/web/admin_api/views/account_view.ex
+++ b/lib/pleroma/web/admin_api/views/account_view.ex
@@ -6,7 +6,9 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
use Pleroma.Web, :view
alias Pleroma.User
+ alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView
+ alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MediaProxy
def render("index.json", %{users: users, count: count, page_size: page_size}) do
@@ -119,6 +121,13 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
}
end
+ def merge_account_views(%User{} = user) do
+ MastodonAPI.AccountView.render("show.json", %{user: user})
+ |> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
+ end
+
+ def merge_account_views(_), do: %{}
+
defp parse_error([]), do: ""
defp parse_error(errors) do
diff --git a/lib/pleroma/web/admin_api/views/report_view.ex b/lib/pleroma/web/admin_api/views/report_view.ex
index d50969b2a..f432b8c2c 100644
--- a/lib/pleroma/web/admin_api/views/report_view.ex
+++ b/lib/pleroma/web/admin_api/views/report_view.ex
@@ -7,10 +7,13 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
alias Pleroma.HTML
alias Pleroma.User
+ alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.StatusView
+ defdelegate merge_account_views(user), to: AdminAPI.AccountView
+
def render("index.json", %{reports: reports}) do
%{
reports:
@@ -41,8 +44,7 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
statuses:
StatusView.render("index.json", %{
activities: statuses,
- as: :activity,
- skip_relationships: false
+ as: :activity
}),
state: report.data["state"],
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes})
@@ -70,11 +72,4 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
created_at: Utils.to_masto_date(inserted_at)
}
end
-
- defp merge_account_views(%User{} = user) do
- Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
- |> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
- end
-
- defp merge_account_views(_), do: %{}
end
diff --git a/lib/pleroma/web/admin_api/views/status_view.ex b/lib/pleroma/web/admin_api/views/status_view.ex
index 3637dee24..500800be2 100644
--- a/lib/pleroma/web/admin_api/views/status_view.ex
+++ b/lib/pleroma/web/admin_api/views/status_view.ex
@@ -7,24 +7,19 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
require Pleroma.Constants
- alias Pleroma.User
- alias Pleroma.Web.MastodonAPI.StatusView
+ alias Pleroma.Web.AdminAPI
+ alias Pleroma.Web.MastodonAPI
+
+ defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", opts) do
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
- user = StatusView.get_user(activity.data["actor"])
+ user = MastodonAPI.StatusView.get_user(activity.data["actor"])
- StatusView.render("show.json", opts)
+ MastodonAPI.StatusView.render("show.json", opts)
|> Map.merge(%{account: merge_account_views(user)})
end
-
- defp merge_account_views(%User{} = user) do
- Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
- |> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
- end
-
- defp merge_account_views(_), do: %{}
end
diff --git a/lib/pleroma/web/api_spec/helpers.ex b/lib/pleroma/web/api_spec/helpers.ex
index 183df43ee..a9cfe0fed 100644
--- a/lib/pleroma/web/api_spec/helpers.ex
+++ b/lib/pleroma/web/api_spec/helpers.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Web.ApiSpec.Helpers do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def request_body(description, schema_ref, opts \\ []) do
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]
@@ -47,6 +48,15 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
]
end
+ def with_relationships_param do
+ Operation.parameter(
+ :with_relationships,
+ :query,
+ BooleanLike,
+ "Embed relationships into accounts."
+ )
+ end
+
def empty_object_response do
Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}})
end
@@ -54,4 +64,8 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
def empty_array_response do
Operation.response("Empty array", "application/json", %Schema{type: :array, example: []})
end
+
+ def no_content_response do
+ Operation.response("No Content", "application/json", %Schema{type: :string, example: ""})
+ end
end
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index 70069d6f9..934f6038e 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -155,8 +155,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
security: [%{"oAuth" => ["read:accounts"]}],
description:
"Accounts which follow the given account, if network is not hidden by the account owner.",
- parameters:
- [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
+ parameters: [
+ %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
+ with_relationships_param() | pagination_params()
+ ],
responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts())
}
@@ -171,8 +173,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
security: [%{"oAuth" => ["read:accounts"]}],
description:
"Accounts which the given account is following, if network is not hidden by the account owner.",
- parameters:
- [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
+ parameters: [
+ %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
+ with_relationships_param() | pagination_params()
+ ],
responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())}
}
end
@@ -367,15 +371,18 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
title: "AccountCreateRequest",
description: "POST body for creating an account",
type: :object,
+ required: [:username, :password, :agreement],
properties: %{
reason: %Schema{
type: :string,
+ nullable: true,
description:
"Text that will be reviewed by moderators if registrations require manual approval"
},
username: %Schema{type: :string, description: "The desired username for the account"},
email: %Schema{
type: :string,
+ nullable: true,
description:
"The email address to be used for login. Required when `account_activation_required` is enabled.",
format: :email
@@ -392,23 +399,33 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
},
locale: %Schema{
type: :string,
+ nullable: true,
description: "The language of the confirmation email that will be sent"
},
# Pleroma-specific properties:
- fullname: %Schema{type: :string, description: "Full name"},
- bio: %Schema{type: :string, description: "Bio", default: ""},
+ fullname: %Schema{type: :string, nullable: true, description: "Full name"},
+ bio: %Schema{type: :string, description: "Bio", nullable: true, default: ""},
captcha_solution: %Schema{
type: :string,
+ nullable: true,
description: "Provider-specific captcha solution"
},
- captcha_token: %Schema{type: :string, description: "Provider-specific captcha token"},
- captcha_answer_data: %Schema{type: :string, description: "Provider-specific captcha data"},
+ captcha_token: %Schema{
+ type: :string,
+ nullable: true,
+ description: "Provider-specific captcha token"
+ },
+ captcha_answer_data: %Schema{
+ type: :string,
+ nullable: true,
+ description: "Provider-specific captcha data"
+ },
token: %Schema{
type: :string,
+ nullable: true,
description: "Invite token required when the registrations aren't public"
}
},
- required: [:username, :password, :agreement],
example: %{
"username" => "cofe",
"email" => "cofe@example.com",
@@ -447,28 +464,34 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
properties: %{
bot: %Schema{
type: :boolean,
+ nullable: true,
description: "Whether the account has a bot flag."
},
display_name: %Schema{
type: :string,
+ nullable: true,
description: "The display name to use for the profile."
},
note: %Schema{type: :string, description: "The account bio."},
avatar: %Schema{
type: :string,
+ nullable: true,
description: "Avatar image encoded using multipart/form-data",
format: :binary
},
header: %Schema{
type: :string,
+ nullable: true,
description: "Header image encoded using multipart/form-data",
format: :binary
},
locked: %Schema{
type: :boolean,
+ nullable: true,
description: "Whether manual approval of follow requests is required."
},
fields_attributes: %Schema{
+ nullable: true,
oneOf: [
%Schema{type: :array, items: attribute_field()},
%Schema{type: :object, additionalProperties: %Schema{type: attribute_field()}}
@@ -488,47 +511,65 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
# Pleroma-specific fields
no_rich_text: %Schema{
type: :boolean,
+ nullable: true,
description: "html tags are stripped from all statuses requested from the API"
},
- hide_followers: %Schema{type: :boolean, description: "user's followers will be hidden"},
- hide_follows: %Schema{type: :boolean, description: "user's follows will be hidden"},
+ hide_followers: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "user's followers will be hidden"
+ },
+ hide_follows: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "user's follows will be hidden"
+ },
hide_followers_count: %Schema{
type: :boolean,
+ nullable: true,
description: "user's follower count will be hidden"
},
hide_follows_count: %Schema{
type: :boolean,
+ nullable: true,
description: "user's follow count will be hidden"
},
hide_favorites: %Schema{
type: :boolean,
+ nullable: true,
description: "user's favorites timeline will be hidden"
},
show_role: %Schema{
type: :boolean,
+ nullable: true,
description: "user's role (e.g admin, moderator) will be exposed to anyone in the
API"
},
default_scope: VisibilityScope,
pleroma_settings_store: %Schema{
type: :object,
+ nullable: true,
description: "Opaque user settings to be saved on the backend."
},
skip_thread_containment: %Schema{
type: :boolean,
+ nullable: true,
description: "Skip filtering out broken threads"
},
allow_following_move: %Schema{
type: :boolean,
+ nullable: true,
description: "Allows automatically follow moved following accounts"
},
pleroma_background_image: %Schema{
type: :string,
+ nullable: true,
description: "Sets the background image of the user.",
format: :binary
},
discoverable: %Schema{
type: :boolean,
+ nullable: true,
description:
"Discovery of this account in search results and other services is allowed."
},
@@ -624,7 +665,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
description: "POST body for muting an account",
type: :object,
properties: %{
- uri: %Schema{type: :string, format: :uri}
+ uri: %Schema{type: :string, nullable: true, format: :uri}
},
required: [:uri]
}
@@ -638,6 +679,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
properties: %{
notifications: %Schema{
type: :boolean,
+ nullable: true,
description: "Mute notifications in addition to statuses? Defaults to true.",
default: true
}
diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex
index f6ccd073f..ae01cbbec 100644
--- a/lib/pleroma/web/api_spec/operations/app_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/app_operation.ex
@@ -105,7 +105,11 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
description: "Space separated list of scopes",
default: "read"
},
- website: %Schema{type: :string, description: "A URL to the homepage of your app"}
+ website: %Schema{
+ type: :string,
+ nullable: true,
+ description: "A URL to the homepage of your app"
+ }
},
required: [:client_name, :redirect_uris],
example: %{
diff --git a/lib/pleroma/web/api_spec/operations/filter_operation.ex b/lib/pleroma/web/api_spec/operations/filter_operation.ex
index 53e57b46b..7310c1c4d 100644
--- a/lib/pleroma/web/api_spec/operations/filter_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/filter_operation.ex
@@ -199,12 +199,14 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
"Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified."
},
irreversible: %Schema{
- type: :bolean,
+ type: :boolean,
+ nullable: true,
description:
"Should the server irreversibly drop matching entities from home and notifications?"
},
whole_word: %Schema{
- type: :bolean,
+ type: :boolean,
+ nullable: true,
description: "Consider word boundaries?",
default: true
}
diff --git a/lib/pleroma/web/api_spec/operations/marker_operation.ex b/lib/pleroma/web/api_spec/operations/marker_operation.ex
index 06620492a..714ef1f99 100644
--- a/lib/pleroma/web/api_spec/operations/marker_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/marker_operation.ex
@@ -110,14 +110,16 @@ defmodule Pleroma.Web.ApiSpec.MarkerOperation do
properties: %{
notifications: %Schema{
type: :object,
+ nullable: true,
properties: %{
- last_read_id: %Schema{type: :string}
+ last_read_id: %Schema{nullable: true, type: :string}
}
},
home: %Schema{
type: :object,
+ nullable: true,
properties: %{
- last_read_id: %Schema{type: :string}
+ last_read_id: %Schema{nullable: true, type: :string}
}
}
},
diff --git a/lib/pleroma/web/api_spec/operations/media_operation.ex b/lib/pleroma/web/api_spec/operations/media_operation.ex
new file mode 100644
index 000000000..d9c3c42db
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/media_operation.ex
@@ -0,0 +1,132 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.MediaOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Helpers
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+ alias Pleroma.Web.ApiSpec.Schemas.Attachment
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def create_operation do
+ %Operation{
+ tags: ["media"],
+ summary: "Upload media as attachment",
+ description: "Creates an attachment to be used with a new status.",
+ operationId: "MediaController.create",
+ security: [%{"oAuth" => ["write:media"]}],
+ requestBody: Helpers.request_body("Parameters", create_request()),
+ responses: %{
+ 200 => Operation.response("Media", "application/json", Attachment),
+ 401 => Operation.response("Media", "application/json", ApiError),
+ 422 => Operation.response("Media", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp create_request do
+ %Schema{
+ title: "MediaCreateRequest",
+ description: "POST body for creating an attachment",
+ type: :object,
+ required: [:file],
+ properties: %{
+ file: %Schema{
+ type: :string,
+ format: :binary,
+ description: "The file to be attached, using multipart form data."
+ },
+ description: %Schema{
+ type: :string,
+ description: "A plain-text description of the media, for accessibility purposes."
+ },
+ focus: %Schema{
+ type: :string,
+ description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."
+ }
+ }
+ }
+ end
+
+ def update_operation do
+ %Operation{
+ tags: ["media"],
+ summary: "Upload media as attachment",
+ description: "Creates an attachment to be used with a new status.",
+ operationId: "MediaController.update",
+ security: [%{"oAuth" => ["write:media"]}],
+ parameters: [id_param()],
+ requestBody: Helpers.request_body("Parameters", update_request()),
+ responses: %{
+ 200 => Operation.response("Media", "application/json", Attachment),
+ 400 => Operation.response("Media", "application/json", ApiError),
+ 401 => Operation.response("Media", "application/json", ApiError),
+ 422 => Operation.response("Media", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp update_request do
+ %Schema{
+ title: "MediaUpdateRequest",
+ description: "POST body for updating an attachment",
+ type: :object,
+ properties: %{
+ file: %Schema{
+ type: :string,
+ format: :binary,
+ description: "The file to be attached, using multipart form data."
+ },
+ description: %Schema{
+ type: :string,
+ description: "A plain-text description of the media, for accessibility purposes."
+ },
+ focus: %Schema{
+ type: :string,
+ description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."
+ }
+ }
+ }
+ end
+
+ def show_operation do
+ %Operation{
+ tags: ["media"],
+ summary: "Show Uploaded media attachment",
+ operationId: "MediaController.show",
+ parameters: [id_param()],
+ security: [%{"oAuth" => ["read:media"]}],
+ responses: %{
+ 200 => Operation.response("Media", "application/json", Attachment),
+ 401 => Operation.response("Media", "application/json", ApiError),
+ 422 => Operation.response("Media", "application/json", ApiError)
+ }
+ }
+ end
+
+ def create2_operation do
+ %Operation{
+ tags: ["media"],
+ summary: "Upload media as attachment",
+ description: "Creates an attachment to be used with a new status.",
+ operationId: "MediaController.create2",
+ security: [%{"oAuth" => ["write:media"]}],
+ requestBody: Helpers.request_body("Parameters", create_request()),
+ responses: %{
+ 202 => Operation.response("Media", "application/json", Attachment),
+ 422 => Operation.response("Media", "application/json", ApiError),
+ 500 => Operation.response("Media", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp id_param do
+ Operation.parameter(:id, :path, :string, "The ID of the Attachment entity")
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex
new file mode 100644
index 000000000..90922c064
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex
@@ -0,0 +1,187 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+ alias Pleroma.Web.ApiSpec.Schemas.FlakeID
+ alias Pleroma.Web.ApiSpec.StatusOperation
+
+ import Pleroma.Web.ApiSpec.Helpers
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def confirmation_resend_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Resend confirmation email. Expects `email` or `nickname`",
+ operationId: "PleromaAPI.AccountController.confirmation_resend",
+ parameters: [
+ Operation.parameter(:email, :query, :string, "Email of that needs to be verified",
+ example: "cofe@cofe.io"
+ ),
+ Operation.parameter(
+ :nickname,
+ :query,
+ :string,
+ "Nickname of user that needs to be verified",
+ example: "cofefe"
+ )
+ ],
+ responses: %{
+ 204 => no_content_response()
+ }
+ }
+ end
+
+ def update_avatar_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Set/clear user avatar image",
+ operationId: "PleromaAPI.AccountController.update_avatar",
+ requestBody:
+ request_body("Parameters", update_avatar_or_background_request(), required: true),
+ security: [%{"oAuth" => ["write:accounts"]}],
+ responses: %{
+ 200 => update_response(),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def update_banner_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Set/clear user banner image",
+ operationId: "PleromaAPI.AccountController.update_banner",
+ requestBody: request_body("Parameters", update_banner_request(), required: true),
+ security: [%{"oAuth" => ["write:accounts"]}],
+ responses: %{
+ 200 => update_response()
+ }
+ }
+ end
+
+ def update_background_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Set/clear user background image",
+ operationId: "PleromaAPI.AccountController.update_background",
+ security: [%{"oAuth" => ["write:accounts"]}],
+ requestBody:
+ request_body("Parameters", update_avatar_or_background_request(), required: true),
+ responses: %{
+ 200 => update_response()
+ }
+ }
+ end
+
+ def favourites_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Returns favorites timeline of any user",
+ operationId: "PleromaAPI.AccountController.favourites",
+ parameters: [id_param() | pagination_params()],
+ security: [%{"oAuth" => ["read:favourites"]}],
+ responses: %{
+ 200 =>
+ Operation.response(
+ "Array of Statuses",
+ "application/json",
+ StatusOperation.array_of_statuses()
+ ),
+ 403 => Operation.response("Forbidden", "application/json", ApiError),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ def subscribe_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Subscribe to receive notifications for all statuses posted by a user",
+ operationId: "PleromaAPI.AccountController.subscribe",
+ parameters: [id_param()],
+ security: [%{"oAuth" => ["follow", "write:follows"]}],
+ responses: %{
+ 200 => Operation.response("Relationship", "application/json", AccountRelationship),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ def unsubscribe_operation do
+ %Operation{
+ tags: ["Accounts"],
+ summary: "Unsubscribe to stop receiving notifications from user statuses",
+ operationId: "PleromaAPI.AccountController.unsubscribe",
+ parameters: [id_param()],
+ security: [%{"oAuth" => ["follow", "write:follows"]}],
+ responses: %{
+ 200 => Operation.response("Relationship", "application/json", AccountRelationship),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp id_param do
+ Operation.parameter(:id, :path, FlakeID, "Account ID",
+ example: "9umDrYheeY451cQnEe",
+ required: true
+ )
+ end
+
+ defp update_avatar_or_background_request do
+ %Schema{
+ title: "PleromaAccountUpdateAvatarOrBackgroundRequest",
+ type: :object,
+ properties: %{
+ img: %Schema{
+ nullable: true,
+ type: :string,
+ format: :binary,
+ description: "Image encoded using `multipart/form-data` or an empty string to clear"
+ }
+ }
+ }
+ end
+
+ defp update_banner_request do
+ %Schema{
+ title: "PleromaAccountUpdateBannerRequest",
+ type: :object,
+ properties: %{
+ banner: %Schema{
+ type: :string,
+ nullable: true,
+ format: :binary,
+ description: "Image encoded using `multipart/form-data` or an empty string to clear"
+ }
+ }
+ }
+ end
+
+ defp update_response do
+ Operation.response("PleromaAccountUpdateResponse", "application/json", %Schema{
+ type: :object,
+ properties: %{
+ url: %Schema{
+ type: :string,
+ format: :uri,
+ nullable: true,
+ description: "Image URL"
+ }
+ },
+ example: %{
+ "url" =>
+ "https://cofe.party/media/9d0add56-bcb6-4c0f-8225-cbbd0b6dd773/13eadb6972c9ccd3f4ffa3b8196f0e0d38b4d2f27594457c52e52946c054cd9a.gif"
+ }
+ })
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/report_operation.ex b/lib/pleroma/web/api_spec/operations/report_operation.ex
index da4d50703..882177c96 100644
--- a/lib/pleroma/web/api_spec/operations/report_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/report_operation.ex
@@ -37,15 +37,18 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
account_id: %Schema{type: :string, description: "ID of the account to report"},
status_ids: %Schema{
type: :array,
+ nullable: true,
items: %Schema{type: :string},
description: "Array of Statuses to attach to the report, for context"
},
comment: %Schema{
type: :string,
+ nullable: true,
description: "Reason for the report"
},
forward: %Schema{
type: :boolean,
+ nullable: true,
default: false,
description:
"If the account is remote, should the report be forwarded to the remote admin?"
diff --git a/lib/pleroma/web/api_spec/operations/search_operation.ex b/lib/pleroma/web/api_spec/operations/search_operation.ex
index 6ea00a9a8..169c36d87 100644
--- a/lib/pleroma/web/api_spec/operations/search_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/search_operation.ex
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
apply(__MODULE__, operation, [])
end
+ # Note: `with_relationships` param is not supported (PleromaFE uses this op for autocomplete)
def account_search_operation do
%Operation{
tags: ["Search"],
@@ -96,8 +97,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
:query,
%Schema{type: :integer},
"Offset"
- )
- | pagination_params()
+ ),
+ with_relationships_param() | pagination_params()
],
responses: %{
200 => Operation.response("Results", "application/json", results())
@@ -138,8 +139,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
:query,
%Schema{allOf: [BooleanLike], default: false},
"Only include accounts that the user is following"
- )
- | pagination_params()
+ ),
+ with_relationships_param() | pagination_params()
],
responses: %{
200 => Operation.response("Results", "application/json", results2())
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index a6bb87560..4b284c537 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -7,7 +7,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.AccountOperation
alias Pleroma.Web.ApiSpec.Schemas.ApiError
- alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
alias Pleroma.Web.ApiSpec.Schemas.Status
@@ -349,10 +348,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
summary: "Bookmarked statuses",
description: "Statuses the user has bookmarked",
operationId: "StatusController.bookmarks",
- parameters: [
- Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
- | pagination_params()
- ],
+ parameters: pagination_params(),
security: [%{"oAuth" => ["read:bookmarks"]}],
responses: %{
200 => Operation.response("Array of Statuses", "application/json", array_of_statuses())
@@ -360,7 +356,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
}
end
- defp array_of_statuses do
+ def array_of_statuses do
%Schema{type: :array, items: Status, example: [Status.schema().example]}
end
@@ -371,15 +367,18 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
properties: %{
status: %Schema{
type: :string,
+ nullable: true,
description:
"Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided."
},
media_ids: %Schema{
+ nullable: true,
type: :array,
items: %Schema{type: :string},
description: "Array of Attachment ids to be attached as media."
},
poll: %Schema{
+ nullable: true,
type: :object,
required: [:options],
properties: %{
@@ -390,26 +389,35 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
},
expires_in: %Schema{
type: :integer,
+ nullable: true,
description:
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`"
},
- multiple: %Schema{type: :boolean, description: "Allow multiple choices?"},
+ multiple: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Allow multiple choices?"
+ },
hide_totals: %Schema{
type: :boolean,
+ nullable: true,
description: "Hide vote counts until the poll ends?"
}
}
},
in_reply_to_id: %Schema{
+ nullable: true,
allOf: [FlakeID],
description: "ID of the status being replied to, if status is a reply"
},
sensitive: %Schema{
type: :boolean,
+ nullable: true,
description: "Mark status and attached media as sensitive?"
},
spoiler_text: %Schema{
type: :string,
+ nullable: true,
description:
"Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field."
},
@@ -420,25 +428,33 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
description:
"ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future."
},
- language: %Schema{type: :string, description: "ISO 639 language code for this status."},
+ language: %Schema{
+ type: :string,
+ nullable: true,
+ description: "ISO 639 language code for this status."
+ },
# Pleroma-specific properties:
preview: %Schema{
type: :boolean,
+ nullable: true,
description:
"If set to `true` the post won't be actually posted, but the status entitiy would still be rendered back. This could be useful for previewing rich text/custom emoji, for example"
},
content_type: %Schema{
type: :string,
+ nullable: true,
description:
"The MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint."
},
to: %Schema{
type: :array,
+ nullable: true,
items: %Schema{type: :string},
description:
"A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply"
},
visibility: %Schema{
+ nullable: true,
anyOf: [
VisibilityScope,
%Schema{type: :string, description: "`list:LIST_ID`", example: "LIST:123"}
@@ -447,11 +463,13 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
"Visibility of the posted status. Besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID`"
},
expires_in: %Schema{
+ nullable: true,
type: :integer,
description:
"The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour."
},
in_reply_to_conversation_id: %Schema{
+ nullable: true,
type: :string,
description:
"Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`."
diff --git a/lib/pleroma/web/api_spec/operations/subscription_operation.ex b/lib/pleroma/web/api_spec/operations/subscription_operation.ex
index 663b8fa11..cf6dcb068 100644
--- a/lib/pleroma/web/api_spec/operations/subscription_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/subscription_operation.ex
@@ -109,19 +109,38 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
required: [:endpoint, :keys]
},
data: %Schema{
+ nullable: true,
type: :object,
properties: %{
alerts: %Schema{
+ nullable: true,
type: :object,
properties: %{
- follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
+ follow: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive follow notifications?"
+ },
favourite: %Schema{
type: :boolean,
+ nullable: true,
description: "Receive favourite notifications?"
},
- reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
- mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
- poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
+ reblog: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive reblog notifications?"
+ },
+ mention: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive mention notifications?"
+ },
+ poll: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive poll notifications?"
+ }
}
}
}
@@ -154,19 +173,38 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
type: :object,
properties: %{
data: %Schema{
+ nullable: true,
type: :object,
properties: %{
alerts: %Schema{
+ nullable: true,
type: :object,
properties: %{
- follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
+ follow: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive follow notifications?"
+ },
favourite: %Schema{
type: :boolean,
+ nullable: true,
description: "Receive favourite notifications?"
},
- reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
- mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
- poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
+ reblog: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive reblog notifications?"
+ },
+ mention: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive mention notifications?"
+ },
+ poll: %Schema{
+ type: :boolean,
+ nullable: true,
+ description: "Receive poll notifications?"
+ }
}
}
}
diff --git a/lib/pleroma/web/api_spec/operations/timeline_operation.ex b/lib/pleroma/web/api_spec/operations/timeline_operation.ex
index 1b89035d4..cb9d75841 100644
--- a/lib/pleroma/web/api_spec/operations/timeline_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/timeline_operation.ex
@@ -27,8 +27,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(),
with_muted_param(),
exclude_visibilities_param(),
- reply_visibility_param(),
- with_relationships_param() | pagination_params()
+ reply_visibility_param() | pagination_params()
],
operationId: "TimelineController.home",
responses: %{
@@ -63,8 +62,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
only_media_param(),
with_muted_param(),
exclude_visibilities_param(),
- reply_visibility_param(),
- with_relationships_param() | pagination_params()
+ reply_visibility_param() | pagination_params()
],
operationId: "TimelineController.public",
responses: %{
@@ -109,8 +107,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(),
only_media_param(),
with_muted_param(),
- exclude_visibilities_param(),
- with_relationships_param() | pagination_params()
+ exclude_visibilities_param() | pagination_params()
],
operationId: "TimelineController.hashtag",
responses: %{
@@ -134,8 +131,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
required: true
),
with_muted_param(),
- exclude_visibilities_param(),
- with_relationships_param() | pagination_params()
+ exclude_visibilities_param() | pagination_params()
],
operationId: "TimelineController.list",
responses: %{
@@ -153,10 +149,6 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
}
end
- defp with_relationships_param do
- Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
- end
-
defp local_param do
Operation.parameter(
:local,
diff --git a/lib/pleroma/web/api_spec/schemas/attachment.ex b/lib/pleroma/web/api_spec/schemas/attachment.ex
index c146c416e..c6edf6d36 100644
--- a/lib/pleroma/web/api_spec/schemas/attachment.ex
+++ b/lib/pleroma/web/api_spec/schemas/attachment.ex
@@ -13,7 +13,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Attachment do
type: :object,
requried: [:id, :url, :preview_url],
properties: %{
- id: %Schema{type: :string},
+ id: %Schema{type: :string, description: "The ID of the attachment in the database."},
url: %Schema{
type: :string,
format: :uri,
diff --git a/lib/pleroma/web/auth/totp_authenticator.ex b/lib/pleroma/web/auth/totp_authenticator.ex
index 04e489c83..ce8a76219 100644
--- a/lib/pleroma/web/auth/totp_authenticator.ex
+++ b/lib/pleroma/web/auth/totp_authenticator.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Web.Auth.TOTPAuthenticator do
alias Pleroma.MFA
alias Pleroma.MFA.TOTP
+ alias Pleroma.Plugs.AuthenticationPlug
alias Pleroma.User
@doc "Verify code or check backup code."
@@ -30,7 +31,7 @@ defmodule Pleroma.Web.Auth.TOTPAuthenticator do
code
)
when is_list(codes) and is_binary(code) do
- hash_code = Enum.find(codes, fn hash -> Pbkdf2.verify_pass(code, hash) end)
+ hash_code = Enum.find(codes, fn hash -> AuthenticationPlug.checkpw(code, hash) end)
if hash_code do
MFA.invalidate_backup_code(user, hash_code)
diff --git a/lib/pleroma/web/chat_channel.ex b/lib/pleroma/web/chat_channel.ex
index 38ec774f7..bce27897f 100644
--- a/lib/pleroma/web/chat_channel.ex
+++ b/lib/pleroma/web/chat_channel.ex
@@ -23,6 +23,7 @@ defmodule Pleroma.Web.ChatChannel do
if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do
author = User.get_cached_by_nickname(user_name)
author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author)
+
message = ChatChannelState.add_message(%{text: text, author: author})
broadcast!(socket, "new_msg", message)
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 601caeb46..7c94f16b6 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -25,10 +25,21 @@ defmodule Pleroma.Web.CommonAPI do
require Logger
def unblock(blocker, blocked) do
- with %Activity{} = block <- Utils.fetch_latest_block(blocker, blocked),
+ with {_, %Activity{} = block} <- {:fetch_block, Utils.fetch_latest_block(blocker, blocked)},
{:ok, unblock_data, _} <- Builder.undo(blocker, block),
{:ok, unblock, _} <- Pipeline.common_pipeline(unblock_data, local: true) do
{:ok, unblock}
+ else
+ {:fetch_block, nil} ->
+ if User.blocks?(blocker, blocked) do
+ User.unblock(blocker, blocked)
+ {:ok, :no_activity}
+ else
+ {:error, :not_blocking}
+ end
+
+ e ->
+ e
end
end
diff --git a/lib/pleroma/web/controller_helper.ex b/lib/pleroma/web/controller_helper.ex
index eb97ae975..5a1316a5f 100644
--- a/lib/pleroma/web/controller_helper.ex
+++ b/lib/pleroma/web/controller_helper.ex
@@ -5,8 +5,6 @@
defmodule Pleroma.Web.ControllerHelper do
use Pleroma.Web, :controller
- alias Pleroma.Config
-
# As in Mastodon API, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
@falsy_param_values [false, 0, "0", "f", "F", "false", "False", "FALSE", "off", "OFF"]
@@ -106,13 +104,16 @@ defmodule Pleroma.Web.ControllerHelper do
def put_if_exist(map, key, value), do: Map.put(map, key, value)
- @doc "Whether to skip rendering `[:account][:pleroma][:relationship]`for statuses/notifications"
- def skip_relationships?(params) do
- if Config.get([:extensions, :output_relationships_in_statuses_by_default]) do
- false
- else
- # BREAKING: older PleromaFE versions do not send this param but _do_ expect relationships.
- not truthy_param?(params["with_relationships"])
- end
+ @doc """
+ Returns true if request specifies to include embedded relationships in account objects.
+ May only be used in selected account-related endpoints; has no effect for status- or
+ notification-related endpoints.
+ """
+ # Intended for PleromaFE: https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838
+ def embed_relationships?(params) do
+ # To do once OpenAPI transition mess is over: just `truthy_param?(params[:with_relationships])`
+ params
+ |> Map.get(:with_relationships, params["with_relationships"])
+ |> truthy_param?()
end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index b9ed2d7b2..ef41f9e96 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -10,8 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
add_link_headers: 2,
truthy_param?: 1,
assign_account_by_id: 2,
- json_response: 3,
- skip_relationships?: 1
+ embed_relationships?: 1,
+ json_response: 3
]
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@@ -247,8 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|> render("index.json",
activities: activities,
for: reading_user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
else
_e -> render_error(conn, :not_found, "Can't find user")
@@ -271,7 +270,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn
|> add_link_headers(followers)
- |> render("index.json", for: for_user, users: followers, as: :user)
+ # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
+ |> render("index.json",
+ for: for_user,
+ users: followers,
+ as: :user,
+ embed_relationships: embed_relationships?(params)
+ )
end
@doc "GET /api/v1/accounts/:id/following"
@@ -290,7 +295,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn
|> add_link_headers(followers)
- |> render("index.json", for: for_user, users: followers, as: :user)
+ # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
+ |> render("index.json",
+ for: for_user,
+ users: followers,
+ as: :user,
+ embed_relationships: embed_relationships?(params)
+ )
end
@doc "GET /api/v1/accounts/:id/lists"
diff --git a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex
index e36751220..a21233393 100644
--- a/lib/pleroma/web/mastodon_api/controllers/media_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/media_controller.ex
@@ -11,17 +11,20 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
alias Pleroma.Web.ActivityPub.ActivityPub
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
plug(OAuthScopesPlug, %{scopes: ["write:media"]})
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.MediaOperation
+
@doc "POST /api/v1/media"
- def create(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do
+ def create(%{assigns: %{user: user}, body_params: %{file: file} = data} = conn, _) do
with {:ok, object} <-
ActivityPub.upload(
file,
actor: User.ap_id(user),
- description: Map.get(data, "description")
+ description: Map.get(data, :description)
) do
attachment_data = Map.put(object.data, "id", object.id)
@@ -29,9 +32,28 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
end
end
+ def create(_conn, _data), do: {:error, :bad_request}
+
+ @doc "POST /api/v2/media"
+ def create2(%{assigns: %{user: user}, body_params: %{file: file} = data} = conn, _) do
+ with {:ok, object} <-
+ ActivityPub.upload(
+ file,
+ actor: User.ap_id(user),
+ description: Map.get(data, :description)
+ ) do
+ attachment_data = Map.put(object.data, "id", object.id)
+
+ conn
+ |> put_status(202)
+ |> render("attachment.json", %{attachment: attachment_data})
+ end
+ end
+
+ def create2(_conn, _data), do: {:error, :bad_request}
+
@doc "PUT /api/v1/media/:id"
- def update(%{assigns: %{user: user}} = conn, %{"id" => id, "description" => description})
- when is_binary(description) do
+ def update(%{assigns: %{user: user}, body_params: %{description: description}} = conn, %{id: id}) do
with %Object{} = object <- Object.get_by_id(id),
true <- Object.authorize_mutation(object, user),
{:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do
@@ -41,5 +63,16 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
end
end
- def update(_conn, _data), do: {:error, :bad_request}
+ def update(conn, data), do: show(conn, data)
+
+ @doc "GET /api/v1/media/:id"
+ def show(conn, %{id: id}) do
+ with %Object{data: data, id: object_id} <- Object.get_by_id(id) do
+ attachment_data = Map.put(data, "id", object_id)
+
+ render(conn, "attachment.json", %{attachment: attachment_data})
+ end
+ end
+
+ def get_media(_conn, _data), do: {:error, :bad_request}
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
index 596b85617..bcd12c73f 100644
--- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
@@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.NotificationController do
use Pleroma.Web, :controller
- import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1]
+ import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Notification
alias Pleroma.Plugs.OAuthScopesPlug
@@ -50,8 +50,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
|> add_link_headers(notifications)
|> render("index.json",
notifications: notifications,
- for: user,
- skip_relationships: skip_relationships?(params)
+ for: user
)
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
index 0e0d54ba4..77e2224e4 100644
--- a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
@@ -5,14 +5,13 @@
defmodule Pleroma.Web.MastodonAPI.SearchController do
use Pleroma.Web, :controller
- import Pleroma.Web.ControllerHelper, only: [skip_relationships?: 1]
-
alias Pleroma.Activity
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web
+ alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView
@@ -34,7 +33,11 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
conn
|> put_view(AccountView)
- |> render("index.json", users: accounts, for: user, as: :user)
+ |> render("index.json",
+ users: accounts,
+ for: user,
+ as: :user
+ )
end
def search2(conn, params), do: do_search(:v2, conn, params)
@@ -71,13 +74,13 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
defp search_options(params, user) do
[
- skip_relationships: skip_relationships?(params),
resolve: params[:resolve],
following: params[:following],
limit: params[:limit],
offset: params[:offset],
type: params[:type],
author: get_author(params),
+ embed_relationships: ControllerHelper.embed_relationships?(params),
for_user: user
]
|> Enum.filter(&elem(&1, 1))
@@ -90,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
users: accounts,
for: options[:for_user],
as: :user,
- skip_relationships: false
+ embed_relationships: options[:embed_relationships]
)
end
@@ -100,8 +103,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
StatusView.render("index.json",
activities: statuses,
for: options[:for_user],
- as: :activity,
- skip_relationships: options[:skip_relationships]
+ as: :activity
)
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 25e499a77..9dbf4f33c 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper,
- only: [try_render: 3, add_link_headers: 2, skip_relationships?: 1]
+ only: [try_render: 3, add_link_headers: 2]
require Ecto.Query
@@ -105,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required
"""
- def index(%{assigns: %{user: user}} = conn, %{ids: ids} = params) do
+ def index(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
limit = 100
activities =
@@ -117,8 +117,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
render(conn, "index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
@@ -383,8 +382,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
@@ -406,8 +404,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index bbd576ffd..958567510 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper,
- only: [add_link_headers: 2, add_link_headers: 3, skip_relationships?: 1]
+ only: [add_link_headers: 2, add_link_headers: 3]
alias Pleroma.Pagination
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@@ -63,8 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
@@ -88,8 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
@@ -125,8 +123,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
end
@@ -173,8 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
@@ -203,8 +199,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
render(conn, "index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
else
_e -> render_error(conn, :forbidden, "Error.")
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 835dfe9f4..45fffaad2 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -15,13 +15,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
def render("index.json", %{users: users} = opts) do
reading_user = opts[:for]
- # Note: :skip_relationships option is currently intentionally not supported for accounts
relationships_opt =
cond do
Map.has_key?(opts, :relationships) ->
opts[:relationships]
- is_nil(reading_user) ->
+ is_nil(reading_user) || !opts[:embed_relationships] ->
UserRelationship.view_relationships_option(nil, [])
true ->
@@ -193,14 +192,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
end)
relationship =
- if opts[:skip_relationships] do
- %{}
- else
+ if opts[:embed_relationships] do
render("relationship.json", %{
user: opts[:for],
target: user,
relationships: opts[:relationships]
})
+ else
+ %{}
end
%{
diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex
index 4da1ab67f..c46ddcf55 100644
--- a/lib/pleroma/web/mastodon_api/views/notification_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex
@@ -51,9 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
|> Enum.filter(& &1)
|> Kernel.++(move_activities_targets)
- UserRelationship.view_relationships_option(reading_user, actors,
- source_mutes_only: opts[:skip_relationships]
- )
+ UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
end
opts =
@@ -83,15 +81,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
mastodon_type = Activity.mastodon_notification_type(activity)
- render_opts = %{
- relationships: opts[:relationships],
- skip_relationships: opts[:skip_relationships]
- }
+ # Note: :relationships contain user mutes (needed for :muted flag in :status)
+ status_render_opts = %{relationships: opts[:relationships]}
with %{id: _} = account <-
AccountView.render(
"show.json",
- Map.merge(render_opts, %{user: actor, for: reading_user})
+ %{user: actor, for: reading_user}
) do
response = %{
id: to_string(notification.id),
@@ -105,21 +101,20 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
case mastodon_type do
"mention" ->
- put_status(response, activity, reading_user, render_opts)
+ put_status(response, activity, reading_user, status_render_opts)
"favourite" ->
- put_status(response, parent_activity_fn.(), reading_user, render_opts)
+ put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"reblog" ->
- put_status(response, parent_activity_fn.(), reading_user, render_opts)
+ put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"move" ->
- # Note: :skip_relationships option being applied to _account_ rendering (here)
- put_target(response, activity, reading_user, render_opts)
+ put_target(response, activity, reading_user, %{})
"pleroma:emoji_reaction" ->
response
- |> put_status(parent_activity_fn.(), reading_user, render_opts)
+ |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
|> put_emoji(activity)
type when type in ["follow", "follow_request"] ->
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 24167f66f..05a26017a 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -107,9 +107,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|> Enum.map(&get_user(&1.data["actor"], false))
|> Enum.filter(& &1)
- UserRelationship.view_relationships_option(reading_user, actors,
- source_mutes_only: opts[:skip_relationships]
- )
+ UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
end
opts =
@@ -162,9 +160,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
account:
AccountView.render("show.json", %{
user: user,
- for: opts[:for],
- relationships: opts[:relationships],
- skip_relationships: opts[:skip_relationships]
+ for: opts[:for]
}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
@@ -330,9 +326,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
account:
AccountView.render("show.json", %{
user: user,
- for: opts[:for],
- relationships: opts[:relationships],
- skip_relationships: opts[:skip_relationships]
+ for: opts[:for]
}),
in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),
diff --git a/lib/pleroma/web/mongooseim/mongoose_im_controller.ex b/lib/pleroma/web/mongooseim/mongoose_im_controller.ex
index 0814b3bc3..6cbbe8fd8 100644
--- a/lib/pleroma/web/mongooseim/mongoose_im_controller.ex
+++ b/lib/pleroma/web/mongooseim/mongoose_im_controller.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Web.MongooseIM.MongooseIMController do
use Pleroma.Web, :controller
+ alias Pleroma.Plugs.AuthenticationPlug
alias Pleroma.Plugs.RateLimiter
alias Pleroma.Repo
alias Pleroma.User
@@ -27,7 +28,7 @@ defmodule Pleroma.Web.MongooseIM.MongooseIMController do
def check_password(conn, %{"user" => username, "pass" => password}) do
with %User{password_hash: password_hash, deactivated: false} <-
Repo.get_by(User, nickname: username, local: true),
- true <- Pbkdf2.verify_pass(password, password_hash) do
+ true <- AuthenticationPlug.checkpw(password, password_hash) do
conn
|> json(true)
else
diff --git a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex
index be7477867..0a3f45620 100644
--- a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper,
- only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2, skip_relationships?: 1]
+ only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
alias Ecto.Changeset
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@@ -19,6 +19,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
require Pleroma.Constants
plug(
+ OpenApiSpex.Plug.PutApiSpec,
+ [module: Pleroma.Web.ApiSpec] when action == :confirmation_resend
+ )
+
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
+
+ plug(
:skip_plug,
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirmation_resend
)
@@ -49,9 +56,11 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation
+
@doc "POST /api/v1/pleroma/accounts/confirmation_resend"
def confirmation_resend(conn, params) do
- nickname_or_email = params["email"] || params["nickname"]
+ nickname_or_email = params[:email] || params[:nickname]
with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
{:ok, _} <- User.try_send_confirmation_email(user) do
@@ -60,7 +69,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
end
@doc "PATCH /api/v1/pleroma/accounts/update_avatar"
- def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
+ def update_avatar(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do
{:ok, _user} =
user
|> Changeset.change(%{avatar: nil})
@@ -69,7 +78,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
json(conn, %{url: nil})
end
- def update_avatar(%{assigns: %{user: user}} = conn, params) do
+ def update_avatar(%{assigns: %{user: user}, body_params: params} = conn, _params) do
{:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
{:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
%{"url" => [%{"href" => href} | _]} = data
@@ -78,14 +87,14 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
end
@doc "PATCH /api/v1/pleroma/accounts/update_banner"
- def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
+ def update_banner(%{assigns: %{user: user}, body_params: %{banner: ""}} = conn, _) do
with {:ok, _user} <- User.update_banner(user, %{}) do
json(conn, %{url: nil})
end
end
- def update_banner(%{assigns: %{user: user}} = conn, params) do
- with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
+ def update_banner(%{assigns: %{user: user}, body_params: params} = conn, _) do
+ with {:ok, object} <- ActivityPub.upload(%{img: params[:banner]}, type: :banner),
{:ok, _user} <- User.update_banner(user, object.data) do
%{"url" => [%{"href" => href} | _]} = object.data
@@ -94,13 +103,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
end
@doc "PATCH /api/v1/pleroma/accounts/update_background"
- def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
+ def update_background(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do
with {:ok, _user} <- User.update_background(user, %{}) do
json(conn, %{url: nil})
end
end
- def update_background(%{assigns: %{user: user}} = conn, params) do
+ def update_background(%{assigns: %{user: user}, body_params: params} = conn, _) do
with {:ok, object} <- ActivityPub.upload(params, type: :background),
{:ok, _user} <- User.update_background(user, object.data) do
%{"url" => [%{"href" => href} | _]} = object.data
@@ -117,6 +126,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
params =
params
+ |> Map.new(fn {key, value} -> {to_string(key), value} end)
|> Map.put("type", "Create")
|> Map.put("favorited_by", user.ap_id)
|> Map.put("blocking_user", for_user)
@@ -139,8 +149,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|> render("index.json",
activities: activities,
for: for_user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
end
diff --git a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
index 8bc77b75e..e834133b2 100644
--- a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
@@ -5,7 +5,7 @@
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
use Pleroma.Web, :controller
- import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1]
+ import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Activity
alias Pleroma.Conversation.Participation
@@ -69,7 +69,12 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
%{
name: emoji,
count: length(users),
- accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}),
+ accounts:
+ AccountView.render("index.json", %{
+ users: users,
+ for: user,
+ as: :user
+ }),
me: !!(user && user.ap_id in user_ap_ids)
}
end
@@ -145,8 +150,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|> render("index.json",
activities: activities,
for: user,
- as: :activity,
- skip_relationships: skip_relationships?(params)
+ as: :activity
)
else
_error ->
@@ -201,7 +205,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
end
end
- def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id} = params) do
+ def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id}) do
with notifications <- Notification.set_read_up_to(user, max_id) do
notifications = Enum.take(notifications, 80)
@@ -209,8 +213,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|> put_view(NotificationView)
|> render("index.json",
notifications: notifications,
- for: user,
- skip_relationships: skip_relationships?(params)
+ for: user
)
end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 7a171f9fb..d77a61361 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -403,6 +403,7 @@ defmodule Pleroma.Web.Router do
post("/markers", MarkerController, :upsert)
post("/media", MediaController, :create)
+ get("/media/:id", MediaController, :show)
put("/media/:id", MediaController, :update)
get("/notifications", NotificationController, :index)
@@ -497,6 +498,8 @@ defmodule Pleroma.Web.Router do
scope "/api/v2", Pleroma.Web.MastodonAPI do
pipe_through(:api)
get("/search", SearchController, :search2)
+
+ post("/media", MediaController, :create2)
end
scope "/api", Pleroma.Web do
diff --git a/mix.exs b/mix.exs
index 0186d291f..b8e663a03 100644
--- a/mix.exs
+++ b/mix.exs
@@ -127,6 +127,7 @@ defmodule Pleroma.Mixfile do
{:oban, "~> 1.2"},
{:gettext, "~> 0.15"},
{:pbkdf2_elixir, "~> 1.0"},
+ {:bcrypt_elixir, "~> 2.0"},
{:trailing_format_plug, "~> 0.0.7"},
{:fast_sanitize, "~> 0.1"},
{:html_entities, "~> 0.5", override: true},
diff --git a/mix.lock b/mix.lock
index 62fe35146..955b2bb37 100644
--- a/mix.lock
+++ b/mix.lock
@@ -5,6 +5,7 @@
"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"]},
"bbcode_pleroma": {:hex, :bbcode_pleroma, "0.2.0", "d36f5bca6e2f62261c45be30fa9b92725c0655ad45c99025cb1c3e28e25803ef", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "19851074419a5fedb4ef49e1f01b30df504bb5dbb6d6adfc135238063bebd1c3"},
+ "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.2.0", "3df902b81ce7fa8867a2ae30d20a1da6877a2c056bfb116fd0bc8a5f0190cea4", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "762be3fcb779f08207531bc6612cca480a338e4b4357abb49f5ce00240a77d1e"},
"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"},
@@ -29,6 +30,7 @@
"ecto": {:hex, :ecto, "3.4.0", "a7a83ab8359bf816ce729e5e65981ce25b9fc5adfc89c2ea3980f4fed0bfd7c1", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "5eed18252f5b5bbadec56a24112b531343507dbe046273133176b12190ce19cc"},
"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.3.4", "aa18af12eb875fbcda2f75e608b3bd534ebf020fc4f6448e4672fcdcbb081244", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4 or ~> 3.3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5eccbdbf92e3c6f213007a82d5dbba4cd9bb659d1a21331f89f408e4c0efd7a8"},
+ "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
"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"},
diff --git a/priv/gettext/fr/LC_MESSAGES/errors.po b/priv/gettext/fr/LC_MESSAGES/errors.po
index 678b32289..406f98de9 100644
--- a/priv/gettext/fr/LC_MESSAGES/errors.po
+++ b/priv/gettext/fr/LC_MESSAGES/errors.po
@@ -8,8 +8,16 @@
## to merge POT files into PO files.
msgid ""
msgstr ""
+"PO-Revision-Date: 2020-05-12 15:52+0000\n"
+"Last-Translator: Haelwenn (lanodan) Monnier "
+"<contact+translate.pleroma.social@hacktivis.me>\n"
+"Language-Team: French <https://translate.pleroma.social/projects/pleroma/"
+"pleroma/fr/>\n"
"Language: fr\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 4.0.4\n"
+"Content-Transfer-Encoding: 8bit\n"
msgid "can't be blank"
msgstr "ne peut être vide"
@@ -35,10 +43,10 @@ msgid "does not match confirmation"
msgstr "ne correspondent pas"
msgid "is still associated with this entry"
-msgstr ""
+msgstr "est toujours associé à cette entrée"
msgid "are still associated with this entry"
-msgstr ""
+msgstr "sont toujours associés à cette entrée"
msgid "should be %{count} character(s)"
msgid_plural "should be %{count} character(s)"
@@ -85,375 +93,375 @@ msgstr "doit être supérieur ou égal à %{number}"
msgid "must be equal to %{number}"
msgstr "doit égal à %{number}"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:381
+#, elixir-format
msgid "Account not found"
msgstr "Compte non trouvé"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:153
+#, elixir-format
msgid "Already voted"
msgstr "A déjà voté"
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:263
+#, elixir-format
msgid "Bad request"
msgstr "Requête Invalide"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254
+#, elixir-format
msgid "Can't delete object"
msgstr "Ne peut supprimer cet objet"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569
+#, elixir-format
msgid "Can't delete this post"
msgstr "Ne peut supprimer ce message"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1731
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737
+#, elixir-format
msgid "Can't display this activity"
msgstr "Ne peut afficher cette activitée"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195
+#, elixir-format
msgid "Can't find user"
msgstr "Compte non trouvé"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148
+#, elixir-format
msgid "Can't get favorites"
msgstr "Favoris non trouvables"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263
+#, elixir-format
msgid "Can't like object"
msgstr "Ne peut aimer cet objet"
-#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:518
+#, elixir-format
msgid "Cannot post an empty status without attachments"
msgstr "Ne peut envoyer un status vide sans attachements"
-#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:461
+#, elixir-format
msgid "Comment must be up to %{max_size} characters"
msgstr "Le commentaire ne doit faire plus de %{max_size} charactères"
-#, elixir-format
#: lib/pleroma/web/admin_api/config.ex:63
+#, elixir-format
msgid "Config with params %{params} not found"
msgstr "Configuration avec les paramètres %{params} non trouvée"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:78
+#, elixir-format
msgid "Could not delete"
msgstr "Échec de la suppression"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:110
+#, elixir-format
msgid "Could not favorite"
msgstr "Échec de mise en favoris"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:310
+#, elixir-format
msgid "Could not pin"
msgstr "Échec de l'épinglage"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:89
+#, elixir-format
msgid "Could not repeat"
msgstr "Échec de création la répétition"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:120
+#, elixir-format
msgid "Could not unfavorite"
msgstr "Échec de suppression des favoris"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:327
+#, elixir-format
msgid "Could not unpin"
msgstr "Échec du dépinglage"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:99
+#, elixir-format
msgid "Could not unrepeat"
msgstr "Échec de suppression de la répétition"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:392
+#, elixir-format
msgid "Could not update state"
msgstr "Échec de la mise à jour du status"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271
+#, elixir-format
msgid "Error."
msgstr "Erreur."
-#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:36
+#, elixir-format
msgid "Invalid CAPTCHA"
msgstr "CAPTCHA invalide"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700
#: lib/pleroma/web/oauth/oauth_controller.ex:465
+#, elixir-format
msgid "Invalid credentials"
msgstr "Paramètres d'authentification invalides"
-#, elixir-format
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:20
+#, elixir-format
msgid "Invalid credentials."
msgstr "Paramètres d'authentification invalides."
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:154
+#, elixir-format
msgid "Invalid indices"
msgstr "Indices invalides"
-#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:411
+#, elixir-format
msgid "Invalid parameters"
msgstr "Paramètres invalides"
-#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:377
+#, elixir-format
msgid "Invalid password."
msgstr "Mot de passe invalide."
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163
+#, elixir-format
msgid "Invalid request"
msgstr "Requête invalide"
-#, elixir-format
#: lib/pleroma/captcha/kocaptcha.ex:16
+#, elixir-format
msgid "Kocaptcha service unavailable"
msgstr "Service Kocaptcha non disponible"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696
+#, elixir-format
msgid "Missing parameters"
msgstr "Paramètres manquants"
-#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:496
+#, elixir-format
msgid "No such conversation"
msgstr "Conversation inconnue"
-#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:163
#: lib/pleroma/web/admin_api/admin_api_controller.ex:206
+#, elixir-format
msgid "No such permission_group"
msgstr "Groupe de permission inconnu"
-#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:69
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311
#: lib/pleroma/web/admin_api/admin_api_controller.ex:399
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:63
#: lib/pleroma/web/ostatus/ostatus_controller.ex:248
+#, elixir-format
msgid "Not found"
msgstr "Non Trouvé"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:152
+#, elixir-format
msgid "Poll's author can't vote"
msgstr "L'auteur·rice d'un sondage ne peut voter"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:443
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:444
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:473
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:476
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1180
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564
+#, elixir-format
msgid "Record not found"
msgstr "Enregistrement non trouvé"
-#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:417
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1570
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:69
#: lib/pleroma/web/ostatus/ostatus_controller.ex:252
+#, elixir-format
msgid "Something went wrong"
msgstr "Erreur inconnue"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:253
+#, elixir-format
msgid "The message visibility must be direct"
msgstr "La visibilitée du message doit être « direct »"
-#, elixir-format
#: lib/pleroma/web/common_api/utils.ex:521
+#, elixir-format
msgid "The status is over the character limit"
msgstr "Le status est au-delà de la limite de charactères"
-#, elixir-format
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27
+#, elixir-format
msgid "This resource requires authentication."
msgstr "Cette resource nécessite une authentification."
-#, elixir-format
#: lib/pleroma/plugs/rate_limiter.ex:89
+#, elixir-format
msgid "Throttled"
msgstr "Limité"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:155
+#, elixir-format
msgid "Too many choices"
msgstr "Trop de choix"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268
+#, elixir-format
msgid "Unhandled activity type"
msgstr "Type d'activitée non-gérée"
-#, elixir-format
#: lib/pleroma/plugs/user_is_admin_plug.ex:20
+#, elixir-format
msgid "User is not admin."
msgstr "Le compte n'est pas admin."
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:380
+#, elixir-format
msgid "Valid `account_id` required"
msgstr "Un `account_id` valide est requis"
-#, elixir-format
#: lib/pleroma/web/admin_api/admin_api_controller.ex:185
+#, elixir-format
msgid "You can't revoke your own admin status."
msgstr "Vous ne pouvez révoquer votre propre status d'admin."
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:216
+#, elixir-format
msgid "Your account is currently disabled"
msgstr "Votre compte est actuellement désactivé"
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:158
#: lib/pleroma/web/oauth/oauth_controller.ex:213
+#, elixir-format
msgid "Your login is missing a confirmed e-mail address"
msgstr "Une confirmation de l'addresse de couriel est requise pour l'authentification"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:221
+#, elixir-format
msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr "Ne peut lire la boite de réception de %{nickname} en tant que %{as_nickname}"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:297
+#, elixir-format
msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr "Ne peut poster dans la boite d'émission de %{nickname} en tant que %{as_nickname}"
-#, elixir-format
#: lib/pleroma/web/common_api/common_api.ex:335
+#, elixir-format
msgid "conversation is already muted"
msgstr "la conversation est déjà baillonée"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:192
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:317
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1196
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247
+#, elixir-format
msgid "error"
msgstr "erreur"
-#, elixir-format
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789
+#, elixir-format
msgid "mascots can only be images"
msgstr "les mascottes ne peuvent être que des images"
-#, elixir-format
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34
+#, elixir-format
msgid "not found"
msgstr "non trouvé"
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:298
+#, elixir-format
msgid "Bad OAuth request."
msgstr "Requête OAuth invalide."
-#, elixir-format
#: lib/pleroma/captcha/captcha.ex:92
+#, elixir-format
msgid "CAPTCHA already used"
msgstr "CAPTCHA déjà utilisé"
-#, elixir-format
#: lib/pleroma/captcha/captcha.ex:89
+#, elixir-format
msgid "CAPTCHA expired"
msgstr "CAPTCHA expiré"
-#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:50
+#, elixir-format
msgid "Failed"
msgstr "Échec"
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:314
+#, elixir-format
msgid "Failed to authenticate: %{message}."
-msgstr "Échec de l'authentification: %{message}"
+msgstr "Échec de l'authentification : %{message}."
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:345
+#, elixir-format
msgid "Failed to set up user account."
msgstr "Échec de création de votre compte."
-#, elixir-format
#: lib/pleroma/plugs/oauth_scopes_plug.ex:37
+#, elixir-format
msgid "Insufficient permissions: %{permissions}."
-msgstr "Permissions insuffisantes: %{permissions}."
+msgstr "Permissions insuffisantes : %{permissions}."
-#, elixir-format
#: lib/pleroma/plugs/uploaded_media.ex:89
+#, elixir-format
msgid "Internal Error"
msgstr "Erreur interne"
-#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
+#, elixir-format
msgid "Invalid Username/Password"
msgstr "Nom d'utilisateur/mot de passe invalide"
-#, elixir-format
#: lib/pleroma/captcha/captcha.ex:107
+#, elixir-format
msgid "Invalid answer data"
msgstr "Réponse invalide"
-#, elixir-format
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204
+#, elixir-format
msgid "Nodeinfo schema version not handled"
msgstr "Version du schéma nodeinfo non géré"
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:145
+#, elixir-format
msgid "This action is outside the authorized scopes"
-msgstr "Cette action est en dehors des authorisations" # "scopes" ?
+msgstr "Cette action est en dehors des authorisations" # "scopes"
-#, elixir-format
#: lib/pleroma/web/oauth/fallback_controller.ex:14
+#, elixir-format
msgid "Unknown error, please check the details and try again."
msgstr "Erreur inconnue, veuillez vérifier les détails et réessayer."
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:93
#: lib/pleroma/web/oauth/oauth_controller.ex:131
+#, elixir-format
msgid "Unlisted redirect_uri."
msgstr "redirect_uri non listé."
-#, elixir-format
#: lib/pleroma/web/oauth/oauth_controller.ex:294
+#, elixir-format
msgid "Unsupported OAuth provider: %{provider}."
msgstr "Fournisseur OAuth non supporté : %{provider}."
-#, elixir-format
#: lib/pleroma/uploaders/uploader.ex:71
+#, elixir-format
msgid "Uploader callback timeout"
-msgstr ""
-## msgstr "Attente écoulée"
+msgstr "Temps d'attente du téléverseur écoulé"
-#, elixir-format
+## msgstr "Attente écoulée"
#: lib/pleroma/web/uploader_controller.ex:11
#: lib/pleroma/web/uploader_controller.ex:23
+#, elixir-format
msgid "bad request"
msgstr "requête invalide"
diff --git a/priv/gettext/pl/LC_MESSAGES/errors.po b/priv/gettext/pl/LC_MESSAGES/errors.po
new file mode 100644
index 000000000..af9e214c6
--- /dev/null
+++ b/priv/gettext/pl/LC_MESSAGES/errors.po
@@ -0,0 +1,587 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-05-13 16:37+0000\n"
+"PO-Revision-Date: 2020-05-14 14:37+0000\n"
+"Last-Translator: Michał Sidor <pleromeme@meekchopp.es>\n"
+"Language-Team: Polish <https://translate.pleroma.social/projects/pleroma/"
+"pleroma/pl/>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 4.0.4\n"
+
+## This file is a PO Template file.
+##
+## `msgid`s here are often extracted from source code.
+## Add new translations manually only if they're dynamic
+## translations that can't be statically extracted.
+##
+## Run `mix gettext.extract` to bring this file up to
+## date. Leave `msgstr`s empty as changing them here as no
+## effect: edit them in PO (`.po`) files instead.
+## From Ecto.Changeset.cast/4
+msgid "can't be blank"
+msgstr "nie może być pusty"
+
+## From Ecto.Changeset.unique_constraint/3
+msgid "has already been taken"
+msgstr "jest już zajęty"
+
+## From Ecto.Changeset.put_change/3
+msgid "is invalid"
+msgstr "jest nieprawidłowy"
+
+## From Ecto.Changeset.validate_format/3
+msgid "has invalid format"
+msgstr "ma niepoprawny format"
+
+## From Ecto.Changeset.validate_subset/3
+msgid "has an invalid entry"
+msgstr "ma niepoprawny wpis"
+
+## From Ecto.Changeset.validate_exclusion/3
+msgid "is reserved"
+msgstr ""
+
+## From Ecto.Changeset.validate_confirmation/3
+msgid "does not match confirmation"
+msgstr ""
+
+## From Ecto.Changeset.no_assoc_constraint/3
+msgid "is still associated with this entry"
+msgstr ""
+
+msgid "are still associated with this entry"
+msgstr ""
+
+## From Ecto.Changeset.validate_length/3
+msgid "should be %{count} character(s)"
+msgid_plural "should be %{count} character(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "should have %{count} item(s)"
+msgid_plural "should have %{count} item(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "should be at least %{count} character(s)"
+msgid_plural "should be at least %{count} character(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "should have at least %{count} item(s)"
+msgid_plural "should have at least %{count} item(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "should be at most %{count} character(s)"
+msgid_plural "should be at most %{count} character(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "should have at most %{count} item(s)"
+msgid_plural "should have at most %{count} item(s)"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+## From Ecto.Changeset.validate_number/3
+msgid "must be less than %{number}"
+msgstr ""
+
+msgid "must be greater than %{number}"
+msgstr ""
+
+msgid "must be less than or equal to %{number}"
+msgstr ""
+
+msgid "must be greater than or equal to %{number}"
+msgstr ""
+
+msgid "must be equal to %{number}"
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:421
+#, elixir-format
+msgid "Account not found"
+msgstr "Nie znaleziono konta"
+
+#: lib/pleroma/web/common_api/common_api.ex:249
+#, elixir-format
+msgid "Already voted"
+msgstr "Już zagłosowano"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:360
+#, elixir-format
+msgid "Bad request"
+msgstr "Nieprawidłowe żądanie"
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:425
+#, elixir-format
+msgid "Can't delete object"
+msgstr "Nie można usunąć obiektu"
+
+#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:196
+#, elixir-format
+msgid "Can't delete this post"
+msgstr "Nie udało się usunąć tego statusu"
+
+#: lib/pleroma/web/controller_helper.ex:95
+#: lib/pleroma/web/controller_helper.ex:101
+#, elixir-format
+msgid "Can't display this activity"
+msgstr "Nie można wyświetlić tej aktywności"
+
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:227
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:254
+#, elixir-format
+msgid "Can't find user"
+msgstr "Nie znaleziono użytkownika"
+
+#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:114
+#, elixir-format
+msgid "Can't get favorites"
+msgstr ""
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:437
+#, elixir-format
+msgid "Can't like object"
+msgstr "Nie udało się polubić obiektu"
+
+#: lib/pleroma/web/common_api/utils.ex:556
+#, elixir-format
+msgid "Cannot post an empty status without attachments"
+msgstr "Nie można opublikować pustego statusu bez załączników"
+
+#: lib/pleroma/web/common_api/utils.ex:504
+#, elixir-format
+msgid "Comment must be up to %{max_size} characters"
+msgstr "Komentarz może mieć co najwyżej %{max_size} znaków"
+
+#: lib/pleroma/config/config_db.ex:222
+#, elixir-format
+msgid "Config with params %{params} not found"
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:95
+#, elixir-format
+msgid "Could not delete"
+msgstr "Nie udało się usunąć"
+
+#: lib/pleroma/web/common_api/common_api.ex:141
+#, elixir-format
+msgid "Could not favorite"
+msgstr "Nie udało się dodać do ulubionych"
+
+#: lib/pleroma/web/common_api/common_api.ex:370
+#, elixir-format
+msgid "Could not pin"
+msgstr "Nie udało się przypiąć"
+
+#: lib/pleroma/web/common_api/common_api.ex:112
+#, elixir-format
+msgid "Could not repeat"
+msgstr "Nie udało się powtórzyć"
+
+#: lib/pleroma/web/common_api/common_api.ex:188
+#, elixir-format
+msgid "Could not unfavorite"
+msgstr "Nie udało się usunąć z ulubionych"
+
+#: lib/pleroma/web/common_api/common_api.ex:380
+#, elixir-format
+msgid "Could not unpin"
+msgstr "Nie udało się odpiąć"
+
+#: lib/pleroma/web/common_api/common_api.ex:126
+#, elixir-format
+msgid "Could not unrepeat"
+msgstr "Nie udało się cofnąć powtórzenia"
+
+#: lib/pleroma/web/common_api/common_api.ex:428
+#: lib/pleroma/web/common_api/common_api.ex:437
+#, elixir-format
+msgid "Could not update state"
+msgstr ""
+
+#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:202
+#, elixir-format
+msgid "Error."
+msgstr ""
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:106
+#, elixir-format
+msgid "Invalid CAPTCHA"
+msgstr ""
+
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:117
+#: lib/pleroma/web/oauth/oauth_controller.ex:569
+#, elixir-format
+msgid "Invalid credentials"
+msgstr ""
+
+#: lib/pleroma/plugs/ensure_authenticated_plug.ex:38
+#, elixir-format
+msgid "Invalid credentials."
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:265
+#, elixir-format
+msgid "Invalid indices"
+msgstr ""
+
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:1147
+#, elixir-format
+msgid "Invalid parameters"
+msgstr ""
+
+#: lib/pleroma/web/common_api/utils.ex:411
+#, elixir-format
+msgid "Invalid password."
+msgstr "Nieprawidłowe hasło."
+
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:187
+#, elixir-format
+msgid "Invalid request"
+msgstr "Nieprawidłowe żądanie"
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:109
+#, elixir-format
+msgid "Kocaptcha service unavailable"
+msgstr "Usługa Kocaptcha niedostępna"
+
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:113
+#, elixir-format
+msgid "Missing parameters"
+msgstr "Brakujące parametry"
+
+#: lib/pleroma/web/common_api/utils.ex:540
+#, elixir-format
+msgid "No such conversation"
+msgstr "Nie ma takiej rozmowy"
+
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:439
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:465 lib/pleroma/web/admin_api/admin_api_controller.ex:507
+#, elixir-format
+msgid "No such permission_group"
+msgstr "Nie ma takiej grupy uprawnień"
+
+#: lib/pleroma/plugs/uploaded_media.ex:74
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:485 lib/pleroma/web/admin_api/admin_api_controller.ex:1135
+#: lib/pleroma/web/feed/user_controller.ex:73 lib/pleroma/web/ostatus/ostatus_controller.ex:143
+#, elixir-format
+msgid "Not found"
+msgstr "Nie znaleziono"
+
+#: lib/pleroma/web/common_api/common_api.ex:241
+#, elixir-format
+msgid "Poll's author can't vote"
+msgstr "Autor ankiety nie może głosować"
+
+#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
+#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49
+#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:50 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:290
+#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71
+#, elixir-format
+msgid "Record not found"
+msgstr "Nie znaleziono rekordu"
+
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:1153
+#: lib/pleroma/web/feed/user_controller.ex:79 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:32
+#: lib/pleroma/web/ostatus/ostatus_controller.ex:149
+#, elixir-format
+msgid "Something went wrong"
+msgstr "Coś się zepsuło"
+
+#: lib/pleroma/web/common_api/activity_draft.ex:107
+#, elixir-format
+msgid "The message visibility must be direct"
+msgstr ""
+
+#: lib/pleroma/web/common_api/utils.ex:566
+#, elixir-format
+msgid "The status is over the character limit"
+msgstr "Ten status przekracza limit znaków"
+
+#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31
+#, elixir-format
+msgid "This resource requires authentication."
+msgstr ""
+
+#: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206
+#, elixir-format
+msgid "Throttled"
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:266
+#, elixir-format
+msgid "Too many choices"
+msgstr ""
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:442
+#, elixir-format
+msgid "Unhandled activity type"
+msgstr "Nieobsługiwany typ aktywności"
+
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:536
+#, elixir-format
+msgid "You can't revoke your own admin status."
+msgstr "Nie możesz odebrać samemu sobie statusu administratora."
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:218
+#: lib/pleroma/web/oauth/oauth_controller.ex:309
+#, elixir-format
+msgid "Your account is currently disabled"
+msgstr "Twoje konto jest obecnie nieaktywne"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:180
+#: lib/pleroma/web/oauth/oauth_controller.ex:332
+#, elixir-format
+msgid "Your login is missing a confirmed e-mail address"
+msgstr ""
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:389
+#, elixir-format
+msgid "can't read inbox of %{nickname} as %{as_nickname}"
+msgstr ""
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:472
+#, elixir-format
+msgid "can't update outbox of %{nickname} as %{as_nickname}"
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:388
+#, elixir-format
+msgid "conversation is already muted"
+msgstr "rozmowa jest już wyciszona"
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:316
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491
+#, elixir-format
+msgid "error"
+msgstr "błąd"
+
+#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:29
+#, elixir-format
+msgid "mascots can only be images"
+msgstr "maskotki muszą być obrazkami"
+
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:60
+#, elixir-format
+msgid "not found"
+msgstr "nie znaleziono"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:395
+#, elixir-format
+msgid "Bad OAuth request."
+msgstr "Niepoprawne żądanie OAuth."
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:115
+#, elixir-format
+msgid "CAPTCHA already used"
+msgstr "Zużyta CAPTCHA"
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:112
+#, elixir-format
+msgid "CAPTCHA expired"
+msgstr "CAPTCHA wygasła"
+
+#: lib/pleroma/plugs/uploaded_media.ex:55
+#, elixir-format
+msgid "Failed"
+msgstr "Nie udało się"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:411
+#, elixir-format
+msgid "Failed to authenticate: %{message}."
+msgstr ""
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:442
+#, elixir-format
+msgid "Failed to set up user account."
+msgstr ""
+
+#: lib/pleroma/plugs/oauth_scopes_plug.ex:38
+#, elixir-format
+msgid "Insufficient permissions: %{permissions}."
+msgstr "Niewystarczające uprawnienia: %{permissions}."
+
+#: lib/pleroma/plugs/uploaded_media.ex:94
+#, elixir-format
+msgid "Internal Error"
+msgstr "Błąd wewnętrzny"
+
+#: lib/pleroma/web/oauth/fallback_controller.ex:22
+#: lib/pleroma/web/oauth/fallback_controller.ex:29
+#, elixir-format
+msgid "Invalid Username/Password"
+msgstr "Nieprawidłowa nazwa użytkownika lub hasło"
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:118
+#, elixir-format
+msgid "Invalid answer data"
+msgstr ""
+
+#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:128
+#, elixir-format
+msgid "Nodeinfo schema version not handled"
+msgstr "Nieobsługiwana wersja schematu Nodeinfo"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:169
+#, elixir-format
+msgid "This action is outside the authorized scopes"
+msgstr ""
+
+#: lib/pleroma/web/oauth/fallback_controller.ex:14
+#, elixir-format
+msgid "Unknown error, please check the details and try again."
+msgstr "Nieznany błąd, sprawdź szczegóły i spróbuj ponownie."
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:116
+#: lib/pleroma/web/oauth/oauth_controller.ex:155
+#, elixir-format
+msgid "Unlisted redirect_uri."
+msgstr ""
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:391
+#, elixir-format
+msgid "Unsupported OAuth provider: %{provider}."
+msgstr "Nieobsługiwany dostawca OAuth: %{provider}."
+
+#: lib/pleroma/uploaders/uploader.ex:72
+#, elixir-format
+msgid "Uploader callback timeout"
+msgstr ""
+
+#: lib/pleroma/web/uploader_controller.ex:23
+#, elixir-format
+msgid "bad request"
+msgstr "nieprawidłowe żądanie"
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:103
+#, elixir-format
+msgid "CAPTCHA Error"
+msgstr "Błąd CAPTCHA"
+
+#: lib/pleroma/web/common_api/common_api.ex:200
+#, elixir-format
+msgid "Could not add reaction emoji"
+msgstr ""
+
+#: lib/pleroma/web/common_api/common_api.ex:211
+#, elixir-format
+msgid "Could not remove reaction emoji"
+msgstr ""
+
+#: lib/pleroma/web/twitter_api/twitter_api.ex:129
+#, elixir-format
+msgid "Invalid CAPTCHA (Missing parameter: %{name})"
+msgstr "Nieprawidłowa CAPTCHA (Brakujący parametr: %{name})"
+
+#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92
+#, elixir-format
+msgid "List not found"
+msgstr "Nie znaleziono listy"
+
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:124
+#, elixir-format
+msgid "Missing parameter: %{name}"
+msgstr "Brakujący parametr: %{name}"
+
+#: lib/pleroma/web/oauth/oauth_controller.ex:207
+#: lib/pleroma/web/oauth/oauth_controller.ex:322
+#, elixir-format
+msgid "Password reset is required"
+msgstr "Wymagany reset hasła"
+
+#: lib/pleroma/tests/auth_test_controller.ex:9
+#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/admin_api_controller.ex:6
+#: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/fallback_redirect_controller.ex:6
+#: lib/pleroma/web/feed/tag_controller.ex:6 lib/pleroma/web/feed/user_controller.ex:6
+#: lib/pleroma/web/mailer/subscription_controller.ex:2 lib/pleroma/web/masto_fe_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/app_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/report_controller.ex:8 lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6
+#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 lib/pleroma/web/media_proxy/media_proxy_controller.ex:6
+#: lib/pleroma/web/mongooseim/mongoose_im_controller.ex:6 lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6
+#: lib/pleroma/web/oauth/fallback_controller.ex:6 lib/pleroma/web/oauth/mfa_controller.ex:10
+#: lib/pleroma/web/oauth/oauth_controller.ex:6 lib/pleroma/web/ostatus/ostatus_controller.ex:6
+#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:2
+#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex:6
+#: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6
+#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/static_fe/static_fe_controller.ex:6
+#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6
+#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 lib/pleroma/web/twitter_api/twitter_api_controller.ex:6
+#: lib/pleroma/web/uploader_controller.ex:6 lib/pleroma/web/web_finger/web_finger_controller.ex:6
+#, elixir-format
+msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
+msgstr ""
+
+#: lib/pleroma/plugs/ensure_authenticated_plug.ex:28
+#, elixir-format
+msgid "Two-factor authentication enabled, you must use a access token."
+msgstr "Uwierzytelnienie dwuskładnikowe jest włączone, musisz użyć tokenu."
+
+#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:210
+#, elixir-format
+msgid "Unexpected error occurred while adding file to pack."
+msgstr "Nieoczekiwany błąd podczas dodawania pliku do paczki."
+
+#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:138
+#, elixir-format
+msgid "Unexpected error occurred while creating pack."
+msgstr "Nieoczekiwany błąd podczas tworzenia paczki."
+
+#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:278
+#, elixir-format
+msgid "Unexpected error occurred while removing file from pack."
+msgstr "Nieoczekiwany błąd podczas usuwania pliku z paczki."
+
+#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:250
+#, elixir-format
+msgid "Unexpected error occurred while updating file in pack."
+msgstr "Nieoczekiwany błąd podczas zmieniania pliku w paczce."
+
+#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:179
+#, elixir-format
+msgid "Unexpected error occurred while updating pack metadata."
+msgstr "Nieoczekiwany błąd podczas zmieniania metadanych paczki."
+
+#: lib/pleroma/plugs/user_is_admin_plug.ex:40
+#, elixir-format
+msgid "User is not an admin or OAuth admin scope is not granted."
+msgstr ""
+
+#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61
+#, elixir-format
+msgid "Web push subscription is disabled on this Pleroma instance"
+msgstr "Powiadomienia web push są wyłączone na tej instancji Pleromy"
+
+#: lib/pleroma/web/admin_api/admin_api_controller.ex:502
+#, elixir-format
+msgid "You can't revoke your own admin/moderator status."
+msgstr "Nie możesz odebrać samemu sobie statusu administratora/moderatora."
+
+#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:105
+#, elixir-format
+msgid "authorization required for timeline view"
+msgstr "logowanie wymagane do przeglądania osi czasu"
diff --git a/priv/static/static/config.json b/priv/static/static/config.json
index c82678699..727dde73b 100644
--- a/priv/static/static/config.json
+++ b/priv/static/static/config.json
@@ -1,23 +1,28 @@
{
- "theme": "pleroma-dark",
+ "alwaysShowSubjectInput": true,
"background": "/static/aurora_borealis.jpg",
- "logo": "/static/logo.png",
- "logoMask": true,
- "logoMargin": ".1em",
- "redirectRootNoLogin": "/main/all",
- "redirectRootLogin": "/main/friends",
- "showInstanceSpecificPanel": false,
"collapseMessageWithSubject": false,
- "scopeCopy": true,
- "subjectLineBehavior": "email",
- "postContentType": "text/plain",
- "alwaysShowSubjectInput": true,
+ "disableChat": false,
+ "greentext": false,
+ "hideFilteredStatuses": false,
+ "hideMutedPosts": false,
"hidePostStats": false,
+ "hideSitename": false,
"hideUserStats": false,
"loginMethod": "password",
- "webPushNotifications": false,
+ "logo": "/static/logo.png",
+ "logoMargin": ".1em",
+ "logoMask": true,
+ "minimalScopesMode": false,
"noAttachmentLinks": false,
"nsfwCensorImage": "",
+ "postContentType": "text/plain",
+ "redirectRootLogin": "/main/friends",
+ "redirectRootNoLogin": "/main/all",
+ "scopeCopy": true,
"showFeaturesPanel": true,
- "minimalScopesMode": false
+ "showInstanceSpecificPanel": false,
+ "subjectLineBehavior": "email",
+ "theme": "pleroma-dark",
+ "webPushNotifications": false
}
diff --git a/test/config/config_db_test.exs b/test/config/config_db_test.exs
index a8e947365..336de7359 100644
--- a/test/config/config_db_test.exs
+++ b/test/config/config_db_test.exs
@@ -476,6 +476,14 @@ defmodule Pleroma.ConfigDBTest do
assert ConfigDB.from_binary(binary) == [key: "value"]
end
+ test "keyword with partial_chain key" do
+ binary =
+ ConfigDB.transform([%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}])
+
+ assert binary == :erlang.term_to_binary(partial_chain: &:hackney_connect.partial_chain/1)
+ assert ConfigDB.from_binary(binary) == [partial_chain: &:hackney_connect.partial_chain/1]
+ end
+
test "keyword" do
binary =
ConfigDB.transform([
diff --git a/test/plugs/authentication_plug_test.exs b/test/plugs/authentication_plug_test.exs
index 31e20d726..c8ede71c0 100644
--- a/test/plugs/authentication_plug_test.exs
+++ b/test/plugs/authentication_plug_test.exs
@@ -79,6 +79,13 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
assert AuthenticationPlug.checkpw("password", hash)
end
+ test "check bcrypt hash" do
+ hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"
+
+ assert AuthenticationPlug.checkpw("password", hash)
+ refute AuthenticationPlug.checkpw("password1", hash)
+ end
+
test "it returns false when hash invalid" do
hash =
"psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 56fde97e7..77bd07edf 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -951,7 +951,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "works with base64 encoded images" do
file = %{
- "img" => data_uri()
+ img: data_uri()
}
{:ok, %Object{}} = ActivityPub.upload(file)
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index e4b0dd627..370d876d0 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -2509,6 +2509,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
+ %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
@@ -2532,6 +2533,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
+ %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
@@ -2544,6 +2546,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
":seconds_valid",
":path",
":key1",
+ ":partial_chain",
":regex1",
":regex2",
":regex3",
@@ -2940,6 +2943,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value
assert ":proxy_url" in db
end
+
+ test "doesn't set keys not in the whitelist", %{conn: conn} do
+ clear_config(:database_config_whitelist, [
+ {:pleroma, :key1},
+ {:pleroma, :key2},
+ {:pleroma, Pleroma.Captcha.NotReal},
+ {:not_real}
+ ])
+
+ post(conn, "/api/pleroma/admin/config", %{
+ configs: [
+ %{group: ":pleroma", key: ":key1", value: "value1"},
+ %{group: ":pleroma", key: ":key2", value: "value2"},
+ %{group: ":pleroma", key: ":key3", value: "value3"},
+ %{group: ":pleroma", key: "Pleroma.Web.Endpoint.NotReal", value: "value4"},
+ %{group: ":pleroma", key: "Pleroma.Captcha.NotReal", value: "value5"},
+ %{group: ":not_real", key: ":anything", value: "value6"}
+ ]
+ })
+
+ assert Application.get_env(:pleroma, :key1) == "value1"
+ assert Application.get_env(:pleroma, :key2) == "value2"
+ assert Application.get_env(:pleroma, :key3) == nil
+ assert Application.get_env(:pleroma, Pleroma.Web.Endpoint.NotReal) == nil
+ assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5"
+ assert Application.get_env(:not_real, :anything) == "value6"
+ end
end
describe "GET /api/pleroma/admin/restart" do
@@ -3571,19 +3601,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
- test "GET /api/pleroma/admin/config/descriptions", %{conn: conn} do
- admin = insert(:user, is_admin: true)
+ describe "GET /api/pleroma/admin/config/descriptions" do
+ test "structure", %{conn: conn} do
+ admin = insert(:user, is_admin: true)
- conn =
- assign(conn, :user, admin)
- |> get("/api/pleroma/admin/config/descriptions")
+ conn =
+ assign(conn, :user, admin)
+ |> get("/api/pleroma/admin/config/descriptions")
+
+ assert [child | _others] = json_response(conn, 200)
+
+ assert child["children"]
+ assert child["key"]
+ assert String.starts_with?(child["group"], ":")
+ assert child["description"]
+ end
+
+ test "filters by database configuration whitelist", %{conn: conn} do
+ clear_config(:database_config_whitelist, [
+ {:pleroma, :instance},
+ {:pleroma, :activitypub},
+ {:pleroma, Pleroma.Upload},
+ {:esshd}
+ ])
+
+ admin = insert(:user, is_admin: true)
+
+ conn =
+ assign(conn, :user, admin)
+ |> get("/api/pleroma/admin/config/descriptions")
- assert [child | _others] = json_response(conn, 200)
+ children = json_response(conn, 200)
- assert child["children"]
- assert child["key"]
- assert String.starts_with?(child["group"], ":")
- assert child["description"]
+ assert length(children) == 4
+
+ assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3
+
+ instance = Enum.find(children, fn c -> c["key"] == ":instance" end)
+ assert instance["children"]
+
+ activitypub = Enum.find(children, fn c -> c["key"] == ":activitypub" end)
+ assert activitypub["children"]
+
+ web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end)
+ assert web_endpoint["children"]
+
+ esshd = Enum.find(children, fn c -> c["group"] == ":esshd" end)
+ assert esshd["children"]
+ end
end
describe "/api/pleroma/admin/stats" do
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 26e41c313..fd8299013 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -23,6 +23,18 @@ defmodule Pleroma.Web.CommonAPITest do
setup do: clear_config([:instance, :limit])
setup do: clear_config([:instance, :max_pinned_statuses])
+ describe "unblocking" do
+ test "it works even without an existing block activity" do
+ blocked = insert(:user)
+ blocker = insert(:user)
+ User.block(blocker, blocked)
+
+ assert User.blocks?(blocker, blocked)
+ assert {:ok, :no_activity} == CommonAPI.unblock(blocker, blocked)
+ refute User.blocks?(blocker, blocked)
+ end
+ end
+
describe "deletion" do
test "it works with pruned objects" do
user = insert(:user)
diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/web/mastodon_api/controllers/media_controller_test.exs
index 6ac4cf63b..7ba1727f2 100644
--- a/test/web/mastodon_api/controllers/media_controller_test.exs
+++ b/test/web/mastodon_api/controllers/media_controller_test.exs
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
setup do: oauth_access(["write:media"])
- describe "media upload" do
+ describe "Upload media" do
setup do
image = %Plug.Upload{
content_type: "image/jpg",
@@ -25,13 +25,14 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
setup do: clear_config([:media_proxy])
setup do: clear_config([Pleroma.Upload])
- test "returns uploaded image", %{conn: conn, image: image} do
+ test "/api/v1/media", %{conn: conn, image: image} do
desc = "Description of the image"
media =
conn
+ |> put_req_header("content-type", "multipart/form-data")
|> post("/api/v1/media", %{"file" => image, "description" => desc})
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
assert media["type"] == "image"
assert media["description"] == desc
@@ -40,9 +41,32 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
object = Object.get_by_id(media["id"])
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
end
+
+ test "/api/v2/media", %{conn: conn, image: image} do
+ desc = "Description of the image"
+
+ response =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> post("/api/v2/media", %{"file" => image, "description" => desc})
+ |> json_response_and_validate_schema(202)
+
+ assert media_id = response["id"]
+
+ media =
+ conn
+ |> get("/api/v1/media/#{media_id}")
+ |> json_response_and_validate_schema(200)
+
+ assert media["type"] == "image"
+ assert media["description"] == desc
+ assert media["id"]
+ object = Object.get_by_id(media["id"])
+ assert object.data["actor"] == User.ap_id(conn.assigns[:user])
+ end
end
- describe "PUT /api/v1/media/:id" do
+ describe "Update media description" do
setup %{user: actor} do
file = %Plug.Upload{
content_type: "image/jpg",
@@ -60,23 +84,45 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
[object: object]
end
- test "updates name of media", %{conn: conn, object: object} do
+ test "/api/v1/media/:id good request", %{conn: conn, object: object} do
media =
conn
+ |> put_req_header("content-type", "multipart/form-data")
|> put("/api/v1/media/#{object.id}", %{"description" => "test-media"})
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
assert media["description"] == "test-media"
assert refresh_record(object).data["name"] == "test-media"
end
+ end
- test "returns error when request is bad", %{conn: conn, object: object} do
+ describe "Get media by id" do
+ setup %{user: actor} do
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, %Object{} = object} =
+ ActivityPub.upload(
+ file,
+ actor: User.ap_id(actor),
+ description: "test-media"
+ )
+
+ [object: object]
+ end
+
+ test "/api/v1/media/:id", %{conn: conn, object: object} do
media =
conn
- |> put("/api/v1/media/#{object.id}", %{})
- |> json_response(400)
+ |> get("/api/v1/media/#{object.id}")
+ |> json_response_and_validate_schema(:ok)
- assert media == %{"error" => "bad_request"}
+ assert media["description"] == "test-media"
+ assert media["type"] == "image"
+ assert media["id"]
end
end
end
diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs
index d9356a844..562fc4d8e 100644
--- a/test/web/mastodon_api/controllers/notification_controller_test.exs
+++ b/test/web/mastodon_api/controllers/notification_controller_test.exs
@@ -12,9 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
import Pleroma.Factory
- test "does NOT render account/pleroma/relationship if this is disabled by default" do
- clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
-
+ test "does NOT render account/pleroma/relationship by default" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs
index a4403132c..bdee88fd3 100644
--- a/test/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/web/mastodon_api/controllers/status_controller_test.exs
@@ -1176,7 +1176,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "bookmarks" do
- bookmarks_uri = "/api/v1/bookmarks?with_relationships=true"
+ bookmarks_uri = "/api/v1/bookmarks"
%{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"])
author = insert(:user)
diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs
index f8b9289f3..2375ac8e8 100644
--- a/test/web/mastodon_api/controllers/timeline_controller_test.exs
+++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs
@@ -20,12 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "home" do
setup do: oauth_access(["read:statuses"])
- test "does NOT render account/pleroma/relationship if this is disabled by default", %{
+ test "does NOT embed account/pleroma/relationship in statuses", %{
user: user,
conn: conn
} do
- clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
-
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
@@ -41,72 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end)
end
- test "the home timeline", %{user: user, conn: conn} do
- uri = "/api/v1/timelines/home?with_relationships=1"
-
- following = insert(:user, nickname: "followed")
- third_user = insert(:user, nickname: "repeated")
-
- {:ok, _activity} = CommonAPI.post(following, %{status: "post"})
- {:ok, activity} = CommonAPI.post(third_user, %{status: "repeated post"})
- {:ok, _, _} = CommonAPI.repeat(activity.id, following)
-
- ret_conn = get(conn, uri)
-
- assert Enum.empty?(json_response_and_validate_schema(ret_conn, :ok))
-
- {:ok, _user} = User.follow(user, following)
-
- ret_conn = get(conn, uri)
-
- assert [
- %{
- "reblog" => %{
- "content" => "repeated post",
- "account" => %{
- "pleroma" => %{
- "relationship" => %{"following" => false, "followed_by" => false}
- }
- }
- },
- "account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
- },
- %{
- "content" => "post",
- "account" => %{
- "acct" => "followed",
- "pleroma" => %{"relationship" => %{"following" => true}}
- }
- }
- ] = json_response_and_validate_schema(ret_conn, :ok)
-
- {:ok, _user} = User.follow(third_user, user)
-
- ret_conn = get(conn, uri)
-
- assert [
- %{
- "reblog" => %{
- "content" => "repeated post",
- "account" => %{
- "acct" => "repeated",
- "pleroma" => %{
- "relationship" => %{"following" => false, "followed_by" => true}
- }
- }
- },
- "account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
- },
- %{
- "content" => "post",
- "account" => %{
- "acct" => "followed",
- "pleroma" => %{"relationship" => %{"following" => true}}
- }
- }
- ] = json_response_and_validate_schema(ret_conn, :ok)
- end
-
test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
{:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs
index 69ddbb5d4..487ec26c2 100644
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ b/test/web/mastodon_api/views/account_view_test.exs
@@ -302,82 +302,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end
end
- test "represent an embedded relationship" do
- user =
- insert(:user, %{
- follower_count: 0,
- note_count: 5,
- actor_type: "Service",
- nickname: "shp@shitposter.club",
- inserted_at: ~N[2017-08-15 15:47:06.597036]
- })
-
- other_user = insert(:user)
- {:ok, other_user} = User.follow(other_user, user)
- {:ok, _user_relationship} = User.block(other_user, user)
- {:ok, _} = User.follow(insert(:user), user)
-
- expected = %{
- id: to_string(user.id),
- username: "shp",
- acct: user.nickname,
- display_name: user.name,
- locked: false,
- created_at: "2017-08-15T15:47:06.000Z",
- followers_count: 1,
- following_count: 0,
- statuses_count: 5,
- note: user.bio,
- url: user.ap_id,
- avatar: "http://localhost:4001/images/avi.png",
- avatar_static: "http://localhost:4001/images/avi.png",
- header: "http://localhost:4001/images/banner.png",
- header_static: "http://localhost:4001/images/banner.png",
- emojis: [],
- fields: [],
- bot: true,
- source: %{
- note: user.bio,
- sensitive: false,
- pleroma: %{
- actor_type: "Service",
- discoverable: false
- },
- fields: []
- },
- pleroma: %{
- background_image: nil,
- confirmation_pending: false,
- tags: [],
- is_admin: false,
- is_moderator: false,
- hide_favorites: true,
- hide_followers: false,
- hide_follows: false,
- hide_followers_count: false,
- hide_follows_count: false,
- relationship: %{
- id: to_string(user.id),
- following: false,
- followed_by: false,
- blocking: true,
- blocked_by: false,
- subscribing: false,
- muting: false,
- muting_notifications: false,
- requested: false,
- domain_blocking: false,
- showing_reblogs: true,
- endorsed: false
- },
- skip_thread_containment: false
- }
- }
-
- assert expected ==
- AccountView.render("show.json", %{user: refresh_record(user), for: other_user})
- end
-
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
user = insert(:user, pleroma_settings_store: %{fe: "test"})
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs
index 04a774d17..9839e48fc 100644
--- a/test/web/mastodon_api/views/notification_view_test.exs
+++ b/test/web/mastodon_api/views/notification_view_test.exs
@@ -42,7 +42,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
id: to_string(notification.id),
pleroma: %{is_seen: false},
type: "mention",
- account: AccountView.render("show.json", %{user: user, for: mentioned_user}),
+ account:
+ AccountView.render("show.json", %{
+ user: user,
+ for: mentioned_user
+ }),
status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
index ffad65b01..5d7adbe29 100644
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ b/test/web/mastodon_api/views/status_view_test.exs
@@ -576,7 +576,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
end
end
- test "embeds a relationship in the account" do
+ test "does not embed a relationship in the account" do
user = insert(:user)
other_user = insert(:user)
@@ -587,13 +587,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
result = StatusView.render("show.json", %{activity: activity, for: other_user})
- assert result[:account][:pleroma][:relationship] ==
- AccountView.render("relationship.json", %{user: other_user, target: user})
-
+ assert result[:account][:pleroma][:relationship] == %{}
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end
- test "embeds a relationship in the account in reposts" do
+ test "does not embed a relationship in the account in reposts" do
user = insert(:user)
other_user = insert(:user)
@@ -606,12 +604,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
result = StatusView.render("show.json", %{activity: activity, for: user})
- assert result[:account][:pleroma][:relationship] ==
- AccountView.render("relationship.json", %{user: user, target: other_user})
-
- assert result[:reblog][:account][:pleroma][:relationship] ==
- AccountView.render("relationship.json", %{user: user, target: user})
-
+ assert result[:account][:pleroma][:relationship] == %{}
+ assert result[:reblog][:account][:pleroma][:relationship] == %{}
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end
diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs
index 34fc4aa23..103997c31 100644
--- a/test/web/pleroma_api/controllers/account_controller_test.exs
+++ b/test/web/pleroma_api/controllers/account_controller_test.exs
@@ -31,8 +31,28 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
test "resend account confirmation email", %{conn: conn, user: user} do
conn
+ |> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}")
- |> json_response(:no_content)
+ |> json_response_and_validate_schema(:no_content)
+
+ ObanHelpers.perform_all()
+
+ email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
+ notify_email = Config.get([:instance, :notify_email])
+ instance_name = Config.get([:instance, :name])
+
+ assert_email_sent(
+ from: {instance_name, notify_email},
+ to: {user.name, user.email},
+ html_body: email.html_body
+ )
+ end
+
+ test "resend account confirmation email (with nickname)", %{conn: conn, user: user} do
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/accounts/confirmation_resend?nickname=#{user.nickname}")
+ |> json_response_and_validate_schema(:no_content)
ObanHelpers.perform_all()
@@ -54,7 +74,10 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
test "user avatar can be set", %{user: user, conn: conn} do
avatar_image = File.read!("test/fixtures/avatar_data_uri")
- conn = patch(conn, "/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image})
user = refresh_record(user)
@@ -70,17 +93,20 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
]
} = user.avatar
- assert %{"url" => _} = json_response(conn, 200)
+ assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
end
test "user avatar can be reset", %{user: user, conn: conn} do
- conn = patch(conn, "/api/v1/pleroma/accounts/update_avatar", %{img: ""})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: ""})
user = User.get_cached_by_id(user.id)
assert user.avatar == nil
- assert %{"url" => nil} = json_response(conn, 200)
+ assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
end
end
@@ -88,21 +114,27 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
setup do: oauth_access(["write:accounts"])
test "can set profile banner", %{user: user, conn: conn} do
- conn = patch(conn, "/api/v1/pleroma/accounts/update_banner", %{"banner" => @image})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => @image})
user = refresh_record(user)
assert user.banner["type"] == "Image"
- assert %{"url" => _} = json_response(conn, 200)
+ assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
end
test "can reset profile banner", %{user: user, conn: conn} do
- conn = patch(conn, "/api/v1/pleroma/accounts/update_banner", %{"banner" => ""})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => ""})
user = refresh_record(user)
assert user.banner == %{}
- assert %{"url" => nil} = json_response(conn, 200)
+ assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
end
end
@@ -110,19 +142,26 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
setup do: oauth_access(["write:accounts"])
test "background image can be set", %{user: user, conn: conn} do
- conn = patch(conn, "/api/v1/pleroma/accounts/update_background", %{"img" => @image})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => @image})
user = refresh_record(user)
assert user.background["type"] == "Image"
- assert %{"url" => _} = json_response(conn, 200)
+ # assert %{"url" => _} = json_response(conn, 200)
+ assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
end
test "background image can be reset", %{user: user, conn: conn} do
- conn = patch(conn, "/api/v1/pleroma/accounts/update_background", %{"img" => ""})
+ conn =
+ conn
+ |> put_req_header("content-type", "multipart/form-data")
+ |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => ""})
user = refresh_record(user)
assert user.background == %{}
- assert %{"url" => nil} = json_response(conn, 200)
+ assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
end
end
@@ -143,7 +182,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
conn
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
[like] = response
@@ -160,7 +199,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
build_conn()
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(200)
+ |> json_response_and_validate_schema(200)
assert length(response) == 1
end
@@ -183,7 +222,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
|> assign(:user, u)
|> assign(:token, insert(:oauth_token, user: u, scopes: ["read:favourites"]))
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
assert length(response) == 1
end
@@ -191,7 +230,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
build_conn()
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(200)
+ |> json_response_and_validate_schema(200)
assert length(response) == 0
end
@@ -213,7 +252,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
conn
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
assert Enum.empty?(response)
end
@@ -233,11 +272,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{
- since_id: third_activity.id,
- max_id: seventh_activity.id
- })
- |> json_response(:ok)
+ |> get(
+ "/api/v1/pleroma/accounts/#{user.id}/favourites?since_id=#{third_activity.id}&max_id=#{
+ seventh_activity.id
+ }"
+ )
+ |> json_response_and_validate_schema(:ok)
assert length(response) == 3
refute third_activity in response
@@ -256,8 +296,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{limit: "3"})
- |> json_response(:ok)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites?limit=3")
+ |> json_response_and_validate_schema(:ok)
assert length(response) == 3
end
@@ -269,7 +309,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
response =
conn
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
+ |> json_response_and_validate_schema(:ok)
assert Enum.empty?(response)
end
@@ -277,7 +317,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
test "returns 404 error when specified user is not exist", %{conn: conn} do
conn = get(conn, "/api/v1/pleroma/accounts/test/favourites")
- assert json_response(conn, 404) == %{"error" => "Record not found"}
+ assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
end
test "returns 403 error when user has hidden own favorites", %{conn: conn} do
@@ -287,7 +327,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
- assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
+ assert json_response_and_validate_schema(conn, 403) == %{"error" => "Can't get favorites"}
end
test "hides favorites for new users by default", %{conn: conn} do
@@ -298,7 +338,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
assert user.hide_favorites
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites")
- assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
+ assert json_response_and_validate_schema(conn, 403) == %{"error" => "Can't get favorites"}
end
end
@@ -312,11 +352,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
|> assign(:user, user)
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
- assert %{"id" => _id, "subscribing" => true} = json_response(ret_conn, 200)
+ assert %{"id" => _id, "subscribing" => true} =
+ json_response_and_validate_schema(ret_conn, 200)
conn = post(conn, "/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
- assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200)
+ assert %{"id" => _id, "subscribing" => false} = json_response_and_validate_schema(conn, 200)
end
end
@@ -326,7 +367,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
conn = post(conn, "/api/v1/pleroma/accounts/target_id/subscribe")
- assert %{"error" => "Record not found"} = json_response(conn, 404)
+ assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404)
end
end
@@ -336,7 +377,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
conn = post(conn, "/api/v1/pleroma/accounts/target_id/unsubscribe")
- assert %{"error" => "Record not found"} = json_response(conn, 404)
+ assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404)
end
end
end