Compare commits

...

97 commits

Author SHA1 Message Date
Henry Jameson
4e05e7a989 Merge remote-tracking branch 'origin/develop' into shigusegubu 2024-12-18 11:34:33 +02:00
Haelwenn
16027b769c Merge branch 'fix/install-frontend-in-otp27' into 'develop'
Fix installing frontend in Erlang/OTP 27.1+

See merge request pleroma/pleroma!4300
2024-11-27 14:48:53 +00:00
kPherox
3f98c8bd1b
fix: skip directory entries
In OTP 27.1 or later, `:zip.unzip/2` without `:skip_directories` option returns directory entries.
However in OTP 26, passing `:skip_directories` returns a `:bad_option` error, so this option is not available for compatibility.
2024-11-27 17:55:33 +09:00
lain
36f8b924ae Merge branch 'mergeback/2.7.1' into 'develop'
mergeback: Version 2.7.1

See merge request pleroma/pleroma!4299
2024-11-27 08:09:51 +00:00
Haelwenn (lanodan) Monnier
3a8e24fed4
Merge remote-tracking branch 'pleroma/stable' into mergeback/2.7.1 2024-11-26 16:46:47 +01:00
Haelwenn
31487e5be4 Merge branch 'release/2.7.1' into 'stable'
Version 2.7.1

See merge request pleroma/pleroma!4298
2024-11-26 13:38:35 +00:00
Haelwenn (lanodan) Monnier
7bb2dccc05
Version 2.7.1 2024-11-26 14:09:09 +01:00
feld
6a0883e5d3
Merge branch 'bugfix-truncate-remote-user-fields' into 'develop'
User: truncate remote user fields instead of rejecting

See merge request pleroma/pleroma!4220
2024-11-26 14:06:49 +01:00
lain
53c2d2cd87
Merge branch 'mastodon-websocket-fix' into 'develop'
Fix Mastodon WebSocket authentication

See merge request pleroma/pleroma!4206
2024-11-26 14:06:31 +01:00
lain
f45f17b5ff
Merge branch 'follow-validator' into 'develop'
Do not require a cc field when validating an incoming Follow activity

See merge request pleroma/pleroma!4212
2024-11-26 14:04:45 +01:00
feld
a6e97c497b
Merge branch 'following-state-bug' into 'develop'
Fix Following status bug

See merge request pleroma/pleroma!4251
2024-11-26 14:04:21 +01:00
feld
2977779e94
Merge branch 'well-known' into 'develop'
NodeInfo: Accept application/activity+json requests

See merge request pleroma/pleroma!4242
2024-11-26 14:03:18 +01:00
feld
ced6b10c70
Merge branch 'swoosh-mailgun' into 'develop'
Fix Swoosh Mailgun support

See merge request pleroma/pleroma!4217
2024-11-26 13:58:48 +01:00
lain
d92d6132f2 Merge branch 'meilisearch/misc-fixes' into 'develop'
Miscellaneous fixes for Meilisearch

See merge request pleroma/pleroma!4296
2024-11-21 14:29:26 +00:00
Mint
462a6a2000 Revert "Docs: fix OTP mix task command for Meilisearch"
This reverts commit 3a82a51a6e.
2024-11-21 16:52:30 +03:00
lain
2482d56153 Merge branch 'fix-module-search-in-pleroma-ctl' into 'develop'
B ReleaseTasks: Fix task module finding.

See merge request pleroma/pleroma!4297
2024-11-21 13:15:33 +00:00
Lain Soykaf
14dbf789b3 Linting 2024-11-21 16:32:05 +04:00
Lain Soykaf
551534f3ee B ReleaseTasks: Fix task module finding. 2024-11-21 16:07:09 +04:00
Mint
da7132caba Remove unused import 2024-11-21 02:40:27 +03:00
Mint
af7de4c17a Changelog 2024-11-21 02:17:53 +03:00
Mint
3a82a51a6e Docs: fix OTP mix task command for Meilisearch 2024-11-21 02:16:36 +03:00
Mint
d65f768b59 Meilisearch: stop attempting to index posts with nil date 2024-11-21 02:14:55 +03:00
Mint
c9f9ec04c8 Meilisearch: use PUT method for indexing Mix task
See https://github.com/meilisearch/meilisearch/issues/2619
2024-11-21 02:13:10 +03:00
lain
dcb0c47773 Merge branch 'mastodon-websocket-fix' into 'develop'
Fix Mastodon WebSocket authentication

See merge request pleroma/pleroma!4206
2024-11-13 08:22:44 +00:00
lain
83b866b257 Merge branch 'bump-lexbor' into 'develop'
bump fast_html to 2.3.0

See merge request pleroma/pleroma!4294
2024-11-13 07:18:18 +00:00
Haelwenn (lanodan) Monnier
0c3b71e1cc
mix.lock: bump fast_html to 2.3.0 2024-11-13 05:17:51 +01:00
lain
62bbed1e58 Merge branch 'token-view-scopes' into 'develop'
Include session scopes in TokenView

See merge request pleroma/pleroma!4273
2024-11-12 11:18:10 +00:00
lain
4626a9280a Merge branch 'activity-pub-metadata' into 'develop'
Add metadata provider for ActivityPub alternate links

See merge request pleroma/pleroma!4286
2024-11-12 10:49:36 +00:00
Lain Soykaf
29b048d351 B TwitterAPI/ControllerTest: Actually test the keys 2024-11-12 14:35:02 +04:00
Lain Soykaf
2baa9b0072 Merge branch 'develop' into pleroma-token-view-scopes 2024-11-12 14:33:30 +04:00
lain
8b31316d2d Merge branch 'tusooa/se-opt-out' into 'develop'
Fix nonexisting user will not generate metadata for search engine opt-out

Closes #3329

See merge request pleroma/pleroma!4279
2024-11-12 10:24:28 +00:00
Lain Soykaf
5b3e4cf49b B Providers/ActivityPub: Ensure that nothing explodes on unexpected input. 2024-11-12 14:22:02 +04:00
lain
a815feb299 Merge branch 'weblate' into 'develop'
Translations update from Pleroma Weblate

See merge request pleroma/pleroma!4287
2024-11-12 10:12:09 +00:00
Codimp
1e9edccab8 Translated using Weblate (French)
Currently translated at 5.4% (53 of 974 strings)

Translation: Pleroma/Pleroma Backend (domain config_descriptions)
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-backend-domain-config_descriptions/fr/
2024-11-12 10:01:15 +00:00
lain
91b26c683a Merge branch 'fix/vapid_keyword_fallback' into 'develop'
push: make vapid_config fallback to empty array

See merge request pleroma/pleroma!4276
2024-11-12 10:01:05 +00:00
lain
6941c47ac8 Merge branch 'develop' into 'tusooa/se-opt-out'
# Conflicts:
#   lib/pleroma/web/metadata/providers/feed.ex
2024-11-12 09:58:28 +00:00
lain
ee3ab8b625 Merge branch 'atom-tag' into 'develop'
Metadata: Do not include .atom feed links for remote accounts

See merge request pleroma/pleroma!4281
2024-11-12 09:44:29 +00:00
lain
f7bf9a8c8f Merge branch 'dedupe-sharding' into 'develop'
Pleroma.Upload.Filter.Dedupe: sharding directory structure

See merge request pleroma/pleroma!4292
2024-11-12 09:22:44 +00:00
Lain Soykaf
ebea518c8c B DedupeTest: Add explicit test for the sharding structure 2024-11-12 12:43:16 +04:00
Mark Felder
d2de251c4d Pleroma.Upload.Filter.Dedupe: sharding directory structure
Dedupe now uses a three-level sharding directory structure to improve performance when many files are uploaded and stored on a filesystem instead of an object store. (note: Minio still affected as it still uses a traditional filesystem)

This does not help if you already have hundreds of thousands of files uploaded. The media URLs are permanently part of the activity so the files cannot be relocated. A motivated user could write a tool to move the files and perhaps write an Nginx or equivalent redirect to make the files still accessible, but that is beyond the scope of this change.
2024-10-29 16:00:18 -04:00
feld
6099a94dbc Merge branch 'mediav2-fix' into 'develop'
Fix /api/v2/media returning the wrong status code for media processed synchronously

See merge request pleroma/pleroma!4291
2024-10-28 02:11:49 +00:00
Mark Felder
7d5ef81737 Fix /api/v2/media returning the wrong status code for media processed synchronously
The API should return a 202 only if data cannot be returned yet and a followup GET /api/v1/media/:id should be called to retrieve it. This is something Mastodon does when it needs to transcode large media files. It does not apply to Pleroma and causes apps to waste an API call when posting a status which causes apps to appear to hang on higher latency environments, such as on mobile networks.

https://docs.joinmastodon.org/methods/media/#v2
2024-10-27 21:52:42 -04:00
feld
2d591aedae Merge branch 'fzdevelop' into 'develop'
OpenBSD docs update

See merge request pleroma/pleroma!4290
2024-10-25 16:01:10 +00:00
Mark Felder
00b6a586ac OpenBSD needs libvips
Confirmed package exists by testing an OpenBSD 7.6 arm64 VM
2024-10-25 11:56:57 -04:00
Mark Felder
63c6dacfce Changelog 2024-10-25 11:40:58 -04:00
feld
bb3403abd8 Merge branch 'fzdevelop' into 'develop'
include vips in the media/graphics packages section

See merge request pleroma/pleroma!4289
2024-10-25 15:40:20 +00:00
Mark Felder
dc6362f71d Changelog 2024-10-25 11:38:20 -04:00
feld
7e3532a073 Merge branch 'release-tuning' into 'develop'
Release tuning

See merge request pleroma/pleroma!4275
2024-10-25 15:35:32 +00:00
Mark Felder
e1296737a6 Disable busywaits in releases 2024-10-25 11:34:54 -04:00
tusooa
78dc592696 Merge branch 'develop' into 'develop'
Some tidying and grammer improvements for these installation docs, based on my experience installing Pleroma on Ubuntu 24.04 a few minutes ago.

See merge request pleroma/pleroma!4288
2024-10-21 00:10:28 +00:00
Mark Jaroski
f048637b41 Some tidying and grammer improvements for these installation docs, based on my experience installing Pleroma on Ubuntu 24.04 a few minutes ago. 2024-10-21 00:10:27 +00:00
marcin mikołajczak
60ec42cb9c Add metadata provider for ActivityPub alternate links
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-10-12 23:45:18 +02:00
feld
639016bdee Merge branch 'refactor-change-password' into 'develop'
LDAP: permit password changing

See merge request pleroma/pleroma!4285
2024-10-11 20:48:20 +00:00
feld
4557cd960e Merge branch 'remote-report-policy' into 'develop'
Remote report policy

See merge request pleroma/pleroma!4280
2024-10-11 20:23:46 +00:00
feld
dd7f699d4a Merge branch 'tusooa/3331-fix-incoming-block' into 'develop'
Fix incoming Blocks being rejected

Closes #3331

See merge request pleroma/pleroma!4282
2024-10-11 20:22:21 +00:00
Mark Felder
b6a951cfb5 LDAP password changing changelog 2024-10-11 16:20:38 -04:00
Mark Felder
1da057e6a4 Reorganize the LDAP module 2024-10-11 15:51:56 -04:00
Mark Felder
6bc70b8b2a Add change_password/3 to LDAP module 2024-10-11 15:45:09 -04:00
Mark Felder
ff039f9530 Add example OpenLDAP ldif to enable users to change their own passwords 2024-10-11 15:41:08 -04:00
Mark Felder
67cc38b5ac Support password changes for LDAP auth backend 2024-10-11 15:39:38 -04:00
Mark Felder
23f78c7573 Refactor password changes to go through Pleroma.Web.Auth so they can be supported by the different auth backends 2024-10-11 14:29:15 -04:00
feld
3f3f8bc57a Merge branch 'poll-refresh' into 'develop'
Refactor Poll Refreshing

