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:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/netcell-it/deklarix/internal/evidence"
|
||||
"github.com/netcell-it/deklarix/internal/extract"
|
||||
"github.com/netcell-it/deklarix/internal/rules"
|
||||
"github.com/netcell-it/deklarix/internal/socialconnect"
|
||||
"github.com/netcell-it/deklarix/internal/store"
|
||||
"github.com/netcell-it/deklarix/internal/web"
|
||||
)
|
||||
@@ -53,7 +54,21 @@ func main() {
|
||||
assetDir = "assets"
|
||||
}
|
||||
|
||||
server, err := web.NewServer(extractor, ruleSet, db, timestamper, dossierDir, assetDir)
|
||||
connectors := map[string]socialconnect.Connector{}
|
||||
publicBaseURL := os.Getenv("PUBLIC_BASE_URL")
|
||||
if publicBaseURL != "" {
|
||||
if id, secret := os.Getenv("INSTAGRAM_CLIENT_ID"), os.Getenv("INSTAGRAM_CLIENT_SECRET"); id != "" && secret != "" {
|
||||
connectors["instagram"] = socialconnect.NewInstagramConnector(id, secret, publicBaseURL+"/oauth/instagram/callback")
|
||||
}
|
||||
if key, secret := os.Getenv("TIKTOK_CLIENT_KEY"), os.Getenv("TIKTOK_CLIENT_SECRET"); key != "" && secret != "" {
|
||||
connectors["tiktok"] = socialconnect.NewTikTokConnector(key, secret, publicBaseURL+"/oauth/tiktok/callback")
|
||||
}
|
||||
}
|
||||
if len(connectors) == 0 {
|
||||
log.Print("keine Plattform-Verbindungen konfiguriert (INSTAGRAM_CLIENT_ID/TIKTOK_CLIENT_KEY/PUBLIC_BASE_URL fehlen) — /verbindungen zeigt nur manuelle Beweissicherung an")
|
||||
}
|
||||
|
||||
server, err := web.NewServer(extractor, ruleSet, db, timestamper, dossierDir, assetDir, connectors)
|
||||
if err != nil {
|
||||
log.Fatalf("web server: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user