122 lines
3.1 KiB
C#
122 lines
3.1 KiB
C#
namespace IronServices.Client;
|
|
|
|
/// <summary>
|
|
/// Interface for storing authentication tokens.
|
|
/// Implement this for platform-specific secure storage (e.g., MAUI SecureStorage, Windows Credential Manager).
|
|
/// </summary>
|
|
public interface ITokenStorage
|
|
{
|
|
/// <summary>
|
|
/// Save the session token.
|
|
/// </summary>
|
|
Task SaveTokenAsync(string token, DateTime? expiresAt);
|
|
|
|
/// <summary>
|
|
/// Get the stored session token.
|
|
/// </summary>
|
|
Task<(string? Token, DateTime? ExpiresAt)> GetTokenAsync();
|
|
|
|
/// <summary>
|
|
/// Clear the stored token.
|
|
/// </summary>
|
|
Task ClearTokenAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// In-memory token storage (not persisted across app restarts).
|
|
/// </summary>
|
|
public class InMemoryTokenStorage : ITokenStorage
|
|
{
|
|
private string? _token;
|
|
private DateTime? _expiresAt;
|
|
|
|
public Task SaveTokenAsync(string token, DateTime? expiresAt)
|
|
{
|
|
_token = token;
|
|
_expiresAt = expiresAt;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<(string? Token, DateTime? ExpiresAt)> GetTokenAsync()
|
|
{
|
|
return Task.FromResult((_token, _expiresAt));
|
|
}
|
|
|
|
public Task ClearTokenAsync()
|
|
{
|
|
_token = null;
|
|
_expiresAt = null;
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// File-based token storage (for console apps, testing).
|
|
/// </summary>
|
|
public class FileTokenStorage : ITokenStorage
|
|
{
|
|
private readonly string _filePath;
|
|
|
|
public FileTokenStorage(string? filePath = null)
|
|
{
|
|
_filePath = filePath ?? Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
|
"IronServices",
|
|
"session.json");
|
|
}
|
|
|
|
public async Task SaveTokenAsync(string token, DateTime? expiresAt)
|
|
{
|
|
var directory = Path.GetDirectoryName(_filePath);
|
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
|
|
var data = new { token, expiresAt = expiresAt?.ToString("O") };
|
|
var json = System.Text.Json.JsonSerializer.Serialize(data);
|
|
await File.WriteAllTextAsync(_filePath, json);
|
|
}
|
|
|
|
public async Task<(string? Token, DateTime? ExpiresAt)> GetTokenAsync()
|
|
{
|
|
if (!File.Exists(_filePath))
|
|
{
|
|
return (null, null);
|
|
}
|
|
|
|
try
|
|
{
|
|
var json = await File.ReadAllTextAsync(_filePath);
|
|
var data = System.Text.Json.JsonSerializer.Deserialize<TokenData>(json);
|
|
|
|
DateTime? expiresAt = null;
|
|
if (!string.IsNullOrEmpty(data?.ExpiresAt))
|
|
{
|
|
expiresAt = DateTime.Parse(data.ExpiresAt, null, System.Globalization.DateTimeStyles.RoundtripKind);
|
|
}
|
|
|
|
return (data?.Token, expiresAt);
|
|
}
|
|
catch
|
|
{
|
|
return (null, null);
|
|
}
|
|
}
|
|
|
|
public Task ClearTokenAsync()
|
|
{
|
|
if (File.Exists(_filePath))
|
|
{
|
|
File.Delete(_filePath);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private class TokenData
|
|
{
|
|
public string? Token { get; set; }
|
|
public string? ExpiresAt { get; set; }
|
|
}
|
|
}
|