using System.Net; namespace DbFirst.BlazorWebApp.Services; public class AuthApiClient(HttpClient httpClient, AuthService authService, CookieContainer cookieContainer) : IAuthApiClient { private const string LoginEndpoint = "api/Auth/db-first/login"; private const string LogoutEndpoint = "api/Auth/logout"; private const string CheckEndpoint = "api/Auth/check"; public async Task LoginAsync(string username, string password, CancellationToken ct = default) { var content = new MultipartFormDataContent(); content.Add(new StringContent(username), "Username"); content.Add(new StringContent(password), "Password"); content.Add(new StringContent(string.Empty), "UserId"); var response = await httpClient.PostAsync(LoginEndpoint, content, ct); if (!response.IsSuccessStatusCode) return false; var rawCookie = ExtractCookies(); authService.SetAuthenticated(username, rawCookie); return true; } public async Task LogoutAsync(CancellationToken ct = default) { await httpClient.PostAsync(LogoutEndpoint, null, ct); authService.SetUnauthenticated(); } public async Task RestoreAsync(string username, string rawCookieHeader, CancellationToken ct = default) { RestoreCookies(rawCookieHeader); var response = await httpClient.GetAsync(CheckEndpoint, ct); if (response.IsSuccessStatusCode) { authService.SetAuthenticated(username, rawCookieHeader); return true; } authService.SetUnauthenticated(); return false; } private string ExtractCookies() { if (httpClient.BaseAddress is null) return string.Empty; var cookies = cookieContainer.GetCookies(httpClient.BaseAddress); return string.Join("; ", cookies.Cast().Select(c => $"{c.Name}={c.Value}")); } private void RestoreCookies(string rawCookieHeader) { if (httpClient.BaseAddress is null) return; foreach (var part in rawCookieHeader.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) { var eqIdx = part.IndexOf('='); if (eqIdx > 0) cookieContainer.Add(httpClient.BaseAddress, new Cookie(part[..eqIdx].Trim(), part[(eqIdx + 1)..].Trim())); } } }