Merge remote-tracking branch 'remotes/origin/develop' into feature/object-hashtags-rework

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Ivan Tashkinov 2021-01-21 20:20:35 +03:00
commit 2634a16b4c
160 changed files with 1414 additions and 425 deletions

View File

@ -8,13 +8,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed ### Changed
- **Breaking:** Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
- Polls now always return a `voters_count`, even if they are single-choice. - Polls now always return a `voters_count`, even if they are single-choice.
- Admin Emails: The ap id is used as the user link in emails now. - Admin Emails: The ap id is used as the user link in emails now.
- Improved registration workflow for email confirmation and account approval modes. - Improved registration workflow for email confirmation and account approval modes.
- **Breaking:** Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
- Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries. - Search: When using Postgres 11+, Pleroma will use the `websearch_to_tsvector` function to parse search queries.
- Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators. - Emoji: Support the full Unicode 13.1 set of Emoji for reactions, plus regional indicators.
- Admin API: Reports now ordered by newest - Admin API: Reports now ordered by newest
- Deprecated `Pleroma.Uploaders.S3, :public_endpoint`. Now `Pleroma.Upload, :base_url` is the standard configuration key for all uploaders.
- Extracted object hashtags into separate table in order to improve hashtag timeline performance (via background migration in `Pleroma.Migrators.HashtagsTableMigrator`). - Extracted object hashtags into separate table in order to improve hashtag timeline performance (via background migration in `Pleroma.Migrators.HashtagsTableMigrator`).
### Added ### Added
@ -32,6 +35,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OAuth form improvements: users are remembered by their cookie, the CSS is overridable by the admin, and the style has been improved. - OAuth form improvements: users are remembered by their cookie, the CSS is overridable by the admin, and the style has been improved.
- OAuth improvements and fixes: more secure session-based authentication (by token that could be revoked anytime), ability to revoke belonging OAuth token from any client etc. - OAuth improvements and fixes: more secure session-based authentication (by token that could be revoked anytime), ability to revoke belonging OAuth token from any client etc.
- Ability to set ActivityPub aliases for follower migration. - Ability to set ActivityPub aliases for follower migration.
- Configurable background job limits for RichMedia (link previews) and MediaProxyWarmingPolicy
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
@ -41,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute. - Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
- Admin API: An endpoint to manage frontends. - Admin API: An endpoint to manage frontends.
- Streaming API: Add follow relationships updates. - Streaming API: Add follow relationships updates.
- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types
</details> </details>
### Fixed ### Fixed
@ -48,6 +54,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Users with `is_discoverable` field set to false (default value) will appear in in-service search results but be hidden from external services (search bots etc.). - Users with `is_discoverable` field set to false (default value) will appear in in-service search results but be hidden from external services (search bots etc.).
- Streaming API: Posts and notifications are not dropped, when CLI task is executing. - Streaming API: Posts and notifications are not dropped, when CLI task is executing.
- Creating incorrect IPv4 address-style HTTP links when encountering certain numbers. - Creating incorrect IPv4 address-style HTTP links when encountering certain numbers.
- Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private.
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
@ -57,11 +64,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased (Patch) ## Unreleased (Patch)
## [2.2.2] - 2020-01-18
### Fixed ### Fixed
- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
- Emoji Reaction activity filtering from blocked and muted accounts.
- StealEmojiPolicy creates dir for emojis, if it doesn't exist. - StealEmojiPolicy creates dir for emojis, if it doesn't exist.
- Updated `elixir_make` to a non-retired version
### Upgrade notes
1. Restart Pleroma
## [2.2.1] - 2020-12-22 ## [2.2.1] - 2020-12-22
@ -77,6 +90,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Rich Media Previews sometimes showed the wrong preview due to a bug following redirects. - Rich Media Previews sometimes showed the wrong preview due to a bug following redirects.
- Fixes for the autolinker. - Fixes for the autolinker.
- Forwarded reports duplication from Pleroma instances. - Forwarded reports duplication from Pleroma instances.
- Emoji Reaction activity filtering from blocked and muted accounts.
- <details> - <details>
<summary>API</summary> <summary>API</summary>

View File

@ -55,7 +55,7 @@ defp generate_user(i) do
name: "Test テスト User #{i}", name: "Test テスト User #{i}",
email: "user#{i}@example.com", email: "user#{i}@example.com",
nickname: "nick#{i}", nickname: "nick#{i}",
password_hash: Pbkdf2.hash_pwd_salt("test"), password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt("test"),
bio: "Tester Number #{i}", bio: "Tester Number #{i}",
local: !remote local: !remote
} }

View File

@ -64,14 +64,23 @@
link_name: false, link_name: false,
proxy_remote: false, proxy_remote: false,
filename_display_max_length: 30, filename_display_max_length: 30,
default_description: nil default_description: nil,
base_url: nil
config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads" config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads"
config :pleroma, Pleroma.Uploaders.S3, config :pleroma, Pleroma.Uploaders.S3,
bucket: nil, bucket: nil,
streaming_enabled: true, bucket_namespace: nil,
public_endpoint: "https://s3.amazonaws.com" truncated_namespace: nil,
streaming_enabled: true
config :ex_aws, :s3,
# host: "s3.wasabisys.com", # required if not Amazon AWS
access_key_id: nil,
secret_access_key: nil,
# region: "us-east-1", # may be required for Amazon AWS
scheme: "https://"
config :pleroma, :emoji, config :pleroma, :emoji,
shortcode_globs: ["/emoji/custom/**/*.png"], shortcode_globs: ["/emoji/custom/**/*.png"],
@ -542,7 +551,7 @@
scheduled_activities: 10, scheduled_activities: 10,
background: 5, background: 5,
remote_fetcher: 2, remote_fetcher: 2,
attachments_cleanup: 5, attachments_cleanup: 1,
new_users_digest: 1, new_users_digest: 1,
mute_expire: 5 mute_expire: 5
], ],
@ -823,6 +832,11 @@
limit_days: 7, limit_days: 7,
dir: nil dir: nil
config :pleroma, ConcurrentLimiter, [
{Pleroma.Web.RichMedia.Helpers, [max_running: 5, max_waiting: 5]},
{Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy, [max_running: 5, max_waiting: 5]}
]
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{Mix.env()}.exs"

View File

@ -149,18 +149,12 @@
description: "S3 bucket namespace", description: "S3 bucket namespace",
suggestions: ["pleroma"] suggestions: ["pleroma"]
}, },
%{
key: :public_endpoint,
type: :string,
description: "S3 endpoint",
suggestions: ["https://s3.amazonaws.com"]
},
%{ %{
key: :truncated_namespace, key: :truncated_namespace,
type: :string, type: :string,
description: description:
"If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc." <> "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc." <>
" For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in public_endpoint." " For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url."
}, },
%{ %{
key: :streaming_enabled, key: :streaming_enabled,
@ -3342,5 +3336,53 @@
suggestions: [:text, :protobuf] suggestions: [:text, :protobuf]
} }
] ]
},
%{
group: :pleroma,
key: ConcurrentLimiter,
type: :group,
description: "Limits configuration for background tasks.",
children: [
%{
key: Pleroma.Web.RichMedia.Helpers,
type: :keyword,
description: "Concurrent limits configuration for getting RichMedia for activities.",
suggestions: [max_running: 5, max_waiting: 5],
children: [
%{
key: :max_running,
type: :integer,
description: "Max running concurrently jobs.",
suggestion: [5]
},
%{
key: :max_waiting,
type: :integer,
description: "Max waiting jobs.",
suggestion: [5]
}
]
},
%{
key: Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy,
type: :keyword,
description: "Concurrent limits configuration for MediaProxyWarmingPolicy.",
suggestions: [max_running: 5, max_waiting: 5],
children: [
%{
key: :max_running,
type: :integer,
description: "Max running concurrently jobs.",
suggestion: [5]
},
%{
key: :max_waiting,
type: :integer,
description: "Max waiting jobs.",
suggestion: [5]
}
]
}
]
} }
] ]

View File

@ -53,7 +53,7 @@
config :pleroma, :dangerzone, override_repo_pool_size: true config :pleroma, :dangerzone, override_repo_pool_size: true
# Reduce hash rounds for testing # Reduce hash rounds for testing
config :pbkdf2_elixir, rounds: 1 config :pleroma, :password, iterations: 1
config :tesla, adapter: Tesla.Mock config :tesla, adapter: Tesla.Mock
@ -115,11 +115,6 @@
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true
config :pleroma, Pleroma.Uploaders.S3,
bucket: nil,
streaming_enabled: true,
public_endpoint: nil
config :tzdata, :autoupdate, :disabled config :tzdata, :autoupdate, :disabled
config :pleroma, :mrf, policies: [] config :pleroma, :mrf, policies: []

View File

