94 lines
3.8 KiB
PHP
94 lines
3.8 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
require_once __DIR__ . '/includes/bootstrap.php';
|
||
pnpaas_session_start();
|
||
|
||
if (!empty($_SESSION['pnpaas_admin'])) {
|
||
header('Location: dashboard.php');
|
||
exit;
|
||
}
|
||
|
||
if (empty($_SESSION['csrf_token'])) {
|
||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||
}
|
||
|
||
$error = null;
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
$csrf = (string)($_POST['csrf_token'] ?? '');
|
||
$login = trim((string)($_POST['username'] ?? ''));
|
||
$password = (string)($_POST['password'] ?? '');
|
||
|
||
if (!hash_equals((string)$_SESSION['csrf_token'], $csrf)) {
|
||
$error = 'Die Sitzung ist abgelaufen. Bitte laden Sie die Seite neu.';
|
||
} elseif ($login === '' || $password === '') {
|
||
$error = 'Bitte Benutzername oder E-Mail-Adresse und Passwort eingeben.';
|
||
} else {
|
||
try {
|
||
$statement = pnpaas_db()->prepare(
|
||
'SELECT id, username, password_hash, role, status
|
||
FROM users
|
||
WHERE (username = :login_username OR email = :login_email) AND status = :status
|
||
LIMIT 1'
|
||
);
|
||
$statement->execute([
|
||
'login_username' => $login,
|
||
'login_email' => $login,
|
||
'status' => 'active',
|
||
]);
|
||
$user = $statement->fetch();
|
||
|
||
if (is_array($user) && password_verify($password, (string)$user['password_hash'])) {
|
||
session_regenerate_id(true);
|
||
$_SESSION['pnpaas_admin'] = (string)$user['username'];
|
||
$_SESSION['pnpaas_user_id'] = (int)$user['id'];
|
||
$_SESSION['pnpaas_role'] = (string)$user['role'];
|
||
header('Location: dashboard.php');
|
||
exit;
|
||
}
|
||
$error = 'Benutzername, E-Mail-Adresse oder Passwort ist nicht korrekt.';
|
||
} catch (Throwable $exception) {
|
||
error_log('PnPaaS login error: ' . $exception->getMessage());
|
||
$error = 'Die Anmeldung ist derzeit nicht möglich. Bitte prüfen Sie die Serverkonfiguration.';
|
||
}
|
||
}
|
||
}
|
||
?>
|
||
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>PnPaaS – Administration</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500;600&family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="assets/style.css">
|
||
</head>
|
||
<body class="auth-page">
|
||
<main class="auth-card" aria-labelledby="login-title">
|
||
<div class="brand-mark" aria-hidden="true">✦</div>
|
||
<p class="eyebrow">PnPaaS Administration</p>
|
||
<h1 id="login-title">Anmelden</h1>
|
||
<p class="intro">Verwalten Sie FoundryVTT-Instanzen und Benutzerzugänge zentral.</p>
|
||
|
||
<?php if ($error !== null): ?>
|
||
<div class="alert alert-error" role="alert"><?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?></div>
|
||
<?php endif; ?>
|
||
|
||
<form method="post" action="index.php" class="login-form">
|
||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars((string)$_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8') ?>">
|
||
<label for="username">Benutzername oder E-Mail-Adresse</label>
|
||
<input id="username" name="username" type="text" autocomplete="username" required autofocus value="<?= htmlspecialchars((string)($_POST['username'] ?? ''), ENT_QUOTES, 'UTF-8') ?>">
|
||
|
||
<label for="password">Passwort</label>
|
||
<input id="password" name="password" type="password" autocomplete="current-password" required>
|
||
|
||
<button type="submit">Anmelden</button>
|
||
</form>
|
||
<p class="form-footer"><a href="forgot-password.php">Passwort vergessen?</a> · <a href="register.php">Konto registrieren</a></p>
|
||
</main>
|
||
</body>
|
||
</html>
|