Compare commits

...

6 Commits

Author SHA1 Message Date
0107602a84 upg Abstraction.Application and Application projects 2025-10-22 18:34:40 +02:00
02ecd88758 feat(TestAnnotationController): include receiver signature in RemoveSignatureNotification
Updated TestAnnotationController.Delete to extract the receiver signature from the envelope key
and pass it along with the envelope UUID when publishing RemoveSignatureNotification.
Returns BadRequest if the signature is missing.
2025-10-22 14:29:38 +02:00
17c7e46388 fix(AnnotationController): use PublishSafely for docSignedNotification
Replaced `await _mediator.Publish(docSignedNotification, cancel)` with
`await _mediator.PublishSafely(docSignedNotification, cancel)` to ensure
safe publishing of notifications without unhandled exceptions.
2025-10-22 14:25:50 +02:00
f3af30c67d feat(DocSignedNotificationExtensions): add PublishSafely extension for DocSignedNotification
- Introduced PublishSafely method to safely publish DocSignedNotification events.
- Added fallback logic to publish RemoveSignatureNotification when publishing fails.
- Added missing using directive for RemoveSignatureNotification namespace.
2025-10-22 13:10:38 +02:00
90e10d3d04 refactor(RemoveSignatureNotification): update handlers to throw exception if there is no filter 2025-10-22 12:50:57 +02:00
af14ef7ce5 feat(RemoveSignatureNotification): add validation and filter logic to RemoveSignatureNotification
- Added `HasFilter` property to check if any filter parameters are provided.
- Implemented `ThrowIfHasNoFilter()` method to enforce at least one filter parameter.
- Improves robustness and validation of RemoveSignatureNotification.
2025-10-22 11:02:10 +02:00
15 changed files with 71 additions and 18 deletions

View File

@@ -1,6 +1,7 @@
using EnvelopeGenerator.Application.Common.Dto;
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Common.Notifications.RemoveSignature;
using EnvelopeGenerator.Domain.Constants;
using MediatR;
using System.Dynamic;
@@ -60,4 +61,28 @@ public static class DocSignedNotificationExtensions
/// <returns></returns>
public static async Task<DocSignedNotification?> ToDocSignedNotification(this Task<EnvelopeReceiverDto?> dtoTask, PsPdfKitAnnotation psPdfKitAnnotation)
=> await dtoTask is EnvelopeReceiverDto dto ? new(dto) { PsPdfKitAnnotation = psPdfKitAnnotation } : null;
/// <summary>
///
/// </summary>
/// <param name="publisher"></param>
/// <param name="notification"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static async Task PublishSafely(this IPublisher publisher, DocSignedNotification notification, CancellationToken cancel = default)
{
try
{
await publisher.Publish(notification, cancel);
}
catch (Exception)
{
await publisher.Publish(new RemoveSignatureNotification()
{
EnvelopeId = notification.EnvelopeId,
ReceiverId = notification.ReceiverId
}, cancel);
throw;
}
}
}

View File

