Sync changes from upstream on develop branch #1

Merged
fedward merged 21 commits from AkkomaGang/akkoma:develop into develop 2022-11-15 15:32:17 +00:00
29 changed files with 463 additions and 71 deletions

1
.gitignore vendored
View file

@ -1,5 +1,6 @@
# App artifacts # App artifacts
docs/site docs/site
*.zip
*.sw* *.sw*
secret secret
/_build /_build

View file

@ -4,12 +4,13 @@ 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/).
## Unreleased ## 2022.11
## Added ## Added
- Officially supported docker release - Officially supported docker release
- Ability to remove followers unilaterally without a block - Ability to remove followers unilaterally without a block
- Scraping of nodeinfo from remote instances to display instance info - Scraping of nodeinfo from remote instances to display instance info
- `requested_by` in relationships when the user has requested to follow you
## Changes ## Changes
- Follows no longer override domain blocks, a domain block is final - Follows no longer override domain blocks, a domain block is final
@ -19,6 +20,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Fixed ## Fixed
- Registrations via ldap are now compatible with the latest OTP24 - Registrations via ldap are now compatible with the latest OTP24
## Update notes
- If you use LDAP and run from source, please update your elixir/erlang
to the latest. The changes in OTP24.3 are breaking.
- You can now remove the leading `*.` from domain blocks, but you do not have to.
## 2022.10 ## 2022.10
### Added ### Added

View file

