diff --git a/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs b/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs
new file mode 100644
index 00000000..e94298c3
--- /dev/null
+++ b/EnvelopeGenerator.Application/PdfSigning/SignPdfByEnvelopeCommand.cs
@@ -0,0 +1,86 @@
+using DigitalData.Core.Abstraction.Application.Repository;
+using DigitalData.Core.Exceptions;
+using EnvelopeGenerator.Application.Common.Query;
+using EnvelopeGenerator.Domain.Entities;
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+
+namespace EnvelopeGenerator.Application.PdfSigning;
+///
+///
+///
+public record SignPdfByEnvelopeCommand : EnvelopeQueryBase, IRequest
+{
+ ///
+ ///
+ ///
+ public int? ReceiverId { get; init; } = null;
+
+ internal int? UserId { get; private set; } = null;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public SignPdfByEnvelopeCommand Authorized(int userId)
+ {
+ UserId = userId;
+ return this;
+ }
+}
+
+///
+///
+///
+public class SignPdfByEnvelopeCommandHandler(IRepository Repo, ISender sender) : IRequestHandler
+{
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task Handle(SignPdfByEnvelopeCommand request, CancellationToken cancel)
+ {
+ var envelopeQuery = Repo.Query;
+
+ if (request.Id is int id)
+ envelopeQuery = envelopeQuery.Where(e => e.Id == id);
+ else if (request.Uuid is string uuid)
+ envelopeQuery = envelopeQuery.Where(e => e.Uuid == uuid);
+
+ var envelope = await envelopeQuery.Include(e => e.EnvelopeReceivers).Include(e => e.Documents).SingleOrDefaultAsync(cancel)
+ ?? throw new NotFoundException($"Envelope is not found ID: {request.Id} UUID: {request.Uuid}");
+
+ if (request.UserId is int userId && userId != envelope.UserId)
+ throw new UnauthorizedAccessException($"Envelope is not authorized for user with Id: {request.UserId} Envelope ID: {request.Id} UUID: {request.Uuid}");
+
+ if (envelope.EnvelopeReceivers.Count == 0)
+ throw new NotFoundException($"Envelope has no receivers to sign ID: {request.Id} UUID: {request.Uuid}");
+
+ if(envelope.Documents.FirstOrDefault() is not Document document || document.ByteData is not byte[] byteData || byteData.Length == 0)
+ throw new NotFoundException($"Envelope has no documents to sign ID: {request.Id} UUID: {request.Uuid}");
+
+ Stream doc = new MemoryStream(byteData);
+
+ var eReceivers = request.ReceiverId is int receiverId
+ ? envelope.EnvelopeReceivers.Where(e => e.ReceiverId == receiverId)
+ : envelope.EnvelopeReceivers;
+
+ foreach (var eReceiver in eReceivers)
+ {
+ var signedDoc = await sender.Send(new SignPdfByEnvelopeReceiverCommand()
+ {
+ EnvelopeId = eReceiver.EnvelopeId,
+ ReceiverId = eReceiver.ReceiverId
+ }, cancel);
+
+ await doc.DisposeAsync();
+ doc = signedDoc;
+ }
+
+ return doc;
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfSignatureController.cs b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfSignatureController.cs
index bd046d93..0900bfca 100644
--- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfSignatureController.cs
+++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfSignatureController.cs
@@ -18,6 +18,23 @@ namespace EnvelopeGenerator.Server.Controllers;
[Route("api/[controller]")]
public class PdfSignatureController(IPdfDigitalSignatureService SignatureService, IMediator Mediator) : ControllerBase
{
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ [Authorize(AuthenticationSchemes = AuthScheme.Sender)]
+ public async Task SignDocument(SignPdfByEnvelopeCommand command, CancellationToken cancel)
+ {
+ var senderId = User.SenderId();
+ var result = await Mediator.Send(command.Authorized(senderId), cancel);
+ result.Position = 0;
+ var fileName = Path.GetFileNameWithoutExtension($"e{command.Id.ToString() ?? command.Uuid}_s{senderId}");
+ return File(result, "application/pdf", $"{fileName}_signed.pdf");
+ }
+
///
/// Gets the document for the specified envelope key.
///
@@ -26,7 +43,7 @@ public class PdfSignatureController(IPdfDigitalSignatureService SignatureService
///
[Authorize(Policy = AuthPolicy.Receiver)]
[HttpPost("{envelopeKey}")]
- public async Task SignDocument(string envelopeKey, CancellationToken cancel)
+ public async Task SignDocumentByReceiver(string envelopeKey, CancellationToken cancel)
{
int envelopeId = User.EnvelopeId();
int receiverId = User.ReceiverId();
@@ -38,8 +55,8 @@ public class PdfSignatureController(IPdfDigitalSignatureService SignatureService
}, cancel);
senderDoc.Position = 0;
- var fileName = Path.GetFileNameWithoutExtension(envelopeKey);
- return File(senderDoc, "application/pdf", $"{fileName}-signed.pdf");
+ var fileName = Path.GetFileNameWithoutExtension($"e{envelopeId}_r{receiverId}");
+ return File(senderDoc, "application/pdf", $"{fileName}_signed.pdf");
}
#region Test Endpoints
@@ -76,6 +93,7 @@ public class PdfSignatureController(IPdfDigitalSignatureService SignatureService
///
///
///
+ [NonAction]
[AllowAnonymous]
[HttpPost("sign")]
[Consumes("multipart/form-data")]
@@ -100,6 +118,7 @@ public class PdfSignatureController(IPdfDigitalSignatureService SignatureService
///
///
///
+ [NonAction]
[AllowAnonymous]
[HttpPost("is-signed")]
[Consumes("multipart/form-data")]