diff --git a/dev/frontend/hub-flux/PROGRESS.md b/dev/frontend/hub-flux/PROGRESS.md index 31d18ea..dda0558 100644 --- a/dev/frontend/hub-flux/PROGRESS.md +++ b/dev/frontend/hub-flux/PROGRESS.md @@ -5,6 +5,39 @@ --- +## 2026-06-16 · WS-1/WS-6/WS-2 · Canonical, Auth-Flow, Sicherheitsfix, Firmen-Scope ✅ + +- **WS-1 (Canonical/SEO)**: Zentrale `
`-Infrastruktur im Web-Layout + (``, 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 diff --git a/docs/README.md b/docs/README.md index 7bd6101..fe0f28e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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 diff --git a/docs/weiteres/Sicherheit & Deployment-Hinweise (Auth, Rollen, Verifizierung).md b/docs/weiteres/Sicherheit & Deployment-Hinweise (Auth, Rollen, Verifizierung).md new file mode 100644 index 0000000..81cab24 --- /dev/null +++ b/docs/weiteres/Sicherheit & Deployment-Hinweise (Auth, Rollen, Verifizierung).md @@ -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.