Docker Compose mit drei Services (nginx auf Port 8000), Migrationsmechanik, Update- und Backup-Skript. Anwendung: Router mit CSRF-Prüfung, Anmeldung und Ersteinrichtung, zentraler Einstellungsdialog mit Reitern, ein- und ausschaltbares Debug-Log mit Maskierung von Zugangsdaten. Layout nach Vorbild des FinanzManagers: feste Navigation links, Werkzeugleiste oben, Tab-Leiste; Farbschema hell/dunkel/System. Tests: 51 PHP-Prüfungen und 7 Playwright-Tests, alle grün.
92 lines
2.9 KiB
PHP
92 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Finanzmanager\Controllers;
|
|
|
|
use Finanzmanager\Auth;
|
|
use Finanzmanager\Models\Benutzer;
|
|
use Finanzmanager\Services\DebugLog;
|
|
use Finanzmanager\View;
|
|
|
|
class LoginController extends BaseController
|
|
{
|
|
public function formular(): void
|
|
{
|
|
Auth::startSession();
|
|
|
|
if (Auth::benutzerId() !== null) {
|
|
View::redirect('/');
|
|
}
|
|
|
|
// Frische Installation: solange kein Benutzer existiert, führt der
|
|
// Weg zur Ersteinrichtung statt zur Anmeldung.
|
|
if (Benutzer::anzahl() === 0) {
|
|
View::redirect('/einrichtung');
|
|
}
|
|
|
|
$this->render('auth/login.php', ['titel' => 'Anmeldung']);
|
|
}
|
|
|
|
public function anmelden(): void
|
|
{
|
|
$benutzername = $this->post('benutzername');
|
|
$passwort = $_POST['passwort'] ?? '';
|
|
|
|
$benutzer = Benutzer::pruefeAnmeldung($benutzername, is_string($passwort) ? $passwort : '');
|
|
|
|
if ($benutzer === null) {
|
|
DebugLog::schreibe('auth', 'Anmeldung fehlgeschlagen', ['benutzername' => $benutzername]);
|
|
// Bewusst unspezifisch: kein Hinweis darauf, ob der Name existiert.
|
|
View::redirect('/login', 'Benutzername oder Passwort ist falsch.', 'fehler');
|
|
}
|
|
|
|
Auth::anmelden((int)$benutzer['id']);
|
|
Benutzer::anmeldungVermerken((int)$benutzer['id']);
|
|
DebugLog::schreibe('auth', 'Anmeldung erfolgreich', ['benutzer_id' => $benutzer['id']]);
|
|
|
|
View::redirect('/');
|
|
}
|
|
|
|
public function abmelden(): void
|
|
{
|
|
Auth::abmelden();
|
|
View::redirect('/login', 'Du bist abgemeldet.');
|
|
}
|
|
|
|
/** Ersteinrichtung: legt den ersten Benutzer an. Danach nicht mehr erreichbar. */
|
|
public function einrichtungFormular(): void
|
|
{
|
|
if (Benutzer::anzahl() > 0) {
|
|
View::redirect('/login');
|
|
}
|
|
$this->render('auth/einrichtung.php', ['titel' => 'Ersteinrichtung']);
|
|
}
|
|
|
|
public function einrichtungSpeichern(): void
|
|
{
|
|
if (Benutzer::anzahl() > 0) {
|
|
View::redirect('/login');
|
|
}
|
|
|
|
$benutzername = $this->post('benutzername');
|
|
$passwort = (string)($_POST['passwort'] ?? '');
|
|
$wiederholung = (string)($_POST['passwort_wdh'] ?? '');
|
|
|
|
$fehler = match (true) {
|
|
$benutzername === '' => 'Bitte einen Benutzernamen angeben.',
|
|
mb_strlen($passwort) < 10 => 'Das Passwort muss mindestens 10 Zeichen lang sein.',
|
|
$passwort !== $wiederholung => 'Die beiden Passwörter stimmen nicht überein.',
|
|
default => null,
|
|
};
|
|
|
|
if ($fehler !== null) {
|
|
View::redirect('/einrichtung', $fehler, 'fehler');
|
|
}
|
|
|
|
$id = Benutzer::anlegen($benutzername, $passwort, $this->post('anzeigename'));
|
|
Auth::anmelden($id);
|
|
|
|
View::redirect('/', 'Willkommen! Der Zugang ist eingerichtet.');
|
|
}
|
|
}
|