defmodule AshHqWeb.Pages.ResetPassword do
@moduledoc "Log in page"
use Surface.LiveComponent
alias Surface.Components.{Form, LiveRedirect}
alias Surface.Components.Form.{
ErrorTag,
Field,
Label,
PasswordInput,
Submit,
TextInput
}
alias AshHqWeb.Router.Helpers, as: Routes
prop params, :map
data error, :boolean, default: false
data password_reset_form, :any
def render(assigns) do
~F"""
{#if @password_reset_form}
{#else}
Remember your password?
{/if}
"""
end
def update(assigns, socket) do
{:ok, socket |> assign(assigns) |> assign_reset_form()}
end
defp assign_reset_form(socket) do
case socket.assigns[:params]["token"] do
nil ->
assign(socket, password_reset_form: nil)
token ->
user =
AshHq.Accounts.User
|> Ash.Query.for_read(
:with_verified_email_token,
%{token: token, context: "reset_password"},
authorize?: false
)
|> AshHq.Accounts.read_one!()
if user do
assign(
socket,
:password_reset_form,
AshPhoenix.Form.for_update(user, :reset_password,
as: "reset_password",
api: AshHq.Accounts
)
)
else
socket
|> put_flash(:error, "Reset password link is invalid or it has expired.")
|> assign(password_reset_form: nil)
end
end
end
@impl true
def handle_event("reset_password", %{"reset_password" => params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.password_reset_form,
params: params
) do
{:ok, _result} ->
{:noreply,
socket
|> put_flash(:info, "Successfully reset password.")
|> push_redirect(to: Routes.app_view_path(AshHqWeb.Endpoint, :log_in))}
{:error, form} ->
{:noreply, assign(socket, password_reset_form: form)}
end
end
@impl true
def handle_event(
"request_password_reset",
%{"request_password_reset" => %{"email" => email}},
socket
) do
with {:ok, user} <-
AshHq.Accounts.get(AshHq.Accounts.User, [email: String.trim(email)], authorize?: false) do
user
|> Ash.Changeset.for_update(
:deliver_user_reset_password_instructions,
%{reset_password_url_fun: &Routes.app_view_url(AshHqWeb.Endpoint, :reset_password, &1)},
authorize?: false
)
|> AshHq.Accounts.update!()
end
{:noreply,
socket
|> put_flash(
:info,
"If your email is in our system, you will receive instructions to reset your password shortly."
)
|> push_redirect(to: Routes.app_view_path(AshHqWeb.Endpoint, :reset_password))}
end
end