aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/mix/tasks/pleroma/relay.ex20
-rw-r--r--lib/mix/tasks/pleroma/user.ex4
-rw-r--r--lib/pleroma/emails/admin_email.ex1
-rw-r--r--lib/pleroma/user/search.ex2
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex7
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex17
-rw-r--r--lib/pleroma/web/activity_pub/views/object_view.ex4
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex2
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex6
-rw-r--r--lib/pleroma/web/admin_api/config.ex15
-rw-r--r--lib/pleroma/web/common_api/utils.ex100
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex4
-rw-r--r--lib/pleroma/web/media_proxy/media_proxy.ex14
-rw-r--r--lib/pleroma/web/ostatus/activity_representer.ex3
-rw-r--r--lib/pleroma/web/rich_media/parsers/twitter_card.ex21
-rw-r--r--lib/pleroma/web/templates/layout/app.html.eex5
16 files changed, 143 insertions, 82 deletions
diff --git a/lib/mix/tasks/pleroma/relay.ex b/lib/mix/tasks/pleroma/relay.ex
index 83ed0ed02..c7324fff6 100644
--- a/lib/mix/tasks/pleroma/relay.ex
+++ b/lib/mix/tasks/pleroma/relay.ex
@@ -5,6 +5,7 @@
defmodule Mix.Tasks.Pleroma.Relay do
use Mix.Task
import Mix.Pleroma
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay
@shortdoc "Manages remote relays"
@@ -22,6 +23,10 @@ defmodule Mix.Tasks.Pleroma.Relay do
``mix pleroma.relay unfollow <relay_url>``
Example: ``mix pleroma.relay unfollow https://example.org/relay``
+
+ ## List relay subscriptions
+
+ ``mix pleroma.relay list``
"""
def run(["follow", target]) do
start_pleroma()
@@ -44,4 +49,19 @@ defmodule Mix.Tasks.Pleroma.Relay do
{:error, e} -> shell_error("Error while following #{target}: #{inspect(e)}")
end
end
+
+ def run(["list"]) do
+ start_pleroma()
+
+ with %User{} = user <- Relay.get_actor() do
+ user.following
+ |> Enum.each(fn entry ->
+ URI.parse(entry)
+ |> Map.get(:host)
+ |> shell_info()
+ end)
+ else
+ e -> shell_error("Error while fetching relay subscription list: #{inspect(e)}")
+ end
+ end
end
diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex
index c9b84b8f9..a3f8bc945 100644
--- a/lib/mix/tasks/pleroma/user.ex
+++ b/lib/mix/tasks/pleroma/user.ex
@@ -31,8 +31,8 @@ defmodule Mix.Tasks.Pleroma.User do
mix pleroma.user invite [OPTION...]
Options:
- - `--expires_at DATE` - last day on which token is active (e.g. "2019-04-05")
- - `--max_use NUMBER` - maximum numbers of token uses
+ - `--expires-at DATE` - last day on which token is active (e.g. "2019-04-05")
+ - `--max-use NUMBER` - maximum numbers of token uses
## List generated invites
diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
index d0e254362..c14be02dd 100644
--- a/lib/pleroma/emails/admin_email.ex
+++ b/lib/pleroma/emails/admin_email.ex
@@ -63,7 +63,6 @@ defmodule Pleroma.Emails.AdminEmail do
new()
|> to({to.name, to.email})
|> from({instance_name(), instance_notify_email()})
- |> reply_to({reporter.name, reporter.email})
|> subject("#{instance_name()} Report")
|> html_body(html_body)
end
diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index 46620b89a..6fb2c2352 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -44,7 +44,7 @@ defmodule Pleroma.User.Search do
query_string = String.trim_leading(query_string, "@")
with [name, domain] <- String.split(query_string, "@"),
- formatted_domain <- String.replace(domain, ~r/[!-\-|@|[-`|{-~|\/|:]+/, "") do
+ formatted_domain <- String.replace(domain, ~r/[!-\-|@|[-`|{-~|\/|:|\s]+/, "") do
name <> "@" <> to_string(:idna.encode(formatted_domain))
else
_ -> query_string
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 07a65127b..1a279a7df 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -267,6 +267,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
else
{:fake, true, activity} ->
{:ok, activity}
+
+ {:error, message} ->
+ {:error, message}
end
end
@@ -746,8 +749,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_favorited_by(query, %{"favorited_by" => ap_id}) do
from(
- activity in query,
- where: fragment(~s(? <@ (? #> '{"object","likes"}'\)), ^ap_id, activity.data)
+ [_activity, object] in query,
+ where: fragment("(?)->'likes' \\? (?)", object.data, ^ap_id)
)
end
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 39074888b..fc5305c58 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -251,20 +251,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
def insert_full_object(map), do: {:ok, map, nil}
- def update_object_in_activities(%{data: %{"id" => id}} = object) do
- # TODO
- # Update activities that already had this. Could be done in a seperate process.
- # Alternatively, just don't do this and fetch the current object each time. Most
- # could probably be taken from cache.
- relevant_activities = Activity.get_all_create_by_object_ap_id(id)
-
- Enum.map(relevant_activities, fn activity ->
- new_activity_data = activity.data |> Map.put("object", object.data)
- changeset = Changeset.change(activity, data: new_activity_data)
- Repo.update(changeset)
- end)
- end
-
#### Like-related helpers
@doc """
@@ -347,8 +333,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> Map.put("#{property}_count", length(element))
|> Map.put("#{property}s", element),
changeset <- Changeset.change(object, data: new_data),
- {:ok, object} <- Object.update_and_set_cache(changeset),
- _ <- update_object_in_activities(object) do
+ {:ok, object} <- Object.update_and_set_cache(changeset) do
{:ok, object}
end
end
diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex
index 6028b773c..94d05f49b 100644
--- a/lib/pleroma/web/activity_pub/views/object_view.ex
+++ b/lib/pleroma/web/activity_pub/views/object_view.ex
@@ -66,8 +66,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
"orderedItems" => items
}
- if offset < total do
+ if offset + length(items) < total do
Map.put(map, "next", "#{iri}?page=#{page + 1}")
+ else
+ map
end
end
end
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 639519e0a..06c9e1c71 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -65,7 +65,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
do: render("service.json", %{user: user})
def render("user.json", %{user: %User{nickname: "internal." <> _} = user}),
- do: render("service.json", %{user: user})
+ do: render("service.json", %{user: user}) |> Map.put("preferredUsername", user.nickname)
def render("user.json", %{user: user}) do
{:ok, user} = User.ensure_keys_present(user)
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index fcda57b3e..2d3d0adc4 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -402,9 +402,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
if Pleroma.Config.get([:instance, :dynamic_configuration]) do
updated =
Enum.map(configs, fn
- %{"group" => group, "key" => key, "delete" => "true"} ->
- {:ok, _} = Config.delete(%{group: group, key: key})
- nil
+ %{"group" => group, "key" => key, "delete" => "true"} = params ->
+ {:ok, config} = Config.delete(%{group: group, key: key, subkeys: params["subkeys"]})
+ config
%{"group" => group, "key" => key, "value" => value} ->
{:ok, config} = Config.update_or_create(%{group: group, key: key, value: value})
diff --git a/lib/pleroma/web/admin_api/config.ex b/lib/pleroma/web/admin_api/config.ex
index dde05ea7b..a10cc779b 100644
--- a/lib/pleroma/web/admin_api/config.ex
+++ b/lib/pleroma/web/admin_api/config.ex
@@ -55,8 +55,19 @@ defmodule Pleroma.Web.AdminAPI.Config do
@spec delete(map()) :: {:ok, Config.t()} | {:error, Changeset.t()}
def delete(params) do
- with %Config{} = config <- Config.get_by_params(params) do
- Repo.delete(config)
+ with %Config{} = config <- Config.get_by_params(Map.delete(params, :subkeys)) do
+ if params[:subkeys] do
+ updated_value =
+ Keyword.drop(
+ :erlang.binary_to_term(config.value),
+ Enum.map(params[:subkeys], &do_transform_string(&1))
+ )
+
+ Config.update(config, %{value: updated_value})
+ else
+ Repo.delete(config)
+ {:ok, nil}
+ end
else
nil ->
err =
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index c8a743e8e..22c44a0a3 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -47,26 +47,43 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def get_replied_to_activity(_), do: nil
- def attachments_from_ids(data) do
- if Map.has_key?(data, "descriptions") do
- attachments_from_ids_descs(data["media_ids"], data["descriptions"])
- else
- attachments_from_ids_no_descs(data["media_ids"])
- end
+ def attachments_from_ids(%{"media_ids" => ids, "descriptions" => desc} = _) do
+ attachments_from_ids_descs(ids, desc)
+ end
+
+ def attachments_from_ids(%{"media_ids" => ids} = _) do
+ attachments_from_ids_no_descs(ids)
end
+ def attachments_from_ids(_), do: []
+
+ def attachments_from_ids_no_descs([]), do: []
+
def attachments_from_ids_no_descs(ids) do
- Enum.map(ids || [], fn media_id ->
- Repo.get(Object, media_id).data
+ Enum.map(ids, fn media_id ->
+ case Repo.get(Object, media_id) do
+ %Object{data: data} = _ -> data
+ _ -> nil
+ end
end)
+ |> Enum.filter(& &1)
end
+ def attachments_from_ids_descs([], _), do: []
+
def attachments_from_ids_descs(ids, descs_str) do
{_, descs} = Jason.decode(descs_str)
- Enum.map(ids || [], fn media_id ->
- Map.put(Repo.get(Object, media_id).data, "name", descs[media_id])
+ Enum.map(ids, fn media_id ->
+ case Repo.get(Object, media_id) do
+ %Object{data: data} = _ ->
+ Map.put(data, "name", descs[media_id])
+
+ _ ->
+ nil
+ end
end)
+ |> Enum.filter(& &1)
end
@spec get_to_and_cc(User.t(), list(String.t()), Activity.t() | nil, String.t()) ::
@@ -247,20 +264,18 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end
def add_attachments(text, attachments) do
- attachment_text =
- Enum.map(attachments, fn
- %{"url" => [%{"href" => href} | _]} = attachment ->
- name = attachment["name"] || URI.decode(Path.basename(href))
- href = MediaProxy.url(href)
- "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
-
- _ ->
- ""
- end)
-
+ attachment_text = Enum.map(attachments, &build_attachment_link/1)
Enum.join([text | attachment_text], "<br>")
end
+ defp build_attachment_link(%{"url" => [%{"href" => href} | _]} = attachment) do
+ name = attachment["name"] || URI.decode(Path.basename(href))
+ href = MediaProxy.url(href)
+ "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
+ end
+
+ defp build_attachment_link(_), do: ""
+
def format_input(text, format, options \\ [])
@doc """
@@ -320,7 +335,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
sensitive \\ false,
merge \\ %{}
) do
- object = %{
+ %{
"type" => "Note",
"to" => to,
"cc" => cc,
@@ -330,18 +345,20 @@ defmodule Pleroma.Web.CommonAPI.Utils do
"context" => context,
"attachment" => attachments,
"actor" => actor,
- "tag" => tags |> Enum.map(fn {_, tag} -> tag end) |> Enum.uniq()
+ "tag" => Keyword.values(tags) |> Enum.uniq()
}
+ |> add_in_reply_to(in_reply_to)
+ |> Map.merge(merge)
+ end
- object =
- with false <- is_nil(in_reply_to),
- %Object{} = in_reply_to_object <- Object.normalize(in_reply_to) do
- Map.put(object, "inReplyTo", in_reply_to_object.data["id"])
- else
- _ -> object
- end
+ defp add_in_reply_to(object, nil), do: object
- Map.merge(object, merge)
+ defp add_in_reply_to(object, in_reply_to) do
+ with %Object{} = in_reply_to_object <- Object.normalize(in_reply_to) do
+ Map.put(object, "inReplyTo", in_reply_to_object.data["id"])
+ else
+ _ -> object
+ end
end
def format_naive_asctime(date) do
@@ -373,17 +390,16 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
end
- def to_masto_date(date) do
- try do
- date
- |> NaiveDateTime.from_iso8601!()
- |> NaiveDateTime.to_iso8601()
- |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
- rescue
- _e -> ""
+ def to_masto_date(date) when is_binary(date) do
+ with {:ok, date} <- NaiveDateTime.from_iso8601(date) do
+ to_masto_date(date)
+ else
+ _ -> ""
end
end
+ def to_masto_date(_), do: ""
+
defp shortname(name) do
if String.length(name) < 30 do
name
@@ -428,7 +444,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
object_data =
cond do
- !is_nil(object) ->
+ not is_nil(object) ->
object.data
is_map(data["object"]) ->
@@ -472,9 +488,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def maybe_extract_mentions(%{"tag" => tag}) do
tag
- |> Enum.filter(fn x -> is_map(x) end)
- |> Enum.filter(fn x -> x["type"] == "Mention" end)
+ |> Enum.filter(fn x -> is_map(x) && x["type"] == "Mention" end)
|> Enum.map(fn x -> x["href"] end)
+ |> Enum.uniq()
end
def maybe_extract_mentions(_), do: []
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index b2b06eeb9..de084fd6e 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
id: to_string(user.id),
acct: user.nickname,
username: username_from_nickname(user.nickname),
- url: user.ap_id
+ url: User.profile_url(user)
}
end
@@ -106,7 +106,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
following_count: user_info.following_count,
statuses_count: user_info.note_count,
note: bio || "",
- url: user.ap_id,
+ url: User.profile_url(user),
avatar: image,
avatar_static: image,
header: header,
diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex
index a661e9bb7..1725ab071 100644
--- a/lib/pleroma/web/media_proxy/media_proxy.ex
+++ b/lib/pleroma/web/media_proxy/media_proxy.ex
@@ -4,6 +4,7 @@
defmodule Pleroma.Web.MediaProxy do
alias Pleroma.Config
+ alias Pleroma.Upload
alias Pleroma.Web
@base64_opts [padding: false]
@@ -26,7 +27,18 @@ defmodule Pleroma.Web.MediaProxy do
defp whitelisted?(url) do
%{host: domain} = URI.parse(url)
- Enum.any?(Config.get([:media_proxy, :whitelist]), fn pattern ->
+ mediaproxy_whitelist = Config.get([:media_proxy, :whitelist])
+
+ upload_base_url_domain =
+ if !is_nil(Config.get([Upload, :base_url])) do
+ [URI.parse(Config.get([Upload, :base_url])).host]
+ else
+ []
+ end
+
+ whitelist = mediaproxy_whitelist ++ upload_base_url_domain
+
+ Enum.any?(whitelist, fn pattern ->
String.equivalent?(domain, pattern)
end)
end
diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex
index 760345301..8e55b9f0b 100644
--- a/lib/pleroma/web/ostatus/activity_representer.ex
+++ b/lib/pleroma/web/ostatus/activity_representer.ex
@@ -183,6 +183,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
retweeted_activity = Activity.get_create_by_object_ap_id(activity.data["object"])
+ retweeted_object = Object.normalize(retweeted_activity)
retweeted_user = User.get_cached_by_ap_id(retweeted_activity.data["actor"])
retweeted_xml = to_simple_form(retweeted_activity, retweeted_user, true)
@@ -197,7 +198,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/share']},
{:id, h.(activity.data["id"])},
{:title, ['#{user.nickname} repeated a notice']},
- {:content, [type: 'html'], ['RT #{retweeted_activity.data["object"]["content"]}']},
+ {:content, [type: 'html'], ['RT #{retweeted_object.data["content"]}']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)},
{:"ostatus:conversation", [ref: h.(activity.data["context"])],
diff --git a/lib/pleroma/web/rich_media/parsers/twitter_card.ex b/lib/pleroma/web/rich_media/parsers/twitter_card.ex
index e4efe2dd0..afaa98f3d 100644
--- a/lib/pleroma/web/rich_media/parsers/twitter_card.ex
+++ b/lib/pleroma/web/rich_media/parsers/twitter_card.ex
@@ -3,13 +3,20 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.Parsers.TwitterCard do
+ alias Pleroma.Web.RichMedia.Parsers.MetaTagsParser
+
+ @spec parse(String.t(), map()) :: {:ok, map()} | {:error, String.t()}
def parse(html, data) do
- Pleroma.Web.RichMedia.Parsers.MetaTagsParser.parse(
- html,
- data,
- "twitter",
- "No twitter card metadata found",
- "name"
- )
+ data
+ |> parse_name_attrs(html)
+ |> parse_property_attrs(html)
+ end
+
+ defp parse_name_attrs(data, html) do
+ MetaTagsParser.parse(html, data, "twitter", %{}, "name")
+ end
+
+ defp parse_property_attrs({_, data}, html) do
+ MetaTagsParser.parse(html, data, "twitter", "No twitter card metadata found", "property")
end
end
diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex
index b3cf9ed11..5836ec1e0 100644
--- a/lib/pleroma/web/templates/layout/app.html.eex
+++ b/lib/pleroma/web/templates/layout/app.html.eex
@@ -36,6 +36,11 @@
margin-bottom: 20px;
}
+ a {
+ color: color: #d8a070;
+ text-decoration: none;
+ }
+
form {
width: 100%;
}