From 07cb89823f2a33bc540fe53bd784e4b8e9197506 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 18:59:51 -0400 Subject: More robust validation the vapid config is set --- lib/pleroma/web/push.ex | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/push.ex b/lib/pleroma/web/push.ex index 0d43f402e..af895467b 100644 --- a/lib/pleroma/web/push.ex +++ b/lib/pleroma/web/push.ex @@ -20,16 +20,10 @@ defmodule Pleroma.Web.Push do end def vapid_config do - Application.get_env(:web_push_encryption, :vapid_details, []) + Application.get_env(:web_push_encryption, :vapid_details, nil) end - def enabled do - case vapid_config() do - [] -> false - list when is_list(list) -> true - _ -> false - end - end + def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config()) def send(notification) do WebPusherWorker.enqueue("web_push", %{"notification_id" => notification.id}) -- cgit v1.2.3 From db88bf30d50a546114d3ee22a3c67b53975257d4 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:20:38 -0400 Subject: Add spec for send/1 --- lib/pleroma/web/push.ex | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/push.ex b/lib/pleroma/web/push.ex index af895467b..d4693f63e 100644 --- a/lib/pleroma/web/push.ex +++ b/lib/pleroma/web/push.ex @@ -25,6 +25,8 @@ defmodule Pleroma.Web.Push do def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config()) + @spec send(Pleroma.Notification.t()) :: + {:ok, Oban.Job.t()} | {:error, Oban.Job.changeset() | term()} def send(notification) do WebPusherWorker.enqueue("web_push", %{"notification_id" => notification.id}) end -- cgit v1.2.3 From 86fa0889bc9906aced78b60ada932b569743340a Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:30:27 -0400 Subject: Remove unnecessary mastodon_type hack --- lib/pleroma/web/push/impl.ex | 53 +++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 53334e72c..1853fdc2d 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -29,7 +29,6 @@ defmodule Pleroma.Web.Push.Impl do when activity_type in @types do actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) - mastodon_type = notification.type gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key) avatar_url = User.avatar_url(actor) object = Object.normalize(activity, fetch: false) @@ -37,11 +36,11 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id = Activity.direct_conversation_id(activity, user) for subscription <- fetch_subscriptions(user_id), - Subscription.enabled?(subscription, mastodon_type) do + Subscription.enabled?(subscription, notification.type) do %{ access_token: subscription.token.token, notification_id: notification.id, - notification_type: mastodon_type, + notification_type: notification.type, icon: avatar_url, preferred_locale: "en", pleroma: %{ @@ -49,7 +48,7 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id: direct_conversation_id } } - |> Map.merge(build_content(notification, actor, object, mastodon_type)) + |> Map.merge(build_content(notification, actor, object)) |> Jason.encode!() |> push_message(build_sub(subscription), gcm_api_key, subscription) end @@ -106,31 +105,24 @@ defmodule Pleroma.Web.Push.Impl do } end - def build_content(notification, actor, object, mastodon_type \\ nil) - def build_content( %{ user: %{notification_settings: %{hide_notification_contents: true}} } = notification, _actor, - _object, - mastodon_type + _object ) do - %{body: format_title(notification, mastodon_type)} + %{body: format_title(notification)} end - def build_content(notification, actor, object, mastodon_type) do - mastodon_type = mastodon_type || notification.type - + def build_content(notification, actor, object) do %{ - title: format_title(notification, mastodon_type), - body: format_body(notification, actor, object, mastodon_type) + title: format_title(notification), + body: format_body(notification, actor, object) } end - def format_body(activity, actor, object, mastodon_type \\ nil) - - def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}, _) do + def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}) do case data["content"] do nil -> "@#{actor.nickname}: (Attachment)" content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" @@ -140,8 +132,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Create"}}}, actor, - %{data: %{"content" => content}}, - _mastodon_type + %{data: %{"content" => content}} ) do "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end @@ -149,8 +140,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Announce"}}}, actor, - %{data: %{"content" => content}}, - _mastodon_type + %{data: %{"content" => content}} ) do "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" end @@ -158,8 +148,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "EmojiReact", "content" => content}}}, actor, - _object, - _mastodon_type + _object ) do "@#{actor.nickname} reacted with #{content}" end @@ -167,13 +156,10 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => type}}} = notification, actor, - _object, - mastodon_type + _object ) when type in ["Follow", "Like"] do - mastodon_type = mastodon_type || notification.type - - case mastodon_type do + case notification.type do "follow" -> "@#{actor.nickname} has followed you" "follow_request" -> "@#{actor.nickname} has requested to follow you" "favourite" -> "@#{actor.nickname} has favorited your post" @@ -183,20 +169,17 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Update"}}}, actor, - _object, - _mastodon_type + _object ) do "@#{actor.nickname} edited a status" end - def format_title(activity, mastodon_type \\ nil) - - def format_title(%{activity: %{data: %{"directMessage" => true}}}, _mastodon_type) do + def format_title(%{activity: %{data: %{"directMessage" => true}}}) do "New Direct Message" end - def format_title(%{type: type}, mastodon_type) do - case mastodon_type || type do + def format_title(%{type: type}) do + case type do "mention" -> "New Mention" "status" -> "New Status" "follow" -> "New Follower" -- cgit v1.2.3 From b1ef6e5e9ad5afc9d556a4d88ff34c9b62f5fea2 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:48:41 -0400 Subject: Cleanup to make the code easier to follow --- lib/pleroma/web/push/impl.ex | 46 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 1853fdc2d..df7e0c53f 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -27,10 +27,10 @@ defmodule Pleroma.Web.Push.Impl do } = notification ) when activity_type in @types do - actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) + user = User.get_cached_by_ap_id(notification.activity.data["actor"]) gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key) - avatar_url = User.avatar_url(actor) + avatar_url = User.avatar_url(user) object = Object.normalize(activity, fetch: false) user = User.get_cached_by_id(user_id) direct_conversation_id = Activity.direct_conversation_id(activity, user) @@ -48,7 +48,7 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id: direct_conversation_id } } - |> Map.merge(build_content(notification, actor, object)) + |> Map.merge(build_content(notification, user, object)) |> Jason.encode!() |> push_message(build_sub(subscription), gcm_api_key, subscription) end @@ -109,71 +109,73 @@ defmodule Pleroma.Web.Push.Impl do %{ user: %{notification_settings: %{hide_notification_contents: true}} } = notification, - _actor, + _user, _object ) do %{body: format_title(notification)} end - def build_content(notification, actor, object) do + def build_content(notification, user, object) do %{ title: format_title(notification), - body: format_body(notification, actor, object) + body: format_body(notification, user, object) } end - def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}) do - case data["content"] do - nil -> "@#{actor.nickname}: (Attachment)" - content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + @spec format_body(Notification.t(), User.t(), Object.t()) :: String.t() + def format_body(_notification, user, %{data: %{"type" => "ChatMessage"} = object}) do + case object["content"] do + nil -> "@#{user.nickname}: (Attachment)" + content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end end def format_body( %{activity: %{data: %{"type" => "Create"}}}, - actor, + user, %{data: %{"content" => content}} ) do - "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end def format_body( %{activity: %{data: %{"type" => "Announce"}}}, - actor, + user, %{data: %{"content" => content}} ) do - "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" end def format_body( %{activity: %{data: %{"type" => "EmojiReact", "content" => content}}}, - actor, + user, _object ) do - "@#{actor.nickname} reacted with #{content}" + "@#{user.nickname} reacted with #{content}" end def format_body( %{activity: %{data: %{"type" => type}}} = notification, - actor, + user, _object ) when type in ["Follow", "Like"] do case notification.type do - "follow" -> "@#{actor.nickname} has followed you" - "follow_request" -> "@#{actor.nickname} has requested to follow you" - "favourite" -> "@#{actor.nickname} has favorited your post" + "follow" -> "@#{user.nickname} has followed you" + "follow_request" -> "@#{user.nickname} has requested to follow you" + "favourite" -> "@#{user.nickname} has favorited your post" end end def format_body( %{activity: %{data: %{"type" => "Update"}}}, - actor, + user, _object ) do - "@#{actor.nickname} edited a status" + "@#{user.nickname} edited a status" end + @spec format_title(Notification.t()) :: String.t() def format_title(%{activity: %{data: %{"directMessage" => true}}}) do "New Direct Message" end -- cgit v1.2.3 From 3211557f742e07d5144426a71c39267480656a38 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 20:30:43 -0400 Subject: Render nice web push notifications for polls --- lib/pleroma/web/push/impl.ex | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index df7e0c53f..98e7659ab 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -130,6 +130,24 @@ defmodule Pleroma.Web.Push.Impl do end end + def format_body( + %{type: "poll"} = _notification, + _user, + %{data: %{"content" => content} = data} = _object + ) do + options = Map.get(data, "anyOf") || Map.get(data, "oneOf") + + content_text = content <> "\n" + + options_text = + Enum.map(options, fn x -> "○ #{x["name"]}" end) + |> Enum.join("\n") + + [content_text, options_text] + |> Enum.join("\n") + |> Utils.scrub_html_and_truncate(80) + end + def format_body( %{activity: %{data: %{"type" => "Create"}}}, user, @@ -191,6 +209,7 @@ defmodule Pleroma.Web.Push.Impl do "update" -> "New Update" "pleroma:chat_mention" -> "New Chat Message" "pleroma:emoji_reaction" -> "New Reaction" + "poll" -> "Poll Results" type -> "New #{String.capitalize(type || "event")}" end end -- cgit v1.2.3 From dcc50da4009f19303dec36e0969f3fca0f690e4f Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:40:08 -0400 Subject: Stream the notifications as part of the job --- lib/pleroma/notification.ex | 2 -- lib/pleroma/workers/poll_worker.ex | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index b9694a353..de2508b93 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -479,8 +479,6 @@ defmodule Pleroma.Notification do end end) - stream(notifications) - {:ok, notifications} end end diff --git a/lib/pleroma/workers/poll_worker.ex b/lib/pleroma/workers/poll_worker.ex index 70df54193..3fcac9bc3 100644 --- a/lib/pleroma/workers/poll_worker.ex +++ b/lib/pleroma/workers/poll_worker.ex @@ -14,8 +14,9 @@ defmodule Pleroma.Workers.PollWorker do @impl Oban.Worker def perform(%Job{args: %{"op" => "poll_end", "activity_id" => activity_id}}) do - with %Activity{} = activity <- find_poll_activity(activity_id) do - Notification.create_poll_notifications(activity) + with %Activity{} = activity <- find_poll_activity(activity_id), + {:ok, notifications} <- Notification.create_poll_notifications(activity) do + Notification.stream(notifications) end end -- cgit v1.2.3 From c1b84edefcd8db998a7eabff110f2dabecfc8dde Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:48:38 -0400 Subject: Increase web push character limit for the body --- lib/pleroma/web/push/impl.ex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 98e7659ab..13c054e05 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -16,6 +16,7 @@ defmodule Pleroma.Web.Push.Impl do require Logger import Ecto.Query + @body_chars 140 @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact", "Update"] @doc "Performs sending notifications for user subscriptions" @@ -126,7 +127,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body(_notification, user, %{data: %{"type" => "ChatMessage"} = object}) do case object["content"] do nil -> "@#{user.nickname}: (Attachment)" - content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end end @@ -145,7 +146,7 @@ defmodule Pleroma.Web.Push.Impl do [content_text, options_text] |> Enum.join("\n") - |> Utils.scrub_html_and_truncate(80) + |> Utils.scrub_html_and_truncate(@body_chars) end def format_body( @@ -153,7 +154,7 @@ defmodule Pleroma.Web.Push.Impl do user, %{data: %{"content" => content}} ) do - "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end def format_body( @@ -161,7 +162,7 @@ defmodule Pleroma.Web.Push.Impl do user, %{data: %{"content" => content}} ) do - "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end def format_body( -- cgit v1.2.3