defmodule PlausibleWeb.Live.ResetPasswordForm do
@moduledoc """
LiveView for password reset form.
"""
use PlausibleWeb, :live_view
alias Plausible.Auth
alias Plausible.Repo
def mount(_params, %{"email" => email}, socket) do
socket =
assign_new(socket, :user, fn ->
Repo.get_by!(Auth.User, email: email)
end)
changeset = Auth.User.settings_changeset(socket.assigns.user)
{:ok,
assign(socket,
form: to_form(changeset),
password_strength: Auth.User.password_strength(changeset),
trigger_submit: false
)}
end
def render(assigns) do
~H"""
<.form
:let={f}
for={@form}
method="post"
phx-change="validate"
phx-submit="set"
phx-trigger-action={@trigger_submit}
class="flex flex-col gap-y-6"
>
<.password_input_with_strength
field={f[:password]}
strength={@password_strength}
phx-debounce={200}
mt?={false}
/>
<.password_length_hint minimum={12} field={f[:password]} hide_when_used?={true} />
<.button id="set" type="submit" class="w-full" mt?={false}>
Update password
<.styled_link href="/login">Back to sign in
"""
end
def handle_event("validate", %{"user" => %{"password" => password}}, socket) do
changeset =
socket.assigns.user
|> Auth.User.set_password(password)
|> Map.put(:action, :validate)
password_strength = Auth.User.password_strength(changeset)
{:noreply, assign(socket, form: to_form(changeset), password_strength: password_strength)}
end
def handle_event("set", %{"user" => %{"password" => password}}, socket) do
result =
Repo.transaction(fn ->
changeset = Auth.User.set_password(socket.assigns.user, password)
case Repo.update(changeset) do
{:ok, user} ->
Auth.TOTP.reset_token(user)
{:error, changeset} ->
Repo.rollback(changeset)
end
end)
case result do
{:ok, user} ->
Auth.UserSessions.revoke_all(user)
{:noreply, assign(socket, trigger_submit: true)}
{:error, changeset} ->
{:noreply,
assign(socket,
form: to_form(Map.put(changeset, :action, :validate))
)}
end
end
end