79 lines
2.2 KiB
C#
79 lines
2.2 KiB
C#
|
|
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
|
||
|
|
using Microsoft.EntityFrameworkCore;
|
||
|
|
using radiuscontroller.Data;
|
||
|
|
|
||
|
|
namespace radiuscontroller.Services;
|
||
|
|
|
||
|
|
public class AdminAuthService
|
||
|
|
{
|
||
|
|
private readonly RadiusDbContext _db;
|
||
|
|
private readonly ProtectedSessionStorage _sessionStorage;
|
||
|
|
|
||
|
|
private const string SessionKey = "AdminUsername";
|
||
|
|
public string? CurrentAdminUsername { get; private set; }
|
||
|
|
public bool IsAuthenticated => !string.IsNullOrEmpty(CurrentAdminUsername);
|
||
|
|
|
||
|
|
public event Action? OnAuthStateChanged;
|
||
|
|
|
||
|
|
public AdminAuthService(RadiusDbContext db, ProtectedSessionStorage sessionStorage)
|
||
|
|
{
|
||
|
|
_db = db;
|
||
|
|
_sessionStorage = sessionStorage;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task InitializeAsync()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var result = await _sessionStorage.GetAsync<string>(SessionKey);
|
||
|
|
if (result.Success && !string.IsNullOrEmpty(result.Value))
|
||
|
|
{
|
||
|
|
CurrentAdminUsername = result.Value;
|
||
|
|
NotifyStateChanged();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
// Session storage might fail during prerendering or early socket connection
|
||
|
|
CurrentAdminUsername = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<bool> LoginAsync(string username, string password)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
var admin = await _db.AdminUsers.FirstOrDefaultAsync(u => u.Username == username.Trim().ToLowerInvariant());
|
||
|
|
if (admin == null)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
bool isValid = BCrypt.Net.BCrypt.Verify(password, admin.PasswordHash);
|
||
|
|
if (isValid)
|
||
|
|
{
|
||
|
|
CurrentAdminUsername = admin.Username;
|
||
|
|
await _sessionStorage.SetAsync(SessionKey, admin.Username);
|
||
|
|
NotifyStateChanged();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task LogoutAsync()
|
||
|
|
{
|
||
|
|
CurrentAdminUsername = null;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await _sessionStorage.DeleteAsync(SessionKey);
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
// Ignore storage errors during logout
|
||
|
|
}
|
||
|
|
NotifyStateChanged();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void NotifyStateChanged() => OnAuthStateChanged?.Invoke();
|
||
|
|
}
|