using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using System.Text.Json; using EnvelopeGenerator.API.Options; using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.API.Extensions; namespace EnvelopeGenerator.API.Controllers; /// /// Manages cached data for receivers using distributed cache. /// [ApiController] [Route("api/[controller]")] [Authorize(Policy = AuthPolicy.Receiver)] public class CacheController( IDistributedCache cache, IOptions cacheOptions) : ControllerBase { private const string SignatureCacheKeyPrefix = "envelope-generator.receiver-ui.signature:"; /// /// Stores a receiver's signature in cache for the specified envelope. /// [Authorize(Policy = AuthPolicy.Receiver)] [HttpPost("SignatureCapture/{envelopeKey}")] public async Task SaveSignature( [FromRoute] string envelopeKey, [FromBody] SignatureCacheRequest request, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{User.ReceiverSignature()}"; var json = JsonSerializer.Serialize(request); var options = cacheOptions.Value.SignatureCacheExpiration.HasValue ? new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = cacheOptions.Value.SignatureCacheExpiration.Value } : null; await cache.SetStringAsync(cacheKey, json, options ?? new DistributedCacheEntryOptions(), cancel); return Ok(); } /// /// Retrieves a cached signature for the specified envelope. /// [Authorize(Policy = AuthPolicy.Receiver)] [HttpGet("SignatureCapture/{envelopeKey}")] public async Task GetSignature([FromRoute] string envelopeKey, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{User.ReceiverSignature()}"; var json = await cache.GetStringAsync(cacheKey, cancel); if (json is null) return NotFound(); var signature = JsonSerializer.Deserialize(json); return Ok(signature); } /// /// Deletes a cached signature for the specified envelope. /// [Authorize(Policy = AuthPolicy.Receiver)] [HttpDelete("SignatureCapture/{envelopeKey}")] public async Task DeleteSignature([FromRoute] string envelopeKey, CancellationToken cancel) { var cacheKey = $"{SignatureCacheKeyPrefix}{User.ReceiverSignature()}"; await cache.RemoveAsync(cacheKey, cancel); return Ok(); } } /// /// Request model for caching signature data. /// public sealed record SignatureCacheRequest( string DataUrl, string FullName, string Place, string? Position = null);