See merge request pleroma/pleroma!4278
2024-10-10 00:46:28 +00:00
Mark Felder
5b04c2bf13 Test the final refresh behavior of a PollWorker poll_end job 2024-10-09 20:15:00 -04:00
Mark Felder
03a6e33b81 Skip the final refresh job if the activity is local 2024-10-09 16:25:58 -04:00
fzorb fzorbius
37b1192b7b Should probably also include vips in the media/graphics packages section, as you need it to compile some library 2024-10-09 18:33:22 +00:00
marcin mikołajczak
ddedc575e7 Merge branch 'hashtag-feeds-restricted' into 'develop'
Repesct :restrict_unauthenticated for hashtag rss/atom feeds

See merge request pleroma/pleroma!4266
2024-10-09 09:42:53 +00:00
tusooa
f758b6e37c
Fix incoming Blocks being rejected 2024-10-08 23:09:59 -04:00
marcin mikołajczak
0c41d986de Metadata: Do not include .atom feed links for remote accounts
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-10-06 17:02:31 +02:00
Mint
eb971aa022 Changelog 2024-10-03 20:03:52 +03:00
Mint
48af6850fc RemoteReportPolicy: Fix third-party report detection 2024-10-03 20:00:36 +03:00
Alex Gleason
55612cb8ee mix format 2024-10-03 20:00:15 +03:00
Mint
fd83b86b99 RemoteReportPolicy: add reject_third_party option 2024-10-03 20:00:15 +03:00
Alex Gleason
b7c91876d2 RemoteReportPolicy: add :reject_all option, fix tests 2024-10-03 19:59:39 +03:00
Alex Gleason
4533f171ab Add RemoteReportPolicy to reject reports without enough information 2024-10-03 19:59:39 +03:00
Mark Felder
a3038aa6a2 Increase poll refresh interval to 120 seconds 2024-10-03 11:01:33 -04:00
Mark Felder
b854e3836f Remove pattern that can never match 2024-10-03 10:30:32 -04:00
Mark Felder
fa8de790df Remove test superceded by logic change
We will not be inserting jobs that should be skipped due to updated_at
2024-10-03 10:19:11 -04:00
Mark Felder
ba2ae5e40b Check if a refresh is permitted by comparing timestamps before attempting to insert an Oban job
It's better to avoid inserting an Oban job that will just be rejected if it's not expensive to check.
2024-10-03 10:14:02 -04:00
tusooa
35bd197733
Fix nonexisting user will not generate metadata for search engine opt-out 2024-10-02 18:41:35 -04:00
Mark Felder
0a42a3f2ea Do not attempt to schedule poll refresh jobs for local activities 2024-10-02 11:05:17 -04:00
Mark Felder
9ff57946e7 Credo 2024-09-30 15:25:13 -04:00
Mark Felder
b735d9e6e1 Improve assertion 2024-09-30 14:55:38 -04:00
Mark Felder
2ab4049508 Poll refreshing changelog 2024-09-30 14:47:30 -04:00
Mark Felder
a1b384f63c Test that a poll refresh is cancelled if updated_at on the object is newer than the poll closing time 2024-09-30 14:45:41 -04:00
Mark Felder
b2340b5b77 Permit backdating the poll closed timestamp 2024-09-30 14:45:13 -04:00
Mark Felder
766edfe5b2 Test Poll refresh jobs stream out updates after refetching the object 2024-09-30 14:32:28 -04:00
Mark Felder
a2e7db43aa Rename assignment for consistency 2024-09-30 14:23:04 -04:00
Mark Felder
47ce3a4a96 Schedule a final poll refresh before streaming out the notifications 2024-09-30 14:17:35 -04:00
Mark Felder
4b3f604f95 Skip refetching poll results if the object's updated_at is newer than the poll closed timestamp 2024-09-30 14:02:41 -04:00
Mark Felder
c077a14ce1 Add Oban job to handle poll refreshing and stream out the update 2024-09-30 13:54:56 -04:00
Mark Felder
2380ae6dcc Validate an Oban job is inserted for poll refreshes 2024-09-30 13:38:13 -04:00
Mark Felder
382426e033 Remove Object.get_by_id_and_maybe_refetch/2
This was only used for poll refreshing and is not a good approach to the problem.
2024-09-30 12:41:09 -04:00
Haelwenn (lanodan) Monnier
7dd3a4d86d
push: make vapid_config fallback to empty array
2024-09-24T03:53:27.770757+00:00 NightmareMoon pleroma: path=/notice/AmJcSqyeyij4W70K36 [error] Preloading for /notice/AmJcSqyeyij4W70K36 failed.
    ** (FunctionClauseError) no function clause matching in Keyword.get/3
        (elixir 1.15.8) lib/keyword.ex:388: Keyword.get(nil, :public_key, nil)
        (pleroma 2.7.0-3067-g9b76dbd4-dev-lanodan2) lib/pleroma/web/mastodon_api/views/instance_view.ex:262: Pleroma.Web.MastodonAPI.InstanceView.pleroma_configuration/1
        (pleroma 2.7.0-3067-g9b76dbd4-dev-lanodan2) lib/pleroma/web/mastodon_api/views/instance_view.ex:45: Pleroma.Web.MastodonAPI.InstanceView.render/2
        (pleroma 2.7.0-3067-g9b76dbd4-dev-lanodan2) lib/pleroma/web/preload/providers/instance.ex:28: Pleroma.Web.Preload.Providers.Instance.build_info_tag/1
        (pleroma 2.7.0-3067-g9b76dbd4-dev-lanodan2) lib/pleroma/web/preload/providers/instance.ex:21: Pleroma.Web.Preload.Providers.Instance.generate_terms/1
        (pleroma 2.7.0-3067-g9b76dbd4-dev-lanodan2) lib/pleroma/web/preload.ex:13: anonymous fn/3 in Pleroma.Web.Preload.build_tags/2
2024-09-24 05:57:41 +02:00
marcin mikołajczak
23e5eed4e0 Include session scopes in TokenView
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-09-19 10:57:50 +02:00
marcin mikołajczak
e74e0089bf Repesct :restrict_unauthenticated for hashtag rss/atom feeds
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
2024-09-16 17:19:21 +02:00
Mark Felder
8c91fd8785 Fix Mastodon WebSocket authentication
Mastodon uses the Sec-Websocket-Protocol header to send the auth token. It is not clear if this is a violation of the RFC, but Mastodon is not the first application in the wild to use this header for authentication purposes. Phoenix does not allow accessing this header, so we work around it temporarily with a minor patch to Phoenix 1.7.14. We will reach out to Phoenix to discuss how to make this use case possible.
2024-08-04 15:04:29 -04:00
Mark Felder
3e4768efca Revert "Remove invalid test"
This reverts commit d0f4b2b02f.
2024-08-04 13:59:13 -04:00
84 changed files with 965 additions and 320 deletions

View file

@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 2.7.1
### Changed
- Accept `application/activity+json` for requests to `/.well-known/nodeinfo`
### Fixed
- Truncate remote user fields, avoids them getting rejected
- Improve the `FollowValidator` to successfully incoming activities with an errant `cc` field.
- Resolved edge case where the API can report you are following a user but the relationship is not fully established.
- The Swoosh email adapter for Mailgun was missing a new dependency on `:multipart`
- Fix Mastodon WebSocket authentication
## 2.7.0 ## 2.7.0
### Security ### Security

View file

@ -0,0 +1 @@
Add metadata provider for ActivityPub alternate links

View file

@ -0,0 +1 @@
Metadata: Do not include .atom feed links for remote accounts

View file

@ -1 +0,0 @@
Truncate remote user fields, avoids them getting rejected

View file

@ -0,0 +1 @@
- Bumped `fast_html` to v2.3.0, which notably allows to use system-installed lexbor with passing `WITH_SYSTEM_LEXBOR=1` environment variable at build-time

View file

@ -0,0 +1 @@
Fixed a formatting issue that had a required commend embedded in a textblock, and change the language to make it a bit more idiomatic.

View file

@ -0,0 +1 @@
Dedupe upload filter now uses a three-level sharding directory structure

View file

View file

@ -1 +0,0 @@
Improve the FollowValidator to successfully incoming activities with an errant cc field.

View file

@ -1 +0,0 @@
Resolved edge case where the API can report you are following a user but the relationship is not fully established.

View file

View file

@ -0,0 +1 @@
Repesct :restrict_unauthenticated for hashtag rss/atom feeds

View file

@ -0,0 +1 @@
Fix incoming Block activities being rejected

View file

@ -0,0 +1 @@
LDAP now supports users changing their passwords

View file

@ -1 +0,0 @@
The Swoosh email adapter for Mailgun was missing a new dependency on :multipart

View file

@ -0,0 +1 @@
Fix /api/v2/media returning the wrong status code (202) for media processed synchronously

View file

@ -0,0 +1 @@
Miscellaneous fixes for Meilisearch support

View file

@ -0,0 +1 @@
Fix pleroma_ctl mix task calls sometimes not being found

View file

@ -0,0 +1 @@
Poll results refreshing is handled asynchronously and will not attempt to keep fetching updates to a closed poll.

View file

@ -0,0 +1 @@
Tuning for release builds to lower CPU usage.

View file

@ -0,0 +1 @@
Added RemoteReportPolicy from Rebased for handling bogus federated reports

View file

@ -0,0 +1 @@
Fix nonexisting user will not generate metadata for search engine opt-out

View file

@ -0,0 +1 @@
Include session scopes in TokenView

View file

@ -0,0 +1 @@
Make vapid_config return empty array, fixing preloading for instances without push notifications configured

View file

@ -1 +0,0 @@
Accept application/activity+json for requests to .well-known/nodeinfo

View file

@ -447,6 +447,11 @@ config :pleroma, :mrf_follow_bot, follower_nickname: nil
config :pleroma, :mrf_inline_quote, template: "<bdi>RT:</bdi> {url}" config :pleroma, :mrf_inline_quote, template: "<bdi>RT:</bdi> {url}"
config :pleroma, :mrf_remote_report,
reject_all: false,
reject_anonymous: true,
reject_empty_message: true
config :pleroma, :mrf_force_mention, config :pleroma, :mrf_force_mention,
mention_parent: true, mention_parent: true,
mention_quoted: true mention_quoted: true

View file

@ -69,12 +69,18 @@ cd /opt/pleroma
sudo -Hu pleroma mix deps.get sudo -Hu pleroma mix deps.get
``` ```
* Generate the configuration: `sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen` * Generate the configuration:
```shell
sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen`
```
* During this process:
* Answer with `yes` if it asks you to install `rebar3`. * Answer with `yes` if it asks you to install `rebar3`.
* This may take some time, because parts of pleroma get compiled first. * This may take some time, because parts of pleroma get compiled first.
* After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`. * After that it will ask you a few questions about your instance and generates a configuration file in `config/generated_config.exs`.
* 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 production instances, `dev.secret.exs` for development instances):
```shell ```shell
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs} sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}

View file

@ -31,7 +31,7 @@ Setup the required services to automatically start at boot, using `sysrc(8)`.
### Install media / graphics packages (optional, see [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md)) ### Install media / graphics packages (optional, see [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md))
```shell ```shell
# pkg install imagemagick ffmpeg p5-Image-ExifTool # pkg install imagemagick ffmpeg p5-Image-ExifTool vips
``` ```
## Configuring Pleroma ## Configuring Pleroma

View file

@ -12,7 +12,7 @@ For any additional information regarding commands and configuration files mentio
To install them, run the following command (with doas or as root): To install them, run the following command (with doas or as root):
``` ```
pkg_add elixir gmake git postgresql-server postgresql-contrib cmake ffmpeg ImageMagick pkg_add elixir gmake git postgresql-server postgresql-contrib cmake ffmpeg ImageMagick libvips
``` ```
Pleroma requires a reverse proxy, OpenBSD has relayd in base (and is used in this guide) and packages/ports are available for nginx (www/nginx) and apache (www/apache-httpd). Independently of the reverse proxy, [acme-client(1)](https://man.openbsd.org/acme-client) can be used to get a certificate from Let's Encrypt. Pleroma requires a reverse proxy, OpenBSD has relayd in base (and is used in this guide) and packages/ports are available for nginx (www/nginx) and apache (www/apache-httpd). Independently of the reverse proxy, [acme-client(1)](https://man.openbsd.org/acme-client) can be used to get a certificate from Let's Encrypt.

View file

@ -18,7 +18,7 @@ Matrix-kanava #pleroma:libera.chat ovat hyviä paikkoja löytää apua
Asenna tarvittava ohjelmisto: Asenna tarvittava ohjelmisto:
`# pkg_add git elixir gmake postgresql-server-10.3 postgresql-contrib-10.3 cmake ffmpeg ImageMagick` `# pkg_add git elixir gmake postgresql-server-10.3 postgresql-contrib-10.3 cmake ffmpeg ImageMagick libvips`
#### Optional software #### Optional software

View file

@ -0,0 +1,7 @@
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {1}to attrs=userPassword
by self write
by anonymous auth
by * none

View file

@ -9,7 +9,7 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
import Ecto.Query import Ecto.Query
import Pleroma.Search.Meilisearch, import Pleroma.Search.Meilisearch,
only: [meili_post: 2, meili_put: 2, meili_get: 1, meili_delete: 1] only: [meili_put: 2, meili_get: 1, meili_delete: 1]
def run(["index"]) do def run(["index"]) do
start_pleroma() start_pleroma()
@ -28,7 +28,7 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
end end
{:ok, _} = {:ok, _} =
meili_post( meili_put(
"/indexes/objects/settings/ranking-rules", "/indexes/objects/settings/ranking-rules",
[ [
"published:desc", "published:desc",
@ -42,7 +42,7 @@ defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
) )
{:ok, _} = {:ok, _} =
meili_post( meili_put(
"/indexes/objects/settings/searchable-attributes", "/indexes/objects/settings/searchable-attributes",
[ [
"content" "content"

View file

@ -87,6 +87,7 @@ defmodule Pleroma.Constants do
const(activity_types, const(activity_types,
do: [ do: [
"Block",
"Create", "Create",
"Update", "Update",
"Delete", "Delete",
@ -115,6 +116,10 @@ defmodule Pleroma.Constants do
] ]
) )
const(object_types,
do: ~w[Event Question Answer Audio Video Image Article Note Page ChatMessage]
)
# basic regex, just there to weed out potential mistakes # basic regex, just there to weed out potential mistakes
# https://datatracker.ietf.org/doc/html/rfc2045#section-5.1 # https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
const(mime_regex, const(mime_regex,

View file

@ -74,11 +74,14 @@ defmodule Pleroma.Frontend do
new_file_path = Path.join(dest, path) new_file_path = Path.join(dest, path)
new_file_path path
|> Path.dirname() |> Path.dirname()
|> then(&Path.join(dest, &1))
|> File.mkdir_p!() |> File.mkdir_p!()
File.write!(new_file_path, data) if not File.dir?(new_file_path) do
File.write!(new_file_path, data)
end
end) end)
end end
end end

View file

@ -15,6 +15,14 @@ defmodule Pleroma.LDAP do
GenServer.start_link(__MODULE__, [], name: __MODULE__) GenServer.start_link(__MODULE__, [], name: __MODULE__)
end end
def bind_user(name, password) do
GenServer.call(__MODULE__, {:bind_user, name, password})
end
def change_password(name, password, new_password) do
GenServer.call(__MODULE__, {:change_password, name, password, new_password})
end
@impl true @impl true
def init(state) do def init(state) do
case {Config.get(Pleroma.Web.Auth.Authenticator), Config.get([:ldap, :enabled])} do case {Config.get(Pleroma.Web.Auth.Authenticator), Config.get([:ldap, :enabled])} do
@ -47,13 +55,42 @@ defmodule Pleroma.LDAP do
def handle_info(:connect, _state), do: do_handle_connect() def handle_info(:connect, _state), do: do_handle_connect()
def handle_info({:bind_after_reconnect, name, password, from}, state) do def handle_info({:bind_after_reconnect, name, password, from}, state) do
result = bind_user(state[:handle], name, password) result = do_bind_user(state[:handle], name, password)
GenServer.reply(from, result) GenServer.reply(from, result)
{:noreply, state} {:noreply, state}
end end
@impl true
def handle_call({:bind_user, name, password}, from, state) do
case do_bind_user(state[:handle], name, password) do
:needs_reconnect ->
Process.send(self(), {:bind_after_reconnect, name, password, from}, [])
{:noreply, state, {:continue, :connect}}
result ->
{:reply, result, state, :hibernate}
end
end
def handle_call({:change_password, name, password, new_password}, _from, state) do
result = change_password(state[:handle], name, password, new_password)
{:reply, result, state, :hibernate}
end
@impl true
def terminate(_, state) do
handle = Keyword.get(state, :handle)
if not is_nil(handle) do
:eldap.close(handle)
end
:ok
end
defp do_handle_connect do defp do_handle_connect do
state = state =
case connect() do case connect() do
@ -71,33 +108,6 @@ defmodule Pleroma.LDAP do
{:noreply, state} {:noreply, state}
end end
@impl true
def handle_call({:bind_user, name, password}, from, state) do
case bind_user(state[:handle], name, password) do
:needs_reconnect ->
Process.send(self(), {:bind_after_reconnect, name, password, from}, [])
{:noreply, state, {:continue, :connect}}
result ->
{:reply, result, state, :hibernate}
end
end
@impl true
def terminate(_, state) do
handle = Keyword.get(state, :handle)
if not is_nil(handle) do
:eldap.close(handle)
end
:ok
end
def bind_user(name, password) do
GenServer.call(__MODULE__, {:bind_user, name, password})
end
defp connect do defp connect do
ldap = Config.get(:ldap, []) ldap = Config.get(:ldap, [])
host = Keyword.get(ldap, :host, "localhost") host = Keyword.get(ldap, :host, "localhost")
@ -161,18 +171,17 @@ defmodule Pleroma.LDAP do
end end
end end
defp bind_user(handle, name, password) do defp do_bind_user(handle, name, password) do
uid = Config.get([:ldap, :uid], "cn") dn = make_dn(name)
base = Config.get([:ldap, :base])
case :eldap.simple_bind(handle, "#{uid}=#{name},#{base}", password) do case :eldap.simple_bind(handle, dn, password) do
:ok -> :ok ->
case fetch_user(name) do case fetch_user(name) do
%User{} = user -> %User{} = user ->
user user
_ -> _ ->
register_user(handle, base, uid, name) register_user(handle, ldap_base(), ldap_uid(), name)
end end
# eldap does not inform us of socket closure # eldap does not inform us of socket closure
@ -231,6 +240,14 @@ defmodule Pleroma.LDAP do
end end
end end
defp change_password(handle, name, password, new_password) do
dn = make_dn(name)
with :ok <- :eldap.simple_bind(handle, dn, password) do
:eldap.modify_password(handle, dn, to_charlist(new_password), to_charlist(password))
end
end
defp decode_certfile(file) do defp decode_certfile(file) do
with {:ok, data} <- File.read(file) do with {:ok, data} <- File.read(file) do
data data
@ -242,4 +259,13 @@ defmodule Pleroma.LDAP do
[] []
end end
end end
defp ldap_uid, do: to_charlist(Config.get([:ldap, :uid], "cn"))
defp ldap_base, do: to_charlist(Config.get([:ldap, :base]))
defp make_dn(name) do
uid = ldap_uid()
base = ldap_base()
~c"#{uid}=#{name},#{base}"
end
end end

View file

@ -99,27 +99,6 @@ defmodule Pleroma.Object do
def get_by_id(nil), do: nil def get_by_id(nil), do: nil
def get_by_id(id), do: Repo.get(Object, id) def get_by_id(id), do: Repo.get(Object, id)
@spec get_by_id_and_maybe_refetch(integer(), list()) :: Object.t() | nil
def get_by_id_and_maybe_refetch(id, opts \\ []) do
with %Object{updated_at: updated_at} = object <- get_by_id(id) do
if opts[:interval] &&
NaiveDateTime.diff(NaiveDateTime.utc_now(), updated_at) > opts[:interval] do
case Fetcher.refetch_object(object) do
{:ok, %Object{} = object} ->
object
e ->
Logger.error("Couldn't refresh #{object.data["id"]}:\n#{inspect(e)}")
object
end
else
object
end
else
nil -> nil
end
end
def get_by_ap_id(nil), do: nil def get_by_ap_id(nil), do: nil
def get_by_ap_id(ap_id) do def get_by_ap_id(ap_id) do

View file

@ -16,17 +16,24 @@ defmodule Pleroma.ReleaseTasks do
end end
end end
def find_module(task) do
module_name =
task
|> String.split(".")
|> Enum.map(&String.capitalize/1)
|> then(fn x -> [Mix, Tasks, Pleroma] ++ x end)
|> Module.concat()
case Code.ensure_loaded(module_name) do
{:module, _} -> module_name
_ -> nil
end
end
defp mix_task(task, args) do defp mix_task(task, args) do
Application.load(:pleroma) Application.load(:pleroma)
{:ok, modules} = :application.get_key(:pleroma, :modules)
module = module = find_module(task)
Enum.find(modules, fn module ->
module = Module.split(module)
match?(["Mix", "Tasks", "Pleroma" | _], module) and
String.downcase(List.last(module)) == task
end)
if module do if module do
module.run(args) module.run(args)

View file

@ -122,6 +122,7 @@ defmodule Pleroma.Search.Meilisearch do
# Only index public or unlisted Notes # Only index public or unlisted Notes
if not is_nil(object) and object.data["type"] == "Note" and if not is_nil(object) and object.data["type"] == "Note" and
not is_nil(object.data["content"]) and not is_nil(object.data["content"]) and
not is_nil(object.data["published"]) and
(Pleroma.Constants.as_public() in object.data["to"] or (Pleroma.Constants.as_public() in object.data["to"] or
Pleroma.Constants.as_public() in object.data["cc"]) and Pleroma.Constants.as_public() in object.data["cc"]) and
object.data["content"] not in ["", "."] do object.data["content"] not in ["", "."] do

View file

@ -17,8 +17,16 @@ defmodule Pleroma.Upload.Filter.Dedupe do
|> Base.encode16(case: :lower) |> Base.encode16(case: :lower)
filename = shasum <> "." <> extension filename = shasum <> "." <> extension
{:ok, :filtered, %Upload{upload | id: shasum, path: filename}}
{:ok, :filtered, %Upload{upload | id: shasum, path: shard_path(filename)}}
end end
def filter(_), do: {:ok, :noop} def filter(_), do: {:ok, :noop}
@spec shard_path(String.t()) :: String.t()
def shard_path(
<<a::binary-size(2), b::binary-size(2), c::binary-size(2), _::binary>> = filename
) do
Path.join([a, b, c, filename])
end
end end

View file

@ -0,0 +1,118 @@
defmodule Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy do
@moduledoc "Drop remote reports if they don't contain enough information."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
alias Pleroma.Config
@impl true
def filter(%{"type" => "Flag"} = object) do
with {_, false} <- {:local, local?(object)},
{:ok, _} <- maybe_reject_all(object),
{:ok, _} <- maybe_reject_anonymous(object),
{:ok, _} <- maybe_reject_third_party(object),
{:ok, _} <- maybe_reject_empty_message(object) do
{:ok, object}
else
{:local, true} -> {:ok, object}
{:reject, message} -> {:reject, message}
error -> {:reject, error}
end
end
def filter(object), do: {:ok, object}
defp maybe_reject_all(object) do
if Config.get([:mrf_remote_report, :reject_all]) do
{:reject, "[RemoteReportPolicy] Remote report"}
else
{:ok, object}
end
end
defp maybe_reject_anonymous(%{"actor" => actor} = object) do
with true <- Config.get([:mrf_remote_report, :reject_anonymous]),
%URI{path: "/actor"} <- URI.parse(actor) do
{:reject, "[RemoteReportPolicy] Anonymous: #{actor}"}
else
_ -> {:ok, object}
end
end
defp maybe_reject_third_party(%{"object" => objects} = object) do
{_, to} =
case objects do
[head | tail] when is_binary(head) -> {tail, head}
s when is_binary(s) -> {[], s}
_ -> {[], ""}
end
with true <- Config.get([:mrf_remote_report, :reject_third_party]),
false <- String.starts_with?(to, Pleroma.Web.Endpoint.url()) do
{:reject, "[RemoteReportPolicy] Third-party: #{to}"}
else
_ -> {:ok, object}
end
end
defp maybe_reject_empty_message(%{"content" => content} = object)
when is_binary(content) and content != "" do
{:ok, object}
end
defp maybe_reject_empty_message(object) do
if Config.get([:mrf_remote_report, :reject_empty_message]) do
{:reject, ["RemoteReportPolicy] No content"]}
else
{:ok, object}
end
end
defp local?(%{"actor" => actor}) do
String.starts_with?(actor, Pleroma.Web.Endpoint.url())
end
@impl true
def describe do
mrf_remote_report =
Config.get(:mrf_remote_report)
|> Enum.into(%{})
{:ok, %{mrf_remote_report: mrf_remote_report}}
end
@impl true
def config_description do
%{
key: :mrf_remote_report,
related_policy: "Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy",
label: "MRF Remote Report",
description: "Drop remote reports if they don't contain enough information.",
children: [
%{
key: :reject_all,
type: :boolean,
description: "Reject all remote reports? (this option takes precedence)",
suggestions: [false]
},
%{
key: :reject_anonymous,
type: :boolean,
description: "Reject anonymous remote reports?",
suggestions: [true]
},
%{
key: :reject_third_party,
type: :boolean,
description: "Reject reports on users from third-party instances?",
suggestions: [true]
},
%{
key: :reject_empty_message,
type: :boolean,
description: "Reject remote reports with no message?",
suggestions: [true]
}
]
}
end
end

View file

@ -11,6 +11,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
@behaviour Pleroma.Web.ActivityPub.ObjectValidator.Validating @behaviour Pleroma.Web.ActivityPub.ObjectValidator.Validating
import Pleroma.Constants, only: [activity_types: 0, object_types: 0]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object alias Pleroma.Object
@ -38,6 +40,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
@impl true @impl true
def validate(object, meta) def validate(object, meta)
# This overload works together with the InboxGuardPlug
# and ensures that we are not accepting any activity type
# that cannot pass InboxGuardPlug.
# If we want to support any more activity types, make sure to
# add it in Pleroma.Constants's activity_types or object_types,
# and, if applicable, allowed_activity_types_from_strangers.
def validate(%{"type" => type}, _meta)
when type not in activity_types() and type not in object_types(),
do: {:error, :not_allowed_object_type}
def validate(%{"type" => "Block"} = block_activity, meta) do def validate(%{"type" => "Block"} = block_activity, meta) do
with {:ok, block_activity} <- with {:ok, block_activity} <-
block_activity block_activity

View file

@ -121,7 +121,7 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do
security: [%{"oAuth" => ["write:media"]}], security: [%{"oAuth" => ["write:media"]}],
requestBody: Helpers.request_body("Parameters", create_request()), requestBody: Helpers.request_body("Parameters", create_request()),
responses: %{ responses: %{
202 => Operation.response("Media", "application/json", Attachment), 200 => Operation.response("Media", "application/json", Attachment),
400 => Operation.response("Media", "application/json", ApiError), 400 => Operation.response("Media", "application/json", ApiError),
422 => Operation.response("Media", "application/json", ApiError), 422 => Operation.response("Media", "application/json", ApiError),
500 => Operation.response("Media", "application/json", ApiError) 500 => Operation.response("Media", "application/json", ApiError)

View file

@ -10,4 +10,9 @@ defmodule Pleroma.Web.Auth.Authenticator do
@callback handle_error(Plug.Conn.t(), any()) :: any() @callback handle_error(Plug.Conn.t(), any()) :: any()
@callback auth_template() :: String.t() | nil @callback auth_template() :: String.t() | nil
@callback oauth_consumer_template() :: String.t() | nil @callback oauth_consumer_template() :: String.t() | nil
@callback change_password(Pleroma.User.t(), String.t(), String.t(), String.t()) ::
{:ok, Pleroma.User.t()} | {:error, term()}
@optional_callbacks change_password: 4
end end

View file

@ -30,4 +30,13 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do
error error
end end
end end
def change_password(user, password, new_password, new_password) do
case LDAP.change_password(user.nickname, password, new_password) do
:ok -> {:ok, user}
e -> e
end
end
def change_password(_, _, _, _), do: {:error, :password_confirmation}
end end

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do
alias Pleroma.Registration alias Pleroma.Registration
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.AuthenticationPlug alias Pleroma.Web.Plugs.AuthenticationPlug
import Pleroma.Web.Auth.Helpers, only: [fetch_credentials: 1, fetch_user: 1] import Pleroma.Web.Auth.Helpers, only: [fetch_credentials: 1, fetch_user: 1]
@ -101,4 +102,23 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do
def auth_template, do: nil def auth_template, do: nil
def oauth_consumer_template, do: nil def oauth_consumer_template, do: nil
@doc "Changes Pleroma.User password in the database"
def change_password(user, password, new_password, new_password) do
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
with {:ok, _user} <-
User.reset_password(user, %{
password: new_password,
password_confirmation: new_password
}) do
{:ok, user}
end
error ->
error
end
end
def change_password(_, _, _, _), do: {:error, :password_confirmation}
end end

View file

@ -39,4 +39,8 @@ defmodule Pleroma.Web.Auth.WrapperAuthenticator do
implementation().oauth_consumer_template() || implementation().oauth_consumer_template() ||
Pleroma.Config.get([:auth, :oauth_consumer_template], "consumer.html") Pleroma.Config.get([:auth, :oauth_consumer_template], "consumer.html")
end end
@impl true
def change_password(user, password, new_password, new_password_confirmation),
do: implementation().change_password(user, password, new_password, new_password_confirmation)
end end

View file

@ -14,6 +14,7 @@ defmodule Pleroma.Web.Endpoint do
websocket: [ websocket: [
path: "/", path: "/",
compress: false, compress: false,
connect_info: [:sec_websocket_protocol],
error_handler: {Pleroma.Web.MastodonAPI.WebsocketHandler, :handle_error, []}, error_handler: {Pleroma.Web.MastodonAPI.WebsocketHandler, :handle_error, []},
fullsweep_after: 20 fullsweep_after: 20
] ]

View file

@ -46,7 +46,7 @@ defmodule Pleroma.Web.Fallback.RedirectController do
redirector_with_meta(conn, %{user: user}) redirector_with_meta(conn, %{user: user})
else else
nil -> nil ->
redirector(conn, params) redirector_with_meta(conn, Map.delete(params, "maybe_nickname_or_id"))
end end
end end

View file

@ -10,7 +10,7 @@ defmodule Pleroma.Web.Feed.TagController do
alias Pleroma.Web.Feed.FeedView alias Pleroma.Web.Feed.FeedView
def feed(conn, params) do def feed(conn, params) do
if Config.get!([:instance, :public]) do if not Config.restrict_unauthenticated_access?(:timelines, :local) do
render_feed(conn, params) render_feed(conn, params)
else else
render_error(conn, :not_found, "Not found") render_error(conn, :not_found, "Not found")
@ -18,10 +18,12 @@ defmodule Pleroma.Web.Feed.TagController do
end end
defp render_feed(conn, %{"tag" => raw_tag} = params) do defp render_feed(conn, %{"tag" => raw_tag} = params) do
local_only = Config.restrict_unauthenticated_access?(:timelines, :federated)
{format, tag} = parse_tag(raw_tag) {format, tag} = parse_tag(raw_tag)
activities = activities =
%{type: ["Create"], tag: tag} %{type: ["Create"], tag: tag, local_only: local_only}
|> Pleroma.Maps.put_if_present(:max_id, params["max_id"]) |> Pleroma.Maps.put_if_present(:max_id, params["max_id"])
|> ActivityPub.fetch_public_activities() |> ActivityPub.fetch_public_activities()

View file

@ -15,11 +15,11 @@ defmodule Pleroma.Web.Feed.UserController do
action_fallback(:errors) action_fallback(:errors)
def feed_redirect(%{assigns: %{format: "html"}} = conn, %{"nickname" => nickname}) do def feed_redirect(%{assigns: %{format: "html"}} = conn, %{"nickname" => nickname} = params) do
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname_or_id(nickname)} do with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname_or_id(nickname)} do
Pleroma.Web.Fallback.RedirectController.redirector_with_meta(conn, %{user: user}) Pleroma.Web.Fallback.RedirectController.redirector_with_meta(conn, %{user: user})
else else
_ -> Pleroma.Web.Fallback.RedirectController.redirector(conn, nil) _ -> Pleroma.Web.Fallback.RedirectController.redirector_with_meta(conn, params)
end end
end end

View file

@ -53,9 +53,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
) do ) do
attachment_data = Map.put(object.data, "id", object.id) attachment_data = Map.put(object.data, "id", object.id)
conn render(conn, "attachment.json", %{attachment: attachment_data})
|> put_status(202)
|> render("attachment.json", %{attachment: attachment_data})
end end
end end

View file

@ -12,6 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Workers.PollWorker
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
@ -27,12 +28,16 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PollOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PollOperation
@cachex Pleroma.Config.get([:cachex, :provider], Cachex) @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
@poll_refresh_interval 120
@doc "GET /api/v1/polls/:id" @doc "GET /api/v1/polls/:id"
def show(%{assigns: %{user: user}, private: %{open_api_spex: %{params: %{id: id}}}} = conn, _) do def show(%{assigns: %{user: user}, private: %{open_api_spex: %{params: %{id: id}}}} = conn, _) do
with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60), with %Object{} = object <- Object.get_by_id(id),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]), %Activity{} = activity <-
Activity.get_create_by_object_ap_id_with_object(object.data["id"]),
true <- Visibility.visible_for_user?(activity, user) do true <- Visibility.visible_for_user?(activity, user) do
maybe_refresh_poll(activity)
try_render(conn, "show.json", %{object: object, for: user}) try_render(conn, "show.json", %{object: object, for: user})
else else
error when is_nil(error) or error == false -> error when is_nil(error) or error == false ->
@ -70,4 +75,13 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
end end
end) end)
end end
defp maybe_refresh_poll(%Activity{object: %Object{} = object} = activity) do
with false <- activity.local,
{:ok, end_time} <- NaiveDateTime.from_iso8601(object.data["closed"]),
{_, :lt} <- {:closed_compare, NaiveDateTime.compare(object.updated_at, end_time)} do
PollWorker.new(%{"op" => "refresh", "activity_id" => activity.id})
|> Oban.insert(unique: [period: @poll_refresh_interval])
end
end
end end

