174 lines
5.2 KiB
HTML
174 lines
5.2 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Account Settings{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="grow container mx-auto">
|
|
{% if not auth.has_totp %}
|
|
<div class="border rounded-md shadow-md border-red-500 bg-red-200 dark:bg-red-900/25 flex flex-col gap-4 p-6 mt-4">
|
|
<h1 class="text-danger font-semibold">
|
|
Two-factor authentication is not enabled on your account.
|
|
</h1>
|
|
<p>
|
|
Two-factor authentication (2FA) is an extra layer of security for your account. When
|
|
enabled, you will need to provide a code from your authenticator app in addition to your
|
|
password when logging in.
|
|
</p>
|
|
<div class="buttons">
|
|
<button
|
|
type="button"
|
|
class="button"
|
|
title="Add MFA to your account"
|
|
hx-get="/user/settings/totp"
|
|
hx-target="body"
|
|
hx-swap="beforeend">
|
|
Setup two-factor authentication
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-4 p-4 lg:p-0 lg:mt-4">
|
|
<div class="panel">
|
|
<h1 class="heading">
|
|
Account settings
|
|
</h1>
|
|
{% if settings_success %}
|
|
<div id="success" class="text-success">
|
|
{{ settings_success }}
|
|
</div>
|
|
{% endif %}
|
|
{% if settings_error %}
|
|
<div id="error" class="text-danger">
|
|
{{ settings_error }}
|
|
</div>
|
|
{% endif %}
|
|
<form method="POST" action="/user/settings" class="form" id="username-form">
|
|
<input type="hidden" name="token" value="{{ token }}">
|
|
<label for="username">Change your username</label>
|
|
<input
|
|
class="field"
|
|
type="text"
|
|
name="username"
|
|
id="username"
|
|
placeholder="Username"
|
|
value="{{ auth.username }}"
|
|
required />
|
|
<label for="name">Display name</label>
|
|
<input
|
|
type="text"
|
|
class="field"
|
|
name="name"
|
|
id="name"
|
|
placeholder="Display Name"
|
|
value="{{ auth.name }}"
|
|
required
|
|
/>
|
|
<div class="buttons end">
|
|
<button type="submit" class="button">Update settings</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="panel flex flex-col gap-2">
|
|
<h1 class="heading">
|
|
Account password
|
|
</h1>
|
|
{% if password_success %}
|
|
<div id="password-success" class="text-success">
|
|
{{ password_success }}
|
|
</div>
|
|
{% endif %}
|
|
{% if password_error %}
|
|
<div id="password-error" class="text-danger">
|
|
{{ password_error }}
|
|
</div>
|
|
{% endif %}
|
|
<form method="POST" action="/user/settings/password" class="form grow" id="password-form">
|
|
<input type="hidden" name="token" value="{{ token }}">
|
|
<label for="username">Change your password</label>
|
|
<input
|
|
class="field"
|
|
type="password"
|
|
name="password"
|
|
id="password"
|
|
placeholder="New password"
|
|
required />
|
|
<input
|
|
class="field"
|
|
type="password"
|
|
name="confirm"
|
|
id="confirm"
|
|
placeholder="Confirm password"
|
|
required />
|
|
<div class="buttons end" style="margin-top: auto">
|
|
<button type="submit" class="button">Change password</button>
|
|
{% if auth.has_totp %}
|
|
<button
|
|
type="button"
|
|
class="button hollow danger"
|
|
title="Remove MFA from your account"
|
|
hx-get="/user/settings/totp/remove"
|
|
hx-target="body"
|
|
hx-swap="beforeend">
|
|
Remove two-factor authentication
|
|
</button>
|
|
{% else %}
|
|
<button
|
|
type="button"
|
|
class="button hollow"
|
|
title="Add MFA to your account"
|
|
hx-get="/user/settings/totp"
|
|
hx-target="body"
|
|
hx-swap="beforeend">
|
|
Setup two-factor authentication
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.querySelectorAll("form").forEach((element) => {
|
|
element.addEventListener("submit", (event) => {
|
|
// Disable all submit buttons so we don't try multiple submissions.
|
|
document.querySelector("button[type=submit]").disabled = true;
|
|
});
|
|
});
|
|
|
|
function setError(target, message) {
|
|
const existing = target.parentElement.querySelector(".text-danger");
|
|
if (existing) {
|
|
existing.innerHTML = message;
|
|
return;
|
|
}
|
|
|
|
const div = document.createElement("DIV");
|
|
div.classList.add("text-danger");
|
|
div.innerHTML = message;
|
|
target.parentElement.insertBefore(div, target);
|
|
}
|
|
|
|
document.querySelector("#password-form").addEventListener("submit", (event) => {
|
|
const password = document.querySelector("input[name='password']").value;
|
|
const confirm = document.querySelector("input[name='confirm']").value;
|
|
|
|
if (password.length === 0) {
|
|
event.preventDefault();
|
|
setError(event.target, "Your new password cannot be empty.");
|
|
return;
|
|
}
|
|
|
|
if (password !== confirm) {
|
|
event.preventDefault();
|
|
setError(event.target, "The passwords do not match");
|
|
return;
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|