FruitBankHybridApp/FruitBankHybrid/Services/MauiSecureCredentialService.cs

69 lines
2.0 KiB
C#

using System.Text.Json;
using FruitBank.Common.Services;
namespace FruitBankHybrid.Services;
/// <summary>
/// MAUI implementation of ISecureCredentialService using SecureStorage.
/// </summary>
public sealed class MauiSecureCredentialService : ISecureCredentialService
{
private const string CredentialsKey = "FruitBank_UserCredentials";
private static readonly TimeSpan ExpirationDuration = TimeSpan.FromDays(2);
public async Task SaveCredentialsAsync(string email, string password)
{
var data = new SecureCredentialData
{
Email = email,
Password = password,
ExpiresAtUtc = DateTime.UtcNow.Add(ExpirationDuration)
};
var json = JsonSerializer.Serialize(data);
await SecureStorage.Default.SetAsync(CredentialsKey, json);
}
public async Task<StoredCredentials?> GetCredentialsAsync()
{
try
{
var json = await SecureStorage.Default.GetAsync(CredentialsKey);
if (string.IsNullOrEmpty(json))
return null;
var data = JsonSerializer.Deserialize<SecureCredentialData>(json);
if (data == null)
return null;
// Check expiration
if (DateTime.UtcNow > data.ExpiresAtUtc)
{
await ClearCredentialsAsync();
return null;
}
return new StoredCredentials(data.Email, data.Password);
}
catch
{
// If any error occurs (corrupted data, etc.), clear and return null
await ClearCredentialsAsync();
return null;
}
}
public Task ClearCredentialsAsync()
{
SecureStorage.Default.Remove(CredentialsKey);
return Task.CompletedTask;
}
private sealed class SecureCredentialData
{
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public DateTime ExpiresAtUtc { get; set; }
}
}