View file

@ -22,7 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
# This only prepares the connection and is not in the process yet # This only prepares the connection and is not in the process yet
@impl Phoenix.Socket.Transport @impl Phoenix.Socket.Transport
def connect(%{params: params} = transport_info) do def connect(%{params: params} = transport_info) do
with access_token <- Map.get(params, "access_token"), with access_token <- find_access_token(transport_info),
{:ok, user, oauth_token} <- authenticate_request(access_token), {:ok, user, oauth_token} <- authenticate_request(access_token),
{:ok, topic} <- {:ok, topic} <-
Streamer.get_topic(params["stream"], user, oauth_token, params) do Streamer.get_topic(params["stream"], user, oauth_token, params) do
@ -244,4 +244,13 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
def handle_error(conn, _reason) do def handle_error(conn, _reason) do
Plug.Conn.send_resp(conn, 404, "Not Found") Plug.Conn.send_resp(conn, 404, "Not Found")
end end
defp find_access_token(%{
connect_info: %{sec_websocket_protocol: [token]}
}),
do: token
defp find_access_token(%{params: %{"access_token" => token}}), do: token
defp find_access_token(_), do: nil
end end

View file

@ -7,6 +7,7 @@ defmodule Pleroma.Web.Metadata do
def build_tags(params) do def build_tags(params) do
providers = [ providers = [
Pleroma.Web.Metadata.Providers.ActivityPub,
Pleroma.Web.Metadata.Providers.RelMe, Pleroma.Web.Metadata.Providers.RelMe,
Pleroma.Web.Metadata.Providers.RestrictIndexing Pleroma.Web.Metadata.Providers.RestrictIndexing
| activated_providers() | activated_providers()

View file

@ -0,0 +1,22 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Providers.ActivityPub do
alias Pleroma.Web.Metadata.Providers.Provider
@behaviour Provider
@impl Provider
def build_tags(%{object: %{data: %{"id" => object_id}}}) do
[{:link, [rel: "alternate", type: "application/activity+json", href: object_id], []}]
end
@impl Provider
def build_tags(%{user: user}) do
[{:link, [rel: "alternate", type: "application/activity+json", href: user.ap_id], []}]
end
@impl Provider
def build_tags(_), do: []
end

View file

@ -10,7 +10,7 @@ defmodule Pleroma.Web.Metadata.Providers.Feed do
@behaviour Provider @behaviour Provider
@impl Provider @impl Provider
def build_tags(%{user: user}) do def build_tags(%{user: %{local: true} = user}) do
[ [
{:link, {:link,
[ [
@ -20,4 +20,7 @@ defmodule Pleroma.Web.Metadata.Providers.Feed do
], []} ], []}
] ]
end end
@impl Provider
def build_tags(_), do: []
end end

View file

@ -67,6 +67,9 @@ defmodule Pleroma.Web.Metadata.Providers.OpenGraph do
end end
end end
@impl Provider
def build_tags(_), do: []
defp build_attachments(%{data: %{"attachment" => attachments}}) do defp build_attachments(%{data: %{"attachment" => attachments}}) do
Enum.reduce(attachments, [], fn attachment, acc -> Enum.reduce(attachments, [], fn attachment, acc ->
rendered_tags = rendered_tags =

View file

@ -20,6 +20,9 @@ defmodule Pleroma.Web.Metadata.Providers.RelMe do
end) end)
end end
@impl Provider
def build_tags(_), do: []
defp append_fields_tag(bio, fields) do defp append_fields_tag(bio, fields) do
fields fields
|> Enum.reduce(bio, fn %{"value" => v}, res -> res <> v end) |> Enum.reduce(bio, fn %{"value" => v}, res -> res <> v end)

View file

@ -44,6 +44,9 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
end end
end end
@impl Provider
def build_tags(_), do: []
defp title_tag(user) do defp title_tag(user) do
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []} {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}
end end

View file

@ -20,7 +20,7 @@ defmodule Pleroma.Web.Push do
end end
def vapid_config do def vapid_config do
Application.get_env(:web_push_encryption, :vapid_details, nil) Application.get_env(:web_push_encryption, :vapid_details, [])
end end
def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config()) def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config())