@ -549,7 +549,7 @@ the source code is here: [kocaptcha](https://github.com/koto-bank/kocaptcha). Th
* `uploader`: Which one of the [uploaders](#uploaders) to use. * `uploader`: Which one of the [uploaders](#uploaders) to use.
* `filters`: List of [upload filters](#upload-filters) to use. * `filters`: List of [upload filters](#upload-filters) to use.
* `link_name`: When enabled Pleroma will add a `name` parameter to the url of the upload, for example `https://instance.tld/media/corndog.png?name=corndog.png`. This is needed to provide the correct filename in Content-Disposition headers when using filters like `Pleroma.Upload.Filter.Dedupe` * `link_name`: When enabled Pleroma will add a `name` parameter to the url of the upload, for example `https://instance.tld/media/corndog.png?name=corndog.png`. This is needed to provide the correct filename in Content-Disposition headers when using filters like `Pleroma.Upload.Filter.Dedupe`
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host. * `base_url`: The base URL to access a user-uploaded file. Useful when you want to host the media files via another domain or are using a 3rd party S3 provider.
* `proxy_remote`: If you're using a remote uploader, Pleroma will proxy media requests instead of redirecting to it. * `proxy_remote`: If you're using a remote uploader, Pleroma will proxy media requests instead of redirecting to it.
* `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation. * `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation.
* `filename_display_max_length`: Set max length of a filename to display. 0 = no limit. Default: 30. * `filename_display_max_length`: Set max length of a filename to display. 0 = no limit. Default: 30.
@ -570,10 +570,7 @@ Don't forget to configure [Ex AWS S3](#ex-aws-s3-settings)
* `bucket`: S3 bucket name. * `bucket`: S3 bucket name.
* `bucket_namespace`: S3 bucket namespace. * `bucket_namespace`: S3 bucket namespace.
* `public_endpoint`: S3 endpoint that the user finally accesses(ex. "https://s3.dualstack.ap-northeast-1.amazonaws.com")
* `truncated_namespace`: If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or "" etc. * `truncated_namespace`: If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or "" etc.
For example, when using CDN to S3 virtual host format, set "".
At this time, write CNAME to CDN in public_endpoint.
* `streaming_enabled`: Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems. * `streaming_enabled`: Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems.
#### Ex AWS S3 settings #### Ex AWS S3 settings
@ -1113,3 +1110,15 @@ Settings to enable and configure expiration for ephemeral activities
* `:enabled` - enables ephemeral activities creation * `:enabled` - enables ephemeral activities creation
* `:min_lifetime` - minimum lifetime for ephemeral activities (in seconds). Default: 10 minutes. * `:min_lifetime` - minimum lifetime for ephemeral activities (in seconds). Default: 10 minutes.
## ConcurrentLimiter
Settings to restrict concurrently running jobs. Jobs which can be configured:
* `Pleroma.Web.RichMedia.Helpers` - generating link previews of URLs in activities
* `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy` - warming remote media cache via MediaProxyWarmingPolicy
Each job has these settings:
* `:max_running` - max concurrently runnings jobs
* `:max_waiting` - max waiting jobs

View File

@ -1,10 +1,28 @@
# Optimizing your PostgreSQL performance # Optimizing PostgreSQL performance
Pleroma performance depends to a large extent on good database performance. The default PostgreSQL settings are mostly fine, but often you can get better performance by changing a few settings. Pleroma performance is largely dependent on performance of the underlying database. Better performance can be achieved by adjusting a few settings.
You can use [PGTune](https://pgtune.leopard.in.ua) to get recommendations for your setup. If you do, set the "Number of Connections" field to 20, as Pleroma will only use 10 concurrent connections anyway. If you don't, it will give you advice that might even hurt your performance. ## PGTune
We also recommend not using the "Network Storage" option. [PgTune](https://pgtune.leopard.in.ua) can be used to get recommended settings. Be sure to set "Number of Connections" to 20, otherwise it might produce settings hurtful to database performance. It is also recommended to not use "Network Storage" option.
## Disable generic query plans
When PostgreSQL receives a query, it decides on a strategy for searching the requested data, this is called a query plan. The query planner has two modes: generic and custom. Generic makes a plan for all queries of the same shape, ignoring the parameters, which is then cached and reused. Custom, on the contrary, generates a unique query plan based on query parameters.
By default PostgreSQL has an algorithm to decide which mode is more efficient for particular query, however this algorithm has been observed to be wrong on some of the queries Pleroma sends, leading to serious performance loss. Therefore, it is recommended to disable generic mode.
Pleroma already avoids generic query plans by default, however the method it uses is not the most efficient because it needs to be compatible with all supported PostgreSQL versions. For PostgreSQL 12 and higher additional performance can be gained by adding the following to Pleroma configuration:
```elixir
config :pleroma, Pleroma.Repo,
prepare: :named,
parameters: [
plan_cache_mode: "force_custom_plan"
]
```
A more detailed explaination of the issue can be found at <https://blog.soykaf.com/post/postgresql-elixir-troubles/>.
## Example configurations ## Example configurations
@ -28,4 +46,3 @@ max_worker_processes = 2
max_parallel_workers_per_gather = 1 max_parallel_workers_per_gather = 1
max_parallel_workers = 2 max_parallel_workers = 2
``` ```

View File

@ -89,6 +89,8 @@ RUM indexes are an alternative indexing scheme that is not included in PostgreSQ
#### (Optional) Performance configuration #### (Optional) Performance configuration
It is encouraged to check [Optimizing your PostgreSQL performance](../configuration/postgresql.md) document, for tips on PostgreSQL tuning. It is encouraged to check [Optimizing your PostgreSQL performance](../configuration/postgresql.md) document, for tips on PostgreSQL tuning.
Restart PostgreSQL to apply configuration changes:
=== "Alpine" === "Alpine"
``` ```
rc-service postgresql restart rc-service postgresql restart
@ -99,17 +101,6 @@ It is encouraged to check [Optimizing your PostgreSQL performance](../configurat
systemctl restart postgresql systemctl restart postgresql
``` ```
If you are using PostgreSQL 12 or higher, add this to your Ecto database configuration
```elixir
#
config :pleroma, Pleroma.Repo,
prepare: :named,
parameters: [
plan_cache_mode: "force_custom_plan"
]
```
### Installing Pleroma ### Installing Pleroma
```sh ```sh
# Create a Pleroma user # Create a Pleroma user

View File

@ -13,7 +13,8 @@ defmodule Mix.Pleroma do
:flake_id, :flake_id,
:swoosh, :swoosh,
:timex, :timex,
:fast_html :fast_html,
:oban
] ]
@cachex_children ["object", "user", "scrubber", "web_resp"] @cachex_children ["object", "user", "scrubber", "web_resp"]
@doc "Common functions to be reused in mix tasks" @doc "Common functions to be reused in mix tasks"

View File

@ -34,7 +34,7 @@ def run(["resend_confirmation_emails"]) do
Pleroma.User.Query.build(%{ Pleroma.User.Query.build(%{
local: true, local: true,
deactivated: false, deactivated: false,
confirmation_pending: true, is_confirmed: false,
invisible: false invisible: false
}) })
|> Pleroma.Repo.chunk_stream(500) |> Pleroma.Repo.chunk_stream(500)

View File

@ -74,7 +74,7 @@ def run(["new", nickname, email | rest]) do
bio: bio bio: bio
} }
changeset = User.register_changeset(%User{}, params, need_confirmation: false) changeset = User.register_changeset(%User{}, params, is_confirmed: true)
{:ok, _user} = User.register(changeset) {:ok, _user} = User.register(changeset)
shell_info("User #{nickname} created") shell_info("User #{nickname} created")
@ -213,7 +213,7 @@ def run(["set", nickname | rest]) do
user = user =
case Keyword.get(options, :confirmed) do case Keyword.get(options, :confirmed) do
nil -> user nil -> user
value -> set_confirmed(user, value) value -> set_confirmation(user, value)
end end
user = user =
@ -351,7 +351,7 @@ def run(["confirm", nickname]) do
with %User{} = user <- User.get_cached_by_nickname(nickname) do with %User{} = user <- User.get_cached_by_nickname(nickname) do
{:ok, user} = User.confirm(user) {:ok, user} = User.confirm(user)
message = if user.confirmation_pending, do: "needs", else: "doesn't need" message = if !user.is_confirmed, do: "needs", else: "doesn't need"
shell_info("#{nickname} #{message} confirmation.") shell_info("#{nickname} #{message} confirmation.")
else else
@ -373,7 +373,7 @@ def run(["confirm_all"]) do
|> Pleroma.Repo.chunk_stream(500, :batches) |> Pleroma.Repo.chunk_stream(500, :batches)
|> Stream.each(fn users -> |> Stream.each(fn users ->
users users
|> Enum.each(fn user -> User.need_confirmation(user, false) end) |> Enum.each(fn user -> User.set_confirmation(user, true) end)
end) end)
|> Stream.run() |> Stream.run()
end end
@ -391,7 +391,7 @@ def run(["unconfirm_all"]) do
|> Pleroma.Repo.chunk_stream(500, :batches) |> Pleroma.Repo.chunk_stream(500, :batches)
|> Stream.each(fn users -> |> Stream.each(fn users ->
users users
|> Enum.each(fn user -> User.need_confirmation(user, true) end) |> Enum.each(fn user -> User.set_confirmation(user, false) end)
end) end)
|> Stream.run() |> Stream.run()
end end
@ -454,10 +454,10 @@ defp set_locked(user, value) do
user user
end end
defp set_confirmed(user, value) do defp set_confirmation(user, value) do
{:ok, user} = User.need_confirmation(user, !value) {:ok, user} = User.set_confirmation(user, value)
shell_info("Confirmation pending status of #{user.nickname}: #{user.confirmation_pending}") shell_info("Confirmation status of #{user.nickname}: #{user.is_confirmed}")
user user
end end
end end

View File

@ -298,7 +298,16 @@ defp http_children(_, _), do: []
@spec limiters_setup() :: :ok @spec limiters_setup() :: :ok
def limiters_setup do def limiters_setup do
[Pleroma.Web.RichMedia.Helpers, Pleroma.Web.MediaProxy] config = Config.get(ConcurrentLimiter, [])
|> Enum.each(&ConcurrentLimiter.new(&1, 1, 0))
[Pleroma.Web.RichMedia.Helpers, Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy]
|> Enum.each(fn module ->
mod_config = Keyword.get(config, module, [])
max_running = Keyword.get(mod_config, :max_running, 5)
max_waiting = Keyword.get(mod_config, :max_waiting, 5)
ConcurrentLimiter.new(module, max_running, max_waiting)
end)
end end
end end

View File

@ -40,7 +40,8 @@ def warn do
:ok <- check_welcome_message_config(), :ok <- check_welcome_message_config(),
:ok <- check_gun_pool_options(), :ok <- check_gun_pool_options(),
:ok <- check_activity_expiration_config(), :ok <- check_activity_expiration_config(),
:ok <- check_remote_ip_plug_name() do :ok <- check_remote_ip_plug_name(),
:ok <- check_uploders_s3_public_endpoint() do
:ok :ok
else else
_ -> _ ->
@ -193,4 +194,25 @@ def check_remote_ip_plug_name do
warning_preface warning_preface
) )
end end
@spec check_uploders_s3_public_endpoint() :: :ok | nil
def check_uploders_s3_public_endpoint do
s3_config = Pleroma.Config.get([Pleroma.Uploaders.S3])
use_old_config = Keyword.has_key?(s3_config, :public_endpoint)
if use_old_config do
Logger.error("""
!!!DEPRECATION WARNING!!!
Your config is using the old setting for controlling the URL of media uploaded to your S3 bucket.\n
Please make the following change at your earliest convenience.\n
\n* `config :pleroma, Pleroma.Uploaders.S3, public_endpoint` is now equal to:
\n* `config :pleroma, Pleroma.Upload, base_url`
""")
:error
else
:ok
end
end
end end