@ -8,7 +8,7 @@
This is a fork of Pleroma, which is a microblogging server software that can federate (= exchange messages with) other servers that support ActivityPub. What that means is that you can host a server for yourself or your friends and stay in control of your online identity, but still exchange messages with people on larger servers. Akkoma will federate with all servers that implement ActivityPub, like Friendica, GNU Social, Hubzilla, Mastodon, Misskey, Peertube, and Pixelfed. This is a fork of Pleroma, which is a microblogging server software that can federate (= exchange messages with) other servers that support ActivityPub. What that means is that you can host a server for yourself or your friends and stay in control of your online identity, but still exchange messages with people on larger servers. Akkoma will federate with all servers that implement ActivityPub, like Friendica, GNU Social, Hubzilla, Mastodon, Misskey, Peertube, and Pixelfed.
Akkoma is written in Elixir and uses PostgresSQL for data storage. Akkoma is written in Elixir and uses PostgreSQL for data storage.
For clients it supports the [Mastodon client API](https://docs.joinmastodon.org/api/guidelines/) with Pleroma extensions (see the API section on <https://docs.akkoma.dev/stable/>). For clients it supports the [Mastodon client API](https://docs.joinmastodon.org/api/guidelines/) with Pleroma extensions (see the API section on <https://docs.akkoma.dev/stable/>).
@ -46,15 +46,13 @@ If your platform is not supported, or you just want to be able to edit the sourc
- [Alpine Linux](https://docs.akkoma.dev/stable/installation/alpine_linux_en/) - [Alpine Linux](https://docs.akkoma.dev/stable/installation/alpine_linux_en/)
- [Arch Linux](https://docs.akkoma.dev/stable/installation/arch_linux_en/) - [Arch Linux](https://docs.akkoma.dev/stable/installation/arch_linux_en/)
- [Debian-based](https://docs.akkoma.dev/stable/installation/debian_based_en/) - [Debian-based](https://docs.akkoma.dev/stable/installation/debian_based_en/)
- [Debian-based (jp)](https://docs.akkoma.dev/stable/installation/debian_based_jp/)
- [FreeBSD](https://docs.akkoma.dev/stable/installation/freebsd_en/) - [FreeBSD](https://docs.akkoma.dev/stable/installation/freebsd_en/)
- [Gentoo Linux](https://docs.akkoma.dev/stable/installation/gentoo_en/) - [Gentoo Linux](https://docs.akkoma.dev/stable/installation/gentoo_en/)
- [NetBSD](https://docs.akkoma.dev/stable/installation/netbsd_en/) - [NetBSD](https://docs.akkoma.dev/stable/installation/netbsd_en/)
- [OpenBSD](https://docs.akkoma.dev/stable/installation/openbsd_en/) - [OpenBSD](https://docs.akkoma.dev/stable/installation/openbsd_en/)
- [OpenBSD (fi)](https://docs.akkoma.dev/stable/installation/openbsd_fi/)
### Docker ### Docker
While we dont provide docker files, other people have written very good ones. Take a look at <https://github.com/angristan/docker-pleroma> or <https://glitch.sh/sn0w/pleroma-docker>. Docker installation is supported via [this setup](https://docs.akkoma.dev/stable/installation/docker_en/)
### Compilation Troubleshooting ### Compilation Troubleshooting
If you ever encounter compilation issues during the updating of Akkoma, you can try these commands and see if they fix things: If you ever encounter compilation issues during the updating of Akkoma, you can try these commands and see if they fix things:
@ -66,3 +64,4 @@ If you ever encounter compilation issues during the updating of Akkoma, you can
## Documentation ## Documentation
- https://docs.akkoma.dev/stable - https://docs.akkoma.dev/stable
- https://docs.akkoma.dev/develop

View file

@ -317,7 +317,7 @@
nsfwCensorImage: "", nsfwCensorImage: "",
postContentType: "text/plain", postContentType: "text/plain",
redirectRootLogin: "/main/friends", redirectRootLogin: "/main/friends",
redirectRootNoLogin: "/main/all", redirectRootNoLogin: "/main/public",
scopeCopy: true, scopeCopy: true,
sidebarRight: false, sidebarRight: false,
showFeaturesPanel: true, showFeaturesPanel: true,
@ -584,6 +584,27 @@
federator_incoming: 5, federator_incoming: 5,
federator_outgoing: 5, federator_outgoing: 5,
search_indexing: 2 search_indexing: 2
],
timeout: [
activity_expiration: :timer.seconds(5),
token_expiration: :timer.seconds(5),
filter_expiration: :timer.seconds(5),
backup: :timer.seconds(900),
federator_incoming: :timer.seconds(10),
federator_outgoing: :timer.seconds(10),
ingestion_queue: :timer.seconds(5),
web_push: :timer.seconds(5),
mailer: :timer.seconds(5),
transmogrifier: :timer.seconds(5),
scheduled_activities: :timer.seconds(5),
poll_notifications: :timer.seconds(5),
background: :timer.seconds(5),
remote_fetcher: :timer.seconds(10),
attachments_cleanup: :timer.seconds(900),
new_users_digest: :timer.seconds(10),
mute_expire: :timer.seconds(5),
search_indexing: :timer.seconds(5),
nodeinfo_fetcher: :timer.seconds(10)
] ]
config :pleroma, Pleroma.Formatter, config :pleroma, Pleroma.Formatter,

View file

@ -1979,6 +1979,32 @@
federator_incoming: 5, federator_incoming: 5,
federator_outgoing: 5 federator_outgoing: 5
] ]
},
%{
key: :timeout,
type: {:keyword, :integer},
description: "Timeout for jobs, per `Oban` queue, in ms",
suggestions: [
activity_expiration: :timer.seconds(5),
token_expiration: :timer.seconds(5),
filter_expiration: :timer.seconds(5),
backup: :timer.seconds(900),
federator_incoming: :timer.seconds(10),
federator_outgoing: :timer.seconds(10),
ingestion_queue: :timer.seconds(5),
web_push: :timer.seconds(5),
mailer: :timer.seconds(5),
transmogrifier: :timer.seconds(5),
scheduled_activities: :timer.seconds(5),
poll_notifications: :timer.seconds(5),
background: :timer.seconds(5),
remote_fetcher: :timer.seconds(10),
attachments_cleanup: :timer.seconds(900),
new_users_digest: :timer.seconds(10),
mute_expire: :timer.seconds(5),
search_indexing: :timer.seconds(5),
nodeinfo_fetcher: :timer.seconds(10)
]
} }
] ]
}, },

View file

@ -1,9 +1,14 @@
all: install all: install
pipenv run mkdocs build pipenv run mkdocs build
branch := $(shell git rev-parse --abbrev-ref HEAD)
install: install:
pipenv install pipenv install
clean: clean:
rm -rf site rm -rf site
serve: serve:
pipenv run python3 -m http.server -d site pipenv run python3 -m http.server -d site
zip:
zip -r docs.zip site/*
deploy:
cd site && rclone copy . scaleway:akkoma-docs/$(branch)

95
docs/Pipfile.lock generated
View file

@ -14,6 +14,22 @@
] ]
}, },
"default": { "default": {
"certifi": {
"hashes": [
"sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14",
"sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"
],
"markers": "python_version >= '3.6'",
"version": "==2022.9.24"
},
"charset-normalizer": {
"hashes": [
"sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845",
"sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"
],
"markers": "python_version >= '3.6'",
"version": "==2.1.1"
},
"click": { "click": {
"hashes": [ "hashes": [
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
@ -29,13 +45,13 @@
], ],
"version": "==2.1.0" "version": "==2.1.0"
}, },
"importlib-metadata": { "idna": {
"hashes": [ "hashes": [
"sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
"sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.5'",
"version": "==4.12.0" "version": "==3.4"
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
@ -55,10 +71,10 @@
}, },
"markdown-include": { "markdown-include": {
"hashes": [ "hashes": [
"sha256:6f5d680e36f7780c7f0f61dca53ca581bd50d1b56137ddcd6353efafa0c3e4a2" "sha256:a06183b7c7225e73112737acdc6fe0ac0686c39457234eeb5ede23881fed001d"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.6.0" "version": "==0.7.0"
}, },
"markupsafe": { "markupsafe": {
"hashes": [ "hashes": [
@ -116,27 +132,27 @@
}, },
"mkdocs": { "mkdocs": {
"hashes": [ "hashes": [
"sha256:26bd2b03d739ac57a3e6eed0b7bcc86168703b719c27b99ad6ca91dc439aacde", "sha256:8947af423a6d0facf41ea1195b8e1e8c85ad94ac95ae307fe11232e0424b11c5",
"sha256:b504405b04da38795fec9b2e5e28f6aa3a73bb0960cb6d5d27ead28952bd35ea" "sha256:c8856a832c1e56702577023cd64cc5f84948280c1c0fcc6af4cd39006ea6aa8c"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.7'",
"version": "==1.3.0" "version": "==1.4.2"
}, },
"mkdocs-material": { "mkdocs-material": {
"hashes": [ "hashes": [
"sha256:263f2721f3abe533b61f7c8bed435a0462620912742c919821ac2d698b4bfe67", "sha256:143ea55843b3747b640e1110824d91e8a4c670352380e166e64959f9abe98862",
"sha256:dc82b667d2a83f0de581b46a6d0949732ab77e7638b87ea35b770b33bc02e75a" "sha256:45eeabb23d2caba8fa3b85c91d9ec8e8b22add716e9bba8faf16d56af8aa5622"
], ],
"index": "pypi", "index": "pypi",
"version": "==8.3.9" "version": "==8.5.9"
}, },
"mkdocs-material-extensions": { "mkdocs-material-extensions": {
"hashes": [ "hashes": [
"sha256:a82b70e533ce060b2a5d9eb2bc2e1be201cf61f901f93704b4acf6e3d5983a44", "sha256:96ca979dae66d65c2099eefe189b49d5ac62f76afb59c38e069ffc7cf3c131ec",
"sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2" "sha256:bcc2e5fc70c0ec50e59703ee6e639d87c7e664c0c441c014ea84461a90f1e902"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.7'",
"version": "==1.0.3" "version": "==1.1"
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
@ -148,19 +164,19 @@
}, },
"pygments": { "pygments": {
"hashes": [ "hashes": [
"sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb", "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1",
"sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519" "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==2.12.0" "version": "==2.13.0"
}, },
"pymdown-extensions": { "pymdown-extensions": {
"hashes": [ "hashes": [
"sha256:3ef2d998c0d5fa7eb09291926d90d69391283561cf6306f85cd588a5eb5befa0", "sha256:1bd4a173095ef8c433b831af1f3cb13c10883be0c100ae613560668e594651f7",
"sha256:ec141c0f4983755349f0c8710416348d1a13753976c028186ed14f190c8061c4" "sha256:8e62688a8b1128acd42fa823f3d429d22f4284b5e6dd4d3cd56721559a5a211b"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==9.5" "version": "==9.8"
}, },
"pyparsing": { "pyparsing": {
"hashes": [ "hashes": [
@ -180,6 +196,7 @@
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
"sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf",
"sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
"sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
"sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
@ -191,26 +208,32 @@
"sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
"sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
"sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
"sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782",
"sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
"sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
"sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
"sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
"sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
"sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1",
"sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
"sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
"sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
"sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
"sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
"sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
"sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d",
"sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
"sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
"sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7",
"sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
"sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
"sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
"sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358",
"sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
"sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
"sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
"sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
"sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f",
"sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
"sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
], ],
@ -225,6 +248,14 @@
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==0.1" "version": "==0.1"
}, },
"requests": {
"hashes": [
"sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983",
"sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"
],
"markers": "python_version >= '3.7' and python_version < '4'",
"version": "==2.28.1"
},
"six": { "six": {
"hashes": [ "hashes": [
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
@ -233,6 +264,14 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.16.0" "version": "==1.16.0"
}, },
"urllib3": {
"hashes": [
"sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e",
"sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'",
"version": "==1.26.12"
},
"watchdog": { "watchdog": {
"hashes": [ "hashes": [
"sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412", "sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412",
@ -263,14 +302,6 @@
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==2.1.9" "version": "==2.1.9"
},
"zipp": {
"hashes": [
"sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad",
"sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"
],
"markers": "python_version >= '3.7'",
"version": "==3.8.0"
} }
}, },
"develop": {} "develop": {}

View file

@ -195,7 +195,7 @@ Additional parameters can be added to the JSON body/Form data:
- `preview`: boolean, if set to `true` the post won't be actually posted, but the status entity would still be rendered back. This could be useful for previewing rich text/custom emoji, for example. - `preview`: boolean, if set to `true` the post won't be actually posted, but the status entity would still be rendered back. This could be useful for previewing rich text/custom emoji, for example.
- `content_type`: string, contain the MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint. - `content_type`: string, contain the MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint.
- `to`: A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for post visibility are not affected by this and will still apply. - `to`: A list of nicknames (like `admin@otp.akkoma.dev` or `admin` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for post visibility are not affected by this and will still apply.
- `visibility`: string, besides standard MastoAPI values (`direct`, `private`, `unlisted`, `local` or `public`) it can be used to address a List by setting it to `list:LIST_ID`. - `visibility`: string, besides standard MastoAPI values (`direct`, `private`, `unlisted`, `local` or `public`) it can be used to address a List by setting it to `list:LIST_ID`.
- `expires_in`: The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour. - `expires_in`: The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour.
- `in_reply_to_conversation_id`: Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`. - `in_reply_to_conversation_id`: Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`.

View file

@ -40,5 +40,5 @@ The following is a config example to use with [Grafana](https://grafana.com)
metrics_path: /api/pleroma/app_metrics metrics_path: /api/pleroma/app_metrics
scheme: https scheme: https
static_configs: static_configs:
- targets: ['pleroma.soykaf.com'] - targets: ['otp.akkoma.dev']
``` ```

View file

@ -29,14 +29,14 @@ If you don't feel like joining an existing instance, but instead prefer to deplo
Installation instructions can be found in the installation section of these docs. Installation instructions can be found in the installation section of these docs.
## I got an account, now what? ## I got an account, now what?
Great! Now you can explore the fediverse! Open the login page for your Akkoma instance (e.g. <https://pleroma.soykaf.com>) and login with your username and password. (If you don't have an account yet, click on Register) Great! Now you can explore the fediverse! Open the login page for your Akkoma instance (e.g. <https://otp.akkoma.dev>) and login with your username and password. (If you don't have an account yet, click on Register)
### Pleroma-FE ### Pleroma-FE
The default front-end used by Akkoma is Pleroma-FE. You can find more information on what it is and how to use it in the [Introduction to Pleroma-FE](https://docs-fe.akkoma.dev/stable/). The default front-end used by Akkoma is Pleroma-FE. You can find more information on what it is and how to use it in the [Introduction to Pleroma-FE](https://docs-fe.akkoma.dev/stable/).
### Mastodon interface ### Mastodon interface
If the Pleroma-FE interface isn't your thing, or you're just trying something new but you want to keep using the familiar Mastodon interface, we got that too! If the Pleroma-FE interface isn't your thing, or you're just trying something new but you want to keep using the familiar Mastodon interface, we got that too!
Just add a "/web" after your instance url (e.g. <https://pleroma.soykaf.com/web>) and you'll end on the Mastodon web interface, but with a Akkoma backend! MAGIC! Just add a "/web" after your instance url (e.g. <https://otp.akkoma.dev/web>) and you'll end on the Mastodon web interface, but with a Akkoma backend! MAGIC!
The Mastodon interface is from the Glitch-soc fork. For more information on the Mastodon interface you can check the [Mastodon](https://docs.joinmastodon.org/) and [Glitch-soc](https://glitch-soc.github.io/docs/) documentation. The Mastodon interface is from the Glitch-soc fork. For more information on the Mastodon interface you can check the [Mastodon](https://docs.joinmastodon.org/) and [Glitch-soc](https://glitch-soc.github.io/docs/) documentation.
Remember, what you see is only the frontend part of Mastodon, the backend is still Akkoma. Remember, what you see is only the frontend part of Mastodon, the backend is still Akkoma.

View file

@ -1,22 +1,26 @@
certifi==2022.9.24
charset-normalizer==2.1.1
click==8.1.3 click==8.1.3
ghp-import==2.1.0 ghp-import==2.1.0
idna==3.4
importlib-metadata==4.12.0 importlib-metadata==4.12.0
Jinja2==3.1.2 Jinja2==3.1.2
Markdown==3.3.7 Markdown==3.3.7
markdown-include==0.6.0 markdown-include==0.7.0
MarkupSafe==2.1.1 MarkupSafe==2.1.1
mergedeep==1.3.4 mergedeep==1.3.4
mkdocs==1.3.0 mkdocs==1.4.2
mkdocs-bootswatch==1.1 mkdocs-material==8.5.9
mkdocs-material==8.1.8 mkdocs-material-extensions==1.1
mkdocs-material-extensions==1.0.3
packaging==21.3 packaging==21.3
Pygments==2.11.2 Pygments==2.13.0
pymdown-extensions==9.1 pymdown-extensions==9.8
pyparsing==3.0.9 pyparsing==3.0.9
python-dateutil==2.8.2 python-dateutil==2.8.2
PyYAML==6.0 PyYAML==6.0
pyyaml_env_tag==0.1 pyyaml_env_tag==0.1
requests==2.28.1
six==1.16.0 six==1.16.0
urllib3==1.26.12
watchdog==2.1.9 watchdog==2.1.9
zipp==3.8.0 zipp==3.8.0

View file

@ -48,7 +48,9 @@ def publish(%{id: "pleroma:fakeid"} = activity) do
@impl true @impl true
def publish(%{data: %{"object" => object}} = activity) when is_binary(object) do def publish(%{data: %{"object" => object}} = activity) when is_binary(object) do
PublisherWorker.enqueue("publish", %{"activity_id" => activity.id, "object_data" => nil}) PublisherWorker.enqueue("publish", %{"activity_id" => activity.id, "object_data" => nil},
priority: publish_priority(activity)
)
end end
@impl true @impl true
@ -63,7 +65,7 @@ def publish(%{data: %{"object" => object}} = activity) when is_map(object) or is
) )
end end
defp publish_priority(%{type: "Delete"}), do: 3 defp publish_priority(%{data: %{"type" => "Delete"}}), do: 3
defp publish_priority(_), do: 0 defp publish_priority(_), do: 0
# Job Worker Callbacks # Job Worker Callbacks

View file

@ -94,12 +94,12 @@ def render(
followed_by = followed_by =
if following_relationships do if following_relationships do
case FollowingRelationship.find(following_relationships, target, reading_user) do target_to_user_following_relation =
%{state: :follow_accept} -> true FollowingRelationship.find(following_relationships, target, reading_user)
_ -> false
end User.get_follow_state(target, reading_user, target_to_user_following_relation)
else else
User.following?(target, reading_user) User.get_follow_state(target, reading_user)
end end
subscribing = subscribing =
@ -115,7 +115,7 @@ def render(
%{ %{
id: to_string(target.id), id: to_string(target.id),
following: follow_state == :follow_accept, following: follow_state == :follow_accept,
followed_by: followed_by, followed_by: followed_by == :follow_accept,
blocking: blocking:
UserRelationship.exists?( UserRelationship.exists?(
user_relationships, user_relationships,
@ -151,6 +151,7 @@ def render(
subscribing: subscribing, subscribing: subscribing,
notifying: subscribing, notifying: subscribing,
requested: follow_state == :follow_pending, requested: follow_state == :follow_pending,
requested_by: followed_by == :follow_pending,
domain_blocking: User.blocks_domain?(reading_user, target), domain_blocking: User.blocks_domain?(reading_user, target),
showing_reblogs: showing_reblogs:
not UserRelationship.exists?( not UserRelationship.exists?(

View file

@ -104,13 +104,12 @@ defp csp_string do
{[img_src, " https:"], [media_src, " https:"]} {[img_src, " https:"], [media_src, " https:"]}
end end
connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
connect_src = connect_src =
if Config.get(:env) == :dev do if Config.get([:media_proxy, :enabled]) do
[connect_src, " http://localhost:3035/"] sources = build_csp_multimedia_source_list()
["connect-src 'self' blob: ", static_url, ?\s, websocket_url, ?\s, sources]
else else
connect_src ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
end end
script_src = script_src =

View file

@ -35,7 +35,7 @@ def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do
conn = conn =
case fetch_query_params(conn) do case fetch_query_params(conn) do
%{query_params: %{"name" => name}} = conn -> %{query_params: %{"name" => name}} = conn ->
name = String.replace(name, "\"", "\\\"") name = escape_header_value(name)
put_resp_header(conn, "content-disposition", "filename=\"#{name}\"") put_resp_header(conn, "content-disposition", "filename=\"#{name}\"")
@ -98,4 +98,11 @@ defp get_media(conn, unknown, _) do
|> send_resp(:internal_server_error, dgettext("errors", "Internal Error")) |> send_resp(:internal_server_error, dgettext("errors", "Internal Error"))
|> halt() |> halt()
end end
defp escape_header_value(value) do
value
|> String.replace("\"", "\\\"")
|> String.replace("\\r", "")
|> String.replace("\\n", "")
end
end end

View file

@ -14,6 +14,11 @@ def process(backup, admin_user_id \\ nil) do
|> Oban.insert() |> Oban.insert()
end end
@impl Oban.Worker
def timeout(_job) do
Pleroma.Config.get([:workers, :timeout, :backup], :timer.minutes(1))
end
def schedule_deletion(backup) do def schedule_deletion(backup) do
days = Pleroma.Config.get([Backup, :purge_after_days]) days = Pleroma.Config.get([Backup, :purge_after_days])
time = 60 * 60 * 24 * days time = 60 * 60 * 24 * days
@ -30,6 +35,7 @@ def delete(backup) do
|> Oban.insert() |> Oban.insert()
end end
@impl true
def perform(%Job{ def perform(%Job{
args: %{"op" => "process", "backup_id" => backup_id, "admin_user_id" => admin_user_id} args: %{"op" => "process", "backup_id" => backup_id, "admin_user_id" => admin_user_id}
}) do }) do

View file

@ -27,6 +27,11 @@ def enqueue(args) do
end end
end end
@impl Oban.Worker
def timeout(_job) do
Pleroma.Config.get([:workers, :timeout, :activity_expiration], :timer.minutes(1))
end
@impl true @impl true
def perform(%Oban.Job{args: %{"activity_id" => id}}) do def perform(%Oban.Job{args: %{"activity_id" => id}}) do
with %Activity{} = activity <- find_activity(id), with %Activity{} = activity <- find_activity(id),

View file

@ -24,6 +24,11 @@ def enqueue(args) do
|> Oban.insert() |> Oban.insert()
end end
@impl Oban.Worker
def timeout(_job) do
Pleroma.Config.get([:workers, :timeout, :filter_expiration], :timer.minutes(1))
end
@impl true @impl true
def perform(%Job{args: %{"filter_id" => id}}) do def perform(%Job{args: %{"filter_id" => id}}) do
Pleroma.Filter Pleroma.Filter

View file

@ -19,6 +19,11 @@ def enqueue(args) do
|> Oban.insert() |> Oban.insert()
end end
@impl Oban.Worker
def timeout(_job) do
Pleroma.Config.get([:workers, :timeout, :token_expiration], :timer.minutes(1))
end
@impl true @impl true
def perform(%Oban.Job{args: %{"token_id" => id, "mod" => module}}) do def perform(%Oban.Job{args: %{"token_id" => id, "mod" => module}}) do
module module

View file

@ -43,6 +43,12 @@ def enqueue(op, params, worker_args \\ []) do
|> apply(:new, [params, worker_args]) |> apply(:new, [params, worker_args])
|> Oban.insert() |> Oban.insert()
end end
@impl Oban.Worker
def timeout(_job) do
queue_atom = String.to_atom(unquote(queue))
Config.get([:workers, :timeout, queue_atom], :timer.minutes(1))
end
end end
end 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("3.3.1"), version: version("3.4.0"),
elixir: "~> 1.12", elixir: "~> 1.12",
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(), compilers: [:phoenix, :gettext] ++ Mix.compilers(),

View file

@ -3,16 +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: 2020-09-09 09:49+0000\n" "POT-Creation-Date: 2020-09-09 09:49+0000\n"
"PO-Revision-Date: 2020-09-11 21:26+0000\n" "PO-Revision-Date: 2022-08-19 09:25+0000\n"
"Last-Translator: tarteka <info@tarteka.net>\n" "Last-Translator: mint <they@mint.lgbt>\n"
"Language-Team: Spanish <https://translate.pleroma.social/projects/pleroma/" "Language-Team: Spanish <http://translate.akkoma.dev/projects/akkoma/"
"pleroma/es/>\n" "akkoma-backend-errors/es/>\n"
"Language: es\n" "Language: es\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"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.0.4\n" "X-Generator: Weblate 4.13.1\n"
## This file is a PO Template file. ## This file is a PO Template file.
## ##
@ -66,8 +66,8 @@ msgstr[1] "debe tener %{count} caracteres"
msgid "should have %{count} item(s)" msgid "should have %{count} item(s)"
msgid_plural "should have %{count} item(s)" msgid_plural "should have %{count} item(s)"
msgstr[0] "" msgstr[0] "debería tener %{count} item"
msgstr[1] "" msgstr[1] "debería tener %{count} items"
msgid "should be at least %{count} character(s)" msgid "should be at least %{count} character(s)"
msgid_plural "should be at least %{count} character(s)" msgid_plural "should be at least %{count} character(s)"

View file

@ -0,0 +1,163 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-16 10:49+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Translate Toolkit 3.7.1\n"
## This file is a PO Template file.
##
## `msgid`s here are often extracted from source code.
## Add new translations manually only if they're dynamic
## translations that can't be statically extracted.
##
## Run `mix gettext.extract` to bring this file up to
## date. Leave `msgstr`s empty as changing them here as no
## effect: edit them in PO (`.po`) files instead.
msgid "eperm"
msgstr ""
msgid "eacces"
msgstr ""
msgid "eagain"
msgstr ""
msgid "ebadf"
msgstr ""
msgid "ebadmsg"
msgstr ""
msgid "ebusy"
msgstr ""
msgid "edeadlk"
msgstr ""
msgid "edeadlock"
msgstr ""
msgid "edquot"
msgstr ""
msgid "eexist"
msgstr ""
msgid "efault"
msgstr ""
msgid "efbig"
msgstr ""
msgid "eftype"
msgstr ""
msgid "eintr"
msgstr ""
msgid "einval"
msgstr ""
msgid "eio"
msgstr ""
msgid "eisdir"
msgstr ""
msgid "eloop"
msgstr ""
msgid "emfile"
msgstr ""
msgid "emlink"
msgstr ""
msgid "emultihop"
msgstr ""
msgid "enametoolong"
msgstr ""
msgid "enfile"
msgstr ""
msgid "enobufs"
msgstr ""
msgid "enodev"
msgstr ""
msgid "enolck"
msgstr ""
msgid "enolink"
msgstr ""
msgid "enoent"
msgstr ""
msgid "enomem"
msgstr ""
msgid "enospc"
msgstr ""
msgid "enosr"
msgstr ""
msgid "enostr"
msgstr ""
msgid "enosys"
msgstr ""
msgid "enotblk"
msgstr ""
msgid "enotdir"
msgstr ""
msgid "enotsup"
msgstr ""
msgid "enxio"
msgstr ""
msgid "eopnotsupp"
msgstr ""
msgid "eoverflow"
msgstr ""
msgid "epipe"
msgstr ""
msgid "erange"
msgstr ""
msgid "erofs"
msgstr ""
msgid "espipe"
msgstr ""
msgid "esrch"
msgstr ""
msgid "estale"
msgstr ""
msgid "etxtbsy"
msgstr ""
msgid "exdev"
msgstr ""

View file

@ -347,6 +347,7 @@ defp test_relationship_rendering(user, other_user, expected_result) do
subscribing: false, subscribing: false,
notifying: false, notifying: false,
requested: false, requested: false,
requested_by: false,
domain_blocking: false, domain_blocking: false,
showing_reblogs: true, showing_reblogs: true,
endorsed: false, endorsed: false,
@ -432,6 +433,24 @@ test "represent a relationship for the user with a pending follow request" do
end end
end end
test "represent a relationship for a user with an inbound pending follow request" do
follower = insert(:user)
followed = insert(:user, is_locked: true)
{:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
follower = User.get_cached_by_id(follower.id)
followed = User.get_cached_by_id(followed.id)
expected =
Map.merge(
@blank_response,
%{requested_by: true, followed_by: false, id: to_string(follower.id)}
)
test_relationship_rendering(followed, follower, expected)
end
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
user = insert(:user, pleroma_settings_store: %{fe: "test"}) user = insert(:user, pleroma_settings_store: %{fe: "test"})

View file

@ -100,12 +100,14 @@ test "media_proxy with base_url", %{conn: conn} do
url = "https://example.com" url = "https://example.com"
clear_config([:media_proxy, :base_url], url) clear_config([:media_proxy, :base_url], url)
assert_media_img_src(conn, url) assert_media_img_src(conn, url)
assert_connect_src(conn, url)
end end
test "upload with base url", %{conn: conn} do test "upload with base url", %{conn: conn} do
url = "https://example2.com" url = "https://example2.com"
clear_config([Pleroma.Upload, :base_url], url) clear_config([Pleroma.Upload, :base_url], url)
assert_media_img_src(conn, url) assert_media_img_src(conn, url)
assert_connect_src(conn, url)
end end
test "with S3 public endpoint", %{conn: conn} do test "with S3 public endpoint", %{conn: conn} do
@ -138,6 +140,12 @@ defp assert_media_img_src(conn, url) do
assert csp =~ "img-src 'self' data: blob: #{url};" assert csp =~ "img-src 'self' data: blob: #{url};"
end end
defp assert_connect_src(conn, url) do
conn = get(conn, "/api/v1/instance")
[csp] = Conn.get_resp_header(conn, "content-security-policy")
assert csp =~ ~r/connect-src 'self' blob: [^;]+ #{url}/
end
test "it does not send CSP headers when disabled", %{conn: conn} do test "it does not send CSP headers when disabled", %{conn: conn} do
clear_config([:http_security, :enabled], false) clear_config([:http_security, :enabled], false)

View file

@ -40,4 +40,15 @@ test "sends Content-Disposition header when name param is set", %{
&(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""}) &(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
) )
end end
test "removes control characters from the Content-Disposition header", %{
attachment_url: attachment_url
} do
conn = get(build_conn(), attachment_url <> "?name=\"cofe\".gif\\r\\n")
assert Enum.any?(
conn.resp_headers,
&(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
)
end
end end

View file

@ -0,0 +1,52 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.PublisherWorkerTest do
use Pleroma.DataCase, async: true
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Federator
describe "Oban job priority:" do
setup do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "Regrettable post"})
object = Object.normalize(post, fetch: false)
{:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
{:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
%{
post: post,
delete: delete
}
end
test "Deletions are lower priority", %{delete: delete} do
assert {:ok, %Oban.Job{priority: 3}} = Federator.publish(delete)
end
test "Creates are normal priority", %{post: post} do
assert {:ok, %Oban.Job{priority: 0}} = Federator.publish(post)
end
end
describe "Oban job timeout" do
test "should have a timeout" do
clear_config([:workers, :timeout, :federator_outgoing], :timer.minutes(2))
assert Pleroma.Workers.PublisherWorker.timeout(nil) == :timer.minutes(2)
end
test "should use a default timeout if none specified" do
clear_config([:workers, :timeout, :federator_outgoing])
assert Pleroma.Workers.PublisherWorker.timeout(nil) == :timer.seconds(10)
end
end
end

View file

@ -56,4 +56,9 @@ test "error if actiivity was not found" do
assert {:error, :activity_not_found} = assert {:error, :activity_not_found} =
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: "some_if"}) perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: "some_if"})
end end
test "has a timeout" do
clear_config([:workers, :timeout, :activity_expiration], 50)
assert Pleroma.Workers.PurgeExpiredActivity.timeout(%Oban.Job{}) == 50
end
end end

View file

@ -49,4 +49,9 @@ test "error message for non-existent scheduled activity" do
ScheduledActivityWorker.perform(%Oban.Job{args: %{"activity_id" => 42}}) ScheduledActivityWorker.perform(%Oban.Job{args: %{"activity_id" => 42}})
end) =~ "Couldn't find scheduled activity: 42" end) =~ "Couldn't find scheduled activity: 42"
end end
test "has a timeout" do
clear_config([:workers, :timeout, :scheduled_activities], :timer.minutes(5))
assert ScheduledActivityWorker.timeout(nil) == :timer.minutes(5)
end
end end