Merge remote-tracking branch 'origin/develop' into fix-attachment-dimensions
This commit is contained in:
commit
2c96668a2c
3836 changed files with 4191 additions and 12264 deletions
|
|
@ -25,6 +25,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
alias Pleroma.Web.Streamer
|
||||
alias Pleroma.Web.WebFinger
|
||||
alias Pleroma.Workers.BackgroundWorker
|
||||
alias Pleroma.Workers.PollWorker
|
||||
|
||||
import Ecto.Query
|
||||
import Pleroma.Web.ActivityPub.Utils
|
||||
|
|
@ -288,6 +289,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
{:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
|
||||
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
|
||||
_ <- notify_and_stream(activity),
|
||||
:ok <- maybe_schedule_poll_notifications(activity),
|
||||
:ok <- maybe_federate(activity) do
|
||||
{:ok, activity}
|
||||
else
|
||||
|
|
@ -302,6 +304,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_schedule_poll_notifications(activity) do
|
||||
PollWorker.schedule_poll_end(activity)
|
||||
:ok
|
||||
end
|
||||
|
||||
@spec listen(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
|
||||
additional = params[:additional] || %{}
|
||||
|
|
@ -434,6 +441,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> maybe_preload_bookmarks(opts)
|
||||
|> maybe_set_thread_muted_field(opts)
|
||||
|> restrict_blocked(opts)
|
||||
|> restrict_blockers_visibility(opts)
|
||||
|> restrict_recipients(recipients, opts[:user])
|
||||
|> restrict_filtered(opts)
|
||||
|> where(
|
||||
|
|
@ -1021,7 +1029,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
from(
|
||||
[activity, object: o] in query,
|
||||
# You don't block the author
|
||||
where: fragment("not (? = ANY(?))", activity.actor, ^blocked_ap_ids),
|
||||
|
||||
# You don't block any recipients, and didn't author the post
|
||||
where:
|
||||
fragment(
|
||||
"((not (? && ?)) or ? = ?)",
|
||||
|
|
@ -1030,12 +1041,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
activity.actor,
|
||||
^user.ap_id
|
||||
),
|
||||
|
||||
# You don't block the domain of any recipients, and didn't author the post
|
||||
where:
|
||||
fragment(
|
||||
"recipients_contain_blocked_domains(?, ?) = false",
|
||||
"(recipients_contain_blocked_domains(?, ?) = false) or ? = ?",
|
||||
activity.recipients,
|
||||
^domain_blocks
|
||||
^domain_blocks,
|
||||
activity.actor,
|
||||
^user.ap_id
|
||||
),
|
||||
|
||||
# It's not a boost of a user you block
|
||||
where:
|
||||
fragment(
|
||||
"not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
|
||||
|
|
@ -1043,6 +1060,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
activity.data,
|
||||
^blocked_ap_ids
|
||||
),
|
||||
|
||||
# You don't block the author's domain, and also don't follow the author
|
||||
where:
|
||||
fragment(
|
||||
"(not (split_part(?, '/', 3) = ANY(?))) or ? = ANY(?)",
|
||||
|
|
@ -1051,6 +1070,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
activity.actor,
|
||||
^following_ap_ids
|
||||
),
|
||||
|
||||
# Same as above, but checks the Object
|
||||
where:
|
||||
fragment(
|
||||
"(not (split_part(?->>'actor', '/', 3) = ANY(?))) or (?->>'actor') = ANY(?)",
|
||||
|
|
@ -1064,6 +1085,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp restrict_blocked(query, _), do: query
|
||||
|
||||
defp restrict_blockers_visibility(query, %{blocking_user: %User{} = user}) do
|
||||
if Config.get([:activitypub, :blockers_visible]) == true do
|
||||
query
|
||||
else
|
||||
blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block])
|
||||
|
||||
from(
|
||||
activity in query,
|
||||
# The author doesn't block you
|
||||
where: fragment("not (? = ANY(?))", activity.actor, ^blocker_ap_ids),
|
||||
|
||||
# It's not a boost of a user that blocks you
|
||||
where:
|
||||
fragment(
|
||||
"not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
|
||||
activity.data,
|
||||
activity.data,
|
||||
^blocker_ap_ids
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
defp restrict_blockers_visibility(query, _), do: query
|
||||
|
||||
defp restrict_unlisted(query, %{restrict_unlisted: true}) do
|
||||
from(
|
||||
activity in query,
|
||||
|
|
@ -1290,6 +1336,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> restrict_state(opts)
|
||||
|> restrict_favorited_by(opts)
|
||||
|> restrict_blocked(restrict_blocked_opts)
|
||||
|> restrict_blockers_visibility(opts)
|
||||
|> restrict_muted(restrict_muted_opts)
|
||||
|> restrict_filtered(opts)
|
||||
|> restrict_media(opts)
|
||||
|
|
@ -1590,9 +1637,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
%User{} = old_user <- User.get_by_nickname(nickname),
|
||||
{_, false} <- {:ap_id_comparison, data[:ap_id] == old_user.ap_id} do
|
||||
Logger.info(
|
||||
"Found an old user for #{nickname}, the old ap id is #{old_user.ap_id}, new one is #{
|
||||
data[:ap_id]
|
||||
}, renaming."
|
||||
"Found an old user for #{nickname}, the old ap id is #{old_user.ap_id}, new one is #{data[:ap_id]}, renaming."
|
||||
)
|
||||
|
||||
old_user
|
||||
|
|
|
|||
|
|
@ -283,15 +283,29 @@ 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")
|
||||
end
|
||||
|
||||
# POST /relay/inbox -or- POST /internal/fetch/inbox
|
||||
def inbox(conn, params) do
|
||||
if params["type"] == "Create" && FederatingPlug.federating?() do
|
||||
def inbox(conn, %{"type" => "Create"} = params) do
|
||||
if FederatingPlug.federating?() do
|
||||
post_inbox_relayed_create(conn, params)
|
||||
else
|
||||
post_inbox_fallback(conn, params)
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("Not federating")
|
||||
end
|
||||
end
|
||||
|
||||
def inbox(conn, _params) do
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("error, missing HTTP Signature")
|
||||
end
|
||||
|
||||
defp post_inbox_relayed_create(conn, params) do
|
||||
Logger.debug(
|
||||
"Signature missing or not from author, relayed Create message, fetching object from source"
|
||||
|
|
@ -302,23 +316,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
json(conn, "ok")
|
||||
end
|
||||
|
||||
defp post_inbox_fallback(conn, params) do
|
||||
headers = Enum.into(conn.req_headers, %{})
|
||||
|
||||
if headers["signature"] && params["actor"] &&
|
||||
String.contains?(headers["signature"], params["actor"]) do
|
||||
Logger.debug(
|
||||
"Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
|
||||
)
|
||||
|
||||
Logger.debug(inspect(conn.req_headers))
|
||||
end
|
||||
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json(dgettext("errors", "error"))
|
||||
end
|
||||
|
||||
defp represent_service_actor(%User{} = user, conn) do
|
||||
with {:ok, user} <- User.ensure_keys_present(user) do
|
||||
conn
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
alias Pleroma.Web.ActivityPub.Relay
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
|
|
@ -125,6 +126,37 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
|> Pleroma.Maps.put_if_present("context", context), []}
|
||||
end
|
||||
|
||||
@spec note(ActivityDraft.t()) :: {:ok, map(), keyword()}
|
||||
def note(%ActivityDraft{} = draft) do
|
||||
data =
|
||||
%{
|
||||
"type" => "Note",
|
||||
"to" => draft.to,
|
||||
"cc" => draft.cc,
|
||||
"content" => draft.content_html,
|
||||
"summary" => draft.summary,
|
||||
"sensitive" => draft.sensitive,
|
||||
"context" => draft.context,
|
||||
"attachment" => draft.attachments,
|
||||
"actor" => draft.user.ap_id,
|
||||
"tag" => Keyword.values(draft.tags) |> Enum.uniq()
|
||||
}
|
||||
|> add_in_reply_to(draft.in_reply_to)
|
||||
|> Map.merge(draft.extra)
|
||||
|
||||
{:ok, data, []}
|
||||
end
|
||||
|
||||
defp add_in_reply_to(object, nil), do: object
|
||||
|
||||
defp add_in_reply_to(object, in_reply_to) do
|
||||
with %Object{} = in_reply_to_object <- Object.normalize(in_reply_to, fetch: false) do
|
||||
Map.put(object, "inReplyTo", in_reply_to_object.data["id"])
|
||||
else
|
||||
_ -> object
|
||||
end
|
||||
end
|
||||
|
||||
def chat_message(actor, recipient, content, opts \\ []) do
|
||||
basic = %{
|
||||
"id" => Utils.generate_object_id(),
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
%{
|
||||
key: :transparency_exclusions,
|
||||
label: "MRF transparency exclusions",
|
||||
type: {:list, :string},
|
||||
type: {:list, :tuple},
|
||||
key_placeholder: "instance",
|
||||
value_placeholder: "reason",
|
||||
description:
|
||||
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.",
|
||||
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. You can also provide a reason for excluding these instance names. The instances and reasons won't be publicly disclosed.",
|
||||
suggestions: [
|
||||
"exclusion.com"
|
||||
]
|
||||
|
|
@ -100,6 +102,11 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
|
||||
end
|
||||
|
||||
@spec instance_list_from_tuples([{String.t(), String.t()}]) :: [String.t()]
|
||||
def instance_list_from_tuples(list) do
|
||||
Enum.map(list, fn {instance, _} -> instance end)
|
||||
end
|
||||
|
||||
def describe(policies) do
|
||||
{:ok, policy_configs} =
|
||||
policies
|
||||
|
|
@ -150,9 +157,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
[description | acc]
|
||||
else
|
||||
Logger.warn(
|
||||
"#{policy} config description doesn't have one or all required keys #{
|
||||
inspect(@required_description_keys)
|
||||
}"
|
||||
"#{policy} config description doesn't have one or all required keys #{inspect(@required_description_keys)}"
|
||||
)
|
||||
|
||||
acc
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
|||
%{
|
||||
key: :replace,
|
||||
type: {:list, :tuple},
|
||||
key_placeholder: "instance",
|
||||
value_placeholder: "reason",
|
||||
description: """
|
||||
**Pattern**: a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`.
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
|
|||
|
||||
@impl true
|
||||
def describe,
|
||||
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Enum.into(%{})}}
|
||||
do: {:ok, %{mrf_rejectnonpublic: Config.get(:mrf_rejectnonpublic) |> Map.new()}}
|
||||
|
||||
@impl true
|
||||
def config_description do
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_accept(%{host: actor_host} = _actor_info, object) do
|
||||
accepts =
|
||||
Config.get([:mrf_simple, :accept])
|
||||
instance_list(:accept)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
cond do
|
||||
|
|
@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_reject(%{host: actor_host} = _actor_info, object) do
|
||||
rejects =
|
||||
Config.get([:mrf_simple, :reject])
|
||||
instance_list(:reject)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
if MRF.subdomain_match?(rejects, actor_host) do
|
||||
|
|
@ -44,7 +44,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
)
|
||||
when length(child_attachment) > 0 do
|
||||
media_removal =
|
||||
Config.get([:mrf_simple, :media_removal])
|
||||
instance_list(:media_removal)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
object =
|
||||
|
|
@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
} = object
|
||||
) do
|
||||
media_nsfw =
|
||||
Config.get([:mrf_simple, :media_nsfw])
|
||||
instance_list(:media_nsfw)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
object =
|
||||
|
|
@ -85,7 +85,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
|
||||
timeline_removal =
|
||||
Config.get([:mrf_simple, :federated_timeline_removal])
|
||||
instance_list(:federated_timeline_removal)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
object =
|
||||
|
|
@ -112,7 +112,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_followers_only(%{host: actor_host} = _actor_info, object) do
|
||||
followers_only =
|
||||
Config.get([:mrf_simple, :followers_only])
|
||||
instance_list(:followers_only)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
object =
|
||||
|
|
@ -137,7 +137,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do
|
||||
report_removal =
|
||||
Config.get([:mrf_simple, :report_removal])
|
||||
instance_list(:report_removal)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
if MRF.subdomain_match?(report_removal, actor_host) do
|
||||
|
|
@ -151,7 +151,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_avatar_removal(%{host: actor_host} = _actor_info, %{"icon" => _icon} = object) do
|
||||
avatar_removal =
|
||||
Config.get([:mrf_simple, :avatar_removal])
|
||||
instance_list(:avatar_removal)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
if MRF.subdomain_match?(avatar_removal, actor_host) do
|
||||
|
|
@ -165,7 +165,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image} = object) do
|
||||
banner_removal =
|
||||
Config.get([:mrf_simple, :banner_removal])
|
||||
instance_list(:banner_removal)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
if MRF.subdomain_match?(banner_removal, actor_host) do
|
||||
|
|
@ -185,12 +185,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
defp check_object(object), do: {:ok, object}
|
||||
|
||||
defp instance_list(config_key) do
|
||||
Config.get([:mrf_simple, config_key])
|
||||
|> MRF.instance_list_from_tuples()
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Delete", "actor" => actor} = object) do
|
||||
%{host: actor_host} = URI.parse(actor)
|
||||
|
||||
reject_deletes =
|
||||
Config.get([:mrf_simple, :reject_deletes])
|
||||
instance_list(:reject_deletes)
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
if MRF.subdomain_match?(reject_deletes, actor_host) do
|
||||
|
|
@ -253,14 +258,42 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
|
||||
@impl true
|
||||
def describe do
|
||||
exclusions = Config.get([:mrf, :transparency_exclusions])
|
||||
exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples()
|
||||
|
||||
mrf_simple_excluded =
|
||||
Config.get(:mrf_simple)
|
||||
|> Enum.map(fn {rule, instances} ->
|
||||
{rule, Enum.reject(instances, fn {host, _} -> host in exclusions end)}
|
||||
end)
|
||||
|
||||
mrf_simple =
|
||||
Config.get(:mrf_simple)
|
||||
|> Enum.map(fn {k, v} -> {k, Enum.reject(v, fn v -> v in exclusions end)} end)
|
||||
|> Enum.into(%{})
|
||||
mrf_simple_excluded
|
||||
|> Enum.map(fn {rule, instances} ->
|
||||
{rule, Enum.map(instances, fn {host, _} -> host end)}
|
||||
end)
|
||||
|> Map.new()
|
||||
|
||||
{:ok, %{mrf_simple: mrf_simple}}
|
||||
# This is for backwards compatibility. We originally didn't sent
|
||||
# extra info like a reason why an instance was rejected/quarantined/etc.
|
||||
# Because we didn't want to break backwards compatibility it was decided
|
||||
# to add an extra "info" key.
|
||||
mrf_simple_info =
|
||||
mrf_simple_excluded
|
||||
|> Enum.map(fn {rule, instances} ->
|
||||
{rule, Enum.reject(instances, fn {_, reason} -> reason == "" end)}
|
||||
end)
|
||||
|> Enum.reject(fn {_, instances} -> instances == [] end)
|
||||
|> Enum.map(fn {rule, instances} ->
|
||||
instances =
|
||||
instances
|
||||
|> Enum.map(fn {host, reason} -> {host, %{"reason" => reason}} end)
|
||||
|> Map.new()
|
||||
|
||||
{rule, instances}
|
||||
end)
|
||||
|> Map.new()
|
||||
|
||||
{:ok, %{mrf_simple: mrf_simple, mrf_simple_info: mrf_simple_info}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -270,70 +303,67 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy",
|
||||
label: "MRF Simple",
|
||||
description: "Simple ingress policies",
|
||||
children: [
|
||||
%{
|
||||
key: :media_removal,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to strip media attachments from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :media_nsfw,
|
||||
label: "Media NSFW",
|
||||
type: {:list, :string},
|
||||
description: "List of instances to tag all media as NSFW (sensitive) from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :federated_timeline_removal,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :reject,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to reject activities from (except deletes)",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :accept,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to only accept activities from (except deletes)",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :followers_only,
|
||||
type: {:list, :string},
|
||||
description: "Force posts from the given instances to be visible by followers only",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :report_removal,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to reject reports from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :avatar_removal,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to strip avatars from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :banner_removal,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to strip banners from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
},
|
||||
%{
|
||||
key: :reject_deletes,
|
||||
type: {:list, :string},
|
||||
description: "List of instances to reject deletions from",
|
||||
suggestions: ["example.com", "*.example.com"]
|
||||
}
|
||||
]
|
||||
children:
|
||||
[
|
||||
%{
|
||||
key: :media_removal,
|
||||
description:
|
||||
"List of instances to strip media attachments from and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :media_nsfw,
|
||||
label: "Media NSFW",
|
||||
description:
|
||||
"List of instances to tag all media as NSFW (sensitive) from and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :federated_timeline_removal,
|
||||
description:
|
||||
"List of instances to remove from the Federated (aka The Whole Known Network) Timeline and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :reject,
|
||||
description:
|
||||
"List of instances to reject activities from (except deletes) and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :accept,
|
||||
description:
|
||||
"List of instances to only accept activities from (except deletes) and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :followers_only,
|
||||
description:
|
||||
"Force posts from the given instances to be visible by followers only and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :report_removal,
|
||||
description: "List of instances to reject reports from and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :avatar_removal,
|
||||
description: "List of instances to strip avatars from and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :banner_removal,
|
||||
description: "List of instances to strip banners from and the reason for doing so"
|
||||
},
|
||||
%{
|
||||
key: :reject_deletes,
|
||||
description: "List of instances to reject deletions from and the reason for doing so"
|
||||
}
|
||||
]
|
||||
|> Enum.map(fn setting ->
|
||||
Map.merge(
|
||||
setting,
|
||||
%{
|
||||
type: {:list, :tuple},
|
||||
key_placeholder: "instance",
|
||||
value_placeholder: "reason",
|
||||
suggestions: [{"example.com", "Some reason"}, {"*.example.com", "Another reason"}]
|
||||
}
|
||||
)
|
||||
end)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
|||
end
|
||||
else
|
||||
Logger.debug(
|
||||
"MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{
|
||||
size_limit
|
||||
} B)"
|
||||
"MRF.StealEmojiPolicy: :#{shortcode}: at #{url} (#{byte_size(response.body)} B) over size limit (#{size_limit} B)"
|
||||
)
|
||||
|
||||
nil
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
|
|||
def filter(%{"actor" => actor} = message) do
|
||||
with {:ok, match, subchain} <- lookup_subchain(actor) do
|
||||
Logger.debug(
|
||||
"[SubchainPolicy] Matched #{actor} against #{inspect(match)} with subchain #{
|
||||
inspect(subchain)
|
||||
}"
|
||||
"[SubchainPolicy] Matched #{actor} against #{inspect(match)} with subchain #{inspect(subchain)}"
|
||||
)
|
||||
|
||||
MRF.filter(subchain, message)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
|
|||
def describe do
|
||||
mrf_user_allowlist =
|
||||
Config.get([:mrf_user_allowlist], [])
|
||||
|> Enum.into(%{}, fn {k, v} -> {k, length(v)} end)
|
||||
|> Map.new(fn {k, v} -> {k, length(v)} end)
|
||||
|
||||
{:ok, %{mrf_user_allowlist: mrf_user_allowlist}}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
|
|||
|
||||
@impl true
|
||||
def describe,
|
||||
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Enum.into(%{})}}
|
||||
do: {:ok, %{mrf_vocabulary: Pleroma.Config.get(:mrf_vocabulary) |> Map.new()}}
|
||||
|
||||
@impl true
|
||||
def config_description do
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
|
||||
def stringify_keys(object) when is_map(object) do
|
||||
object
|
||||
|> Enum.filter(fn {_, v} -> v != nil end)
|
||||
|> Map.new(fn {key, val} -> {to_string(key), stringify_keys(val)} end)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator do
|
|||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
|
||||
import Ecto.Changeset
|
||||
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
|
@ -14,12 +13,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
|
|
|
|||
|
|
@ -10,19 +10,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AddRemoveValidator do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.User
|
||||
|
||||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:target)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:type)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -20,13 +20,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:context, :string)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
|
|||
@derive Jason.Encoder
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
field(:type, :string)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:name, :string)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
|||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Ecto.Changeset
|
||||
|
|
@ -18,38 +16,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
|||
@derive Jason.Encoder
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
embeds_many(:tag, TagValidator)
|
||||
field(:type, :string)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
field(:content, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
object_fields()
|
||||
status_object_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,11 +5,8 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Ecto.Changeset
|
||||
|
|
@ -18,38 +15,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
|
|||
@derive Jason.Encoder
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
embeds_many(:tag, TagValidator)
|
||||
field(:type, :string)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
field(:content, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
object_fields()
|
||||
status_object_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_and_apply(data) do
|
||||
|
|
|
|||
|
|
@ -5,20 +5,21 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
import Ecto.Changeset
|
||||
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
@primary_key false
|
||||
@derive Jason.Encoder
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
|
|
@ -30,8 +31,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator do
|
|||
cng
|
||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||
|> validate_inclusion(:type, ["Block"])
|
||||
|> validate_actor_presence()
|
||||
|> validate_actor_presence(field_name: :object)
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|> CommonValidations.validate_actor_presence(field_name: :object)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
|
||||
# Activities and Objects, except (Create)ChatMessage
|
||||
defmacro message_fields do
|
||||
quote bind_quoted: binding() do
|
||||
field(:type, :string)
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
end
|
||||
|
||||
defmacro activity_fields do
|
||||
quote bind_quoted: binding() do
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
end
|
||||
end
|
||||
|
||||
# All objects except Answer and CHatMessage
|
||||
defmacro object_fields do
|
||||
quote bind_quoted: binding() do
|
||||
field(:content, :string)
|
||||
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
end
|
||||
end
|
||||
|
||||
# Basically objects that aren't ChatMessage and Answer
|
||||
defmacro status_object_fields do
|
||||
quote bind_quoted: binding() do
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
|
||||
embeds_many(:tag, TagValidator)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
field(:sensitive, :boolean, default: false)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,11 +17,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:type, :string)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
end
|
||||
|
||||
def cast_and_apply(data) do
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:type, :string)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:expires_at, ObjectValidators.DateTime)
|
||||
|
||||
# Should be moved to object, done for CommonAPI.Utils.make_context
|
||||
|
|
|
|||
|
|
@ -15,13 +15,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:deleted_activity_id, ObjectValidators.ObjectID)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
|
||||
|
|
@ -15,14 +14,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:context, :string)
|
||||
field(:content, :string)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -5,11 +5,8 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Ecto.Changeset
|
||||
|
|
@ -19,38 +16,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
|||
|
||||
# Extends from NoteValidator
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
embeds_many(:tag, TagValidator)
|
||||
field(:type, :string)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
field(:content, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
object_fields()
|
||||
status_object_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_and_apply(data) do
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
|
||||
import Ecto.Changeset
|
||||
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:state, :string, default: "pending")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
|
@ -16,13 +15,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:context, :string)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Ecto.Changeset
|
||||
|
|
@ -20,35 +18,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
|
||||
# Extends from NoteValidator
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
embeds_many(:tag, TagValidator)
|
||||
field(:type, :string)
|
||||
field(:content, :string)
|
||||
field(:context, :string)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:summary, :string)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
object_fields()
|
||||
status_object_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:closed, ObjectValidators.DateTime)
|
||||
field(:voters, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do
|
|||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.User
|
||||
|
||||
import Ecto.Changeset
|
||||
|
|
@ -15,12 +14,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
activity_fields()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -13,11 +13,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateValidator do
|
|||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
quote do
|
||||
unquote do
|
||||
import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
|
||||
message_fields()
|
||||
end
|
||||
end
|
||||
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
# In this case, we save the full object in this activity instead of just a
|
||||
# reference, so we can always see what was actually changed by this.
|
||||
field(:object, :map)
|
||||
|
|
|
|||
|
|
@ -63,18 +63,17 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
date: date
|
||||
})
|
||||
|
||||
with {:ok, %{status: code}} when code in 200..299 <-
|
||||
result =
|
||||
HTTP.post(
|
||||
inbox,
|
||||
json,
|
||||
[
|
||||
{"Content-Type", "application/activity+json"},
|
||||
{"Date", date},
|
||||
{"signature", signature},
|
||||
{"digest", digest}
|
||||
]
|
||||
) do
|
||||
with {:ok, %{status: code}} = result when code in 200..299 <-
|
||||
HTTP.post(
|
||||
inbox,
|
||||
json,
|
||||
[
|
||||
{"Content-Type", "application/activity+json"},
|
||||
{"Date", date},
|
||||
{"signature", signature},
|
||||
{"digest", digest}
|
||||
]
|
||||
) do
|
||||
if not Map.has_key?(params, :unreachable_since) || params[:unreachable_since] do
|
||||
Instances.set_reachable(inbox)
|
||||
end
|
||||
|
|
@ -112,6 +111,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
|
||||
quarantined_instances =
|
||||
Config.get([:instance, :quarantined_instances], [])
|
||||
|> Pleroma.Web.ActivityPub.MRF.instance_list_from_tuples()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomains_regex()
|
||||
|
||||
!Pleroma.Web.ActivityPub.MRF.subdomain_match?(quarantined_instances, host)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Streamer
|
||||
alias Pleroma.Workers.PollWorker
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
@ -194,7 +195,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
# - Set up notifications
|
||||
@impl true
|
||||
def handle(%{data: %{"type" => "Create"}} = activity, meta) do
|
||||
with {:ok, object, meta} <- handle_object_creation(meta[:object_data], meta),
|
||||
with {:ok, object, meta} <- handle_object_creation(meta[:object_data], activity, meta),
|
||||
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
|
||||
{:ok, notifications} = Notification.create_notifications(activity, do_send: false)
|
||||
{:ok, _user} = ActivityPub.increase_note_count_if_public(user, object)
|
||||
|
|
@ -388,7 +389,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
def handle_object_creation(%{"type" => "ChatMessage"} = object, meta) do
|
||||
def handle_object_creation(%{"type" => "ChatMessage"} = object, _activity, meta) do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
|
||||
actor = User.get_cached_by_ap_id(object.data["actor"])
|
||||
recipient = User.get_cached_by_ap_id(hd(object.data["to"]))
|
||||
|
|
@ -423,7 +424,14 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_object_creation(%{"type" => "Answer"} = object_map, meta) do
|
||||
def handle_object_creation(%{"type" => "Question"} = object, activity, meta) do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
|
||||
PollWorker.schedule_poll_end(activity)
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_object_creation(%{"type" => "Answer"} = object_map, _activity, meta) do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object_map, meta) do
|
||||
Object.increase_vote_count(
|
||||
object.data["inReplyTo"],
|
||||
|
|
@ -435,15 +443,15 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_object_creation(%{"type" => objtype} = object, meta)
|
||||
when objtype in ~w[Audio Video Question Event Article Note Page] do
|
||||
def handle_object_creation(%{"type" => objtype} = object, _activity, meta)
|
||||
when objtype in ~w[Audio Video Event Article Note Page] do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
# Nothing to do
|
||||
def handle_object_creation(object, meta) do
|
||||
def handle_object_creation(object, _activity, meta) do
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["admin:read:statuses"]}
|
||||
when action in [:list_user_statuses, :list_instance_statuses]
|
||||
when action in [:list_user_statuses]
|
||||
)
|
||||
|
||||
plug(
|
||||
|
|
@ -81,24 +81,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
|
||||
action_fallback(AdminAPI.FallbackController)
|
||||
|
||||
def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
||||
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||
{page, page_size} = page_params(params)
|
||||
|
||||
result =
|
||||
ActivityPub.fetch_statuses(nil, %{
|
||||
instance: instance,
|
||||
limit: page_size,
|
||||
offset: (page - 1) * page_size,
|
||||
exclude_reblogs: not with_reblogs,
|
||||
total: true
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
|
||||
end
|
||||
|
||||
def list_user_statuses(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do
|
||||
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||
godmode = params["godmode"] == "true" || params["godmode"] == true
|
||||
|
|
|
|||
63
lib/pleroma/web/admin_api/controllers/instance_controller.ex
Normal file
63
lib/pleroma/web/admin_api/controllers/instance_controller.ex
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.InstanceController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [fetch_integer_param: 3]
|
||||
|
||||
alias Pleroma.Instances.Instance
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
||||
require Logger
|
||||
|
||||
@default_page_size 50
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["admin:read:statuses"]}
|
||||
when action in [:list_statuses]
|
||||
)
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["admin:write:accounts", "admin:write:statuses"]}
|
||||
when action in [:delete]
|
||||
)
|
||||
|
||||
action_fallback(AdminAPI.FallbackController)
|
||||
|
||||
def list_statuses(conn, %{"instance" => instance} = params) do
|
||||
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||
{page, page_size} = page_params(params)
|
||||
|
||||
result =
|
||||
ActivityPub.fetch_statuses(nil, %{
|
||||
instance: instance,
|
||||
limit: page_size,
|
||||
offset: (page - 1) * page_size,
|
||||
exclude_reblogs: not with_reblogs,
|
||||
total: true
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{total: result[:total], activities: result[:items], as: :activity})
|
||||
end
|
||||
|
||||
def delete(conn, %{"instance" => instance}) do
|
||||
with {:ok, _job} <- Instance.delete_users_and_activities(instance) do
|
||||
json(conn, instance)
|
||||
end
|
||||
end
|
||||
|
||||
defp page_params(params) do
|
||||
{
|
||||
fetch_integer_param(params, "page", 1),
|
||||
fetch_integer_param(params, "page_size", @default_page_size)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -195,7 +195,8 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
|
|||
"pleroma:chat_mention",
|
||||
"pleroma:report",
|
||||
"move",
|
||||
"follow_request"
|
||||
"follow_request",
|
||||
"poll"
|
||||
],
|
||||
description: """
|
||||
The type of event that resulted in the notification.
|
||||
|
|
|
|||
|
|
@ -121,7 +121,10 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
|
|||
type: :object,
|
||||
required: [:email, :password],
|
||||
properties: %{
|
||||
email: %Schema{type: :string, description: "New email"},
|
||||
email: %Schema{
|
||||
type: :string,
|
||||
description: "New email. Set to blank to remove the user's email."
|
||||
},
|
||||
password: %Schema{type: :string, description: "Current password"}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -487,9 +487,7 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
else
|
||||
{what, result} = error ->
|
||||
Logger.warn(
|
||||
"CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{
|
||||
activity_id
|
||||
}"
|
||||
"CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{activity_id}"
|
||||
)
|
||||
|
||||
{:error, error}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
|
||||
|
|
@ -213,8 +214,10 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
|||
|
||||
emoji = Map.merge(emoji, summary_emoji)
|
||||
|
||||
{:ok, note_data, _meta} = Builder.note(draft)
|
||||
|
||||
object =
|
||||
Utils.make_note_data(draft)
|
||||
note_data
|
||||
|> Map.put("emoji", emoji)
|
||||
|> Map.put("source", draft.status)
|
||||
|> Map.put("generator", draft.params[:generator])
|
||||
|
|
|
|||
|
|
@ -291,33 +291,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
|> Formatter.html_escape("text/html")
|
||||
end
|
||||
|
||||
def make_note_data(%ActivityDraft{} = draft) do
|
||||
%{
|
||||
"type" => "Note",
|
||||
"to" => draft.to,
|
||||
"cc" => draft.cc,
|
||||
"content" => draft.content_html,
|
||||
"summary" => draft.summary,
|
||||
"sensitive" => draft.sensitive,
|
||||
"context" => draft.context,
|
||||
"attachment" => draft.attachments,
|
||||
"actor" => draft.user.ap_id,
|
||||
"tag" => Keyword.values(draft.tags) |> Enum.uniq()
|
||||
}
|
||||
|> add_in_reply_to(draft.in_reply_to)
|
||||
|> Map.merge(draft.extra)
|
||||
end
|
||||
|
||||
defp add_in_reply_to(object, nil), do: object
|
||||
|
||||
defp add_in_reply_to(object, in_reply_to) do
|
||||
with %Object{} = in_reply_to_object <- Object.normalize(in_reply_to, fetch: false) do
|
||||
Map.put(object, "inReplyTo", in_reply_to_object.data["id"])
|
||||
else
|
||||
_ -> object
|
||||
end
|
||||
end
|
||||
|
||||
def format_naive_asctime(date) do
|
||||
date |> DateTime.from_naive!("Etc/UTC") |> format_asctime
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ defmodule Pleroma.Web.Feed.UserController do
|
|||
def feed_redirect(%{assigns: %{format: "html"}} = conn, %{"nickname" => nickname}) do
|
||||
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname_or_id(nickname)} do
|
||||
Pleroma.Web.Fallback.RedirectController.redirector_with_meta(conn, %{user: user})
|
||||
else
|
||||
_ -> Pleroma.Web.Fallback.RedirectController.redirector(conn, nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastoFEController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.MastodonAPI.AuthController
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
||||
plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action == :put_settings)
|
||||
|
||||
# Note: :index action handles attempt of unauthenticated access to private instance with redirect
|
||||
plug(:skip_public_check when action == :index)
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["read"], fallback: :proceed_unauthenticated}
|
||||
when action == :index
|
||||
)
|
||||
|
||||
plug(:skip_auth when action == :manifest)
|
||||
|
||||
@doc "GET /web/*path"
|
||||
def index(conn, _params) do
|
||||
with %{assigns: %{user: %User{} = user, token: %Token{app_id: token_app_id} = token}} <- conn,
|
||||
{:ok, %{id: ^token_app_id}} <- AuthController.local_mastofe_app() do
|
||||
conn
|
||||
|> put_layout(false)
|
||||
|> render("index.html",
|
||||
token: token.token,
|
||||
user: user,
|
||||
custom_emojis: Pleroma.Emoji.get_all()
|
||||
)
|
||||
else
|
||||
_ ->
|
||||
conn
|
||||
|> put_session(:return_to, conn.request_path)
|
||||
|> redirect(to: "/web/login")
|
||||
end
|
||||
end
|
||||
|
||||
@doc "GET /web/manifest.json"
|
||||
def manifest(conn, _params) do
|
||||
render(conn, "manifest.json")
|
||||
end
|
||||
|
||||
@doc "PUT /api/web/settings: Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere"
|
||||
def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
|
||||
with {:ok, _} <- User.mastodon_settings_update(user, settings) do
|
||||
json(conn, %{})
|
||||
else
|
||||
e ->
|
||||
conn
|
||||
|> put_status(:internal_server_error)
|
||||
|> json(%{error: inspect(e)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -21,8 +21,6 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
|
|||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
@local_mastodon_name "Mastodon-Local"
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation
|
||||
|
||||
@doc "POST /api/v1/apps"
|
||||
|
|
@ -35,7 +33,6 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
|
|||
|> Map.put(:scopes, scopes)
|
||||
|
||||
with cs <- App.register_changeset(%App{}, app_attrs),
|
||||
false <- cs.changes[:client_name] == @local_mastodon_name,
|
||||
{:ok, app} <- Repo.insert(cs) do
|
||||
render(conn, "show.json", app: app)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,77 +7,12 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
|
|||
|
||||
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||
|
||||
alias Pleroma.Helpers.AuthHelper
|
||||
alias Pleroma.Helpers.UriHelper
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.OAuth.App
|
||||
alias Pleroma.Web.OAuth.Authorization
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken
|
||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
|
||||
plug(Pleroma.Web.Plugs.RateLimiter, [name: :password_reset] when action == :password_reset)
|
||||
|
||||
@local_mastodon_name "Mastodon-Local"
|
||||
|
||||
@doc "GET /web/login"
|
||||
# Local Mastodon FE login callback action
|
||||
def login(conn, %{"code" => auth_token} = params) do
|
||||
with {:ok, app} <- local_mastofe_app(),
|
||||
{:ok, auth} <- Authorization.get_by_token(app, auth_token),
|
||||
{:ok, oauth_token} <- Token.exchange_token(app, auth) do
|
||||
redirect_to =
|
||||
conn
|
||||
|> local_mastodon_post_login_path()
|
||||
|> UriHelper.modify_uri_params(%{"access_token" => oauth_token.token})
|
||||
|
||||
conn
|
||||
|> AuthHelper.put_session_token(oauth_token.token)
|
||||
|> redirect(to: redirect_to)
|
||||
else
|
||||
_ -> redirect_to_oauth_form(conn, params)
|
||||
end
|
||||
end
|
||||
|
||||
def login(conn, params) do
|
||||
with %{assigns: %{user: %User{}, token: %Token{app_id: app_id}}} <- conn,
|
||||
{:ok, %{id: ^app_id}} <- local_mastofe_app() do
|
||||
redirect(conn, to: local_mastodon_post_login_path(conn))
|
||||
else
|
||||
_ -> redirect_to_oauth_form(conn, params)
|
||||
end
|
||||
end
|
||||
|
||||
defp redirect_to_oauth_form(conn, _params) do
|
||||
with {:ok, app} <- local_mastofe_app() do
|
||||
path =
|
||||
Routes.o_auth_path(conn, :authorize,
|
||||
response_type: "code",
|
||||
client_id: app.client_id,
|
||||
redirect_uri: ".",
|
||||
scope: Enum.join(app.scopes, " ")
|
||||
)
|
||||
|
||||
redirect(conn, to: path)
|
||||
end
|
||||
end
|
||||
|
||||
@doc "DELETE /auth/sign_out"
|
||||
def logout(conn, _) do
|
||||
conn =
|
||||
with %{assigns: %{token: %Token{} = oauth_token}} <- conn,
|
||||
session_token = AuthHelper.get_session_token(conn),
|
||||
{:ok, %Token{token: ^session_token}} <- RevokeToken.revoke(oauth_token) do
|
||||
AuthHelper.delete_session_token(conn)
|
||||
else
|
||||
_ -> conn
|
||||
end
|
||||
|
||||
redirect(conn, to: "/")
|
||||
end
|
||||
|
||||
@doc "POST /auth/password"
|
||||
def password_reset(conn, params) do
|
||||
nickname_or_email = params["email"] || params["nickname"]
|
||||
|
|
@ -86,23 +21,4 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
|
|||
|
||||
json_response(conn, :no_content, "")
|
||||
end
|
||||
|
||||
defp local_mastodon_post_login_path(conn) do
|
||||
case get_session(conn, :return_to) do
|
||||
nil ->
|
||||
Routes.masto_fe_path(conn, :index, ["getting-started"])
|
||||
|
||||
return_to ->
|
||||
delete_session(conn, :return_to)
|
||||
return_to
|
||||
end
|
||||
end
|
||||
|
||||
@spec local_mastofe_app() :: {:ok, App.t()} | {:error, Ecto.Changeset.t()}
|
||||
def local_mastofe_app do
|
||||
App.get_or_make(
|
||||
%{client_name: @local_mastodon_name, redirect_uris: "."},
|
||||
["read", "write", "follow", "push", "admin"]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
|
|||
favourite
|
||||
move
|
||||
pleroma:emoji_reaction
|
||||
poll
|
||||
}
|
||||
def index(%{assigns: %{user: user}} = conn, params) do
|
||||
params =
|
||||
|
|
|
|||
|
|
@ -95,7 +95,20 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
{:ok, data} = MRF.describe()
|
||||
|
||||
data
|
||||
|> Map.merge(%{quarantined_instances: quarantined})
|
||||
|> Map.put(
|
||||
:quarantined_instances,
|
||||
Enum.map(quarantined, fn {instance, _reason} -> instance end)
|
||||
)
|
||||
# This is for backwards compatibility. We originally didn't sent
|
||||
# extra info like a reason why an instance was rejected/quarantined/etc.
|
||||
# Because we didn't want to break backwards compatibility it was decided
|
||||
# to add an extra "info" key.
|
||||
|> Map.put(:quarantined_instances_info, %{
|
||||
"quarantined_instances" =>
|
||||
quarantined
|
||||
|> Enum.map(fn {instance, reason} -> {instance, %{"reason" => reason}} end)
|
||||
|> Map.new()
|
||||
})
|
||||
else
|
||||
%{}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
|
|||
"move" ->
|
||||
put_target(response, activity, reading_user, %{})
|
||||
|
||||
"poll" ->
|
||||
put_status(response, activity, reading_user, status_render_opts)
|
||||
|
||||
"pleroma:emoji_reaction" ->
|
||||
response
|
||||
|> put_status(parent_activity_fn.(), reading_user, status_render_opts)
|
||||
|
|
|
|||
|
|
@ -49,9 +49,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
|||
|
||||
def websocket_init(state) do
|
||||
Logger.debug(
|
||||
"#{__MODULE__} accepted websocket connection for user #{
|
||||
(state.user || %{id: "anonymous"}).id
|
||||
}, topic #{state.topic}"
|
||||
"#{__MODULE__} accepted websocket connection for user #{(state.user || %{id: "anonymous"}).id}, topic #{state.topic}"
|
||||
)
|
||||
|
||||
Streamer.add_socket(state.topic, state.user)
|
||||
|
|
@ -106,9 +104,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
|||
|
||||
def terminate(reason, _req, state) do
|
||||
Logger.debug(
|
||||
"#{__MODULE__} terminating websocket connection for user #{
|
||||
(state.user || %{id: "anonymous"}).id
|
||||
}, topic #{state.topic || "?"}: #{inspect(reason)}"
|
||||
"#{__MODULE__} terminating websocket connection for user #{(state.user || %{id: "anonymous"}).id}, topic #{state.topic || "?"}: #{inspect(reason)}"
|
||||
)
|
||||
|
||||
Streamer.remove_socket(state.topic)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
|
|||
openRegistrations: Config.get([:instance, :registrations_open]),
|
||||
usage: %{
|
||||
users: %{
|
||||
total: Map.get(stats, :user_count, 0)
|
||||
total: Map.get(stats, :user_count, 0),
|
||||
activeMonth: Pleroma.User.active_user_count(30),
|
||||
activeHalfyear: Pleroma.User.active_user_count(180)
|
||||
},
|
||||
localPosts: Map.get(stats, :status_count, 0)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -597,9 +597,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do
|
|||
end
|
||||
end
|
||||
|
||||
# Special case: Local MastodonFE
|
||||
defp redirect_uri(%Plug.Conn{} = conn, "."), do: Routes.auth_url(conn, :login)
|
||||
|
||||
defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri
|
||||
|
||||
defp get_session_registration_id(%Plug.Conn{} = conn), do: get_session(conn, :registration_id)
|
||||
|
|
|
|||
23
lib/pleroma/web/plugs/user_is_staff_plug.ex
Normal file
23
lib/pleroma/web/plugs/user_is_staff_plug.ex
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.UserIsStaffPlug do
|
||||
import Pleroma.Web.TranslationHelpers
|
||||
import Plug.Conn
|
||||
|
||||
alias Pleroma.User
|
||||
|
||||
def init(options) do
|
||||
options
|
||||
end
|
||||
|
||||
def call(%{assigns: %{user: %User{is_admin: true}}} = conn, _), do: conn
|
||||
def call(%{assigns: %{user: %User{is_moderator: true}}} = conn, _), do: conn
|
||||
|
||||
def call(conn, _) do
|
||||
conn
|
||||
|> render_error(:forbidden, "User is not a staff member.")
|
||||
|> halt()
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
defmodule Pleroma.Web.Preload do
|
||||
alias Phoenix.HTML
|
||||
require Logger
|
||||
|
||||
def build_tags(_conn, params) do
|
||||
preload_data =
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ defmodule Pleroma.Web.Push.Impl do
|
|||
|
||||
def format_body(activity, actor, object, mastodon_type \\ nil)
|
||||
|
||||
def format_body(_activity, actor, %{data: %{"type" => "ChatMessage", "content" => content}}, _) do
|
||||
case content do
|
||||
def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}, _) do
|
||||
case data["content"] do
|
||||
nil -> "@#{actor.nickname}: (Attachment)"
|
||||
content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ defmodule Pleroma.Web.Push.Subscription do
|
|||
end
|
||||
|
||||
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
|
||||
@supported_alert_types ~w[follow favourite mention reblog pleroma:chat_mention pleroma:emoji_reaction]a
|
||||
@supported_alert_types ~w[follow favourite mention reblog poll pleroma:chat_mention pleroma:emoji_reaction]a
|
||||
|
||||
defp alerts(%{data: %{alerts: alerts}}) do
|
||||
alerts = Map.take(alerts, @supported_alert_types)
|
||||
|
|
|
|||
|
|
@ -96,14 +96,12 @@ defmodule Pleroma.Web.Router do
|
|||
plug(Pleroma.Web.Plugs.AdminSecretAuthenticationPlug)
|
||||
plug(:after_auth)
|
||||
plug(Pleroma.Web.Plugs.EnsureAuthenticatedPlug)
|
||||
plug(Pleroma.Web.Plugs.UserIsAdminPlug)
|
||||
plug(Pleroma.Web.Plugs.UserIsStaffPlug)
|
||||
plug(Pleroma.Web.Plugs.IdempotencyPlug)
|
||||
end
|
||||
|
||||
pipeline :mastodon_html do
|
||||
plug(:browser)
|
||||
plug(:authenticate)
|
||||
plug(:after_auth)
|
||||
pipeline :require_admin do
|
||||
plug(Pleroma.Web.Plugs.UserIsAdminPlug)
|
||||
end
|
||||
|
||||
pipeline :pleroma_html do
|
||||
|
|
@ -160,7 +158,7 @@ defmodule Pleroma.Web.Router do
|
|||
end
|
||||
|
||||
scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do
|
||||
pipe_through(:admin_api)
|
||||
pipe_through([:admin_api, :require_admin])
|
||||
|
||||
put("/users/disable_mfa", AdminAPIController, :disable_mfa)
|
||||
put("/users/tag", AdminAPIController, :tag_users)
|
||||
|
|
@ -213,7 +211,8 @@ defmodule Pleroma.Web.Router do
|
|||
get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
|
||||
get("/users/:nickname/chats", AdminAPIController, :list_user_chats)
|
||||
|
||||
get("/instances/:instance/statuses", AdminAPIController, :list_instance_statuses)
|
||||
get("/instances/:instance/statuses", InstanceController, :list_statuses)
|
||||
delete("/instances/:instance", InstanceController, :delete)
|
||||
|
||||
get("/instance_document/:name", InstanceDocumentController, :show)
|
||||
patch("/instance_document/:name", InstanceDocumentController, :update)
|
||||
|
|
@ -265,7 +264,7 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do
|
||||
scope "/pack" do
|
||||
pipe_through(:admin_api)
|
||||
pipe_through([:admin_api, :require_admin])
|
||||
|
||||
post("/", EmojiPackController, :create)
|
||||
patch("/", EmojiPackController, :update)
|
||||
|
|
@ -280,7 +279,7 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
# Modifying packs
|
||||
scope "/packs" do
|
||||
pipe_through(:admin_api)
|
||||
pipe_through([:admin_api, :require_admin])
|
||||
|
||||
get("/import", EmojiPackController, :import_from_filesystem)
|
||||
get("/remote", EmojiPackController, :remote)
|
||||
|
|
@ -542,13 +541,6 @@ defmodule Pleroma.Web.Router do
|
|||
get("/timelines/list/:list_id", TimelineController, :list)
|
||||
end
|
||||
|
||||
scope "/api/web", Pleroma.Web do
|
||||
pipe_through(:authenticated_api)
|
||||
|
||||
# Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere
|
||||
put("/settings", MastoFEController, :put_settings)
|
||||
end
|
||||
|
||||
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
||||
pipe_through(:app_api)
|
||||
|
||||
|
|
@ -745,22 +737,9 @@ defmodule Pleroma.Web.Router do
|
|||
end
|
||||
|
||||
scope "/", Pleroma.Web do
|
||||
pipe_through(:api)
|
||||
pipe_through(:pleroma_html)
|
||||
|
||||
get("/web/manifest.json", MastoFEController, :manifest)
|
||||
end
|
||||
|
||||
scope "/", Pleroma.Web do
|
||||
pipe_through(:mastodon_html)
|
||||
|
||||
get("/web/login", MastodonAPI.AuthController, :login)
|
||||
delete("/auth/sign_out", MastodonAPI.AuthController, :logout)
|
||||
|
||||
post("/auth/password", MastodonAPI.AuthController, :password_reset)
|
||||
|
||||
get("/web/*path", MastoFEController, :index)
|
||||
|
||||
get("/embed/:id", EmbedController, :show)
|
||||
post("/auth/password", TwitterAPI.PasswordController, :request)
|
||||
end
|
||||
|
||||
scope "/proxy/", Pleroma.Web do
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta content='width=device-width, initial-scale=1' name='viewport'>
|
||||
<title>
|
||||
<%= Config.get([:instance, :name]) %>
|
||||
</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||
<link rel="manifest" type="applicaton/manifest+json" href="<%= Routes.masto_fe_path(Pleroma.Web.Endpoint, :manifest) %>" />
|
||||
|
||||
<meta name="theme-color" content="<%= Config.get([:manifest, :theme_color]) %>" />
|
||||
|
||||
<script crossorigin='anonymous' src="/packs/locales.js"></script>
|
||||
<script crossorigin='anonymous' src="/packs/locales/glitch/en.js"></script>
|
||||
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/getting_started.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/compose.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/notifications.js'>
|
||||
<script id='initial-state' type='application/json'><%= initial_state(@token, @user, @custom_emojis) %></script>
|
||||
|
||||
<script src="/packs/core/common.js"></script>
|
||||
<link rel="stylesheet" media="all" href="/packs/core/common.css" />
|
||||
|
||||
<script src="/packs/flavours/glitch/common.js"></script>
|
||||
<link rel="stylesheet" media="all" href="/packs/flavours/glitch/common.css" />
|
||||
|
||||
<script src="/packs/flavours/glitch/home.js"></script>
|
||||
</head>
|
||||
<body class='app-body no-reduce-motion system-font'>
|
||||
<div class='app-holder' data-props='{"locale":"en"}' id='mastodon'>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -11,9 +11,23 @@ defmodule Pleroma.Web.TwitterAPI.PasswordController do
|
|||
|
||||
require Logger
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||
|
||||
alias Pleroma.PasswordResetToken
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||
|
||||
plug(Pleroma.Web.Plugs.RateLimiter, [name: :request] when action == :request)
|
||||
|
||||
@doc "POST /auth/password"
|
||||
def request(conn, params) do
|
||||
nickname_or_email = params["email"] || params["nickname"]
|
||||
|
||||
TwitterAPI.password_reset(nickname_or_email)
|
||||
|
||||
json_response(conn, :no_content, "")
|
||||
end
|
||||
|
||||
def reset(conn, %{"token" => token}) do
|
||||
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastoFEView do
|
||||
use Pleroma.Web, :view
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.CustomEmojiView
|
||||
|
||||
def initial_state(token, user, custom_emojis) do
|
||||
limit = Config.get([:instance, :limit])
|
||||
|
||||
%{
|
||||
meta: %{
|
||||
streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
|
||||
access_token: token,
|
||||
locale: "en",
|
||||
domain: Pleroma.Web.Endpoint.host(),
|
||||
admin: "1",
|
||||
me: "#{user.id}",
|
||||
unfollow_modal: false,
|
||||
boost_modal: false,
|
||||
delete_modal: true,
|
||||
auto_play_gif: false,
|
||||
display_sensitive_media: false,
|
||||
reduce_motion: false,
|
||||
max_toot_chars: limit,
|
||||
mascot: User.get_mascot(user)["url"]
|
||||
},
|
||||
poll_limits: Config.get([:instance, :poll_limits]),
|
||||
rights: %{
|
||||
delete_others_notice: present?(user.is_moderator),
|
||||
admin: present?(user.is_admin)
|
||||
},
|
||||
compose: %{
|
||||
me: "#{user.id}",
|
||||
default_privacy: user.default_scope,
|
||||
default_sensitive: false,
|
||||
allow_content_types: Config.get([:instance, :allowed_post_formats])
|
||||
},
|
||||
media_attachments: %{
|
||||
accept_content_types: [
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".png",
|
||||
".gif",
|
||||
".webm",
|
||||
".mp4",
|
||||
".m4v",
|
||||
"image\/jpeg",
|
||||
"image\/png",
|
||||
"image\/gif",
|
||||
"video\/webm",
|
||||
"video\/mp4"
|
||||
]
|
||||
},
|
||||
settings: user.mastofe_settings || %{},
|
||||
push_subscription: nil,
|
||||
accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)},
|
||||
custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis),
|
||||
char_limit: limit
|
||||
}
|
||||
|> Jason.encode!()
|
||||
|> Phoenix.HTML.raw()
|
||||
end
|
||||
|
||||
defp present?(nil), do: false
|
||||
defp present?(false), do: false
|
||||
defp present?(_), do: true
|
||||
|
||||
def render("manifest.json", _params) do
|
||||
%{
|
||||
name: Config.get([:instance, :name]),
|
||||
description: Config.get([:instance, :description]),
|
||||
icons: Config.get([:manifest, :icons]),
|
||||
theme_color: Config.get([:manifest, :theme_color]),
|
||||
background_color: Config.get([:manifest, :background_color]),
|
||||
display: "standalone",
|
||||
scope: Pleroma.Web.Endpoint.url(),
|
||||
start_url: Routes.masto_fe_path(Pleroma.Web.Endpoint, :index, ["getting-started"]),
|
||||
categories: [
|
||||
"social"
|
||||
],
|
||||
serviceworker: %{
|
||||
src: "/sw.js"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue