diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/EnvelopeGenerator.Server.Client.csproj b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/EnvelopeGenerator.Server.Client.csproj index c6654766..b00ba988 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/EnvelopeGenerator.Server.Client.csproj +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/EnvelopeGenerator.Server.Client.csproj @@ -29,6 +29,10 @@ + + + + XtraReport diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor index e1117038..3a6a5f5b 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor @@ -2,6 +2,7 @@ @attribute [Microsoft.AspNetCore.Authorization.Authorize(Policy = "Sender")] @using System.Text.Json +@using EnvelopeGenerator.Domain.Constants @using EnvelopeGenerator.Server.Client.Models @using DevExpress.Blazor @using EnvelopeGenerator.Server.Client.Services @@ -10,6 +11,12 @@ @inject NavigationManager Navigation @inject IJSRuntime JSRuntime @inject AppVersionService AppVersion +@using EnvelopeGenerator.Application.Common.Dto +@inject EnvelopeGenerator.Server.Client.Services.EnvelopeService EnvelopeService +@inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService +@inject NavigationManager Navigation +@inject IJSRuntime JSRuntime +@inject AppVersionService AppVersion @@ -161,7 +168,7 @@ @{ var envelope = cellContext.DataItem as EnvelopeDto; if (envelope != null) { - var receivers = envelope.EnvelopeReceivers ?? new List(); + var receivers = envelope.EnvelopeReceivers?.ToList() ?? []; var signed = receivers.Count(r => r.Signed); var total = receivers.Count;
@@ -204,7 +211,7 @@
@receiver.Name - @receiver.Email + @receiver.Receiver?.EmailAddress
} @@ -257,7 +264,7 @@ @{ var envelope = cellContext.DataItem as EnvelopeDto; if (envelope != null) { - var receivers = envelope.EnvelopeReceivers ?? new List(); + var receivers = envelope.EnvelopeReceivers?.ToList() ?? []; var signed = receivers.Count(r => r.Signed); var total = receivers.Count;
@@ -300,7 +307,7 @@
@receiver.Name - @receiver.Email + @receiver.Receiver?.EmailAddress
} @@ -333,7 +340,7 @@ protected override async Task OnInitializedAsync() { - var hasAccess = await AuthService.CheckSenderAsync(); + var hasAccess = await AuthService.CheckSenderAccessAsync(); if (!hasAccess) { Navigation.NavigateTo($"/sender/login"); @@ -411,9 +418,8 @@ return status >= EnvelopeStatus.EnvelopeQueued; } - (string Label, string CssClass, string DotColor) GetStatusInfo(int statusCode) + (string Label, string CssClass, string DotColor) GetStatusInfo(EnvelopeStatus status) { - var status = (EnvelopeStatus)statusCode; return status switch { EnvelopeStatus.EnvelopePartlySigned => ("Teilweise unterschrieben", "partly-signed", "green"), diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/AuthService.cs b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/AuthService.cs index c5e74eef..bb8658a6 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/AuthService.cs +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/AuthService.cs @@ -22,6 +22,17 @@ public class AuthService(IHttpClientFactory httpClientFactory) return response.StatusCode == HttpStatusCode.OK; } + /// + /// Checks whether the current user holds a valid receiver token for the given envelope key. + /// Calls GET /api/auth/check/envelope/{envelopeKey}. + /// + public async Task CheckSenderAccessAsync(CancellationToken cancel = default) + { + using var http = CreateDefaultClient(); + var response = await http.GetAsync($"/api/auth/check", cancel); + return response.StatusCode == HttpStatusCode.OK; + } + /// /// Submits the access code for the given envelope key. /// Calls POST /api/Auth/envelope-receiver/{key} with multipart/form-data. @@ -61,6 +72,19 @@ public class AuthService(IHttpClientFactory httpClientFactory) return response.IsSuccessStatusCode; } + /// + /// Removes the per-envelope receiver cookie for the given envelope key. + /// Calls POST /api/auth/logout/envelope/{envelopeKey}. + /// + public async Task LogoutSenderAsync(CancellationToken cancel = default) + { + using var http = CreateDefaultClient(); + var response = await http.PostAsync( + $"/api/auth/logout", + null, cancel); + return response.IsSuccessStatusCode; + } + /// /// Authenticates a sender user with username and password. /// Calls POST /api/auth?cookie=true with JSON body. diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/AuthController.cs b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/AuthController.cs index a45e9899..19b47068 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/AuthController.cs +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/AuthController.cs @@ -40,17 +40,11 @@ public partial class AuthController(IOptions authTokenKeyOptions, /// Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [Authorize(Policy = AuthPolicy.SenderOrReceiver)] + [Authorize(Policy = AuthPolicy.Sender)] [HttpPost("logout")] - public async Task Logout() + public IActionResult Logout() { - if (await this.IsUserInPolicyAsync(AuthPolicy.Sender)) - Response.Cookies.Delete(authTokenKeys.Cookie); - else if (await this.IsUserInPolicyAsync(AuthPolicy.ReceiverOrReceiverTFA)) - await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - else - return Unauthorized(); - + Response.Cookies.Delete(authTokenKeys.Cookie); return Ok(); }