Commit Graph
7 Commits
Author SHA1 Message Date
clemensandClaude Opus 4.8 d18c55eef5 Formular-Abstaende korrigiert und Anleitungsseite ergaenzt
Abstaende:
Im Template hat das Label 1em Abstand nach unten, das Eingabefeld aber gar
keinen, und die Formular-Grids nutzen keinen vertikalen Gutter (gtr-uniform).
Dadurch war der Abstand vom Feld zum naechsten Label 0, waehrend Label zu
eigenem Feld 1em betrug - das Label wirkte, als gehoere es zum Feld darueber.
Jetzt sitzt das Label eng an seinem eigenen Feld (0,5em) und die Felder haben
1,5em Abstand nach unten.

Ausserdem stylt main.css die Typen number, date, datetime-local und file gar
nicht; diese Felder erschienen als kleine native Kaestchen zwischen den sonst
einheitlichen Feldern (z. B. "Listenfenster in Tagen" und "Zeilenhoehe im
Ausdruck"). Sie bekommen jetzt dasselbe Aussehen wie die Textfelder.

Die Anpassungen liegen in einer eigenen assets/css/app.css, damit main.css als
Template-Datei unveraendert bleibt. Nebenbei: .hint-box.error war nirgends
definiert, obwohl es die haeufigste Variante ist - Fehlermeldungen erschienen
ungefaerbt wie neutrale Hinweise.

In faq.php, hinweise.php, namenanpassen.php und stricheintragen.php standen
<br>/<br><br> als Abstandsersatz hinter Labels und Feldern; mit den neuen
Abstaenden waere daraus doppelter Leerraum geworden. Entfernt, das Layout
kommt jetzt aus dem CSS.

Anleitung:
Neue Seite anleitung.php mit den wichtigsten Funktionen, gegliedert nach
Zielgruppe. Die Abschnitte fuer Kassenwart bzw. Administration werden nur
eingeblendet, wenn die Rolle sie auch nutzen kann - sonst stuenden dort
Hinweise auf Menuepunkte, die es fuer den Nutzer nicht gibt. Verlinkt im Menue
unter "Kaffeeliste" und im Smoke-Test abgedeckt.

Geprueft: alle 12 Formularseiten rendern fehlerfrei, http-smoke 34/0,
role-matrix 55/0, tenant-isolation 12/0, settings-flow 15/0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 11:51:14 +02:00
clemensandClaude Opus 4.8 3e24910831 Legacy-Abbau Schritt 2: Legacy-Authentifizierung entfernt
Die Zugriffspruefung lief bisher in 19 Dateien auf einen Fallback gegen die
Legacy-Tabelle kl_Mitarbeiter (checkKaffeelisteAdmin/-Access). Der Zugang
haengt jetzt ausschliesslich an der SaaS-Anmeldung.

- Fallback-Bloecke in allen 19 Dateien entfernt, ebenso getUserName/getUserId
- functions.php besteht nur noch aus der SaaS-Anmeldung; die per String
  zusammengebaute Abfrage "WHERE Email like '<eingabe>'" ist damit weg
- config.php baut keine sqlsrv-Verbindung mehr auf, der Kompatibilitaetslayer
  lib/sqlsrv_mysql_compat.php ist verwaist und entfaellt
- Auto-Login per DEV_AUTH_EMAIL gibt es nicht mehr: er meldete jeden Besucher
  an und machte damit den Login-Schutz unpruefbar. Angemeldet wird auch lokal
  ueber login.php; die Variable dient nur noch scripts/init-mysql-dev.php

http-smoke war an die Golden-Master-Daten des Default-Mandanten gebunden und
hatte deshalb sechs dauerhaft rote Pruefungen. Der Test legt sich jetzt einen
eigenen Mandanten mit bekannten Salden an, meldet sich per HTTP an und raeumt
danach auf. Geschuetzte Seiten werden nicht mehr ueber das Wort "Login" im
Text geprueft, sondern ueber die tatsaechliche 302-Umleitung.

  http-smoke        27 PASS / 6 FAIL  ->  33 PASS / 0 FAIL
  role-matrix       55 PASS / 0 FAIL  ->  unveraendert
  tenant-isolation   9 PASS / 1 FAIL  ->  11 PASS / 1 FAIL (Altfehler)

Ausserdem "keine Zugang" -> "keinen Zugang" in zwei Fehlermeldungen; der
Rollentest erkannte die Ablehnung an genau diesem Tippfehler und wurde
mitgezogen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:10:09 +02:00
clemensandClaude Sonnet 5 54217d2acb M8: Security-Headers, Rate-Limits und Audit-Log
Erste drei Bausteine der Haertung:

- Security-Headers (X-Content-Type-Options, X-Frame-Options, Referrer-
  Policy, Permissions-Policy, HSTS bei HTTPS) laufen automatisch ueber
  app_send_security_headers() am Ende von app/bootstrap.php fuer jede
  dynamische Seite; landing.php war als einzige Seite ganz ohne PHP und
  bekam einen minimalen Bootstrap-Aufruf. Bewusst kein CSP, da die
  bestehenden Templates durchgaengig auf Inline-style-Attribute setzen.
- DB-gestuetzte Rate-Limits (neue Tabelle rate_limit_attempts) fuer
  Login (10/15min je E-Mail, 20/15min je IP), Registrierung (5/h je IP)
  und Passwort-Reset-Anfrage (5/h je E-Mail, 10/h je IP); bei
  ausgereiztem Reset-Limit erscheint dieselbe generische Meldung wie im
  Erfolgsfall, um kein Konto-Enumeration-Signal zu geben.
- Zentrales Audit-Log (neue Tabelle audit_log) fuer Mitgliederverwaltung,
  Zugangsvergabe/-entzug, Storno, Mandant-Einstellungen, Hinweise,
  CSV-Import, Jahresbonus-Verteilung und Live-Mailversand; sichtbar fuer
  Owner/Admin auf mandant-einstellungen.php.

Live getestet: Rate-Limit greift nach 10 Fehlversuchen, Audit-Log-Eintrag
mit korrekten Metadaten und Nutzernamen ueber einen isolierten Test-
Mandanten geprueft. Alle Regressionstests weiterhin gruen (26/26 Smoke,
104 Golden-Master-Assertions).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 18:04:14 +02:00
clemensandClaude Sonnet 5 aeb687f42e M5: Hinweise auf tenant-scoped Notices umziehen, Mitgliederzugang auf Rollen umstellen
Hinweise:
- Neue Tabelle notices (tenant-scoped, Soft-Delete via deleted_at) loest
  die global unscoped kl_hinweise als aktive Datenquelle ab; Migration
  uebernimmt einmalig aktuell gueltige kl_hinweise-Eintraege fuer den
  Default-Mandanten. kl_hinweise bleibt als Golden-Master-Referenz stehen.
- hinweise.php und der Banner in header.php sind tenant-scoped umgestellt.

Mitgliederverwaltung:
- mitarbeiterverwalten.php verwaltet jetzt participants (tenant-scoped)
  statt der global unscoped kl_Mitarbeiter-Tabelle als primaere Quelle.
  Das behebt nebenbei ein Mandanten-Datenleck: jeder SaaS-Mandant mit
  Owner/Admin-Rolle haette zuvor die komplette Default-Mandanten-
  Mitgliederliste sehen und bearbeiten koennen.
- Fuer den Default-Mandanten bleibt Dual-Write nach kl_Mitarbeiter
  bestehen, damit stricheintragen.php/einzahlung.php weiter funktionieren;
  andere Mandanten werden rein participant-nativ verwaltet.
- Die Legacy-Administrator-Checkbox ist raus. Stattdessen kann ein Admin
  je Mitglied unabhaengig von Name/E-Mail einen Login-Zugang mit Rolle
  (member/treasurer/admin) gewaehren oder entziehen
  (saas_grant_participant_access / saas_revoke_participant_access).
  Einladung laeuft ueber den bestehenden Passwort-Reset-Mechanismus,
  Entzug setzt die Mitgliedschaft auf revoked statt sie zu loeschen.
- Kompletter Flow live getestet: anlegen, Zugang gewaehren, Einladungsmail,
  Passwort setzen, Login, Rollenschutz, Zugang entziehen, Login-Sperre.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 00:18:55 +02:00
clemens 444f0a269b CSRF - erste Erichtigung 2026-07-12 08:55:56 +02:00
clemens 2e6d79e896 M0 Einrichtung 2026-07-11 22:24:22 +02:00
clemens 92d94f1c95 renew 2026-07-11 18:21:33 +02:00