View File

@ -71,7 +71,7 @@ def invalidate_backup_code(%User{} = user, hash_code) do
@spec generate_backup_codes(User.t()) :: {:ok, list(binary)} | {:error, String.t()} @spec generate_backup_codes(User.t()) :: {:ok, list(binary)} | {:error, String.t()}
def generate_backup_codes(%User{} = user) do def generate_backup_codes(%User{} = user) do
with codes <- BackupCodes.generate(), with codes <- BackupCodes.generate(),
hashed_codes <- Enum.map(codes, &Pbkdf2.hash_pwd_salt/1), hashed_codes <- Enum.map(codes, &Pleroma.Password.Pbkdf2.hash_pwd_salt/1),
changeset <- Changeset.cast_backup_codes(user, hashed_codes), changeset <- Changeset.cast_backup_codes(user, hashed_codes),
{:ok, _} <- User.update_and_set_cache(changeset) do {:ok, _} <- User.update_and_set_cache(changeset) do
{:ok, codes} {:ok, codes}

View File

@ -0,0 +1,55 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Password.Pbkdf2 do
@moduledoc """
This module implements Pbkdf2 passwords in terms of Plug.Crypto.
"""
alias Plug.Crypto.KeyGenerator
def decode64(str) do
str
|> String.replace(".", "+")
|> Base.decode64!(padding: false)
end
def encode64(bin) do
bin
|> Base.encode64(padding: false)
|> String.replace("+", ".")
end
def verify_pass(password, hash) do
["pbkdf2-" <> digest, iterations, salt, hash] = String.split(hash, "$", trim: true)
salt = decode64(salt)
iterations = String.to_integer(iterations)
digest = String.to_atom(digest)
binary_hash =
KeyGenerator.generate(password, salt, digest: digest, iterations: iterations, length: 64)
encode64(binary_hash) == hash
end
def hash_pwd_salt(password, opts \\ []) do
salt =
Keyword.get_lazy(opts, :salt, fn ->
:crypto.strong_rand_bytes(16)
end)
digest = Keyword.get(opts, :digest, :sha512)
iterations =
Keyword.get(opts, :iterations, Pleroma.Config.get([:password, :iterations], 160_000))
binary_hash =
KeyGenerator.generate(password, salt, digest: digest, iterations: iterations, length: 64)
"$pbkdf2-#{digest}$#{iterations}$#{encode64(salt)}$#{encode64(binary_hash)}"
end
end

View File

@ -131,12 +131,7 @@ defp get_opts(opts) do
uploader: Keyword.get(opts, :uploader, Pleroma.Config.get([__MODULE__, :uploader])), uploader: Keyword.get(opts, :uploader, Pleroma.Config.get([__MODULE__, :uploader])),
filters: Keyword.get(opts, :filters, Pleroma.Config.get([__MODULE__, :filters])), filters: Keyword.get(opts, :filters, Pleroma.Config.get([__MODULE__, :filters])),
description: Keyword.get(opts, :description), description: Keyword.get(opts, :description),
base_url: base_url: base_url()
Keyword.get(
opts,
:base_url,
Pleroma.Config.get([__MODULE__, :base_url], Pleroma.Web.base_url())
)
} }
end end
@ -217,14 +212,7 @@ defp url_from_spec(%__MODULE__{name: name}, base_url, {:file, path}) do
"" ""
end end
prefix = [base_url, path]
if is_nil(Pleroma.Config.get([__MODULE__, :base_url])) do
"media"
else
""
end
[base_url, prefix, path]
|> Path.join() |> Path.join()
end end
@ -241,13 +229,15 @@ def base_url do
Pleroma.Uploaders.S3 -> Pleroma.Uploaders.S3 ->
bucket = Config.get([Pleroma.Uploaders.S3, :bucket]) bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
truncated_namespace = Config.get([Pleroma.Uploaders.S3, :truncated_namespace])
namespace = Config.get([Pleroma.Uploaders.S3, :bucket_namespace])
bucket_with_namespace = bucket_with_namespace =
cond do cond do
truncated_namespace = Config.get([Pleroma.Uploaders.S3, :truncated_namespace]) -> !is_nil(truncated_namespace) ->
truncated_namespace truncated_namespace
namespace = Config.get([Pleroma.Uploaders.S3, :bucket_namespace]) -> !is_nil(namespace) ->
namespace <> ":" <> bucket namespace <> ":" <> bucket
true -> true ->
@ -261,7 +251,7 @@ def base_url do
end end
_ -> _ ->
public_endpoint || upload_base_url public_endpoint || upload_base_url || Pleroma.Web.base_url() <> "/media/"
end end
end end
end end

View File

