Display-Seiten: Gäste holen sich den Zugang selbst
Für Empfang, Lobby oder Tagungsraum lässt sich je Site eine öffentliche Seite anlegen (kiosk.php), die auf einem Bildschirm oder Tablet läuft: ein großer Knopf, ein Klick, ein Zugangscode mit QR-Code. Nach einer einstellbaren Anzeigedauer springt der Bildschirm zurück, damit der nächste Gast nicht den Code seines Vorgängers sieht. Verwaltung unter Administration → Display-Seiten: - Site und optionales Voucher-Profil (bestimmt Laufzeit, Geräte, QoS) - eigene Überschrift und Text für den Bildschirm - Codes pro Tag, Wartezeit zwischen zwei Codes, Anzeigedauer - geheimer Link zum Kopieren, als QR-Code anzeigbar und jederzeit erneuerbar (der alte Link gilt dann sofort nicht mehr) Absicherung: der Link ist der Zugang, deshalb Tageslimit und Wartezeit je Display, CSRF-Token am Formular, `noindex` im Kopf und ein Eintrag im Audit-Log für jeden ausgegebenen Code. Webhooks werden für Kiosk-Codes bewusst nicht ausgelöst – ein Empfangsdisplay würde den Kanal fluten. Technik: - neue Tabelle `kiosks`, `vouchers.kiosk_id` hält die Herkunft fest (Migration 0005, database.sql nachgezogen) - includes/Kiosk.php kapselt Token, Limits und Profil-Auflösung - includes/VoucherService.php bündelt die Voucher-Erstellung, die vorher in index.php lag und für den Kiosk ein zweites Mal nötig gewesen wäre - Startbildschirm zeigt zusätzlich einen QR auf sich selbst, damit Gäste die Seite am eigenen Handy öffnen können Tests: 9 neue Fälle für Token-Prüfung, Wartezeit, Tageslimit und Profil-Auflösung (38 Tests gesamt), PHPStan deckt Kiosk.php mit ab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5d72febadc
commit
61810eb050
30 changed files with 1360 additions and 29 deletions
30
index.php
30
index.php
|
|
@ -20,6 +20,7 @@ require_once __DIR__ . '/includes/Notifier.php';
|
|||
require_once __DIR__ . '/includes/Captcha.php';
|
||||
require_once __DIR__ . '/includes/Sms.php';
|
||||
require_once __DIR__ . '/includes/Ui.php';
|
||||
require_once __DIR__ . '/includes/VoucherService.php';
|
||||
require_once __DIR__ . '/includes/I18n.php';
|
||||
|
||||
$auth = new Auth();
|
||||
|
|
@ -115,34 +116,9 @@ if ($auth->isLoggedIn()) {
|
|||
|
||||
$autoSelectSite = (count($sites) === 1) ? $sites[0]['id'] : 0;
|
||||
|
||||
// Helper: create one voucher and save to DB
|
||||
// Voucher-Erstellung liegt gebuendelt in includes/VoucherService.php.
|
||||
function doCreateVoucher($db, $site, $voucherName, $maxUses, $expireMinutes, $userId, $qos = []) {
|
||||
$datum = date('Y-m-d');
|
||||
$fullName = $datum . '_' . $voucherName;
|
||||
$controller = new UniFiController(
|
||||
$site['unifi_controller_url'],
|
||||
$site['unifi_username'],
|
||||
Crypto::decrypt($site['unifi_password']),
|
||||
$site['site_id']
|
||||
);
|
||||
$voucher = $controller->createVoucher($fullName, $maxUses, $expireMinutes, $qos);
|
||||
if (!is_array($voucher) || empty($voucher['formatted_code'])) {
|
||||
throw new Exception(__('error_voucher_invalid'));
|
||||
}
|
||||
$db->execute(
|
||||
"INSERT INTO vouchers (site_id, user_id, voucher_code, voucher_name, max_uses, expire_minutes, unifi_voucher_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
[$site['id'], $userId, $voucher['code'], $fullName, $maxUses, $expireMinutes, $voucher['unifi_id'] ?? null]
|
||||
);
|
||||
$expiryTs = time() + ($expireMinutes * 60);
|
||||
return [
|
||||
'code' => $voucher['formatted_code'],
|
||||
'site_name' => $site['name'],
|
||||
'max_uses' => $maxUses,
|
||||
'expire_min' => $expireMinutes,
|
||||
'expiry_date' => date('d.m.Y', $expiryTs),
|
||||
'expiry_time' => date('H:i', $expiryTs),
|
||||
];
|
||||
return VoucherService::create($db, $site, $voucherName, $maxUses, $expireMinutes, $userId, $qos);
|
||||
}
|
||||
|
||||
// Single voucher
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue