From 675639225a905f5b0b2650cd3f20a4758fc3f868 Mon Sep 17 00:00:00 2001
From: HJ <30-hj@users.noreply.git.pleroma.social>
Date: Fri, 28 Apr 2023 11:13:42 +0000
Subject: allow https: so that flash works across instances without need for
media proxy
---
lib/pleroma/web/plugs/http_security_plug.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index 34895c8d5..045384e08 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -104,7 +104,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
{[img_src, " https:"], [media_src, " https:"]}
end
- connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
+ connect_src = ["connect-src 'self' blob: https: ", static_url, ?\s, websocket_url]
connect_src =
if Config.get(:env) == :dev do
--
cgit v1.2.3
From c0d11da2d8edc57ef88163c06a19aad3e28d14db Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Sun, 7 May 2023 15:16:30 +0300
Subject: conditionally set csp depnding on media-proxy state
---
lib/pleroma/web/plugs/http_security_plug.ex | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index 045384e08..df46cfa0c 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -93,18 +93,26 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
+ connect_src = ["connect-src 'self' blob:", static_url, ?\s, websocket_url]
# Strict multimedia CSP enforcement only when MediaProxy is enabled
- {img_src, media_src} =
+ {img_src, media_src, connect_src} =
if Config.get([:media_proxy, :enabled]) &&
!Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do
sources = build_csp_multimedia_source_list()
- {[img_src, sources], [media_src, sources]}
+ {
+ [img_src, sources],
+ [media_src, sources],
+ [connect_src, sources]
+ }
else
- {[img_src, " https:"], [media_src, " https:"]}
+ {
+ [img_src, " https:"],
+ [media_src, " https:"],
+ [connect_src, " https:"]
+ }
end
- connect_src = ["connect-src 'self' blob: https: ", static_url, ?\s, websocket_url]
connect_src =
if Config.get(:env) == :dev do
--
cgit v1.2.3
From f8ef4924ecab5ba6851eee82845624bc15f868de Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Sun, 7 May 2023 15:24:09 +0300
Subject: fix whitespace
---
lib/pleroma/web/plugs/http_security_plug.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index df46cfa0c..a3166bc96 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
- connect_src = ["connect-src 'self' blob:", static_url, ?\s, websocket_url]
+ connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
# Strict multimedia CSP enforcement only when MediaProxy is enabled
{img_src, media_src, connect_src} =
--
cgit v1.2.3
From f50fd9278fd36e6bd3ae36bb7f5033d9fd8a84ac Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Sun, 7 May 2023 15:29:19 +0300
Subject: reduce redundant reduntancy reduction
---
lib/pleroma/web/plugs/http_security_plug.ex | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index a3166bc96..b189d5bfd 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
- connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
+ connect_src = "connect-src 'self' blob:"
# Strict multimedia CSP enforcement only when MediaProxy is enabled
{img_src, media_src, connect_src} =
@@ -103,7 +103,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
{
[img_src, sources],
[media_src, sources],
- [connect_src, sources]
+ [connect_src, sources, ?\s, websocket_url]
}
else
{
--
cgit v1.2.3
From 2a07411b0cb14ea26966659605d95074b02a8538 Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Sun, 7 May 2023 15:34:17 +0300
Subject: keep the websocket url for all modes
---
lib/pleroma/web/plugs/http_security_plug.ex | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index b189d5bfd..b3dc8a3a6 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
- connect_src = "connect-src 'self' blob:"
+ connect_src = ["connect-src 'self' blob: ", ?\s, websocket_url]
# Strict multimedia CSP enforcement only when MediaProxy is enabled
{img_src, media_src, connect_src} =
@@ -103,7 +103,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
{
[img_src, sources],
[media_src, sources],
- [connect_src, sources, ?\s, websocket_url]
+ [connect_src, sources]
}
else
{
--
cgit v1.2.3
From d838d1990bf23d452c1cc830629e42e51dbd7047 Mon Sep 17 00:00:00 2001
From: Haelwenn
Date: Wed, 16 Aug 2023 13:34:32 +0000
Subject: Apply lanodan's suggestion(s) to 1 file(s)
---
lib/pleroma/web/plugs/http_security_plug.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index b3dc8a3a6..a3166bc96 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
- connect_src = ["connect-src 'self' blob: ", ?\s, websocket_url]
+ connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
# Strict multimedia CSP enforcement only when MediaProxy is enabled
{img_src, media_src, connect_src} =
--
cgit v1.2.3
From 3d09bc320efcc68beb9b57fba23b6b9f3dc17905 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 30 Aug 2023 20:34:16 -0400
Subject: Make lint happy
---
lib/pleroma/web/plugs/http_security_plug.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index a3166bc96..5093414c4 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -100,6 +100,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
if Config.get([:media_proxy, :enabled]) &&
!Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do
sources = build_csp_multimedia_source_list()
+
{
[img_src, sources],
[media_src, sources],
@@ -113,7 +114,6 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
}
end
-
connect_src =
if Config.get(:env) == :dev do
[connect_src, " http://localhost:3035/"]
--
cgit v1.2.3
From 1afde067b12ad0062c1820091ea9b0a680819281 Mon Sep 17 00:00:00 2001
From: Mint
Date: Sat, 2 Sep 2023 01:43:25 +0300
Subject: CommonAPI: Prevent users from accessing media of other users
---
lib/pleroma/scheduled_activity.ex | 6 +++++-
lib/pleroma/web/common_api.ex | 12 ++++++++++++
lib/pleroma/web/common_api/activity_draft.ex | 2 +-
lib/pleroma/web/common_api/utils.ex | 27 ++++++++++++++-------------
4 files changed, 32 insertions(+), 15 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/scheduled_activity.ex b/lib/pleroma/scheduled_activity.ex
index a7be58512..0ed51ad07 100644
--- a/lib/pleroma/scheduled_activity.ex
+++ b/lib/pleroma/scheduled_activity.ex
@@ -40,7 +40,11 @@ defmodule Pleroma.ScheduledActivity do
%{changes: %{params: %{"media_ids" => media_ids} = params}} = changeset
)
when is_list(media_ids) do
- media_attachments = Utils.attachments_from_ids(%{media_ids: media_ids})
+ media_attachments =
+ Utils.attachments_from_ids(
+ %{media_ids: media_ids},
+ User.get_cached_by_id(changeset.data.user_id)
+ )
params =
params
diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex
index 77b3fa5d2..82c7f70d2 100644
--- a/lib/pleroma/web/common_api.ex
+++ b/lib/pleroma/web/common_api.ex
@@ -33,6 +33,7 @@ defmodule Pleroma.Web.CommonAPI do
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_attachment_attribution(maybe_attachment, user),
:ok <- validate_chat_content_length(content, !!maybe_attachment),
{_, {:ok, chat_message_data, _meta}} <-
{:build_object,
@@ -71,6 +72,17 @@ defmodule Pleroma.Web.CommonAPI do
text
end
+ defp validate_chat_attachment_attribution(nil, _), do: :ok
+
+ defp validate_chat_attachment_attribution(attachment, user) do
+ with :ok <- Object.authorize_access(attachment, user) do
+ :ok
+ else
+ e ->
+ e
+ end
+ end
+
defp validate_chat_content_length(_, true), do: :ok
defp validate_chat_content_length(nil, false), do: {:error, :no_content}
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 9af635da8..63ed48a27 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -111,7 +111,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
end
defp attachments(%{params: params} = draft) do
- attachments = Utils.attachments_from_ids(params)
+ attachments = Utils.attachments_from_ids(params, draft.user)
draft = %__MODULE__{draft | attachments: attachments}
case Utils.validate_attachments_count(attachments) do
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index b9fe0224c..0f394e951 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -23,21 +23,21 @@ defmodule Pleroma.Web.CommonAPI.Utils do
require Logger
require Pleroma.Constants
- def attachments_from_ids(%{media_ids: ids, descriptions: desc}) do
- attachments_from_ids_descs(ids, desc)
+ def attachments_from_ids(%{media_ids: ids, descriptions: desc}, user) do
+ attachments_from_ids_descs(ids, desc, user)
end
- def attachments_from_ids(%{media_ids: ids}) do
- attachments_from_ids_no_descs(ids)
+ def attachments_from_ids(%{media_ids: ids}, user) do
+ attachments_from_ids_no_descs(ids, user)
end
- def attachments_from_ids(_), do: []
+ def attachments_from_ids(_, _), do: []
- def attachments_from_ids_no_descs([]), do: []
+ def attachments_from_ids_no_descs([], _), do: []
- def attachments_from_ids_no_descs(ids) do
+ def attachments_from_ids_no_descs(ids, user) do
Enum.map(ids, fn media_id ->
- case get_attachment(media_id) do
+ case get_attachment(media_id, user) do
%Object{data: data} -> data
_ -> nil
end
@@ -45,22 +45,23 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|> Enum.reject(&is_nil/1)
end
- def attachments_from_ids_descs([], _), do: []
+ def attachments_from_ids_descs([], _, _), do: []
- def attachments_from_ids_descs(ids, descs_str) do
+ def attachments_from_ids_descs(ids, descs_str, user) do
{_, descs} = Jason.decode(descs_str)
Enum.map(ids, fn media_id ->
- with %Object{data: data} <- get_attachment(media_id) do
+ with %Object{data: data} <- get_attachment(media_id, user) do
Map.put(data, "name", descs[media_id])
end
end)
|> Enum.reject(&is_nil/1)
end
- defp get_attachment(media_id) do
+ defp get_attachment(media_id, user) do
with %Object{data: data} = object <- Repo.get(Object, media_id),
- %{"type" => type} when type in Pleroma.Constants.upload_object_types() <- data do
+ %{"type" => type} when type in Pleroma.Constants.upload_object_types() <- data,
+ :ok <- Object.authorize_access(object, user) do
object
else
_ -> nil
--
cgit v1.2.3
From 31eb3dc24587ad3715da9fe00886867a6c0bf0c4 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 16:41:30 -0600
Subject: ObjectValidators: accept "quoteUrl" field
---
lib/pleroma/web/activity_pub/object_validators/common_fields.ex | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
index d580208df..835ed97b7 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
@@ -27,7 +27,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do
end
end
- # All objects except Answer and CHatMessage
+ # All objects except Answer and ChatMessage
defmacro object_fields do
quote bind_quoted: binding() do
field(:content, :string)
@@ -58,6 +58,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFields do
field(:like_count, :integer, default: 0)
field(:announcement_count, :integer, default: 0)
field(:inReplyTo, ObjectValidators.ObjectID)
+ field(:quoteUrl, ObjectValidators.ObjectID)
field(:url, ObjectValidators.BareUri)
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
--
cgit v1.2.3
From 795736af16dca77929725e7dd55f5de04a796fdb Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 18:03:22 -0600
Subject: ObjectValidators: improve quoteUrl compatibility
---
.../object_validators/article_note_page_validator.ex | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
index 2670e3f17..40bb67934 100644
--- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
@@ -76,6 +76,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
def fix_attachments(data), do: data
+ defp fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data
+
+ # Fix for Fedibird
+ # https://github.com/fedibird/mastodon/issues/9
+ defp fix_quote_url(%{"quoteURL" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ # Misskey fallback
+ defp fix_quote_url(%{"_misskey_quote" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ defp fix_quote_url(data), do: data
+
defp fix(data) do
data
|> CommonFixes.fix_actor()
@@ -84,6 +99,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|> fix_tag()
|> fix_replies()
|> fix_attachments()
+ |> fix_quote_url()
|> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map()
end
--
cgit v1.2.3
From b022d6635dad4b2769fbf1fd4b97f77a4cc646b4 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 18:46:58 -0600
Subject: Transmogrifier: fetch quoted post
---
lib/pleroma/web/activity_pub/transmogrifier.ex | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 0e6c429f9..c466271ca 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -166,6 +166,22 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_in_reply_to(object, _options), do: object
+ def fix_quote(object, options \\ [])
+
+ def fix_quote(%{"quoteUrl" => quote_url} = object, options)
+ when not is_nil(quote_url) do
+ with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
+ %Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
+ Map.put(object, "quoteUrl", quoted_object.data["id"])
+ else
+ e ->
+ Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
+ object
+ end
+ end
+
+ def fix_quote(object, _options), do: object
+
defp prepare_in_reply_to(in_reply_to) do
cond do
is_bitstring(in_reply_to) ->
@@ -454,6 +470,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> strip_internal_fields()
|> fix_type(fetch_options)
|> fix_in_reply_to(fetch_options)
+ |> fix_quote(fetch_options)
data = Map.put(data, "object", object)
options = Keyword.put(options, :local, false)
--
cgit v1.2.3
From cc4badaf60462fdb8bb57225437e3dd360ee0dfb Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 19:14:39 -0600
Subject: Transmogrifier: fix quoteUrl here too
---
lib/pleroma/web/activity_pub/transmogrifier.ex | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index c466271ca..f5771e75e 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -166,9 +166,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_in_reply_to(object, _options), do: object
- def fix_quote(object, options \\ [])
+ def fix_quote_url(object, options \\ [])
- def fix_quote(%{"quoteUrl" => quote_url} = object, options)
+ def fix_quote_url(%{"quoteUrl" => quote_url} = object, options)
when not is_nil(quote_url) do
with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
%Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
@@ -180,7 +180,22 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- def fix_quote(object, _options), do: object
+ # Fix for Fedibird
+ # https://github.com/fedibird/mastodon/issues/9
+ def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUrl", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ # Misskey fallback
+ def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUrl", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ def fix_quote_url(object, _options), do: object
defp prepare_in_reply_to(in_reply_to) do
cond do
@@ -470,7 +485,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> strip_internal_fields()
|> fix_type(fetch_options)
|> fix_in_reply_to(fetch_options)
- |> fix_quote(fetch_options)
+ |> fix_quote_url(fetch_options)
data = Map.put(data, "object", object)
options = Keyword.put(options, :local, false)
--
cgit v1.2.3
From ce5eb3172321f0ef2ae85d7819b44cc8241a5581 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 19:47:08 -0600
Subject: StatusView: show quoted posts through the API, probably
---
lib/pleroma/web/mastodon_api/views/status_view.ex | 42 ++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index dea22f9c2..b966a84d0 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -57,6 +57,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end)
end
+ defp get_quoted_activities([]), do: %{}
+
+ defp get_quoted_activities(activities) do
+ activities
+ |> Enum.map(fn
+ %{data: %{"type" => "Create"}} = activity ->
+ object = Object.normalize(activity, fetch: false)
+ object && object.data["quoteUrl"] != "" && object.data["quoteUrl"]
+
+ _ ->
+ nil
+ end)
+ |> Enum.filter(& &1)
+ |> Activity.create_by_object_ap_id_with_object()
+ |> Repo.all()
+ |> Enum.reduce(%{}, fn activity, acc ->
+ object = Object.normalize(activity, fetch: false)
+ if object, do: Map.put(acc, object.data["id"], activity), else: acc
+ end)
+ end
+
# DEPRECATED This field seems to be a left-over from the StatusNet era.
# If your application uses `pleroma.conversation_id`: this field is deprecated.
# It is currently stubbed instead by doing a CRC32 of the context, and
@@ -97,6 +118,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
# length(activities_with_links) * timeout
fetch_rich_media_for_activities(activities)
replied_to_activities = get_replied_to_activities(activities)
+ quoted_activities = get_quoted_activities(activities)
parent_activities =
activities
@@ -129,6 +151,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
opts =
opts
|> Map.put(:replied_to_activities, replied_to_activities)
+ |> Map.put(:quoted_activities, quoted_activities)
|> Map.put(:parent_activities, parent_activities)
|> Map.put(:relationships, relationships_opt)
@@ -277,7 +300,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
reply_to = get_reply_to(activity, opts)
-
reply_to_user = reply_to && CommonAPI.get_user(reply_to.data["actor"])
history_len =
@@ -290,6 +312,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
# Here the implicit index of the current content is 0
chrono_order = history_len - 1
+ quote_activity = get_quote(activity, opts)
+
content =
object
|> render_content()
@@ -398,6 +422,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
conversation_id: get_context_id(activity),
context: object.data["context"],
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
+ quote_id: quote_activity && to_string(quote_activity.id),
content: %{"text/plain" => content_plaintext},
spoiler_text: %{"text/plain" => summary},
expires_at: expires_at,
@@ -633,6 +658,21 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
+ def get_quote(activity, %{quoted_activities: quoted_activities}) do
+ object = Object.normalize(activity, fetch: false)
+ quoted_activities[object.data["quoteUrl"]]
+ end
+
+ def get_quote(%{data: %{"object" => _object}} = activity, _) do
+ object = Object.normalize(activity, fetch: false)
+
+ if object.data["quoteUrl"] && object.data["quoteUrl"] != "" do
+ Activity.get_create_by_object_ap_id(object.data["quoteUrl"])
+ else
+ nil
+ end
+ end
+
def render_content(%{data: %{"name" => name}} = object) when not is_nil(name) and name != "" do
url = object.data["url"] || object.data["id"]
--
cgit v1.2.3
From 0d9c443e51c85d9ded3e20954c9620f7a9d2361e Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 20:05:58 -0600
Subject: StatusView: render the whole quoted status
---
lib/pleroma/web/api_spec/schemas/status.ex | 5 +++++
lib/pleroma/web/mastodon_api/views/status_view.ex | 10 +++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index bc29cf4a6..39241aa39 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -193,6 +193,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
nullable: true,
description: "The `acct` property of User entity for replied user (if any)"
},
+ quote: %Schema{
+ allOf: [%OpenApiSpex.Reference{"$ref": "#/components/schemas/Status"}],
+ nullable: true,
+ description: "Quoted status (if any)"
+ },
local: %Schema{
type: :boolean,
description: "`true` if the post was made on the local instance"
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index b966a84d0..5bde1ce04 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -314,6 +314,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
quote_activity = get_quote(activity, opts)
+ quote_post =
+ if quote_activity do
+ quote_rendering_opts = Map.put(opts, :activity, quote_activity)
+ render("show.json", quote_rendering_opts)
+ else
+ nil
+ end
+
content =
object
|> render_content()
@@ -422,7 +430,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
conversation_id: get_context_id(activity),
context: object.data["context"],
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
- quote_id: quote_activity && to_string(quote_activity.id),
+ quote: quote_post,
content: %{"text/plain" => content_plaintext},
spoiler_text: %{"text/plain" => summary},
expires_at: expires_at,
--
cgit v1.2.3
From 6ac19c3999c543e5a26bbf04932a6a7aaa447b99 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 21:27:05 -0600
Subject: ActivityDraft: create quote posts
---
lib/pleroma/web/common_api/activity_draft.ex | 14 ++++++++++++++
1 file changed, 14 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 63ed48a27..375aabc91 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
attachments: [],
in_reply_to: nil,
in_reply_to_conversation: nil,
+ quote_post: nil,
visibility: nil,
expires_at: nil,
extra: nil,
@@ -53,6 +54,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|> poll()
|> with_valid(&in_reply_to/1)
|> with_valid(&in_reply_to_conversation/1)
+ |> with_valid("e_post/1)
|> with_valid(&visibility/1)
|> content()
|> with_valid(&to_and_cc/1)
@@ -132,6 +134,18 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp in_reply_to(draft), do: draft
+ defp quote_post(%{params: %{quote_id: ""}} = draft), do: draft
+
+ defp quote_post(%{params: %{quote_id: id}} = draft) when is_binary(id) do
+ %__MODULE__{draft | quote_post: Activity.get_by_id(id)}
+ end
+
+ defp quote_post(%{params: %{quote_id: %Activity{} = quote_post}} = draft) do
+ %__MODULE__{draft | quote_post: quote_post}
+ end
+
+ defp quote_post(draft), do: draft
+
defp in_reply_to_conversation(draft) do
in_reply_to_conversation = Participation.get(draft.params[:in_reply_to_conversation_id])
%__MODULE__{draft | in_reply_to_conversation: in_reply_to_conversation}
--
cgit v1.2.3
From d4fea8b5595e9e6cd37bdb1cee21285f905693f1 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 22:15:54 -0600
Subject: ActivityDraft: allow quoting
---
lib/pleroma/web/activity_pub/builder.ex | 11 +++++++++++
lib/pleroma/web/api_spec/operations/status_operation.ex | 7 ++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex
index 8eab3a241..eb0bb0e33 100644
--- a/lib/pleroma/web/activity_pub/builder.ex
+++ b/lib/pleroma/web/activity_pub/builder.ex
@@ -217,6 +217,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
"tag" => Keyword.values(draft.tags) |> Enum.uniq()
}
|> add_in_reply_to(draft.in_reply_to)
+ |> add_quote(draft.quote_post)
|> Map.merge(draft.extra)
{:ok, data, []}
@@ -232,6 +233,16 @@ defmodule Pleroma.Web.ActivityPub.Builder do
end
end
+ defp add_quote(object, nil), do: object
+
+ defp add_quote(object, quote_post) do
+ with %Object{} = quote_object <- Object.normalize(quote_post, fetch: false) do
+ Map.put(object, "quoteUrl", quote_object.data["id"])
+ else
+ _ -> object
+ end
+ end
+
def chat_message(actor, recipient, content, opts \\ []) do
basic = %{
"id" => Utils.generate_object_id(),
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index 5d6e82f3c..8fa3b0890 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -581,7 +581,12 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
type: :string,
description:
"Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`."
- }
+ },
+ quote_id: %Schema{
+ nullable: true,
+ allOf: [FlakeID],
+ description: "ID of the status being quoted, if any"
+ },
},
example: %{
"status" => "What time is it?",
--
cgit v1.2.3
From 96009739173e5e48a636bb964855eb7aea11c828 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 22:57:42 -0600
Subject: mix format
---
lib/pleroma/web/api_spec/operations/status_operation.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index 8fa3b0890..c133a3aac 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -586,7 +586,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
nullable: true,
allOf: [FlakeID],
description: "ID of the status being quoted, if any"
- },
+ }
},
example: %{
"status" => "What time is it?",
--
cgit v1.2.3
From 5716f88a1d8424cf7c62a0491b3bf9607dc9aa3f Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sat, 22 Jan 2022 23:09:33 -0600
Subject: InstanceView: add "quote_posting" feature
---
lib/pleroma/web/mastodon_api/views/instance_view.ex | 1 +
1 file changed, 1 insertion(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
index efd2a0af6..1b01d7371 100644
--- a/lib/pleroma/web/mastodon_api/views/instance_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -69,6 +69,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
"multifetch",
"pleroma:api/v1/notifications:include_types_filter",
"editing",
+ "quote_posting",
if Config.get([:activitypub, :blockers_visible]) do
"blockers_visible"
end,
--
cgit v1.2.3
From 80ab2572a4d5590d738cc763a87156b3f79362fb Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sun, 23 Jan 2022 13:55:25 -0600
Subject: Return quote_url through the API, don't render quotes more than 1
level deep
---
lib/pleroma/web/api_spec/schemas/status.ex | 6 ++++++
lib/pleroma/web/mastodon_api/views/status_view.ex | 7 ++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index 39241aa39..f4ee9b38c 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -198,6 +198,12 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
nullable: true,
description: "Quoted status (if any)"
},
+ quote_url: %Schema{
+ type: :string,
+ format: :uri,
+ nullable: true,
+ description: "URL of the quoted status"
+ },
local: %Schema{
type: :boolean,
description: "`true` if the post was made on the local instance"
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 5bde1ce04..06adfb221 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -316,7 +316,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
quote_post =
if quote_activity do
- quote_rendering_opts = Map.put(opts, :activity, quote_activity)
+ quote_rendering_opts = Map.merge(opts, %{activity: quote_activity, show_quote: false})
render("show.json", quote_rendering_opts)
else
nil
@@ -431,6 +431,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
context: object.data["context"],
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
quote: quote_post,
+ quote_url: object.data["quoteUrl"],
content: %{"text/plain" => content_plaintext},
spoiler_text: %{"text/plain" => summary},
expires_at: expires_at,
@@ -666,6 +667,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
+ def get_quote(_activity, %{show_quote: false}) do
+ nil
+ end
+
def get_quote(activity, %{quoted_activities: quoted_activities}) do
object = Object.normalize(activity, fetch: false)
quoted_activities[object.data["quoteUrl"]]
--
cgit v1.2.3
From 54a989793878c63900d2c6de7b4ffc8fbd8fe8c6 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sun, 23 Jan 2022 15:46:44 -0600
Subject: ActivityDraft: mention the OP of a quoted post
---
lib/pleroma/web/common_api/activity_draft.ex | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 375aabc91..588aba55e 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -137,11 +137,11 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp quote_post(%{params: %{quote_id: ""}} = draft), do: draft
defp quote_post(%{params: %{quote_id: id}} = draft) when is_binary(id) do
- %__MODULE__{draft | quote_post: Activity.get_by_id(id)}
- end
-
- defp quote_post(%{params: %{quote_id: %Activity{} = quote_post}} = draft) do
- %__MODULE__{draft | quote_post: quote_post}
+ with %Activity{actor: actor_ap_id} = activity <- Activity.get_by_id(id) do
+ %__MODULE__{draft | quote_post: activity, mentions: [actor_ap_id]}
+ else
+ _ -> draft
+ end
end
defp quote_post(draft), do: draft
@@ -178,12 +178,15 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
end
end
- defp content(draft) do
+ defp content(%{mentions: mentions} = draft) do
{content_html, mentioned_users, tags} = Utils.make_content_html(draft)
+ mentioned_ap_ids =
+ Enum.map(mentioned_users, fn {_, mentioned_user} -> mentioned_user.ap_id end)
+
mentions =
- mentioned_users
- |> Enum.map(fn {_, mentioned_user} -> mentioned_user.ap_id end)
+ mentions
+ |> Kernel.++(mentioned_ap_ids)
|> Utils.get_addressed_users(draft.params[:to])
%__MODULE__{draft | content_html: content_html, mentions: mentions, tags: tags}
--
cgit v1.2.3
From 1f19dd76f66ca657ddfe79a51e59b8997a4c6321 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sun, 23 Jan 2022 16:03:46 -0600
Subject: ActivityDraft: mix format, defensive actor ID
---
lib/pleroma/web/common_api/activity_draft.ex | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 588aba55e..95534f3cb 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
alias Pleroma.Web.CommonAPI.Utils
import Pleroma.Web.Gettext
+ import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1]
defstruct valid?: true,
errors: [],
@@ -134,13 +135,16 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp in_reply_to(draft), do: draft
- defp quote_post(%{params: %{quote_id: ""}} = draft), do: draft
+ defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do
+ case Activity.get_by_id(id) do
+ %Activity{actor: actor_ap_id} = activity when not_empty_string(actor_ap_id) ->
+ %__MODULE__{draft | quote_post: activity, mentions: [actor_ap_id]}
- defp quote_post(%{params: %{quote_id: id}} = draft) when is_binary(id) do
- with %Activity{actor: actor_ap_id} = activity <- Activity.get_by_id(id) do
- %__MODULE__{draft | quote_post: activity, mentions: [actor_ap_id]}
- else
- _ -> draft
+ %Activity{} = activity ->
+ %__MODULE__{draft | quote_post: activity}
+
+ _ ->
+ draft
end
end
--
cgit v1.2.3
From 57ef1d121101d785c043ef6aaf2d33bb9be3ec3b Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Mon, 24 Jan 2022 16:44:35 -0600
Subject: Add InlineQuotePolicy to force quote URLs inline
---
.../web/activity_pub/mrf/inline_quote_policy.ex | 53 ++++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
new file mode 100644
index 000000000..0f1dc9f42
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -0,0 +1,53 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
+ @moduledoc "Force a quote line into the message content."
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ defp build_inline_quote(prefix, url) do
+ "
#{prefix}: #{url}"
+ end
+
+ defp filter_object(%{"quoteUrl" => quote_url} = object) do
+ content = object["content"] || ""
+
+ if content =~ quote_url do
+ object
+ else
+ prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
+ content = content <> build_inline_quote(prefix, quote_url)
+ Map.put(object, "content", content)
+ end
+ end
+
+ @impl true
+ def filter(%{"object" => %{"quoteUrl" => _} = object} = activity) do
+ {:ok, Map.put(activity, "object", filter_object(object))}
+ end
+
+ @impl true
+ def filter(object), do: {:ok, object}
+
+ @impl true
+ def describe, do: {:ok, %{}}
+
+ @impl true
+ def config_description do
+ %{
+ key: :mrf_inline_quote,
+ related_policy: "Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy",
+ label: "MRF Inline Quote",
+ description: "Force quote post URLs inline",
+ children: [
+ %{
+ key: :prefix,
+ type: :string,
+ description: "Prefix before the link",
+ suggestions: ["RT", "QT", "RE", "RN"]
+ }
+ ]
+ }
+ end
+end
--
cgit v1.2.3
From 59326247aa754991add9170e204257a8bf94c40f Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Wed, 26 Jan 2022 11:21:49 -0600
Subject: CommonAPI: disallow quoting private posts through the API
---
lib/pleroma/web/common_api/activity_draft.ex | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 95534f3cb..d4875765c 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
alias Pleroma.Conversation.Participation
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Builder
+ alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
@@ -57,6 +58,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|> with_valid(&in_reply_to_conversation/1)
|> with_valid("e_post/1)
|> with_valid(&visibility/1)
+ |> with_valid("ing_visibility/1)
|> content()
|> with_valid(&to_and_cc/1)
|> with_valid(&context/1)
@@ -136,7 +138,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp in_reply_to(draft), do: draft
defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do
- case Activity.get_by_id(id) do
+ case Activity.get_by_id_with_object(id) do
%Activity{actor: actor_ap_id} = activity when not_empty_string(actor_ap_id) ->
%__MODULE__{draft | quote_post: activity, mentions: [actor_ap_id]}
@@ -165,6 +167,17 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
end
end
+ defp quoting_visibility(%{quote_post: %Activity{}} = draft) do
+ with %Object{} = object <- Object.normalize(draft.quote_post, fetch: false),
+ visibility when visibility in ~w(public unlisted) <- Visibility.get_visibility(object) do
+ draft
+ else
+ _ -> add_error(draft, dgettext("errors", "Cannot quote private message"))
+ end
+ end
+
+ defp quoting_visibility(draft), do: draft
+
defp expires_at(draft) do
case CommonAPI.check_expiry_date(draft.params[:expires_in]) do
{:ok, expires_at} -> %__MODULE__{draft | expires_at: expires_at}
--
cgit v1.2.3
From 6f11f11519f9c735f6b059c250f4bf01e09b305f Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Wed, 26 Jan 2022 11:49:31 -0600
Subject: StatusView: fix quote visibility
---
lib/pleroma/web/mastodon_api/views/status_view.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 06adfb221..7360d1093 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -315,7 +315,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
quote_activity = get_quote(activity, opts)
quote_post =
- if quote_activity do
+ if visible_for_user?(quote_activity, opts[:for]) do
quote_rendering_opts = Map.merge(opts, %{activity: quote_activity, show_quote: false})
render("show.json", quote_rendering_opts)
else
--
cgit v1.2.3
From 74e0a4555f583a6962ad116bf6e54f06e42fe465 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Wed, 26 Jan 2022 11:52:50 -0600
Subject: StatusView: add `quote_visible` param
---
lib/pleroma/web/api_spec/schemas/status.ex | 4 ++++
lib/pleroma/web/mastodon_api/views/status_view.ex | 1 +
2 files changed, 5 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index f4ee9b38c..5d0eedb08 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -204,6 +204,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
nullable: true,
description: "URL of the quoted status"
},
+ quote_visible: %Schema{
+ type: :boolean,
+ description: "`true` if the quoted post is visible to the user"
+ },
local: %Schema{
type: :boolean,
description: "`true` if the post was made on the local instance"
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 7360d1093..2aa44b0f6 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -432,6 +432,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
quote: quote_post,
quote_url: object.data["quoteUrl"],
+ quote_visible: visible_for_user?(quote_activity, opts[:for]),
content: %{"text/plain" => content_plaintext},
spoiler_text: %{"text/plain" => summary},
expires_at: expires_at,
--
cgit v1.2.3
From bee7e419597615ac6852942fe563166feba3fe73 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Thu, 27 Jan 2022 14:28:06 -0600
Subject: InlineQuotePolicy: don't add line breaks to markdown posts
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index 0f1dc9f42..46013fc5e 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -6,8 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@moduledoc "Force a quote line into the message content."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
- defp build_inline_quote(prefix, url) do
- "
#{prefix}: #{url}"
+ defp build_inline_quote(prefix, url, br) do
+ "#{String.duplicate("
", br)}#{prefix}: #{url}"
end
defp filter_object(%{"quoteUrl" => quote_url} = object) do
@@ -17,7 +17,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
object
else
prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
- content = content <> build_inline_quote(prefix, quote_url)
+
+ inline_quote =
+ if String.ends_with?(content, "
"),
+ do: build_inline_quote(prefix, quote_url, 0),
+ else: build_inline_quote(prefix, quote_url, 2)
+
+ content = content <> inline_quote
Map.put(object, "content", content)
end
end
--
cgit v1.2.3
From cf8e4258830e3f362ab1e54238d622f6b2056502 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Fri, 28 Jan 2022 12:33:07 -0600
Subject: StatusView: return quote post inside a reblog
---
lib/pleroma/web/mastodon_api/views/status_view.ex | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 2aa44b0f6..ba4a8f3eb 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -668,13 +668,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
- def get_quote(_activity, %{show_quote: false}) do
- nil
- end
+ def get_quote(_activity, %{show_quote: false}), do: nil
def get_quote(activity, %{quoted_activities: quoted_activities}) do
object = Object.normalize(activity, fetch: false)
- quoted_activities[object.data["quoteUrl"]]
+
+ with nil <- quoted_activities[object.data["quoteUrl"]] do
+ # For when a quote post is inside an Announce
+ Activity.get_create_by_object_ap_id_with_object(object.data["quoteUrl"])
+ end
end
def get_quote(%{data: %{"object" => _object}} = activity, _) do
--
cgit v1.2.3
From 3c8319fe9f7a7c793f8fdc347be2015190981e33 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Fri, 28 Jan 2022 14:06:32 -0600
Subject: Transmogrifier: federate quotes with _misskey_quote field
---
lib/pleroma/web/activity_pub/transmogrifier.ex | 9 +++++++++
1 file changed, 9 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index f5771e75e..163ae54fa 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -660,6 +660,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def set_reply_to_uri(obj), do: obj
+ # Misskey quotes
+ # Despite being underscored, it's potentially more reliable for interop.
+ def set_quote_url(%{"quoteUrl" => quote_url} = object) when is_binary(quote_url) do
+ Map.put(object, "_misskey_quote", quote_url)
+ end
+
+ def set_quote_url(obj), do: obj
+
@doc """
Serialized Mastodon-compatible `replies` collection containing _self-replies_.
Based on Mastodon's ActivityPub::NoteSerializer#replies.
@@ -714,6 +722,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> prepare_attachments
|> set_conversation
|> set_reply_to_uri
+ |> set_quote_url
|> set_replies
|> strip_internal_fields
|> strip_internal_tags
--
cgit v1.2.3
From 817e308c0d9e42dfc39742c554e4c7a8da6f1c50 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Fri, 28 Jan 2022 15:55:52 -0600
Subject: Handle Fedibird's new quoteUri field
---
.../object_validators/article_note_page_validator.ex | 8 +++++++-
lib/pleroma/web/activity_pub/transmogrifier.ex | 19 +++++++++++++++----
2 files changed, 22 insertions(+), 5 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
index 40bb67934..0b435b251 100644
--- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
@@ -78,7 +78,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
defp fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data
- # Fix for Fedibird
+ # Fedibird
+ # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
+ defp fix_quote_url(%{"quoteUri" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ # Old Fedibird (bug)
# https://github.com/fedibird/mastodon/issues/9
defp fix_quote_url(%{"quoteURL" => quote_url} = data) do
Map.put(data, "quoteUrl", quote_url)
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 163ae54fa..01e135fc1 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -180,7 +180,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- # Fix for Fedibird
+ # Fedibird
+ # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
+ def fix_quote_url(%{"quoteUri" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUrl", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ # Old Fedibird (bug)
# https://github.com/fedibird/mastodon/issues/9
def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
object
@@ -660,10 +668,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def set_reply_to_uri(obj), do: obj
- # Misskey quotes
- # Despite being underscored, it's potentially more reliable for interop.
def set_quote_url(%{"quoteUrl" => quote_url} = object) when is_binary(quote_url) do
- Map.put(object, "_misskey_quote", quote_url)
+ Map.merge(object, %{
+ # Fedibird quote
+ "quoteUri" => quote_url,
+ # Misskey quote
+ "_misskey_quote" => quote_url
+ })
end
def set_quote_url(obj), do: obj
--
cgit v1.2.3
From 4075eecca0033e4487fa9d5d5bb75384597c3e79 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Fri, 28 Jan 2022 16:07:17 -0600
Subject: InlineQuotePolicy: improve the way Markdown quotes are displayed by
other software
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index 46013fc5e..7de4935f2 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -6,8 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@moduledoc "Force a quote line into the message content."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
- defp build_inline_quote(prefix, url, br) do
- "#{String.duplicate("
", br)}#{prefix}: #{url}"
+ defp build_inline_quote(prefix, url) do
+ "
#{prefix}: #{url}"
end
defp filter_object(%{"quoteUrl" => quote_url} = object) do
@@ -18,12 +18,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
else
prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
- inline_quote =
+ content =
if String.ends_with?(content, ""),
- do: build_inline_quote(prefix, quote_url, 0),
- else: build_inline_quote(prefix, quote_url, 2)
+ do:
+ String.trim_trailing(content, "") <>
+ build_inline_quote(prefix, quote_url) <> "",
+ else: content <> build_inline_quote(prefix, quote_url)
- content = content <> inline_quote
Map.put(object, "content", content)
end
end
--
cgit v1.2.3
From 79fca39faf6d084eabb6be44a2263431943b8dd4 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Fri, 28 Jan 2022 17:53:19 -0600
Subject: Actually, don't send _misskey_quote anymore
---
lib/pleroma/web/activity_pub/transmogrifier.ex | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 01e135fc1..6c6cd712b 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -668,13 +668,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def set_reply_to_uri(obj), do: obj
+ @doc """
+ Fedibird compatibility
+ https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
+ """
def set_quote_url(%{"quoteUrl" => quote_url} = object) when is_binary(quote_url) do
- Map.merge(object, %{
- # Fedibird quote
- "quoteUri" => quote_url,
- # Misskey quote
- "_misskey_quote" => quote_url
- })
+ Map.put(object, "quoteUri", quote_url)
end
def set_quote_url(obj), do: obj
--
cgit v1.2.3
From f9697e68c2b75a77575b9b7c89d08a5687bfd7b4 Mon Sep 17 00:00:00 2001
From: Alex Gleason
Date: Sun, 30 Jan 2022 10:57:29 -0600
Subject: InlineQuotePolicy: skip objects which already have an .inline-quote
span
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index 7de4935f2..c78675caf 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -10,10 +10,21 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
"
#{prefix}: #{url}"
end
+ defp has_inline_quote?(content, quote_url) do
+ cond do
+ # Does the quote URL exist in the content?
+ content =~ quote_url -> true
+ # Does the content already have a .quote-inline span?
+ content =~ "" -> true
+ # No inline quote found
+ true -> false
+ end
+ end
+
defp filter_object(%{"quoteUrl" => quote_url} = object) do
content = object["content"] || ""
- if content =~ quote_url do
+ if has_inline_quote?(content, quote_url) do
object
else
prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
--
cgit v1.2.3
From b0a7e795e799d3c8d750ab909657ec7b3d0bfd58 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Mon, 10 Jul 2023 17:57:09 -0400
Subject: Unify logic for normalizing quoteUri
---
.../article_note_page_validator.ex | 23 +-----------
.../activity_pub/object_validators/common_fixes.ex | 21 +++++++++++
lib/pleroma/web/activity_pub/transmogrifier.ex | 42 +++++++---------------
3 files changed, 34 insertions(+), 52 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
index 0b435b251..1b5b2e8fb 100644
--- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
@@ -76,27 +76,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
def fix_attachments(data), do: data
- defp fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data
-
- # Fedibird
- # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
- defp fix_quote_url(%{"quoteUri" => quote_url} = data) do
- Map.put(data, "quoteUrl", quote_url)
- end
-
- # Old Fedibird (bug)
- # https://github.com/fedibird/mastodon/issues/9
- defp fix_quote_url(%{"quoteURL" => quote_url} = data) do
- Map.put(data, "quoteUrl", quote_url)
- end
-
- # Misskey fallback
- defp fix_quote_url(%{"_misskey_quote" => quote_url} = data) do
- Map.put(data, "quoteUrl", quote_url)
- end
-
- defp fix_quote_url(data), do: data
-
defp fix(data) do
data
|> CommonFixes.fix_actor()
@@ -105,7 +84,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|> fix_tag()
|> fix_replies()
|> fix_attachments()
- |> fix_quote_url()
+ |> CommonFixes.fix_quote_url()
|> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map()
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
index add46d561..cc2ad9116 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
@@ -76,4 +76,25 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
Map.put(data, "to", to)
end
+
+ def fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data
+
+ # Fedibird
+ # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
+ def fix_quote_url(%{"quoteUri" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ # Old Fedibird (bug)
+ # https://github.com/fedibird/mastodon/issues/9
+ def fix_quote_url(%{"quoteURL" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ # Misskey fallback
+ def fix_quote_url(%{"_misskey_quote" => quote_url} = data) do
+ Map.put(data, "quoteUrl", quote_url)
+ end
+
+ def fix_quote_url(data), do: data
end
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 6c6cd712b..86d3ac60f 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -166,45 +166,27 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_in_reply_to(object, _options), do: object
- def fix_quote_url(object, options \\ [])
+ def fix_quote_url_and_maybe_fetch(object, options \\ []) do
+ quote_url =
+ case Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes.fix_quote_url(object) do
+ %{"quoteUrl" => quote_url} -> quote_url
+ _ -> nil
+ end
- def fix_quote_url(%{"quoteUrl" => quote_url} = object, options)
- when not is_nil(quote_url) do
- with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
+ with {:quoting?, true} <- {:quoting?, not is_nil(quote_url)},
+ {:ok, quoted_object} <- get_obj_helper(quote_url, options),
%Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
Map.put(object, "quoteUrl", quoted_object.data["id"])
else
+ {:quoting?, _} ->
+ object
+
e ->
Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
object
end
end
- # Fedibird
- # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac
- def fix_quote_url(%{"quoteUri" => quote_url} = object, options) do
- object
- |> Map.put("quoteUrl", quote_url)
- |> fix_quote_url(options)
- end
-
- # Old Fedibird (bug)
- # https://github.com/fedibird/mastodon/issues/9
- def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
- object
- |> Map.put("quoteUrl", quote_url)
- |> fix_quote_url(options)
- end
-
- # Misskey fallback
- def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
- object
- |> Map.put("quoteUrl", quote_url)
- |> fix_quote_url(options)
- end
-
- def fix_quote_url(object, _options), do: object
-
defp prepare_in_reply_to(in_reply_to) do
cond do
is_bitstring(in_reply_to) ->
@@ -493,7 +475,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> strip_internal_fields()
|> fix_type(fetch_options)
|> fix_in_reply_to(fetch_options)
- |> fix_quote_url(fetch_options)
+ |> fix_quote_url_and_maybe_fetch(fetch_options)
data = Map.put(data, "object", object)
options = Keyword.put(options, :local, false)
--
cgit v1.2.3
From 9bcec87aba5ce4de6b61b5a95d6832da9dfa0fd8 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Mon, 10 Jul 2023 18:27:23 -0400
Subject: Allow local quote and private self-quote
---
lib/pleroma/web/common_api/activity_draft.ex | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index d4875765c..32921aa5a 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -167,9 +167,21 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
end
end
+ defp can_quote?(_draft, _object, visibility) when visibility in ~w(public unlisted local) do
+ true
+ end
+
+ defp can_quote?(draft, object, "private") do
+ draft.user.ap_id == object.data["actor"]
+ end
+
+ defp can_quote?(_, _, _) do
+ false
+ end
+
defp quoting_visibility(%{quote_post: %Activity{}} = draft) do
with %Object{} = object <- Object.normalize(draft.quote_post, fetch: false),
- visibility when visibility in ~w(public unlisted) <- Visibility.get_visibility(object) do
+ true <- can_quote?(draft, object, Visibility.get_visibility(object)) do
draft
else
_ -> add_error(draft, dgettext("errors", "Cannot quote private message"))
--
cgit v1.2.3
From 163e5637335f9454688d3cc83530f82fc640a5b9 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 09:30:43 -0400
Subject: Allow more flexibility in InlineQuotePolicy
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index c78675caf..a0eefefc0 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -6,8 +6,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@moduledoc "Force a quote line into the message content."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
- defp build_inline_quote(prefix, url) do
- "
#{prefix}: #{url}"
+ defp build_inline_quote(template, url) do
+ quote_line = String.replace(template, "{url}", "#{url}")
+
+ "
#{quote_line}"
end
defp has_inline_quote?(content, quote_url) do
@@ -27,14 +29,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
if has_inline_quote?(content, quote_url) do
object
else
- prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
+ template = Pleroma.Config.get([:mrf_inline_quote, :template])
content =
if String.ends_with?(content, ""),
do:
String.trim_trailing(content, "") <>
- build_inline_quote(prefix, quote_url) <> "",
- else: content <> build_inline_quote(prefix, quote_url)
+ build_inline_quote(template, quote_url) <> "",
+ else: content <> build_inline_quote(template, quote_url)
Map.put(object, "content", content)
end
--
cgit v1.2.3
From e9cd004ba1b904d92b1c07446bbf03dc070cce6a Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 11:09:10 -0400
Subject: Parse object link as quoteUrl
---
lib/pleroma/constants.ex | 7 ++++++
.../audio_image_video_validator.ex | 1 +
.../activity_pub/object_validators/common_fixes.ex | 27 ++++++++++++++++++++++
.../object_validators/question_validator.ex | 1 +
4 files changed, 36 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index 6befc6897..9d764ec25 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -83,4 +83,11 @@ defmodule Pleroma.Constants do
)
const(upload_object_types, do: ["Document", "Image"])
+
+ const(activity_json_mime_types,
+ do: [
+ "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
+ "application/activity+json"
+ ]
+ )
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex
index 79ff76104..65ac6bb93 100644
--- a/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/audio_image_video_validator.ex
@@ -99,6 +99,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioImageVideoValidator do
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
+ |> CommonFixes.fix_quote_url()
|> Transmogrifier.fix_emoji()
|> fix_url()
|> fix_content()
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
index cc2ad9116..65b8d9a2c 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
@@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
+ require Pleroma.Constants
+
def cast_and_filter_recipients(message, field, follower_collection, field_fallback \\ []) do
{:ok, data} = ObjectValidators.Recipients.cast(message[field] || field_fallback)
@@ -96,5 +98,30 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
Map.put(data, "quoteUrl", quote_url)
end
+ def fix_quote_url(%{"tag" => [_ | _] = tags} = data) do
+ tag = Enum.find(tags, &is_object_link_tag/1)
+
+ if not is_nil(tag) do
+ data
+ |> Map.put("quoteUrl", tag["href"])
+ else
+ data
+ end
+ end
+
def fix_quote_url(data), do: data
+
+ # https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
+ defp is_object_link_tag(
+ %{
+ "type" => "Link",
+ "mediaType" => media_type,
+ "href" => href
+ } = tag
+ )
+ when media_type in Pleroma.Constants.activity_json_mime_types() and is_binary(href) do
+ true
+ end
+
+ defp is_object_link_tag(_), do: false
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
index ce3305142..621085e6c 100644
--- a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex
@@ -62,6 +62,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
+ |> CommonFixes.fix_quote_url()
|> Transmogrifier.fix_emoji()
|> fix_closed()
end
--
cgit v1.2.3
From 479a6f11dbbba0c945c08883956ffab198f91688 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 14:08:24 -0400
Subject: Keep incoming Link tag
---
.../web/activity_pub/object_validators/tag_validator.ex | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex b/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex
index cfd510c19..47cf7b415 100644
--- a/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex
@@ -9,15 +9,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
import Ecto.Changeset
+ require Pleroma.Constants
+
@primary_key false
embedded_schema do
# Common
field(:type, :string)
field(:name, :string)
- # Mention, Hashtag
+ # Mention, Hashtag, Link
field(:href, ObjectValidators.Uri)
+ # Link
+ field(:mediaType, :string)
+
# Emoji
embeds_one :icon, IconObjectValidator, primary_key: false do
field(:type, :string)
@@ -68,6 +73,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|> validate_required([:type, :name, :icon])
end
+ def changeset(struct, %{"type" => "Link"} = data) do
+ struct
+ |> cast(data, [:type, :name, :mediaType, :href])
+ |> validate_inclusion(:mediaType, Pleroma.Constants.activity_json_mime_types())
+ |> validate_required([:type, :href, :mediaType])
+ end
+
def changeset(struct, %{"type" => _} = data) do
struct
|> cast(data, [])
--
cgit v1.2.3
From e349e92a441840bbbdbf13cacd307e65f85a38ff Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 14:27:29 -0400
Subject: Add mrf to force link tag of quoting posts
---
lib/pleroma/constants.ex | 4 ++
.../activity_pub/mrf/quote_to_link_tag_policy.ex | 49 ++++++++++++++++++++++
.../activity_pub/object_validators/common_fixes.ex | 16 ++++---
3 files changed, 60 insertions(+), 9 deletions(-)
create mode 100644 lib/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy.ex
(limited to 'lib')
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index 9d764ec25..ed60bcc37 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -84,6 +84,10 @@ defmodule Pleroma.Constants do
const(upload_object_types, do: ["Document", "Image"])
+ const(activity_json_canonical_mime_type,
+ do: "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
+ )
+
const(activity_json_mime_types,
do: [
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
diff --git a/lib/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy.ex
new file mode 100644
index 000000000..f1c573d1b
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/quote_to_link_tag_policy.ex
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2023 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy do
+ @moduledoc "Force a Link tag for posts quoting another post. (may break outgoing federation of quote posts with older Pleroma versions)"
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
+
+ require Pleroma.Constants
+
+ @impl Pleroma.Web.ActivityPub.MRF.Policy
+ def filter(%{"object" => %{"quoteUrl" => _} = object} = activity) do
+ {:ok, Map.put(activity, "object", filter_object(object))}
+ end
+
+ @impl Pleroma.Web.ActivityPub.MRF.Policy
+ def filter(object), do: {:ok, object}
+
+ @impl Pleroma.Web.ActivityPub.MRF.Policy
+ def describe, do: {:ok, %{}}
+
+ @impl Pleroma.Web.ActivityPub.MRF.Policy
+ def history_awareness, do: :auto
+
+ defp filter_object(%{"quoteUrl" => quote_url} = object) do
+ tags = object["tag"] || []
+
+ if Enum.any?(tags, fn tag ->
+ CommonFixes.is_object_link_tag(tag) and tag["href"] == quote_url
+ end) do
+ object
+ else
+ object
+ |> Map.put(
+ "tag",
+ tags ++
+ [
+ %{
+ "type" => "Link",
+ "mediaType" => Pleroma.Constants.activity_json_canonical_mime_type(),
+ "href" => quote_url
+ }
+ ]
+ )
+ end
+ end
+end
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
index 65b8d9a2c..4d9be0bdd 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
@@ -112,16 +112,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
def fix_quote_url(data), do: data
# https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
- defp is_object_link_tag(
- %{
- "type" => "Link",
- "mediaType" => media_type,
- "href" => href
- } = tag
- )
- when media_type in Pleroma.Constants.activity_json_mime_types() and is_binary(href) do
+ def is_object_link_tag(%{
+ "type" => "Link",
+ "mediaType" => media_type,
+ "href" => href
+ })
+ when media_type in Pleroma.Constants.activity_json_mime_types() and is_binary(href) do
true
end
- defp is_object_link_tag(_), do: false
+ def is_object_link_tag(_), do: false
end
--
cgit v1.2.3
From 8b98a98dfb4ab3db9b4f2347713d86ed9c87b61b Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 14:37:12 -0400
Subject: Make InlineQuotePolicy history aware
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 3 +++
1 file changed, 3 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index a0eefefc0..aaa209aa1 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -53,6 +53,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@impl true
def describe, do: {:ok, %{}}
+ @impl Pleroma.Web.ActivityPub.MRF.Policy
+ def history_awareness, do: :auto
+
@impl true
def config_description do
%{
--
cgit v1.2.3
From 87353e5ad12799d12507253fe9a0363fd9f0c817 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 22:07:16 -0400
Subject: Fix config descriptions for mrf inline quote
---
lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index aaa209aa1..171b22c5e 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -61,14 +61,16 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
%{
key: :mrf_inline_quote,
related_policy: "Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy",
- label: "MRF Inline Quote",
- description: "Force quote post URLs inline",
+ label: "MRF Inline Quote Policy",
+ type: :group,
+ description: "Force quote url to appear in post content.",
children: [
%{
- key: :prefix,
+ key: :template,
type: :string,
- description: "Prefix before the link",
- suggestions: ["RT", "QT", "RE", "RN"]
+ description:
+ "The template to append to the post. `{url}` will be replaced with the actual link to the quoted post.",
+ suggestions: ["RT: {url}"]
}
]
}
--
cgit v1.2.3
From 875b46d97d910ffd2c33ac26ed8dfe38f7672f52 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 23:29:23 -0400
Subject: Do not mention original poster when quoting
---
lib/pleroma/web/common_api/activity_draft.ex | 3 ---
1 file changed, 3 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex
index 32921aa5a..ca1329284 100644
--- a/lib/pleroma/web/common_api/activity_draft.ex
+++ b/lib/pleroma/web/common_api/activity_draft.ex
@@ -139,9 +139,6 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do
case Activity.get_by_id_with_object(id) do
- %Activity{actor: actor_ap_id} = activity when not_empty_string(actor_ap_id) ->
- %__MODULE__{draft | quote_post: activity, mentions: [actor_ap_id]}
-
%Activity{} = activity ->
%__MODULE__{draft | quote_post: activity}
--
cgit v1.2.3
From a8b2f9205d16465a3b11d3802c966db3da908c5d Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 23:47:31 -0400
Subject: Expose quote_id parameter on the api
---
lib/pleroma/web/api_spec/schemas/status.ex | 5 +++++
lib/pleroma/web/mastodon_api/views/status_view.ex | 10 ++++++++++
2 files changed, 15 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex
index 5d0eedb08..07f03134a 100644
--- a/lib/pleroma/web/api_spec/schemas/status.ex
+++ b/lib/pleroma/web/api_spec/schemas/status.ex
@@ -198,6 +198,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
nullable: true,
description: "Quoted status (if any)"
},
+ quote_id: %Schema{
+ nullable: true,
+ allOf: [FlakeID],
+ description: "ID of the status being quoted, if any"
+ },
quote_url: %Schema{
type: :string,
format: :uri,
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index ba4a8f3eb..3d3039751 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -312,6 +312,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
# Here the implicit index of the current content is 0
chrono_order = history_len - 1
+ quote_id = get_quote_id(activity)
+
quote_activity = get_quote(activity, opts)
quote_post =
@@ -431,6 +433,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
context: object.data["context"],
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
quote: quote_post,
+ quote_id: quote_id,
quote_url: object.data["quoteUrl"],
quote_visible: visible_for_user?(quote_activity, opts[:for]),
content: %{"text/plain" => content_plaintext},
@@ -689,6 +692,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
+ defp get_quote_id(activity) do
+ case get_quote(activity, %{}) do
+ %Activity{id: id} -> id
+ _ -> nil
+ end
+ end
+
def render_content(%{data: %{"name" => name}} = object) when not is_nil(name) and name != "" do
url = object.data["url"] || object.data["id"]
--
cgit v1.2.3
From 08608afca5566f712acdc14b7c43976d6d071106 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Wed, 12 Jul 2023 23:56:54 -0400
Subject: Fix quote_visible attribute
---
lib/pleroma/web/mastodon_api/views/status_view.ex | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 3d3039751..d070262cc 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -312,12 +312,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
# Here the implicit index of the current content is 0
chrono_order = history_len - 1
- quote_id = get_quote_id(activity)
-
quote_activity = get_quote(activity, opts)
+ quote_id =
+ case quote_activity do
+ %Activity{id: id} -> id
+ _ -> nil
+ end
+
quote_post =
- if visible_for_user?(quote_activity, opts[:for]) do
+ if visible_for_user?(quote_activity, opts[:for]) and opts[:show_quote] != false do
quote_rendering_opts = Map.merge(opts, %{activity: quote_activity, show_quote: false})
render("show.json", quote_rendering_opts)
else
@@ -671,8 +675,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
- def get_quote(_activity, %{show_quote: false}), do: nil
-
def get_quote(activity, %{quoted_activities: quoted_activities}) do
object = Object.normalize(activity, fetch: false)
@@ -692,13 +694,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
- defp get_quote_id(activity) do
- case get_quote(activity, %{}) do
- %Activity{id: id} -> id
- _ -> nil
- end
- end
-
def render_content(%{data: %{"name" => name}} = object) when not is_nil(name) and name != "" do
url = object.data["url"] || object.data["id"]
--
cgit v1.2.3
From 2b5636bf127b1987736c281d346a5771c8168c09 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Fri, 31 Mar 2023 21:47:37 -0400
Subject: Allow unified streaming endpoint
---
lib/pleroma/web/mastodon_api/websocket_handler.ex | 17 ++++++++++++-----
lib/pleroma/web/streamer.ex | 8 ++++++--
2 files changed, 18 insertions(+), 7 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex
index 88444106d..97a1f1401 100644
--- a/lib/pleroma/web/mastodon_api/websocket_handler.ex
+++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex
@@ -32,8 +32,15 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
req
end
+ topics =
+ if topic do
+ [topic]
+ else
+ []
+ end
+
{:cowboy_websocket, req,
- %{user: user, topic: topic, oauth_token: oauth_token, count: 0, timer: nil},
+ %{user: user, topics: topics, oauth_token: oauth_token, count: 0, timer: nil},
%{idle_timeout: @timeout}}
else
{:error, :bad_topic} ->
@@ -50,10 +57,10 @@ 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}, topics #{state.topics}"
)
- Streamer.add_socket(state.topic, state.oauth_token)
+ Enum.each(state.topics, fn topic -> Streamer.add_socket(topic, state.oauth_token) end)
{:ok, %{state | timer: timer()}}
end
@@ -109,10 +116,10 @@ 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}, topics #{state.topics || "?"}: #{inspect(reason)}"
)
- Streamer.remove_socket(state.topic)
+ Enum.each(state.topics, fn topic -> Streamer.remove_socket(topic) end)
:ok
end
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index b9a04cc76..6b5fdbf0c 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -59,10 +59,14 @@ defmodule Pleroma.Web.Streamer do
end
@doc "Expand and authorizes a stream"
- @spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) ::
- {:ok, topic :: String.t()} | {:error, :bad_topic}
+ @spec get_topic(stream :: String.t() | nil, User.t() | nil, Token.t() | nil, Map.t()) ::
+ {:ok, topic :: String.t() | nil} | {:error, :bad_topic}
def get_topic(stream, user, oauth_token, params \\ %{})
+ def get_topic(nil = _stream, _user, _oauth_token, _params) do
+ {:ok, nil}
+ end
+
# Allow all public steams if the instance allows unauthenticated access.
# Otherwise, only allow users with valid oauth tokens.
def get_topic(stream, user, oauth_token, _params) when stream in @public_streams do
--
cgit v1.2.3
From 273cda63ad79b61f4d37e4b7603694908e894e4f Mon Sep 17 00:00:00 2001
From: tusooa
Date: Fri, 31 Mar 2023 22:55:52 -0400
Subject: Allow subscribing to streams
---
lib/pleroma/web/mastodon_api/websocket_handler.ex | 74 +++++++++++++++++++++++
lib/pleroma/web/views/streamer_view.ex | 18 ++++++
2 files changed, 92 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex
index 97a1f1401..a42a9a63c 100644
--- a/lib/pleroma/web/mastodon_api/websocket_handler.ex
+++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
alias Pleroma.User
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Streamer
+ alias Pleroma.Web.StreamerView
@behaviour :cowboy_websocket
@@ -73,6 +74,16 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
# We only receive pings for now
def websocket_handle(:ping, state), do: {:ok, state}
+ def websocket_handle({:text, text}, state) do
+ with {:ok, %{} = event} <- Jason.decode(text) do
+ handle_client_event(event, state)
+ else
+ _ ->
+ Logger.error("#{__MODULE__} received non-JSON event: #{inspect(text)}")
+ {:ok, state}
+ end
+ end
+
def websocket_handle(frame, state) do
Logger.error("#{__MODULE__} received frame: #{inspect(frame)}")
{:ok, state}
@@ -144,4 +155,67 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
defp timer do
Process.send_after(self(), :tick, @tick)
end
+
+ defp handle_client_event(%{"type" => "subscribe", "stream" => _topic} = params, state) do
+ with {_, {:ok, topic}} <-
+ {:topic, Streamer.get_topic(params["stream"], state.user, state.oauth_token, params)},
+ {_, false} <- {:subscribed, topic in state.topics} do
+ Streamer.add_socket(topic, state.oauth_token)
+
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{type: "subscribe", result: "success"})}
+ ], %{state | topics: [topic | state.topics]}}
+ else
+ {:subscribed, true} ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{type: "subscribe", result: "ignored"})}
+ ], state}
+
+ {:topic, {:error, error}} ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{
+ type: "subscribe",
+ result: "error",
+ error: error
+ })}
+ ], state}
+ end
+ end
+
+ defp handle_client_event(%{"type" => "unsubscribe", "stream" => _topic} = params, state) do
+ with {_, {:ok, topic}} <-
+ {:topic, Streamer.get_topic(params["stream"], state.user, state.oauth_token, params)},
+ {_, true} <- {:subscribed, topic in state.topics} do
+ Streamer.remove_socket(topic)
+
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{type: "unsubscribe", result: "success"})}
+ ], %{state | topics: List.delete(state.topics, topic)}}
+ else
+ {:subscribed, false} ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{type: "unsubscribe", result: "ignored"})}
+ ], state}
+
+ {:topic, {:error, error}} ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{
+ type: "unsubscribe",
+ result: "error",
+ error: error
+ })}
+ ], state}
+ end
+ end
+
+ defp handle_client_event(params, state) do
+ Logger.error("#{__MODULE__} received unknown event: #{inspect(params)}")
+ {[], state}
+ end
end
diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex
index 6a55242b0..19f098783 100644
--- a/lib/pleroma/web/views/streamer_view.ex
+++ b/lib/pleroma/web/views/streamer_view.ex
@@ -135,4 +135,22 @@ defmodule Pleroma.Web.StreamerView do
}
|> Jason.encode!()
end
+
+ def render("pleroma_respond.json", %{type: type, result: result} = params) do
+ %{
+ event: "pleroma.respond",
+ payload:
+ %{
+ result: result,
+ type: type
+ }
+ |> Map.merge(maybe_error(params))
+ |> Jason.encode!()
+ }
+ |> Jason.encode!()
+ end
+
+ defp maybe_error(%{error: :bad_topic}), do: %{error: "bad_topic"}
+ defp maybe_error(%{error: :unauthorized}), do: %{error: "unauthorized"}
+ defp maybe_error(_), do: %{}
end
--
cgit v1.2.3
From 21395aa5090f2a53bdbe0ef5fac46693d16025ed Mon Sep 17 00:00:00 2001
From: tusooa
Date: Fri, 31 Mar 2023 23:19:57 -0400
Subject: Allow authenticating via client-sent events
---
lib/pleroma/web/mastodon_api/websocket_handler.ex | 36 +++++++++++++++++++++++
lib/pleroma/web/views/streamer_view.ex | 1 +
2 files changed, 37 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex
index a42a9a63c..6233c3340 100644
--- a/lib/pleroma/web/mastodon_api/websocket_handler.ex
+++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex
@@ -214,6 +214,42 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
end
end
+ defp handle_client_event(
+ %{"type" => "pleroma.authenticate", "token" => access_token} = _params,
+ state
+ ) do
+ with {:auth, nil, nil} <- {:auth, state.user, state.oauth_token},
+ {:ok, user, oauth_token} <- authenticate_request(access_token, nil) do
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{
+ type: "pleroma.authenticate",
+ result: "success"
+ })}
+ ], %{state | user: user, oauth_token: oauth_token}}
+ else
+ {:auth, _, _} ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{
+ type: "pleroma.authenticate",
+ result: "error",
+ error: :already_authenticated
+ })}
+ ], state}
+
+ _ ->
+ {[
+ {:text,
+ StreamerView.render("pleroma_respond.json", %{
+ type: "pleroma.authenticate",
+ result: "error",
+ error: :unauthorized
+ })}
+ ], state}
+ end
+ end
+
defp handle_client_event(params, state) do
Logger.error("#{__MODULE__} received unknown event: #{inspect(params)}")
{[], state}
diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex
index 19f098783..0cdcb1918 100644
--- a/lib/pleroma/web/views/streamer_view.ex
+++ b/lib/pleroma/web/views/streamer_view.ex
@@ -152,5 +152,6 @@ defmodule Pleroma.Web.StreamerView do
defp maybe_error(%{error: :bad_topic}), do: %{error: "bad_topic"}
defp maybe_error(%{error: :unauthorized}), do: %{error: "unauthorized"}
+ defp maybe_error(%{error: :already_authenticated}), do: %{error: "already_authenticated"}
defp maybe_error(_), do: %{}
end
--
cgit v1.2.3
From 7d005e8c93b22dc3d7be1a66dd2d404b7f54306a Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 01:25:13 -0400
Subject: Return stream attribute in server-sent events
---
lib/pleroma/constants.ex | 4 +++
lib/pleroma/web/mastodon_api/websocket_handler.ex | 4 +--
lib/pleroma/web/streamer.ex | 27 +++++++++------
lib/pleroma/web/views/streamer_view.ex | 42 ++++++++++++++++++-----
4 files changed, 57 insertions(+), 20 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
index ed60bcc37..77bc4bfac 100644
--- a/lib/pleroma/constants.ex
+++ b/lib/pleroma/constants.ex
@@ -94,4 +94,8 @@ defmodule Pleroma.Constants do
"application/activity+json"
]
)
+
+ const(public_streams,
+ do: ["public", "public:local", "public:media", "public:local:media"]
+ )
end
diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex
index 6233c3340..2707673ba 100644
--- a/lib/pleroma/web/mastodon_api/websocket_handler.ex
+++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex
@@ -89,11 +89,11 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
{:ok, state}
end
- def websocket_info({:render_with_user, view, template, item}, state) do
+ def websocket_info({:render_with_user, view, template, item, topic}, state) do
user = %User{} = User.get_cached_by_ap_id(state.user.ap_id)
unless Streamer.filtered_by_user?(user, item) do
- websocket_info({:text, view.render(template, item, user)}, %{state | user: user})
+ websocket_info({:text, view.render(template, item, user, topic)}, %{state | user: user})
else
{:ok, state}
end
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 6b5fdbf0c..70e46617a 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -4,6 +4,7 @@
defmodule Pleroma.Web.Streamer do
require Logger
+ require Pleroma.Constants
alias Pleroma.Activity
alias Pleroma.Chat.MessageReference
@@ -24,7 +25,7 @@ defmodule Pleroma.Web.Streamer do
def registry, do: @registry
- @public_streams ["public", "public:local", "public:media", "public:local:media"]
+ @public_streams Pleroma.Constants.public_streams()
@local_streams ["public:local", "public:local:media"]
@user_streams ["user", "user:notification", "direct", "user:pleroma_chat"]
@@ -223,8 +224,8 @@ defmodule Pleroma.Web.Streamer do
end
defp do_stream("follow_relationship", item) do
- text = StreamerView.render("follow_relationships_update.json", item)
user_topic = "user:#{item.follower.id}"
+ text = StreamerView.render("follow_relationships_update.json", item, user_topic)
Logger.debug("Trying to push follow relationship update to #{user_topic}\n\n")
@@ -270,9 +271,11 @@ defmodule Pleroma.Web.Streamer do
defp do_stream(topic, %Notification{} = item)
when topic in ["user", "user:notification"] do
- Registry.dispatch(@registry, "#{topic}:#{item.user_id}", fn list ->
+ user_topic = "#{topic}:#{item.user_id}"
+
+ Registry.dispatch(@registry, user_topic, fn list ->
Enum.each(list, fn {pid, _auth} ->
- send(pid, {:render_with_user, StreamerView, "notification.json", item})
+ send(pid, {:render_with_user, StreamerView, "notification.json", item, user_topic})
end)
end)
end
@@ -281,7 +284,7 @@ defmodule Pleroma.Web.Streamer do
when topic in ["user", "user:pleroma_chat"] do
topic = "#{topic}:#{user.id}"
- text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
+ text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}, topic)
Registry.dispatch(@registry, topic, fn list ->
Enum.each(list, fn {pid, _auth} ->
@@ -309,7 +312,7 @@ defmodule Pleroma.Web.Streamer do
end
defp push_to_socket(topic, %Participation{} = participation) do
- rendered = StreamerView.render("conversation.json", participation)
+ rendered = StreamerView.render("conversation.json", participation, topic)
Registry.dispatch(@registry, topic, fn list ->
Enum.each(list, fn {pid, _} ->
@@ -337,12 +340,15 @@ defmodule Pleroma.Web.Streamer do
Pleroma.Activity.get_create_by_object_ap_id(item.object.data["id"])
|> Map.put(:object, item.object)
- anon_render = StreamerView.render("status_update.json", create_activity)
+ anon_render = StreamerView.render("status_update.json", create_activity, topic)
Registry.dispatch(@registry, topic, fn list ->
Enum.each(list, fn {pid, auth?} ->
if auth? do
- send(pid, {:render_with_user, StreamerView, "status_update.json", create_activity})
+ send(
+ pid,
+ {:render_with_user, StreamerView, "status_update.json", create_activity, topic}
+ )
else
send(pid, {:text, anon_render})
end
@@ -351,12 +357,13 @@ defmodule Pleroma.Web.Streamer do
end
defp push_to_socket(topic, item) do
- anon_render = StreamerView.render("update.json", item)
+ Logger.debug("topic=#{topic}")
+ anon_render = StreamerView.render("update.json", item, topic)
Registry.dispatch(@registry, topic, fn list ->
Enum.each(list, fn {pid, auth?} ->
if auth? do
- send(pid, {:render_with_user, StreamerView, "update.json", item})
+ send(pid, {:render_with_user, StreamerView, "update.json", item, topic})
else
send(pid, {:text, anon_render})
end
diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex
index 0cdcb1918..f591da9a6 100644
--- a/lib/pleroma/web/views/streamer_view.ex
+++ b/lib/pleroma/web/views/streamer_view.ex
@@ -11,8 +11,11 @@ defmodule Pleroma.Web.StreamerView do
alias Pleroma.User
alias Pleroma.Web.MastodonAPI.NotificationView
- def render("update.json", %Activity{} = activity, %User{} = user) do
+ require Pleroma.Constants
+
+ def render("update.json", %Activity{} = activity, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -25,8 +28,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("status_update.json", %Activity{} = activity, %User{} = user) do
+ def render("status_update.json", %Activity{} = activity, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "status.update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -39,8 +43,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("notification.json", %Notification{} = notify, %User{} = user) do
+ def render("notification.json", %Notification{} = notify, %User{} = user, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "notification",
payload:
NotificationView.render(
@@ -52,8 +57,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("update.json", %Activity{} = activity) do
+ def render("update.json", %Activity{} = activity, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -65,8 +71,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("status_update.json", %Activity{} = activity) do
+ def render("status_update.json", %Activity{} = activity, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "status.update",
payload:
Pleroma.Web.MastodonAPI.StatusView.render(
@@ -78,7 +85,7 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("chat_update.json", %{chat_message_reference: cm_ref}) do
+ def render("chat_update.json", %{chat_message_reference: cm_ref}, topic) do
# Explicitly giving the cmr for the object here, so we don't accidentally
# send a later 'last_message' that was inserted between inserting this and
# streaming it out
@@ -93,6 +100,7 @@ defmodule Pleroma.Web.StreamerView do
)
%{
+ stream: render("stream.json", %{topic: topic}),
event: "pleroma:chat_update",
payload:
representation
@@ -101,8 +109,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("follow_relationships_update.json", item) do
+ def render("follow_relationships_update.json", item, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "pleroma:follow_relationships_update",
payload:
%{
@@ -123,8 +132,9 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
- def render("conversation.json", %Participation{} = participation) do
+ def render("conversation.json", %Participation{} = participation, topic) do
%{
+ stream: render("stream.json", %{topic: topic}),
event: "conversation",
payload:
Pleroma.Web.MastodonAPI.ConversationView.render("participation.json", %{
@@ -150,6 +160,22 @@ defmodule Pleroma.Web.StreamerView do
|> Jason.encode!()
end
+ def render("stream.json", %{topic: "user:pleroma_chat:" <> _}), do: ["user:pleroma_chat"]
+ def render("stream.json", %{topic: "user:notification:" <> _}), do: ["user:notification"]
+ def render("stream.json", %{topic: "user:" <> _}), do: ["user"]
+ def render("stream.json", %{topic: "direct:" <> _}), do: ["direct"]
+ def render("stream.json", %{topic: "list:" <> id}), do: ["list", id]
+ def render("stream.json", %{topic: "hashtag:" <> tag}), do: ["hashtag", tag]
+
+ def render("stream.json", %{topic: "public:remote:media:" <> instance}),
+ do: ["public:remote:media", instance]
+
+ def render("stream.json", %{topic: "public:remote:" <> instance}),
+ do: ["public:remote", instance]
+
+ def render("stream.json", %{topic: stream}) when stream in Pleroma.Constants.public_streams(),
+ do: [stream]
+
defp maybe_error(%{error: :bad_topic}), do: %{error: "bad_topic"}
defp maybe_error(%{error: :unauthorized}), do: %{error: "unauthorized"}
defp maybe_error(%{error: :already_authenticated}), do: %{error: "already_authenticated"}
--
cgit v1.2.3
From a348c2e4dd0551a603509501d718d9e0b995be90 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 01:29:11 -0400
Subject: Use pleroma: instead of pleroma. for ws events
---
lib/pleroma/web/mastodon_api/websocket_handler.ex | 8 ++++----
lib/pleroma/web/views/streamer_view.ex | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex
index 2707673ba..07c2b62e3 100644
--- a/lib/pleroma/web/mastodon_api/websocket_handler.ex
+++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex
@@ -215,7 +215,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
end
defp handle_client_event(
- %{"type" => "pleroma.authenticate", "token" => access_token} = _params,
+ %{"type" => "pleroma:authenticate", "token" => access_token} = _params,
state
) do
with {:auth, nil, nil} <- {:auth, state.user, state.oauth_token},
@@ -223,7 +223,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
{[
{:text,
StreamerView.render("pleroma_respond.json", %{
- type: "pleroma.authenticate",
+ type: "pleroma:authenticate",
result: "success"
})}
], %{state | user: user, oauth_token: oauth_token}}
@@ -232,7 +232,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
{[
{:text,
StreamerView.render("pleroma_respond.json", %{
- type: "pleroma.authenticate",
+ type: "pleroma:authenticate",
result: "error",
error: :already_authenticated
})}
@@ -242,7 +242,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
{[
{:text,
StreamerView.render("pleroma_respond.json", %{
- type: "pleroma.authenticate",
+ type: "pleroma:authenticate",
result: "error",
error: :unauthorized
})}
diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex
index f591da9a6..f97570b0a 100644
--- a/lib/pleroma/web/views/streamer_view.ex
+++ b/lib/pleroma/web/views/streamer_view.ex
@@ -148,7 +148,7 @@ defmodule Pleroma.Web.StreamerView do
def render("pleroma_respond.json", %{type: type, result: result} = params) do
%{
- event: "pleroma.respond",
+ event: "pleroma:respond",
payload:
%{
result: result,
--
cgit v1.2.3
From eebc605bc25deead55c305d703c06ddb9d9b1107 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 08:27:43 -0400
Subject: Clear up debug statement
---
lib/pleroma/web/streamer.ex | 1 -
1 file changed, 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 70e46617a..48ca82421 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -357,7 +357,6 @@ defmodule Pleroma.Web.Streamer do
end
defp push_to_socket(topic, item) do
- Logger.debug("topic=#{topic}")
anon_render = StreamerView.render("update.json", item, topic)
Registry.dispatch(@registry, topic, fn list ->
--
cgit v1.2.3
From 844d1a14e0b4aabbb61a6693fa6dd3a0aa0dbc5b Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 15:31:56 -0400
Subject: Start writing api docs for streaming endpoint
---
lib/pleroma/web/api_spec.ex | 10 +-
.../web/api_spec/operations/streaming_operation.ex | 186 +++++++++++++++++++++
2 files changed, 195 insertions(+), 1 deletion(-)
create mode 100644 lib/pleroma/web/api_spec/operations/streaming_operation.ex
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec.ex b/lib/pleroma/web/api_spec.ex
index 2d56dc643..163226ce5 100644
--- a/lib/pleroma/web/api_spec.ex
+++ b/lib/pleroma/web/api_spec.ex
@@ -10,6 +10,14 @@ defmodule Pleroma.Web.ApiSpec do
@behaviour OpenApi
+ defp streaming_paths do
+ %{
+ "/api/v1/streaming" => %OpenApiSpex.PathItem{
+ get: Pleroma.Web.ApiSpec.StreamingOperation.streaming_operation()
+ }
+ }
+ end
+
@impl OpenApi
def spec(opts \\ []) do
%OpenApi{
@@ -45,7 +53,7 @@ defmodule Pleroma.Web.ApiSpec do
}
},
# populate the paths from a phoenix router
- paths: OpenApiSpex.Paths.from_router(Router),
+ paths: Map.merge(streaming_paths(), OpenApiSpex.Paths.from_router(Router)),
components: %OpenApiSpex.Components{
parameters: %{
"accountIdOrNickname" =>
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
new file mode 100644
index 000000000..1ef7d72ef
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -0,0 +1,186 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.StreamingOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Response
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Helpers
+ alias Pleroma.Web.ApiSpec.Schemas.Status
+
+ @spec open_api_operation(atom) :: Operation.t()
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ @spec streaming_operation() :: Operation.t()
+ def streaming_operation do
+ %Operation{
+ tags: ["Timelines"],
+ summary: "Establish streaming connection",
+ description: "Receive statuses in real-time via WebSocket.",
+ security: [%{"oAuth" => ["read:statuses", "read:notifications"]}],
+ parameters: [
+ Operation.parameter(:connection, :header, %Schema{type: :string}, "connection header",
+ required: true
+ ),
+ Operation.parameter(:upgrade, :header, %Schema{type: :string}, "upgrade header",
+ required: true
+ ),
+ Operation.parameter(
+ :"sec-websocket-key",
+ :header,
+ %Schema{type: :string},
+ "sec-websocket-key header",
+ required: true
+ ),
+ Operation.parameter(
+ :"sec-websocket-version",
+ :header,
+ %Schema{type: :string},
+ "sec-websocket-version header",
+ required: true
+ )
+ ],
+ responses: %{
+ 101 => switching_protocols_response(),
+ 200 =>
+ Operation.response(
+ "Server-sent events",
+ "application/json",
+ server_sent_events()
+ )
+ }
+ }
+ end
+
+ defp switching_protocols_response do
+ %Response{
+ description: "Switching protocols",
+ headers: %{
+ "connection" => %OpenApiSpex.Header{required: true},
+ "upgrade" => %OpenApiSpex.Header{required: true},
+ "sec-websocket-accept" => %OpenApiSpex.Header{required: true}
+ }
+ }
+ end
+
+ defp server_sent_events do
+ %Schema{
+ oneOf: [
+ update_event(),
+ status_update_event(),
+ pleroma_respond_event()
+ ]
+ }
+ end
+
+ defp stream do
+ %Schema{
+ type: :array,
+ title: "Stream",
+ description: """
+ The stream identifier.
+ The first item is the name of the stream. If the stream needs a differentiator, the second item will be the corresponding identifier.
+ Currently, for the following stream types, there is a second element in the array:
+
+ - `list`: The second element is the id of the list, as a string.
+ - `hashtag`: The second element is the name of the hashtag.
+ - `public:remote:media` and `public:remote`: The second element is the domain of the corresponding instance.
+ """,
+ maxItems: 2,
+ minItems: 1,
+ items: %Schema{type: :string},
+ example: ["hashtag", "mew"]
+ }
+ end
+
+ defp get_schema(%Schema{} = schema), do: schema
+ defp get_schema(schema), do: schema.schema
+
+ defp server_sent_event_helper(name, description, type, payload, opts \\ []) do
+ payload_type = opts[:payload_type] || :json
+ has_stream = opts[:has_stream] || true
+
+ stream_properties =
+ if has_stream do
+ %{stream: stream()}
+ else
+ %{}
+ end
+
+ stream_example = if has_stream, do: %{"stream" => get_schema(stream()).example}, else: %{}
+
+ stream_required = if has_stream, do: [:stream], else: []
+
+ %Schema{
+ type: :object,
+ title: name,
+ description: description,
+ required: [:event, :payload] ++ stream_required,
+ properties:
+ %{
+ event: %Schema{
+ title: "Event type",
+ description: "Type of the event.",
+ type: :string,
+ required: true,
+ enum: [type]
+ },
+ payload:
+ if payload_type == :json do
+ %Schema{
+ title: "Event payload",
+ description: "JSON-encoded string of #{get_schema(payload).title}",
+ allOf: [payload]
+ }
+ else
+ payload
+ end
+ }
+ |> Map.merge(stream_properties),
+ example:
+ %{
+ "event" => type,
+ "payload" => get_schema(payload).example |> Jason.encode!()
+ }
+ |> Map.merge(stream_example)
+ }
+ end
+
+ defp update_event do
+ server_sent_event_helper("New status", "A newly-posted status.", "update", Status)
+ end
+
+ defp status_update_event do
+ server_sent_event_helper("Edit", "A status that was just edited", "status.update", Status)
+ end
+
+ defp pleroma_respond_event do
+ server_sent_event_helper(
+ "Server response",
+ "A response to a client-sent event.",
+ "pleroma:respond",
+ %Schema{
+ type: :object,
+ title: "Results",
+ required: [:result],
+ properties: %{
+ result: %Schema{
+ type: :string,
+ title: "Result of the request",
+ enum: ["success", "error", "ignored"]
+ },
+ error: %Schema{
+ type: :string,
+ title: "Error code",
+ description: "An error identifier. Only appears if `result` is `error`."
+ }
+ },
+ example: %{"result" => "success"}
+ }
+ )
+ end
+end
--
cgit v1.2.3
From dcef33f5f0c93883a634d12dc662b83d7ef6abfa Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 16:07:27 -0400
Subject: Document server-sent events of streaming
---
.../web/api_spec/operations/streaming_operation.ex | 106 +++++++++++++++++++++
1 file changed, 106 insertions(+)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index 1ef7d72ef..cdef41603 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -7,6 +7,10 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
alias OpenApiSpex.Response
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers
+ alias Pleroma.Web.ApiSpec.NotificationOperation
+ alias Pleroma.Web.ApiSpec.Schemas.Chat
+ alias Pleroma.Web.ApiSpec.Schemas.Conversation
+ alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.Status
@spec open_api_operation(atom) :: Operation.t()
@@ -22,6 +26,7 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
summary: "Establish streaming connection",
description: "Receive statuses in real-time via WebSocket.",
security: [%{"oAuth" => ["read:statuses", "read:notifications"]}],
+ operationId: "WebsocketHandler.streaming",
parameters: [
Operation.parameter(:connection, :header, %Schema{type: :string}, "connection header",
required: true
@@ -72,6 +77,11 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
oneOf: [
update_event(),
status_update_event(),
+ notification_event(),
+ chat_update_event(),
+ follow_relationships_update_event(),
+ conversation_event(),
+ delete_event(),
pleroma_respond_event()
]
}
@@ -158,6 +168,102 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
server_sent_event_helper("Edit", "A status that was just edited", "status.update", Status)
end
+ defp notification_event do
+ server_sent_event_helper(
+ "Notification",
+ "A new notification.",
+ "notification",
+ NotificationOperation.notification()
+ )
+ end
+
+ defp follow_relationships_update_event do
+ server_sent_event_helper(
+ "Follow relationships update",
+ "An update to follow relationships.",
+ "pleroma:follow_relationships_update",
+ %Schema{
+ type: :object,
+ title: "Follow relationships update",
+ required: [:state, :follower, :following],
+ properties: %{
+ state: %Schema{
+ type: :string,
+ description: "Follow state of the relationship.",
+ enum: ["follow_pending", "follow_accept", "follow_reject", "unfollow"]
+ },
+ follower: %Schema{
+ type: :object,
+ description: "Information about the follower.",
+ required: [:id, :follower_count, :following_count],
+ properties: %{
+ id: FlakeID,
+ follower_count: %Schema{type: :integer},
+ following_count: %Schema{type: :integer}
+ }
+ },
+ following: %Schema{
+ type: :object,
+ description: "Information about the following person.",
+ required: [:id, :follower_count, :following_count],
+ properties: %{
+ id: FlakeID,
+ follower_count: %Schema{type: :integer},
+ following_count: %Schema{type: :integer}
+ }
+ }
+ },
+ example: %{
+ "state" => "follow_pending",
+ "follower" => %{
+ "id" => "someUser1",
+ "follower_count" => 1,
+ "following_count" => 1
+ },
+ "following" => %{
+ "id" => "someUser2",
+ "follower_count" => 1,
+ "following_count" => 1
+ }
+ }
+ }
+ )
+ end
+
+ defp chat_update_event do
+ server_sent_event_helper(
+ "Chat update",
+ "A new chat message.",
+ "pleroma:chat_update",
+ Chat
+ )
+ end
+
+ defp conversation_event do
+ server_sent_event_helper(
+ "Conversation",
+ "An update about a conversation",
+ "conversation",
+ Conversation
+ )
+ end
+
+ defp delete_event do
+ server_sent_event_helper(
+ "Delete",
+ "A status that was just deleted.",
+ "delete",
+ %Schema{
+ type: :string,
+ title: "Status id",
+ description: "Id of the deleted status",
+ allOf: [FlakeID],
+ example: "some-opaque-id"
+ },
+ payload_type: :string
+ )
+ end
+
defp pleroma_respond_event do
server_sent_event_helper(
"Server response",
--
cgit v1.2.3
From 8829dcaee42b3ad1ee50f95b0586b22118771785 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 16:33:22 -0400
Subject: Document client-sent events in streaming
---
.../web/api_spec/operations/streaming_operation.ex | 126 ++++++++++++++++++++-
1 file changed, 125 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index cdef41603..18674c9a1 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -6,13 +6,14 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Response
alias OpenApiSpex.Schema
- alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.NotificationOperation
alias Pleroma.Web.ApiSpec.Schemas.Chat
alias Pleroma.Web.ApiSpec.Schemas.Conversation
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.Status
+ require Pleroma.Constants
+
@spec open_api_operation(atom) :: Operation.t()
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
@@ -49,6 +50,7 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
required: true
)
],
+ requestBody: request_body("Client-sent events", client_sent_events()),
responses: %{
101 => switching_protocols_response(),
200 =>
@@ -289,4 +291,126 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
}
)
end
+
+ defp client_sent_events do
+ %Schema{
+ oneOf: [
+ subscribe_event(),
+ unsubscribe_event(),
+ authenticate_event()
+ ]
+ }
+ end
+
+ defp request_body(description, schema, opts \\ []) do
+ %OpenApiSpex.RequestBody{
+ description: description,
+ content: %{
+ "application/json" => %OpenApiSpex.MediaType{
+ schema: schema,
+ example: opts[:example],
+ examples: opts[:examples]
+ }
+ }
+ }
+ end
+
+ defp client_sent_event_helper(name, description, type, properties, opts) do
+ required = opts[:required] || []
+
+ %Schema{
+ type: :object,
+ title: name,
+ required: [:type] ++ required,
+ description: description,
+ properties:
+ %{
+ type: %Schema{type: :string, enum: [type], description: "Type of the event."}
+ }
+ |> Map.merge(properties),
+ example: opts[:example]
+ }
+ end
+
+ defp subscribe_event do
+ client_sent_event_helper(
+ "Subscribe",
+ "Subscribe to a stream.",
+ "subscribe",
+ stream_specifier(),
+ required: [:stream],
+ example: %{"type" => "subscribe", "stream" => "list", "list" => "1"}
+ )
+ end
+
+ defp unsubscribe_event do
+ client_sent_event_helper(
+ "Unsubscribe",
+ "Unsubscribe from a stream.",
+ "subscribe",
+ stream_specifier(),
+ required: [:stream],
+ example: %{
+ "type" => "unsubscribe",
+ "stream" => "public:remote:media",
+ "instance" => "example.org"
+ }
+ )
+ end
+
+ defp authenticate_event do
+ client_sent_event_helper(
+ "Authenticate",
+ "Authenticate via an access token.",
+ "pleroma:authenticate",
+ %{
+ token: %Schema{
+ type: :string,
+ description: "An OAuth access token with corresponding permissions.",
+ example: "some token"
+ }
+ },
+ required: [:token]
+ )
+ end
+
+ defp stream_specifier do
+ %{
+ stream: %Schema{
+ type: :string,
+ description: "The name of the stream.",
+ enum:
+ Pleroma.Constants.public_streams() ++
+ [
+ "public:remote",
+ "public:remote:media",
+ "user",
+ "user:pleroma_chat",
+ "user:notification",
+ "direct",
+ "list",
+ "hashtag"
+ ]
+ },
+ list: %Schema{
+ type: :string,
+ title: "List id",
+ description: "The id of the list. Required when `stream` is `list`.",
+ example: "some-id"
+ },
+ tag: %Schema{
+ type: :string,
+ title: "Hashtag name",
+ description: "The name of the hashtag. Required when `stream` is `hashtag`.",
+ example: "mew"
+ },
+ instance: %Schema{
+ type: :string,
+ title: "Domain name",
+ description:
+ "Domain name of the instance. Required when `stream` is `public:remote` or `public:remote:media`.",
+ example: "example.org"
+ }
+ }
+ end
end
--
cgit v1.2.3
From f393a15dd1217a7f6aec9e9acc7b983e7b165a91 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 16:46:32 -0400
Subject: Fix some specs about server-sent events in streaming
---
.../web/api_spec/operations/streaming_operation.ex | 49 ++++++++++++++--------
1 file changed, 32 insertions(+), 17 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index 18674c9a1..fa48b9613 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -113,8 +113,8 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
defp get_schema(schema), do: schema.schema
defp server_sent_event_helper(name, description, type, payload, opts \\ []) do
- payload_type = opts[:payload_type] || :json
- has_stream = opts[:has_stream] || true
+ payload_type = Keyword.get(opts, :payload_type, :json)
+ has_stream = Keyword.get(opts, :has_stream, true)
stream_properties =
if has_stream do
@@ -127,6 +127,24 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
stream_required = if has_stream, do: [:stream], else: []
+ payload_schema =
+ if payload_type == :json do
+ %Schema{
+ title: "Event payload",
+ description: "JSON-encoded string of #{get_schema(payload).title}",
+ allOf: [payload]
+ }
+ else
+ payload
+ end
+
+ payload_example =
+ if payload_type == :json do
+ get_schema(payload).example |> Jason.encode!()
+ else
+ get_schema(payload).example
+ end
+
%Schema{
type: :object,
title: name,
@@ -141,22 +159,13 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
required: true,
enum: [type]
},
- payload:
- if payload_type == :json do
- %Schema{
- title: "Event payload",
- description: "JSON-encoded string of #{get_schema(payload).title}",
- allOf: [payload]
- }
- else
- payload
- end
+ payload: payload_schema
}
|> Map.merge(stream_properties),
example:
%{
"event" => type,
- "payload" => get_schema(payload).example |> Jason.encode!()
+ "payload" => payload_example
}
|> Map.merge(stream_example)
}
@@ -262,7 +271,8 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
allOf: [FlakeID],
example: "some-opaque-id"
},
- payload_type: :string
+ payload_type: :string,
+ has_stream: false
)
end
@@ -274,7 +284,7 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
%Schema{
type: :object,
title: "Results",
- required: [:result],
+ required: [:result, :type],
properties: %{
result: %Schema{
type: :string,
@@ -285,10 +295,15 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
type: :string,
title: "Error code",
description: "An error identifier. Only appears if `result` is `error`."
+ },
+ type: %Schema{
+ type: :string,
+ description: "Type of the request."
}
},
- example: %{"result" => "success"}
- }
+ example: %{"result" => "success", "type" => "pleroma:authenticate"}
+ },
+ has_stream: false
)
end
--
cgit v1.2.3
From c13f0a8460853d8fe9aa04cb5d57ea06b692a3bf Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 17:00:35 -0400
Subject: Add meta-info and query strings to streaming doc
---
.../web/api_spec/operations/streaming_operation.ex | 89 +++++++++++++++-------
1 file changed, 61 insertions(+), 28 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index fa48b9613..4c4888d8e 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -25,31 +25,46 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
%Operation{
tags: ["Timelines"],
summary: "Establish streaming connection",
- description: "Receive statuses in real-time via WebSocket.",
+ description: """
+ Receive statuses in real-time via WebSocket.
+
+ You can specify the access token on the query string or through the `sec-websocket-protocol` header. Using
+ the query string to authenticate is considered unsafe and should not be used unless you have to (e.g. to maintain
+ your client's compatibility with Mastodon).
+
+ You may specify a stream on the query string. If you do so and you are connecting to a stream that requires logged-in users,
+ you must specify the access token at the time of the connection (i.e. via query string or header).
+
+ Otherwise, you have the option to authenticate after you have established the connection through client-sent events.
+
+ The "Request body" section below describes what events clients can send through WebSocket, and the "Responses" section
+ describes what events server will send through WebSocket.
+ """,
security: [%{"oAuth" => ["read:statuses", "read:notifications"]}],
operationId: "WebsocketHandler.streaming",
- parameters: [
- Operation.parameter(:connection, :header, %Schema{type: :string}, "connection header",
- required: true
- ),
- Operation.parameter(:upgrade, :header, %Schema{type: :string}, "upgrade header",
- required: true
- ),
- Operation.parameter(
- :"sec-websocket-key",
- :header,
- %Schema{type: :string},
- "sec-websocket-key header",
- required: true
- ),
- Operation.parameter(
- :"sec-websocket-version",
- :header,
- %Schema{type: :string},
- "sec-websocket-version header",
- required: true
- )
- ],
+ parameters:
+ [
+ Operation.parameter(:connection, :header, %Schema{type: :string}, "connection header",
+ required: true
+ ),
+ Operation.parameter(:upgrade, :header, %Schema{type: :string}, "upgrade header",
+ required: true
+ ),
+ Operation.parameter(
+ :"sec-websocket-key",
+ :header,
+ %Schema{type: :string},
+ "sec-websocket-key header",
+ required: true
+ ),
+ Operation.parameter(
+ :"sec-websocket-version",
+ :header,
+ %Schema{type: :string},
+ "sec-websocket-version header",
+ required: true
+ )
+ ] ++ stream_params() ++ access_token_params(),
requestBody: request_body("Client-sent events", client_sent_events()),
responses: %{
101 => switching_protocols_response(),
@@ -63,6 +78,20 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
}
end
+ defp stream_params do
+ stream_specifier()
+ |> Enum.map(fn {name, schema} ->
+ Operation.parameter(name, :query, schema, get_schema(schema).description)
+ end)
+ end
+
+ defp access_token_params do
+ [
+ Operation.parameter(:access_token, :query, token(), token().description),
+ Operation.parameter(:"sec-websocket-protocol", :header, token(), token().description)
+ ]
+ end
+
defp switching_protocols_response do
%Response{
description: "Switching protocols",
@@ -379,16 +408,20 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
"Authenticate via an access token.",
"pleroma:authenticate",
%{
- token: %Schema{
- type: :string,
- description: "An OAuth access token with corresponding permissions.",
- example: "some token"
- }
+ token: token()
},
required: [:token]
)
end
+ defp token do
+ %Schema{
+ type: :string,
+ description: "An OAuth access token with corresponding permissions.",
+ example: "some token"
+ }
+ end
+
defp stream_specifier do
%{
stream: %Schema{
--
cgit v1.2.3
From 32de0683c4069f5877722dce0b4f5a9a6825b7c7 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 17:15:58 -0400
Subject: Fix unsubscribe event type in streaming doc
---
lib/pleroma/web/api_spec/operations/streaming_operation.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index 4c4888d8e..ae3aeb4ab 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -391,7 +391,7 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
client_sent_event_helper(
"Unsubscribe",
"Unsubscribe from a stream.",
- "subscribe",
+ "unsubscribe",
stream_specifier(),
required: [:stream],
example: %{
--
cgit v1.2.3
From 840dd01035581a37613f695facdd99fbf6ac8319 Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 1 Apr 2023 18:33:43 -0400
Subject: Fix duplicated schema names
---
lib/pleroma/web/api_spec/operations/streaming_operation.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/web/api_spec/operations/streaming_operation.ex b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
index ae3aeb4ab..b580bc2f0 100644
--- a/lib/pleroma/web/api_spec/operations/streaming_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/streaming_operation.ex
@@ -281,7 +281,7 @@ defmodule Pleroma.Web.ApiSpec.StreamingOperation do
defp conversation_event do
server_sent_event_helper(
- "Conversation",
+ "Conversation update",
"An update about a conversation",
"conversation",
Conversation
--
cgit v1.2.3
From b748efe66a099b66300f2beda42f5639911bab4a Mon Sep 17 00:00:00 2001
From: tusooa
Date: Sat, 29 Jul 2023 12:55:43 -0400
Subject: Fix mentioning punycode domains when using Markdown
---
lib/pleroma/formatter.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index a46c3e381..11d5af2fb 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -124,7 +124,7 @@ defmodule Pleroma.Formatter do
end
def markdown_to_html(text) do
- Earmark.as_html!(text, %Earmark.Options{compact_output: true})
+ Earmark.as_html!(text, %Earmark.Options{compact_output: true, smartypants: false})
end
def html_escape({text, mentions, hashtags}, type) do
--
cgit v1.2.3
From bf426c53b4e1c025d7857adf485976421175cdf6 Mon Sep 17 00:00:00 2001
From: Mark Felder
Date: Tue, 7 Nov 2023 15:11:14 -0500
Subject: Fix digest email processing, consolidate Oban queues
The email related jobs can all share a single Oban queue
---
lib/pleroma/workers/cron/digest_emails_worker.ex | 2 +-
lib/pleroma/workers/cron/new_users_digest_worker.ex | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/pleroma/workers/cron/digest_emails_worker.ex b/lib/pleroma/workers/cron/digest_emails_worker.ex
index 1540c1605..0292bbb3b 100644
--- a/lib/pleroma/workers/cron/digest_emails_worker.ex
+++ b/lib/pleroma/workers/cron/digest_emails_worker.ex
@@ -7,7 +7,7 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorker do
The worker to send digest emails.
"""
- use Oban.Worker, queue: "digest_emails"
+ use Oban.Worker, queue: "mailer"
alias Pleroma.Config
alias Pleroma.Emails
diff --git a/lib/pleroma/workers/cron/new_users_digest_worker.ex b/lib/pleroma/workers/cron/new_users_digest_worker.ex
index 267fe2837..1c3e445aa 100644
--- a/lib/pleroma/workers/cron/new_users_digest_worker.ex
+++ b/lib/pleroma/workers/cron/new_users_digest_worker.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorker do
import Ecto.Query
- use Pleroma.Workers.WorkerHelper, queue: "new_users_digest"
+ use Pleroma.Workers.WorkerHelper, queue: "mailer"
@impl Oban.Worker
def perform(_job) do
--
cgit v1.2.3
From e23672d82f0a6e61bf4ada65cfca6cfbc647710d Mon Sep 17 00:00:00 2001
From: Mark Felder
Date: Wed, 8 Nov 2023 12:21:34 -0500
Subject: Ensure benchee doesn't run unless we are executing benchmarks
---
lib/mix/tasks/pleroma/benchmark.ex | 113 -------------------------------------
1 file changed, 113 deletions(-)
delete mode 100644 lib/mix/tasks/pleroma/benchmark.ex
(limited to 'lib')
diff --git a/lib/mix/tasks/pleroma/benchmark.ex b/lib/mix/tasks/pleroma/benchmark.ex
deleted file mode 100644
index f32492169..000000000
--- a/lib/mix/tasks/pleroma/benchmark.ex
+++ /dev/null
@@ -1,113 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Mix.Tasks.Pleroma.Benchmark do
- import Mix.Pleroma
- use Mix.Task
-
- def run(["search"]) do
- start_pleroma()
-
- Benchee.run(%{
- "search" => fn ->
- Pleroma.Activity.search(nil, "cofe")
- end
- })
- end
-
- def run(["tag"]) do
- start_pleroma()
-
- Benchee.run(%{
- "tag" => fn ->
- %{"type" => "Create", "tag" => "cofe"}
- |> Pleroma.Web.ActivityPub.ActivityPub.fetch_public_activities()
- end
- })
- end
-
- def run(["render_timeline", nickname | _] = args) do
- start_pleroma()
- user = Pleroma.User.get_by_nickname(nickname)
-
- activities =
- %{}
- |> Map.put("type", ["Create", "Announce"])
- |> Map.put("blocking_user", user)
- |> Map.put("muting_user", user)
- |> Map.put("user", user)
- |> Map.put("limit", 4096)
- |> Pleroma.Web.ActivityPub.ActivityPub.fetch_public_activities()
- |> Enum.reverse()
-
- inputs = %{
- "1 activity" => Enum.take_random(activities, 1),
- "10 activities" => Enum.take_random(activities, 10),
- "20 activities" => Enum.take_random(activities, 20),
- "40 activities" => Enum.take_random(activities, 40),
- "80 activities" => Enum.take_random(activities, 80)
- }
-
- inputs =
- if Enum.at(args, 2) == "extended" do
- Map.merge(inputs, %{
- "200 activities" => Enum.take_random(activities, 200),
- "500 activities" => Enum.take_random(activities, 500),
- "2000 activities" => Enum.take_random(activities, 2000),
- "4096 activities" => Enum.take_random(activities, 4096)
- })
- else
- inputs
- end
-
- Benchee.run(
- %{
- "Standart rendering" => fn activities ->
- Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
- activities: activities,
- for: user,
- as: :activity
- })
- end
- },
- inputs: inputs
- )
- end
-
- def run(["adapters"]) do
- start_pleroma()
-
- :ok =
- Pleroma.Gun.Conn.open(
- "https://httpbin.org/stream-bytes/1500",
- :gun_connections
- )
-
- Process.sleep(1_500)
-
- Benchee.run(
- %{
- "Without conn and without pool" => fn ->
- {:ok, %Tesla.Env{}} =
- Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [],
- pool: :no_pool,
- receive_conn: false
- )
- end,
- "Without conn and with pool" => fn ->
- {:ok, %Tesla.Env{}} =
- Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], receive_conn: false)
- end,
- "With reused conn and without pool" => fn ->
- {:ok, %Tesla.Env{}} =
- Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], pool: :no_pool)
- end,
- "With reused conn and with pool" => fn ->
- {:ok, %Tesla.Env{}} = Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500")
- end
- },
- parallel: 10
- )
- end
-end
--
cgit v1.2.3