diff --git a/Controller/AuthController.php b/Controller/AuthController.php new file mode 100644 index 0000000..b8808e8 --- /dev/null +++ b/Controller/AuthController.php @@ -0,0 +1,151 @@ +model = new AuthModel(); + $this->view = $view; + } + + public function showLoginForm() { + $this->view->setVars([ + 'labels' => [ + "email" => "E-Mail-Adresse", + "password" => "Passwort", + "password_repeat" => "Passwort wiederholen", + "old_password" => "Altes Passwort" + ], + 'errors' => $_SESSION['auth_errors'] ?? [], + 'validData' => $_SESSION['auth_validData'] ?? [] + ]); + unset($_SESSION['auth_errors'], $_SESSION['auth_validData']); + } + + public function showRegistrationForm() { + $this->view->setVars([ + 'labels' => [ + "email" => "E-Mail-Adresse", + "password" => "Passwort", + "password_repeat" => "Passwort wiederholen", + "old_password" => "Altes Passwort" + ], + 'errors' => $_SESSION['auth_errors'] ?? [], + 'validData' => $_SESSION['auth_validData'] ?? [] + ]); + unset($_SESSION['auth_errors'], $_SESSION['auth_validData']); + } + + public function login() { + $email = $_POST['email']; + $password = $_POST['password']; + + $result = $this->model->login($email, $password); + + if ($result === true) { + $_SESSION['user'] = $email; + header('Location: /bibarts/?controller=News&do=showNews'); + exit(); + } else { + $this->view->setVars([ + 'errors' => ['login' => is_string($result) ? $result : "Login fehlgeschlagen."], + 'validData' => ['email' => $email], + 'loginSuccess' => false + ]); + } + } + + public function register() { + $data = [ + 'first_name' => $_POST['vorname'] ?? '', + 'last_name' => $_POST['nachname'] ?? '', + 'street' => $_POST['strasse'] ?? '', + 'house_number' => $_POST['hausnr'] ?? '', + 'postal_code' => $_POST['plz'] ?? '', + 'city' => $_POST['ort'] ?? '', + 'country' => $_POST['land'] ?? '', + 'phone' => $_POST['tel'] ?? '', + 'email' => $_POST['email'] ?? '', + 'password' => $_POST['password'] ?? '', + 'password_repeat' => $_POST['password_repeat'] ?? '', + 'is_admin' => $_POST['isAdmin'] ?? false, + ]; + + $result = $this->model->register($data); + + if ($result === true) { + $this->view->setVars(['success' => 'Registrierung erfolgreich!']); + $this->view->render('Auth/showLoginForm'); + exit; + } else { + $errors['register'] = is_string($result) ? $result : "Registrierung fehlgeschlagen."; + $this->view->setVars(['errors' => $errors, 'validData' => $data]); + $this->view->render('Auth/showRegistrationForm'); + exit; + } + } + + public function forgotPassword() { + $email = $_POST['email'] ?? ''; + if (empty($email)) { + $_SESSION['auth_errors']['email'] = "Bitte E-Mail-Adresse angeben."; + header("Location: /?controller=Auth&do=showAuthForm"); + exit; + } + $this->model->pwForgot($email); + header("Location: /?controller=Auth&do=showConfirmation&msg=pwforgot"); + exit; + } + + public function changePassword() + { + $email = $_POST['email'] ?? ''; + $oldpw = $_POST['old_password'] ?? ''; + $newpw = $_POST['password'] ?? ''; + $repeat = $_POST['password_repeat'] ?? ''; + + if (!$this->model->checkDoublePw($newpw, $repeat)) { + $_SESSION['auth_errors']['password'] = "Neue Passwörter stimmen nicht überein."; + header("Location: /?controller=Auth&do=showAuthForm"); + exit; + } + + $result = $this->model->updatePassword($email, $oldpw, $newpw); + + if ($result === true) { + header("Location: /?controller=Auth&do=showConfirmation&msg=pwchange"); + exit; + } else { + $_SESSION['auth_errors']['password'] = is_string($result) ? $result : "Fehler beim Aktualisieren des Passworts."; + header("Location: /?controller=Auth&do=showAuthForm"); + exit; + } + } + + public function showConfirmation() + { + $messages = [ + 'login' => "Login erfolgreich.", + 'register' => "Registrierung erfolgreich.", + 'pwforgot' => "Ein temporäres Passwort wurde an Ihre E-Mail gesendet.", + 'pwchange' => "Passwort erfolgreich geändert." + ]; + $msgKey = $_GET['msg'] ?? ''; + $message = $messages[$msgKey] ?? "Aktion erfolgreich."; + $this->view->setVars(['message' => $message]); + $this->view->render('auth/confirmation'); + } + + public function logout() { + unset($_SESSION['user']); + session_destroy(); + header('Location: /bibarts/?controller=Auth&do=showLoginForm'); + exit(); + } +} \ No newline at end of file diff --git a/Controller/LoginController.php b/Controller/LoginController.php deleted file mode 100644 index 6540e35..0000000 --- a/Controller/LoginController.php +++ /dev/null @@ -1,12 +0,0 @@ -linkDB(); + $sql = "SELECT email, password, valid_until FROM user WHERE email = :email"; + $params = [":email" => $email]; + + try { + $sth = $pdo->prepare($sql); + $sth->execute($params); + $user = $sth->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + new \Blog\Library\ErrorMsg("Fehler beim Abrufen der Benutzerdaten.", $e); + return "Interner Datenbankfehler."; // Nur für Debug sichtbar machen, sonst besser allgemein halten + } + + if (!$user) { + return "Benutzer mit dieser E-Mail wurde nicht gefunden."; + } + + if (!password_verify($password, $user['password'])) { + return "Das eingegebene Passwort ist falsch."; + } + + try { + $now = new DateTime(); + $validUntil = new DateTime($user['valid_until']); + + if ($now > $validUntil) { + return "Ihr Passwort ist abgelaufen. Bitte setzen Sie ein neues über \"Passwort vergessen\"."; + } + } catch (\Exception $e) { + new \Blog\Library\ErrorMsg("Fehler beim Verarbeiten des Gültigkeitsdatums.", $e); + return "Fehler bei der Passwortprüfung."; + } + + return true; + } + + public function register($data) { + if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { + return "Bitte geben Sie eine gültige E-Mail ein."; + } + + $requiredFields = [ + 'email', 'password', 'street', 'house_number', 'city', 'postal_code', + 'country', 'first_name', 'last_name', 'phone' + ]; + + foreach ($requiredFields as $field) { + if (empty($data[$field])) { + return "Bitte füllen Sie alle Felder aus."; + } + } + + if ($this->userExistsByEmail($data['email'])) { + return "Ein Account mit dieser E-Mail existiert bereits."; + } + + // Passwort-Validierung + if (!$this->checkDoublePw($data['password'], $data['password_repeat'])) { + return "Passwörter stimmen nicht überein."; + } + + if ($this->pwRequirementCheck($data['password']) !== true) { + return "Passwort muss mindestens 8 Zeichen lang sein und mindestens ein Großbuchstabe, ein Kleinbuchstabe, eine Zahl und ein Sonderzeichen enthalten."; + } + + $hashedPassword = password_hash($data['password'], PASSWORD_DEFAULT); + + $sql = "INSERT INTO user (email, password, street, house_number, city, postal_code, country, first_name, last_name, phone, is_admin) + VALUES (:email, :password, :street, :house_number, :city, :postal_code, :country, :first_name, :last_name, :phone, :is_admin)"; + + $params = [ + ':email' => $data['email'], + ':password' => $hashedPassword, + ':street' => $data['street'], + ':house_number' => $data['house_number'], + ':city' => $data['city'], + ':postal_code'=> $data['postal_code'], + ':country'=> $data['country'], + ':first_name' => $data['first_name'], + ':last_name'=> $data['last_name'], + ':phone' => $data['phone'], + ':is_admin' => $data['is_admin'] ? 1 : 0, + ]; + + try { + $pdo = $this->linkDB(); + $stmt = $pdo->prepare($sql); + $stmt->execute($params); + return true; + } catch (PDOException $e) { + new \Blog\Library\ErrorMsg("Fehler beim Schreiben der Daten.", $e); + return false; + } + } + + private function userExistsByEmail($email) { + try { + $pdo = $this->linkDB(); + + $sql = "SELECT user_id FROM user WHERE email = :email"; + $params = [':email' => $email]; + + $stmt = $pdo->prepare($sql); + $stmt->execute($params); + + return (bool) $stmt->fetch(); + } catch (\PDOException $e) { + new \Blog\Library\ErrorMsg("Fehler bei der E-Mail-Prüfung", $e); + return false; + } + } + + public function pwForgot($email){ + $randomPw = bin2hex(random_bytes(12 / 2)); + $hashedPassword = password_hash($randomPw, PASSWORD_DEFAULT); + + $this->forgottenPwUpdate($email, $hashedPassword); + + $betreff = "Passwort zurücksetzen bei bibArts"; + $nachricht = "Hallo,\n\nhier ihr temporäres Passwort:\n\n $randomPw \n\n Bitte beachten Sie, dass das Passwort nur 2 stunden Gülltig ist. \nViele Grüße,\nbibArts Team"; + + $header = "From: noreply@edu.bib.de\r\n"; + $header .= "Content-Type: text/plain; charset=UTF-8\r\n"; + + $maxTries = 5; + $try = 0; + $success = false; + + while ($try < $maxTries && !$success) { + $erfolg = mail($email, $betreff, $nachricht, $header); + $try++; + if (!$erfolg) { + error_log("Mailversuch $try an $email fehlgeschlagen."); + sleep(1); + } + } + } + + private function forgottenPwUpdate($email, $hashedPassword) { + try{ + $pdo = $this->linkDB(); + + $sqlCheck = "SELECT COUNT(*) FROM user WHERE email = :email"; + $stmt = $pdo->prepare($sqlCheck); + $stmt->execute([':email' => $email]); + if ($stmt->fetchColumn() == 0) { + return false; + } + + $validUntil = (new DateTime())->add(new DateInterval('PT2H'))->format('Y-m-d H:i:s'); + + + $sql = "UPDATE user + SET password = :password, valid_until = :valid_until + WHERE email = :email"; + + $stmt = $pdo->prepare($sql); + $params = [ + ':email' => $email, + ':password' => $hashedPassword, + ':valid_until' => $validUntil + ]; + return $stmt->execute($params); + } catch (PDOException $e) { + new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren der Daten.", $e); + die; + return false; + } + } + + public function updatePassword($email, $oldpw, $newpw){ + if(!$this->login($email, $oldpw)) { + return false; + } + + $requiredFields = [$email, $oldpw, $newpw]; + foreach ($requiredFields as $field) { + if (empty($field)) { + return "Bitte füllen Sie alle Felder aus"; + } + } + $hashedPassword = password_hash($newpw, PASSWORD_DEFAULT); + + $sql = "UPDATE user SET password = :password WHERE email = :email"; + + try{ + $pdo = $this->linkDB(); + $stmt = $pdo->prepare($sql); + $params = [ + ':email' => $email, + ':password' => $hashedPassword, + ]; + return $stmt->execute($params); + } catch (PDOException $e) { + new \Blog\Library\ErrorMsg("Fehler beim Schreiben der Daten.", $e); + die; + } + } + + public function checkDoublePw($password1, $password2){ + if($password1 === $password2){ + return true; + } + else + return false; + } + + public function pwRequirementCheck($password){ + $error = []; + + if(strlen($password) <= 8) + $error[] = "min 8 Charackter"; + if(!preg_match("/[A-Z]/", $password)) + $error[] = "min one large Character"; + if(!preg_match("/[a-z]/", $password)) + $error[] = "min one small charakter"; + if(!preg_match("/[0-9]/", $password)) + $error[] = "min one number"; + if(!preg_match("[^a-zA-Z0-9\s]", $password)); + $error[] = "min one special character"; + + if(empty($error)) + return true; + else + return $error; + } +} diff --git a/Views/Login/showLoginPage.phtml b/Views/Auth/showLoginForm.phtml similarity index 100% rename from Views/Login/showLoginPage.phtml rename to Views/Auth/showLoginForm.phtml diff --git a/Views/Login/showPasswortVergessen.phtml b/Views/Auth/showPasswortVergessen.phtml similarity index 100% rename from Views/Login/showPasswortVergessen.phtml rename to Views/Auth/showPasswortVergessen.phtml