feat: implement identity authentication, authorization policies, and MAUI platform support with Docker orchestration
This commit is contained in:
@@ -9,6 +9,7 @@ public interface IIdentityService
|
||||
Task<bool> LoginAsync(string email, string password);
|
||||
Task LogoutAsync();
|
||||
Task<UserProfile?> GetProfileAsync();
|
||||
Task<bool> RefreshTokenAsync();
|
||||
}
|
||||
|
||||
public record UserProfile(
|
||||
@@ -16,7 +17,9 @@ public record UserProfile(
|
||||
int AITokenLimit,
|
||||
int AITokensUsed,
|
||||
string CurrentPlan,
|
||||
Guid TenantId);
|
||||
Guid TenantId,
|
||||
int AverageQuizScore,
|
||||
string LastReadBookTitle);
|
||||
|
||||
public class IdentityService : IIdentityService
|
||||
{
|
||||
@@ -24,6 +27,7 @@ public class IdentityService : IIdentityService
|
||||
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,
|
||||
@@ -51,6 +55,10 @@ public class IdentityService : IIdentityService
|
||||
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;
|
||||
}
|
||||
@@ -62,6 +70,7 @@ public class IdentityService : IIdentityService
|
||||
public async Task LogoutAsync()
|
||||
{
|
||||
_storageService.RemoveSecure(TokenKey);
|
||||
_storageService.RemoveSecure(RefreshTokenKey);
|
||||
_authStateProvider.NotifyUserLogout();
|
||||
}
|
||||
|
||||
@@ -77,6 +86,33 @@ public class IdentityService : IIdentityService
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user