Separate login and registration email guidance
Some checks are pending
Quality / full-local-gates (push) Waiting to run

This commit is contained in:
SimpleTest 2026-07-21 23:38:42 +03:00
parent 5881dd62f5
commit 5923608f07
5 changed files with 100 additions and 53 deletions

View File

@ -14,8 +14,9 @@ defmodule WhoNeedHelpWeb.UserRegistrationController do
render_registration(conn, changeset)
end
def sent(conn, _params) do
render(conn, :sent)
def sent(conn, params) do
email_flow = if params["flow"] == "register", do: "register", else: "login"
render(conn, :sent, email_flow: email_flow)
end
def create(conn, %{"user" => user_params}) when is_map(user_params) do
@ -112,7 +113,7 @@ defmodule WhoNeedHelpWeb.UserRegistrationController do
"If this address can be registered or signed in, login instructions will arrive shortly."
)
)
|> redirect(to: ~p"/users/check-email")
|> redirect(to: ~p"/users/check-email?flow=register")
end
defp unique_email_error?(%Ecto.Changeset{} = changeset) do

View File

@ -1,47 +1,83 @@
<.header>
{gettext("Check your email")}
<:subtitle>
{gettext("If the address can be used, a secure link will arrive shortly.")}
</:subtitle>
</.header>
<div class="mx-auto mt-8 max-w-xl rounded-3xl border border-base-300 bg-base-100 p-6 shadow-sm sm:p-8">
<div role="status" class="alert alert-success items-start">
<.icon name="hero-check-circle" class="mt-0.5 size-6 shrink-0" />
<div>
<h2 class="font-bold">{gettext("Request accepted")}</h2>
<p class="mt-1 text-sm">
{gettext("The site processed your request. Follow the email instructions if they arrive.")}
</p>
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-xl space-y-6">
<div class="text-center">
<.header>
{if @email_flow == "register",
do: gettext("Check your email to finish registration"),
else: gettext("Sign-in request processed")}
<:subtitle>
<%= if @email_flow == "register" do %>
{gettext("Use the newest confirmation link if it arrives.")}
<% else %>
{gettext("Signing in does not create a new account.")}
<% end %>
</:subtitle>
</.header>
</div>
</div>
<div class="mt-6 flex gap-4">
<div class="grid size-11 shrink-0 place-items-center rounded-full bg-success/15 text-success">
<.icon name="hero-envelope" class="size-6" />
</div>
<div>
<h2 class="text-lg font-bold">{gettext("Open the newest Who Need Help email")}</h2>
<p class="mt-2 text-sm leading-6 text-base-content/70">
<div class="rounded-3xl border border-base-300 bg-base-100 p-6 shadow-sm sm:p-8">
<div role="status" class="alert alert-success items-start">
<.icon name="hero-check-circle" class="mt-0.5 size-6 shrink-0" />
<div>
<h2 class="font-bold">
{if @email_flow == "register",
do: gettext("Registration request accepted"),
else: gettext("Sign-in request accepted")}
</h2>
<p class="mt-1 text-sm">
<%= if @email_flow == "register" do %>
{gettext("The site processed your registration request.")}
<% else %>
{gettext(
"If this email belongs to an existing account, a secure sign-in link will arrive shortly."
)}
<% end %>
</p>
</div>
</div>
<div class="mt-6 flex gap-4">
<div class="grid size-11 shrink-0 place-items-center rounded-full bg-success/15 text-success">
<.icon name="hero-envelope" class="size-6" />
</div>
<div>
<h2 class="text-lg font-bold">
<%= if @email_flow == "register" do %>
{gettext("Open the newest Who Need Help email")}
<% else %>
{gettext("Already registered? Check your email")}
<% end %>
</h2>
<p class="mt-2 text-sm leading-6 text-base-content/70">
<%= if @email_flow == "register" do %>
{gettext(
"Use the confirmation link in the message. You do not need to enter your address again on this site."
)}
<% else %>
{gettext(
"For privacy, this page cannot reveal whether an account exists. If you are new to Who Need Help, choose Register instead."
)}
<% end %>
</p>
</div>
</div>
<div class="mt-6 rounded-2xl bg-base-200 p-4 text-sm leading-6 text-base-content/70">
{gettext(
"If a message arrives, use the secure link in it. You do not need to enter your address again on this site."
"If the message is not in your inbox after a minute, check Spam. Older secure links may have been replaced by the newest one."
)}
</p>
</div>
<div class="mt-6 grid gap-3 sm:grid-cols-2">
<.link navigate={~p"/users/log-in"} class="btn btn-primary">
{gettext("Back to log in")}
</.link>
<.link navigate={~p"/users/register"} class="btn btn-outline">
{if @email_flow == "register",
do: gettext("Use another email"),
else: gettext("Register instead")}
</.link>
</div>
</div>
</div>
<div class="mt-6 rounded-2xl bg-base-200 p-4 text-sm leading-6 text-base-content/70">
{gettext(
"If the message is not in your inbox after a minute, check Spam. Older confirmation links may have been replaced by the newest one."
)}
</div>
<div class="mt-6 grid gap-3 sm:grid-cols-2">
<.link navigate={~p"/users/log-in"} class="btn btn-primary">
{gettext("Back to log in")}
</.link>
<.link navigate={~p"/users/register"} class="btn btn-outline">
{gettext("Register instead")}
</.link>
</div>
</div>
</Layouts.app>

