feat(auth): Stabilize authentication flow and implement premium hydration preloader (#60)

This pull request stabilizes the authentication infrastructure, resolves expired JWT tokens, safely redirects users post-login, and integrates a premium glassmorphic session hydration preloader during client-side boot-up.

---------

Co-authored-by: Marek Jaisński <jasins.marek@gmail.com>
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #60
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
This commit was merged in pull request #60.
This commit is contained in:
2026-05-27 10:29:52 +00:00
committed by Marek Jaisński
parent 76b828395d
commit a90507ad8a
2 changed files with 21 additions and 2 deletions
@@ -4,6 +4,14 @@
@using NexusReader.Application.Abstractions.Services @using NexusReader.Application.Abstractions.Services
@using NexusReader.UI.Shared.Services @using NexusReader.UI.Shared.Services
@if (!_isFullyLoaded)
{
<div class="app-preloader" style="backdrop-filter: blur(15px); background: rgba(18, 18, 18, 0.95); z-index: 100000;">
<div class="preloader-spinner"></div>
<div class="preloader-text">Synchronizing Secure Session...</div>
</div>
}
<div class="hub-container @(_isMobileMenuOpen ? "mobile-menu-open" : "")"> <div class="hub-container @(_isMobileMenuOpen ? "mobile-menu-open" : "")">
<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
@@ -80,6 +88,7 @@
</div> </div>
<span class="nav-text">Concenters</span> <span class="nav-text">Concenters</span>
</NavLink> </NavLink>
</nav> </nav>
<div class="sidebar-footer"> <div class="sidebar-footer">
@@ -113,6 +122,7 @@
private bool _isSyncing = false; private bool _isSyncing = false;
private bool _isMobileMenuOpen = false; private bool _isMobileMenuOpen = false;
private bool _isFullyLoaded = false;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@@ -127,6 +137,15 @@
} }
} }
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
_isFullyLoaded = true;
StateHasChanged();
}
}
private void ToggleMobileMenu() private void ToggleMobileMenu()
{ {
_isMobileMenuOpen = !_isMobileMenuOpen; _isMobileMenuOpen = !_isMobileMenuOpen;
+2 -2
View File
@@ -518,7 +518,7 @@ app.MapGet("/identity/login/google", (string? returnUrl) =>
var properties = new AuthenticationProperties var properties = new AuthenticationProperties
{ {
RedirectUri = "/identity/callback/google", RedirectUri = "/identity/callback/google",
Items = { { "returnUrl", returnUrl ?? "/" } } Items = { { "returnUrl", string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl } }
}; };
return Results.Challenge(properties, new[] { "Google" }); return Results.Challenge(properties, new[] { "Google" });
}); });
@@ -598,7 +598,7 @@ app.MapPost("/account/login-form", async (
if (result.Succeeded) if (result.Succeeded)
{ {
logger.LogInformation("User logged in: {Email}", email); logger.LogInformation("User logged in: {Email}", email);
return Results.Redirect(returnUrl ?? "/"); return Results.Redirect(string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl);
} }
var error = result.IsLockedOut ? "LockedOut" : "InvalidCredentials"; var error = result.IsLockedOut ? "LockedOut" : "InvalidCredentials";