Commit Graph
2 Commits
Author SHA1 Message Date
florian.wildeandClaude Opus 5 7f52613821 feat(admin): Verwaltung fuer Benutzer, Gruppen und das eigene Konto
Setzt die Rechte aus dem vorigen Commit in den Oberflaechen um und
ergaenzt die fehlenden Verwaltungsseiten.

Neu:
- /admin/users  - Konten anlegen, Rolle und Sperre setzen, Passwort
  zuruecksetzen, Gruppenzuordnung je Konto
- /admin/groups - Gruppen anlegen und umbenennen, Mitglieder samt
  Rolle pflegen, zugeordnete Domains einsehen
- /admin/profile - eigenes Konto: Gruppenzugehoerigkeit ansehen und
  das Passwort aendern. Das fehlte bisher vollstaendig, auch fuer
  den einen Administrator.

Domains sind jetzt Administratorsache, weil dort die Gruppe zugewiesen
wird. Kurzlinks, Statistik und QR-Codes richten sich nach der Gruppe:
ein fremder Kurzlink antwortet mit 404 (seine Existenz geht den
Aufrufer nichts an), ein sichtbarer ohne Schreibrecht mit 403.

Geschlossene Luecke: /admin/uploads/{file} pruefte bisher nur, ob
ueberhaupt jemand angemeldet ist. Da alle Logos in einem gemeinsamen
Verzeichnis liegen, war der Dateiname die einzige Huerde. Ausgeliefert
wird jetzt nur noch, was laut Datenbank zu einem Kurzlink aus einer
Gruppe des Aufrufers gehoert.

Die Navigation blendet aus, wofuer die Rechte fehlen - das ist
Bedienkomfort, kein Zugriffsschutz: die Routen pruefen unabhaengig
davon noch einmal.

Der Setup-Assistent legt das erste Konto als Administrator an und
traegt es gleich als Editor der Gruppe "Standard" ein. Ohne das
koennte es zwar verwalten, aber selbst keine Kurzlinks anlegen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:03:20 +02:00
florian.wilde 8b6e05020b feat(domains): Mehrere Kurzlink-Domains je Installation
short.example.de/messe und qr.example.de/messe koennen auf
unterschiedliche Ziele zeigen. Die Domain ergibt sich aus dem
Host-Header; Slugs sind nur noch innerhalb ihrer Domain eindeutig.

Bestandslinks tragen nach der Migration den Platzhalter 0 und werden
beim ersten Zugriff der aus APP_BASE_URL erzeugten Standarddomain
zugeordnet. Ein Sentinel statt NULL, weil SQLite NULL-Werte in einem
UNIQUE-Index als jeweils verschieden behandelt - die Eindeutigkeit
waere sonst nicht durchgesetzt.

Unbekannte Hosts landen auf der Standarddomain, damit bestehende Links
auch beim Aufruf ueber die IP oder hinter einem Proxy funktionieren.
2026-08-03 18:11:39 +02:00