Files
deskhub/DeskHub-Webseite/login.php
T
2026-10-24 20:14:46 +00:00

160 lines
7.0 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
require_once __DIR__ . '/includes/bootstrap.php';
if (current_user()) { redirect('/home.php'); }
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !csrf_valid()) {
$errors[] = 'Die Anmeldeseite war zu lange geöffnet und die Sitzung ist abgelaufen. Bitte melden Sie sich jetzt noch einmal an.';
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = trim($_POST['email'] ?? '');
$pass = $_POST['password'] ?? '';
if (!rate_limit_check('login_attempt', client_ip(), 10, 15)) {
$errors[] = 'Zu viele Anmeldeversuche. Bitte versuchen Sie es in einigen Minuten erneut.';
} elseif ($email && !rate_limit_check('login_email', strtolower($email), 5, 15)) {
$errors[] = 'Zu viele Anmeldeversuche für dieses Konto. Bitte warten Sie einige Minuten.';
} else {
$stmt = get_db()->prepare('SELECT * FROM users WHERE LOWER(email) = LOWER(?)');
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($pass, $user['password_hash'])) {
rate_limit_reset('login_email', strtolower($email));
customer_login($user);
redirect('/home.php');
}
$errors[] = 'E-Mail-Adresse oder Passwort ist falsch.';
}
}
$logo = get_setting('logo_path');
$banner = get_setting('banner_path');
$displayName = get_setting('display_name', config()['site']['name']);
$kbEnabled = get_setting('kb_enabled', '1') === '1';
$privacyLabel = get_setting('footer_privacy_label', 'Datenschutz');
$privacyUrl = get_setting('footer_privacy_url', '');
$privacyHtml = get_setting('footer_privacy_html', '');
$imprintLabel = get_setting('footer_imprint_label', 'Impressum');
$imprintUrl = get_setting('footer_imprint_url', '');
$imprintHtml = get_setting('footer_imprint_html', '');
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Anmelden – <?= e($displayName) ?></title>
<link rel="stylesheet" href="/assets/css/style.css?v=<?= @filemtime(__DIR__ . "/assets/css/style.css") ?: time() ?>">
<?php $customThemeStylesheet = active_custom_theme_stylesheet(); ?>
<?php if ($customThemeStylesheet): ?>
<link rel="stylesheet" href="<?= e($customThemeStylesheet) ?>">
<?php endif; ?>
<link rel="manifest" href="/manifest.php">
<meta name="theme-color" content="#0f6f6a">
<meta name="apple-mobile-web-app-capable" content="yes">
<?= site_icon_links() ?>
<script>if('serviceWorker'in navigator){navigator.serviceWorker.register('/sw.js').catch(function(){});}</script>
<?php if (!$banner && !$customThemeStylesheet): ?>
<style>
.login-bg { background: linear-gradient(135deg, #16202a 0%, #20303d 55%, #16202a 100%); }
</style>
<?php endif; ?>
</head>
<body class="login-page" style="margin:0; display:flex; flex-direction:column; min-height:100vh">
<?= i18n_switcher_html('floating') ?>
<!-- Header -->
<header class="site-header">
<div class="topbar-thin">
<span class="welcome">Willkommen, Gast</span>
<nav>
<a href="/home.php">Supportcenter-Startseite</a>
<a href="/ticket_new.php">Neues Ticket eröffnen</a>
<a href="/ticket_lookup.php">Ticketstatus überprüfen</a>
<?php if ($kbEnabled): ?><a href="/kb.php">Wissensdatenbank</a><?php endif; ?>
<a href="/login.php" class="active">Anmelden</a>
</nav>
</div>
<div class="logo-row" style="display:flex; align-items:center; gap:12px">
<a href="/home.php" style="line-height:0; flex-shrink:0">
<?php if ($logo): ?>
<img src="<?= e($logo) ?>" alt="<?= e($displayName) ?>">
<?php else: ?>
<span class="text-brand">Desk<span>Hub</span></span>
<?php endif; ?>
</a>
<?php if ($logo && $displayName && get_setting('logo_hide_name', '0') !== '1'): ?>
<span style="font-size:1.15rem; font-weight:700; color:var(--ink); letter-spacing:-.01em"><?= e($displayName) ?></span>
<?php endif; ?>
</div>
</header>
<!-- Login-Bereich: volle Breite, dunkler Hintergrund -->
<div class="login-bg login-screen<?= $banner ? ' has-image' : '' ?>"<?php if ($banner): ?> style="background-image:url('<?= e($banner) ?>');"<?php endif; ?>>
<div class="auth-card login-card">
<div class="brand-block brand-block-lg">
<?php if ($logo): ?>
<img src="<?= e($logo) ?>" alt="<?= e($displayName) ?>">
<?php else: ?>
<span class="brand-block-text">Desk<span>Hub</span></span>
<?php endif; ?>
</div>
<h1>Anmelden</h1>
<p class="sub">Melden Sie sich an, um alle Ihre Tickets im Überblick zu sehen.</p>
<?php foreach ($errors as $err): ?>
<div class="flash error"><?= e($err) ?></div>
<?php endforeach; ?>
<?php foreach (get_flashes() as $f): ?>
<div class="flash <?= e($f['type']) ?>"><?= e($f['message']) ?></div>
<?php endforeach; ?>
<form method="post">
<?= csrf_field() ?>
<label for="email">E-Mail-Adresse</label>
<input type="email" id="email" name="email" required autofocus autocomplete="email" autocapitalize="none" autocorrect="off" spellcheck="false">
<label for="password">Passwort</label>
<input type="password" id="password" name="password" required autocomplete="current-password" autocapitalize="none" autocorrect="off" spellcheck="false">
<div style="text-align:right; margin-top:6px">
<a href="/forgot_password.php" class="login-forgot">Passwort vergessen?</a>
</div>
<div class="btn-row">
<button type="submit" class="btn login-submit">Anmelden</button>
</div>
</form>
<div class="login-links">
<span>Noch kein Konto? <a href="/register.php">Jetzt registrieren</a></span>
<span class="login-guest-links">Kein Konto nötig: <a href="/ticket_new.php">Ticket erstellen</a> · <a href="/ticket_lookup.php">Status prüfen</a></span>
<a href="/staff/login.php" class="login-staff-link">Mitarbeiter-Login →</a>
</div>
</div>
</div>
<!-- Footer -->
<footer class="public-footer">
<?php if ($privacyUrl || $privacyHtml || $imprintUrl || $imprintHtml): ?>
<nav style="margin-bottom:8px; display:flex; gap:20px; justify-content:center; flex-wrap:wrap">
<?php if ($privacyUrl || $privacyHtml): ?>
<a href="<?= $privacyUrl ? e($privacyUrl) : '#' ?>" style="color:#6b7280; font-size:.78rem"><?= e($privacyLabel) ?></a>
<?php endif; ?>
<?php if ($imprintUrl || $imprintHtml): ?>
<a href="<?= $imprintUrl ? e($imprintUrl) : '#' ?>" style="color:#6b7280; font-size:.78rem"><?= e($imprintLabel) ?></a>
<?php endif; ?>
</nav>
<?php endif; ?>
Copyright &copy; <?= date('Y') ?> <?= e($displayName) ?> &ndash; Alle Rechte vorbehalten.
</footer>
<script>
// Hält die Sitzung der offenen Anmeldeseite am Leben: Der Server räumt ungenutzte Sitzungen nach etwa 24 Minuten auf, und dann wäre das
// Anmeldeformular ungültig. Ein kurzer Abruf alle 8 Minuten genügt.
setInterval(function () { fetch('/staff/session_ping.php?check=1', { credentials: 'same-origin', cache: 'no-store' }).catch(function () {}); }, 8 * 60 * 1000);
</script>
</body>
</html>