Refactor: Aktualisierung von APIs und Anwendungsschichten zur Umsetzung von Änderungen im Bereich
This commit is contained in:
@@ -5,67 +5,123 @@ using OtpNet;
|
||||
using QRCoder;
|
||||
using System.Text;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Authenticator : IAuthenticator
|
||||
{
|
||||
public class Authenticator : IAuthenticator
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static Lazy<Authenticator> LazyStatic => new(() => new Authenticator(Options.Create<AuthenticatorParams>(new()), new QRCodeGenerator()));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static Authenticator Static => LazyStatic.Value;
|
||||
|
||||
private readonly AuthenticatorParams _params;
|
||||
|
||||
private readonly QRCodeGenerator _qrCodeGenerator;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="qrCodeGenerator"></param>
|
||||
public Authenticator(IOptions<AuthenticatorParams> options, QRCodeGenerator qrCodeGenerator)
|
||||
{
|
||||
public static Lazy<Authenticator> LazyStatic => new(() => new Authenticator(Options.Create<AuthenticatorParams>(new()), new QRCodeGenerator()));
|
||||
|
||||
public static Authenticator Static => LazyStatic.Value;
|
||||
|
||||
private readonly AuthenticatorParams _params;
|
||||
|
||||
private readonly QRCodeGenerator _qrCodeGenerator;
|
||||
|
||||
public Authenticator(IOptions<AuthenticatorParams> options, QRCodeGenerator qrCodeGenerator)
|
||||
{
|
||||
_params = options.Value;
|
||||
_qrCodeGenerator = qrCodeGenerator;
|
||||
}
|
||||
|
||||
public string GenerateCode(int length)
|
||||
{
|
||||
//TODO: Inject Random as a singleton to support multithreading to improve performance.
|
||||
Random random = new();
|
||||
|
||||
if (length <= 0)
|
||||
throw new ArgumentException("Password length must be greater than 0.");
|
||||
|
||||
var passwordBuilder = new StringBuilder(length);
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
passwordBuilder.Append(_params.CharPool[random.Next(_params.CharPool.Length)]);
|
||||
|
||||
return passwordBuilder.ToString();
|
||||
}
|
||||
|
||||
public string GenerateTotpSecretKey(int? length = null)
|
||||
=> Base32Encoding.ToString(KeyGeneration.GenerateRandomKey(length ?? _params.DefaultTotpSecretKeyLength));
|
||||
|
||||
public byte[] GenerateTotpQrCode(string userEmail, string secretKey, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null)
|
||||
{
|
||||
var url = string.Format(totpUrlFormat ?? _params.TotpUrlFormat,
|
||||
Uri.EscapeDataString(userEmail),
|
||||
Uri.EscapeDataString(secretKey),
|
||||
Uri.EscapeDataString(issuer ?? _params.TotpIssuer));
|
||||
using var qrCodeData = _qrCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
|
||||
using var qrCode = new BitmapByteQRCode(qrCodeData);
|
||||
return qrCode.GetGraphic(pixelsPerModule ?? _params.TotpQRPixelsPerModule);
|
||||
}
|
||||
|
||||
public byte[] GenerateTotpQrCode(string userEmail, int? length = null, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null)
|
||||
{
|
||||
return GenerateTotpQrCode(
|
||||
userEmail: userEmail,
|
||||
secretKey: GenerateTotpSecretKey(length: length),
|
||||
issuer: issuer,
|
||||
totpUrlFormat: totpUrlFormat,
|
||||
pixelsPerModule: pixelsPerModule);
|
||||
}
|
||||
|
||||
public string GenerateTotp(string secretKey, int step = 30) => new Totp(Base32Encoding.ToBytes(secretKey), step).ComputeTotp();
|
||||
|
||||
public bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null)
|
||||
=> new Totp(Base32Encoding.ToBytes(secretKey), step).VerifyTotp(totpCode, out _, window);
|
||||
_params = options.Value;
|
||||
_qrCodeGenerator = qrCodeGenerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public string GenerateCode(int length)
|
||||
{
|
||||
//TODO: Inject Random as a singleton to support multithreading to improve performance.
|
||||
Random random = new();
|
||||
|
||||
if (length <= 0)
|
||||
throw new ArgumentException("Password length must be greater than 0.");
|
||||
|
||||
var passwordBuilder = new StringBuilder(length);
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
passwordBuilder.Append(_params.CharPool[random.Next(_params.CharPool.Length)]);
|
||||
|
||||
return passwordBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public string GenerateTotpSecretKey(int? length = null)
|
||||
=> Base32Encoding.ToString(KeyGeneration.GenerateRandomKey(length ?? _params.DefaultTotpSecretKeyLength));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userEmail"></param>
|
||||
/// <param name="secretKey"></param>
|
||||
/// <param name="issuer"></param>
|
||||
/// <param name="totpUrlFormat"></param>
|
||||
/// <param name="pixelsPerModule"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] GenerateTotpQrCode(string userEmail, string secretKey, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null)
|
||||
{
|
||||
var url = string.Format(totpUrlFormat ?? _params.TotpUrlFormat,
|
||||
Uri.EscapeDataString(userEmail),
|
||||
Uri.EscapeDataString(secretKey),
|
||||
Uri.EscapeDataString(issuer ?? _params.TotpIssuer));
|
||||
using var qrCodeData = _qrCodeGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
|
||||
using var qrCode = new BitmapByteQRCode(qrCodeData);
|
||||
return qrCode.GetGraphic(pixelsPerModule ?? _params.TotpQRPixelsPerModule);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userEmail"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <param name="issuer"></param>
|
||||
/// <param name="totpUrlFormat"></param>
|
||||
/// <param name="pixelsPerModule"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] GenerateTotpQrCode(string userEmail, int? length = null, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null)
|
||||
{
|
||||
return GenerateTotpQrCode(
|
||||
userEmail: userEmail,
|
||||
secretKey: GenerateTotpSecretKey(length: length),
|
||||
issuer: issuer,
|
||||
totpUrlFormat: totpUrlFormat,
|
||||
pixelsPerModule: pixelsPerModule);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="secretKey"></param>
|
||||
/// <param name="step"></param>
|
||||
/// <returns></returns>
|
||||
public string GenerateTotp(string secretKey, int step = 30) => new Totp(Base32Encoding.ToBytes(secretKey), step).ComputeTotp();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="totpCode"></param>
|
||||
/// <param name="secretKey"></param>
|
||||
/// <param name="step"></param>
|
||||
/// <param name="window"></param>
|
||||
/// <returns></returns>
|
||||
public bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null)
|
||||
=> new Totp(Base32Encoding.ToBytes(secretKey), step).VerifyTotp(totpCode, out _, window);
|
||||
}
|
||||
@@ -1,26 +1,44 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class ConfigService : ReadService<IConfigRepository, ConfigDto, Config, int>, IConfigService
|
||||
{
|
||||
private static readonly Guid DefaultConfigCacheId = Guid.NewGuid();
|
||||
private static readonly Guid DefaultConfigCacheId = Guid.NewGuid();
|
||||
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ILogger<ConfigService> _logger;
|
||||
public ConfigService(IConfigRepository repository, IMapper mapper, IMemoryCache memoryCache, ILogger<ConfigService> logger) : base(repository, mapper)
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="memoryCache"></param>
|
||||
/// <param name="logger"></param>
|
||||
public ConfigService(IConfigRepository repository, IMapper mapper, IMemoryCache memoryCache, ILogger<ConfigService> logger) : base(repository, mapper)
|
||||
{
|
||||
_cache = memoryCache;
|
||||
_cache = memoryCache;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<ConfigDto>> ReadFirstAsync()
|
||||
{
|
||||
var config = await _repository.ReadFirstAsync();
|
||||
@@ -29,31 +47,36 @@ public class ConfigService : ReadService<IConfigRepository, ConfigDto, Config, i
|
||||
: Result.Success(_mapper.Map<ConfigDto>(config));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the default configuration asynchronously.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The configuration is cached in memory upon the first retrieval. If the configuration is updated,
|
||||
/// the application needs to be restarted for the changes to take effect as the memory cache will not be updated automatically.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous read operation. The task result contains the default configuration as a <see cref="ConfigDto"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown when the default configuration cannot be found.
|
||||
/// </exception>
|
||||
public async Task<ConfigDto> ReadDefaultAsync()
|
||||
/// <summary>
|
||||
/// Reads the default configuration asynchronously.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The configuration is cached in memory upon the first retrieval. If the configuration is updated,
|
||||
/// the application needs to be restarted for the changes to take effect as the memory cache will not be updated automatically.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous read operation. The task result contains the default configuration as a <see cref="ConfigDto"/>.
|
||||
/// </returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown when the default configuration cannot be found.
|
||||
/// </exception>
|
||||
public async Task<ConfigDto> ReadDefaultAsync()
|
||||
{
|
||||
var config = await _cache.GetOrCreateAsync(DefaultConfigCacheId, _ => ReadFirstAsync().ThenAsync(
|
||||
Success: config => config,
|
||||
Fail: (mssg, ntc) =>
|
||||
{
|
||||
_logger.LogNotice(ntc);
|
||||
throw new InvalidOperationException("Default configuration cannot find.");
|
||||
}));
|
||||
Success: config => config,
|
||||
Fail: (mssg, ntc) =>
|
||||
{
|
||||
_logger.LogNotice(ntc);
|
||||
throw new InvalidOperationException("Default configuration cannot find.");
|
||||
})
|
||||
);
|
||||
|
||||
return config!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<string> ReadDefaultSignatureHost() => (await ReadDefaultAsync()).SignatureHost;
|
||||
}
|
||||
@@ -7,8 +7,18 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class DocumentReceiverElementService : BasicCRUDService<IDocumentReceiverElementRepository, DocumentReceiverElementDto, DocumentReceiverElement, int>, IDocumentReceiverElementService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
[Obsolete("Use MediatR")]
|
||||
public DocumentReceiverElementService(IDocumentReceiverElementRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
|
||||
@@ -7,10 +7,19 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class DocumentStatusService : BasicCRUDService<IDocumentStatusRepository, DocumentStatusDto, DocumentStatus, int>, IDocumentStatusService
|
||||
{
|
||||
public DocumentStatusService(IDocumentStatusRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
[Obsolete("Use MediatR")]
|
||||
public DocumentStatusService(IDocumentStatusRepository repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,34 @@ using DigitalData.Core.Application;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using static EnvelopeGenerator.CommonServices.Constants;
|
||||
using DigitalData.Core.DTO;
|
||||
using static EnvelopeGenerator.Domain.Constants;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EmailTemplateService : BasicCRUDService<IEmailTemplateRepository, EmailTemplateDto, EmailTemplate, int>, IEmailTemplateService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public EmailTemplateService(IEmailTemplateRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<EmailTemplateDto>> ReadByNameAsync(EmailTemplateType type)
|
||||
{
|
||||
var temp = await _repository.ReadByNameAsync(type);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Application;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
@@ -8,8 +7,17 @@ using EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeCertificateService : BasicCRUDService<IEnvelopeCertificateRepository, EnvelopeCertificateDto, EnvelopeCertificate, int>, IEnvelopeCertificateService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public EnvelopeCertificateService(IEnvelopeCertificateRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
|
||||
@@ -7,8 +7,18 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeDocumentService : BasicCRUDService<IEnvelopeDocumentRepository, EnvelopeDocumentDto, EnvelopeDocument, int>, IEnvelopeDocumentService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
[Obsolete("Use MediatR")]
|
||||
public EnvelopeDocumentService(IEnvelopeDocumentRepository repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2,34 +2,68 @@
|
||||
using DigitalData.Core.Application;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using static EnvelopeGenerator.CommonServices.Constants;
|
||||
using DigitalData.Core.DTO;
|
||||
using static EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using DigitalData.Core.Application.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null) => await _repository.CountAsync(envelopeId: envelopeId, userReference: userReference, status: status);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="status"></param>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> HasStatus(EnvelopeStatus status, int envelopeId, string userReference) => await _repository.CountAsync(
|
||||
envelopeId: envelopeId,
|
||||
userReference: userReference,
|
||||
status: (int) status) > 0;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AccessCodeAlreadyRequested(int envelopeId, string userReference) => await _repository.CountAsync(
|
||||
envelopeId: envelopeId,
|
||||
userReference:userReference,
|
||||
status: (int) EnvelopeStatus.AccessCodeRequested) > 0;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> IsSigned(int envelopeId, string userReference) => await _repository.CountAsync(
|
||||
envelopeId: envelopeId,
|
||||
userReference: userReference,
|
||||
@@ -50,6 +84,16 @@ public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, En
|
||||
status: (int)EnvelopeStatus.DocumentRejected) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <param name="referenceType"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <param name="withSender"></param>
|
||||
/// <param name="withReceiver"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false)
|
||||
{
|
||||
var histDTOs = _mapper.Map<IEnumerable<EnvelopeHistoryDto>>(
|
||||
@@ -62,21 +106,40 @@ public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, En
|
||||
return referenceType is null ? histDTOs : histDTOs.Where(h => h.ReferenceType == referenceType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null) =>
|
||||
await ReadAsync(envelopeId: envelopeId, userReference: userReference, status: (int)EnvelopeStatus.DocumentRejected, withReceiver:true);
|
||||
|
||||
//TODO: use IQueryable in repository to incerease the performance
|
||||
public async Task<IEnumerable<ReceiverReadDto>> ReadRejectingReceivers(int envelopeId)
|
||||
{
|
||||
var envelopes = await ReadRejectedAsync(envelopeId);
|
||||
return envelopes is null
|
||||
? Enumerable.Empty<ReceiverReadDto>()
|
||||
: envelopes
|
||||
.Where(eh => eh?.Receiver != null)
|
||||
.Select(eh => eh.Receiver!);
|
||||
}
|
||||
//TODO: use IQueryable in repository to incerease the performance
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<ReceiverReadDto>> ReadRejectingReceivers(int envelopeId)
|
||||
{
|
||||
var envelopes = await ReadRejectedAsync(envelopeId);
|
||||
return envelopes is null
|
||||
? Enumerable.Empty<ReceiverReadDto>()
|
||||
: envelopes
|
||||
.Where(eh => eh?.Receiver != null)
|
||||
.Select(eh => eh.Receiver!);
|
||||
}
|
||||
|
||||
public async Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null) =>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeId"></param>
|
||||
/// <param name="userReference"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <param name="comment"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null) =>
|
||||
await CreateAsync(new ()
|
||||
{
|
||||
EnvelopeId = envelopeId,
|
||||
@@ -85,8 +148,8 @@ public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, En
|
||||
ActionDate = DateTime.Now,
|
||||
Comment = comment
|
||||
})
|
||||
.ThenAsync(
|
||||
Success: dto => Result.Success(dto.Id),
|
||||
Fail: (mssg, ntc) => Result.Fail<long>().Message(mssg).Notice(ntc)
|
||||
);
|
||||
.ThenAsync(
|
||||
Success: dto => Result.Success(dto.Id),
|
||||
Fail: (mssg, ntc) => Result.Fail<long>().Message(mssg).Notice(ntc)
|
||||
);
|
||||
}
|
||||
@@ -1,175 +1,213 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.CommonServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using static EnvelopeGenerator.CommonServices.Constants;
|
||||
using static EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Extensions;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.Configurations;
|
||||
using EnvelopeGenerator.Application.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Domain;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||
{
|
||||
public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||
private readonly IEmailTemplateService _tempService;
|
||||
private readonly IEnvelopeReceiverService _envRcvService;
|
||||
private readonly DispatcherParams _dConfig;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Dictionary<string, string> _placeholders;
|
||||
private readonly IAuthenticator _authenticator;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="tempService"></param>
|
||||
/// <param name="envelopeReceiverService"></param>
|
||||
/// <param name="dispatcherConfigOptions"></param>
|
||||
/// <param name="configService"></param>
|
||||
/// <param name="mailConfig"></param>
|
||||
/// <param name="authenticator"></param>
|
||||
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, IAuthenticator authenticator) : base(repository, mapper)
|
||||
{
|
||||
private readonly IEmailTemplateService _tempService;
|
||||
private readonly IEnvelopeReceiverService _envRcvService;
|
||||
private readonly DispatcherParams _dConfig;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Dictionary<string, string> _placeholders;
|
||||
private readonly IAuthenticator _authenticator;
|
||||
_tempService = tempService;
|
||||
_envRcvService = envelopeReceiverService;
|
||||
_dConfig = dispatcherConfigOptions.Value;
|
||||
_configService = configService;
|
||||
_placeholders = mailConfig.Value.Placeholders;
|
||||
_authenticator = authenticator;
|
||||
}
|
||||
|
||||
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, IAuthenticator authenticator) : base(repository, mapper)
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
||||
{
|
||||
if (accessCode is not null)
|
||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||
|
||||
if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||
{
|
||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
{
|
||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||
{
|
||||
_tempService = tempService;
|
||||
_envRcvService = envelopeReceiverService;
|
||||
_dConfig = dispatcherConfigOptions.Value;
|
||||
_configService = configService;
|
||||
_placeholders = mailConfig.Value.Placeholders;
|
||||
_authenticator = authenticator;
|
||||
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMailAsync(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||
var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
||||
{
|
||||
if (accessCode is not null)
|
||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="tempType"></param>
|
||||
/// <param name="optionalPlaceholders"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, EmailTemplateType tempType, Dictionary<string, object>? optionalPlaceholders = null)
|
||||
{
|
||||
var tempSerResult = await _tempService.ReadByNameAsync(tempType);
|
||||
if (tempSerResult.IsFailed)
|
||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, DigitalData.Core.Abstraction.Application.DTO.Flag.DataIntegrityIssue, $"The email cannot send because '{tempType}' template cannot found.");
|
||||
var temp = tempSerResult.Data;
|
||||
|
||||
if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||
{
|
||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
var mail = new EmailOutCreateDto()
|
||||
{
|
||||
EmailAddress = dto.Receiver!.EmailAddress,
|
||||
EmailSubj = temp.Subject,
|
||||
EmailBody = temp.Body,
|
||||
//email_type = envelope_status,
|
||||
//message = envelope_message,
|
||||
ReferenceId = dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||
ReferenceString = dto!.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||
//receiver_name = receiver.name,
|
||||
//receiver_access_code = receiver.access_code,
|
||||
//sender_adress = envelope.user.email,
|
||||
//sender_name = envelope.user.full_name,
|
||||
//envelope_title = envelope.title,
|
||||
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||
SendingProfile = _dConfig.SendingProfile,
|
||||
EntityId = null,
|
||||
WfId = (int) EnvelopeStatus.MessageAccessCodeSent,
|
||||
WfReference = null,
|
||||
AddedWho = _dConfig.AddedWho,
|
||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||
};
|
||||
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
{
|
||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||
{
|
||||
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMailAsync(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||
var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
|
||||
return _placeholders;
|
||||
}
|
||||
//get acccess code
|
||||
var acResult = await _envRcvService.ReadAccessCodeByIdAsync(envelopeId: dto.EnvelopeId, receiverId: dto.ReceiverId);
|
||||
if (acResult.IsFailed)
|
||||
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
||||
var accessCode = acResult.Data;
|
||||
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, EmailTemplateType tempType, Dictionary<string, object>? optionalPlaceholders = null)
|
||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||
|
||||
// Add optional place holders.
|
||||
if (optionalPlaceholders is not null)
|
||||
foreach (var oph in optionalPlaceholders)
|
||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||
|
||||
//TODO: remove the requirement to add the models using reflections
|
||||
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
||||
dto, dto.Envelope.User!, dto.Envelope);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="optionalPlaceholders"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary<string, object>? optionalPlaceholders = null)
|
||||
{
|
||||
var tempSerResult = await _tempService.ReadByNameAsync(EmailTemplateType.DocumentShared);
|
||||
if (tempSerResult.IsFailed)
|
||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{Constants.EmailTemplateType.DocumentShared}' template cannot found.");
|
||||
var temp = tempSerResult.Data;
|
||||
|
||||
var mail = new EmailOutCreateDto()
|
||||
{
|
||||
var tempSerResult = await _tempService.ReadByNameAsync(tempType);
|
||||
if (tempSerResult.IsFailed)
|
||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{tempType}' template cannot found.");
|
||||
var temp = tempSerResult.Data;
|
||||
EmailAddress = dto.ReceiverMail,
|
||||
EmailSubj = temp.Subject,
|
||||
EmailBody = temp.Body,
|
||||
//TODO: remove int casting when all
|
||||
ReferenceId = (int) dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||
ReferenceString = dto.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||
//receiver_name = receiver.name,
|
||||
//receiver_access_code = receiver.access_code,
|
||||
//sender_adress = envelope.user.email,
|
||||
//sender_name = envelope.user.full_name,
|
||||
//envelope_title = envelope.title,
|
||||
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||
SendingProfile = _dConfig.SendingProfile,
|
||||
EntityId = null,
|
||||
WfId = (int)EnvelopeStatus.EnvelopeShared,
|
||||
WfReference = null,
|
||||
AddedWho = _dConfig.AddedWho,
|
||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||
};
|
||||
|
||||
var mail = new EmailOutCreateDto()
|
||||
{
|
||||
EmailAddress = dto.Receiver!.EmailAddress,
|
||||
EmailSubj = temp.Subject,
|
||||
EmailBody = temp.Body,
|
||||
//email_type = envelope_status,
|
||||
//message = envelope_message,
|
||||
ReferenceId = dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||
ReferenceString = dto!.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||
//receiver_name = receiver.name,
|
||||
//receiver_access_code = receiver.access_code,
|
||||
//sender_adress = envelope.user.email,
|
||||
//sender_name = envelope.user.full_name,
|
||||
//envelope_title = envelope.title,
|
||||
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||
SendingProfile = _dConfig.SendingProfile,
|
||||
EntityId = null,
|
||||
WfId = (int) EnvelopeStatus.MessageAccessCodeSent,
|
||||
WfReference = null,
|
||||
AddedWho = _dConfig.AddedWho,
|
||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||
};
|
||||
var placeholders = await CreatePlaceholders(readOnlyDto: dto);
|
||||
|
||||
//get acccess code
|
||||
var acResult = await _envRcvService.ReadAccessCodeByIdAsync(envelopeId: dto.EnvelopeId, receiverId: dto.ReceiverId);
|
||||
if (acResult.IsFailed)
|
||||
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
||||
var accessCode = acResult.Data;
|
||||
|
||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||
// Add optional place holders.
|
||||
if (optionalPlaceholders is not null)
|
||||
foreach (var oph in optionalPlaceholders)
|
||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||
|
||||
// Add optional place holders.
|
||||
if (optionalPlaceholders is not null)
|
||||
foreach (var oph in optionalPlaceholders)
|
||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
||||
}
|
||||
|
||||
//TODO: remove the requirement to add the models using reflections
|
||||
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
||||
dto, dto.Envelope.User!, dto.Envelope);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: EmailTemplateType.DocumentAccessCodeReceived);
|
||||
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary<string, object>? optionalPlaceholders = null)
|
||||
{
|
||||
var tempSerResult = await _tempService.ReadByNameAsync(EmailTemplateType.DocumentShared);
|
||||
if (tempSerResult.IsFailed)
|
||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{Constants.EmailTemplateType.DocumentShared}' template cannot found.");
|
||||
var temp = tempSerResult.Data;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public Task<DataResult<int>> SendTFAQrCodeAsync(EnvelopeReceiverDto dto)
|
||||
{
|
||||
// Check if receiver or secret key is null
|
||||
if (dto.Receiver is null)
|
||||
throw new ArgumentNullException(nameof(dto), $"TFA Qr Code cannot sent. Receiver information is missing. Envelope receiver dto is {JsonConvert.SerializeObject(dto)}");
|
||||
if (dto.Receiver.TotpSecretkey is null)
|
||||
throw new ArgumentNullException(nameof(dto), $"TFA Qr Code cannot sent. Receiver.TotpSecretKey is null. Envelope receiver dto is {JsonConvert.SerializeObject(dto)}");
|
||||
|
||||
var mail = new EmailOutCreateDto()
|
||||
{
|
||||
EmailAddress = dto.ReceiverMail,
|
||||
EmailSubj = temp.Subject,
|
||||
EmailBody = temp.Body,
|
||||
//TODO: remove int casting when all
|
||||
ReferenceId = (int) dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||
ReferenceString = dto.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||
//receiver_name = receiver.name,
|
||||
//receiver_access_code = receiver.access_code,
|
||||
//sender_adress = envelope.user.email,
|
||||
//sender_name = envelope.user.full_name,
|
||||
//envelope_title = envelope.title,
|
||||
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||
SendingProfile = _dConfig.SendingProfile,
|
||||
EntityId = null,
|
||||
WfId = (int)EnvelopeStatus.EnvelopeShared,
|
||||
WfReference = null,
|
||||
AddedWho = _dConfig.AddedWho,
|
||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||
};
|
||||
|
||||
var placeholders = await CreatePlaceholders(readOnlyDto: dto);
|
||||
|
||||
// Add optional place holders.
|
||||
if (optionalPlaceholders is not null)
|
||||
foreach (var oph in optionalPlaceholders)
|
||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||
|
||||
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
||||
}
|
||||
|
||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: EmailTemplateType.DocumentAccessCodeReceived);
|
||||
|
||||
public Task<DataResult<int>> SendTFAQrCodeAsync(EnvelopeReceiverDto dto)
|
||||
{
|
||||
// Check if receiver or secret key is null
|
||||
if (dto.Receiver is null)
|
||||
throw new ArgumentNullException(nameof(dto), $"TFA Qr Code cannot sent. Receiver information is missing. Envelope receiver dto is {JsonConvert.SerializeObject(dto)}");
|
||||
if (dto.Receiver.TotpSecretkey is null)
|
||||
throw new ArgumentNullException(nameof(dto), $"TFA Qr Code cannot sent. Receiver.TotpSecretKey is null. Envelope receiver dto is {JsonConvert.SerializeObject(dto)}");
|
||||
|
||||
var totp_qr_64 = _authenticator.GenerateTotpQrCode(userEmail: dto.Receiver.EmailAddress, secretKey: dto.Receiver.TotpSecretkey).ToBase64String();
|
||||
return SendAsync(dto, EmailTemplateType.TotpSecret, new()
|
||||
{
|
||||
{"[TFA_QR_CODE]", totp_qr_64 },
|
||||
});
|
||||
}
|
||||
var totp_qr_64 = _authenticator.GenerateTotpQrCode(userEmail: dto.Receiver.EmailAddress, secretKey: dto.Receiver.TotpSecretkey).ToBase64String();
|
||||
return SendAsync(dto, EmailTemplateType.TotpSecret, new()
|
||||
{
|
||||
{"[TFA_QR_CODE]", totp_qr_64 },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,17 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
@@ -8,13 +8,29 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeService : BasicCRUDService<IEnvelopeRepository, EnvelopeDto, Envelope, int>, IEnvelopeService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public EnvelopeService(IEnvelopeRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="documents"></param>
|
||||
/// <param name="history"></param>
|
||||
/// <param name="documentReceiverElement"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<IEnumerable<EnvelopeDto>>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false)
|
||||
{
|
||||
var envelopes = await _repository.ReadAllWithAsync(documents: documents, history: history, documentReceiverElement: documentReceiverElement);
|
||||
@@ -22,6 +38,16 @@ public class EnvelopeService : BasicCRUDService<IEnvelopeRepository, EnvelopeDto
|
||||
return Result.Success(readDto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="withDocuments"></param>
|
||||
/// <param name="withHistory"></param>
|
||||
/// <param name="withDocumentReceiverElement"></param>
|
||||
/// <param name="withUser"></param>
|
||||
/// <param name="withAll"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<EnvelopeDto>> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false)
|
||||
{
|
||||
var envelope = await _repository.ReadByUuidAsync(uuid: uuid, withDocuments: withDocuments, withHistory: withHistory, withDocumentReceiverElement: withDocumentReceiverElement, withUser:withUser, withAll:withAll);
|
||||
@@ -33,6 +59,14 @@ public class EnvelopeService : BasicCRUDService<IEnvelopeRepository, EnvelopeDto
|
||||
return Result.Success(readDto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="min_status"></param>
|
||||
/// <param name="max_status"></param>
|
||||
/// <param name="ignore_statuses"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<IEnumerable<EnvelopeDto>>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses)
|
||||
{
|
||||
var users = await _repository.ReadByUserAsync(userId: userId, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses);
|
||||
|
||||
@@ -8,6 +8,9 @@ using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EnvelopeSmsHandler : IEnvelopeSmsHandler
|
||||
{
|
||||
private readonly ISmsSender _sender;
|
||||
@@ -18,6 +21,13 @@ public class EnvelopeSmsHandler : IEnvelopeSmsHandler
|
||||
|
||||
private readonly IAuthenticator _authenticator;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="totpSmsParamsOptions"></param>
|
||||
/// <param name="distributedCache"></param>
|
||||
/// <param name="authenticator"></param>
|
||||
public EnvelopeSmsHandler(ISmsSender sender, IOptions<TotpSmsParams> totpSmsParamsOptions, IDistributedCache distributedCache, IAuthenticator authenticator)
|
||||
{
|
||||
_sender = sender;
|
||||
@@ -49,6 +59,12 @@ public class EnvelopeSmsHandler : IEnvelopeSmsHandler
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="totpCode"></param>
|
||||
/// <param name="secretKey"></param>
|
||||
/// <returns></returns>
|
||||
public bool VerifyTotp(string totpCode, string secretKey) => _authenticator
|
||||
.VerifyTotp(totpCode, secretKey, _totpSmsParams.TotpStep, _totpSmsParams.TotpVerificationWindow);
|
||||
}
|
||||
@@ -4,24 +4,38 @@ using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class EnvelopeTypeService : BasicCRUDService<IEnvelopeTypeRepository, EnvelopeTypeDto, EnvelopeType, int>, IEnvelopeTypeService
|
||||
{
|
||||
private static readonly Guid CacheKey = Guid.NewGuid();
|
||||
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
/// <param name="cache"></param>
|
||||
public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper, IMemoryCache cache)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override async Task<DataResult<IEnumerable<EnvelopeTypeDto>>> ReadAllAsync()
|
||||
=> await _cache.GetOrCreateAsync(CacheKey, async entry => await base.ReadAllAsync())
|
||||
?? Result.Fail<IEnumerable<EnvelopeTypeDto>>().Notice(LogLevel.Error, Flag.NotFound, "No cached envelope types are available in the database. If you have added any envelope types after the server started, please restart the server.");
|
||||
|
||||
@@ -9,6 +9,9 @@ using Microsoft.Extensions.Options;
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
//TODO: move to DigitalData.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class GTXSmsSender : ISmsSender
|
||||
{
|
||||
private readonly IHttpClientService<GtxMessagingParams> _smsClient;
|
||||
@@ -17,8 +20,17 @@ public class GTXSmsSender : ISmsSender
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ServiceProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="smsClient"></param>
|
||||
/// <param name="smsParamsOptions"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public GTXSmsSender(IHttpClientService<GtxMessagingParams> smsClient, IOptions<GtxMessagingParams> smsParamsOptions, IMapper mapper)
|
||||
{
|
||||
_smsClient = smsClient;
|
||||
@@ -27,6 +39,12 @@ public class GTXSmsSender : ISmsSender
|
||||
ServiceProvider = GetType().Name.Replace("Service", string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="recipient"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<SmsResponse> SendSmsAsync(string recipient, string message)
|
||||
{
|
||||
return await _smsClient.FetchAsync(queryParams: new Dictionary<string, object?>()
|
||||
|
||||
@@ -3,19 +3,33 @@ using DigitalData.Core.Application;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDto, ReceiverReadDto, Receiver, int>, IReceiverService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public ReceiverService(IReceiverRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="emailAddress"></param>
|
||||
/// <param name="signature"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null)
|
||||
{
|
||||
var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature);
|
||||
@@ -26,6 +40,12 @@ public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDt
|
||||
return Result.Success(_mapper.Map<ReceiverReadDto>(rcv));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="emailAddress"></param>
|
||||
/// <param name="signature"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Result> DeleteByAsync(string? emailAddress = null, string? signature = null)
|
||||
{
|
||||
var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature);
|
||||
@@ -35,16 +55,4 @@ public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDt
|
||||
|
||||
return await _repository.DeleteAsync(rcv) ? Result.Success() : Result.Fail();
|
||||
}
|
||||
|
||||
public virtual async Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto)
|
||||
{
|
||||
var val = await _repository.ReadByIdAsync(updateDto.GetId<int>());
|
||||
if (val == null)
|
||||
{
|
||||
return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.GetIdOrDefault<int>()} is not found in update process of {GetType()} entity.");
|
||||
}
|
||||
|
||||
var entity = _mapper.Map(updateDto, val);
|
||||
return (await _repository.UpdateAsync(entity)) ? Result.Success() : Result.Fail();
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,17 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use MediatR")]
|
||||
public class UserReceiverService : BasicCRUDService<IUserReceiverRepository, UserReceiverDto, UserReceiver, int>, IUserReceiverService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public UserReceiverService(IUserReceiverRepository repository, IMapper mapper)
|
||||
: base(repository, mapper)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user