feat: technisches Grundgerüst für Instagram-/TikTok-OAuth (Plattform-Verbindung)

Vorbereitung für automatische Beweissicherung statt manuellem
Screenshot-Upload: ein Kunde kann künftig seinen eigenen Instagram-
oder TikTok-Account per Standard-OAuth-Consent verbinden. Bewusst nur
das Grundgerüst — Meta/TikTok verlangen vor öffentlicher Nutzung eine
einmalige Business-Verification/App-Review (Wochen Vorlauf, siehe
CLAUDE.md-Abschnitt "Plattform-Verbindung (OAuth)"), die separat von
dieser Codeänderung läuft.

- internal/socialconnect: Connector-Interface + InstagramConnector/
  TikTokConnector (reiner Authorization-Code-Flow, kein DB-Zugriff).
  Instagram tauscht den Code zweistufig (kurzlebiges → 60-Tage-Token),
  TikTok liefert Access-/Refresh-Token direkt. Endpunkte/Scopes wurden
  gegen aktuelle Entwicklerdokumentation gebaut, nie gegen die echte
  API verifiziert (keine Zugangsdaten vorhanden) — Hinweis dazu im
  Paket- und CLAUDE.md-Kommentar.
- Migration 0006: platform_connection (NICHT append-only, anders als
  finding/extraction/asset — ein Token wird ersetzt, keine Korrektur-
  Zeile), höchstens eine Verbindung pro Account+Plattform.
- internal/web: GET /verbindungen (Übersicht je Plattform: verbunden/
  nicht verbunden/nicht konfiguriert), GET /oauth/{platform}/start
  (State-Cookie gegen CSRF, Redirect zum Consent-Screen),
  GET /oauth/{platform}/callback (State prüfen, Code tauschen,
  Verbindung speichern), POST /verbindungen/{platform}/trennen.
- Ohne gesetzte Client-Credentials + PUBLIC_BASE_URL bleibt die
  Funktion inaktiv (kein Connector konfiguriert, /verbindungen zeigt
  "nicht konfiguriert", kein Absturz) — main.go loggt das beim Start.

Volle Testsuite inkl. echter Postgres-Tests grün; OAuth-Flow gegen
Fake-Connector/httptest-Server verifiziert (State-Mismatch, Ablehnung
durch Nutzer, Token-Speicherung, Mandantentrennung). Kein Live-Test
gegen echte Meta-/TikTok-Endpunkte möglich, da noch keine echten
Client-Credentials existieren.
This commit is contained in:
noroot
2026-08-28 09:32:43 +02:00
parent 790ab20651
commit 5813e6209c
18 changed files with 1246 additions and 15 deletions

View File

@@ -112,6 +112,7 @@ Managed Postgres in der EU (DSGVO).
│ ├── rules/ # YAML-Loader, Auswertung, Versionierung
│ ├── evidence/ # Hashing, Zeitstempel, Append-only-Log
│ ├── dossier/ # PDF-Erzeugung
│ ├── socialconnect/ # OAuth-Flow Instagram/TikTok (Plattform-Verbindung)
│ ├── store/ # Postgres, Migrationen
│ └── web/ # Handler, Templates
├── rules/ # YAML-Regeln, versioniert im Git
@@ -180,6 +181,12 @@ Plus drei Tabellen für Auth/Mandantentrennung (`account`, `app_user`,
- `participant` — Beteiligter an einer Submission mit Rolle
(`creator`, `agentur`, `marke`, `kanzlei`) und Beitrag zur
Verantwortungsmatrix (wer hat vorgegeben, wer freigegeben)
- `platform_connection` — die per OAuth hergestellte Verbindung eines
Accounts zu seinem eigenen Instagram- oder TikTok-Account (siehe
Abschnitt „Plattform-Verbindung (OAuth)" unten). NICHT append-only —
Tokens laufen ab und werden erneuert, eine Verbindung kann getrennt
und neu hergestellt werden; höchstens eine Verbindung pro
Account+Plattform (`UNIQUE(account_id, platform)`)
**Append-only.** Kein UPDATE auf `finding`, `extraction`, `asset`,
`evidence_package` oder `audit_log`. Korrekturen sind neue Zeilen mit
@@ -203,6 +210,39 @@ gültige Sitzung (sonst Redirect zu `/login`); `POST /pruefen`,
existierender behandelt (404), nie mit einer expliziten 403 bestätigt —
sonst würde die Antwort selbst verraten, dass die ID existiert.
**Plattform-Verbindung (OAuth):** Jeder Kunde kann optional seinen
eigenen Instagram- oder TikTok-Account verbinden (`GET /verbindungen`),
damit die Beweissicherung einen veröffentlichten Beitrag künftig direkt
per API abrufen kann, statt ihn manuell hochzuladen — reiner
Authorization-Code-Flow, jeder Kunde autorisiert nur seinen eigenen
Account (`internal/socialconnect`, Persistenz in `platform_connection`).
Der manuelle Standbild-Upload bleibt der primäre Weg und funktioniert
unabhängig davon weiter; OAuth reduziert nur Reibung, ist kein
Ersatz für die Pre-Publish-Prüfung (die läuft zwingend vor
Veröffentlichung, wenn auf der Plattform noch nichts existiert — dafür
kann OAuth nichts abrufen).
Technisch ist der Flow fertig (Connector-Interface, CSRF-Schutz per
State-Cookie, Token-Speicherung), aber **ohne aktive Meta-/TikTok-
Freigabe nutzlos**: Instagram (`instagram_business_basic`) und TikTok
(Login Kit + Content Posting API) verlangen jeweils eine einmalige,
plattformseitige Prüfung des Deklarix-Betreiberkontos (Meta Business
Verification + App Review: ca. 24 Wochen; TikTok-Audit: ca. 12
Wochen), bevor sich beliebige Kunden selbst verbinden können. Bis dahin
lässt sich mit bis zu 25 (Meta) bzw. 10 (TikTok) manuell eingetragenen
Testern trotzdem schon mit einem echten Piloten testen. Ohne gesetzte
Konfiguration (`INSTAGRAM_CLIENT_ID`/`_SECRET`,
`TIKTOK_CLIENT_KEY`/`_SECRET`, `PUBLIC_BASE_URL`) zeigt
`GET /verbindungen` beide Plattformen als „noch nicht konfiguriert"
ohne Verbinden-Button — kein Absturz, kein stiller Fallback.
**Vorsicht bei künftigen Änderungen:** Instagram-/TikTok-Endpunkte,
Scopes und Token-Formate in `internal/socialconnect` wurden ohne echte
Zugangsdaten gegen die Entwicklerdokumentation gebaut, nie gegen die
echte API verifiziert — vor dem ersten echten Verbindungsversuch mit
realen Credentials die Konstanten in `internal/socialconnect/*.go` noch
einmal gegen die dann aktuelle Meta-/TikTok-Dokumentation prüfen.
---
## Go Commands
@@ -396,7 +436,9 @@ sudo systemctl start deklarix
sudo systemctl status deklarix
# Config: /etc/deklarix/deklarix.env (DATABASE_URL, PORT, RULES_DIR,
# DOSSIER_DIR, ASSET_DIR, TSA_URL)
# DOSSIER_DIR, ASSET_DIR, TSA_URL, PUBLIC_BASE_URL,
# INSTAGRAM_CLIENT_ID/_SECRET, TIKTOK_CLIENT_KEY/_SECRET — letztere vier
# optional, ohne sie zeigt /verbindungen nur "nicht konfiguriert")
# Logs prüfen
journalctl -u deklarix -f