feat(GtxMessagingService): Zwischenspeicherung für SMS-Code und Ablauf des SMS-Codes mittels Envelope-Receiver-ID hinzugefügt
- Erweiterungsmethode für Zeitcaching hinzugefügt.
This commit is contained in:
parent
2a963a1861
commit
cdec5485c6
@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Abstractions.Client;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Configurations.GtxMessaging
|
||||
{
|
||||
@ -20,5 +21,19 @@ namespace EnvelopeGenerator.Application.Configurations.GtxMessaging
|
||||
public string MessageQueryParamName { get; init; } = "text";
|
||||
|
||||
public int CodeLength { get; init; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cache key format for SMS codes.
|
||||
/// The placeholder {0} represents the envelopeReceiverId.
|
||||
/// </summary>
|
||||
public string CodeCacheKeyFormat { get; init; } = "sms-code-{0}";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cache expiration key format for SMS codes.
|
||||
/// The placeholder {0} represents the envelopeReceiverId.
|
||||
/// </summary>
|
||||
public string CodeExpirationCacheKeyFormat { get; init; } = "sms-code-expiration-{0}";
|
||||
|
||||
public TimeSpan CodeCacheValidityPeriod { get; init; } = new(0, 5, 0);
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,6 @@ namespace EnvelopeGenerator.Application.Contracts
|
||||
|
||||
Task<SmsResponse> SendSmsAsync(string recipient, string message);
|
||||
|
||||
Task<SmsResponse> SendSmsCodeAsync(string recipient);
|
||||
Task<SmsResponse> SendSmsCodeAsync(string recipient, string envelopeReceiverId);
|
||||
}
|
||||
}
|
||||
43
EnvelopeGenerator.Application/Extensions/CacheExtensions.cs
Normal file
43
EnvelopeGenerator.Application/Extensions/CacheExtensions.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Extensions
|
||||
{
|
||||
public static class CacheExtensions
|
||||
{
|
||||
public static Task SetLongAsync(this IDistributedCache cache, string key, long value, DistributedCacheEntryOptions? options = null)
|
||||
=> options is null
|
||||
? cache.SetAsync(key, BitConverter.GetBytes(value))
|
||||
: cache.SetAsync(key, BitConverter.GetBytes(value), options: options);
|
||||
|
||||
public static async Task<long?> GetLongAsync(this IDistributedCache cache, string key)
|
||||
{
|
||||
var value = await cache.GetAsync(key);
|
||||
return value is null ? null : BitConverter.ToInt64(value, 0);
|
||||
}
|
||||
|
||||
public static Task SetDateTimeAsync(this IDistributedCache cache, string key, DateTime value, DistributedCacheEntryOptions? options = null)
|
||||
=> cache.SetLongAsync(key: key, value: value.Ticks, options: options);
|
||||
|
||||
public static async Task<DateTime?> GetDateTimeAsync(this IDistributedCache cache, string key)
|
||||
{
|
||||
var value = await cache.GetAsync(key);
|
||||
return value is null ? null : new(BitConverter.ToInt64(value, 0));
|
||||
}
|
||||
|
||||
public static Task SetTimeSpanAsync(this IDistributedCache cache, string key, TimeSpan value, DistributedCacheEntryOptions? options = null)
|
||||
=> cache.SetLongAsync(key: key, value: value.Ticks, options: options);
|
||||
|
||||
public static async Task<TimeSpan?> GetTimeSpanAsync(this IDistributedCache cache, string key)
|
||||
{
|
||||
var value = await cache.GetAsync(key);
|
||||
return value is null ? null : new(BitConverter.ToInt64(value, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using DigitalData.Core.Client;
|
||||
using EnvelopeGenerator.Application.Configurations.GtxMessaging;
|
||||
|
||||
namespace EnvelopeGenerator.Application
|
||||
namespace EnvelopeGenerator.Application.Extensions
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
@ -1,6 +1,6 @@
|
||||
using EnvelopeGenerator.Domain.HttpResponse;
|
||||
|
||||
namespace EnvelopeGenerator.Application
|
||||
namespace EnvelopeGenerator.Application.Extensions
|
||||
{
|
||||
public static class MappingExtensions
|
||||
{
|
||||
@ -5,6 +5,7 @@ using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Domain.HttpResponse;
|
||||
|
||||
|
||||
@ -4,7 +4,9 @@ using DigitalData.Core.Client;
|
||||
using EnvelopeGenerator.Application.Configurations.GtxMessaging;
|
||||
using EnvelopeGenerator.Application.Contracts;
|
||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using EnvelopeGenerator.Domain.HttpResponse;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services
|
||||
@ -19,15 +21,21 @@ namespace EnvelopeGenerator.Application.Services
|
||||
|
||||
private readonly ICodeGenerator _codeGen;
|
||||
|
||||
private readonly IDistributedCache _cache;
|
||||
|
||||
public string ServiceProvider { get; }
|
||||
|
||||
public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator)
|
||||
private readonly DistributedCacheEntryOptions _codeCacheOptions;
|
||||
|
||||
public GtxMessagingService(IHttpClientService<SmsParams> smsClient, IOptions<SmsParams> smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator, IDistributedCache distributedCache)
|
||||
{
|
||||
_smsClient = smsClient;
|
||||
_smsParams = smsParamsOptions.Value;
|
||||
_mapper = mapper;
|
||||
ServiceProvider = GetType().Name.Replace("Service", string.Empty);
|
||||
_codeGen = codeGenerator;
|
||||
_cache = distributedCache;
|
||||
_codeCacheOptions = new() { AbsoluteExpirationRelativeToNow = smsParamsOptions.Value.CodeCacheValidityPeriod };
|
||||
}
|
||||
|
||||
public async Task<SmsResponse> SendSmsAsync(string recipient, string message)
|
||||
@ -41,10 +49,30 @@ namespace EnvelopeGenerator.Application.Services
|
||||
.ThenAsync(_mapper.Map<SmsResponse>);
|
||||
}
|
||||
|
||||
public async Task<SmsResponse> SendSmsCodeAsync(string recipient)
|
||||
public async Task<SmsResponse> SendSmsCodeAsync(string recipient, string envelopeReceiverId)
|
||||
{
|
||||
var code = _codeGen.GenerateCode(_smsParams.CodeLength);
|
||||
return await SendSmsAsync(recipient: recipient, message: code);
|
||||
var code_expiration_key = string.Format(_smsParams.CodeExpirationCacheKeyFormat, envelopeReceiverId);
|
||||
|
||||
var code_key = string.Format(_smsParams.CodeCacheKeyFormat, envelopeReceiverId);
|
||||
var code = await _cache.GetStringAsync(code_key);
|
||||
|
||||
if (code is null)
|
||||
{
|
||||
code = _codeGen.GenerateCode(_smsParams.CodeLength);
|
||||
|
||||
await _cache.SetStringAsync(code_key, code, _codeCacheOptions);
|
||||
|
||||
await _cache.SetDateTimeAsync(code_expiration_key, DateTime.Now + _smsParams.CodeCacheValidityPeriod, _codeCacheOptions);
|
||||
|
||||
return await SendSmsAsync(recipient: recipient, message: code);
|
||||
}
|
||||
else
|
||||
{
|
||||
var code_expiration = await _cache.GetDateTimeAsync(code_expiration_key);
|
||||
return code_expiration is null
|
||||
? new() { Ok = false }
|
||||
: new() { Ok = false, AllowedAt = code_expiration };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
using DigitalData.Core.API;
|
||||
using DigitalData.Core.Application;
|
||||
using DigitalData.UserManager.Application;
|
||||
using EnvelopeGenerator.Application;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using EnvelopeGenerator.Infrastructure;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
|
||||
@ -190,7 +190,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
//check if the user has phone is added
|
||||
if (er_secret.HasPhoneNumber)
|
||||
{
|
||||
var res = await _msgService.SendSmsCodeAsync(er_secret.PhoneNumber!);
|
||||
var res = await _msgService.SendSmsCodeAsync(er_secret.PhoneNumber!, envelopeReceiverId: envelopeReceiverId);
|
||||
if(res.Ok)
|
||||
return View("EnvelopeLocked").WithData("ViaSms", true);
|
||||
else
|
||||
|
||||
@ -15,6 +15,7 @@ using EnvelopeGenerator.Application;
|
||||
using DigitalData.EmailProfilerDispatcher;
|
||||
using EnvelopeGenerator.Infrastructure;
|
||||
using EnvelopeGenerator.Web.Sanitizers;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
|
||||
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||
logger.Info("Logging initialized!");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user