Replaced PKCS#11-based cryptographic operations with a new DocumentService API integration. Removed all PKCS#11-related code, configurations, and dependencies, including options, self-test status, and signing logic. Updated `FinalizeEnvelopeCommand` to include a notification service and added base64 conversion for documents. Updated `ServiceCollectionExtensions` to register the new DocumentService client. Removed outdated documentation and diagrams related to PKCS#11. Updated project files and configurations to reflect these changes and incremented the version number. Added a comment in `EnvelopeFinalizationWorker` for future RabbitMQ integration.
78 lines
3.5 KiB
C#
78 lines
3.5 KiB
C#
using DocumentService.Client.Interfaces;
|
|
using DocumentService.Client.Models.Requests;
|
|
using EnvelopeGenerator.Application.Common.Dto;
|
|
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
|
using ClientCertLevel = DocumentService.Client.Models.Requests.PdfSignatureCertificationLevel;
|
|
using ClientCoordUnit = DocumentService.Client.Models.Requests.PdfSignatureCoordinateUnit;
|
|
using ClientCoordOrigin = DocumentService.Client.Models.Requests.PdfSignatureCoordinateOrigin;
|
|
|
|
namespace EnvelopeGenerator.Infrastructure.Crypt.Services;
|
|
|
|
/// <summary>
|
|
/// Proxy that forwards PDF signing to the remote DocumentService API via <see cref="IPdfSignatureClient"/>.
|
|
/// </summary>
|
|
public sealed class PdfDigitalSignatureService(IPdfSignatureClient signatureClient) : IPdfDigitalSignatureService
|
|
{
|
|
public async Task SignPdfAsync(Stream inputPdf, Stream outputPdf, PdfSignOptionsDto? options = null, Stream? image = null, CancellationToken cancellationToken = default)
|
|
{
|
|
var pdfBytes = await ReadAllBytesAsync(inputPdf, cancellationToken);
|
|
var imageBytes = image is null ? null : await ReadAllBytesAsync(image, cancellationToken);
|
|
|
|
using var signed = await signatureClient.SignAsync(pdfBytes, Map(options), imageBytes, cancellationToken);
|
|
await signed.CopyToAsync(outputPdf, cancellationToken);
|
|
}
|
|
|
|
public Task<PdfSignatureCheckResultDto> CheckPdfSignatureAsync(Stream inputPdf, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException("Signature checking is handled by DocumentService and is not available through this proxy.");
|
|
|
|
private static SignPdfOptions Map(PdfSignOptionsDto? o) => new()
|
|
{
|
|
DocumentElementId = o?.DocumentElementId ?? 0,
|
|
Name = o?.Name ?? string.Empty,
|
|
Reason = o?.Reason,
|
|
Location = o?.Location,
|
|
Email = o?.Email,
|
|
Phone = o?.Phone,
|
|
ApplicationName = o?.ApplicationName,
|
|
CertificationLevel = (ClientCertLevel)(o?.CertificationLevel ?? EnvelopeGenerator.Application.Common.Enums.PdfSignatureCertificationLevel.NoCertification),
|
|
Appearance = o?.Appearance is null ? null : MapAppearance(o.Appearance)
|
|
};
|
|
|
|
private static PdfSignatureAppearance MapAppearance(PdfSignatureAppearanceDto a) => new()
|
|
{
|
|
PageNumber = a.PageNumber,
|
|
Left = a.Left,
|
|
Bottom = a.Bottom,
|
|
Width = a.Width,
|
|
Height = a.Height,
|
|
ShowLabels = a.ShowLabels,
|
|
ShowName = a.ShowName,
|
|
ShowDate = a.ShowDate,
|
|
ShowReason = a.ShowReason,
|
|
ShowLocation = a.ShowLocation,
|
|
ShowDistinguishedName = a.ShowDistinguishedName,
|
|
DateTimeFormat = a.DateTimeFormat,
|
|
CoordinateUnit = (ClientCoordUnit)a.CoordinateUnit,
|
|
CoordinateOrigin = (ClientCoordOrigin)a.CoordinateOrigin,
|
|
Font = new PdfSignatureFont
|
|
{
|
|
FamilyName = a.Font.FamilyName,
|
|
Size = a.Font.Size,
|
|
IsBold = a.Font.IsBold,
|
|
IsItalic = a.Font.IsItalic,
|
|
IsUnderline = a.Font.IsUnderline,
|
|
Color = new PdfSignatureColor { R = a.Font.Color.R, G = a.Font.Color.G, B = a.Font.Color.B }
|
|
}
|
|
};
|
|
|
|
private static async Task<byte[]> ReadAllBytesAsync(Stream stream, CancellationToken cancellationToken)
|
|
{
|
|
if (stream is MemoryStream memory && memory.TryGetBuffer(out var buffer))
|
|
return buffer.AsSpan(0, (int)memory.Length).ToArray();
|
|
|
|
using var copy = new MemoryStream();
|
|
await stream.CopyToAsync(copy, cancellationToken);
|
|
return copy.ToArray();
|
|
}
|
|
}
|