Merge branch 'develop' into '2435-list-multiple-users'
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
229acae6c3
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -8,13 +8,19 @@ 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**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
|
||||||
|
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||||
|
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
|
||||||
|
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
|
||||||
- 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.
|
||||||
|
- Improved Apache webserver support: updated sample configuration, MediaProxy cache invalidation verified with the included sample script
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
@ -31,6 +37,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>
|
||||||
|
@ -48,18 +56,30 @@ 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.
|
||||||
|
- Tag URLs in statuses are now absolute
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
- Mastodon API: Current user is now included in conversation if it's the only participant.
|
- Mastodon API: Current user is now included in conversation if it's the only participant.
|
||||||
- Mastodon API: Fixed last_status.account being not filled with account data.
|
- Mastodon API: Fixed last_status.account being not filled with account data.
|
||||||
- Mastodon API: Fix not being able to add or remove multiple users at once in lists.
|
- Mastodon API: Fix not being able to add or remove multiple users at once in lists.
|
||||||
|
- Mastodon API: Fixed own_votes being not returned with poll data.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Unreleased (Patch)
|
## Unreleased (Patch)
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.2] - 2020-01-18
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- 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
|
||||||
|
|
||||||
|
|
|
@ -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"],
|
||||||
|
@ -429,7 +438,9 @@
|
||||||
headers: [],
|
headers: [],
|
||||||
options: []
|
options: []
|
||||||
|
|
||||||
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, script_path: nil
|
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script,
|
||||||
|
script_path: nil,
|
||||||
|
url_format: nil
|
||||||
|
|
||||||
# Note: media preview proxy depends on media proxy to be enabled
|
# Note: media preview proxy depends on media proxy to be enabled
|
||||||
config :pleroma, :media_preview_proxy,
|
config :pleroma, :media_preview_proxy,
|
||||||
|
@ -823,6 +834,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"
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -1633,13 +1627,20 @@
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: Pleroma.Web.MediaProxy.Invalidation.Script,
|
key: Pleroma.Web.MediaProxy.Invalidation.Script,
|
||||||
type: :group,
|
type: :group,
|
||||||
description: "Script invalidate settings",
|
description: "Invalidation script settings",
|
||||||
children: [
|
children: [
|
||||||
%{
|
%{
|
||||||
key: :script_path,
|
key: :script_path,
|
||||||
type: :string,
|
type: :string,
|
||||||
description: "Path to shell script. Which will run purge cache.",
|
description: "Path to executable script which will purge cached items.",
|
||||||
suggestions: ["./installation/nginx-cache-purge.sh.example"]
|
suggestions: ["./installation/nginx-cache-purge.sh.example"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :url_format,
|
||||||
|
type: :string,
|
||||||
|
description:
|
||||||
|
"Optional URL format preprocessing. Only required for Apache's htcacheclean.",
|
||||||
|
suggestions: [":htcacheclean"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -3336,5 +3337,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]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -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: []
|
||||||
|
|
|
@ -133,22 +133,20 @@
|
||||||
mix pleroma.user sign_out <nickname>
|
mix pleroma.user sign_out <nickname>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Activate a user
|
||||||
## Deactivate or activate a user
|
|
||||||
|
|
||||||
=== "OTP"
|
=== "OTP"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./bin/pleroma_ctl user toggle_activated <nickname>
|
./bin/pleroma_ctl user activate NICKNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "From Source"
|
=== "From Source"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mix pleroma.user toggle_activated <nickname>
|
mix pleroma.user activate NICKNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Deactivate a user and unsubscribes local users from the user
|
## Deactivate a user and unsubscribes local users from the user
|
||||||
|
|
||||||
=== "OTP"
|
=== "OTP"
|
||||||
|
|
|
@ -321,9 +321,10 @@ This section describe PWA manifest instance-specific values. Currently this opti
|
||||||
#### Pleroma.Web.MediaProxy.Invalidation.Script
|
#### Pleroma.Web.MediaProxy.Invalidation.Script
|
||||||
|
|
||||||
This strategy allow perform external shell script to purge cache.
|
This strategy allow perform external shell script to purge cache.
|
||||||
Urls of attachments pass to script as arguments.
|
Urls of attachments are passed to the script as arguments.
|
||||||
|
|
||||||
* `script_path`: path to external script.
|
* `script_path`: Path to the external script.
|
||||||
|
* `url_format`: Set to `:htcacheclean` if using Apache's htcacheclean utility.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -549,7 +550,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 +571,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 +1111,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
|
||||||
|
|
|
@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
||||||
|
|
|
@ -100,7 +100,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
||||||
|
|
|
@ -98,7 +98,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ sudo -Hu pleroma mix pleroma.instance gen
|
||||||
|
|
||||||
* コンフィギュレーションを確認して、もし問題なければ、ファイル名を変更してください。
|
* コンフィギュレーションを確認して、もし問題なければ、ファイル名を変更してください。
|
||||||
```
|
```
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。
|
* 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# A simple shell script to delete a media from Apache's mod_disk_cache.
|
||||||
|
# You will likely need to setup a sudo rule like the following:
|
||||||
|
#
|
||||||
|
# Cmnd_Alias HTCACHECLEAN = /usr/local/sbin/htcacheclean
|
||||||
|
# pleroma ALL=HTCACHECLEAN, NOPASSWD: HTCACHECLEAN
|
||||||
|
#
|
||||||
|
# Please also ensure you have enabled:
|
||||||
|
#
|
||||||
|
# config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, url_format: :htcacheclean
|
||||||
|
#
|
||||||
|
# which will correctly format the URLs passed to this script for the htcacheclean utility.
|
||||||
|
#
|
||||||
|
|
||||||
|
SCRIPTNAME=${0##*/}
|
||||||
|
|
||||||
|
# mod_disk_cache directory
|
||||||
|
CACHE_DIRECTORY="/tmp/pleroma-media-cache"
|
||||||
|
|
||||||
|
## Removes an item via the htcacheclean utility
|
||||||
|
## $1 - the filename, can be a pattern .
|
||||||
|
## $2 - the cache directory.
|
||||||
|
purge_item() {
|
||||||
|
sudo htcacheclean -v -p "${2}" "${1}"
|
||||||
|
} # purge_item
|
||||||
|
|
||||||
|
purge() {
|
||||||
|
for url in $@
|
||||||
|
do
|
||||||
|
echo "$SCRIPTNAME delete \`$url\` from cache ($CACHE_DIRECTORY)"
|
||||||
|
purge_item "$url" $CACHE_DIRECTORY
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
purge $@
|
|
@ -1,73 +1,84 @@
|
||||||
# default Apache site config for Pleroma
|
# Sample Apache config for Pleroma
|
||||||
#
|
|
||||||
# needed modules: define headers proxy proxy_http proxy_wstunnel rewrite ssl
|
|
||||||
# optional modules: cache cache_disk
|
|
||||||
#
|
#
|
||||||
# Simple installation instructions:
|
# Simple installation instructions:
|
||||||
# 1. Install your TLS certificate, possibly using Let's Encrypt.
|
# 1. Install your TLS certificate. We recommend using Let's Encrypt via Certbot
|
||||||
# 2. Replace 'example.tld' with your instance's domain wherever it appears.
|
# 2. Replace 'example.tld' with your instance's domain.
|
||||||
# 3. This assumes a Debian style Apache config. Copy this file to
|
# 3. This assumes a Debian-style Apache config. Copy this file to
|
||||||
# /etc/apache2/sites-available/ and then add a symlink to it in
|
# /etc/apache2/sites-available/ and then activate the site by running
|
||||||
# /etc/apache2/sites-enabled/ by running 'a2ensite pleroma-apache.conf', then restart Apache.
|
# 'a2ensite pleroma-apache.conf', then restart Apache.
|
||||||
#
|
#
|
||||||
# Optional: enable disk-based caching for the media proxy
|
# Optional: enable disk-based caching for the media proxy
|
||||||
# For details, see https://git.pleroma.social/pleroma/pleroma/wikis/How%20to%20activate%20mediaproxy
|
# For details, see https://git.pleroma.social/pleroma/pleroma/wikis/How%20to%20activate%20mediaproxy
|
||||||
#
|
#
|
||||||
# 1. Create the directory listed below as the CacheRoot, and make sure
|
# 1. Create a directory as shown below for the CacheRoot and make sure
|
||||||
# the Apache user can write to it.
|
# the Apache user can write to it.
|
||||||
# 2. Configure Apache's htcacheclean to clean the directory periodically.
|
# 2. Configure Apache's htcacheclean to clean the directory periodically.
|
||||||
# 3. Run 'a2enmod cache cache_disk' and restart Apache.
|
# Your OS may provide a service you can enable to do this automatically.
|
||||||
|
|
||||||
Define servername example.tld
|
Define servername example.tld
|
||||||
|
|
||||||
|
<IfModule !proxy_module>
|
||||||
|
LoadModule proxy_module libexec/apache24/mod_proxy.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !proxy_http_module>
|
||||||
|
LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !proxy_wstunnel_module>
|
||||||
|
LoadModule proxy_wstunnel_module libexec/apache24/mod_proxy_wstunnel.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !rewrite_module>
|
||||||
|
LoadModule rewrite_module libexec/apache24/mod_rewrite.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !ssl_module>
|
||||||
|
LoadModule ssl_module libexec/apache24/mod_ssl.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !cache_module>
|
||||||
|
LoadModule cache_module libexec/apache24/mod_cache.so
|
||||||
|
</IfModule>
|
||||||
|
<IfModule !cache_disk_module>
|
||||||
|
LoadModule cache_disk_module libexec/apache24/mod_cache_disk.so
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
ServerName ${servername}
|
ServerName ${servername}
|
||||||
ServerTokens Prod
|
ServerTokens Prod
|
||||||
|
|
||||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
# If you want Pleroma-specific logs
|
||||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
#ErrorLog /var/log/httpd-pleroma-error.log
|
||||||
|
#CustomLog /var/log/httpd-pleroma-access.log combined
|
||||||
|
|
||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
Redirect permanent / https://${servername}
|
RewriteEngine on
|
||||||
|
RewriteCond %{SERVER_NAME} =${servername}
|
||||||
|
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
<VirtualHost *:443>
|
<VirtualHost *:443>
|
||||||
SSLEngine on
|
SSLEngine on
|
||||||
SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem
|
SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem
|
||||||
SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem
|
SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem
|
||||||
|
# Make sure you have the certbot-apache module installed
|
||||||
|
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||||
|
|
||||||
# Mozilla modern configuration, tweak to your needs
|
# Uncomment the following to enable MediaProxy caching on disk
|
||||||
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
|
#CacheRoot /tmp/pleroma-media-cache/
|
||||||
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
|
#CacheDirLevels 1
|
||||||
SSLHonorCipherOrder on
|
#CacheDirLength 2
|
||||||
SSLCompression off
|
#CacheEnable disk /proxy
|
||||||
SSLSessionTickets off
|
#CacheLock on
|
||||||
|
#CacheHeader on
|
||||||
# uncomment the following to enable mediaproxy caching on disk
|
#CacheDetailHeader on
|
||||||
# <IfModule mod_cache_disk.c>
|
## 16MB max filesize for caching, configure as desired
|
||||||
# CacheRoot /var/cache/apache2/mod_cache_disk
|
#CacheMaxFileSize 16000000
|
||||||
# CacheDirLevels 1
|
#CacheDefaultExpire 86400
|
||||||
# CacheDirLength 2
|
|
||||||
# CacheEnable disk /proxy
|
|
||||||
# CacheLock on
|
|
||||||
# </IfModule>
|
|
||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
RewriteCond %{HTTP:Connection} Upgrade [NC]
|
RewriteCond %{HTTP:Connection} Upgrade [NC]
|
||||||
RewriteCond %{HTTP:Upgrade} websocket [NC]
|
RewriteCond %{HTTP:Upgrade} websocket [NC]
|
||||||
RewriteRule /(.*) ws://localhost:4000/$1 [P,L]
|
RewriteRule /(.*) ws://127.0.0.1:4000/$1 [P,L]
|
||||||
|
|
||||||
|
#ProxyRequests must be off or you open your server to abuse as an open proxy
|
||||||
ProxyRequests off
|
ProxyRequests off
|
||||||
# this is explicitly IPv4 since Pleroma.Web.Endpoint binds on IPv4 only
|
|
||||||
# and `localhost.` resolves to [::0] on some systems: see issue #930
|
|
||||||
ProxyPass / http://127.0.0.1:4000/
|
ProxyPass / http://127.0.0.1:4000/
|
||||||
ProxyPassReverse / http://127.0.0.1:4000/
|
ProxyPassReverse / http://127.0.0.1:4000/
|
||||||
|
|
||||||
RequestHeader set Host ${servername}
|
|
||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
# OCSP Stapling, only in httpd 2.3.3 and later
|
|
||||||
SSLUseStapling on
|
|
||||||
SSLStaplingResponderTimeout 5
|
|
||||||
SSLStaplingReturnResponderErrors off
|
|
||||||
SSLStaplingCache shmcb:/var/run/ocsp(128000)
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -33,8 +33,8 @@ def run(["resend_confirmation_emails"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
confirmation_pending: true,
|
is_confirmed: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
})
|
})
|
||||||
|> Pleroma.Repo.chunk_stream(500)
|
|> Pleroma.Repo.chunk_stream(500)
|
||||||
|
|
|
@ -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")
|
||||||
|
@ -107,21 +107,6 @@ def run(["rm", nickname]) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(["toggle_activated", nickname]) do
|
|
||||||
start_pleroma()
|
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
|
||||||
{:ok, user} = User.deactivate(user, !user.deactivated)
|
|
||||||
|
|
||||||
shell_info(
|
|
||||||
"Activation status of #{nickname}: #{if(user.deactivated, do: "de", else: "")}activated"
|
|
||||||
)
|
|
||||||
else
|
|
||||||
_ ->
|
|
||||||
shell_error("No user #{nickname}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def run(["reset_password", nickname]) do
|
def run(["reset_password", nickname]) do
|
||||||
start_pleroma()
|
start_pleroma()
|
||||||
|
|
||||||
|
@ -156,20 +141,41 @@ def run(["reset_mfa", nickname]) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def run(["activate", nickname]) do
|
||||||
|
start_pleroma()
|
||||||
|
|
||||||
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
|
false <- user.is_active do
|
||||||
|
User.set_activation(user, true)
|
||||||
|
:timer.sleep(500)
|
||||||
|
|
||||||
|
shell_info("Successfully activated #{nickname}")
|
||||||
|
else
|
||||||
|
true ->
|
||||||
|
shell_info("User #{nickname} already activated")
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
shell_error("No user #{nickname}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def run(["deactivate", nickname]) do
|
def run(["deactivate", nickname]) do
|
||||||
start_pleroma()
|
start_pleroma()
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
shell_info("Deactivating #{user.nickname}")
|
true <- user.is_active do
|
||||||
User.deactivate(user)
|
User.set_activation(user, false)
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
|
|
||||||
user = User.get_cached_by_id(user.id)
|
user = User.get_cached_by_id(user.id)
|
||||||
|
|
||||||
if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do
|
if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do
|
||||||
shell_info("Successfully unsubscribed all local followers from #{user.nickname}")
|
shell_info("Successfully deactivated #{nickname} and unsubscribed all local followers")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
false ->
|
||||||
|
shell_info("User #{nickname} already deactivated")
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
shell_error("No user #{nickname}")
|
shell_error("No user #{nickname}")
|
||||||
end
|
end
|
||||||
|
@ -213,7 +219,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 +357,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
|
||||||
|
@ -365,7 +371,7 @@ def run(["confirm_all"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
|
@ -373,7 +379,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
|
||||||
|
@ -383,7 +389,7 @@ def run(["unconfirm_all"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
|
@ -391,7 +397,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
|
||||||
|
@ -420,7 +426,7 @@ def run(["list"]) do
|
||||||
shell_info(
|
shell_info(
|
||||||
"#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{
|
"#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{
|
||||||
user.is_locked
|
user.is_locked
|
||||||
}, deactivated: #{user.deactivated}"
|
}, is_active: #{user.is_active}"
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -454,10 +460,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
|
||||||
|
|
|
@ -297,7 +297,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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -152,7 +152,7 @@ def get_follow_requests(%User{id: id}) do
|
||||||
|> join(:inner, [r], f in assoc(r, :follower))
|
|> join(:inner, [r], f in assoc(r, :follower))
|
||||||
|> where([r], r.state == ^:follow_pending)
|
|> where([r], r.state == ^:follow_pending)
|
||||||
|> where([r], r.following_id == ^id)
|
|> where([r], r.following_id == ^id)
|
||||||
|> where([r, f], f.deactivated != true)
|
|> where([r, f], f.is_active == true)
|
||||||
|> select([r, f], f)
|
|> select([r, f], f)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
|
@ -115,7 +115,7 @@ def for_user_query(user, opts \\ %{}) do
|
||||||
|> where(
|
|> where(
|
||||||
[n, a],
|
[n, a],
|
||||||
fragment(
|
fragment(
|
||||||
"? not in (SELECT ap_id FROM users WHERE deactivated = 'true')",
|
"? not in (SELECT ap_id FROM users WHERE is_active = 'false')",
|
||||||
a.actor
|
a.actor
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -75,7 +75,7 @@ def calculate_stat_data do
|
||||||
|
|
||||||
users_query =
|
users_query =
|
||||||
from(u in User,
|
from(u in User,
|
||||||
where: u.deactivated != true,
|
where: u.is_active == true,
|
||||||
where: u.local == true,
|
where: u.local == true,
|
||||||
where: not is_nil(u.nickname),
|
where: not is_nil(u.nickname),
|
||||||
where: not u.invisible
|
where: not u.invisible
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -110,14 +110,14 @@ 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")
|
||||||
field(:domain_blocks, {:array, :string}, default: [])
|
field(:domain_blocks, {:array, :string}, default: [])
|
||||||
field(:deactivated, :boolean, default: false)
|
field(:is_active, :boolean, default: true)
|
||||||
field(:no_rich_text, :boolean, default: false)
|
field(:no_rich_text, :boolean, default: false)
|
||||||
field(:ap_enabled, :boolean, default: false)
|
field(:ap_enabled, :boolean, default: false)
|
||||||
field(:is_moderator, :boolean, default: false)
|
field(:is_moderator, :boolean, default: false)
|
||||||
|
@ -217,7 +217,8 @@ def unquote(:"#{outgoing_relation_target}_relation")(user, restrict_deactivated?
|
||||||
target_users_query = assoc(user, unquote(outgoing_relation_target))
|
target_users_query = assoc(user, unquote(outgoing_relation_target))
|
||||||
|
|
||||||
if restrict_deactivated? do
|
if restrict_deactivated? do
|
||||||
restrict_deactivated(target_users_query)
|
target_users_query
|
||||||
|
|> User.Query.build(%{deactivated: false})
|
||||||
else
|
else
|
||||||
target_users_query
|
target_users_query
|
||||||
end
|
end
|
||||||
|
@ -286,18 +287,10 @@ def binary_id(%User{} = user), do: binary_id(user.id)
|
||||||
|
|
||||||
@doc "Returns status account"
|
@doc "Returns status account"
|
||||||
@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{is_active: false}), 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) ::
|
||||||
|
@ -386,11 +379,6 @@ def ap_followers(%User{} = user), do: "#{ap_id(user)}/followers"
|
||||||
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
||||||
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
||||||
|
|
||||||
@spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t()
|
|
||||||
def restrict_deactivated(query) do
|
|
||||||
from(u in query, where: u.deactivated != ^true)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp truncate_fields_param(params) do
|
defp truncate_fields_param(params) do
|
||||||
if Map.has_key?(params, :fields) do
|
if Map.has_key?(params, :fields) do
|
||||||
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
|
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
|
||||||
|
@ -704,23 +692,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,
|
||||||
|
@ -785,7 +773,7 @@ defp autofollow_users(user) do
|
||||||
candidates = Config.get([:instance, :autofollowed_nicknames])
|
candidates = Config.get([:instance, :autofollowed_nicknames])
|
||||||
|
|
||||||
autofollowed_users =
|
autofollowed_users =
|
||||||
User.Query.build(%{nickname: candidates, local: true, deactivated: false})
|
User.Query.build(%{nickname: candidates, local: true, is_active: true})
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
|
||||||
follow_all(user, autofollowed_users)
|
follow_all(user, autofollowed_users)
|
||||||
|
@ -808,20 +796,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 +870,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)
|
||||||
|
@ -946,7 +934,7 @@ def follow(%User{} = follower, %User{} = followed, state \\ :follow_accept) do
|
||||||
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
|
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
followed.deactivated ->
|
not followed.is_active ->
|
||||||
{:error, "Could not follow user: #{followed.nickname} is deactivated."}
|
{:error, "Could not follow user: #{followed.nickname} is deactivated."}
|
||||||
|
|
||||||
deny_follow_blocked and blocks?(followed, follower) ->
|
deny_follow_blocked and blocks?(followed, follower) ->
|
||||||
|
@ -1181,7 +1169,7 @@ def get_or_fetch_by_nickname(nickname) do
|
||||||
|
|
||||||
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
||||||
def get_followers_query(%User{} = user, nil) do
|
def get_followers_query(%User{} = user, nil) do
|
||||||
User.Query.build(%{followers: user, deactivated: false})
|
User.Query.build(%{followers: user, is_active: true})
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_followers_query(%User{} = user, page) do
|
def get_followers_query(%User{} = user, page) do
|
||||||
|
@ -1357,7 +1345,7 @@ def update_following_count(%User{local: true} = user) do
|
||||||
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
|
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
|
||||||
def get_users_from_set(ap_ids, opts \\ []) do
|
def get_users_from_set(ap_ids, opts \\ []) do
|
||||||
local_only = Keyword.get(opts, :local_only, true)
|
local_only = Keyword.get(opts, :local_only, true)
|
||||||
criteria = %{ap_id: ap_ids, deactivated: false}
|
criteria = %{ap_id: ap_ids, is_active: true}
|
||||||
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
|
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
|
||||||
|
|
||||||
User.Query.build(criteria)
|
User.Query.build(criteria)
|
||||||
|
@ -1368,7 +1356,7 @@ def get_users_from_set(ap_ids, opts \\ []) do
|
||||||
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
|
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
|
||||||
to = [actor | to]
|
to = [actor | to]
|
||||||
|
|
||||||
query = User.Query.build(%{recipients_from_activity: to, local: true, deactivated: false})
|
query = User.Query.build(%{recipients_from_activity: to, local: true, is_active: true})
|
||||||
|
|
||||||
query
|
query
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
@ -1587,19 +1575,19 @@ defp maybe_filter_on_ap_id(query, ap_ids) when is_list(ap_ids) do
|
||||||
|
|
||||||
defp maybe_filter_on_ap_id(query, _ap_ids), do: query
|
defp maybe_filter_on_ap_id(query, _ap_ids), do: query
|
||||||
|
|
||||||
def deactivate_async(user, status \\ true) do
|
def set_activation_async(user, status \\ true) do
|
||||||
BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
|
BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status})
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate(user, status \\ true)
|
@spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
|
||||||
|
def set_activation(users, status) when is_list(users) do
|
||||||
def deactivate(users, status) when is_list(users) do
|
|
||||||
Repo.transaction(fn ->
|
Repo.transaction(fn ->
|
||||||
for user <- users, do: deactivate(user, status)
|
for user <- users, do: set_activation(user, status)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate(%User{} = user, status) do
|
@spec set_activation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
|
||||||
|
def set_activation(%User{} = user, status) do
|
||||||
with {:ok, user} <- set_activation_status(user, status) do
|
with {:ok, user} <- set_activation_status(user, status) do
|
||||||
user
|
user
|
||||||
|> get_followers()
|
|> get_followers()
|
||||||
|
@ -1624,8 +1612,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 +1630,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,13 +1670,13 @@ 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: [],
|
||||||
deactivated: true,
|
is_active: false,
|
||||||
ap_enabled: false,
|
ap_enabled: false,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
|
@ -1762,7 +1750,7 @@ def perform(:delete, %User{} = user) do
|
||||||
delete_or_deactivate(user)
|
delete_or_deactivate(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(:deactivate_async, user, status), do: deactivate(user, status)
|
def perform(:set_activation_async, user, status), do: set_activation(user, status)
|
||||||
|
|
||||||
@spec external_users_query() :: Ecto.Query.t()
|
@spec external_users_query() :: Ecto.Query.t()
|
||||||
def external_users_query do
|
def external_users_query do
|
||||||
|
@ -2056,7 +2044,7 @@ def error_user(ap_id) do
|
||||||
|
|
||||||
@spec all_superusers() :: [User.t()]
|
@spec all_superusers() :: [User.t()]
|
||||||
def all_superusers do
|
def all_superusers do
|
||||||
User.Query.build(%{super_users: true, local: true, deactivated: false})
|
User.Query.build(%{super_users: true, local: true, is_active: true})
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2097,7 +2085,7 @@ def list_inactive_users_query(inactivity_threshold \\ 7) do
|
||||||
left_join: a in Pleroma.Activity,
|
left_join: a in Pleroma.Activity,
|
||||||
on: u.ap_id == a.actor,
|
on: u.ap_id == a.actor,
|
||||||
where: not is_nil(u.nickname),
|
where: not is_nil(u.nickname),
|
||||||
where: u.deactivated != ^true,
|
where: u.is_active == ^true,
|
||||||
where: u.id not in ^has_read_notifications,
|
where: u.id not in ^has_read_notifications,
|
||||||
group_by: u.id,
|
group_by: u.id,
|
||||||
having:
|
having:
|
||||||
|
@ -2138,10 +2126,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
|
||||||
|
|
||||||
|
@ -2218,9 +2206,9 @@ def change_email(user, email) do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Internal function; public one is `deactivate/2`
|
# Internal function; public one is `deactivate/2`
|
||||||
defp set_activation_status(user, deactivated) do
|
defp set_activation_status(user, status) do
|
||||||
user
|
user
|
||||||
|> cast(%{deactivated: deactivated}, [:deactivated])
|
|> cast(%{is_active: status}, [:is_active])
|
||||||
|> update_and_set_cache()
|
|> update_and_set_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2309,27 +2297,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
|
||||||
|
|
|
@ -137,8 +137,9 @@ defp compose_query({:local, _}, query), do: location_query(query, true)
|
||||||
defp compose_query({:external, _}, query), do: location_query(query, false)
|
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)
|
where(query, [u], u.is_active == true)
|
||||||
|> 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
|
||||||
|
@ -147,23 +148,23 @@ defp compose_query({:legacy_active, _}, query) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:deactivated, false}, query) do
|
defp compose_query({:deactivated, false}, query) do
|
||||||
User.restrict_deactivated(query)
|
where(query, [u], u.is_active == true)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:deactivated, true}, query) do
|
defp compose_query({:deactivated, true}, query) do
|
||||||
where(query, [u], u.deactivated == ^true)
|
where(query, [u], u.is_active == false)
|
||||||
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
|
||||||
|
|
|
@ -56,7 +56,7 @@ defp check_actor_is_active(nil), do: true
|
||||||
|
|
||||||
defp check_actor_is_active(actor) when is_binary(actor) do
|
defp check_actor_is_active(actor) when is_binary(actor) do
|
||||||
case User.get_cached_by_ap_id(actor) do
|
case User.get_cached_by_ap_id(actor) do
|
||||||
%User{deactivated: deactivated} -> not deactivated
|
%User{is_active: true} -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -35,7 +35,7 @@ def validate_actor_presence(cng, options \\ []) do
|
||||||
cng
|
cng
|
||||||
|> validate_change(field_name, fn field_name, actor ->
|
|> validate_change(field_name, fn field_name, actor ->
|
||||||
case User.get_cached_by_ap_id(actor) do
|
case User.get_cached_by_ap_id(actor) do
|
||||||
%User{deactivated: true} ->
|
%User{is_active: false} ->
|
||||||
[{field_name, "user is deactivated"}]
|
[{field_name, "user is deactivated"}]
|
||||||
|
|
||||||
%User{} ->
|
%User{} ->
|
||||||
|
|
|
@ -172,9 +172,9 @@ def show(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
||||||
def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
||||||
user = User.get_cached_by_nickname(nickname)
|
user = User.get_cached_by_nickname(nickname)
|
||||||
|
|
||||||
{:ok, updated_user} = User.deactivate(user, !user.deactivated)
|
{:ok, updated_user} = User.set_activation(user, !user.is_active)
|
||||||
|
|
||||||
action = if user.deactivated, do: "activate", else: "deactivate"
|
action = if !user.is_active, do: "activate", else: "deactivate"
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
@ -189,7 +189,7 @@ def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nicknam
|
||||||
|
|
||||||
def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
||||||
{:ok, updated_users} = User.deactivate(users, false)
|
{:ok, updated_users} = User.set_activation(users, true)
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
@ -204,7 +204,7 @@ def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
|
|
||||||
def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
||||||
{:ok, updated_users} = User.deactivate(users, true)
|
{:ok, updated_users} = User.set_activation(users, false)
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
|
|
@ -73,12 +73,12 @@ def render("show.json", %{user: user}) do
|
||||||
"avatar" => avatar,
|
"avatar" => avatar,
|
||||||
"nickname" => user.nickname,
|
"nickname" => user.nickname,
|
||||||
"display_name" => display_name,
|
"display_name" => display_name,
|
||||||
"deactivated" => user.deactivated,
|
"is_active" => user.is_active,
|
||||||
"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
|
||||||
|
|
|
@ -182,7 +182,7 @@ defp account_admin do
|
||||||
properties:
|
properties:
|
||||||
Map.merge(Account.schema().properties, %{
|
Map.merge(Account.schema().properties, %{
|
||||||
nickname: %Schema{type: :string},
|
nickname: %Schema{type: :string},
|
||||||
deactivated: %Schema{type: :boolean},
|
is_active: %Schema{type: :boolean},
|
||||||
local: %Schema{type: :boolean},
|
local: %Schema{type: :boolean},
|
||||||
roles: %Schema{
|
roles: %Schema{
|
||||||
type: :object,
|
type: :object,
|
||||||
|
@ -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
|
||||||
|
|
|
@ -132,7 +132,7 @@ def admin_account do
|
||||||
avatar: %Schema{type: :string},
|
avatar: %Schema{type: :string},
|
||||||
nickname: %Schema{type: :string},
|
nickname: %Schema{type: :string},
|
||||||
display_name: %Schema{type: :string},
|
display_name: %Schema{type: :string},
|
||||||
deactivated: %Schema{type: :boolean},
|
is_active: %Schema{type: :boolean},
|
||||||
local: %Schema{type: :boolean},
|
local: %Schema{type: :boolean},
|
||||||
roles: %Schema{
|
roles: %Schema{
|
||||||
type: :object,
|
type: :object,
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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: %{
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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, _} <-
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -376,7 +376,7 @@ defp maybe_put_allow_following_move(data, %User{id: user_id} = user, %User{id: u
|
||||||
defp maybe_put_allow_following_move(data, _, _), do: data
|
defp maybe_put_allow_following_move(data, _, _), do: data
|
||||||
|
|
||||||
defp maybe_put_activation_status(data, user, %User{is_admin: true}) do
|
defp maybe_put_activation_status(data, user, %User{is_admin: true}) do
|
||||||
Kernel.put_in(data, [:pleroma, :deactivated], user.deactivated)
|
Kernel.put_in(data, [:pleroma, :deactivated], !user.is_active)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_put_activation_status(data, _, _), do: data
|
defp maybe_put_activation_status(data, _, _), do: data
|
||||||
|
|
|
@ -11,7 +11,7 @@ def render("show.json", %{object: object, multiple: multiple, options: options}
|
||||||
{end_time, expired} = end_time_and_expired(object)
|
{end_time, expired} = end_time_and_expired(object)
|
||||||
{options, votes_count} = options_and_votes_count(options)
|
{options, votes_count} = options_and_votes_count(options)
|
||||||
|
|
||||||
%{
|
poll = %{
|
||||||
# Mastodon uses separate ids for polls, but an object can't have
|
# Mastodon uses separate ids for polls, but an object can't have
|
||||||
# more than one poll embedded so object id is fine
|
# more than one poll embedded so object id is fine
|
||||||
id: to_string(object.id),
|
id: to_string(object.id),
|
||||||
|
@ -21,9 +21,16 @@ def render("show.json", %{object: object, multiple: multiple, options: options}
|
||||||
votes_count: votes_count,
|
votes_count: votes_count,
|
||||||
voters_count: voters_count(object),
|
voters_count: voters_count(object),
|
||||||
options: options,
|
options: options,
|
||||||
voted: voted?(params),
|
|
||||||
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"])
|
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params[:for] do
|
||||||
|
# when unauthenticated Mastodon doesn't include `voted` & `own_votes` keys in response
|
||||||
|
{voted, own_votes} = voted_and_own_votes(params, options)
|
||||||
|
Map.merge(poll, %{voted: voted, own_votes: own_votes})
|
||||||
|
else
|
||||||
|
poll
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("show.json", %{object: object} = params) do
|
def render("show.json", %{object: object} = params) do
|
||||||
|
@ -67,12 +74,29 @@ defp voters_count(%{data: %{"voters" => [_ | _] = voters}}) do
|
||||||
|
|
||||||
defp voters_count(_), do: 0
|
defp voters_count(_), do: 0
|
||||||
|
|
||||||
defp voted?(%{object: object} = opts) do
|
defp voted_and_own_votes(%{object: object} = params, options) do
|
||||||
if opts[:for] do
|
if params[:for] do
|
||||||
existing_votes = Pleroma.Web.ActivityPub.Utils.get_existing_votes(opts[:for].ap_id, object)
|
existing_votes =
|
||||||
existing_votes != [] or opts[:for].ap_id == object.data["actor"]
|
Pleroma.Web.ActivityPub.Utils.get_existing_votes(params[:for].ap_id, object)
|
||||||
|
|
||||||
|
voted = existing_votes != [] or params[:for].ap_id == object.data["actor"]
|
||||||
|
|
||||||
|
own_votes =
|
||||||
|
if voted do
|
||||||
|
titles = Enum.map(options, & &1[:title])
|
||||||
|
|
||||||
|
Enum.reduce(existing_votes, [], fn vote, acc ->
|
||||||
|
data = vote |> Map.get(:object) |> Map.get(:data)
|
||||||
|
index = Enum.find_index(titles, &(&1 == data["name"]))
|
||||||
|
[index | acc]
|
||||||
|
end)
|
||||||
else
|
else
|
||||||
false
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
{voted, own_votes}
|
||||||
|
else
|
||||||
|
{false, []}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -491,7 +491,7 @@ def render_content(object), do: object.data["content"] || ""
|
||||||
def build_tags(object_tags) when is_list(object_tags) do
|
def build_tags(object_tags) when is_list(object_tags) do
|
||||||
object_tags
|
object_tags
|
||||||
|> Enum.filter(&is_binary/1)
|
|> Enum.filter(&is_binary/1)
|
||||||
|> Enum.map(&%{name: &1, url: "/tag/#{URI.encode(&1)}"})
|
|> Enum.map(&%{name: &1, url: "#{Pleroma.Web.base_url()}/tag/#{URI.encode(&1)}"})
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_tags(_), do: []
|
def build_tags(_), do: []
|
||||||
|
|
|
@ -13,6 +13,7 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.Script do
|
||||||
def purge(urls, opts \\ []) do
|
def purge(urls, opts \\ []) do
|
||||||
args =
|
args =
|
||||||
urls
|
urls
|
||||||
|
|> maybe_format_urls(Keyword.get(opts, :url_format))
|
||||||
|> List.wrap()
|
|> List.wrap()
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|> Enum.join(" ")
|
|> Enum.join(" ")
|
||||||
|
@ -40,4 +41,22 @@ defp handle_result(error, _) do
|
||||||
Logger.error("Error while cache purge: #{inspect(error)}")
|
Logger.error("Error while cache purge: #{inspect(error)}")
|
||||||
{:error, inspect(error)}
|
{:error, inspect(error)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def maybe_format_urls(urls, :htcacheclean) do
|
||||||
|
urls
|
||||||
|
|> Enum.map(fn url ->
|
||||||
|
uri = URI.parse(url)
|
||||||
|
|
||||||
|
query =
|
||||||
|
if !is_nil(uri.query) do
|
||||||
|
"?" <> uri.query
|
||||||
|
else
|
||||||
|
"?"
|
||||||
|
end
|
||||||
|
|
||||||
|
uri.scheme <> "://" <> uri.host <> ":#{inspect(uri.port)}" <> uri.path <> query
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def maybe_format_urls(urls, _), do: urls
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ defmodule Pleroma.Web.MongooseIM.MongooseIMController do
|
||||||
plug(RateLimiter, [name: :authentication, params: ["user"]] when action == :check_password)
|
plug(RateLimiter, [name: :authentication, params: ["user"]] when action == :check_password)
|
||||||
|
|
||||||
def user_exists(conn, %{"user" => username}) do
|
def user_exists(conn, %{"user" => username}) do
|
||||||
with %User{} <- Repo.get_by(User, nickname: username, local: true, deactivated: false) do
|
with %User{} <- Repo.get_by(User, nickname: username, local: true, is_active: true) do
|
||||||
conn
|
conn
|
||||||
|> json(true)
|
|> json(true)
|
||||||
else
|
else
|
||||||
|
@ -26,7 +26,7 @@ def user_exists(conn, %{"user" => username}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
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, is_active: true} <-
|
||||||
Repo.get_by(User, nickname: username, local: true),
|
Repo.get_by(User, nickname: username, local: true),
|
||||||
true <- AuthenticationPlug.checkpw(password, password_hash) do
|
true <- AuthenticationPlug.checkpw(password, password_hash) do
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -26,7 +26,7 @@ defp fetch_users(user_ap_ids) do
|
||||||
user_ap_ids
|
user_ap_ids
|
||||||
|> Enum.map(&Pleroma.User.get_cached_by_ap_id/1)
|
|> Enum.map(&Pleroma.User.get_cached_by_ap_id/1)
|
||||||
|> Enum.filter(fn
|
|> Enum.filter(fn
|
||||||
%{deactivated: false} -> true
|
%{is_active: true} -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -150,7 +150,7 @@ def delete_account(%{assigns: %{user: user}} = conn, params) do
|
||||||
def disable_account(%{assigns: %{user: user}} = conn, params) do
|
def disable_account(%{assigns: %{user: user}} = conn, params) do
|
||||||
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
|
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
|
||||||
{:ok, user} ->
|
{:ok, user} ->
|
||||||
User.deactivate_async(user)
|
User.set_activation_async(user, false)
|
||||||
json(conn, %{status: "success"})
|
json(conn, %{status: "success"})
|
||||||
|
|
||||||
{:error, msg} ->
|
{:error, msg} ->
|
||||||
|
|
|
@ -59,7 +59,7 @@ defp create_user(params, opts) do
|
||||||
|
|
||||||
def password_reset(nickname_or_email) do
|
def password_reset(nickname_or_email) do
|
||||||
with true <- is_binary(nickname_or_email),
|
with true <- is_binary(nickname_or_email),
|
||||||
%User{local: true, email: email, deactivated: false} = user when is_binary(email) <-
|
%User{local: true, email: email, is_active: true} = user when is_binary(email) <-
|
||||||
User.get_by_nickname_or_email(nickname_or_email),
|
User.get_by_nickname_or_email(nickname_or_email),
|
||||||
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||||
user
|
user
|
||||||
|
|
|
@ -9,9 +9,9 @@ defmodule Pleroma.Workers.BackgroundWorker do
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
|
|
||||||
def perform(%Job{args: %{"op" => "deactivate_user", "user_id" => user_id, "status" => status}}) do
|
def perform(%Job{args: %{"op" => "user_activation", "user_id" => user_id, "status" => status}}) do
|
||||||
user = User.get_cached_by_id(user_id)
|
user = User.get_cached_by_id(user_id)
|
||||||
User.perform(:deactivate_async, user, status)
|
User.perform(:set_activation_async, user, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
||||||
|
|
32
mix.exs
32
mix.exs
|
@ -123,7 +123,7 @@ 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"},
|
||||||
{:bcrypt_elixir, "~> 2.2"},
|
{:bcrypt_elixir, "~> 2.2"},
|
||||||
{:trailing_format_plug, "~> 0.0.7"},
|
{:trailing_format_plug, "~> 0.0.7"},
|
||||||
|
@ -229,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
|
||||||
|
|
||||||
|
@ -332,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
|
||||||
|
|
8
mix.lock
8
mix.lock
|
@ -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"},
|
||||||
|
|
|
@ -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."
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# 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.RefactorDeactivatedUserField do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
# Flip the values before we change the meaning of the column
|
||||||
|
execute("UPDATE users SET deactivated = NOT deactivated;")
|
||||||
|
execute("ALTER TABLE users RENAME COLUMN deactivated TO is_active;")
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN is_active SET DEFAULT true;")
|
||||||
|
execute("ALTER INDEX users_deactivated_index RENAME TO users_is_active_index;")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
execute("UPDATE users SET is_active = NOT is_active;")
|
||||||
|
execute("ALTER TABLE users RENAME COLUMN is_active TO deactivated;")
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN deactivated SET DEFAULT false;")
|
||||||
|
execute("ALTER INDEX users_is_active_index RENAME TO users_deactivated_index;")
|
||||||
|
end
|
||||||
|
end
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.6b30c658.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.1428845f.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.
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.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue