Merge develop to bump elixir version in the CI so I don't get failing formatting
[akkoma] / lib / pleroma / web / push / push.ex
index 4779434504fc917a68b3e0b34e0ec835f90c9d37..5259e8e33083c248f38621fcfdc693e63dcb2fc9 100644 (file)
@@ -1,23 +1,27 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
 defmodule Pleroma.Web.Push do
   use GenServer
 
 defmodule Pleroma.Web.Push do
   use GenServer
 
-  alias Pleroma.{Repo, User}
-  alias Pleroma.Web.Push.Subscription
+  alias Pleroma.Web.Push.Impl
 
   require Logger
 
   require Logger
-  import Ecto.Query
 
 
-  @types ["Create", "Follow", "Announce", "Like"]
+  ##############
+  # Client API #
+  ##############
 
 
-  def start_link() do
+  def start_link do
     GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
   end
 
     GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
   end
 
-  def vapid_config() do
+  def vapid_config do
     Application.get_env(:web_push_encryption, :vapid_details, [])
   end
 
     Application.get_env(:web_push_encryption, :vapid_details, [])
   end
 
-  def enabled() do
+  def enabled do
     case vapid_config() do
       [] -> false
       list when is_list(list) -> true
     case vapid_config() do
       [] -> false
       list when is_list(list) -> true
@@ -25,14 +29,18 @@ defmodule Pleroma.Web.Push do
     end
   end
 
     end
   end
 
-  def send(notification) do
-    if enabled() do
-      GenServer.cast(Pleroma.Web.Push, {:send, notification})
-    end
-  end
+  def send(notification),
+    do: GenServer.cast(__MODULE__, {:send, notification})
 
 
+  ####################
+  # Server Callbacks #
+  ####################
+
+  @impl true
   def init(:ok) do
   def init(:ok) do
-    if !enabled() do
+    if enabled() do
+      {:ok, nil}
+    else
       Logger.warn("""
       VAPID key pair is not found. If you wish to enabled web push, please run
 
       Logger.warn("""
       VAPID key pair is not found. If you wish to enabled web push, please run
 
@@ -42,93 +50,15 @@ defmodule Pleroma.Web.Push do
       """)
 
       :ignore
       """)
 
       :ignore
-    else
-      {:ok, nil}
     end
   end
 
     end
   end
 
-  def handle_cast(
-        {:send, %{activity: %{data: %{"type" => type}}, user_id: user_id} = notification},
-        state
-      )
-      when type in @types do
-    actor = User.get_cached_by_ap_id(notification.activity.data["actor"])
-
-    type = Pleroma.Activity.mastodon_notification_type(notification.activity)
-
-    Subscription
-    |> where(user_id: ^user_id)
-    |> preload(:token)
-    |> Repo.all()
-    |> Enum.filter(fn subscription ->
-      get_in(subscription.data, ["alerts", type]) || false
-    end)
-    |> Enum.each(fn subscription ->
-      sub = %{
-        keys: %{
-          p256dh: subscription.key_p256dh,
-          auth: subscription.key_auth
-        },
-        endpoint: subscription.endpoint
-      }
-
-      body =
-        Jason.encode!(%{
-          title: format_title(notification),
-          access_token: subscription.token.token,
-          body: format_body(notification, actor),
-          notification_id: notification.id,
-          notification_type: type,
-          icon: User.avatar_url(actor),
-          preferred_locale: "en"
-        })
-
-      case WebPushEncryption.send_web_push(
-             body,
-             sub,
-             Application.get_env(:web_push_encryption, :gcm_api_key)
-           ) do
-        {:ok, %{status_code: code}} when 400 <= code and code < 500 ->
-          Logger.debug("Removing subscription record")
-          Repo.delete!(subscription)
-          :ok
-
-        {:ok, %{status_code: code}} when 200 <= code and code < 300 ->
-          :ok
-
-        {:ok, %{status_code: code}} ->
-          Logger.error("Web Push Notification failed with code: #{code}")
-          :error
-
-        _ ->
-          Logger.error("Web Push Notification failed with unknown error")
-          :error
-      end
-    end)
-
-    {:noreply, state}
-  end
-
-  def handle_cast({:send, _}, state) do
-    Logger.warn("Unknown notification type")
-    {:noreply, state}
-  end
-
-  defp format_title(%{activity: %{data: %{"type" => type}}}) do
-    case type do
-      "Create" -> "New Mention"
-      "Follow" -> "New Follower"
-      "Announce" -> "New Repeat"
-      "Like" -> "New Favorite"
+  @impl true
+  def handle_cast({:send, notification}, state) do
+    if enabled() do
+      Impl.perform_send(notification)
     end
     end
-  end
 
 
-  defp format_body(%{activity: %{data: %{"type" => type}}}, actor) do
-    case type do
-      "Create" -> "@#{actor.nickname} has mentioned you"
-      "Follow" -> "@#{actor.nickname} has followed you"
-      "Announce" -> "@#{actor.nickname} has repeated your post"
-      "Like" -> "@#{actor.nickname} has favorited your post"
-    end
+    {:noreply, state}
   end
 end
   end
 end