@ -110,9 +110,9 @@ defmodule Pleroma.User do
field(:follower_count, :integer, default: 0) field(:follower_count, :integer, default: 0)
field(:following_count, :integer, default: 0) field(:following_count, :integer, default: 0)
field(:is_locked, :boolean, default: false) field(:is_locked, :boolean, default: false)
field(:confirmation_pending, :boolean, default: false) field(:is_confirmed, :boolean, default: true)
field(:password_reset_pending, :boolean, default: false) field(:password_reset_pending, :boolean, default: false)
field(:approval_pending, :boolean, default: false) field(:is_approved, :boolean, default: true)
field(:registration_reason, :string, default: nil) field(:registration_reason, :string, default: nil)
field(:confirmation_token, :string, default: nil) field(:confirmation_token, :string, default: nil)
field(:default_scope, :string, default: "public") field(:default_scope, :string, default: "public")
@ -288,16 +288,8 @@ def binary_id(%User{} = user), do: binary_id(user.id)
@spec account_status(User.t()) :: account_status() @spec account_status(User.t()) :: account_status()
def account_status(%User{deactivated: true}), do: :deactivated def account_status(%User{deactivated: true}), do: :deactivated
def account_status(%User{password_reset_pending: true}), do: :password_reset_pending def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
def account_status(%User{local: true, approval_pending: true}), do: :approval_pending def account_status(%User{local: true, is_approved: false}), do: :approval_pending
def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending
def account_status(%User{local: true, confirmation_pending: true}) do
if Config.get([:instance, :account_activation_required]) do
:confirmation_pending
else
:active
end
end
def account_status(%User{}), do: :active def account_status(%User{}), do: :active
@spec visible_for(User.t(), User.t() | nil) :: @spec visible_for(User.t(), User.t() | nil) ::
@ -704,23 +696,23 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do
reason_limit = Config.get([:instance, :registration_reason_length], 500) reason_limit = Config.get([:instance, :registration_reason_length], 500)
params = Map.put_new(params, :accepts_chat_messages, true) params = Map.put_new(params, :accepts_chat_messages, true)
need_confirmation? = confirmed? =
if is_nil(opts[:need_confirmation]) do if is_nil(opts[:confirmed]) do
Config.get([:instance, :account_activation_required]) !Config.get([:instance, :account_activation_required])
else else
opts[:need_confirmation] opts[:confirmed]
end end
need_approval? = approved? =
if is_nil(opts[:need_approval]) do if is_nil(opts[:approved]) do
Config.get([:instance, :account_approval_required]) !Config.get([:instance, :account_approval_required])
else else
opts[:need_approval] opts[:approved]
end end
struct struct
|> confirmation_changeset(need_confirmation: need_confirmation?) |> confirmation_changeset(set_confirmation: confirmed?)
|> approval_changeset(need_approval: need_approval?) |> approval_changeset(set_approval: approved?)
|> cast(params, [ |> cast(params, [
:bio, :bio,
:raw_bio, :raw_bio,
@ -808,20 +800,20 @@ def register(%Ecto.Changeset{} = changeset) do
end end
end end
def post_register_action(%User{confirmation_pending: true} = user) do def post_register_action(%User{is_confirmed: false} = user) do
with {:ok, _} <- try_send_confirmation_email(user) do with {:ok, _} <- try_send_confirmation_email(user) do
{:ok, user} {:ok, user}
end end
end end
def post_register_action(%User{approval_pending: true} = user) do def post_register_action(%User{is_approved: false} = user) do
with {:ok, _} <- send_user_approval_email(user), with {:ok, _} <- send_user_approval_email(user),
{:ok, _} <- send_admin_approval_emails(user) do {:ok, _} <- send_admin_approval_emails(user) do
{:ok, user} {:ok, user}
end end
end end
def post_register_action(%User{approval_pending: false, confirmation_pending: false} = user) do def post_register_action(%User{is_approved: true, is_confirmed: true} = user) do
with {:ok, user} <- autofollow_users(user), with {:ok, user} <- autofollow_users(user),
{:ok, _} <- autofollowing_users(user), {:ok, _} <- autofollowing_users(user),
{:ok, user} <- set_cache(user), {:ok, user} <- set_cache(user),
@ -882,7 +874,7 @@ def send_welcome_email(%User{email: email} = user) when is_binary(email) do
def send_welcome_email(_), do: {:ok, :noop} def send_welcome_email(_), do: {:ok, :noop}
@spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop} @spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
def try_send_confirmation_email(%User{confirmation_pending: true, email: email} = user) def try_send_confirmation_email(%User{is_confirmed: false, email: email} = user)
when is_binary(email) do when is_binary(email) do
if Config.get([:instance, :account_activation_required]) do if Config.get([:instance, :account_activation_required]) do
send_confirmation_email(user) send_confirmation_email(user)
@ -1624,8 +1616,8 @@ def approve(users) when is_list(users) do
end) end)
end end
def approve(%User{approval_pending: true} = user) do def approve(%User{is_approved: false} = user) do
with chg <- change(user, approval_pending: false), with chg <- change(user, is_approved: true),
{:ok, user} <- update_and_set_cache(chg) do {:ok, user} <- update_and_set_cache(chg) do
post_register_action(user) post_register_action(user)
{:ok, user} {:ok, user}
@ -1642,8 +1634,8 @@ def confirm(users) when is_list(users) do
end) end)
end end
def confirm(%User{confirmation_pending: true} = user) do def confirm(%User{is_confirmed: false} = user) do
with chg <- confirmation_changeset(user, need_confirmation: false), with chg <- confirmation_changeset(user, set_confirmation: true),
{:ok, user} <- update_and_set_cache(chg) do {:ok, user} <- update_and_set_cache(chg) do
post_register_action(user) post_register_action(user)
{:ok, user} {:ok, user}
@ -1682,9 +1674,9 @@ def purge_user_changeset(user) do
follower_count: 0, follower_count: 0,
following_count: 0, following_count: 0,
is_locked: false, is_locked: false,
confirmation_pending: false, is_confirmed: true,
password_reset_pending: false, password_reset_pending: false,
approval_pending: false, is_approved: true,
registration_reason: nil, registration_reason: nil,
confirmation_token: nil, confirmation_token: nil,
domain_blocks: [], domain_blocks: [],
@ -2138,10 +2130,10 @@ def touch_last_digest_emailed_at(user) do
updated_user updated_user
end end
@spec need_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec set_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
def need_confirmation(%User{} = user, bool) do def set_confirmation(%User{} = user, bool) do
user user
|> confirmation_changeset(need_confirmation: bool) |> confirmation_changeset(set_confirmation: bool)
|> update_and_set_cache() |> update_and_set_cache()
end end
@ -2187,7 +2179,7 @@ def get_ap_ids_by_nicknames(nicknames) do
defp put_password_hash( defp put_password_hash(
%Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset %Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset
) do ) do
change(changeset, password_hash: Pbkdf2.hash_pwd_salt(password)) change(changeset, password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt(password))
end end
defp put_password_hash(changeset), do: changeset defp put_password_hash(changeset), do: changeset
@ -2309,27 +2301,26 @@ def mastodon_settings_update(user, settings) do
end end
@spec confirmation_changeset(User.t(), keyword()) :: Changeset.t() @spec confirmation_changeset(User.t(), keyword()) :: Changeset.t()
def confirmation_changeset(user, need_confirmation: need_confirmation?) do def confirmation_changeset(user, set_confirmation: confirmed?) do
params = params =
if need_confirmation? do if confirmed? do
%{ %{
confirmation_pending: true, is_confirmed: true,
confirmation_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64() confirmation_token: nil
} }
else else
%{ %{
confirmation_pending: false, is_confirmed: false,
confirmation_token: nil confirmation_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64()
} }
end end
cast(user, params, [:confirmation_pending, :confirmation_token]) cast(user, params, [:is_confirmed, :confirmation_token])
end end
@spec approval_changeset(User.t(), keyword()) :: Changeset.t() @spec approval_changeset(User.t(), keyword()) :: Changeset.t()
def approval_changeset(user, need_approval: need_approval?) do def approval_changeset(user, set_approval: approved?) do
params = if need_approval?, do: %{approval_pending: true}, else: %{approval_pending: false} cast(user, %{is_approved: approved?}, [:is_approved])
cast(user, params, [:approval_pending])
end end
def add_pinnned_activity(user, %Pleroma.Activity{id: id}) do def add_pinnned_activity(user, %Pleroma.Activity{id: id}) do

View File

@ -138,7 +138,8 @@ defp compose_query({:external, _}, query), do: location_query(query, false)
defp compose_query({:active, _}, query) do defp compose_query({:active, _}, query) do
User.restrict_deactivated(query) User.restrict_deactivated(query)
|> where([u], u.approval_pending == false) |> where([u], u.is_approved == true)
|> where([u], u.is_confirmed == true)
end end
defp compose_query({:legacy_active, _}, query) do defp compose_query({:legacy_active, _}, query) do
@ -155,15 +156,15 @@ defp compose_query({:deactivated, true}, query) do
end end
defp compose_query({:confirmation_pending, bool}, query) do defp compose_query({:confirmation_pending, bool}, query) do
where(query, [u], u.confirmation_pending == ^bool) where(query, [u], u.is_confirmed != ^bool)
end end
defp compose_query({:need_approval, _}, query) do defp compose_query({:need_approval, _}, query) do
where(query, [u], u.approval_pending) where(query, [u], u.is_approved == false)
end end
defp compose_query({:unconfirmed, _}, query) do defp compose_query({:unconfirmed, _}, query) do
where(query, [u], u.confirmation_pending) where(query, [u], u.is_confirmed == false)
end end
defp compose_query({:followers, %User{id: id}}, query) do defp compose_query({:followers, %User{id: id}}, query) do

View File

@ -30,7 +30,10 @@ def compile_dir(dir) when is_binary(dir) do
""" """
@spec command_available?(String.t()) :: boolean() @spec command_available?(String.t()) :: boolean()
def command_available?(command) do def command_available?(command) do
match?({_output, 0}, System.cmd("sh", ["-c", "command -v #{command}"])) case :os.find_executable(String.to_charlist(command)) do
false -> false
_ -> true
end
end end
@doc "creates the uniq temporary directory" @doc "creates the uniq temporary directory"

View File

@ -27,7 +27,7 @@ defp prefetch(url) do
if Pleroma.Config.get(:env) == :test do if Pleroma.Config.get(:env) == :test do
fetch(prefetch_url) fetch(prefetch_url)
else else
ConcurrentLimiter.limit(MediaProxy, fn -> ConcurrentLimiter.limit(__MODULE__, fn ->
Task.start(fn -> fetch(prefetch_url) end) Task.start(fn -> fetch(prefetch_url) end)
end) end)
end end

View File

@ -77,8 +77,8 @@ def render("show.json", %{user: user}) do
"local" => user.local, "local" => user.local,
"roles" => User.roles(user), "roles" => User.roles(user),
"tags" => user.tags || [], "tags" => user.tags || [],
"confirmation_pending" => user.confirmation_pending, "is_confirmed" => user.is_confirmed,
"approval_pending" => user.approval_pending, "is_approved" => user.is_approved,
"url" => user.uri || user.ap_id, "url" => user.uri || user.ap_id,
"registration_reason" => user.registration_reason, "registration_reason" => user.registration_reason,
"actor_type" => user.actor_type "actor_type" => user.actor_type

