API Test
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Web.Services;
|
||||
|
||||
public class AuthService
|
||||
{
|
||||
private readonly string _graphqlEndpoint;
|
||||
private readonly HttpClient _http;
|
||||
private readonly IJSRuntime? _jsRuntime;
|
||||
private readonly NetworkStatusService _networkStatus;
|
||||
|
||||
public AuthService(HttpClient http, NetworkStatusService networkStatus, IServiceProvider serviceProvider)
|
||||
{
|
||||
_http = http;
|
||||
_networkStatus = networkStatus;
|
||||
_jsRuntime = serviceProvider.GetService(typeof(IJSRuntime)) as IJSRuntime;
|
||||
_graphqlEndpoint = http.BaseAddress != null && http.BaseAddress.Port == 5256
|
||||
? "/graphql"
|
||||
: "http://localhost:5256/graphql";
|
||||
}
|
||||
|
||||
public bool IsLoggedIn => !string.IsNullOrEmpty(AuthToken);
|
||||
public string? CurrentUsername { get; private set; }
|
||||
public string? AuthToken { get; private set; }
|
||||
|
||||
public event Action? AuthStateChanged;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
if (_jsRuntime != null)
|
||||
try
|
||||
{
|
||||
var storedToken = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", "chrono_auth_token");
|
||||
var storedUser = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", "chrono_auth_user");
|
||||
if (!string.IsNullOrEmpty(storedToken) && !string.IsNullOrEmpty(storedUser))
|
||||
{
|
||||
AuthToken = storedToken;
|
||||
CurrentUsername = storedUser;
|
||||
AuthStateChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// LocalStorage not available in testing or SSR
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<AuthResult> LoginAsync(string username, string password)
|
||||
{
|
||||
if (!_networkStatus.IsOnline)
|
||||
return new AuthResult { Success = false, Message = "Cannot login while offline." };
|
||||
|
||||
try
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query = @"mutation Login($username: String!, $password: String!) {
|
||||
login(username: $username, password: $password) {
|
||||
success
|
||||
token
|
||||
username
|
||||
message
|
||||
}
|
||||
}",
|
||||
Variables = new Dictionary<string, object>
|
||||
{
|
||||
["username"] = username,
|
||||
["password"] = password
|
||||
}
|
||||
};
|
||||
|
||||
var response = await SendGraphQLAsync<LoginResponseData>(request);
|
||||
var payload = response?.Data?.Login;
|
||||
if (payload != null && payload.Success && !string.IsNullOrEmpty(payload.Token))
|
||||
{
|
||||
AuthToken = payload.Token;
|
||||
CurrentUsername = payload.Username ?? username;
|
||||
|
||||
if (_jsRuntime != null)
|
||||
try
|
||||
{
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "chrono_auth_token", AuthToken);
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "chrono_auth_user", CurrentUsername);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
AuthStateChanged?.Invoke();
|
||||
return new AuthResult { Success = true, Message = payload.Message ?? "Login successful" };
|
||||
}
|
||||
|
||||
return new AuthResult { Success = false, Message = payload?.Message ?? "Invalid username or password." };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new AuthResult { Success = false, Message = $"Login error: {ex.Message}" };
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LogoutAsync()
|
||||
{
|
||||
AuthToken = null;
|
||||
CurrentUsername = null;
|
||||
|
||||
if (_jsRuntime != null)
|
||||
try
|
||||
{
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", "chrono_auth_token");
|
||||
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", "chrono_auth_user");
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
AuthStateChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void SetAuth(string username, string token)
|
||||
{
|
||||
CurrentUsername = username;
|
||||
AuthToken = token;
|
||||
AuthStateChanged?.Invoke();
|
||||
}
|
||||
|
||||
private async Task<GraphQLResponse<T>?> SendGraphQLAsync<T>(GraphQLRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpResponse = await _http.PostAsJsonAsync(_graphqlEndpoint, request);
|
||||
if (httpResponse.IsSuccessStatusCode)
|
||||
return await httpResponse.Content.ReadFromJsonAsync<GraphQLResponse<T>>();
|
||||
|
||||
if (_graphqlEndpoint == "/graphql")
|
||||
{
|
||||
var fallbackResponse = await _http.PostAsJsonAsync("http://localhost:5256/graphql", request);
|
||||
if (fallbackResponse.IsSuccessStatusCode)
|
||||
return await fallbackResponse.Content.ReadFromJsonAsync<GraphQLResponse<T>>();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
var fallbackResponse = await _http.PostAsJsonAsync("http://localhost:5256/graphql", request);
|
||||
if (fallbackResponse.IsSuccessStatusCode)
|
||||
return await fallbackResponse.Content.ReadFromJsonAsync<GraphQLResponse<T>>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public class AuthResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private class GraphQLRequest
|
||||
{
|
||||
[JsonPropertyName("query")] public string Query { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("variables")] public Dictionary<string, object>? Variables { get; set; }
|
||||
}
|
||||
|
||||
private class GraphQLResponse<T>
|
||||
{
|
||||
[JsonPropertyName("data")] public T? Data { get; set; }
|
||||
|
||||
[JsonPropertyName("errors")] public List<GraphQLError>? Errors { get; set; }
|
||||
}
|
||||
|
||||
private class GraphQLError
|
||||
{
|
||||
[JsonPropertyName("message")] public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private class LoginResponseData
|
||||
{
|
||||
[JsonPropertyName("login")] public LoginPayloadData? Login { get; set; }
|
||||
}
|
||||
|
||||
private class LoginPayloadData
|
||||
{
|
||||
[JsonPropertyName("success")] public bool Success { get; set; }
|
||||
|
||||
[JsonPropertyName("token")] public string? Token { get; set; }
|
||||
|
||||
[JsonPropertyName("username")] public string? Username { get; set; }
|
||||
|
||||
[JsonPropertyName("message")] public string? Message { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user