using System.IO; using System.Security.Cryptography; using System.Text.Json; using ytLive.Models; namespace ytLive.Helpers; /// /// Persists the OAuth session (channel + tokens) to a DPAPI-protected file in /// %APPDATA%\ytLlive\ytLlive.auth so sign-in survives restarts. The whole /// payload is protected with DataProtectionScope.CurrentUser — only the /// signed-in Windows user can decrypt it. /// public static class TokenStore { public static string DefaultPath => Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ytLlive", "ytLlive.auth"); public static void Save(YouTubeChannel channel, string? path = null) { var json = JsonSerializer.Serialize(channel); var plain = System.Text.Encoding.UTF8.GetBytes(json); var protectedBytes = ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser); var file = path ?? DefaultPath; Directory.CreateDirectory(Path.GetDirectoryName(file)!); File.WriteAllBytes(file, protectedBytes); } public static YouTubeChannel? Load(string? path = null) { var file = path ?? DefaultPath; if (!File.Exists(file)) return null; try { var protectedBytes = File.ReadAllBytes(file); var plain = ProtectedData.Unprotect(protectedBytes, null, DataProtectionScope.CurrentUser); var json = System.Text.Encoding.UTF8.GetString(plain); return JsonSerializer.Deserialize(json); } catch { return null; } } public static void Clear(string? path = null) { var file = path ?? DefaultPath; if (File.Exists(file)) File.Delete(file); } }