View file

@ -13,6 +13,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.Healthcheck alias Pleroma.Healthcheck
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.WebFinger alias Pleroma.Web.WebFinger
@ -195,19 +196,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
%{assigns: %{user: user}, private: %{open_api_spex: %{body_params: body_params}}} = conn, %{assigns: %{user: user}, private: %{open_api_spex: %{body_params: body_params}}} = conn,
_ _
) do ) do
case CommonAPI.Utils.confirm_current_password(user, body_params.password) do with {:ok, %User{}} <-
{:ok, user} -> Authenticator.change_password(
with {:ok, _user} <- user,
User.reset_password(user, %{ body_params.password,
password: body_params.new_password, body_params.new_password,
password_confirmation: body_params.new_password_confirmation body_params.new_password_confirmation
}) do ) do
json(conn, %{status: "success"}) json(conn, %{status: "success"})
else else
{:error, changeset} -> {:error, %Ecto.Changeset{} = changeset} ->
{_, {error, _}} = Enum.at(changeset.errors, 0) {_, {error, _}} = Enum.at(changeset.errors, 0)
json(conn, %{error: "New password #{error}."}) json(conn, %{error: "New password #{error}."})
end
{:error, :password_confirmation} ->
json(conn, %{error: "New password does not match confirmation."})
{:error, msg} -> {:error, msg} ->
json(conn, %{error: msg}) json(conn, %{error: msg})

View file

@ -15,7 +15,8 @@ defmodule Pleroma.Web.TwitterAPI.TokenView do
%{ %{
id: token_entry.id, id: token_entry.id,
valid_until: token_entry.valid_until, valid_until: token_entry.valid_until,
app_name: token_entry.app.client_name app_name: token_entry.app.client_name,
scopes: token_entry.scopes
} }
end end
end end

View file

@ -11,27 +11,46 @@ defmodule Pleroma.Workers.PollWorker do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Object.Fetcher
@stream_out_impl Pleroma.Config.get(
[__MODULE__, :stream_out],
Pleroma.Web.ActivityPub.ActivityPub
)
@impl true @impl true
def perform(%Job{args: %{"op" => "poll_end", "activity_id" => activity_id}}) do def perform(%Job{args: %{"op" => "poll_end", "activity_id" => activity_id}}) do
with %Activity{} = activity <- find_poll_activity(activity_id), with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id(activity_id)},
{:ok, notifications} <- Notification.create_poll_notifications(activity) do {:ok, notifications} <- Notification.create_poll_notifications(activity) do
unless activity.local do
# Schedule a final refresh
__MODULE__.new(%{"op" => "refresh", "activity_id" => activity_id})
|> Oban.insert()
end
Notification.stream(notifications) Notification.stream(notifications)
else else
{:error, :poll_activity_not_found} = e -> {:cancel, e} {:activity, nil} -> {:cancel, :poll_activity_not_found}
e -> {:error, e} e -> {:error, e}
end end
end end
def perform(%Job{args: %{"op" => "refresh", "activity_id" => activity_id}}) do
with {_, %Activity{object: object}} <-
{:activity, Activity.get_by_id_with_object(activity_id)},
{_, {:ok, _object}} <- {:refetch, Fetcher.refetch_object(object)} do
stream_update(activity_id)
:ok
else
{:activity, nil} -> {:cancel, :poll_activity_not_found}
{:refetch, _} = e -> {:cancel, e}
end
end
@impl true @impl true
def timeout(_job), do: :timer.seconds(5) def timeout(_job), do: :timer.seconds(5)
defp find_poll_activity(activity_id) do
with nil <- Activity.get_by_id(activity_id) do
{:error, :poll_activity_not_found}
end
end
def schedule_poll_end(%Activity{data: %{"type" => "Create"}, id: activity_id} = activity) do def schedule_poll_end(%Activity{data: %{"type" => "Create"}, id: activity_id} = activity) do
with %Object{data: %{"type" => "Question", "closed" => closed}} when is_binary(closed) <- with %Object{data: %{"type" => "Question", "closed" => closed}} when is_binary(closed) <-
Object.normalize(activity), Object.normalize(activity),
@ -49,4 +68,10 @@ defmodule Pleroma.Workers.PollWorker do
end end
def schedule_poll_end(activity), do: {:error, activity} def schedule_poll_end(activity), do: {:error, activity}
defp stream_update(activity_id) do
Activity.get_by_id(activity_id)
|> Activity.normalize()
|> @stream_out_impl.stream_out()
end
end end

View file