View File

@ -191,7 +191,7 @@ defp account_admin do
moderator: %Schema{type: :boolean} moderator: %Schema{type: :boolean}
} }
}, },
confirmation_pending: %Schema{type: :boolean} is_confirmed: %Schema{type: :boolean}
}) })
} }
end end

View File

@ -142,7 +142,7 @@ def admin_account do
} }
}, },
tags: %Schema{type: :string}, tags: %Schema{type: :string},
confirmation_pending: %Schema{type: :string} is_confirmed: %Schema{type: :string}
} }
} }
end end

View File

@ -236,7 +236,7 @@ def chats_response do
"account" => %{ "account" => %{
"pleroma" => %{ "pleroma" => %{
"is_admin" => false, "is_admin" => false,
"confirmation_pending" => false, "is_confirmed" => true,
"hide_followers_count" => false, "hide_followers_count" => false,
"is_moderator" => false, "is_moderator" => false,
"hide_favorites" => true, "hide_favorites" => true,

View File

@ -117,7 +117,7 @@ def reblog_operation do
request_body("Parameters", %Schema{ request_body("Parameters", %Schema{
type: :object, type: :object,
properties: %{ properties: %{
visibility: %Schema{allOf: [VisibilityScope], default: "public"} visibility: %Schema{allOf: [VisibilityScope]}
} }
}), }),
responses: %{ responses: %{

View File

@ -48,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
}, },
background_image: %Schema{type: :string, nullable: true, format: :uri}, background_image: %Schema{type: :string, nullable: true, format: :uri},
chat_token: %Schema{type: :string}, chat_token: %Schema{type: :string},
confirmation_pending: %Schema{ is_confirmed: %Schema{
type: :boolean, type: :boolean,
description: description:
"whether the user account is waiting on email confirmation to be activated" "whether the user account is waiting on email confirmation to be activated"
@ -166,7 +166,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
"pleroma" => %{ "pleroma" => %{
"allow_following_move" => true, "allow_following_move" => true,
"background_image" => nil, "background_image" => nil,
"confirmation_pending" => true, "is_confirmed" => false,
"hide_favorites" => true, "hide_favorites" => true,
"hide_followers" => false, "hide_followers" => false,
"hide_followers_count" => false, "hide_followers_count" => false,

View File

@ -23,7 +23,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Chat do
"account" => %{ "account" => %{
"pleroma" => %{ "pleroma" => %{
"is_admin" => false, "is_admin" => false,
"confirmation_pending" => false, "is_confirmed" => true,
"hide_followers_count" => false, "hide_followers_count" => false,
"is_moderator" => false, "is_moderator" => false,
"hide_favorites" => true, "hide_favorites" => true,

View File

@ -256,7 +256,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
"note" => "Tester Number 6", "note" => "Tester Number 6",
"pleroma" => %{ "pleroma" => %{
"background_image" => nil, "background_image" => nil,
"confirmation_pending" => false, "is_confirmed" => true,
"hide_favorites" => true, "hide_favorites" => true,
"hide_followers" => false, "hide_followers" => false,
"hide_followers_count" => false, "hide_followers_count" => false,

View File

@ -84,7 +84,7 @@ def create_from_registration(
password_confirmation: random_password password_confirmation: random_password
}, },
external: true, external: true,
need_confirmation: false confirmed: true
) )
|> Repo.insert(), |> Repo.insert(),
{:ok, _} <- {:ok, _} <-

View File

@ -266,7 +266,7 @@ defp do_render("show.json", %{user: user} = opts) do
pleroma: %{ pleroma: %{
ap_id: user.ap_id, ap_id: user.ap_id,
also_known_as: user.also_known_as, also_known_as: user.also_known_as,
confirmation_pending: user.confirmation_pending, is_confirmed: user.is_confirmed,
tags: user.tags, tags: user.tags,
hide_followers_count: user.hide_followers_count, hide_followers_count: user.hide_followers_count,
hide_follows_count: user.hide_follows_count, hide_follows_count: user.hide_follows_count,

View File

@ -48,7 +48,7 @@ def checkpw(password, "$2" <> _ = password_hash) do
end end
def checkpw(password, "$pbkdf2" <> _ = password_hash) do def checkpw(password, "$pbkdf2" <> _ = password_hash) do
Pbkdf2.verify_pass(password, password_hash) Pleroma.Password.Pbkdf2.verify_pass(password, password_hash)
end end
def checkpw(_password, _password_hash) do def checkpw(_password, _password_hash) do

View File

@ -30,7 +30,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
with %User{} = user <- User.get_cached_by_id(uid), with %User{} = user <- User.get_cached_by_id(uid),
true <- user.local and user.confirmation_pending and user.confirmation_token == token, true <- user.local and !user.is_confirmed and user.confirmation_token == token,
{:ok, _} <- User.confirm(user) do {:ok, _} <- User.confirm(user) do
redirect(conn, to: "/") redirect(conn, to: "/")
end end

33
mix.exs
View File

@ -123,9 +123,8 @@ defp deps do
{:ecto_enum, "~> 1.4"}, {:ecto_enum, "~> 1.4"},
{:ecto_sql, "~> 3.4.4"}, {:ecto_sql, "~> 3.4.4"},
{:postgrex, ">= 0.15.5"}, {:postgrex, ">= 0.15.5"},
{:oban, "~> 2.1.0"}, {:oban, "~> 2.3.4"},
{:gettext, "~> 0.18"}, {:gettext, "~> 0.18"},
{:pbkdf2_elixir, "~> 1.2"},
{:bcrypt_elixir, "~> 2.2"}, {:bcrypt_elixir, "~> 2.2"},
{:trailing_format_plug, "~> 0.0.7"}, {:trailing_format_plug, "~> 0.0.7"},
{:fast_sanitize, "~> 0.2.0"}, {:fast_sanitize, "~> 0.2.0"},
@ -230,7 +229,9 @@ defp aliases do
"ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"], test: ["ecto.create --quiet", "ecto.migrate", "test"],
docs: ["pleroma.docs", "docs"], docs: ["pleroma.docs", "docs"],
analyze: ["credo --strict --only=warnings,todo,fixme,consistency,readability"] analyze: ["credo --strict --only=warnings,todo,fixme,consistency,readability"],
copyright: &add_copyright/1,
"copyright.bump": &bump_copyright/1
] ]
end end
@ -333,4 +334,30 @@ defp version(version) do
|> Enum.filter(fn string -> string && string != "" end) |> Enum.filter(fn string -> string && string != "" end)
|> Enum.join() |> Enum.join()
end end
defp add_copyright(_) do
year = NaiveDateTime.utc_now().year
template = ~s[\
# Pleroma: A lightweight social networking server
# Copyright © 2017-#{year} Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
] |> String.replace("\n", "\\n")
find = "find lib test priv -type f \\( -name '*.ex' -or -name '*.exs' \\) -exec "
grep = "grep -L '# Copyright © [0-9\-]* Pleroma' {} \\;"
xargs = "xargs -n1 sed -i'' '1s;^;#{template};'"
:os.cmd(String.to_charlist("#{find}#{grep} | #{xargs}"))
end
defp bump_copyright(_) do
year = NaiveDateTime.utc_now().year
find = "find lib test priv -type f \\( -name '*.ex' -or -name '*.exs' \\)"
xargs =
"xargs sed -i'' 's;# Copyright © [0-9\-]* Pleroma.*$;# Copyright © 2017-#{year} Pleroma Authors <https://pleroma.social/>;'"
:os.cmd(String.to_charlist("#{find} | #{xargs}"))
end
end end

View File

@ -15,7 +15,7 @@
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"}, "comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"},
"concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "d81be41024569330f296fc472e24198d7499ba78", [ref: "d81be41024569330f296fc472e24198d7499ba78"]}, "concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "d81be41024569330f296fc472e24198d7499ba78", [ref: "d81be41024569330f296fc472e24198d7499ba78"]},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"cors_plug": {:hex, :cors_plug, "2.0.2", "2b46083af45e4bc79632bd951550509395935d3e7973275b2b743bd63cc942ce", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f0d0e13f71c51fd4ef8b2c7e051388e4dfb267522a83a22392c856de7e46465f"}, "cors_plug": {:hex, :cors_plug, "2.0.2", "2b46083af45e4bc79632bd951550509395935d3e7973275b2b743bd63cc942ce", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f0d0e13f71c51fd4ef8b2c7e051388e4dfb267522a83a22392c856de7e46465f"},
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"}, "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.0", "69fdb5cf92df6373e15675eb4018cf629f5d8e35e74841bb637d6596cb797bbc", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "42868c229d9a2900a1501c5d0355bfd46e24c862c322b0b4f5a6f14fe0216753"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.0", "69fdb5cf92df6373e15675eb4018cf629f5d8e35e74841bb637d6596cb797bbc", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "42868c229d9a2900a1501c5d0355bfd46e24c862c322b0b4f5a6f14fe0216753"},
@ -24,7 +24,7 @@
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/crypt.git", "cf2aa3f11632e8b0634810a15b3e612c7526f6a3", [ref: "cf2aa3f11632e8b0634810a15b3e612c7526f6a3"]}, "crypt": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/crypt.git", "cf2aa3f11632e8b0634810a15b3e612c7526f6a3", [ref: "cf2aa3f11632e8b0634810a15b3e612c7526f6a3"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"}, "db_connection": {:hex, :db_connection, "2.3.1", "4c9f3ed1ef37471cbdd2762d6655be11e38193904d9c5c1c9389f1b891a3088e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "abaab61780dde30301d840417890bd9f74131041afd02174cf4e10635b3a63f5"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"}, "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
@ -81,7 +81,7 @@
"nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"}, "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
"nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"}, "nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
"oban": {:hex, :oban, "2.1.0", "034144686f7e76a102b5d67731f098d98a9e4a52b07c25ad580a01f83a7f1cf5", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c6f067fa3b308ed9e0e6beb2b34277c9c4e48bf95338edabd8f4a757a26e04c2"}, "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
"open_api_spex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", "f296ac0924ba3cf79c7a588c4c252889df4c2edd", [ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"]}, "open_api_spex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", "f296ac0924ba3cf79c7a588c4c252889df4c2edd", [ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"]},
"p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"}, "p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"},
"parse_trans": {:git, "https://github.com/uwiger/parse_trans.git", "76abb347c3c1d00fb0ccf9e4b43e22b3d2288484", [tag: "3.3.0"]}, "parse_trans": {:git, "https://github.com/uwiger/parse_trans.git", "76abb347c3c1d00fb0ccf9e4b43e22b3d2288484", [tag: "3.3.0"]},
@ -97,7 +97,7 @@
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"}, "plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.15.6", "a464c72010a56e3214fe2b99c1a76faab4c2bb0255cabdef30dea763a3569aa2", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "f99268325ac8f66ffd6c4964faab9e70fbf721234ab2ad238c00f9530b8cdd55"}, "postgrex": {:hex, :postgrex, "0.15.7", "724410acd48abac529d0faa6c2a379fb8ae2088e31247687b16cacc0e0883372", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "88310c010ff047cecd73d5ceca1d99205e4b1ab1b9abfdab7e00f5c9d20ef8f9"},
"pot": {:hex, :pot, "0.11.0", "61bad869a94534739dd4614a25a619bc5c47b9970e9a0ea5bef4628036fc7a16", [:rebar3], [], "hexpm", "57ee6ee6bdeb639661ffafb9acefe3c8f966e45394de6a766813bb9e1be4e54b"}, "pot": {:hex, :pot, "0.11.0", "61bad869a94534739dd4614a25a619bc5c47b9970e9a0ea5bef4628036fc7a16", [:rebar3], [], "hexpm", "57ee6ee6bdeb639661ffafb9acefe3c8f966e45394de6a766813bb9e1be4e54b"},
"prometheus": {:hex, :prometheus, "4.6.0", "20510f381db1ccab818b4cf2fac5fa6ab5cc91bc364a154399901c001465f46f", [:mix, :rebar3], [], "hexpm", "4905fd2992f8038eccd7aa0cd22f40637ed618c0bed1f75c05aacec15b7545de"}, "prometheus": {:hex, :prometheus, "4.6.0", "20510f381db1ccab818b4cf2fac5fa6ab5cc91bc364a154399901c001465f46f", [:mix, :rebar3], [], "hexpm", "4905fd2992f8038eccd7aa0cd22f40637ed618c0bed1f75c05aacec15b7545de"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"}, "prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"},

View File

@ -0,0 +1,594 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-18 17:19+0000\n"
"PO-Revision-Date: 2021-01-18 17:54+0000\n"
"Last-Translator: João Rodrigues <joaoadriano3@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pleroma.social/"
"projects/pleroma/pleroma/pt_PT/>\n"
"Language: pt_PT\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\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 "não pode estar em branco"
## From Ecto.Changeset.unique_constraint/3
msgid "has already been taken"
msgstr "já se encontra em utilização"
## From Ecto.Changeset.put_change/3
msgid "is invalid"
msgstr "é inválido"
## From Ecto.Changeset.validate_format/3
msgid "has invalid format"
msgstr "tem um formato inválido"
## From Ecto.Changeset.validate_subset/3
msgid "has an invalid entry"
msgstr "tem uma entrada inválida"
## From Ecto.Changeset.validate_exclusion/3
msgid "is reserved"
msgstr "é reservado"
## From Ecto.Changeset.validate_confirmation/3
msgid "does not match confirmation"
msgstr "não corresponde à confirmação"
## From Ecto.Changeset.no_assoc_constraint/3
msgid "is still associated with this entry"
msgstr "ainda se encontra associado a esta entrada"
msgid "are still associated with this entry"
msgstr "ainda está associado a esta entrada"
## From Ecto.Changeset.validate_length/3
msgid "should be %{count} character(s)"
msgid_plural "should be %{count} character(s)"
msgstr[0] "deve conter %{count} caracter"
msgstr[1] "deve conter %{count} caracteres"
msgid "should have %{count} item(s)"
msgid_plural "should have %{count} item(s)"
msgstr[0] "deve ter %{count} item"
msgstr[1] "deve ter %{count} items"
msgid "should be at least %{count} character(s)"
msgid_plural "should be at least %{count} character(s)"
msgstr[0] "deve ter pelo menos %{count} caracter"
msgstr[1] "deve ter pelo menos %{count} caracteres"
msgid "should have at least %{count} item(s)"
msgid_plural "should have at least %{count} item(s)"
msgstr[0] "deve ter pelo menos %{count} item"
msgstr[1] "deve ter pelo menos %{count} items"
msgid "should be at most %{count} character(s)"
msgid_plural "should be at most %{count} character(s)"
msgstr[0] "deve ter pelo menos %{count} caracter"
msgstr[1] "deve ter pelo menos %{count} caracteres"
msgid "should have at most %{count} item(s)"
msgid_plural "should have at most %{count} item(s)"
msgstr[0] "deve ter pelo menos %{count} item"
msgstr[1] "deve ter pelo menos %{count} items"
## From Ecto.Changeset.validate_number/3
msgid "must be less than %{number}"
msgstr "deve ser menor que %{number}"
msgid "must be greater than %{number}"
msgstr "deve ser maior que %{number}"
msgid "must be less than or equal to %{number}"
msgstr "deve ser menor ou igual que %{number}"
msgid "must be greater than or equal to %{number}"
msgstr "deve ser maior ou igual que %{number}"
msgid "must be equal to %{number}"
msgstr "deve ser igual a %{number}"
#: lib/pleroma/web/common_api/common_api.ex:505
#, elixir-format
msgid "Account not found"
msgstr "Conta não encontrada"
#: lib/pleroma/web/common_api/common_api.ex:339
#, elixir-format
msgid "Already voted"
msgstr "Já votou"
#: lib/pleroma/web/oauth/oauth_controller.ex:359
#, elixir-format
msgid "Bad request"
msgstr "Pedido inválido"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:426
#, elixir-format
msgid "Can't delete object"
msgstr "Não é possível apagar o objeto"
#: lib/pleroma/web/controller_helper.ex:105
#: lib/pleroma/web/controller_helper.ex:111
#, elixir-format
msgid "Can't display this activity"
msgstr "Não é possível exibir esta atividade"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:285
#, elixir-format
msgid "Can't find user"
msgstr "Não foi possível encontrar o utilizador"
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:61
#, elixir-format
msgid "Can't get favorites"
msgstr "Não foi possível obter os favoritos"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:438
#, elixir-format
msgid "Can't like object"
msgstr "Não foi possível gostar do objeto"
#: lib/pleroma/web/common_api/utils.ex:563
#, elixir-format
msgid "Cannot post an empty status without attachments"
msgstr "Não é possível publicar um estado vazio e sem ficheiro anexados"
#: lib/pleroma/web/common_api/utils.ex:511
#, elixir-format
msgid "Comment must be up to %{max_size} characters"
msgstr "Comentários devem ter até %{max_size} caracteres"
#: lib/pleroma/config/config_db.ex:191
#, elixir-format
msgid "Config with params %{params} not found"
msgstr "Configuração com parâmetros %{params} não encontrada"
#: lib/pleroma/web/common_api/common_api.ex:181
#: lib/pleroma/web/common_api/common_api.ex:185
#, elixir-format
msgid "Could not delete"
msgstr "Não foi possível apagar"
#: lib/pleroma/web/common_api/common_api.ex:231
#, elixir-format
msgid "Could not favorite"
msgstr "Não foi possível favoritar"
#: lib/pleroma/web/common_api/common_api.ex:453
#, elixir-format
msgid "Could not pin"
msgstr "Não foi possível fixar"
#: lib/pleroma/web/common_api/common_api.ex:278
#, elixir-format
msgid "Could not unfavorite"
msgstr "Não foi possível retirar favorito"
#: lib/pleroma/web/common_api/common_api.ex:463
#, elixir-format
msgid "Could not unpin"
msgstr "Não foi possível desafixar"
#: lib/pleroma/web/common_api/common_api.ex:216
#, elixir-format
msgid "Could not unrepeat"
msgstr "Não foi possível deixar de repetir"
#: lib/pleroma/web/common_api/common_api.ex:512
#: lib/pleroma/web/common_api/common_api.ex:521
#, elixir-format
msgid "Could not update state"
msgstr "Não foi possível atualizar estado"
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207
#, elixir-format
msgid "Error."
msgstr "Erro."
#: lib/pleroma/web/twitter_api/twitter_api.ex:106
#, elixir-format
msgid "Invalid CAPTCHA"
msgstr "CAPTCHA Inválido"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:116
#: lib/pleroma/web/oauth/oauth_controller.ex:568
#, elixir-format
msgid "Invalid credentials"
msgstr "Credenciais inválidas"
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:38
#, elixir-format
msgid "Invalid credentials."
msgstr "Credenciais inválidas."
#: lib/pleroma/web/common_api/common_api.ex:355
#, elixir-format
msgid "Invalid indices"
msgstr "Índices inválidos"
#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29
#, elixir-format
msgid "Invalid parameters"
msgstr "Parâmetros inválidos"
#: lib/pleroma/web/common_api/utils.ex:414
#, elixir-format
msgid "Invalid password."
msgstr "Palavra-passe inválida."
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:220
#, elixir-format
msgid "Invalid request"
msgstr "Pedido inválido"
#: lib/pleroma/web/twitter_api/twitter_api.ex:109
#, elixir-format
msgid "Kocaptcha service unavailable"
msgstr "Serviço Kocaptcha indisponível"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:112
#, elixir-format
msgid "Missing parameters"
msgstr "Parâmetros em falta"
#: lib/pleroma/web/common_api/utils.ex:547
#, elixir-format
msgid "No such conversation"
msgstr "Não existe tal conversação"
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:388
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:414 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:456
#, elixir-format
msgid "No such permission_group"
msgstr "Não existe permission_group"
#: lib/pleroma/plugs/uploaded_media.ex:84
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:486 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11
#: lib/pleroma/web/feed/user_controller.ex:71 lib/pleroma/web/ostatus/ostatus_controller.ex:143
#, elixir-format
msgid "Not found"
msgstr "Não encontrado"
#: lib/pleroma/web/common_api/common_api.ex:331
#, elixir-format
msgid "Poll's author can't vote"
msgstr "O autor da sondagem não pode votar"
#: 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:306
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71
#, elixir-format
msgid "Record not found"
msgstr "Registo não encontrado"
#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35
#: lib/pleroma/web/feed/user_controller.ex:77 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:36
#: lib/pleroma/web/ostatus/ostatus_controller.ex:149
#, elixir-format
msgid "Something went wrong"
msgstr "Algo ocorreu de errado"
#: lib/pleroma/web/common_api/activity_draft.ex:107
#, elixir-format
msgid "The message visibility must be direct"
msgstr "A visibilidade da mensagem deve ser direta"
#: lib/pleroma/web/common_api/utils.ex:573
#, elixir-format
msgid "The status is over the character limit"
msgstr "O estado está acima do limite de caracteres"
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31
#, elixir-format
msgid "This resource requires authentication."
msgstr "Este recurso requer autenticação."
#: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206
#, elixir-format
msgid "Throttled"
msgstr "Limitado"
#: lib/pleroma/web/common_api/common_api.ex:356
#, elixir-format
msgid "Too many choices"
msgstr "Demasiadas opções"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:443
#, elixir-format
msgid "Unhandled activity type"
msgstr "Tipo de atividade não controlada"
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:485
#, elixir-format
msgid "You can't revoke your own admin status."
msgstr "Não podes revogar o teu próprio estatuto de admin."
#: lib/pleroma/web/oauth/oauth_controller.ex:221
#: lib/pleroma/web/oauth/oauth_controller.ex:308
#, elixir-format
msgid "Your account is currently disabled"
msgstr "A tua conta está atualmente desativada"
#: lib/pleroma/web/oauth/oauth_controller.ex:183
#: lib/pleroma/web/oauth/oauth_controller.ex:331
#, elixir-format
msgid "Your login is missing a confirmed e-mail address"
msgstr ""
"O teu início de sessão necessita que tenhas o endereço de e-mail confirmado"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390
#, elixir-format
msgid "can't read inbox of %{nickname} as %{as_nickname}"
msgstr ""
"não foi possível ler a caixa de entrada de %{nickname} como %{as_nickname}"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:473
#, elixir-format
msgid "can't update outbox of %{nickname} as %{as_nickname}"
msgstr ""
"não foi possível atualizar caixa de saída de %{nickname} como %{as_nickname}"
#: lib/pleroma/web/common_api/common_api.ex:471
#, elixir-format
msgid "conversation is already muted"
msgstr "conversação já silenciada"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:314
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:492
#, elixir-format
msgid "error"
msgstr "erro"
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:32
#, elixir-format
msgid "mascots can only be images"
msgstr "mascotes apenas podem ser imagens"
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:62
#, elixir-format
msgid "not found"
msgstr "não encontrado"
#: lib/pleroma/web/oauth/oauth_controller.ex:394
#, elixir-format
msgid "Bad OAuth request."
msgstr "Pedido OAuth inválido."
#: lib/pleroma/web/twitter_api/twitter_api.ex:115
#, elixir-format
msgid "CAPTCHA already used"
msgstr "CPATCHA já utilizado"
#: lib/pleroma/web/twitter_api/twitter_api.ex:112
#, elixir-format
msgid "CAPTCHA expired"
msgstr "CAPTCHA expirado"
#: lib/pleroma/plugs/uploaded_media.ex:57
#, elixir-format
msgid "Failed"
msgstr "Falhou"
#: lib/pleroma/web/oauth/oauth_controller.ex:410
#, elixir-format
msgid "Failed to authenticate: %{message}."
msgstr "Falha ao autenticar: %{message}."
#: lib/pleroma/web/oauth/oauth_controller.ex:441
#, elixir-format
msgid "Failed to set up user account."
msgstr "Falha ao configurar conta de utilizador."
#: lib/pleroma/plugs/oauth_scopes_plug.ex:38
#, elixir-format
msgid "Insufficient permissions: %{permissions}."
msgstr "Permissões insuficientes: %{permissions}."
#: lib/pleroma/plugs/uploaded_media.ex:104
#, elixir-format
msgid "Internal Error"
msgstr "Erro Interno"
#: lib/pleroma/web/oauth/fallback_controller.ex:22
#: lib/pleroma/web/oauth/fallback_controller.ex:29
#, elixir-format
msgid "Invalid Username/Password"
msgstr "Nome de Utilizador/Palavra-passe inválidos"
#: lib/pleroma/web/twitter_api/twitter_api.ex:118
#, elixir-format
msgid "Invalid answer data"
msgstr "Informação de resposta inválida"
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33
#, elixir-format
msgid "Nodeinfo schema version not handled"
msgstr "Versão do schema de nodeinfo não tratado"
#: lib/pleroma/web/oauth/oauth_controller.ex:172
#, elixir-format
msgid "This action is outside the authorized scopes"
msgstr "Esta ação está fora dos escopos autorizados"
#: lib/pleroma/web/oauth/fallback_controller.ex:14
#, elixir-format
msgid "Unknown error, please check the details and try again."
msgstr "Erro desconhecido, verifica os detalhes e tenta novamente."
#: lib/pleroma/web/oauth/oauth_controller.ex:119
#: lib/pleroma/web/oauth/oauth_controller.ex:158
#, elixir-format
msgid "Unlisted redirect_uri."
msgstr "redirect_uri não listado."
#: lib/pleroma/web/oauth/oauth_controller.ex:390
#, elixir-format
msgid "Unsupported OAuth provider: %{provider}."
msgstr "Portal OAuth não suportado: %{provider}."
#: lib/pleroma/uploaders/uploader.ex:72
#, elixir-format
msgid "Uploader callback timeout"
msgstr "Tempo expirado para callback de quem envia"
#: lib/pleroma/web/uploader_controller.ex:23
#, elixir-format
msgid "bad request"
msgstr "pedido inválido"
#: lib/pleroma/web/twitter_api/twitter_api.ex:103
#, elixir-format
msgid "CAPTCHA Error"
msgstr "Erro de CAPTCHA"
#: lib/pleroma/web/common_api/common_api.ex:290
#, elixir-format
msgid "Could not add reaction emoji"
msgstr "Não foi possível adicionar reação"
#: lib/pleroma/web/common_api/common_api.ex:301
#, elixir-format
msgid "Could not remove reaction emoji"
msgstr "Não foi possível remover reação"
#: lib/pleroma/web/twitter_api/twitter_api.ex:129
#, elixir-format
msgid "Invalid CAPTCHA (Missing parameter: %{name})"
msgstr "CAPTCHA inválido (Falta o parâmetro: %{name})"
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92
#, elixir-format
msgid "List not found"
msgstr "Lista não encontrada"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:123
#, elixir-format
msgid "Missing parameter: %{name}"
msgstr "Parâmetro em falta: %{name}"
#: lib/pleroma/web/oauth/oauth_controller.ex:210
#: lib/pleroma/web/oauth/oauth_controller.ex:321
#, elixir-format
msgid "Password reset is required"
msgstr "É necessário repor palavra-passe"
#: lib/pleroma/tests/auth_test_controller.ex:9
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6
#: lib/pleroma/web/admin_api/controllers/config_controller.ex:6 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:6
#: lib/pleroma/web/admin_api/controllers/invite_controller.ex:6 lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex:6
#: lib/pleroma/web/admin_api/controllers/oauth_app_controller.ex:6 lib/pleroma/web/admin_api/controllers/relay_controller.ex:6
#: lib/pleroma/web/admin_api/controllers/report_controller.ex:6 lib/pleroma/web/admin_api/controllers/status_controller.ex:6
#: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/embed_controller.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/chat_controller.ex:5 lib/pleroma/web/pleroma_api/controllers/conversation_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:2 lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex:6
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/notification_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 ""
"Violação de segurança: a verificação de escopo OAuth não foi nem tratada nem "
"explicitamente ignorada."
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:28
#, elixir-format
msgid "Two-factor authentication enabled, you must use a access token."
msgstr ""
"Autenticação de dois fatores ativada, deves utilizar uma token de acesso."
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:210
#, elixir-format
msgid "Unexpected error occurred while adding file to pack."
msgstr "Ocorreu um erro inesperado ao adicionar ficheiro ao pack."
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:138
#, elixir-format
msgid "Unexpected error occurred while creating pack."
msgstr "Ocorreu um erro inesperado ao criar o pack."
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:278
#, elixir-format
msgid "Unexpected error occurred while removing file from pack."
msgstr "Ocorreu um erro inesperado ao remover ficheiro do pack."
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:250
#, elixir-format
msgid "Unexpected error occurred while updating file in pack."
msgstr "Ocorreu um erro inesperado a atualizar ficheiro no pack."
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:179
#, elixir-format
msgid "Unexpected error occurred while updating pack metadata."
msgstr "Ocorreu um erro inesperado a atualizar os metadados do pack."
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61
#, elixir-format
msgid "Web push subscription is disabled on this Pleroma instance"
msgstr ""
"Subscrição de notificações push no browser está desativada nesta instância "
"do Pleroma"
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:451
#, elixir-format
msgid "You can't revoke your own admin/moderator status."
msgstr "Não podes revogar o teu próprio estatuto de admin/moderador."
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:126
#, elixir-format
msgid "authorization required for timeline view"
msgstr "autorização necessária para visualizar cronologia"
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24
#, elixir-format
msgid "Access denied"
msgstr "Acesso negado"
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:282
#, elixir-format
msgid "This API requires an authenticated user"
msgstr "Esta API requer um utilizador autenticado"
#: lib/pleroma/plugs/user_is_admin_plug.ex:21
#, elixir-format
msgid "User is not an admin."
msgstr "Utilizador não é um admin."

View File

@ -1,6 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddObanJobsTable do defmodule Pleroma.Repo.Migrations.AddObanJobsTable do
use Ecto.Migration use Ecto.Migration
defdelegate up, to: Oban.Migrations def up do
Oban.Migrations.up(version: 2)
end
defdelegate down, to: Oban.Migrations defdelegate down, to: Oban.Migrations
end end

View File

@ -6,6 +6,6 @@ def up do
end end
def down do def down do
Oban.Migrations.down(version: 2) Oban.Migrations.down(version: 3)
end end
end end

View File

@ -6,6 +6,6 @@ def up do
end end
def down do def down do
Oban.Migrations.down(version: 7) Oban.Migrations.down(version: 8)
end end
end end

View File

@ -6,6 +6,8 @@ defmodule Pleroma.Repo.Migrations.MoveActivityExpirationsToOban do
def change do def change do
Pleroma.Config.Oban.warn() Pleroma.Config.Oban.warn()
Application.ensure_all_started(:oban)
Supervisor.start_link([{Oban, Pleroma.Config.get(Oban)}], Supervisor.start_link([{Oban, Pleroma.Config.get(Oban)}],
strategy: :one_for_one, strategy: :one_for_one,
name: Pleroma.Supervisor name: Pleroma.Supervisor

View File

@ -6,6 +6,8 @@ defmodule Pleroma.Repo.Migrations.MoveTokensExpirationIntoOban do
def change do def change do
Pleroma.Config.Oban.warn() Pleroma.Config.Oban.warn()
Application.ensure_all_started(:oban)
Supervisor.start_link([{Oban, Pleroma.Config.get(Oban)}], Supervisor.start_link([{Oban, Pleroma.Config.get(Oban)}],
strategy: :one_for_one, strategy: :one_for_one,
name: Pleroma.Supervisor name: Pleroma.Supervisor

View File

@ -0,0 +1,20 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.RefactorConfirmationPendingUserField do
use Ecto.Migration
def up do
# Flip the values before we change the meaning of the column
execute("UPDATE users SET confirmation_pending = NOT confirmation_pending;")
execute("ALTER TABLE users RENAME COLUMN confirmation_pending TO is_confirmed;")
execute("ALTER TABLE users ALTER COLUMN is_confirmed SET DEFAULT true;")
end
def down do
execute("UPDATE users SET is_confirmed = NOT is_confirmed;")
execute("ALTER TABLE users RENAME COLUMN is_confirmed TO confirmation_pending;")
execute("ALTER TABLE users ALTER COLUMN confirmation_pending SET DEFAULT false;")
end
end

View File

@ -0,0 +1,20 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.RefactorApprovalPendingUserField do
use Ecto.Migration
def up do
# Flip the values before we change the meaning of the column
execute("UPDATE users SET approval_pending = NOT approval_pending;")
execute("ALTER TABLE users RENAME COLUMN approval_pending TO is_approved;")
execute("ALTER TABLE users ALTER COLUMN is_approved SET DEFAULT true;")
end
def down do
execute("UPDATE users SET is_approved = NOT is_approved;")
execute("ALTER TABLE users RENAME COLUMN is_approved TO approval_pending;")
execute("ALTER TABLE users ALTER COLUMN approval_pending SET DEFAULT false;")
end
end

View File

@ -11,9 +11,9 @@ defmodule Pleroma.Repo.Migrations.ConfirmLoggedInUsers do
def up do def up do
User User
|> where([u], u.confirmation_pending == true) |> where([u], u.is_confirmed == false)
|> join(:inner, [u], t in Token, on: t.user_id == u.id) |> join(:inner, [u], t in Token, on: t.user_id == u.id)
|> Repo.update_all(set: [confirmation_pending: false]) |> Repo.update_all(set: [is_confirmed: true])
end end
def down do def down do

View File

@ -0,0 +1,57 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.DeprecatePublicEndpoint do
use Ecto.Migration
def up do
with %Pleroma.ConfigDB{} = s3_config <-
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Uploaders.S3}),
%Pleroma.ConfigDB{} = upload_config <-
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Upload}) do
public_endpoint = s3_config.value[:public_endpoint]
if !is_nil(public_endpoint) do
upload_value = upload_config.value |> Keyword.merge(base_url: public_endpoint)
upload_config
|> Ecto.Changeset.change(value: upload_value)
|> Pleroma.Repo.update()
s3_value = s3_config.value |> Keyword.delete(:public_endpoint)
s3_config
|> Ecto.Changeset.change(value: s3_value)
|> Pleroma.Repo.update()
end
else
_ -> :ok
end
end
def down do
with %Pleroma.ConfigDB{} = upload_config <-
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Upload}),
%Pleroma.ConfigDB{} = s3_config <-
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Uploaders.S3}) do
base_url = upload_config.value[:base_url]
if !is_nil(base_url) do
s3_value = s3_config.value |> Keyword.merge(public_endpoint: base_url)
s3_config
|> Ecto.Changeset.change(value: s3_value)
|> Pleroma.Repo.update()
upload_value = upload_config.value |> Keyword.delete(:base_url)
upload_config
|> Ecto.Changeset.change(value: upload_value)
|> Pleroma.Repo.update()
end
else
_ -> :ok
end
end
end

View File

@ -0,0 +1,15 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.UpgradeObanJobsToV9 do
use Ecto.Migration
def up do
Oban.Migrations.up(version: 9)
end
def down do
Oban.Migrations.down(version: 9)
end
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.f77689d7.css rel=stylesheet><link href=chunk-libs.5cf7f50a.css rel=stylesheet><link href=app.6fb984d1.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.ba96836e.js></script><script type=text/javascript src=static/js/chunk-elementUI.21957ec8.js></script><script type=text/javascript src=static/js/chunk-libs.32ea9181.js></script><script type=text/javascript src=static/js/app.c67f9a2f.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.f77689d7.css rel=stylesheet><link href=chunk-libs.5cf7f50a.css rel=stylesheet><link href=app.6fb984d1.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.5c1034c4.js></script><script type=text/javascript src=static/js/chunk-elementUI.21957ec8.js></script><script type=text/javascript src=static/js/chunk-libs.5ca2c8e8.js></script><script type=text/javascript src=static/js/app.01bfc983.js></script></body></html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More