using DocumentOperator.Application.Common.Dto; using DocumentOperator.Application.SignPdf; using DocumentService.Domain.Common.Exceptions; using MediatR; using Microsoft.AspNetCore.Mvc; namespace DocumentService.API.Controllers; /// /// Controller for PDF digital signing (PKCS#11 / company certificate). /// [ApiController] [Route("api/pdf/signature")] public class PdfSignatureController(IMediator mediator) : ControllerBase { /// /// Digitally signs a PDF using the configured PKCS#11 signing infrastructure. /// /// Base64-encoded PDF, optional signature image, and signing options /// Cancellation token /// Signed PDF /// PDF signed successfully - returns signed PDF /// Invalid input (Base64 format error, invalid appearance) /// Internal server error during signing [HttpPost("sign")] [Consumes("application/json")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] public async Task Sign([FromBody] SignPdfRequest request, CancellationToken cancellationToken) { byte[] signedPdf; try { signedPdf = await mediator.Send(new SignPdfCommand { InputPdf = new MemoryStream(Convert.FromBase64String(request.Base64Pdf)), Options = request.Options, SignatureImage = string.IsNullOrWhiteSpace(request.Base64SignatureImage) ? null : new MemoryStream(Convert.FromBase64String(request.Base64SignatureImage)) }, cancellationToken); } catch (FormatException ex) { throw new BadRequestException("Invalid Base64 format: " + ex.Message); } return File(signedPdf, "application/pdf", "signed.pdf"); } } /// /// Request DTO for PDF signing via JSON payload. /// public sealed class SignPdfRequest { /// /// Base64-encoded PDF to sign. /// public required string Base64Pdf { get; init; } /// /// Optional Base64-encoded signature image (PNG/JPEG). /// public string? Base64SignatureImage { get; init; } /// /// Signing options (metadata + appearance). /// public required PdfSignOptionsDto Options { get; init; } }