snapshot: preserve auth invite flow and password reset UX cleanup
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort gespeichert" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "Passwort gespeichert" %}</h1>
|
||||
<p>{% trans "Ihr Passwort wurde erfolgreich gesetzt. Sie können sich jetzt mit Ihrem Benutzerkonto anmelden." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,45 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort festlegen" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
{% if validlink %}
|
||||
<h1>{% trans "Passwort festlegen" %}</h1>
|
||||
<p>{% trans "Bitte vergeben Sie jetzt ein neues Passwort für Ihr Konto." %}</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="app-alert app-alert-error" role="alert" aria-live="assertive">
|
||||
<div class="app-alert-body">
|
||||
<strong>{% trans "Passwort konnte nicht gespeichert werden" %}</strong><br />
|
||||
<span>{% trans "Bitte prüfen Sie die beiden Passwortfelder und versuchen Sie es erneut." %}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="field{% if form.new_password1.errors %} has-error{% endif %}">
|
||||
{{ form.new_password1.label_tag }}{{ form.new_password1 }}
|
||||
</div>
|
||||
<div class="field{% if form.new_password2.errors %} has-error{% endif %}">
|
||||
{{ form.new_password2.label_tag }}{{ form.new_password2 }}
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Passwort speichern" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<h1>{% trans "Link ungültig" %}</h1>
|
||||
<p>{% trans "Dieser Link ist nicht mehr gültig. Bitte fordern Sie einen neuen Passwort-Link an." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "E-Mail versendet" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "E-Mail versendet" %}</h1>
|
||||
<p>{% trans "Wenn ein passendes Konto existiert, wurde ein Passwort-Link an die hinterlegte E-Mail-Adresse verschickt." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,28 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort zurücksetzen" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "Passwort zurücksetzen" %}</h1>
|
||||
<p>{% trans "Geben Sie Ihre E-Mail-Adresse ein. Wenn ein Konto vorhanden ist, erhalten Sie einen Passwort-Link." %}</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="field{% if form.email.errors %} has-error{% endif %}">
|
||||
{{ form.email.label_tag }}{{ form.email }}
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Link anfordern" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
39
backend/workflows/templates/workflows/auth/login.html
Normal file
39
backend/workflows/templates/workflows/auth/login.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Anmeldung" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "Anmeldung" %}</h1>
|
||||
<p>{% trans "Bitte melden Sie sich mit Ihrem Benutzerkonto an." %}</p>
|
||||
|
||||
<form method="post" action="/accounts/login/">
|
||||
{% csrf_token %}
|
||||
{% if next %}
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
{% endif %}
|
||||
{% if form.errors %}
|
||||
<div class="app-alert app-alert-error" role="alert" aria-live="assertive">
|
||||
<div class="app-alert-body">
|
||||
<strong>{% trans "Anmeldung fehlgeschlagen" %}</strong><br />
|
||||
<span>{% trans "Benutzername oder Passwort sind nicht korrekt. Bitte versuchen Sie es erneut." %}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="field{% if form.errors %} has-error{% endif %}">{{ form.username.label_tag }}{{ form.username }}</div>
|
||||
<div class="field{% if form.errors %} has-error{% endif %}">{{ form.password.label_tag }}{{ form.password }}</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Anmelden" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort gespeichert" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "Passwort gespeichert" %}</h1>
|
||||
<p>{% trans "Ihr Passwort wurde erfolgreich gesetzt. Sie können sich jetzt mit Ihrem Benutzerkonto anmelden." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,47 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort festlegen" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
{% if validlink %}
|
||||
<h1>{% trans "Passwort festlegen" %}</h1>
|
||||
<p>{% trans "Bitte vergeben Sie jetzt ein neues Passwort für Ihr Konto." %}</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="app-alert app-alert-error" role="alert" aria-live="assertive">
|
||||
<div class="app-alert-body">
|
||||
<strong>{% trans "Passwort konnte nicht gespeichert werden" %}</strong><br />
|
||||
<span>{% trans "Bitte prüfen Sie die beiden Passwortfelder und versuchen Sie es erneut." %}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="field{% if form.new_password1.errors %} has-error{% endif %}">
|
||||
{{ form.new_password1.label_tag }}{{ form.new_password1 }}
|
||||
{% for error in form.new_password1.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<div class="field{% if form.new_password2.errors %} has-error{% endif %}">
|
||||
{{ form.new_password2.label_tag }}{{ form.new_password2 }}
|
||||
{% for error in form.new_password2.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Passwort speichern" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<h1>{% trans "Link ungültig" %}</h1>
|
||||
<p>{% trans "Dieser Link ist nicht mehr gültig. Bitte fordern Sie einen neuen Passwort-Link an." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "E-Mail versendet" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "E-Mail versendet" %}</h1>
|
||||
<p>{% trans "Wenn ein passendes Konto existiert, wurde ein Passwort-Link an die hinterlegte E-Mail-Adresse verschickt." %}</p>
|
||||
<a class="btn btn-primary" href="/accounts/login/">{% trans "Zur Anmeldung" %}</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort zurücksetzen" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 header_inside_shell=1 %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<section class="login-shell-body">
|
||||
<div class="login-card">
|
||||
<h1>{% trans "Passwort zurücksetzen" %}</h1>
|
||||
<p>{% trans "Geben Sie Ihre E-Mail-Adresse ein. Wenn ein Konto vorhanden ist, erhalten Sie einen Passwort-Link." %}</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="field{% if form.email.errors %} has-error{% endif %}">
|
||||
{{ form.email.label_tag }}{{ form.email }}
|
||||
{% for error in form.email.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Link anfordern" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -107,7 +107,7 @@ docker compose exec -T web python manage.py check</code></pre>
|
||||
<li>Capability checks are centralized in <code>workflows.roles.CAPABILITIES</code>.</li>
|
||||
<li>Use <code>_require_capability(...)</code> in views instead of flat <code>is_staff</code> checks.</li>
|
||||
<li>Templates receive permission flags from <code>workflows.context_processors.role_context</code>.</li>
|
||||
<li>Super-admin-only user management lives at <code>/admin-tools/users/</code> and is the preferred path for normal role assignment, account activation, password-reset mail dispatch, and controlled user deletion.</li>
|
||||
<li>Super-admin-only user management lives at <code>/admin-tools/users/</code> and is the preferred path for normal role assignment, account activation, invitation mail dispatch, password-reset mail dispatch, and controlled user deletion.</li>
|
||||
<li>Backward-compatibility rule: authenticated legacy users with <code>is_staff=True</code> but no explicit role group currently fall back to the <code>Admin</code> capability set.</li>
|
||||
<li><code>superuser</code> accounts resolve to <code>Super Admin</code>.</li>
|
||||
<li>When adding a new operational page or action, define the capability in <code>roles.py</code>, gate the view, and hide the UI affordance when the capability is absent.</li>
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
<li><strong>Form Builder:</strong> manage field visibility/order/options.</li>
|
||||
<li><strong>Einweisungs-Builder:</strong> manage custom checklist items for the intro PDF and live introduction checklist, including section, visibility, and conditional display logic.</li>
|
||||
<li><strong>Integrations:</strong> Nextcloud, SMTP, default routing addresses, notification rules, workflow rules, and remote backup target settings.</li>
|
||||
<li><strong>Benutzer & Rollen:</strong> super-admin-only page for creating users, assigning roles, activating/deactivating access, sending password-reset links, and deleting accounts when appropriate.</li>
|
||||
<li><strong>Benutzer & Rollen:</strong> super-admin-only page for creating users, assigning roles, activating/deactivating access, sending access or password-reset links by email, and deleting accounts when appropriate.</li>
|
||||
<li><strong>Welcome Emails:</strong> scheduled jobs, pause/resume/cancel/trigger now.</li>
|
||||
<li><strong>Audit Log:</strong> staff-only trace of important admin changes such as builder edits, settings updates, PDF generation, welcome-email operations, and request deletions. Supports filtering by action, user, and date range.</li>
|
||||
<li><strong>Requests Dashboard:</strong> search records, open PDFs, delete records (single/bulk for staff).</li>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
<section class="card">
|
||||
<h2>{% trans "Benutzer anlegen" %}</h2>
|
||||
<p class="sub">{% trans "Nach dem Anlegen wird automatisch eine Zugangseinladung mit Passwort-Link per E-Mail versendet." %}</p>
|
||||
<form method="post" action="{% url 'create_user_from_admin' %}">
|
||||
{% csrf_token %}
|
||||
<div class="grid">
|
||||
@@ -48,20 +49,10 @@
|
||||
{{ create_form.role_key }}
|
||||
{% for error in create_form.role_key.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<div>
|
||||
<label for="{{ create_form.password1.id_for_label }}">{{ create_form.password1.label }}</label>
|
||||
{{ create_form.password1 }}
|
||||
{% for error in create_form.password1.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<div>
|
||||
<label for="{{ create_form.password2.id_for_label }}">{{ create_form.password2.label }}</label>
|
||||
{{ create_form.password2 }}
|
||||
{% for error in create_form.password2.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% for error in create_form.non_field_errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
<div class="actions">
|
||||
<button class="btn btn-primary" type="submit">{% trans "Benutzer erstellen" %}</button>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Benutzer anlegen und einladen" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user