@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
def project do def project do
[ [
app: :pleroma, app: :pleroma,
version: version("2.7.0"), version: version("2.7.51"),
elixir: "~> 1.14", elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
compilers: Mix.compilers(), compilers: Mix.compilers(),
@ -132,7 +132,8 @@ defmodule Pleroma.Mixfile do
# Type `mix help deps` for examples and options. # Type `mix help deps` for examples and options.
defp deps do defp deps do
[ [
{:phoenix, "~> 1.7.3"}, {:phoenix,
git: "https://github.com/feld/phoenix", branch: "v1.7.14-websocket-headers", override: true},
{:phoenix_ecto, "~> 4.4"}, {:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.10"}, {:ecto_sql, "~> 3.10"},
{:ecto_enum, "~> 1.4"}, {:ecto_enum, "~> 1.4"},

View file

@ -50,7 +50,7 @@
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
"exile": {:hex, :exile, "0.10.0", "b69e2d27a9af670b0f0a0898addca0eda78f6f5ba95ccfbc9bc6ccdd04925436", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "c62ee8fee565b5ac4a898d0dcd58d2b04fb5eec1655af1ddcc9eb582c6732c33"}, "exile": {:hex, :exile, "0.10.0", "b69e2d27a9af670b0f0a0898addca0eda78f6f5ba95ccfbc9bc6ccdd04925436", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "c62ee8fee565b5ac4a898d0dcd58d2b04fb5eec1655af1ddcc9eb582c6732c33"},
"expo": {:hex, :expo, "0.5.1", "249e826a897cac48f591deba863b26c16682b43711dd15ee86b92f25eafd96d9", [:mix], [], "hexpm", "68a4233b0658a3d12ee00d27d37d856b1ba48607e7ce20fd376958d0ba6ce92b"}, "expo": {:hex, :expo, "0.5.1", "249e826a897cac48f591deba863b26c16682b43711dd15ee86b92f25eafd96d9", [:mix], [], "hexpm", "68a4233b0658a3d12ee00d27d37d856b1ba48607e7ce20fd376958d0ba6ce92b"},
"fast_html": {:hex, :fast_html, "2.2.0", "6c5ef1be087a4ed613b0379c13f815c4d11742b36b67bb52cee7859847c84520", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "064c4f23b4a6168f9187dac8984b056f2c531bb0787f559fd6a8b34b38aefbae"}, "fast_html": {:hex, :fast_html, "2.3.0", "08c1d8ead840dd3060ba02c761bed9f37f456a1ddfe30bcdcfee8f651cec06a6", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "f18e3c7668f82d3ae0b15f48d48feeb257e28aa5ab1b0dbf781c7312e5da029d"},
"fast_sanitize": {:hex, :fast_sanitize, "0.2.3", "67b93dfb34e302bef49fec3aaab74951e0f0602fd9fa99085987af05bd91c7a5", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e8ad286d10d0386e15d67d0ee125245ebcfbc7d7290b08712ba9013c8c5e56e2"}, "fast_sanitize": {:hex, :fast_sanitize, "0.2.3", "67b93dfb34e302bef49fec3aaab74951e0f0602fd9fa99085987af05bd91c7a5", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e8ad286d10d0386e15d67d0ee125245ebcfbc7d7290b08712ba9013c8c5e56e2"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"},
@ -98,7 +98,7 @@
"open_api_spex": {:hex, :open_api_spex, "3.18.2", "8c855e83bfe8bf81603d919d6e892541eafece3720f34d1700b58024dadde247", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0 or ~> 4.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "aa3e6dcfc0ad6a02596b2172662da21c9dd848dac145ea9e603f54e3d81b8d2b"}, "open_api_spex": {:hex, :open_api_spex, "3.18.2", "8c855e83bfe8bf81603d919d6e892541eafece3720f34d1700b58024dadde247", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0 or ~> 4.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "aa3e6dcfc0ad6a02596b2172662da21c9dd848dac145ea9e603f54e3d81b8d2b"},
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
"phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, "phoenix": {:git, "https://github.com/feld/phoenix", "fb6dc76c657422e49600896c64aab4253fceaef6", [branch: "v1.7.14-websocket-headers"]},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.3", "86e9878f833829c3f66da03d75254c155d91d72a201eb56ae83482328dc7ca93", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d36c401206f3011fefd63d04e8ef626ec8791975d9d107f9a0817d426f61ac07"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.3", "86e9878f833829c3f66da03d75254c155d91d72a201eb56ae83482328dc7ca93", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d36c401206f3011fefd63d04e8ef626ec8791975d9d107f9a0817d426f61ac07"},
"phoenix_html": {:hex, :phoenix_html, "3.3.4", "42a09fc443bbc1da37e372a5c8e6755d046f22b9b11343bf885067357da21cb3", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0249d3abec3714aff3415e7ee3d9786cb325be3151e6c4b3021502c585bf53fb"}, "phoenix_html": {:hex, :phoenix_html, "3.3.4", "42a09fc443bbc1da37e372a5c8e6755d046f22b9b11343bf885067357da21cb3", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0249d3abec3714aff3415e7ee3d9786cb325be3151e6c4b3021502c585bf53fb"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.3", "7ff51c9b6609470f681fbea20578dede0e548302b0c8bdf338b5a753a4f045bf", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "f9470a0a8bae4f56430a23d42f977b5a6205fdba6559d76f932b876bfaec652d"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.3", "7ff51c9b6609470f681fbea20578dede0e548302b0c8bdf338b5a753a4f045bf", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "f9470a0a8bae4f56430a23d42f977b5a6205fdba6559d76f932b876bfaec652d"},

View file

@ -3,14 +3,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-22 02:09+0300\n" "POT-Creation-Date: 2022-07-22 02:09+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: 2024-10-13 21:03+0000\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Codimp <contact@lithio.fr>\n"
"Language-Team: none\n" "Language-Team: French <https://translate.pleroma.social/projects/pleroma/"
"pleroma-backend-domain-config_descriptions/fr/>\n"
"Language: fr\n" "Language: fr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 3.7.2\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.13.1\n"
## This file is a PO Template file. ## This file is a PO Template file.
## ##
@ -21,7 +23,6 @@ msgstr ""
## Run "mix gettext.extract" to bring this file up to ## Run "mix gettext.extract" to bring this file up to
## date. Leave "msgstr"s empty as changing them here has no ## date. Leave "msgstr"s empty as changing them here has no
## effect: edit them in PO (.po) files instead. ## effect: edit them in PO (.po) files instead.
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :esshd" msgctxt "config description at :esshd"
@ -32,25 +33,30 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :logger" msgctxt "config description at :logger"
msgid "Logger-related settings" msgid "Logger-related settings"
msgstr "" msgstr "Paramètres liés à la journalisation"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :mime" msgctxt "config description at :mime"
msgid "Mime Types settings" msgid "Mime Types settings"
msgstr "" msgstr "Paramètres des types Mime"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma" msgctxt "config description at :pleroma"
msgid "Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)" msgid "Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)"
msgstr "" msgstr ""
"Permet de configurer un jeton qui peut être utilisé pour authentifier les "
"requêtes avec des privilèges administrateurs sans utiliser un jeton de "
"compte utilisateur standard. Pour l'utiliser, ajoutez le paramètre "
"`admin_token`aux requêtes. (Vous devriez utiliser l'authentification HTTP "
"Basic ou OAuth à la place si vous le pouvez)"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma" msgctxt "config description at :pleroma"
msgid "Authenticator" msgid "Authenticator"
msgstr "" msgstr "Authentifieur"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -62,7 +68,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config label at :cors_plug" msgctxt "config label at :cors_plug"
msgid "CORS plug config" msgid "CORS plug config"
msgstr "" msgstr "Configuration du plug CORS"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -74,25 +80,25 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config label at :logger" msgctxt "config label at :logger"
msgid "Logger" msgid "Logger"
msgstr "" msgstr "Journaliseur"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config label at :mime" msgctxt "config label at :mime"
msgid "Mime Types" msgid "Mime Types"
msgstr "" msgstr "Types Mime"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config label at :pleroma" msgctxt "config label at :pleroma"
msgid "Pleroma Admin Token" msgid "Pleroma Admin Token"
msgstr "" msgstr "Jeton Administrateur Pleroma"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config label at :pleroma" msgctxt "config label at :pleroma"
msgid "Pleroma Authenticator" msgid "Pleroma Authenticator"
msgstr "" msgstr "Authentifieur Pleroma"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -104,103 +110,111 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :logger-:console" msgctxt "config description at :logger-:console"
msgid "Console logger settings" msgid "Console logger settings"
msgstr "" msgstr "Paramètres de journalisation de la console"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :logger-:ex_syslogger" msgctxt "config description at :logger-:ex_syslogger"
msgid "ExSyslogger-related settings" msgid "ExSyslogger-related settings"
msgstr "" msgstr "Paramètres liés à ExSyslogger"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:activitypub" msgctxt "config description at :pleroma-:activitypub"
msgid "ActivityPub-related settings" msgid "ActivityPub-related settings"
msgstr "" msgstr "Paramètres liés à ActivityPub"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:assets" msgctxt "config description at :pleroma-:assets"
msgid "This section configures assets to be used with various frontends. Currently the only option relates to mascots on the mastodon frontend" msgid "This section configures assets to be used with various frontends. Currently the only option relates to mascots on the mastodon frontend"
msgstr "" msgstr ""
"Cette section configure les annexes (assets) à utiliser avec divers "
"frontaux. La seule option est actuellement liée au mascottes du frontal "
"mastodon"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:auth" msgctxt "config description at :pleroma-:auth"
msgid "Authentication / authorization settings" msgid "Authentication / authorization settings"
msgstr "" msgstr "Paramètres d'authentification/autorisations"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:connections_pool" msgctxt "config description at :pleroma-:connections_pool"
msgid "Advanced settings for `Gun` connections pool" msgid "Advanced settings for `Gun` connections pool"
msgstr "" msgstr "Paramètres avancés pour le bac (pool) de connexions `Gun`"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:email_notifications" msgctxt "config description at :pleroma-:email_notifications"
msgid "Email notifications settings" msgid "Email notifications settings"
msgstr "" msgstr "Paramètres de notification par email"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:features" msgctxt "config description at :pleroma-:features"
msgid "Customizable features" msgid "Customizable features"
msgstr "" msgstr "Fonctionnalités personnalisables"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:feed" msgctxt "config description at :pleroma-:feed"
msgid "Configure feed rendering" msgid "Configure feed rendering"
msgstr "" msgstr "Configurer le rendu des flux"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:frontend_configurations" msgctxt "config description at :pleroma-:frontend_configurations"
msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete." msgid "This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for pleroma_fe are configured. If you want to add your own configuration your settings all fields must be complete."
msgstr "" msgstr ""
"Ce formulaire peut être utilisé pour configurer une liste de clés (keyword) "
"qui contiennent les données de configuration pour tout types de frontaux. "
"Par défaut, les paramètres pour pleroma_fe sont configurés. Si vous voulez "
"ajouter vos propres paramètres de configurations, tout les champs doivent "
"être remplis."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:frontends" msgctxt "config description at :pleroma-:frontends"
msgid "Installed frontends management" msgid "Installed frontends management"
msgstr "" msgstr "Gestion des frontaux installés"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:gopher" msgctxt "config description at :pleroma-:gopher"
msgid "Gopher settings" msgid "Gopher settings"
msgstr "" msgstr "Paramètres Gopher"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:hackney_pools" msgctxt "config description at :pleroma-:hackney_pools"
msgid "Advanced settings for `Hackney` connections pools" msgid "Advanced settings for `Hackney` connections pools"
msgstr "" msgstr "Paramètres avancés pour les bacs (pool) de connexions `Hackney`"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:http" msgctxt "config description at :pleroma-:http"
msgid "HTTP settings" msgid "HTTP settings"
msgstr "" msgstr "Paramètres HTTP"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:http_security" msgctxt "config description at :pleroma-:http_security"
msgid "HTTP security settings" msgid "HTTP security settings"
msgstr "" msgstr "Paramètres de sécurité HTTP"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:instance" msgctxt "config description at :pleroma-:instance"
msgid "Instance-related settings" msgid "Instance-related settings"
msgstr "" msgstr "Paramètres liés à l'instance"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:instances_favicons" msgctxt "config description at :pleroma-:instances_favicons"
msgid "Control favicons for instances" msgid "Control favicons for instances"
msgstr "" msgstr "Gère les favicons des instances"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -212,151 +226,177 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:majic_pool" msgctxt "config description at :pleroma-:majic_pool"
msgid "Majic/libmagic configuration" msgid "Majic/libmagic configuration"
msgstr "" msgstr "Configuration de majic/libmagic"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:manifest" msgctxt "config description at :pleroma-:manifest"
msgid "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE." msgid "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE."
msgstr "" msgstr ""
"Cette section décrit les valeurs spécifique à l'instance du manifeste PWA. "
"Actuellement, cette option ne concerne que MastoFE."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:media_preview_proxy" msgctxt "config description at :pleroma-:media_preview_proxy"
msgid "Media preview proxy" msgid "Media preview proxy"
msgstr "" msgstr "Proxy de prévisualisation média"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:media_proxy" msgctxt "config description at :pleroma-:media_proxy"
msgid "Media proxy" msgid "Media proxy"
msgstr "" msgstr "Proxy média"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:modules" msgctxt "config description at :pleroma-:modules"
msgid "Custom Runtime Modules" msgid "Custom Runtime Modules"
msgstr "" msgstr "Modules Runtime Personalisés"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf" msgctxt "config description at :pleroma-:mrf"
msgid "General MRF settings" msgid "General MRF settings"
msgstr "" msgstr "Paramètres généraux MRF"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_activity_expiration" msgctxt "config description at :pleroma-:mrf_activity_expiration"
msgid "Adds automatic expiration to all local activities" msgid "Adds automatic expiration to all local activities"
msgstr "" msgstr "Ajoute une expiration automatique à toutes les activités locales"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_follow_bot" msgctxt "config description at :pleroma-:mrf_follow_bot"
msgid "Automatically follows newly discovered accounts." msgid "Automatically follows newly discovered accounts."
msgstr "" msgstr "Suivre automatiquement les comptes venant d'être découverts."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_hashtag" msgctxt "config description at :pleroma-:mrf_hashtag"
msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n" msgid "Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)\n\nNote: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.\n"
msgstr "" msgstr ""
"Rejeter, Enlever de TWKN ou marquer comme contenu sensible les messages avec "
"des mots-croisillons (sans mettre le # du début)\n"
"\n"
"Note: cette politique MRF est toujours activée. Si vous voulez la "
"désactiver, vous devez configurer des listes vides.\n"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_hellthread" msgctxt "config description at :pleroma-:mrf_hellthread"
msgid "Block messages with excessive user mentions" msgid "Block messages with excessive user mentions"
msgstr "" msgstr "Bloquer les messages avec un nombre excessif de mentions"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_keyword" msgctxt "config description at :pleroma-:mrf_keyword"
msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)." msgid "Reject or Word-Replace messages matching a keyword or [Regex](https://hexdocs.pm/elixir/Regex.html)."
msgstr "" msgstr ""
"Rejeter ou remplacer les mots des messages qui correspondent à un mot clef "
"ou à une [expression rationnelle (Regex)](https://hexdocs.pm/elixir/Regex."
"html)."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_mention" msgctxt "config description at :pleroma-:mrf_mention"
msgid "Block messages which mention a specific user" msgid "Block messages which mention a specific user"
msgstr "" msgstr "Bloquer les messages mentionnant un utilisateur particulier"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_normalize_markup" msgctxt "config description at :pleroma-:mrf_normalize_markup"
msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup." msgid "MRF NormalizeMarkup settings. Scrub configured hypertext markup."
msgstr "" msgstr ""
"Paramètres de normalisation MRF. Balaie les balises hypertextes configurées."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_object_age" msgctxt "config description at :pleroma-:mrf_object_age"
msgid "Rejects or delists posts based on their timestamp deviance from your server's clock." msgid "Rejects or delists posts based on their timestamp deviance from your server's clock."
msgstr "" msgstr ""
"Rejette ou retire des listes les messages selon l'écart entre leur heure et "
"l'horloge de votre serveur."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_rejectnonpublic" msgctxt "config description at :pleroma-:mrf_rejectnonpublic"
msgid "RejectNonPublic drops posts with non-public visibility settings." msgid "RejectNonPublic drops posts with non-public visibility settings."
msgstr "" msgstr ""
"RejectNonPublic enlève les messages avec des paramètres de visibilité non-"
"publics."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_simple" msgctxt "config description at :pleroma-:mrf_simple"
msgid "Simple ingress policies" msgid "Simple ingress policies"
msgstr "" msgstr "Politiques simples pour entrants"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_steal_emoji" msgctxt "config description at :pleroma-:mrf_steal_emoji"
msgid "Steals emojis from selected instances when it sees them." msgid "Steals emojis from selected instances when it sees them."
msgstr "" msgstr "Vole les emojis des instances sélectionnées quand il les voit."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_subchain" msgctxt "config description at :pleroma-:mrf_subchain"
msgid "This policy processes messages through an alternate pipeline when a given message matches certain criteria. All criteria are configured as a map of regular expressions to lists of policy modules." msgid "This policy processes messages through an alternate pipeline when a given message matches certain criteria. All criteria are configured as a map of regular expressions to lists of policy modules."
msgstr "" msgstr ""
"Cette politique traite les messages à travers un tuyau séparé lorsqu'un "
"message donné correspond à certain critères. Chaque critère est configuré "
"comme une correspondance entre une expression rationnelle et une liste de "
"modules de politiques."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:mrf_vocabulary" msgctxt "config description at :pleroma-:mrf_vocabulary"
msgid "Filter messages which belong to certain activity vocabularies" msgid "Filter messages which belong to certain activity vocabularies"
msgstr "" msgstr ""
"Filtrer les messages qui correspondent à certain vocabulaires d'activités"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:oauth2" msgctxt "config description at :pleroma-:oauth2"
msgid "Configure OAuth 2 provider capabilities" msgid "Configure OAuth 2 provider capabilities"
msgstr "" msgstr "Configurer les capacités du fournisseur OAuth 2"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:pools" msgctxt "config description at :pleroma-:pools"
msgid "Advanced settings for `Gun` workers pools" msgid "Advanced settings for `Gun` workers pools"
msgstr "" msgstr "Paramètres avancés pour les bacs (pools) de travailleurs `Gun`"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:populate_hashtags_table" msgctxt "config description at :pleroma-:populate_hashtags_table"
msgid "`populate_hashtags_table` background migration settings" msgid "`populate_hashtags_table` background migration settings"
msgstr "" msgstr "Paramètres de migration en arrière-plan `populate_hashtags_table`"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:rate_limit" msgctxt "config description at :pleroma-:rate_limit"
msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default." msgid "Rate limit settings. This is an advanced feature enabled only for :authentication by default."
msgstr "" msgstr ""
"Paramètres de limites par secondes. C'est une fonctionnalité avancée qui, "
"par défaut, n'est activée que pour :authentication."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:restrict_unauthenticated" msgctxt "config description at :pleroma-:restrict_unauthenticated"
msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users." msgid "Disallow viewing timelines, user profiles and statuses for unauthenticated users."
msgstr "" msgstr ""
"Empêche de regarder les flux, les profils utilisateurs et les status pour "
"les utilisateurs non-authentifiés."
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:rich_media" msgctxt "config description at :pleroma-:rich_media"
msgid "If enabled the instance will parse metadata from attached links to generate link previews" msgid "If enabled the instance will parse metadata from attached links to generate link previews"
msgstr "" msgstr ""
"Si activé, l'instance interprétera les métadonnées des liens joins pour "
"générer les prévisualisations de liens"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -369,6 +409,8 @@ msgstr ""
msgctxt "config description at :pleroma-:static_fe" msgctxt "config description at :pleroma-:static_fe"
msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript" msgid "Render profiles and posts using server-generated HTML that is viewable without using JavaScript"
msgstr "" msgstr ""
"Rendre les profils et les status en utilisant du HTML généré par le serveur "
"qui ne nécessitera pas de JavaScript"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
@ -380,7 +422,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgctxt "config description at :pleroma-:uri_schemes" msgctxt "config description at :pleroma-:uri_schemes"
msgid "URI schemes related settings" msgid "URI schemes related settings"
msgstr "" msgstr "Paramètres liés au schémas d'URI"
#: lib/pleroma/docs/translator.ex:5 #: lib/pleroma/docs/translator.ex:5
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format

View file

@ -9,3 +9,8 @@
## Tweak GC to run more often ## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10 ##-env ERL_FULLSWEEP_AFTER 10
# Disable wasteful busywait.
+sbwt none
+sbwtdcpu none
+sbwtdio none

View file

@ -268,6 +268,17 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end) end)
end end
test "accepts valid token on Sec-WebSocket-Protocol header", %{token: token} do
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
capture_log(fn ->
assert {:error, %WebSockex.RequestError{code: 401}} =
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
Process.sleep(30)
end)
end
test "accepts valid token on client-sent event", %{token: token} do test "accepts valid token on client-sent event", %{token: token} do
assert {:ok, pid} = start_socket() assert {:ok, pid} = start_socket()

View file

@ -6,12 +6,10 @@ defmodule Pleroma.ObjectTest do
use Pleroma.DataCase use Pleroma.DataCase
use Oban.Testing, repo: Pleroma.Repo use Oban.Testing, repo: Pleroma.Repo
import ExUnit.CaptureLog
import Mox import Mox
import Pleroma.Factory import Pleroma.Factory
import Tesla.Mock import Tesla.Mock
alias Pleroma.Activity
alias Pleroma.Hashtag alias Pleroma.Hashtag
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
@ -176,8 +174,9 @@ defmodule Pleroma.ObjectTest do
filename = Path.basename(href) filename = Path.basename(href)
assert {:ok, files} = File.ls(uploads_dir) expected_path = Path.join([uploads_dir, Pleroma.Upload.Filter.Dedupe.shard_path(filename)])
assert filename in files
assert File.exists?(expected_path)
Object.delete(note) Object.delete(note)
@ -185,8 +184,7 @@ defmodule Pleroma.ObjectTest do
assert Object.get_by_id(note.id).data["deleted"] assert Object.get_by_id(note.id).data["deleted"]
assert Object.get_by_id(attachment.id) == nil assert Object.get_by_id(attachment.id) == nil
assert {:ok, files} = File.ls(uploads_dir) refute File.exists?(expected_path)
refute filename in files
end end
test "with objects that have legacy data.url attribute" do test "with objects that have legacy data.url attribute" do
@ -282,148 +280,6 @@ defmodule Pleroma.ObjectTest do
end end
end end
describe "get_by_id_and_maybe_refetch" do
setup do
mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_original.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
env ->
apply(HttpRequestMock, :request, [env])
end)
mock_modified = fn resp ->
mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
resp
env ->
apply(HttpRequestMock, :request, [env])
end)
end
on_exit(fn -> mock(fn env -> apply(HttpRequestMock, :request, [env]) end) end)
[mock_modified: mock_modified]
end
test "refetches if the time since the last refetch is greater than the interval", %{
mock_modified: mock_modified
} do
%Object{} =
object =
Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
fetch: true
)
Object.set_cache(object)
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
object_in_cache = Object.get_cached_by_ap_id(object.data["id"])
assert updated_object == object_in_cache
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
end
test "returns the old object if refetch fails", %{mock_modified: mock_modified} do
%Object{} =
object =
Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
fetch: true
)
Object.set_cache(object)
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
assert capture_log(fn ->
mock_modified.(%Tesla.Env{status: 404, body: ""})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
object_in_cache = Object.get_cached_by_ap_id(object.data["id"])
assert updated_object == object_in_cache
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
end) =~
"[error] Couldn't refresh https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"
end
test "does not refetch if the time since the last refetch is greater than the interval", %{
mock_modified: mock_modified
} do
%Object{} =
object =
Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
fetch: true
)
Object.set_cache(object)
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: 100)
object_in_cache = Object.get_cached_by_ap_id(object.data["id"])
assert updated_object == object_in_cache
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
end
test "preserves internal fields on refetch", %{mock_modified: mock_modified} do
%Object{} =
object =
Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d",
fetch: true
)
Object.set_cache(object)
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
user = insert(:user)
activity = Activity.get_create_by_object_ap_id(object.data["id"])
{:ok, activity} = CommonAPI.favorite(activity.id, user)
object = Object.get_by_ap_id(activity.data["object"])
assert object.data["like_count"] == 1
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json"),
headers: HttpRequestMock.activitypub_object_headers()
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
object_in_cache = Object.get_cached_by_ap_id(object.data["id"])
assert updated_object == object_in_cache
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
assert updated_object.data["like_count"] == 1
end
end
describe ":hashtags association" do describe ":hashtags association" do
test "Hashtag records are created with Object record and updated on its change" do test "Hashtag records are created with Object record and updated on its change" do
user = insert(:user) user = insert(:user)

