Unify architecture with Blazor WASM and YARP proxy
Refactored the deployment architecture to include two distinct
presentation projects: `EnvelopeGenerator.API` (ASP.NET Core Web
API with YARP Reverse Proxy) and `EnvelopeGenerator.ReceiverUI`
(Blazor WebAssembly). The API now acts as the single entry point,
proxying requests to the ReceiverUI and external authentication
services.
Redefined the route structure for clarity, introducing sender
routes (`/sender/login`, `/sender`) and receiver routes
(`/envelope/login/{EnvelopeKey}`, `/envelope/{EnvelopeKey}`).
Added multi-envelope support with per-envelope cookies for
simultaneous authentication.
Renamed `EnvelopeViewer` to `EnvelopeReceiver` to reflect its
expanded functionality for viewing and signing envelopes.
Replaced iText7 and PSPDFKit with PDF.js 3.11.174 for document
viewing and signing, with configurable quality settings.
Updated `AuthService` and `SignatureCacheService` to support the
new route structure and multi-envelope authentication. Adjusted
sender login flow to redirect to `/sender` upon success.
Updated documentation to reflect the new architecture, route
structure, and file renames. Deprecated libraries and past
mistakes were documented to avoid repetition.
This commit is contained in:
@@ -7,6 +7,51 @@ Digital document signing system with **unified Blazor WASM frontend** for both S
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Deployment Architecture
|
||||||
|
|
||||||
|
**Two Presentation Projects (Both Required):**
|
||||||
|
|
||||||
|
1. **EnvelopeGenerator.API** (ASP.NET Core Web API)
|
||||||
|
- Runs independently (development & production)
|
||||||
|
- **YARP Reverse Proxy** configured via `yarp.json`
|
||||||
|
- Proxies requests to:
|
||||||
|
- `EnvelopeGenerator.ReceiverUI` (Blazor WASM)
|
||||||
|
- External Auth.API service
|
||||||
|
- Serves as single entry point for all requests
|
||||||
|
|
||||||
|
2. **EnvelopeGenerator.ReceiverUI** (Blazor WebAssembly)
|
||||||
|
- Runs on separate host/port
|
||||||
|
- Accessed **only through API proxy** (not directly)
|
||||||
|
- Serves static files (HTML, JS, CSS, WASM)
|
||||||
|
|
||||||
|
**Request Flow:**
|
||||||
|
```
|
||||||
|
Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM)
|
||||||
|
? Auth.API:9090 (External Auth Service)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration:** `EnvelopeGenerator.API/yarp.json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ReceiverUI Route Structure
|
||||||
|
|
||||||
|
### Sender Routes
|
||||||
|
| Route | File | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `/sender/login` | `LoginSender.razor` | Username/password authentication |
|
||||||
|
| `/sender` | `EnvelopeSender.razor` | Sender dashboard (envelope list) |
|
||||||
|
|
||||||
|
### Receiver Routes
|
||||||
|
| Route | File | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `/envelope/login/{EnvelopeKey}` | `LoginReceiver.razor` | Access code authentication for specific envelope |
|
||||||
|
| `/envelope/{EnvelopeKey}` | `EnvelopeReceiver.razor` | View & sign envelope (PDF.js viewer) |
|
||||||
|
|
||||||
|
**Multi-Envelope Support:** Receivers can login to multiple envelopes simultaneously (per-envelope cookie authentication).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Architecture Evolution
|
## Architecture Evolution
|
||||||
|
|
||||||
### Old Architecture (Deprecated)
|
### Old Architecture (Deprecated)
|
||||||
@@ -42,9 +87,10 @@ Digital document signing system with **unified Blazor WASM frontend** for both S
|
|||||||
|
|
||||||
| File | Route/Purpose |
|
| File | Route/Purpose |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `ReceiverUI/Pages/EnvelopeViewer.razor` | `/envelope/{key}` — PDF.js viewer (read-only). |
|
| `ReceiverUI/Pages/EnvelopeSender.razor` | `/sender` — Sender dashboard (envelope list). |
|
||||||
| `ReceiverUI/Pages/LoginReceiver.razor` | `/login/{EnvelopeKey}` — Access code auth. |
|
| `ReceiverUI/Pages/EnvelopeReceiver.razor` | `/envelope/{key}` — Receiver PDF viewer & signing. |
|
||||||
| `ReceiverUI/Pages/LoginSender.razor` | `/login` — Username/password auth. |
|
| `ReceiverUI/Pages/LoginSender.razor` | `/sender/login` — Sender username/password auth. |
|
||||||
|
| `ReceiverUI/Pages/LoginReceiver.razor` | `/envelope/login/{EnvelopeKey}` — Receiver access code auth. |
|
||||||
| `ReceiverUI/wwwroot/js/pdf-viewer.js` | PDF.js wrapper (zoom, pagination, thumbnails). |
|
| `ReceiverUI/wwwroot/js/pdf-viewer.js` | PDF.js wrapper (zoom, pagination, thumbnails). |
|
||||||
| `ReceiverUI/wwwroot/js/receiver-signature.js` | Signature pad (draw/type/image). |
|
| `ReceiverUI/wwwroot/js/receiver-signature.js` | Signature pad (draw/type/image). |
|
||||||
| `ReceiverUI/wwwroot/css/envelope-viewer.css` | EnvelopeViewer styles. |
|
| `ReceiverUI/wwwroot/css/envelope-viewer.css` | EnvelopeViewer styles. |
|
||||||
@@ -83,11 +129,11 @@ Digital document signing system with **unified Blazor WASM frontend** for both S
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## EnvelopeViewer — PDF.js Viewer
|
## EnvelopeReceiver — PDF.js Viewer & Signing
|
||||||
|
|
||||||
**Route:** `/envelope/{EnvelopeKey}`
|
**Route:** `/envelope/{EnvelopeKey}`
|
||||||
**Tech:** PDF.js 3.11.174 + Blazor WASM + configurable quality
|
**Tech:** PDF.js 3.11.174 + Blazor WASM + configurable quality
|
||||||
**File:** `ReceiverUI/Pages/EnvelopeViewer.razor`
|
**File:** `ReceiverUI/Pages/EnvelopeReceiver.razor`
|
||||||
|
|
||||||
### Key Features
|
### Key Features
|
||||||
1. HiDPI/Retina support (4x quality)
|
1. HiDPI/Retina support (4x quality)
|
||||||
@@ -126,7 +172,7 @@ window.pdfViewer = {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Signature Workflow — EnvelopeViewer
|
## Signature Workflow — EnvelopeReceiver
|
||||||
|
|
||||||
**IMPORTANT:** iText7 NOT used (GPL license issue). Client-side overlay system only.
|
**IMPORTANT:** iText7 NOT used (GPL license issue). Client-side overlay system only.
|
||||||
|
|
||||||
@@ -214,7 +260,7 @@ public class SignatureCacheService {
|
|||||||
|
|
||||||
## Sender Login
|
## Sender Login
|
||||||
|
|
||||||
**Route:** `/login`
|
**Route:** `/sender/login`
|
||||||
**File:** `ReceiverUI/Pages/LoginSender.razor`
|
**File:** `ReceiverUI/Pages/LoginSender.razor`
|
||||||
**Tech:** Bootstrap 5 + DevExpress Blazing Berry theme
|
**Tech:** Bootstrap 5 + DevExpress Blazing Berry theme
|
||||||
|
|
||||||
@@ -246,7 +292,7 @@ public async Task<SenderLoginResult> LoginSenderAsync(string username, string pa
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
- `200 OK` ? Cookie set, redirect to `/`
|
- `200 OK` ? Cookie set, redirect to `/sender`
|
||||||
- `401 Unauthorized` ? Show error: "Ungültige Anmeldedaten"
|
- `401 Unauthorized` ? Show error: "Ungültige Anmeldedaten"
|
||||||
- Other ? Show error: "Serverfehler"
|
- Other ? Show error: "Serverfehler"
|
||||||
|
|
||||||
@@ -256,16 +302,18 @@ public async Task<SenderLoginResult> LoginSenderAsync(string username, string pa
|
|||||||
1. User enters username + password
|
1. User enters username + password
|
||||||
2. Click "Anmelden" or press Enter
|
2. Click "Anmelden" or press Enter
|
||||||
3. Call `AuthService.LoginSenderAsync()`
|
3. Call `AuthService.LoginSenderAsync()`
|
||||||
4. Success ? `Navigation.NavigateTo("/", forceLoad: true)`
|
4. Success ? `Navigation.NavigateTo("/sender", forceLoad: true)`
|
||||||
5. Error ? Display alert
|
5. Error ? Display alert
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Receiver Login
|
## Receiver Login
|
||||||
|
|
||||||
**Route:** `/login/{EnvelopeKey}`
|
**Route:** `/envelope/login/{EnvelopeKey}`
|
||||||
**File:** `ReceiverUI/Pages/LoginReceiver.razor`
|
**File:** `ReceiverUI/Pages/LoginReceiver.razor`
|
||||||
|
|
||||||
|
**Multi-Envelope Support:** Cookies are stored per-envelope (e.g., `AuthTokenSignFLOWReceiver.{envelopeKey}`), allowing simultaneous authentication for multiple envelopes in the same browser session.
|
||||||
|
|
||||||
### AuthService Method
|
### AuthService Method
|
||||||
```csharp
|
```csharp
|
||||||
public enum EnvelopeLoginResult { Success, InvalidCode, NotFound, Error }
|
public enum EnvelopeLoginResult { Success, InvalidCode, NotFound, Error }
|
||||||
@@ -307,7 +355,7 @@ public async Task<EnvelopeLoginResult> LoginEnvelopeReceiverAsync(string key, st
|
|||||||
|
|
||||||
| Mistake | Why Wrong |
|
| Mistake | Why Wrong |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Using iText7 in EnvelopeViewer | GPL license issue. Use overlay system instead. |
|
| Using iText7 in EnvelopeReceiver | GPL license issue. Use overlay system instead. |
|
||||||
| Using PSPDFKit | Removed from architecture. Use PDF.js + DevExpress. |
|
| Using PSPDFKit | Removed from architecture. Use PDF.js + DevExpress. |
|
||||||
| Hardcoded quality values in PDF.js | Use `appsettings.json` for configurability. |
|
| Hardcoded quality values in PDF.js | Use `appsettings.json` for configurability. |
|
||||||
| Complex toolbar layouts | User wants simplicity. Keep horizontal layout. |
|
| Complex toolbar layouts | User wants simplicity. Keep horizontal layout. |
|
||||||
@@ -367,4 +415,4 @@ Proves database uses INCHES natively.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Last Updated:** Session 17 (Architecture unification documentation)
|
**Last Updated:** Session 18 (File renames & routing restructure)
|
||||||
|
|||||||
Reference in New Issue
Block a user