Compare commits

..

22 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
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 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
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
21 changed files with 309 additions and 35 deletions

View file

@ -6,10 +6,17 @@ 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

@ -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,

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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -84,8 +84,13 @@ def whitelisted?(url) do
end
def blocked?(url) do
%{host: domain} = URI.parse(url)
domain in Config.get([:media_proxy, :whitelist])
%{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

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

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,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" => []
}