View file

@ -0,0 +1,19 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReleaseTaskTest do
use Pleroma.DataCase, async: true
alias Pleroma.ReleaseTasks
test "finding the module" do
task = "search.meilisearch"
assert Mix.Tasks.Pleroma.Search.Meilisearch == ReleaseTasks.find_module(task)
task = "user"
assert Mix.Tasks.Pleroma.User == ReleaseTasks.find_module(task)
refute ReleaseTasks.find_module("doesnt.exist")
end
end

View file

@ -10,6 +10,10 @@ defmodule Pleroma.Upload.Filter.DedupeTest do
@shasum "e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781" @shasum "e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781"
test "generates a shard path for a shasum" do
assert "e3/03/97/" <> _path = Dedupe.shard_path(@shasum)
end
test "adds shasum" do test "adds shasum" do
File.cp!( File.cp!(
"test/fixtures/image.jpg", "test/fixtures/image.jpg",
@ -23,10 +27,12 @@ defmodule Pleroma.Upload.Filter.DedupeTest do
tempfile: Path.absname("test/fixtures/image_tmp.jpg") tempfile: Path.absname("test/fixtures/image_tmp.jpg")
} }
expected_path = Dedupe.shard_path(@shasum <> ".jpg")
assert { assert {
:ok, :ok,
:filtered, :filtered,
%Pleroma.Upload{id: @shasum, path: @shasum <> ".jpg"} %Pleroma.Upload{id: @shasum, path: ^expected_path}
} = Dedupe.filter(upload) } = Dedupe.filter(upload)
end end
end end

View file

@ -149,6 +149,9 @@ defmodule Pleroma.UploadTest do
test "copies the file to the configured folder with deduping" do test "copies the file to the configured folder with deduping" do
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
expected_filename = "e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781.jpg"
expected_path = Pleroma.Upload.Filter.Dedupe.shard_path(expected_filename)
file = %Plug.Upload{ file = %Plug.Upload{
content_type: "image/jpeg", content_type: "image/jpeg",
@ -159,8 +162,7 @@ defmodule Pleroma.UploadTest do
{:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.Dedupe]) {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.Dedupe])
assert List.first(data["url"])["href"] == assert List.first(data["url"])["href"] ==
Pleroma.Upload.base_url() <> Path.join([Pleroma.Upload.base_url(), expected_path])
"e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781.jpg"
end end
test "copies the file to the configured folder without deduping" do test "copies the file to the configured folder without deduping" do

View file

@ -1320,6 +1320,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
html_body: ~r/#{note.data["object"]}/i html_body: ~r/#{note.data["object"]}/i
) )
end end
test "it accepts an incoming Block", %{conn: conn, data: data} do
user = insert(:user)
data =
data
|> Map.put("type", "Block")
|> Map.put("to", [user.ap_id])
|> Map.put("cc", [])
|> Map.put("object", user.ap_id)
conn =
conn
|> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/inbox", data)
assert "ok" == json_response(conn, 200)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
end end
describe "GET /users/:nickname/outbox" do describe "GET /users/:nickname/outbox" do

