Refactor sender page and auth service logic
- Added project reference to `EnvelopeGenerator.Application` in the client project. - Updated imports and injected services in `EnvelopeSenderPage.razor`. - Improved null handling for `EnvelopeReceivers` and updated email display logic. - Replaced `CheckSenderAsync` with `CheckSenderAccessAsync` for authorization. - Refactored `GetStatusInfo` to use `EnvelopeStatus` enum directly. - Added `CheckSenderAccessAsync` and `LogoutSenderAsync` methods in `AuthService`. - Simplified `Logout` logic in `AuthController` to remove redundant checks.
This commit is contained in:
@@ -29,6 +29,10 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="PredefinedReports\Report.cs">
|
<Compile Update="PredefinedReports\Report.cs">
|
||||||
<SubType>XtraReport</SubType>
|
<SubType>XtraReport</SubType>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@attribute [Microsoft.AspNetCore.Authorization.Authorize(Policy = "Sender")]
|
@attribute [Microsoft.AspNetCore.Authorization.Authorize(Policy = "Sender")]
|
||||||
|
|
||||||
@using System.Text.Json
|
@using System.Text.Json
|
||||||
|
@using EnvelopeGenerator.Domain.Constants
|
||||||
@using EnvelopeGenerator.Server.Client.Models
|
@using EnvelopeGenerator.Server.Client.Models
|
||||||
@using DevExpress.Blazor
|
@using DevExpress.Blazor
|
||||||
@using EnvelopeGenerator.Server.Client.Services
|
@using EnvelopeGenerator.Server.Client.Services
|
||||||
@@ -10,6 +11,12 @@
|
|||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inject AppVersionService AppVersion
|
@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
|
||||||
|
|
||||||
<link href="_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css" rel="stylesheet" />
|
<link href="_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css" rel="stylesheet" />
|
||||||
<link href="@AppVersion.GetVersionedUrl("css/envelope-viewer.css")" rel="stylesheet" />
|
<link href="@AppVersion.GetVersionedUrl("css/envelope-viewer.css")" rel="stylesheet" />
|
||||||
@@ -161,7 +168,7 @@
|
|||||||
@{
|
@{
|
||||||
var envelope = cellContext.DataItem as EnvelopeDto;
|
var envelope = cellContext.DataItem as EnvelopeDto;
|
||||||
if (envelope != null) {
|
if (envelope != null) {
|
||||||
var receivers = envelope.EnvelopeReceivers ?? new List<EnvelopeReceiverSimpleDto>();
|
var receivers = envelope.EnvelopeReceivers?.ToList() ?? [];
|
||||||
var signed = receivers.Count(r => r.Signed);
|
var signed = receivers.Count(r => r.Signed);
|
||||||
var total = receivers.Count;
|
var total = receivers.Count;
|
||||||
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
||||||
@@ -204,7 +211,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<div style="flex: 1; font-size: 0.875rem;">
|
<div style="flex: 1; font-size: 0.875rem;">
|
||||||
<strong style="color: #1f2937;">@receiver.Name</strong>
|
<strong style="color: #1f2937;">@receiver.Name</strong>
|
||||||
<span style="color: #6b7280; margin-left: 0.5rem;">@receiver.Email</span>
|
<span style="color: #6b7280; margin-left: 0.5rem;">@receiver.Receiver?.EmailAddress</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -257,7 +264,7 @@
|
|||||||
@{
|
@{
|
||||||
var envelope = cellContext.DataItem as EnvelopeDto;
|
var envelope = cellContext.DataItem as EnvelopeDto;
|
||||||
if (envelope != null) {
|
if (envelope != null) {
|
||||||
var receivers = envelope.EnvelopeReceivers ?? new List<EnvelopeReceiverSimpleDto>();
|
var receivers = envelope.EnvelopeReceivers?.ToList() ?? [];
|
||||||
var signed = receivers.Count(r => r.Signed);
|
var signed = receivers.Count(r => r.Signed);
|
||||||
var total = receivers.Count;
|
var total = receivers.Count;
|
||||||
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
||||||
@@ -300,7 +307,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<div style="flex: 1; font-size: 0.875rem;">
|
<div style="flex: 1; font-size: 0.875rem;">
|
||||||
<strong style="color: #1f2937;">@receiver.Name</strong>
|
<strong style="color: #1f2937;">@receiver.Name</strong>
|
||||||
<span style="color: #6b7280; margin-left: 0.5rem;">@receiver.Email</span>
|
<span style="color: #6b7280; margin-left: 0.5rem;">@receiver.Receiver?.EmailAddress</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -333,7 +340,7 @@
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var hasAccess = await AuthService.CheckSenderAsync();
|
var hasAccess = await AuthService.CheckSenderAccessAsync();
|
||||||
if (!hasAccess)
|
if (!hasAccess)
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"/sender/login");
|
Navigation.NavigateTo($"/sender/login");
|
||||||
@@ -411,9 +418,8 @@
|
|||||||
return status >= EnvelopeStatus.EnvelopeQueued;
|
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
|
return status switch
|
||||||
{
|
{
|
||||||
EnvelopeStatus.EnvelopePartlySigned => ("Teilweise unterschrieben", "partly-signed", "green"),
|
EnvelopeStatus.EnvelopePartlySigned => ("Teilweise unterschrieben", "partly-signed", "green"),
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ public class AuthService(IHttpClientFactory httpClientFactory)
|
|||||||
return response.StatusCode == HttpStatusCode.OK;
|
return response.StatusCode == HttpStatusCode.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the current user holds a valid receiver token for the given envelope key.
|
||||||
|
/// Calls GET /api/auth/check/envelope/{envelopeKey}.
|
||||||
|
/// </summary>
|
||||||
|
public async Task<bool> CheckSenderAccessAsync(CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
using var http = CreateDefaultClient();
|
||||||
|
var response = await http.GetAsync($"/api/auth/check", cancel);
|
||||||
|
return response.StatusCode == HttpStatusCode.OK;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Submits the access code for the given envelope key.
|
/// Submits the access code for the given envelope key.
|
||||||
/// Calls POST /api/Auth/envelope-receiver/{key} with multipart/form-data.
|
/// Calls POST /api/Auth/envelope-receiver/{key} with multipart/form-data.
|
||||||
@@ -61,6 +72,19 @@ public class AuthService(IHttpClientFactory httpClientFactory)
|
|||||||
return response.IsSuccessStatusCode;
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the per-envelope receiver cookie for the given envelope key.
|
||||||
|
/// Calls POST /api/auth/logout/envelope/{envelopeKey}.
|
||||||
|
/// </summary>
|
||||||
|
public async Task<bool> LogoutSenderAsync(CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
using var http = CreateDefaultClient();
|
||||||
|
var response = await http.PostAsync(
|
||||||
|
$"/api/auth/logout",
|
||||||
|
null, cancel);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Authenticates a sender user with username and password.
|
/// Authenticates a sender user with username and password.
|
||||||
/// Calls POST /api/auth?cookie=true with JSON body.
|
/// Calls POST /api/auth?cookie=true with JSON body.
|
||||||
|
|||||||
@@ -40,17 +40,11 @@ public partial class AuthController(IOptions<AuthTokenKeys> authTokenKeyOptions,
|
|||||||
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
[Authorize(Policy = AuthPolicy.SenderOrReceiver)]
|
[Authorize(Policy = AuthPolicy.Sender)]
|
||||||
[HttpPost("logout")]
|
[HttpPost("logout")]
|
||||||
public async Task<IActionResult> Logout()
|
public IActionResult Logout()
|
||||||
{
|
{
|
||||||
if (await this.IsUserInPolicyAsync(AuthPolicy.Sender))
|
|
||||||
Response.Cookies.Delete(authTokenKeys.Cookie);
|
Response.Cookies.Delete(authTokenKeys.Cookie);
|
||||||
else if (await this.IsUserInPolicyAsync(AuthPolicy.ReceiverOrReceiverTFA))
|
|
||||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
||||||
else
|
|
||||||
return Unauthorized();
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user