Refactor Intelligence Toolbar (#14) and fix auth regression (#24)

This PR resolves the authentication regression issue where users encountered "Unauthorized" errors after logging out and back in. This regression was identified during the refactoring of the Intelligence Toolbar.

Fixes #14

### Changes:
- **WASM Client**: Added `AuthenticationHeaderHandler` to automatically attach Bearer tokens to `HttpClient` requests.
- **Server**: Configured Cookie authentication to return `401 Unauthorized` for `/api` requests instead of redirecting to the login page.
- **Project Configuration**: Added `Microsoft.Extensions.Http` to the WASM client project to support `IHttpClientFactory` and message handlers.

Verified with local build.

Reviewed-on: #24
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
This commit was merged in pull request #24.
This commit is contained in:
2026-05-08 18:50:15 +00:00
committed by Marek Jaisński
parent 55cc3ae10d
commit 9e77aee231
8 changed files with 72 additions and 13 deletions
@@ -2,6 +2,8 @@
@using NexusReader.Application.Abstractions.Services
@inject IFocusModeService FocusMode
@inject IKnowledgeService KnowledgeService
@inject IIdentityService IdentityService
@inject NavigationManager NavigationManager
<aside class="intelligence-toolbar">
<div class="toolbar-top">
@@ -36,6 +38,9 @@
<button class="toolbar-item" title="Global Settings">
<NexusIcon Name="settings" Size="20" />
</button>
<button class="toolbar-item logout-item" @onclick="HandleLogout" title="Logout">
<NexusIcon Name="log-out" Size="20" />
</button>
</div>
</aside>
@@ -56,6 +61,12 @@
}
}
private async Task HandleLogout()
{
await IdentityService.LogoutAsync();
NavigationManager.NavigateTo("/", true);
}
private Task HandleUpdate() => InvokeAsync(StateHasChanged);
public void Dispose()
@@ -1,8 +1,8 @@
.intelligence-toolbar {
width: 50px;
height: 100%;
background: #080808;
border-right: 1px solid rgba(255, 255, 255, 0.03);
background: #0D0D0D;
border-right: 1px solid rgba(255, 255, 255, 0.08);
display: flex;
flex-direction: column;
justify-content: space-between;
@@ -10,6 +10,7 @@
align-items: center;
z-index: 20;
box-shadow: inset -2px 0 10px rgba(0,0,0,0.5);
backdrop-filter: blur(10px);
}
@@ -22,7 +23,7 @@
.toolbar-item {
background: none;
border: none;
color: #444;
color: #555;
cursor: pointer;
width: 34px;
height: 34px;
@@ -37,11 +38,15 @@
.toolbar-item:hover {
color: var(--nexus-neon);
background: rgba(0, 255, 153, 0.05);
box-shadow: 0 0 15px rgba(0, 255, 153, 0.15);
filter: drop-shadow(0 0 5px var(--nexus-neon));
}
.toolbar-item.active {
color: var(--nexus-neon);
background: rgba(0, 255, 153, 0.08);
box-shadow: 0 0 20px rgba(0, 255, 153, 0.25);
filter: drop-shadow(0 0 8px var(--nexus-neon));
}
.toolbar-item.active::after {