View file

@ -0,0 +1,155 @@
defmodule Pleroma.Web.ActivityPub.MRF.RemoteReportPolicyTest do
use Pleroma.DataCase, async: true
alias Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy
setup do
clear_config([:mrf_remote_report, :reject_all], false)
end
test "doesn't impact local report" do
clear_config([:mrf_remote_report, :reject_anonymous], true)
clear_config([:mrf_remote_report, :reject_empty_message], true)
activity = %{
"type" => "Flag",
"actor" => "http://localhost:4001/actor",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "rejects anonymous report if `reject_anonymous: true`" do
clear_config([:mrf_remote_report, :reject_anonymous], true)
clear_config([:mrf_remote_report, :reject_empty_message], true)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/actor",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:reject, _} = RemoteReportPolicy.filter(activity)
end
test "preserves anonymous report if `reject_anonymous: false`" do
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/actor",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "rejects report on third party if `reject_third_party: true`" do
clear_config([:mrf_remote_report, :reject_third_party], true)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:reject, _} = RemoteReportPolicy.filter(activity)
end
test "preserves report on first party if `reject_third_party: true`" do
clear_config([:mrf_remote_report, :reject_third_party], true)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["http://localhost:4001/actor"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "preserves report on third party if `reject_third_party: false`" do
clear_config([:mrf_remote_report, :reject_third_party], false)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "rejects empty message report if `reject_empty_message: true`" do
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], true)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:reject, _} = RemoteReportPolicy.filter(activity)
end
test "rejects empty message report (\"\") if `reject_empty_message: true`" do
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], true)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["https://mastodon.online/users/Gargron"],
"content" => ""
}
assert {:reject, _} = RemoteReportPolicy.filter(activity)
end
test "preserves empty message report if `reject_empty_message: false`" do
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "preserves anonymous, empty message report with all settings disabled" do
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/actor",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:ok, _} = RemoteReportPolicy.filter(activity)
end
test "reject remote report if `reject_all: true`" do
clear_config([:mrf_remote_report, :reject_all], true)
clear_config([:mrf_remote_report, :reject_anonymous], false)
clear_config([:mrf_remote_report, :reject_empty_message], false)
activity = %{
"type" => "Flag",
"actor" => "https://mastodon.social/users/Gargron",
"content" => "Transphobia",
"object" => ["https://mastodon.online/users/Gargron"]
}
assert {:reject, _} = RemoteReportPolicy.filter(activity)
end
end

View file

@ -32,7 +32,7 @@ defmodule Pleroma.Web.FallbackTest do
resp = get(conn, "/foo") resp = get(conn, "/foo")
assert html_response(resp, 200) =~ "<title>a cool title</title>" assert html_response(resp, 200) =~ "<title>a cool title</title>"
refute html_response(resp, 200) =~ "initial-results" assert html_response(resp, 200) =~ "<meta content=\"noindex, noarchive\" name=\"robots\">"
end end
test "GET /*path", %{conn: conn} do test "GET /*path", %{conn: conn} do

View file

@ -191,4 +191,60 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|> response(404) |> response(404)
end end
end end
describe "restricted for unauthenticated" do
test "returns 404 when local timeline is disabled", %{conn: conn} do
clear_config([:restrict_unauthenticated, :timelines], %{local: true, federated: false})
conn
|> put_req_header("accept", "application/rss+xml")
|> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
|> response(404)
end
test "returns local posts only when federated timeline is disabled", %{conn: conn} do
clear_config([:restrict_unauthenticated, :timelines], %{local: false, federated: true})
local_user = insert(:user)
remote_user = insert(:user, local: false)
local_note =
insert(:note,
user: local_user,
data: %{
"content" => "local post #PleromaArt",
"summary" => "",
"tag" => ["pleromaart"]
}
)
remote_note =
insert(:note,
user: remote_user,
data: %{
"content" => "remote post #PleromaArt",
"summary" => "",
"tag" => ["pleromaart"]
},
local: false
)
insert(:note_activity, user: local_user, note: local_note)
insert(:note_activity, user: remote_user, note: remote_note, local: false)
response =
conn
|> put_req_header("accept", "application/rss+xml")
|> get(tag_feed_path(conn, :feed, "pleromaart.rss"))
|> response(200)
xml = parse(response)
assert xpath(xml, ~x"//channel/title/text()") == ~c"#pleromaart"
assert xpath(xml, ~x"//channel/item/title/text()"l) == [
~c"local post #PleromaArt"
]
end
end
end end

View file

@ -147,6 +147,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
assert response(conn, 404) assert response(conn, 404)
end end
test "returns noindex meta for missing user", %{conn: conn} do
conn =
conn
|> put_req_header("accept", "text/html")
|> get("/users/nonexisting")
assert html_response(conn, 200) =~ "<meta content=\"noindex, noarchive\" name=\"robots\">"
end
test "returns feed with public and unlisted activities", %{conn: conn} do test "returns feed with public and unlisted activities", %{conn: conn} do
user = insert(:user) user = insert(:user)

View file

@ -56,7 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
conn conn
|> put_req_header("content-type", "multipart/form-data") |> put_req_header("content-type", "multipart/form-data")
|> post("/api/v2/media", %{"file" => image, "description" => desc}) |> post("/api/v2/media", %{"file" => image, "description" => desc})
|> json_response_and_validate_schema(202) |> json_response_and_validate_schema(200)
assert media_id = response["id"] assert media_id = response["id"]
@ -111,7 +111,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
"file" => large_binary, "file" => large_binary,
"description" => desc "description" => desc
}) })
|> json_response_and_validate_schema(202) |> json_response_and_validate_schema(200)
assert media_id = response["id"] assert media_id = response["id"]

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.PollControllerTest do defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
alias Pleroma.Object alias Pleroma.Object
@ -27,6 +28,33 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
response = json_response_and_validate_schema(conn, 200) response = json_response_and_validate_schema(conn, 200)
id = to_string(object.id) id = to_string(object.id)
assert %{"id" => ^id, "expired" => false, "multiple" => false} = response assert %{"id" => ^id, "expired" => false, "multiple" => false} = response
# Local activities should not generate an Oban job to refresh
assert activity.local
refute_enqueued(
worker: Pleroma.Workers.PollWorker,
args: %{"op" => "refresh", "activity_id" => activity.id}
)
end
test "creates an oban job to refresh poll if activity is remote", %{conn: conn} do
user = insert(:user, local: false)
question = insert(:question, user: user)
activity = insert(:question_activity, question: question, local: false)
# Ensure this is not represented as a local activity
refute activity.local
object = Object.normalize(activity, fetch: false)
get(conn, "/api/v1/polls/#{object.id}")
|> json_response_and_validate_schema(200)
assert_enqueued(
worker: Pleroma.Workers.PollWorker,
args: %{"op" => "refresh", "activity_id" => activity.id}
)
end end
test "does not expose polls for private statuses", %{conn: conn} do test "does not expose polls for private statuses", %{conn: conn} do

View file

@ -0,0 +1,40 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Providers.ActivityPubTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Metadata.Providers.ActivityPub
setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
test "it renders a link for user info" do
user = insert(:user)
res = ActivityPub.build_tags(%{user: user})
assert res == [
{:link, [rel: "alternate", type: "application/activity+json", href: user.ap_id], []}
]
end
test "it renders a link for a post" do
user = insert(:user)
{:ok, %{id: activity_id, object: object}} = CommonAPI.post(user, %{status: "hi"})
result = ActivityPub.build_tags(%{object: object, user: user, activity_id: activity_id})
assert [
{:link,
[rel: "alternate", type: "application/activity+json", href: object.data["id"]], []}
] == result
end
test "it returns an empty array for anything else" do
result = ActivityPub.build_tags(%{})
assert result == []
end
end

View file

@ -15,4 +15,10 @@ defmodule Pleroma.Web.Metadata.Providers.FeedTest do
[rel: "alternate", type: "application/atom+xml", href: "/users/lain/feed.atom"], []} [rel: "alternate", type: "application/atom+xml", href: "/users/lain/feed.atom"], []}
] ]
end end
test "it doesn't render a link to remote user's feed" do
user = insert(:user, nickname: "lain@lain.com", local: false)
assert Feed.build_tags(%{user: user}) == []
end
end end

View file

@ -69,7 +69,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> hd() |> hd()
|> Map.keys() |> Map.keys()
assert keys -- ["id", "app_name", "valid_until"] == [] assert Enum.sort(keys) == Enum.sort(["id", "app_name", "valid_until", "scopes"])
end end
test "revoke token", %{token: token} do test "revoke token", %{token: token} do

View file

@ -11,10 +11,10 @@ defmodule Pleroma.Workers.PollWorkerTest do
alias Pleroma.Workers.PollWorker alias Pleroma.Workers.PollWorker
test "poll notification job" do test "local poll ending notification job" do
user = insert(:user) user = insert(:user)
question = insert(:question, user: user) question = insert(:question, user: user)
activity = insert(:question_activity, question: question) activity = insert(:question_activity, question: question, user: user)
PollWorker.schedule_poll_end(activity) PollWorker.schedule_poll_end(activity)
@ -44,6 +44,65 @@ defmodule Pleroma.Workers.PollWorkerTest do
# Ensure notifications were streamed out when job executes # Ensure notifications were streamed out when job executes
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], :_)) assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], :_))
assert called(Pleroma.Web.Push.send(:_)) assert called(Pleroma.Web.Push.send(:_))
# Skip refreshing polls for local activities
assert activity.local
refute_enqueued(
worker: PollWorker,
args: %{"op" => "refresh", "activity_id" => activity.id}
)
end
end
test "remote poll ending notification job schedules refresh" do
user = insert(:user, local: false)
question = insert(:question, user: user)
activity = insert(:question_activity, question: question, user: user)
PollWorker.schedule_poll_end(activity)
expected_job_args = %{"activity_id" => activity.id, "op" => "poll_end"}
assert_enqueued(args: expected_job_args)
[job] = all_enqueued(worker: PollWorker)
PollWorker.perform(job)
refute activity.local
assert_enqueued(
worker: PollWorker,
args: %{"op" => "refresh", "activity_id" => activity.id}
)
end
test "poll refresh" do
user = insert(:user, local: false)
question = insert(:question, user: user)
activity = insert(:question_activity, question: question)
PollWorker.new(%{"op" => "refresh", "activity_id" => activity.id})
|> Oban.insert()
expected_job_args = %{"activity_id" => activity.id, "op" => "refresh"}
assert_enqueued(args: expected_job_args)
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
}
]) do
[job] = all_enqueued(worker: PollWorker)
PollWorker.perform(job)
# Ensure updates are streamed out
assert called(Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], :_))
end end
end end
end end

View file

@ -241,6 +241,7 @@ defmodule Pleroma.Factory do
def question_factory(attrs \\ %{}) do def question_factory(attrs \\ %{}) do
user = attrs[:user] || insert(:user) user = attrs[:user] || insert(:user)
closed = attrs[:closed] || DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601()
data = %{ data = %{
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(), "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
@ -251,7 +252,7 @@ defmodule Pleroma.Factory do
"to" => ["https://www.w3.org/ns/activitystreams#Public"], "to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [user.follower_address], "cc" => [user.follower_address],
"context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(), "context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(),
"closed" => DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601(), "closed" => closed,
"content" => "Which flavor of ice cream do you prefer?", "content" => "Which flavor of ice cream do you prefer?",
"oneOf" => [ "oneOf" => [
%{ %{
@ -509,7 +510,8 @@ defmodule Pleroma.Factory do
%Pleroma.Activity{ %Pleroma.Activity{
data: data, data: data,
actor: data["actor"], actor: data["actor"],
recipients: data["to"] recipients: data["to"],
local: user.local
} }
|> Map.merge(attrs) |> Map.merge(attrs)
end end