using System.Security.Claims; using System.Text.Json; using Microsoft.AspNetCore.Components.Authorization; using NexusReader.Application.Abstractions.Services; namespace NexusReader.UI.Shared.Services; public class NexusAuthenticationStateProvider : AuthenticationStateProvider { private readonly INativeStorageService _storageService; private const string TokenKey = "nexus_auth_token"; public NexusAuthenticationStateProvider(INativeStorageService storageService) { _storageService = storageService; } public override async Task GetAuthenticationStateAsync() { try { var result = await _storageService.GetSecureString(TokenKey); var token = result.IsSuccess ? result.Value : null; if (string.IsNullOrWhiteSpace(token)) { return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); } var identity = new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"); var user = new ClaimsPrincipal(identity); return new AuthenticationState(user); } catch (Exception) { return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); } } public void NotifyUserAuthentication(string token) { var identity = new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"); var user = new ClaimsPrincipal(identity); var authState = Task.FromResult(new AuthenticationState(user)); NotifyAuthenticationStateChanged(authState); } public void NotifyUserLogout() { var guest = new ClaimsPrincipal(new ClaimsIdentity()); var authState = Task.FromResult(new AuthenticationState(guest)); NotifyAuthenticationStateChanged(authState); } private IEnumerable ParseClaimsFromJwt(string jwt) { var claims = new List(); var payload = jwt.Split('.')[1]; var jsonBytes = ParseBase64WithoutPadding(payload); var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes); if (keyValuePairs != null) { claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString() ?? string.Empty))); } return claims; } private byte[] ParseBase64WithoutPadding(string base64) { switch (base64.Length % 4) { case 2: base64 += "=="; break; case 3: base64 += "="; break; } return Convert.FromBase64String(base64); } }