From 2fed1baff57aa719c51184882f66277b15023ca9 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 29 May 2026 08:47:54 +0200 Subject: [PATCH] Add JWT token support for EnvelopeReceiver entities Enhanced the `AuthController` to support JWT token generation for `EnvelopeReceiverSecretDto` entities. Added a new dependency `IJwtSignatureHandler` and updated the constructor to inject it. Refactored the `CreateTokenForEnvelopeReceiver` method: - Added a `cookie` query parameter to control token delivery. - Implemented consumer validation using `_consumerService`. - Added token descriptor retrieval from `_keyPool`. - Improved `AccessCode` validation for `EnvelopeReceiver`. - Added logic to set tokens as cookies or return in the body. Updated `using` directives to include required namespaces. Improved error handling, readability, and flexibility in token generation and delivery. --- .../Controllers/AuthController.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/DigitalData.Auth.API/Controllers/AuthController.cs b/src/DigitalData.Auth.API/Controllers/AuthController.cs index 09a6a34..94ecc85 100644 --- a/src/DigitalData.Auth.API/Controllers/AuthController.cs +++ b/src/DigitalData.Auth.API/Controllers/AuthController.cs @@ -8,6 +8,7 @@ using DigitalData.Core.Abstractions.Security.Extensions; using DigitalData.Core.Abstractions.Security.Services; using DigitalData.UserManager.Application.Contracts; using DigitalData.UserManager.Application.DTOs.User; +using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver; using EnvelopeGenerator.Application.Common.Extensions; using EnvelopeGenerator.Application.Common.Interfaces.Services; using EnvelopeGenerator.Application.EnvelopeReceivers.Queries; @@ -18,6 +19,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.Options; +using System.Net; using System.Text; namespace DigitalData.Auth.API.Controllers @@ -26,6 +28,8 @@ namespace DigitalData.Auth.API.Controllers [ApiController] public class AuthController : ControllerBase { + private readonly IJwtSignatureHandler _erSignatureHandler; + private readonly IJwtSignatureHandler _userSignatureHandler; private readonly IJwtSignatureHandler _consumerSignatureHandler; @@ -46,7 +50,7 @@ namespace DigitalData.Auth.API.Controllers private readonly IMediator _mediator; - public AuthController(IJwtSignatureHandler userSignatureHandler, IOptions cookieParamsOptions, IAsymmetricKeyPool keyPool, ILogger logger, IUserService userService, IDirectorySearchService dirSearchService, IConsumerService consumerService, IJwtSignatureHandler apiSignatureHandler, IOptionsMonitor backdoorMonitor, IMediator mediator) + public AuthController(IJwtSignatureHandler userSignatureHandler, IOptions cookieParamsOptions, IAsymmetricKeyPool keyPool, ILogger logger, IUserService userService, IDirectorySearchService dirSearchService, IConsumerService consumerService, IJwtSignatureHandler apiSignatureHandler, IOptionsMonitor backdoorMonitor, IMediator mediator, IJwtSignatureHandler erSignatureHandler) { _apiParams = cookieParamsOptions.Value; _userSignatureHandler = userSignatureHandler; @@ -58,6 +62,7 @@ namespace DigitalData.Auth.API.Controllers _consumerSignatureHandler = apiSignatureHandler; _backdoorMonitor = backdoorMonitor; _mediator = mediator; + _erSignatureHandler = erSignatureHandler; } private async Task CreateTokenAsync(UserLogin login, string consumerName, bool cookie = true) @@ -223,17 +228,41 @@ namespace DigitalData.Auth.API.Controllers public IActionResult Check() => Ok(); [HttpPost("envelope-receiver/{key}")] - public async Task CreateTokenForEnvelopeReceiver([FromRoute]string key, [FromForm] ReceiverLogin receiverLogin, CancellationToken cancel) + public async Task CreateTokenForEnvelopeReceiver([FromRoute]string key, [FromForm] ReceiverLogin receiverLogin, [FromQuery] bool cookie = true, CancellationToken cancel = default) { + //find the consumer + var consumer = await _consumerService.ReadByNameAsync("sign-flow"); + if (consumer is null) + return Unauthorized(); + + if (!_keyPool.TokenDescriptors.TryGet(_apiParams.Issuer, consumer.Audience, out var descriptor)) + return StatusCode(StatusCodes.Status500InternalServerError); + + // find receiver var er = await _mediator.Send(new ReadEnvelopeReceiverSecretQuery() { Key = key }, cancel); - if(er is null) + if (er is null) return NotFound(); - return er.AccessCode == receiverLogin.AccessCode ? Ok() : Unauthorized(); + // check acccess code + if (er.AccessCode != receiverLogin.AccessCode) + return Unauthorized(); + + // create token + var token = _erSignatureHandler.WriteToken(er, descriptor); + + //set cookie + if (cookie) + { + var cookieOptions = consumer.CookieOptions ?? _apiParams.DefaultCookieOptions; + Response.Cookies.Append(_apiParams.DefaultCookieName, token, cookieOptions.Create(lifetime: descriptor.Lifetime)); + return Ok(); + } + else + return Ok(token); } } } \ No newline at end of file