From ec2d45c319668393cf28438377acee2218fb5bce Mon Sep 17 00:00:00 2001 From: cschlaefke Date: Tue, 3 Nov 2026 10:42:28 +0100 Subject: [PATCH] docs(auth): document E2E setup and SMTP outage spike result Refs #38 Co-Authored-By: Claude Sonnet 5.5 --- .gitignore | 4 +++ docs/auth-konfiguration.md | 25 +++++++++++++++++ e2e/README.md | 55 ++++++++++++++++++++++++++++++++++++++ supabase/README.md | 5 ++++ 4 files changed, 89 insertions(+) create mode 100644 e2e/README.md diff --git a/.gitignore b/.gitignore index 09dff15..222a72c 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,10 @@ app/coverage/ node_modules/ test-results/ playwright-report/ +blob-report/ +playwright/.cache/ +.playwright-mcp/ +e2e/.auth/ # OS .DS_Store diff --git a/docs/auth-konfiguration.md b/docs/auth-konfiguration.md index 82410f5..9eeeddc 100644 --- a/docs/auth-konfiguration.md +++ b/docs/auth-konfiguration.md @@ -176,3 +176,28 @@ Automatisiert nicht abdeckbar (Spec § 7.1); vor dem Release abhaken: - **Magic Link / OTP** sind nicht abschaltbar, nur am Gateway sperrbar (R4). - **Vorlagen-Rückfall:** Unerreichbare Vorlagen-URL → stille englische Standardvorlage (R5). - **Plain-Text-Teil der Mails:** GoTrue sendet nur HTML. Die Vorlagen zeigen den Link deshalb zusätzlich als Klartext; Mailpit erzeugt lokal einen Text-Teil. + +## 7. E2E-Tests und SMTP-Ausfall (Issue #38, Spike #37) + +Die Playwright-Tests unter `e2e/` (Projekte `api`, `web`, `throttle`, `spike`; Anleitung `e2e/README.md`) sichern diese Konfiguration ab. Konstanten stehen in `e2e/support/auth-config.ts`; `tests/api/config.spec.ts` prüft sie gegen `supabase/config.toml` und diese Datei (alle IDs AUTH-CFG-01 bis -25 müssen in Abschnitt 1 vorkommen). + +| ID | Absichernder Test | +|---|---| +| AUTH-CFG-04, -24 | `tests/api/krit04-enumeration.spec.ts` (Signup mit bestätigter Adresse → 200, `identities` leer, keine Mail, altes Passwort gilt) | +| AUTH-CFG-05 | `krit02-03-validierung.spec.ts` (9 Zeichen → 422 `weak_password`) | +| AUTH-CFG-07 | `krit08-reset-link.spec.ts` und `web/krit08-reset.spec.ts` (Link nach 1 h + 1 s abgelaufen, 60 s vor Ablauf gültig) | +| AUTH-CFG-10, -13 | `tests/throttle/krit07-drosselung.spec.ts` (Login #31 → 429, zweite IP unbeeinflusst, kein `Retry-After`, ohne Header keine Drosselung) | +| AUTH-CFG-14, -15, -16 | `krit05-sitzung.spec.ts`, `config.spec.ts` | +| AUTH-CFG-17, -18, -19 | `krit11-sprache-benachrichtigungen.spec.ts` | + +### SMTP-Ausfall (Spike #37, Stand 2026-11-03, GoTrue `v2.197.0`) + +Messung gegen einen zusätzlichen GoTrue-Container, dessen SMTP-Port 1 die Verbindung ablehnt (`e2e/support/start-throttle-gotrue.sh start smtp-down`, Test `e2e/tests/spike/smtp-down.spec.ts`). Mailpit bleibt für die anderen Tests unberührt. Die Tests prüfen nichts, sie protokollieren. + +| Aufruf | bekannte Adresse | unbekannte Adresse | +|---|---|---| +| `POST /recover` | **500** `unexpected_failure` „Error sending recovery email“ | **200** | +| `POST /resend` (signup) | unbestätigt: **500** „Error sending confirmation email“ | **200** | +| `POST /signup` | unbestätigt: **500**; bestätigt: **200** (erfundener Nutzer, kein Versand) | neu: **500** „Error sending confirmation email“, Nutzer wird **nicht** angelegt (Rollback) | + +Antwortzeiten liegen alle im einstelligen bis niedrigen zweistelligen Millisekundenbereich (Verbindung wird sofort abgelehnt), also kein Zeit-Seitenkanal. **Befund:** Bei nicht erreichbarem SMTP unterscheiden sich die Antworten von `/recover`, `/resend` und `/signup` je nach Existenz des Kontos (500 vs. 200), und zwar nicht nur bei erschöpftem Mail-Limit (R3, F12). Die rohe API verrät dann die Existenz; laut Mapping 4.4 (nicht getestet) würde die App bei Reset 500 als `unexpected`, bei Registrierung als `registrationRejected` anzeigen, also einen Fehler statt des neutralen Bildschirms. Ob die App bei HTTP 500 aus Sendefehlern neutral bleiben soll (wie bei `over_email_send_rate_limit`), ist offen (Issue #37). Nicht untersucht: ein SMTP-Server, der die Verbindung annimmt, aber nicht antwortet (Timeout), und GoTrue hinter dem Produktions-Gateway. Dafür den Container mit einer nicht routbaren SMTP-Adresse (z. B. `GOTRUE_SMTP_HOST=10.255.255.1`) starten und `GOTRUE_SMTP_PORT` bis zum Timeout beobachten. diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 0000000..5879132 --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,55 @@ +# E2E-Tests (Playwright) + +Auth-Tests für KTO-01 (Spec `docs/specs/1-auth-registrierung-anmeldung.md` § 7, Issue #38). Jeder Test +nutzt zufällige E-Mail-Adressen und filtert Mails je Adresse (Mailpit wird nie global geleert), +die Tests laufen deshalb parallel. + +## Projekte + +| Projekt | Ziel | Voraussetzung | Tests | +|---|---|---|---| +| `api` | GoTrue über Kong (`:54321`) + Mailpit (`:54324`) + Postgres (`:54322`) | `supabase start` | 52 | +| `web` | gebaute Flutter-Web-App auf `http://localhost:3000` | zusätzlich `flutter build web` | 21 | +| `throttle` | Extra-GoTrue-Container mit `GOTRUE_RATE_LIMIT_HEADER` (AUTH-CFG-13) | `THROTTLE_GOTRUE_URL` | 4 | +| `spike` | GoTrue mit unerreichbarem SMTP (Issue #37), nicht blockierend | `SPIKE_GOTRUE_URL` | 3 | + +`throttle` und `spike` werden nur registriert, wenn die jeweilige Variable gesetzt ist. + +## Lokal ausführen + +```bash +supabase start -x studio,imgproxy,vector,logflare,edge-runtime,postgres-meta,realtime,storage-api +supabase db reset + +# Web-Build gegen die lokale CLI (echten Anon-Key aus `supabase status -o env` eintragen) +cd app && flutter build web --dart-define-from-file=env/ci.example.json # SUPABASE_URL/ANON_KEY anpassen + +cd ../e2e && npm ci && npx playwright install chromium +npx playwright test --project=api +npx playwright test --project=web # startet `serve -s ../app/build/web -l 3000` selbst + +# Drosselung (Krit. 7) und SMTP-Spike +./support/start-throttle-gotrue.sh start throttle # :9998 +./support/start-throttle-gotrue.sh start smtp-down # :9997 +THROTTLE_GOTRUE_URL=http://127.0.0.1:9998 SPIKE_GOTRUE_URL=http://127.0.0.1:9997 npx playwright test +./support/start-throttle-gotrue.sh stop throttle; ./support/start-throttle-gotrue.sh stop smtp-down +``` + +Umgebungsvariablen (Standard = lokale CLI-Demo-Werte, keine Secrets): `SUPABASE_URL`, +`SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY`, `MAILPIT_URL`, `E2E_DB_URL`, `WEB_URL`, +`TERMS_VERSION`. + +## Aufbau + +- `support/auth-config.ts` – Konstanten mit `AUTH-CFG-nn`-Bezug; `tests/api/config.spec.ts` prüft sie gegen `supabase/config.toml` und `docs/auth-konfiguration.md`. +- `support/gotrue.ts`, `support/mailpit.ts` – REST-Client und Mailfänger-Helfer. +- `support/db.ts` – direkter Postgres-Zugriff, **nur lokal/CI** (bricht bei anderem Host ab); setzt `recovery_sent_at`/`confirmation_sent_at` für Ablauftests. +- `support/web.ts` – Flutter-Web-Helfer (Semantics einschalten, Felder füllen, Uhr verschieben). +- `support/start-throttle-gotrue.sh` – zweiter GoTrue-Container (Profile `throttle`, `smtp-down`). + +## Hinweise zum Web-Projekt + +- Flutter zeichnet auf Canvas. Der Semantics-Baum wird über `flt-semantics-placeholder` eingeschaltet (`enableSemantics`). +- Eingabefelder werden mit `click` + `pressSequentially` gefüllt; `fill` allein geht gelegentlich verloren. +- Immer `localhost` (nicht `127.0.0.1`): Die Mail-Links nutzen die Site-URL (AUTH-CFG-01), sonst liegt die Sitzung in einem anderen `localStorage`. +- Gegen die gemeinsame CLI-Instanz werden nie `X-Forwarded-For`-Header gesendet (R13). diff --git a/supabase/README.md b/supabase/README.md index 09513d8..d25fab8 100644 --- a/supabase/README.md +++ b/supabase/README.md @@ -22,6 +22,11 @@ supabase test db # alle pgTAP-Tests ausführen - Auth-Einstellungen (`AUTH-CFG-nn` in `config.toml`), Env-Block für Staging/Produktion, Release-Checkliste und bekannte Grenzen: [`docs/auth-konfiguration.md`](../docs/auth-konfiguration.md). - Mailvorlagen (Bestätigung, Passwort-Reset; de/en nach `user_metadata.locale`): `templates/`. Lokal landen Mails in Mailpit (`http://127.0.0.1:54324`). +## E2E-Tests (Playwright) +- `e2e/` testet GoTrue über Kong (`api`), die gebaute Web-App (`web`), die IP-Drosselung (`throttle`) und den SMTP-Ausfall (`spike`). Voraussetzung: `supabase start` mit Mailpit und Postgres (Ports 54321, 54322, 54324). +- `e2e/support/db.ts` verbindet sich direkt mit dem lokalen Postgres (Rolle `postgres`) und setzt `recovery_sent_at`/`confirmation_sent_at` für die Ablauftests; es bricht bei nicht-lokalem Host ab. +- Der Extra-Container für `throttle`/`spike` startet mit `e2e/support/start-throttle-gotrue.sh`. Details: [`e2e/README.md`](../e2e/README.md). + ## Regeln - Jede Tabelle hat `id` (uuid, PK), `created_at`, `updated_at` und Row Level Security. - `updated_at` setzt ein Trigger; `id` und `created_at` sind nach dem Anlegen unveränderlich.