Commit graph

69 commits

Author SHA1 Message Date
3a09e35097 Merge pull request 'Display-Seiten individuell gestalten' (#8) from feature/kiosk-branding into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Release-Paket / ZIP bauen und veröffentlichen (push) Waiting to run
2026-09-23 16:59:11 +00:00
4159b92268 Display-Seiten individuell gestalten
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Jede Display-Seite bringt jetzt ihr eigenes Erscheinungsbild mit – der
Empfang sieht anders aus als der Tagungsraum nebenan:

- eigenes Logo (leer = Logo aus den Einstellungen)
- formatfüllendes Hintergrundbild mit einstellbarer Abdunklung (0–90 %),
  damit die Karte auf hellen Fotos lesbar bleibt
- eigene Akzentfarbe für den Knopf (leer = Farbe aus dem Design-Tab)
- Karte wahlweise hell oder dunkel; auf Fotos wirkt dunkel meist ruhiger

Logo und Hintergrund lassen sich hochladen oder als URL hinterlegen; beim
Löschen einer Display-Seite verschwinden die hochgeladenen Dateien mit.

Nebenbei aufgeräumt: das Bildfeld (Vorschau + Upload + URL + Entfernen)
lag als Funktion in admin/settings.php und wird jetzt von beiden Seiten
genutzt – Ui::imageField() für die Darstellung, Upload::resolveField()
für die Auswertung.

Sicherheit: die Akzentfarbe landet in einem style-Attribut, deshalb wird
sie sowohl beim Speichern als auch beim Ausgeben auf eine echte Hex-Farbe
geprüft; ein Test hält das fest.

Migration 0006, database.sql nachgezogen, 4 neue Tests (42 gesamt),
Screenshots ergänzt, Version 2.8.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 16:58:54 +00:00
943e427150 Merge pull request 'Display-Seiten: Gäste holen sich den Zugang selbst' (#7) from feature/kiosk into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Release-Paket / ZIP bauen und veröffentlichen (push) Waiting to run
2026-09-23 16:52:17 +00:00
ee3b85add4 Version 2.7.0
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 16:51:58 +00:00
61810eb050 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>
2026-09-23 16:51:50 +00:00
5d72febadc Merge pull request 'Einrichtung für einen Forgejo-Actions-Runner' (#6) from ci/runner-setup into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Release-Paket / ZIP bauen und veröffentlichen (push) Waiting to run
2026-09-23 15:06:36 +00:00
83f4223d89 Einrichtung für einen Forgejo-Actions-Runner beilegen
Some checks are pending
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
tools/runner/ enthält eine Compose-Datei, eine Beispiel-Konfiguration und
eine Schritt-für-Schritt-Anleitung, um den Runner auf dem Server zu
registrieren. Der Runner läuft in einem eigenen Verzeichnis und fasst
/opt/forgejo nicht an.

Abgestimmt auf die vorhandenen Workflows und den Server:
- Label-Zuordnung ubuntu-latest -> node:20-bookworm, damit runs-on in
  ci.yml und release.yml greift
- capacity 1 und Speicherlimit, weil der Server nur 4 GB hat
- Hinweis darauf, was das Reichen des Docker-Sockets bedeutet, und die
  Host-Modus-Alternative samt ihrer Grenzen (setup-php braucht Container)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 15:06:19 +00:00
ad197ecf90 Merge pull request 'Release-Workflow: ZIP bei jedem Merge nach main' (#5) from ci/release-zip into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Release-Paket / ZIP bauen und veröffentlichen (push) Waiting to run
2026-09-23 14:50:36 +00:00
8facc71455 Release-Workflow: ZIP bei jedem Merge nach main
Some checks are pending
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
.github/workflows/release.yml baut bei jedem Push auf main (also auch
nach jedem gemergten Pull Request) ein installierbares Paket und hängt es
an das rollende Vorab-Release "latest-main". Der Download-Link bleibt
damit stabil und zeigt immer auf den aktuellen Stand. Ein Tag v* erzeugt
mit derselben Mechanik ein reguläres Release.

Details:
- das ZIP entsteht per `git archive`, die Auswahl steuert .gitattributes
  (export-ignore) – docs/, tests/, tools/ und CI bleiben draußen, das
  Paket ist rund 1,4 MB groß
- eine Prüfschritt kontrolliert, dass Kerndateien wirklich enthalten sind,
  dazu gibt es eine .sha256-Datei
- zusätzlich als Build-Artefakt abgelegt (optional, bricht nicht ab, wenn
  der Artefakt-Speicher fehlt)
- Release-API wird über den automatisch bereitgestellten Token
  angesprochen, FORGEJO_TOKEN dient als Ausweichweg; ohne Token wird der
  Schritt übersprungen statt fehlzuschlagen

Neu ist die Datei VERSION als einzige Quelle der Versionsnummer: sie
benennt das Paket und erscheint über Ui::version() unten in der
Admin-Seitenleiste ("v2.6.0 · Entwickelt von Loheide.eu").

Geprüft: Paket lokal gebaut, entpackt und die Anwendung daraus gestartet –
alle Seiten antworten mit 200, keine fehlenden Dateien.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 14:50:10 +00:00
b7f13d8fac Merge pull request 'README auf Forgejo umstellen' (#4) from docs/forgejo into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
2026-09-23 13:58:31 +00:00
5f7c503dff README: Projekt liegt auf Forgejo, nicht mehr auf GitHub
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
- CI-Badge von github.com entfernt (zeigte ins Leere); stattdessen ein
  statisches Test-Badge und ein Link zum Repository
- Clone-Befehl in der Installation auf git.loheide.cloud umgestellt
- neuer Abschnitt "Repository & Mitwirken" mit HTTPS-/SSH-Adressen,
  Hinweis auf Issues und Pull Requests sowie der tea-CLI
- vermerkt, dass .github/workflows von Forgejo Actions mitgelesen wird und
  docker-publish.yml (ghcr.io) noch aus der GitHub-Zeit stammt
- klargestellt, dass der Auto-Updater unabhängig davon über
  update.loheide.eu läuft
- Entwicklungs-Abschnitt nennt jetzt auch die CI-Prüfungen der Sprachdateien
- composer.json: homepage, authors und support-Links ergänzt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 13:58:16 +00:00
068f6c08f9 Merge pull request 'Entwicklerhinweis "Entwickelt von Loheide.eu"' (#3) from feature/credit into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
2026-09-23 11:22:15 +00:00
7fa423a74c Entwicklerhinweis "Entwickelt von Loheide.eu" ergänzen
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
Zentral in Ui::credit() gepflegt und dezent im Seitenfuß eingebunden:

- Admin-Bereich: unter dem Benutzerbereich in der Sidebar
- öffentliche Voucher-Seite: unter der Karte
- Anmeldung, Installer und Updater: am Ende der jeweiligen Karte
- Wartungsseite: direkt im Markup, da sie bewusst eigenständig bleibt
- README: im Kopf und in der Fußzeile

Der Hinweis ist übersetzt ("Entwickelt von" / "Developed by") und stört
das Branding der Betreiber nicht – die konfigurierbare Fußzeile der
Login-Seite bleibt unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 11:21:53 +00:00
7dc60c5bb0 Merge pull request 'Self-Hosting, Branding, i18n, Barrierefreiheit und Werkzeuge' (#2) from feature/self-hosted-assets-branding into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
2026-09-23 06:54:39 +00:00
2fe7e9522d Theme-Auswahl aus dem Seitenkopf nicht mehr überschreiben
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
global.js hat beim Laden erneut ein Theme gesetzt und dabei die
Entscheidung des Inline-Schnipsels im <head> verworfen – sichtbar als
kurzes Umspringen und daran, dass erzwungene Themes ignoriert wurden.
Jetzt gilt: ausdrückliche Auswahl > bereits gesetztes Attribut > System.

Updater-Seite übernimmt ebenfalls die Markenfarben, Screenshots neu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:53:57 +00:00
0716311ff6 Tests für Upload und Ui, strengere CI-Prüfungen
- tests/UploadTest.php prüft den SVG-Filter (Skripte, Event-Handler,
  javascript:-Verweise) und Upload::isLocal gegen Pfad-Tricks
- tests/UiTest.php prüft Versionsstempel, Media-Pfade und die
  Branding-Overrides inklusive Abweisung ungültiger Farbwerte
- PHPStan analysiert jetzt auch includes/Ui.php und includes/Upload.php
- CI vergleicht die Sprachdateien (gleiche Schlüsselmenge) und prüft,
  dass jeder im Code verwendete Schlüssel existiert

Dabei aufgefallen und behoben: Upload.php rief __() direkt auf und wäre
außerhalb einer Seite mit geladener I18n mit einem Fatal Error
abgebrochen; jetzt gibt es einen Fallback auf die deutsche Meldung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:52:22 +00:00
36e06ac817 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>
2026-09-23 06:49:14 +00:00
e28527ed91 E-Mails und Druckvorlage im neuen Design
E-Mail:
- Nachrichten werden in ein markentreues HTML-Gerüst gelegt (Tabellen +
  Inline-Styles, damit Outlook & Co. es zuverlässig darstellen); die
  Kopfleiste nutzt den eingestellten Markenverlauf
- neuer Platzhalter {VOUCHER_CARD} rendert den Code als hervorgehobene
  Karte; bestehende Vorlagen mit {VOUCHER_CODE} funktionieren unverändert
  weiter, sie werden lediglich eingerahmt
- Zeilenumbrüche der Vorlage werden vor dem Einsetzen der Platzhalter
  umgewandelt, Markup aus dem WYSIWYG-Editor bleibt unangetastet

Druck:
- neue Standardvorlage als Ticket mit QR-Code, Code, Gültigkeit und
  Anleitung; zentral in Ui::defaultPrintTemplate()
- neuer Platzhalter {QR_CODE}; der QR-Code wird lokal im Browser erzeugt
  (qrcodejs aus assets/vendor), auch bei Bulk-Erstellung für jede Karte
- die Druckvorlage ist am Bildschirm ausgeblendet und erscheint nur im
  Ausdruck

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:42:45 +00:00
7f1d93debd Barrierefreiheit und mobile Darstellung
- Kontrast: gedämpfter Text war mit 3,1:1 unter WCAG AA, jetzt 4,9:1
  (hell) bzw. 6,4:1 (dunkel)
- Sprungmarke „Zum Inhalt springen" in Admin-Shell und Voucher-Seite
- aria-label für alle reinen Icon-Schaltflächen (Theme, Menü, Abmelden,
  Zeilenaktionen), aria-current auf dem aktiven Navigationspunkt,
  role="group" für den Sprachumschalter
- 194 dekorative Icons mit aria-hidden versehen, damit Screenreader sie
  nicht vorlesen
- Toast-Container als aria-live-Bereich ausgezeichnet
- prefers-reduced-motion schaltet Animationen und Übergänge ab

Tabellen (Benutzer, Vouchers, Profile, Audit-Log, Dashboard, API-Keys)
werden unter 720 px zu Karten: die Spaltenüberschrift steht per
data-label vor dem Wert, statt horizontal zu scrollen.

Datums- und Zeitformat in der Voucher-Liste folgen jetzt der gewählten
Sprache statt fest de-DE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:38:08 +00:00
850a04d628 Englische Übersetzungen für die restlichen Admin-Seiten
API-Schlüssel, Integration & Wartung, Voucher-Import, Backup & Restore,
Reporting, Sicherheit (2FA) und Audit-Log waren fest auf Deutsch
verdrahtet, obwohl in der Kopfzeile ein DE/EN-Umschalter sitzt. Diese
Seiten laufen jetzt komplett über lang/de.php bzw. lang/en.php.

- rund 200 neue Sprachschlüssel, beide Dateien deckungsgleich
- Aktionsnamen im Audit-Log werden übersetzt statt fest ausgegeben
- Bestätigungsdialoge und Statusmeldungen in JavaScript ebenfalls
- admin/security.php initialisiert jetzt I18n und setzt <html lang>
  passend zur Auswahl

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:34:25 +00:00
30d0ce3a23 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>
2026-09-23 06:27:30 +00:00
6da46f040a Alle Frontend-Assets lokal ausliefern statt über CDNs
Inter, Font Awesome, Chart.js, qrcodejs und TinyMCE liegen jetzt unter
assets/vendor/ und werden vom eigenen Server ausgeliefert.

Warum:
- Datenschutz: bisher ging bei jedem Seitenaufruf die IP der Nutzer an
  Google Fonts, cdnjs, jsDelivr und Tiny Cloud
- Funktion: UniFi-Installationen stehen oft in abgeschotteten Netzen –
  dort fehlten bisher Schrift, Icons, Diagramme und Editor

Neu: includes/Ui.php
- Ui::head()/Ui::script() binden die Assets ein und hängen einen
  Versionsstempel an (?v=filemtime), damit Browser nach einem Update
  nicht das alte CSS aus dem Cache nehmen
- Ui::themeScript() setzt das Theme aus der gespeicherten Auswahl oder
  – wenn keine vorliegt – aus prefers-color-scheme; global.js folgt
  Systemwechseln live, solange nichts manuell gewählt wurde
- <meta name="color-scheme"> ergänzt, damit Formularelemente passen

Der TinyMCE-API-Key entfällt: der Editor läuft immer lokal (GPL-Variante),
inklusive deutscher Oberfläche, wenn die App auf Deutsch steht.

Neu: tools/demo/build.py – baut aus dem Projekt eine Demo-Instanz ohne
Datenbank (Stubs für Database/Auth, feste Beispieldaten). Damit lassen
sich Screenshots reproduzierbar erzeugen und alle Seiten einmal rendern
(Smoke-Test), ohne eine MySQL-Instanz aufzusetzen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 06:23:44 +00:00
ba90ffef03 Merge pull request 'Redesign: gemeinsames Design-System für Frontend und Backend' (#1) from redesign/design-system into main
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
2026-09-23 06:16:42 +00:00
9a4b2e1cd4 Login-Seite individualisierbar (Branding, Texte, Hintergrund)
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
Neuer Einstellungs-Tab "Login-Seite" (Administration → Einstellungen):

- Firmenname und eigenes Logo für die Anmeldeseite
- Überschrift, Beschreibungstext, Stichpunkte (eine Zeile je Punkt) und
  Fußzeile frei setzbar
- Hintergrundbild für die linke Bildspalte, alternativ Farbverlauf mit
  Farbwähler (Start-/Endfarbe) sowie einstellbarer Abdunklung für die
  Lesbarkeit auf hellen Bildern
- Bildspalte abschaltbar: dann zentrierte Anmeldekarte auf dem
  App-Hintergrund
- "Vorschau öffnen" zeigt die Login-Seite als angemeldeter Admin
  (login.php?preview=1), ohne die Sitzung zu beenden

Alle Felder sind optional; leere Werte fallen auf die bisherigen
Standardtexte und -farben zurück. Bestehende Installationen sehen
unverändert aus, es ist keine Migration nötig.

README um den Abschnitt "Login-Seite individualisieren" mit Beispiel-
Screenshots ergänzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 20:40:48 +00:00
498c7e28e0 Redesign: gemeinsames Design-System für Frontend und Backend
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
Frontend, Login/Installer/Updater und der komplette Admin-Bereich nutzen
jetzt ein einziges Stylesheet (assets/global.css) statt pro Seite
dupliziertem Inline-CSS.

Design-System
- Tokens für Flächen, Text, Linien, Marke, Status, Radien, Schatten und
  Layout-Maße; Dark Mode ausschließlich über Tokens (keine !important-
  Overrides mehr)
- Komponenten: Buttons, Formularfelder, Cards, Tabellen, Badges, Alerts,
  Tabs, Pagination, Modals, Toasts, Statistik-Kacheln, Empty States
- Schrift Inter mit System-Fallback

Oberfläche
- Admin-Shell neu: durchgehende Sidebar mit Marke, gruppierter Navigation
  und Benutzerbereich; schlanke Topbar mit Breadcrumb
- Dashboard: ruhige KPI-Kacheln mit Icon-Chips, Charts an Theme-Farben
  gekoppelt
- Öffentliche Voucher-Seite: App-Topbar, klare Formularstruktur und
  Ticket-Darstellung des erstellten Codes inkl. QR-Code
- Login/Passwort/2FA: zweispaltiges Auth-Layout bzw. Fokus-Karten
- Updater und Wartungsmodus im gleichen Look (Wartungsseite bleibt
  bewusst eigenständig ohne externe Abhängigkeiten)
- Emoji-Icons in der UI durch Font-Awesome-Icons ersetzt

Nebenbei behoben
- Falscher SRI-Hash blockierte qrcode.min.js – QR-Codes wurden auf der
  Voucher-Seite und bei der 2FA-Einrichtung nie gerendert
- assets/global.css wurde in mehreren Admin-Seiten über einen falschen
  Pfad eingebunden ($adminBase = '' statt '../')
- TinyMCE lädt ohne API-Key jetzt die GPL-Variante von cdnjs – kein
  "valid API key required"-Banner mehr im Einstellungs-Editor
- Tabellen in Cards scrollen horizontal statt zu überlaufen

Screenshots in docs/screenshots neu erstellt, README aktualisiert (neuer
Abschnitt "Design-System", Version 2.5.0).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 20:33:52 +00:00
friloo
bad70a631f
Merge pull request #10 from friloo/claude/ecstatic-cannon-H5hGy
Security-Härtung, Auto-Updater, UI-Features & erweiterte Funktionen (v2.3.0)
2026-06-09 21:31:15 +02:00
Claude
87af72e51c
README: SSO/SMS/CSV-Import/CAPTCHA/DB-Sessions ergänzt, v2.4.0 2026-06-06 05:51:59 +00:00
Claude
1a51721477
DB-gestützte Sessions (opt-in) + 'überall abmelden'
- includes/DbSessionHandler.php (SessionHandlerInterface, fehlertolerant)
- Auth: opt-in-Registrierung (Setting session_driver=db), activeSessionCount(),
  logoutOtherSessions()
- Migration 0004 (sessions.user_id NULL) + database.sql
- Settings-Toggle in integrations.php; 'überall abmelden' in security.php
2026-06-06 05:49:53 +00:00
Claude
ebfa27d5c3
Generisches OIDC-SSO (weitere Auth-Quelle)
- oidc_callback.php (Auth-Code-Flow, state-Validierung, Code->Token->Userinfo)
- login.php: OIDC-Button (konfigurierbarer Name)
- Settings in admin/integrations.php (Endpoints, Client, Scopes)
- nutzt vorhandene externe-SSO-Verknüpfung (loginWithMicrosoft, sub als ID)
2026-06-06 05:47:20 +00:00
Claude
976b357952
SMS-Versand (Twilio): includes/Sms.php + Option im Voucher-Formular + Settings 2026-06-06 05:44:46 +00:00
Claude
46c03d53b8
Batch-CSV-Import: admin/import.php (Name,MaxGeräte,Minuten; max 200 Zeilen) 2026-06-06 05:43:09 +00:00
Claude
ce75215498
CAPTCHA für öffentlichen Modus (Rechenaufgabe oder hCaptcha)
- includes/Captcha.php (math self-contained / hcaptcha via siteverify)
- index.php: Verifikation bei anonymer Erstellung + Anzeige in beiden Formularen
- Settings in admin/integrations.php (Modus, Site-Key, Secret)
2026-06-06 05:42:06 +00:00
Claude
546accc185
Konsolidierung: Security-Härtung + .gitignore
- TOTP-Secret wird verschlüsselt-at-rest gespeichert (Crypto, Klartext-Fallback)
- forgot_password.php: Throttle (3/15min je Session) gegen Reset-Spam
- .gitignore für vendor/, composer.lock, phpunit-Cache, Updater-Laufzeitdaten
- Verifiziert: PHPUnit 15/15 grün, PHPStan ohne Fehler
2026-06-06 05:38:40 +00:00
Claude
c63c5e78f0
README: Maturity-Features dokumentieren (2FA-Recovery, API-Scopes, Reporting, Health, Tests), v2.3.0 + CI-Badge 2026-06-05 20:57:04 +00:00
Claude
997cda01a8
E-Mail-Retry, Voucher-Resend, Tageslimit, Docker-Politur
- Mailer::send mit Retry (2 Versuche); SMTP-Test & Templates waren bereits da
- admin/vouchers.php: Code per E-Mail (erneut) versenden (ajax_resend)
- Tageslimit Voucher pro Nicht-Admin-Benutzer (Setting + Durchsetzung in index)
- Docker: HEALTHCHECK (health.php) + curl; GHCR-Publish-Workflow
- Setting user_daily_voucher_limit + enforce in integrations.php
2026-06-05 20:56:26 +00:00
Claude
2e0f36d6c1
Reporting: admin/reports.php mit Charts, CSV-Export (täglich/Site/Nutzer) & Druck/PDF 2026-06-05 20:50:18 +00:00
Claude
0b1d4ec3b8
Webhook-Events & Health-Endpoint
- Notifier: controllerUnreachable, loginNewIp, updateAvailable
- Login von neuer IP -> Webhook (Abgleich gegen audit_log)
- cron_sync meldet nicht erreichbare Controller; cron_cleanup prüft täglich
  optional auf Updates und meldet Verfügbarkeit
- health.php: Status-Endpoint (DB; optional Controller per ?deep=1&token=)
2026-06-05 20:49:06 +00:00
Claude
c7f9b7d39c
API-Reife: Scopes (read/write), Rate-Limit pro Key, OpenAPI-Spec
- ApiKey::hasScope + checkRateLimit (Fixed-Window/min via api_key_hits)
- bootstrap erzwingt Rate-Limit (429) und api_require_scope() in Endpunkten
- admin/api_keys.php: Scope-Auswahl + Limit beim Erstellen, Anzeige in Tabelle
- api/openapi.php: OpenAPI-3.0-Spec (Import in Postman/Swagger)
- Schema 0003 (api_keys.scope, api_keys.rate_limit, Tabelle api_key_hits)
2026-06-05 20:47:26 +00:00
Claude
ba121d60e6
2FA-Reife: Recovery-Codes, Enforce-Policy für Admins, Admin-Reset
- Recovery-/Backup-Codes (8x, einmalig nutzbar) bei Aktivierung + Regenerieren;
  Login akzeptiert TOTP ODER Recovery-Code
- Setting enforce_2fa_admins: Admins ohne 2FA werden zur Einrichtung geleitet
- Admin kann 2FA eines Nutzers zurücksetzen (admin/users.php)
- Schema 0003 (users.totp_backup_codes); security.php zeigt Codes & Restanzahl
2026-06-05 20:45:28 +00:00
Claude
dce10a8a08
Screenshots vereinheitlicht (1200px/2×) + neue Seiten (API-Keys, 2FA, Integration)
Alle Screenshots im einheitlichen Format neu gerendert; Admin-Mockups mit
vollständiger, konsistenter Sidebar. Neue README-Sektion mit API-Keys-,
Integration-&-Wartung- und 2FA-Screenshot.
2026-06-05 20:19:55 +00:00
Claude
0cc4d3a047
README: neue Features dokumentieren (REST-API, 2FA, Webhooks, Docker), v2.2.0 2026-06-05 19:46:14 +00:00
Claude
9463486225
Erweiterte Features (2/2): Cleanup/DSGVO, Webhooks, REST-API, Backup, CI, Docker
- Auto-Cleanup/DSGVO: cron_cleanup.php (token-geschützt) löscht abgelaufene
  Voucher, Audit-Log, Login-Versuche und Reset-Tokens nach konfigurierbaren
  Fristen
- Webhooks: includes/Notifier.php (Slack/Teams/generisch), Auslösung bei
  Voucher-Erstellung (Web + API)
- REST-API: includes/ApiKey.php (SHA-256, Präfix-Lookup), api/bootstrap.php,
  api/vouchers.php (GET/POST), api/sites.php; admin/api_keys.php zur Verwaltung
- Config-Backup/Restore: admin/backup.php (JSON Export/Import, Cron-Token
  geschützt)
- admin/integrations.php: Trusted-Proxy, Webhook, Cleanup-Fristen
- CI: .github/workflows/ci.yml (php -l auf 7.4 & 8.2, lang-Validierung)
- Docker: Dockerfile, docker-compose.yml (MariaDB), entrypoint (config aus ENV),
  .dockerignore
- Nav + i18n (DE/EN) für alle neuen Admin-Seiten
2026-06-05 19:45:28 +00:00
Claude
eec28f77b8
Erweiterte Features (1/2): Trusted-Proxy-IP, Bandbreitenlimits, 2FA
- Schema: updater/migrations/0002 + database.sql (users.totp_*, voucher_templates
  qos_*, neue Tabelle api_keys)
- Trusted-Proxy-IP: Auth::clientIp() wertet X-Forwarded-For nur hinter
  konfiguriertem trusted_proxy aus (korrektes Rate-Limit/Audit hinter Proxy)
- Bandbreiten-/Datenlimits: UniFiController::createVoucher akzeptiert QoS
  (down/up kbit/s, Datenkontingent MB); Voucher-Profile speichern Limits,
  Voucher-Formular reicht sie via Template-Quick-Select durch
- 2FA (TOTP, RFC 6238): includes/Totp.php (gegen RFC-Testvektoren verifiziert),
  zweistufiger Login, admin/security.php zum Aktivieren/Deaktivieren mit QR,
  Nav-Link + i18n
2026-06-05 19:39:28 +00:00
friloo
f747a3d429
Merge pull request #9 from friloo/claude/ecstatic-cannon-H5hGy
Updater-Migration für Feature-Tabellen + README um neue Features erwe…
2026-06-05 21:27:10 +02:00
Claude
51485810b4
Updater-Migration für Feature-Tabellen + README um neue Features erweitern
- updater/migrations/0001_feature_ui_tables.sql: legt voucher_templates und
  password_reset_tokens idempotent an (CREATE TABLE IF NOT EXISTS), damit
  bestehende Installationen die neuen Tabellen per System-Update erhalten
- Updater-UI: Button "Ausstehende Migrationen ausführen" + run_migrations-Action
  (CSRF-geschützt) im Migrations-Tab
- README: Features (Bulk, Templates, Dark Mode, i18n, Audit-Log, Passwort-Reset),
  zwei neue Screenshots (Bulk-Erstellung, Dashboard Dark Mode), Roadmap & Updater-
  Abschnitt aktualisiert
2026-06-05 19:16:55 +00:00
friloo
607d05c609
Merge pull request #8 from friloo/claude/ecstatic-cannon-H5hGy
Claude/ecstatic cannon h5h gy
2026-06-05 21:12:31 +02:00
Claude
526c43e8ee
Merge: UI/UX-Feature-Branch integrieren + Security-Patches re-applien
Integriert die Feature-Branch (Dark Mode, i18n DE/EN, mobile Admin-Layout,
shared admin_nav, Toasts, Voucher-Templates, Bulk-Erstellung, konfigurierbare
Defaults, Password-Reset, Audit-Log-UI + Audit-Logging) mit der bestehenden
Security-/Updater-Arbeit.

Konfliktauflösung (6 Dateien: index.php + admin/*): Feature-Version als Basis,
darauf die Security-Patches re-appliziert:
- display_errors=0 + log_errors in allen neuen/gemergten Entry-Points
- Crypto::encrypt/decrypt an allen Site-Passwort-Pfaden (sites/index/vouchers/
  dashboard-Sync, inkl. doCreateVoucher + Bulk)
- CSRF-Prüfung für ALLE Voucher-Erstellungen (auch anonym/öffentlich), Token
  unbedingt im Formular; Session-Throttle gegen Spam
- Updater-Maintenance-Hook am Anfang von index.php wiederhergestellt

Auto-Merge verifiziert: Auth.php enthält Session-Timeout UND writeAuditLog;
login.php behält display_errors=0 + OAuth-state. Updater-Link in shared
admin_nav.php (i18n-Key nav_update DE/EN). Alle PHP-Dateien linten sauber.
2026-06-05 19:10:18 +00:00
friloo
8319432317
Merge pull request #7 from friloo/claude/ecstatic-cannon-H5hGy
Claude/ecstatic cannon h5h gy
2026-06-05 21:05:15 +02:00
Claude
63f1e07681
Neue README mit Screenshots + Updater-Dokumentation
- Überarbeitete, bebilderte Readme.md (Features, Installation, Auto-Updater,
  Sicherheit, Troubleshooting, API)
- 7 gerenderte Screenshots unter docs/screenshots/ (Login, Voucher-Erstellung,
  Voucher-Ergebnis, Dashboard, Updater, Wartungsmodus)
2026-06-05 19:00:36 +00:00
friloo
15dc87cb2d
Merge pull request #6 from friloo/claude/ecstatic-cannon-H5hGy
Claude/ecstatic cannon h5h gy
2026-06-05 20:56:51 +02:00