Compare commits

...

42 commits

Author SHA1 Message Date
FloatingGhost 33e7ae7637 Allow nil attachments 2023-07-17 20:03:31 +01:00
floatingghost fa40db6b5a Merge pull request 'fix ImageMagick typo in media_graphics_packages.md' (#593) from norm/akkoma:media-graphics-typo into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/593
2023-07-17 18:49:44 +00:00
floatingghost ccd8cd6c59 Merge pull request 'Exclude deactivated users from emoji reaction lists' (#592) from active-emoji-reactions into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/592
2023-07-17 18:49:15 +00:00
FloatingGhost 900b9b0124 Merge branch 'develop' into active-emoji-reactions 2023-07-17 19:45:43 +01:00
Norm 43aef8b5b1
fix ImageMagick typo in media_graphics_packages.md 2023-07-17 14:44:39 -04:00
FloatingGhost f1611b6292 Update changelog 2023-07-17 19:19:03 +01:00
FloatingGhost c63ae73bc0 Add embed controller tests 2023-07-17 19:18:21 +01:00
FloatingGhost 16d2bfef80 Ensure embeds will not be served if unauthenticated users could not see it 2023-07-17 18:24:53 +01:00
FloatingGhost c8904f15a2 Correct behaviour of mediaproxy blocklist 2023-07-17 18:17:04 +01:00
FloatingGhost 8fe29bf5d2 Exclude deactivated users from emoji reaction lists 2023-07-17 17:53:03 +01:00
floatingghost 452f9e14fb Merge pull request 'docs: Update Pleroma references to Akkoma in optional packages guide' (#550) from norm/akkoma:docs/media_graphics_packages into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/550
2023-07-17 16:47:32 +00:00
floatingghost 5fa1cfc513 Merge pull request 'docs: Add Kaiteki to list of clients' (#548) from norm/akkoma:add-kaiteki into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/548
2023-07-17 16:32:38 +00:00
floatingghost 2aac70d690 Merge pull request 'Add config for media subdomain for Caddy' (#555) from norm/akkoma:media-subdomain-caddyfile into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/555
2023-07-17 16:30:42 +00:00
floatingghost 3fa65a5c53 Merge pull request 'docs: Update Pleroma-FE references to Akkoma-FE' (#551) from norm/akkoma:docs/akkoma-fe into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/551
2023-07-17 16:28:41 +00:00
floatingghost 210df6fe92 Merge pull request 'Fix the /embed endpoint' (#540) from mikihau/akkoma:develop into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/540
2023-07-15 20:48:30 +00:00
Norm 8c956bc671 Add OnlyMedia upload filter change to changelog 2023-06-28 01:56:34 +01:00
Mark Felder 5144d6f4ba Add OnlyMedia Upload Filter to simplify restricting uploads to audio, image, and video types
Original: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3897
2023-06-28 01:56:14 +01:00
floatingghost 3e4a279a1b Merge pull request 'Implement blocklists for MediaProxy' (#574) from XxXCertifiedForkliftDriverXxX/akkoma:feature/mediaproxy-blocklist into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/574
2023-06-28 00:54:25 +00:00
floatingghost fc87baf1cf Merge pull request 'Use OS CA store for Mint HTTP connections' (#573) from XxXCertifiedForkliftDriverXxX/akkoma:fix/use-os-certs into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/573
2023-06-28 00:52:26 +00:00
XxXCertifiedForkliftDriverXxX 767e1272b3 Use OS CA store for Mint HTTP connections 2023-06-26 15:50:49 +02:00
XxXCertifiedForkliftDriverXxX 07b478dc49 Implement blocklists for MediaProxy 2023-06-26 15:18:31 +02:00
floatingghost 67cae52b08 Merge pull request 'Add asdf install guide for debian/ubuntu' (#559) from norm/akkoma:asdf into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/559
2023-06-26 12:58:01 +00:00
floatingghost 4db42f5ab5 Merge pull request 'Adapt some migrations so they can be rolled back' (#565) from ilja/akkoma:fix_some_migrations_for_rollback into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/565
2023-06-26 12:52:22 +00:00
floatingghost 145191ef26 Merge pull request 'Update docker compose commands to Compose V2' (#570) from norm/akkoma:docker-compose into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/570
2023-06-26 12:37:38 +00:00
Norm 6674b33d75
update docs with new docker compose commands 2023-06-18 01:44:25 -04:00
Norm 2dfce40117
Update docker compose commands to Compose V2
This just replaces all instances of `docker-compose` with `docker
compose` in the docker scripts.

The old Compose V1 program is unsupported since 2021:
https://docs.docker.com/compose/migrate/#will-i-still-be-able-to-use-compose-v1-if-i-really-want-to
2023-06-18 01:37:40 -04:00
Francis Dinh 5e3ca133f2
reword to not mention specific elixir version 2023-06-11 08:46:56 -04:00
ilja 3a13f91fff Adapt some migrations so they can be rolled back
This is useful for people who want to migrate back to Pleroma.
It's also added in the docs, but also noted that this is barely tested and to be used at their own risk.
2023-06-09 22:02:26 +02:00
Miki Hau 593ddbd796 fix the /embed endpoint 2023-05-31 23:42:08 +00:00
lain 1ae89bddcd Merge branch 'feature/embeddable-posts' into 'develop'
Add embeddable posts

Closes #1288

See merge request pleroma/pleroma!2319
2023-05-31 23:40:16 +00:00
Francis Dinh 5fe41df8aa
docs: Add Kaiteki to list of clients 2023-05-31 18:19:06 -04:00
Francis Dinh 5ce38591e5
fix typo 2023-05-31 09:03:25 -04:00
Francis Dinh 2482d96782
remove one more java dep 2023-05-31 08:59:03 -04:00
Francis Dinh f68b047bf7
remove java and gui dependencies 2023-05-31 08:46:05 -04:00
Francis Dinh 48a0145736
add command to restart shell 2023-05-30 21:21:44 -04:00
Francis Dinh d956dc2f09
Add asdf install guide for debian/ubuntu
Closes #557
2023-05-30 21:17:26 -04:00
Francis Dinh 40627a94d4
Add config for media subdomain for Caddy
A recent group of vulnerabilities have been found in Pleroma (and
inherited by Akkoma) that involve media files either uploaded by local
users or proxied from remote instances (if media proxy is enabled).

It is recommended that media files are served on a separate subdomain
in order to mitigate this class of vulnerabilities.

Based on https://meta.akkoma.dev/t/another-vector-for-the-injection-vulnerability-found/483/2
2023-05-29 14:04:00 -04:00
floatingghost fb8081e1a3 Merge pull request 'Stop exposing if a user blocks you over the API.' (#553) from XxXCertifiedForkliftDriverXxX/akkoma:feature/hide-blocked_by into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/553
2023-05-28 22:02:33 +00:00
XxXCertifiedForkliftDriverXxX 1b560d547a Stop exposing if a user blocks you over the API. 2023-05-28 23:42:27 +02:00
Francis Dinh 0e5f55deea
more references being updated 2023-05-26 22:54:12 -04:00
Francis Dinh f0f0c76805
docs: Update Pleroma-FE references to Akkoma-FE
The frontend got renamed a while back, so the docs should be updated to
reflect that.
2023-05-26 22:36:27 -04:00
Francis Dinh b3fc098b83
docs: Update Pleroma references to Akkoma in optional packages guide
This apparently slipped past though all of the doc updates from a while
back.
2023-05-26 22:26:14 -04:00
45 changed files with 595 additions and 94 deletions

View file

@ -4,6 +4,19 @@ 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/).
## Unreleased
## Added
- Added a new configuration option to the MediaProxy feature that allows the blocking of specific domains from using the media proxy or being explicitly allowed by the Content-Security-Policy.
- Please make sure instances you wanted to block media from are not in the MediaProxy `whitelist`, and instead use `blocklist`.
- `OnlyMedia` Upload Filter to simplify restricting uploads to audio, image, and video types
## Fixed
- Deactivated users can no longer show up in the emoji reaction list
- Embedded posts can no longer bypass `:restrict\_unauthenticated`
## 2023.05
## Added

View file

@ -443,7 +443,8 @@
# Note: max_read_duration defaults to Pleroma.ReverseProxy.max_read_duration_default/1
max_read_duration: 30_000
],
whitelist: []
whitelist: [],
blocklist: []
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
method: :purge,

View file

@ -1558,7 +1558,21 @@
%{
key: :whitelist,
type: {:list, :string},
description: "List of hosts with scheme to bypass the MediaProxy",
description: """
List of hosts with scheme to bypass the MediaProxy.\n
The media will be fetched by the client, directly from the remote server.\n
To allow this, it will Content-Security-Policy exceptions for each instance listed.\n
This is to be used for instances you trust and do not want to cache media for.
""",
suggestions: ["http://example.com"]
},
%{
key: :blocklist,
type: {:list, :string},
description: """
List of hosts with scheme which will not go through the MediaProxy, and will not be explicitly allowed by the Content-Security-Policy.
This is to be used for instances where you do not want their media to go through your server or to be accessed by clients.
""",
suggestions: ["http://example.com"]
}
]

View file

@ -1,4 +1,4 @@
#!/bin/sh
docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) akkoma
docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) db
docker compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) akkoma
docker compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) db

View file

@ -1,3 +1,3 @@
#!/bin/sh
docker-compose run --rm akkoma $@
docker compose run --rm akkoma $@

View file

@ -42,7 +42,7 @@ For a frontend configured under the `available` key, it's enough to install it b
This will download the latest build for the pre-configured `ref` and install it. It can then be configured as the one of the served frontends in the config file (see `primary` or `admin`).
You can override any of the details. To install a Pleroma-FE build from a different URL, you could do this:
You can override any of the details. To install an Akkoma-FE build from a different URL, you could do this:
=== "OTP"

View file

@ -62,6 +62,6 @@ mix ecto.migrate
# Start akkoma (replace with your system service manager's equivalent if different)
sudo systemctl start akkoma
# Update Pleroma-FE frontend to latest stable. For other Frontends see Frontend Configuration doc for more information.
# Update Akkoma-FE frontend to latest stable. For other Frontends see Frontend Configuration doc for more information.
mix pleroma.frontend install pleroma-fe --ref stable
```

View file

@ -2,6 +2,14 @@
Note: Additional clients may work, but these are known to work with Akkoma.
Apps listed here might not support all of Akkoma's features.
## Multiplatform
### Kaiteki
- Homepage: <https://kaiteki.app/>
- Source Code: <https://github.com/Kaiteki-Fedi/Kaiteki>
- Contact: [@kaiteki@fedi.software](https://fedi.software/@Kaiteki)
- Platforms: Web, Windows, Linux, Android
- Features: MastoAPI, Supports multiple backends
## Desktop
### Whalebird
- Homepage: <https://whalebird.social/>

View file

@ -246,11 +246,11 @@ Notes:
### :frontend_configurations
This can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for `pleroma_fe` and `masto_fe` are configured. You can find the documentation for `pleroma_fe` configuration into [Pleroma-FE configuration and customization for instance administrators](https://docs-fe.akkoma.dev/stable/CONFIGURATION/#options).
This can be used to configure a keyword list that keeps the configuration data for any kind of frontend. By default, settings for `pleroma_fe` and `masto_fe` are configured. You can find the documentation for `pleroma_fe` configuration into [Akkoma-FE configuration and customization for instance administrators](https://docs-fe.akkoma.dev/stable/CONFIGURATION/#options).
Frontends can access these settings at `/api/v1/pleroma/frontend_configurations`
To add your own configuration for Pleroma-FE, use it like this:
To add your own configuration for Akkoma-FE, use it like this:
```elixir
config :pleroma, :frontend_configurations,
@ -615,6 +615,12 @@ This filter only strips the GPS and location metadata with Exiftool leaving colo
No specific configuration.
#### Pleroma.Upload.Filter.OnlyMedia
This filter rejects uploads that are not identified with Content-Type matching audio/\*, image/\*, or video/\*
No specific configuration.
#### Pleroma.Upload.Filter.Mogrify
* `args`: List of actions for the `mogrify` command like `"strip"` or `["strip", "auto-orient", {"implode", "1"}]`.

View file

@ -6,7 +6,7 @@ To add a custom theme to your instance, you'll first need to get a custom theme,
### Create your own theme
* You can create your own theme using the Pleroma FE by going to settings (gear on the top right) and choose the Theme tab. Here you have the options to create a personal theme.
* You can create your own theme using the Akkoma FE by going to settings (gear on the top right) and choose the Theme tab. Here you have the options to create a personal theme.
* To download your theme, you can do Save preset
* If you want to upload a theme to customise it further, you can upload it using Load preset

View file

@ -3,7 +3,7 @@
# Introduction to Akkoma
## What is Akkoma?
Akkoma is a federated social networking platform, compatible with Mastodon and other ActivityPub implementations. It is free software licensed under the AGPLv3.
It actually consists of two components: a backend, named simply Akkoma, and a user-facing frontend, named Pleroma-FE. It also includes the Mastodon frontend, if that's your thing.
It actually consists of two components: a backend, named simply Akkoma, and a user-facing frontend, named Akkoma-FE. It also includes the Mastodon frontend, if that's your thing.
It's part of what we call the fediverse, a federated network of instances which speak common protocols and can communicate with each other.
One account on an instance is enough to talk to the entire fediverse!
@ -31,11 +31,11 @@ Installation instructions can be found in the installation section of these docs
## I got an account, now what?
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
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/).
### Akkoma-FE
The default front-end used by Akkoma is Akkoma-FE. You can find more information on what it is and how to use it in the [Introduction to Akkoma-FE](https://docs-fe.akkoma.dev/stable/).
### 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 Akkoma-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://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.

View file

@ -23,23 +23,7 @@ sudo apt full-upgrade
sudo apt install git build-essential postgresql postgresql-contrib cmake libmagic-dev
```
### Install Elixir and Erlang
* Install Elixir and Erlang (you might need to use backports or [asdf](https://github.com/asdf-vm/asdf) on old systems):
```shell
sudo apt update
sudo apt install elixir erlang-dev erlang-nox
```
### Optional packages: [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md)
```shell
sudo apt install imagemagick ffmpeg libimage-exiftool-perl
```
### Install AkkomaBE
### Create the akkoma user
* Add a new system user for the Akkoma service:
@ -49,7 +33,67 @@ sudo useradd -r -s /bin/false -m -d /var/lib/akkoma -U akkoma
**Note**: To execute a single command as the Akkoma system user, use `sudo -Hu akkoma command`. You can also switch to a shell by using `sudo -Hu akkoma $SHELL`. If you dont have and want `sudo` on your system, you can use `su` as root user (UID 0) for a single command by using `su -l akkoma -s $SHELL -c 'command'` and `su -l akkoma -s $SHELL` for starting a shell.
* Git clone the AkkomaBE repository from stable-branch and make the Akkoma user the owner of the directory:
### Install Elixir and Erlang
If your distribution packages a recent enough version of Elixir, you can install it directly from the distro repositories and skip to the next section of the guide:
```shell
sudo apt install elixir erlang-dev erlang-nox
```
Otherwise use [asdf](https://github.com/asdf-vm/asdf) to install the latest versions of Elixir and Erlang.
First, install some dependencies needed to build Elixir and Erlang:
```shell
sudo apt install curl unzip build-essential autoconf m4 libncurses5-dev libssh-dev unixodbc-dev xsltproc libxml2-utils libncurses-dev
```
Then login to the `akkoma` user and install asdf:
```shell
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.3
```
Add the following lines to `~/.bashrc`:
```shell
. "$HOME/.asdf/asdf.sh"
# asdf completions
. "$HOME/.asdf/completions/asdf.bash"
```
Restart the shell:
```shell
exec $SHELL
```
Next install Erlang:
```shell
asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
export KERL_CONFIGURE_OPTIONS="--disable-debug --without-javac"
asdf install erlang 25.3.2.1
asdf global erlang 25.3.2.1
```
Now install Elixir:
```shell
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
asdf install elixir 1.14.5-otp-25
asdf global elixir 1.14.5-otp-25
```
Confirm that Elixir is installed correctly by checking the version:
```shell
elixir --version
```
### Optional packages: [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md)
```shell
sudo apt install imagemagick ffmpeg libimage-exiftool-perl
```
### Install AkkomaBE
* Log into the `akkoma` user and clone the AkkomaBE repository from the stable branch and make the Akkoma user the owner of the directory:
```shell
sudo mkdir -p /opt/akkoma

View file

@ -10,7 +10,7 @@ If you want to migrate from or OTP to docker, check out [the migration guide](./
### Prepare the system
* Install docker and docker-compose
* Install docker and docker compose
* [Docker](https://docs.docker.com/engine/install/)
* [Docker-compose](https://docs.docker.com/compose/install/)
* This will usually just be a repository installation and a package manager invocation.
@ -26,7 +26,7 @@ echo "DOCKER_USER=$(id -u):$(id -g)" >> .env
```
This probably won't need to be changed, it's only there to set basic environment
variables for the docker-compose file.
variables for the docker compose file.
### Building the container
@ -65,9 +65,9 @@ cp config/generated_config.exs config/prod.secret.exs
We need to run a few commands on the database container, this isn't too bad
```bash
docker-compose run --rm --user akkoma -d db
docker compose run --rm --user akkoma -d db
# Note down the name it gives here, it will be something like akkoma_db_run
docker-compose run --rm akkoma psql -h db -U akkoma -f config/setup_db.psql
docker compose run --rm akkoma psql -h db -U akkoma -f config/setup_db.psql
docker stop akkoma_db_run # Replace with the name you noted down
```
@ -84,17 +84,17 @@ We're going to run it in the foreground on the first run, just to make sure
everything start up.
```bash
docker-compose up
docker compose up
```
If everything went well, you should be able to access your instance at http://localhost:4000
You can `ctrl-c` out of the docker-compose now to shutdown the server.
You can `ctrl-c` out of the docker compose now to shutdown the server.
### Running in the background
```bash
docker-compose up -d
docker compose up -d
```
### Create your first user
@ -125,8 +125,8 @@ cp docker-resources/Caddyfile.example docker-resources/Caddyfile
Then edit the TLD in your caddyfile to the domain you're serving on.
Uncomment the `caddy` section in the docker-compose file,
then run `docker-compose up -d` again.
Uncomment the `caddy` section in the docker compose file,
then run `docker compose up -d` again.
#### Running a reverse proxy on the host
@ -152,7 +152,7 @@ git pull
./docker-resources/manage.sh mix deps.get
./docker-resources/manage.sh mix compile
./docker-resources/manage.sh mix ecto.migrate
docker-compose restart akkoma db
docker compose restart akkoma db
```
#### Further reading

View file

@ -118,3 +118,15 @@ To fix this, run:
```
which will remove the config from the database. Things should work now.
## Migrating back to Pleroma
Akkoma is a hard fork of Pleroma. As such, migrating back is not guaranteed to always work. But if you want to migrate back to Pleroma, you can always try. Just note that you may run into unexpected issues and you're basically on your own. The following are some tips that may help, but note that these are barely tested, so proceed at your own risk.
First you will need to roll back the database migrations. The latest migration both Akkoma and Pleroma still have in common should be 20210416051708, so roll back to that. If you run from source, that should be
```sh
MIX_ENV=prod mix ecto.rollback --to 20210416051708
```
Then switch back to Pleroma for updates (similar to how was done to migrate to Akkoma), and remove the front-ends. The front-ends are installed in the `frontends` folder in the [static directory](../configuration/static_dir.md). Once you are back to Pleroma, you will need to run the database migrations again. See the Pleroma documentation for this.

View file

@ -10,7 +10,7 @@ You probably should, in the first instance.
### Prepare the system
* Install docker and docker-compose
* Install docker and docker compose
* [Docker](https://docs.docker.com/engine/install/)
* [Docker-compose](https://docs.docker.com/compose/install/)
* This will usually just be a repository installation and a package manager invocation.
@ -46,7 +46,7 @@ For *most* from-source installs it'll already be there.
And the same with `uploads`, make sure your uploads (if you have them on disk) are
located at `uploads/` in the akkoma source directory.
If you have them on a different disk, you will need to mount that disk into the docker-compose file,
If you have them on a different disk, you will need to mount that disk into the docker compose file,
with an entry that looks like this:
```yaml
@ -66,7 +66,7 @@ echo "DOCKER_USER=$(id -u):$(id -g)" >> .env
```
This probably won't need to be changed, it's only there to set basic environment
variables for the docker-compose file.
variables for the docker compose file.
=== "From source"
@ -126,21 +126,21 @@ mkdir pgdata
Now we can import our database to the container.
```bash
docker-compose run --rm --user akkoma -d db
docker-compose run --rm akkoma pg_restore -v -U akkoma -j $(grep -c ^processor /proc/cpuinfo) -d akkoma -h db akkoma_backup.sql
docker compose run --rm --user akkoma -d db
docker compose run --rm akkoma pg_restore -v -U akkoma -j $(grep -c ^processor /proc/cpuinfo) -d akkoma -h db akkoma_backup.sql
```
### Reverse proxies
If you're just reusing your old proxy, you may have to uncomment the line in
the docker-compose file under `ports`. You'll find it.
the docker compose file under `ports`. You'll find it.
Otherwise, you can use the same setup as the [docker installation guide](./docker_en.md#reverse-proxies).
### Let's go
```bash
docker-compose up -d
docker compose up -d
```
You should now be at the same point as you were before, but with a docker install.

View file

@ -1,19 +1,19 @@
# Optional software packages needed for specific functionality
For specific Pleroma functionality (which is disabled by default) some or all of the below packages are required:
* `ImageMagic`
For specific Akkoma functionality (which is disabled by default) some or all of the below packages are required:
* `ImageMagick`
* `ffmpeg`
* `exiftool`
Please refer to documentation in `docs/installation` on how to install them on specific OS.
Note: the packages are not required with the current default settings of Pleroma.
Note: the packages are not required with the current default settings of Akkoma.
## `ImageMagick`
`ImageMagick` is a set of tools to create, edit, compose, or convert bitmap images.
It is required for the following Pleroma features:
It is required for the following Akkoma features:
* `Pleroma.Upload.Filters.Mogrify`, `Pleroma.Upload.Filters.Mogrifun` upload filters (related config: `Plaroma.Upload/filters` in `config/config.exs`)
* Media preview proxy for still images (related config: `media_preview_proxy/enabled` in `config/config.exs`)
@ -21,12 +21,12 @@ It is required for the following Pleroma features:
`ffmpeg` is software to record, convert and stream audio and video.
It is required for the following Pleroma features:
It is required for the following Akkoma features:
* Media preview proxy for videos (related config: `media_preview_proxy/enabled` in `config/config.exs`)
## `exiftool`
`exiftool` is media files metadata reader/writer.
It is required for the following Pleroma features:
It is required for the following Akkoma features:
* `Pleroma.Upload.Filters.Exiftool` upload filter (related config: `Plaroma.Upload/filters` in `config/config.exs`)

View file

@ -38,11 +38,11 @@
{% endif %}
{% if page and page.url.startswith('backend') %}
{% set repo_url = "https://git.pleroma.social/pleroma/pleroma" %}
{% set repo_name = "pleroma/pleroma" %}
{% set repo_url = "https://akkoma.dev/AkkomaGang/akkoma" %}
{% set repo_name = "AkkomaGang/akkoma" %}
{% elif page and page.url.startswith('frontend') %}
{% set repo_url = "https://git.pleroma.social/pleroma/pleroma-fe" %}
{% set repo_name = "pleroma/pleroma-fe" %}
{% set repo_url = "https://akkoma.dev/AkkomaGang/akkoma-fe" %}
{% set repo_name = "AkkomaGang/akkoma-fe" %}
{% else %}
{% set repo_url = config.repo_url %}
{% set repo_name = config.repo_name %}

View file

@ -8,6 +8,8 @@ Restart=on-failure
; Uncomment this if you're on Arch Linux
; Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl"
; Uncomment if using asdf to manage Elixir and Erlang
; Environment="PATH=/var/lib/akkoma/.asdf/shims:/var/lib/akkoma/.asdf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
; Name of the user that runs the Akkoma service.
User=akkoma
@ -24,6 +26,8 @@ Environment="HOME=/var/lib/akkoma"
WorkingDirectory=/opt/akkoma
; Path to the Mix binary.
ExecStart=/usr/bin/mix phx.server
; If using asdf comment the above line and uncomment the one below instead
; ExecStart=/var/lib/akkoma/.asdf/shims/mix phx.server
; Some security directives.
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.

View file

@ -4,6 +4,9 @@
# 1. Replace 'example.tld' with your instance's domain wherever it appears.
# 2. Copy this section into your Caddyfile and restart Caddy.
# If you are able to, it's highly recommended to have your media served via a separate subdomain for improved security.
# Uncomment the relevant sectons here and modify the base_url setting for Pleroma.Upload and :media_proxy accordingly.
example.tld {
log {
output file /var/log/caddy/akkoma.log
@ -14,4 +17,21 @@ example.tld {
# this is explicitly IPv4 since Pleroma.Web.Endpoint binds on IPv4 only
# and `localhost.` resolves to [::0] on some systems: see issue #930
reverse_proxy 127.0.0.1:4000
# Uncomment if using a separate media subdomain
#@mediaproxy path /media/* /proxy/*
#handle @mediaproxy {
# redir https://media.example.tld{uri} permanent
#}
}
# Uncomment if using a separate media subdomain
#media.example.tld {
# @mediaproxy path /media/* /proxy/*
# reverse_proxy @mediaproxy 127.0.0.1:4000 {
# transport http {
# response_header_timeout 10s
# read_timeout 15s
# }
# }
#}

View file

@ -262,11 +262,14 @@ defp http_children do
proxy = Pleroma.HTTP.AdapterHelper.format_proxy(proxy_url)
pool_size = Config.get([:http, :pool_size])
:public_key.cacerts_load()
config =
[:http, :adapter]
|> Config.get([])
|> Pleroma.HTTP.AdapterHelper.add_pool_size(pool_size)
|> Pleroma.HTTP.AdapterHelper.maybe_add_proxy_pool(proxy)
|> Pleroma.HTTP.AdapterHelper.maybe_add_cacerts(:public_key.cacerts_get())
|> Keyword.put(:name, MyFinch)
[{Finch, config}]

View file

@ -25,7 +25,7 @@ defmodule Pleroma.Constants do
const(static_only_files,
do:
~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)
~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance embed sw.js sw-pleroma.js favicon.png schemas doc)
)
const(status_updatable_fields,

View file

@ -47,6 +47,17 @@ def maybe_add_proxy_pool(opts, proxy) do
|> put_in([:pools, :default, :conn_opts, :proxy], proxy)
end
def maybe_add_cacerts(opts, nil), do: opts
def maybe_add_cacerts(opts, cacerts) do
opts
|> maybe_add_pools()
|> maybe_add_default_pool()
|> maybe_add_conn_opts()
|> maybe_add_transport_opts()
|> put_in([:pools, :default, :conn_opts, :transport_opts, :cacerts], cacerts)
end
def add_pool_size(opts, pool_size) do
opts
|> maybe_add_pools()
@ -82,6 +93,16 @@ defp maybe_add_conn_opts(opts) do
end
end
defp maybe_add_transport_opts(opts) do
transport_opts = get_in(opts, [:pools, :default, :conn_opts, :transport_opts])
unless is_nil(transport_opts) do
opts
else
put_in(opts, [:pools, :default, :conn_opts, :transport_opts], [])
end
end
@doc """
Merge default connection & adapter options with received ones.
"""

View file

@ -38,9 +38,9 @@ def filter([filter | rest], upload) do
{:ok, :noop} ->
filter(rest, upload)
error ->
Logger.error("#{__MODULE__}: Filter #{filter} failed: #{inspect(error)}")
error
{:error, e} ->
Logger.error("#{__MODULE__}: Filter #{filter} failed: #{inspect(e)}")
{:error, e}
end
end
end

View file

@ -0,0 +1,20 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Upload.Filter.OnlyMedia do
@behaviour Pleroma.Upload.Filter
alias Pleroma.Upload
def filter(%Upload{content_type: content_type}) do
[type, _subtype] = String.split(content_type, "/")
if type in ["image", "video", "audio"] do
{:ok, :noop}
else
{:error, "Disallowed content-type: #{content_type}"}
end
end
def filter(_), do: {:ok, :noop}
end

View file

@ -919,9 +919,13 @@ def add_attributed_to(object) do
end
def prepare_attachments(object) do
attachments = case Map.get(object, "attachment", []) do
[_ | _] = list -> list
_ -> []
end
attachments =
object
|> Map.get("attachment", [])
attachments
|> Enum.map(fn data ->
[%{"mediaType" => media_type, "href" => href} = url | _] = data["url"]

View file

@ -767,7 +767,7 @@ defp array_of_relationships do
"showing_reblogs" => true,
"followed_by" => true,
"blocking" => false,
"blocked_by" => true,
"blocked_by" => false,
"muting" => false,
"muting_notifications" => false,
"note" => "",
@ -783,7 +783,7 @@ defp array_of_relationships do
"showing_reblogs" => true,
"followed_by" => true,
"blocking" => false,
"blocked_by" => true,
"blocked_by" => false,
"muting" => true,
"muting_notifications" => false,
"note" => "",

View file

@ -13,7 +13,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.AccountRelationship do
description: "Relationship between current account and requested account",
type: :object,
properties: %{
blocked_by: %Schema{type: :boolean},
blocked_by: %Schema{
type: :boolean,
description: "Represents being blocked by this user. Always false."
},
blocking: %Schema{type: :boolean},
domain_blocking: %Schema{type: :boolean},
endorsed: %Schema{type: :boolean},

View file

@ -11,22 +11,31 @@ defmodule Pleroma.Web.EmbedController do
alias Pleroma.Web.ActivityPub.Visibility
plug(:put_layout, :embed)
def show(conn, %{"id" => id}) do
with %Activity{local: true} = activity <-
Activity.get_by_id_with_object(id),
true <- Visibility.is_public?(activity.object) do
with {:activity, %Activity{} = activity} <-
{:activity, Activity.get_by_id_with_object(id)},
{:local, true} <- {:local, activity.local},
{:visible, true} <- {:visible, Visibility.visible_for_user?(activity, nil)} do
{:ok, author} = User.get_or_fetch(activity.object.data["actor"])
conn
|> delete_resp_header("x-frame-options")
|> delete_resp_header("content-security-policy")
|> put_view(Pleroma.Web.EmbedView)
|> render("show.html",
activity: activity,
author: User.sanitize_html(author),
counts: get_counts(activity)
)
else
{:activity, _} ->
render_error(conn, :not_found, "Post not found")
{:local, false} ->
render_error(conn, :unauthorized, "Federated posts cannot be embedded")
{:visible, false} ->
render_error(conn, :unauthorized, "Not authorized to view this post")
end
end

View file

@ -124,14 +124,7 @@ def render(
target,
&User.blocks_user?(&1, &2)
),
blocked_by:
UserRelationship.exists?(
user_relationships,
:block,
target,
reading_user,
&User.blocks_user?(&1, &2)
),
blocked_by: false,
muting:
UserRelationship.exists?(
user_relationships,

View file

@ -52,7 +52,7 @@ def url(url) do
@spec url_proxiable?(String.t()) :: boolean()
def url_proxiable?(url) do
not local?(url) and not whitelisted?(url)
not local?(url) and not whitelisted?(url) and not blocked?(url)
end
def preview_url(url, preview_params \\ []) do
@ -83,6 +83,16 @@ def whitelisted?(url) do
domain in mediaproxy_whitelist_domains
end
def blocked?(url) do
%{scheme: scheme, host: domain} = URI.parse(url)
# Block either the bare domain or the scheme-domain combo
scheme_domain = "#{scheme}://#{domain}"
blocklist = Config.get([:media_proxy, :blocklist])
Enum.member?(blocklist, domain) ||
Enum.member?(blocklist, scheme_domain)
end
defp maybe_get_domain_from_url("http" <> _ = url) do
URI.parse(url).host
end

View file

@ -41,6 +41,17 @@ def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do
end
end
defp filter_allowed_user_by_ap_id(ap_ids, excluded_ap_ids) do
Enum.reject(ap_ids, fn ap_id ->
with false <- ap_id in excluded_ap_ids,
%{is_active: true} <- User.get_cached_by_ap_id(ap_id) do
false
else
_ -> true
end
end)
end
def filter_allowed_users(reactions, user, with_muted) do
exclude_ap_ids =
if is_nil(user) do
@ -51,7 +62,7 @@ def filter_allowed_users(reactions, user, with_muted) do
end
filter_emoji = fn emoji, users, url ->
case Enum.reject(users, &(&1 in exclude_ap_ids)) do
case filter_allowed_user_by_ap_id(users, exclude_ap_ids) do
[] -> nil
users -> {emoji, users, url}
end

View file

@ -6,10 +6,10 @@
<title><%= Pleroma.Config.get([:instance, :name]) %></title>
<meta content='noindex' name='robots'>
<%= Phoenix.HTML.raw(assigns[:meta] || "") %>
<link rel="stylesheet" href="/embed.css">
<link rel="stylesheet" href="/embed/embed.css">
<base target="_parent">
</head>
<body>
<%= render @view_module, @view_template, assigns %>
<%= render view_module(@conn), view_template(@conn), assigns %>
</body>
</html>

View file

@ -15,7 +15,7 @@ defmodule Pleroma.Web.EmbedView do
alias Pleroma.Web.Metadata.Utils
alias Pleroma.Web.Router.Helpers
use Phoenix.HTML
import Phoenix.HTML
defdelegate full_nickname(user), to: User
@ -55,10 +55,13 @@ defp activity_url(%User{local: false}, %Activity{object: %Object{data: data}}) d
data["url"] || data["external_url"] || data["id"]
end
defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}}) do
defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}})
when is_list(attachments) do
attachments
end
defp attachments(_), do: []
defp sensitive?(%Activity{object: %Object{data: %{"sensitive" => sensitive}}}) do
sensitive
end

View file

@ -203,7 +203,8 @@ defp deps do
{:excoveralls, "0.15.1", only: :test},
{:mox, "~> 1.0", only: :test},
{:websockex, "~> 0.4.3", only: :test},
{:dialyxir, "~> 1.0", only: [:dev], runtime: false}
{:dialyxir, "~> 1.0", only: [:dev], runtime: false},
{:mint, "~> 1.5.1", override: true}
] ++ oauth_deps()
end

View file

@ -1,11 +1,19 @@
defmodule Pleroma.Repo.Migrations.ForcePinnedObjectsToExist do
use Ecto.Migration
def change do
def up do
execute("UPDATE users SET pinned_objects = '{}' WHERE pinned_objects IS NULL")
alter table("users") do
modify(:pinned_objects, :map, null: false, default: %{})
end
end
def down do
alter table("users") do
modify(:pinned_objects, :map, null: true, default: nil)
end
execute("UPDATE users SET pinned_objects = NULL WHERE pinned_objects = '{}'")
end
end

View file

@ -1,9 +1,15 @@
defmodule Pleroma.Repo.Migrations.AddMastofeSettings do
use Ecto.Migration
def change do
def up do
alter table(:users) do
add_if_not_exists(:mastofe_settings, :map)
end
end
def down do
alter table(:users) do
remove_if_exists(:mastofe_settings, :map)
end
end
end

View file

@ -1,9 +1,15 @@
defmodule Pleroma.Repo.Migrations.AddLanguageToUsers do
use Ecto.Migration
def change do
def up do
alter table(:users) do
add_if_not_exists(:language, :string)
end
end
def down do
alter table(:users) do
remove_if_exists(:language, :string)
end
end
end

115
priv/static/embed/embed.css Normal file
View file

@ -0,0 +1,115 @@
body {
background-color: #282c37;
font-family: sans-serif;
color: white;
margin: 0;
padding: 1em;
padding-bottom: 0;
}
.avatar {
cursor: pointer;
}
.avatar img {
float: left;
border-radius: 4px;
margin-right: 4px;
}
.activity-content {
padding-top: 1em;
}
.attachment {
margin-top: 1em;
}
.attachment img {
max-width: 100%;
}
.date a {
text-decoration: none;
}
.date a:hover {
text-decoration: underline;
}
.date a,
.counts {
color: #666;
font-size: 0.9em;
}
.counts dt,
.counts dd {
float: left;
margin-left: 1em;
}
a {
color: white;
}
.h-card {
min-height: 48px;
margin-bottom: 8px;
}
.h-card a {
text-decoration: none;
}
.h-card a:hover {
text-decoration: underline;
}
.display-name {
padding-top: 4px;
display: block;
text-overflow: ellipsis;
overflow: hidden;
color: white;
}
/* keep emoji from being hilariously huge */
.display-name img {
max-height: 1em;
}
.display-name .nickname {
padding-top: 4px;
display: block;
}
.nickname:hover {
text-decoration: none;
}
.pull-right {
float: right;
}
.collapse {
margin: 0;
width: auto;
}
a.button {
box-sizing: border-box;
display: inline-block;
color: white;
background-color: #419bdd;
border-radius: 4px;
border: none;
padding: 10px;
font-weight: 500;
font-size: 0.9em;
}
a.button:hover {
text-decoration: none;
background-color: #61a6d9;
}

View file

@ -0,0 +1,43 @@
(function () {
'use strict'
var ready = function (loaded) {
if (['interactive', 'complete'].indexOf(document.readyState) !== -1) {
loaded()
} else {
document.addEventListener('DOMContentLoaded', loaded)
}
}
ready(function () {
var iframes = []
window.addEventListener('message', function (e) {
var data = e.data || {}
if (data.type !== 'setHeightPleromaEmbed' || !iframes[data.id]) {
return
}
iframes[data.id].height = data.height
});
[].forEach.call(document.querySelectorAll('iframe.pleroma-embed'), function (iframe) {
iframe.scrolling = 'no'
iframe.style.overflow = 'hidden'
iframes.push(iframe)
var id = iframes.length - 1
iframe.onload = function () {
iframe.contentWindow.postMessage({
type: 'setHeightPleromaEmbed',
id: id
}, '*')
}
iframe.onload()
})
})
})()

View file

@ -0,0 +1,32 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Upload.Filter.OnlyMediaTest do
use Pleroma.DataCase, async: true
alias Pleroma.Upload
alias Pleroma.Upload.Filter.OnlyMedia
test "Allows media Content-Type" do
["audio/mpeg", "image/jpeg", "video/mp4"]
|> Enum.each(fn type ->
upload = %Upload{
content_type: type
}
assert {:ok, :noop} = OnlyMedia.filter(upload)
end)
end
test "Disallows non-media Content-Type" do
["application/javascript", "application/pdf", "text/html"]
|> Enum.each(fn type ->
upload = %Upload{
content_type: type
}
assert {:error, _} = OnlyMedia.filter(upload)
end)
end
end

View file

@ -0,0 +1,44 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.EmbedControllerTest do
use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory
test "/embed", %{conn: conn} do
activity = insert(:note_activity)
resp =
conn
|> get("/embed/#{activity.id}")
|> response(200)
object = Pleroma.Object.get_by_ap_id(activity.data["object"])
assert String.contains?(resp, object.data["content"])
end
test "/embed with a restricted post", %{conn: conn} do
activity = insert(:note_activity)
clear_config([:restrict_unauthenticated, :activities, :local], true)
conn
|> get("/embed/#{activity.id}")
|> response(401)
end
test "/embed with a private post", %{conn: conn} do
user = insert(:user)
{:ok, activity} =
Pleroma.Web.CommonAPI.post(user, %{
status: "Mega ultra chicken status: #fried",
visibility: "private"
})
conn
|> get("/embed/#{activity.id}")
|> response(401)
end
end

View file

@ -1960,6 +1960,10 @@ test "index" do
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
User.mute(user, other_user)
deactivated_user = insert(:user)
{:ok, _} = CommonAPI.react_with_emoji(activity.id, deactivated_user, "🎅")
User.set_activation(deactivated_user, false)
result =
conn
|> get("/api/v1/statuses/?ids[]=#{activity.id}")
@ -1967,6 +1971,7 @@ test "index" do
assert [
%{
"emoji_reactions" => [],
"pleroma" => %{
"emoji_reactions" => []
}

View file

@ -397,7 +397,22 @@ test "represent a relationship for the blocking and blocked user" do
expected =
Map.merge(
@blank_response,
%{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)}
%{following: false, blocking: true, blocked_by: false, id: to_string(other_user.id)}
)
test_relationship_rendering(user, other_user, expected)
end
test "blocks are not visible to the blocked user" do
user = insert(:user)
other_user = insert(:user)
{:ok, _user_relationship} = User.block(other_user, user)
expected =
Map.merge(
@blank_response,
%{following: false, blocking: false, blocked_by: false, id: to_string(other_user.id)}
)
test_relationship_rendering(user, other_user, expected)

View file

@ -199,6 +199,15 @@ test "mediaproxy whitelist" do
assert unencoded == url
end
test "mediaproxy blocklist" do
clear_config([:media_proxy, :whitelist], ["https://google.com"])
clear_config([:media_proxy, :blocklist], ["https://feld.me"])
url = "https://feld.me/foo.png"
unencoded = MediaProxy.url(url)
assert unencoded == url
end
# TODO: delete after removing support bare domains for media proxy whitelist
test "mediaproxy whitelist bare domains whitelist (deprecated)" do
clear_config([:media_proxy, :whitelist], ["google.com", "feld.me"])
@ -220,6 +229,18 @@ test "does not change whitelisted urls" do
assert String.starts_with?(encoded, media_url)
end
test "does not change blocked urls" do
clear_config([:media_proxy, :whitelist], ["mycdn.akamai.com"])
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
media_url = "https://mycdn.akamai.com"
url = "#{media_url}/static/logo.png"
encoded = MediaProxy.url(url)
assert String.starts_with?(encoded, media_url)
end
test "ensure Pleroma.Upload base_url is always whitelisted" do
media_url = "https://media.pleroma.social"
clear_config([Pleroma.Upload, :base_url], media_url)

View file

@ -128,6 +128,12 @@ test "with media_proxy bare domains whitelist (deprecated)", %{conn: conn} do
clear_config([:media_proxy, :whitelist], ["example4.com", "example5.com"])
assert_media_img_src(conn, "example5.com example4.com")
end
test "with media_proxy blocklist", %{conn: conn} do
clear_config([:media_proxy, :whitelist], ["https://example6.com", "https://example7.com"])
clear_config([:media_proxy, :blocklist], ["https://example8.com"])
assert_media_img_src(conn, "https://example7.com https://example6.com")
end
end
defp assert_media_img_src(conn, url) do