add emails
This commit is contained in:
		
							
								
								
									
										48
									
								
								lib/lokal/accounts/email.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/lokal/accounts/email.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| defmodule Lokal.Email do | ||||
|   @moduledoc """ | ||||
|   Emails that can be sent using Swoosh. | ||||
|  | ||||
|   You can find the base email templates at | ||||
|   `lib/Lokal_web/templates/layout/email.html.heex` for html emails and | ||||
|   `lib/Lokal_web/templates/layout/email.txt.heex` for text emails. | ||||
|   """ | ||||
|  | ||||
|   use Phoenix.Swoosh, view: LokalWeb.EmailView, layout: {LokalWeb.LayoutView, :email} | ||||
|   import LokalWeb.Gettext | ||||
|   alias Lokal.Accounts.User | ||||
|   alias LokalWeb.EmailView | ||||
|  | ||||
|   @typedoc """ | ||||
|   Represents an HTML and text body email that can be sent | ||||
|   """ | ||||
|   @type t() :: Swoosh.Email.t() | ||||
|  | ||||
|   @spec base_email(User.t(), String.t()) :: t() | ||||
|   defp base_email(%User{email: email}, subject) do | ||||
|     from = Application.get_env(:Lokal, Lokal.Mailer)[:email_from] || "noreply@localhost" | ||||
|     name = Application.get_env(:Lokal, Lokal.Mailer)[:email_name] | ||||
|     new() |> to(email) |> from({name, from}) |> subject(subject) | ||||
|   end | ||||
|  | ||||
|   @spec generate_email(key :: String.t(), User.t(), attrs :: map()) :: t() | ||||
|   def generate_email("welcome", user, %{"url" => url}) do | ||||
|     user | ||||
|     |> base_email(dgettext("emails", "Confirm your %{name} account", name: "Lokal")) | ||||
|     |> render_body("confirm_email.html", %{user: user, url: url}) | ||||
|     |> text_body(EmailView.render("confirm_email.txt", %{user: user, url: url})) | ||||
|   end | ||||
|  | ||||
|   def generate_email("reset_password", user, %{"url" => url}) do | ||||
|     user | ||||
|     |> base_email(dgettext("emails", "Reset your %{name} password", name: "Lokal")) | ||||
|     |> render_body("reset_password.html", %{user: user, url: url}) | ||||
|     |> text_body(EmailView.render("reset_password.txt", %{user: user, url: url})) | ||||
|   end | ||||
|  | ||||
|   def generate_email("update_email", user, %{"url" => url}) do | ||||
|     user | ||||
|     |> base_email(dgettext("emails", "Update your %{name} email", name: "Lokal")) | ||||
|     |> render_body("update_email.html", %{user: user, url: url}) | ||||
|     |> text_body(EmailView.render("update_email.txt", %{user: user, url: url})) | ||||
|   end | ||||
| end | ||||
							
								
								
									
										13
									
								
								lib/lokal/accounts/email_worker.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lib/lokal/accounts/email_worker.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| defmodule Lokal.EmailWorker do | ||||
