diff --git a/.beads/last-touched b/.beads/last-touched index 4dddbd8..b6164a8 100644 --- a/.beads/last-touched +++ b/.beads/last-touched @@ -1 +1 @@ -fotospiel-app-vel +fotospiel-app-vc3 diff --git a/docs/testing/e2e.md b/docs/testing/e2e.md index f70b222..ac13d34 100644 --- a/docs/testing/e2e.md +++ b/docs/testing/e2e.md @@ -57,6 +57,48 @@ The backend exposes `/api/_testing/...` endpoints (local/testing env only): Playwright fixtures (`tests/ui/helpers/test-fixtures.ts`) provide helpers that wrap these endpoints. +## Security Review (Dynamic Tests) + +This section provides a staged, repeatable checklist for dynamic security reviews across product surfaces. It complements the UI suites above and is intended for staging/test environments. + +### Environment Assumptions (Required) +- **Run in staging/test only** — never against production data. +- **Dedicated test tenants/users** — use seeded accounts (see above) and avoid real customer data. +- **Sandbox billing** — Paddle sandbox and mock webhook endpoints only. +- **Testing token enabled** — set `E2E_TESTING_TOKEN` and ensure the backend accepts it for `/api/_testing/*`. +- **Stable base URL** — set `E2E_BASE_URL` to the target environment (`http://localhost:8000` or staging). +- **Email sink** — use `/api/_testing/mailbox` instead of real email delivery. +- **Rate limits** — keep request volume low; avoid concurrent fuzzing unless explicitly safe. + +### Checklist: Marketing + Public API (Dynamic) +1) **Public routes**: `/de`, `/en`, `/de/packages`, `/de/blog`, `/de/kontakt` render with expected locale and canonical/hreflang tags. +2) **Redirect hygiene**: non‑prefixed routes redirect to locale (`/contact` → `/de/kontakt` or `/en/contact`). +3) **Contact form**: validation errors for missing fields; honeypot rejects bot payload; throttle returns 429 on excessive posts. +4) **Public API**: `GET /api/v1/events/{token}` and `/photos` reject invalid/expired tokens with 404/410 (no sensitive info). +5) **Abuse controls**: upload endpoints return 429 when rate‑limited; no 500s on malformed payloads. +6) **CORS**: public API does not allow wildcard origins for authenticated endpoints. + +### Checklist: Guest PWA (Dynamic) +1) **Join token**: valid token joins, invalid/expired token shows safe error (no leakage). +2) **Permissions**: guest cannot access tenant/admin endpoints; 401/403 as expected. +3) **Uploads**: file type + size limits enforced; invalid uploads fail gracefully. +4) **Offline mode**: queued uploads don’t leak data; resync uses same join token. +5) **Likes/tasks**: actions scoped to event; cross‑event access denied. + +### Checklist: Event Admin (Dynamic) +1) **Login flow**: correct error on invalid creds; throttling kicks in after repeated attempts. +2) **Tenant isolation**: admin cannot access other tenants’ events/photos (403/404). +3) **Join token lifecycle**: regenerate/disable token invalidates old links immediately. +4) **Moderation controls**: only admin can approve/hide; guest cannot mutate. +5) **Exports**: admin‑only endpoints require auth; signed URLs expire as expected. + +### Checklist: Webhooks/Billing (Dynamic) +1) **Signature validation**: invalid signature is rejected (401/403) and logged. +2) **Freshness**: stale timestamps are rejected; replayed webhook payloads are idempotent. +3) **Paddle sandbox flow**: use `/api/_testing/checkout/sessions/{session}/simulate-paddle` to simulate success/failure; verify ledger updates. +4) **Webhook retries**: transient failures produce retry‑safe behavior (no duplicate ledger entries). +5) **Error handling**: malformed payload returns 4xx (not 500), with minimal error detail. + ## Suite Layout & Goals | Suite | Location | Primary Coverage |