feat(HomeController): Aktualisiert, um SMS über zu senden.

- Unnötige Parameter in SmsParams entfernt.
 - Code-Sendefunktion von IMessagingService entfernt.
 - GetTotpExpirationTime Methode im CodeGenerator entfernt.
This commit is contained in:
Developer 02 2025-01-27 17:09:23 +01:00
parent cf300d3ade
commit 6abc17c3bf
8 changed files with 30 additions and 42 deletions

View File

@ -1,7 +1,4 @@
using DigitalData.Core.Abstractions.Client; using DigitalData.Core.Abstractions.Client;
using Microsoft.Extensions.Caching.Distributed;
using OtpNet;
namespace EnvelopeGenerator.Application.Configurations.GtxMessaging namespace EnvelopeGenerator.Application.Configurations.GtxMessaging
{ {
/// <summary> /// <summary>
@ -20,11 +17,5 @@ namespace EnvelopeGenerator.Application.Configurations.GtxMessaging
public string RecipientQueryParamName { get; init; } = "to"; public string RecipientQueryParamName { get; init; } = "to";
public string MessageQueryParamName { get; init; } = "text"; public string MessageQueryParamName { get; init; } = "text";
public int CodeLength { get; init; } = 5;
public int SmsTotpStep { get; init; } = 300;
public string DefaultTotpMessageFormat { get; init; } = "{0}";
} }
} }

View File

@ -15,7 +15,5 @@ namespace EnvelopeGenerator.Application.Contracts
string GenerateTotp(string secretKey, int step = 30); string GenerateTotp(string secretKey, int step = 30);
bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null); bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null);
bool GetTotpExpirationTime(int step = 30);
} }
} }

View File

@ -7,6 +7,4 @@ public interface IMessagingService
string ServiceProvider { get; } string ServiceProvider { get; }
Task<SmsResponse> SendSmsAsync(string recipient, string message); Task<SmsResponse> SendSmsAsync(string recipient, string message);
Task<SmsResponse> SendSmsCodeAsync(string recipient, string secretKey, string messageFormat = "{0}");
} }

View File

@ -4,6 +4,8 @@
{ {
public required bool Ok { get; init; } public required bool Ok { get; init; }
public bool Failed => !Ok;
public dynamic? Errors { get; init; } public dynamic? Errors { get; init; }
} }
} }

View File

@ -62,7 +62,6 @@ namespace EnvelopeGenerator.Application.Extensions
services.AddHttpClientService<SmsParams>(smsConfigSection); services.AddHttpClientService<SmsParams>(smsConfigSection);
services.TryAddSingleton<IMessagingService, GtxMessagingService>(); services.TryAddSingleton<IMessagingService, GtxMessagingService>();
services.TryAddSingleton<ICodeGenerator, CodeGenerator>(); services.TryAddSingleton<ICodeGenerator, CodeGenerator>();
services.TryAddSingleton<IEnvelopeReceiverCache, EnvelopeReceiverCache>();
services.TryAddSingleton<QRCodeGenerator>(); services.TryAddSingleton<QRCodeGenerator>();
return services; return services;

View File

@ -67,10 +67,5 @@ namespace EnvelopeGenerator.Application.Services
public bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null) public bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null)
=> new Totp(Base32Encoding.ToBytes(secretKey), step).VerifyTotp(totpCode, out _, window); => new Totp(Base32Encoding.ToBytes(secretKey), step).VerifyTotp(totpCode, out _, window);
public bool GetTotpExpirationTime(int step = 30)
{
throw new NotImplementedException();
}
} }
} }

View File

@ -16,17 +16,14 @@ public class GtxMessagingService : IMessagingService
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly ICodeGenerator _codeGen;
public string ServiceProvider { get; } public string ServiceProvider { get; }
public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator) public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper)
{ {
_smsClient = smsClient; _smsClient = smsClient;
_smsParams = smsParamsOptions.Value; _smsParams = smsParamsOptions.Value;
_mapper = mapper; _mapper = mapper;
ServiceProvider = GetType().Name.Replace("Service", string.Empty); ServiceProvider = GetType().Name.Replace("Service", string.Empty);
_codeGen = codeGenerator;
} }
public async Task<SmsResponse> SendSmsAsync(string recipient, string message) public async Task<SmsResponse> SendSmsAsync(string recipient, string message)
@ -39,11 +36,4 @@ public class GtxMessagingService : IMessagingService
.ThenAsync(res => res.Json<GtxMessagingResponse>()) .ThenAsync(res => res.Json<GtxMessagingResponse>())
.ThenAsync(_mapper.Map<SmsResponse>); .ThenAsync(_mapper.Map<SmsResponse>);
} }
public async Task<SmsResponse> SendSmsCodeAsync(string recipient, string secretKey, string? messageFormat = null)
{
var code = _codeGen.GenerateTotp(secretKey, _smsParams.SmsTotpStep);
var message = string.Format(messageFormat ?? _smsParams.DefaultTotpMessageFormat, code);
return await SendSmsAsync(recipient: recipient, message: message);
}
} }

