- Updated the .env.example file to reflect a development environment setup with enhanced secret key requirements and local host settings. - Modified the Docker Compose configuration to enhance security with read-only settings and no-new-privileges options. - Updated requirements.txt to pin package versions for better dependency management. - Enhanced the FastAPI application to include dynamic OpenAPI and documentation URLs based on the environment. - Implemented session versioning in JWT tokens to improve security and user session management. - Added new validation for user roles and password strength in schemas. - Improved email sending logic to handle recipient lists more robustly and added logging for SMTP operations. - Updated dashboard and profile templates to reflect new features and improve user experience.
116 lines
5.2 KiB
HTML
116 lines
5.2 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Benutzerverwaltung{% endblock %}
|
||
{% block content %}
|
||
|
||
<div class="page-header">
|
||
<h2>Benutzerverwaltung</h2>
|
||
<p class="page-lead"><a href="/dashboard">← Zurück zum Dashboard</a></p>
|
||
</div>
|
||
|
||
<div class="layout-2col">
|
||
<div class="main-col">
|
||
<section class="card card-accent-orange">
|
||
<div class="card-header">
|
||
<h3>Neuen Benutzer anlegen</h3>
|
||
</div>
|
||
{% if error_message %}
|
||
<p class="error">{{ error_message }}</p>
|
||
{% endif %}
|
||
{% if success_message %}
|
||
<p class="hint" style="color:var(--tk-success);font-weight:600;">{{ success_message }}</p>
|
||
{% endif %}
|
||
<form method="post" action="/admin/users" class="form-grid">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<div class="form-row">
|
||
<label>E-Mail
|
||
<input type="email" name="email" required placeholder="name@firma.de">
|
||
</label>
|
||
<label>Vollständiger Name
|
||
<input type="text" name="full_name" required>
|
||
</label>
|
||
</div>
|
||
<div class="form-row">
|
||
<label>Passwort
|
||
<input type="password" name="password" required minlength="10" placeholder="Mind. 10 Zeichen, Groß/Klein/Ziffer">
|
||
</label>
|
||
<label>Rolle
|
||
<select name="role">
|
||
<option value="reader">Leser (nur ansehen)</option>
|
||
<option value="editor">Editor (generieren & senden)</option>
|
||
<option value="admin">Admin (voller Zugriff)</option>
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<button type="submit" class="btn-primary">Benutzer erstellen</button>
|
||
</form>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<div class="card-header">
|
||
<h3>Bestehende Benutzer <span class="count-badge">{{ users|length }}</span></h3>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>E-Mail</th><th>Name</th><th>Rolle</th><th>Status</th><th>Aktionen</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for u in users %}
|
||
<tr>
|
||
<td>{{ u.email }}</td>
|
||
<td>{{ u.full_name }}</td>
|
||
<td>
|
||
{% if u.id == user.id %}
|
||
<span class="badge badge-{{ u.role }}">{{ u.role }}</span>
|
||
{% else %}
|
||
<form method="post" action="/admin/users/{{ u.id }}/role" class="inline-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<select name="role" onchange="this.form.submit()">
|
||
<option value="reader" {% if u.role == 'reader' %}selected{% endif %}>reader</option>
|
||
<option value="editor" {% if u.role == 'editor' %}selected{% endif %}>editor</option>
|
||
<option value="admin" {% if u.role == 'admin' %}selected{% endif %}>admin</option>
|
||
</select>
|
||
</form>
|
||
{% endif %}
|
||
</td>
|
||
<td>{{ "Aktiv" if u.is_active else "Inaktiv" }}</td>
|
||
<td>
|
||
{% if u.id != user.id %}
|
||
<form method="post" action="/admin/users/{{ u.id }}/toggle-active" class="inline-form">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="btn-secondary btn-small">
|
||
{% if u.is_active %}Deaktivieren{% else %}Aktivieren{% endif %}
|
||
</button>
|
||
</form>
|
||
{% else %}
|
||
<span class="hint">Eigenes Konto</span>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<aside class="sidebar-col">
|
||
<div class="sidebar-card">
|
||
<h4>Rollen</h4>
|
||
<ul>
|
||
<li><strong>Leser</strong> – Newsletter ansehen</li>
|
||
<li><strong>Editor</strong> – Generieren & senden</li>
|
||
<li><strong>Admin</strong> – Benutzer & SMTP</li>
|
||
</ul>
|
||
</div>
|
||
<div class="sidebar-card">
|
||
<h4>Sicherheit</h4>
|
||
<ul>
|
||
<li>Rollen- oder Statusänderung beendet alle aktiven Sitzungen des Benutzers.</li>
|
||
</ul>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
|
||
{% endblock %}
|