using System.Security.Claims; using System.Net.Http.Json; using Microsoft.AspNetCore.Components.Authorization; using timetracker.Shared; namespace timetracker.Client.Services; public class HostAuthenticationStateProvider : AuthenticationStateProvider { private readonly HttpClient _http; private static readonly ClaimsPrincipal Anonymous = new(new ClaimsIdentity()); private ClaimsPrincipal? _currentUser; public HostAuthenticationStateProvider(HttpClient http) { _http = http; } public override async Task GetAuthenticationStateAsync() { if (_currentUser != null) { return new AuthenticationState(_currentUser); } try { var response = await _http.GetAsync("api/auth/me"); if (response.IsSuccessStatusCode) { var userInfo = await response.Content.ReadFromJsonAsync(); if (userInfo != null) { var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()), new Claim(ClaimTypes.Name, userInfo.Username) }; var identity = new ClaimsIdentity(claims, "Cookie"); _currentUser = new ClaimsPrincipal(identity); return new AuthenticationState(_currentUser); } } } catch { // Ignore error and fall back to anonymous (e.g. server offline or network issues) } _currentUser = Anonymous; return new AuthenticationState(_currentUser); } public void NotifyUserChanged(UserInfo? userInfo) { if (userInfo != null) { var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()), new Claim(ClaimTypes.Name, userInfo.Username) }; var identity = new ClaimsIdentity(claims, "Cookie"); _currentUser = new ClaimsPrincipal(identity); } else { _currentUser = Anonymous; } NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser))); } }