Merge branch 'tesla-get-to-pleroma' into 'develop'
[akkoma] / lib / pleroma / emails / user_email.ex
index bf6b811b1c47515ad53baa4249dff71605f6f6af..806a61fd226f85b2e168bfcdf873322911df2c53 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,21 +7,26 @@ 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 sender do
-    email = Keyword.get(instance_config(), :notify_email, instance_config()[:email])
-    {instance_name(), email}
-  end
+  import Pleroma.Config.Helpers, only: [instance_name: 0, sender: 0]
 
   defp recipient(email, nil), do: email
   defp recipient(email, name), do: {name, email}
 
   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)
+
+  @spec welcome(User.t(), map()) :: Swoosh.Email.t()
+  def welcome(user, opts \\ %{}) do
+    new()
+    |> to(recipient(user))
+    |> from(Map.get(opts, :sender, sender()))
+    |> subject(Map.get(opts, :subject, "Welcome to #{instance_name()}!"))
+    |> html_body(Map.get(opts, :html, "Welcome to #{instance_name()}!"))
+    |> text_body(Map.get(opts, :text, "Welcome to #{instance_name()}!"))
+  end
 
   def password_reset_email(user, token) when is_binary(token) do
     password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
 
   def password_reset_email(user, token) when is_binary(token) do
     password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
@@ -72,7 +77,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 = """
@@ -93,50 +98,63 @@ 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} = activity} = notification,
-        acc ->
-          new_mention = %{
-            data: notification,
-            object: Pleroma.Object.normalize(activity),
-            from: Pleroma.User.get_by_ap_id(actor)
-          }
+    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)
 
 
-          %{acc | mentions: [new_mention | acc.mentions]}
+        if not is_nil(object) do
+          object = update_in(object.data["content"], &format_links/1)
 
 
-        %{activity: %{data: %{"type" => "Follow"}, actor: actor} = activity} = notification,
-        acc ->
-          new_follower = %{
+          %{
             data: notification,
             data: notification,
-            object: Pleroma.Object.normalize(activity),
-            from: Pleroma.User.get_by_ap_id(actor)
+            object: object,
+            from: User.get_by_ap_id(notification.activity.actor)
           }
           }
+        end
+      end)
+      |> Enum.filter(& &1)
 
 
-          %{acc | followers: [new_follower | acc.followers]}
+    followers =
+      notifications
+      |> Enum.filter(&(&1.activity.data["type"] == "Follow"))
+      |> Enum.map(fn notification ->
+        from = User.get_by_ap_id(notification.activity.actor)
 
 
-        _, acc ->
-          acc
+        if not is_nil(from) do
+          %{
+            data: notification,
+            object: Pleroma.Object.normalize(notification.activity),
+            from: User.get_by_ap_id(notification.activity.actor)
+          }
+        end
       end)
       end)
+      |> Enum.filter(& &1)
 
 
-    with [_ | _] = mentions <- new_notifications.mentions do
-      mentions =
-        Enum.map(mentions, fn mention ->
-          update_in(mention.object.data["content"], &format_links/1)
-        end)
+    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 = Path.join(:code.priv_dir(:pleroma), "static/static/logo.png")
+      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))
 
       new()
       |> to(recipient(user))
@@ -145,17 +163,15 @@ defmodule Pleroma.Emails.UserEmail do
       |> put_layout(false)
       |> render_body("digest.html", html_data)
       |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.png", type: :inline))
       |> put_layout(false)
       |> render_body("digest.html", html_data)
       |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.png", type: :inline))
-    else
-      _ ->
-        nil
     end
   end
 
   defp format_links(str) do
     re = ~r/<a.+href=['"].*>/iU
     end
   end
 
   defp format_links(str) do
     re = ~r/<a.+href=['"].*>/iU
+    %{link_color: color} = Config.get([__MODULE__, :styling])
 
 
-    String.replace(str, re, fn link ->
-      String.replace(link, "<a", "<a style=\"color: #d8a070;text-decoration: none;\"")
+    Regex.replace(re, str, fn link ->
+      String.replace(link, "<a", "<a style=\"color: #{color};text-decoration: none;\"")
     end)
   end
 
     end)
   end
 
@@ -164,13 +180,39 @@ defmodule Pleroma.Emails.UserEmail do
   The link contains JWT token with the data, and subscription can be modified without
   authorization.
   """
   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
+
+  def backup_is_ready_email(backup, admin_user_id \\ nil) do
+    %{user: user} = Pleroma.Repo.preload(backup, :user)
+    download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup)
+
+    html_body =
+      if is_nil(admin_user_id) do
+        """
+        <p>You requested a full backup of your Pleroma account. It's ready for download:</p>
+        <p><a href="#{download_url}">#{download_url}</a></p>
+        """
+      else
+        admin = Pleroma.Repo.get(User, admin_user_id)
+
+        """
+        <p>Admin @#{admin.nickname} requested a full backup of your Pleroma account. It's ready for download:</p>
+        <p><a href="#{download_url}">#{download_url}</a></p>
+        """
+      end
+
+    new()
+    |> to(recipient(user))
+    |> from(sender())
+    |> subject("Your account archive is ready")
+    |> html_body(html_body)
   end
 end
   end
 end