diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Auth/ApiAuthStateProvider.cs b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Auth/ApiAuthStateProvider.cs
new file mode 100644
index 00000000..9604e409
--- /dev/null
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Auth/ApiAuthStateProvider.cs
@@ -0,0 +1,46 @@
+using System.Security.Claims;
+using Microsoft.AspNetCore.Components.Authorization;
+using EnvelopeGenerator.ReceiverUI.Client.Services;
+
+namespace EnvelopeGenerator.ReceiverUI.Client.Auth;
+
+///
+/// Fragt die API, ob der Nutzer eingeloggt ist.
+///
+/// WARUM nicht selbst Token lesen?
+/// - Das Auth-Cookie ist HttpOnly → JavaScript/WASM kann es nicht lesen
+/// - Stattdessen: Frage die API "bin ich eingeloggt?" → GET /api/auth/check
+/// - Die API prüft das Cookie serverseitig und antwortet mit 200 oder 401
+///
+public class ApiAuthStateProvider : AuthenticationStateProvider
+{
+ private readonly IAuthService _authService;
+
+ public ApiAuthStateProvider(IAuthService authService)
+ {
+ _authService = authService;
+ }
+
+ public override async Task GetAuthenticationStateAsync()
+ {
+ var result = await _authService.CheckAuthAsync();
+
+ if (result.IsSuccess)
+ {
+ // Eingeloggt → Erstelle einen authentifizierten ClaimsPrincipal
+ var identity = new ClaimsIdentity("cookie");
+ return new AuthenticationState(new ClaimsPrincipal(identity));
+ }
+
+ // Nicht eingeloggt
+ return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
+ }
+
+ ///
+ /// Wird nach Login/Logout aufgerufen, damit Blazor den Auth-State aktualisiert.
+ ///
+ public void NotifyAuthChanged()
+ {
+ NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Components/Envelope/AccessCodeForm.razor b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Components/Envelope/AccessCodeForm.razor
index 70d23e4b..1113b905 100644
--- a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Components/Envelope/AccessCodeForm.razor
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.Client/Components/Envelope/AccessCodeForm.razor
@@ -1,5 +1,60 @@
-
AccessCodeForm
+@* DUMB COMPONENT: Kennt keine Services, nur Parameter und Events *@
+
+
+
Zugangscode eingeben
+
Ein Zugangscode wurde an Ihre E-Mail-Adresse gesendet.
- An unhandled error has occurred.
- Reload
- 🗙
-
+@code {
+ private ErrorBoundary? _errorBoundary;
+
+ private void Recover() => _errorBoundary?.Recover();
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/Routes.razor b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/Routes.razor
index d39c7e89..a2f43181 100644
--- a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/Routes.razor
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/Routes.razor
@@ -3,4 +3,12 @@
-
+
+
+
+
404
+
Diese Seite wurde nicht gefunden.
+
+
+
+
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/_Imports.razor b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/_Imports.razor
new file mode 100644
index 00000000..c8cadf00
--- /dev/null
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Components/_Imports.razor
@@ -0,0 +1,9 @@
+@using System.Net.Http
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using static Microsoft.AspNetCore.Components.Web.RenderMode
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.JSInterop
+@using EnvelopeGenerator.ReceiverUI.Components
+@using EnvelopeGenerator.ReceiverUI.Components.Layout
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.csproj b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.csproj
index e4d216dc..440ffc1e 100644
--- a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.csproj
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI.csproj
@@ -1,18 +1,15 @@
-
- net8.0
- enable
- enable
-
+
+ net9.0
+ enable
+ enable
+
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Program.cs b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Program.cs
index 119ae224..85c40e23 100644
--- a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Program.cs
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/Program.cs
@@ -1,16 +1,21 @@
-using EnvelopeGenerator.ReceiverUI.Client.Pages;
-using EnvelopeGenerator.ReceiverUI.Components;
+using EnvelopeGenerator.ReceiverUI.Components;
var builder = WebApplication.CreateBuilder(args);
-// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
+// API-Proxy: Alle /api/* Aufrufe an die echte API weiterleiten
+// WARUM: Der Blazor-Client ruft /api/envelope auf. Diese Anfrage geht an den
+// ReceiverUI-Server (gleiche Domain, kein CORS), der sie an die echte API weiterleitet.
+var apiBaseUrl = builder.Configuration["ApiBaseUrl"]
+ ?? throw new InvalidOperationException("ApiBaseUrl is not configured in appsettings.json.");
+
+builder.Services.AddHttpForwarder();
+
var app = builder.Build();
-// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
@@ -18,18 +23,20 @@ if (app.Environment.IsDevelopment())
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
- // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
-
app.UseStaticFiles();
app.UseAntiforgery();
+// Alle /api/* Requests an die echte EnvelopeGenerator.API weiterleiten
+// So muss der Browser nie direkt mit der API sprechen → kein CORS, Cookies funktionieren
+app.MapForwarder("/api/{**catch-all}", apiBaseUrl);
+
app.MapRazorComponents()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(EnvelopeGenerator.ReceiverUI.Client._Imports).Assembly);
-app.Run();
+app.Run();
\ No newline at end of file
diff --git a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/appsettings.json b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/appsettings.json
index 10f68b8c..bbee3a49 100644
--- a/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/appsettings.json
+++ b/EnvelopeGenerator.ReceiverUI/EnvelopeGenerator.ReceiverUI/appsettings.json
@@ -1,9 +1,9 @@
{
+ "ApiBaseUrl": "https://localhost:5001",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
- },
- "AllowedHosts": "*"
-}
+ }
+}
\ No newline at end of file