Implement password change flow
This commit is contained in:
@ -0,0 +1,67 @@
|
||||
{% extends "/dashboard/_base.html" %} {% block content %}
|
||||
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4">
|
||||
<div class="w-full max-w-xl p-6 space-y-8 bg-white rounded-lg shadow sm:p-8 dark:bg-gray-800">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">
|
||||
Change Password
|
||||
</h2>
|
||||
{% if errors | list %}
|
||||
<div class="flex p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert">
|
||||
<svg class="shrink-0 inline w-4 h-4 me-3 mt-[2px]" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/>
|
||||
</svg>
|
||||
<span class="sr-only">Danger</span>
|
||||
<div>
|
||||
<span class="font-medium">Error changing password:</span>
|
||||
<ul class="mt-1.5 list-disc list-inside">
|
||||
{% for error in errors %}
|
||||
<li> {{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form class="mt-8 space-y-6" action="/password" method="POST" id="password-change-form">
|
||||
<input hidden type="text" name="username" value="{{ user.display_name }}" autocomplete="username">
|
||||
<div>
|
||||
<label for="current_password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Current password</label>
|
||||
<input type="password" name="current_password" id="current_password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" required autocomplete="current-password">
|
||||
</div>
|
||||
|
||||
<div hx-target="this" hx-swap="outerHTML">
|
||||
<div>
|
||||
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">New password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="••••••••"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<label for="confirm_password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Confirm New Password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirm_password"
|
||||
id="confirm-password"
|
||||
placeholder="••••••••"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
hx-post="/password/validate-confirm"
|
||||
hx-include="[name='password']"
|
||||
>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button type="submit" class="w-full px-5 py-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 sm:w-auto dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Change password</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,37 @@
|
||||
<div hx-target="this" hx-swap="outerHTML">
|
||||
<div>
|
||||
<label for="password" class="block mb-2 text-sm font-medium text-red-900 dark:text-white">New password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="••••••••"
|
||||
value="{{ password }}"
|
||||
class="bg-red-50 border border-red-500 text-red-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-red-700 dark:border-red-600 dark:placeholder-red-400 dark:text-white dark:focus:ring-red-500 dark:focus:border-red-500"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<label for="confirm_password" class="block mb-2 text-sm font-medium text-red-900 dark:text-white">Confirm New Password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirm_password"
|
||||
id="confirm-password"
|
||||
placeholder="••••••••"
|
||||
class="bg-red-50 border border-red-500 text-red-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-red-700 dark:border-red-600 dark:placeholder-red-400 dark:text-white dark:focus:ring-red-500 dark:focus:border-red-500"
|
||||
required
|
||||
value="{{ confirm_password }}"
|
||||
autocomplete="new-password"
|
||||
hx-post="/password/validate-confirm"
|
||||
hx-include="[name='password']"
|
||||
>
|
||||
</div>
|
||||
|
||||
<p class="mt-2 text-sm text-red-600 dark:text-red-500"><span class="font-medium">Oops!</span> Passwords do not match!</p>
|
||||
|
||||
<div class="mt-2">
|
||||
<button type="submit" class="w-full px-5 py-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 sm:w-auto dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800 cursor-not-allowed" disabled>Change password</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -0,0 +1,12 @@
|
||||
{% extends "/dashboard/_base.html" %} {% block content %}
|
||||
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4">
|
||||
<div class="text-center xl:max-w-4xl">
|
||||
<h1 class="mb-3 text-2xl font-bold leading-tight text-gray-900 sm:text-4xl lg:text-5xl dark:text-white">Password Changed</h1>
|
||||
<p class="mb-5 text-base font-normal text-gray-500 md:text-lg dark:text-gray-400">Your password was changed sucessfully. Next time you log in, use your new password.</p>
|
||||
<a href="/dashboard" class="text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center mr-3 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
|
||||
<svg class="mr-2 -ml-1 w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"></path></svg>
|
||||
Go back to the dashboard
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
@ -0,0 +1,33 @@
|
||||
<div hx-target="this" hx-swap="outerHTML">
|
||||
<div>
|
||||
<label for="password" class="block mb-2 text-sm font-medium text-green-900 dark:text-white">New password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="••••••••"
|
||||
value="{{ password }}"
|
||||
class="bg-green-50 border border-green-500 text-green-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-green-700 dark:border-green-600 dark:placeholder-green-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<label for="confirm_password" class="block mb-2 text-sm font-medium text-green-900 dark:text-white">Confirm New Password</label>
|
||||
<input
|
||||
type="password"
|
||||
name="confirm_password"
|
||||
id="confirm-password"
|
||||
placeholder="••••••••"
|
||||
class="bg-green-50 border border-green-500 text-green-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-green-700 dark:border-green-600 dark:placeholder-green-400 dark:text-white dark:focus:ring-green-500 dark:focus:border-green-500"
|
||||
required
|
||||
value="{{ confirm_password }}"
|
||||
autocomplete="new-password"
|
||||
hx-post="/password/validate-confirm"
|
||||
hx-include="[name='password']"
|
||||
>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button type="submit" class="w-full px-5 py-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 sm:w-auto dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Change password</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -94,7 +94,7 @@
|
||||
{% if user.local %}
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
href="/password"
|
||||
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
role="menuitem"
|
||||
>Change Password</a
|
||||
|
||||
Reference in New Issue
Block a user