@@ -28,6 +28,7 @@ public class RemoveAnnotationHandler : INotificationHandler<RemoveSignatureNotif
/// <returns></returns>
public Task Handle(RemoveSignatureNotification notification, CancellationToken cancel)
{
notification.ThrowIfHasNoFilter();
return _repo.DeleteAsync(annots =>
{
// envelope ID filter

View File

@@ -28,6 +28,7 @@ public class RemoveDocStatusHandler : INotificationHandler<RemoveSignatureNotifi
/// <returns></returns>
public Task Handle(RemoveSignatureNotification notification, CancellationToken cancel)
{
notification.ThrowIfHasNoFilter();
return _repo.DeleteAsync(statuses =>
{
// envelope ID filter

View File

@@ -29,6 +29,7 @@ public class RemoveHistoryHandler : INotificationHandler<RemoveSignatureNotifica
/// <returns></returns>
public Task Handle(RemoveSignatureNotification notification, CancellationToken cancel)
{
notification.ThrowIfHasNoFilter();
return _repo.DeleteAsync(hists =>
{
hists = hists.Where(hist => hist.Status == EnvelopeStatus.DocumentSigned);

View File

@@ -14,4 +14,24 @@ public record RemoveSignatureNotification(
int? ReceiverId = null,
string? EnvelopeUuid = null,
string? ReceiverSignature = null
) : INotification;
) : INotification
{
/// <summary>
///
/// </summary>
public bool HasFilter =>
EnvelopeId is not null
|| ReceiverId is not null
|| EnvelopeUuid is not null
|| ReceiverSignature is not null;
/// <summary>
///
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
public void ThrowIfHasNoFilter()
{
if (!HasFilter)
throw new InvalidOperationException("At least one filter parameter must be provided.");
}
}

View File

@@ -14,7 +14,7 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.7" />
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
<PackageReference Include="DigitalData.Core.Client" Version="2.1.0" />
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />

View File

@@ -70,8 +70,8 @@
<Reference Include="DigitalData.Controls.DocumentViewer, Version=1.9.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Controls.DocumentViewer.1.9.8\lib\net462\DigitalData.Controls.DocumentViewer.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.6\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.7\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath>

View File

@@ -3,7 +3,7 @@
<package id="AutoMapper" version="10.1.1" targetFramework="net462" />
<package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" />
<package id="DigitalData.Controls.DocumentViewer" version="1.9.8" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.6" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.7" targetFramework="net462" />
<package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" />
<package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" />
<package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" />

View File

@@ -72,8 +72,8 @@
<Reference Include="DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraGauges.v21.2.Core, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraReports.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.6\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
<Reference Include="DigitalData.Core.Abstraction.Application, Version=1.3.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstraction.Application.1.3.7\lib\net462\DigitalData.Core.Abstraction.Application.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Abstractions, Version=4.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DigitalData.Core.Abstractions.4.1.1\lib\net462\DigitalData.Core.Abstractions.dll</HintPath>

View File

@@ -2,7 +2,7 @@
<packages>
<package id="AutoMapper" version="10.1.1" targetFramework="net462" />
<package id="BouncyCastle.Cryptography" version="2.5.0" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.6" targetFramework="net462" />
<package id="DigitalData.Core.Abstraction.Application" version="1.3.7" targetFramework="net462" />
<package id="DigitalData.Core.Abstractions" version="4.1.1" targetFramework="net462" />
<package id="DigitalData.Modules.Base" version="1.3.8" targetFramework="net462" />
<package id="DigitalData.Modules.Config" version="1.3.0" targetFramework="net462" />

View File

@@ -201,7 +201,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Identity.Client" publicKeyToken="0a613f4dd989e8ae" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.55.0.0" newVersion="4.55.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.8.0" newVersion="3.0.8.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.JsonWebTokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />

View File

@@ -22,8 +22,8 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.4.4" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.7" />
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.4.5" />
<PackageReference Include="QuestPDF" Version="2025.7.1" />
</ItemGroup>

View File

@@ -20,7 +20,7 @@
<ItemGroup>
<PackageReference Include="Bogus" Version="35.6.3" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.6" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.3.7" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="4.1.1" />
<PackageReference Include="DigitalData.Core.API" Version="2.2.1" />
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />

View File

@@ -65,7 +65,7 @@ public class AnnotationController : ControllerBase
.ToDocSignedNotification(psPdfKitAnnotation)
?? throw new NotFoundException("Envelope receiver is not found.");
await _mediator.Publish(docSignedNotification, cancel);
await _mediator.PublishSafely(docSignedNotification, cancel);
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

View File

@@ -9,7 +9,7 @@ namespace EnvelopeGenerator.Web.Controllers.Test;
[ApiController]
public class TestAnnotationController : ControllerBase
{
private IMediator _mediator;
private readonly IMediator _mediator;
public TestAnnotationController(IMediator mediator)
{
@@ -19,12 +19,17 @@ public class TestAnnotationController : ControllerBase
[HttpDelete("{envelopeKey}")]
public async Task<IActionResult> Delete([FromRoute] string envelopeKey)
{
var uuid = envelopeKey.GetEnvelopeUuid();
if (uuid == null)
if (envelopeKey.GetEnvelopeUuid() is not string uuid)
return BadRequest();
await _mediator.Publish(new RemoveSignatureNotification(uuid));
if (envelopeKey.GetReceiverSignature() is not string signature)
return BadRequest();
await _mediator.Publish(new RemoveSignatureNotification()
{
EnvelopeUuid = uuid,
ReceiverSignature = signature
});
return Ok();
}
}