diff --git a/partials/structure/header.php b/partials/structure/header.php
index 34417de..e24f6d8 100644
--- a/partials/structure/header.php
+++ b/partials/structure/header.php
@@ -1,9 +1,9 @@
-
+
diff --git a/partials/structure/layout_start.php b/partials/structure/layout_start.php
index 610e50c..f3610cb 100644
--- a/partials/structure/layout_start.php
+++ b/partials/structure/layout_start.php
@@ -20,6 +20,8 @@ if (!isset($pageDescription) || !is_string($pageDescription)) {
$pageDescription = '';
}
+tpl_add_script('/assets/js/header-user-menu.js', 'footer', true, false, '', null);
+
// Kann später genutzt werden, falls du host-spezifische Sachen brauchst
$host = $_SERVER['HTTP_HOST'] ?? '';
?>
diff --git a/public/assets/js/header-user-menu.js b/public/assets/js/header-user-menu.js
new file mode 100644
index 0000000..23df8e6
--- /dev/null
+++ b/public/assets/js/header-user-menu.js
@@ -0,0 +1,35 @@
+document.addEventListener('DOMContentLoaded', function () {
+ var avatarBtn = document.getElementById('userAvatar');
+ var userMenu = document.getElementById('userMenu');
+ var logoutLink = document.getElementById('userMenuLogout');
+
+ if (avatarBtn && userMenu) {
+ // Avatar klick → Menü toggeln
+ avatarBtn.addEventListener('click', function (e) {
+ e.stopPropagation();
+ userMenu.classList.toggle('hidden');
+ });
+
+ // Klick in Menü nicht nach außen „bubblen“
+ userMenu.addEventListener('click', function (e) {
+ e.stopPropagation();
+ });
+
+ // Klick irgendwo außerhalb → Menü schließen
+ document.addEventListener('click', function () {
+ if (!userMenu.classList.contains('hidden')) {
+ userMenu.classList.add('hidden');
+ }
+ });
+ }
+
+ // Logout mit Confirm
+ if (logoutLink) {
+ logoutLink.addEventListener('click', function (e) {
+ var ok = confirm('Möchtest du dich wirklich abmelden?');
+ if (!ok) {
+ e.preventDefault();
+ }
+ });
+ }
+});
diff --git a/public/auth/login.php b/public/auth/login.php
index 71ca0a4..bab0f9f 100644
--- a/public/auth/login.php
+++ b/public/auth/login.php
@@ -1,4 +1,4 @@
prepare('SELECT * FROM users WHERE email = :email LIMIT 1');
$stmt->execute([':email' => $email]);
@@ -41,20 +46,27 @@ if (!$user) {
exit;
}
-// Account gesperrt?
+/* ---------------------------------------------------------
+ ACCOUNT GESPERRT?
+--------------------------------------------------------- */
+
if (!empty($user['is_locked'])) {
flash_set('error', 'Dein Konto ist gesperrt. Bitte kontaktiere den Support.', 'login');
header('Location: /login/?lang=' . urlencode($lang) . '&view=login#auth');
exit;
}
-// Passwort prüfen
+/* ---------------------------------------------------------
+ PASSWORT PRÜFEN
+--------------------------------------------------------- */
+
if (!password_verify($password, $user['password_hash'])) {
- // Fehlversuche hochzählen (optional)
+
+ // Fehlversuche hochzählen
try {
$failed = (int)($user['failed_logins'] ?? 0) + 1;
+ $lock = 0;
- $lock = 0;
if ($failed >= 5) {
$lock = 1;
}
@@ -66,7 +78,7 @@ if (!password_verify($password, $user['password_hash'])) {
':id' => $user['id'],
]);
} catch (Throwable $e) {
- // Ignorieren, Login-Fehler reicht
+ // Nicht kritisch, Meldung reicht
}
$msg = 'E-Mail oder Passwort ist falsch.';
@@ -79,7 +91,10 @@ if (!password_verify($password, $user['password_hash'])) {
exit;
}
-// Passwort korrekt → Fehlversuche zurücksetzen & letztes Login speichern
+/* ---------------------------------------------------------
+ PASSWORT KORREKT → FAILED_LOGINS RESET + LAST_LOGIN
+--------------------------------------------------------- */
+
try {
$upd = $pdo->prepare('UPDATE users SET failed_logins = 0, last_login_at = NOW() WHERE id = :id');
$upd->execute([':id' => $user['id']]);
@@ -87,12 +102,10 @@ try {
// Nicht kritisch für den Nutzer
}
-// Session füllen
-if (session_status() !== PHP_SESSION_ACTIVE) {
- @session_start();
-}
+/* ---------------------------------------------------------
+ SESSION FÜLLEN
+--------------------------------------------------------- */
-// Initialen bauen
$firstName = $user['first_name'] ?? '';
$lastName = $user['last_name'] ?? '';
$initials = '';
@@ -118,16 +131,19 @@ $_SESSION['user'] = [
'initials' => $initials,
];
-// Flash für „Willkommen“
+/* ---------------------------------------------------------
+ FLASH & REDIRECT
+--------------------------------------------------------- */
+
flash_set('success', 'Willkommen zurück, ' . ($user['first_name'] ?: 'User') . '!', 'login');
-// Redirect-Ziel prüfen (nur interne Pfade erlauben)
+// Redirect absichern: nur interne Pfade
$target = is_string($redirect) ? trim($redirect) : '/';
-if ($target === '' || $target[0] !== '/') {
+if ($target === '' || !str_starts_with($target, '/')) {
$target = '/';
}
-// Sprache ggf. anfügen, wenn noch nicht als Parameter vorhanden
+// Sprache anhängen
$sep = (strpos($target, '?') === false) ? '?' : '&';
$target = $target . $sep . 'lang=' . urlencode($lang);
diff --git a/src/auth/logout.php b/src/auth/logout.php
index a8cfe10..8392255 100644
--- a/src/auth/logout.php
+++ b/src/auth/logout.php
@@ -1,20 +1,22 @@
prepare('SELECT id FROM users WHERE email = :email LIMIT 1');
$stmt->execute([':email' => $email]);
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
- flash_set('error', 'Es ist ein Fehler bei der Registrierung aufgetreten. Bitte versuche es später erneut.', 'register');
+ flash_set('error', 'Es ist ein technischer Fehler aufgetreten. Bitte später erneut versuchen.', 'register');
header('Location: /login/?lang=' . urlencode($lang) . '&view=register#auth');
exit;
}
@@ -42,10 +54,11 @@ if ($existing) {
exit;
}
-// Username aus E-Mail ableiten (oder einfach die komplette E-Mail nutzen)
-$username = $email;
-// Vor- und Nachname grob aus dem „Name“-Feld splitten
+/* ---------------------------------------------------------
+ NAME AUFTEILEN (Vorname / Nachname)
+--------------------------------------------------------- */
+
$firstName = $name;
$lastName = null;
@@ -55,6 +68,11 @@ if (count($parts) >= 2) {
$lastName = implode(' ', $parts);
}
+/* ---------------------------------------------------------
+ USER ANLEGEN
+--------------------------------------------------------- */
+
+$username = $email;
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
try {
@@ -80,10 +98,10 @@ try {
exit;
}
-// Direkt einloggen
-if (session_status() !== PHP_SESSION_ACTIVE) {
- @session_start();
-}
+
+/* ---------------------------------------------------------
+ DIREKT EINLOGGEN
+--------------------------------------------------------- */
$initials = '';
if ($firstName !== '') {
@@ -107,16 +125,22 @@ $_SESSION['user'] = [
'initials' => $initials,
];
+
+/* ---------------------------------------------------------
+ ERFOLGSMELDUNG + REDIRECT
+--------------------------------------------------------- */
+
flash_set('success', 'Konto erfolgreich erstellt. Willkommen bei USBCheck!', 'login');
-// Redirect-Ziel prüfen (nur interne Pfade)
+// Redirect absichern: nur interne Pfade erlauben
$target = is_string($redirect) ? trim($redirect) : '/';
-if ($target === '' || $target[0] !== '/') {
+if ($target === '' || !str_starts_with($target, '/')) {
$target = '/';
}
-$sep = (strpos($target, '?') === false) ? '?' : '&';
-$target = $target . $sep . 'lang=' . urlencode($lang);
+$separator = (strpos($target, '?') === false) ? '?' : '&';
+$target .= $separator . 'lang=' . urlencode($lang);
header('Location: ' . $target);
exit;
+