This PR provides critical stabilization, memory leak resolution, and security enhancements for the NexusReader application, specifically focusing on Blazor InteractiveAuto lifecycle safety, thread-safe automated authentication token refresh, and deduplication of active AI service queries.
### Key Enhancements
#### 1. Security & Lifecycle Stabilization (`AuthenticationHeaderHandler.cs` & `Library.razor`)
* **Secure Token Propagation (CWE-200)**: Modified the outbound delegating handler to only append JWT Bearer headers to trusted base origin requests matching the application's configured `NavigationManager.BaseUri`, preventing potential token leakage to external services.
* **Captive Dependency & Memory Leak Fix (CWE-400)**: Avoided capturing scoped dependencies in a singleton handler by wrapping the resolution of `IIdentityService` inside a dedicated, disposable `IServiceProvider` scope (`_serviceProvider.CreateScope()`).
* **Thread-Safe Automated Refresh**: Embedded a `SemaphoreSlim` lock around the automated `RefreshTokenAsync` renewal sequence to handle concurrent API requests gracefully without triggering duplicate token refresh attempts.
* **Pre-rendering Safety**: Deferred the secure book loading query in `Library.razor` from `OnInitializedAsync` to client-side `OnAfterRenderAsync(firstRender: true)` to avoid inevitable `401 Unauthorized` responses and logs during the server pre-rendering phase.
#### 2. Robust AI Request Deduplication (`KnowledgeService.cs`)
* **State Recovery Guards**: Enhanced the thread-safe `Lazy<Task<Result<KnowledgePacket>>>` deduplication map by adding thorough failure handling blocks. Active requests are guaranteed to be cleaned up (`TryRemove`) inside `finally` and failed results pathways, ensuring future retries can run immediately if an initial request encounters an error.
#### 3. Idempotent AI UI Fetching & JSRuntime Guards
* **Interactive Guards**: Added an `_isInteractive` check to `GroundednessBadge.razor` and `AiAssistantBubble.razor` components, deferring WebAssembly API executions and DOM updates to client-side `OnAfterRenderAsync`.
* **State Synchronization**: Integrated a synchronous `OnParametersSet` to properly reset groundedness badges when content changes.
* **Flicker Elimination**: Moved JSRuntime local-storage checks in `Home.razor` (for focus mode preferences) to `OnAfterRenderAsync(firstRender: true)`, resolving startup JSInterop exceptions and eliminating layout shifts.
### Verification Performed
* Mandatory build gate verified: `Kompilacja powiodła się.` with zero compile errors (`dotnet build NexusReader.slnx --no-restore`).
* Validated dependency resolution patterns and async safety (no `async void`).
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #45
Reviewed-by: Marek Jaisński <jasins.marek@gmail.com>
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
This Pull Request encapsulates all outstanding AI, Blazor InteractiveAuto lifecycle, pgvector, and Firefox authorization/session compatibility fixes.
### Key Accomplishments:
1. **Concurrent Request Deduplication (Option B):** Implemented a thread-safe active task registry in `KnowledgeService` that groups concurrent graph extraction queries for the same content, preventing duplicate AI calls completely.
2. **Resilience Strategy for Downstream Demands:** Extended the `ai-retry` resilience pipeline to automatically intercept and retry on temporary Google API `503 ServiceUnavailable` / `high demand` spikes.
3. **Interactive Graph Generation Guard (Option A):** Prevented server-side prerender-phase graph requests in the reader canvas component.
4. **Firefox Compatibility & Cookie Handler:** Implemented an authentication endpoint and hybrid hidden-form submission flow to solve login, registration, and logout redirections and cookies securely.
5. **Autoscrolling & Graph Exclusions:** Added concept-to-block smooth scrolling, active block badging, and filtered out markdown code blocks from being extracted as nodes.
All unit tests compiled and passed 100% cleanly.
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #44
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
This PR finalizes the implementation of issue #35 by establishing a formal foreign key relationship between `KnowledgeUnit` and `Ebook`.
Closes#35
### Changes:
- **Domain**: Refactored `KnowledgeUnit` to use `Guid EbookId` and added navigation property.
- **Data**: Updated `AppDbContext` fluent configuration and generated a new migration.
- **Service**: Updated `IKnowledgeService` and its implementations to propagate `ebookId`.
- **API**: Updated Web API endpoints to support linking extracted knowledge to specific ebooks.
### Verification:
- [x] Solution builds successfully (`dotnet build`).
- [x] Schema changes verified in migration file.
- [x] Cascading delete behavior confirmed.
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #43
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
This PR stabilizes the Nexus Ingestion Engine by implementing functional service proxies for the Blazor WASM client and refining the backend infrastructure for real-time progress tracking and database compatibility.
### Key Changes
- **Infrastructure Stabilization**:
- Implemented production-grade `EbookRepository` with PostgreSQL `EF.Functions.ILike` support.
- Enforced `IsReadyForReading = false` state for newly added ebooks (resolves#35).
- Updated `SignalRSyncBroadcaster` to support targeted user messaging and ingestion-specific progress updates (resolves#37).
- **WASM Client Functional Proxies**:
- Replaced "Throwing" dummy services with `WasmEbookRepository`, `WasmSyncBroadcaster`, `WasmBookStorageService`, and `WasmEmbeddingGenerator`.
- These services proxy requests to the backend via a new set of Minimal API endpoints in `NexusReader.Web`.
- **Domain Refinement**:
- Added `IsReadyForReading` flag to the `Ebook` entity to manage background AI processing states.
### Related Issues
- Fixes#35
- Fixes#36
- Fixes#37
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #42
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
### Description
This PR implements **Issue #34: [UI/UX] Implement Hybrid Metadata Verification Form in Ingestion Modal**.
### Key Changes
- **Metadata Verification State**: Introduced a new state in `BookIngestionModal.razor` allowing users to edit `Title` and `Author` before final ingestion.
- **Cover Image Preview**: Added a high-fidelity cover preview with a CSS-based glowing placeholder fallback for books without embedded covers.
- **Ingestion Pipeline**:
- Implemented `IngestEbookCommand` and `IngestEbookCommandHandler`.
- Added `IBookStorageService` and its implementation for managing EPUB and cover file storage.
- Exposed `POST /api/library/ingest` Minimal API endpoint with `.DisableAntiforgery()` to handle client-side JSON uploads.
- **Stability Fixes**:
- Resolved DI validation errors in the WASM client by providing a dummy `IBookStorageService` registration.
- Adjusted Kestrel request limits to handle large EPUB payloads (up to 100MB).
- Corrected middleware ordering to ensure Antiforgery works correctly with Authentication.
### Verification
- Solution builds successfully.
- Manual verification of modal state transitions and API ingestion logic.
Closes#34.
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #41
Reviewed-by: Marek Jaisński <jasins.marek@gmail.com>
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
## Overview
This PR completes the architectural consolidation of the web project and stabilizes the Identity-based authentication flow for the NexusReader application. It also refines the UI aesthetic for the Book Ingestion Modal as requested in #33.
## Key Changes
- **Project Consolidation**: Fully merged `NexusReader.Web.New` into `NexusReader.Web`. This includes updating all namespace references, VS Code launch/task configurations, and CI/CD (`Dockerfile`).
- **Identity Stabilization**:
- Implemented `IIdentityService` on the server using `SignInManager<NexusUser>` and `UserManager<NexusUser>`.
- Fixed registration logic to include mandatory fields (`SubscriptionPlanId`, `TenantId`).
- Updated `Login.razor` to force a page reload on successful login, ensuring proper synchronization of authentication cookies between SignalR and the browser.
- **UI/UX Refinement**:
- Updated `BookIngestionModal` styling to follow the **Nexus Neon** design system.
- Added premium button styles with hover effects and glows.
- Improved modal layout and interaction feedback (shimmer effects, spinner colors).
- **Cleanup**: Removed obsolete interfaces and constants that were superseded by newer Application layer implementations.
## Verification
- Successfully built the solution: `dotnet build NexusReader.slnx --no-restore`
- Verified project structure and file moves.
- Validated server-side authentication logic.
Fixes#33
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #40
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
Resolves#32
### Changes:
- Added '[+] Add New Book' button to `Library.razor`.
- Wrapped the button in `AuthorizeView` for `Admin` and `ContentManager` roles.
- Updated `NexusButton` styling to follow standards: secondary gray background with neon glow on hover/focus.
- Refined `Library.razor` layout with a header and glassmorphism panel.
---------
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #38
Reviewed-by: Marek Jaisński <jasins.marek@gmail.com>
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
This PR implements the Hub Navigation system and the Profile Dashboard, while resolving critical session synchronization issues.
### Key Changes
- **Hub Navigation**: Introduced `MainHubLayout` with a premium glassmorphism sidebar, providing access to Dashboard, Library, Concepts Map, and Profile.
- **Profile Dashboard**: Implemented a high-fidelity Profile page (#27) with learning metrics, AI token usage tracking, and system rank visualization.
- **Stability Fixes**:
- Resolved an infinite network loop on the `/profile` page by implementing request deduplication and in-memory caching in `IdentityService`.
- Added environment-aware guards to prevent illegal JavaScript interop calls during server-side prerendering.
- Implemented automatic session invalidation on `401 Unauthorized` responses to handle stale authentication states gracefully.
- **Reader Integration**: Added a "Return to Dashboard" option in the reader toolbar (#26).
Closes#26Closes#27
Reviewed-on: #31
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
This PR addresses several UI/UX and architectural refinements for the Knowledge Graph and Intelligence Sidebar.
### Key Changes:
- **Knowledge Graph (#21, #22)**:
- Implemented \"pill-shaped\" nodes with dynamic label truncation and SVG tooltips.
- Added bound-constrained simulation to keep nodes within the viewport.
- Integrated `ResizeObserver` for dynamic layout handling.
- Implemented Zoom-to-Fit functionality.
- Enforced unique concept IDs in AI prompts and hardened JS logic to prevent multi-selection bugs.
- **Intelligence Sidebar (#23)**:
- Improved visual depth with a radial gradient background for the graph.
- Increased sidebar divider contrast for better layering.
- Transformed graph controls into a floating glassmorphism panel.
- Relocated the \"Logout\" action to the toolbar bottom and rebranded it as \"Exit\".
Fixes#21Fixes#22Fixes#23
Reviewed-on: #25
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
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 PR implements proper logging and error handling for the Google OAuth callback as requested in issue #3.
### Changes:
- Added `ILogger<Program>` to the Google callback endpoint.
- Logged warning if external login info is null.
- Logged error details from `userManager.CreateAsync` if provisioning fails.
- Introduced specific error codes `UserAlreadyExists` and `LockedOut` to improve UX.
- Updated `Login.razor` to display descriptive Polish error messages based on the query parameter.
Fixes#3
Reviewed-on: #18
Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>