Merge branch 'develop' into gun
[akkoma] / lib / pleroma / emails / user_email.ex
index 64f8551122c7db5ab9e58fdb4345e83bc0a53c2e..dfadc10b3d962165bb5fba8df5276776646e7a36 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Emails.UserEmail do
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Emails.UserEmail do
@@ -7,29 +7,24 @@ defmodule Pleroma.Emails.UserEmail do
 
   use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email}
 
 
   use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email}
 
+  alias Pleroma.Config
+  alias Pleroma.User
   alias Pleroma.Web.Endpoint
   alias Pleroma.Web.Router
 
   alias Pleroma.Web.Endpoint
   alias Pleroma.Web.Router
 
-  defp instance_config, do: Pleroma.Config.get(:instance)
-
-  defp instance_name, do: instance_config()[:name]
+  defp instance_name, do: Config.get([:instance, :name])
 
   defp sender do
 
   defp sender do
-    email = Keyword.get(instance_config(), :notify_email, instance_config()[:email])
+    email = Config.get([:instance, :notify_email]) || Config.get([:instance, :email])
     {instance_name(), email}
   end
 
   defp recipient(email, nil), do: email
   defp recipient(email, name), do: {name, email}
     {instance_name(), email}
   end
 
   defp recipient(email, nil), do: email
   defp recipient(email, name), do: {name, email}
-  defp recipient(%Pleroma.User{} = user), do: recipient(user.email, user.name)
+  defp recipient(%User{} = user), do: recipient(user.email, user.name)
 
 
-  def password_reset_email(user, password_reset_token) when is_binary(password_reset_token) do
-    password_reset_url =
-      Router.Helpers.util_url(
-        Endpoint,
-        :show_password_reset,
-        password_reset_token
-      )
+  def password_reset_email(user, token) when is_binary(token) do
+    password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
 
     html_body = """
     <h3>Reset your password at #{instance_name()}</h3>
 
     html_body = """
     <h3>Reset your password at #{instance_name()}</h3>
@@ -77,7 +72,7 @@ defmodule Pleroma.Emails.UserEmail do
         Endpoint,
         :confirm_email,
         user.id,
         Endpoint,
         :confirm_email,
         user.id,
-        to_string(user.info.confirmation_token)
+        to_string(user.confirmation_token)
       )
 
     html_body = """
       )
 
     html_body = """
@@ -98,55 +93,86 @@ defmodule Pleroma.Emails.UserEmail do
   Includes Mentions and New Followers data
   If there are no mentions (even when new followers exist), the function will return nil
   """
   Includes Mentions and New Followers data
   If there are no mentions (even when new followers exist), the function will return nil
   """
-  @spec digest_email(Pleroma.User.t()) :: Swoosh.Email.t() | nil
+  @spec digest_email(User.t()) :: Swoosh.Email.t() | nil
   def digest_email(user) do
   def digest_email(user) do
-    new_notifications =
-      Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at)
-      |> Enum.reduce(%{followers: [], mentions: []}, fn
-        %{activity: %{data: %{"type" => "Create"}, actor: actor}} = notification, acc ->
-          new_mention = %{data: notification, from: Pleroma.User.get_by_ap_id(actor)}
-          %{acc | mentions: [new_mention | acc.mentions]}
-
-        %{activity: %{data: %{"type" => "Follow"}, actor: actor}} = notification, acc ->
-          new_follower = %{data: notification, from: Pleroma.User.get_by_ap_id(actor)}
-          %{acc | followers: [new_follower | acc.followers]}
-
-        _, acc ->
-          acc
+    notifications = Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at)
+
+    mentions =
+      notifications
+      |> Enum.filter(&(&1.activity.data["type"] == "Create"))
+      |> Enum.map(fn notification ->
+        object = Pleroma.Object.normalize(notification.activity)
+        object = update_in(object.data["content"], &format_links/1)
+
+        %{
+          data: notification,
+          object: object,
+          from: User.get_by_ap_id(notification.activity.actor)
+        }
+      end)
+
+    followers =
+      notifications
+      |> Enum.filter(&(&1.activity.data["type"] == "Follow"))
+      |> Enum.map(fn notification ->
+        %{
+          data: notification,
+          object: Pleroma.Object.normalize(notification.activity),
+          from: User.get_by_ap_id(notification.activity.actor)
+        }
       end)
 
       end)
 
-    with [_ | _] = mentions <- new_notifications.mentions do
+    unless Enum.empty?(mentions) do
+      styling = Config.get([__MODULE__, :styling])
+      logo = Config.get([__MODULE__, :logo])
+
       html_data = %{
         instance: instance_name(),
         user: user,
         mentions: mentions,
       html_data = %{
         instance: instance_name(),
         user: user,
         mentions: mentions,
-        followers: new_notifications.followers,
-        unsubscribe_link: unsubscribe_url(user, "digest")
+        followers: followers,
+        unsubscribe_link: unsubscribe_url(user, "digest"),
+        styling: styling
       }
 
       }
 
+      logo_path =
+        if is_nil(logo) do
+          Path.join(:code.priv_dir(:pleroma), "static/static/logo.png")
+        else
+          Path.join(Config.get([:instance, :static_dir]), logo)
+        end
+
       new()
       |> to(recipient(user))
       |> from(sender())
       |> subject("Your digest from #{instance_name()}")
       new()
       |> to(recipient(user))
       |> from(sender())
       |> subject("Your digest from #{instance_name()}")
+      |> put_layout(false)
       |> render_body("digest.html", html_data)
       |> render_body("digest.html", html_data)
-    else
-      _ ->
-        nil
+      |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.png", type: :inline))
     end
   end
 
     end
   end
 
+  defp format_links(str) do
+    re = ~r/<a.+href=['"].*>/iU
+    %{link_color: color} = Config.get([__MODULE__, :styling])
+
+    Regex.replace(re, str, fn link ->
+      String.replace(link, "<a", "<a style=\"color: #{color};text-decoration: none;\"")
+    end)
+  end
+
   @doc """
   Generate unsubscribe link for given user and notifications type.
   The link contains JWT token with the data, and subscription can be modified without
   authorization.
   """
   @doc """
   Generate unsubscribe link for given user and notifications type.
   The link contains JWT token with the data, and subscription can be modified without
   authorization.
   """
-  @spec unsubscribe_url(Pleroma.User.t(), String.t()) :: String.t()
+  @spec unsubscribe_url(User.t(), String.t()) :: String.t()
   def unsubscribe_url(user, notifications_type) do
     token =
       %{"sub" => user.id, "act" => %{"unsubscribe" => notifications_type}, "exp" => false}
       |> Pleroma.JWT.generate_and_sign!()
       |> Base.encode64()
 
   def unsubscribe_url(user, notifications_type) do
     token =
       %{"sub" => user.id, "act" => %{"unsubscribe" => notifications_type}, "exp" => false}
       |> Pleroma.JWT.generate_and_sign!()
       |> Base.encode64()
 
-    Router.Helpers.subscription_url(Pleroma.Web.Endpoint, :unsubscribe, token)
+    Router.Helpers.subscription_url(Endpoint, :unsubscribe, token)
   end
 end
   end
 end