Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into revert-d6888e24
This commit is contained in:
commit
346014b897
224 changed files with 2531 additions and 1033 deletions
|
|
@ -330,7 +330,13 @@ defmodule Mix.Tasks.Pleroma.Config do
|
|||
|> Enum.each(&write_and_delete(&1, file, opts[:delete]))
|
||||
|
||||
:ok = File.close(file)
|
||||
System.cmd("mix", ["format", path])
|
||||
|
||||
# Ensure `mix format` runs in the same env as the current task and doesn't
|
||||
# emit config-time stderr noise (e.g. dev secret warnings) into `mix test`.
|
||||
System.cmd("mix", ["format", path],
|
||||
env: [{"MIX_ENV", to_string(Mix.env())}],
|
||||
stderr_to_stdout: true
|
||||
)
|
||||
end
|
||||
|
||||
defp config_header, do: "import Config\r\n\r\n"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ defmodule Pleroma.Emoji do
|
|||
|
||||
alias Pleroma.Emoji.Combinations
|
||||
alias Pleroma.Emoji.Loader
|
||||
alias Pleroma.Utils.URIEncoding
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
require Logger
|
||||
|
||||
|
|
@ -189,6 +191,34 @@ defmodule Pleroma.Emoji do
|
|||
|
||||
def emoji_url(_), do: nil
|
||||
|
||||
@spec local_url(String.t() | nil) :: String.t() | nil
|
||||
def local_url(nil), do: nil
|
||||
|
||||
def local_url("http" <> _ = url) do
|
||||
URIEncoding.encode_url(url)
|
||||
end
|
||||
|
||||
def local_url("/" <> _ = path) do
|
||||
path = URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true)
|
||||
Endpoint.url() <> path
|
||||
end
|
||||
|
||||
def local_url(path) when is_binary(path) do
|
||||
local_url("/" <> path)
|
||||
end
|
||||
|
||||
def build_emoji_tag({name, url}) do
|
||||
url = URIEncoding.encode_url(url)
|
||||
|
||||
%{
|
||||
"icon" => %{"url" => "#{url}", "type" => "Image"},
|
||||
"name" => ":" <> name <> ":",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z",
|
||||
"id" => url
|
||||
}
|
||||
end
|
||||
|
||||
def emoji_name_with_instance(name, url) do
|
||||
url = url |> URI.parse() |> Map.get(:host)
|
||||
"#{name}@#{url}"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
defmodule Pleroma.Emoji.Formatter do
|
||||
alias Pleroma.Emoji
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
def emojify(text) do
|
||||
|
|
@ -44,7 +43,7 @@ defmodule Pleroma.Emoji.Formatter do
|
|||
Emoji.get_all()
|
||||
|> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end)
|
||||
|> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
|
||||
Map.put(acc, name, to_string(URI.merge(Endpoint.url(), file)))
|
||||
Map.put(acc, name, Emoji.local_url(file))
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -147,24 +147,22 @@ defmodule Pleroma.FollowingRelationship do
|
|||
|> Repo.aggregate(:count, :id)
|
||||
end
|
||||
|
||||
def get_follow_requests(%User{id: id}) do
|
||||
def get_follow_requests_query(%User{id: id}) do
|
||||
__MODULE__
|
||||
|> join(:inner, [r], f in assoc(r, :follower))
|
||||
|> join(:inner, [r], f in assoc(r, :follower), as: :follower)
|
||||
|> where([r], r.state == ^:follow_pending)
|
||||
|> where([r], r.following_id == ^id)
|
||||
|> where([r, f], f.is_active == true)
|
||||
|> select([r, f], f)
|
||||
|> Repo.all()
|
||||
|> where([r, follower: f], f.is_active == true)
|
||||
|> select([r, follower: f], f)
|
||||
end
|
||||
|
||||
def get_outgoing_follow_requests(%User{id: id}) do
|
||||
def get_outgoing_follow_requests_query(%User{id: id}) do
|
||||
__MODULE__
|
||||
|> join(:inner, [r], f in assoc(r, :following))
|
||||
|> join(:inner, [r], f in assoc(r, :following), as: :following)
|
||||
|> where([r], r.state == ^:follow_pending)
|
||||
|> where([r], r.follower_id == ^id)
|
||||
|> where([r, f], f.is_active == true)
|
||||
|> select([r, f], f)
|
||||
|> Repo.all()
|
||||
|> where([r, following: f], f.is_active == true)
|
||||
|> select([r, following: f], f)
|
||||
end
|
||||
|
||||
def following?(%User{id: follower_id}, %User{id: followed_id}) do
|
||||
|
|
|
|||
|
|
@ -29,22 +29,26 @@ defmodule Pleroma.Upload.Filter.Exiftool.ReadDescription do
|
|||
do: current_description
|
||||
|
||||
defp read_when_empty(_, file, tag) do
|
||||
try do
|
||||
{tag_content, 0} =
|
||||
System.cmd("exiftool", ["-b", "-s3", tag, file],
|
||||
stderr_to_stdout: false,
|
||||
parallelism: true
|
||||
)
|
||||
if File.exists?(file) do
|
||||
try do
|
||||
{tag_content, 0} =
|
||||
System.cmd("exiftool", ["-m", "-b", "-s3", tag, file],
|
||||
stderr_to_stdout: false,
|
||||
parallelism: true
|
||||
)
|
||||
|
||||
tag_content = String.trim(tag_content)
|
||||
tag_content = String.trim(tag_content)
|
||||
|
||||
if tag_content != "" and
|
||||
String.length(tag_content) <=
|
||||
Pleroma.Config.get([:instance, :description_limit]),
|
||||
do: tag_content,
|
||||
else: nil
|
||||
rescue
|
||||
_ in ErlangError -> nil
|
||||
if tag_content != "" and
|
||||
String.length(tag_content) <=
|
||||
Pleroma.Config.get([:instance, :description_limit]),
|
||||
do: tag_content,
|
||||
else: nil
|
||||
rescue
|
||||
_ in ErlangError -> nil
|
||||
end
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripLocation do
|
|||
|
||||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
|
||||
try do
|
||||
case System.cmd("exiftool", ["-overwrite_original", "-gps:all=", "-png:all=", file],
|
||||
case System.cmd("exiftool", ["-m", "-overwrite_original", "-gps:all=", "-png:all=", file],
|
||||
stderr_to_stdout: true,
|
||||
parallelism: true
|
||||
) do
|
||||
{_response, 0} -> {:ok, :filtered}
|
||||
{error, 1} -> {:error, error}
|
||||
{error, _} -> {:error, error}
|
||||
end
|
||||
rescue
|
||||
e in ErlangError ->
|
||||
|
|
|
|||
|
|
@ -287,8 +287,14 @@ defmodule Pleroma.User do
|
|||
defdelegate following(user), to: FollowingRelationship
|
||||
defdelegate following?(follower, followed), to: FollowingRelationship
|
||||
defdelegate following_ap_ids(user), to: FollowingRelationship
|
||||
defdelegate get_follow_requests(user), to: FollowingRelationship
|
||||
defdelegate get_outgoing_follow_requests(user), to: FollowingRelationship
|
||||
defdelegate get_follow_requests_query(user), to: FollowingRelationship
|
||||
defdelegate get_outgoing_follow_requests_query(user), to: FollowingRelationship
|
||||
|
||||
def get_follow_requests(user) do
|
||||
get_follow_requests_query(user)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
defdelegate search(query, opts \\ []), to: User.Search
|
||||
|
||||
@doc """
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
|
|
@ -64,15 +63,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
|
||||
defp add_emoji_content(data, emoji, url) do
|
||||
tag = [
|
||||
%{
|
||||
"id" => url,
|
||||
"type" => "Emoji",
|
||||
"name" => Emoji.maybe_quote(emoji),
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" => url
|
||||
}
|
||||
}
|
||||
Emoji.build_emoji_tag({Emoji.maybe_strip_name(emoji), url})
|
||||
]
|
||||
|
||||
data
|
||||
|
|
@ -113,7 +104,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
|
||||
defp local_custom_emoji_react(data, emoji) do
|
||||
with %{file: path} = emojo <- Emoji.get(emoji) do
|
||||
url = "#{Endpoint.url()}#{path}"
|
||||
url = Emoji.local_url(path)
|
||||
add_emoji_content(data, emojo.code, url)
|
||||
else
|
||||
_ -> {:error, "Emoji does not exist"}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
@behaviour Pleroma.Web.ActivityPub.Transmogrifier.API
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Emoji
|
||||
alias Pleroma.Maps
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Containment
|
||||
|
|
@ -1005,32 +1006,20 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
def take_emoji_tags(%User{emoji: emoji}) do
|
||||
emoji
|
||||
|> Map.to_list()
|
||||
|> Enum.map(&build_emoji_tag/1)
|
||||
|> Enum.map(&Emoji.build_emoji_tag/1)
|
||||
end
|
||||
|
||||
# TODO: we should probably send mtime instead of unix epoch time for updated
|
||||
def add_emoji_tags(%{"emoji" => emoji} = object) do
|
||||
tags = object["tag"] || []
|
||||
|
||||
out = Enum.map(emoji, &build_emoji_tag/1)
|
||||
out = Enum.map(emoji, &Emoji.build_emoji_tag/1)
|
||||
|
||||
Map.put(object, "tag", tags ++ out)
|
||||
end
|
||||
|
||||
def add_emoji_tags(object), do: object
|
||||
|
||||
def build_emoji_tag({name, url}) do
|
||||
url = URI.encode(url)
|
||||
|
||||
%{
|
||||
"icon" => %{"url" => "#{url}", "type" => "Image"},
|
||||
"name" => ":" <> name <> ":",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z",
|
||||
"id" => url
|
||||
}
|
||||
end
|
||||
|
||||
def set_conversation(object) do
|
||||
Map.put(object, "conversation", object["context"])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -73,6 +73,22 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
|||
|> Pleroma.List.member?(user)
|
||||
end
|
||||
|
||||
def visible_for_user?(%Activity{object: %Object{} = object} = activity, nil) do
|
||||
activity_visibility? = restrict_unauthenticated_access?(activity)
|
||||
activity_public? = public?(activity) and not local_public?(activity)
|
||||
object_visibility? = restrict_unauthenticated_access?(object)
|
||||
object_public? = public?(object) and not local_public?(object)
|
||||
|
||||
# Activity could be local, but object might not (Announce/Like)
|
||||
cond do
|
||||
activity_visibility? or object_visibility? ->
|
||||
false
|
||||
|
||||
true ->
|
||||
activity_public? and object_public?
|
||||
end
|
||||
end
|
||||
|
||||
def visible_for_user?(%{__struct__: module} = message, nil)
|
||||
when module in [Activity, Object] do
|
||||
if restrict_unauthenticated_access?(message),
|
||||
|
|
|
|||
|
|
@ -123,7 +123,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
|
|||
name: %Schema{type: :string, description: "Application Name"},
|
||||
scopes: %Schema{type: :array, items: %Schema{type: :string}, description: "oAuth scopes"},
|
||||
redirect_uris: %Schema{
|
||||
type: :string,
|
||||
oneOf: [
|
||||
%Schema{type: :string},
|
||||
%Schema{type: :array, items: %Schema{type: :string}}
|
||||
],
|
||||
description:
|
||||
"Where the user should be redirected after authorization. To display the authorization code to the user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in this parameter."
|
||||
},
|
||||
|
|
@ -141,7 +144,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
|
|||
},
|
||||
example: %{
|
||||
"name" => "My App",
|
||||
"redirect_uris" => "https://myapp.com/auth/callback",
|
||||
"redirect_uris" => ["https://myapp.com/auth/callback"],
|
||||
"website" => "https://myapp.com/",
|
||||
"scopes" => ["read", "write"],
|
||||
"trusted" => true
|
||||
|
|
@ -157,7 +160,10 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
|
|||
name: %Schema{type: :string, description: "Application Name"},
|
||||
scopes: %Schema{type: :array, items: %Schema{type: :string}, description: "oAuth scopes"},
|
||||
redirect_uris: %Schema{
|
||||
type: :string,
|
||||
oneOf: [
|
||||
%Schema{type: :string},
|
||||
%Schema{type: :array, items: %Schema{type: :string}}
|
||||
],
|
||||
description:
|
||||
"Where the user should be redirected after authorization. To display the authorization code to the user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in this parameter."
|
||||
},
|
||||
|
|
@ -175,7 +181,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
|
|||
},
|
||||
example: %{
|
||||
"name" => "My App",
|
||||
"redirect_uris" => "https://myapp.com/auth/callback",
|
||||
"redirect_uris" => ["https://myapp.com/auth/callback"],
|
||||
"website" => "https://myapp.com/",
|
||||
"scopes" => ["read", "write"],
|
||||
"trusted" => true
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
|
|||
properties: %{
|
||||
client_name: %Schema{type: :string, description: "A name for your application."},
|
||||
redirect_uris: %Schema{
|
||||
type: :string,
|
||||
oneOf: [
|
||||
%Schema{type: :string},
|
||||
%Schema{type: :array, items: %Schema{type: :string}}
|
||||
],
|
||||
description:
|
||||
"Where the user should be redirected after authorization. To display the authorization code to the user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in this parameter."
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.ApiSpec.FollowRequestOperation do
|
|||
summary: "Retrieve follow requests",
|
||||
security: [%{"oAuth" => ["read:follows", "follow"]}],
|
||||
operationId: "FollowRequestController.index",
|
||||
parameters: pagination_params(),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of Account", "application/json", %Schema{
|
||||
|
|
@ -62,4 +63,22 @@ defmodule Pleroma.Web.ApiSpec.FollowRequestOperation do
|
|||
required: true
|
||||
)
|
||||
end
|
||||
|
||||
defp pagination_params do
|
||||
[
|
||||
Operation.parameter(:max_id, :query, :string, "Return items older than this ID"),
|
||||
Operation.parameter(
|
||||
:since_id,
|
||||
:query,
|
||||
:string,
|
||||
"Return the oldest items newer than this ID"
|
||||
),
|
||||
Operation.parameter(
|
||||
:limit,
|
||||
:query,
|
||||
%Schema{type: :integer, default: 20},
|
||||
"Maximum number of items to return. Will be ignored if it's more than 40"
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -57,6 +57,22 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
end
|
||||
|
||||
def domain_blocks_operation do
|
||||
%Operation{
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve instance domain blocks",
|
||||
operationId: "InstanceController.domain_blocks",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response(
|
||||
"Array of domain blocks",
|
||||
"application/json",
|
||||
array_of_domain_blocks()
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def translation_languages_operation do
|
||||
%Operation{
|
||||
tags: ["Instance misc"],
|
||||
|
|
@ -420,4 +436,19 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_domain_blocks do
|
||||
%Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
domain: %Schema{type: :string},
|
||||
digest: %Schema{type: :string},
|
||||
severity: %Schema{type: :string},
|
||||
comment: %Schema{type: :string}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ defmodule Pleroma.Web.ApiSpec.PleromaFollowRequestOperation do
|
|||
summary: "Retrieve outgoing follow requests",
|
||||
security: [%{"oAuth" => ["read:follows", "follow"]}],
|
||||
operationId: "PleromaFollowRequestController.outgoing",
|
||||
parameters: pagination_params(),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of Account", "application/json", %Schema{
|
||||
|
|
@ -28,4 +29,22 @@ defmodule Pleroma.Web.ApiSpec.PleromaFollowRequestOperation do
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp pagination_params do
|
||||
[
|
||||
Operation.parameter(:max_id, :query, :string, "Return items older than this ID"),
|
||||
Operation.parameter(
|
||||
:since_id,
|
||||
:query,
|
||||
:string,
|
||||
"Return the oldest items newer than this ID"
|
||||
),
|
||||
Operation.parameter(
|
||||
:limit,
|
||||
:query,
|
||||
%Schema{type: :integer, default: 20},
|
||||
"Maximum number of items to return. Will be ignored if it's more than 40"
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|
|||
)
|
||||
end
|
||||
|
||||
def live_dashboard(conn, _params) do
|
||||
conn
|
||||
|> redirect(to: "/pleroma/live_dashboard")
|
||||
end
|
||||
|
||||
def redirector(conn, _params, code \\ 200) do
|
||||
{:ok, index_content} = File.read(index_file_path(conn))
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.FollowRequestController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [add_link_headers: 2]
|
||||
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
|
@ -24,10 +28,15 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestController do
|
|||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.FollowRequestOperation
|
||||
|
||||
@doc "GET /api/v1/follow_requests"
|
||||
def index(%{assigns: %{user: followed}} = conn, _params) do
|
||||
follow_requests = User.get_follow_requests(followed)
|
||||
def index(%{assigns: %{user: followed}} = conn, params) do
|
||||
follow_requests =
|
||||
followed
|
||||
|> User.get_follow_requests_query()
|
||||
|> Pagination.fetch_paginated(params, :keyset, :follower)
|
||||
|
||||
render(conn, "index.json", for: followed, users: follow_requests, as: :user)
|
||||
conn
|
||||
|> add_link_headers(follow_requests)
|
||||
|> render("index.json", for: followed, users: follow_requests, as: :user)
|
||||
end
|
||||
|
||||
@doc "POST /api/v1/follow_requests/:id/authorize"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(:skip_auth when action in [:show, :show2, :peers])
|
||||
plug(:skip_auth)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.InstanceOperation
|
||||
|
||||
|
|
@ -31,6 +31,11 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
render(conn, "rules.json")
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/instance/domain_blocks"
|
||||
def domain_blocks(conn, _params) do
|
||||
render(conn, "domain_blocks.json")
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/instance/translation_languages"
|
||||
def translation_languages(conn, _params) do
|
||||
render(conn, "translation_languages.json")
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
alias Pleroma.User
|
||||
alias Pleroma.UserNote
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Utils.URIEncoding
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
|
@ -238,7 +239,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
|
||||
emojis =
|
||||
Enum.map(user.emoji, fn {shortcode, raw_url} ->
|
||||
url = MediaProxy.url(raw_url)
|
||||
url =
|
||||
raw_url
|
||||
|> encode_emoji_url()
|
||||
|> MediaProxy.url()
|
||||
|
||||
%{
|
||||
shortcode: shortcode,
|
||||
|
|
@ -356,8 +360,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
%User{id: user_id}
|
||||
) do
|
||||
count =
|
||||
User.get_follow_requests(user)
|
||||
|> length()
|
||||
user
|
||||
|> User.get_follow_requests_query()
|
||||
|> Pleroma.Repo.aggregate(:count)
|
||||
|
||||
data
|
||||
|> Kernel.put_in([:follow_requests_count], count)
|
||||
|
|
@ -511,4 +516,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
# See https://git.pleroma.social/pleroma/pleroma-meta/-/issues/14
|
||||
user.actor_type == "Service" || user.actor_type == "Group"
|
||||
end
|
||||
|
||||
defp encode_emoji_url(nil), do: nil
|
||||
defp encode_emoji_url("http" <> _ = url), do: URIEncoding.encode_url(url)
|
||||
|
||||
defp encode_emoji_url("/" <> _ = path),
|
||||
do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true)
|
||||
|
||||
defp encode_emoji_url(path) when is_binary(path),
|
||||
do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@ defmodule Pleroma.Web.MastodonAPI.CustomEmojiView do
|
|||
use Pleroma.Web, :view
|
||||
|
||||
alias Pleroma.Emoji
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
def render("index.json", %{custom_emojis: custom_emojis}) do
|
||||
render_many(custom_emojis, __MODULE__, "show.json")
|
||||
end
|
||||
|
||||
def render("show.json", %{custom_emoji: {shortcode, %Emoji{file: relative_url, tags: tags}}}) do
|
||||
url = Endpoint.url() |> URI.merge(relative_url) |> to_string()
|
||||
url = Emoji.local_url(relative_url)
|
||||
|
||||
%{
|
||||
"shortcode" => shortcode,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,18 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
||||
use Pleroma.Web, :view
|
||||
|
||||
import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1]
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
@mastodon_api_level "2.7.2"
|
||||
|
||||
@block_severities %{
|
||||
federated_timeline_removal: "silence",
|
||||
reject: "suspend"
|
||||
}
|
||||
|
||||
def render("show.json", _) do
|
||||
instance = Config.get(:instance)
|
||||
|
||||
|
|
@ -90,6 +97,53 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
}
|
||||
end
|
||||
|
||||
def render("domain_blocks.json", _) do
|
||||
if Config.get([:mrf, :transparency]) do
|
||||
exclusions = Config.get([:mrf, :transparency_exclusions]) |> MRF.instance_list_from_tuples()
|
||||
|
||||
domain_blocks =
|
||||
Config.get(:mrf_simple)
|
||||
|> Enum.map(fn {rule, instances} ->
|
||||
instances
|
||||
|> Enum.map(fn
|
||||
{host, reason} when not_empty_string(host) and not_empty_string(reason) ->
|
||||
{host, reason}
|
||||
|
||||
{host, _reason} when not_empty_string(host) ->
|
||||
{host, ""}
|
||||
|
||||
host when not_empty_string(host) ->
|
||||
{host, ""}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.reject(fn {host, _} ->
|
||||
host in exclusions or not Map.has_key?(@block_severities, rule)
|
||||
end)
|
||||
|> Enum.map(fn {host, reason} ->
|
||||
domain_block = %{
|
||||
domain: host,
|
||||
digest: :crypto.hash(:sha256, host) |> Base.encode16(case: :lower),
|
||||
severity: Map.get(@block_severities, rule)
|
||||
}
|
||||
|
||||
if not_empty_string(reason) do
|
||||
Map.put(domain_block, :comment, reason)
|
||||
else
|
||||
domain_block
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|> List.flatten()
|
||||
|
||||
domain_blocks
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def render("translation_languages.json", _) do
|
||||
with true <- Pleroma.Language.Translation.configured?(),
|
||||
{:ok, languages} <- Pleroma.Language.Translation.languages_matrix() do
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
user = CommonAPI.get_user(activity.data["actor"])
|
||||
user = CommonAPI.get_user(object.data["actor"])
|
||||
user_follower_address = user.follower_address
|
||||
|
||||
like_count = object.data["like_count"] || 0
|
||||
|
|
|
|||
|
|
@ -31,9 +31,32 @@ defmodule Pleroma.Web.OAuth.App do
|
|||
|
||||
@spec changeset(t(), map()) :: Ecto.Changeset.t()
|
||||
def changeset(struct, params) do
|
||||
params = normalize_redirect_uris_param(params)
|
||||
|
||||
cast(struct, params, [:client_name, :redirect_uris, :scopes, :website, :trusted, :user_id])
|
||||
end
|
||||
|
||||
defp normalize_redirect_uris_param(%{} = params) do
|
||||
case params do
|
||||
%{redirect_uris: redirect_uris} when is_list(redirect_uris) ->
|
||||
Map.put(params, :redirect_uris, normalize_redirect_uris(redirect_uris))
|
||||
|
||||
%{"redirect_uris" => redirect_uris} when is_list(redirect_uris) ->
|
||||
Map.put(params, "redirect_uris", normalize_redirect_uris(redirect_uris))
|
||||
|
||||
_ ->
|
||||
params
|
||||
end
|
||||
end
|
||||
|
||||
defp normalize_redirect_uris(redirect_uris) when is_list(redirect_uris) do
|
||||
redirect_uris
|
||||
|> Enum.filter(&is_binary/1)
|
||||
|> Enum.map(&String.trim/1)
|
||||
|> Enum.reject(&(&1 == ""))
|
||||
|> Enum.join("\n")
|
||||
end
|
||||
|
||||
@spec register_changeset(t(), map()) :: Ecto.Changeset.t()
|
||||
def register_changeset(struct, params \\ %{}) do
|
||||
changeset =
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
defmodule Pleroma.Web.PleromaAPI.FollowRequestController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [add_link_headers: 2]
|
||||
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
||||
|
|
@ -17,11 +21,15 @@ defmodule Pleroma.Web.PleromaAPI.FollowRequestController do
|
|||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaFollowRequestOperation
|
||||
|
||||
@doc "GET /api/v1/pleroma/outgoing_follow_requests"
|
||||
def outgoing(%{assigns: %{user: follower}} = conn, _params) do
|
||||
follow_requests = User.get_outgoing_follow_requests(follower)
|
||||
def outgoing(%{assigns: %{user: follower}} = conn, params) do
|
||||
follow_requests =
|
||||
follower
|
||||
|> User.get_outgoing_follow_requests_query()
|
||||
|> Pagination.fetch_paginated(params, :keyset, :following)
|
||||
|
||||
conn
|
||||
|> put_view(Pleroma.Web.MastodonAPI.FollowRequestView)
|
||||
|> add_link_headers(follow_requests)
|
||||
|> render("index.json", for: follower, users: follow_requests, as: :user)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
|
|||
|
||||
alias Pleroma.BookmarkFolder
|
||||
alias Pleroma.Emoji
|
||||
alias Pleroma.Web.Endpoint
|
||||
|
||||
def render("show.json", %{folder: %BookmarkFolder{} = folder}) do
|
||||
%{
|
||||
|
|
@ -33,7 +32,7 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
|
|||
emoji = Emoji.get(emoji)
|
||||
|
||||
if emoji != nil do
|
||||
Endpoint.url() |> URI.merge(emoji.file) |> to_string()
|
||||
Emoji.local_url(emoji.file)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.Router do
|
||||
use Pleroma.Web, :router
|
||||
import Phoenix.LiveDashboard.Router
|
||||
import Oban.Web.Router
|
||||
|
||||
pipeline :accepts_html do
|
||||
plug(:accepts, ["html"])
|
||||
|
|
@ -813,6 +814,7 @@ defmodule Pleroma.Web.Router do
|
|||
get("/instance", InstanceController, :show)
|
||||
get("/instance/peers", InstanceController, :peers)
|
||||
get("/instance/rules", InstanceController, :rules)
|
||||
get("/instance/domain_blocks", InstanceController, :domain_blocks)
|
||||
get("/instance/translation_languages", InstanceController, :translation_languages)
|
||||
|
||||
get("/statuses", StatusController, :index)
|
||||
|
|
@ -1043,7 +1045,8 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
scope "/" do
|
||||
pipe_through([:pleroma_html, :authenticate, :require_admin])
|
||||
live_dashboard("/phoenix/live_dashboard", additional_pages: [oban: Oban.LiveDashboard])
|
||||
live_dashboard("/pleroma/live_dashboard", additional_pages: [oban: Oban.LiveDashboard])
|
||||
oban_dashboard("/pleroma/oban")
|
||||
end
|
||||
|
||||
# Test-only routes needed to test action dispatching and plug chain execution
|
||||
|
|
@ -1084,14 +1087,20 @@ defmodule Pleroma.Web.Router do
|
|||
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
|
||||
match(:*, "/api/pleroma/*path", LegacyPleromaApiRerouterPlug, [])
|
||||
get("/api/*path", RedirectController, :api_not_implemented)
|
||||
get("/phoenix/live_dashboard", RedirectController, :live_dashboard)
|
||||
get("/*path", RedirectController, :redirector_with_preload)
|
||||
|
||||
options("/*path", RedirectController, :empty)
|
||||
end
|
||||
|
||||
# /pleroma/{phoenix,oban}/* need to get filtered out from api routes for frontend configuration
|
||||
# to not drop admin overrides for /pleroma/admin.
|
||||
@non_api_routes ["/pleroma/live_dashboard", "/pleroma/oban"]
|
||||
|
||||
def get_api_routes do
|
||||
Phoenix.Router.routes(__MODULE__)
|
||||
|> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end)
|
||||
|> Enum.reject(fn r -> String.starts_with?(r.path, @non_api_routes) end)
|
||||
|> Enum.map(fn r ->
|
||||
r.path
|
||||
|> String.split("/", trim: true)
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ defmodule Pleroma.Web.Streamer do
|
|||
end)
|
||||
end
|
||||
|
||||
defp do_stream("user", item) do
|
||||
defp do_stream("user", %Activity{} = item) do
|
||||
Logger.debug("Trying to push to users")
|
||||
|
||||
recipient_topics =
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|
|||
alias Pleroma.Emoji
|
||||
alias Pleroma.Healthcheck
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Utils.URIEncoding
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -180,12 +181,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|
|||
def emoji(conn, _params) do
|
||||
emoji =
|
||||
Enum.reduce(Emoji.get_all(), %{}, fn {code, %Emoji{file: file, tags: tags}}, acc ->
|
||||
file = encode_emoji_url(file)
|
||||
Map.put(acc, code, %{image_url: file, tags: tags})
|
||||
end)
|
||||
|
||||
json(conn, emoji)
|
||||
end
|
||||
|
||||
defp encode_emoji_url(nil), do: nil
|
||||
defp encode_emoji_url("http" <> _ = url), do: URIEncoding.encode_url(url)
|
||||
|
||||
defp encode_emoji_url("/" <> _ = path),
|
||||
do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true)
|
||||
|
||||
defp encode_emoji_url(path) when is_binary(path),
|
||||
do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true)
|
||||
|
||||
def update_notification_settings(%{assigns: %{user: user}} = conn, params) do
|
||||
with {:ok, _} <- User.update_notification_settings(user, params) do
|
||||
json(conn, %{status: "success"})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue