0,'B'=>1,'C'=>2,'D'=>3,'E'=>4,'F'=>5,'G'=>6,'H'=>7,'I'=>8,'J'=>9,'K'=>10,'L'=>11,'M'=>12,'N'=>13,'O'=>14,'P'=>15,'Q'=>16,'R'=>17,'S'=>18,'T'=>19,'U'=>20,'V'=>21,'W'=>22,'X'=>23,'Y'=>24,'Z'=>25,'2'=>26,'3'=>27,'4'=>28,'5'=>29,'6'=>30,'7'=>31];
$decoded = ''; $buffer = 0; $bits = 0;
for ($i = 0; $i < strlen($b32); $i++) {
$char = $b32[$i];
if (!isset($map[$char])) continue;
$buffer = ($buffer << 5) | $map[$char];
$bits += 5;
if ($bits >= 8) { $bits -= 8; $decoded .= chr(($buffer >> $bits) & 0xFF); }
}
return $decoded;
}
public static function generateSecret($length = 16) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$secret = '';
for ($i = 0; $i < $length; $i++) $secret .= $chars[random_int(0, 31)];
return $secret;
}
public static function getQRCodeUrl($username, $secret) {
$issuer = urlencode("SG 07 St.Leon");
$account = urlencode($username);
$otpauth = "otpauth://totp/{$issuer}:{$account}?secret={$secret}&issuer={$issuer}";
return "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=" . urlencode($otpauth);
}
}
// ============================================================================
// 2. DATENBANK SETUP (News & Benutzer)
// ============================================================================
try {
$db = new PDO('sqlite:news_database.sqlite');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// News Tabelle
$db->exec("CREATE TABLE IF NOT EXISTS news (
id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT, department TEXT, title TEXT, content TEXT, full_text TEXT, image TEXT, link TEXT
)");
try { $db->exec("ALTER TABLE news ADD COLUMN full_text TEXT"); } catch(PDOException $e) {}
// Benutzer Tabelle
$db->exec("CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, password_hash TEXT, totp_secret TEXT
)");
} catch(PDOException $e) {
die("Datenbankfehler: " . $e->getMessage());
}
$userCount = $db->query("SELECT COUNT(*) FROM users")->fetchColumn();
// ============================================================================
// 3. ERSTEINRICHTUNG (Wenn keine Nutzer existieren)
// ============================================================================
if ($userCount == 0) {
$setup_msg = "";
$new_secret = MiniTOTP::generateSecret();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['do_setup'])) {
$user = trim($_POST['username']);
$pass = $_POST['password'];
$secret = $_POST['totp_secret'];
if (!empty($user) && !empty($pass)) {
$stmt = $db->prepare("INSERT INTO users (username, password_hash, totp_secret) VALUES (?, ?, ?)");
$stmt->execute([$user, password_hash($pass, PASSWORD_DEFAULT), $secret]);
header("Location: admin.php");
exit;
}
}
?>
Setup | SG 07
Ersteinrichtung Erstelle den ersten Admin-Zugang.
1. Scanne diesen QR-Code mit dem Google Authenticator oder Authy .
prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([trim($_POST['username'])]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($_POST['password'], $user['password_hash'])) {
if (MiniTOTP::verify($user['totp_secret'], $_POST['totp_code'])) {
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $user['username'];
header("Location: admin.php"); exit;
} else {
$login_error = "Der 2FA Code ist falsch oder abgelaufen.";
}
} else {
$login_error = "Benutzername oder Passwort falsch.";
}
}
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
?>
Login | SG 07
🔒
Admin Login
$login_error
"; ?>
prepare("UPDATE news SET date=?, department=?, title=?, content=?, full_text=?, image=?, link=? WHERE id=?");
if ($stmt->execute([$_POST['date'], $_POST['department'], $_POST['title'], $_POST['content'], $_POST['full_text'], $final_image_path, $_POST['link'], $_POST['news_id']])) {
$message = "✓ News erfolgreich aktualisiert!
";
}
}
// Aktion: News speichern (NEU ERSTELLEN)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_news'])) {
$final_image_path = '';
$uploaded_img = handleImageUpload();
if ($uploaded_img) {
$final_image_path = $uploaded_img;
} else {
$final_image_path = str_replace(['http://new.sg07-stleon.de/', 'https://new.sg07-stleon.de/', 'new.sg07-stleon.de/', 'new.sg07-stleon.de\\'], '', trim($_POST['image_url'] ?? ''));
}
$stmt = $db->prepare("INSERT INTO news (date, department, title, content, full_text, image, link) VALUES (?, ?, ?, ?, ?, ?, ?)");
if ($stmt->execute([$_POST['date'], $_POST['department'], $_POST['title'], $_POST['content'], $_POST['full_text'], $final_image_path, $_POST['link']])) {
$message = "✓ News erfolgreich veröffentlicht!
";
}
}
// Aktion: News löschen
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_news'])) {
$stmt = $db->prepare("DELETE FROM news WHERE id = ?");
if ($stmt->execute([$_POST['delete_id']])) {
$message = "✓ Die News wurde unwiderruflich gelöscht!
";
}
}
// Aktion: Neuen Benutzer anlegen
$new_user_qr = "";
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_user'])) {
$new_user = trim($_POST['new_username']);
$new_pass = $_POST['new_password'];
$new_secret = MiniTOTP::generateSecret();
try {
$stmt = $db->prepare("INSERT INTO users (username, password_hash, totp_secret) VALUES (?, ?, ?)");
$stmt->execute([$new_user, password_hash($new_pass, PASSWORD_DEFAULT), $new_secret]);
$url = MiniTOTP::getQRCodeUrl($new_user, $new_secret);
$new_user_qr = "Benutzer '$new_user' angelegt! Bitte lasse den neuen Benutzer jetzt sofort diesen QR Code scannen.
Geheimer Schlüssel (falls QR nicht geht): $new_secret
";
} catch(PDOException $e) {
$message = "Fehler: Benutzername existiert evtl. schon.
";
}
}
// Edit-Modus prüfen (Ist ein Klick auf "Ändern" erfolgt?)
$is_edit = false;
$edit_news = null;
if (isset($_GET['edit_id'])) {
$stmt = $db->prepare("SELECT * FROM news WHERE id = ?");
$stmt->execute([$_GET['edit_id']]);
$edit_news = $stmt->fetch(PDO::FETCH_ASSOC);
if ($edit_news) $is_edit = true;
}
// Alle bestehenden News abrufen, um sie aufzulisten
$existing_news = $db->query("SELECT id, date, department, title FROM news ORDER BY id DESC")->fetchAll(PDO::FETCH_ASSOC);
?>
Admin Dashboard | SG 07 St. Leon
= $message ?>
= $new_user_qr ?>
= $is_edit ? 'News bearbeiten' : 'News veröffentlichen' ?>
Bestehende News verwalten
Hier kannst du fehlerhafte oder veraltete News endgültig von der Website entfernen.
Datum
Abteilung
Titel
Aktion
= htmlspecialchars($news_item['date']) ?>
= htmlspecialchars($news_item['department']) ?>
= htmlspecialchars($news_item['title']) ?>
Ändern
Löschen
Noch keine News in der Datenbank vorhanden.