Refactor: Aktualisierung von APIs und Anwendungsschichten zur Umsetzung von Änderungen im Bereich

This commit is contained in:
Developer 02
2025-05-28 12:55:11 +02:00
parent c1d46b446a
commit 3c60f31050
91 changed files with 1712 additions and 535 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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)
{
}
}

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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)
{
}

View File

@@ -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)
);
}

View File

@@ -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 },
});
}
}

View File

@@ -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)
{
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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.");

View File

@@ -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?>()

View File

@@ -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();
}
}

View File

@@ -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)
{