requireAdmin(); I18n::init(); $db = Database::getInstance(); $appTitle = $db->getSetting('app_title', 'UniFi Voucher System'); // AJAX: SMTP-Test-E-Mail senden if (isset($_POST['ajax_smtp_test'])) { header('Content-Type: application/json'); if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { echo json_encode(['success' => false, 'message' => __('error_csrf')]); exit; } $to = trim($_POST['test_email'] ?? ''); if (!filter_var($to, FILTER_VALIDATE_EMAIL)) { echo json_encode(['success' => false, 'message' => __('error_email_invalid')]); exit; } $mailer = new Mailer(); $ok = $mailer->sendTestEmail($to); echo json_encode([ 'success' => $ok, 'message' => $ok ? "Test-E-Mail wurde an {$to} gesendet." : 'Versand fehlgeschlagen. Prüfen Sie die SMTP-Einstellungen.' ]); exit; } $error = ''; $success = ''; // Einstellungen speichern if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) { if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { $error = __('error_csrf'); } else { try { $settings = []; $formType = $_POST['form_type'] ?? ''; if ($formType === 'general') { $settings['app_title'] = trim($_POST['app_title'] ?? ''); $settings['logo_url'] = trim($_POST['logo_url'] ?? ''); $settings['favicon_url'] = trim($_POST['favicon_url'] ?? ''); $settings['instruction_header'] = trim($_POST['instruction_header'] ?? ''); $settings['instruction_text'] = $_POST['instruction_text'] ?? ''; $settings['public_access'] = isset($_POST['public_access']) ? '1' : '0'; } if ($formType === 'defaults') { $expMin = (int)($_POST['default_expire_minutes'] ?? 480); $defDev = (int)($_POST['default_max_uses'] ?? 1); $maxDev = (int)($_POST['max_uses_limit'] ?? 10); if ($expMin < 1) $expMin = 480; if ($defDev < 1) $defDev = 1; if ($maxDev < 1) $maxDev = 10; $settings['default_expire_minutes'] = (string)$expMin; $settings['default_max_uses'] = (string)$defDev; $settings['max_uses_limit'] = (string)$maxDev; } if ($formType === 'm365') { $settings['m365_client_id'] = trim($_POST['m365_client_id'] ?? ''); // Secret nur aktualisieren, wenn eines eingegeben wurde – es wird // (wie das SMTP-Passwort) nicht mehr ins Formular zurueckgegeben. if (!empty($_POST['m365_client_secret'])) { $settings['m365_client_secret'] = trim($_POST['m365_client_secret']); } $settings['m365_tenant_id'] = trim($_POST['m365_tenant_id'] ?? ''); } if ($formType === 'smtp') { $settings['smtp_enabled'] = isset($_POST['smtp_enabled']) ? '1' : '0'; $settings['smtp_host'] = trim($_POST['smtp_host'] ?? ''); $settings['smtp_port'] = trim($_POST['smtp_port'] ?? '587'); $settings['smtp_username'] = trim($_POST['smtp_username'] ?? ''); if (!empty($_POST['smtp_password'])) { $settings['smtp_password'] = trim($_POST['smtp_password']); } $settings['smtp_encryption'] = trim($_POST['smtp_encryption'] ?? 'tls'); $settings['smtp_from_email'] = trim($_POST['smtp_from_email'] ?? ''); $settings['smtp_from_name'] = trim($_POST['smtp_from_name'] ?? ''); } if ($formType === 'templates') { $settings['email_voucher_subject'] = trim($_POST['email_voucher_subject'] ?? ''); $settings['email_voucher_body'] = $_POST['email_voucher_body'] ?? ''; $settings['email_user_notification_subject'] = trim($_POST['email_user_notification_subject'] ?? ''); $settings['email_user_notification_body'] = $_POST['email_user_notification_body'] ?? ''; $settings['system_url'] = trim($_POST['system_url'] ?? ''); } if ($formType === 'system') { $settings['tinymce_api_key'] = trim($_POST['tinymce_api_key'] ?? ''); $settings['print_template'] = $_POST['print_template'] ?? ''; } foreach ($settings as $key => $value) { $db->setSetting($key, $value); } // PRG + Tab-Anker: F5 speichert nicht erneut, und der Nutzer landet // wieder auf dem Tab, in dem er gespeichert hat. $tabAnchors = [ 'general' => 'general', 'defaults' => 'defaults', 'm365' => 'm365', 'smtp' => 'smtp', 'templates' => 'templates_email', 'system' => 'system', ]; flashSet(__('settings_saved')); header('Location: settings.php#' . ($tabAnchors[$formType] ?? 'general')); exit; } catch (Exception $e) { $error = 'Fehler: ' . $e->getMessage(); } } } // Cron-Token generieren/löschen if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['generate_cron_token'])) { if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { $error = __('error_csrf'); } else { $db->setSetting('cron_token', bin2hex(random_bytes(32))); flashSet(__('cron_token_generated')); header('Location: settings.php#cron'); exit; } } if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_cron_token'])) { if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { $error = __('error_csrf'); } else { $db->setSetting('cron_token', ''); flashSet(__('cron_token_deleted')); header('Location: settings.php#cron'); exit; } } // Passwort ändern if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['change_password'])) { if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { $error = __('error_csrf'); } else { try { $user = $auth->getCurrentUser(); if (!password_verify($_POST['current_password'], $user['password_hash'])) { throw new Exception(__('error_pw_current')); } if (strlen($_POST['new_password']) < 8) { throw new Exception(__('settings_pw_minlength')); } if ($_POST['new_password'] !== $_POST['confirm_password']) { throw new Exception(__('error_pw_mismatch')); } $db->query("UPDATE users SET password_hash = ? WHERE id = ?", [password_hash($_POST['new_password'], PASSWORD_DEFAULT), $user['id']]); flashSet(__('settings_pw_changed')); header('Location: settings.php#password'); exit; } catch (Exception $e) { $error = $e->getMessage(); } } } if (empty($success) && empty($error) && ($flash = flashGet())) { $success = $flash['message']; } $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST']; $scriptPath = dirname($_SERVER['SCRIPT_NAME'], 2); $scriptPath = $scriptPath === '/' ? '' : $scriptPath; $autoDetectedUrl = $protocol . '://' . $host . $scriptPath; $cs = [ 'app_title' => $db->getSetting('app_title', 'UniFi Voucher System'), 'logo_url' => $db->getSetting('logo_url', ''), 'favicon_url' => $db->getSetting('favicon_url', ''), 'instruction_header' => $db->getSetting('instruction_header', 'So verwenden Sie Ihren Code'), 'instruction_text' => $db->getSetting('instruction_text', ''), 'public_access' => $db->getSetting('public_access', '0'), 'default_expire_minutes' => $db->getSetting('default_expire_minutes', '480'), 'default_max_uses' => $db->getSetting('default_max_uses', '1'), 'max_uses_limit' => $db->getSetting('max_uses_limit', '10'), 'm365_client_id' => $db->getSetting('m365_client_id', ''), 'm365_client_secret' => $db->getSetting('m365_client_secret', ''), 'm365_tenant_id' => $db->getSetting('m365_tenant_id', ''), 'smtp_enabled' => $db->getSetting('smtp_enabled', '0'), 'smtp_host' => $db->getSetting('smtp_host', ''), 'smtp_port' => $db->getSetting('smtp_port', '587'), 'smtp_username' => $db->getSetting('smtp_username', ''), 'smtp_password' => $db->getSetting('smtp_password', ''), 'smtp_encryption' => $db->getSetting('smtp_encryption', 'tls'), 'smtp_from_email' => $db->getSetting('smtp_from_email', ''), 'smtp_from_name' => $db->getSetting('smtp_from_name', ''), 'system_url' => $db->getSetting('system_url', $autoDetectedUrl), 'email_voucher_subject' => $db->getSetting('email_voucher_subject', '{APP_TITLE} - Ihr WLAN-Zugang'), 'email_voucher_body' => $db->getSetting('email_voucher_body', "Hallo,\n\nIhr Code: {VOUCHER_CODE}\n\nGültigkeit: 8h\nGeräte: {MAX_USES}\nSite: {SITE_NAME}"), 'email_user_notification_subject' => $db->getSetting('email_user_notification_subject', '{APP_TITLE} - Berechtigungen geändert'), 'email_user_notification_body' => $db->getSetting('email_user_notification_body', "Hallo {USER_NAME},\n\n{CHANGES}"), 'tinymce_api_key' => $db->getSetting('tinymce_api_key', ''), 'print_template' => $db->getSetting('print_template', '
Gültig bis: {EXPIRY_DATE} {EXPIRY_TIME}
Site: {SITE_NAME}
Geräte: {MAX_USES}
= __('settings_subtitle') ?>
Diese Werte werden als Vorgabe im Voucher-Formular verwendet.
Der Cron-Job synchronisiert automatisch alle Voucher von Ihren UniFi Controllern in die lokale Datenbank.
Kein Token konfiguriert.
Letzte Synchronisation: = $cs['last_cron_sync'] ? date('d.m.Y H:i:s', strtotime($cs['last_cron_sync'])) : 'Noch nie' ?>
Redirect URI: = $protocol . '://' . $host . $scriptPath ?>/m365_callback.php
| PHP Version: | = phpversion() ?> |
| Datenbank: | = DB_NAME ?> |
| Version: | 2.1.0 |