|   @moduledoc """ | ||||
|   Oban worker that dispatches emails | ||||
|   """ | ||||
|  | ||||
|   use Oban.Worker, queue: :mailers, tags: ["email"] | ||||
|   alias Lokal.{Accounts, Email, Mailer} | ||||
|  | ||||
|   @impl Oban.Worker | ||||
|   def perform(%Oban.Job{args: %{"email" => email, "user_id" => user_id, "attrs" => attrs}}) do | ||||
|     Email.generate_email(email, user_id |> Accounts.get_user!(), attrs) |> Mailer.deliver() | ||||
|   end | ||||
| end | ||||
| @@ -1,7 +1,42 @@ | ||||
| defmodule Lokal.Mailer do | ||||
|   @moduledoc """ | ||||
|   Mailer, currently uses Swoosh | ||||
|   Mailer adapter for emails | ||||
|  | ||||
|   Since emails are loaded as Oban jobs, the `:attrs` map must be serializable to | ||||
|   json with Jason, which restricts the use of structs. | ||||
|   """ | ||||
|  | ||||
|   use Swoosh.Mailer, otp_app: :lokal | ||||
|   alias Lokal.{Accounts.User, EmailWorker} | ||||
|   alias Oban.Job | ||||
|  | ||||
|   @doc """ | ||||
|   Deliver instructions to confirm account. | ||||
|   """ | ||||
|   @spec deliver_confirmation_instructions(User.t(), String.t()) :: Job.t() | ||||
|   def deliver_confirmation_instructions(%User{id: user_id}, url) do | ||||
|     %{email: :welcome, user_id: user_id, attrs: %{url: url}} | ||||
|     |> EmailWorker.new() | ||||
|     |> Oban.insert!() | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Deliver instructions to reset a user password. | ||||
|   """ | ||||
|   @spec deliver_reset_password_instructions(User.t(), String.t()) :: Job.t() | ||||
|   def deliver_reset_password_instructions(%User{id: user_id}, url) do | ||||
|     %{email: :reset_password, user_id: user_id, attrs: %{url: url}} | ||||
|     |> EmailWorker.new() | ||||
|     |> Oban.insert!() | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
|   Deliver instructions to update a user email. | ||||
|   """ | ||||
|   @spec deliver_update_email_instructions(User.t(), String.t()) :: Job.t() | ||||
|   def deliver_update_email_instructions(%User{id: user_id}, url) do | ||||
|     %{email: :update_email, user_id: user_id, attrs: %{url: url}} | ||||
|     |> EmailWorker.new() | ||||
|     |> Oban.insert!() | ||||
|   end | ||||
| end | ||||
|   | ||||
							
								
								
									
										25
									
								
								lib/lokal_web/templates/email/confirm_email.html.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/lokal_web/templates/email/confirm_email.html.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;"> | ||||
|   <span style="margin-bottom: 0.75em; font-size: 1.5em;"> | ||||
|     <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|   </span> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <span style="margin-bottom: 1em; font-size: 1.25em;"> | ||||
|     <%= dgettext("emails", "Welcome to %{name}!", name: "Lokal") %> | ||||
|   </span> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", "You can confirm your account by visiting the URL below:") %> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <a style="margin: 1em; color: rgb(31, 31, 31);" href="<%= @url %>"><%= @url %></a> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", | ||||
|     "If you didn't create an account at %{name}, please ignore this.", | ||||
|     name: "Lokal") %> | ||||
| </div> | ||||
							
								
								
									
										12
									
								
								lib/lokal_web/templates/email/confirm_email.txt.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lib/lokal_web/templates/email/confirm_email.txt.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
|  | ||||
| <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|  | ||||
| <%= dgettext("emails", "Welcome to %{name}%!", name: "Lokal") %> | ||||
|  | ||||
| <%= dgettext("emails", "You can confirm your account by visiting the URL below:") %> | ||||
|  | ||||
| <%= @url %> | ||||
|  | ||||
| <%= dgettext("emails", | ||||
|   "If you didn't create an account at %{url}, please ignore this.", | ||||
|   url: Routes.live_url(Endpoint, PageLive)) %> | ||||
							
								
								
									
										19
									
								
								lib/lokal_web/templates/email/reset_password.html.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/lokal_web/templates/email/reset_password.html.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;"> | ||||
|   <span style="margin-bottom: 0.5em; font-size: 1.5em;"> | ||||
|     <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|   </span> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", "You can reset your password by visiting the URL below:") %> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <a style="margin: 1em; color: rgb(31, 31, 31);" href="<%= @url %>"><%= @url %></a> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", | ||||
|     "If you didn't request this change from %{name}, please ignore this.", | ||||
|     name: "Lokal") %> | ||||
| </div> | ||||
							
								
								
									
										10
									
								
								lib/lokal_web/templates/email/reset_password.txt.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/lokal_web/templates/email/reset_password.txt.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
|  | ||||
| <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|  | ||||
| <%= dgettext("emails", "You can reset your password by visiting the URL below:") %> | ||||
|  | ||||
| <%= @url %> | ||||
|  | ||||
| <%= dgettext("emails", | ||||
|   "If you didn't request this change from %{url}, please ignore this.", | ||||
|   url: Routes.live_url(Endpoint, PageLive)) %> | ||||
							
								
								
									
										19
									
								
								lib/lokal_web/templates/email/update_email.html.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/lokal_web/templates/email/update_email.html.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;"> | ||||
|   <span style="margin-bottom: 0.5em; font-size: 1.5em;"> | ||||
|     <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|   </span> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", "You can change your email by visiting the URL below:") %> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <a style="margin: 1em; color: rgb(31, 31, 31);" href="<%= @url %>"><%= @url %></a> | ||||
|  | ||||
|   <br/> | ||||
|  | ||||
|   <%= dgettext("emails", | ||||
|     "If you didn't request this change from %{name}, please ignore this.", | ||||
|     name: "Lokal") %> | ||||
| </div> | ||||
							
								
								
									
										10
									
								
								lib/lokal_web/templates/email/update_email.txt.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/lokal_web/templates/email/update_email.txt.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
|  | ||||
| <%= dgettext("emails", "Hi %{email},", email: @user.email) %> | ||||
|  | ||||
| <%= dgettext("emails", "You can change your email by visiting the URL below:") %> | ||||
|  | ||||
| <%= @url %> | ||||
|  | ||||
| <%= dgettext("emails", | ||||
|   "If you didn't request this change from %{url}, please ignore this.", | ||||
|   url: Routes.live_url(Endpoint, PageLive)) %> | ||||
							
								
								
									
										24
									
								
								lib/lokal_web/templates/layout/email.html.heex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								lib/lokal_web/templates/layout/email.html.heex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <title> | ||||
|       <%= @email.subject %> | ||||
|     </title> | ||||
|   </head> | ||||
|   <body | ||||
|     style="padding: 2em; color: rgb(31, 31, 31); background-color: rgb(220, 220, 228); font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; text-align: center;" | ||||
|   > | ||||
|     <%= @inner_content %> | ||||
|  | ||||
|     <hr | ||||
|       style="margin: 2em auto; border-width: 1px; border-color: rgb(212, 212, 216); width: 100%; max-width: 42rem;" | ||||
|     /> | ||||
|  | ||||
|     <a style="color: rgb(31, 31, 31);" href={Routes.live_url(Endpoint, PageLive)}> | ||||
|       <%= dgettext( | ||||
|         "emails", | ||||
|         "This email was sent from %{name}, the self-hosted firearm tracker website.", | ||||
|         name: "Lokal" | ||||
|       ) %> | ||||
|     </a> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										12
									
								
								lib/lokal_web/templates/layout/email.txt.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lib/lokal_web/templates/layout/email.txt.eex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <%= @email.subject %> | ||||
|  | ||||
| ==================== | ||||
|  | ||||
| <%= @inner_content %> | ||||
|  | ||||
| ===================== | ||||
|  | ||||
| <%= dgettext("emails", | ||||
|   "This email was sent from %{name} at %{url}, the self-hosted firearm tracker website.", | ||||
|   name: "Lokal", | ||||
|   url: Routes.live_url(Endpoint, PageLive)) %> | ||||
							
								
								
									
										1
									
								
								lib/lokal_web/templates/layout/empty.html.heex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/lokal_web/templates/layout/empty.html.heex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <%= @inner_content %> | ||||
							
								
								
									
										8
									
								
								lib/lokal_web/views/email_view.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/lokal_web/views/email_view.ex
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| defmodule LokalWeb.EmailView do | ||||
|   @moduledoc """ | ||||
|   A view for email-related helper functions | ||||
|   """ | ||||
|   alias LokalWeb.{Endpoint, PageLive} | ||||
|  | ||||
|   use LokalWeb, :view | ||||
| end | ||||
		Reference in New Issue
	
	Block a user