Files
usbcheck.it/src/auth/login.php
2025-11-28 02:46:51 +01:00

191 lines
5.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// src/auth/login.php
// wird durch public/auth/login.php aufgerufen
// Basis-Setup: Session, $pdo, flash_*, Sprachlogik etc.
require_once $_SERVER['DOCUMENT_ROOT']. '/../config/fileload.php';
// Sprache aus der zentralen Sprachlogik holen
// (fileload.php sollte $GLOBALS['lang'] anhand von URL, Session, Browser etc. setzen)
$lang = $GLOBALS['lang'] ?? 'en';
// Nur POST zulassen alles andere zurück zur Login-Seite
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$target = '/login/?lang=' . urlencode($lang) . '&view=login#auth';
header('Location: ' . $target);
exit;
}
// ---------------------------------------------------------
// Form-Daten einsammeln
// ---------------------------------------------------------
$email = trim((string)($_POST['email'] ?? ''));
$password = (string)($_POST['password'] ?? '');
$redirect = $_POST['redirect'] ?? '/';
// (Optional) Falls das Formular noch ein <input name="lang"> hat,
// kannst du das nutzen, falls kein $GLOBALS['lang'] gesetzt ist:
if (empty($lang) && !empty($_POST['lang'])) {
$lang = substr((string)$_POST['lang'], 0, 2);
}
// Minimal-Validierung
if (
$email === '' ||
!filter_var($email, FILTER_VALIDATE_EMAIL) ||
$password === ''
) {
flash_set('error', 'Bitte E-Mail-Adresse und Passwort eingeben.', 'login');
header('Location: /login/?lang=' . urlencode($lang) . '&view=login#auth');
exit;
}
/* ---------------------------------------------------------
USER LADEN
--------------------------------------------------------- */
try {
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email LIMIT 1');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
// DB-Fehler → generische Meldung
flash_set('error', 'Es ist ein Fehler beim Login aufgetreten. Bitte versuche es später erneut.', 'login');
header('Location: /login/?lang=' . urlencode($lang) . '&view=login#auth');
exit;
}
if (!$user) {
flash_set('error', 'E-Mail oder Passwort ist falsch.', 'login');
header('Location: /login/?lang=' . urlencode($lang) . '&view=login#auth');
exit;
}
/* ---------------------------------------------------------
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
--------------------------------------------------------- */
if (!password_verify($password, $user['password_hash'])) {
// Fehlversuche hochzählen
try {
$failed = (int)($user['failed_logins'] ?? 0) + 1;
$lock = 0;
if ($failed >= 5) {
$lock = 1;
}
$upd = $pdo->prepare('UPDATE users SET failed_logins = :failed, is_locked = :locked WHERE id = :id');
$upd->execute([
':failed' => $failed,
':locked' => $lock,
':id' => $user['id'],
]);
} catch (Throwable $e) {
// Nicht kritisch, Meldung reicht
}
$msg = 'E-Mail oder Passwort ist falsch.';
if (($user['failed_logins'] ?? 0) + 1 >= 5) {
$msg = 'Zu viele Fehlversuche. Dein Konto wurde vorübergehend gesperrt.';
}
flash_set('error', $msg, 'login');
header('Location: /login/?lang=' . urlencode($lang) . '&view=login#auth');
exit;
}
/* ---------------------------------------------------------
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']]);
} catch (Throwable $e) {
// Nicht kritisch für den Nutzer
}
/* ---------------------------------------------------------
SESSION FÜLLEN
--------------------------------------------------------- */
$firstName = $user['first_name'] ?? '';
$lastName = $user['last_name'] ?? '';
$initials = '';
if ($firstName !== '') {
$initials .= mb_substr($firstName, 0, 1);
}
if ($lastName !== '') {
$initials .= mb_substr($lastName, 0, 1);
}
if ($initials === '') {
$initials = mb_substr($user['username'] ?? $user['email'], 0, 2);
}
$initials = mb_strtoupper($initials);
$_SESSION['user'] = [
'id' => $user['id'],
'email' => $user['email'],
'username' => $user['username'],
'first_name' => $user['first_name'],
'last_name' => $user['last_name'],
'plan' => $user['plan'] ?? 'free',
'initials' => $initials,
];
/* ---------------------------------------------------------
FLASH & SMART REDIRECT
--------------------------------------------------------- */
flash_set('success', 'Willkommen zurück, ' . ($user['first_name'] ?: 'User') . '!', 'login');
// redirect normalisieren
$redirect = trim((string)($redirect ?? ''));
// Flag: sollen wir stattdessen aufs Dashboard?
$goDashboard = false;
// 1) redirect leer → Dashboard
if ($redirect === '') {
$goDashboard = true;
}
// 2) redirect zeigt auf /login → Dashboard (Endlosschleife vermeiden)
if (!$goDashboard && preg_match('#^/login(/|\?|$)#i', $redirect)) {
$goDashboard = true;
}
// 3) redirect ist keine interne URL → Dashboard (Sicherheit!)
if (!$goDashboard && strpos($redirect, '/') !== 0) {
$goDashboard = true;
}
// 4) Finales Ziel bestimmen
if ($goDashboard) {
// Immer Dashboard-Seite
$target = '/dashboard/?lang=' . urlencode($lang);
} else {
// Internes Ziel, Sprache anhängen falls noch nicht vorhanden
if (strpos($redirect, 'lang=') === false) {
$sep = (strpos($redirect, '?') === false) ? '?' : '&';
$redirect = $redirect . $sep . 'lang=' . urlencode($lang);
}
$target = $redirect;
}
header('Location: ' . $target);
exit;