Merge remote-tracking branch 'upstream/develop' into neckbeard
This commit is contained in:
commit
9b0a8d0745
|
@ -1,12 +1,13 @@
|
|||
image: git.pleroma.social:5050/pleroma/pleroma/ci-base
|
||||
|
||||
variables: &global_variables
|
||||
# Only used for the release
|
||||
ELIXIR_VER: 1.12.3
|
||||
POSTGRES_DB: pleroma_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_PORT: "5432"
|
||||
MIX_ENV: test
|
||||
|
||||
workflow:
|
||||
|
@ -153,22 +154,6 @@ unit-testing-erratic:
|
|||
- mix ecto.migrate
|
||||
- mix test --only=erratic
|
||||
|
||||
# Removed to fix CI issue. In this early state it wasn't adding much value anyway.
|
||||
# TODO Fix and reinstate federated testing
|
||||
# federated-testing:
|
||||
# stage: test
|
||||
# cache: *testing_cache_policy
|
||||
# services:
|
||||
# - name: minibikini/postgres-with-rum:12
|
||||
# alias: postgres
|
||||
# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
# script:
|
||||
# - mix deps.get
|
||||
# - mix ecto.create
|
||||
# - mix ecto.migrate
|
||||
# - epmd -daemon
|
||||
# - mix test --trace --only federated
|
||||
|
||||
unit-testing-rum:
|
||||
extends:
|
||||
- .build_changes_policy
|
||||
|
@ -176,7 +161,7 @@ unit-testing-rum:
|
|||
stage: test
|
||||
cache: *testing_cache_policy
|
||||
services:
|
||||
- name: minibikini/postgres-with-rum:12
|
||||
- name: git.pleroma.social:5050/pleroma/pleroma/postgres-with-rum-13
|
||||
alias: postgres
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
variables:
|
||||
|
@ -190,7 +175,7 @@ unit-testing-rum:
|
|||
|
||||
lint:
|
||||
extends: .build_changes_policy
|
||||
image: ¤t_elixir elixir:1.12-alpine
|
||||
image: ¤t_elixir elixir:1.13-alpine
|
||||
stage: test
|
||||
cache: *testing_cache_policy
|
||||
before_script: ¤t_bfr_script
|
||||
|
@ -319,8 +304,9 @@ amd64:
|
|||
- deps
|
||||
variables: &release-variables
|
||||
MIX_ENV: prod
|
||||
VIX_COMPILATION_MODE: PLATFORM_PROVIDED_LIBVIPS
|
||||
before_script: &before-release
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev libvips-dev erlang-dev
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
|
@ -341,7 +327,7 @@ amd64-musl:
|
|||
cache: *release-cache
|
||||
variables: *release-variables
|
||||
before_script: &before-release-musl
|
||||
- apk add git build-base cmake file-dev openssl
|
||||
- apk add git build-base cmake file-dev openssl vips-dev
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -4,6 +4,17 @@ 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/).
|
||||
|
||||
## 2.6.1
|
||||
### Changed
|
||||
- - Document maximum supported version of Erlang & Elixir
|
||||
|
||||
### Added
|
||||
- [docs] add frontends management documentation
|
||||
|
||||
### Fixed
|
||||
- TwitterAPI: Return proper error when healthcheck is disabled
|
||||
- Fix eblurhash and elixir-captcha not using system cflags
|
||||
|
||||
## 2.6.0
|
||||
### Security
|
||||
- Preload: Make generated JSON html-safe. It already was html safe because it only consists of config data that is base64 encoded, but this will keep it safe it that ever changes.
|
||||
|
|
|
@ -8,8 +8,9 @@ FROM ${ELIXIR_IMG}:${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER} as bu
|
|||
COPY . .
|
||||
|
||||
ENV MIX_ENV=prod
|
||||
ENV VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS
|
||||
|
||||
RUN apk add git gcc g++ musl-dev make cmake file-dev rust &&\
|
||||
RUN apk add git gcc g++ musl-dev make cmake file-dev vips-dev &&\
|
||||
echo "import Config" > config/prod.secret.exs &&\
|
||||
mix local.hex --force &&\
|
||||
mix local.rebar --force &&\
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Remove checking ImageMagick's commands for Pleroma.Upload.Filter.AnalyzeMetadata
|
|
@ -0,0 +1 @@
|
|||
ap userview: add outbox field.
|
|
@ -1 +0,0 @@
|
|||
Fix XML External Entity (XXE) loading vulnerability allowing to fetch arbitary files from the server's filesystem
|
|
@ -0,0 +1 @@
|
|||
Support /authorize-interaction route used by Mastodon
|
|
@ -0,0 +1 @@
|
|||
Invalid activities delivered to the inbox will be rejected with a 400 Bad Request
|
|
@ -1 +0,0 @@
|
|||
CommonAPI: Prevent users from accessing media of other users by creating a status with reused attachment ID
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
Emoji pack loader sanitizes pack names
|
|
@ -0,0 +1 @@
|
|||
Implement /api/v2/instance route
|
|
@ -0,0 +1 @@
|
|||
- Change AccountView `last_status_at` from a datetime to a date (as done in Mastodon 3.1.0)
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
Add media proxy to opengraph rich media cards
|
|
@ -0,0 +1 @@
|
|||
Optimistic Inbox reduces the processing overhead of incoming activities without instantly verifiable signatures.
|
|
@ -1 +0,0 @@
|
|||
- Reduced permissions of config files and directories, distros requiring greater permissions like group-read need to pre-create the directories
|
|
@ -0,0 +1 @@
|
|||
- Prioritize mentioned recipients (i.e., those that are not just followers) when federating.
|
|
@ -0,0 +1 @@
|
|||
Reduce the reachability timestamp update to a single upsert query
|
|
@ -0,0 +1 @@
|
|||
- scrubbers/default: Add more formatting elements from HTML4 / GoToSocial (acronym, bdo, big, cite, dfn, ins, kbd, q, samp, s, tt, var, wbr)
|
|
@ -0,0 +1 @@
|
|||
Fix web push notifications not successfully delivering
|
|
@ -0,0 +1,3 @@
|
|||
FROM postgres:13-bullseye
|
||||
|
||||
RUN apt-get update && apt-get install -y postgresql-13-rum/bullseye-pgdg
|
|
@ -0,0 +1 @@
|
|||
docker buildx build --platform linux/amd64,linux/arm64 -t git.pleroma.social:5050/pleroma/pleroma/postgres-with-rum-13:latest --push .
|
|
@ -14,7 +14,7 @@ config :pleroma, Pleroma.Captcha,
|
|||
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: []
|
||||
|
||||
|
|
|
@ -1187,7 +1187,7 @@ config :pleroma, :config_description, [
|
|||
type: [:atom, :tuple, :module],
|
||||
description:
|
||||
"Where logs will be sent, :console - send logs to stdout, { ExSyslogger, :ex_syslogger } - to syslog, Quack.Logger - to Slack.",
|
||||
suggestions: [:console, {ExSyslogger, :ex_syslogger}, Quack.Logger]
|
||||
suggestions: [:console, {ExSyslogger, :ex_syslogger}]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1202,7 +1202,7 @@ config :pleroma, :config_description, [
|
|||
key: :level,
|
||||
type: {:dropdown, :atom},
|
||||
description: "Log level",
|
||||
suggestions: [:debug, :info, :warn, :error]
|
||||
suggestions: [:debug, :info, :warning, :error]
|
||||
},
|
||||
%{
|
||||
key: :ident,
|
||||
|
@ -1235,7 +1235,7 @@ config :pleroma, :config_description, [
|
|||
key: :level,
|
||||
type: {:dropdown, :atom},
|
||||
description: "Log level",
|
||||
suggestions: [:debug, :info, :warn, :error]
|
||||
suggestions: [:debug, :info, :warning, :error]
|
||||
},
|
||||
%{
|
||||
key: :format,
|
||||
|
@ -1937,7 +1937,7 @@ config :pleroma, :config_description, [
|
|||
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 @@ config :pleroma, Pleroma.Captcha,
|
|||
|
||||
# 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: []
|
||||
|
@ -143,6 +143,25 @@ config :phoenix, :plug_init_mode, :runtime
|
|||
|
||||
config :pleroma, :config_impl, Pleroma.UnstubbedConfigMock
|
||||
|
||||
config :pleroma, Pleroma.PromEx, disabled: true
|
||||
|
||||
# Mox definitions. Only read during compile time.
|
||||
config :pleroma, Pleroma.User.Backup, config_impl: Pleroma.UnstubbedConfigMock
|
||||
config :pleroma, Pleroma.Uploaders.S3, ex_aws_impl: Pleroma.Uploaders.S3.ExAwsMock
|
||||
config :pleroma, Pleroma.Uploaders.S3, config_impl: Pleroma.UnstubbedConfigMock
|
||||
config :pleroma, Pleroma.Upload, config_impl: Pleroma.UnstubbedConfigMock
|
||||
config :pleroma, Pleroma.ScheduledActivity, config_impl: Pleroma.UnstubbedConfigMock
|
||||
config :pleroma, Pleroma.Web.RichMedia.Helpers, config_impl: Pleroma.StaticStubbedConfigMock
|
||||
|
||||
peer_module =
|
||||
if String.to_integer(System.otp_release()) >= 25 do
|
||||
:peer
|
||||
else
|
||||
:slave
|
||||
end
|
||||
|
||||
config :pleroma, Pleroma.Cluster, peer_module: peer_module
|
||||
|
||||
if File.exists?("./config/test.secret.exs") do
|
||||
import_config "test.secret.exs"
|
||||
else
|
||||
|
|
|
@ -38,7 +38,7 @@ config :logger, :console,
|
|||
|
||||
## Testing
|
||||
|
||||
1. Create a `test.secret.exs` file with the content as shown below
|
||||
1. Create a `config/test.secret.exs` file with the content as shown below
|
||||
2. Create the database user and test database.
|
||||
1. You can use the `config/setup_db.psql` as a template. Copy the file if you want and change the database name, user and password to the values for the test-database (e.g. 'pleroma_local_test' for database and user). Then run this file like you did during installation.
|
||||
2. The tests will try to create the Database, so we'll have to allow our test-database user to create databases, `sudo -Hu postgres psql -c "ALTER USER pleroma_local_test WITH CREATEDB;"`
|
||||
|
|
|
@ -138,7 +138,7 @@ defmodule Pleroma.Application do
|
|||
num
|
||||
else
|
||||
e ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Could not get the postgres version: #{inspect(e)}.\nSetting the default value of 9.6"
|
||||
)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
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 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
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.
|
||||
|
@ -168,8 +168,6 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
check_filter(Pleroma.Upload.Filter.Exiftool.ReadDescription, "exiftool"),
|
||||
check_filter(Pleroma.Upload.Filter.Mogrify, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filter.Mogrifun, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "convert"),
|
||||
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "ffprobe")
|
||||
]
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
filters = Config.get([Pleroma.Upload]) |> Keyword.get(:filters, [])
|
||||
|
||||
if Pleroma.Upload.Filter.Exiftool in filters do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using Exiftool as a filter instead of Exiftool.StripLocation. This should work for now, but you are advised to change to the new configuration to prevent possible issues later:
|
||||
|
||||
|
@ -63,7 +63,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
|> Enum.any?(fn {_, v} -> 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:
|
||||
|
||||
|
@ -121,7 +121,7 @@ defmodule Pleroma.Config.DeprecationWarnings 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:
|
||||
|
||||
|
@ -158,7 +158,7 @@ defmodule Pleroma.Config.DeprecationWarnings 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:
|
||||
|
||||
|
@ -193,7 +193,7 @@ defmodule Pleroma.Config.DeprecationWarnings 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.
|
||||
""")
|
||||
|
@ -274,7 +274,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
if warning == "" do
|
||||
:ok
|
||||
else
|
||||
Logger.warn(warning_preface <> warning)
|
||||
Logger.warning(warning_preface <> warning)
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
@ -284,7 +284,7 @@ defmodule Pleroma.Config.DeprecationWarnings 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.
|
||||
""")
|
||||
|
@ -299,7 +299,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
pool_config = Config.get(:connections_pool)
|
||||
|
||||
if timeout = pool_config[:await_up_timeout] do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using old setting `config :pleroma, :connections_pool, await_up_timeout`. Please change to `config :pleroma, :connections_pool, connect_timeout` to ensure compatibility with future releases.
|
||||
""")
|
||||
|
@ -331,7 +331,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
"\n* `:timeout` options in #{pool_name} pool is now `:recv_timeout`"
|
||||
end)
|
||||
|
||||
Logger.warn(Enum.join([warning_preface | pool_warnings]))
|
||||
Logger.warning(Enum.join([warning_preface | pool_warnings]))
|
||||
|
||||
Config.put(:pools, updated_config)
|
||||
:error
|
||||
|
|
|
@ -23,7 +23,7 @@ defmodule Pleroma.Config.Oban 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
|
||||
|
|
|
@ -144,7 +144,7 @@ defmodule Pleroma.Config.TransferTask 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
|
||||
|
@ -178,12 +178,12 @@ defmodule Pleroma.Config.TransferTask 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
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ defmodule Pleroma.Docs.Generator do
|
|||
# This shouldn't be needed as all modules are expected to have module_info/1,
|
||||
# but in test enviroments some transient modules `:elixir_compiler_XX`
|
||||
# are loaded for some reason (where XX is a random integer).
|
||||
Code.ensure_loaded(module)
|
||||
|
||||
if function_exported?(module, :module_info, 1) do
|
||||
module.module_info(:attributes)
|
||||
|> Keyword.get_values(:behaviour)
|
||||
|
|
|
@ -59,7 +59,7 @@ defmodule Pleroma.Emoji.Loader 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
|
||||
|
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Gun.Conn do
|
|||
{:ok, conn, protocol}
|
||||
else
|
||||
error ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Opening proxied connection to #{compose_uri_log(uri)} failed with error #{inspect(error)}"
|
||||
)
|
||||
|
||||
|
@ -90,7 +90,7 @@ defmodule Pleroma.Gun.Conn do
|
|||
{:ok, conn, protocol}
|
||||
else
|
||||
error ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Opening socks proxied connection to #{compose_uri_log(uri)} failed with error #{inspect(error)}"
|
||||
)
|
||||
|
||||
|
@ -106,7 +106,7 @@ defmodule Pleroma.Gun.Conn do
|
|||
{:ok, conn, protocol}
|
||||
else
|
||||
error ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Opening connection to #{compose_uri_log(uri)} failed with error #{inspect(error)}"
|
||||
)
|
||||
|
||||
|
|
|
@ -70,15 +70,15 @@ defmodule Pleroma.HTTP.AdapterHelper do
|
|||
{:ok, parse_host(host), port}
|
||||
else
|
||||
{_, _} ->
|
||||
Logger.warn("Parsing port failed #{inspect(proxy)}")
|
||||
Logger.warning("Parsing port failed #{inspect(proxy)}")
|
||||
{:error, :invalid_proxy_port}
|
||||
|
||||
:error ->
|
||||
Logger.warn("Parsing port failed #{inspect(proxy)}")
|
||||
Logger.warning("Parsing port failed #{inspect(proxy)}")
|
||||
{:error, :invalid_proxy_port}
|
||||
|
||||
_ ->
|
||||
Logger.warn("Parsing proxy failed #{inspect(proxy)}")
|
||||
Logger.warning("Parsing proxy failed #{inspect(proxy)}")
|
||||
{:error, :invalid_proxy}
|
||||
end
|
||||
end
|
||||
|
@ -88,7 +88,7 @@ defmodule Pleroma.HTTP.AdapterHelper do
|
|||
{:ok, type, parse_host(host), port}
|
||||
else
|
||||
_ ->
|
||||
Logger.warn("Parsing proxy failed #{inspect(proxy)}")
|
||||
Logger.warning("Parsing proxy failed #{inspect(proxy)}")
|
||||
{:error, :invalid_proxy}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,11 @@ defmodule Pleroma.HTTP.WebPush do
|
|||
@moduledoc false
|
||||
|
||||
def post(url, payload, headers, options \\ []) do
|
||||
list_headers = Map.to_list(headers)
|
||||
list_headers =
|
||||
headers
|
||||
|> Map.to_list()
|
||||
|> Kernel.++([{"content-type", "octet-stream"}])
|
||||
|
||||
Pleroma.HTTP.post(url, payload, list_headers, options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -97,13 +97,9 @@ defmodule Pleroma.Instances.Instance do
|
|||
def reachable?(url_or_host) when is_binary(url_or_host), do: true
|
||||
|
||||
def set_reachable(url_or_host) when is_binary(url_or_host) do
|
||||
with host <- host(url_or_host),
|
||||
%Instance{} = existing_record <- Repo.get_by(Instance, %{host: host}) do
|
||||
{:ok, _instance} =
|
||||
existing_record
|
||||
|> changeset(%{unreachable_since: nil})
|
||||
|> Repo.update()
|
||||
end
|
||||
%Instance{host: host(url_or_host)}
|
||||
|> changeset(%{unreachable_since: nil})
|
||||
|> Repo.insert(on_conflict: {:replace, [:unreachable_since]}, conflict_target: :host)
|
||||
end
|
||||
|
||||
def set_reachable(_), do: {:error, nil}
|
||||
|
@ -177,7 +173,7 @@ defmodule Pleroma.Instances.Instance do
|
|||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.warn("Instance.get_or_update_favicon(\"#{host}\") error: #{inspect(e)}")
|
||||
Logger.warning("Instance.get_or_update_favicon(\"#{host}\") error: #{inspect(e)}")
|
||||
nil
|
||||
end
|
||||
|
||||
|
@ -205,7 +201,7 @@ defmodule Pleroma.Instances.Instance do
|
|||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Instance.scrape_favicon(\"#{to_string(instance_uri)}\") error: #{inspect(e)}"
|
||||
)
|
||||
|
||||
|
@ -288,7 +284,7 @@ defmodule Pleroma.Instances.Instance do
|
|||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Instance.scrape_metadata(\"#{to_string(instance_uri)}\") error: #{inspect(e)}"
|
||||
)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ defmodule Pleroma.Maintenance 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 @@ defmodule Pleroma.Migrators.Support.BaseMigrator 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 @@ defmodule Pleroma.Migrators.Support.BaseMigrator 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 @@ defmodule Pleroma.Migrators.Support.BaseMigrator 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."
|
||||
)
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ defmodule Pleroma.ReverseProxy do
|
|||
halt(conn)
|
||||
|
||||
{:error, error, conn} ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"#{__MODULE__} request to #{url} failed while reading/chunking: #{inspect(error)}"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ defmodule Pleroma.ScheduledActivity do
|
|||
use Ecto.Schema
|
||||
|
||||
alias Ecto.Multi
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.User
|
||||
|
@ -20,6 +19,8 @@ defmodule Pleroma.ScheduledActivity do
|
|||
|
||||
@min_offset :timer.minutes(5)
|
||||
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
||||
schema "scheduled_activities" do
|
||||
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
||||
field(:scheduled_at, :naive_datetime)
|
||||
|
@ -87,7 +88,7 @@ defmodule Pleroma.ScheduledActivity do
|
|||
|> where([sa], type(sa.scheduled_at, :date) == type(^scheduled_at, :date))
|
||||
|> select([sa], count(sa.id))
|
||||
|> Repo.one()
|
||||
|> Kernel.>=(Config.get([ScheduledActivity, :daily_user_limit]))
|
||||
|> Kernel.>=(@config_impl.get([ScheduledActivity, :daily_user_limit]))
|
||||
end
|
||||
|
||||
def exceeds_total_user_limit?(user_id) do
|
||||
|
@ -95,7 +96,7 @@ defmodule Pleroma.ScheduledActivity do
|
|||
|> where(user_id: ^user_id)
|
||||
|> select([sa], count(sa.id))
|
||||
|> Repo.one()
|
||||
|> Kernel.>=(Config.get([ScheduledActivity, :total_user_limit]))
|
||||
|> Kernel.>=(@config_impl.get([ScheduledActivity, :total_user_limit]))
|
||||
end
|
||||
|
||||
def far_enough?(scheduled_at) when is_binary(scheduled_at) do
|
||||
|
@ -123,7 +124,7 @@ defmodule Pleroma.ScheduledActivity do
|
|||
def create(%User{} = user, attrs) do
|
||||
Multi.new()
|
||||
|> Multi.insert(:scheduled_activity, new(user, attrs))
|
||||
|> maybe_add_jobs(Config.get([ScheduledActivity, :enabled]))
|
||||
|> maybe_add_jobs(@config_impl.get([ScheduledActivity, :enabled]))
|
||||
|> Repo.transaction()
|
||||
|> transaction_response
|
||||
end
|
||||
|
|
|
@ -70,7 +70,7 @@ defmodule Pleroma.Telemetry.Logger do
|
|||
%{key: key},
|
||||
_
|
||||
) do
|
||||
Logger.warn(fn ->
|
||||
Logger.warning(fn ->
|
||||
"Pool worker for #{key}: Client #{inspect(client_pid)} died before releasing the connection with #{inspect(reason)}"
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -34,7 +34,6 @@ defmodule Pleroma.Upload do
|
|||
|
||||
"""
|
||||
alias Ecto.UUID
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Maps
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
require Logger
|
||||
|
@ -76,6 +75,8 @@ defmodule Pleroma.Upload do
|
|||
:path
|
||||
]
|
||||
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
||||
defp get_description(upload) do
|
||||
case {upload.description, Pleroma.Config.get([Pleroma.Upload, :default_description])} do
|
||||
{description, _} when is_binary(description) -> description
|
||||
|
@ -244,18 +245,18 @@ defmodule Pleroma.Upload do
|
|||
defp url_from_spec(_upload, _base_url, {:url, url}), do: url
|
||||
|
||||
def base_url do
|
||||
uploader = Config.get([Pleroma.Upload, :uploader])
|
||||
upload_base_url = Config.get([Pleroma.Upload, :base_url])
|
||||
public_endpoint = Config.get([uploader, :public_endpoint])
|
||||
uploader = @config_impl.get([Pleroma.Upload, :uploader])
|
||||
upload_base_url = @config_impl.get([Pleroma.Upload, :base_url])
|
||||
public_endpoint = @config_impl.get([uploader, :public_endpoint])
|
||||
|
||||
case uploader do
|
||||
Pleroma.Uploaders.Local ->
|
||||
upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
|
||||
|
||||
Pleroma.Uploaders.S3 ->
|
||||
bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
|
||||
truncated_namespace = Config.get([Pleroma.Uploaders.S3, :truncated_namespace])
|
||||
namespace = Config.get([Pleroma.Uploaders.S3, :bucket_namespace])
|
||||
bucket = @config_impl.get([Pleroma.Uploaders.S3, :bucket])
|
||||
truncated_namespace = @config_impl.get([Pleroma.Uploaders.S3, :truncated_namespace])
|
||||
namespace = @config_impl.get([Pleroma.Uploaders.S3, :bucket_namespace])
|
||||
|
||||
bucket_with_namespace =
|
||||
cond do
|
||||
|
|
|
@ -29,7 +29,7 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
|
|||
{:ok, :filtered, upload}
|
||||
rescue
|
||||
e in ErlangError ->
|
||||
Logger.warn("#{__MODULE__}: #{inspect(e)}")
|
||||
Logger.warning("#{__MODULE__}: #{inspect(e)}")
|
||||
{:ok, :noop}
|
||||
end
|
||||
end
|
||||
|
@ -46,7 +46,7 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do
|
|||
{:ok, :filtered, upload}
|
||||
rescue
|
||||
e in ErlangError ->
|
||||
Logger.warn("#{__MODULE__}: #{inspect(e)}")
|
||||
Logger.warning("#{__MODULE__}: #{inspect(e)}")
|
||||
{:ok, :noop}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,8 +10,6 @@ defmodule Pleroma.Upload.Filter.Exiftool.ReadDescription do
|
|||
"""
|
||||
@behaviour Pleroma.Upload.Filter
|
||||
|
||||
@spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()}
|
||||
|
||||
def filter(%Pleroma.Upload{description: description})
|
||||
when is_binary(description),
|
||||
do: {:ok, :noop}
|
||||
|
|
|
@ -6,7 +6,8 @@ defmodule Pleroma.Uploaders.S3 do
|
|||
@behaviour Pleroma.Uploaders.Uploader
|
||||
require Logger
|
||||
|
||||
alias Pleroma.Config
|
||||
@ex_aws_impl Application.compile_env(:pleroma, [__MODULE__, :ex_aws_impl], ExAws)
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
||||
# The file name is re-encoded with S3's constraints here to comply with previous
|
||||
# links with less strict filenames
|
||||
|
@ -22,7 +23,7 @@ defmodule Pleroma.Uploaders.S3 do
|
|||
|
||||
@impl true
|
||||
def put_file(%Pleroma.Upload{} = upload) do
|
||||
config = Config.get([__MODULE__])
|
||||
config = @config_impl.get([__MODULE__])
|
||||
bucket = Keyword.get(config, :bucket)
|
||||
streaming = Keyword.get(config, :streaming_enabled)
|
||||
|
||||
|
@ -56,7 +57,7 @@ defmodule Pleroma.Uploaders.S3 do
|
|||
])
|
||||
end
|
||||
|
||||
case ExAws.request(op) do
|
||||
case @ex_aws_impl.request(op) do
|
||||
{:ok, _} ->
|
||||
{:ok, {:file, s3_name}}
|
||||
|
||||
|
@ -69,9 +70,9 @@ defmodule Pleroma.Uploaders.S3 do
|
|||
@impl true
|
||||
def delete_file(file) do
|
||||
[__MODULE__, :bucket]
|
||||
|> Config.get()
|
||||
|> @config_impl.get()
|
||||
|> ExAws.S3.delete_object(file)
|
||||
|> ExAws.request()
|
||||
|> @ex_aws_impl.request()
|
||||
|> case do
|
||||
{:ok, %{status_code: 204}} -> :ok
|
||||
error -> {:error, inspect(error)}
|
||||
|
@ -83,3 +84,7 @@ defmodule Pleroma.Uploaders.S3 do
|
|||
String.replace(name, @regex, "-")
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Pleroma.Uploaders.S3.ExAwsAPI do
|
||||
@callback request(op :: ExAws.Operation.t()) :: {:ok, ExAws.Operation.t()} | {:error, term()}
|
||||
end
|
||||
|
|
|
@ -1560,7 +1560,7 @@ defmodule Pleroma.User 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}"
|
||||
)
|
||||
|
||||
|
@ -2136,7 +2136,7 @@ defmodule Pleroma.User do
|
|||
def public_key(_), do: {:error, "key not found"}
|
||||
|
||||
def get_public_key_for_ap_id(ap_id) do
|
||||
with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id),
|
||||
with %User{} = user <- get_cached_by_ap_id(ap_id),
|
||||
{:ok, public_key} <- public_key(user) do
|
||||
{:ok, public_key}
|
||||
else
|
||||
|
@ -2681,6 +2681,8 @@ defmodule Pleroma.User do
|
|||
|> update_and_set_cache()
|
||||
end
|
||||
|
||||
def update_last_active_at(user), do: user
|
||||
|
||||
def active_user_count(days \\ 30) do
|
||||
active_after = Timex.shift(NaiveDateTime.utc_now(), days: -days)
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ defmodule Pleroma.User.Backup do
|
|||
timestamps()
|
||||
end
|
||||
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
||||
def create(user, admin_id \\ nil) do
|
||||
with :ok <- validate_limit(user, admin_id),
|
||||
{:ok, backup} <- user |> new() |> Repo.insert() do
|
||||
|
@ -124,7 +126,10 @@ defmodule Pleroma.User.Backup do
|
|||
|> Repo.update()
|
||||
end
|
||||
|
||||
def process(%__MODULE__{} = backup) do
|
||||
def process(
|
||||
%__MODULE__{} = backup,
|
||||
processor_module \\ __MODULE__.Processor
|
||||
) do
|
||||
set_state(backup, :running, 0)
|
||||
|
||||
current_pid = self()
|
||||
|
@ -132,7 +137,7 @@ defmodule Pleroma.User.Backup do
|
|||
task =
|
||||
Task.Supervisor.async_nolink(
|
||||
Pleroma.TaskSupervisor,
|
||||
__MODULE__,
|
||||
processor_module,
|
||||
:do_process,
|
||||
[backup, current_pid]
|
||||
)
|
||||
|
@ -140,25 +145,8 @@ defmodule Pleroma.User.Backup do
|
|||
wait_backup(backup, backup.processed_number, task)
|
||||
end
|
||||
|
||||
def do_process(backup, current_pid) do
|
||||
with {:ok, zip_file} <- export(backup, current_pid),
|
||||
{:ok, %{size: size}} <- File.stat(zip_file),
|
||||
{:ok, _upload} <- upload(backup, zip_file) do
|
||||
backup
|
||||
|> cast(
|
||||
%{
|
||||
file_size: size,
|
||||
processed: true,
|
||||
state: :complete
|
||||
},
|
||||
[:file_size, :processed, :state]
|
||||
)
|
||||
|> Repo.update()
|
||||
end
|
||||
end
|
||||
|
||||
defp wait_backup(backup, current_processed, task) do
|
||||
wait_time = Pleroma.Config.get([__MODULE__, :process_wait_time])
|
||||
wait_time = @config_impl.get([__MODULE__, :process_wait_time])
|
||||
|
||||
receive do
|
||||
{:progress, new_processed} ->
|
||||
|
@ -305,7 +293,7 @@ defmodule Pleroma.User.Backup do
|
|||
acc + 1
|
||||
else
|
||||
{:error, e} ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Error processing backup item: #{inspect(e)}\n The item is: #{inspect(i)}"
|
||||
)
|
||||
|
||||
|
@ -365,3 +353,35 @@ defmodule Pleroma.User.Backup do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Pleroma.User.Backup.ProcessorAPI do
|
||||
@callback do_process(%Pleroma.User.Backup{}, pid()) ::
|
||||
{:ok, %Pleroma.User.Backup{}} | {:error, any()}
|
||||
end
|
||||
|
||||
defmodule Pleroma.User.Backup.Processor do
|
||||
@behaviour Pleroma.User.Backup.ProcessorAPI
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User.Backup
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
@impl true
|
||||
def do_process(backup, current_pid) do
|
||||
with {:ok, zip_file} <- Backup.export(backup, current_pid),
|
||||
{:ok, %{size: size}} <- File.stat(zip_file),
|
||||
{:ok, _upload} <- Backup.upload(backup, zip_file) do
|
||||
backup
|
||||
|> cast(
|
||||
%{
|
||||
file_size: size,
|
||||
processed: true,
|
||||
state: :complete
|
||||
},
|
||||
[:file_size, :processed, :state]
|
||||
)
|
||||
|> Repo.update()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -273,12 +273,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
end
|
||||
|
||||
def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do
|
||||
with %User{} = recipient <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(params["actor"]),
|
||||
with %User{is_active: true} = recipient <- User.get_cached_by_nickname(nickname),
|
||||
{:ok, %User{is_active: true} = actor} <- User.get_or_fetch_by_ap_id(params["actor"]),
|
||||
true <- Utils.recipient_in_message(recipient, actor, params),
|
||||
params <- Utils.maybe_splice_recipient(recipient.ap_id, params) do
|
||||
Federator.incoming_ap_doc(params)
|
||||
json(conn, "ok")
|
||||
else
|
||||
_ ->
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("Invalid request.")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -287,10 +292,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
json(conn, "ok")
|
||||
end
|
||||
|
||||
def inbox(%{assigns: %{valid_signature: false}} = conn, _params) do
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("Invalid HTTP Signature")
|
||||
def inbox(%{assigns: %{valid_signature: false}, req_headers: req_headers} = conn, params) do
|
||||
Federator.incoming_ap_doc(%{req_headers: req_headers, params: params})
|
||||
json(conn, "ok")
|
||||
end
|
||||
|
||||
# POST /relay/inbox -or- POST /internal/fetch/inbox
|
||||
|
@ -476,7 +480,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
|> json(message)
|
||||
|
||||
e ->
|
||||
Logger.warn(fn -> "AP C2S: #{inspect(e)}" end)
|
||||
Logger.warning(fn -> "AP C2S: #{inspect(e)}" end)
|
||||
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|
|
|
@ -54,6 +54,8 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
@required_description_keys [:key, :related_policy]
|
||||
|
||||
def filter_one(policy, message) do
|
||||
Code.ensure_loaded(policy)
|
||||
|
||||
should_plug_history? =
|
||||
if function_exported?(policy, :history_awareness, 0) do
|
||||
policy.history_awareness()
|
||||
|
@ -188,6 +190,8 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
|
||||
def config_descriptions(policies) do
|
||||
Enum.reduce(policies, @mrf_config_descriptions, fn policy, acc ->
|
||||
Code.ensure_loaded(policy)
|
||||
|
||||
if function_exported?(policy, :config_description, 0) do
|
||||
description =
|
||||
@default_description
|
||||
|
@ -199,7 +203,7 @@ defmodule Pleroma.Web.ActivityPub.MRF 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)}"
|
||||
)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.FollowBotPolicy do
|
|||
try_follow(follower, message)
|
||||
else
|
||||
nil ->
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"#{__MODULE__} skipped because of missing `:mrf_follow_bot, :follower_nickname` configuration, the :follower_nickname
|
||||
account does not exist, or the account is not correctly configured as a bot."
|
||||
)
|
||||
|
|
|
@ -41,7 +41,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy 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 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy 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
|
||||
|
|
|
@ -118,7 +118,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
end
|
||||
end
|
||||
|
||||
@spec recipients(User.t(), Activity.t()) :: list(User.t()) | []
|
||||
@spec recipients(User.t(), Activity.t()) :: [[User.t()]]
|
||||
defp recipients(actor, activity) do
|
||||
followers =
|
||||
if actor.follower_address in activity.recipients do
|
||||
|
@ -138,7 +138,10 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
[]
|
||||
end
|
||||
|
||||
Pleroma.Web.Federator.Publisher.remote_users(actor, activity) ++ followers ++ fetchers
|
||||
mentioned = Pleroma.Web.Federator.Publisher.remote_users(actor, activity)
|
||||
non_mentioned = (followers ++ fetchers) -- mentioned
|
||||
|
||||
[mentioned, non_mentioned]
|
||||
end
|
||||
|
||||
defp get_cc_ap_ids(ap_id, recipients) do
|
||||
|
@ -195,34 +198,39 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
public = is_public?(activity)
|
||||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
recipients = recipients(actor, activity)
|
||||
[priority_recipients, recipients] = recipients(actor, activity)
|
||||
|
||||
inboxes =
|
||||
recipients
|
||||
|> Enum.map(fn actor -> actor.inbox end)
|
||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||
|> Instances.filter_reachable()
|
||||
[priority_recipients, recipients]
|
||||
|> Enum.map(fn recipients ->
|
||||
recipients
|
||||
|> Enum.map(fn actor -> actor.inbox end)
|
||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||
|> Instances.filter_reachable()
|
||||
end)
|
||||
|
||||
Repo.checkout(fn ->
|
||||
Enum.each(inboxes, fn {inbox, unreachable_since} ->
|
||||
%User{ap_id: ap_id} = Enum.find(recipients, fn actor -> actor.inbox == inbox end)
|
||||
Enum.each(inboxes, fn inboxes ->
|
||||
Enum.each(inboxes, fn {inbox, unreachable_since} ->
|
||||
%User{ap_id: ap_id} = Enum.find(recipients, fn actor -> actor.inbox == inbox end)
|
||||
|
||||
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
||||
# instance would only accept a first message for the first recipient and ignore the rest.
|
||||
cc = get_cc_ap_ids(ap_id, recipients)
|
||||
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
||||
# instance would only accept a first message for the first recipient and ignore the rest.
|
||||
cc = get_cc_ap_ids(ap_id, recipients)
|
||||
|
||||
json =
|
||||
data
|
||||
|> Map.put("cc", cc)
|
||||
|> Jason.encode!()
|
||||
json =
|
||||
data
|
||||
|> Map.put("cc", cc)
|
||||
|> Jason.encode!()
|
||||
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(__MODULE__, %{
|
||||
inbox: inbox,
|
||||
json: json,
|
||||
actor_id: actor.id,
|
||||
id: activity.data["id"],
|
||||
unreachable_since: unreachable_since
|
||||
})
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(__MODULE__, %{
|
||||
inbox: inbox,
|
||||
json: json,
|
||||
actor_id: actor.id,
|
||||
id: activity.data["id"],
|
||||
unreachable_since: unreachable_since
|
||||
})
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
@ -239,25 +247,36 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
json = Jason.encode!(data)
|
||||
|
||||
recipients(actor, activity)
|
||||
|> Enum.map(fn %User{} = user ->
|
||||
determine_inbox(activity, user)
|
||||
end)
|
||||
|> Enum.uniq()
|
||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||
|> Instances.filter_reachable()
|
||||
|> Enum.each(fn {inbox, unreachable_since} ->
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(
|
||||
__MODULE__,
|
||||
%{
|
||||
inbox: inbox,
|
||||
json: json,
|
||||
actor_id: actor.id,
|
||||
id: activity.data["id"],
|
||||
unreachable_since: unreachable_since
|
||||
}
|
||||
)
|
||||
[priority_inboxes, inboxes] =
|
||||
recipients(actor, activity)
|
||||
|> Enum.map(fn recipients ->
|
||||
recipients
|
||||
|> Enum.map(fn actor -> actor.inbox end)
|
||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||
end)
|
||||
|
||||
inboxes = inboxes -- priority_inboxes
|
||||
|
||||
[{priority_inboxes, 0}, {inboxes, 1}]
|
||||
|> Enum.each(fn {inboxes, priority} ->
|
||||
inboxes
|
||||
|> Instances.filter_reachable()
|
||||
|> Enum.each(fn {inbox, unreachable_since} ->
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(
|
||||
__MODULE__,
|
||||
%{
|
||||
inbox: inbox,
|
||||
json: json,
|
||||
actor_id: actor.id,
|
||||
id: activity.data["id"],
|
||||
unreachable_since: unreachable_since
|
||||
},
|
||||
priority: priority
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
def gather_webfinger_links(%User{} = user) do
|
||||
|
|
|
@ -156,7 +156,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|> Map.drop(["conversation", "inReplyToAtomUri"])
|
||||
else
|
||||
e ->
|
||||
Logger.warn("Couldn't fetch #{inspect(in_reply_to_id)}, error: #{inspect(e)}")
|
||||
Logger.warning("Couldn't fetch #{inspect(in_reply_to_id)}, error: #{inspect(e)}")
|
||||
object
|
||||
end
|
||||
else
|
||||
|
@ -182,7 +182,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
object
|
||||
|
||||
e ->
|
||||
Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
|
||||
Logger.warning("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
|
||||
object
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,6 +46,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
|||
"following" => "#{user.ap_id}/following",
|
||||
"followers" => "#{user.ap_id}/followers",
|
||||
"inbox" => "#{user.ap_id}/inbox",
|
||||
"outbox" => "#{user.ap_id}/outbox",
|
||||
"name" => "Pleroma",
|
||||
"summary" =>
|
||||
"An internal service actor for this Pleroma instance. No user-serviceable parts inside.",
|
||||
|
|
|
@ -23,6 +23,18 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
end
|
||||
|
||||
def show2_operation do
|
||||
%Operation{
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve instance information",
|
||||
description: "Information about the server",
|
||||
operationId: "InstanceController.show2",
|
||||
responses: %{
|
||||
200 => Operation.response("Instance", "application/json", instance2())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def peers_operation do
|
||||
%Operation{
|
||||
tags: ["Instance misc"],
|
||||
|
@ -165,6 +177,166 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
end
|
||||
|
||||
defp instance2 do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
domain: %Schema{type: :string, description: "The domain name of the instance"},
|
||||
title: %Schema{type: :string, description: "The title of the website"},
|
||||
version: %Schema{
|
||||
type: :string,
|
||||
description: "The version of Pleroma installed on the instance"
|
||||
},
|
||||
source_url: %Schema{
|
||||
type: :string,
|
||||
description: "The version of Pleroma installed on the instance"
|
||||
},
|
||||
description: %Schema{
|
||||
type: :string,
|
||||
description: "Admin-defined description of the Pleroma site"
|
||||
},
|
||||
usage: %Schema{
|
||||
type: :object,
|
||||
description: "Instance usage statistics",
|
||||
properties: %{
|
||||
users: %Schema{
|
||||
type: :object,
|
||||
description: "User count statistics",
|
||||
properties: %{
|
||||
active_month: %Schema{
|
||||
type: :integer,
|
||||
description: "Monthly active users"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
email: %Schema{
|
||||
type: :string,
|
||||
description: "An email that may be contacted for any inquiries",
|
||||
format: :email
|
||||
},
|
||||
urls: %Schema{
|
||||
type: :object,
|
||||
description: "URLs of interest for clients apps",
|
||||
properties: %{}
|
||||
},
|
||||
stats: %Schema{
|
||||
type: :object,
|
||||
description: "Statistics about how much information the instance contains",
|
||||
properties: %{
|
||||
user_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Users registered on this instance"
|
||||
},
|
||||
status_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Statuses authored by users on instance"
|
||||
},
|
||||
domain_count: %Schema{
|
||||
type: :integer,
|
||||
description: "Domains federated with this instance"
|
||||
}
|
||||
}
|
||||
},
|
||||
thumbnail: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
url: %Schema{
|
||||
type: :string,
|
||||
description: "Banner image for the website",
|
||||
nullable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
languages: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
description: "Primary langauges of the website and its staff"
|
||||
},
|
||||
registrations: %Schema{
|
||||
type: :object,
|
||||
description: "Registrations-related configuration",
|
||||
properties: %{
|
||||
enabled: %Schema{
|
||||
type: :boolean,
|
||||
description: "Whether registrations are enabled"
|
||||
},
|
||||
approval_required: %Schema{
|
||||
type: :boolean,
|
||||
description: "Whether users need to be manually approved by admin"
|
||||
}
|
||||
}
|
||||
},
|
||||
configuration: %Schema{
|
||||
type: :object,
|
||||
description: "Instance configuration",
|
||||
properties: %{
|
||||
urls: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
streaming: %Schema{
|
||||
type: :string,
|
||||
description: "Websockets address for push streaming"
|
||||
}
|
||||
}
|
||||
},
|
||||
statuses: %Schema{
|
||||
type: :object,
|
||||
description: "A map with poll limits for local statuses",
|
||||
properties: %{
|
||||
max_characters: %Schema{
|
||||
type: :integer,
|
||||
description: "Posts character limit (CW/Subject included in the counter)"
|
||||
},
|
||||
max_media_attachments: %Schema{
|
||||
type: :integer,
|
||||
description: "Media attachment limit"
|
||||
}
|
||||
}
|
||||
},
|
||||
media_attachments: %Schema{
|
||||
type: :object,
|
||||
description: "A map with poll limits for media attachments",
|
||||
properties: %{
|
||||
image_size_limit: %Schema{
|
||||
type: :integer,
|
||||
description: "File size limit of uploaded images"
|
||||
},
|
||||
video_size_limit: %Schema{
|
||||
type: :integer,
|
||||
description: "File size limit of uploaded videos"
|
||||
}
|
||||
}
|
||||
},
|
||||
polls: %Schema{
|
||||
type: :object,
|
||||
description: "A map with poll limits for local polls",
|
||||
properties: %{
|
||||
max_options: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum number of options."
|
||||
},
|
||||
max_characters_per_option: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum number of characters per option."
|
||||
},
|
||||
min_expiration: %Schema{
|
||||
type: :integer,
|
||||
description: "Minimum expiration time (in seconds)."
|
||||
},
|
||||
max_expiration: %Schema{
|
||||
type: :integer,
|
||||
description: "Maximum expiration time (in seconds)."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_domains do
|
||||
%Schema{
|
||||
type: :array,
|
||||
|
|
|
@ -550,7 +550,7 @@ defmodule Pleroma.Web.CommonAPI 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}"
|
||||
)
|
||||
|
||||
|
|
|
@ -321,13 +321,13 @@ defmodule Pleroma.Web.CommonAPI.Utils 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
|
||||
|
||||
|
|
|
@ -35,6 +35,17 @@ defmodule Pleroma.Web.Federator do
|
|||
end
|
||||
|
||||
# Client API
|
||||
def incoming_ap_doc(%{params: params, req_headers: req_headers}) do
|
||||
ReceiverWorker.enqueue(
|
||||
"incoming_ap_doc",
|
||||
%{"req_headers" => req_headers, "params" => params, "timeout" => :timer.seconds(20)},
|
||||
priority: 2
|
||||
)
|
||||
end
|
||||
|
||||
def incoming_ap_doc(%{"type" => "Delete"} = params) do
|
||||
ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params}, priority: 3)
|
||||
end
|
||||
|
||||
def incoming_ap_doc(params) do
|
||||
ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params})
|
||||
|
|
|
@ -29,11 +29,12 @@ defmodule Pleroma.Web.Federator.Publisher do
|
|||
@doc """
|
||||
Enqueue publishing a single activity.
|
||||
"""
|
||||
@spec enqueue_one(module(), Map.t()) :: :ok
|
||||
def enqueue_one(module, %{} = params) do
|
||||
@spec enqueue_one(module(), Map.t(), Keyword.t()) :: {:ok, %Oban.Job{}}
|
||||
def enqueue_one(module, %{} = params, worker_args \\ []) do
|
||||
PublisherWorker.enqueue(
|
||||
"publish_one",
|
||||
%{"module" => to_string(module), "params" => params}
|
||||
%{"module" => to_string(module), "params" => params},
|
||||
worker_args
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(:skip_auth when action in [:show, :peers])
|
||||
plug(:skip_auth when action in [:show, :show2, :peers])
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.InstanceOperation
|
||||
|
||||
|
@ -16,6 +16,11 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
render(conn, "show.json")
|
||||
end
|
||||
|
||||
@doc "GET /api/v2/instance"
|
||||
def show2(conn, _params) do
|
||||
render(conn, "show2.json")
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/instance/peers"
|
||||
def peers(conn, _params) do
|
||||
json(conn, Pleroma.Stats.get_peers())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.AccountView do
|
||||
|
@ -249,6 +249,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
nil
|
||||
end
|
||||
|
||||
last_status_at =
|
||||
user.last_status_at &&
|
||||
user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601()
|
||||
|
||||
%{
|
||||
id: to_string(user.id),
|
||||
username: username_from_nickname(user.nickname),
|
||||
|
@ -277,7 +281,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
actor_type: user.actor_type
|
||||
}
|
||||
},
|
||||
last_status_at: user.last_status_at,
|
||||
last_status_at: last_status_at,
|
||||
|
||||
# Pleroma extensions
|
||||
# Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub
|
||||
|
|
|
@ -13,12 +13,11 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
def render("show.json", _) do
|
||||
instance = Config.get(:instance)
|
||||
|
||||
%{
|
||||
uri: Pleroma.Web.Endpoint.url(),
|
||||
title: Keyword.get(instance, :name),
|
||||
common_information(instance)
|
||||
|> Map.merge(%{
|
||||
uri: Pleroma.Web.WebFinger.host(),
|
||||
description: Keyword.get(instance, :description),
|
||||
short_description: Keyword.get(instance, :short_description),
|
||||
version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
|
||||
email: Keyword.get(instance, :email),
|
||||
urls: %{
|
||||
streaming_api: Pleroma.Web.Endpoint.websocket_url()
|
||||
|
@ -27,9 +26,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
thumbnail:
|
||||
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|
||||
|> to_string,
|
||||
languages: Keyword.get(instance, :languages, ["en"]),
|
||||
registrations: Keyword.get(instance, :registrations_open),
|
||||
approval_required: Keyword.get(instance, :account_approval_required),
|
||||
configuration: configuration(),
|
||||
# Extra (not present in Mastodon):
|
||||
max_toot_chars: Keyword.get(instance, :limit),
|
||||
max_media_attachments: Keyword.get(instance, :max_media_attachments),
|
||||
|
@ -41,19 +40,44 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
background_image: Pleroma.Web.Endpoint.url() <> Keyword.get(instance, :background_image),
|
||||
shout_limit: Config.get([:shout, :limit]),
|
||||
description_limit: Keyword.get(instance, :description_limit),
|
||||
pleroma: %{
|
||||
metadata: %{
|
||||
account_activation_required: Keyword.get(instance, :account_activation_required),
|
||||
features: features(),
|
||||
federation: federation(),
|
||||
fields_limits: fields_limits(),
|
||||
post_formats: Config.get([:instance, :allowed_post_formats]),
|
||||
birthday_required: Config.get([:instance, :birthday_required]),
|
||||
birthday_min_age: Config.get([:instance, :birthday_min_age])
|
||||
},
|
||||
stats: %{mau: Pleroma.User.active_user_count()},
|
||||
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
|
||||
}
|
||||
pleroma: pleroma_configuration(instance)
|
||||
})
|
||||
end
|
||||
|
||||
def render("show2.json", _) do
|
||||
instance = Config.get(:instance)
|
||||
|
||||
common_information(instance)
|
||||
|> Map.merge(%{
|
||||
domain: Pleroma.Web.WebFinger.host(),
|
||||
source_url: Pleroma.Application.repository(),
|
||||
description: Keyword.get(instance, :short_description),
|
||||
usage: %{users: %{active_month: Pleroma.User.active_user_count()}},
|
||||
thumbnail: %{
|
||||
url:
|
||||
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|
||||
|> to_string
|
||||
},
|
||||
configuration: configuration2(),
|
||||
registrations: %{
|
||||
enabled: Keyword.get(instance, :registrations_open),
|
||||
approval_required: Keyword.get(instance, :account_approval_required),
|
||||
message: nil
|
||||
},
|
||||
contact: %{
|
||||
email: Keyword.get(instance, :email),
|
||||
account: nil
|
||||
},
|
||||
# Extra (not present in Mastodon):
|
||||
pleroma: pleroma_configuration2(instance)
|
||||
})
|
||||
end
|
||||
|
||||
defp common_information(instance) do
|
||||
%{
|
||||
title: Keyword.get(instance, :name),
|
||||
version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
|
||||
languages: Keyword.get(instance, :languages, ["en"])
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -133,7 +157,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
|> Map.put(:enabled, Config.get([:instance, :federating]))
|
||||
end
|
||||
|
||||
def fields_limits do
|
||||
defp fields_limits do
|
||||
%{
|
||||
max_fields: Config.get([:instance, :max_account_fields]),
|
||||
max_remote_fields: Config.get([:instance, :max_remote_account_fields]),
|
||||
|
@ -141,4 +165,65 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
value_length: Config.get([:instance, :account_field_value_length])
|
||||
}
|
||||
end
|
||||
|
||||
defp configuration do
|
||||
%{
|
||||
statuses: %{
|
||||
max_characters: Config.get([:instance, :limit]),
|
||||
max_media_attachments: Config.get([:instance, :max_media_attachments])
|
||||
},
|
||||
media_attachments: %{
|
||||
image_size_limit: Config.get([:instance, :upload_limit]),
|
||||
video_size_limit: Config.get([:instance, :upload_limit])
|
||||
},
|
||||
polls: %{
|
||||
max_options: Config.get([:instance, :poll_limits, :max_options]),
|
||||
max_characters_per_option: Config.get([:instance, :poll_limits, :max_option_chars]),
|
||||
min_expiration: Config.get([:instance, :poll_limits, :min_expiration]),
|
||||
max_expiration: Config.get([:instance, :poll_limits, :max_expiration])
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp configuration2 do
|
||||
configuration()
|
||||
|> Map.merge(%{
|
||||
urls: %{streaming: Pleroma.Web.Endpoint.websocket_url()}
|
||||
})
|
||||
end
|
||||
|
||||
defp pleroma_configuration(instance) do
|
||||
%{
|
||||
metadata: %{
|
||||
account_activation_required: Keyword.get(instance, :account_activation_required),
|
||||
features: features(),
|
||||
federation: federation(),
|
||||
fields_limits: fields_limits(),
|
||||
post_formats: Config.get([:instance, :allowed_post_formats]),
|
||||
birthday_required: Config.get([:instance, :birthday_required]),
|
||||
birthday_min_age: Config.get([:instance, :birthday_min_age])
|
||||
},
|
||||
stats: %{mau: Pleroma.User.active_user_count()},
|
||||
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
|
||||
}
|
||||
end
|
||||
|
||||
defp pleroma_configuration2(instance) do
|
||||
configuration = pleroma_configuration(instance)
|
||||
|
||||
configuration
|
||||
|> Map.merge(%{
|
||||
metadata:
|
||||
configuration.metadata
|
||||
|> Map.merge(%{
|
||||
avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit),
|
||||
background_upload_limit: Keyword.get(instance, :background_upload_limit),
|
||||
banner_upload_limit: Keyword.get(instance, :banner_upload_limit),
|
||||
background_image:
|
||||
Pleroma.Web.Endpoint.url() <> Keyword.get(instance, :background_image),
|
||||
description_limit: Keyword.get(instance, :description_limit),
|
||||
shout_limit: Config.get([:shout, :limit])
|
||||
})
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -563,25 +563,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
|
||||
page_url = page_url_data |> to_string
|
||||
|
||||
image_url_data =
|
||||
if is_binary(rich_media["image"]) do
|
||||
URI.parse(rich_media["image"])
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
image_url = build_image_url(image_url_data, page_url_data)
|
||||
image_url = proxied_url(rich_media["image"], page_url_data)
|
||||
audio_url = proxied_url(rich_media["audio"], page_url_data)
|
||||
video_url = proxied_url(rich_media["video"], page_url_data)
|
||||
|
||||
%{
|
||||
type: "link",
|
||||
provider_name: page_url_data.host,
|
||||
provider_url: page_url_data.scheme <> "://" <> page_url_data.host,
|
||||
url: page_url,
|
||||
image: image_url |> MediaProxy.url(),
|
||||
image: image_url,
|
||||
title: rich_media["title"] || "",
|
||||
description: rich_media["description"] || "",
|
||||
pleroma: %{
|
||||
opengraph: rich_media
|
||||
opengraph:
|
||||
rich_media
|
||||
|> Maps.put_if_present("image", image_url)
|
||||
|> Maps.put_if_present("audio", audio_url)
|
||||
|> Maps.put_if_present("video", video_url)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -818,4 +817,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
defp get_source_content_type(_source) do
|
||||
Utils.get_content_type(nil)
|
||||
end
|
||||
|
||||
defp proxied_url(url, page_url_data) do
|
||||
if is_binary(url) do
|
||||
build_image_url(URI.parse(url), page_url_data) |> MediaProxy.url()
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -201,7 +201,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
|
|||
|
||||
def warn_if_disabled do
|
||||
unless Config.get([:http_security, :enabled]) do
|
||||
Logger.warn("
|
||||
Logger.warning("
|
||||
.i;;;;i.
|
||||
iYcviii;vXY:
|
||||
.YXi .i1c.
|
||||
|
|
|
@ -89,7 +89,7 @@ defmodule Pleroma.Web.Plugs.RateLimiter do
|
|||
end
|
||||
|
||||
defp handle_disabled(conn) do
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"Rate limiter disabled due to forwarded IP not being found. Please ensure your reverse proxy is providing the X-Forwarded-For header or disable the RemoteIP plug/rate limiter."
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.Push do
|
|||
|
||||
def init do
|
||||
unless enabled() do
|
||||
Logger.warn("""
|
||||
Logger.warning("""
|
||||
VAPID key pair is not found. If you wish to enabled web push, please run
|
||||
|
||||
mix web_push.gen.keypair
|
||||
|
|
|
@ -57,7 +57,7 @@ defmodule Pleroma.Web.Push.Impl do
|
|||
end
|
||||
|
||||
def perform(_) do
|
||||
Logger.warn("Unknown notification type")
|
||||
Logger.warning("Unknown notification type")
|
||||
{:error, :unknown_type}
|
||||
end
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
defmodule Pleroma.Web.RichMedia.Helpers do
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.RichMedia.Parser
|
||||
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
||||
@options [
|
||||
pool: :media,
|
||||
max_body: 2_000_000,
|
||||
|
@ -17,7 +18,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do
|
|||
|
||||
@spec validate_page_url(URI.t() | binary()) :: :ok | :error
|
||||
defp validate_page_url(page_url) when is_binary(page_url) do
|
||||
validate_tld = Config.get([Pleroma.Formatter, :validate_tld])
|
||||
validate_tld = @config_impl.get([Pleroma.Formatter, :validate_tld])
|
||||
|
||||
page_url
|
||||
|> Linkify.Parser.url?(validate_tld: validate_tld)
|
||||
|
@ -27,10 +28,10 @@ defmodule Pleroma.Web.RichMedia.Helpers do
|
|||
defp validate_page_url(%URI{host: host, scheme: "https", authority: authority})
|
||||
when is_binary(authority) do
|
||||
cond do
|
||||
host in Config.get([:rich_media, :ignore_hosts], []) ->
|
||||
host in @config_impl.get([:rich_media, :ignore_hosts], []) ->
|
||||
:error
|
||||
|
||||
get_tld(host) in Config.get([:rich_media, :ignore_tld], []) ->
|
||||
get_tld(host) in @config_impl.get([:rich_media, :ignore_tld], []) ->
|
||||
:error
|
||||
|
||||
true ->
|
||||
|
@ -56,7 +57,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do
|
|||
end
|
||||
|
||||
def fetch_data_for_object(object) do
|
||||
with true <- Config.get([:rich_media, :enabled]),
|
||||
with true <- @config_impl.get([:rich_media, :enabled]),
|
||||
{:ok, page_url} <-
|
||||
HTML.extract_first_external_url_from_object(object),
|
||||
:ok <- validate_page_url(page_url),
|
||||
|
@ -68,7 +69,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do
|
|||
end
|
||||
|
||||
def fetch_data_for_activity(%Activity{data: %{"type" => "Create"}} = activity) do
|
||||
with true <- Config.get([:rich_media, :enabled]),
|
||||
with true <- @config_impl.get([:rich_media, :enabled]),
|
||||
%Object{} = object <- Object.normalize(activity, fetch: false) do
|
||||
fetch_data_for_object(object)
|
||||
else
|
||||
|
|
|
@ -75,7 +75,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
|
|||
end
|
||||
|
||||
defp log_error(url, reason) do
|
||||
Logger.warn(fn -> "Rich media error for #{url}: #{inspect(reason)}" end)
|
||||
Logger.warning(fn -> "Rich media error for #{url}: #{inspect(reason)}" end)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -471,6 +471,8 @@ defmodule Pleroma.Web.Router do
|
|||
get("/main/ostatus", UtilController, :show_subscribe_form)
|
||||
get("/ostatus_subscribe", RemoteFollowController, :follow)
|
||||
post("/ostatus_subscribe", RemoteFollowController, :do_follow)
|
||||
|
||||
get("/authorize_interaction", RemoteFollowController, :authorize_interaction)
|
||||
end
|
||||
|
||||
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
|
||||
|
@ -781,11 +783,14 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
scope "/api/v2", Pleroma.Web.MastodonAPI do
|
||||
pipe_through(:api)
|
||||
|
||||
get("/search", SearchController, :search2)
|
||||
|
||||
post("/media", MediaController, :create2)
|
||||
|
||||
get("/suggestions", SuggestionController, :index2)
|
||||
|
||||
get("/instance", InstanceController, :show2)
|
||||
end
|
||||
|
||||
scope "/api", Pleroma.Web do
|
||||
|
|
|
@ -121,6 +121,13 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
|
|||
render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
|
||||
end
|
||||
|
||||
# GET /authorize_interaction
|
||||
#
|
||||
def authorize_interaction(conn, %{"uri" => uri}) do
|
||||
conn
|
||||
|> redirect(to: Routes.remote_follow_path(conn, :follow, %{acct: uri}))
|
||||
end
|
||||
|
||||
defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do
|
||||
render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})
|
||||
end
|
||||
|
|
|
@ -70,7 +70,7 @@ defmodule Pleroma.Web.WebFinger do
|
|||
|
||||
def represent_user(user, "JSON") do
|
||||
%{
|
||||
"subject" => "acct:#{user.nickname}@#{domain()}",
|
||||
"subject" => "acct:#{user.nickname}@#{host()}",
|
||||
"aliases" => gather_aliases(user),
|
||||
"links" => gather_links(user)
|
||||
}
|
||||
|
@ -90,13 +90,13 @@ defmodule Pleroma.Web.WebFinger do
|
|||
:XRD,
|
||||
%{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
|
||||
[
|
||||
{:Subject, "acct:#{user.nickname}@#{domain()}"}
|
||||
{:Subject, "acct:#{user.nickname}@#{host()}"}
|
||||
] ++ aliases ++ links
|
||||
}
|
||||
|> XmlBuilder.to_doc()
|
||||
end
|
||||
|
||||
defp domain do
|
||||
def host do
|
||||
Pleroma.Config.get([__MODULE__, :domain]) || Pleroma.Web.Endpoint.host()
|
||||
end
|
||||
|
||||
|
@ -163,7 +163,7 @@ defmodule Pleroma.Web.WebFinger do
|
|||
get_template_from_xml(body)
|
||||
else
|
||||
error ->
|
||||
Logger.warn("Can't find LRDD template in #{inspect(meta_url)}: #{inspect(error)}")
|
||||
Logger.warning("Can't find LRDD template in #{inspect(meta_url)}: #{inspect(error)}")
|
||||
{:error, :lrdd_not_found}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,24 +3,56 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Workers.ReceiverWorker do
|
||||
alias Pleroma.Signature
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Federator
|
||||
|
||||
use Pleroma.Workers.WorkerHelper, queue: "federator_incoming"
|
||||
|
||||
@impl Oban.Worker
|
||||
|
||||
def perform(%Job{
|
||||
args: %{"op" => "incoming_ap_doc", "req_headers" => req_headers, "params" => params}
|
||||
}) do
|
||||
# Oban's serialization converts our tuple headers to lists.
|
||||
# Revert it for the signature validation.
|
||||
req_headers = Enum.into(req_headers, [], &List.to_tuple(&1))
|
||||
|
||||
conn_data = %{params: params, req_headers: req_headers}
|
||||
|
||||
with {:ok, %User{} = _actor} <- User.get_or_fetch_by_ap_id(conn_data.params["actor"]),
|
||||
{:ok, _public_key} <- Signature.refetch_public_key(conn_data),
|
||||
{:signature, true} <- {:signature, HTTPSignatures.validate_conn(conn_data)},
|
||||
{:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
|
||||
{:ok, res}
|
||||
else
|
||||
e -> process_errors(e)
|
||||
end
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do
|
||||
with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do
|
||||
{:ok, res}
|
||||
else
|
||||
e -> process_errors(e)
|
||||
end
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(%_{args: %{"timeout" => timeout}}), do: timeout
|
||||
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
|
||||
defp process_errors(errors) do
|
||||
case errors do
|
||||
{:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}
|
||||
{:error, :already_present} -> {:cancel, :already_present}
|
||||
{:error, {:validate_object, reason}} -> {:cancel, reason}
|
||||
{:error, {:error, {:validate, reason}}} -> {:cancel, reason}
|
||||
{:error, {:reject, reason}} -> {:cancel, reason}
|
||||
{:signature, false} -> {:cancel, :invalid_signature}
|
||||
{:error, {:error, reason = "Object has been deleted"}} -> {:cancel, reason}
|
||||
e -> e
|
||||
end
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
4
mix.exs
4
mix.exs
|
@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
|
|||
def project do
|
||||
[
|
||||
app: :pleroma,
|
||||
version: version("2.6.50"),
|
||||
version: version("2.6.51"),
|
||||
elixir: "~> 1.11",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
compilers: Mix.compilers(),
|
||||
|
@ -184,7 +184,7 @@ defmodule Pleroma.Mixfile do
|
|||
{:majic, "~> 1.0"},
|
||||
{:open_api_spex, "~> 3.16"},
|
||||
{:ecto_psql_extras, "~> 0.6"},
|
||||
{:vix, "~> 0.25.0"},
|
||||
{:vix, "~> 0.26.0"},
|
||||
{:elixir_make, "~> 0.7.7", override: true},
|
||||
{:blurhash, "~> 0.1.0", hex: :rinpatch_blurhash},
|
||||
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -137,7 +137,7 @@
|
|||
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
|
||||
"vix": {:hex, :vix, "0.25.0", "b294ca3140c0357b262d86e9966949949844282b81923bb990668c1ee5a35337", [:make, :mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.1.4 or ~> 0.2", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7.3 or ~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "be09c96982978bc2d0c501a73e0b65ba58ec94c1afb94e3617029d6ce7ae8c3f"},
|
||||
"vix": {:hex, :vix, "0.26.0", "027f10b6969b759318be84bd0bd8c88af877445e4e41cf96a0460392cea5399c", [:make, :mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:cc_precompiler, "~> 0.1.4 or ~> 0.2", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7.3 or ~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:kino, "~> 0.7", [hex: :kino, repo: "hexpm", optional: true]}], "hexpm", "71b0a79ae7f199cacfc8e679b0e4ba25ee47dc02e182c5b9097efb29fbe14efd"},
|
||||
"web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
|
||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||
"websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"},
|
||||
|
|
|
@ -7,13 +7,13 @@ defmodule Pleroma.Repo.Migrations.AddTrigramExtension do
|
|||
require Logger
|
||||
|
||||
def up do
|
||||
Logger.warn("ATTENTION ATTENTION ATTENTION\n")
|
||||
Logger.warning("ATTENTION ATTENTION ATTENTION\n")
|
||||
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n"
|
||||
)
|
||||
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n"
|
||||
)
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ defmodule Pleroma.Repo.Migrations.AddFollowingAddressFromSourceData do
|
|||
|> Pleroma.Repo.update()
|
||||
|
||||
user ->
|
||||
Logger.warn("User #{user.id} / #{user.nickname} does not seem to have source_data")
|
||||
Logger.warning("User #{user.id} / #{user.nickname} does not seem to have source_data")
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -63,7 +63,7 @@ defmodule Pleroma.Repo.Migrations.DataMigrationPopulateUserRelationships do
|
|||
ON CONFLICT (source_id, relationship_type, target_id) DO NOTHING
|
||||
""")
|
||||
else
|
||||
_ -> Logger.warn("Unresolved #{field} reference: (#{source_uuid}, #{target_id})")
|
||||
_ -> Logger.warning("Unresolved #{field} reference: (#{source_uuid}, #{target_id})")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Repo.Migrations.ApIdNotNull do
|
|||
require Logger
|
||||
|
||||
def up do
|
||||
Logger.warn(
|
||||
Logger.warning(
|
||||
"If this migration fails please open an issue at https://git.pleroma.social/pleroma/pleroma/-/issues/new \n"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
|
||||
defmodule Pleroma.Repo.Migrations.AddQuoteUrlIndexToObjects do
|
||||
use Ecto.Migration
|
||||
@disable_ddl_transaction true
|
||||
|
||||
def change do
|
||||
create_if_not_exists(index(:objects, ["(data->'quoteUrl')"], name: :objects_quote_url))
|
||||
create_if_not_exists(
|
||||
index(:objects, ["(data->'quoteUrl')"],
|
||||
name: :objects_quote_url,
|
||||
concurrently: true
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,30 +36,45 @@ defmodule Pleroma.HTML.Scrubber.Default do
|
|||
Meta.allow_tag_with_these_attributes(:a, ["name", "title", "lang"])
|
||||
|
||||
Meta.allow_tag_with_these_attributes(:abbr, ["title", "lang"])
|
||||
Meta.allow_tag_with_these_attributes(:acronym, ["title", "lang"])
|
||||
|
||||
Meta.allow_tag_with_these_attributes(:b, ["lang"])
|
||||
# sort(1)-ed list
|
||||
Meta.allow_tag_with_these_attributes(:bdi, [])
|
||||
Meta.allow_tag_with_these_attributes(:bdo, ["dir"])
|
||||
Meta.allow_tag_with_these_attributes(:big, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:b, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:blockquote, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:br, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:cite, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:code, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:del, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:dfn, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:em, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:hr, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:i, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:ins, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:kbd, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:li, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:ol, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:p, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:pre, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:q, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rb, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rp, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rtc, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rt, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:ruby, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:samp, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:s, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:small, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:strong, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:sub, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:sup, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:ruby, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rb, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rp, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rt, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:rtc, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:tt, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:u, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:ul, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:var, ["lang"])
|
||||
Meta.allow_tag_with_these_attributes(:wbr, ["lang"])
|
||||
|
||||
Meta.allow_tag_with_this_attribute_values(:span, "class", [
|
||||
"h-card",
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><script defer=defer src=/static/js/3733.7060d1e6bca813125a0c.js></script><script defer=defer src=/static/js/app.7c4b412b26221a7c8572.js></script><link href=/static/css/app.c18a2c80794a1b699a61.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><div id=modal></div><div id=popovers></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><link rel=icon type=image/png href=/favicon.png><!--server-generated-meta--><script defer=defer src=/static/js/3733.7060d1e6bca813125a0c.js></script><script defer=defer src=/static/js/app.d42ab31e1d50a3265a82.js></script><link href=/static/css/app.a7f63ee9107a77599942.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><div id=modal></div><div id=popovers></body></html>
|
|
@ -0,0 +1,2 @@
|
|||
.ModifiedIndicator{display:inline-block;position:relative}.modified-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.ProfileSettingIndicator{display:inline-block;position:relative}.profilesetting-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.DraftButtons{display:inline-block;position:relative}.DraftButtons .button-default{margin-left:.5em}.draft-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.AttachmentSetting .attachment{display:block;height:15em;margin-bottom:.5em;width:100%}.AttachmentSetting .attachment-input{display:flex;flex-direction:column;margin-left:1em;width:20em}.AttachmentSetting.-compact .attachment-input{align-items:flex-end;flex-direction:row}.AttachmentSetting.-compact .attachment{align-self:center;display:block;flex:0;height:4em;margin-bottom:0;min-width:4em;order:0}.AttachmentSetting.-compact .control-field{margin-left:.5em;min-width:12em;order:1}.AttachmentSetting.-compact .control-upload{min-width:12em;order:2;padding:0 .5em}.AttachmentSetting .controls{margin-bottom:.5em}.AttachmentSetting .controls button,.AttachmentSetting .controls input{width:100%}.frontends-tab .cards-list{padding:0}.frontends-tab .relative{position:relative}.frontends-tab .overlay{background:var(--bg);bottom:0;left:0;opacity:.9;position:absolute;right:0;top:0;z-index:2}.frontends-tab dd{word-wrap:nowrap;max-width:10em;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.settings_tab-switcher{height:100%}.settings_tab-switcher .setting-item{border-bottom:2px solid var(--fg,#182230);margin:1em 1em 1.4em;padding-bottom:1.4em}.settings_tab-switcher .setting-item>div,.settings_tab-switcher .setting-item>label{display:block;margin-bottom:.5em}.settings_tab-switcher .setting-item>div:last-child,.settings_tab-switcher .setting-item>label:last-child{margin-bottom:0}.settings_tab-switcher .setting-item .select-multiple{display:flex}.settings_tab-switcher .setting-item .select-multiple .option-list{margin:0;padding-left:.5em}.settings_tab-switcher .setting-item:last-child{border-bottom:none;margin-bottom:1em;padding-bottom:0}.settings_tab-switcher .setting-item select{min-width:10em}.settings_tab-switcher .setting-item textarea{height:100px;max-width:100%;width:100%}.settings_tab-switcher .setting-item .unavailable,.settings_tab-switcher .setting-item .unavailable svg{color:var(--cRed,red);color:red}
|
||||
/*# sourceMappingURL=8859.d26a3b0841a7beb8fd4a.css.map*/
|
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
|||
.ModifiedIndicator{display:inline-block;position:relative}.modified-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.ProfileSettingIndicator{display:inline-block;position:relative}.profilesetting-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.DraftButtons{display:inline-block;position:relative}.DraftButtons .button-default{margin-left:.5em}.draft-tooltip{margin:.5em 1em;min-width:10em;text-align:center}.AttachmentSetting .attachment{display:block;height:15em;margin-bottom:.5em;width:100%}.AttachmentSetting .attachment-input{display:flex;flex-direction:column;margin-left:1em;width:20em}.AttachmentSetting .controls{margin-bottom:.5em}.AttachmentSetting .controls button,.AttachmentSetting .controls input{width:100%}.frontends-tab .cards-list{padding:0}.frontends-tab dd{word-wrap:nowrap;max-width:10em;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.settings_tab-switcher{height:100%}.settings_tab-switcher .setting-item{border-bottom:2px solid var(--fg,#182230);margin:1em 1em 1.4em;padding-bottom:1.4em}.settings_tab-switcher .setting-item>div,.settings_tab-switcher .setting-item>label{display:block;margin-bottom:.5em}.settings_tab-switcher .setting-item>div:last-child,.settings_tab-switcher .setting-item>label:last-child{margin-bottom:0}.settings_tab-switcher .setting-item .select-multiple{display:flex}.settings_tab-switcher .setting-item .select-multiple .option-list{margin:0;padding-left:.5em}.settings_tab-switcher .setting-item:last-child{border-bottom:none;margin-bottom:1em;padding-bottom:0}.settings_tab-switcher .setting-item select{min-width:10em}.settings_tab-switcher .setting-item textarea{height:100px;max-width:100%;width:100%}.settings_tab-switcher .setting-item .unavailable,.settings_tab-switcher .setting-item .unavailable svg{color:var(--cRed,red);color:red}
|
||||
/*# sourceMappingURL=9801.cfe503d4c949ae0c3813.css.map*/
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"static/css/9801.cfe503d4c949ae0c3813.css","mappings":"AACA,mBACE,qBACA,kBAGF,kBACE,gBACA,eACA,kBCRF,yBACE,qBACA,kBAGF,wBACE,gBACA,eACA,kBCRF,cACE,qBACA,kBAEA,8BACE,iBAIJ,eACE,gBACA,eACA,kBCXA,+BACE,cAEA,YACA,mBAFA,UAEA,CAGF,qCAEE,aACA,sBAFA,gBAGA,WAGF,6BACE,mBAEA,uEAEE,WCpBJ,2BACE,UAGF,kBAEE,iBAGA,eADA,kBAHA,uBAEA,kBAEA,CCRJ,uBACE,YAEA,qCACE,0CACA,qBACA,qBAEA,oFAEE,cACA,mBAEA,0GACE,gBAIJ,sDACE,aAEA,mEACE,SACA,kBAIJ,gDACE,mBAEA,kBADA,gBACA,CAGF,4CACE,eAGF,8CAGE,aADA,eADA,UAEA,CAGF,wGAEE,sBACA,SCnCW","sources":["webpack://pleroma_fe/./src/components/settings_modal/helpers/modified_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/profile_setting_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/draft_buttons.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/attachment_setting.vue","webpack://pleroma_fe/./src/components/settings_modal/admin_tabs/frontends_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/settings_modal_admin_content.scss","webpack://pleroma_fe/./src/_variables.scss"],"sourcesContent":["\n.ModifiedIndicator {\n display: inline-block;\n position: relative;\n}\n\n.modified-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.ProfileSettingIndicator {\n display: inline-block;\n position: relative;\n}\n\n.profilesetting-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.DraftButtons {\n display: inline-block;\n position: relative;\n\n .button-default {\n margin-left: 0.5em;\n }\n}\n\n.draft-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.AttachmentSetting {\n .attachment {\n display: block;\n width: 100%;\n height: 15em;\n margin-bottom: 0.5em;\n }\n\n .attachment-input {\n margin-left: 1em;\n display: flex;\n flex-direction: column;\n width: 20em;\n }\n\n .controls {\n margin-bottom: 0.5em;\n\n input,\n button {\n width: 100%;\n }\n }\n}\n",".frontends-tab {\n .cards-list {\n padding: 0;\n }\n\n dd {\n text-overflow: ellipsis;\n word-wrap: nowrap;\n white-space: nowrap;\n overflow-x: hidden;\n max-width: 10em;\n }\n}\n","@import \"src/variables\";\n\n.settings_tab-switcher {\n height: 100%;\n\n .setting-item {\n border-bottom: 2px solid var(--fg, $fallback--fg);\n margin: 1em 1em 1.4em;\n padding-bottom: 1.4em;\n\n > div,\n > label {\n display: block;\n margin-bottom: 0.5em;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .select-multiple {\n display: flex;\n\n .option-list {\n margin: 0;\n padding-left: 0.5em;\n }\n }\n\n &:last-child {\n border-bottom: none;\n padding-bottom: 0;\n margin-bottom: 1em;\n }\n\n select {\n min-width: 10em;\n }\n\n textarea {\n width: 100%;\n max-width: 100%;\n height: 100px;\n }\n\n .unavailable,\n .unavailable svg {\n color: var(--cRed, $fallback--cRed);\n color: $fallback--cRed;\n }\n }\n}\n","$main-color: #f58d2c;\n$main-background: white;\n$darkened-background: whitesmoke;\n\n$fallback--bg: #121a24;\n$fallback--fg: #182230;\n$fallback--faint: rgb(185 185 186 / 50%);\n$fallback--text: #b9b9ba;\n$fallback--link: #d8a070;\n$fallback--icon: #666;\n$fallback--lightBg: rgb(21 30 42);\n$fallback--lightText: #b9b9ba;\n$fallback--border: #222;\n$fallback--cRed: #f00;\n$fallback--cBlue: #0095ff;\n$fallback--cGreen: #0fa00f;\n$fallback--cOrange: orange;\n\n$fallback--alertError: rgb(211 16 20 / 50%);\n$fallback--alertWarning: rgb(111 111 20 / 50%);\n\n$fallback--panelRadius: 10px;\n$fallback--checkboxRadius: 2px;\n$fallback--btnRadius: 4px;\n$fallback--inputRadius: 4px;\n$fallback--tooltipRadius: 5px;\n$fallback--avatarRadius: 4px;\n$fallback--avatarAltRadius: 10px;\n$fallback--attachmentRadius: 10px;\n$fallback--chatMessageRadius: 10px;\n\n$fallback--buttonShadow: 0 0 2px 0 rgb(0 0 0 / 100%),\n 0 1px 0 0 rgb(255 255 255 / 20%) inset,\n 0 -1px 0 0 rgb(0 0 0 / 20%) inset;\n\n$status-margin: 0.75em;\n"],"names":[],"sourceRoot":""}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue