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; +