Doku: Sicherheits- & Deployment-Hinweise (Auth, Rollen, Verifizierung)

Dokumentiert die deployment-kritischen und sicherheitsrelevanten Punkte der
Auth-Phase: Reihenfolge der Migrationen (Verifizierungs-Backfill gegen Lockout,
Legacy-editor→customer-Downgrade), der Sicherheits-Fix der Editor-Über-
berechtigung (65.950 Legacy-User hatten Admin-Zugriff), die Firmen-Scope-
Verhaltensänderung bei PMs und der Magic-Link-Kontaktzugang. PROGRESS-Log-
Eintrag (16.06.) und README-Index ergänzt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-06-16 08:35:04 +00:00
parent 980763c362
commit 84f7eb3aab
3 changed files with 113 additions and 1 deletions

View file

@ -5,6 +5,39 @@
---
## 2026-06-16 · WS-1/WS-6/WS-2 · Canonical, Auth-Flow, Sicherheitsfix, Firmen-Scope ✅
- **WS-1 (Canonical/SEO)**: Zentrale `<head>`-Infrastruktur im Web-Layout
(`<link rel="canonical">`, OpenGraph, Twitter-Cards). Self-Canonical aus der
Portal-URL + Request-Pfad (pro Portal getrennt) — bewusst nicht aus
`url()->current()`, da `URL::forceRootUrl` sonst alle Portale auf
pressekonto.test kanonisiert. Erfüllt Duplicate-Content-Update §5.
- **WS-6 (Auth-Flow)**: E-Mail-Verifizierung scharf geschaltet
(`User implements MustVerifyEmail`). Registrierung → inaktives, rollenloses
Konto → Danke-/Notice-Seite → Verifizierungsmail → Klick aktiviert + vergibt
`customer` (`ActivateUserAfterVerification`). Backfill-Migration verhindert
Lockout der ~59k aktiven Bestands-User. Magic-Link als Modal mit eigener
E-Mail-Eingabe. Logout auf Notice via POST-Formular (419-Fix). Guest-Redirect
rollenbewusst (403-Sackgasse). Magic-Link-Consume rollensicher.
- **🔒 SICHERHEIT**: Legacy-Import mappte Alt-Gruppe 2 (Self-Publisher, **65.950
User**) auf `editor` = **Admin-Panel-Zugriff**. Mapping auf `customer`
korrigiert; Daten-Migration stuft die bestehenden Legacy-Editoren herab
(`editor` → 0). Details + Deployment-Reihenfolge siehe
`docs/weiteres/Sicherheit & Deployment-Hinweise (Auth, Rollen, Verifizierung).md`.
- **WS-2 (Firmenkontakt-Zugang)**: PM-Zugriff von Autor-only auf **Autor ODER
Firmenmitglied** erweitert (Policy + Queries). `/pressekontakt-zugang`:
enumeration-sicheres Formular → lazy, de-duplizierter `customer`-Account +
Firmen-Mitgliedschaft + Login-Magic-Link (bestehende Infra wiederverwendet,
keine Schema-Änderung). Lazy-Account entsteht bei der Anfrage (bewusst, statt
fragiler `magic_links`-ENUM/FK-Migration über SQLite/MySQL).
- **Commits**: c804f3b (WS-1), 94cb209 (WS-6 + Sicherheitsfix), 980763c (WS-2).
- **Build/Test**: Suite 582 passed / 1 skipped, Pint clean, Web-Bundle gebaut.
- **Offen**: Google-Login (Socialite) als Rest aus WS-6; „Verwalten"-Link auf
der öffentlichen PM beim PM-Frontend-Wiring; strikt „Account erst beim Klick"
nur falls gewünscht (kostet Migration).
---
## 2026-06-12 · Tagesabschluss · PM-Vorschau-Feinschliff + Next Steps ✅
- **Was**: Letzte Review-Runde auf der PM-Vorschauseite: Sprache-Kachel

View file

