Developer 02 5f780f8d1e fix(EnvelopeSmsHandler): Korrekte Ablaufprüfung und Cache-Aktualisierung in SendTotpAsync
- Die Bedingung für die Überprüfung des Ablaufs wurde korrigiert, so dass sie korrekt null zurückgibt, wenn der gespeicherte Ablauf in der Zukunft liegt.
- Fehlende Cache-Aktualisierung zur Speicherung des neuen Verfallsdatums nach dem Versand der TOTP-SMS hinzugefügt.
2025-02-10 11:48:36 +01:00

54 lines
2.4 KiB
C#

using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
namespace EnvelopeGenerator.Application.Services;
public class EnvelopeSmsHandler : IEnvelopeSmsHandler
{
private readonly ISmsSender _sender;
private readonly TotpSmsParams _totpSmsParams;
private readonly IDistributedCache _dCache;
private readonly IAuthenticator _authenticator;
public EnvelopeSmsHandler(ISmsSender sender, IOptions<TotpSmsParams> totpSmsParamsOptions, IDistributedCache distributedCache, IAuthenticator authenticator)
{
_sender = sender;
_totpSmsParams = totpSmsParamsOptions.Value;
_dCache = distributedCache;
_authenticator = authenticator;
}
/// <summary>
/// If expiration is passed then, sends sms and returns smsResponse and up-to-date expiration; otherwise send expiration.
/// </summary>
/// <param name="er_secret"></param>
/// <param name="cToken"></param>
/// <returns></returns>
public async Task<(SmsResponse? SmsResponse, DateTime Expiration)> SendTotpAsync(EnvelopeReceiverSecretDto er_secret, CancellationToken cToken = default)
{
var key = string.Format(_totpSmsParams.Expiration.CacheKeyFormat, er_secret.EnvelopeId, er_secret.ReceiverId);
var expiration = await _dCache.GetDateTimeAsync(key, cToken);
if(expiration is DateTime expirationDateTime && expirationDateTime >= DateTime.Now)
return (null, expirationDateTime);
else
{
var new_expiration = DateTime.Now.AddSeconds(_totpSmsParams.TotpStep);
var totp = _authenticator.GenerateTotp(er_secret.Receiver!.TotpSecretkey!, _totpSmsParams.TotpStep);
var msg = string.Format(_totpSmsParams.Format, totp, new_expiration.ToString(_totpSmsParams.Expiration.Format, _totpSmsParams.Expiration.CultureInfo));
await _dCache.SetDateTimeAsync(key, new_expiration, cToken: cToken);
return (await _sender.SendSmsAsync(er_secret.PhoneNumber!, msg), new_expiration);
}
}
public bool VerifyTotp(string totpCode, string secretKey) => _authenticator
.VerifyTotp(totpCode, secretKey, _totpSmsParams.TotpStep, _totpSmsParams.TotpVerificationWindow);
}