using EnvelopeGenerator.Web.Models; using Ganss.Xss; using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Extensions; using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Extensions; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication; using EnvelopeGenerator.Application.Interfaces.Services; using DigitalData.Core.Abstraction.Application.DTO; using static EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Web.Extensions; namespace EnvelopeGenerator.Web.Controllers; //TODO: Add authorization as well as limiting the link duration (intermediate token with different role) or sign it public class TFARegController : ViewControllerBase { [Obsolete("Use MediatR")] private readonly IEnvelopeReceiverService _envRcvService; private readonly IAuthenticator _authenticator; [Obsolete("Use MediatR")] private readonly IReceiverService _rcvService; private readonly TFARegParams _params; [Obsolete("Use MediatR")] public TFARegController(ILogger logger, Cultures cultures, IStringLocalizer localizer, IEnvelopeReceiverService erService, IAuthenticator authenticator, IReceiverService receiverService, IOptions tfaRegParamsOptions) : base(logger, cultures, localizer) { _envRcvService = erService; _authenticator = authenticator; _rcvService = receiverService; _params = tfaRegParamsOptions.Value; } //TODO: move under auth route [Authorize] [HttpGet("tfa/{envelopeReceiverId}")] [Obsolete("Use MediatR")] public async Task Reg(string envelopeReceiverId) { try { (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); if (uuid is null || signature is null) { _logger.LogEnvelopeError(uuid: uuid, signature: signature, message: _localizer.WrongEnvelopeReceiverId()); return Unauthorized(); } var er_secret_res = await _envRcvService.ReadWithSecretByUuidSignatureAsync(uuid: uuid, signature: signature); if (er_secret_res.IsFailed) { _logger.LogNotice(er_secret_res.Notices); return this.ViewEnvelopeNotFound(); } var er_secret = er_secret_res.Data; if (!er_secret.Envelope!.TFAEnabled) return Unauthorized(); var rcv = er_secret.Receiver; // Generate QR code as base 64 rcv!.TotpSecretkey = _authenticator.GenerateTotpSecretKey(); await _rcvService.UpdateAsync(rcv); var totp_qr_64 = _authenticator.GenerateTotpQrCode(userEmail: rcv.EmailAddress, secretKey: rcv.TotpSecretkey).ToBase64String(); // Calculate RFA registiration deadline if (rcv.TfaRegDeadline is null) { rcv.TfaRegDeadline = _params.Deadline; await _rcvService.UpdateAsync(rcv); } else if (rcv.TfaRegDeadline <= DateTime.Now) return View("_Expired"); ViewData["RegDeadline"] = rcv.TfaRegDeadline; ViewData["TotpQR64"] = totp_qr_64; return View(); } catch(Exception ex) { _logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex, message: _localizer.WrongEnvelopeReceiverId()); return this.ViewInnerServiceError(); } } [Authorize(Roles = ReceiverRole.FullyAuth)] [HttpPost("auth/logout")] public async Task LogOut() { try { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Ok(); } catch(Exception ex) { _logger.LogError(ex, "{message}", ex.Message); return this.ViewInnerServiceError(); } } }