feat: Major updates to backend structure and security enhancements

- Removed `COMMON_ERRORS.md` file to streamline documentation.
- Added `Flask-Limiter` for rate limiting and `redis` for session management in `requirements.txt`.
- Expanded `ROADMAP.md` to include completed security features and planned enhancements for version 2.2.
- Enhanced `setup_myp.sh` for ultra-secure kiosk installation, including system hardening and security configurations.
- Updated `app.py` to integrate CSRF protection and improved logging setup.
- Refactored user model to include username and active status for better user management.
- Improved job scheduler with uptime tracking and task management features.
- Updated various templates for a more cohesive user interface and experience.
This commit is contained in:
2025-05-25 20:33:38 +02:00
parent e21104611f
commit 2d33753b94
1288 changed files with 247388 additions and 3249 deletions

View File

@@ -6,18 +6,18 @@
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Header -->
<div class="mb-8">
<h1 class="text-3xl font-bold text-mercedes-black">Mein Profil</h1>
<p class="mt-2 text-mercedes-gray">Verwalten Sie Ihre Kontoinformationen und Einstellungen</p>
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">Mein Profil</h1>
<p class="mt-2 text-slate-500 dark:text-slate-400">Verwalten Sie Ihre Kontoinformationen und Einstellungen</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Profile Information -->
<div class="lg:col-span-2">
<div class="mercedes-card rounded-xl p-6 mb-6">
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-md border border-gray-200 dark:border-slate-700/50 mb-6">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-mercedes-black">Persönliche Informationen</h2>
<h2 class="text-xl font-bold text-slate-900 dark:text-white">Persönliche Informationen</h2>
<button onclick="toggleEditMode()" id="edit-button"
class="bg-mercedes-blue hover:bg-blue-700 text-white px-4 py-2 rounded-lg mercedes-button transition-all duration-200">
class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 text-white px-4 py-2 rounded-lg transition-all duration-200">
<svg class="h-5 w-5 inline mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
</svg>
@@ -28,61 +28,61 @@
<form id="profile-form" onsubmit="handleProfileUpdate(event)">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="first-name" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="first-name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Vorname
</label>
<input type="text" id="first-name" name="first_name" value="{{ current_user.first_name or '' }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue disabled:bg-mercedes-light disabled:cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white disabled:bg-gray-100 dark:disabled:bg-slate-800 disabled:cursor-not-allowed">
</div>
<div>
<label for="last-name" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="last-name" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Nachname
</label>
<input type="text" id="last-name" name="last_name" value="{{ current_user.last_name or '' }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue disabled:bg-mercedes-light disabled:cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white disabled:bg-gray-100 dark:disabled:bg-slate-800 disabled:cursor-not-allowed">
</div>
<div>
<label for="email" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="email" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
E-Mail-Adresse
</label>
<input type="email" id="email" name="email" value="{{ current_user.email }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue disabled:bg-mercedes-light disabled:cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white disabled:bg-gray-100 dark:disabled:bg-slate-800 disabled:cursor-not-allowed">
</div>
<div>
<label for="phone" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="phone" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Telefonnummer
</label>
<input type="tel" id="phone" name="phone" value="{{ current_user.phone or '' }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue disabled:bg-mercedes-light disabled:cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white disabled:bg-gray-100 dark:disabled:bg-slate-800 disabled:cursor-not-allowed">
</div>
<div>
<label for="department" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="department" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Abteilung
</label>
<input type="text" id="department" name="department" value="{{ current_user.department or '' }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue disabled:bg-mercedes-light disabled:cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white disabled:bg-gray-100 dark:disabled:bg-slate-800 disabled:cursor-not-allowed">
</div>
<div>
<label for="role" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="role" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Rolle
</label>
<input type="text" id="role" value="{{ 'Administrator' if current_user.is_admin else 'Benutzer' }}" disabled
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg bg-mercedes-light cursor-not-allowed">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg bg-gray-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 cursor-not-allowed">
</div>
</div>
<div id="form-actions" class="hidden mt-6 flex space-x-4">
<button type="submit"
class="bg-mercedes-green hover:bg-green-700 text-white px-6 py-2 rounded-lg mercedes-button transition-all duration-200">
class="bg-green-600 hover:bg-green-700 dark:bg-green-600 dark:hover:bg-green-500 text-white px-6 py-2 rounded-lg transition-all duration-200">
Änderungen speichern
</button>
<button type="button" onclick="cancelEdit()"
class="bg-mercedes-silver hover:bg-gray-400 text-mercedes-black px-6 py-2 rounded-lg mercedes-button transition-all duration-200">
class="bg-gray-200 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-600 text-slate-800 dark:text-white px-6 py-2 rounded-lg transition-all duration-200">
Abbrechen
</button>
</div>
@@ -90,37 +90,37 @@
</div>
<!-- Password Change -->
<div class="mercedes-card rounded-xl p-6">
<h2 class="text-xl font-bold text-mercedes-black mb-6">Passwort ändern</h2>
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-md border border-gray-200 dark:border-slate-700/50">
<h2 class="text-xl font-bold text-slate-900 dark:text-white mb-6">Passwort ändern</h2>
<form id="password-form" onsubmit="handlePasswordChange(event)" class="space-y-4">
<div>
<label for="current-password" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="current-password" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Aktuelles Passwort
</label>
<input type="password" id="current-password" name="current_password" required
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white">
</div>
<div>
<label for="new-password" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="new-password" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Neues Passwort
</label>
<input type="password" id="new-password" name="new_password" required minlength="8"
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue">
<p class="mt-1 text-xs text-mercedes-gray">Mindestens 8 Zeichen</p>
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white">
<p class="mt-1 text-xs text-slate-500 dark:text-slate-400">Mindestens 8 Zeichen</p>
</div>
<div>
<label for="confirm-password" class="block text-sm font-medium text-mercedes-black mb-2">
<label for="confirm-password" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Passwort bestätigen
</label>
<input type="password" id="confirm-password" name="confirm_password" required
class="w-full px-3 py-2 border border-mercedes-silver rounded-lg focus:ring-2 focus:ring-mercedes-blue focus:border-mercedes-blue">
class="w-full px-3 py-2 border border-gray-300 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-blue-600 focus:border-blue-600 bg-white dark:bg-slate-700 text-slate-900 dark:text-white">
</div>
<button type="submit"
class="bg-mercedes-blue hover:bg-blue-700 text-white px-6 py-2 rounded-lg mercedes-button transition-all duration-200">
class="bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 text-white px-6 py-2 rounded-lg transition-all duration-200">
Passwort ändern
</button>
</form>
@@ -130,51 +130,51 @@
<!-- Sidebar -->
<div class="space-y-6">
<!-- Profile Stats -->
<div class="mercedes-card rounded-xl p-6">
<h3 class="text-lg font-bold text-mercedes-black mb-4">Statistiken</h3>
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-md border border-gray-200 dark:border-slate-700/50">
<h3 class="text-lg font-bold text-slate-900 dark:text-white mb-4">Statistiken</h3>
<div class="space-y-4">
<div class="flex items-center justify-between">
<span class="text-sm text-mercedes-gray">Gesamte Aufträge</span>
<span id="total-jobs" class="text-lg font-bold text-mercedes-black">-</span>
<span class="text-sm text-slate-600 dark:text-slate-400">Gesamte Aufträge</span>
<span id="total-jobs" class="text-lg font-bold text-slate-900 dark:text-white">-</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-mercedes-gray">Abgeschlossene Aufträge</span>
<span id="completed-jobs" class="text-lg font-bold text-mercedes-green">-</span>
<span class="text-sm text-slate-600 dark:text-slate-400">Abgeschlossene Aufträge</span>
<span id="completed-jobs" class="text-lg font-bold text-green-600 dark:text-green-400">-</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-mercedes-gray">Aktive Aufträge</span>
<span id="active-jobs" class="text-lg font-bold text-mercedes-blue">-</span>
<span class="text-sm text-slate-600 dark:text-slate-400">Aktive Aufträge</span>
<span id="active-jobs" class="text-lg font-bold text-blue-600 dark:text-blue-400">-</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-mercedes-gray">Fehlgeschlagene Aufträge</span>
<span id="failed-jobs" class="text-lg font-bold text-mercedes-red">-</span>
<span class="text-sm text-slate-600 dark:text-slate-400">Fehlgeschlagene Aufträge</span>
<span id="failed-jobs" class="text-lg font-bold text-red-600 dark:text-red-400">-</span>
</div>
</div>
</div>
<!-- Account Info -->
<div class="mercedes-card rounded-xl p-6">
<h3 class="text-lg font-bold text-mercedes-black mb-4">Kontoinformationen</h3>
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-md border border-gray-200 dark:border-slate-700/50">
<h3 class="text-lg font-bold text-slate-900 dark:text-white mb-4">Kontoinformationen</h3>
<div class="space-y-3 text-sm">
<div>
<span class="text-mercedes-gray">Mitglied seit:</span>
<div class="font-medium text-mercedes-black">{{ current_user.created_at.strftime('%d.%m.%Y') if current_user.created_at else 'Unbekannt' }}</div>
<span class="text-slate-600 dark:text-slate-400">Mitglied seit:</span>
<div class="font-medium text-slate-900 dark:text-white">{{ current_user.created_at.strftime('%d.%m.%Y') if current_user.created_at else 'Unbekannt' }}</div>
</div>
<div>
<span class="text-mercedes-gray">Letzte Anmeldung:</span>
<div class="font-medium text-mercedes-black">{{ current_user.last_login.strftime('%d.%m.%Y %H:%M') if current_user.last_login else 'Nie' }}</div>
<span class="text-slate-600 dark:text-slate-400">Letzte Anmeldung:</span>
<div class="font-medium text-slate-900 dark:text-white">{{ current_user.last_login.strftime('%d.%m.%Y %H:%M') if current_user.last_login else 'Nie' }}</div>
</div>
<div>
<span class="text-mercedes-gray">Konto-Status:</span>
<span class="text-slate-600 dark:text-slate-400">Konto-Status:</span>
<div class="font-medium">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-mercedes-green text-white">
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-600 dark:bg-green-700 text-white">
Aktiv
</span>
</div>
@@ -183,22 +183,22 @@
</div>
<!-- Quick Actions -->
<div class="mercedes-card rounded-xl p-6">
<h3 class="text-lg font-bold text-mercedes-black mb-4">Schnellaktionen</h3>
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 shadow-md border border-gray-200 dark:border-slate-700/50">
<h3 class="text-lg font-bold text-slate-900 dark:text-white mb-4">Schnellaktionen</h3>
<div class="space-y-3">
<a href="/new-job"
class="block w-full bg-mercedes-green hover:bg-green-700 text-white text-center py-2 px-4 rounded-lg mercedes-button transition-all duration-200">
class="block w-full bg-green-600 hover:bg-green-700 dark:bg-green-600 dark:hover:bg-green-500 text-white text-center py-2 px-4 rounded-lg transition-all duration-200">
Neuer Auftrag
</a>
<a href="/my/jobs"
class="block w-full bg-mercedes-blue hover:bg-blue-700 text-white text-center py-2 px-4 rounded-lg mercedes-button transition-all duration-200">
class="block w-full bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 text-white text-center py-2 px-4 rounded-lg transition-all duration-200">
Meine Aufträge
</a>
<button onclick="downloadUserData()"
class="block w-full bg-mercedes-silver hover:bg-gray-400 text-mercedes-black text-center py-2 px-4 rounded-lg mercedes-button transition-all duration-200">
class="block w-full bg-gray-200 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-600 text-slate-800 dark:text-white text-center py-2 px-4 rounded-lg transition-all duration-200">
Daten exportieren
</button>
</div>