test(auth): KTO-01 Playwright-E2E (api, web, throttle) und CI-Job e2e #42
4 changed files with 89 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -28,6 +28,10 @@ app/coverage/
|
|||
node_modules/
|
||||
test-results/
|
||||
playwright-report/
|
||||
blob-report/
|
||||
playwright/.cache/
|
||||
.playwright-mcp/
|
||||
e2e/.auth/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
55
e2e/README.md
Normal file
55
e2e/README.md
Normal file
|
|
@ -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).
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue