snapshot: preserve account security and profile UI cleanup
This commit is contained in:
@@ -20,10 +20,6 @@
|
||||
<h1>{% trans "Profil" %}</h1>
|
||||
<p>{% trans "Ihre aktuelle Workdock-Kontoübersicht und wichtige Sicherheitsaktionen." %}</p>
|
||||
</div>
|
||||
<div class="account-hero-badges">
|
||||
<span class="account-chip">{{ role_label }}</span>
|
||||
<span class="account-chip account-chip-muted">{{ account_user.username }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="account-layout">
|
||||
@@ -58,14 +54,6 @@
|
||||
<p>{{ account_user.email|default:account_user.username }}</p>
|
||||
</div>
|
||||
<div class="account-profile-meta">
|
||||
<div>
|
||||
<span>{% trans "Rolle" %}</span>
|
||||
<strong>{{ role_label }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>{% trans "Benutzername" %}</span>
|
||||
<strong>{{ account_user.username }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>{% trans "Position" %}</span>
|
||||
<strong>{{ account_user_profile.job_title|default:"-" }}</strong>
|
||||
@@ -171,29 +159,36 @@
|
||||
<section class="account-panel">
|
||||
<div class="account-panel-head">
|
||||
<h2>{% trans "Sicherheit & Aktionen" %}</h2>
|
||||
<p>{% trans "Direkte Aktionen für Ihr Workdock-Konto." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="account-action-grid">
|
||||
<a class="account-action-card" href="{% url 'password_change' %}">
|
||||
<strong>{% trans "Passwort ändern" %}</strong>
|
||||
<span>{% trans "Aktualisieren Sie Ihr Passwort direkt im Konto." %}</span>
|
||||
</a>
|
||||
|
||||
<div class="account-action-card{% if account_user_profile.totp_enabled %}{% else %} account-action-card-muted{% endif %}">
|
||||
<strong>{% trans "TOTP" %}</strong>
|
||||
<span>
|
||||
<div class="account-security-overview">
|
||||
<div class="account-security-item">
|
||||
<span>{% trans "TOTP" %}</span>
|
||||
<strong>{% if account_user_profile.totp_enabled %}{% trans "Aktiv" %}{% else %}{% trans "Aus" %}{% endif %}</strong>
|
||||
<p>
|
||||
{% if account_user_profile.totp_enabled %}
|
||||
{% trans "Zweiter Faktor ist aktiv und wird bei der Anmeldung geprüft." %}
|
||||
{% trans "Anmeldung wird zusätzlich mit einem zweiten Faktor geschützt." %}
|
||||
{% else %}
|
||||
{% trans "Standardmäßig deaktiviert. Kann hier jederzeit aktiviert werden." %}
|
||||
{% trans "Optional. Kann bei Bedarf direkt unten aktiviert werden." %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="account-action-card account-action-card-muted">
|
||||
<strong>{% trans "Sitzung" %}</strong>
|
||||
<span>{% trans "Sie können sich jederzeit sicher vom aktuellen Gerät abmelden." %}</span>
|
||||
<div class="account-security-item">
|
||||
<span>{% trans "Recovery-Codes" %}</span>
|
||||
<strong>
|
||||
{% if account_user_profile.totp_enabled %}
|
||||
{{ account_user_profile.totp_recovery_codes|length }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</strong>
|
||||
<p>
|
||||
{% if account_user_profile.totp_enabled %}
|
||||
{% trans "Einmal-Codes für Notfälle oder verlorene Authenticator-Geräte." %}
|
||||
{% else %}
|
||||
{% trans "Werden automatisch erzeugt, sobald TOTP aktiviert wird." %}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -241,18 +236,52 @@
|
||||
<button class="btn btn-secondary" type="submit">{% trans "TOTP deaktivieren" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="account-detail-grid">
|
||||
<div class="account-detail">
|
||||
<span>{% trans "Manueller Schlüssel" %}</span>
|
||||
<strong class="account-secret">{{ totp_pending_secret }}</strong>
|
||||
<form class="account-totp-form" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="account_form" value="totp_regenerate_codes" />
|
||||
<div class="account-form-grid">
|
||||
{% for field in totp_regenerate_form %}
|
||||
<div class="account-form-field{% if field.errors %} has-error{% endif %}">
|
||||
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}
|
||||
<div class="account-form-error">{{ field.errors|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="account-detail">
|
||||
<span>{% trans "Setup-Link" %}</span>
|
||||
<strong class="account-secret">{{ totp_otpauth_uri }}</strong>
|
||||
<div class="account-inline-actions">
|
||||
<button class="btn btn-primary" type="submit">{% trans "Recovery-Codes neu erzeugen" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="account-qr-card">
|
||||
{% if totp_qr_svg %}
|
||||
{{ totp_qr_svg|safe }}
|
||||
{% endif %}
|
||||
<div class="account-secret-panel">
|
||||
<div class="account-secret-head">
|
||||
<div>
|
||||
<span>{% trans "Manueller Schlüssel" %}</span>
|
||||
<strong>{% trans "Nur bei Bedarf anzeigen" %}</strong>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-secondary account-secret-toggle"
|
||||
type="button"
|
||||
data-secret-toggle
|
||||
aria-expanded="false"
|
||||
aria-controls="totp-manual-secret"
|
||||
title="{% trans 'Manuellen Schlüssel anzeigen oder ausblenden' %}"
|
||||
>
|
||||
<span data-secret-toggle-icon>◐</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="account-secret-body is-hidden" id="totp-manual-secret" data-secret-body>
|
||||
<strong class="account-secret">{{ totp_pending_secret }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mini">{% trans "Wenn Ihre App keinen QR-Code scannen kann, tragen Sie den Schlüssel oder den otpauth-Link manuell ein." %}</p>
|
||||
<p class="mini">{% trans "Scannen Sie den QR-Code mit Ihrer Authenticator-App. Den manuellen Schlüssel können Sie bei Bedarf einblenden." %}</p>
|
||||
<form class="account-totp-form" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="account_form" value="totp_enable" />
|
||||
@@ -272,14 +301,22 @@
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="account-actions">
|
||||
<a class="btn btn-primary" href="{% url 'password_change' %}">{% trans "Passwort ändern" %}</a>
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button class="btn btn-secondary" type="submit">{% trans "Abmelden" %}</button>
|
||||
</form>
|
||||
{% if totp_recovery_codes %}
|
||||
<div class="account-recovery-card">
|
||||
<div class="account-panel-head">
|
||||
<div>
|
||||
<h3>{% trans "Recovery-Codes" %}</h3>
|
||||
<p>{% trans "Diese Codes werden nur jetzt im Klartext angezeigt. Jeden Code können Sie genau einmal verwenden." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-recovery-grid">
|
||||
{% for code in totp_recovery_codes %}
|
||||
<div class="account-recovery-code">{{ code }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -295,6 +332,9 @@
|
||||
var cancel = document.querySelector('[data-account-edit-cancel="details"]');
|
||||
var view = document.querySelector('[data-account-edit-view="details"]');
|
||||
var form = document.querySelector('[data-account-edit-form="details"]');
|
||||
var secretToggle = document.querySelector('[data-secret-toggle]');
|
||||
var secretBody = document.querySelector('[data-secret-body]');
|
||||
var secretIcon = document.querySelector('[data-secret-toggle-icon]');
|
||||
if (!toggle || !cancel || !view || !form) return;
|
||||
|
||||
function setMode(editing) {
|
||||
@@ -310,6 +350,17 @@
|
||||
cancel.addEventListener('click', function () {
|
||||
setMode(false);
|
||||
});
|
||||
|
||||
if (secretToggle && secretBody) {
|
||||
secretToggle.addEventListener('click', function () {
|
||||
var isOpen = secretToggle.getAttribute('aria-expanded') === 'true';
|
||||
secretToggle.setAttribute('aria-expanded', isOpen ? 'false' : 'true');
|
||||
secretBody.classList.toggle('is-hidden', isOpen);
|
||||
if (secretIcon) {
|
||||
secretIcon.textContent = isOpen ? '◐' : '◑';
|
||||
}
|
||||
});
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
{{ form.otp_code.label_tag }}{{ form.otp_code }}
|
||||
<div class="mini">{% trans "Nur erforderlich, wenn TOTP für Ihr Konto aktiviert ist." %}</div>
|
||||
</div>
|
||||
<div class="field{% if form.recovery_code.errors %} has-error{% endif %}">
|
||||
{{ form.recovery_code.label_tag }}{{ form.recovery_code }}
|
||||
<div class="mini">{% trans "Alternativ können Sie einen einmaligen Recovery-Code verwenden." %}</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Anmelden" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user