@@ -28,6 +28,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:api/v1/notifications:include_types_filter` to the `features` list. | ||||
- NodeInfo: `pleroma_emoji_reactions` 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: `: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. | - 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. | - Mix task to create trusted OAuth App. | ||||
- Notifications: Added `follow_request` notification type. | - Notifications: Added `follow_request` notification type. | ||||
@@ -387,56 +387,47 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||||
favourites = ActivityPub.fetch_favourites(user) | favourites = ActivityPub.fetch_favourites(user) | ||||
output_relationships = | |||||
!!Pleroma.Config.get([:extensions, :output_relationships_in_statuses_by_default]) | |||||
Benchee.run( | Benchee.run( | ||||
%{ | %{ | ||||
"Rendering home timeline" => fn -> | "Rendering home timeline" => fn -> | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: home_activities, | activities: home_activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: !output_relationships | |||||
as: :activity | |||||
}) | }) | ||||
end, | end, | ||||
"Rendering direct timeline" => fn -> | "Rendering direct timeline" => fn -> | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: direct_activities, | activities: direct_activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: !output_relationships | |||||
as: :activity | |||||
}) | }) | ||||
end, | end, | ||||
"Rendering public timeline" => fn -> | "Rendering public timeline" => fn -> | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: public_activities, | activities: public_activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: !output_relationships | |||||
as: :activity | |||||
}) | }) | ||||
end, | end, | ||||
"Rendering tag timeline" => fn -> | "Rendering tag timeline" => fn -> | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: tag_activities, | activities: tag_activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: !output_relationships | |||||
as: :activity | |||||
}) | }) | ||||
end, | end, | ||||
"Rendering notifications" => fn -> | "Rendering notifications" => fn -> | ||||
Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{ | Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{ | ||||
notifications: notifications, | notifications: notifications, | ||||
for: user, | |||||
skip_relationships: !output_relationships | |||||
for: user | |||||
}) | }) | ||||
end, | end, | ||||
"Rendering favourites timeline" => fn -> | "Rendering favourites timeline" => fn -> | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: favourites, | activities: favourites, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: !output_relationships | |||||
as: :activity | |||||
}) | }) | ||||
end | end | ||||
}, | }, | ||||
@@ -251,8 +251,6 @@ config :pleroma, :instance, | |||||
] | ] | ||||
] | ] | ||||
config :pleroma, :extensions, output_relationships_in_statuses_by_default: true | |||||
config :pleroma, :feed, | config :pleroma, :feed, | ||||
post_title: %{ | post_title: %{ | ||||
max_length: 100, | max_length: 100, | ||||
@@ -680,15 +680,6 @@ config :pleroma, :config_description, [ | |||||
] | ] | ||||
}, | }, | ||||
%{ | %{ | ||||
key: :federation_publisher_modules, | |||||
type: {:list, :module}, | |||||
description: | |||||
"List of modules for federation publishing. Module names are shortened (removed leading `Pleroma.Web.` part), but on adding custom module you need to use full name.", | |||||
suggestions: [ | |||||
Pleroma.Web.ActivityPub.Publisher | |||||
] | |||||
}, | |||||
%{ | |||||
key: :allow_relay, | key: :allow_relay, | ||||
type: :boolean, | type: :boolean, | ||||
description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance" | description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance" | ||||
@@ -1105,38 +1096,40 @@ config :pleroma, :config_description, [ | |||||
description: "Settings for Pleroma FE", | description: "Settings for Pleroma FE", | ||||
suggestions: [ | 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, | collapseMessageWithSubject: false, | ||||
disableChat: false, | |||||
greentext: false, | |||||
hideFilteredStatuses: false, | |||||
hideMutedPosts: false, | |||||
hidePostStats: false, | hidePostStats: false, | ||||
hideSitename: false, | |||||
hideUserStats: 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, | scopeCopy: true, | ||||
showFeaturesPanel: true, | |||||
showInstanceSpecificPanel: false, | |||||
subjectLineBehavior: "email", | subjectLineBehavior: "email", | ||||
alwaysShowSubjectInput: true, | |||||
logoMask: false, | |||||
logoMargin: ".1em", | |||||
stickers: false, | |||||
enableEmojiPicker: false | |||||
theme: "pleroma-dark", | |||||
webPushNotifications: false | |||||
} | } | ||||
], | ], | ||||
children: [ | 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, | key: :background, | ||||
@@ -1146,46 +1139,35 @@ config :pleroma, :config_description, [ | |||||
suggestions: ["/images/city.jpg"] | 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: | 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, | 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, | 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, | 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, | type: :boolean, | ||||
description: | |||||
"When a message has a subject (aka Content Warning), collapse it by default" | |||||
description: "Hides muted statuses from timelines." | |||||
}, | }, | ||||
%{ | %{ | ||||
key: :hidePostStats, | key: :hidePostStats, | ||||
@@ -1194,6 +1176,12 @@ config :pleroma, :config_description, [ | |||||
description: "Hide notices statistics (repeats, favorites, ...)" | description: "Hide notices statistics (repeats, favorites, ...)" | ||||
}, | }, | ||||
%{ | %{ | ||||
key: :hideSitename, | |||||
label: "Hide Sitename", | |||||
type: :boolean, | |||||
description: "Hides instance name from PleromaFE banner." | |||||
}, | |||||
%{ | |||||
key: :hideUserStats, | key: :hideUserStats, | ||||
label: "Hide user stats", | label: "Hide user stats", | ||||
type: :boolean, | type: :boolean, | ||||
@@ -1201,26 +1189,19 @@ config :pleroma, :config_description, [ | |||||
"Hide profile statistics (posts, posts per day, followers, followings, ...)" | "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, | 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, | key: :logoMask, | ||||
@@ -1231,24 +1212,78 @@ config :pleroma, :config_description, [ | |||||
"If you want a colorful logo you must disable logoMask." | "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, | type: :string, | ||||
description: | 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: :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: :stickers, | |||||
key: :showFeaturesPanel, | |||||
label: "Show instance features panel", | |||||
type: :boolean, | 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, | 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"] | |||||
} | } | ||||
] | ] | ||||
}, | }, | ||||
@@ -1859,12 +1894,6 @@ config :pleroma, :config_description, [ | |||||
""", | """, | ||||
children: [ | children: [ | ||||
%{ | %{ | ||||
key: :repo, | |||||
type: :module, | |||||
description: "Application's Ecto repo", | |||||
suggestions: [Pleroma.Repo] | |||||
}, | |||||
%{ | |||||
key: :verbose, | key: :verbose, | ||||
type: {:dropdown, :atom}, | type: {:dropdown, :atom}, | ||||
description: "Logs verbose mode", | description: "Logs verbose mode", | ||||
@@ -2639,18 +2668,6 @@ config :pleroma, :config_description, [ | |||||
] | ] | ||||
}, | }, | ||||
%{ | %{ | ||||
group: :http_signatures, | |||||
type: :group, | |||||
description: "HTTP Signatures settings", | |||||
children: [ | |||||
%{ | |||||
key: :adapter, | |||||
type: :module, | |||||
suggestions: [Pleroma.Signature] | |||||
} | |||||
] | |||||
}, | |||||
%{ | |||||
group: :pleroma, | group: :pleroma, | ||||
key: :http, | key: :http, | ||||
type: :group, | type: :group, | ||||
@@ -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. | 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 | ### Multi-factor authentication - :two_factor_authentication | ||||
* `totp` - a list containing TOTP configuration | * `totp` - a list containing TOTP configuration | ||||
@@ -1,21 +1,45 @@ | |||||
#!/sbin/openrc-run | #!/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_user=pleroma:pleroma | ||||
command_background=1 | command_background=1 | ||||
export PORT=4000 | |||||
export MIX_ENV=prod | |||||
# Ask process to terminate within 30 seconds, otherwise kill it | # Ask process to terminate within 30 seconds, otherwise kill it | ||||
retry="SIGTERM/30/SIGKILL/5" | retry="SIGTERM/30/SIGKILL/5" | ||||
pidfile="/var/run/pleroma.pid" | 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() { | 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" | |||||
} | } |
@@ -67,8 +67,7 @@ defmodule Mix.Tasks.Pleroma.Benchmark do | |||||
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{ | Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{ | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: true | |||||
as: :activity | |||||
}) | }) | ||||
end | end | ||||
}, | }, | ||||
@@ -1,5 +1,6 @@ | |||||
defmodule Mix.Tasks.Pleroma.Digest do | defmodule Mix.Tasks.Pleroma.Digest do | ||||
use Mix.Task | use Mix.Task | ||||
import Mix.Pleroma | |||||
@shortdoc "Manages digest emails" | @shortdoc "Manages digest emails" | ||||
@moduledoc File.read!("docs/administration/CLI_tasks/digest.md") | @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 | with %Swoosh.Email{} = email <- Pleroma.Emails.UserEmail.digest_email(patched_user) do | ||||
{:ok, _} = Pleroma.Emails.Mailer.deliver(email) | {: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 | 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 | end | ||||
end | end |
@@ -4,6 +4,7 @@ | |||||
defmodule Pleroma.BBS.Authenticator do | defmodule Pleroma.BBS.Authenticator do | ||||
use Sshd.PasswordAuthenticator | use Sshd.PasswordAuthenticator | ||||
alias Pleroma.Plugs.AuthenticationPlug | |||||
alias Pleroma.User | alias Pleroma.User | ||||
def authenticate(username, password) do | def authenticate(username, password) do | ||||
@@ -11,7 +12,7 @@ defmodule Pleroma.BBS.Authenticator do | |||||
password = to_string(password) | password = to_string(password) | ||||
with %User{} = user <- User.get_by_nickname(username) do | with %User{} = user <- User.get_by_nickname(username) do | ||||
Pbkdf2.verify_pass(password, user.password_hash) | |||||
AuthenticationPlug.checkpw(password, user.password_hash) | |||||
else | else | ||||
_e -> false | _e -> false | ||||
end | end | ||||
@@ -278,6 +278,8 @@ defmodule Pleroma.ConfigDB do | |||||
} | } | ||||
end | end | ||||
defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]} | |||||
defp do_convert(entity) when is_tuple(entity) do | defp do_convert(entity) when is_tuple(entity) do | ||||
value = | value = | ||||
entity | entity | ||||
@@ -321,6 +323,15 @@ defmodule Pleroma.ConfigDB do | |||||
{:proxy_url, {do_transform_string(type), parse_host(host), port}} | {:proxy_url, {do_transform_string(type), parse_host(host), port}} | ||||
end | 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 | defp do_transform(%{"tuple" => entity}) do | ||||
Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end) | Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end) | ||||
end | end | ||||
@@ -17,7 +17,8 @@ defmodule Pleroma.Constants do | |||||
"announcement_count", | "announcement_count", | ||||
"emoji", | "emoji", | ||||
"context_id", | "context_id", | ||||
"deleted_activity_id" | |||||
"deleted_activity_id", | |||||
"pleroma_internal" | |||||
] | ] | ||||
) | ) | ||||
@@ -18,7 +18,6 @@ defmodule Pleroma.Docs.JSON do | |||||
with config <- Pleroma.Config.Loader.read("config/description.exs") do | with config <- Pleroma.Config.Loader.read("config/description.exs") do | ||||
config[:pleroma][:config_description] | config[:pleroma][:config_description] | ||||
|> Pleroma.Docs.Generator.convert_to_strings() | |> Pleroma.Docs.Generator.convert_to_strings() | ||||
|> Jason.encode!() | |||||
end | end | ||||
end | end | ||||
end | end |
@@ -16,6 +16,11 @@ defmodule Pleroma.Plugs.AuthenticationPlug do | |||||
:crypt.crypt(password, password_hash) == password_hash | :crypt.crypt(password, password_hash) == password_hash | ||||
end | 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 | def checkpw(password, "$pbkdf2" <> _ = password_hash) do | ||||
Pbkdf2.verify_pass(password, password_hash) | Pbkdf2.verify_pass(password, password_hash) | ||||
end | end | ||||
@@ -25,6 +30,25 @@ defmodule Pleroma.Plugs.AuthenticationPlug do | |||||
false | false | ||||
end | end | ||||
def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do | |||||
do_update_password(user, password) | |||||
end | |||||
def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do | |||||
do_update_password(user, password) | |||||
end | |||||
def maybe_update_password(user, _), do: {:ok, user} | |||||
defp do_update_password(user, password) do | |||||
user | |||||
|> User.password_update_changeset(%{ | |||||
"password" => password, | |||||
"password_confirmation" => password | |||||
}) | |||||
|> Pleroma.Repo.update() | |||||
end | |||||
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn | def call(%{assigns: %{user: %User{}}} = conn, _), do: conn | ||||
def call( | def call( | ||||
@@ -36,7 +60,9 @@ defmodule Pleroma.Plugs.AuthenticationPlug do | |||||
} = conn, | } = conn, | ||||
_ | _ | ||||
) do | ) do | ||||
if Pbkdf2.verify_pass(password, password_hash) do | |||||
if checkpw(password, password_hash) do | |||||
{:ok, auth_user} = maybe_update_password(auth_user, password) | |||||
conn | conn | ||||
|> assign(:user, auth_user) | |> assign(:user, auth_user) | ||||
|> OAuthScopesPlug.skip_plug() | |> OAuthScopesPlug.skip_plug() | ||||
@@ -134,7 +134,7 @@ defmodule Pleroma.Upload do | |||||
end | end | ||||
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) | parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data) | ||||
data = Base.decode64!(parsed["data"], ignore: :whitespace) | data = Base.decode64!(parsed["data"], ignore: :whitespace) | ||||
hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data))) | hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data))) | ||||
@@ -87,6 +87,22 @@ defmodule Pleroma.UserRelationship do | |||||
source_to_target_rel_types \\ nil, | source_to_target_rel_types \\ nil, | ||||
target_to_source_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 | when is_list(source_users) and is_list(target_users) do | ||||
source_user_ids = User.binary_id(source_users) | source_user_ids = User.binary_id(source_users) | ||||
target_user_ids = User.binary_id(target_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 | def view_relationships_option(%User{} = reading_user, actors, opts) do | ||||
{source_to_target_rel_types, target_to_source_rel_types} = | {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 | end | ||||
user_relationships = | user_relationships = | ||||
@@ -153,7 +174,17 @@ defmodule Pleroma.UserRelationship do | |||||
target_to_source_rel_types | 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} | %{user_relationships: user_relationships, following_relationships: following_relationships} | ||||
end | end | ||||
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
alias Pleroma.Web.ActivityPub.Pipeline | alias Pleroma.Web.ActivityPub.Pipeline | ||||
alias Pleroma.Web.ActivityPub.Relay | alias Pleroma.Web.ActivityPub.Relay | ||||
alias Pleroma.Web.ActivityPub.Utils | alias Pleroma.Web.ActivityPub.Utils | ||||
alias Pleroma.Web.AdminAPI | |||||
alias Pleroma.Web.AdminAPI.AccountView | alias Pleroma.Web.AdminAPI.AccountView | ||||
alias Pleroma.Web.AdminAPI.ConfigView | alias Pleroma.Web.AdminAPI.ConfigView | ||||
alias Pleroma.Web.AdminAPI.ModerationLogView | alias Pleroma.Web.AdminAPI.ModerationLogView | ||||
@@ -30,14 +31,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
alias Pleroma.Web.AdminAPI.Search | alias Pleroma.Web.AdminAPI.Search | ||||
alias Pleroma.Web.CommonAPI | alias Pleroma.Web.CommonAPI | ||||
alias Pleroma.Web.Endpoint | alias Pleroma.Web.Endpoint | ||||
alias Pleroma.Web.MastodonAPI | |||||
alias Pleroma.Web.MastodonAPI.AppView | alias Pleroma.Web.MastodonAPI.AppView | ||||
alias Pleroma.Web.MastodonAPI.StatusView | |||||
alias Pleroma.Web.OAuth.App | alias Pleroma.Web.OAuth.App | ||||
alias Pleroma.Web.Router | alias Pleroma.Web.Router | ||||
require Logger | require Logger | ||||
@descriptions_json Pleroma.Docs.JSON.compile() | |||||
@descriptions Pleroma.Docs.JSON.compile() | |||||
@users_page_size 50 | @users_page_size 50 | ||||
plug( | plug( | ||||
@@ -280,8 +281,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
}) | }) | ||||
conn | 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 | end | ||||
def list_user_statuses(conn, %{"nickname" => nickname} = params) do | def list_user_statuses(conn, %{"nickname" => nickname} = params) do | ||||
@@ -299,8 +300,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
}) | }) | ||||
conn | 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 | else | ||||
_ -> {:error, :not_found} | _ -> {:error, :not_found} | ||||
end | end | ||||
@@ -829,14 +830,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
}) | }) | ||||
conn | 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 | end | ||||
def status_show(conn, %{"id" => id}) do | def status_show(conn, %{"id" => id}) do | ||||
with %Activity{} = activity <- Activity.get_by_id(id) do | with %Activity{} = activity <- Activity.get_by_id(id) do | ||||
conn | conn | ||||
|> put_view(StatusView) | |||||
|> put_view(MastodonAPI.StatusView) | |||||
|> render("show.json", %{activity: activity}) | |> render("show.json", %{activity: activity}) | ||||
else | else | ||||
_ -> errors(conn, {:error, :not_found}) | _ -> errors(conn, {:error, :not_found}) | ||||
@@ -861,7 +862,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
}) | }) | ||||
conn | conn | ||||
|> put_view(StatusView) | |||||
|> put_view(MastodonAPI.StatusView) | |||||
|> render("show.json", %{activity: activity}) | |> render("show.json", %{activity: activity}) | ||||
end | end | ||||
end | end | ||||
@@ -897,9 +898,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
end | end | ||||
def config_descriptions(conn, _params) do | 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 | end | ||||
def config_show(conn, %{"only_db" => true}) do | 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 | def config_update(conn, %{"configs" => configs}) do | ||||
with :ok <- configurable_from_database(conn) do | with :ok <- configurable_from_database(conn) do | ||||
{_errors, results} = | {_errors, results} = | ||||
Enum.map(configs, fn | |||||
configs | |||||
|> Enum.filter(&whitelisted_config?/1) | |||||
|> Enum.map(fn | |||||
%{"group" => group, "key" => key, "delete" => true} = params -> | %{"group" => group, "key" => key, "delete" => true} = params -> | ||||
ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]}) | ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]}) | ||||
@@ -1016,6 +1019,28 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||||
end | end | ||||
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 | def reload_emoji(conn, _params) do | ||||
Pleroma.Emoji.reload() | Pleroma.Emoji.reload() | ||||
@@ -6,7 +6,9 @@ defmodule Pleroma.Web.AdminAPI.AccountView do | |||||
use Pleroma.Web, :view | use Pleroma.Web, :view | ||||
alias Pleroma.User | alias Pleroma.User | ||||
alias Pleroma.Web.AdminAPI | |||||
alias Pleroma.Web.AdminAPI.AccountView | alias Pleroma.Web.AdminAPI.AccountView | ||||
alias Pleroma.Web.MastodonAPI | |||||
alias Pleroma.Web.MediaProxy | alias Pleroma.Web.MediaProxy | ||||
def render("index.json", %{users: users, count: count, page_size: page_size}) do | def render("index.json", %{users: users, count: count, page_size: page_size}) do | ||||
@@ -119,6 +121,13 @@ defmodule Pleroma.Web.AdminAPI.AccountView do | |||||
} | } | ||||
end | 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([]), do: "" | ||||
defp parse_error(errors) do | defp parse_error(errors) do | ||||
@@ -7,10 +7,13 @@ defmodule Pleroma.Web.AdminAPI.ReportView do | |||||
alias Pleroma.HTML | alias Pleroma.HTML | ||||
alias Pleroma.User | alias Pleroma.User | ||||
alias Pleroma.Web.AdminAPI | |||||
alias Pleroma.Web.AdminAPI.Report | alias Pleroma.Web.AdminAPI.Report | ||||
alias Pleroma.Web.CommonAPI.Utils | alias Pleroma.Web.CommonAPI.Utils | ||||
alias Pleroma.Web.MastodonAPI.StatusView | alias Pleroma.Web.MastodonAPI.StatusView | ||||
defdelegate merge_account_views(user), to: AdminAPI.AccountView | |||||
def render("index.json", %{reports: reports}) do | def render("index.json", %{reports: reports}) do | ||||
%{ | %{ | ||||
reports: | reports: | ||||
@@ -41,8 +44,7 @@ defmodule Pleroma.Web.AdminAPI.ReportView do | |||||
statuses: | statuses: | ||||
StatusView.render("index.json", %{ | StatusView.render("index.json", %{ | ||||
activities: statuses, | activities: statuses, | ||||
as: :activity, | |||||
skip_relationships: false | |||||
as: :activity | |||||
}), | }), | ||||
state: report.data["state"], | state: report.data["state"], | ||||
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes}) | 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) | created_at: Utils.to_masto_date(inserted_at) | ||||
} | } | ||||
end | 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 | end |
@@ -7,24 +7,19 @@ defmodule Pleroma.Web.AdminAPI.StatusView do | |||||
require Pleroma.Constants | 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 | def render("index.json", opts) do | ||||
safe_render_many(opts.activities, __MODULE__, "show.json", opts) | safe_render_many(opts.activities, __MODULE__, "show.json", opts) | ||||
end | end | ||||
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do | 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)}) | |> Map.merge(%{account: merge_account_views(user)}) | ||||
end | 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 | end |
@@ -5,6 +5,7 @@ | |||||
defmodule Pleroma.Web.ApiSpec.Helpers do | defmodule Pleroma.Web.ApiSpec.Helpers do | ||||
alias OpenApiSpex.Operation | alias OpenApiSpex.Operation | ||||
alias OpenApiSpex.Schema | alias OpenApiSpex.Schema | ||||
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike | |||||
def request_body(description, schema_ref, opts \\ []) do | def request_body(description, schema_ref, opts \\ []) do | ||||
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"] | media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"] | ||||
@@ -47,6 +48,15 @@ defmodule Pleroma.Web.ApiSpec.Helpers do | |||||
] | ] | ||||
end | end | ||||
def with_relationships_param do | |||||
Operation.parameter( | |||||
:with_relationships, | |||||
:query, | |||||
BooleanLike, | |||||
"Embed relationships into accounts." | |||||
) | |||||
end | |||||
def empty_object_response do | def empty_object_response do | ||||
Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}}) | Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}}) | ||||
end | end | ||||
@@ -54,4 +64,8 @@ defmodule Pleroma.Web.ApiSpec.Helpers do | |||||
def empty_array_response do | def empty_array_response do | ||||
Operation.response("Empty array", "application/json", %Schema{type: :array, example: []}) | Operation.response("Empty array", "application/json", %Schema{type: :array, example: []}) | ||||
end | end | ||||
def no_content_response do | |||||
Operation.response("No Content", "application/json", %Schema{type: :string, example: ""}) | |||||
end | |||||
end | end |
@@ -155,8 +155,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
security: [%{"oAuth" => ["read:accounts"]}], | security: [%{"oAuth" => ["read:accounts"]}], | ||||
description: | description: | ||||
"Accounts which follow the given account, if network is not hidden by the account owner.", | "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: %{ | responses: %{ | ||||
200 => Operation.response("Accounts", "application/json", array_of_accounts()) | 200 => Operation.response("Accounts", "application/json", array_of_accounts()) | ||||
} | } | ||||
@@ -171,8 +173,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
security: [%{"oAuth" => ["read:accounts"]}], | security: [%{"oAuth" => ["read:accounts"]}], | ||||
description: | description: | ||||
"Accounts which the given account is following, if network is not hidden by the account owner.", | "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())} | responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())} | ||||
} | } | ||||
end | end | ||||
@@ -367,15 +371,18 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
title: "AccountCreateRequest", | title: "AccountCreateRequest", | ||||
description: "POST body for creating an account", | description: "POST body for creating an account", | ||||
type: :object, | type: :object, | ||||
required: [:username, :password, :agreement], | |||||
properties: %{ | properties: %{ | ||||
reason: %Schema{ | reason: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: | description: | ||||
"Text that will be reviewed by moderators if registrations require manual approval" | "Text that will be reviewed by moderators if registrations require manual approval" | ||||
}, | }, | ||||
username: %Schema{type: :string, description: "The desired username for the account"}, | username: %Schema{type: :string, description: "The desired username for the account"}, | ||||
email: %Schema{ | email: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: | description: | ||||
"The email address to be used for login. Required when `account_activation_required` is enabled.", | "The email address to be used for login. Required when `account_activation_required` is enabled.", | ||||
format: :email | format: :email | ||||
@@ -392,23 +399,33 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
}, | }, | ||||
locale: %Schema{ | locale: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "The language of the confirmation email that will be sent" | description: "The language of the confirmation email that will be sent" | ||||
}, | }, | ||||
# Pleroma-specific properties: | # 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{ | captcha_solution: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Provider-specific captcha solution" | 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{ | token: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Invite token required when the registrations aren't public" | description: "Invite token required when the registrations aren't public" | ||||
} | } | ||||
}, | }, | ||||
required: [:username, :password, :agreement], | |||||
example: %{ | example: %{ | ||||
"username" => "cofe", | "username" => "cofe", | ||||
"email" => "cofe@example.com", | "email" => "cofe@example.com", | ||||
@@ -447,28 +464,34 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
properties: %{ | properties: %{ | ||||
bot: %Schema{ | bot: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Whether the account has a bot flag." | description: "Whether the account has a bot flag." | ||||
}, | }, | ||||
display_name: %Schema{ | display_name: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "The display name to use for the profile." | description: "The display name to use for the profile." | ||||
}, | }, | ||||
note: %Schema{type: :string, description: "The account bio."}, | note: %Schema{type: :string, description: "The account bio."}, | ||||
avatar: %Schema{ | avatar: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Avatar image encoded using multipart/form-data", | description: "Avatar image encoded using multipart/form-data", | ||||
format: :binary | format: :binary | ||||
}, | }, | ||||
header: %Schema{ | header: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Header image encoded using multipart/form-data", | description: "Header image encoded using multipart/form-data", | ||||
format: :binary | format: :binary | ||||
}, | }, | ||||
locked: %Schema{ | locked: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Whether manual approval of follow requests is required." | description: "Whether manual approval of follow requests is required." | ||||
}, | }, | ||||
fields_attributes: %Schema{ | fields_attributes: %Schema{ | ||||
nullable: true, | |||||
oneOf: [ | oneOf: [ | ||||
%Schema{type: :array, items: attribute_field()}, | %Schema{type: :array, items: attribute_field()}, | ||||
%Schema{type: :object, additionalProperties: %Schema{type: attribute_field()}} | %Schema{type: :object, additionalProperties: %Schema{type: attribute_field()}} | ||||
@@ -488,47 +511,65 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
# Pleroma-specific fields | # Pleroma-specific fields | ||||
no_rich_text: %Schema{ | no_rich_text: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "html tags are stripped from all statuses requested from the API" | 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{ | hide_followers_count: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "user's follower count will be hidden" | description: "user's follower count will be hidden" | ||||
}, | }, | ||||
hide_follows_count: %Schema{ | hide_follows_count: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "user's follow count will be hidden" | description: "user's follow count will be hidden" | ||||
}, | }, | ||||
hide_favorites: %Schema{ | hide_favorites: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "user's favorites timeline will be hidden" | description: "user's favorites timeline will be hidden" | ||||
}, | }, | ||||
show_role: %Schema{ | show_role: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "user's role (e.g admin, moderator) will be exposed to anyone in the | description: "user's role (e.g admin, moderator) will be exposed to anyone in the | ||||
API" | API" | ||||
}, | }, | ||||
default_scope: VisibilityScope, | default_scope: VisibilityScope, | ||||
pleroma_settings_store: %Schema{ | pleroma_settings_store: %Schema{ | ||||
type: :object, | type: :object, | ||||
nullable: true, | |||||
description: "Opaque user settings to be saved on the backend." | description: "Opaque user settings to be saved on the backend." | ||||
}, | }, | ||||
skip_thread_containment: %Schema{ | skip_thread_containment: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Skip filtering out broken threads" | description: "Skip filtering out broken threads" | ||||
}, | }, | ||||
allow_following_move: %Schema{ | allow_following_move: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Allows automatically follow moved following accounts" | description: "Allows automatically follow moved following accounts" | ||||
}, | }, | ||||
pleroma_background_image: %Schema{ | pleroma_background_image: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Sets the background image of the user.", | description: "Sets the background image of the user.", | ||||
format: :binary | format: :binary | ||||
}, | }, | ||||
discoverable: %Schema{ | discoverable: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: | description: | ||||
"Discovery of this account in search results and other services is allowed." | "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", | description: "POST body for muting an account", | ||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
uri: %Schema{type: :string, format: :uri} | |||||
uri: %Schema{type: :string, nullable: true, format: :uri} | |||||
}, | }, | ||||
required: [:uri] | required: [:uri] | ||||
} | } | ||||
@@ -638,6 +679,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
properties: %{ | properties: %{ | ||||
notifications: %Schema{ | notifications: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Mute notifications in addition to statuses? Defaults to true.", | description: "Mute notifications in addition to statuses? Defaults to true.", | ||||
default: true | default: true | ||||
} | } | ||||
@@ -105,7 +105,11 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do | |||||
description: "Space separated list of scopes", | description: "Space separated list of scopes", | ||||
default: "read" | 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], | required: [:client_name, :redirect_uris], | ||||
example: %{ | example: %{ | ||||
@@ -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." | "Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified." | ||||
}, | }, | ||||
irreversible: %Schema{ | irreversible: %Schema{ | ||||
type: :bolean, | |||||
type: :boolean, | |||||
nullable: true, | |||||
description: | description: | ||||
"Should the server irreversibly drop matching entities from home and notifications?" | "Should the server irreversibly drop matching entities from home and notifications?" | ||||
}, | }, | ||||
whole_word: %Schema{ | whole_word: %Schema{ | ||||
type: :bolean, | |||||
type: :boolean, | |||||
nullable: true, | |||||
description: "Consider word boundaries?", | description: "Consider word boundaries?", | ||||
default: true | default: true | ||||
} | } | ||||
@@ -110,14 +110,16 @@ defmodule Pleroma.Web.ApiSpec.MarkerOperation do | |||||
properties: %{ | properties: %{ | ||||
notifications: %Schema{ | notifications: %Schema{ | ||||
type: :object, | type: :object, | ||||
nullable: true, | |||||
properties: %{ | properties: %{ | ||||
last_read_id: %Schema{type: :string} | |||||
last_read_id: %Schema{nullable: true, type: :string} | |||||
} | } | ||||
}, | }, | ||||
home: %Schema{ | home: %Schema{ | ||||
type: :object, | type: :object, | ||||
nullable: true, | |||||
properties: %{ | properties: %{ | ||||
last_read_id: %Schema{type: :string} | |||||
last_read_id: %Schema{nullable: true, type: :string} | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -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 |
@@ -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 |
@@ -37,15 +37,18 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do | |||||
account_id: %Schema{type: :string, description: "ID of the account to report"}, | account_id: %Schema{type: :string, description: "ID of the account to report"}, | ||||
status_ids: %Schema{ | status_ids: %Schema{ | ||||
type: :array, | type: :array, | ||||
nullable: true, | |||||
items: %Schema{type: :string}, | items: %Schema{type: :string}, | ||||
description: "Array of Statuses to attach to the report, for context" | description: "Array of Statuses to attach to the report, for context" | ||||
}, | }, | ||||
comment: %Schema{ | comment: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: "Reason for the report" | description: "Reason for the report" | ||||
}, | }, | ||||
forward: %Schema{ | forward: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
default: false, | default: false, | ||||
description: | description: | ||||
"If the account is remote, should the report be forwarded to the remote admin?" | "If the account is remote, should the report be forwarded to the remote admin?" | ||||
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do | |||||
apply(__MODULE__, operation, []) | apply(__MODULE__, operation, []) | ||||
end | end | ||||
# Note: `with_relationships` param is not supported (PleromaFE uses this op for autocomplete) | |||||
def account_search_operation do | def account_search_operation do | ||||
%Operation{ | %Operation{ | ||||
tags: ["Search"], | tags: ["Search"], | ||||
@@ -96,8 +97,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do | |||||
:query, | :query, | ||||
%Schema{type: :integer}, | %Schema{type: :integer}, | ||||
"Offset" | "Offset" | ||||
) | |||||
| pagination_params() | |||||
), | |||||
with_relationships_param() | pagination_params() | |||||
], | ], | ||||
responses: %{ | responses: %{ | ||||
200 => Operation.response("Results", "application/json", results()) | 200 => Operation.response("Results", "application/json", results()) | ||||
@@ -138,8 +139,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do | |||||
:query, | :query, | ||||
%Schema{allOf: [BooleanLike], default: false}, | %Schema{allOf: [BooleanLike], default: false}, | ||||
"Only include accounts that the user is following" | "Only include accounts that the user is following" | ||||
) | |||||
| pagination_params() | |||||
), | |||||
with_relationships_param() | pagination_params() | |||||
], | ], | ||||
responses: %{ | responses: %{ | ||||
200 => Operation.response("Results", "application/json", results2()) | 200 => Operation.response("Results", "application/json", results2()) | ||||
@@ -7,7 +7,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do | |||||
alias OpenApiSpex.Schema | alias OpenApiSpex.Schema | ||||
alias Pleroma.Web.ApiSpec.AccountOperation | alias Pleroma.Web.ApiSpec.AccountOperation | ||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError | alias Pleroma.Web.ApiSpec.Schemas.ApiError | ||||
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike | |||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID | alias Pleroma.Web.ApiSpec.Schemas.FlakeID | ||||
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus | alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus | ||||
alias Pleroma.Web.ApiSpec.Schemas.Status | alias Pleroma.Web.ApiSpec.Schemas.Status | ||||
@@ -349,10 +348,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do | |||||
summary: "Bookmarked statuses", | summary: "Bookmarked statuses", | ||||
description: "Statuses the user has bookmarked", | description: "Statuses the user has bookmarked", | ||||
operationId: "StatusController.bookmarks", | operationId: "StatusController.bookmarks", | ||||
parameters: [ | |||||
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships") | |||||
| pagination_params() | |||||
], | |||||
parameters: pagination_params(), | |||||
security: [%{"oAuth" => ["read:bookmarks"]}], | security: [%{"oAuth" => ["read:bookmarks"]}], | ||||
responses: %{ | responses: %{ | ||||
200 => Operation.response("Array of Statuses", "application/json", array_of_statuses()) | 200 => Operation.response("Array of Statuses", "application/json", array_of_statuses()) | ||||
@@ -360,7 +356,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do | |||||
} | } | ||||
end | end | ||||
defp array_of_statuses do | |||||
def array_of_statuses do | |||||
%Schema{type: :array, items: Status, example: [Status.schema().example]} | %Schema{type: :array, items: Status, example: [Status.schema().example]} | ||||
end | end | ||||
@@ -371,15 +367,18 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do | |||||
properties: %{ | properties: %{ | ||||
status: %Schema{ | status: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: | description: | ||||
"Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided." | "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{ | media_ids: %Schema{ | ||||
nullable: true, | |||||
type: :array, | type: :array, | ||||
items: %Schema{type: :string}, | items: %Schema{type: :string}, | ||||
description: "Array of Attachment ids to be attached as media." | description: "Array of Attachment ids to be attached as media." | ||||
}, | }, | ||||
poll: %Schema{ | poll: %Schema{ | ||||
nullable: true, | |||||
type: :object, | type: :object, | ||||
required: [:options], | required: [:options], | ||||
properties: %{ | properties: %{ | ||||
@@ -390,26 +389,35 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do | |||||
}, | }, | ||||
expires_in: %Schema{ | expires_in: %Schema{ | ||||
type: :integer, | type: :integer, | ||||
nullable: true, | |||||
description: | description: | ||||
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`" | "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{ | hide_totals: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Hide vote counts until the poll ends?" | description: "Hide vote counts until the poll ends?" | ||||
} | } | ||||
} | } | ||||
}, | }, | ||||
in_reply_to_id: %Schema{ | in_reply_to_id: %Schema{ | ||||
nullable: true, | |||||
allOf: [FlakeID], | allOf: [FlakeID], | ||||
description: "ID of the status being replied to, if status is a reply" | description: "ID of the status being replied to, if status is a reply" | ||||
}, | }, | ||||
sensitive: %Schema{ | sensitive: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Mark status and attached media as sensitive?" | description: "Mark status and attached media as sensitive?" | ||||
}, | }, | ||||
spoiler_text: %Schema{ | spoiler_text: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: | description: | ||||
"Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field." | "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: | 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." | "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: | # Pleroma-specific properties: | ||||
preview: %Schema{ | preview: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: | 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" | "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{ | content_type: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | |||||
description: | 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." | "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{ | to: %Schema{ | ||||
type: :array, | type: :array, | ||||
nullable: true, | |||||
items: %Schema{type: :string}, | items: %Schema{type: :string}, | ||||
description: | 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" | "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{ | visibility: %Schema{ | ||||
nullable: true, | |||||
anyOf: [ | anyOf: [ | ||||
VisibilityScope, | VisibilityScope, | ||||
%Schema{type: :string, description: "`list:LIST_ID`", example: "LIST:123"} | %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`" | "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{ | expires_in: %Schema{ | ||||
nullable: true, | |||||
type: :integer, | type: :integer, | ||||
description: | 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." | "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{ | in_reply_to_conversation_id: %Schema{ | ||||
nullable: true, | |||||
type: :string, | type: :string, | ||||
description: | 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`." | "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`." | ||||
@@ -109,19 +109,38 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do | |||||
required: [:endpoint, :keys] | required: [:endpoint, :keys] | ||||
}, | }, | ||||
data: %Schema{ | data: %Schema{ | ||||
nullable: true, | |||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
alerts: %Schema{ | alerts: %Schema{ | ||||
nullable: true, | |||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"}, | |||||
follow: %Schema{ | |||||
type: :boolean, | |||||
nullable: true, | |||||
description: "Receive follow notifications?" | |||||
}, | |||||
favourite: %Schema{ | favourite: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Receive favourite notifications?" | 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, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
data: %Schema{ | data: %Schema{ | ||||
nullable: true, | |||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
alerts: %Schema{ | alerts: %Schema{ | ||||
nullable: true, | |||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"}, | |||||
follow: %Schema{ | |||||
type: :boolean, | |||||
nullable: true, | |||||
description: "Receive follow notifications?" | |||||
}, | |||||
favourite: %Schema{ | favourite: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
nullable: true, | |||||
description: "Receive favourite notifications?" | 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?" | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -27,8 +27,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do | |||||
local_param(), | local_param(), | ||||
with_muted_param(), | with_muted_param(), | ||||
exclude_visibilities_param(), | exclude_visibilities_param(), | ||||
reply_visibility_param(), | |||||
with_relationships_param() | pagination_params() | |||||
reply_visibility_param() | pagination_params() | |||||
], | ], | ||||
operationId: "TimelineController.home", | operationId: "TimelineController.home", | ||||
responses: %{ | responses: %{ | ||||
@@ -63,8 +62,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do | |||||
only_media_param(), | only_media_param(), | ||||
with_muted_param(), | with_muted_param(), | ||||
exclude_visibilities_param(), | exclude_visibilities_param(), | ||||
reply_visibility_param(), | |||||
with_relationships_param() | pagination_params() | |||||
reply_visibility_param() | pagination_params() | |||||
], | ], | ||||
operationId: "TimelineController.public", | operationId: "TimelineController.public", | ||||
responses: %{ | responses: %{ | ||||
@@ -109,8 +107,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do | |||||
local_param(), | local_param(), | ||||
only_media_param(), | only_media_param(), | ||||
with_muted_param(), | with_muted_param(), | ||||
exclude_visibilities_param(), | |||||
with_relationships_param() | pagination_params() | |||||
exclude_visibilities_param() | pagination_params() | |||||
], | ], | ||||
operationId: "TimelineController.hashtag", | operationId: "TimelineController.hashtag", | ||||
responses: %{ | responses: %{ | ||||
@@ -134,8 +131,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do | |||||
required: true | required: true | ||||
), | ), | ||||
with_muted_param(), | with_muted_param(), | ||||
exclude_visibilities_param(), | |||||
with_relationships_param() | pagination_params() | |||||
exclude_visibilities_param() | pagination_params() | |||||
], | ], | ||||
operationId: "TimelineController.list", | operationId: "TimelineController.list", | ||||
responses: %{ | responses: %{ | ||||
@@ -153,10 +149,6 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do | |||||
} | } | ||||
end | end | ||||
defp with_relationships_param do | |||||
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships") | |||||
end | |||||
defp local_param do | defp local_param do | ||||
Operation.parameter( | Operation.parameter( | ||||
:local, | :local, | ||||
@@ -13,7 +13,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Attachment do | |||||
type: :object, | type: :object, | ||||
requried: [:id, :url, :preview_url], | requried: [:id, :url, :preview_url], | ||||
properties: %{ | properties: %{ | ||||
id: %Schema{type: :string}, | |||||
id: %Schema{type: :string, description: "The ID of the attachment in the database."}, | |||||
url: %Schema{ | url: %Schema{ | ||||
type: :string, | type: :string, | ||||
format: :uri, | format: :uri, | ||||
@@ -16,7 +16,8 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do | |||||
def get_user(%Plug.Conn{} = conn) do | def get_user(%Plug.Conn{} = conn) do | ||||
with {:ok, {name, password}} <- fetch_credentials(conn), | with {:ok, {name, password}} <- fetch_credentials(conn), | ||||
{_, %User{} = user} <- {:user, fetch_user(name)}, | {_, %User{} = user} <- {:user, fetch_user(name)}, | ||||
{_, true} <- {:checkpw, AuthenticationPlug.checkpw(password, user.password_hash)} do | |||||
{_, true} <- {:checkpw, AuthenticationPlug.checkpw(password, user.password_hash)}, | |||||
{:ok, user} <- AuthenticationPlug.maybe_update_password(user, password) do | |||||
{:ok, user} | {:ok, user} | ||||
else | else | ||||
{:error, _reason} = error -> error | {:error, _reason} = error -> error | ||||
@@ -5,6 +5,7 @@ | |||||
defmodule Pleroma.Web.Auth.TOTPAuthenticator do | defmodule Pleroma.Web.Auth.TOTPAuthenticator do | ||||
alias Pleroma.MFA | alias Pleroma.MFA | ||||
alias Pleroma.MFA.TOTP | alias Pleroma.MFA.TOTP | ||||
alias Pleroma.Plugs.AuthenticationPlug | |||||
alias Pleroma.User | alias Pleroma.User | ||||
@doc "Verify code or check backup code." | @doc "Verify code or check backup code." | ||||
@@ -30,7 +31,7 @@ defmodule Pleroma.Web.Auth.TOTPAuthenticator do | |||||
code | code | ||||
) | ) | ||||
when is_list(codes) and is_binary(code) do | 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 | if hash_code do | ||||
MFA.invalidate_backup_code(user, hash_code) | MFA.invalidate_backup_code(user, hash_code) | ||||
@@ -23,6 +23,7 @@ defmodule Pleroma.Web.ChatChannel do | |||||
if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do | if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do | ||||
author = User.get_cached_by_nickname(user_name) | author = User.get_cached_by_nickname(user_name) | ||||
author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author) | author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author) | ||||
message = ChatChannelState.add_message(%{text: text, author: author}) | message = ChatChannelState.add_message(%{text: text, author: author}) | ||||
broadcast!(socket, "new_msg", message) | broadcast!(socket, "new_msg", message) | ||||
@@ -25,10 +25,21 @@ defmodule Pleroma.Web.CommonAPI do | |||||
require Logger | require Logger | ||||
def unblock(blocker, blocked) do | 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_data, _} <- Builder.undo(blocker, block), | ||||
{:ok, unblock, _} <- Pipeline.common_pipeline(unblock_data, local: true) do | {:ok, unblock, _} <- Pipeline.common_pipeline(unblock_data, local: true) do | ||||
{:ok, unblock} | {: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 | ||||
end | end | ||||
@@ -5,8 +5,6 @@ | |||||
defmodule Pleroma.Web.ControllerHelper do | defmodule Pleroma.Web.ControllerHelper do | ||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
alias Pleroma.Config | |||||
# As in Mastodon API, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html | # 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"] | @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) | 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 | ||||
end | end |
@@ -10,8 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
add_link_headers: 2, | add_link_headers: 2, | ||||
truthy_param?: 1, | truthy_param?: 1, | ||||
assign_account_by_id: 2, | assign_account_by_id: 2, | ||||
json_response: 3, | |||||
skip_relationships?: 1 | |||||
embed_relationships?: 1, | |||||
json_response: 3 | |||||
] | ] | ||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | ||||
@@ -247,8 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: reading_user, | for: reading_user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
else | else | ||||
_e -> render_error(conn, :not_found, "Can't find user") | _e -> render_error(conn, :not_found, "Can't find user") | ||||
@@ -271,7 +270,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
conn | conn | ||||
|> add_link_headers(followers) | |> 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 | end | ||||
@doc "GET /api/v1/accounts/:id/following" | @doc "GET /api/v1/accounts/:id/following" | ||||
@@ -290,7 +295,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
conn | conn | ||||
|> add_link_headers(followers) | |> 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 | end | ||||
@doc "GET /api/v1/accounts/:id/lists" | @doc "GET /api/v1/accounts/:id/lists" | ||||
@@ -11,17 +11,20 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do | |||||
alias Pleroma.Web.ActivityPub.ActivityPub | alias Pleroma.Web.ActivityPub.ActivityPub | ||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) | action_fallback(Pleroma.Web.MastodonAPI.FallbackController) | ||||
plug(Pleroma.Web.ApiSpec.CastAndValidate) | |||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView) | plug(:put_view, Pleroma.Web.MastodonAPI.StatusView) | ||||
plug(OAuthScopesPlug, %{scopes: ["write:media"]}) | plug(OAuthScopesPlug, %{scopes: ["write:media"]}) | ||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.MediaOperation | |||||
@doc "POST /api/v1/media" | @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} <- | with {:ok, object} <- | ||||
ActivityPub.upload( | ActivityPub.upload( | ||||
file, | file, | ||||
actor: User.ap_id(user), | actor: User.ap_id(user), | ||||
description: Map.get(data, "description") | |||||
description: Map.get(data, :description) | |||||
) do | ) do | ||||
attachment_data = Map.put(object.data, "id", object.id) | attachment_data = Map.put(object.data, "id", object.id) | ||||
@@ -29,9 +32,28 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do | |||||
end | end | ||||
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" | @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), | with %Object{} = object <- Object.get_by_id(id), | ||||
true <- Object.authorize_mutation(object, user), | true <- Object.authorize_mutation(object, user), | ||||
{:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do | {:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do | ||||
@@ -41,5 +63,16 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do | |||||
end | end | ||||
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 | end |
@@ -5,7 +5,7 @@ | |||||
defmodule Pleroma.Web.MastodonAPI.NotificationController do | defmodule Pleroma.Web.MastodonAPI.NotificationController do | ||||
use Pleroma.Web, :controller | 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.Notification | ||||
alias Pleroma.Plugs.OAuthScopesPlug | alias Pleroma.Plugs.OAuthScopesPlug | ||||
@@ -50,8 +50,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do | |||||
|> add_link_headers(notifications) | |> add_link_headers(notifications) | ||||
|> render("index.json", | |> render("index.json", | ||||
notifications: notifications, | notifications: notifications, | ||||
for: user, | |||||
skip_relationships: skip_relationships?(params) | |||||
for: user | |||||
) | ) | ||||
end | end | ||||
@@ -5,14 +5,13 @@ | |||||
defmodule Pleroma.Web.MastodonAPI.SearchController do | defmodule Pleroma.Web.MastodonAPI.SearchController do | ||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
import Pleroma.Web.ControllerHelper, only: [skip_relationships?: 1] | |||||
alias Pleroma.Activity | alias Pleroma.Activity | ||||
alias Pleroma.Plugs.OAuthScopesPlug | alias Pleroma.Plugs.OAuthScopesPlug | ||||
alias Pleroma.Plugs.RateLimiter | alias Pleroma.Plugs.RateLimiter | ||||
alias Pleroma.Repo | alias Pleroma.Repo | ||||
alias Pleroma.User | alias Pleroma.User | ||||
alias Pleroma.Web | alias Pleroma.Web | ||||
alias Pleroma.Web.ControllerHelper | |||||
alias Pleroma.Web.MastodonAPI.AccountView | alias Pleroma.Web.MastodonAPI.AccountView | ||||
alias Pleroma.Web.MastodonAPI.StatusView | alias Pleroma.Web.MastodonAPI.StatusView | ||||
@@ -34,7 +33,11 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do | |||||
conn | conn | ||||
|> put_view(AccountView) | |> put_view(AccountView) | ||||
|> render("index.json", users: accounts, for: user, as: :user) | |||||
|> render("index.json", | |||||
users: accounts, | |||||
for: user, | |||||
as: :user | |||||
) | |||||
end | end | ||||
def search2(conn, params), do: do_search(:v2, conn, params) | 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 | defp search_options(params, user) do | ||||
[ | [ | ||||
skip_relationships: skip_relationships?(params), | |||||
resolve: params[:resolve], | resolve: params[:resolve], | ||||
following: params[:following], | following: params[:following], | ||||
limit: params[:limit], | limit: params[:limit], | ||||
offset: params[:offset], | offset: params[:offset], | ||||
type: params[:type], | type: params[:type], | ||||
author: get_author(params), | author: get_author(params), | ||||
embed_relationships: ControllerHelper.embed_relationships?(params), | |||||
for_user: user | for_user: user | ||||
] | ] | ||||
|> Enum.filter(&elem(&1, 1)) | |> Enum.filter(&elem(&1, 1)) | ||||
@@ -90,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do | |||||
users: accounts, | users: accounts, | ||||
for: options[:for_user], | for: options[:for_user], | ||||
as: :user, | as: :user, | ||||
skip_relationships: false | |||||
embed_relationships: options[:embed_relationships] | |||||
) | ) | ||||
end | end | ||||
@@ -100,8 +103,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do | |||||
StatusView.render("index.json", | StatusView.render("index.json", | ||||
activities: statuses, | activities: statuses, | ||||
for: options[:for_user], | for: options[:for_user], | ||||
as: :activity, | |||||
skip_relationships: options[:skip_relationships] | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do | |||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
import Pleroma.Web.ControllerHelper, | 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 | require Ecto.Query | ||||
@@ -105,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do | |||||
`ids` query param is required | `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 | limit = 100 | ||||
activities = | activities = | ||||
@@ -117,8 +117,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do | |||||
render(conn, "index.json", | render(conn, "index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -383,8 +382,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -406,8 +404,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
end | end |
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
import Pleroma.Web.ControllerHelper, | 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.Pagination | ||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | ||||
@@ -63,8 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -88,8 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -125,8 +123,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
end | end | ||||
@@ -173,8 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -203,8 +199,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||||
render(conn, "index.json", | render(conn, "index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
else | else | ||||
_e -> render_error(conn, :forbidden, "Error.") | _e -> render_error(conn, :forbidden, "Error.") | ||||
@@ -15,13 +15,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||||
def render("index.json", %{users: users} = opts) do | def render("index.json", %{users: users} = opts) do | ||||
reading_user = opts[:for] | reading_user = opts[:for] | ||||
# Note: :skip_relationships option is currently intentionally not supported for accounts | |||||
relationships_opt = | relationships_opt = | ||||
cond do | cond do | ||||
Map.has_key?(opts, :relationships) -> | Map.has_key?(opts, :relationships) -> | ||||
opts[:relationships] | opts[:relationships] | ||||
is_nil(reading_user) -> | |||||
is_nil(reading_user) || !opts[:embed_relationships] -> | |||||
UserRelationship.view_relationships_option(nil, []) | UserRelationship.view_relationships_option(nil, []) | ||||
true -> | true -> | ||||
@@ -193,14 +192,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||||
end) | end) | ||||
relationship = | relationship = | ||||
if opts[:skip_relationships] do | |||||
%{} | |||||
else | |||||
if opts[:embed_relationships] do | |||||
render("relationship.json", %{ | render("relationship.json", %{ | ||||
user: opts[:for], | user: opts[:for], | ||||
target: user, | target: user, | ||||
relationships: opts[:relationships] | relationships: opts[:relationships] | ||||
}) | }) | ||||
else | |||||
%{} | |||||
end | end | ||||
%{ | %{ | ||||
@@ -51,9 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do | |||||
|> Enum.filter(& &1) | |> Enum.filter(& &1) | ||||
|> Kernel.++(move_activities_targets) | |> 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 | end | ||||
opts = | opts = | ||||
@@ -83,15 +81,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do | |||||
mastodon_type = Activity.mastodon_notification_type(activity) | 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 <- | with %{id: _} = account <- | ||||
AccountView.render( | AccountView.render( | ||||
"show.json", | "show.json", | ||||
Map.merge(render_opts, %{user: actor, for: reading_user}) | |||||
%{user: actor, for: reading_user} | |||||
) do | ) do | ||||
response = %{ | response = %{ | ||||
id: to_string(notification.id), | id: to_string(notification.id), | ||||
@@ -105,21 +101,20 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do | |||||
case mastodon_type do | case mastodon_type do | ||||
"mention" -> | "mention" -> | ||||
put_status(response, activity, reading_user, render_opts) | |||||
put_status(response, activity, reading_user, status_render_opts) | |||||
"favourite" -> | "favourite" -> | ||||
put_status(response, parent_activity_fn.(), reading_user, render_opts) | |||||
put_status(response, parent_activity_fn.(), reading_user, status_render_opts) | |||||
"reblog" -> | "reblog" -> | ||||
put_status(response, parent_activity_fn.(), reading_user, render_opts) | |||||
put_status(response, parent_activity_fn.(), reading_user, status_render_opts) | |||||
"move" -> | "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" -> | "pleroma:emoji_reaction" -> | ||||
response | response | ||||
|> put_status(parent_activity_fn.(), reading_user, render_opts) | |||||
|> put_status(parent_activity_fn.(), reading_user, status_render_opts) | |||||
|> put_emoji(activity) | |> put_emoji(activity) | ||||
type when type in ["follow", "follow_request"] -> | type when type in ["follow", "follow_request"] -> | ||||
@@ -107,9 +107,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do | |||||
|> Enum.map(&get_user(&1.data["actor"], false)) | |> Enum.map(&get_user(&1.data["actor"], false)) | ||||
|> Enum.filter(& &1) | |> 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 | end | ||||
opts = | opts = | ||||
@@ -162,9 +160,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do | |||||
account: | account: | ||||
AccountView.render("show.json", %{ | AccountView.render("show.json", %{ | ||||
user: user, | user: user, | ||||
for: opts[:for], | |||||
relationships: opts[:relationships], | |||||
skip_relationships: opts[:skip_relationships] | |||||
for: opts[:for] | |||||
}), | }), | ||||
in_reply_to_id: nil, | in_reply_to_id: nil, | ||||
in_reply_to_account_id: nil, | in_reply_to_account_id: nil, | ||||
@@ -330,9 +326,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do | |||||
account: | account: | ||||
AccountView.render("show.json", %{ | AccountView.render("show.json", %{ | ||||
user: user, | 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_id: reply_to && to_string(reply_to.id), | ||||
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), | in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), | ||||
@@ -5,6 +5,7 @@ | |||||
defmodule Pleroma.Web.MongooseIM.MongooseIMController do | defmodule Pleroma.Web.MongooseIM.MongooseIMController do | ||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
alias Pleroma.Plugs.AuthenticationPlug | |||||
alias Pleroma.Plugs.RateLimiter | alias Pleroma.Plugs.RateLimiter | ||||
alias Pleroma.Repo | alias Pleroma.Repo | ||||
alias Pleroma.User | alias Pleroma.User | ||||
@@ -27,7 +28,7 @@ defmodule Pleroma.Web.MongooseIM.MongooseIMController do | |||||
def check_password(conn, %{"user" => username, "pass" => password}) do | def check_password(conn, %{"user" => username, "pass" => password}) do | ||||
with %User{password_hash: password_hash, deactivated: false} <- | with %User{password_hash: password_hash, deactivated: false} <- | ||||
Repo.get_by(User, nickname: username, local: true), | Repo.get_by(User, nickname: username, local: true), | ||||
true <- Pbkdf2.verify_pass(password, password_hash) do | |||||
true <- AuthenticationPlug.checkpw(password, password_hash) do | |||||
conn | conn | ||||
|> json(true) | |> json(true) | ||||
else | else | ||||
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
use Pleroma.Web, :controller | use Pleroma.Web, :controller | ||||
import Pleroma.Web.ControllerHelper, | 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 Ecto.Changeset | ||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | ||||
@@ -19,6 +19,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
require Pleroma.Constants | require Pleroma.Constants | ||||
plug( | plug( | ||||
OpenApiSpex.Plug.PutApiSpec, | |||||
[module: Pleroma.Web.ApiSpec] when action == :confirmation_resend | |||||
) | |||||
plug(Pleroma.Web.ApiSpec.CastAndValidate) | |||||
plug( | |||||
:skip_plug, | :skip_plug, | ||||
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirmation_resend | [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(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe]) | ||||
plug(:put_view, Pleroma.Web.MastodonAPI.AccountView) | 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" | @doc "POST /api/v1/pleroma/accounts/confirmation_resend" | ||||
def confirmation_resend(conn, params) do | 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), | with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email), | ||||
{:ok, _} <- User.try_send_confirmation_email(user) do | {:ok, _} <- User.try_send_confirmation_email(user) do | ||||
@@ -60,7 +69,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
end | end | ||||
@doc "PATCH /api/v1/pleroma/accounts/update_avatar" | @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} = | {:ok, _user} = | ||||
user | user | ||||
|> Changeset.change(%{avatar: nil}) | |> Changeset.change(%{avatar: nil}) | ||||
@@ -69,7 +78,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
json(conn, %{url: nil}) | json(conn, %{url: nil}) | ||||
end | 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, %{data: data}} = ActivityPub.upload(params, type: :avatar) | ||||
{:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache() | {:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache() | ||||
%{"url" => [%{"href" => href} | _]} = data | %{"url" => [%{"href" => href} | _]} = data | ||||
@@ -78,14 +87,14 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
end | end | ||||
@doc "PATCH /api/v1/pleroma/accounts/update_banner" | @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 | with {:ok, _user} <- User.update_banner(user, %{}) do | ||||
json(conn, %{url: nil}) | json(conn, %{url: nil}) | ||||
end | end | ||||
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 | {:ok, _user} <- User.update_banner(user, object.data) do | ||||
%{"url" => [%{"href" => href} | _]} = object.data | %{"url" => [%{"href" => href} | _]} = object.data | ||||
@@ -94,13 +103,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
end | end | ||||
@doc "PATCH /api/v1/pleroma/accounts/update_background" | @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 | with {:ok, _user} <- User.update_background(user, %{}) do | ||||
json(conn, %{url: nil}) | json(conn, %{url: nil}) | ||||
end | end | ||||
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), | with {:ok, object} <- ActivityPub.upload(params, type: :background), | ||||
{:ok, _user} <- User.update_background(user, object.data) do | {:ok, _user} <- User.update_background(user, object.data) do | ||||
%{"url" => [%{"href" => href} | _]} = object.data | %{"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 | def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do | ||||
params = | params = | ||||
params | params | ||||
|> Map.new(fn {key, value} -> {to_string(key), value} end) | |||||
|> Map.put("type", "Create") | |> Map.put("type", "Create") | ||||
|> Map.put("favorited_by", user.ap_id) | |> Map.put("favorited_by", user.ap_id) | ||||
|> Map.put("blocking_user", for_user) | |> Map.put("blocking_user", for_user) | ||||
@@ -139,8 +149,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: for_user, | for: for_user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
end | end | ||||
@@ -5,7 +5,7 @@ | |||||
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | ||||
use Pleroma.Web, :controller | 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.Activity | ||||
alias Pleroma.Conversation.Participation | alias Pleroma.Conversation.Participation | ||||
@@ -69,7 +69,12 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | |||||
%{ | %{ | ||||
name: emoji, | name: emoji, | ||||
count: length(users), | 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) | me: !!(user && user.ap_id in user_ap_ids) | ||||
} | } | ||||
end | end | ||||
@@ -145,8 +150,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | |||||
|> render("index.json", | |> render("index.json", | ||||
activities: activities, | activities: activities, | ||||
for: user, | for: user, | ||||
as: :activity, | |||||
skip_relationships: skip_relationships?(params) | |||||
as: :activity | |||||
) | ) | ||||
else | else | ||||
_error -> | _error -> | ||||
@@ -201,7 +205,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | |||||
end | end | ||||
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 | with notifications <- Notification.set_read_up_to(user, max_id) do | ||||
notifications = Enum.take(notifications, 80) | notifications = Enum.take(notifications, 80) | ||||
@@ -209,8 +213,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do | |||||
|> put_view(NotificationView) | |> put_view(NotificationView) | ||||
|> render("index.json", | |> render("index.json", | ||||
notifications: notifications, | notifications: notifications, | ||||
for: user, | |||||
skip_relationships: skip_relationships?(params) | |||||
for: user | |||||
) | ) | ||||
end | end | ||||
end | end | ||||
@@ -403,6 +403,7 @@ defmodule Pleroma.Web.Router do | |||||
post("/markers", MarkerController, :upsert) | post("/markers", MarkerController, :upsert) | ||||
post("/media", MediaController, :create) | post("/media", MediaController, :create) | ||||
get("/media/:id", MediaController, :show) | |||||
put("/media/:id", MediaController, :update) | put("/media/:id", MediaController, :update) | ||||
get("/notifications", NotificationController, :index) | get("/notifications", NotificationController, :index) | ||||
@@ -497,6 +498,8 @@ defmodule Pleroma.Web.Router do | |||||
scope "/api/v2", Pleroma.Web.MastodonAPI do | scope "/api/v2", Pleroma.Web.MastodonAPI do | ||||
pipe_through(:api) | pipe_through(:api) | ||||
get("/search", SearchController, :search2) | get("/search", SearchController, :search2) | ||||
post("/media", MediaController, :create2) | |||||
end | end | ||||
scope "/api", Pleroma.Web do | scope "/api", Pleroma.Web do | ||||
@@ -127,6 +127,7 @@ defmodule Pleroma.Mixfile do | |||||
{:oban, "~> 1.2"}, | {:oban, "~> 1.2"}, | ||||
{:gettext, "~> 0.15"}, | {:gettext, "~> 0.15"}, | ||||
{:pbkdf2_elixir, "~> 1.0"}, | {:pbkdf2_elixir, "~> 1.0"}, | ||||
{:bcrypt_elixir, "~> 2.0"}, | |||||
{:trailing_format_plug, "~> 0.0.7"}, | {:trailing_format_plug, "~> 0.0.7"}, | ||||
{:fast_sanitize, "~> 0.1"}, | {:fast_sanitize, "~> 0.1"}, | ||||
{:html_entities, "~> 0.5", override: true}, | {:html_entities, "~> 0.5", override: true}, | ||||
@@ -5,6 +5,7 @@ | |||||
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, | "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": {: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"}, | "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"}, | "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"}, | "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"}, | "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": {: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_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"}, | "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"}, | "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"}, | ||||
"eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"}, | "eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"}, | ||||
"ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"}, | "ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"}, | ||||
@@ -8,8 +8,16 @@ | |||||
## to merge POT files into PO files. | ## to merge POT files into PO files. | ||||
msgid "" | msgid "" | ||||
msgstr "" | 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" | "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" | msgid "can't be blank" | ||||
msgstr "ne peut être vide" | msgstr "ne peut être vide" | ||||
@@ -35,10 +43,10 @@ msgid "does not match confirmation" | |||||
msgstr "ne correspondent pas" | msgstr "ne correspondent pas" | ||||
msgid "is still associated with this entry" | msgid "is still associated with this entry" | ||||
msgstr "" | |||||
msgstr "est toujours associé à cette entrée" | |||||
msgid "are still associated with this entry" | msgid "are still associated with this entry" | ||||
msgstr "" | |||||
msgstr "sont toujours associés à cette entrée" | |||||
msgid "should be %{count} character(s)" | msgid "should be %{count} character(s)" | ||||
msgid_plural "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}" | msgid "must be equal to %{number}" | ||||
msgstr "doit égal à %{number}" | msgstr "doit égal à %{number}" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:381 | #: lib/pleroma/web/common_api/common_api.ex:381 | ||||
#, elixir-format | |||||
msgid "Account not found" | msgid "Account not found" | ||||
msgstr "Compte non trouvé" | msgstr "Compte non trouvé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:153 | #: lib/pleroma/web/common_api/common_api.ex:153 | ||||
#, elixir-format | |||||
msgid "Already voted" | msgid "Already voted" | ||||
msgstr "A déjà voté" | msgstr "A déjà voté" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:263 | #: lib/pleroma/web/oauth/oauth_controller.ex:263 | ||||
#, elixir-format | |||||
msgid "Bad request" | msgid "Bad request" | ||||
msgstr "Requête Invalide" | msgstr "Requête Invalide" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:254 | ||||
#, elixir-format | |||||
msgid "Can't delete object" | msgid "Can't delete object" | ||||
msgstr "Ne peut supprimer cet objet" | msgstr "Ne peut supprimer cet objet" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:569 | ||||
#, elixir-format | |||||
msgid "Can't delete this post" | msgid "Can't delete this post" | ||||
msgstr "Ne peut supprimer ce message" | 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:1731 | ||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1737 | ||||
#, elixir-format | |||||
msgid "Can't display this activity" | msgid "Can't display this activity" | ||||
msgstr "Ne peut afficher cette activitée" | msgstr "Ne peut afficher cette activitée" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:195 | ||||
#, elixir-format | |||||
msgid "Can't find user" | msgid "Can't find user" | ||||
msgstr "Compte non trouvé" | msgstr "Compte non trouvé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1148 | ||||
#, elixir-format | |||||
msgid "Can't get favorites" | msgid "Can't get favorites" | ||||
msgstr "Favoris non trouvables" | msgstr "Favoris non trouvables" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:263 | ||||
#, elixir-format | |||||
msgid "Can't like object" | msgid "Can't like object" | ||||
msgstr "Ne peut aimer cet objet" | msgstr "Ne peut aimer cet objet" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/utils.ex:518 | #: lib/pleroma/web/common_api/utils.ex:518 | ||||
#, elixir-format | |||||
msgid "Cannot post an empty status without attachments" | msgid "Cannot post an empty status without attachments" | ||||
msgstr "Ne peut envoyer un status vide sans attachements" | msgstr "Ne peut envoyer un status vide sans attachements" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/utils.ex:461 | #: lib/pleroma/web/common_api/utils.ex:461 | ||||
#, elixir-format | |||||
msgid "Comment must be up to %{max_size} characters" | msgid "Comment must be up to %{max_size} characters" | ||||
msgstr "Le commentaire ne doit faire plus de %{max_size} charactères" | msgstr "Le commentaire ne doit faire plus de %{max_size} charactères" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/admin_api/config.ex:63 | #: lib/pleroma/web/admin_api/config.ex:63 | ||||
#, elixir-format | |||||
msgid "Config with params %{params} not found" | msgid "Config with params %{params} not found" | ||||
msgstr "Configuration avec les paramètres %{params} non trouvée" | msgstr "Configuration avec les paramètres %{params} non trouvée" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:78 | #: lib/pleroma/web/common_api/common_api.ex:78 | ||||
#, elixir-format | |||||
msgid "Could not delete" | msgid "Could not delete" | ||||
msgstr "Échec de la suppression" | msgstr "Échec de la suppression" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:110 | #: lib/pleroma/web/common_api/common_api.ex:110 | ||||
#, elixir-format | |||||
msgid "Could not favorite" | msgid "Could not favorite" | ||||
msgstr "Échec de mise en favoris" | msgstr "Échec de mise en favoris" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:310 | #: lib/pleroma/web/common_api/common_api.ex:310 | ||||
#, elixir-format | |||||
msgid "Could not pin" | msgid "Could not pin" | ||||
msgstr "Échec de l'épinglage" | msgstr "Échec de l'épinglage" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:89 | #: lib/pleroma/web/common_api/common_api.ex:89 | ||||
#, elixir-format | |||||
msgid "Could not repeat" | msgid "Could not repeat" | ||||
msgstr "Échec de création la répétition" | msgstr "Échec de création la répétition" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:120 | #: lib/pleroma/web/common_api/common_api.ex:120 | ||||
#, elixir-format | |||||
msgid "Could not unfavorite" | msgid "Could not unfavorite" | ||||
msgstr "Échec de suppression des favoris" | msgstr "Échec de suppression des favoris" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:327 | #: lib/pleroma/web/common_api/common_api.ex:327 | ||||
#, elixir-format | |||||
msgid "Could not unpin" | msgid "Could not unpin" | ||||
msgstr "Échec du dépinglage" | msgstr "Échec du dépinglage" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:99 | #: lib/pleroma/web/common_api/common_api.ex:99 | ||||
#, elixir-format | |||||
msgid "Could not unrepeat" | msgid "Could not unrepeat" | ||||
msgstr "Échec de suppression de la répétition" | msgstr "Échec de suppression de la répétition" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:392 | #: lib/pleroma/web/common_api/common_api.ex:392 | ||||
#, elixir-format | |||||
msgid "Could not update state" | msgid "Could not update state" | ||||
msgstr "Échec de la mise à jour du status" | msgstr "Échec de la mise à jour du status" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1271 | ||||
#, elixir-format | |||||
msgid "Error." | msgid "Error." | ||||
msgstr "Erreur." | msgstr "Erreur." | ||||
#, elixir-format | |||||
#: lib/pleroma/captcha/kocaptcha.ex:36 | #: lib/pleroma/captcha/kocaptcha.ex:36 | ||||
#, elixir-format | |||||
msgid "Invalid CAPTCHA" | msgid "Invalid CAPTCHA" | ||||
msgstr "CAPTCHA invalide" | msgstr "CAPTCHA invalide" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1700 | ||||
#: lib/pleroma/web/oauth/oauth_controller.ex:465 | #: lib/pleroma/web/oauth/oauth_controller.ex:465 | ||||
#, elixir-format | |||||
msgid "Invalid credentials" | msgid "Invalid credentials" | ||||
msgstr "Paramètres d'authentification invalides" | msgstr "Paramètres d'authentification invalides" | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:20 | #: lib/pleroma/plugs/ensure_authenticated_plug.ex:20 | ||||
#, elixir-format | |||||
msgid "Invalid credentials." | msgid "Invalid credentials." | ||||
msgstr "Paramètres d'authentification invalides." | msgstr "Paramètres d'authentification invalides." | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:154 | #: lib/pleroma/web/common_api/common_api.ex:154 | ||||
#, elixir-format | |||||
msgid "Invalid indices" | msgid "Invalid indices" | ||||
msgstr "Indices invalides" | msgstr "Indices invalides" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:411 | #: lib/pleroma/web/admin_api/admin_api_controller.ex:411 | ||||
#, elixir-format | |||||
msgid "Invalid parameters" | msgid "Invalid parameters" | ||||
msgstr "Paramètres invalides" | msgstr "Paramètres invalides" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/utils.ex:377 | #: lib/pleroma/web/common_api/utils.ex:377 | ||||
#, elixir-format | |||||
msgid "Invalid password." | msgid "Invalid password." | ||||
msgstr "Mot de passe invalide." | msgstr "Mot de passe invalide." | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:163 | ||||
#, elixir-format | |||||
msgid "Invalid request" | msgid "Invalid request" | ||||
msgstr "Requête invalide" | msgstr "Requête invalide" | ||||
#, elixir-format | |||||
#: lib/pleroma/captcha/kocaptcha.ex:16 | #: lib/pleroma/captcha/kocaptcha.ex:16 | ||||
#, elixir-format | |||||
msgid "Kocaptcha service unavailable" | msgid "Kocaptcha service unavailable" | ||||
msgstr "Service Kocaptcha non disponible" | msgstr "Service Kocaptcha non disponible" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1696 | ||||
#, elixir-format | |||||
msgid "Missing parameters" | msgid "Missing parameters" | ||||
msgstr "Paramètres manquants" | msgstr "Paramètres manquants" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/utils.ex:496 | #: lib/pleroma/web/common_api/utils.ex:496 | ||||
#, elixir-format | |||||
msgid "No such conversation" | msgid "No such conversation" | ||||
msgstr "Conversation inconnue" | msgstr "Conversation inconnue" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:163 | #: lib/pleroma/web/admin_api/admin_api_controller.ex:163 | ||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:206 | #: lib/pleroma/web/admin_api/admin_api_controller.ex:206 | ||||
#, elixir-format | |||||
msgid "No such permission_group" | msgid "No such permission_group" | ||||
msgstr "Groupe de permission inconnu" | msgstr "Groupe de permission inconnu" | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/uploaded_media.ex:69 | #: lib/pleroma/plugs/uploaded_media.ex:69 | ||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:311 | ||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:399 | #: lib/pleroma/web/admin_api/admin_api_controller.ex:399 | ||||
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:63 | #: lib/pleroma/web/mastodon_api/subscription_controller.ex:63 | ||||
#: lib/pleroma/web/ostatus/ostatus_controller.ex:248 | #: lib/pleroma/web/ostatus/ostatus_controller.ex:248 | ||||
#, elixir-format | |||||
msgid "Not found" | msgid "Not found" | ||||
msgstr "Non Trouvé" | msgstr "Non Trouvé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:152 | #: lib/pleroma/web/common_api/common_api.ex:152 | ||||
#, elixir-format | |||||
msgid "Poll's author can't vote" | msgid "Poll's author can't vote" | ||||
msgstr "L'auteur·rice d'un sondage ne peut voter" | 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:443 | ||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:444 | #: 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:473 | ||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:476 | #: 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:1180 | ||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1564 | ||||
#, elixir-format | |||||
msgid "Record not found" | msgid "Record not found" | ||||
msgstr "Enregistrement non trouvé" | msgstr "Enregistrement non trouvé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:417 | #: 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/mastodon_api_controller.ex:1570 | ||||
#: lib/pleroma/web/mastodon_api/subscription_controller.ex:69 | #: lib/pleroma/web/mastodon_api/subscription_controller.ex:69 | ||||
#: lib/pleroma/web/ostatus/ostatus_controller.ex:252 | #: lib/pleroma/web/ostatus/ostatus_controller.ex:252 | ||||
#, elixir-format | |||||
msgid "Something went wrong" | msgid "Something went wrong" | ||||
msgstr "Erreur inconnue" | msgstr "Erreur inconnue" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:253 | #: lib/pleroma/web/common_api/common_api.ex:253 | ||||
#, elixir-format | |||||
msgid "The message visibility must be direct" | msgid "The message visibility must be direct" | ||||
msgstr "La visibilitée du message doit être « direct »" | msgstr "La visibilitée du message doit être « direct »" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/utils.ex:521 | #: lib/pleroma/web/common_api/utils.ex:521 | ||||
#, elixir-format | |||||
msgid "The status is over the character limit" | msgid "The status is over the character limit" | ||||
msgstr "Le status est au-delà de la limite de charactères" | msgstr "Le status est au-delà de la limite de charactères" | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27 | #: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:27 | ||||
#, elixir-format | |||||
msgid "This resource requires authentication." | msgid "This resource requires authentication." | ||||
msgstr "Cette resource nécessite une authentification." | msgstr "Cette resource nécessite une authentification." | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/rate_limiter.ex:89 | #: lib/pleroma/plugs/rate_limiter.ex:89 | ||||
#, elixir-format | |||||
msgid "Throttled" | msgid "Throttled" | ||||
msgstr "Limité" | msgstr "Limité" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:155 | #: lib/pleroma/web/common_api/common_api.ex:155 | ||||
#, elixir-format | |||||
msgid "Too many choices" | msgid "Too many choices" | ||||
msgstr "Trop de choix" | msgstr "Trop de choix" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:268 | ||||
#, elixir-format | |||||
msgid "Unhandled activity type" | msgid "Unhandled activity type" | ||||
msgstr "Type d'activitée non-gérée" | msgstr "Type d'activitée non-gérée" | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/user_is_admin_plug.ex:20 | #: lib/pleroma/plugs/user_is_admin_plug.ex:20 | ||||
#, elixir-format | |||||
msgid "User is not admin." | msgid "User is not admin." | ||||
msgstr "Le compte n'est pas admin." | msgstr "Le compte n'est pas admin." | ||||
#, elixir-format | |||||
#: lib/pleroma/web/common_api/common_api.ex:380 | #: lib/pleroma/web/common_api/common_api.ex:380 | ||||
#, elixir-format | |||||
msgid "Valid `account_id` required" | msgid "Valid `account_id` required" | ||||
msgstr "Un `account_id` valide est requis" | msgstr "Un `account_id` valide est requis" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:185 | #: lib/pleroma/web/admin_api/admin_api_controller.ex:185 | ||||
#, elixir-format | |||||
msgid "You can't revoke your own admin status." | msgid "You can't revoke your own admin status." | ||||
msgstr "Vous ne pouvez révoquer votre propre status d'admin." | msgstr "Vous ne pouvez révoquer votre propre status d'admin." | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:216 | #: lib/pleroma/web/oauth/oauth_controller.ex:216 | ||||
#, elixir-format | |||||
msgid "Your account is currently disabled" | msgid "Your account is currently disabled" | ||||
msgstr "Votre compte est actuellement désactivé" | msgstr "Votre compte est actuellement désactivé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:158 | #: lib/pleroma/web/oauth/oauth_controller.ex:158 | ||||
#: lib/pleroma/web/oauth/oauth_controller.ex:213 | #: lib/pleroma/web/oauth/oauth_controller.ex:213 | ||||
#, elixir-format | |||||
msgid "Your login is missing a confirmed e-mail address" | msgid "Your login is missing a confirmed e-mail address" | ||||
msgstr "Une confirmation de l'addresse de couriel est requise pour l'authentification" | 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 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:221 | ||||
#, elixir-format | |||||
msgid "can't read inbox of %{nickname} as %{as_nickname}" | 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}" | 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 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:297 | ||||
#, elixir-format | |||||
msgid "can't update outbox of %{nickname} as %{as_nickname}" | 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}" | 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 | #: lib/pleroma/web/common_api/common_api.ex:335 | ||||
#, elixir-format | |||||
msgid "conversation is already muted" | msgid "conversation is already muted" | ||||
msgstr "la conversation est déjà baillonée" | 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:192 | ||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:317 | #: 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:1196 | ||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:1247 | ||||
#, elixir-format | |||||
msgid "error" | msgid "error" | ||||
msgstr "erreur" | msgstr "erreur" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789 | #: lib/pleroma/web/mastodon_api/mastodon_api_controller.ex:789 | ||||
#, elixir-format | |||||
msgid "mascots can only be images" | msgid "mascots can only be images" | ||||
msgstr "les mascottes ne peuvent être que des images" | msgstr "les mascottes ne peuvent être que des images" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34 | #: lib/pleroma/web/activity_pub/activity_pub_controller.ex:34 | ||||
#, elixir-format | |||||
msgid "not found" | msgid "not found" | ||||
msgstr "non trouvé" | msgstr "non trouvé" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:298 | #: lib/pleroma/web/oauth/oauth_controller.ex:298 | ||||
#, elixir-format | |||||
msgid "Bad OAuth request." | msgid "Bad OAuth request." | ||||
msgstr "Requête OAuth invalide." | msgstr "Requête OAuth invalide." | ||||
#, elixir-format | |||||
#: lib/pleroma/captcha/captcha.ex:92 | #: lib/pleroma/captcha/captcha.ex:92 | ||||
#, elixir-format | |||||
msgid "CAPTCHA already used" | msgid "CAPTCHA already used" | ||||
msgstr "CAPTCHA déjà utilisé" | msgstr "CAPTCHA déjà utilisé" | ||||
#, elixir-format | |||||
#: lib/pleroma/captcha/captcha.ex:89 | #: lib/pleroma/captcha/captcha.ex:89 | ||||
#, elixir-format | |||||
msgid "CAPTCHA expired" | msgid "CAPTCHA expired" | ||||
msgstr "CAPTCHA expiré" | msgstr "CAPTCHA expiré" | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/uploaded_media.ex:50 | #: lib/pleroma/plugs/uploaded_media.ex:50 | ||||
#, elixir-format | |||||
msgid "Failed" | msgid "Failed" | ||||
msgstr "Échec" | msgstr "Échec" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:314 | #: lib/pleroma/web/oauth/oauth_controller.ex:314 | ||||
#, elixir-format | |||||
msgid "Failed to authenticate: %{message}." | 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 | #: lib/pleroma/web/oauth/oauth_controller.ex:345 | ||||
#, elixir-format | |||||
msgid "Failed to set up user account." | msgid "Failed to set up user account." | ||||
msgstr "Échec de création de votre compte." | msgstr "Échec de création de votre compte." | ||||
#, elixir-format | |||||
#: lib/pleroma/plugs/oauth_scopes_plug.ex:37 | #: lib/pleroma/plugs/oauth_scopes_plug.ex:37 | ||||
#, elixir-format | |||||
msgid "Insufficient permissions: %{permissions}." | msgid "Insufficient permissions: %{permissions}." | ||||
msgstr "Permissions insuffisantes: %{permissions}." | |||||
msgstr "Permissions insuffisantes : %{permissions}." | |||||
#, elixir-format | |||||
#: lib/pleroma/plugs/uploaded_media.ex:89 | #: lib/pleroma/plugs/uploaded_media.ex:89 | ||||
#, elixir-format | |||||
msgid "Internal Error" | msgid "Internal Error" | ||||
msgstr "Erreur interne" | msgstr "Erreur interne" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/fallback_controller.ex:22 | #: lib/pleroma/web/oauth/fallback_controller.ex:22 | ||||
#: lib/pleroma/web/oauth/fallback_controller.ex:29 | #: lib/pleroma/web/oauth/fallback_controller.ex:29 | ||||
#, elixir-format | |||||
msgid "Invalid Username/Password" | msgid "Invalid Username/Password" | ||||
msgstr "Nom d'utilisateur/mot de passe invalide" | msgstr "Nom d'utilisateur/mot de passe invalide" | ||||
#, elixir-format | |||||
#: lib/pleroma/captcha/captcha.ex:107 | #: lib/pleroma/captcha/captcha.ex:107 | ||||
#, elixir-format | |||||
msgid "Invalid answer data" | msgid "Invalid answer data" | ||||
msgstr "Réponse invalide" | msgstr "Réponse invalide" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204 | #: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:204 | ||||
#, elixir-format | |||||
msgid "Nodeinfo schema version not handled" | msgid "Nodeinfo schema version not handled" | ||||
msgstr "Version du schéma nodeinfo non géré" | msgstr "Version du schéma nodeinfo non géré" | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:145 | #: lib/pleroma/web/oauth/oauth_controller.ex:145 | ||||
#, elixir-format | |||||
msgid "This action is outside the authorized scopes" | 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 | #: lib/pleroma/web/oauth/fallback_controller.ex:14 | ||||
#, elixir-format | |||||
msgid "Unknown error, please check the details and try again." | msgid "Unknown error, please check the details and try again." | ||||
msgstr "Erreur inconnue, veuillez vérifier les détails et réessayer." | 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:93 | ||||
#: lib/pleroma/web/oauth/oauth_controller.ex:131 | #: lib/pleroma/web/oauth/oauth_controller.ex:131 | ||||
#, elixir-format | |||||
msgid "Unlisted redirect_uri." | msgid "Unlisted redirect_uri." | ||||
msgstr "redirect_uri non listé." | msgstr "redirect_uri non listé." | ||||
#, elixir-format | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:294 | #: lib/pleroma/web/oauth/oauth_controller.ex:294 | ||||
#, elixir-format | |||||
msgid "Unsupported OAuth provider: %{provider}." | msgid "Unsupported OAuth provider: %{provider}." | ||||
msgstr "Fournisseur OAuth non supporté : %{provider}." | msgstr "Fournisseur OAuth non supporté : %{provider}." | ||||
#, elixir-format | |||||
#: lib/pleroma/uploaders/uploader.ex:71 | #: lib/pleroma/uploaders/uploader.ex:71 | ||||
#, elixir-format | |||||
msgid "Uploader callback timeout" | 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:11 | ||||
#: lib/pleroma/web/uploader_controller.ex:23 | #: lib/pleroma/web/uploader_controller.ex:23 | ||||
#, elixir-format | |||||
msgid "bad request" | msgid "bad request" | ||||
msgstr "requête invalide" | msgstr "requête invalide" |
@@ -0,0 +1,578 @@ | |||||
msgid "" | |||||
msgstr "" | |||||
"Project-Id-Version: PACKAGE VERSION\n" | |||||
"Report-Msgid-Bugs-To: \n" | |||||
"POT-Creation-Date: 2020-05-15 09:37+0000\n" | |||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |||||
"Last-Translator: Automatically generated\n" | |||||
"Language-Team: none\n" | |||||
"Language: nl\n" | |||||
"MIME-Version: 1.0\n" | |||||
"Content-Type: text/plain; charset=UTF-8\n" | |||||
"Content-Transfer-Encoding: 8bit\n" | |||||
"X-Generator: Translate Toolkit 2.5.1\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 "" | |||||
## From Ecto.Changeset.unique_constraint/3 | |||||
msgid "has already been taken" | |||||
msgstr "" | |||||
## From Ecto.Changeset.put_change/3 | |||||
msgid "is invalid" | |||||
msgstr "" | |||||
## From Ecto.Changeset.validate_format/3 | |||||
msgid "has invalid format" | |||||
msgstr "" | |||||
## From Ecto.Changeset.validate_subset/3 | |||||
msgid "has an invalid entry" | |||||
msgstr "" | |||||
## 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] "" | |||||
msgid "should have %{count} item(s)" | |||||
msgid_plural "should have %{count} item(s)" | |||||
msgstr[0] "" | |||||
msgstr[1] "" | |||||
msgid "should be at least %{count} character(s)" | |||||
msgid_plural "should be at least %{count} character(s)" | |||||
msgstr[0] "" | |||||
msgstr[1] "" | |||||
msgid "should have at least %{count} item(s)" | |||||
msgid_plural "should have at least %{count} item(s)" | |||||
msgstr[0] "" | |||||
msgstr[1] "" | |||||
msgid "should be at most %{count} character(s)" | |||||
msgid_plural "should be at most %{count} character(s)" | |||||
msgstr[0] "" | |||||
msgstr[1] "" | |||||
msgid "should have at most %{count} item(s)" | |||||
msgid_plural "should have at most %{count} item(s)" | |||||
msgstr[0] "" | |||||
msgstr[1] "" | |||||
## 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 "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:249 | |||||
#, elixir-format | |||||
msgid "Already voted" | |||||
msgstr "" | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:360 | |||||
#, elixir-format | |||||
msgid "Bad request" | |||||
msgstr "" | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:425 | |||||
#, elixir-format | |||||
msgid "Can't delete object" | |||||
msgstr "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:196 | |||||
#, elixir-format | |||||
msgid "Can't delete this post" | |||||
msgstr "" | |||||
#: lib/pleroma/web/controller_helper.ex:95 | |||||
#: lib/pleroma/web/controller_helper.ex:101 | |||||
#, elixir-format | |||||
msgid "Can't display this activity" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/common_api/utils.ex:556 | |||||
#, elixir-format | |||||
msgid "Cannot post an empty status without attachments" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/utils.ex:504 | |||||
#, elixir-format | |||||
msgid "Comment must be up to %{max_size} characters" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:141 | |||||
#, elixir-format | |||||
msgid "Could not favorite" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:370 | |||||
#, elixir-format | |||||
msgid "Could not pin" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:112 | |||||
#, elixir-format | |||||
msgid "Could not repeat" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:188 | |||||
#, elixir-format | |||||
msgid "Could not unfavorite" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:380 | |||||
#, elixir-format | |||||
msgid "Could not unpin" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:126 | |||||
#, elixir-format | |||||
msgid "Could not unrepeat" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:187 | |||||
#, elixir-format | |||||
msgid "Invalid request" | |||||
msgstr "" | |||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:109 | |||||
#, elixir-format | |||||
msgid "Kocaptcha service unavailable" | |||||
msgstr "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:113 | |||||
#, elixir-format | |||||
msgid "Missing parameters" | |||||
msgstr "" | |||||
#: lib/pleroma/web/common_api/utils.ex:540 | |||||
#, elixir-format | |||||
msgid "No such conversation" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/common_api/common_api.ex:241 | |||||
#, elixir-format | |||||
msgid "Poll's author can't vote" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:536 | |||||
#, elixir-format | |||||
msgid "You can't revoke your own admin status." | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:29 | |||||
#, elixir-format | |||||
msgid "mascots can only be images" | |||||
msgstr "" | |||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:60 | |||||
#, elixir-format | |||||
msgid "not found" | |||||
msgstr "" | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:395 | |||||
#, elixir-format | |||||
msgid "Bad OAuth request." | |||||
msgstr "" | |||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:115 | |||||
#, elixir-format | |||||
msgid "CAPTCHA already used" | |||||
msgstr "" | |||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:112 | |||||
#, elixir-format | |||||
msgid "CAPTCHA expired" | |||||
msgstr "" | |||||
#: lib/pleroma/plugs/uploaded_media.ex:55 | |||||
#, elixir-format | |||||
msgid "Failed" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/plugs/uploaded_media.ex:94 | |||||
#, elixir-format | |||||
msgid "Internal Error" | |||||
msgstr "" | |||||
#: lib/pleroma/web/oauth/fallback_controller.ex:22 | |||||
#: lib/pleroma/web/oauth/fallback_controller.ex:29 | |||||
#, elixir-format | |||||
msgid "Invalid Username/Password" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:103 | |||||
#, elixir-format | |||||
msgid "CAPTCHA Error" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92 | |||||
#, elixir-format | |||||
msgid "List not found" | |||||
msgstr "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:124 | |||||
#, elixir-format | |||||
msgid "Missing parameter: %{name}" | |||||
msgstr "" | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:207 | |||||
#: lib/pleroma/web/oauth/oauth_controller.ex:322 | |||||
#, elixir-format | |||||
msgid "Password reset is required" | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:210 | |||||
#, elixir-format | |||||
msgid "Unexpected error occurred while adding file to pack." | |||||
msgstr "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:138 | |||||
#, elixir-format | |||||
msgid "Unexpected error occurred while creating pack." | |||||
msgstr "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:278 | |||||
#, elixir-format | |||||
msgid "Unexpected error occurred while removing file from pack." | |||||
msgstr "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:250 | |||||
#, elixir-format | |||||
msgid "Unexpected error occurred while updating file in pack." | |||||
msgstr "" | |||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:179 | |||||
#, elixir-format | |||||
msgid "Unexpected error occurred while updating pack metadata." | |||||
msgstr "" | |||||
#: 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 "" | |||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:502 | |||||
#, elixir-format | |||||
msgid "You can't revoke your own admin/moderator status." | |||||
msgstr "" | |||||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:105 | |||||
#, elixir-format | |||||
msgid "authorization required for timeline view" | |||||
msgstr "" |
@@ -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-16 17:13+0000\n" | |||||
"Last-Translator: Jędrzej Tomaszewski <jederow@hotmail.com>\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 "jest zarezerwowany" | |||||
## 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 "jest wciąż powiązane z tym wpisem" | |||||
msgid "are still associated with this entry" | |||||
msgstr "są wciąż powiązane z tym wpisem" | |||||
## From Ecto.Changeset.validate_length/3 | |||||
msgid "should be %{count} character(s)" | |||||
msgid_plural "should be %{count} character(s)" | |||||
msgstr[0] "powinno mieć %{count} znak" | |||||
msgstr[1] "powinno mieć %{count} znaki" | |||||
msgstr[2] "powinno mieć %{count} znaków" | |||||
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" |
@@ -1 +1 @@ | |||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.18fea621d430000acc27.css rel=stylesheet><link href=/static/css/app.613cef07981cd95ccceb.css rel=stylesheet><link href=/static/fontello.1588947937982.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.561a1c605d1dfb0e6f74.js></script><script type=text/javascript src=/static/js/app.996428ccaaaa7f28cb8d.js></script></body></html> | |||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.18fea621d430000acc27.css rel=stylesheet><link href=/static/css/app.613cef07981cd95ccceb.css rel=stylesheet><link href=/static/fontello.1589385935077.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.561a1c605d1dfb0e6f74.js></script><script type=text/javascript src=/static/js/app.838ffa9aecf210c7d744.js></script></body></html> |
@@ -1,23 +1,28 @@ | |||||
{ | { | ||||
"theme": "pleroma-dark", | |||||
"alwaysShowSubjectInput": true, | |||||
"background": "/static/aurora_borealis.jpg", | "background": "/static/aurora_borealis.jpg", | ||||
"logo": "/static/logo.png", | |||||
"logoMask": true, | |||||
"logoMargin": ".1em", | |||||
"redirectRootNoLogin": "/main/all", | |||||
"redirectRootLogin": "/main/friends", | |||||
"showInstanceSpecificPanel": false, | |||||
"collapseMessageWithSubject": false, | "collapseMessageWithSubject": false, | ||||
"scopeCopy": true, | |||||
"subjectLineBehavior": "email", | |||||
"postContentType": "text/plain", | |||||
"alwaysShowSubjectInput": true, | |||||
"disableChat": false, | |||||
"greentext": false, | |||||
"hideFilteredStatuses": false, | |||||
"hideMutedPosts": false, | |||||
"hidePostStats": false, | "hidePostStats": false, | ||||
"hideSitename": false, | |||||
"hideUserStats": false, | "hideUserStats": false, | ||||
"loginMethod": "password", | "loginMethod": "password", | ||||
"webPushNotifications": false, | |||||
"logo": "/static/logo.png", | |||||
"logoMargin": ".1em", | |||||
"logoMask": true, | |||||
"minimalScopesMode": false, | |||||
"noAttachmentLinks": false, | "noAttachmentLinks": false, | ||||
"nsfwCensorImage": "", | "nsfwCensorImage": "", | ||||
"postContentType": "text/plain", | |||||
"redirectRootLogin": "/main/friends", | |||||
"redirectRootNoLogin": "/main/all", | |||||
"scopeCopy": true, | |||||
"showFeaturesPanel": true, | "showFeaturesPanel": true, | ||||
"minimalScopesMode": false | |||||
"showInstanceSpecificPanel": false, | |||||
"subjectLineBehavior": "email", | |||||
"theme": "pleroma-dark", | |||||
"webPushNotifications": false | |||||
} | } |
@@ -1,11 +1,11 @@ | |||||
@font-face { | @font-face { | ||||
font-family: "Icons"; | font-family: "Icons"; | ||||
src: url("./font/fontello.1588947937982.eot"); | |||||
src: url("./font/fontello.1588947937982.eot") format("embedded-opentype"), | |||||
url("./font/fontello.1588947937982.woff2") format("woff2"), | |||||
url("./font/fontello.1588947937982.woff") format("woff"), | |||||
url("./font/fontello.1588947937982.ttf") format("truetype"), | |||||
url("./font/fontello.1588947937982.svg") format("svg"); | |||||
src: url("./font/fontello.1589385935077.eot"); | |||||
src: url("./font/fontello.1589385935077.eot") format("embedded-opentype"), | |||||
url("./font/fontello.1589385935077.woff2") format("woff2"), | |||||
url("./font/fontello.1589385935077.woff") format("woff"), | |||||
url("./font/fontello.1589385935077.ttf") format("truetype"), | |||||
url("./font/fontello.1589385935077.svg") format("svg"); | |||||
font-weight: normal; | font-weight: normal; | ||||
font-style: normal; | font-style: normal; | ||||
} | } |
@@ -1,4 +1,4 @@ | |||||
var serviceWorkerOption = {"assets":["/static/fontello.1588947937982.css","/static/font/fontello.1588947937982.eot","/static/font/fontello.1588947937982.svg","/static/font/fontello.1588947937982.ttf","/static/font/fontello.1588947937982.woff","/static/font/fontello.1588947937982.woff2","/static/img/nsfw.74818f9.png","/static/css/app.613cef07981cd95ccceb.css","/static/js/app.996428ccaaaa7f28cb8d.js","/static/css/vendors~app.18fea621d430000acc27.css","/static/js/vendors~app.561a1c605d1dfb0e6f74.js","/static/js/2.18e4adec273c4ce867a8.js"]}; | |||||
var serviceWorkerOption = {"assets":["/static/fontello.1589385935077.css","/static/font/fontello.1589385935077.eot","/static/font/fontello.1589385935077.svg","/static/font/fontello.1589385935077.ttf","/static/font/fontello.1589385935077.woff","/static/font/fontello.1589385935077.woff2","/static/img/nsfw.74818f9.png","/static/css/app.613cef07981cd95ccceb.css","/static/js/app.838ffa9aecf210c7d744.js","/static/css/vendors~app.18fea621d430000acc27.css","/static/js/vendors~app.561a1c605d1dfb0e6f74.js","/static/js/2.18e4adec273c4ce867a8.js"]}; | |||||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){ | !function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){ | ||||
/*! | /*! | ||||
@@ -476,6 +476,14 @@ defmodule Pleroma.ConfigDBTest do | |||||
assert ConfigDB.from_binary(binary) == [key: "value"] | assert ConfigDB.from_binary(binary) == [key: "value"] | ||||
end | 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 | test "keyword" do | ||||
binary = | binary = | ||||
ConfigDB.transform([ | ConfigDB.transform([ | ||||
@@ -11,6 +11,7 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||||
alias Pleroma.User | alias Pleroma.User | ||||
import ExUnit.CaptureLog | import ExUnit.CaptureLog | ||||
import Pleroma.Factory | |||||
setup %{conn: conn} do | setup %{conn: conn} do | ||||
user = %User{ | user = %User{ | ||||
@@ -50,16 +51,41 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug) | assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug) | ||||
end | end | ||||
test "with a wrong password in the credentials, it does nothing", %{conn: conn} do | |||||
test "with a bcrypt hash, it updates to a pkbdf2 hash", %{conn: conn} do | |||||
user = insert(:user, password_hash: Bcrypt.hash_pwd_salt("123")) | |||||
assert "$2" <> _ = user.password_hash | |||||
conn = | conn = | ||||
conn | conn | ||||
|> assign(:auth_credentials, %{password: "wrong"}) | |||||
|> assign(:auth_user, user) | |||||
|> assign(:auth_credentials, %{password: "123"}) | |||||
|> AuthenticationPlug.call(%{}) | |||||
ret_conn = | |||||
assert conn.assigns.user.id == conn.assigns.auth_user.id | |||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug) | |||||
user = User.get_by_id(user.id) | |||||
assert "$pbkdf2" <> _ = user.password_hash | |||||
end | |||||
test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do | |||||
user = | |||||
insert(:user, | |||||
password_hash: | |||||
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" | |||||
) | |||||
conn = | |||||
conn | conn | ||||
|> assign(:auth_user, user) | |||||
|> assign(:auth_credentials, %{password: "password"}) | |||||
|> AuthenticationPlug.call(%{}) | |> AuthenticationPlug.call(%{}) | ||||
assert conn == ret_conn | |||||
assert conn.assigns.user.id == conn.assigns.auth_user.id | |||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug) | |||||
user = User.get_by_id(user.id) | |||||
assert "$pbkdf2" <> _ = user.password_hash | |||||
end | end | ||||
describe "checkpw/2" do | describe "checkpw/2" do | ||||
@@ -79,6 +105,13 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do | |||||
assert AuthenticationPlug.checkpw("password", hash) | assert AuthenticationPlug.checkpw("password", hash) | ||||
end | 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 | test "it returns false when hash invalid" do | ||||
hash = | hash = | ||||
"psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" | "psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" | ||||
@@ -951,7 +951,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||||
test "works with base64 encoded images" do | test "works with base64 encoded images" do | ||||
file = %{ | file = %{ | ||||
"img" => data_uri() | |||||
img: data_uri() | |||||
} | } | ||||
{:ok, %Object{}} = ActivityPub.upload(file) | {:ok, %Object{}} = ActivityPub.upload(file) | ||||
@@ -2509,6 +2509,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
%{"tuple" => [":seconds_valid", 60]}, | %{"tuple" => [":seconds_valid", 60]}, | ||||
%{"tuple" => [":path", ""]}, | %{"tuple" => [":path", ""]}, | ||||
%{"tuple" => [":key1", nil]}, | %{"tuple" => [":key1", nil]}, | ||||
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}, | |||||
%{"tuple" => [":regex1", "~r/https:\/\/example.com/"]}, | %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]}, | ||||
%{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]}, | %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]}, | ||||
%{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]}, | %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]}, | ||||
@@ -2532,6 +2533,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
%{"tuple" => [":seconds_valid", 60]}, | %{"tuple" => [":seconds_valid", 60]}, | ||||
%{"tuple" => [":path", ""]}, | %{"tuple" => [":path", ""]}, | ||||
%{"tuple" => [":key1", nil]}, | %{"tuple" => [":key1", nil]}, | ||||
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}, | |||||
%{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]}, | %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]}, | ||||
%{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]}, | %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]}, | ||||
%{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]}, | %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]}, | ||||
@@ -2544,6 +2546,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
":seconds_valid", | ":seconds_valid", | ||||
":path", | ":path", | ||||
":key1", | ":key1", | ||||
":partial_chain", | |||||
":regex1", | ":regex1", | ||||
":regex2", | ":regex2", | ||||
":regex3", | ":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 %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value | ||||
assert ":proxy_url" in db | assert ":proxy_url" in db | ||||
end | 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 | end | ||||
describe "GET /api/pleroma/admin/restart" do | describe "GET /api/pleroma/admin/restart" do | ||||
@@ -3571,19 +3601,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
end | end | ||||
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 | end | ||||
describe "/api/pleroma/admin/stats" do | describe "/api/pleroma/admin/stats" do | ||||
@@ -15,11 +15,16 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do | |||||
{:ok, [user: user, name: name, password: password]} | {:ok, [user: user, name: name, password: password]} | ||||
end | end | ||||
test "get_user/authorization", %{user: user, name: name, password: password} do | |||||
test "get_user/authorization", %{name: name, password: password} do | |||||
name = name <> "1" | |||||
user = insert(:user, nickname: name, password_hash: Bcrypt.hash_pwd_salt(password)) | |||||
params = %{"authorization" => %{"name" => name, "password" => password}} | params = %{"authorization" => %{"name" => name, "password" => password}} | ||||
res = PleromaAuthenticator.get_user(%Plug.Conn{params: params}) | res = PleromaAuthenticator.get_user(%Plug.Conn{params: params}) | ||||
assert {:ok, user} == res | |||||
assert {:ok, returned_user} = res | |||||
assert returned_user.id == user.id | |||||
assert "$pbkdf2" <> _ = returned_user.password_hash | |||||
end | end | ||||
test "get_user/authorization with invalid password", %{name: name} do | test "get_user/authorization with invalid password", %{name: name} do | ||||
@@ -23,6 +23,18 @@ defmodule Pleroma.Web.CommonAPITest do | |||||
setup do: clear_config([:instance, :limit]) | setup do: clear_config([:instance, :limit]) | ||||
setup do: clear_config([:instance, :max_pinned_statuses]) | 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 | describe "deletion" do | ||||
test "it works with pruned objects" do | test "it works with pruned objects" do | ||||
user = insert(:user) | user = insert(:user) | ||||
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do | |||||
setup do: oauth_access(["write:media"]) | setup do: oauth_access(["write:media"]) | ||||
describe "media upload" do | |||||
describe "Upload media" do | |||||
setup do | setup do | ||||
image = %Plug.Upload{ | image = %Plug.Upload{ | ||||
content_type: "image/jpg", | content_type: "image/jpg", | ||||
@@ -25,13 +25,14 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do | |||||
setup do: clear_config([:media_proxy]) | setup do: clear_config([:media_proxy]) | ||||
setup do: clear_config([Pleroma.Upload]) | 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" | desc = "Description of the image" | ||||
media = | media = | ||||
conn | conn | ||||
|> put_req_header("content-type", "multipart/form-data") | |||||
|> post("/api/v1/media", %{"file" => image, "description" => desc}) | |> post("/api/v1/media", %{"file" => image, "description" => desc}) | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
assert media["type"] == "image" | assert media["type"] == "image" | ||||
assert media["description"] == desc | assert media["description"] == desc | ||||
@@ -40,9 +41,32 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do | |||||
object = Object.get_by_id(media["id"]) | object = Object.get_by_id(media["id"]) | ||||
assert object.data["actor"] == User.ap_id(conn.assigns[:user]) | assert object.data["actor"] == User.ap_id(conn.assigns[:user]) | ||||
end | 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 | end | ||||
describe "PUT /api/v1/media/:id" do | |||||
describe "Update media description" do | |||||
setup %{user: actor} do | setup %{user: actor} do | ||||
file = %Plug.Upload{ | file = %Plug.Upload{ | ||||
content_type: "image/jpg", | content_type: "image/jpg", | ||||
@@ -60,23 +84,45 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do | |||||
[object: object] | [object: object] | ||||
end | end | ||||
test "updates name of media", %{conn: conn, object: object} do | |||||
test "/api/v1/media/:id good request", %{conn: conn, object: object} do | |||||
media = | media = | ||||
conn | conn | ||||
|> put_req_header("content-type", "multipart/form-data") | |||||
|> put("/api/v1/media/#{object.id}", %{"description" => "test-media"}) | |> put("/api/v1/media/#{object.id}", %{"description" => "test-media"}) | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
assert media["description"] == "test-media" | assert media["description"] == "test-media" | ||||
assert refresh_record(object).data["name"] == "test-media" | assert refresh_record(object).data["name"] == "test-media" | ||||
end | 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 = | media = | ||||
conn | 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 | end | ||||
end | end |
@@ -12,9 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do | |||||
import Pleroma.Factory | 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"]) | %{user: user, conn: conn} = oauth_access(["read:notifications"]) | ||||
other_user = insert(:user) | other_user = insert(:user) | ||||
@@ -1176,7 +1176,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do | |||||
end | end | ||||
test "bookmarks" do | test "bookmarks" do | ||||
bookmarks_uri = "/api/v1/bookmarks?with_relationships=true" | |||||
bookmarks_uri = "/api/v1/bookmarks" | |||||
%{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) | %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) | ||||
author = insert(:user) | author = insert(:user) | ||||
@@ -20,12 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do | |||||
describe "home" do | describe "home" do | ||||
setup do: oauth_access(["read:statuses"]) | 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, | user: user, | ||||
conn: conn | conn: conn | ||||
} do | } do | ||||
clear_config([:extensions, :output_relationships_in_statuses_by_default], false) | |||||
other_user = insert(:user) | other_user = insert(:user) | ||||
{:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) | {:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) | ||||
@@ -41,72 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do | |||||
end) | end) | ||||
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 | 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, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"}) | ||||
{:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"}) | {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"}) | ||||
@@ -302,82 +302,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
end | end | ||||
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 | 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"}) | user = insert(:user, pleroma_settings_store: %{fe: "test"}) | ||||
@@ -42,7 +42,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do | |||||
id: to_string(notification.id), | id: to_string(notification.id), | ||||
pleroma: %{is_seen: false}, | pleroma: %{is_seen: false}, | ||||
type: "mention", | 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}), | status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}), | ||||
created_at: Utils.to_masto_date(notification.inserted_at) | created_at: Utils.to_masto_date(notification.inserted_at) | ||||
} | } | ||||
@@ -576,7 +576,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do | |||||
end | end | ||||
end | end | ||||
test "embeds a relationship in the account" do | |||||
test "does not embed a relationship in the account" do | |||||
user = insert(:user) | user = insert(:user) | ||||
other_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}) | 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()) | assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) | ||||
end | 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) | user = insert(:user) | ||||
other_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}) | 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()) | assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) | ||||
end | end | ||||
@@ -31,8 +31,28 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
test "resend account confirmation email", %{conn: conn, user: user} do | test "resend account confirmation email", %{conn: conn, user: user} do | ||||
conn | conn | ||||
|> put_req_header("content-type", "application/json") | |||||
|> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}") | |> 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() | ObanHelpers.perform_all() | ||||
@@ -54,7 +74,10 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
test "user avatar can be set", %{user: user, conn: conn} do | test "user avatar can be set", %{user: user, conn: conn} do | ||||
avatar_image = File.read!("test/fixtures/avatar_data_uri") | 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) | user = refresh_record(user) | ||||
@@ -70,17 +93,20 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
] | ] | ||||
} = user.avatar | } = user.avatar | ||||
assert %{"url" => _} = json_response(conn, 200) | |||||
assert %{"url" => _} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
test "user avatar can be reset", %{user: user, conn: conn} do | 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) | user = User.get_cached_by_id(user.id) | ||||
assert user.avatar == nil | assert user.avatar == nil | ||||
assert %{"url" => nil} = json_response(conn, 200) | |||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
end | end | ||||
@@ -88,21 +114,27 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
setup do: oauth_access(["write:accounts"]) | setup do: oauth_access(["write:accounts"]) | ||||
test "can set profile banner", %{user: user, conn: conn} do | 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) | user = refresh_record(user) | ||||
assert user.banner["type"] == "Image" | assert user.banner["type"] == "Image" | ||||
assert %{"url" => _} = json_response(conn, 200) | |||||
assert %{"url" => _} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
test "can reset profile banner", %{user: user, conn: conn} do | 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) | user = refresh_record(user) | ||||
assert user.banner == %{} | assert user.banner == %{} | ||||
assert %{"url" => nil} = json_response(conn, 200) | |||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
end | end | ||||
@@ -110,19 +142,26 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
setup do: oauth_access(["write:accounts"]) | setup do: oauth_access(["write:accounts"]) | ||||
test "background image can be set", %{user: user, conn: conn} do | 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) | user = refresh_record(user) | ||||
assert user.background["type"] == "Image" | 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 | end | ||||
test "background image can be reset", %{user: user, conn: conn} do | 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) | user = refresh_record(user) | ||||
assert user.background == %{} | assert user.background == %{} | ||||
assert %{"url" => nil} = json_response(conn, 200) | |||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200) | |||||
end | end | ||||
end | end | ||||
@@ -143,7 +182,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
conn | conn | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
[like] = response | [like] = response | ||||
@@ -160,7 +199,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
build_conn() | build_conn() | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(200) | |||||
|> json_response_and_validate_schema(200) | |||||
assert length(response) == 1 | assert length(response) == 1 | ||||
end | end | ||||
@@ -183,7 +222,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
|> assign(:user, u) | |> assign(:user, u) | ||||
|> assign(:token, insert(:oauth_token, user: u, scopes: ["read:favourites"])) | |> assign(:token, insert(:oauth_token, user: u, scopes: ["read:favourites"])) | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
assert length(response) == 1 | assert length(response) == 1 | ||||
end | end | ||||
@@ -191,7 +230,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
build_conn() | build_conn() | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(200) | |||||
|> json_response_and_validate_schema(200) | |||||
assert length(response) == 0 | assert length(response) == 0 | ||||
end | end | ||||
@@ -213,7 +252,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
conn | conn | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
assert Enum.empty?(response) | assert Enum.empty?(response) | ||||
end | end | ||||
@@ -233,11 +272,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
conn | 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 | assert length(response) == 3 | ||||
refute third_activity in response | refute third_activity in response | ||||
@@ -256,8 +296,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
conn | 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 | assert length(response) == 3 | ||||
end | end | ||||
@@ -269,7 +309,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
response = | response = | ||||
conn | conn | ||||
|> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") | ||||
|> json_response(:ok) | |||||
|> json_response_and_validate_schema(:ok) | |||||
assert Enum.empty?(response) | assert Enum.empty?(response) | ||||
end | end | ||||
@@ -277,7 +317,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
test "returns 404 error when specified user is not exist", %{conn: conn} do | test "returns 404 error when specified user is not exist", %{conn: conn} do | ||||
conn = get(conn, "/api/v1/pleroma/accounts/test/favourites") | 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 | end | ||||
test "returns 403 error when user has hidden own favorites", %{conn: conn} do | 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") | 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 | ||||
test "hides favorites for new users by default", %{conn: conn} do | 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 | assert user.hide_favorites | ||||
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites") | 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 | ||||
end | end | ||||
@@ -312,11 +352,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
|> assign(:user, user) | |> assign(:user, user) | ||||
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe") | |> 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") | 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 | ||||
end | end | ||||
@@ -326,7 +367,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
conn = post(conn, "/api/v1/pleroma/accounts/target_id/subscribe") | 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 | ||||
end | end | ||||
@@ -336,7 +377,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
conn = post(conn, "/api/v1/pleroma/accounts/target_id/unsubscribe") | 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 | end | ||||
end | end |