Refactor signature caching and navigation logic

Replaced the previous signature persistence mechanism with
`IMemoryCache` for temporary storage of captured signatures
using a unique `Guid` key and a 1-minute TTL. Added logging
to track cached signatures and their associated envelope keys.

Removed the logic for rebuilding and displaying reports with
overlaid signatures. Instead, implemented navigation to a
new signed page (`/envelope/{EnvelopeKey}/signed`) with the
signature ID passed as a query parameter.
This commit is contained in:
2026-07-01 01:41:19 +02:00
parent 49ec9fbead
commit df154d83cc

View File

@@ -10,12 +10,14 @@
@using DevExpress.Blazor @using DevExpress.Blazor
@using System.Drawing @using System.Drawing
@using System.Security.Claims @using System.Security.Claims
@using Microsoft.Extensions.Caching.Memory
@inject NavigationManager Navigation @inject NavigationManager Navigation
@inject IJSRuntime JSRuntime @inject IJSRuntime JSRuntime
@inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService @inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService
@inject EnvelopeGenerator.Server.Services.EnvelopeReceiverAuthorizationService ReceiverAuthorizationService @inject EnvelopeGenerator.Server.Services.EnvelopeReceiverAuthorizationService ReceiverAuthorizationService
@inject EnvelopeGenerator.Server.Services.EnvelopeReceiverPageDataService PageDataService @inject EnvelopeGenerator.Server.Services.EnvelopeReceiverPageDataService PageDataService
@inject AppVersionService AppVersion @inject AppVersionService AppVersion
@inject IMemoryCache MemoryCache
@inject ILogger<EnvelopeReceiverReportPage> Logger @inject ILogger<EnvelopeReceiverReportPage> Logger
@implements IDisposable @implements IDisposable
@@ -678,32 +680,19 @@
}; };
_signaturePopupVisible = false; _signaturePopupVisible = false;
// Persist to cache (fire-and-forget) // Store signature in IMemoryCache with a Guid key (1 minute TTL)
if (_receiverUser is not null) var sid = Guid.NewGuid().ToString("N");
{ MemoryCache.Set(
_ = Task.Run(async () => sid,
{ _capturedSignature,
try { await PageDataService.SaveCachedSignatureAsync(_receiverUser, _capturedSignature); } TimeSpan.FromMinutes(1));
catch { /* non-critical */ }
});
}
// Rebuild the report with signatures overlaid Logger.LogInformation(
if (_pdfBytes is not null) "Signature cached with sid={Sid} for envelope {EnvelopeKey}", sid, EnvelopeKey);
{
var newReport = BuildReport(_pdfBytes, _signatures, _capturedSignature);
if (_reportViewer is not null) // Navigate to signed page
{ Navigation.NavigateTo(
await _reportViewer.OpenReportAsync(newReport); $"/envelope/{Uri.EscapeDataString(EnvelopeKey!)}/signed?sid={sid}");
// Dispose previous report after opening new one
_report?.Dispose();
}
_report = newReport;
}
await InvokeAsync(StateHasChanged);
} }
async Task<string?> GetActiveSignatureDataUrlAsync() async Task<string?> GetActiveSignatureDataUrlAsync()