analytics/lib/plausible_web/live/reset_password_form.ex

99 lines
3.0 KiB
Elixir
Raw Normal View History

Implement better user password validation (#3344) * Add zxcvbn dependency * Change password length range requirement from 6-64 to 12-128 * Reimplement register form in LV * Implement server-side check for password strength * Add rudimentary strength meter * Make password input with strength a separate component and improve it * Fix existing tests to provide strong enough password * Apply formatting * Replace existing registration form with new one * Hide built-in label in `.input` component when none provided * Crop password to first 32 chars for analysis by zxcvbn * Add tests for new form components * Integrate hCaptcha into LV * Fix existing AuthController tests * Add tests for Live.RegisterForm * Hide strength meter when password input is empty * Randomize client IP in headers during tests to avoid hitting rate limit * Apply auxilliary formatting fixes to AuthController * Integrate registration from invitation into LV registration logic * Fix existing password set and reset forms * Make `password_length_hint` component more customizable * Optimize `Auth.User.set_password/2` * Remove unnecessary attribute from registration form * Move password set and reset forms to LV * Add tests for SetPasswordForm LV component * Add tests for password checks in `Auth.User` * Document code a bit * Implement simpler approach to hCaptcha integration * Update CHANGELOG.md * Improve consistency of color scheme * Introduce debounce across all text inputs in registration and password forms * Fix email input background in register form * Ensure only single error is rendered for empty password confirmation case * Remove `/password` form entirely in favor of preferred password reset * Remove unnecessary `router` option from `live_render` calls * Make expensive assigns in LV with `assign_new` (h/t @aerosol) * Accept passwords longer than 32 bytes uniformly as very strong * Avoid displaying blank error side by side with weak password error * Make register actions handle errors gracefully * Render only a single piece of feedback to reduce noise * Make register and password reset forms pw manager friendly (h/t @cnkk) * Move registration forms to live routes * Delete no longer used deadviews * Adjust registration form in accordance to changes in #3290 * Reintroduce dogfood page path for invitation form from #3290 * Use alternative approach to submitting plausible metrics from LV form * Rename metrics events and extend tests to account for them
2023-09-25 11:27:29 +03:00
defmodule PlausibleWeb.Live.ResetPasswordForm do
@moduledoc """
LiveView for password reset form.
"""
use Phoenix.LiveView
use Phoenix.HTML
import PlausibleWeb.Live.Components.Form
alias Plausible.Auth
alias Plausible.Repo
def mount(_params, %{"email" => email}, socket) do
Implement better user password validation (#3344) * Add zxcvbn dependency * Change password length range requirement from 6-64 to 12-128 * Reimplement register form in LV * Implement server-side check for password strength * Add rudimentary strength meter * Make password input with strength a separate component and improve it * Fix existing tests to provide strong enough password * Apply formatting * Replace existing registration form with new one * Hide built-in label in `.input` component when none provided * Crop password to first 32 chars for analysis by zxcvbn * Add tests for new form components * Integrate hCaptcha into LV * Fix existing AuthController tests * Add tests for Live.RegisterForm * Hide strength meter when password input is empty * Randomize client IP in headers during tests to avoid hitting rate limit * Apply auxilliary formatting fixes to AuthController * Integrate registration from invitation into LV registration logic * Fix existing password set and reset forms * Make `password_length_hint` component more customizable * Optimize `Auth.User.set_password/2` * Remove unnecessary attribute from registration form * Move password set and reset forms to LV * Add tests for SetPasswordForm LV component * Add tests for password checks in `Auth.User` * Document code a bit * Implement simpler approach to hCaptcha integration * Update CHANGELOG.md * Improve consistency of color scheme * Introduce debounce across all text inputs in registration and password forms * Fix email input background in register form * Ensure only single error is rendered for empty password confirmation case * Remove `/password` form entirely in favor of preferred password reset * Remove unnecessary `router` option from `live_render` calls * Make expensive assigns in LV with `assign_new` (h/t @aerosol) * Accept passwords longer than 32 bytes uniformly as very strong * Avoid displaying blank error side by side with weak password error * Make register actions handle errors gracefully * Render only a single piece of feedback to reduce noise * Make register and password reset forms pw manager friendly (h/t @cnkk) * Move registration forms to live routes * Delete no longer used deadviews * Adjust registration form in accordance to changes in #3290 * Reintroduce dogfood page path for invitation form from #3290 * Use alternative approach to submitting plausible metrics from LV form * Rename metrics events and extend tests to account for them
2023-09-25 11:27:29 +03:00
socket =
assign_new(socket, :user, fn ->
Repo.get_by!(Auth.User, email: email)
end)
changeset = Auth.User.settings_changeset(socket.assigns.user)
Implement better user password validation (#3344) * Add zxcvbn dependency * Change password length range requirement from 6-64 to 12-128 * Reimplement register form in LV * Implement server-side check for password strength * Add rudimentary strength meter * Make password input with strength a separate component and improve it * Fix existing tests to provide strong enough password * Apply formatting * Replace existing registration form with new one * Hide built-in label in `.input` component when none provided * Crop password to first 32 chars for analysis by zxcvbn * Add tests for new form components * Integrate hCaptcha into LV * Fix existing AuthController tests * Add tests for Live.RegisterForm * Hide strength meter when password input is empty * Randomize client IP in headers during tests to avoid hitting rate limit * Apply auxilliary formatting fixes to AuthController * Integrate registration from invitation into LV registration logic * Fix existing password set and reset forms * Make `password_length_hint` component more customizable * Optimize `Auth.User.set_password/2` * Remove unnecessary attribute from registration form * Move password set and reset forms to LV * Add tests for SetPasswordForm LV component * Add tests for password checks in `Auth.User` * Document code a bit * Implement simpler approach to hCaptcha integration * Update CHANGELOG.md * Improve consistency of color scheme * Introduce debounce across all text inputs in registration and password forms * Fix email input background in register form * Ensure only single error is rendered for empty password confirmation case * Remove `/password` form entirely in favor of preferred password reset * Remove unnecessary `router` option from `live_render` calls * Make expensive assigns in LV with `assign_new` (h/t @aerosol) * Accept passwords longer than 32 bytes uniformly as very strong * Avoid displaying blank error side by side with weak password error * Make register actions handle errors gracefully * Render only a single piece of feedback to reduce noise * Make register and password reset forms pw manager friendly (h/t @cnkk) * Move registration forms to live routes * Delete no longer used deadviews * Adjust registration form in accordance to changes in #3290 * Reintroduce dogfood page path for invitation form from #3290 * Use alternative approach to submitting plausible metrics from LV form * Rename metrics events and extend tests to account for them
2023-09-25 11:27:29 +03:00
{: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="bg-white dark:bg-gray-800 max-w-md w-full mx-auto shadow-md rounded px-8 py-6 mt-8"
>
<input name="_csrf_token" type="hidden" value={Plug.CSRFProtection.get_csrf_token()} />
<h2 class="text-xl font-black dark:text-gray-100">
Reset your password
</h2>
<div class="my-4">
<.password_length_hint
minimum={12}
field={f[:password]}
class={["text-sm", "mt-1", "mb-2"]}
ok_class="text-gray-600 dark:text-gray-600"
error_class="text-red-600 dark:text-red-500"
/>
<.password_input_with_strength
field={f[:password]}
strength={@password_strength}
phx-debounce={200}
class="transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500"
/>
</div>
<PlausibleWeb.Components.Generic.button id="set" type="submit" class="mt-4 w-full">
Implement better user password validation (#3344) * Add zxcvbn dependency * Change password length range requirement from 6-64 to 12-128 * Reimplement register form in LV * Implement server-side check for password strength * Add rudimentary strength meter * Make password input with strength a separate component and improve it * Fix existing tests to provide strong enough password * Apply formatting * Replace existing registration form with new one * Hide built-in label in `.input` component when none provided * Crop password to first 32 chars for analysis by zxcvbn * Add tests for new form components * Integrate hCaptcha into LV * Fix existing AuthController tests * Add tests for Live.RegisterForm * Hide strength meter when password input is empty * Randomize client IP in headers during tests to avoid hitting rate limit * Apply auxilliary formatting fixes to AuthController * Integrate registration from invitation into LV registration logic * Fix existing password set and reset forms * Make `password_length_hint` component more customizable * Optimize `Auth.User.set_password/2` * Remove unnecessary attribute from registration form * Move password set and reset forms to LV * Add tests for SetPasswordForm LV component * Add tests for password checks in `Auth.User` * Document code a bit * Implement simpler approach to hCaptcha integration * Update CHANGELOG.md * Improve consistency of color scheme * Introduce debounce across all text inputs in registration and password forms * Fix email input background in register form * Ensure only single error is rendered for empty password confirmation case * Remove `/password` form entirely in favor of preferred password reset * Remove unnecessary `router` option from `live_render` calls * Make expensive assigns in LV with `assign_new` (h/t @aerosol) * Accept passwords longer than 32 bytes uniformly as very strong * Avoid displaying blank error side by side with weak password error * Make register actions handle errors gracefully * Render only a single piece of feedback to reduce noise * Make register and password reset forms pw manager friendly (h/t @cnkk) * Move registration forms to live routes * Delete no longer used deadviews * Adjust registration form in accordance to changes in #3290 * Reintroduce dogfood page path for invitation form from #3290 * Use alternative approach to submitting plausible metrics from LV form * Rename metrics events and extend tests to account for them
2023-09-25 11:27:29 +03:00
Set password
</PlausibleWeb.Components.Generic.button>
Implement better user password validation (#3344) * Add zxcvbn dependency * Change password length range requirement from 6-64 to 12-128 * Reimplement register form in LV * Implement server-side check for password strength * Add rudimentary strength meter * Make password input with strength a separate component and improve it * Fix existing tests to provide strong enough password * Apply formatting * Replace existing registration form with new one * Hide built-in label in `.input` component when none provided * Crop password to first 32 chars for analysis by zxcvbn * Add tests for new form components * Integrate hCaptcha into LV * Fix existing AuthController tests * Add tests for Live.RegisterForm * Hide strength meter when password input is empty * Randomize client IP in headers during tests to avoid hitting rate limit * Apply auxilliary formatting fixes to AuthController * Integrate registration from invitation into LV registration logic * Fix existing password set and reset forms * Make `password_length_hint` component more customizable * Optimize `Auth.User.set_password/2` * Remove unnecessary attribute from registration form * Move password set and reset forms to LV * Add tests for SetPasswordForm LV component * Add tests for password checks in `Auth.User` * Document code a bit * Implement simpler approach to hCaptcha integration * Update CHANGELOG.md * Improve consistency of color scheme * Introduce debounce across all text inputs in registration and password forms * Fix email input background in register form * Ensure only single error is rendered for empty password confirmation case * Remove `/password` form entirely in favor of preferred password reset * Remove unnecessary `router` option from `live_render` calls * Make expensive assigns in LV with `assign_new` (h/t @aerosol) * Accept passwords longer than 32 bytes uniformly as very strong * Avoid displaying blank error side by side with weak password error * Make register actions handle errors gracefully * Render only a single piece of feedback to reduce noise * Make register and password reset forms pw manager friendly (h/t @cnkk) * Move registration forms to live routes * Delete no longer used deadviews * Adjust registration form in accordance to changes in #3290 * Reintroduce dogfood page path for invitation form from #3290 * Use alternative approach to submitting plausible metrics from LV form * Rename metrics events and extend tests to account for them
2023-09-25 11:27:29 +03:00
<p class="text-center text-gray-500 text-xs mt-4">
Don't have an account? <%= link("Register",
to: "/register",
class: "underline text-gray-800 dark:text-gray-200"
) %> instead.
</p>
</.form>
"""
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
user = Auth.User.set_password(socket.assigns.user, password)
case Repo.update(user) do
{:ok, _user} ->
{:noreply, assign(socket, trigger_submit: true)}
{:error, changeset} ->
{:noreply,
assign(socket,
form: to_form(Map.put(changeset, :action, :validate))
)}
end
end
end