forked from AkkomaGang/akkoma
Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
This commit is contained in:
commit
5f4fc0c373
24 changed files with 167 additions and 100 deletions
|
@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Deprecated `User.Info` embedded schema (fields moved to `User`)
|
- Deprecated `User.Info` embedded schema (fields moved to `User`)
|
||||||
- Store status data inside Flag activity
|
- Store status data inside Flag activity
|
||||||
- Deprecated (reorganized as `UserRelationship` entity) User fields with user AP IDs (`blocks`, `mutes`, `muted_reblogs`, `muted_notifications`, `subscribers`).
|
- Deprecated (reorganized as `UserRelationship` entity) User fields with user AP IDs (`blocks`, `mutes`, `muted_reblogs`, `muted_notifications`, `subscribers`).
|
||||||
|
- Logger: default log level changed from `warn` to `info`.
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
|
||||||
|
@ -51,6 +52,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Support for `X-Forwarded-For` and similar HTTP headers which used by reverse proxies to pass a real user IP address to the backend. Must not be enabled unless your instance is behind at least one reverse proxy (such as Nginx, Apache HTTPD or Varnish Cache).
|
- Support for `X-Forwarded-For` and similar HTTP headers which used by reverse proxies to pass a real user IP address to the backend. Must not be enabled unless your instance is behind at least one reverse proxy (such as Nginx, Apache HTTPD or Varnish Cache).
|
||||||
- MRF: New module which handles incoming posts based on their age. By default, all incoming posts that are older than 2 days will be unlisted and not shown to their followers.
|
- MRF: New module which handles incoming posts based on their age. By default, all incoming posts that are older than 2 days will be unlisted and not shown to their followers.
|
||||||
- User notification settings: Add `privacy_option` option.
|
- User notification settings: Add `privacy_option` option.
|
||||||
|
- Support for custom Elixir modules (such as MRF policies)
|
||||||
- User settings: Add _This account is a_ option.
|
- User settings: Add _This account is a_ option.
|
||||||
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
|
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
|
||||||
<details>
|
<details>
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha,
|
config :pleroma, Pleroma.Captcha,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
seconds_valid: 60,
|
seconds_valid: 3000,
|
||||||
method: Pleroma.Captcha.Native
|
method: Pleroma.Captcha.Native
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
|
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
|
||||||
|
@ -621,6 +621,8 @@
|
||||||
activity_pub: nil,
|
activity_pub: nil,
|
||||||
activity_pub_question: 30_000
|
activity_pub_question: 30_000
|
||||||
|
|
||||||
|
config :pleroma, :modules, runtime_dir: "instance/modules"
|
||||||
|
|
||||||
config :swarm, node_blacklist: [~r/myhtml_.*$/]
|
config :swarm, node_blacklist: [~r/myhtml_.*$/]
|
||||||
# Import environment specific config. This must remain at the bottom
|
# Import environment specific config. This must remain at the bottom
|
||||||
# of this file so it overrides the configuration defined above.
|
# of this file so it overrides the configuration defined above.
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
config :phoenix, serve_endpoints: true
|
config :phoenix, serve_endpoints: true
|
||||||
|
|
||||||
# Do not print debug messages in production
|
# Do not print debug messages in production
|
||||||
config :logger, :console, level: :warn
|
config :logger, :console, level: :info
|
||||||
config :logger, :ex_syslogger, level: :warn
|
config :logger, :ex_syslogger, level: :info
|
||||||
|
|
||||||
# ## SSL Support
|
# ## SSL Support
|
||||||
#
|
#
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
|
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
|
||||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
|
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
|
||||||
|
config :pleroma, :modules, runtime_dir: "/var/lib/pleroma/modules"
|
||||||
|
|
||||||
config_path = System.get_env("PLEROMA_CONFIG_PATH") || "/etc/pleroma/config.exs"
|
config_path = System.get_env("PLEROMA_CONFIG_PATH") || "/etc/pleroma/config.exs"
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,8 @@
|
||||||
|
|
||||||
config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
|
config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
|
||||||
|
|
||||||
|
config :pleroma, :modules, runtime_dir: "test/fixtures/modules"
|
||||||
|
|
||||||
if File.exists?("./config/test.secret.exs") do
|
if File.exists?("./config/test.secret.exs") do
|
||||||
import_config "test.secret.exs"
|
import_config "test.secret.exs"
|
||||||
else
|
else
|
||||||
|
|
|
@ -70,59 +70,6 @@ Request parameters can be passed via [query strings](https://en.wikipedia.org/wi
|
||||||
* Response: JSON. Returns `{"status": "success"}` if the account was successfully disabled, `{"error": "[error message]"}` otherwise
|
* Response: JSON. Returns `{"status": "success"}` if the account was successfully disabled, `{"error": "[error message]"}` otherwise
|
||||||
* Example response: `{"error": "Invalid password."}`
|
* Example response: `{"error": "Invalid password."}`
|
||||||
|
|
||||||
## `/api/account/register`
|
|
||||||
### Register a new user
|
|
||||||
* Method `POST`
|
|
||||||
* Authentication: not required
|
|
||||||
* Params:
|
|
||||||
* `nickname`
|
|
||||||
* `fullname`
|
|
||||||
* `bio`
|
|
||||||
* `email`
|
|
||||||
* `password`
|
|
||||||
* `confirm`
|
|
||||||
* `captcha_solution`: optional, contains provider-specific captcha solution,
|
|
||||||
* `captcha_token`: optional, contains provider-specific captcha token
|
|
||||||
* `token`: invite token required when the registrations aren't public.
|
|
||||||
* Response: JSON. Returns a user object on success, otherwise returns `{"error": "error_msg"}`
|
|
||||||
* Example response:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"background_image": null,
|
|
||||||
"cover_photo": "https://pleroma.soykaf.com/images/banner.png",
|
|
||||||
"created_at": "Tue Dec 18 16:55:56 +0000 2018",
|
|
||||||
"default_scope": "public",
|
|
||||||
"description": "blushy-crushy fediverse idol + pleroma dev\nlet's be friends \nぷれろまの生徒会長。謎の外人。日本語OK. \n公主病.",
|
|
||||||
"description_html": "blushy-crushy fediverse idol + pleroma dev.<br />let's be friends <br />ぷれろまの生徒会長。謎の外人。日本語OK. <br />公主病.",
|
|
||||||
"favourites_count": 0,
|
|
||||||
"fields": [],
|
|
||||||
"followers_count": 0,
|
|
||||||
"following": false,
|
|
||||||
"follows_you": false,
|
|
||||||
"friends_count": 0,
|
|
||||||
"id": 6,
|
|
||||||
"is_local": true,
|
|
||||||
"locked": false,
|
|
||||||
"name": "lain",
|
|
||||||
"name_html": "lain",
|
|
||||||
"no_rich_text": false,
|
|
||||||
"pleroma": {
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
"profile_image_url": "https://pleroma.soykaf.com/images/avi.png",
|
|
||||||
"profile_image_url_https": "https://pleroma.soykaf.com/images/avi.png",
|
|
||||||
"profile_image_url_original": "https://pleroma.soykaf.com/images/avi.png",
|
|
||||||
"profile_image_url_profile_size": "https://pleroma.soykaf.com/images/avi.png",
|
|
||||||
"rights": {
|
|
||||||
"delete_others_notice": false
|
|
||||||
},
|
|
||||||
"screen_name": "lain",
|
|
||||||
"statuses_count": 0,
|
|
||||||
"statusnet_blocking": false,
|
|
||||||
"statusnet_profile_url": "https://pleroma.soykaf.com/users/lain"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## `/api/pleroma/admin/`…
|
## `/api/pleroma/admin/`…
|
||||||
See [Admin-API](admin_api.md)
|
See [Admin-API](admin_api.md)
|
||||||
|
|
||||||
|
|
|
@ -836,3 +836,7 @@ config :auto_linker,
|
||||||
rel: "ugc"
|
rel: "ugc"
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Custom Runtime Modules (`:modules`)
|
||||||
|
|
||||||
|
* `runtime_dir`: A path to custom Elixir modules (such as MRF policies).
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Application do
|
defmodule Pleroma.Application do
|
||||||
import Cachex.Spec
|
import Cachex.Spec
|
||||||
use Application
|
use Application
|
||||||
|
require Logger
|
||||||
|
|
||||||
@name Mix.Project.config()[:name]
|
@name Mix.Project.config()[:name]
|
||||||
@version Mix.Project.config()[:version]
|
@version Mix.Project.config()[:version]
|
||||||
|
@ -33,6 +34,7 @@ def start(_type, _args) do
|
||||||
Pleroma.HTML.compile_scrubbers()
|
Pleroma.HTML.compile_scrubbers()
|
||||||
Pleroma.Config.DeprecationWarnings.warn()
|
Pleroma.Config.DeprecationWarnings.warn()
|
||||||
setup_instrumenters()
|
setup_instrumenters()
|
||||||
|
load_custom_modules()
|
||||||
|
|
||||||
# Define workers and child supervisors to be supervised
|
# Define workers and child supervisors to be supervised
|
||||||
children =
|
children =
|
||||||
|
@ -68,6 +70,28 @@ def start(_type, _args) do
|
||||||
Supervisor.start_link(children, opts)
|
Supervisor.start_link(children, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_custom_modules do
|
||||||
|
dir = Pleroma.Config.get([:modules, :runtime_dir])
|
||||||
|
|
||||||
|
if dir && File.exists?(dir) do
|
||||||
|
dir
|
||||||
|
|> Pleroma.Utils.compile_dir()
|
||||||
|
|> case do
|
||||||
|
{:error, _errors, _warnings} ->
|
||||||
|
raise "Invalid custom modules"
|
||||||
|
|
||||||
|
{:ok, modules, _warnings} ->
|
||||||
|
if @env != :test do
|
||||||
|
Enum.each(modules, fn mod ->
|
||||||
|
Logger.info("Custom module loaded: #{inspect(mod)}")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp setup_instrumenters do
|
defp setup_instrumenters do
|
||||||
require Prometheus.Registry
|
require Prometheus.Registry
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,7 @@ def compile_scrubbers do
|
||||||
dir = Path.join(:code.priv_dir(:pleroma), "scrubbers")
|
dir = Path.join(:code.priv_dir(:pleroma), "scrubbers")
|
||||||
|
|
||||||
dir
|
dir
|
||||||
|> File.ls!()
|
|> Pleroma.Utils.compile_dir()
|
||||||
|> Enum.map(&Path.join(dir, &1))
|
|
||||||
|> Kernel.ParallelCompiler.compile()
|
|
||||||
|> case do
|
|> case do
|
||||||
{:error, _errors, _warnings} ->
|
{:error, _errors, _warnings} ->
|
||||||
raise "Compiling scrubbers failed"
|
raise "Compiling scrubbers failed"
|
||||||
|
|
|
@ -154,7 +154,7 @@ defp maybe_date_fetch(headers, date) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_and_contain_remote_object_from_id(id) when is_binary(id) do
|
def fetch_and_contain_remote_object_from_id(id) when is_binary(id) do
|
||||||
Logger.info("Fetching object #{id} via AP")
|
Logger.debug("Fetching object #{id} via AP")
|
||||||
|
|
||||||
date = Pleroma.Signature.signed_date()
|
date = Pleroma.Signature.signed_date()
|
||||||
|
|
||||||
|
|
12
lib/pleroma/utils.ex
Normal file
12
lib/pleroma/utils.ex
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Utils do
|
||||||
|
def compile_dir(dir) when is_binary(dir) do
|
||||||
|
dir
|
||||||
|
|> File.ls!()
|
||||||
|
|> Enum.map(&Path.join(dir, &1))
|
||||||
|
|> Kernel.ParallelCompiler.compile()
|
||||||
|
end
|
||||||
|
end
|
|
@ -1298,27 +1298,25 @@ defp object_to_user_data(data) do
|
||||||
def fetch_follow_information_for_user(user) do
|
def fetch_follow_information_for_user(user) do
|
||||||
with {:ok, following_data} <-
|
with {:ok, following_data} <-
|
||||||
Fetcher.fetch_and_contain_remote_object_from_id(user.following_address),
|
Fetcher.fetch_and_contain_remote_object_from_id(user.following_address),
|
||||||
following_count when is_integer(following_count) <- following_data["totalItems"],
|
|
||||||
{:ok, hide_follows} <- collection_private(following_data),
|
{:ok, hide_follows} <- collection_private(following_data),
|
||||||
{:ok, followers_data} <-
|
{:ok, followers_data} <-
|
||||||
Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address),
|
Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address),
|
||||||
followers_count when is_integer(followers_count) <- followers_data["totalItems"],
|
|
||||||
{:ok, hide_followers} <- collection_private(followers_data) do
|
{:ok, hide_followers} <- collection_private(followers_data) do
|
||||||
{:ok,
|
{:ok,
|
||||||
%{
|
%{
|
||||||
hide_follows: hide_follows,
|
hide_follows: hide_follows,
|
||||||
follower_count: followers_count,
|
follower_count: normalize_counter(followers_data["totalItems"]),
|
||||||
following_count: following_count,
|
following_count: normalize_counter(following_data["totalItems"]),
|
||||||
hide_followers: hide_followers
|
hide_followers: hide_followers
|
||||||
}}
|
}}
|
||||||
else
|
else
|
||||||
{:error, _} = e ->
|
{:error, _} = e -> e
|
||||||
e
|
e -> {:error, e}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
e ->
|
defp normalize_counter(counter) when is_integer(counter), do: counter
|
||||||
{:error, e}
|
defp normalize_counter(_), do: 0
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp maybe_update_follow_information(data) do
|
defp maybe_update_follow_information(data) do
|
||||||
with {:enabled, true} <-
|
with {:enabled, true} <-
|
||||||
|
@ -1339,24 +1337,18 @@ defp maybe_update_follow_information(data) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp collection_private(%{"first" => %{"type" => type}})
|
||||||
|
when type in ["CollectionPage", "OrderedCollectionPage"],
|
||||||
|
do: {:ok, false}
|
||||||
|
|
||||||
defp collection_private(%{"first" => first}) do
|
defp collection_private(%{"first" => first}) do
|
||||||
if is_map(first) and
|
|
||||||
first["type"] in ["CollectionPage", "OrderedCollectionPage"] do
|
|
||||||
{:ok, false}
|
|
||||||
else
|
|
||||||
with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <-
|
with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <-
|
||||||
Fetcher.fetch_and_contain_remote_object_from_id(first) do
|
Fetcher.fetch_and_contain_remote_object_from_id(first) do
|
||||||
{:ok, false}
|
{:ok, false}
|
||||||
else
|
else
|
||||||
{:error, {:ok, %{status: code}}} when code in [401, 403] ->
|
{:error, {:ok, %{status: code}}} when code in [401, 403] -> {:ok, true}
|
||||||
{:ok, true}
|
{:error, _} = e -> e
|
||||||
|
e -> {:error, e}
|
||||||
{:error, _} = e ->
|
|
||||||
e
|
|
||||||
|
|
||||||
e ->
|
|
||||||
{:error, e}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ def inbox(%{assigns: %{valid_signature: true}} = conn, params) do
|
||||||
|
|
||||||
# only accept relayed Creates
|
# only accept relayed Creates
|
||||||
def inbox(conn, %{"type" => "Create"} = params) do
|
def inbox(conn, %{"type" => "Create"} = params) do
|
||||||
Logger.info(
|
Logger.debug(
|
||||||
"Signature missing or not from author, relayed Create message, fetching object from source"
|
"Signature missing or not from author, relayed Create message, fetching object from source"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -270,11 +270,11 @@ def inbox(conn, params) do
|
||||||
headers = Enum.into(conn.req_headers, %{})
|
headers = Enum.into(conn.req_headers, %{})
|
||||||
|
|
||||||
if String.contains?(headers["signature"], params["actor"]) do
|
if String.contains?(headers["signature"], params["actor"]) do
|
||||||
Logger.info(
|
Logger.debug(
|
||||||
"Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
|
"Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
|
||||||
)
|
)
|
||||||
|
|
||||||
Logger.info(inspect(conn.req_headers))
|
Logger.debug(inspect(conn.req_headers))
|
||||||
end
|
end
|
||||||
|
|
||||||
json(conn, dgettext("errors", "error"))
|
json(conn, dgettext("errors", "error"))
|
||||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DropPolicy do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def filter(object) do
|
def filter(object) do
|
||||||
Logger.info("REJECTING #{inspect(object)}")
|
Logger.debug("REJECTING #{inspect(object)}")
|
||||||
{:reject, object}
|
{:reject, object}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
|
||||||
]
|
]
|
||||||
|
|
||||||
def perform(:prefetch, url) do
|
def perform(:prefetch, url) do
|
||||||
Logger.info("Prefetching #{inspect(url)}")
|
Logger.debug("Prefetching #{inspect(url)}")
|
||||||
|
|
||||||
url
|
url
|
||||||
|> MediaProxy.url()
|
|> MediaProxy.url()
|
||||||
|
|
|
@ -48,7 +48,7 @@ def is_representable?(%Activity{} = activity) do
|
||||||
* `id`: the ActivityStreams URI of the message
|
* `id`: the ActivityStreams URI of the message
|
||||||
"""
|
"""
|
||||||
def publish_one(%{inbox: inbox, json: json, actor: %User{} = actor, id: id} = params) do
|
def publish_one(%{inbox: inbox, json: json, actor: %User{} = actor, id: id} = params) do
|
||||||
Logger.info("Federating #{id} to #{inbox}")
|
Logger.debug("Federating #{id} to #{inbox}")
|
||||||
%{host: host, path: path} = URI.parse(inbox)
|
%{host: host, path: path} = URI.parse(inbox)
|
||||||
|
|
||||||
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
|
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
|
||||||
|
@ -228,7 +228,7 @@ def publish(%User{} = actor, %Activity{} = activity) do
|
||||||
public = is_public?(activity)
|
public = is_public?(activity)
|
||||||
|
|
||||||
if public && Config.get([:instance, :allow_relay]) do
|
if public && Config.get([:instance, :allow_relay]) do
|
||||||
Logger.info(fn -> "Relaying #{activity.data["id"]} out" end)
|
Logger.debug(fn -> "Relaying #{activity.data["id"]} out" end)
|
||||||
Relay.publish(activity)
|
Relay.publish(activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ defmodule Pleroma.Web.Endpoint do
|
||||||
|
|
||||||
plug(Pleroma.Plugs.TrailingFormatPlug)
|
plug(Pleroma.Plugs.TrailingFormatPlug)
|
||||||
plug(Plug.RequestId)
|
plug(Plug.RequestId)
|
||||||
plug(Plug.Logger)
|
plug(Plug.Logger, log: :debug)
|
||||||
|
|
||||||
plug(Pleroma.Plugs.Parsers)
|
plug(Pleroma.Plugs.Parsers)
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ def perform(:publish, activity) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(:incoming_ap_doc, params) do
|
def perform(:incoming_ap_doc, params) do
|
||||||
Logger.info("Handling incoming AP activity")
|
Logger.debug("Handling incoming AP activity")
|
||||||
|
|
||||||
params = Utils.normalize_params(params)
|
params = Utils.normalize_params(params)
|
||||||
|
|
||||||
|
@ -71,13 +71,13 @@ def perform(:incoming_ap_doc, params) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
%Activity{} ->
|
%Activity{} ->
|
||||||
Logger.info("Already had #{params["id"]}")
|
Logger.debug("Already had #{params["id"]}")
|
||||||
:error
|
:error
|
||||||
|
|
||||||
_e ->
|
_e ->
|
||||||
# Just drop those for now
|
# Just drop those for now
|
||||||
Logger.info("Unhandled activity")
|
Logger.debug("Unhandled activity")
|
||||||
Logger.info(Jason.encode!(params, pretty: true))
|
Logger.debug(Jason.encode!(params, pretty: true))
|
||||||
:error
|
:error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,7 @@ def publish(%User{} = user, %Activity{} = activity) do
|
||||||
Config.get([:instance, :federation_publisher_modules])
|
Config.get([:instance, :federation_publisher_modules])
|
||||||
|> Enum.each(fn module ->
|
|> Enum.each(fn module ->
|
||||||
if module.is_representable?(activity) do
|
if module.is_representable?(activity) do
|
||||||
Logger.info("Publishing #{activity.data["id"]} using #{inspect(module)}")
|
Logger.debug("Publishing #{activity.data["id"]} using #{inspect(module)}")
|
||||||
module.publish(user, activity)
|
module.publish(user, activity)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -31,7 +31,7 @@ def build_tags(%{activity_id: id, object: object, user: user}) do
|
||||||
if attachments == [] or Metadata.activity_nsfw?(object) do
|
if attachments == [] or Metadata.activity_nsfw?(object) do
|
||||||
[
|
[
|
||||||
image_tag(user),
|
image_tag(user),
|
||||||
{:meta, [property: "twitter:card", content: "summary_large_image"], []}
|
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
attachments
|
attachments
|
||||||
|
|
9
test/fixtures/modules/runtime_module.ex
vendored
Normal file
9
test/fixtures/modules/runtime_module.ex
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule RuntimeModule do
|
||||||
|
@moduledoc """
|
||||||
|
This is a dummy module to test custom runtime modules.
|
||||||
|
"""
|
||||||
|
end
|
11
test/runtime_test.exs
Normal file
11
test/runtime_test.exs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.RuntimeTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
test "it loads custom runtime modules" do
|
||||||
|
assert Code.ensure_compiled?(RuntimeModule)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1623,6 +1623,44 @@ test "detects hidden follows/followers for friendica" do
|
||||||
assert follow_info.following_count == 32
|
assert follow_info.following_count == 32
|
||||||
assert follow_info.hide_follows == true
|
assert follow_info.hide_follows == true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "doesn't crash when follower and following counters are hidden" do
|
||||||
|
mock(fn env ->
|
||||||
|
case env.url do
|
||||||
|
"http://localhost:4001/users/masto_hidden_counters/following" ->
|
||||||
|
json(%{
|
||||||
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||||
|
"id" => "http://localhost:4001/users/masto_hidden_counters/followers"
|
||||||
|
})
|
||||||
|
|
||||||
|
"http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
|
||||||
|
%Tesla.Env{status: 403, body: ""}
|
||||||
|
|
||||||
|
"http://localhost:4001/users/masto_hidden_counters/followers" ->
|
||||||
|
json(%{
|
||||||
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||||
|
"id" => "http://localhost:4001/users/masto_hidden_counters/following"
|
||||||
|
})
|
||||||
|
|
||||||
|
"http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
|
||||||
|
%Tesla.Env{status: 403, body: ""}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
user =
|
||||||
|
insert(:user,
|
||||||
|
local: false,
|
||||||
|
follower_address: "http://localhost:4001/users/masto_hidden_counters/followers",
|
||||||
|
following_address: "http://localhost:4001/users/masto_hidden_counters/following"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
|
||||||
|
|
||||||
|
assert follow_info.hide_followers == true
|
||||||
|
assert follow_info.follower_count == 0
|
||||||
|
assert follow_info.hide_follows == true
|
||||||
|
assert follow_info.following_count == 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "fetch_favourites/3" do
|
describe "fetch_favourites/3" do
|
||||||
|
|
|
@ -26,7 +26,32 @@ test "it renders twitter card for user info" do
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it does not render attachments if post is nsfw" do
|
test "it uses summary twittercard if post has no attachment" do
|
||||||
|
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "HI"})
|
||||||
|
|
||||||
|
note =
|
||||||
|
insert(:note, %{
|
||||||
|
data: %{
|
||||||
|
"actor" => user.ap_id,
|
||||||
|
"tag" => [],
|
||||||
|
"id" => "https://pleroma.gov/objects/whatever",
|
||||||
|
"content" => "pleroma in a nutshell"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||||
|
|
||||||
|
assert [
|
||||||
|
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||||
|
{:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
|
||||||
|
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||||
|
[]},
|
||||||
|
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||||
|
] == result
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do
|
||||||
Pleroma.Config.put([Pleroma.Web.Metadata, :unfurl_nsfw], false)
|
Pleroma.Config.put([Pleroma.Web.Metadata, :unfurl_nsfw], false)
|
||||||
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
|
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
|
||||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "HI"})
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "HI"})
|
||||||
|
@ -67,7 +92,7 @@ test "it does not render attachments if post is nsfw" do
|
||||||
{:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
|
{:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []},
|
||||||
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||||
[]},
|
[]},
|
||||||
{:meta, [property: "twitter:card", content: "summary_large_image"], []}
|
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||||
] == result
|
] == result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue