using LehrerApp.Sync.Crypto; using System.Text.Json; namespace LehrerApp.Desktop.Services; internal class SyncSettingsConfig { public string ServerUrl { get; set; } = ""; public string Username { get; set; } = ""; public string? EncryptedToken { get; set; } /// Kanonische userId aus der letzten erfolgreichen Login-Antwort (siehe /// SettingsViewModel.SyncLogin) — dient dem Erkennen eines Kontowechsels, unabhängig von der /// beim Login eingegebenen Groß-/Kleinschreibung des Benutzernamens (siehe TODO 10.3.5). public string? LastUserId { get; set; } } /// /// Ersetzt die früheren Klartext-Helfer (AppBootstrapper.LoadServerUrl/SaveServerUrl, /// unverschlüsselte auth.token-Datei). Token liegt wie beim KI-Backend-Token (siehe /// ) AES-256-verschlüsselt über , mit /// eigenem, rein lokalem Schlüssel — nicht zu verwechseln mit dem in AppBootstrapper /// separat verwalteten Sync-Schlüssel (sync.key), der die Ereignis-Payloads zwischen den /// gepaarten Geräten verschlüsselt. /// public class SyncSettingsService { private readonly string _configPath; private readonly string _keyPath; private readonly byte[] _tokenKey; private SyncSettingsConfig _config; public string ServerUrl => _config.ServerUrl; public string Username => _config.Username; public string? LastUserId => _config.LastUserId; public bool IsLoggedIn => _config.EncryptedToken is not null; public SyncSettingsService(string appDataPath) { _configPath = Path.Combine(appDataPath, "sync-settings.json"); _keyPath = Path.Combine(appDataPath, "sync-token.key"); _tokenKey = SyncCrypto.LoadKey(_keyPath) ?? GenerateAndSaveKey(); _config = Load(); } public void SetServerUrl(string url) { _config.ServerUrl = url.Trim(); Save(); } public void SetCredentialsAndToken(string username, string token, string? userId = null) { _config.Username = username; _config.EncryptedToken = SyncCrypto.EncryptObject(token, _tokenKey); if (userId is not null) _config.LastUserId = userId; Save(); } public string? GetToken() => _config.EncryptedToken is null ? null : SyncCrypto.DecryptObject(_config.EncryptedToken, _tokenKey); public void Logout() { _config.EncryptedToken = null; Save(); } private byte[] GenerateAndSaveKey() { var key = SyncCrypto.GenerateKey(); SyncCrypto.SaveKey(key, _keyPath); return key; } private void Save() => File.WriteAllText(_configPath, JsonSerializer.Serialize(_config)); private SyncSettingsConfig Load() { try { if (File.Exists(_configPath)) return JsonSerializer.Deserialize(File.ReadAllText(_configPath)) ?? new SyncSettingsConfig(); } catch { /* beschädigte Konfiguration -> Standardwert */ } return new SyncSettingsConfig(); } }