@@ -281,8 +286,18 @@ defmodule Web.SignUp do
)
case Domain.Repo.transaction(multi) do
- {:ok, result} ->
- socket = assign(socket, account: result.account)
+ {:ok, %{account: account, identity: identity}} ->
+ {:ok, _} =
+ Web.Mailer.AuthEmail.sign_up_link_email(
+ account,
+ identity,
+ identity.provider_virtual_state.sign_in_token,
+ socket.assigns.user_agent,
+ socket.assigns.real_ip
+ )
+ |> Web.Mailer.deliver()
+
+ socket = assign(socket, account: account)
{:noreply, socket}
{:error, :account, err_changeset, _effects_so_far} ->
diff --git a/elixir/apps/web/lib/web/mailer/auth_email.ex b/elixir/apps/web/lib/web/mailer/auth_email.ex
index 9c1fb06c3..118622d54 100644
--- a/elixir/apps/web/lib/web/mailer/auth_email.ex
+++ b/elixir/apps/web/lib/web/mailer/auth_email.ex
@@ -6,6 +6,43 @@ defmodule Web.Mailer.AuthEmail do
embed_templates "auth_email/*.html", suffix: "_html"
embed_templates "auth_email/*.text", suffix: "_text"
+ def sign_up_link_email(
+ %Domain.Accounts.Account{} = account,
+ %Domain.Auth.Identity{} = identity,
+ email_secret,
+ user_agent,
+ remote_ip
+ ) do
+ params =
+ %{
+ identity_id: identity.id,
+ secret: email_secret
+ }
+
+ sign_in_url =
+ url(
+ ~p"/#{account}/sign_in/providers/#{identity.provider_id}/verify_sign_in_token?#{params}"
+ )
+
+ sign_in_form_url = url(~p"/#{account}")
+
+ default_email()
+ |> subject("Welcome to Firezone")
+ |> to(identity.provider_identifier)
+ |> render_body(__MODULE__, :sign_up_link,
+ account: account,
+ sign_in_token_created_at:
+ Cldr.DateTime.to_string!(identity.provider_state["sign_in_token_created_at"], Web.CLDR,
+ format: :short
+ ) <> " UTC",
+ secret: email_secret,
+ sign_in_url: sign_in_url,
+ sign_in_form_url: sign_in_form_url,
+ user_agent: user_agent,
+ remote_ip: "#{:inet.ntoa(remote_ip)}"
+ )
+ end
+
def sign_in_link_email(
%Domain.Auth.Identity{} = identity,
email_secret,
@@ -19,7 +56,7 @@ defmodule Web.Mailer.AuthEmail do
secret: email_secret
})
- sign_in_link =
+ sign_in_url =
url(
~p"/#{identity.account}/sign_in/providers/#{identity.provider_id}/verify_sign_in_token?#{params}"
)
@@ -35,7 +72,7 @@ defmodule Web.Mailer.AuthEmail do
format: :short
) <> " UTC",
secret: email_secret,
- link: sign_in_link,
+ sign_in_url: sign_in_url,
user_agent: user_agent,
remote_ip: "#{:inet.ntoa(remote_ip)}"
)
diff --git a/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.html.heex b/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.html.heex
index ab50409a3..2afcf0e84 100644
--- a/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.html.heex
+++ b/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.html.heex
@@ -6,13 +6,13 @@
- Here is the magic sign-in link
+ Here is the magic sign-in link
you requested to sign in to "<%= @account.name %>".
It is valid for 15 minutes.
- If the link didn't work, please copy this link and open it in your browser. <%= @link %>
+ If the link didn't work, please copy this link and open it in your browser: <%= @sign_in_url %>
diff --git a/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.text.heex b/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.text.heex
index 455a367ac..49768ff0c 100644
--- a/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.text.heex
+++ b/elixir/apps/web/lib/web/mailer/auth_email/sign_in_link.text.heex
@@ -2,7 +2,7 @@ Dear Firezone user,
<%= if is_nil(@client_platform) do %>
Here is the magic sign-in link you requested to sign in to "<%= @account.name %>":
-<%= @link %>
+<%= @sign_in_url %>
Please copy this link and open it in your browser. It is valid for 15 minutes.
<% else %>
diff --git a/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.html.heex b/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.html.heex
new file mode 100644
index 000000000..e6d58923f
--- /dev/null
+++ b/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.html.heex
@@ -0,0 +1,36 @@
+
Thank you for signing up for Firezone!
+
+
+
+ Here is the sign-in link
+ to access your account "<%= @account.name %>".
+ It is valid for 15 minutes.
+
+
+
+ If the link didn't work, please copy this link and open it in your browser. <%= @sign_in_url %>
+
+
+
+
+
In future you can always access the sign in form at the following URL:
+
+
+ <%= @sign_in_form_url %>
+
+
+
+
+ If you did not request this action and have received this email in error, you can safely ignore
+ and discard this email. However, if you continue to receive multiple unsolicited emails of this nature,
+ we strongly recommend contacting your system administrator to report the issue.
+
+
+
+ Request details:
+
Time: <%= @sign_in_token_created_at %>
+
IP address: <%= @remote_ip %>
+
User Agent: <%= @user_agent %>
+
Account ID: <%= @account.id %>
+
Account Slug: <%= @account.slug %>
+
diff --git a/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.text.heex b/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.text.heex
new file mode 100644
index 000000000..77f73cee0
--- /dev/null
+++ b/elixir/apps/web/lib/web/mailer/auth_email/sign_up_link.text.heex
@@ -0,0 +1,23 @@
+Thank you for signing up for Firezone!
+
+
+Here is the sign-in link to access your account "<%= @account.name %>":
+
+<%= @sign_in_url %>
+
+Please copy this link and open it in your browser. It is valid for 15 minutes.
+
+In future you can always access the sign in form at the following URL:
+
+<%= @sign_in_form_url %>
+
+If you did not request this action and have received this email in error, you can safely ignore
+and discard this email. However, if you continue to receive multiple unsolicited emails of this nature,
+we strongly recommend contacting your system administrator to report the issue.
+
+Request details:
+ Time: <%= @sign_in_token_created_at %>
+ IP address: <%= @remote_ip %>
+ User Agent: <%= @user_agent %>
+ Account ID: <%= @account.id %>
+ Account Slug: <%= @account.slug %>
diff --git a/elixir/apps/web/test/web/live/sign_up/sign_up_test.exs b/elixir/apps/web/test/web/live/sign_up/sign_up_test.exs
index 18dba4897..cf99f52cc 100644
--- a/elixir/apps/web/test/web/live/sign_up/sign_up_test.exs
+++ b/elixir/apps/web/test/web/live/sign_up/sign_up_test.exs
@@ -1,7 +1,7 @@
defmodule Web.Live.SignUpTest do
use Web.ConnCase, async: true
- test "renders signup form", %{conn: conn} do
+ test "renders sign up form", %{conn: conn} do
{:ok, lv, _html} = live(conn, ~p"/sign_up")
form = form(lv, "form")
@@ -17,7 +17,7 @@ defmodule Web.Live.SignUpTest do
]
end
- test "creates new account", %{conn: conn} do
+ test "creates new account and sends a welcome email", %{conn: conn} do
Domain.Config.put_system_env_override(:outbound_email_adapter, Swoosh.Adapters.Postmark)
account_name = "FooBar"
@@ -37,6 +37,33 @@ defmodule Web.Live.SignUpTest do
assert html =~ "Your account has been created!"
assert html =~ account_name
+
+ account = Repo.one(Domain.Accounts.Account)
+ assert account.name == account_name
+
+ provider = Repo.one(Domain.Auth.Provider)
+ assert provider.account_id == account.id
+
+ actor = Repo.one(Domain.Actors.Actor)
+ assert actor.account_id == account.id
+ assert actor.name == "John Doe"
+
+ identity = Repo.one(Domain.Auth.Identity)
+ assert identity.account_id == account.id
+ assert identity.provider_identifier == "jdoe@test.local"
+
+ assert_email_sent(fn email ->
+ assert email.subject == "Welcome to Firezone"
+
+ verify_sign_in_token_path =
+ ~p"/#{account.id}/sign_in/providers/#{provider.id}/verify_sign_in_token"
+
+ assert email.text_body =~ "#{verify_sign_in_token_path}"
+ assert email.text_body =~ "identity_id=#{identity.id}"
+ assert email.text_body =~ "secret="
+
+ assert email.text_body =~ url(~p"/#{account.id}")
+ end)
end
test "renders changeset errors on input change", %{conn: conn} do
@@ -79,7 +106,7 @@ defmodule Web.Live.SignUpTest do
}
end
- test "renders signup disabled message", %{conn: conn} do
+ test "renders sign up disabled message", %{conn: conn} do
Domain.Config.feature_flag_override(:signups, false)
{:ok, _lv, html} = live(conn, ~p"/sign_up")