snapshot: preserve session hardening and account surface
This commit is contained in:
52
backend/workflows/templates/workflows/account_profile.html
Normal file
52
backend/workflows/templates/workflows/account_profile.html
Normal file
@@ -0,0 +1,52 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Profil" %}{% endblock %}
|
||||
|
||||
{% block shell_header %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_home=1 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 account-card">
|
||||
<h1>{% trans "Profil" %}</h1>
|
||||
<p>{% trans "Ihre aktuelle Workdock-Kontoübersicht und direkte Kontoaktionen." %}</p>
|
||||
|
||||
<div class="account-grid">
|
||||
<div class="account-row">
|
||||
<span>{% trans "Name" %}</span>
|
||||
<strong>{{ account_user.get_full_name|default:account_user.username }}</strong>
|
||||
</div>
|
||||
<div class="account-row">
|
||||
<span>{% trans "Benutzername" %}</span>
|
||||
<strong>{{ account_user.username }}</strong>
|
||||
</div>
|
||||
<div class="account-row">
|
||||
<span>{% trans "E-Mail" %}</span>
|
||||
<strong>{{ account_user.email|default:"-" }}</strong>
|
||||
</div>
|
||||
<div class="account-row">
|
||||
<span>{% trans "Rolle" %}</span>
|
||||
<strong>{{ role_label }}</strong>
|
||||
</div>
|
||||
<div class="account-row">
|
||||
<span>{% trans "Letzte Anmeldung" %}</span>
|
||||
<strong>{% if account_user.last_login %}{{ account_user.last_login|date:"d.m.Y H:i" }}{% else %}-{% endif %}</strong>
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort geändert" %}{% 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 geändert" %}</h1>
|
||||
<p>{% trans "Ihr Passwort wurde erfolgreich aktualisiert." %}</p>
|
||||
<a class="btn btn-primary" href="{% url 'account_profile_page' %}">{% trans "Zum Profil" %}</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,37 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Passwort ändern" %}{% 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 ändern" %}</h1>
|
||||
<p>{% trans "Vergeben Sie ein neues Passwort für Ihr Konto." %}</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="field{% if form.old_password.errors %} has-error{% endif %}">
|
||||
{{ form.old_password.label_tag }}{{ form.old_password }}
|
||||
{% for error in form.old_password.errors %}<div class="hint">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -177,7 +177,7 @@ docker compose exec -T web django-admin compilemessages</code></pre>
|
||||
<li>Portal-level branding is stored in the singleton model <code>PortalBranding</code>.</li>
|
||||
<li>Configured from Admin Apps → <code>Branding</code>.</li>
|
||||
<li>Current scope: portal title, company name, company domain, support email, sender display name, login subtitle, footer/legal text, logo, favicon, PDF letterhead, and primary/secondary colors.</li>
|
||||
<li>Shared header/logo rendering now uses the branding context processor instead of hardcoded TUBCO asset references.</li>
|
||||
<li>Shared header/logo rendering now uses the branding context processor instead of hardcoded customer-specific asset references.</li>
|
||||
<li>The company domain now drives onboarding/offboarding email autofill and domain validation, so new customer deployments no longer require <code>@tub.co</code> code changes.</li>
|
||||
<li>Outgoing system mail sender names are now branded through the same layer.</li>
|
||||
<li>User invitation emails and welcome-template fallbacks also use the configured branding defaults.</li>
|
||||
|
||||
@@ -10,23 +10,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
<div class="topbar">
|
||||
<div class="brand-wrap">
|
||||
<a class="app-brand" href="/"><img class="brand-logo" src="{{ portal_logo_url }}" alt="{{ portal_company_name }} Logo" /></a>
|
||||
</div>
|
||||
<div class="quick-actions">
|
||||
<form method="post" action="{% url 'set_language' %}" class="lang-switch">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ request.get_full_path }}" />
|
||||
<button class="lang-btn {% if CURRENT_LANGUAGE == 'de' %}active{% endif %}" type="submit" name="language" value="de">DE</button>
|
||||
<button class="lang-btn {% if CURRENT_LANGUAGE == 'en' %}active{% endif %}" type="submit" name="language" value="en">EN</button>
|
||||
</form>
|
||||
<form method="post" action="/accounts/logout/" style="display:inline;">
|
||||
{% csrf_token %}
|
||||
<button class="btn btn-secondary" type="submit">{% trans "Abmelden" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'workflows/includes/app_header.html' with header_show_lang=1 %}
|
||||
|
||||
<div class="hero">
|
||||
<div class="hero-grid">
|
||||
|
||||
@@ -19,5 +19,35 @@
|
||||
{% if header_show_home %}
|
||||
<a class="btn btn-secondary" href="/">{% trans "Zur Startseite" %}</a>
|
||||
{% endif %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<details class="app-user-menu">
|
||||
<summary class="app-user-trigger">
|
||||
<span class="app-user-avatar" aria-hidden="true">
|
||||
{% if request.user.first_name or request.user.last_name %}
|
||||
{{ request.user.first_name|slice:":1" }}{{ request.user.last_name|slice:":1" }}
|
||||
{% else %}
|
||||
{{ request.user.username|slice:":2" }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="app-user-copy">
|
||||
<strong>{{ request.user.get_full_name|default:request.user.username }}</strong>
|
||||
<span>{{ role_label }}</span>
|
||||
</span>
|
||||
<span class="app-user-caret" aria-hidden="true">▾</span>
|
||||
</summary>
|
||||
<div class="app-user-panel">
|
||||
<div class="app-user-panel-head">
|
||||
<strong>{{ request.user.get_full_name|default:request.user.username }}</strong>
|
||||
<span>{{ request.user.email|default:request.user.username }}</span>
|
||||
</div>
|
||||
<a href="{% url 'account_profile_page' %}">{% trans "Profil" %}</a>
|
||||
<a href="{% url 'password_change' %}">{% trans "Passwort ändern" %}</a>
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit">{% trans "Abmelden" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</details>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user