diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 91e568a32..cd0561852 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,6 +8,13 @@ variables: &global_variables
DB_PORT: 5432
MIX_ENV: test
+workflow:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+ - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
+ when: never
+ - if: $CI_COMMIT_BRANCH
+
cache: &global_cache_policy
key:
files:
@@ -17,12 +24,14 @@ cache: &global_cache_policy
- _build
stages:
+ - check-changelog
- build
- test
- benchmark
- deploy
- release
- docker
+ - docker-combine
before_script:
- echo $MIX_ENV
@@ -32,20 +41,39 @@ before_script:
after_script:
- rm -rf _build/*/lib/pleroma
+check-changelog:
+ stage: check-changelog
+ image: alpine
+ rules:
+ - if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'weblate-extract'
+ when: never
+ - if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'weblate'
+ when: never
+ - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
+ before_script: ''
+ after_script: ''
+ cache: {}
+ script:
+ - apk add git
+ - sh ./tools/check-changelog
+
+.build_changes_policy:
+ rules:
+ - changes:
+ - ".gitlab-ci.yml"
+ - "**/*.ex"
+ - "**/*.exs"
+ - "mix.lock"
+
.using-ci-base:
tags:
- amd64
build:
extends:
+ - .build_changes_policy
- .using-ci-base
stage: build
- only:
- changes: &build_changes_policy
- - ".gitlab-ci.yml"
- - "**/*.ex"
- - "**/*.exs"
- - "mix.lock"
script:
- mix compile --force
@@ -53,11 +81,11 @@ spec-build:
extends:
- .using-ci-base
stage: test
- only:
- changes:
- - ".gitlab-ci.yml"
- - "lib/pleroma/web/api_spec/**/*.ex"
- - "lib/pleroma/web/api_spec.ex"
+ rules:
+ - changes:
+ - ".gitlab-ci.yml"
+ - "lib/pleroma/web/api_spec/**/*.ex"
+ - "lib/pleroma/web/api_spec.ex"
artifacts:
paths:
- spec.json
@@ -82,10 +110,9 @@ benchmark:
unit-testing:
extends:
+ - .build_changes_policy
- .using-ci-base
stage: test
- only:
- changes: *build_changes_policy
cache: &testing_cache_policy
<<: *global_cache_policy
policy: pull
@@ -107,12 +134,11 @@ unit-testing:
unit-testing-erratic:
extends:
+ - .build_changes_policy
- .using-ci-base
stage: test
retry: 2
allow_failure: true
- only:
- changes: *build_changes_policy
cache: &testing_cache_policy
<<: *global_cache_policy
policy: pull
@@ -144,10 +170,9 @@ unit-testing-erratic:
unit-testing-rum:
extends:
+ - .build_changes_policy
- .using-ci-base
stage: test
- only:
- changes: *build_changes_policy
cache: *testing_cache_policy
services:
- name: minibikini/postgres-with-rum:12
@@ -163,10 +188,9 @@ unit-testing-rum:
- mix test --preload-modules
lint:
+ extends: .build_changes_policy
image: ¤t_elixir elixir:1.12-alpine
stage: test
- only:
- changes: *build_changes_policy
cache: *testing_cache_policy
before_script: ¤t_bfr_script
- apk update
@@ -179,19 +203,17 @@ lint:
analysis:
extends:
+ - .build_changes_policy
- .using-ci-base
stage: test
- only:
- changes: *build_changes_policy
cache: *testing_cache_policy
script:
- mix credo --strict --only=warnings,todo,fixme,consistency,readability
cycles:
+ extends: .build_changes_policy
image: *current_elixir
stage: test
- only:
- changes: *build_changes_policy
cache: {}
before_script: *current_bfr_script
script:
@@ -208,7 +230,7 @@ docs-deploy:
before_script:
- apk add curl
script:
- - curl -X POST -F"token=$DOCS_PIPELINE_TRIGGER" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" https://git.pleroma.social/api/v4/projects/673/trigger/pipeline
+ - curl --fail-with-body -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" https://git.pleroma.social/api/v4/projects/673/trigger/pipeline
review_app:
image: alpine:3.9
stage: deploy
@@ -249,7 +271,7 @@ spec-deploy:
before_script:
- apk add curl
script:
- - curl -X POST -F"token=$API_DOCS_PIPELINE_TRIGGER" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" -F"variables[JOB_REF]=$CI_JOB_ID" https://git.pleroma.social/api/v4/projects/1130/trigger/pipeline
+ - curl --fail-with-body -X POST -F"token=$CI_JOB_TOKEN" -F'ref=master' -F"variables[BRANCH]=$CI_COMMIT_REF_NAME" -F"variables[JOB_REF]=$CI_JOB_ID" https://git.pleroma.social/api/v4/projects/1130/trigger/pipeline
stop_review_app:
@@ -372,104 +394,167 @@ arm64-musl:
before_script: *before-release-musl
script: *release
-docker:
+.kaniko:
stage: docker
- image: docker:latest
+ image:
+ name: gcr.io/kaniko-project/executor:debug
+ entrypoint: [""]
cache: {}
dependencies: []
- variables: &docker-variables
- DOCKER_DRIVER: overlay2
- DOCKER_HOST: unix:///var/run/docker.sock
- IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- IMAGE_TAG_SLUG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
- IMAGE_TAG_LATEST: $CI_REGISTRY_IMAGE:latest
- IMAGE_TAG_LATEST_STABLE: $CI_REGISTRY_IMAGE:latest-stable
- DOCKER_BUILDX_URL: https://github.com/docker/buildx/releases/download/v0.6.3/buildx-v0.6.3.linux-amd64
- DOCKER_BUILDX_HASH: 980e6b9655f971991fbbb5fd6cd19f1672386195
- before_script: &before-docker
- - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- - docker pull $IMAGE_TAG_SLUG || true
+ before_script: &before-kaniko
- export CI_JOB_TIMESTAMP=$(date --utc -Iseconds)
- export CI_VCS_REF=$CI_COMMIT_SHORT_SHA
- allow_failure: true
- script:
- - mkdir -p /root/.docker/cli-plugins
- - wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- - echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- - chmod +x ~/.docker/cli-plugins/docker-buildx
- - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- - docker buildx create --name mbuilder --driver docker-container --use
- - docker buildx inspect --bootstrap
- - docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
- tags:
- - dind
+ - export IMAGE_TAG=$CI_REGISTRY_IMAGE/$BUILD_ARCH_IMG_SUFFIX:$CI_COMMIT_SHORT_SHA
+ - export IMAGE_TAG_SLUG=$CI_REGISTRY_IMAGE/$BUILD_ARCH_IMG_SUFFIX:$CI_COMMIT_REF_SLUG
+ - export IMAGE_TAG_LATEST=$CI_REGISTRY_IMAGE/$BUILD_ARCH_IMG_SUFFIX:latest
+ - export IMAGE_TAG_LATEST_STABLE=$CI_REGISTRY_IMAGE/$BUILD_ARCH_IMG_SUFFIX:latest-stable
+ - mkdir -p /kaniko/.docker
+ - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+
+.kaniko-latest:
+ extends: .kaniko
only:
- develop@pleroma/pleroma
-
-docker-stable:
- stage: docker
- image: docker:latest
- cache: {}
- dependencies: []
- variables: *docker-variables
- before_script: *before-docker
- allow_failure: true
script:
- - mkdir -p /root/.docker/cli-plugins
- - wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- - echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- - chmod +x ~/.docker/cli-plugins/docker-buildx
- - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- - docker buildx create --name mbuilder --driver docker-container --use
- - docker buildx inspect --bootstrap
- - docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
- tags:
- - dind
+ - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --custom-platform=$BUILD_ARCH --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP --build-arg ELIXIR_IMG=$ELIXIR_IMG --destination $IMAGE_TAG --destination $IMAGE_TAG_SLUG --destination $IMAGE_TAG_LATEST
+
+.kaniko-stable:
+ extends: .kaniko
only:
- stable@pleroma/pleroma
+ script:
+ - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --custom-platform=$BUILD_ARCH --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP --build-arg ELIXIR_IMG=$ELIXIR_IMG --destination $IMAGE_TAG --destination $IMAGE_TAG_SLUG --destination $IMAGE_TAG_LATEST_STABLE
-docker-release:
- stage: docker
- image: docker:latest
- cache: {}
- dependencies: []
- variables: *docker-variables
- before_script: *before-docker
- allow_failure: true
- script:
- script:
- - mkdir -p /root/.docker/cli-plugins
- - wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- - echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- - chmod +x ~/.docker/cli-plugins/docker-buildx
- - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- - docker buildx create --name mbuilder --driver docker-container --use
- - docker buildx inspect --bootstrap
- - docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
- tags:
- - dind
+.kaniko-release:
+ extends: .kaniko
only:
- /^release/.*$/@pleroma/pleroma
+ script:
+ - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --custom-platform=$BUILD_ARCH --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP --build-arg ELIXIR_IMG=$ELIXIR_IMG --destination $IMAGE_TAG --destination $IMAGE_TAG_SLUG
-docker-adhoc:
- stage: docker
- image: docker:latest
- cache: {}
- dependencies: []
- variables: *docker-variables
- before_script: *before-docker
- allow_failure: true
- script:
- script:
- - mkdir -p /root/.docker/cli-plugins
- - wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
- - echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
- - chmod +x ~/.docker/cli-plugins/docker-buildx
- - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- - docker buildx create --name mbuilder --driver docker-container --use
- - docker buildx inspect --bootstrap
- - docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
- tags:
- - dind
+.kaniko-adhoc:
+ extends: .kaniko
only:
- /^build-docker/.*$/@pleroma/pleroma
+ script:
+ - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --custom-platform=$BUILD_ARCH --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP --build-arg ELIXIR_IMG=$ELIXIR_IMG --destination $IMAGE_TAG --destination $IMAGE_TAG_SLUG
+
+.kaniko:linux/amd64:
+ variables:
+ BUILD_ARCH: linux/amd64
+ BUILD_ARCH_IMG_SUFFIX: linux-amd64
+ ELIXIR_IMG: hexpm/elixir
+ tags:
+ - amd64
+
+.kaniko:linux/arm64:
+ variables:
+ BUILD_ARCH: linux/arm64/v8
+ BUILD_ARCH_IMG_SUFFIX: linux-arm64-v8
+ ELIXIR_IMG: hexpm/elixir
+ tags:
+ - arm
+
+.kaniko:linux/arm:
+ variables:
+ BUILD_ARCH: linux/arm/v7
+ BUILD_ARCH_IMG_SUFFIX: linux-arm-v7
+ ELIXIR_IMG: git.pleroma.social:5050/pleroma/ci-image/elixir-linux-arm-v7
+ tags:
+ - arm32-specified
+
+kaniko-latest:linux/amd64:
+ extends:
+ - .kaniko-latest
+ - .kaniko:linux/amd64
+
+kaniko-latest:linux/arm64:
+ extends:
+ - .kaniko-latest
+ - .kaniko:linux/arm64
+
+kaniko-latest:linux/arm:
+ extends:
+ - .kaniko-latest
+ - .kaniko:linux/arm
+
+kaniko-stable:linux/amd64:
+ extends:
+ - .kaniko-stable
+ - .kaniko:linux/amd64
+
+kaniko-stable:linux/arm64:
+ extends:
+ - .kaniko-stable
+ - .kaniko:linux/arm64
+
+kaniko-stable:linux/arm:
+ extends:
+ - .kaniko-stable
+ - .kaniko:linux/arm
+
+kaniko-release:linux/amd64:
+ extends:
+ - .kaniko-release
+ - .kaniko:linux/amd64
+
+kaniko-release:linux/arm64:
+ extends:
+ - .kaniko-release
+ - .kaniko:linux/arm64
+
+kaniko-release:linux/arm:
+ extends:
+ - .kaniko-release
+ - .kaniko:linux/arm
+
+.docker-combine:
+ stage: docker-combine
+ image: docker:cli
+ cache: {}
+ before_script:
+ - 'BUILD_ARCHES="linux-amd64 linux-arm64-v8 linux-arm-v7"'
+ - export IMAGE_TAG=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
+ - export IMAGE_TAG_SLUG=$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ - export IMAGE_TAG_LATEST=$CI_REGISTRY_IMAGE:latest
+ - export IMAGE_TAG_LATEST_STABLE=$CI_REGISTRY_IMAGE:latest-stable
+ - 'IMAGES=; for arch in $BUILD_ARCHES; do IMAGES="$IMAGES $CI_REGISTRY_IMAGE/$arch:$CI_COMMIT_SHORT_SHA"; done'
+ - 'IMAGES_SLUG=; for arch in $BUILD_ARCHES; do IMAGES_SLUG="$IMAGES_SLUG $CI_REGISTRY_IMAGE/$arch:$CI_COMMIT_REF_SLUG"; done'
+ - 'IMAGES_LATEST=; for arch in $BUILD_ARCHES; do IMAGES_LATEST="$IMAGES_LATEST $CI_REGISTRY_IMAGE/$arch:latest"; done'
+ - 'IMAGES_LATEST_STABLE=; for arch in $BUILD_ARCHES; do IMAGES_LATEST_STABLE="$IMAGES_LATEST_STABLE $CI_REGISTRY_IMAGE/$arch:latest"; done'
+ - mkdir -p ~/.docker
+ - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
+
+docker-combine:latest:
+ extends: .docker-combine
+ only:
+ - develop@pleroma/pleroma
+ script:
+ - 'docker manifest create $IMAGE_TAG $IMAGES'
+ - 'docker manifest push $IMAGE_TAG'
+ - 'docker manifest create $IMAGE_TAG_SLUG $IMAGES_SLUG'
+ - 'docker manifest push $IMAGE_TAG_SLUG'
+ - 'docker manifest create $IMAGE_TAG_LATEST $IMAGES_LATEST'
+ - 'docker manifest push $IMAGE_TAG_LATEST'
+
+docker-combine:stable:
+ extends: .docker-combine
+ only:
+ - stable@pleroma/pleroma
+ script:
+ - 'docker manifest create $IMAGE_TAG $IMAGES'
+ - 'docker manifest push $IMAGE_TAG'
+ - 'docker manifest create $IMAGE_TAG_SLUG $IMAGES_SLUG'
+ - 'docker manifest push $IMAGE_TAG_SLUG'
+ - 'docker manifest create $IMAGE_TAG_LATEST_STABLE $IMAGES_LATEST_STABLE'
+ - 'docker manifest push $IMAGE_TAG_LATEST_STABLE'
+
+docker-combine:release:
+ extends: .docker-combine
+ only:
+ - /^release/.*$/@pleroma/pleroma
+ script:
+ - 'docker manifest create $IMAGE_TAG $IMAGES'
+ - 'docker manifest push $IMAGE_TAG'
+ - 'docker manifest create $IMAGE_TAG_SLUG $IMAGES_SLUG'
+ - 'docker manifest push $IMAGE_TAG_SLUG'
diff --git a/.gitlab/merge_request_templates/Default.md b/.gitlab/merge_request_templates/Default.md
new file mode 100644
index 000000000..fdf219f99
--- /dev/null
+++ b/.gitlab/merge_request_templates/Default.md
@@ -0,0 +1,10 @@
+### Checklist
+- [ ] Adding a changelog: In the `changelog.d` directory, create a file named `.
` can be anything, but we recommend using a more or less unique identifier to avoid collisions, such as the branch name.
+
+ `
+
diff --git a/docs/installation/otp_vs_from_source_source.include b/docs/installation/otp_vs_from_source_source.include
index 63482b69d..9f7134229 100644
--- a/docs/installation/otp_vs_from_source_source.include
+++ b/docs/installation/otp_vs_from_source_source.include
@@ -1,3 +1,3 @@
{! backend/installation/otp_vs_from_source.include !}
-This guide covers a from-source installation. To install using OTP releases, please check out [the OTP guide](./otp_en.md).
+This guide covers a manual from-source installation. To install using OTP releases, please check for the presence of a distro package, failing that you can use [Pleroma-provided OTP binaries](./otp_en.md).
diff --git a/installation/init.d/pleroma b/installation/init.d/pleroma
index 384536f7e..cb6635a0b 100755
--- a/installation/init.d/pleroma
+++ b/installation/init.d/pleroma
@@ -8,6 +8,7 @@ pidfile="/var/run/pleroma.pid"
directory=/opt/pleroma
healthcheck_delay=60
healthcheck_timer=30
+no_new_privs="yes"
: ${pleroma_port:-4000}
diff --git a/installation/pleroma-mediaproxy.nginx b/installation/pleroma-mediaproxy.nginx
new file mode 100644
index 000000000..6f2edf212
--- /dev/null
+++ b/installation/pleroma-mediaproxy.nginx
@@ -0,0 +1,97 @@
+# This file is for those who want to serve uploaded media and media proxy over
+# another domain. This is STRONGLY RECOMMENDED.
+# This is meant to be used ALONG WITH `pleroma.nginx`.
+
+# If this is a new instance, replace the `location ~ ^/(media|proxy)` section in
+# `pleroma.nginx` with the following to completely disable access to media from the main domain:
+# location ~ ^/(media|proxy) {
+# return 404;
+# }
+#
+# If you are configuring an existing instance to use another domain
+# for media, you will want to keep redirecting all existing local media to the new domain
+# so already-uploaded media will not break.
+# Replace the `location ~ ^/(media|proxy)` section in `pleroma.nginx` with the following:
+#
+# location /media {
+# return 301 https://some.other.domain$request_uri;
+# }
+#
+# location /proxy {
+# return 404;
+# }
+
+server {
+ server_name some.other.domain;
+
+ listen 80;
+ listen [::]:80;
+
+ # Uncomment this if you need to use the 'webroot' method with certbot. Make sure
+ # that the directory exists and that it is accessible by the webserver. If you followed
+ # the guide, you already ran 'mkdir -p /var/lib/letsencrypt' to create the folder.
+ # You may need to load this file with the ssl server block commented out, run certbot
+ # to get the certificate, and then uncomment it.
+ #
+ # location ~ /\.well-known/acme-challenge {
+ # root /var/lib/letsencrypt/;
+ # }
+ location / {
+ return 301 https://$server_name$request_uri;
+ }
+}
+
+server {
+ server_name some.other.domain;
+
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ ssl_session_timeout 1d;
+ ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
+ ssl_session_tickets off;
+
+ ssl_trusted_certificate /etc/letsencrypt/live/some.other.domain/chain.pem;
+ ssl_certificate /etc/letsencrypt/live/some.other.domain/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/some.other.domain/privkey.pem;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
+ ssl_prefer_server_ciphers off;
+ # In case of an old server with an OpenSSL version of 1.0.2 or below,
+ # leave only prime256v1 or comment out the following line.
+ ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
+ ssl_stapling on;
+ ssl_stapling_verify on;
+
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_buffers 16 8k;
+ gzip_http_version 1.1;
+ gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;
+
+ # the nginx default is 1m, not enough for large media uploads
+ client_max_body_size 16m;
+ ignore_invalid_headers off;
+
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+ location / { return 404; }
+
+ location ~ ^/(media|proxy) {
+ proxy_cache pleroma_media_cache;
+ slice 1m;
+ proxy_cache_key $host$uri$is_args$args$slice_range;
+ proxy_set_header Range $slice_range;
+ proxy_cache_valid 200 206 301 304 1h;
+ proxy_cache_lock on;
+ proxy_ignore_client_abort on;
+ proxy_buffering on;
+ chunked_transfer_encoding on;
+ proxy_pass http://phoenix;
+ }
+}
diff --git a/lib/mix/tasks/pleroma/openapi_spec.ex b/lib/mix/tasks/pleroma/openapi_spec.ex
index 884f931f8..1ea468476 100644
--- a/lib/mix/tasks/pleroma/openapi_spec.ex
+++ b/lib/mix/tasks/pleroma/openapi_spec.ex
@@ -6,7 +6,70 @@ defmodule Mix.Tasks.Pleroma.OpenapiSpec do
def run([path]) do
# Load Pleroma application to get version info
Application.load(:pleroma)
- spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
- File.write(path, spec)
+
+ spec_json = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
+ # to get rid of the structs
+ spec_regened = spec_json |> Jason.decode!()
+
+ check_specs!(spec_regened)
+
+ File.write(path, spec_json)
+ end
+
+ defp check_specs!(spec) do
+ with :ok <- check_specs(spec) do
+ :ok
+ else
+ {_, errors} ->
+ IO.puts(IO.ANSI.format([:red, :bright, "Spec check failed, errors:"]))
+ Enum.map(errors, &IO.puts/1)
+
+ raise "Spec check failed"
+ end
+ end
+
+ def check_specs(spec) do
+ errors =
+ spec["paths"]
+ |> Enum.flat_map(fn {path, %{} = endpoints} ->
+ Enum.map(
+ endpoints,
+ fn {method, endpoint} ->
+ with :ok <- check_endpoint(spec, endpoint) do
+ :ok
+ else
+ error ->
+ "#{endpoint["operationId"]} (#{method} #{path}): #{error}"
+ end
+ end
+ )
+ |> Enum.reject(fn res -> res == :ok end)
+ end)
+
+ if errors == [] do
+ :ok
+ else
+ {:error, errors}
+ end
+ end
+
+ defp check_endpoint(spec, endpoint) do
+ valid_tags = available_tags(spec)
+
+ with {_, [_ | _] = tags} <- {:tags, endpoint["tags"]},
+ {_, []} <- {:unavailable, Enum.reject(tags, &(&1 in valid_tags))} do
+ :ok
+ else
+ {:tags, _} ->
+ "No tags specified"
+
+ {:unavailable, tags} ->
+ "Tags #{inspect(tags)} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
+ end
+ end
+
+ defp available_tags(spec) do
+ spec["x-tagGroups"]
+ |> Enum.flat_map(fn %{"tags" => tags} -> tags end)
end
end
diff --git a/lib/pleroma/bbs/authenticator.ex b/lib/pleroma/bbs/authenticator.ex
deleted file mode 100644
index 0f7543ff5..000000000
--- a/lib/pleroma/bbs/authenticator.ex
+++ /dev/null
@@ -1,20 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors
")
- |> Enum.map(&HTML.strip_tags/1)
- |> Enum.map(&HtmlEntities.decode/1)
- |> Enum.map(&IO.puts/1)
- end
-
- def puts_notification(activity, user) do
- notification =
- Pleroma.Web.MastodonAPI.NotificationView.render("show.json", %{
- notification: activity,
- for: user
- })
-
- IO.puts(
- "== (#{notification.type}) #{notification.status.id} by #{notification.account.display_name} (#{notification.account.acct})"
- )
-
- notification.status.content
- |> String.split("
")
- |> Enum.map(&HTML.strip_tags/1)
- |> Enum.map(&HtmlEntities.decode/1)
- |> (fn x ->
- case x do
- [content] ->
- "> " <> content
-
- [head | _tail] ->
- # "> " <> hd <> "..."
- head
- |> String.slice(1, 80)
- |> (fn x -> "> " <> x <> "..." end).()
- end
- end).()
- |> IO.puts()
-
- IO.puts("")
- end
-
- def handle_command(state, "help") do
- IO.puts("Available commands:")
- IO.puts("help - This help")
- IO.puts("home - Show the home timeline")
- IO.puts("p
#{quote_line}"
+ end
+
+ defp has_inline_quote?(content, quote_url) do
+ cond do
+ # Does the quote URL exist in the content?
+ content =~ quote_url -> true
+ # Does the content already have a .quote-inline span?
+ content =~ "" -> true
+ # No inline quote found
+ true -> false
+ end
+ end
+
+ defp filter_object(%{"quoteUrl" => quote_url} = object) do
+ content = object["content"] || ""
+
+ if has_inline_quote?(content, quote_url) do
+ object
+ else
+ template = Pleroma.Config.get([:mrf_inline_quote, :template])
+
+ content =
+ if String.ends_with?(content, "
<%= scope %>
<%= :"Elixir.Gettext".dgettext(Gettext, "oauth_scopes", scope) %>
<% end %>
<% else %>
diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex
index 6a55242b0..f97570b0a 100644
--- a/lib/pleroma/web/views/streamer_view.ex
+++ b/lib/pleroma/web/views/streamer_view.ex
@@ -11,8 +11,11 @@ defmodule Pleroma.Web.StreamerView do
alias Pleroma.User
alias Pleroma.Web.MastodonAPI.NotificationView
- def render("update.json", %Activity{} = activity, %User{} = user) do
+ require Pleroma.Constants
+
+ def render("update.json", %Activity{} = activity, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -25,8 +28,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("status_update.json", %Activity{} = activity, %User{} = user) do
+ def render("status_update.json", %Activity{} = activity, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "status.update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -39,8 +43,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("notification.json", %Notification{} = notify, %User{} = user) do
+ def render("notification.json", %Notification{} = notify, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "notification",
payload:
NotificationView.render(
@@ -52,8 +57,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("update.json", %Activity{} = activity) do
+ def render("update.json", %Activity{} = activity, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -65,8 +71,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("status_update.json", %Activity{} = activity) do
+ def render("status_update.json", %Activity{} = activity, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "status.update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -78,7 +85,7 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("chat_update.json", %{chat_message_reference: cm_ref}) do
+ def render("chat_update.json", %{chat_message_reference: cm_ref}, topic) do
# Explicitly giving the cmr for the object here, so we don't accidentally
# send a later 'last_message' that was inserted between inserting this and
# streaming it out
@@ -93,6 +100,7 @@ defmodule Pleroma.Web.StreamerView do
)
%{
+ stream: render("stream.json", %{topic: topic}),
event: "pleroma:chat_update",
payload:
representation
@@ -101,8 +109,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("follow_relationships_update.json", item) do
+ def render("follow_relationships_update.json", item, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "pleroma:follow_relationships_update",
payload:
%{
@@ -123,8 +132,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("conversation.json", %Participation{} = participation) do
+ def render("conversation.json", %Participation{} = participation, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "conversation",
payload:
Pleroma.Web.MastodonAPI.ConversationView.render("participation.json", %{
@@ -135,4 +145,39 @@ defmodule Pleroma.Web.StreamerView do
}
|> Jason.encode!()
end
+
+ def render("pleroma_respond.json", %{type: type, result: result} = params) do
+ %{
+ event: "pleroma:respond",
+ payload:
+ %{
+ result: result,
+ type: type
+ }
+ |> Map.merge(maybe_error(params))
+ |> Jason.encode!()
+ }
+ |> Jason.encode!()
+ end
+
+ def render("stream.json", %{topic: "user:pleroma_chat:" <> _}), do: ["user:pleroma_chat"]
+ def render("stream.json", %{topic: "user:notification:" <> _}), do: ["user:notification"]
+ def render("stream.json", %{topic: "user:" <> _}), do: ["user"]
+ def render("stream.json", %{topic: "direct:" <> _}), do: ["direct"]
+ def render("stream.json", %{topic: "list:" <> id}), do: ["list", id]
+ def render("stream.json", %{topic: "hashtag:" <> tag}), do: ["hashtag", tag]
+
+ def render("stream.json", %{topic: "public:remote:media:" <> instance}),
+ do: ["public:remote:media", instance]
+
+ def render("stream.json", %{topic: "public:remote:" <> instance}),
+ do: ["public:remote", instance]
+
+ def render("stream.json", %{topic: stream}) when stream in Pleroma.Constants.public_streams(),
+ do: [stream]
+
+ defp maybe_error(%{error: :bad_topic}), do: %{error: "bad_topic"}
+ defp maybe_error(%{error: :unauthorized}), do: %{error: "unauthorized"}
+ defp maybe_error(%{error: :already_authenticated}), do: %{error: "already_authenticated"}
+ defp maybe_error(_), do: %{}
end
diff --git a/lib/pleroma/web/xml.ex b/lib/pleroma/web/xml.ex
index 380a80ab8..64329e4ba 100644
--- a/lib/pleroma/web/xml.ex
+++ b/lib/pleroma/web/xml.ex
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.XML do
|> :binary.bin_to_list()
|> :xmerl_scan.string(
quiet: true,
- fetch_fun: fn _, _ -> raise "Resolving external entities not supported" end
+ allow_entities: false
)
{:ok, doc}
diff --git a/lib/pleroma/workers/backup_worker.ex b/lib/pleroma/workers/backup_worker.ex
index 12ee70f00..a485ddb4b 100644
--- a/lib/pleroma/workers/backup_worker.ex
+++ b/lib/pleroma/workers/backup_worker.ex
@@ -51,7 +51,7 @@ defmodule Pleroma.Workers.BackupWorker do
end
@impl Oban.Worker
- def timeout(_job), do: :timer.seconds(900)
+ def timeout(_job), do: :infinity
defp has_email?(user) do
not is_nil(user.email) and user.email != ""
diff --git a/lib/pleroma/workers/transmogrifier_worker.ex b/lib/pleroma/workers/transmogrifier_worker.ex
deleted file mode 100644
index 1f3f5385e..000000000
--- a/lib/pleroma/workers/transmogrifier_worker.ex
+++ /dev/null
@@ -1,18 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors You requested a full backup of your Pleroma account. It's ready for download:
\n\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:384 +#, elixir-autogen, elixir-format msgctxt "account archive email subject" msgid "Your account archive is ready" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:188 +#, elixir-autogen, elixir-format msgctxt "approval pending email body" msgid "Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.
\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:202 +#, elixir-autogen, elixir-format msgctxt "approval pending email subject" msgid "Your account is awaiting approval" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:158 +#, elixir-autogen, elixir-format msgctxt "confirmation email body" msgid "Email confirmation is required to activate the account.
\nPlease click the following link to activate your account.
\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:174 +#, elixir-autogen, elixir-format msgctxt "confirmation email subject" msgid "%{instance_name} account confirmation" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:310 +#, elixir-autogen, elixir-format msgctxt "digest email subject" msgid "Your digest from %{instance_name}" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:81 +#, elixir-autogen, elixir-format msgctxt "password reset email body" msgid "Someone has requested password change for your account at %{instance_name}.
\nIf it was you, visit the following link to proceed: reset password.
\nIf it was someone else, nothing to worry about: your data is secure and your password has not been changed.
\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:98 +#, elixir-autogen, elixir-format msgctxt "password reset email subject" msgid "Password reset" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:215 +#, elixir-autogen, elixir-format msgctxt "successful registration email body" msgid "Your account at %{instance_name} has been registered successfully.
\nNo further action is required to activate your account.
\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:231 +#, elixir-autogen, elixir-format msgctxt "successful registration email subject" msgid "Account registered on %{instance_name}" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:119 +#, elixir-autogen, elixir-format msgctxt "user invitation email body" msgid "%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.
\nClick the following link to register: accept invitation.
\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:136 +#, elixir-autogen, elixir-format msgctxt "user invitation email subject" msgid "Invitation to %{instance_name}" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:53 +#, elixir-autogen, elixir-format msgctxt "welcome email html body" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:41 +#, elixir-autogen, elixir-format msgctxt "welcome email subject" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:65 +#, elixir-autogen, elixir-format msgctxt "welcome email text body" msgid "Welcome to %{instance_name}!" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/emails/user_email.ex:368 +#, elixir-autogen, elixir-format msgctxt "account archive email body - admin requested" msgid "Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:
\n\n" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/twitter_api/controllers/util_controller.ex:123 +#, elixir-autogen, elixir-format msgctxt "remote follow error message - unknown error" msgid "Something went wrong." msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/twitter_api/controllers/util_controller.ex:67 +#, elixir-autogen, elixir-format msgctxt "remote follow error message - user not found" msgid "Could not find user" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:8 +#, elixir-autogen, elixir-format msgctxt "status interact authorization button" msgid "Interact" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:2 +#, elixir-autogen, elixir-format msgctxt "status interact error" msgid "Error: %{error}" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/twitter_api/controllers/util_controller.ex:95 +#, elixir-autogen, elixir-format msgctxt "status interact error message - status not found" msgid "Could not find status" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/twitter_api/controllers/util_controller.ex:144 +#, elixir-autogen, elixir-format msgctxt "status interact error message - unknown error" msgid "Something went wrong." msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +#, elixir-autogen, elixir-format msgctxt "status interact header" msgid "Interacting with %{nickname}'s %{status_link}" msgstr "" -#, elixir-autogen, elixir-format #: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +#, elixir-autogen, elixir-format msgctxt "status interact header - status link text" msgid "status" msgstr "" diff --git a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po index cbd6feb60..809b13d47 100644 --- a/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po +++ b/priv/gettext/zh_Hans/LC_MESSAGES/static_pages.po @@ -24,10 +24,6 @@ msgstr "" ## ## Use "mix gettext.extract --merge" or "mix gettext.merge" ## to merge POT files into PO files. -#~ msgid "" -#~ msgstr "" -#~ "Language: zh_Hans\n" -#~ "Plural-Forms: nplurals=1\n" #: lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex:9 #, elixir-format diff --git a/priv/repo/migrations/20221216052127_add_state_to_backups.exs b/priv/repo/migrations/20221216052127_add_state_to_backups.exs new file mode 100644 index 000000000..73b30fc35 --- /dev/null +++ b/priv/repo/migrations/20221216052127_add_state_to_backups.exs @@ -0,0 +1,21 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors