Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into features/mastoapi-2.9.0-status_text
This commit is contained in:
commit
d3efb50262
89 changed files with 1488 additions and 403 deletions
|
|
@ -109,7 +109,7 @@ defmodule Pleroma.HTML do
|
|||
result =
|
||||
content
|
||||
|> Floki.parse_fragment!()
|
||||
|> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"]")
|
||||
|> Floki.filter_out("a.mention,a.hashtag,a.attachment,a[rel~=\"tag\"]")
|
||||
|> Floki.attribute("a", "href")
|
||||
|> Enum.at(0)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.MigrationHelper.NotificationBackfill do
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
|
@ -25,18 +24,27 @@ defmodule Pleroma.MigrationHelper.NotificationBackfill do
|
|||
|> type_from_activity()
|
||||
|
||||
notification
|
||||
|> Notification.changeset(%{type: type})
|
||||
|> Ecto.Changeset.change(%{type: type})
|
||||
|> Repo.update()
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_by_ap_id(ap_id) do
|
||||
q =
|
||||
from(u in User,
|
||||
select: u.id
|
||||
)
|
||||
|
||||
Repo.get_by(q, ap_id: ap_id)
|
||||
end
|
||||
|
||||
# This is copied over from Notifications to keep this stable.
|
||||
defp type_from_activity(%{data: %{"type" => type}} = activity) do
|
||||
case type do
|
||||
"Follow" ->
|
||||
accepted_function = fn activity ->
|
||||
with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]),
|
||||
%User{} = followed <- User.get_by_ap_id(activity.data["object"]) do
|
||||
with %User{} = follower <- get_by_ap_id(activity.data["actor"]),
|
||||
%User{} = followed <- get_by_ap_id(activity.data["object"]) do
|
||||
Pleroma.FollowingRelationship.following?(follower, followed)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -367,6 +367,7 @@ defmodule Pleroma.Notification do
|
|||
do_send = do_send && user in enabled_receivers
|
||||
create_notification(activity, user, do_send)
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
{:ok, notifications}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ defmodule Pleroma.Object.Fetcher do
|
|||
{:transmogrifier, {:error, {:reject, nil}}} ->
|
||||
{:reject, nil}
|
||||
|
||||
{:transmogrifier, _} ->
|
||||
{:error, "Transmogrifier failure."}
|
||||
{:transmogrifier, _} = e ->
|
||||
{:error, e}
|
||||
|
||||
{:object, data, nil} ->
|
||||
reinject_object(%Object{}, data)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ defmodule Pleroma.User do
|
|||
field(:is_moderator, :boolean, default: false)
|
||||
field(:is_admin, :boolean, default: false)
|
||||
field(:show_role, :boolean, default: true)
|
||||
field(:settings, :map, default: nil)
|
||||
field(:mastofe_settings, :map, default: nil)
|
||||
field(:uri, ObjectValidators.Uri, default: nil)
|
||||
field(:hide_followers_count, :boolean, default: false)
|
||||
field(:hide_follows_count, :boolean, default: false)
|
||||
|
|
@ -1309,7 +1309,8 @@ defmodule Pleroma.User do
|
|||
|
||||
unsubscribe(blocked, blocker)
|
||||
|
||||
if following?(blocked, blocker), do: unfollow(blocked, blocker)
|
||||
unfollowing_blocked = Config.get([:activitypub, :unfollow_blocked], true)
|
||||
if unfollowing_blocked && following?(blocked, blocker), do: unfollow(blocked, blocker)
|
||||
|
||||
{:ok, blocker} = update_follower_count(blocker)
|
||||
{:ok, blocker, _} = Participation.mark_all_as_read(blocker, blocked)
|
||||
|
|
@ -1527,8 +1528,7 @@ defmodule Pleroma.User do
|
|||
blocked_identifiers,
|
||||
fn blocked_identifier ->
|
||||
with {:ok, %User{} = blocked} <- get_or_fetch(blocked_identifier),
|
||||
{:ok, _user_block} <- block(blocker, blocked),
|
||||
{:ok, _} <- ActivityPub.block(blocker, blocked) do
|
||||
{:ok, _block} <- CommonAPI.block(blocker, blocked) do
|
||||
blocked
|
||||
else
|
||||
err ->
|
||||
|
|
@ -2118,8 +2118,8 @@ defmodule Pleroma.User do
|
|||
|
||||
def mastodon_settings_update(user, settings) do
|
||||
user
|
||||
|> cast(%{settings: settings}, [:settings])
|
||||
|> validate_required([:settings])
|
||||
|> cast(%{mastofe_settings: settings}, [:mastofe_settings])
|
||||
|> validate_required([:mastofe_settings])
|
||||
|> update_and_set_cache()
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ defmodule Pleroma.User.Search do
|
|||
|> base_query(following)
|
||||
|> filter_blocked_user(for_user)
|
||||
|> filter_invisible_users()
|
||||
|> filter_internal_users()
|
||||
|> filter_blocked_domains(for_user)
|
||||
|> fts_search(query_string)
|
||||
|> trigram_rank(query_string)
|
||||
|
|
@ -109,6 +110,10 @@ defmodule Pleroma.User.Search do
|
|||
from(q in query, where: q.invisible == false)
|
||||
end
|
||||
|
||||
defp filter_internal_users(query) do
|
||||
from(q in query, where: q.actor_type != "Application")
|
||||
end
|
||||
|
||||
defp filter_blocked_user(query, %User{} = blocker) do
|
||||
query
|
||||
|> join(:left, [u], b in Pleroma.UserRelationship,
|
||||
|
|
|
|||
|
|
@ -366,33 +366,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
end
|
||||
|
||||
@spec block(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||
{:ok, Activity.t()} | {:error, any()}
|
||||
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||
with {:ok, result} <-
|
||||
Repo.transaction(fn -> do_block(blocker, blocked, activity_id, local) end) do
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
defp do_block(blocker, blocked, activity_id, local) do
|
||||
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
||||
|
||||
if unfollow_blocked and fetch_latest_follow(blocker, blocked) do
|
||||
unfollow(blocker, blocked, nil, local)
|
||||
end
|
||||
|
||||
block_data = make_block_data(blocker, blocked, activity_id)
|
||||
|
||||
with {:ok, activity} <- insert(block_data, local),
|
||||
_ <- notify_and_stream(activity),
|
||||
:ok <- maybe_federate(activity) do
|
||||
{:ok, activity}
|
||||
else
|
||||
{:error, error} -> Repo.rollback(error)
|
||||
end
|
||||
end
|
||||
|
||||
@spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def flag(
|
||||
%{
|
||||
|
|
@ -1398,6 +1371,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
end
|
||||
|
||||
def maybe_handle_clashing_nickname(nickname) do
|
||||
with %User{} = old_user <- User.get_by_nickname(nickname) do
|
||||
Logger.info("Found an old user for #{nickname}, ap id is #{old_user.ap_id}, renaming.")
|
||||
|
||||
old_user
|
||||
|> User.remote_user_changeset(%{nickname: "#{old_user.id}.#{old_user.nickname}"})
|
||||
|> User.update_and_set_cache()
|
||||
end
|
||||
end
|
||||
|
||||
def make_user_from_ap_id(ap_id) do
|
||||
user = User.get_cached_by_ap_id(ap_id)
|
||||
|
||||
|
|
@ -1410,6 +1393,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> User.remote_user_changeset(data)
|
||||
|> User.update_and_set_cache()
|
||||
else
|
||||
maybe_handle_clashing_nickname(data[:nickname])
|
||||
|
||||
data
|
||||
|> User.remote_user_changeset()
|
||||
|> Repo.insert()
|
||||
|
|
|
|||
|
|
@ -138,6 +138,18 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
}, []}
|
||||
end
|
||||
|
||||
@spec block(User.t(), User.t()) :: {:ok, map(), keyword()}
|
||||
def block(blocker, blocked) do
|
||||
{:ok,
|
||||
%{
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"type" => "Block",
|
||||
"actor" => blocker.ap_id,
|
||||
"object" => blocked.ap_id,
|
||||
"to" => [blocked.ap_id]
|
||||
}, []}
|
||||
end
|
||||
|
||||
@spec announce(User.t(), Object.t(), keyword()) :: {:ok, map(), keyword()}
|
||||
def announce(actor, object, options \\ []) do
|
||||
public? = Keyword.get(options, :public, false)
|
||||
|
|
|
|||
|
|
@ -27,11 +27,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
|
|||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "actor" => actor, "object" => object} = message) do
|
||||
with {:ok, %User{} = u} <- User.get_or_fetch_by_ap_id(actor),
|
||||
with {:ok, %User{local: false} = u} <- User.get_or_fetch_by_ap_id(actor),
|
||||
{:contains_links, true} <- {:contains_links, contains_links?(object)},
|
||||
{:old_user, true} <- {:old_user, old_user?(u)} do
|
||||
{:ok, message}
|
||||
else
|
||||
{:ok, %User{local: true}} ->
|
||||
{:ok, message}
|
||||
|
||||
{:contains_links, false} ->
|
||||
{:ok, message}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
|
||||
|
|
@ -24,6 +25,25 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
|
||||
def validate(object, meta)
|
||||
|
||||
def validate(%{"type" => "Block"} = block_activity, meta) do
|
||||
with {:ok, block_activity} <-
|
||||
block_activity
|
||||
|> BlockValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert) do
|
||||
block_activity = stringify_keys(block_activity)
|
||||
outgoing_blocks = Pleroma.Config.get([:activitypub, :outgoing_blocks])
|
||||
|
||||
meta =
|
||||
if !outgoing_blocks do
|
||||
Keyword.put(meta, :do_not_federate, true)
|
||||
else
|
||||
meta
|
||||
end
|
||||
|
||||
{:ok, block_activity, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Update"} = update_activity, meta) do
|
||||
with {:ok, update_activity} <-
|
||||
update_activity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator 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)
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
%__MODULE__{}
|
||||
|> cast(data, __schema__(:fields))
|
||||
end
|
||||
|
||||
def validate_data(cng) do
|
||||
cng
|
||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||
|> validate_inclusion(:type, ["Block"])
|
||||
|> validate_actor_presence()
|
||||
|> validate_actor_presence(field_name: :object)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
data
|
||||
|> cast_data
|
||||
|> validate_data
|
||||
end
|
||||
end
|
||||
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
collection, and so on.
|
||||
"""
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Activity.Ir.Topics
|
||||
alias Pleroma.Chat
|
||||
alias Pleroma.Chat.MessageReference
|
||||
alias Pleroma.Notification
|
||||
|
|
@ -20,6 +21,21 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
|
||||
def handle(object, meta \\ [])
|
||||
|
||||
# Tasks this handles:
|
||||
# - Unfollow and block
|
||||
def handle(
|
||||
%{data: %{"type" => "Block", "object" => blocked_user, "actor" => blocking_user}} =
|
||||
object,
|
||||
meta
|
||||
) do
|
||||
with %User{} = blocker <- User.get_cached_by_ap_id(blocking_user),
|
||||
%User{} = blocked <- User.get_cached_by_ap_id(blocked_user) do
|
||||
User.block(blocker, blocked)
|
||||
end
|
||||
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
# Tasks this handles:
|
||||
# - Update the user
|
||||
#
|
||||
|
|
@ -82,7 +98,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
|
||||
if !User.is_internal_user?(user) do
|
||||
Notification.create_notifications(object)
|
||||
ActivityPub.stream_out(object)
|
||||
|
||||
object
|
||||
|> Topics.get_activity_topics()
|
||||
|> Streamer.stream(object)
|
||||
end
|
||||
|
||||
{:ok, object, meta}
|
||||
|
|
|
|||
|
|
@ -446,12 +446,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer", "Audio"] do
|
||||
actor = Containment.get_actor(data)
|
||||
|
||||
data =
|
||||
Map.put(data, "actor", actor)
|
||||
|> fix_addressing
|
||||
|
||||
with nil <- Activity.get_create_by_object_ap_id(object["id"]),
|
||||
{:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(data["actor"]) do
|
||||
{:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(actor),
|
||||
data <- Map.put(data, "actor", actor) |> fix_addressing() do
|
||||
object = fix_object(object, options)
|
||||
|
||||
params = %{
|
||||
|
|
@ -673,7 +670,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
|
||||
def handle_incoming(%{"type" => type} = data, _options)
|
||||
when type in ["Like", "EmojiReact", "Announce"] do
|
||||
when type in ~w{Like EmojiReact Announce} do
|
||||
with :ok <- ObjectValidator.fetch_actor_and_object(data),
|
||||
{:ok, activity, _meta} <-
|
||||
Pipeline.common_pipeline(data, local: false) do
|
||||
|
|
@ -684,9 +681,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{"type" => "Update"} = data,
|
||||
%{"type" => type} = data,
|
||||
_options
|
||||
) do
|
||||
)
|
||||
when type in ~w{Update Block} do
|
||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
|
|
@ -765,21 +763,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = _data,
|
||||
_options
|
||||
) do
|
||||
with %User{local: true} = blocked = User.get_cached_by_ap_id(blocked),
|
||||
{:ok, %User{} = blocker} = User.get_or_fetch_by_ap_id(blocker),
|
||||
{:ok, activity} <- ActivityPub.block(blocker, blocked, id, false) do
|
||||
User.unfollow(blocker, blocked)
|
||||
User.block(blocker, blocked)
|
||||
{:ok, activity}
|
||||
else
|
||||
_e -> :error
|
||||
end
|
||||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{
|
||||
"type" => "Move",
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
|||
@spec visible_for_user?(Activity.t(), User.t() | nil) :: boolean()
|
||||
def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true
|
||||
|
||||
def visible_for_user?(nil, _), do: false
|
||||
|
||||
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
||||
|
||||
def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do
|
||||
user.ap_id in activity.data["to"] ||
|
||||
list_ap_id
|
||||
|
|
@ -54,8 +58,6 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
|||
|> Pleroma.List.member?(user)
|
||||
end
|
||||
|
||||
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
||||
|
||||
def visible_for_user?(%{local: local} = activity, nil) do
|
||||
cfg_key =
|
||||
if local,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
|> List.first()
|
||||
|
||||
_ ->
|
||||
nil
|
||||
"application/json"
|
||||
end
|
||||
|
||||
private_data = Map.put(private_data, :operation_id, operation_id)
|
||||
|
|
|
|||
|
|
@ -40,20 +40,53 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
|
|||
pleroma: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
allow_following_move: %Schema{type: :boolean},
|
||||
background_image: %Schema{type: :string, nullable: true},
|
||||
allow_following_move: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user allows automatically follow moved following accounts"
|
||||
},
|
||||
background_image: %Schema{type: :string, nullable: true, format: :uri},
|
||||
chat_token: %Schema{type: :string},
|
||||
confirmation_pending: %Schema{type: :boolean},
|
||||
confirmation_pending: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"whether the user account is waiting on email confirmation to be activated"
|
||||
},
|
||||
hide_favorites: %Schema{type: :boolean},
|
||||
hide_followers_count: %Schema{type: :boolean},
|
||||
hide_followers: %Schema{type: :boolean},
|
||||
hide_follows_count: %Schema{type: :boolean},
|
||||
hide_follows: %Schema{type: :boolean},
|
||||
is_admin: %Schema{type: :boolean},
|
||||
is_moderator: %Schema{type: :boolean},
|
||||
hide_followers_count: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user has follower stat hiding enabled"
|
||||
},
|
||||
hide_followers: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user has follower hiding enabled"
|
||||
},
|
||||
hide_follows_count: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user has follow stat hiding enabled"
|
||||
},
|
||||
hide_follows: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user has follow hiding enabled"
|
||||
},
|
||||
is_admin: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user is an admin of the local instance"
|
||||
},
|
||||
is_moderator: %Schema{
|
||||
type: :boolean,
|
||||
description: "whether the user is a moderator of the local instance"
|
||||
},
|
||||
skip_thread_containment: %Schema{type: :boolean},
|
||||
tags: %Schema{type: :array, items: %Schema{type: :string}},
|
||||
unread_conversation_count: %Schema{type: :integer},
|
||||
tags: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
description:
|
||||
"List of tags being used for things like extra roles or moderation(ie. marking all media as nsfw all)."
|
||||
},
|
||||
unread_conversation_count: %Schema{
|
||||
type: :integer,
|
||||
description: "The count of unread conversations. Only returned to the account owner."
|
||||
},
|
||||
notification_settings: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
|
|
@ -66,7 +99,9 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
|
|||
},
|
||||
relationship: AccountRelationship,
|
||||
settings_store: %Schema{
|
||||
type: :object
|
||||
type: :object,
|
||||
description:
|
||||
"A generic map of settings for frontends. Opaque to the backend. Only returned in `verify_credentials` and `update_credentials`"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -74,16 +109,32 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
|
|||
type: :object,
|
||||
properties: %{
|
||||
fields: %Schema{type: :array, items: AccountField},
|
||||
note: %Schema{type: :string},
|
||||
note: %Schema{
|
||||
type: :string,
|
||||
description:
|
||||
"Plaintext version of the bio without formatting applied by the backend, used for editing the bio."
|
||||
},
|
||||
privacy: VisibilityScope,
|
||||
sensitive: %Schema{type: :boolean},
|
||||
pleroma: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
actor_type: ActorType,
|
||||
discoverable: %Schema{type: :boolean},
|
||||
no_rich_text: %Schema{type: :boolean},
|
||||
show_role: %Schema{type: :boolean}
|
||||
discoverable: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"whether the user allows discovery of the account in search results and other services."
|
||||
},
|
||||
no_rich_text: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"whether the HTML tags for rich-text formatting are stripped from all statuses requested from the API."
|
||||
},
|
||||
show_role: %Schema{
|
||||
type: :boolean,
|
||||
description:
|
||||
"whether the user wants their role (e.g admin, moderator) to be shown"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
|||
thread_muted: %Schema{
|
||||
type: :boolean,
|
||||
description: "`true` if the thread the post belongs to is muted"
|
||||
},
|
||||
parent_visible: %Schema{
|
||||
type: :boolean,
|
||||
description: "`true` if the parent post is visible to the user"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
require Pleroma.Constants
|
||||
require Logger
|
||||
|
||||
def block(blocker, blocked) do
|
||||
with {:ok, block_data, _} <- Builder.block(blocker, blocked),
|
||||
{:ok, block, _} <- Pipeline.common_pipeline(block_data, local: true) do
|
||||
{:ok, block}
|
||||
end
|
||||
end
|
||||
|
||||
def post_chat_message(%User{} = user, %User{} = recipient, content, opts \\ []) do
|
||||
with maybe_attachment <- opts[:media_id] && Object.get_by_id(opts[:media_id]),
|
||||
:ok <- validate_chat_content_length(content, !!maybe_attachment),
|
||||
|
|
|
|||
|
|
@ -385,8 +385,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
|
||||
@doc "POST /api/v1/accounts/:id/block"
|
||||
def block(%{assigns: %{user: blocker, account: blocked}} = conn, _params) do
|
||||
with {:ok, _user_block} <- User.block(blocker, blocked),
|
||||
{:ok, _activity} <- ActivityPub.block(blocker, blocked) do
|
||||
with {:ok, _activity} <- CommonAPI.block(blocker, blocked) do
|
||||
render(conn, "relationship.json", user: blocker, target: blocked)
|
||||
else
|
||||
{:error, message} -> json_response(conn, :forbidden, %{error: message})
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
background_image: Keyword.get(instance, :background_image),
|
||||
pleroma: %{
|
||||
metadata: %{
|
||||
account_activation_required: Keyword.get(instance, :account_activation_required),
|
||||
features: features(),
|
||||
federation: federation()
|
||||
federation: federation(),
|
||||
fields_limits: fields_limits()
|
||||
},
|
||||
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
|
||||
}
|
||||
|
|
@ -88,4 +90,13 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
end
|
||||
|> Map.put(:enabled, Config.get([:instance, :federating]))
|
||||
end
|
||||
|
||||
def fields_limits do
|
||||
%{
|
||||
max_fields: Config.get([:instance, :max_account_fields]),
|
||||
max_remote_fields: Config.get([:instance, :max_remote_account_fields]),
|
||||
name_length: Config.get([:instance, :account_field_name_length]),
|
||||
value_length: Config.get([:instance, :account_field_value_length])
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1]
|
||||
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2]
|
||||
|
||||
# TODO: Add cached version.
|
||||
defp get_replied_to_activities([]), do: %{}
|
||||
|
|
@ -365,7 +365,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
expires_at: expires_at,
|
||||
direct_conversation_id: direct_conversation_id,
|
||||
thread_muted: thread_muted?,
|
||||
emoji_reactions: emoji_reactions
|
||||
emoji_reactions: emoji_reactions,
|
||||
parent_visible: visible_for_user?(reply_to, opts[:for])
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,35 +19,7 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
|
|||
|> Enum.map(fn u -> u.ap_id end)
|
||||
|
||||
federation = InstanceView.federation()
|
||||
|
||||
features =
|
||||
[
|
||||
"pleroma_api",
|
||||
"mastodon_api",
|
||||
"mastodon_api_streaming",
|
||||
"polls",
|
||||
"pleroma_explicit_addressing",
|
||||
"shareable_emoji_packs",
|
||||
"multifetch",
|
||||
"pleroma:api/v1/notifications:include_types_filter",
|
||||
if Config.get([:media_proxy, :enabled]) do
|
||||
"media_proxy"
|
||||
end,
|
||||
if Config.get([:gopher, :enabled]) do
|
||||
"gopher"
|
||||
end,
|
||||
if Config.get([:chat, :enabled]) do
|
||||
"chat"
|
||||
end,
|
||||
if Config.get([:instance, :allow_relay]) do
|
||||
"relay"
|
||||
end,
|
||||
if Config.get([:instance, :safe_dm_mentions]) do
|
||||
"safe_dm_mentions"
|
||||
end,
|
||||
"pleroma_emoji_reactions"
|
||||
]
|
||||
|> Enum.filter(& &1)
|
||||
features = InstanceView.features()
|
||||
|
||||
%{
|
||||
version: "2.0",
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Preload.Providers.Instance do
|
||||
alias Pleroma.Plugs.InstanceStatic
|
||||
alias Pleroma.Web.MastodonAPI.InstanceView
|
||||
alias Pleroma.Web.Nodeinfo.Nodeinfo
|
||||
alias Pleroma.Web.Preload.Providers.Provider
|
||||
|
||||
@behaviour Provider
|
||||
@instance_url :"/api/v1/instance"
|
||||
@panel_url :"/instance/panel.html"
|
||||
@nodeinfo_url :"/nodeinfo/2.0"
|
||||
@instance_url "/api/v1/instance"
|
||||
@panel_url "/instance/panel.html"
|
||||
@nodeinfo_url "/nodeinfo/2.0.json"
|
||||
|
||||
@impl Provider
|
||||
def generate_terms(_params) do
|
||||
|
|
@ -27,7 +28,7 @@ defmodule Pleroma.Web.Preload.Providers.Instance do
|
|||
end
|
||||
|
||||
defp build_panel_tag(acc) do
|
||||
instance_path = Path.join(:code.priv_dir(:pleroma), "static/instance/panel.html")
|
||||
instance_path = InstanceStatic.file_path(@panel_url |> to_string())
|
||||
|
||||
if File.exists?(instance_path) do
|
||||
panel_data = File.read!(instance_path)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
defmodule Pleroma.Web.Preload.Providers.StatusNet do
|
||||
alias Pleroma.Web.Preload.Providers.Provider
|
||||
alias Pleroma.Web.TwitterAPI.UtilView
|
||||
alias Pleroma.Web.TwitterAPI.UtilController
|
||||
|
||||
@behaviour Provider
|
||||
@config_url :"/api/statusnet/config.json"
|
||||
@config_url "/api/statusnet/config.json"
|
||||
|
||||
@impl Provider
|
||||
def generate_terms(_params) do
|
||||
|
|
@ -16,9 +16,10 @@ defmodule Pleroma.Web.Preload.Providers.StatusNet do
|
|||
end
|
||||
|
||||
defp build_config_tag(acc) do
|
||||
instance = Pleroma.Config.get(:instance)
|
||||
info_data = UtilView.status_net_config(instance)
|
||||
resp =
|
||||
Plug.Test.conn(:get, @config_url |> to_string())
|
||||
|> UtilController.config(nil)
|
||||
|
||||
Map.put(acc, @config_url, info_data)
|
||||
Map.put(acc, @config_url, resp.resp_body)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.Preload.Providers.Timelines do
|
|||
alias Pleroma.Web.Preload.Providers.Provider
|
||||
|
||||
@behaviour Provider
|
||||
@public_url :"/api/v1/timelines/public"
|
||||
@public_url "/api/v1/timelines/public"
|
||||
|
||||
@impl Provider
|
||||
def generate_terms(params) do
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Preload.Providers.User do
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.Preload.Providers.Provider
|
||||
|
||||
@behaviour Provider
|
||||
@account_url :"/api/v1/accounts"
|
||||
@account_url_base "/api/v1/accounts"
|
||||
|
||||
@impl Provider
|
||||
def generate_terms(%{user: user}) do
|
||||
|
|
@ -16,10 +17,10 @@ defmodule Pleroma.Web.Preload.Providers.User do
|
|||
|
||||
def generate_terms(_params), do: %{}
|
||||
|
||||
def build_accounts_tag(acc, nil), do: acc
|
||||
|
||||
def build_accounts_tag(acc, user) do
|
||||
def build_accounts_tag(acc, %User{} = user) do
|
||||
account_data = AccountView.render("show.json", %{user: user, for: user})
|
||||
Map.put(acc, @account_url, account_data)
|
||||
Map.put(acc, "#{@account_url_base}/#{user.id}", account_data)
|
||||
end
|
||||
|
||||
def build_accounts_tag(acc, _), do: acc
|
||||
end
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ defmodule Pleroma.Web.Streamer do
|
|||
true <-
|
||||
Enum.all?([blocked_ap_ids, muted_ap_ids], &(item.actor not in &1)),
|
||||
true <- item.data["type"] != "Announce" || item.actor not in reblog_muted_ap_ids,
|
||||
true <- !(item.data["type"] == "Announce" && parent.data["actor"] == user.ap_id),
|
||||
true <- Enum.all?([blocked_ap_ids, muted_ap_ids], &(parent.data["actor"] not in &1)),
|
||||
true <- MapSet.disjoint?(recipients, recipient_blocks),
|
||||
%{host: item_host} <- URI.parse(item.actor),
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ defmodule Pleroma.Web.MastoFEView do
|
|||
"video\/mp4"
|
||||
]
|
||||
},
|
||||
settings: user.settings || @default_settings,
|
||||
settings: user.mastofe_settings || @default_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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue