Native synct bisher per Default beim Login, Web ist Opt-in. Neues EventSyncConfig.requireSyncConsent (Default false → abwärtskompatibel): ist es gesetzt, läuft die Engine ohne explizite Einwilligung lokal-only (authMode() → anonymous trotz JWT, kein Egress, Outbox staut). Einwilligung beim start() aus mana-auth /api/v1/settings (gleiche Quelle wie Web), setSyncConsent(_:) als Konto-Toggle (true claimt+startet wie signIn, false stoppt Server-Sync; lokale Daten bleiben). + syncConsentRequired/hasSyncConsent. Tests: SyncConsentTests (6) grün, volle Suite ohne Regression. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
1 KiB
Swift
27 lines
1 KiB
Swift
import Foundation
|
|
|
|
/// Liest die Cloud-Sync-Einwilligung aus einer mana-auth
|
|
/// `GET /api/v1/settings`-Antwort. Reihenfolge identisch zur Web-App
|
|
/// (`sync.svelte.ts`): **App-Override vor globaler Präferenz**, fehlend =
|
|
/// nicht eingewilligt (Opt-in, DSGVO Art. 25).
|
|
///
|
|
/// Erwartetes Shape (Teilmenge):
|
|
/// ```json
|
|
/// {
|
|
/// "globalSettings": { "sync": { "enabled": true } },
|
|
/// "appOverrides": { "pageta": { "sync": { "enabled": false } } }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Pure Funktion (kein I/O) — direkt testbar.
|
|
func parseSyncConsent(fromSettingsJSON data: Data, appId: String) -> Bool {
|
|
guard let root = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
|
return false
|
|
}
|
|
func enabled(in container: [String: Any]?) -> Bool? {
|
|
(container?["sync"] as? [String: Any])?["enabled"] as? Bool
|
|
}
|
|
let appOverride = enabled(in: (root["appOverrides"] as? [String: Any])?[appId] as? [String: Any])
|
|
let global = enabled(in: root["globalSettings"] as? [String: Any])
|
|
return appOverride ?? global ?? false
|
|
}
|