Files
Nexus.Reader/src/NexusReader.UI.Shared/Services/IdentityService.cs
T

124 lines
4.0 KiB
C#

using System.Net.Http.Json;
using NexusReader.Application.Abstractions.Services;
namespace NexusReader.UI.Shared.Services;
public interface IIdentityService
{
Task<bool> RegisterAsync(string email, string password);
Task<bool> LoginAsync(string email, string password);
Task LogoutAsync();
Task<UserProfile?> GetProfileAsync();
Task<bool> RefreshTokenAsync();
}
public record UserProfile(
string Email,
int AITokenLimit,
int AITokensUsed,
string CurrentPlan,
Guid TenantId,
int AverageQuizScore,
string LastReadBookTitle);
public class IdentityService : IIdentityService
{
private readonly HttpClient _httpClient;
private readonly INativeStorageService _storageService;
private readonly NexusAuthenticationStateProvider _authStateProvider;
private const string TokenKey = "nexus_auth_token";
private const string RefreshTokenKey = "nexus_refresh_token";
public IdentityService(
HttpClient httpClient,
INativeStorageService storageService,
NexusAuthenticationStateProvider authStateProvider)
{
_httpClient = httpClient;
_storageService = storageService;
_authStateProvider = authStateProvider;
}
public async Task<bool> RegisterAsync(string email, string password)
{
var response = await _httpClient.PostAsJsonAsync("identity/register", new { email, password });
return response.IsSuccessStatusCode;
}
public async Task<bool> LoginAsync(string email, string password)
{
var response = await _httpClient.PostAsJsonAsync("identity/login", new { email, password });
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<LoginResponse>();
if (result != null && !string.IsNullOrEmpty(result.AccessToken))
{
await _storageService.SaveSecureString(TokenKey, result.AccessToken);
if (!string.IsNullOrEmpty(result.RefreshToken))
{
await _storageService.SaveSecureString(RefreshTokenKey, result.RefreshToken);
}
_authStateProvider.NotifyUserAuthentication(result.AccessToken);
return true;
}
}
return false;
}
public async Task LogoutAsync()
{
_storageService.RemoveSecure(TokenKey);
_storageService.RemoveSecure(RefreshTokenKey);
_authStateProvider.NotifyUserLogout();
}
public async Task<UserProfile?> GetProfileAsync()
{
try
{
return await _httpClient.GetFromJsonAsync<UserProfile>("identity/profile");
}
catch
{
return null;
}
}
public async Task<bool> RefreshTokenAsync()
{
var result = await _storageService.GetSecureString(RefreshTokenKey);
var refreshToken = result.IsSuccess ? result.Value : null;
if (string.IsNullOrEmpty(refreshToken)) return false;
var response = await _httpClient.PostAsJsonAsync("identity/refresh", new { refreshToken });
if (response.IsSuccessStatusCode)
{
var loginResult = await response.Content.ReadFromJsonAsync<LoginResponse>();
if (loginResult != null && !string.IsNullOrEmpty(loginResult.AccessToken))
{
await _storageService.SaveSecureString(TokenKey, loginResult.AccessToken);
if (!string.IsNullOrEmpty(loginResult.RefreshToken))
{
await _storageService.SaveSecureString(RefreshTokenKey, loginResult.RefreshToken);
}
_authStateProvider.NotifyUserAuthentication(loginResult.AccessToken);
return true;
}
}
return false;
}
private class LoginResponse
{
public string TokenType { get; set; } = string.Empty;
public string AccessToken { get; set; } = string.Empty;
public int ExpiresIn { get; set; }
public string RefreshToken { get; set; } = string.Empty;
}
}