View File

@ -20,6 +20,11 @@ using Newtonsoft.Json;
using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs;
using DigitalData.Core.Client; using DigitalData.Core.Client;
using EnvelopeGenerator.Application.Extensions; using EnvelopeGenerator.Application.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using System.Globalization;
using EnvelopeGenerator.Application.Configurations.GtxMessaging;
using EnvelopeGenerator.Application.DTOs.Messaging;
using OtpNet;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
{ {
@ -38,10 +43,13 @@ namespace EnvelopeGenerator.Web.Controllers
private readonly IMessagingService _msgService; private readonly IMessagingService _msgService;
private readonly ICodeGenerator _codeGenerator; private readonly ICodeGenerator _codeGenerator;
private readonly IReceiverService _rcvService; private readonly IReceiverService _rcvService;
private static readonly int SmsTotpStep = 60 * 3; private readonly IDistributedCache _dCache;
private static readonly string SmsFormat = "{0}"; private static readonly int SmsTotpStep = 60 * 1;
private static readonly string SmsFormat = "signFlow TFA-Passwort ist {0}. Dieses Passwort ist bis {1} Uhr gültig.";
private static readonly string SmsCodeExpirationCacheKeyFormat = "e{0}_r{1}_sms_code_expiration";
private static readonly (string DateTimeFormat, CultureInfo CultureInfo) SmsCodeExpiration = ("HH:mm:ss", new CultureInfo("de-DE"));
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IMessagingService messagingService, ICodeGenerator codeGenerator, IReceiverService receiverService) public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IMessagingService messagingService, ICodeGenerator codeGenerator, IReceiverService receiverService, IDistributedCache distributedCache)
{ {
this.envelopeOldService = envelopeOldService; this.envelopeOldService = envelopeOldService;
_envRcvService = envelopeReceiverService; _envRcvService = envelopeReceiverService;
@ -56,6 +64,7 @@ namespace EnvelopeGenerator.Web.Controllers
_msgService = messagingService; _msgService = messagingService;
_codeGenerator = codeGenerator; _codeGenerator = codeGenerator;
_rcvService = receiverService; _rcvService = receiverService;
_dCache = distributedCache;
} }
[HttpGet("/")] [HttpGet("/")]
@ -197,17 +206,23 @@ namespace EnvelopeGenerator.Web.Controllers
if (viaSms) if (viaSms)
{ {
//add date time cache //add date time cache
var res = await _msgService.SendSmsCodeAsync(er_secret.PhoneNumber!, er_secret.Receiver!.TotpSecretkey!, SmsFormat); var key = string.Format(SmsCodeExpirationCacheKeyFormat, er_secret.EnvelopeId, er_secret.ReceiverId);
if (res.Ok) var expiration = await _dCache.GetDateTimeAsync(key);
return View("EnvelopeLocked").WithData("CodeType", "smsCode").WithData("SmsExpiration", _codeGenerator.GetTotpExpirationTime(SmsTotpStep)); if(expiration is null || expiration <= DateTime.Now)
else if (!res.Allowed)
return View("EnvelopeLocked").WithData("CodeType", "smsCode").WithData("SmsExpiration", res.AllowedAt);
else
{ {
var res_json = JsonConvert.SerializeObject(res); var new_expiration = DateTime.Now.AddMinutes(SmsTotpStep);
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: $"An unexpected error occurred while sending an SMS code. Response: ${res_json}"); var totp = _codeGenerator.GenerateTotp(er_secret.Receiver!.TotpSecretkey!, SmsTotpStep);
return this.ViewInnerServiceError(); var msg = string.Format(SmsFormat, totp, new_expiration.ToString(SmsCodeExpiration.DateTimeFormat, SmsCodeExpiration.CultureInfo));
var smsRes = await _msgService.SendSmsAsync(er_secret.PhoneNumber!, msg);
if (smsRes.Failed)
{
var res_json = JsonConvert.SerializeObject(smsRes);
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: $"An unexpected error occurred while sending an SMS code. Response: ${res_json}");
return this.ViewInnerServiceError();
}
} }
return View("EnvelopeLocked").WithData("CodeType", "smsCode").WithData("SmsExpiration", expiration);
} }
else else
{ {