Branding: Farben systemweit einstellbar + Bild-Upload statt nur URLs

Design-Tab (Administration → Einstellungen → Design):
- Akzentfarbe für Hell- und Dark-Mode, Markenverlauf und Eckenradius
- abgeleitete Töne (Hover, weiche Flächen, Fokusring) werden per
  color-mix aus der Grundfarbe berechnet – eine Farbe genügt
- Live-Vorschau mit Button, Badge, Chip, Logo-Kachel und Link
- Ausgabe als schlanker :root-Override über Ui::brandingStyle(), greift
  auf allen Seiten inklusive Login und Installer

Uploads (includes/Upload.php):
- Logo, Favicon, Login-Logo und Login-Hintergrund lassen sich jetzt
  hochladen; das URL-Feld bleibt als Alternative bestehen
- Whitelist nach Endung, 3-MB-Grenze, getimagesize-Prüfung für Raster,
  SVGs werden von Skripten, Event-Handlern und externen Verweisen befreit
- Zufällige Dateinamen in uploads/, dort sperrt eine .htaccess die
  Ausführung von PHP; beim Ersetzen wird die alte Datei gelöscht

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-23 06:27:30 +00:00
parent 6da46f040a
commit 30d0ce3a23
13 changed files with 437 additions and 32 deletions

View file

@ -146,7 +146,7 @@ try {
. ';--login-to:' . htmlspecialchars($loginBgTo, ENT_QUOTES)
. ';--login-overlay:' . ($loginOverlay / 100);
if ($loginBgImage !== '') {
$visualStyle .= ";--login-image:url('" . htmlspecialchars($loginBgImage, ENT_QUOTES) . "')";
$visualStyle .= ";--login-image:url('" . htmlspecialchars(Ui::mediaUrl($loginBgImage), ENT_QUOTES) . "')";
}
} catch (Exception $e) {
@ -167,7 +167,7 @@ try {
<section class="auth-visual<?= $loginBgImage !== '' ? ' has-image' : '' ?>" style="<?= $visualStyle ?>">
<div class="auth-brand">
<?php if ($loginLogo): ?>
<img src="<?= htmlspecialchars($loginLogo) ?>" alt="<?= htmlspecialchars($loginBrand) ?>" class="auth-brand-logo">
<img src="<?= htmlspecialchars(Ui::mediaUrl($loginLogo)) ?>" alt="<?= htmlspecialchars($loginBrand) ?>" class="auth-brand-logo">
<?php else: ?>
<span class="brand-mark"><i class="fas fa-wifi"></i></span>
<span><?= htmlspecialchars($loginBrand) ?></span>
@ -204,7 +204,7 @@ try {
<div class="login-container">
<?php if (!$showPanel): ?>
<?php if ($loginLogo): ?>
<img src="<?= htmlspecialchars($loginLogo) ?>" alt="<?= htmlspecialchars($loginBrand) ?>" class="logo">
<img src="<?= htmlspecialchars(Ui::mediaUrl($loginLogo)) ?>" alt="<?= htmlspecialchars($loginBrand) ?>" class="logo">
<?php else: ?>
<div class="auth-mark">
<span class="brand-mark"><i class="fas fa-wifi"></i></span>