View File

@ -100,7 +100,7 @@ defmodule WhoNeedHelpWeb.UserSessionController do
conn
|> put_flash(:info, info)
|> redirect(to: ~p"/users/check-email")
|> redirect(to: ~p"/users/check-email?flow=login")
{:error, :rate_limited} ->
conn

View File

@ -30,18 +30,28 @@ defmodule WhoNeedHelpWeb.UserRegistrationControllerTest do
describe "GET /users/check-email" do
test "explains that the confirmation continues from the email", %{conn: conn} do
conn = get(conn, ~p"/users/check-email")
conn = get(conn, ~p"/users/check-email?flow=login")
response = html_response(conn, 200)
assert get_resp_header(conn, "cache-control") == ["no-store"]
assert response =~ "Check your email"
assert response =~ "Request accepted"
assert response =~ "Sign-in request processed"
assert response =~ "Signing in does not create a new account"
assert response =~ "Sign-in request accepted"
assert response =~ "cannot reveal whether an account exists"
assert response =~ ~s(role="status")
assert response =~ "You do not need to enter your address again"
assert response =~ "check Spam"
assert response =~ ~p"/users/log-in"
assert response =~ ~p"/users/register"
end
test "renders registration-specific guidance", %{conn: conn} do
response = conn |> get(~p"/users/check-email?flow=register") |> html_response(200)
assert response =~ "Check your email to finish registration"
assert response =~ "Registration request accepted"
assert response =~ "You do not need to enter your address again"
refute response =~ "cannot reveal whether an account exists"
end
end
describe "POST /users/register" do
@ -77,7 +87,7 @@ defmodule WhoNeedHelpWeb.UserRegistrationControllerTest do
})
refute get_session(conn, :user_token)
assert redirected_to(conn) == ~p"/users/check-email"
assert redirected_to(conn) == ~p"/users/check-email?flow=register"
assert conn.assigns.flash["info"] =~
"If this address can be registered or signed in, login instructions will arrive shortly."
@ -91,7 +101,7 @@ defmodule WhoNeedHelpWeb.UserRegistrationControllerTest do
existing_conn = post(conn, ~p"/users/register", params)
assert redirected_to(existing_conn) == ~p"/users/check-email"
assert redirected_to(existing_conn) == ~p"/users/check-email?flow=register"
assert existing_conn.assigns.flash["info"] ==
"If this address can be registered or signed in, login instructions will arrive shortly."

View File

@ -179,7 +179,7 @@ defmodule WhoNeedHelpWeb.UserSessionControllerTest do
})
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "If your email is in our system"
assert redirected_to(conn) == ~p"/users/check-email"
assert redirected_to(conn) == ~p"/users/check-email?flow=login"
assert WhoNeedHelp.Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "login"
assert_email_sent(fn email ->
@ -199,7 +199,7 @@ defmodule WhoNeedHelpWeb.UserSessionControllerTest do
"user" => %{"email" => user.email}
})
assert redirected_to(conn) == ~p"/users/check-email"
assert redirected_to(conn) == ~p"/users/check-email?flow=login"
refute WhoNeedHelp.Repo.get_by(Accounts.UserToken, user_id: user.id)
end