@ -36,7 +36,8 @@ Sie verlinkt die zentralen Dokumente und sortiert sie nach „Was ist der aktuel
- [`Decision-Update Phase-2-Funktionen & Magic-Link-Änderungsprozess.md`](./weiteres/Decision-Update%20Phase-2-Funktionen%20&%20Magic-Link-%C3%84nderungsprozess.md) — Boost + Veröffentlichungsnachweis (Launch), Magic-Link-Zugangs-/Änderungsprozess, Phase-2-Funktionen (Vorab-Prüfung, Prüfzähler, kostenpflichtige Änderungspfade). **Noch nicht umgesetzt.**
- [`Decision-Update Duplicate-Content & Duplicate-Checking.md`](./weiteres/Decision-Update%20Duplicate-Content%20&%20Duplicate-Checking.md) — Cross-Portal-Duplicate-Content (SEO) vs. Duplikat-Erkennung eingereichter PMs. **Noch nicht umgesetzt.**
- [`Detailplan Umsetzung Launch-Slice (Magic-Link, Compliance, Bestandsschutz, Auth).md`](./weiteres/Detailplan%20Umsetzung%20Launch-Slice%20%28Magic-Link%2C%20Compliance%2C%20Bestandsschutz%2C%20Auth%29.md) — konkreter Umsetzungsplan (WS-1 bis WS-8) aus den beiden Decision-Updates + Merkliste; verbindliche Entscheidungen vom 15.06.2026 (Legacy-Posten bleiben, Pflicht-E-Mail-Verifizierung, Socialite freigegeben). **In Umsetzung.**
- [`Detailplan Umsetzung Launch-Slice (Magic-Link, Compliance, Bestandsschutz, Auth).md`](./weiteres/Detailplan%20Umsetzung%20Launch-Slice%20%28Magic-Link%2C%20Compliance%2C%20Bestandsschutz%2C%20Auth%29.md) — konkreter Umsetzungsplan (WS-1 bis WS-8) aus den beiden Decision-Updates + Merkliste; verbindliche Entscheidungen vom 15.06.2026 (Legacy-Posten bleiben, Pflicht-E-Mail-Verifizierung, Socialite freigegeben). **In Umsetzung** (WS-1, WS-6 ohne Google, WS-2 erledigt).
- [`Sicherheit & Deployment-Hinweise (Auth, Rollen, Verifizierung).md`](./weiteres/Sicherheit%20%26%20Deployment-Hinweise%20%28Auth%2C%20Rollen%2C%20Verifizierung%29.md) — **deployment-kritisch:** Reihenfolge der Migrationen (Verifizierungs-Backfill, Legacy-Rollen-Downgrade), der Sicherheits-Fix der Editor-Überberechtigung, Firmen-Scope-Verhaltensänderung und der Magic-Link-Kontaktzugang. Feed für die Live-Deployment-Checkliste (WS-7).
- Das Decision-Update „Verlinkung & Backlinks" ist umgesetzt (systemseitige `rel`-Auszeichnung, `PressReleaseLinkPolicy`, 12.06.2026) und wurde nach der Integration in §4 des Preisstruktur-Decision-Updates entfernt — Umsetzungsdetails im Hub-Flux-PROGRESS-Log.
### `user-admin/` — User-/Admin-Backend

View file

@ -0,0 +1,78 @@
**Version:** Juni 2026 · **Datum:** 16.06.2026 · **Status:** Umgesetzt
**Scope:** Sicherheits- und deployment-kritische Punkte aus der Auth-/Rollen-/Verifizierungs-Phase (WS-6 & WS-2). Dieses Dokument bündelt, was beim Go-Live zwingend beachtet werden muss. Feed für die spätere Live-Deployment-Checkliste (WS-7).
---
## 1. ⚠️ SICHERHEIT — Legacy-Rollen-Überberechtigung (behoben)
**Befund:** Der Legacy-Import (`app/Services/Import/UserImporter.php`) mappte die Alt-Gruppe 2 auf die neue Rolle `editor`. Die Alt-Gruppe 2 war jedoch die normale **Self-Publisher-Masse** (65.950 von 66.151 Usern) keine Redaktions-Mitarbeiter. Im neuen Rollenmodell gewährt `editor` **Admin-Panel-Zugriff** (`User::canAccessAdmin()` prüft `hasRole(['admin','editor'])`).
**Auswirkung:** Praktisch jeder Legacy-Kunde konnte sich insbesondere über den Magic-Link-Login ins **komplette Admin-Panel** einloggen.
**Fix:**
- Mapping korrigiert: Alt-Gruppe 2 → `customer` (statt `editor`). `editor` wird ab jetzt ausschließlich manuell an echtes Personal vergeben.
- Daten-Migration `2026_06_16_080913_downgrade_legacy_editor_users_to_customer` stuft die bestehenden Legacy-`editor` (alle mit `legacy_portal`) auf `customer` herab. Chunked (Placeholder-Limit), nicht umkehrbar.
- Ergebnis nach Migration: `editor = 0`, `customer ≈ 65.952`.
**Deployment / Nachkontrolle:**
- Migration MUSS auf Prod laufen.
- Es bleiben **4 Legacy-Admins** (Alt-Gruppe 1) **manuell prüfen**, ob das wirklich Personal ist.
- Kontrolle nach Deploy: `Spatie\Permission\Models\Role::findByName('editor')->users()->whereNotNull('legacy_portal')->count()` muss 0 sein.
---
## 2. ⚠️ DEPLOYMENT-KRITISCH — E-Mail-Verifizierung scharf
`User` implementiert jetzt `MustVerifyEmail`; die `verified`-Middleware auf den Panel-Routen greift damit real (war vorher wirkungslos).
**Lockout-Gefahr:** Ohne Vorsorge würden ALLE Bestands-User mit `email_verified_at = NULL` (alle 66.151, davon ~59.403 aktiv) ausgesperrt.
**Absicherung:** Migration `2026_06_15_101337_backfill_email_verified_at_for_existing_users` setzt `email_verified_at` für alle bestehenden User.
**Deployment:** Diese Migration MUSS mit dem Deploy laufen, **bevor** echter Traffic auf die geschützten Routen kommt. Neue Registrierungen (nach Deploy) bleiben absichtlich `NULL`, bis verifiziert.
**Registrierungs-Verhalten (Entscheidung 15.06.):**
- Selbst-Registrierung legt ein **inaktives, rollenloses** Konto an → Danke-/Notice-Seite → Verifizierungsmail.
- Bestätigter Link → `is_active = true` + `customer`-Rolle (`App\Listeners\ActivateUserAfterVerification`).
- **Ausnahme-Kanäle** (gelten als verifiziert, kein E-Mail-Schritt): Magic-Link, Kontaktzugang (WS-2), Google-Login (geplant).
---
## 3. VERHALTENSÄNDERUNG — Firmen-Scope für Pressemitteilungen
PM-Zugriff war hart an `user_id` (Autor) gebunden. Jetzt **additiv**: Zugriff = **Autor ODER Mitglied der zugeordneten Firma** (Owner via `owner_user_id` oder `company_user`-Pivot).
- Betroffen: `PressReleasePolicy::canManage()` (view/update/submitForReview/delete) sowie die Queries der Kunden-Komponenten (Liste/Show/Edit) und `User::accessibleCompanyIds()`.
- **Solo-Owner:** keine sichtbare Änderung (sie sind Autor ihrer PMs).
- **Firmen mit mehreren Mitgliedern:** Mitglieder sehen/bearbeiten jetzt **alle** PMs der Firma (gewollt „gesamte Firma").
---
## 4. Magic-Link-Zugang für Pressekontakte (WS-2)
Öffentliches Formular `/pressekontakt-zugang` (`auth.contact-access`):
- **Enumeration-sicher** (neutrale Antwort unabhängig vom Treffer), **Honeypot** + **Rate-Limit**.
- Eine hinterlegte Kontakt-E-Mail → **lazy** angelegter, per E-Mail **de-duplizierter** `customer`-Account (aktiv, verifiziert), der den Firmen seiner Kontakte als **Mitglied** zugeordnet wird.
- Versand über den **bestehenden Login-Magic-Link** (`MagicLinkGenerator` + `MagicLinkConsumeController`) keine Schema-Änderung.
**Design-Nuance (bewusst):** Der Account wird beim **Absenden der Anfrage** angelegt (nicht erst beim Klick), um eine fragile `magic_links`-Schema-Änderung (ENUM/FK über SQLite-Tests + MySQL-Prod) zu vermeiden. Er ist „lazy" (nur für real existierende Kontakt-Mails) und ohne den per Mail versendeten Token wertlos.
---
## 5. Guest-Redirect rollenbewusst (403-Sackgasse behoben)
`bootstrap/app.php``redirectUsersTo`: eingeloggte User auf Gast-Routen (`/login`, `/register`) werden rollen-/verifizierungsbewusst geleitet (Admin → `/dashboard`, Customer → `/admin/me`, unverifiziert → Notice). Verhindert, dass ein Customer auf das feste `/dashboard` (403) läuft und festsitzt.
Ergänzend: Magic-Link-Consume nutzt einen rollensicheren Redirect **ohne** `intended()` (eine als Gast besuchte Admin-URL darf einen Customer nicht in den 403-Bereich schicken).
---
## 6. Deployment-Reihenfolge (Migrationen dieser Phase)
1. `2026_06_15_101337_backfill_email_verified_at_for_existing_users` — verhindert Lockout.
2. `2026_06_16_080913_downgrade_legacy_editor_users_to_customer` — schließt die Admin-Überberechtigung.
**Nach Deploy prüfen:**
- `editor`-Rolle hat keine Legacy-User mehr.
- Niemand ungewollt ausgesperrt (Stichprobe aktiver Legacy-User → Login/Panel erreichbar).
- Die 4 verbliebenen Legacy-Admins sind legitimes Personal.