Sicherheits-Header, Werkzeuge und Dokumentation
Sicherheit: - .htaccess im Projektstamm mit X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy und einer Content-Security-Policy; da alle Assets lokal liegen, erlaubt sie nur noch die eigene Herkunft (Ausnahme: hCaptcha, falls aktiviert) - includes/, tools/, tests/, updater/storage und uploads/ schützen sich über eigene .htaccess-Dateien – auch bei Installation im Unterordner - Docker: AllowOverride All, damit diese Regeln überhaupt greifen, und ein Volume für uploads/, damit Logos ein Image-Update überstehen Werkzeuge: - tools/screenshots.py erzeugt alle Bilder in docs/screenshots aus der Demo-Instanz; tools/README.md beschreibt beides - Einstellungs-Tabs sind per ?tab=… direkt verlinkbar (serverseitig, also auch ohne JavaScript) Dokumentation: Readme um Markenfarben, Bild-Upload, lokale Assets, Sicherheits-Header (inkl. Nginx-Entsprechung) und einen Abschnitt "Entwicklung" ergänzt; Screenshots neu erzeugt, Version 2.6.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e28527ed91
commit
36e06ac817
30 changed files with 307 additions and 36 deletions
115
Readme.md
115
Readme.md
|
|
@ -8,7 +8,7 @@
|
|||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
</div>
|
||||
|
|
@ -47,6 +47,11 @@
|
|||
- 🌍 **Öffentlicher Modus** – optional ohne Login nutzbar (mit CSRF-Schutz & Throttle)
|
||||
- 🎨 **Einheitliches Design-System** – ein Stylesheet für Frontend, Login und Backend (Tokens, Komponenten, Light/Dark)
|
||||
- 🏷️ **Login-Seite individualisierbar** – Firmenname, Logo, Texte, Hintergrundbild bzw. Farbverlauf
|
||||
- 🖌️ **Eigene Markenfarben** – Akzentfarbe, Verlauf und Eckenradius wirken auf die gesamte Oberfläche
|
||||
- ⬆️ **Bild-Upload** für Logo, Favicon und Login-Hintergrund (kein externes Hosting nötig)
|
||||
- 🔒 **Keine externen CDNs** – Schrift, Icons, Diagramme und Editor werden lokal ausgeliefert (DSGVO, Offline-Netze)
|
||||
- ♿ **Barrierearm** – Kontraste nach WCAG AA, Sprungmarke, aria-Beschriftungen, `prefers-reduced-motion`
|
||||
- 📱 **Mobil nutzbar** – Tabellen werden auf schmalen Geräten zu Karten
|
||||
- 🌗 **Dark Mode** – umschaltbar, Einstellung wird im Browser gespeichert
|
||||
- 🌐 **Mehrsprachig** – Deutsch / Englisch per Umschalter (`lang/`)
|
||||
- 📱 **Responsive Admin-Layout** mit Hamburger-Menü & Sidebar-Overlay
|
||||
|
|
@ -92,6 +97,11 @@
|
|||
<img src="docs/screenshots/settings.png" alt="Einstellungen" width="48%">
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<img src="docs/screenshots/settings-branding.png" alt="Markenfarben einstellen" width="48%">
|
||||
<img src="docs/screenshots/mobile-vouchers.png" alt="Ansicht auf dem Smartphone" width="22%">
|
||||
</div>
|
||||
|
||||
### REST-API, 2FA & Integrationen
|
||||
|
||||
<div align="center">
|
||||
|
|
@ -249,21 +259,44 @@ gemeinsames Stylesheet: **`assets/global.css`**.
|
|||
- **Dark Mode** ausschließlich über Tokens – keine `!important`-Overrides mehr
|
||||
- **Schriftart** Inter (via Google Fonts) mit System-Font-Fallback
|
||||
|
||||
Eigenes Branding lässt sich meist mit wenigen Zeilen umsetzen – z. B. in einer
|
||||
eigenen CSS-Datei oder direkt in `assets/global.css`:
|
||||
### Markenfarben ohne Code
|
||||
|
||||
Unter **Administration → Einstellungen → Design** lassen sich Akzentfarbe
|
||||
(hell und dunkel), Markenverlauf und Eckenradius setzen. Abgeleitete Töne –
|
||||
Hover, weiche Flächen, Rahmen, Fokusring – berechnet das System per `color-mix`
|
||||
aus der Grundfarbe; eine Farbe genügt also. Eine Live-Vorschau zeigt Button,
|
||||
Badge, Chip und Logo-Kachel sofort im neuen Ton.
|
||||
|
||||
Die Werte landen als schlanker `:root`-Override im Seitenkopf und gelten überall,
|
||||
auch auf Login-Seite, Installer und Updater. Wer lieber in CSS arbeitet, kann
|
||||
dieselben Variablen weiterhin in `assets/global.css` überschreiben:
|
||||
|
||||
```css
|
||||
:root {
|
||||
--accent: #0f766e; /* Primärfarbe (Buttons, aktive Navigation) */
|
||||
--accent-hover: #0d5f59;
|
||||
--accent-soft: #e6f4f2; /* Flächen für aktive Zustände */
|
||||
--brand-gradient: linear-gradient(135deg, #0f766e 0%, #0ea5e9 100%);
|
||||
--r-lg: 14px; /* Eckenradius für Cards */
|
||||
}
|
||||
```
|
||||
|
||||
Logo und Favicon werden nicht über CSS, sondern unter
|
||||
**Administration → Einstellungen → Allgemein** gesetzt.
|
||||
### Bilder hochladen
|
||||
|
||||
Logo, Favicon, Login-Logo und Login-Hintergrund lassen sich direkt hochladen –
|
||||
alternativ bleibt das URL-Feld bestehen. Die Dateien landen unter `uploads/`
|
||||
(Docker: eigenes Volume, siehe unten). Erlaubt sind PNG, JPG, WEBP, GIF und SVG
|
||||
bis 3 MB; SVGs werden vor dem Speichern von Skripten und externen Verweisen
|
||||
befreit, und im Upload-Ordner sperrt eine `.htaccess` die PHP-Ausführung.
|
||||
|
||||
### Assets ohne Drittanbieter
|
||||
|
||||
Schrift (Inter), Icons (Font Awesome), Diagramme (Chart.js), QR-Codes und der
|
||||
WYSIWYG-Editor (TinyMCE) liegen unter `assets/vendor/` und kommen vom eigenen
|
||||
Server. Das hält Besucher-IPs bei Ihnen – und die Oberfläche funktioniert auch
|
||||
dort, wo das Netz keinen Weg nach außen hat. Details und Aktualisierungs-Hinweise:
|
||||
[`assets/vendor/README.md`](assets/vendor/README.md).
|
||||
|
||||
Alle Asset-URLs tragen einen Versionsstempel (`?v=…`), damit Browser nach einem
|
||||
Update nicht die alten Dateien aus dem Cache verwenden.
|
||||
|
||||
### Login-Seite individualisieren
|
||||
|
||||
|
|
@ -303,13 +336,30 @@ Das Tool ist auf einen sicheren Standardbetrieb ausgelegt:
|
|||
| **Sessions** | HttpOnly, SameSite, strict mode + absolutes Timeout |
|
||||
| **Fehler** | `display_errors` aus, `log_errors` an (kein Info-Leak) |
|
||||
|
||||
Empfohlene zusätzliche Härtung am Server:
|
||||
Mitgeliefert wird eine `.htaccess` im Projektstamm mit Sicherheits-Headern
|
||||
(`X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`,
|
||||
`Permissions-Policy` und einer Content-Security-Policy). Da alle Assets lokal
|
||||
liegen, erlaubt die CSP nur noch die eigene Herkunft – externe Verbindungen
|
||||
bleiben lediglich für hCaptcha offen, falls es aktiviert wird. Ordner wie
|
||||
`includes/`, `tools/`, `tests/` und `uploads/` schützen sich über eigene
|
||||
`.htaccess`-Dateien.
|
||||
|
||||
```apache
|
||||
# .htaccess – sensible Dateien sperren (wird vom Installer erzeugt)
|
||||
<FilesMatch "^(config\.php|database\.sql|install\.php|test\.php|m365_debug\.php|.*\.md)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
> **Apache:** `AllowOverride All` muss für das Verzeichnis gesetzt sein, sonst
|
||||
> werden die `.htaccess`-Dateien ignoriert. Das mitgelieferte Docker-Image
|
||||
> erledigt das bereits.
|
||||
|
||||
Für **Nginx** entspricht das:
|
||||
|
||||
```nginx
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; frame-ancestors 'self'" always;
|
||||
|
||||
location ~ ^/(includes|tools|tests)/ { deny all; }
|
||||
location ~ ^/updater/(storage|migrations)/ { deny all; }
|
||||
location ~ ^/(config\.php|database\.sql)$ { deny all; }
|
||||
location ^~ /uploads/ { location ~ \.php$ { deny all; } }
|
||||
```
|
||||
|
||||
```sql
|
||||
|
|
@ -432,6 +482,40 @@ Das Schema wird beim ersten Start automatisch in MariaDB geladen; danach den
|
|||
Installer (`/install.php`) für den Admin-Account aufrufen oder Config per ENV
|
||||
setzen (`DB_*`, `APP_KEY`).
|
||||
|
||||
Hochgeladene Logos und Hintergründe liegen im Volume `uploads` und überstehen
|
||||
damit ein Image-Update. Bei eigener Apache-/Nginx-Installation muss `uploads/`
|
||||
für den Webserver beschreibbar sein:
|
||||
|
||||
```bash
|
||||
chown -R www-data:www-data uploads updater/storage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Entwicklung
|
||||
|
||||
Für Screenshots und einen schnellen Durchlauf aller Seiten gibt es eine
|
||||
Demo-Instanz **ohne Datenbank** – `Database` und `Auth` werden durch Stubs mit
|
||||
festen Beispieldaten ersetzt:
|
||||
|
||||
```bash
|
||||
python3 tools/demo/build.py /tmp/uvt-demo
|
||||
php -S 127.0.0.1:8123 -t /tmp/uvt-demo &
|
||||
|
||||
# Bilder in docs/screenshots neu erzeugen (benötigt headless Chromium)
|
||||
CHROME_BIN=/usr/bin/chromium python3 tools/screenshots.py
|
||||
```
|
||||
|
||||
Details und die verfügbaren Demo-Zustände: [`tools/README.md`](tools/README.md).
|
||||
|
||||
Tests und statische Analyse:
|
||||
|
||||
```bash
|
||||
composer install
|
||||
vendor/bin/phpunit
|
||||
vendor/bin/phpstan analyse
|
||||
```
|
||||
|
||||
## 🗺️ Roadmap
|
||||
|
||||
- [x] Voucher-Templates (vordefinierte Laufzeiten)
|
||||
|
|
@ -447,11 +531,14 @@ setzen (`DB_*`, `APP_KEY`).
|
|||
- [x] Erweiterte Reporting-Funktionen (CSV/PDF) + Health-Endpoint
|
||||
- [x] 2FA-Recovery-Codes, API-Scopes/Rate-Limit/OpenAPI, Test-Suite (PHPUnit/PHPStan)
|
||||
- [x] Gemeinsames Design-System für Frontend, Login und Backend
|
||||
- [x] Branding über die Oberfläche (Farben, Logo, Login-Seite)
|
||||
- [x] Assets lokal ausliefern (keine Drittanbieter-CDNs)
|
||||
- [x] Vollständige englische Übersetzung des Admin-Bereichs
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
**Version 2.5.0** · Autor: **Friederich Loheide** · Lizenz: **MIT**
|
||||
**Version 2.6.0** · Autor: **Friederich Loheide** · Lizenz: **MIT**
|
||||
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue