forked from AkkomaGang/akkoma
Compare commits
199 commits
Author | SHA1 | Date | |
---|---|---|---|
1b9edcba64 | |||
5c164028cf | |||
f7ea0a1248 | |||
6139c3346d | |||
98f0820ca4 | |||
9bc0345e57 | |||
f3cc60b202 | |||
063e3c0d34 | |||
6cb40bee26 | |||
7a3529ec1c | |||
76ba400c6d | |||
655c282de3 | |||
0b32beb051 | |||
7bb41bffb3 | |||
fd11e4f8cd | |||
1bd3012c2d | |||
2df7707060 | |||
c22ecac567 | |||
d79c92f9c6 | |||
7bd4ae5412 | |||
165c2485ff | |||
60a07da5ef | |||
73be5c3f30 | |||
e7788f3c82 | |||
f2da47679d | |||
63a5b8506c | |||
c7aeeec232 | |||
80cbdc8480 | |||
3f1e2b0b3b | |||
0c21341156 | |||
fc3cc61768 | |||
7825798e32 | |||
e59fc0677b | |||
650c0c0f62 | |||
7956cfb091 | |||
215b550317 | |||
c193b4d507 | |||
866672b6a7 | |||
ef422a8385 | |||
9723264fe5 | |||
368b22fd2f | |||
9a7c30fc90 | |||
59af68c600 | |||
ec5db753b9 | |||
9b362a6739 | |||
643e7dd7c1 | |||
|
d868348fac | ||
cc2614e10b | |||
31d7cc9a9c | |||
8670d89316 | |||
2556f44219 | |||
b4399574ca | |||
|
9bbe8b4e84 | ||
|
7753fbe633 | ||
|
7ae0b2f5bd | ||
|
69c11643f7 | ||
|
d1af8abe85 | ||
|
7017dc92a8 | ||
|
06f03f8b22 | ||
|
df03e7c8da | ||
|
6abee6eb40 | ||
|
c2bd73518a | ||
|
7f23a3de21 | ||
|
0941896a2e | ||
|
3e224d24d8 | ||
|
16332afb95 | ||
|
0ec5cbe701 | ||
|
2b2a6d0b3b | ||
|
df885b5475 | ||
9c7409808f | |||
|
1f54bea564 | ||
6902ede5b7 | |||
8fd74548ff | |||
8d4d573cc8 | |||
|
bfebb92bea | ||
|
749e9f2229 | ||
|
4f57c87be4 | ||
|
ae03513934 | ||
0b2ec0ccee | |||
1a88d9278b | |||
723bd123a0 | |||
1dc8cc731c | |||
6e293b9280 | |||
87cc5a2110 | |||
64e233ca20 | |||
9aaf5c9332 | |||
2946bf4011 | |||
8cebd74b0a | |||
fe8c166b8f | |||
7e45343f81 | |||
f4fe4fcbcc | |||
02071ab9b4 | |||
d5de05bbe4 | |||
98cb255d12 | |||
babb4b9a8f | |||
b65aafe1e3 | |||
a1fc79c214 | |||
4fe80acf8f | |||
1e66cec654 | |||
27cbfb8985 | |||
|
8b63a17b87 | ||
c38f1aefb1 | |||
1377ec33fe | |||
7ff9c356f4 | |||
801fe9fe32 | |||
08768776e2 | |||
7a6ccf68f0 | |||
800c4bc442 | |||
b63fca2dd7 | |||
|
eba3cce77b | ||
|
99d660c9ad | ||
|
4c9da36748 | ||
|
d8f127f6d5 | ||
|
7f57935669 | ||
|
ec74b60d56 | ||
|
8fa14bcfe4 | ||
|
412f9656f6 | ||
18bf310543 | |||
fa23098093 | |||
079dcd5b17 | |||
597a97cca9 | |||
6db8ab7c94 | |||
d74542148a | |||
db64556306 | |||
a86b010e10 | |||
|
166ddebdbc | ||
c79c0fe6cc | |||
34601065c3 | |||
394174c0a9 | |||
d2d2bbe213 | |||
6fe7bdba46 | |||
0fa0f60520 | |||
f44babd130 | |||
827c6b3344 | |||
a91a3f6e60 | |||
f7a4147788 | |||
de1e487695 | |||
33e7ae7637 | |||
fa40db6b5a | |||
ccd8cd6c59 | |||
900b9b0124 | |||
43aef8b5b1 | |||
f1611b6292 | |||
c63ae73bc0 | |||
16d2bfef80 | |||
c8904f15a2 | |||
8fe29bf5d2 | |||
452f9e14fb | |||
5fa1cfc513 | |||
2aac70d690 | |||
3fa65a5c53 | |||
210df6fe92 | |||
8c956bc671 | |||
5144d6f4ba | |||
3e4a279a1b | |||
fc87baf1cf | |||
|
767e1272b3 | ||
|
07b478dc49 | ||
67cae52b08 | |||
4db42f5ab5 | |||
145191ef26 | |||
6674b33d75 | |||
2dfce40117 | |||
|
c0a01e73cf | ||
|
fee6e2aac4 | ||
|
8669a0abcb | ||
|
37b0d774fa | ||
|
1def80c2e7 | ||
|
3095251e6c | ||
|
79a18f761b | ||
|
8fb235e71b | ||
|
d6271e7613 | ||
5adce547d0 | |||
|
05e80d1879 | ||
|
1268dbc562 | ||
|
651979217a | ||
997551bac9 | |||
|
2a290cb331 | ||
|
dfd6c96808 | ||
|
7b9cc9a9b0 | ||
|
fd38756e92 | ||
|
5ef7c15d92 | ||
3227ebf1e1 | |||
5e3ca133f2 | |||
|
3a13f91fff | ||
b99053d2c2 | |||
593ddbd796 | |||
|
1ae89bddcd | ||
5fe41df8aa | |||
5ce38591e5 | |||
2482d96782 | |||
f68b047bf7 | |||
48a0145736 | |||
d956dc2f09 | |||
40627a94d4 | |||
0e5f55deea | |||
f0f0c76805 | |||
b3fc098b83 | |||
54fdf3a5de |
450 changed files with 125403 additions and 8488 deletions
|
@ -1,3 +1,14 @@
|
|||
[
|
||||
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}", "priv/repo/migrations/*.exs", "priv/repo/optional_migrations/**/*.exs", "priv/scrubbers/*.ex"]
|
||||
import_deps: [:ecto, :ecto_sql, :phoenix],
|
||||
subdirectories: ["priv/*/migrations"],
|
||||
plugins: [Phoenix.LiveView.HTMLFormatter],
|
||||
inputs: [
|
||||
"mix.exs",
|
||||
"*.{heex,ex,exs}",
|
||||
"{config,lib,test}/**/*.{heex,ex,exs}",
|
||||
"priv/*/seeds.exs",
|
||||
"priv/repo/migrations/*.exs",
|
||||
"priv/repo/optional_migrations/**/*.exs",
|
||||
"priv/scrubbers/*.ex"
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
platform: linux/amd64
|
||||
|
||||
depends_on:
|
||||
- test
|
||||
|
||||
variables:
|
||||
- &scw-secrets
|
||||
- SCW_ACCESS_KEY
|
||||
|
@ -12,8 +17,6 @@ variables:
|
|||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- refs/tags/v*
|
||||
- refs/tags/stable-*
|
||||
- &on-stable
|
||||
when:
|
||||
event:
|
||||
|
@ -21,14 +24,6 @@ variables:
|
|||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- refs/tags/stable-*
|
||||
- &on-point-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- &on-pr-open
|
||||
when:
|
||||
event:
|
||||
|
@ -39,63 +34,10 @@ variables:
|
|||
- &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
|
||||
- &mix-clean "mix deps.clean --all && mix clean"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
environment:
|
||||
POSTGRES_DB: pleroma_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
|
||||
pipeline:
|
||||
lint:
|
||||
<<: *on-pr-open
|
||||
image: akkoma/ci-base:1.14
|
||||
commands:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix format --check-formatted
|
||||
|
||||
build:
|
||||
image: akkoma/ci-base:1.14
|
||||
<<: *on-pr-open
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
POSTGRES_DB: pleroma_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
DB_HOST: postgres
|
||||
commands:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
|
||||
test:
|
||||
image: akkoma/ci-base:1.14
|
||||
<<: *on-pr-open
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
POSTGRES_DB: pleroma_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
DB_HOST: postgres
|
||||
commands:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
- mix ecto.drop -f -q
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- mix test --preload-modules --exclude erratic --exclude federated --max-cases 4
|
||||
|
||||
# Canonical amd64
|
||||
ubuntu22:
|
||||
image: hexpm/elixir:1.14.3-erlang-25.2.2-ubuntu-jammy-20221130
|
||||
debian-bookworm:
|
||||
image: hexpm/elixir:1.15.4-erlang-26.0.2-debian-bookworm-20230612
|
||||
<<: *on-release
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
|
@ -108,51 +50,51 @@ pipeline:
|
|||
- *tag-build
|
||||
- mix deps.get --only prod
|
||||
- mix release --path release
|
||||
- zip akkoma-ubuntu-jammy.zip -r release
|
||||
|
||||
release-ubuntu22:
|
||||
image: akkoma/releaser
|
||||
<<: *on-release
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-ubuntu-jammy.zip
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-ubuntu-jammy.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-amd64-ubuntu-jammy.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
|
||||
debian-bullseye:
|
||||
image: hexpm/elixir:1.14.3-erlang-25.2.2-debian-bullseye-20230109
|
||||
<<: *on-release
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
commands:
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev rclone zip imagemagick libmagic-dev git build-essential gcc make g++ wget
|
||||
- *clean
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- *setup-hex
|
||||
- *tag-build
|
||||
- *mix-clean
|
||||
- mix deps.get --only prod
|
||||
- mix release --path release
|
||||
- zip akkoma-amd64.zip -r release
|
||||
|
||||
release-debian:
|
||||
release-debian-bookworm:
|
||||
image: akkoma/releaser
|
||||
<<: *on-release
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-amd64.zip
|
||||
# AMD64
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-amd64.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-debian-stable.zip
|
||||
# Ubuntu jammy (currently compatible)
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-amd64-ubuntu-jammy.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
|
||||
debian-bullseye:
|
||||
image: hexpm/elixir:1.15.4-erlang-26.0.2-debian-bullseye-20230612
|
||||
<<: *on-release
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
commands:
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev rclone zip imagemagick libmagic-dev git build-essential g++ wget
|
||||
- *clean
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- *setup-hex
|
||||
- *tag-build
|
||||
- mix deps.get --only prod
|
||||
- mix release --path release
|
||||
- zip akkoma-amd64-debian-bullseye.zip -r release
|
||||
|
||||
release-debian-bullseye:
|
||||
image: akkoma/releaser
|
||||
<<: *on-release
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-amd64-debian-bullseye.zip
|
||||
# AMD64
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-amd64-debian-bullseye.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
|
||||
# Canonical amd64-musl
|
||||
musl:
|
||||
image: hexpm/elixir:1.14.3-erlang-25.2.2-alpine-3.15.6
|
||||
<<: *on-release
|
||||
image: hexpm/elixir:1.15.4-erlang-26.0.2-alpine-3.18.2
|
||||
<<: *on-stable
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
commands:
|
||||
|
@ -167,31 +109,9 @@ pipeline:
|
|||
|
||||
release-musl:
|
||||
image: akkoma/releaser
|
||||
<<: *on-release
|
||||
<<: *on-stable
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-amd64-musl.zip
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-amd64-musl.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
|
||||
docs:
|
||||
<<: *on-point-release
|
||||
secrets:
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
environment:
|
||||
CI: "true"
|
||||
image: python:3.10-slim
|
||||
commands:
|
||||
- apt-get update && apt-get install -y rclone wget git zip
|
||||
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
|
||||
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
|
||||
- chmod +x scaleway-cli
|
||||
- ./scaleway-cli object config install type=rclone
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
- mkdocs build
|
||||
- zip -r docs.zip site/*
|
||||
- cd site
|
||||
- rclone copy . scaleway:akkoma-docs/$CI_COMMIT_BRANCH/
|
89
.woodpecker/build-arm64.yml
Normal file
89
.woodpecker/build-arm64.yml
Normal file
|
@ -0,0 +1,89 @@
|
|||
platform: linux/arm64
|
||||
|
||||
depends_on:
|
||||
- test
|
||||
|
||||
variables:
|
||||
- &scw-secrets
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
- &setup-hex "mix local.hex --force && mix local.rebar --force"
|
||||
- &on-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- develop
|
||||
- &on-stable
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- &on-pr-open
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- &tag-build "export BUILD_TAG=$${CI_COMMIT_TAG:-\"$CI_COMMIT_BRANCH\"} && export PLEROMA_BUILD_BRANCH=$BUILD_TAG"
|
||||
|
||||
- &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
|
||||
- &mix-clean "mix deps.clean --all && mix clean"
|
||||
|
||||
pipeline:
|
||||
# Canonical arm64
|
||||
debian-bookworm:
|
||||
image: hexpm/elixir:1.15.4-erlang-26.0.2-debian-bookworm-20230612
|
||||
<<: *on-release
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
commands:
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev rclone zip imagemagick libmagic-dev git build-essential g++ wget
|
||||
- *clean
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- *setup-hex
|
||||
- *tag-build
|
||||
- mix deps.get --only prod
|
||||
- mix release --path release
|
||||
- zip akkoma-arm64.zip -r release
|
||||
|
||||
release-debian-bookworm:
|
||||
image: akkoma/releaser:arm64
|
||||
<<: *on-release
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-arm64.zip
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-arm64-ubuntu-jammy.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-arm64.zip
|
||||
- /bin/sh /entrypoint.sh
|
||||
|
||||
# Canonical arm64-musl
|
||||
musl:
|
||||
image: hexpm/elixir:1.15.4-erlang-26.0.2-alpine-3.18.2
|
||||
<<: *on-stable
|
||||
environment:
|
||||
MIX_ENV: prod
|
||||
commands:
|
||||
- apk add git gcc g++ musl-dev make cmake file-dev rclone wget zip imagemagick
|
||||
- *clean
|
||||
- *setup-hex
|
||||
- *mix-clean
|
||||
- *tag-build
|
||||
- mix deps.get --only prod
|
||||
- mix release --path release
|
||||
- zip akkoma-arm64-musl.zip -r release
|
||||
|
||||
release-musl:
|
||||
image: akkoma/releaser:arm64
|
||||
<<: *on-stable
|
||||
secrets: *scw-secrets
|
||||
commands:
|
||||
- export SOURCE=akkoma-arm64-musl.zip
|
||||
- export DEST=scaleway:akkoma-updates/$${CI_COMMIT_TAG:-"$CI_COMMIT_BRANCH"}/akkoma-arm64-musl.zip
|
||||
- /bin/sh /entrypoint.sh
|
69
.woodpecker/docs.yml
Normal file
69
.woodpecker/docs.yml
Normal file
|
@ -0,0 +1,69 @@
|
|||
platform: linux/amd64
|
||||
|
||||
depends_on:
|
||||
- test
|
||||
- build-amd64
|
||||
|
||||
variables:
|
||||
- &scw-secrets
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
- &setup-hex "mix local.hex --force && mix local.rebar --force"
|
||||
- &on-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- refs/tags/v*
|
||||
- refs/tags/stable-*
|
||||
- &on-stable
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- refs/tags/stable-*
|
||||
- &on-point-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- &on-pr-open
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- &tag-build "export BUILD_TAG=$${CI_COMMIT_TAG:-\"$CI_COMMIT_BRANCH\"} && export PLEROMA_BUILD_BRANCH=$BUILD_TAG"
|
||||
|
||||
- &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
|
||||
- &mix-clean "mix deps.clean --all && mix clean"
|
||||
|
||||
pipeline:
|
||||
docs:
|
||||
<<: *on-point-release
|
||||
secrets:
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
environment:
|
||||
CI: "true"
|
||||
image: python:3.10-slim
|
||||
commands:
|
||||
- apt-get update && apt-get install -y rclone wget git zip
|
||||
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
|
||||
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
|
||||
- chmod +x scaleway-cli
|
||||
- ./scaleway-cli object config install type=rclone
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
- mkdocs build
|
||||
- zip -r docs.zip site/*
|
||||
- cd site
|
||||
- rclone copy . scaleway:akkoma-docs/$CI_COMMIT_BRANCH/
|
55
.woodpecker/lint.yml
Normal file
55
.woodpecker/lint.yml
Normal file
|
@ -0,0 +1,55 @@
|
|||
platform: linux/amd64
|
||||
|
||||
variables:
|
||||
- &scw-secrets
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
- &setup-hex "mix local.hex --force && mix local.rebar --force"
|
||||
- &on-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- refs/tags/v*
|
||||
- refs/tags/stable-*
|
||||
- &on-stable
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- refs/tags/stable-*
|
||||
- &on-point-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- &on-pr-open
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- &tag-build "export BUILD_TAG=$${CI_COMMIT_TAG:-\"$CI_COMMIT_BRANCH\"} && export PLEROMA_BUILD_BRANCH=$BUILD_TAG"
|
||||
|
||||
- &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
|
||||
- &mix-clean "mix deps.clean --all && mix clean"
|
||||
|
||||
pipeline:
|
||||
lint:
|
||||
image: akkoma/ci-base:1.15-otp26
|
||||
<<: *on-pr-open
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
commands:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
- mix format --check-formatted
|
93
.woodpecker/test.yml
Normal file
93
.woodpecker/test.yml
Normal file
|
@ -0,0 +1,93 @@
|
|||
platform: linux/amd64
|
||||
|
||||
depends_on:
|
||||
- lint
|
||||
|
||||
matrix:
|
||||
ELIXIR_VERSION:
|
||||
- 1.14
|
||||
- 1.15
|
||||
OTP_VERSION:
|
||||
- 25
|
||||
- 26
|
||||
include:
|
||||
- ELIXIR_VERSION: 1.14
|
||||
OTP_VERSION: 25
|
||||
- ELIXIR_VERSION: 1.15
|
||||
OTP_VERSION: 25
|
||||
- ELIXIR_VERSION: 1.15
|
||||
OTP_VERSION: 26
|
||||
|
||||
variables:
|
||||
- &scw-secrets
|
||||
- SCW_ACCESS_KEY
|
||||
- SCW_SECRET_KEY
|
||||
- SCW_DEFAULT_ORGANIZATION_ID
|
||||
- &setup-hex "mix local.hex --force && mix local.rebar --force"
|
||||
- &on-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- refs/tags/v*
|
||||
- refs/tags/stable-*
|
||||
- &on-stable
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
branch:
|
||||
- stable
|
||||
- refs/tags/stable-*
|
||||
- &on-point-release
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- develop
|
||||
- stable
|
||||
- &on-pr-open
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- &tag-build "export BUILD_TAG=$${CI_COMMIT_TAG:-\"$CI_COMMIT_BRANCH\"} && export PLEROMA_BUILD_BRANCH=$BUILD_TAG"
|
||||
|
||||
- &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
|
||||
- &mix-clean "mix deps.clean --all && mix clean"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
environment:
|
||||
POSTGRES_DB: pleroma_test_${ELIXIR_VERSION}_${OTP_VERSION}
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
|
||||
pipeline:
|
||||
test:
|
||||
image: akkoma/ci-base:${ELIXIR_VERSION}-otp${OTP_VERSION}
|
||||
<<: *on-pr-open
|
||||
environment:
|
||||
MIX_ENV: test
|
||||
POSTGRES_DB: pleroma_test_${ELIXIR_VERSION}_${OTP_VERSION}
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
DB_HOST: postgres
|
||||
commands:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
- mix ecto.drop -f -q
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- mkdir -p test/tmp
|
||||
- mix test --preload-modules --exclude erratic --exclude federated --exclude mocked
|
||||
- mix test --preload-modules --only mocked
|
59
CHANGELOG.md
59
CHANGELOG.md
|
@ -4,6 +4,64 @@ 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
|
||||
- Full compatibility with Erlang OTP26
|
||||
- handling of GET /api/v1/preferences
|
||||
|
||||
## Changed
|
||||
- OTP builds are now built on erlang OTP26
|
||||
- The base Phoenix framework is now updated to 1.7
|
||||
|
||||
## Fixed
|
||||
- Documentation issue in which a non-existing nginx file was referenced
|
||||
- Issue where a bad inbox URL could break federation
|
||||
|
||||
## 2023.08
|
||||
|
||||
## 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
|
||||
- ARM64 OTP builds
|
||||
- Ubuntu22 builds are available for develop and stable
|
||||
- other distributions are stable only
|
||||
- Support for Elixir 1.15
|
||||
- 1.14 is still supported
|
||||
- OTP26 is currently "unsupported". It will probably work, but due to the way
|
||||
it handles map ordering, the test suite will not pass for it as yet.
|
||||
|
||||
## Changed
|
||||
|
||||
- Alpine OTP builds are now from alpine 3.18, which is OpenSSLv3 compatible.
|
||||
If you use alpine OTP builds you will have to update your local system.
|
||||
- Debian OTP builds are now from a base of bookworm, which is OpenSSLv3 compatible.
|
||||
If you use debian OTP builds you will have to update your local system to
|
||||
bookworm (currently: stable).
|
||||
- Ubuntu and debian builds are compatible again! (for now...)
|
||||
- Blocks/Mutes now return from max ID to min ID, in line with mastodon.
|
||||
- The AnonymizeFilename filter is now enabled by default.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Deactivated users can no longer show up in the emoji reaction list
|
||||
- Embedded posts can no longer bypass `:restrict\_unauthenticated`
|
||||
- GET/HEAD requests will now work when requesting AWS-based instances.
|
||||
|
||||
## Security
|
||||
|
||||
- Add `no_new_privs` hardening to OpenRC and systemd service files
|
||||
- XML parsers cannot load any entities (thanks @Mae@is.badat.dev!)
|
||||
- Reduced permissions of config files and directories, distros requiring greater permissions like group-read need to pre-create the directories
|
||||
|
||||
## Removed
|
||||
|
||||
- Builds for debian oldstable (bullseye)
|
||||
- If you are on oldstable you should NOT attempt to update OTP builds without
|
||||
first updating your machine.
|
||||
|
||||
## 2023.05
|
||||
|
||||
## Added
|
||||
|
@ -86,7 +144,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Rich media will now hard-exit after 5 seconds, to prevent timeline hangs
|
||||
- HTTP Content Security Policy is now far more strict to prevent any potential XSS/CSS leakages
|
||||
- Follow requests are now paginated, matches mastodon API spec, so use the Link header to paginate.
|
||||
- `internal.fetch` and `relay` actors are now represented with the actor type `Application`
|
||||
|
||||
### Fixed
|
||||
- /api/v1/accounts/lookup will now respect restrict\_unauthenticated
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM hexpm/elixir:1.14.3-erlang-25.3-alpine-3.17.2
|
||||
FROM hexpm/elixir:1.15.4-erlang-26.0.2-alpine-3.18.2
|
||||
|
||||
ENV MIX_ENV=prod
|
||||
ENV ERL_EPMD_ADDRESS=127.0.0.1
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
method: Pleroma.Captcha.Mock
|
||||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, level: :warn
|
||||
config :logger, level: :warning
|
||||
|
||||
config :pleroma, :auth, oauth_consumer_strategies: []
|
||||
|
||||
|
|
|
@ -110,17 +110,6 @@
|
|||
"xmpp"
|
||||
]
|
||||
|
||||
websocket_config = [
|
||||
path: "/websocket",
|
||||
serializer: [
|
||||
{Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"},
|
||||
{Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}
|
||||
],
|
||||
timeout: 60_000,
|
||||
transport_log: false,
|
||||
compress: false
|
||||
]
|
||||
|
||||
# Configures the endpoint
|
||||
config :pleroma, Pleroma.Web.Endpoint,
|
||||
url: [host: "localhost"],
|
||||
|
@ -130,10 +119,7 @@
|
|||
{:_,
|
||||
[
|
||||
{"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
|
||||
{"/websocket", Phoenix.Endpoint.CowboyWebSocket,
|
||||
{Phoenix.Transports.WebSocket,
|
||||
{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}},
|
||||
{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
|
||||
{:_, Plug.Cowboy.Handler, {Pleroma.Web.Endpoint, []}}
|
||||
]}
|
||||
]
|
||||
],
|
||||
|
@ -170,6 +156,10 @@
|
|||
"application/ld+json" => ["activity+json"]
|
||||
}
|
||||
|
||||
config :mime, :extensions, %{
|
||||
"activity+json" => "application/activity+json"
|
||||
}
|
||||
|
||||
config :tesla, :adapter, {Tesla.Adapter.Finch, name: MyFinch}
|
||||
|
||||
# Configures http settings, upstream proxy etc.
|
||||
|
@ -443,7 +433,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,
|
||||
|
|
|
@ -1081,7 +1081,7 @@
|
|||
key: :level,
|
||||
type: {:dropdown, :atom},
|
||||
description: "Log level",
|
||||
suggestions: [:debug, :info, :warn, :error]
|
||||
suggestions: [:debug, :info, :warning, :error]
|
||||
},
|
||||
%{
|
||||
key: :ident,
|
||||
|
@ -1114,7 +1114,7 @@
|
|||
key: :level,
|
||||
type: {:dropdown, :atom},
|
||||
description: "Log level",
|
||||
suggestions: [:debug, :info, :warn, :error]
|
||||
suggestions: [:debug, :info, :warning, :error]
|
||||
},
|
||||
%{
|
||||
key: :format,
|
||||
|
@ -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"]
|
||||
}
|
||||
]
|
||||
|
@ -1844,7 +1858,7 @@
|
|||
key: :log,
|
||||
type: {:dropdown, :atom},
|
||||
description: "Logs verbose mode",
|
||||
suggestions: [false, :error, :warn, :info, :debug]
|
||||
suggestions: [false, :error, :warning, :info, :debug]
|
||||
},
|
||||
%{
|
||||
key: :queues,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, :console,
|
||||
level: :warn,
|
||||
level: :warning,
|
||||
format: "\n[$level] $message\n"
|
||||
|
||||
config :pleroma, :auth, oauth_consumer_strategies: []
|
||||
|
@ -81,10 +81,7 @@
|
|||
"BLH1qVhJItRGCfxgTtONfsOKDc9VRAraXw-3NsmjMngWSh7NxOizN6bkuRA7iLTMPS82PjwJAr3UoK9EC1IFrz4",
|
||||
private_key: "_-XZ0iebPrRfZ_o0-IatTdszYa8VCH1yLN-JauK7HHA"
|
||||
|
||||
config :pleroma, Oban,
|
||||
queues: false,
|
||||
crontab: false,
|
||||
plugins: false
|
||||
config :pleroma, Oban, testing: :manual
|
||||
|
||||
config :pleroma, Pleroma.ScheduledActivity,
|
||||
daily_user_limit: 2,
|
||||
|
|
|
@ -4,6 +4,7 @@ services:
|
|||
db:
|
||||
image: akkoma-db:latest
|
||||
build: ./docker-resources/database
|
||||
shm_size: 4gb
|
||||
restart: unless-stopped
|
||||
user: ${DOCKER_USER}
|
||||
environment: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
docker-compose run --rm akkoma $@
|
||||
docker compose run --rm akkoma $@
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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/>
|
||||
|
|
|
@ -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"}]`.
|
||||
|
|
|
@ -26,7 +26,7 @@ config :pleroma, :frontends,
|
|||
}
|
||||
```
|
||||
|
||||
This would serve the frontend from the the folder at `$instance_static/frontends/pleroma/stable`. You have to copy the frontend into this folder yourself. You can choose the name and ref any way you like, but they will be used by mix tasks to automate installation in the future, the name referring to the project and the ref referring to a commit.
|
||||
This would serve the frontend from the folder at `$instance_static/frontends/pleroma/stable`. You have to copy the frontend into this folder yourself. You can choose the name and ref any way you like, but they will be used by mix tasks to automate installation in the future, the name referring to the project and the ref referring to a commit.
|
||||
|
||||
Refer to [the frontend CLI task](../../administration/CLI_tasks/frontend) for how to install the frontend's files
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -70,4 +70,4 @@ config :pleroma, :frontend_configurations,
|
|||
}
|
||||
```
|
||||
|
||||
If you added it in the back-end configuration file, you'll need to restart your instance for the changes to take effect. If you don't see the changes, it's probably because the browser has cached the previous theme. In that case you'll want to clear browser caches. Alternatively you can use a private/incognito window just to see the changes.
|
||||
If you added it in the back-end configuration file, you'll need to restart your instance for the changes to take effect. If you don't see the changes, it's probably because the browser has cached the previous theme. In that case you'll want to clear browser caches. Alternatively you can use a private/incognito window just to see the changes.
|
||||
|
|
|
@ -25,6 +25,7 @@ Home, public, hashtag & list timelines accept these parameters:
|
|||
## Statuses
|
||||
|
||||
- `visibility`: has additional possible values `list` and `local` (for local-only statuses)
|
||||
- `emoji_reactions`: additional field since Akkoma 3.2.0; identical to `pleroma/emoji_reactions`
|
||||
|
||||
Has these additional fields under the `pleroma` object:
|
||||
|
||||
|
@ -36,7 +37,9 @@ Has these additional fields under the `pleroma` object:
|
|||
- `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being its mimetype. Currently, the only alternate representation supported is `text/plain`
|
||||
- `expires_at`: a datetime (iso8601) that states when the post will expire (be deleted automatically), or empty if the post won't expire
|
||||
- `thread_muted`: true if the thread the post belongs to is muted
|
||||
- `emoji_reactions`: A list with emoji / reaction maps. The format is `{name: "☕", count: 1, me: true}`. Contains no information about the reacting users, for that use the `/statuses/:id/reactions` endpoint.
|
||||
- `emoji_reactions`: A list with emoji / reaction maps. The format is `{name: "☕", count: 2, me: true, account_ids: ["UserID1", "UserID2"]}`.
|
||||
The `account_ids` property was added in Akkoma 3.2.0.
|
||||
Further info about all reacting users at once, can be found using the `/statuses/:id/reactions` endpoint.
|
||||
- `parent_visible`: If the parent of this post is visible to the user or not.
|
||||
- `pinned_at`: a datetime (iso8601) when status was pinned, `null` otherwise.
|
||||
|
||||
|
@ -214,6 +217,11 @@ Returns: array of Status.
|
|||
|
||||
The maximum number of statuses is limited to 100 per request.
|
||||
|
||||
## PUT `/api/v1/statuses/:id/emoji_reactions/:emoji`
|
||||
|
||||
This endpoint is an extension of the Fedibird Mastodon fork.
|
||||
It behaves identical to PUT `/api/v1/pleroma/statuses/:id/reactions/:emoji`.
|
||||
|
||||
## PATCH `/api/v1/accounts/update_credentials`
|
||||
|
||||
Additional parameters can be added to the JSON body/Form data:
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## Installation
|
||||
|
||||
This guide will assume you are on Debian 11 (“bullseye”) or later. This guide should also work with Ubuntu 18.04 (“Bionic Beaver”) and later. It also assumes that you have administrative rights, either as root or a user with [sudo permissions](https://www.digitalocean.com/community/tutorials/how-to-add-delete-and-grant-sudo-privileges-to-users-on-a-debian-vps). If you want to run this guide with root, ignore the `sudo` at the beginning of the lines, unless it calls a user like `sudo -Hu akkoma`; in this case, use `su <username> -s $SHELL -c 'command'` instead.
|
||||
This guide will assume you are on Debian 12 (“bookworm”) or later. This guide should also work with Ubuntu 22.04 (“Jammy Jellyfish”) and later. It also assumes that you have administrative rights, either as root or a user with [sudo permissions](https://www.digitalocean.com/community/tutorials/how-to-add-delete-and-grant-sudo-privileges-to-users-on-a-debian-vps). If you want to run this guide with root, ignore the `sudo` at the beginning of the lines, unless it calls a user like `sudo -Hu akkoma`; in this case, use `su <username> -s $SHELL -c 'command'` instead.
|
||||
|
||||
{! installation/generic_dependencies.include !}
|
||||
|
||||
|
@ -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 don’t 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.5
|
||||
asdf global erlang 25.3.2.5
|
||||
```
|
||||
|
||||
Now install Elixir:
|
||||
```shell
|
||||
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
|
||||
asdf install elixir 1.15.4-otp-25
|
||||
asdf global elixir 1.15.4-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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
* PostgreSQL 9.6+
|
||||
* Elixir 1.14+
|
||||
* Erlang OTP 24+
|
||||
* Erlang OTP 25+
|
||||
* git
|
||||
* file / libmagic
|
||||
* gcc (clang might also work)
|
||||
|
|
|
@ -40,7 +40,7 @@ If you are on pleroma develop, and have updated since 2022-08, you may have issu
|
|||
Please roll back the given migrations:
|
||||
|
||||
```bash
|
||||
MIX_ENV=prod mix ecto.rollback --migrations-path priv/repo/optional_migrations/pleroma_develop_rollbacks -n3
|
||||
MIX_ENV=prod mix ecto.rollback --migrations-path priv/repo/optional_migrations/pleroma_develop_rollbacks -n5
|
||||
```
|
||||
|
||||
Then compile, migrate and restart as usual.
|
||||
|
@ -117,4 +117,16 @@ To fix this, run:
|
|||
mix pleroma.config delete pleroma frontends
|
||||
```
|
||||
|
||||
which will remove the config from the database. Things should work now.
|
||||
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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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`)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
This guide covers a installation using an OTP release. To install Akkoma from source, please check out the corresponding guide for your distro.
|
||||
|
||||
## Pre-requisites
|
||||
* A machine running Linux with GNU (e.g. Debian, Ubuntu) or musl (e.g. Alpine) libc and an `x86_64` CPU you have root access to. If you are not sure if it's compatible see [Detecting flavour section](#detecting-flavour) below
|
||||
* A machine running Linux with GNU (e.g. Debian, Ubuntu) or musl (e.g. Alpine) libc and an `x86_64` or `arm64` CPU you have root access to. If you are not sure if it's compatible see [Detecting flavour section](#detecting-flavour) below
|
||||
* For installing OTP releases on RedHat-based distros like Fedora and Centos Stream, please follow [this guide](./otp_redhat_en.md) instead.
|
||||
* A (sub)domain pointed to the machine
|
||||
|
||||
|
@ -15,16 +15,16 @@ While in theory OTP releases are possbile to install on any compatible machine,
|
|||
|
||||
### Detecting flavour
|
||||
|
||||
This is a little more complex than it used to be (thanks ubuntu)
|
||||
|
||||
Use the following mapping to figure out your flavour:
|
||||
|
||||
| distribution | flavour | available branches |
|
||||
| ------------- | ------------------ | ------------------- |
|
||||
| debian stable | amd64 | develop, stable |
|
||||
| ubuntu focal | amd64 | develop, stable |
|
||||
| ubuntu jammy | amd64-ubuntu-jammy | develop, stable |
|
||||
| alpine | amd64-musl | stable |
|
||||
| distribution | architecture | flavour | available branches |
|
||||
| --------------- | ------------------ | ------------------- | ------------------- |
|
||||
| debian bookworm | amd64 | amd64 | develop, stable |
|
||||
| debian bookworm | arm64 | arm64 | stable |
|
||||
| ubuntu jammy | amd64 | amd64 | develop, stable |
|
||||
| ubuntu jammy | arm64 | arm64 | develop, stable |
|
||||
| alpine | amd64 | amd64-musl | stable |
|
||||
| alpine | arm64 | arm64-musl | stable |
|
||||
|
||||
Other similar distributions will _probably_ work, but if it is not listed above, there is no official
|
||||
support.
|
||||
|
@ -118,8 +118,12 @@ Restart PostgreSQL to apply configuration changes:
|
|||
adduser --system --shell /bin/false --home /opt/akkoma akkoma
|
||||
|
||||
# Set the flavour environment variable to the string you got in Detecting flavour section.
|
||||
# For example if the flavour is `amd64` the command will be
|
||||
export FLAVOUR="amd64"
|
||||
# For example if the flavour is `amd64-musl` the command will be
|
||||
# export FLAVOUR="amd64-musl"
|
||||
export FLAVOUR="<replace-this-with-the-correct-flavour-string>"
|
||||
|
||||
# Make sure the SHELL variable is set
|
||||
export SHELL="${SHELL:-/bin/sh}"
|
||||
|
||||
# Clone the release build into a temporary directory and unpack it
|
||||
su akkoma -s $SHELL -lc "
|
||||
|
@ -183,18 +187,18 @@ The location of nginx configs is dependent on the distro
|
|||
|
||||
=== "Alpine"
|
||||
```
|
||||
cp /opt/akkoma/installation/nginx/akkoma.nginx /etc/nginx/conf.d/akkoma.conf
|
||||
cp /opt/akkoma/installation/akkoma.nginx /etc/nginx/conf.d/akkoma.conf
|
||||
```
|
||||
|
||||
=== "Debian/Ubuntu"
|
||||
```
|
||||
cp /opt/akkoma/installation/nginx/akkoma.nginx /etc/nginx/sites-available/akkoma.conf
|
||||
cp /opt/akkoma/installation/akkoma.nginx /etc/nginx/sites-available/akkoma.conf
|
||||
ln -s /etc/nginx/sites-available/akkoma.conf /etc/nginx/sites-enabled/akkoma.conf
|
||||
```
|
||||
|
||||
If your distro does not have either of those you can append `include /etc/nginx/akkoma.conf` to the end of the http section in /etc/nginx/nginx.conf and
|
||||
```sh
|
||||
cp /opt/akkoma/installation/nginx/akkoma.nginx /etc/nginx/akkoma.conf
|
||||
cp /opt/akkoma/installation/akkoma.nginx /etc/nginx/akkoma.conf
|
||||
```
|
||||
|
||||
#### Edit the nginx config
|
||||
|
|
|
@ -178,7 +178,7 @@ certbot certonly --standalone --preferred-challenges http -d yourinstance.tld
|
|||
#### Copy Akkoma nginx configuration to the nginx folder
|
||||
|
||||
```shell
|
||||
cp /opt/akkoma/installation/nginx/akkoma.nginx /etc/nginx/conf.d/akkoma.conf
|
||||
cp /opt/akkoma/installation/akkoma.nginx /etc/nginx/conf.d/akkoma.conf
|
||||
```
|
||||
|
||||
#### Edit the nginx config
|
||||
|
|
8
docs/theme/partials/source.html
vendored
8
docs/theme/partials/source.html
vendored
|
@ -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 %}
|
||||
|
|
|
@ -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.
|
||||
|
@ -34,6 +38,8 @@ ProtectHome=true
|
|||
ProtectSystem=full
|
||||
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi.
|
||||
PrivateDevices=false
|
||||
; Ensures that the service process and all its children can never gain new privileges through execve().
|
||||
NoNewPrivileges=true
|
||||
; Drops the sysadmin capability from the daemon.
|
||||
CapabilityBoundingSet=~CAP_SYS_ADMIN
|
||||
|
||||
|
|
|
@ -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
|
||||
# }
|
||||
# }
|
||||
#}
|
||||
|
|
|
@ -8,6 +8,7 @@ pidfile="/var/run/akkoma.pid"
|
|||
directory=/opt/akkoma
|
||||
healthcheck_delay=60
|
||||
healthcheck_timer=30
|
||||
no_new_privs="yes"
|
||||
|
||||
: ${akkoma_port:-4000}
|
||||
|
||||
|
|
|
@ -359,7 +359,7 @@ def run(["set_text_search_config", tsconfig]) do
|
|||
)
|
||||
end
|
||||
|
||||
shell_info('Done.')
|
||||
shell_info(~c"Done.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ def run(["get-packs" | args]) do
|
|||
}
|
||||
|
||||
File.write!(Path.join(pack_path, "pack.json"), Jason.encode!(pack_json, pretty: true))
|
||||
Pleroma.Emoji.reload()
|
||||
else
|
||||
IO.puts(IO.ANSI.format([:bright, :red, "No pack named \"#{pack_name}\" found"]))
|
||||
end
|
||||
|
@ -235,6 +236,8 @@ def run(["gen-pack" | args]) do
|
|||
|
||||
IO.puts("#{pack_file} has been created with the #{name} pack")
|
||||
end
|
||||
|
||||
Pleroma.Emoji.reload()
|
||||
end
|
||||
|
||||
def run(["reload"]) do
|
||||
|
|
|
@ -247,16 +247,22 @@ def run(["gen" | rest]) do
|
|||
config_dir = Path.dirname(config_path)
|
||||
psql_dir = Path.dirname(psql_path)
|
||||
|
||||
# Note: Distros requiring group read (0o750) on those directories should
|
||||
# pre-create the directories.
|
||||
to_create =
|
||||
[config_dir, psql_dir, static_dir, uploads_dir]
|
||||
|> Enum.reject(&File.exists?/1)
|
||||
|
||||
for dir <- to_create do
|
||||
File.mkdir_p!(dir)
|
||||
File.chmod!(dir, 0o700)
|
||||
end
|
||||
|
||||
shell_info("Writing config to #{config_path}.")
|
||||
|
||||
# Sadly no fchmod(2) equivalent in Elixir…
|
||||
File.touch!(config_path)
|
||||
File.chmod!(config_path, 0o640)
|
||||
File.write(config_path, result_config)
|
||||
shell_info("Writing the postgres script to #{psql_path}.")
|
||||
File.write(psql_path, result_psql)
|
||||
|
@ -275,8 +281,7 @@ def run(["gen" | rest]) do
|
|||
else
|
||||
shell_error(
|
||||
"The task would have overwritten the following files:\n" <>
|
||||
(Enum.map(will_overwrite, &"- #{&1}\n") |> Enum.join("")) <>
|
||||
"Rerun with `--force` to overwrite them."
|
||||
Enum.map_join(will_overwrite, &"- #{&1}\n") <> "Rerun with `--force` to overwrite them."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,12 +30,12 @@ def run(["index"]) do
|
|||
meili_put(
|
||||
"/indexes/objects/settings/ranking-rules",
|
||||
[
|
||||
"published:desc",
|
||||
"words",
|
||||
"exactness",
|
||||
"proximity",
|
||||
"typo",
|
||||
"exactness",
|
||||
"attribute",
|
||||
"published:desc",
|
||||
"sort"
|
||||
]
|
||||
)
|
||||
|
|
|
@ -11,6 +11,7 @@ defmodule Mix.Tasks.Pleroma.User do
|
|||
alias Pleroma.UserInviteToken
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.Pipeline
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
@shortdoc "Manages Pleroma users"
|
||||
@moduledoc File.read!("docs/docs/administration/CLI_tasks/user.md")
|
||||
|
@ -113,11 +114,7 @@ def run(["reset_password", nickname]) do
|
|||
{:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||
shell_info("Generated password reset token for #{user.nickname}")
|
||||
|
||||
IO.puts(
|
||||
"URL: #{Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint,
|
||||
:reset,
|
||||
token.token)}"
|
||||
)
|
||||
IO.puts("URL: #{~p[/api/v1/pleroma/password_reset/#{token.token}]}")
|
||||
else
|
||||
_ ->
|
||||
shell_error("No local user #{nickname}")
|
||||
|
@ -303,13 +300,7 @@ def run(["invite" | rest]) do
|
|||
{:ok, invite} <- UserInviteToken.create_invite(options) do
|
||||
shell_info("Generated user invite token " <> String.replace(invite.invite_type, "_", " "))
|
||||
|
||||
url =
|
||||
Pleroma.Web.Router.Helpers.redirect_url(
|
||||
Pleroma.Web.Endpoint,
|
||||
:registration_page,
|
||||
invite.token
|
||||
)
|
||||
|
||||
url = url(~p[/registration/#{invite.token}])
|
||||
IO.puts(url)
|
||||
else
|
||||
error ->
|
||||
|
|
|
@ -26,7 +26,6 @@ def init(%Plug.Conn{method: "GET"} = conn, {endpoint, handler, transport}) do
|
|||
conn
|
||||
|> fetch_query_params
|
||||
|> Transport.transport_log(opts[:transport_log])
|
||||
|> Transport.force_ssl(handler, endpoint, opts)
|
||||
|> Transport.check_origin(handler, endpoint, opts)
|
||||
|
||||
case conn do
|
||||
|
|
|
@ -390,7 +390,8 @@ def restrict_deactivated_users(query) do
|
|||
active in fragment(
|
||||
"SELECT is_active from users WHERE ap_id = ? AND is_active = TRUE",
|
||||
activity.actor
|
||||
)
|
||||
),
|
||||
on: true
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ defp generate_topics(object, activity) do
|
|||
["user", "list"] ++ visibility_tags(object, activity)
|
||||
end
|
||||
|
||||
defp visibility_tags(object, activity) do
|
||||
defp visibility_tags(object, %{data: %{"type" => type}} = activity) when type != "Announce" do
|
||||
case Visibility.get_visibility(activity) do
|
||||
"public" ->
|
||||
if activity.local do
|
||||
|
@ -31,6 +31,10 @@ defp visibility_tags(object, activity) do
|
|||
end
|
||||
|> item_creation_tags(object, activity)
|
||||
|
||||
"local" ->
|
||||
["public:local"]
|
||||
|> item_creation_tags(object, activity)
|
||||
|
||||
"direct" ->
|
||||
["direct"]
|
||||
|
||||
|
@ -39,6 +43,10 @@ defp visibility_tags(object, activity) do
|
|||
end
|
||||
end
|
||||
|
||||
defp visibility_tags(_object, _activity) do
|
||||
[]
|
||||
end
|
||||
|
||||
defp item_creation_tags(tags, object, %{data: %{"type" => "Create"}} = activity) do
|
||||
tags ++
|
||||
remote_topics(activity) ++ hashtags_to_topics(object) ++ attachment_topics(object, activity)
|
||||
|
@ -63,7 +71,18 @@ defp remote_topics(_), do: []
|
|||
|
||||
defp attachment_topics(%{data: %{"attachment" => []}}, _act), do: []
|
||||
|
||||
defp attachment_topics(_object, %{local: true}), do: ["public:media", "public:local:media"]
|
||||
defp attachment_topics(_object, %{local: true} = activity) do
|
||||
case Visibility.get_visibility(activity) do
|
||||
"public" ->
|
||||
["public:media", "public:local:media"]
|
||||
|
||||
"local" ->
|
||||
["public:local:media"]
|
||||
|
||||
_ ->
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp attachment_topics(_object, %{actor: actor}) when is_binary(actor),
|
||||
do: ["public:media", "public:remote:media:" <> URI.parse(actor).host]
|
||||
|
|
|
@ -53,6 +53,7 @@ def start(_type, _args) do
|
|||
Config.DeprecationWarnings.warn()
|
||||
Pleroma.Web.Plugs.HTTPSecurityPlug.warn_if_disabled()
|
||||
Pleroma.ApplicationRequirements.verify!()
|
||||
load_all_pleroma_modules()
|
||||
load_custom_modules()
|
||||
Pleroma.Docs.JSON.compile()
|
||||
limiters_setup()
|
||||
|
@ -87,7 +88,7 @@ def start(_type, _args) do
|
|||
# Go for the default 3 unless we're in test
|
||||
max_restarts =
|
||||
if @mix_env == :test do
|
||||
100
|
||||
1000
|
||||
else
|
||||
3
|
||||
end
|
||||
|
@ -112,7 +113,7 @@ defp set_postgres_server_version do
|
|||
num
|
||||
else
|
||||
e ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Could not get the postgres version: #{inspect(e)}.\nSetting the default value of 9.6"
|
||||
)
|
||||
|
||||
|
@ -144,6 +145,24 @@ def load_custom_modules do
|
|||
end
|
||||
end
|
||||
|
||||
def load_all_pleroma_modules do
|
||||
:code.all_available()
|
||||
|> Enum.filter(fn {mod, _, _} ->
|
||||
mod
|
||||
|> to_string()
|
||||
|> String.starts_with?("Elixir.Pleroma.")
|
||||
end)
|
||||
|> Enum.map(fn {mod, _, _} ->
|
||||
mod
|
||||
|> to_string()
|
||||
|> String.to_existing_atom()
|
||||
|> Code.ensure_loaded!()
|
||||
end)
|
||||
|
||||
# Use this when 1.15 is standard
|
||||
# |> Code.ensure_all_loaded!()
|
||||
end
|
||||
|
||||
defp cachex_children do
|
||||
[
|
||||
build_cachex("used_captcha", ttl_interval: seconds_valid_interval()),
|
||||
|
@ -262,6 +281,8 @@ 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([])
|
||||
|
|
|
@ -34,7 +34,7 @@ defp handle_result({:error, message}), do: raise(VerifyError, message: message)
|
|||
defp check_welcome_message_config!(:ok) do
|
||||
if Pleroma.Config.get([:welcome, :email, :enabled], false) and
|
||||
not Pleroma.Emails.Mailer.enabled?() do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
To send welcome emails, you need to enable the mailer.
|
||||
Welcome emails will NOT be sent with the current config.
|
||||
|
||||
|
@ -53,7 +53,7 @@ defp check_welcome_message_config!(result), do: result
|
|||
def check_confirmation_accounts!(:ok) do
|
||||
if Pleroma.Config.get([:instance, :account_activation_required]) &&
|
||||
not Pleroma.Emails.Mailer.enabled?() do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
Account activation is required, but the mailer is disabled.
|
||||
Users will NOT be able to confirm their accounts with this config.
|
||||
Either disable account activation or enable the mailer.
|
||||
|
|
|
@ -28,7 +28,7 @@ def check_simple_policy_tuples do
|
|||
|> Enum.any?(fn {_, v} -> is_list(v) and Enum.any?(v, &is_binary/1) end)
|
||||
|
||||
if has_strings do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using strings in the SimplePolicy configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later:
|
||||
|
||||
|
@ -87,7 +87,7 @@ def check_quarantined_instances_tuples do
|
|||
has_strings = Config.get([:instance, :quarantined_instances], []) |> Enum.any?(&is_binary/1)
|
||||
|
||||
if has_strings do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using strings in the quarantined_instances configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later:
|
||||
|
||||
|
@ -124,7 +124,7 @@ def check_transparency_exclusions_tuples do
|
|||
has_strings = Config.get([:mrf, :transparency_exclusions]) |> Enum.any?(&is_binary/1)
|
||||
|
||||
if has_strings do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using strings in the transparency_exclusions configuration instead of tuples. They should work for now, but you are advised to change to the new configuration to prevent possible issues later:
|
||||
|
||||
|
@ -159,7 +159,7 @@ def check_transparency_exclusions_tuples do
|
|||
|
||||
def check_hellthread_threshold do
|
||||
if Config.get([:mrf_hellthread, :threshold]) do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
You are using the old configuration mechanism for the hellthread filter. Please check config.md.
|
||||
""")
|
||||
|
@ -264,7 +264,7 @@ def move_namespace_and_warn(config_map, warning_preface) do
|
|||
if warning == "" do
|
||||
:ok
|
||||
else
|
||||
Logger.warn(warning_preface <> warning)
|
||||
Logger.warning(warning_preface <> warning)
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
@ -274,7 +274,7 @@ def check_media_proxy_whitelist_config do
|
|||
whitelist = Config.get([:media_proxy, :whitelist])
|
||||
|
||||
if Enum.any?(whitelist, &(not String.starts_with?(&1, "http"))) do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using old format (only domain) for MediaProxy whitelist option. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later.
|
||||
""")
|
||||
|
|
|
@ -23,7 +23,7 @@ def warn do
|
|||
You are using old workers in Oban crontab settings, which were removed.
|
||||
Please, remove setting from crontab in your config file (prod.secret.exs): #{inspect(setting)}
|
||||
"""
|
||||
|> Logger.warn()
|
||||
|> Logger.warning()
|
||||
|
||||
List.delete(acc, setting)
|
||||
else
|
||||
|
|
|
@ -22,6 +22,20 @@ def load(config, opts) do
|
|||
|
||||
with_runtime_config =
|
||||
if File.exists?(config_path) do
|
||||
# <https://git.pleroma.social/pleroma/pleroma/-/issues/3135>
|
||||
%File.Stat{mode: mode} = File.lstat!(config_path)
|
||||
|
||||
if Bitwise.band(mode, 0o007) > 0 do
|
||||
raise "Configuration at #{config_path} has world-permissions, execute the following: chmod o= #{config_path}"
|
||||
end
|
||||
|
||||
if Bitwise.band(mode, 0o020) > 0 do
|
||||
raise "Configuration at #{config_path} has group-wise write permissions, execute the following: chmod g-w #{config_path}"
|
||||
end
|
||||
|
||||
# Note: Elixir doesn't provides a getuid(2)
|
||||
# so cannot forbid group-read only when config is owned by us
|
||||
|
||||
runtime_config = Config.Reader.read!(config_path)
|
||||
|
||||
with_defaults
|
||||
|
|
|
@ -110,7 +110,7 @@ defp merge_with_default(%{group: group, key: key, value: value} = setting) do
|
|||
|
||||
defp configure({_, :backends, _, merged}) do
|
||||
# removing current backends
|
||||
Enum.each(Application.get_env(:logger, :backends), &Logger.remove_backend/1)
|
||||
Enum.each(Application.get_env(:logger, :backends, []), &Logger.remove_backend/1)
|
||||
|
||||
Enum.each(merged, &Logger.add_backend/1)
|
||||
|
||||
|
@ -149,7 +149,7 @@ defp update({group, key, value, merged}) do
|
|||
error_msg =
|
||||
"updating env causes error, group: #{inspect(group)}, key: #{inspect(key)}, value: #{inspect(value)} error: #{inspect(error)}"
|
||||
|
||||
Logger.warn(error_msg)
|
||||
Logger.warning(error_msg)
|
||||
|
||||
nil
|
||||
end
|
||||
|
@ -183,12 +183,12 @@ defp restart(started_applications, app, _) do
|
|||
:ok = Application.start(app)
|
||||
else
|
||||
nil ->
|
||||
Logger.warn("#{app} is not started.")
|
||||
Logger.warning("#{app} is not started.")
|
||||
|
||||
error ->
|
||||
error
|
||||
|> inspect()
|
||||
|> Logger.warn()
|
||||
|> Logger.warning()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -6,10 +6,13 @@ defmodule Pleroma.Emails.AdminEmail do
|
|||
@moduledoc "Admin emails"
|
||||
|
||||
import Swoosh.Email
|
||||
|
||||
use Pleroma.Web, :mailer
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.Web.Router.Helpers
|
||||
|
||||
use Phoenix.VerifiedRoutes,
|
||||
endpoint: Pleroma.Web.Endpoint,
|
||||
router: Pleroma.Web.Router
|
||||
|
||||
defp instance_config, do: Config.get(:instance)
|
||||
defp instance_name, do: instance_config()[:name]
|
||||
|
@ -45,7 +48,7 @@ def report(to, reporter, account, statuses, comment) do
|
|||
statuses
|
||||
|> Enum.map(fn
|
||||
%{id: id} ->
|
||||
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
|
||||
status_url = url(~p[/notice/#{id}])
|
||||
"<li><a href=\"#{status_url}\">#{status_url}</li>"
|
||||
|
||||
%{"id" => id} when is_binary(id) ->
|
||||
|
|
|
@ -6,12 +6,11 @@ defmodule Pleroma.Emails.UserEmail do
|
|||
@moduledoc "User emails"
|
||||
|
||||
require Pleroma.Web.Gettext
|
||||
use Pleroma.Web, :mailer
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Gettext
|
||||
alias Pleroma.Web.Router
|
||||
|
||||
import Swoosh.Email
|
||||
import Phoenix.Swoosh, except: [render_body: 3]
|
||||
|
@ -75,7 +74,7 @@ def welcome(user, opts \\ %{}) do
|
|||
|
||||
def password_reset_email(user, token) when is_binary(token) do
|
||||
Gettext.with_locale_or_default user.language do
|
||||
password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
|
||||
password_reset_url = ~p[/api/v1/pleroma/password_reset/#{token}]
|
||||
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
|
@ -108,12 +107,7 @@ def user_invitation_email(
|
|||
to_name \\ nil
|
||||
) do
|
||||
Gettext.with_locale_or_default user.language do
|
||||
registration_url =
|
||||
Router.Helpers.redirect_url(
|
||||
Endpoint,
|
||||
:registration_page,
|
||||
user_invite_token.token
|
||||
)
|
||||
registration_url = ~p[/registration/#{user_invite_token.token}]
|
||||
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
|
@ -146,13 +140,7 @@ def user_invitation_email(
|
|||
|
||||
def account_confirmation_email(user) do
|
||||
Gettext.with_locale_or_default user.language do
|
||||
confirmation_url =
|
||||
Router.Helpers.confirm_email_url(
|
||||
Endpoint,
|
||||
:confirm_email,
|
||||
user.id,
|
||||
to_string(user.confirmation_token)
|
||||
)
|
||||
confirmation_url = ~p[/api/account/confirm_email/#{user.id}/#{user.confirmation_token}]
|
||||
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
|
@ -342,7 +330,7 @@ def unsubscribe_url(user, notifications_type) do
|
|||
|> Pleroma.JWT.generate_and_sign!()
|
||||
|> Base.encode64()
|
||||
|
||||
Router.Helpers.subscription_url(Endpoint, :unsubscribe, token)
|
||||
~p[/mailer/unsubscribe/#{token}]
|
||||
end
|
||||
|
||||
def backup_is_ready_email(backup, admin_user_id \\ nil) do
|
||||
|
|
|
@ -59,7 +59,7 @@ def load do
|
|||
Logger.info("Found emoji packs: #{Enum.join(packs, ", ")}")
|
||||
|
||||
if not Enum.empty?(files) do
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Found files in the emoji folder. These will be ignored, please move them to a subdirectory\nFound files: #{Enum.join(files, ", ")}"
|
||||
)
|
||||
end
|
||||
|
|
|
@ -287,6 +287,7 @@ def update_metadata(name, data) do
|
|||
|
||||
@spec load_pack(String.t()) :: {:ok, t()} | {:error, :file.posix()}
|
||||
def load_pack(name) do
|
||||
name = Path.basename(name)
|
||||
pack_file = Path.join([emoji_path(), name, "pack.json"])
|
||||
|
||||
with {:ok, _} <- File.stat(pack_file),
|
||||
|
@ -411,10 +412,10 @@ defp downloadable?(pack) do
|
|||
end
|
||||
|
||||
defp create_archive_and_cache(pack, hash) do
|
||||
files = ['pack.json' | Enum.map(pack.files, fn {_, file} -> to_charlist(file) end)]
|
||||
files = [~c"pack.json" | Enum.map(pack.files, fn {_, file} -> to_charlist(file) end)]
|
||||
|
||||
{:ok, {_, result}} =
|
||||
:zip.zip('#{pack.name}.zip', files, [:memory, cwd: to_charlist(pack.path)])
|
||||
:zip.zip(~c"#{pack.name}.zip", files, [:memory, cwd: to_charlist(pack.path)])
|
||||
|
||||
ttl_per_file = Pleroma.Config.get!([:emoji, :shared_pack_cache_seconds_per_file])
|
||||
overall_ttl = :timer.seconds(ttl_per_file * Enum.count(files))
|
||||
|
@ -581,7 +582,7 @@ defp unzip(archive, pack_info, remote_pack, local_pack) do
|
|||
with :ok <- File.mkdir_p!(local_pack.path) do
|
||||
files = Enum.map(remote_pack["files"], fn {_, path} -> to_charlist(path) end)
|
||||
# Fallback cannot contain a pack.json file
|
||||
files = if pack_info[:fallback], do: files, else: ['pack.json' | files]
|
||||
files = if pack_info[:fallback], do: files, else: [~c"pack.json" | files]
|
||||
|
||||
:zip.unzip(archive, cwd: to_charlist(local_pack.path), file_list: files)
|
||||
end
|
||||
|
|
|
@ -27,10 +27,10 @@ defmodule Pleroma.HTTP do
|
|||
nil | {:ok, Env.t()} | {:error, any()}
|
||||
def get(url, headers \\ [], options \\ [])
|
||||
def get(nil, _, _), do: nil
|
||||
def get(url, headers, options), do: request(:get, url, "", headers, options)
|
||||
def get(url, headers, options), do: request(:get, url, nil, headers, options)
|
||||
|
||||
@spec head(Request.url(), Request.headers(), keyword()) :: {:ok, Env.t()} | {:error, any()}
|
||||
def head(url, headers \\ [], options \\ []), do: request(:head, url, "", headers, options)
|
||||
def head(url, headers \\ [], options \\ []), do: request(:head, url, nil, headers, options)
|
||||
|
||||
@doc """
|
||||
Performs POST request.
|
||||
|
@ -62,6 +62,13 @@ def request(method, url, body, headers, options) when is_binary(url) do
|
|||
uri = URI.parse(url)
|
||||
adapter_opts = AdapterHelper.options(uri, options || [])
|
||||
|
||||
adapter_opts =
|
||||
if uri.scheme == :https do
|
||||
AdapterHelper.maybe_add_cacerts(adapter_opts, :public_key.cacerts_get())
|
||||
else
|
||||
adapter_opts
|
||||
end
|
||||
|
||||
options = put_in(options[:adapter], adapter_opts)
|
||||
params = options[:params] || []
|
||||
request = build_request(method, headers, options, url, body, params)
|
||||
|
|
|
@ -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.
|
||||
"""
|
||||
|
@ -110,7 +131,7 @@ def parse_proxy(proxy) when is_binary(proxy) do
|
|||
{:ok, type, uri.host, uri.port}
|
||||
else
|
||||
e ->
|
||||
Logger.warn("Parsing proxy failed #{inspect(proxy)}, #{inspect(e)}")
|
||||
Logger.warning("Parsing proxy failed #{inspect(proxy)}, #{inspect(e)}")
|
||||
{:error, :invalid_proxy}
|
||||
end
|
||||
end
|
||||
|
@ -120,7 +141,7 @@ def parse_proxy(proxy) when is_tuple(proxy) do
|
|||
{:ok, type, host, port}
|
||||
else
|
||||
_ ->
|
||||
Logger.warn("Parsing proxy failed #{inspect(proxy)}")
|
||||
Logger.warning("Parsing proxy failed #{inspect(proxy)}")
|
||||
{:error, :invalid_proxy}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ def vacuum(args) do
|
|||
"full" ->
|
||||
Logger.info("Running VACUUM FULL.")
|
||||
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Re-packing your entire database may take a while and will consume extra disk space during the process."
|
||||
)
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ def handle_continue(:init_state, _state) do
|
|||
data_migration.state == :manual or data_migration.name in manual_migrations ->
|
||||
message = "Data migration is in manual execution or manual fix mode."
|
||||
update_status(:manual, message)
|
||||
Logger.warn("#{__MODULE__}: #{message}")
|
||||
Logger.warning("#{__MODULE__}: #{message}")
|
||||
|
||||
data_migration.state == :complete ->
|
||||
on_complete(data_migration)
|
||||
|
@ -109,7 +109,7 @@ def handle_info(:perform, state) do
|
|||
Putting data migration to manual fix mode. Try running `#{__MODULE__}.retry_failed/0`.
|
||||
"""
|
||||
|
||||
Logger.warn("#{__MODULE__}: #{message}")
|
||||
Logger.warning("#{__MODULE__}: #{message}")
|
||||
update_status(:manual, message)
|
||||
on_complete(data_migration())
|
||||
|
||||
|
@ -125,7 +125,7 @@ def handle_info(:perform, state) do
|
|||
|
||||
defp on_complete(data_migration) do
|
||||
if data_migration.feature_lock || feature_state() == :disabled do
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"#{__MODULE__}: migration complete but feature is locked; consider enabling."
|
||||
)
|
||||
|
||||
|
|
|
@ -195,6 +195,7 @@ defp exclude_filtered(query, user) do
|
|||
from([_n, a, o] in query,
|
||||
where:
|
||||
fragment("not(?->>'content' ~* ?)", o.data, ^regex) or
|
||||
fragment("?->>'content' is null", o.data) or
|
||||
fragment("?->>'actor' = ?", o.data, ^user.ap_id)
|
||||
)
|
||||
end
|
||||
|
@ -695,7 +696,7 @@ def skip?(
|
|||
cond do
|
||||
opts[:type] == "poll" -> false
|
||||
user.ap_id == actor -> false
|
||||
!User.following?(follower, user) -> true
|
||||
!User.following?(user, follower) -> true
|
||||
true -> false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,6 +117,8 @@ def refetch_object(%Object{data: %{"id" => id}} = object) do
|
|||
# Note: will create a Create activity, which we need internally at the moment.
|
||||
def fetch_object_from_id(id, options \\ []) do
|
||||
with %URI{} = uri <- URI.parse(id),
|
||||
# let's check the URI is even vaguely valid first
|
||||
{:scheme, true} <- {:scheme, uri.scheme == "http" or uri.scheme == "https"},
|
||||
# If we have instance restrictions, apply them here to prevent fetching from unwanted instances
|
||||
{:ok, nil} <- Pleroma.Web.ActivityPub.MRF.SimplePolicy.check_reject(uri),
|
||||
{:ok, _} <- Pleroma.Web.ActivityPub.MRF.SimplePolicy.check_accept(uri),
|
||||
|
@ -135,6 +137,9 @@ def fetch_object_from_id(id, options \\ []) do
|
|||
{:allowed_depth, false} ->
|
||||
{:error, "Max thread distance exceeded."}
|
||||
|
||||
{:scheme, false} ->
|
||||
{:error, "URI Scheme Invalid"}
|
||||
|
||||
{:containment, _} ->
|
||||
{:error, "Object containment failed."}
|
||||
|
||||
|
|
|
@ -129,7 +129,10 @@ def make_update_object_data(original_data, new_data, date) do
|
|||
else
|
||||
%{updated_object: updated_data} =
|
||||
updated_data
|
||||
|> maybe_update_history(original_data, updated: updated, use_history_in_new_object?: false)
|
||||
|> maybe_update_history(original_data,
|
||||
updated: updated,
|
||||
use_history_in_new_object?: false
|
||||
)
|
||||
|
||||
updated_data
|
||||
|> Map.put("updated", date)
|
||||
|
|
|
@ -76,6 +76,6 @@ def sign(%User{keys: keys} = user, headers) do
|
|||
def signed_date, do: signed_date(NaiveDateTime.utc_now())
|
||||
|
||||
def signed_date(%NaiveDateTime{} = date) do
|
||||
Timex.format!(date, "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT")
|
||||
Timex.lformat!(date, "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT", "en")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -63,6 +63,9 @@ defmodule Pleroma.Upload do
|
|||
blurhash: String.t(),
|
||||
path: String.t()
|
||||
}
|
||||
|
||||
@always_enabled_filters [Pleroma.Upload.Filter.AnonymizeFilename]
|
||||
|
||||
defstruct [:id, :name, :tempfile, :content_type, :width, :height, :blurhash, :path]
|
||||
|
||||
@spec store(source, options :: [option()]) :: {:ok, Map.t()} | {:error, any()}
|
||||
|
@ -132,7 +135,11 @@ defp get_opts(opts) do
|
|||
activity_type: Keyword.get(opts, :activity_type, activity_type),
|
||||
size_limit: Keyword.get(opts, :size_limit, size_limit),
|
||||
uploader: Keyword.get(opts, :uploader, Pleroma.Config.get([__MODULE__, :uploader])),
|
||||
filters: Keyword.get(opts, :filters, Pleroma.Config.get([__MODULE__, :filters])),
|
||||
filters:
|
||||
Enum.uniq(
|
||||
Keyword.get(opts, :filters, Pleroma.Config.get([__MODULE__, :filters])) ++
|
||||
@always_enabled_filters
|
||||
),
|
||||
description: Keyword.get(opts, :description),
|
||||
base_url: base_url()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,7 +28,7 @@ def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _} = upload)
|
|||
{:ok, :filtered, upload}
|
||||
rescue
|
||||
e in ErlangError ->
|
||||
Logger.warn("#{__MODULE__}: #{inspect(e)}")
|
||||
Logger.warning("#{__MODULE__}: #{inspect(e)}")
|
||||
{:ok, :noop}
|
||||
end
|
||||
end
|
||||
|
@ -45,7 +45,7 @@ def filter(%Pleroma.Upload{tempfile: file, content_type: "video" <> _} = upload)
|
|||
{:ok, :filtered, upload}
|
||||
rescue
|
||||
e in ErlangError ->
|
||||
Logger.warn("#{__MODULE__}: #{inspect(e)}")
|
||||
Logger.warning("#{__MODULE__}: #{inspect(e)}")
|
||||
{:ok, :noop}
|
||||
end
|
||||
end
|
||||
|
|
20
lib/pleroma/upload/filter/only_media.ex
Normal file
20
lib/pleroma/upload/filter/only_media.ex
Normal 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
|
|
@ -44,6 +44,8 @@ defmodule Pleroma.User do
|
|||
alias Pleroma.Web.RelMe
|
||||
alias Pleroma.Workers.BackgroundWorker
|
||||
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
require Logger
|
||||
|
||||
@type t :: %__MODULE__{}
|
||||
|
@ -876,7 +878,7 @@ def post_register_action(%User{is_approved: true, is_confirmed: true} = user) do
|
|||
end
|
||||
end
|
||||
|
||||
defp send_user_approval_email(user) do
|
||||
defp send_user_approval_email(%User{email: email} = user) when is_binary(email) do
|
||||
user
|
||||
|> Pleroma.Emails.UserEmail.approval_pending_email()
|
||||
|> Pleroma.Emails.Mailer.deliver_async()
|
||||
|
@ -884,6 +886,10 @@ defp send_user_approval_email(user) do
|
|||
{:ok, :enqueued}
|
||||
end
|
||||
|
||||
defp send_user_approval_email(_user) do
|
||||
{:ok, :skipped}
|
||||
end
|
||||
|
||||
defp send_admin_approval_emails(user) do
|
||||
all_superusers()
|
||||
|> Enum.filter(fn user -> not is_nil(user.email) end)
|
||||
|
@ -1489,7 +1495,7 @@ def unmute(muter_id, mutee_id) do
|
|||
unmute(muter, mutee)
|
||||
else
|
||||
{who, result} = error ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"User.unmute/2 failed. #{who}: #{result}, muter_id: #{muter_id}, mutee_id: #{mutee_id}"
|
||||
)
|
||||
|
||||
|
@ -2006,7 +2012,6 @@ defp create_service_actor(uri, nickname) do
|
|||
%User{
|
||||
invisible: true,
|
||||
local: true,
|
||||
actor_type: "Application",
|
||||
ap_id: uri,
|
||||
nickname: nickname,
|
||||
follower_address: uri <> "/followers"
|
||||
|
@ -2444,12 +2449,7 @@ defp validate_rel_me_field(changeset, fields, raw_fields, %User{
|
|||
end
|
||||
|
||||
if is_url(raw_value) do
|
||||
frontend_url =
|
||||
Pleroma.Web.Router.Helpers.redirect_url(
|
||||
Pleroma.Web.Endpoint,
|
||||
:redirector_with_meta,
|
||||
nickname
|
||||
)
|
||||
frontend_url = url(~p[/#{nickname}])
|
||||
|
||||
possible_urls = [ap_id, frontend_url]
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ def process(%__MODULE__{} = backup) do
|
|||
end
|
||||
end
|
||||
|
||||
@files ['actor.json', 'outbox.json', 'likes.json', 'bookmarks.json']
|
||||
@files [~c"actor.json", ~c"outbox.json", ~c"likes.json", ~c"bookmarks.json"]
|
||||
def export(%__MODULE__{} = backup) do
|
||||
backup = Repo.preload(backup, :user)
|
||||
name = String.trim_trailing(backup.file_name, ".zip")
|
||||
|
|
|
@ -27,6 +27,7 @@ defmodule Pleroma.Web do
|
|||
alias Pleroma.Web.Plugs.ExpectPublicOrAuthenticatedCheckPlug
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Web.Plugs.PlugHelper
|
||||
require Pleroma.Constants
|
||||
|
||||
def controller do
|
||||
quote do
|
||||
|
@ -37,7 +38,7 @@ def controller do
|
|||
import Pleroma.Web.Gettext
|
||||
import Pleroma.Web.TranslationHelpers
|
||||
|
||||
alias Pleroma.Web.Router.Helpers, as: Routes
|
||||
unquote(verified_routes())
|
||||
|
||||
plug(:set_put_layout)
|
||||
|
||||
|
@ -184,7 +185,10 @@ def view do
|
|||
|
||||
# Import convenience functions from controllers
|
||||
import Phoenix.Controller,
|
||||
only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1]
|
||||
only: [view_module: 1, view_template: 1]
|
||||
|
||||
import Phoenix.Flash
|
||||
alias Phoenix.Flash
|
||||
|
||||
# Include shared imports and aliases for views
|
||||
unquote(view_helpers())
|
||||
|
@ -218,7 +222,7 @@ def component do
|
|||
|
||||
def router do
|
||||
quote do
|
||||
use Phoenix.Router
|
||||
use Phoenix.Router, helpers: false
|
||||
|
||||
import Plug.Conn
|
||||
import Phoenix.Controller
|
||||
|
@ -246,7 +250,24 @@ defp view_helpers do
|
|||
|
||||
import Pleroma.Web.ErrorHelpers
|
||||
import Pleroma.Web.Gettext
|
||||
alias Pleroma.Web.Router.Helpers, as: Routes
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
|
||||
def static_paths, do: Pleroma.Constants.static_only_files()
|
||||
|
||||
def verified_routes do
|
||||
quote do
|
||||
use Phoenix.VerifiedRoutes,
|
||||
endpoint: Pleroma.Web.Endpoint,
|
||||
router: Pleroma.Web.Router,
|
||||
statics: Pleroma.Web.static_paths()
|
||||
end
|
||||
end
|
||||
|
||||
def mailer do
|
||||
quote do
|
||||
unquote(verified_routes())
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1792,6 +1792,11 @@ def pin_data_from_featured_collection(
|
|||
end)
|
||||
end
|
||||
|
||||
def pin_data_from_featured_collection(obj) do
|
||||
Logger.error("Could not parse featured collection #{inspect(obj)}")
|
||||
%{}
|
||||
end
|
||||
|
||||
def fetch_and_prepare_featured_from_ap_id(nil) do
|
||||
{:ok, %{}}
|
||||
end
|
||||
|
|
|
@ -454,7 +454,7 @@ def update_outbox(
|
|||
|> json(message)
|
||||
|
||||
e ->
|
||||
Logger.warn(fn -> "AP C2S: #{inspect(e)}" end)
|
||||
Logger.warning(fn -> "AP C2S: #{inspect(e)}" end)
|
||||
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|
|
|
@ -18,6 +18,8 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
def accept_or_reject(actor, activity, type) do
|
||||
|
@ -402,6 +404,6 @@ def unpin(%User{} = user, object) do
|
|||
end
|
||||
|
||||
defp pinned_url(nickname) when is_binary(nickname) do
|
||||
Pleroma.Web.Router.Helpers.activity_pub_url(Pleroma.Web.Endpoint, :pinned, nickname)
|
||||
url(~p[/users/#{nickname}/collections/featured])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -70,6 +70,8 @@ def filter_one(policy, %{"type" => type} = message)
|
|||
end
|
||||
|
||||
def filter_one(policy, message) do
|
||||
Code.ensure_loaded!(policy)
|
||||
|
||||
should_plug_history? =
|
||||
if function_exported?(policy, :history_awareness, 0) do
|
||||
policy.history_awareness()
|
||||
|
@ -239,7 +241,7 @@ def config_descriptions(policies) do
|
|||
if Enum.all?(@required_description_keys, &Map.has_key?(description, &1)) do
|
||||
[description | acc]
|
||||
else
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"#{policy} config description doesn't have one or all required keys #{inspect(@required_description_keys)}"
|
||||
)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ defp steal_emoji({shortcode, url}, emoji_dir_path) do
|
|||
shortcode
|
||||
|
||||
e ->
|
||||
Logger.warn("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
|
||||
Logger.warning("MRF.StealEmojiPolicy: Failed to write to #{file_path}: #{inspect(e)}")
|
||||
nil
|
||||
end
|
||||
else
|
||||
|
@ -53,7 +53,7 @@ defp steal_emoji({shortcode, url}, emoji_dir_path) do
|
|||
end
|
||||
else
|
||||
e ->
|
||||
Logger.warn("MRF.StealEmojiPolicy: Failed to fetch #{url}: #{inspect(e)}")
|
||||
Logger.warning("MRF.StealEmojiPolicy: Failed to fetch #{url}: #{inspect(e)}")
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
|||
import Ecto.Changeset
|
||||
|
||||
require Logger
|
||||
require Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
@primary_key false
|
||||
@derive Jason.Encoder
|
||||
|
|
|
@ -22,7 +22,10 @@ def cast_and_filter_recipients(message, field, follower_collection, field_fallba
|
|||
end
|
||||
|
||||
def fix_object_defaults(data) do
|
||||
context = Utils.maybe_create_context(data["context"] || data["conversation"])
|
||||
context =
|
||||
Utils.maybe_create_context(
|
||||
data["context"] || data["conversation"] || data["inReplyTo"] || data["id"]
|
||||
)
|
||||
|
||||
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"])
|
||||
|
||||
|
|
|
@ -115,13 +115,18 @@ defp allowed_instances do
|
|||
def should_federate?(url) do
|
||||
%{host: host} = URI.parse(url)
|
||||
|
||||
with allowed <- allowed_instances(),
|
||||
with {nil, false} <- {nil, is_nil(host)},
|
||||
allowed <- allowed_instances(),
|
||||
false <- Enum.empty?(allowed) do
|
||||
allowed
|
||||
|> Pleroma.Web.ActivityPub.MRF.instance_list_from_tuples()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomains_regex()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomain_match?(host)
|
||||
else
|
||||
# oi!
|
||||
{nil, true} ->
|
||||
false
|
||||
|
||||
_ ->
|
||||
quarantined_instances =
|
||||
blocked_instances()
|
||||
|
|
|
@ -136,7 +136,7 @@ def fix_in_reply_to(%{"inReplyTo" => in_reply_to} = object, options)
|
|||
|> Map.drop(["conversation", "inReplyToAtomUri"])
|
||||
else
|
||||
e ->
|
||||
Logger.warn("Couldn't fetch reply@#{inspect(in_reply_to_id)}, error: #{inspect(e)}")
|
||||
Logger.warning("Couldn't fetch reply@#{inspect(in_reply_to_id)}, error: #{inspect(e)}")
|
||||
object
|
||||
end
|
||||
else
|
||||
|
@ -159,7 +159,7 @@ def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
|
|||
|> Map.put("quoteUri", quoted_object.data["id"])
|
||||
else
|
||||
e ->
|
||||
Logger.warn("Couldn't fetch quote@#{inspect(quote_url)}, error: #{inspect(e)}")
|
||||
Logger.warning("Couldn't fetch quote@#{inspect(quote_url)}, error: #{inspect(e)}")
|
||||
object
|
||||
end
|
||||
else
|
||||
|
@ -920,8 +920,13 @@ def add_attributed_to(object) do
|
|||
|
||||
def prepare_attachments(object) do
|
||||
attachments =
|
||||
object
|
||||
|> Map.get("attachment", [])
|
||||
case Map.get(object, "attachment", []) do
|
||||
[_ | _] = list -> list
|
||||
_ -> []
|
||||
end
|
||||
|
||||
attachments =
|
||||
attachments
|
||||
|> Enum.map(fn data ->
|
||||
[%{"mediaType" => media_type, "href" => href} = url | _] = data["url"]
|
||||
|
||||
|
|
|
@ -16,10 +16,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Router.Helpers
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
require Logger
|
||||
require Pleroma.Constants
|
||||
|
||||
|
@ -124,19 +125,15 @@ def make_date do
|
|||
end
|
||||
|
||||
def generate_activity_id do
|
||||
generate_id("activities")
|
||||
url(~p[/activities/#{UUID.generate()}])
|
||||
end
|
||||
|
||||
def generate_context_id do
|
||||
generate_id("contexts")
|
||||
url(~p[/contexts/#{UUID.generate()}])
|
||||
end
|
||||
|
||||
def generate_object_id do
|
||||
Helpers.o_status_url(Endpoint, :object, UUID.generate())
|
||||
end
|
||||
|
||||
def generate_id(type) do
|
||||
"#{Endpoint.url()}/#{type}/#{UUID.generate()}"
|
||||
url(~p[/objects/#{UUID.generate()}])
|
||||
end
|
||||
|
||||
def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do
|
||||
|
@ -154,7 +151,7 @@ def get_notified_from_object(object) do
|
|||
Notification.get_notified_from_activity(%Activity{data: object}, false)
|
||||
end
|
||||
|
||||
def maybe_create_context(context), do: context || generate_id("contexts")
|
||||
def maybe_create_context(context), do: context || generate_context_id()
|
||||
|
||||
@doc """
|
||||
Enqueues an activity for federation if it's local
|
||||
|
|
|
@ -12,22 +12,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
|||
alias Pleroma.Web.ActivityPub.ObjectView
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Router.Helpers
|
||||
|
||||
require Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do
|
||||
%{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)}
|
||||
%{"sharedInbox" => url(~p"/inbox")}
|
||||
end
|
||||
|
||||
def render("endpoints.json", %{user: %User{local: true} = _user}) do
|
||||
%{
|
||||
"oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize),
|
||||
"oauthRegistrationEndpoint" => Helpers.app_url(Endpoint, :create),
|
||||
"oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange),
|
||||
"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox),
|
||||
"uploadMedia" => Helpers.activity_pub_url(Endpoint, :upload_media)
|
||||
"oauthAuthorizationEndpoint" => url(~p"/oauth/authorize"),
|
||||
"oauthRegistrationEndpoint" => url(~p"/api/v1/apps"),
|
||||
"oauthTokenEndpoint" => url(~p"/oauth/token"),
|
||||
"sharedInbox" => url(~p"/inbox"),
|
||||
"uploadMedia" => url(~p"/api/ap/upload_media")
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -17,9 +17,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.AdminAPI.ModerationLogView
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Web.Router
|
||||
|
||||
@users_page_size 50
|
||||
|
||||
|
@ -256,7 +254,7 @@ def get_password_reset(conn, %{"nickname" => nickname}) do
|
|||
conn
|
||||
|> json(%{
|
||||
token: token.token,
|
||||
link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
|
||||
link: url(~p[/api/v1/pleroma/password_reset/#{token.token}])
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ def blocks_operation do
|
|||
operationId: "AccountController.blocks",
|
||||
description: "View your blocks. See also accounts/:id/{block,unblock}",
|
||||
security: [%{"oAuth" => ["read:blocks"]}],
|
||||
parameters: pagination_params(),
|
||||
parameters: [with_relationships_param() | pagination_params()],
|
||||
responses: %{
|
||||
200 => Operation.response("Accounts", "application/json", array_of_accounts())
|
||||
}
|
||||
|
@ -451,6 +451,20 @@ def endorsements_operation do
|
|||
}
|
||||
end
|
||||
|
||||
def preferences_operation do
|
||||
%Operation{
|
||||
tags: ["Account Preferences"],
|
||||
description: "Preferences defined by the user in their account settings.",
|
||||
summary: "Preferred common behaviors to be shared across clients.",
|
||||
operationId: "AccountController.preferences",
|
||||
security: [%{"oAuth" => ["read:accounts"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Preferences", "application/json", Account),
|
||||
401 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def identity_proofs_operation do
|
||||
%Operation{
|
||||
tags: ["Retrieve account information"],
|
||||
|
|
|
@ -143,7 +143,7 @@ def admin_account do
|
|||
}
|
||||
},
|
||||
tags: %Schema{type: :string},
|
||||
is_confirmed: %Schema{type: :string}
|
||||
is_confirmed: %Schema{type: :boolean}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -232,7 +232,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
source: %Schema{
|
||||
nullable: true,
|
||||
oneOf: [
|
||||
%Schema{type: :string, example: 'plaintext content'},
|
||||
%Schema{type: :string, example: ~c"plaintext content"},
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
|
|
|
@ -110,7 +110,7 @@ defp register_user(connection, base, uid, name) do
|
|||
}
|
||||
|
||||
params =
|
||||
case List.keyfind(attributes, 'mail', 0) do
|
||||
case List.keyfind(attributes, ~c"mail", 0) do
|
||||
{_, [mail]} -> Map.put_new(params, :email, :erlang.list_to_binary(mail))
|
||||
_ -> params
|
||||
end
|
||||
|
|
|
@ -88,7 +88,7 @@ def reject_follow_request(follower, followed) do
|
|||
|
||||
def delete(activity_id, user) do
|
||||
with {_, %Activity{data: %{"object" => _, "type" => "Create"}} = activity} <-
|
||||
{:find_activity, Activity.get_by_id(activity_id)},
|
||||
{:find_activity, Activity.get_by_id(activity_id, filter: [])},
|
||||
{_, %Object{} = object, _} <-
|
||||
{:find_object, Object.normalize(activity, fetch: false), activity},
|
||||
true <- User.superuser?(user) || user.ap_id == object.data["actor"],
|
||||
|
@ -467,7 +467,7 @@ def remove_mute(user_id, activity_id) do
|
|||
remove_mute(user, activity)
|
||||
else
|
||||
{what, result} = error ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{activity_id}"
|
||||
)
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ def make_poll_data(%{poll: %{options: options, expires_in: expires_in}} = data)
|
|||
when is_list(options) do
|
||||
limits = Config.get([:instance, :poll_limits])
|
||||
|
||||
options = options |> Enum.uniq()
|
||||
|
||||
with :ok <- validate_poll_expiration(expires_in, limits),
|
||||
:ok <- validate_poll_options_amount(options, limits),
|
||||
:ok <- validate_poll_options_length(options, limits) do
|
||||
|
@ -179,10 +181,15 @@ def make_poll_data(_data) do
|
|||
end
|
||||
|
||||
defp validate_poll_options_amount(options, %{max_options: max_options}) do
|
||||
if Enum.count(options) > max_options do
|
||||
{:error, "Poll can't contain more than #{max_options} options"}
|
||||
else
|
||||
:ok
|
||||
cond do
|
||||
Enum.count(options) < 2 ->
|
||||
{:error, "Poll must contain at least 2 options"}
|
||||
|
||||
Enum.count(options) > max_options ->
|
||||
{:error, "Poll can't contain more than #{max_options} options"}
|
||||
|
||||
true ->
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -317,13 +324,13 @@ def date_to_asctime(date) when is_binary(date) do
|
|||
format_asctime(date)
|
||||
else
|
||||
_e ->
|
||||
Logger.warn("Date #{date} in wrong format, must be ISO 8601")
|
||||
Logger.warning("Date #{date} in wrong format, must be ISO 8601")
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def date_to_asctime(date) do
|
||||
Logger.warn("Date #{date} in wrong format, must be ISO 8601")
|
||||
Logger.warning("Date #{date} in wrong format, must be ISO 8601")
|
||||
""
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ defmodule Pleroma.Web.Endpoint do
|
|||
Plug.Static,
|
||||
at: "/",
|
||||
from: :pleroma,
|
||||
only: Pleroma.Constants.static_only_files(),
|
||||
only: Pleroma.Web.static_paths(),
|
||||
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
|
||||
gzip: true,
|
||||
cache_control_for_etags: @static_cache_control,
|
||||
|
|
|
@ -30,7 +30,7 @@ def feed_redirect(%{assigns: %{format: format}} = conn, _params)
|
|||
|
||||
def feed_redirect(conn, %{"nickname" => nickname}) do
|
||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
|
||||
redirect(conn, external: "#{Routes.user_feed_url(conn, :feed, user.nickname)}.atom")
|
||||
redirect(conn, external: "#{url(~p"/users/#{user.nickname}/feed")}.atom")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ def index(conn, _params) do
|
|||
|
||||
index =
|
||||
if flavour == "fedibird-fe" do
|
||||
"fedibird.index.html"
|
||||
"fedibird.html"
|
||||
else
|
||||
"glitchsoc.index.html"
|
||||
"glitchsoc.html"
|
||||
end
|
||||
|
||||
conn
|
||||
|
|
|
@ -51,7 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["read:accounts"]}
|
||||
when action in [:verify_credentials, :endorsements, :identity_proofs]
|
||||
when action in [:verify_credentials, :endorsements, :identity_proofs, :preferences]
|
||||
)
|
||||
|
||||
plug(
|
||||
|
@ -497,7 +497,7 @@ def mutes(%{assigns: %{user: user}} = conn, params) do
|
|||
users =
|
||||
user
|
||||
|> User.muted_users_relation(_restrict_deactivated = true)
|
||||
|> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true))
|
||||
|> Pleroma.Pagination.fetch_paginated(params)
|
||||
|
||||
conn
|
||||
|> add_link_headers(users)
|
||||
|
@ -514,11 +514,16 @@ def blocks(%{assigns: %{user: user}} = conn, params) do
|
|||
users =
|
||||
user
|
||||
|> User.blocked_users_relation(_restrict_deactivated = true)
|
||||
|> Pleroma.Pagination.fetch_paginated(Map.put(params, :skip_order, true))
|
||||
|> Pleroma.Pagination.fetch_paginated(params)
|
||||
|
||||
conn
|
||||
|> add_link_headers(users)
|
||||
|> render("index.json", users: users, for: user, as: :user)
|
||||
|> render("index.json",
|
||||
users: users,
|
||||
for: user,
|
||||
as: :user,
|
||||
embed_relationships: embed_relationships?(params)
|
||||
)
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/accounts/lookup"
|
||||
|
@ -539,4 +544,9 @@ def endorsements(conn, params), do: MastodonAPIController.empty_array(conn, para
|
|||
|
||||
@doc "GET /api/v1/identity_proofs"
|
||||
def identity_proofs(conn, params), do: MastodonAPIController.empty_array(conn, params)
|
||||
|
||||
@doc "GET /api/v1/preferences"
|
||||
def preferences(%{assigns: %{user: user}} = conn, _params) do
|
||||
render(conn, "preferences.json", user: user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,12 +54,7 @@ def login(conn, params) do
|
|||
defp redirect_to_oauth_form(conn, _params) do
|
||||
with {:ok, app} <- local_mastofe_app() do
|
||||
path =
|
||||
Routes.o_auth_path(conn, :authorize,
|
||||
response_type: "code",
|
||||
client_id: app.client_id,
|
||||
redirect_uri: ".",
|
||||
scope: Enum.join(app.scopes, " ")
|
||||
)
|
||||
~p[/oauth/authorize?#{[response_type: "code", client_id: app.client_id, redirect_uri: ".", scope: Enum.join(app.scopes, " ")]}]
|
||||
|
||||
redirect(conn, to: path)
|
||||
end
|
||||
|
@ -91,7 +86,7 @@ def password_reset(conn, params) do
|
|||
defp local_mastodon_post_login_path(conn) do
|
||||
case get_session(conn, :return_to) do
|
||||
nil ->
|
||||
Routes.masto_fe_path(conn, :index, ["getting-started"])
|
||||
~p"/web/getting-started"
|
||||
|
||||
return_to ->
|
||||
delete_session(conn, :return_to)
|
||||
|
|
|
@ -190,6 +190,17 @@ def render("instance.json", %{instance: %Pleroma.Instances.Instance{} = instance
|
|||
|
||||
def render("instance.json", _), do: nil
|
||||
|
||||
def render("preferences.json", %{user: user} = _opts) do
|
||||
# TODO: Do we expose more settings that make sense to plug in here?
|
||||
%{
|
||||
"posting:default:visibility": user.default_scope,
|
||||
"posting:default:sensitive": false,
|
||||
"posting:default:language": nil,
|
||||
"reading:expand:media": "default",
|
||||
"reading:expand:spoilers": false
|
||||
}
|
||||
end
|
||||
|
||||
defp do_render("show.json", %{user: user} = opts) do
|
||||
user = User.sanitize_html(user, User.html_filter_policy(opts[:for]))
|
||||
display_name = user.name || user.nickname
|
||||
|
|
|
@ -322,7 +322,7 @@ def render("show.json", %{activity: %{id: id, data: %{"object" => _object}} = ac
|
|||
|
||||
url =
|
||||
if user.local do
|
||||
Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity)
|
||||
url(~p[/notice/#{activity}])
|
||||
else
|
||||
object.data["url"] || object.data["external_url"] || object.data["id"]
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.TagView do
|
||||
use Pleroma.Web, :view
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Router.Helpers
|
||||
|
||||
def render("index.json", %{tags: tags, for_user: user}) do
|
||||
render_many(tags, __MODULE__, "show.json", %{for_user: user})
|
||||
|
@ -17,7 +16,7 @@ def render("show.json", %{tag: tag, for_user: user}) do
|
|||
|
||||
%{
|
||||
name: tag.name,
|
||||
url: Helpers.tag_feed_url(Pleroma.Web.Endpoint, :feed, tag.name),
|
||||
url: url(~p[/tags/#{tag.name}]),
|
||||
history: [],
|
||||
following: following
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -76,13 +76,23 @@ def whitelisted?(url) do
|
|||
|
||||
mediaproxy_whitelist_domains =
|
||||
[:media_proxy, :whitelist]
|
||||
|> Config.get()
|
||||
|> Config.get([])
|
||||
|> Kernel.++(["#{Upload.base_url()}"])
|
||||
|> Enum.map(&maybe_get_domain_from_url/1)
|
||||
|
||||
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
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Metadata.Providers.Feed do
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Metadata.Providers.Provider
|
||||
alias Pleroma.Web.Router.Helpers
|
||||
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
@behaviour Provider
|
||||
|
||||
|
@ -16,7 +16,7 @@ def build_tags(%{user: user}) do
|
|||
[
|
||||
rel: "alternate",
|
||||
type: "application/atom+xml",
|
||||
href: Helpers.user_feed_path(Endpoint, :feed, user.nickname) <> ".atom"
|
||||
href: ~p[/users/#{user.nickname}/feed.atom]
|
||||
], []}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -8,12 +8,20 @@ defmodule Pleroma.Web.Metadata.Providers.RelMe do
|
|||
|
||||
@impl Provider
|
||||
def build_tags(%{user: user}) do
|
||||
bio_tree = Floki.parse_fragment!(user.bio)
|
||||
profile_tree =
|
||||
user.bio
|
||||
|> append_fields_tag(user.fields)
|
||||
|> Floki.parse_fragment!()
|
||||
|
||||
(Floki.attribute(bio_tree, "link[rel~=me]", "href") ++
|
||||
Floki.attribute(bio_tree, "a[rel~=me]", "href"))
|
||||
(Floki.attribute(profile_tree, "link[rel~=me]", "href") ++
|
||||
Floki.attribute(profile_tree, "a[rel~=me]", "href"))
|
||||
|> Enum.map(fn link ->
|
||||
{:link, [rel: "me", href: link], []}
|
||||
end)
|
||||
end
|
||||
|
||||
defp append_fields_tag(bio, fields) do
|
||||
fields
|
||||
|> Enum.reduce(bio, fn %{"value" => v}, res -> res <> v end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
|
|||
alias Pleroma.Web.Metadata.Providers.Provider
|
||||
alias Pleroma.Web.Metadata.Utils
|
||||
|
||||
use Pleroma.Web, :verified_routes
|
||||
|
||||
@behaviour Provider
|
||||
@media_types ["image", "audio", "video"]
|
||||
|
||||
|
@ -20,12 +22,12 @@ def build_tags(%{activity_id: id, object: object, user: user}) do
|
|||
|
||||
[
|
||||
title_tag(user),
|
||||
{:meta, [property: "twitter:description", content: scrubbed_content], []}
|
||||
{:meta, [name: "twitter:description", content: scrubbed_content], []}
|
||||
] ++
|
||||
if attachments == [] or Metadata.activity_nsfw?(object) do
|
||||
[
|
||||
image_tag(user),
|
||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||
]
|
||||
else
|
||||
attachments
|
||||
|
@ -37,20 +39,19 @@ def build_tags(%{user: user}) do
|
|||
with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
|
||||
[
|
||||
title_tag(user),
|
||||
{:meta, [property: "twitter:description", content: truncated_bio], []},
|
||||
{:meta, [name: "twitter:description", content: truncated_bio], []},
|
||||
image_tag(user),
|
||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||
{:meta, [name: "twitter:card", content: "summary"], []}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
defp title_tag(user) do
|
||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}
|
||||
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}
|
||||
end
|
||||
|
||||
def image_tag(user) do
|
||||
{:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))],
|
||||
[]}
|
||||
{:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []}
|
||||
end
|
||||
|
||||
defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
||||
|
@ -60,10 +61,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
|||
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
|
||||
"audio" ->
|
||||
[
|
||||
{:meta, [property: "twitter:card", content: "player"], []},
|
||||
{:meta, [property: "twitter:player:width", content: "480"], []},
|
||||
{:meta, [property: "twitter:player:height", content: "80"], []},
|
||||
{:meta, [property: "twitter:player", content: player_url(id)], []}
|
||||
{:meta, [name: "twitter:card", content: "player"], []},
|
||||
{:meta, [name: "twitter:player:width", content: "480"], []},
|
||||
{:meta, [name: "twitter:player:height", content: "80"], []},
|
||||
{:meta, [name: "twitter:player", content: player_url(id)], []}
|
||||
| acc
|
||||
]
|
||||
|
||||
|
@ -74,10 +75,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
|||
# workaround.
|
||||
"image" ->
|
||||
[
|
||||
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
|
||||
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
|
||||
{:meta,
|
||||
[
|
||||
property: "twitter:player",
|
||||
name: "twitter:player",
|
||||
content: MediaProxy.url(url["href"])
|
||||
], []}
|
||||
| acc
|
||||
|
@ -90,14 +91,14 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
|||
width = url["width"] || 480
|
||||
|
||||
[
|
||||
{:meta, [property: "twitter:card", content: "player"], []},
|
||||
{:meta, [property: "twitter:player", content: player_url(id)], []},
|
||||
{:meta, [property: "twitter:player:width", content: "#{width}"], []},
|
||||
{:meta, [property: "twitter:player:height", content: "#{height}"], []},
|
||||
{:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])],
|
||||
{:meta, [name: "twitter:card", content: "player"], []},
|
||||
{:meta, [name: "twitter:player", content: player_url(id)], []},
|
||||
{:meta, [name: "twitter:player:width", content: "#{width}"], []},
|
||||
{:meta, [name: "twitter:player:height", content: "#{height}"], []},
|
||||
{:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])],
|
||||
[]},
|
||||
{:meta,
|
||||
[property: "twitter:player:stream:content_type", content: url["mediaType"]], []}
|
||||
{:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]],
|
||||
[]}
|
||||
| acc
|
||||
]
|
||||
|
||||
|
@ -113,7 +114,7 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
|
|||
defp build_attachments(_id, _object), do: []
|
||||
|
||||
defp player_url(id) do
|
||||
Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice_player, id)
|
||||
url(~p[/notice/#{id}/embed_player])
|
||||
end
|
||||
|
||||
# Videos have problems without dimensions, but we used to not provide WxH for images.
|
||||
|
@ -123,8 +124,8 @@ defp maybe_add_dimensions(metadata, url) do
|
|||
!is_nil(url["height"]) && !is_nil(url["width"]) ->
|
||||
metadata ++
|
||||
[
|
||||
{:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []},
|
||||
{:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []}
|
||||
{:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []},
|
||||
{:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []}
|
||||
]
|
||||
|
||||
true ->
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue