refactor(HomeController): LogInEnvelope aktualisiert, um SMS-Code als TOTP zu verifizieren

This commit is contained in:
Developer 02
2025-01-27 13:47:26 +01:00
parent 3267acbeb3
commit af5d7c289d
11 changed files with 209 additions and 286 deletions

View File

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

View File

@@ -1,50 +0,0 @@
using AngleSharp.Dom;
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
namespace EnvelopeGenerator.Application.Services
{
public class EnvelopeReceiverCache : IEnvelopeReceiverCache
{
private readonly EnvelopeReceiverCacheParams _cacheParams;
private readonly DistributedCacheEntryOptions _codeCacheOptions;
private readonly IDistributedCache _cache;
public EnvelopeReceiverCache(IOptions<EnvelopeReceiverCacheParams> cacheParamOptions, IDistributedCache cache)
{
_cacheParams = cacheParamOptions.Value;
_codeCacheOptions = new() { AbsoluteExpirationRelativeToNow = cacheParamOptions.Value.CodeCacheValidityPeriod };
_cache = cache;
}
public async Task<string?> GetSmsCodeAsync(string envelopeReceiverId)
{
var code_key = string.Format(_cacheParams.CodeCacheKeyFormat, envelopeReceiverId);
return await _cache.GetStringAsync(code_key);
}
public async Task<DateTime> SetSmsCodeAsync(string envelopeReceiverId, string code)
{
// set key
var code_key = string.Format(_cacheParams.CodeCacheKeyFormat, envelopeReceiverId);
await _cache.SetStringAsync(code_key, code, _codeCacheOptions);
// set expiration
var code_expiration_key = string.Format(_cacheParams.CodeExpirationCacheKeyFormat, envelopeReceiverId);
var expiration = DateTime.Now + _cacheParams.CodeCacheValidityPeriod;
await _cache.SetDateTimeAsync(code_expiration_key, expiration, _codeCacheOptions);
return expiration;
}
public async Task<DateTime?> GetSmsCodeExpirationAsync(string envelopeReceiverId)
{
var code_expiration_key = string.Format(_cacheParams.CodeExpirationCacheKeyFormat, envelopeReceiverId);
return await _cache.GetDateTimeAsync(code_expiration_key);
}
}
}

View File

@@ -6,62 +6,44 @@ using EnvelopeGenerator.Application.Contracts;
using EnvelopeGenerator.Application.DTOs.Messaging;
using Microsoft.Extensions.Options;
namespace EnvelopeGenerator.Application.Services
namespace EnvelopeGenerator.Application.Services;
public class GtxMessagingService : IMessagingService
{
public class GtxMessagingService : IMessagingService
private readonly IHttpClientService<SmsParams> _smsClient;
private readonly SmsParams _smsParams;
private readonly IMapper _mapper;
private readonly ICodeGenerator _codeGen;
public string ServiceProvider { get; }
public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator)
{
private readonly IHttpClientService<SmsParams> _smsClient;
_smsClient = smsClient;
_smsParams = smsParamsOptions.Value;
_mapper = mapper;
ServiceProvider = GetType().Name.Replace("Service", string.Empty);
_codeGen = codeGenerator;
}
private readonly SmsParams _smsParams;
private readonly IMapper _mapper;
private readonly ICodeGenerator _codeGen;
private readonly IEnvelopeReceiverCache _erCache;
public string ServiceProvider { get; }
public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator, IEnvelopeReceiverCache envelopeReceiverCache)
public async Task<SmsResponse> SendSmsAsync(string recipient, string message)
{
return await _smsClient.FetchAsync(queryParams: new Dictionary<string, object?>()
{
_smsClient = smsClient;
_smsParams = smsParamsOptions.Value;
_mapper = mapper;
ServiceProvider = GetType().Name.Replace("Service", string.Empty);
_codeGen = codeGenerator;
_erCache = envelopeReceiverCache;
}
{ _smsParams.RecipientQueryParamName, recipient },
{ _smsParams.MessageQueryParamName, message }
})
.ThenAsync(res => res.Json<GtxMessagingResponse>())
.ThenAsync(_mapper.Map<SmsResponse>);
}
public async Task<SmsResponse> SendSmsAsync(string recipient, string message)
{
return await _smsClient.FetchAsync(queryParams: new Dictionary<string, object?>()
{
{ _smsParams.RecipientQueryParamName, recipient },
{ _smsParams.MessageQueryParamName, message }
})
.ThenAsync(res => res.Json<GtxMessagingResponse>())
.ThenAsync(_mapper.Map<SmsResponse>);
}
public async Task<SmsResponse> SendSmsCodeAsync(string recipient, string envelopeReceiverId)
{
var code = await _erCache.GetSmsCodeAsync(envelopeReceiverId);
if (code is null)
{
code = _codeGen.GenerateCode(_smsParams.CodeLength);
var expiration = await _erCache.SetSmsCodeAsync(envelopeReceiverId, code);
var res = await SendSmsAsync(recipient: recipient, message: code);
res.Expiration = expiration;
return res;
}
else
{
var code_expiration = await _erCache.GetSmsCodeExpirationAsync(envelopeReceiverId);
return code_expiration is null
? new() { Ok = false }
: new() { Ok = false, AllowedAt = code_expiration };
}
}
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);
}
}