diff --git a/EnvelopeGenerator.Application/Configurations/DbTriggerParams.cs b/EnvelopeGenerator.Application/Configurations/DbTriggerParams.cs new file mode 100644 index 00000000..2fd64896 --- /dev/null +++ b/EnvelopeGenerator.Application/Configurations/DbTriggerParams.cs @@ -0,0 +1,5 @@ +namespace EnvelopeGenerator.Application.Configurations; + +public class DbTriggerParams : Dictionary> +{ +} diff --git a/EnvelopeGenerator.Application/Contracts/IAuthenticator.cs b/EnvelopeGenerator.Application/Contracts/IAuthenticator.cs deleted file mode 100644 index 1e3cf1a0..00000000 --- a/EnvelopeGenerator.Application/Contracts/IAuthenticator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using OtpNet; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IAuthenticator - { - string GenerateCode(int length); - - string GenerateTotpSecretKey(int? length = null); - - byte[] GenerateTotpQrCode(string userEmail, string secretKey, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null); - - byte[] GenerateTotpQrCode(string userEmail, int? length = null, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null); - - string GenerateTotp(string secretKey, int step = 30); - - bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IConfigService.cs b/EnvelopeGenerator.Application/Contracts/IConfigService.cs deleted file mode 100644 index 80702fac..00000000 --- a/EnvelopeGenerator.Application/Contracts/IConfigService.cs +++ /dev/null @@ -1,17 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IConfigService : IReadService - { - Task> ReadFirstAsync(); - - Task ReadDefaultAsync(); - - Task ReadDefaultSignatureHost(); - - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs deleted file mode 100644 index 79dfe781..00000000 --- a/EnvelopeGenerator.Application/Contracts/IDocumentReceiverElementService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IDocumentReceiverElementService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs b/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs deleted file mode 100644 index 39852d9c..00000000 --- a/EnvelopeGenerator.Application/Contracts/IDocumentStatusService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IDocumentStatusService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs b/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs deleted file mode 100644 index dc1a8b39..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEmailTemplateService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; -using static EnvelopeGenerator.Common.Constants; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEmailTemplateService : IBasicCRUDService - { - Task> ReadByNameAsync(EmailTemplateType type); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs deleted file mode 100644 index 9f0238a0..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeCertificateService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeCertificateService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeDocumentService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeDocumentService.cs deleted file mode 100644 index 9599644d..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeDocumentService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeDocumentService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs deleted file mode 100644 index b72bdec2..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs +++ /dev/null @@ -1,28 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; -using EnvelopeGenerator.Application.DTOs.Receiver; -using EnvelopeGenerator.Domain.Entities; -using static EnvelopeGenerator.Common.Constants; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeHistoryService : ICRUDService - { - Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null); - - Task AccessCodeAlreadyRequested(int envelopeId, string userReference); - - Task IsSigned(int envelopeId, string userReference); - - Task IsRejected(int envelopeId, string? userReference = null); - - Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false); - - Task> ReadRejectedAsync(int envelopeId, string? userReference = null); - - Task> ReadRejectingReceivers(int envelopeId); - - Task> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs deleted file mode 100644 index 14d94057..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using DigitalData.Core.DTO; -using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; -using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; -using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; -using EnvelopeGenerator.Common; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeMailService : IEmailOutService - { - Task> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType, Dictionary? optionalPlaceholders = null); - - Task> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary? optionalPlaceholders = null); - - Task> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto); - - Task> SendTFAQrCodeAsync(EnvelopeReceiverDto envelopeReceiverDto); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverReadOnlyService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverReadOnlyService.cs deleted file mode 100644 index f657215c..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverReadOnlyService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeReceiverReadOnlyService : ICRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs deleted file mode 100644 index f22fde28..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs +++ /dev/null @@ -1,38 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; -using EnvelopeGenerator.Application.DTOs.Messaging; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeReceiverService : IBasicCRUDService - { - - Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true); - - Task>> ReadAccessCodeByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true); - - Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true); - - Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); - - Task> ReadWithSecretByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); - - Task> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); - - Task> ReadAccessCodeByIdAsync(int envelopeId, int receiverId); - - Task> VerifyAccessCodeAsync(string uuid, string signature, string accessCode); - - Task> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode); - - Task> IsExisting(string envelopeReceiverId); - - Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); - - Task> ReadLastUsedReceiverNameByMail(string mail); - - Task> SendSmsAsync(string envelopeReceiverId, string message); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs deleted file mode 100644 index a8cfbab1..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs +++ /dev/null @@ -1,16 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeService : IBasicCRUDService - { - Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); - - Task> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); - - Task>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[]ignore_statuses); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs deleted file mode 100644 index cfa434a3..00000000 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeTypeService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IEnvelopeTypeService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IReceiverService.cs deleted file mode 100644 index c474363b..00000000 --- a/EnvelopeGenerator.Application/Contracts/IReceiverService.cs +++ /dev/null @@ -1,17 +0,0 @@ -using DigitalData.Core.Abstractions; -using DigitalData.Core.Abstractions.Application; -using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs.Receiver; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IReceiverService : ICRUDService - { - Task> ReadByAsync(string? emailAddress = null, string? signature = null); - - Task DeleteByAsync(string? emailAddress = null, string? signature = null); - - Task UpdateAsync(TUpdateDto updateDto) where TUpdateDto : IUnique; - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs deleted file mode 100644 index 9c6f19fa..00000000 --- a/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Application; -using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Application.Contracts -{ - public interface IUserReceiverService : IBasicCRUDService - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IConfigRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IConfigRepository.cs new file mode 100644 index 00000000..a2969fdd --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IConfigRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IConfigRepository : ICRUDRepository +{ + Task ReadFirstAsync(); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentReceiverElementRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentReceiverElementRepository.cs new file mode 100644 index 00000000..e01a9a0f --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentReceiverElementRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IDocumentReceiverElementRepository : ICRUDRepository +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentStatusRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentStatusRepository.cs new file mode 100644 index 00000000..53d0f8e6 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IDocumentStatusRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IDocumentStatusRepository : ICRUDRepository +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs new file mode 100644 index 00000000..eee57f90 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs @@ -0,0 +1,10 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; +using static EnvelopeGenerator.Common.Constants; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEmailTemplateRepository : ICRUDRepository +{ + Task ReadByNameAsync(EmailTemplateType type); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeCertificateRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeCertificateRepository.cs new file mode 100644 index 00000000..0ab44c65 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeCertificateRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeCertificateRepository : ICRUDRepository +{ +} diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeDocumentRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeDocumentRepository.cs new file mode 100644 index 00000000..f05cdfc5 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeDocumentRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeDocumentRepository : ICRUDRepository +{ +} diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeHistoryRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeHistoryRepository.cs new file mode 100644 index 00000000..e4ce226c --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeHistoryRepository.cs @@ -0,0 +1,11 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeHistoryRepository : ICRUDRepository +{ + Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null); + + Task> ReadAsync(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverReadOnlyRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverReadOnlyRepository.cs new file mode 100644 index 00000000..f10f1f73 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverReadOnlyRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeReceiverReadOnlyRepository : ICRUDRepository +{ +} diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverRepository.cs new file mode 100644 index 00000000..e8cf1659 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeReceiverRepository.cs @@ -0,0 +1,25 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeReceiverRepository : ICRUDRepository +{ + Task> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true); + + Task> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true); + + Task ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); + + Task ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true); + + Task CountAsync(string uuid, string signature); + + Task ReadByIdAsync(int envelopeId, int receiverId, bool readOnly = true); + + Task ReadAccessCodeByIdAsync(int envelopeId, int receiverId, bool readOnly = true); + + Task> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); + + Task ReadLastByReceiver(string email); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeRepository.cs new file mode 100644 index 00000000..88ba257c --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeRepository.cs @@ -0,0 +1,13 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeRepository : ICRUDRepository +{ + Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); + + Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); + + Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeTypeRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeTypeRepository.cs new file mode 100644 index 00000000..e54b7697 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEnvelopeTypeRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IEnvelopeTypeRepository : ICRUDRepository +{ +} diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IReceiverRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IReceiverRepository.cs new file mode 100644 index 00000000..3095d488 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IReceiverRepository.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IReceiverRepository : ICRUDRepository +{ + Task ReadByAsync(string? emailAddress = null, string? signature = null); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IUserReceiverRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IUserReceiverRepository.cs new file mode 100644 index 00000000..d0181151 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IUserReceiverRepository.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Infrastructure; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Repositories; + +public interface IUserReceiverRepository : ICRUDRepository +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IAuthenticator.cs b/EnvelopeGenerator.Application/Contracts/Services/IAuthenticator.cs new file mode 100644 index 00000000..419c2e6d --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IAuthenticator.cs @@ -0,0 +1,18 @@ +using OtpNet; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IAuthenticator +{ + string GenerateCode(int length); + + string GenerateTotpSecretKey(int? length = null); + + byte[] GenerateTotpQrCode(string userEmail, string secretKey, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null); + + byte[] GenerateTotpQrCode(string userEmail, int? length = null, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null); + + string GenerateTotp(string secretKey, int step = 30); + + bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IConfigService.cs b/EnvelopeGenerator.Application/Contracts/Services/IConfigService.cs new file mode 100644 index 00000000..fe0569e0 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IConfigService.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IConfigService : IReadService +{ + Task> ReadFirstAsync(); + + Task ReadDefaultAsync(); + + Task ReadDefaultSignatureHost(); + +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IDocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Contracts/Services/IDocumentReceiverElementService.cs new file mode 100644 index 00000000..cc398a27 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IDocumentReceiverElementService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IDocumentReceiverElementService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IDocumentStatusService.cs b/EnvelopeGenerator.Application/Contracts/Services/IDocumentStatusService.cs new file mode 100644 index 00000000..2ba09003 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IDocumentStatusService.cs @@ -0,0 +1,8 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IDocumentStatusService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEmailTemplateService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEmailTemplateService.cs new file mode 100644 index 00000000..6a7f8ec2 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEmailTemplateService.cs @@ -0,0 +1,12 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; +using static EnvelopeGenerator.Common.Constants; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEmailTemplateService : IBasicCRUDService +{ + Task> ReadByNameAsync(EmailTemplateType type); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeCertificateService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeCertificateService.cs new file mode 100644 index 00000000..279e6aae --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeCertificateService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeCertificateService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeDocumentService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeDocumentService.cs new file mode 100644 index 00000000..3463b6c9 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeDocumentService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeDocumentService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeHistoryService.cs new file mode 100644 index 00000000..04f7ed9e --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeHistoryService.cs @@ -0,0 +1,27 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; +using EnvelopeGenerator.Application.DTOs.Receiver; +using EnvelopeGenerator.Domain.Entities; +using static EnvelopeGenerator.Common.Constants; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeHistoryService : ICRUDService +{ + Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null); + + Task AccessCodeAlreadyRequested(int envelopeId, string userReference); + + Task IsSigned(int envelopeId, string userReference); + + Task IsRejected(int envelopeId, string? userReference = null); + + Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false); + + Task> ReadRejectedAsync(int envelopeId, string? userReference = null); + + Task> ReadRejectingReceivers(int envelopeId); + + Task> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeMailService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeMailService.cs new file mode 100644 index 00000000..ee35c235 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeMailService.cs @@ -0,0 +1,18 @@ +using DigitalData.Core.DTO; +using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; +using EnvelopeGenerator.Common; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeMailService : IEmailOutService +{ + Task> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType, Dictionary? optionalPlaceholders = null); + + Task> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary? optionalPlaceholders = null); + + Task> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto); + + Task> SendTFAQrCodeAsync(EnvelopeReceiverDto envelopeReceiverDto); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverReadOnlyService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverReadOnlyService.cs new file mode 100644 index 00000000..2e4cee14 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverReadOnlyService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeReceiverReadOnlyService : ICRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverService.cs new file mode 100644 index 00000000..14d4f3d1 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeReceiverService.cs @@ -0,0 +1,37 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using EnvelopeGenerator.Application.DTOs.Messaging; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeReceiverService : IBasicCRUDService +{ + + Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true); + + Task>> ReadAccessCodeByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true); + + Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true); + + Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); + + Task> ReadWithSecretByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); + + Task> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); + + Task> ReadAccessCodeByIdAsync(int envelopeId, int receiverId); + + Task> VerifyAccessCodeAsync(string uuid, string signature, string accessCode); + + Task> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode); + + Task> IsExisting(string envelopeReceiverId); + + Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); + + Task> ReadLastUsedReceiverNameByMail(string mail); + + Task> SendSmsAsync(string envelopeReceiverId, string message); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeService.cs new file mode 100644 index 00000000..1435f326 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeService.cs @@ -0,0 +1,15 @@ +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeService : IBasicCRUDService +{ + Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); + + Task> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); + + Task>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeSmsHandler.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeSmsHandler.cs similarity index 91% rename from EnvelopeGenerator.Application/Contracts/IEnvelopeSmsHandler.cs rename to EnvelopeGenerator.Application/Contracts/Services/IEnvelopeSmsHandler.cs index 746988ab..c9ca45ba 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeSmsHandler.cs +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeSmsHandler.cs @@ -1,7 +1,7 @@ using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.DTOs.Messaging; -namespace EnvelopeGenerator.Application.Contracts; +namespace EnvelopeGenerator.Application.Contracts.Services; public interface IEnvelopeSmsHandler { diff --git a/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeTypeService.cs b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeTypeService.cs new file mode 100644 index 00000000..ef8f721b --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IEnvelopeTypeService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IEnvelopeTypeService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/Services/IReceiverService.cs b/EnvelopeGenerator.Application/Contracts/Services/IReceiverService.cs new file mode 100644 index 00000000..70702642 --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IReceiverService.cs @@ -0,0 +1,16 @@ +using DigitalData.Core.Abstractions; +using DigitalData.Core.Abstractions.Application; +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs.Receiver; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IReceiverService : ICRUDService +{ + Task> ReadByAsync(string? emailAddress = null, string? signature = null); + + Task DeleteByAsync(string? emailAddress = null, string? signature = null); + + Task UpdateAsync(TUpdateDto updateDto) where TUpdateDto : IUnique; +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/ISmsSender.cs b/EnvelopeGenerator.Application/Contracts/Services/ISmsSender.cs similarity index 78% rename from EnvelopeGenerator.Application/Contracts/ISmsSender.cs rename to EnvelopeGenerator.Application/Contracts/Services/ISmsSender.cs index 21fb28bf..7c437660 100644 --- a/EnvelopeGenerator.Application/Contracts/ISmsSender.cs +++ b/EnvelopeGenerator.Application/Contracts/Services/ISmsSender.cs @@ -1,6 +1,6 @@ using EnvelopeGenerator.Application.DTOs.Messaging; -namespace EnvelopeGenerator.Application.Contracts; +namespace EnvelopeGenerator.Application.Contracts.Services; //TODO: move to DigitalData.Core public interface ISmsSender diff --git a/EnvelopeGenerator.Application/Contracts/Services/IUserReceiverService.cs b/EnvelopeGenerator.Application/Contracts/Services/IUserReceiverService.cs new file mode 100644 index 00000000..e2b7db9a --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/Services/IUserReceiverService.cs @@ -0,0 +1,9 @@ +using DigitalData.Core.Abstractions.Application; +using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.Services; + +public interface IUserReceiverService : IBasicCRUDService +{ +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index c16b447f..c8b0b4a5 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -26,8 +26,8 @@ + - diff --git a/EnvelopeGenerator.Application/Extensions/DIExtensions.cs b/EnvelopeGenerator.Application/Extensions/DIExtensions.cs index f5156fdf..37579d98 100644 --- a/EnvelopeGenerator.Application/Extensions/DIExtensions.cs +++ b/EnvelopeGenerator.Application/Extensions/DIExtensions.cs @@ -1,39 +1,21 @@ using DigitalData.UserManager.Application.MappingProfiles; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.MappingProfiles; using EnvelopeGenerator.Application.Configurations; using EnvelopeGenerator.Application.Services; -using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Infrastructure.Repositories; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using DigitalData.Core.Client; using QRCoder; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Extensions; public static class DIExtensions { - public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration config) + public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config) { //Inject CRUD Service and repositoriesad - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); @@ -57,6 +39,7 @@ public static class DIExtensions services.Configure(config.GetSection(nameof(MailParams))); services.Configure(config.GetSection(nameof(AuthenticatorParams))); services.Configure(config.GetSection(nameof(TotpSmsParams))); + services.Configure(config.GetSection(nameof(DbTriggerParams))); services.AddHttpClientService(config.GetSection(nameof(GtxMessagingParams))); services.TryAddSingleton(); diff --git a/EnvelopeGenerator.Application/Services/Authenticator.cs b/EnvelopeGenerator.Application/Services/Authenticator.cs index af410d9a..84bc7027 100644 --- a/EnvelopeGenerator.Application/Services/Authenticator.cs +++ b/EnvelopeGenerator.Application/Services/Authenticator.cs @@ -1,5 +1,5 @@ using EnvelopeGenerator.Application.Configurations; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using Microsoft.Extensions.Options; using OtpNet; using QRCoder; diff --git a/EnvelopeGenerator.Application/Services/ConfigService.cs b/EnvelopeGenerator.Application/Services/ConfigService.cs index 1d164d4f..0c98c48b 100644 --- a/EnvelopeGenerator.Application/Services/ConfigService.cs +++ b/EnvelopeGenerator.Application/Services/ConfigService.cs @@ -1,33 +1,33 @@ using AutoMapper; using DigitalData.Core.Application; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class ConfigService : ReadService, IConfigService { - public class ConfigService : ReadService, IConfigService - { private static readonly Guid DefaultConfigCacheId = Guid.NewGuid(); private readonly IMemoryCache _cache; - private readonly ILogger _logger; + private readonly ILogger _logger; public ConfigService(IConfigRepository repository, IMapper mapper, IMemoryCache memoryCache, ILogger logger) : base(repository, mapper) - { + { _cache = memoryCache; - _logger = logger; - } + _logger = logger; + } - public async Task> ReadFirstAsync() - { - var config = await _repository.ReadFirstAsync(); - return config is null - ? Result.Fail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, "There is no configuration in DB.") - : Result.Success(_mapper.Map(config)); - } + public async Task> ReadFirstAsync() + { + var config = await _repository.ReadFirstAsync(); + return config is null + ? Result.Fail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, "There is no configuration in DB.") + : Result.Success(_mapper.Map(config)); + } /// /// Reads the default configuration asynchronously. @@ -43,18 +43,17 @@ namespace EnvelopeGenerator.Application.Services /// Thrown when the default configuration cannot be found. /// public async Task 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."); - })); + { + var config = await _cache.GetOrCreateAsync(DefaultConfigCacheId, _ => ReadFirstAsync().ThenAsync( + Success: config => config, + Fail: (mssg, ntc) => + { + _logger.LogNotice(ntc); + throw new InvalidOperationException("Default configuration cannot find."); + })); - return config!; - } - - public async Task ReadDefaultSignatureHost() => (await ReadDefaultAsync()).SignatureHost; + return config!; } + + public async Task ReadDefaultSignatureHost() => (await ReadDefaultAsync()).SignatureHost; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs index 24c25a25..e30c0311 100644 --- a/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs +++ b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs @@ -1,17 +1,16 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class DocumentReceiverElementService : BasicCRUDService, IDocumentReceiverElementService { - public class DocumentReceiverElementService : BasicCRUDService, IDocumentReceiverElementService + public DocumentReceiverElementService(IDocumentReceiverElementRepository repository, IMapper mapper) + : base(repository, mapper) { - public DocumentReceiverElementService(IDocumentReceiverElementRepository repository, IMapper mapper) - : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/DocumentStatusService.cs b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs index 2a47922d..1b56eee3 100644 --- a/EnvelopeGenerator.Application/Services/DocumentStatusService.cs +++ b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs @@ -1,17 +1,16 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class DocumentStatusService : BasicCRUDService, IDocumentStatusService { - public class DocumentStatusService : BasicCRUDService, IDocumentStatusService + public DocumentStatusService(IDocumentStatusRepository repository, IMapper mapper) + : base(repository, mapper) { - public DocumentStatusService(IDocumentStatusRepository repository, IMapper mapper) - : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EmailTemplateService.cs b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs index 2f9947f4..e8600544 100644 --- a/EnvelopeGenerator.Application/Services/EmailTemplateService.cs +++ b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs @@ -1,30 +1,29 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using static EnvelopeGenerator.Common.Constants; using DigitalData.Core.DTO; using Microsoft.Extensions.Logging; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EmailTemplateService : BasicCRUDService, IEmailTemplateService { - public class EmailTemplateService : BasicCRUDService, IEmailTemplateService + public EmailTemplateService(IEmailTemplateRepository repository, IMapper mapper) + : base(repository, mapper) { - public EmailTemplateService(IEmailTemplateRepository repository, IMapper mapper) - : base(repository, mapper) - { - } + } - public async Task> ReadByNameAsync(EmailTemplateType type) - { - var temp = await _repository.ReadByNameAsync(type); - return temp is null - ? Result.Fail() - .Message(Key.InnerServiceError) - .Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"EmailTemplateType '{type}' is not found in DB. Please, define required e-mail template.") - : Result.Success(_mapper.Map(temp)); - } + public async Task> ReadByNameAsync(EmailTemplateType type) + { + var temp = await _repository.ReadByNameAsync(type); + return temp is null + ? Result.Fail() + .Message(Key.InnerServiceError) + .Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"EmailTemplateType '{type}' is not found in DB. Please, define required e-mail template.") + : Result.Success(_mapper.Map(temp)); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs b/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs index adf1680e..5bea1960 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeCertificateService.cs @@ -1,19 +1,17 @@ using AutoMapper; using DigitalData.Core.Application; using Microsoft.Extensions.Localization; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; +using EnvelopeGenerator.Application.Contracts.Repositories; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeCertificateService : BasicCRUDService, IEnvelopeCertificateService { - public class EnvelopeCertificateService : BasicCRUDService, IEnvelopeCertificateService + public EnvelopeCertificateService(IEnvelopeCertificateRepository repository, IMapper mapper) + : base(repository, mapper) { - public EnvelopeCertificateService(IEnvelopeCertificateRepository repository, IMapper mapper) - : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeDocumentService.cs b/EnvelopeGenerator.Application/Services/EnvelopeDocumentService.cs index 8f53a4df..b8462c26 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeDocumentService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeDocumentService.cs @@ -1,16 +1,15 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeDocumentService : BasicCRUDService, IEnvelopeDocumentService { - public class EnvelopeDocumentService : BasicCRUDService, IEnvelopeDocumentService + public EnvelopeDocumentService(IEnvelopeDocumentRepository repository, IMapper mapper) : base(repository, mapper) { - public EnvelopeDocumentService(IEnvelopeDocumentRepository repository, IMapper mapper) : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs index db72280a..a5d97c3b 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs @@ -1,85 +1,84 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using static EnvelopeGenerator.Common.Constants; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.DTOs.Receiver; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeHistoryService : CRUDService, IEnvelopeHistoryService { - public class EnvelopeHistoryService : CRUDService, IEnvelopeHistoryService + public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper) + : base(repository, mapper) { - public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper) - : base(repository, mapper) - { - } + } - public async Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null) => await _repository.CountAsync(envelopeId: envelopeId, userReference: userReference, status: status); + public async Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null) => await _repository.CountAsync(envelopeId: envelopeId, userReference: userReference, status: status); - public async Task HasStatus(EnvelopeStatus status, int envelopeId, string userReference) => await _repository.CountAsync( + public async Task HasStatus(EnvelopeStatus status, int envelopeId, string userReference) => await _repository.CountAsync( + envelopeId: envelopeId, + userReference: userReference, + status: (int) status) > 0; + + public async Task AccessCodeAlreadyRequested(int envelopeId, string userReference) => await _repository.CountAsync( + envelopeId: envelopeId, + userReference:userReference, + status: (int) EnvelopeStatus.AccessCodeRequested) > 0; + + public async Task IsSigned(int envelopeId, string userReference) => await _repository.CountAsync( + envelopeId: envelopeId, + userReference: userReference, + status: (int) EnvelopeStatus.DocumentSigned) > 0; + + /// + /// Checks if the specified envelope has been rejected. + /// Note: If any document within the envelope is rejected, the entire envelope will be considered rejected. + /// + /// The ID of the envelope to check. + /// Optional user reference associated with the envelope. + /// A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the envelope is rejected. + public async Task IsRejected(int envelopeId, string? userReference = null) + { + return await _repository.CountAsync( envelopeId: envelopeId, userReference: userReference, - status: (int) status) > 0; + status: (int)EnvelopeStatus.DocumentRejected) > 0; + } - public async Task AccessCodeAlreadyRequested(int envelopeId, string userReference) => await _repository.CountAsync( - envelopeId: envelopeId, - userReference:userReference, - status: (int) EnvelopeStatus.AccessCodeRequested) > 0; + public async Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false) + { + var histDTOs = _mapper.Map>( + await _repository.ReadAsync( + envelopeId: envelopeId, + userReference: userReference, + status: status, + withSender: withSender, + withReceiver: withReceiver)); + return referenceType is null ? histDTOs : histDTOs.Where(h => h.ReferenceType == referenceType); + } - public async Task IsSigned(int envelopeId, string userReference) => await _repository.CountAsync( - envelopeId: envelopeId, - userReference: userReference, - status: (int) EnvelopeStatus.DocumentSigned) > 0; - - /// - /// Checks if the specified envelope has been rejected. - /// Note: If any document within the envelope is rejected, the entire envelope will be considered rejected. - /// - /// The ID of the envelope to check. - /// Optional user reference associated with the envelope. - /// A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the envelope is rejected. - public async Task IsRejected(int envelopeId, string? userReference = null) - { - return await _repository.CountAsync( - envelopeId: envelopeId, - userReference: userReference, - status: (int)EnvelopeStatus.DocumentRejected) > 0; - } - - public async Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false) - { - var histDTOs = _mapper.Map>( - await _repository.ReadAsync( - envelopeId: envelopeId, - userReference: userReference, - status: status, - withSender: withSender, - withReceiver: withReceiver)); - return referenceType is null ? histDTOs : histDTOs.Where(h => h.ReferenceType == referenceType); - } - - public async Task> ReadRejectedAsync(int envelopeId, string? userReference = null) => - await ReadAsync(envelopeId: envelopeId, userReference: userReference, status: (int)EnvelopeStatus.DocumentRejected, withReceiver:true); + public async Task> 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> ReadRejectingReceivers(int envelopeId) { var envelopes = await ReadRejectedAsync(envelopeId); - return envelopes is null - ? Enumerable.Empty() - : envelopes - .Where(eh => eh?.Receiver != null) - .Select(eh => eh.Receiver!); + return envelopes is null + ? Enumerable.Empty() + : envelopes + .Where(eh => eh?.Receiver != null) + .Select(eh => eh.Receiver!); } public async Task> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null) => - await CreateAsync(new (EnvelopeId: envelopeId, UserReference: userReference, Status: (int)status, ActionDate: DateTime.Now, Comment: comment)) - .ThenAsync( - Success: id => Result.Success(id), - Fail: (mssg, ntc) => Result.Fail().Message(mssg).Notice(ntc) - ); - } + await CreateAsync(new (EnvelopeId: envelopeId, UserReference: userReference, Status: (int)status, ActionDate: DateTime.Now, Comment: comment)) + .ThenAsync( + Success: id => Result.Success(id), + Fail: (mssg, ntc) => Result.Fail().Message(mssg).Notice(ntc) + ); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs b/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs index a263aeba..203d4a9c 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs @@ -3,7 +3,6 @@ using DigitalData.Core.DTO; using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut; using DigitalData.EmailProfilerDispatcher.Abstraction.Services; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Common; using Microsoft.Extensions.Logging; @@ -14,6 +13,7 @@ using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Application.Configurations; using EnvelopeGenerator.Application.Extensions; using Newtonsoft.Json; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Application.Services { diff --git a/EnvelopeGenerator.Application/Services/EnvelopeReceiverReadOnlyService.cs b/EnvelopeGenerator.Application/Services/EnvelopeReceiverReadOnlyService.cs index 3214cfed..aa4d11da 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeReceiverReadOnlyService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeReceiverReadOnlyService.cs @@ -1,16 +1,15 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeReceiverReadOnlyService : CRUDService, IEnvelopeReceiverReadOnlyService { - public class EnvelopeReceiverReadOnlyService : CRUDService, IEnvelopeReceiverReadOnlyService + public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper) { - public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs index 742c2d41..87961262 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs @@ -1,179 +1,178 @@ using AutoMapper; using DigitalData.Core.Application; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using EnvelopeGenerator.Extensions; using EnvelopeGenerator.Application.DTOs.Messaging; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeReceiverService : BasicCRUDService, IEnvelopeReceiverService { - public class EnvelopeReceiverService : BasicCRUDService, IEnvelopeReceiverService + private readonly IStringLocalizer _localizer; + + private readonly ISmsSender _smsSender; + + public EnvelopeReceiverService(IEnvelopeReceiverRepository repository, IStringLocalizer localizer, IMapper mapper, ISmsSender smsSender) + : base(repository, mapper) { - private readonly IStringLocalizer _localizer; + _localizer = localizer; + _smsSender = smsSender; + } - private readonly ISmsSender _smsSender; + public async Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true) + { + var env_rcvs = await _repository.ReadBySignatureAsync(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); + return Result.Success(_mapper.Map>(env_rcvs)); + } - public EnvelopeReceiverService(IEnvelopeReceiverRepository repository, IStringLocalizer localizer, IMapper mapper, ISmsSender smsSender) - : base(repository, mapper) - { - _localizer = localizer; - _smsSender = smsSender; - } + public async Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true) + { + var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); + return Result.Success(_mapper.Map>(env_rcvs)); + } - public async Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true) - { - var env_rcvs = await _repository.ReadBySignatureAsync(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); - return Result.Success(_mapper.Map>(env_rcvs)); - } + public async Task>> ReadAccessCodeByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true) + { + var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver); + return Result.Success(env_rcvs.Select(er => er.AccessCode)); + } - public async Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true) - { - var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); - return Result.Success(_mapper.Map>(env_rcvs)); - } + public async Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) + { + var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); + if (env_rcv is null) + return Result.Fail() + .Message(Key.EnvelopeReceiverNotFound); - public async Task>> ReadAccessCodeByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true) - { - var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver); - return Result.Success(env_rcvs.Select(er => er.AccessCode)); - } + return Result.Success(_mapper.Map(env_rcv)); + } - public async Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) - { - var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); - if (env_rcv is null) - return Result.Fail() - .Message(Key.EnvelopeReceiverNotFound); + public async Task> ReadWithSecretByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) + { + var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); + if (env_rcv is null) + return Result.Fail() + .Message(Key.EnvelopeReceiverNotFound); - return Result.Success(_mapper.Map(env_rcv)); - } + return Result.Success(_mapper.Map(env_rcv)); + } - public async Task> ReadWithSecretByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) - { - var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); - if (env_rcv is null) - return Result.Fail() - .Message(Key.EnvelopeReceiverNotFound); + public async Task> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) + { + (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); - return Result.Success(_mapper.Map(env_rcv)); - } + if (uuid is null || signature is null) + return Result.Fail() + .Message(_localizer[Key.WrongEnvelopeReceiverId]) + .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) + .Notice(LogLevel.Warning, EnvelopeFlag.WrongEnvelopeReceiverId) + .Notice(LogLevel.Warning, Flag.PossibleSecurityBreach); - public async Task> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) - { - (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); + return await ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); + } - if (uuid is null || signature is null) - return Result.Fail() - .Message(_localizer[Key.WrongEnvelopeReceiverId]) - .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) - .Notice(LogLevel.Warning, EnvelopeFlag.WrongEnvelopeReceiverId) - .Notice(LogLevel.Warning, Flag.PossibleSecurityBreach); + public async Task> VerifyAccessCodeAsync(string uuid, string signature, string accessCode) + { + var er = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature); - return await ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly); - } + if (er is null) + return Result.Fail() + .Message(_localizer[Key.EnvelopeOrReceiverNonexists]) + .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) + .Notice(LogLevel.Warning, EnvelopeFlag.EnvelopeOrReceiverNonexists) + .Notice(LogLevel.Warning, Flag.PossibleDataIntegrityIssue); - public async Task> VerifyAccessCodeAsync(string uuid, string signature, string accessCode) - { - var er = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature); + var actualAccessCode = er.AccessCode; - if (er is null) - return Result.Fail() - .Message(_localizer[Key.EnvelopeOrReceiverNonexists]) - .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) - .Notice(LogLevel.Warning, EnvelopeFlag.EnvelopeOrReceiverNonexists) - .Notice(LogLevel.Warning, Flag.PossibleDataIntegrityIssue); + if (actualAccessCode is null) + return Result.Fail() + .Message(_localizer[Key.AccessCodeNull]) + .Notice(LogLevel.Critical, (uuid, signature).ToTitle()) + .Notice(LogLevel.Critical, EnvelopeFlag.AccessCodeNull) + .Notice(LogLevel.Critical, Flag.DataIntegrityIssue); - var actualAccessCode = er.AccessCode; + else if (accessCode != actualAccessCode) + return Result.Success(false).Message(_localizer[Key.WrongAccessCode]); + else + return Result.Success(true); + } - if (actualAccessCode is null) - return Result.Fail() - .Message(_localizer[Key.AccessCodeNull]) - .Notice(LogLevel.Critical, (uuid, signature).ToTitle()) - .Notice(LogLevel.Critical, EnvelopeFlag.AccessCodeNull) - .Notice(LogLevel.Critical, Flag.DataIntegrityIssue); + public async Task> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode) + { + (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); - else if (accessCode != actualAccessCode) - return Result.Success(false).Message(_localizer[Key.WrongAccessCode]); - else - return Result.Success(true); - } + if (uuid is null || signature is null) + return Result.Fail() + .Message(Key.WrongEnvelopeReceiverId) + .Notice(LogLevel.Critical, EnvelopeFlag.WrongEnvelopeReceiverId) + .Notice(LogLevel.Critical, Flag.SecurityBreach) + .Notice(LogLevel.Critical, "Attempt to verify access code detected. Such actions are generally not initiated by well-intentioned users. Potential security breach suspected. Immediate investigation required."); - public async Task> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode) - { - (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); + return await VerifyAccessCodeAsync(uuid: uuid, signature: signature, accessCode: accessCode); + } - if (uuid is null || signature is null) - return Result.Fail() - .Message(Key.WrongEnvelopeReceiverId) - .Notice(LogLevel.Critical, EnvelopeFlag.WrongEnvelopeReceiverId) - .Notice(LogLevel.Critical, Flag.SecurityBreach) - .Notice(LogLevel.Critical, "Attempt to verify access code detected. Such actions are generally not initiated by well-intentioned users. Potential security breach suspected. Immediate investigation required."); + public async Task> IsExisting(string envelopeReceiverId) + { + (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); - return await VerifyAccessCodeAsync(uuid: uuid, signature: signature, accessCode: accessCode); - } + if (uuid is null || signature is null) + return Result.Fail().Notice(LogLevel.Warning, EnvelopeFlag.NonDecodableEnvelopeReceiverId, "In IsExisting(string envelopeReceiverId)"); - public async Task> IsExisting(string envelopeReceiverId) - { - (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); - - if (uuid is null || signature is null) - return Result.Fail().Notice(LogLevel.Warning, EnvelopeFlag.NonDecodableEnvelopeReceiverId, "In IsExisting(string envelopeReceiverId)"); - - int count = await _repository.CountAsync(uuid:uuid, signature:signature); - return Result.Success(count > 0); - } + int count = await _repository.CountAsync(uuid:uuid, signature:signature); + return Result.Success(count > 0); + } public async Task> ReadAccessCodeByIdAsync(int envelopeId, int receiverId) { - var code = await _repository.ReadAccessCodeByIdAsync(envelopeId: envelopeId, receiverId: receiverId); - return code is null ? - Result.Fail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"Access code is null. Envelope ID is {envelopeId} and receiver ID {receiverId}") - : Result.Success(code); + var code = await _repository.ReadAccessCodeByIdAsync(envelopeId: envelopeId, receiverId: receiverId); + return code is null ? + Result.Fail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"Access code is null. Envelope ID is {envelopeId} and receiver ID {receiverId}") + : Result.Success(code); } - public async Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses) - { - var er_list = await _repository.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses); - var dto_list = _mapper.Map>(er_list); - return Result.Success(dto_list); - } + public async Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses) + { + var er_list = await _repository.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses); + var dto_list = _mapper.Map>(er_list); + return Result.Success(dto_list); + } - public async Task> ReadLastUsedReceiverNameByMail(string mail) - { - var er = await _repository.ReadLastByReceiver(mail); - return er is null ? Result.Fail().Notice(LogLevel.None, Flag.NotFound) : Result.Success(er.Name); - } + public async Task> ReadLastUsedReceiverNameByMail(string mail) + { + var er = await _repository.ReadLastByReceiver(mail); + return er is null ? Result.Fail().Notice(LogLevel.None, Flag.NotFound) : Result.Success(er.Name); + } - public async Task> SendSmsAsync(string envelopeReceiverId, string message) - { - (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); + public async Task> SendSmsAsync(string envelopeReceiverId, string message) + { + (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); - if (uuid is null || signature is null) - return Result.Fail() - .Message(_localizer[Key.WrongEnvelopeReceiverId]) - .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) - .Notice(LogLevel.Warning, EnvelopeFlag.WrongEnvelopeReceiverId) - .Notice(LogLevel.Warning, Flag.PossibleSecurityBreach); + if (uuid is null || signature is null) + return Result.Fail() + .Message(_localizer[Key.WrongEnvelopeReceiverId]) + .Notice(LogLevel.Warning, (uuid, signature).ToTitle()) + .Notice(LogLevel.Warning, EnvelopeFlag.WrongEnvelopeReceiverId) + .Notice(LogLevel.Warning, Flag.PossibleSecurityBreach); - var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: false, withReceiver: false); - if (env_rcv is null) - return Result.Fail() - .Message(Key.EnvelopeReceiverNotFound); + var env_rcv = await _repository.ReadByUuidSignatureAsync(uuid: uuid, signature: signature, withEnvelope: false, withReceiver: false); + if (env_rcv is null) + return Result.Fail() + .Message(Key.EnvelopeReceiverNotFound); - if (env_rcv.PhoneNumber is null) - return Result.Fail() - .Message(Key.PhoneNumberNonexists) - .Notice(LogLevel.Error, Flag.NotFound, $"An attempt was made to send sms to the user whose phone number is null. Envelope recipient ID is {envelopeReceiverId}, UUID is {uuid} and signature is {signature}."); + if (env_rcv.PhoneNumber is null) + return Result.Fail() + .Message(Key.PhoneNumberNonexists) + .Notice(LogLevel.Error, Flag.NotFound, $"An attempt was made to send sms to the user whose phone number is null. Envelope recipient ID is {envelopeReceiverId}, UUID is {uuid} and signature is {signature}."); - var res = await _smsSender.SendSmsAsync(recipient: env_rcv.PhoneNumber, message: message); + var res = await _smsSender.SendSmsAsync(recipient: env_rcv.PhoneNumber, message: message); - return Result.Success(res); - } + return Result.Success(res); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeService.cs index fc84d2f6..7a0552b9 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeService.cs @@ -1,43 +1,42 @@ using AutoMapper; using DigitalData.Core.Application; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeService : BasicCRUDService, IEnvelopeService { - public class EnvelopeService : BasicCRUDService, IEnvelopeService + public EnvelopeService(IEnvelopeRepository repository, IMapper mapper) + : base(repository, mapper) { - public EnvelopeService(IEnvelopeRepository repository, IMapper mapper) - : base(repository, mapper) - { - } + } - public async Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) - { - var envelopes = await _repository.ReadAllWithAsync(documents: documents, history: history, documentReceiverElement: documentReceiverElement); - var readDto = _mapper.Map>(envelopes); - return Result.Success(readDto); - } + public async Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) + { + var envelopes = await _repository.ReadAllWithAsync(documents: documents, history: history, documentReceiverElement: documentReceiverElement); + var readDto = _mapper.Map>(envelopes); + return Result.Success(readDto); + } - public async Task> 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); + public async Task> 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); - if (envelope is null) - return Result.Fail(); + if (envelope is null) + return Result.Fail(); - var readDto = _mapper.Map(envelope); - return Result.Success(readDto); - } + var readDto = _mapper.Map(envelope); + return Result.Success(readDto); + } - public async Task>> 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); - var readDto = _mapper.Map>(users); - return Result.Success(readDto); - } + public async Task>> 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); + var readDto = _mapper.Map>(users); + return Result.Success(readDto); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeSmsHandler.cs b/EnvelopeGenerator.Application/Services/EnvelopeSmsHandler.cs index 36eef84f..e65fcfc8 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeSmsHandler.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeSmsHandler.cs @@ -1,5 +1,5 @@ using EnvelopeGenerator.Application.Configurations; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Extensions; diff --git a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs index 2bc3cc75..082ae40b 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs @@ -1,30 +1,29 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.Extensions.Caching.Memory; using DigitalData.Core.DTO; using Microsoft.Extensions.Logging; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class EnvelopeTypeService : BasicCRUDService, IEnvelopeTypeService { - public class EnvelopeTypeService : BasicCRUDService, IEnvelopeTypeService + private static readonly Guid CacheKey = Guid.NewGuid(); + + private readonly IMemoryCache _cache; + + public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper, IMemoryCache cache) + : base(repository, mapper) { - private static readonly Guid CacheKey = Guid.NewGuid(); - - private readonly IMemoryCache _cache; - - public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper, IMemoryCache cache) - : base(repository, mapper) - { - _cache = cache; - } - - public override async Task>> ReadAllAsync() - => await _cache.GetOrCreateAsync(CacheKey, async entry => await base.ReadAllAsync()) - ?? Result.Fail>().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."); - + _cache = cache; } + + public override async Task>> ReadAllAsync() + => await _cache.GetOrCreateAsync(CacheKey, async entry => await base.ReadAllAsync()) + ?? Result.Fail>().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."); + } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/GTXSmsSender.cs b/EnvelopeGenerator.Application/Services/GTXSmsSender.cs index 5841d5d8..0449887c 100644 --- a/EnvelopeGenerator.Application/Services/GTXSmsSender.cs +++ b/EnvelopeGenerator.Application/Services/GTXSmsSender.cs @@ -2,7 +2,7 @@ using DigitalData.Core.Abstractions.Client; using DigitalData.Core.Client; using EnvelopeGenerator.Application.Configurations; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.Messaging; using Microsoft.Extensions.Options; diff --git a/EnvelopeGenerator.Application/Services/ReceiverService.cs b/EnvelopeGenerator.Application/Services/ReceiverService.cs index 97015953..98b6a58b 100644 --- a/EnvelopeGenerator.Application/Services/ReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/ReceiverService.cs @@ -1,52 +1,51 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using EnvelopeGenerator.Application.DTOs.Receiver; using DigitalData.Core.DTO; using DigitalData.Core.Abstractions; using Microsoft.Extensions.Logging; +using EnvelopeGenerator.Application.Contracts.Services; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class ReceiverService : CRUDService, IReceiverService { - public class ReceiverService : CRUDService, IReceiverService + public ReceiverService(IReceiverRepository repository, IMapper mapper) + : base(repository, mapper) { - public ReceiverService(IReceiverRepository repository, IMapper mapper) - : base(repository, mapper) + } + + public async Task> ReadByAsync(string? emailAddress = null, string? signature = null) + { + var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature); + + if (rcv is null) + return Result.Fail(); + + return Result.Success(_mapper.Map(rcv)); + } + + public async Task DeleteByAsync(string? emailAddress = null, string? signature = null) + { + var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature); + + if (rcv is null) + return Result.Fail(); + + return await _repository.DeleteAsync(rcv) ? Result.Success() : Result.Fail(); + } + + public virtual async Task UpdateAsync(TUpdateDto updateDto) where TUpdateDto : IUnique + { + var val = await _repository.ReadByIdAsync(updateDto.Id); + if (val == null) { + return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.Id} is not found in update process of {GetType()} entity."); } - public async Task> ReadByAsync(string? emailAddress = null, string? signature = null) - { - var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature); - - if (rcv is null) - return Result.Fail(); - - return Result.Success(_mapper.Map(rcv)); - } - - public async Task DeleteByAsync(string? emailAddress = null, string? signature = null) - { - var rcv = await _repository.ReadByAsync(emailAddress: emailAddress, signature: signature); - - if (rcv is null) - return Result.Fail(); - - return await _repository.DeleteAsync(rcv) ? Result.Success() : Result.Fail(); - } - - public virtual async Task UpdateAsync(TUpdateDto updateDto) where TUpdateDto : IUnique - { - var val = await _repository.ReadByIdAsync(updateDto.Id); - if (val == null) - { - return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.Id} is not found in update process of {GetType()} entity."); - } - - var entity = _mapper.Map(updateDto, val); - return (await _repository.UpdateAsync(entity)) ? Result.Success() : Result.Fail(); - } + var entity = _mapper.Map(updateDto, val); + return (await _repository.UpdateAsync(entity)) ? Result.Success() : Result.Fail(); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/UserReceiverService.cs b/EnvelopeGenerator.Application/Services/UserReceiverService.cs index 08da1906..62346a0d 100644 --- a/EnvelopeGenerator.Application/Services/UserReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/UserReceiverService.cs @@ -1,17 +1,16 @@ using AutoMapper; using DigitalData.Core.Application; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Application.Services +namespace EnvelopeGenerator.Application.Services; + +public class UserReceiverService : BasicCRUDService, IUserReceiverService { - public class UserReceiverService : BasicCRUDService, IUserReceiverService + public UserReceiverService(IUserReceiverRepository repository, IMapper mapper) + : base(repository, mapper) { - public UserReceiverService(IUserReceiverRepository repository, IMapper mapper) - : base(repository, mapper) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs index bbf55d2b..283d11f0 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs @@ -50,6 +50,6 @@ namespace EnvelopeGenerator.Domain.Entities public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId); [NotMapped] - public bool HasPhoneNumber => PhoneNumber is not null; + public bool HasPhoneNumber => !string.IsNullOrWhiteSpace(PhoneNumber); } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs index a7306a36..a7835d66 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs index b5a9c989..b81dc1e4 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Common.My.Resources; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs index daacd703..3708cf08 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Net.Mail; diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs index 8b24cc9d..ce0abab4 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System; diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs index 4c057b92..f8c11be2 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs @@ -1,6 +1,6 @@ using DigitalData.Core.API; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Authorization; diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs deleted file mode 100644 index e1e311a3..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IConfigRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IConfigRepository : ICRUDRepository - { - Task ReadFirstAsync(); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs deleted file mode 100644 index 943f3d42..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentReceiverElementRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IDocumentReceiverElementRepository : ICRUDRepository - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs deleted file mode 100644 index a10a9d24..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IDocumentStatusRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IDocumentStatusRepository : ICRUDRepository - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs deleted file mode 100644 index b29f1ab1..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEmailTemplateRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; -using static EnvelopeGenerator.Common.Constants; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEmailTemplateRepository : ICRUDRepository - { - Task ReadByNameAsync(EmailTemplateType type); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs deleted file mode 100644 index c6b94778..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeCertificateRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeCertificateRepository : ICRUDRepository - { - } -} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeDocumentRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeDocumentRepository.cs deleted file mode 100644 index f895146c..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeDocumentRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeDocumentRepository : ICRUDRepository - { - } -} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs deleted file mode 100644 index a473b176..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeHistoryRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeHistoryRepository : ICRUDRepository - { - Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null); - - Task> ReadAsync(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverReadOnlyRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverReadOnlyRepository.cs deleted file mode 100644 index 444937a9..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverReadOnlyRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeReceiverReadOnlyRepository : ICRUDRepository - { - } -} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs deleted file mode 100644 index ffd56528..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs +++ /dev/null @@ -1,26 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeReceiverRepository : ICRUDRepository - { - Task> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true); - - Task> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true); - - Task ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true); - - Task ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true); - - Task CountAsync(string uuid, string signature); - - Task ReadByIdAsync(int envelopeId, int receiverId, bool readOnly = true); - - Task ReadAccessCodeByIdAsync(int envelopeId, int receiverId, bool readOnly = true); - - Task> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); - - Task ReadLastByReceiver(string email); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs deleted file mode 100644 index 5b78658e..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeRepository : ICRUDRepository - { - Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); - - Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); - - Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs deleted file mode 100644 index 32902364..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeTypeRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IEnvelopeTypeRepository : ICRUDRepository - { - } -} diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs deleted file mode 100644 index 83ad4cad..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IReceiverRepository.cs +++ /dev/null @@ -1,10 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IReceiverRepository : ICRUDRepository - { - Task ReadByAsync(string? emailAddress = null, string? signature = null); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs deleted file mode 100644 index 5c8fcfe7..00000000 --- a/EnvelopeGenerator.Infrastructure/Contracts/IUserReceiverRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using DigitalData.Core.Abstractions.Infrastructure; -using EnvelopeGenerator.Domain.Entities; - -namespace EnvelopeGenerator.Infrastructure.Contracts -{ - public interface IUserReceiverRepository : ICRUDRepository - { - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/DIExtensions.cs b/EnvelopeGenerator.Infrastructure/DIExtensions.cs new file mode 100644 index 00000000..36012791 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/DIExtensions.cs @@ -0,0 +1,37 @@ +using EnvelopeGenerator.Application.Contracts.Repositories; +using EnvelopeGenerator.Application.Extensions; +using EnvelopeGenerator.Infrastructure.Repositories; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Configuration; + +namespace EnvelopeGenerator.Infrastructure; + +public static class DIExtensions +{ + public static IServiceCollection AddEnvelopeGeneratorRepositories(this IServiceCollection services) + { + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + + return services; + } + + public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration configuration) => services + .AddEnvelopeGeneratorRepositories() + .AddEnvelopeGeneratorServices(configuration); +} diff --git a/EnvelopeGenerator.Infrastructure/EGDbContext.cs b/EnvelopeGenerator.Infrastructure/EGDbContext.cs index e9a08d14..7772a47a 100644 --- a/EnvelopeGenerator.Infrastructure/EGDbContext.cs +++ b/EnvelopeGenerator.Infrastructure/EGDbContext.cs @@ -7,145 +7,174 @@ using Microsoft.EntityFrameworkCore; using Group = DigitalData.UserManager.Domain.Entities.Group; using Module = DigitalData.UserManager.Domain.Entities.Module; using DigitalData.EmailProfilerDispatcher; +using Microsoft.Extensions.Options; +using EnvelopeGenerator.Application.Configurations; +using DigitalData.Core.Client; +using Microsoft.Extensions.Logging; -namespace EnvelopeGenerator.Infrastructure +namespace EnvelopeGenerator.Infrastructure; + +//TODO: Adding EmailOut instead of EmailOut.Abst is not correct for the arch. Re-design EmailPut consedering this. IMailDbContext shoud move to Abstraction layer (hint: in this case using DBSet in abst. will be problem because entity framework will have to be added. +public class EGDbContext : DbContext, IUserManagerDbContext, IMailDbContext { - //TODO: Adding EmailOut instead of EmailOut.Abst is not correct for the arch. Re-design EmailPut consedering this. IMailDbContext shoud move to Abstraction layer (hint: in this case using DBSet in abst. will be problem because entity framework will have to be added. - public class EGDbContext : DbContext, IUserManagerDbContext, IMailDbContext + public DbSet UserReceivers { get; set; } + + public DbSet Configs { get; set; } + + public DbSet EnvelopeReceivers { get; set; } + + public DbSet Envelopes { get; set; } + + public DbSet DocumentReceiverElements { get; set; } + + public DbSet DocumentStatus { get; set; } + + public DbSet EmailTemplate { get; set; } + + public DbSet EnvelopeCertificates { get; set; } + + public DbSet EnvelopeDocument { get; set; } + + public DbSet EnvelopeHistories { get; set; } + + public DbSet EnvelopeTypes { get; set; } + + public DbSet Receivers { get; set; } + + public DbSet GroupOfUsers { get; set; } + + public DbSet Groups { get; set; } + + public DbSet ModuleOfUsers { get; set; } + + public DbSet Modules { get; set; } + + public DbSet Users { get; set; } + + public DbSet UserReps { get; set; } + + public DbSet EMailOuts { get; set; } + + public DbSet EnvelopeReceiverReadOnlys { get; set; } + + private readonly DbTriggerParams _triggers; + + private readonly ILogger _logger; + + public EGDbContext(DbContextOptions options, IOptions triggerParamOptions, ILogger logger) : base(options) { - public DbSet UserReceivers { get; set; } + _triggers = triggerParamOptions.Value; + _logger = logger; - public DbSet Configs { get; set; } + UserReceivers = Set(); + Configs = Set(); + EnvelopeReceivers = Set(); + Envelopes = Set(); + DocumentReceiverElements = Set(); + DocumentStatus = Set(); + EnvelopeCertificates = Set(); + EnvelopeDocument = Set(); + EnvelopeHistories = Set(); + EnvelopeTypes = Set(); + Receivers = Set(); - public DbSet EnvelopeReceivers { get; set; } + GroupOfUsers = Set(); + Groups = Set(); + ModuleOfUsers = Set(); + Modules = Set(); + Users = Set(); + UserReps = Set(); + EMailOuts = Set(); + EnvelopeReceiverReadOnlys = Set(); + } - public DbSet Envelopes { get; set; } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasNoKey(); - public DbSet DocumentReceiverElements { get; set; } + modelBuilder.Entity() + .HasKey(er => new { er.EnvelopeId, er.ReceiverId }); - public DbSet DocumentStatus { get; set; } + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); - public DbSet EmailTemplate { get; set; } + // Configure the one-to-many relationship of Envelope + modelBuilder.Entity() + .HasMany(e => e.Documents) + .WithOne() + .HasForeignKey(ed => ed.EnvelopeId); - public DbSet EnvelopeCertificates { get; set; } + modelBuilder.Entity() + .HasMany(e => e.History) + .WithOne() + .HasForeignKey(eh => eh.EnvelopeId); - public DbSet EnvelopeDocument { get; set; } + modelBuilder.Entity() + .HasMany(ed => ed.Elements) + .WithOne(e => e.Document) + .HasForeignKey(e => e.DocumentId); - public DbSet EnvelopeHistories { get; set; } + modelBuilder.Entity() + .HasOne(dre => dre.Document) + .WithMany(ed => ed.Elements) + .HasForeignKey(dre => dre.DocumentId); - public DbSet EnvelopeTypes { get; set; } + modelBuilder.Entity() + .HasOne(eh => eh.Receiver) + .WithMany() + .HasForeignKey(eh => eh.UserReference) + .HasPrincipalKey(e => e.EmailAddress); - public DbSet Receivers { get; set; } + modelBuilder.Entity() + .HasOne(eh => eh.Sender) + .WithMany() + .HasForeignKey(eh => eh.UserReference) + .HasPrincipalKey(e => e.Email); - public DbSet GroupOfUsers { get; set; } + modelBuilder.Entity() + .HasOne(erro => erro.Receiver) + .WithMany() + .HasForeignKey(erro => erro.AddedWho) + .HasPrincipalKey(r => r.EmailAddress); - public DbSet Groups { get; set; } + // Configure entities to handle database triggers + void AddTrigger() where T : class => _triggers + .Where(t => t.Key == typeof(T).Name) + .SelectMany(t => t.Value) + .ForEach(tName => + { + modelBuilder.Entity().ToTable(tb => tb.HasTrigger(tName)); + _logger.LogInformation("Trigger '{triggerName}' has been added to the '{entityName}' entity.", tName, typeof(T).Name); + }); + + // TODO: call add trigger methods with attributes and reflection + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); + AddTrigger(); - public DbSet ModuleOfUsers { get; set; } + //configure model builder for user manager tables + modelBuilder.ConfigureUserManager(); - public DbSet Modules { get; set; } - - public DbSet Users { get; set; } - - public DbSet UserReps { get; set; } - - public DbSet EMailOuts { get; set; } - - public DbSet EnvelopeReceiverReadOnlys { get; set; } - - public EGDbContext(DbContextOptions options) : base(options) - { - UserReceivers = Set(); - Configs = Set(); - EnvelopeReceivers = Set(); - Envelopes = Set(); - DocumentReceiverElements = Set(); - DocumentStatus = Set(); - EnvelopeCertificates = Set(); - EnvelopeDocument = Set(); - EnvelopeHistories = Set(); - EnvelopeTypes = Set(); - Receivers = Set(); - - GroupOfUsers = Set(); - Groups = Set(); - ModuleOfUsers = Set(); - Modules = Set(); - Users = Set(); - UserReps = Set(); - EMailOuts = Set(); - EnvelopeReceiverReadOnlys = Set(); - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity().HasNoKey(); - - modelBuilder.Entity() - .HasKey(er => new { er.EnvelopeId, er.ReceiverId }); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - // Configure the one-to-many relationship of Envelope - modelBuilder.Entity() - .HasMany(e => e.Documents) - .WithOne() - .HasForeignKey(ed => ed.EnvelopeId); - - modelBuilder.Entity() - .HasMany(e => e.History) - .WithOne() - .HasForeignKey(eh => eh.EnvelopeId); - - modelBuilder.Entity() - .HasMany(ed => ed.Elements) - .WithOne(e => e.Document) - .HasForeignKey(e => e.DocumentId); - - modelBuilder.Entity() - .HasOne(dre => dre.Document) - .WithMany(ed => ed.Elements) - .HasForeignKey(dre => dre.DocumentId); - - modelBuilder.Entity() - .HasOne(eh => eh.Receiver) - .WithMany() - .HasForeignKey(eh => eh.UserReference) - .HasPrincipalKey(e => e.EmailAddress); - - modelBuilder.Entity() - .HasOne(eh => eh.Sender) - .WithMany() - .HasForeignKey(eh => eh.UserReference) - .HasPrincipalKey(e => e.Email); - - modelBuilder.Entity() - .HasOne(erro => erro.Receiver) - .WithMany() - .HasForeignKey(erro => erro.AddedWho) - .HasPrincipalKey(r => r.EmailAddress); - - // Configure entities to handle database triggers - modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS")); - modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS")); - modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_INS")); - modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_UPD")); - modelBuilder.Entity().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD")); - - //configure model builder for user manager tables - modelBuilder.ConfigureUserManager(); - - base.OnModelCreating(modelBuilder); - } + base.OnModelCreating(modelBuilder); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index 146af618..892bbe5a 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -20,6 +20,7 @@ + diff --git a/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs index bae012ae..103e2ddb 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs @@ -1,20 +1,19 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories -{ - public class ConfigRepository : CRUDRepository, IConfigRepository - { - public ConfigRepository(EGDbContext dbContext) : base(dbContext, dbContext.Configs) - { - } +namespace EnvelopeGenerator.Infrastructure.Repositories; - public async Task ReadFirstAsync() - { - var configs = await _dbSet.ToListAsync(); - return configs.Count > 0 ? configs[0] : default; - } +public class ConfigRepository : CRUDRepository, IConfigRepository +{ + public ConfigRepository(EGDbContext dbContext) : base(dbContext, dbContext.Configs) + { + } + + public async Task ReadFirstAsync() + { + var configs = await _dbSet.ToListAsync(); + return configs.Count > 0 ? configs[0] : default; } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs index a57bde74..c663c7fe 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs @@ -1,13 +1,12 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class DocumentReceiverElementRepository : CRUDRepository, IDocumentReceiverElementRepository { - public class DocumentReceiverElementRepository : CRUDRepository, IDocumentReceiverElementRepository + public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentReceiverElements) { - public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentReceiverElements) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs index e27e56a6..83b3e638 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs @@ -1,14 +1,13 @@ using DigitalData.Core.Infrastructure; using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class DocumentStatusRepository : CRUDRepository, IDocumentStatusRepository { - public class DocumentStatusRepository : CRUDRepository, IDocumentStatusRepository + public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentStatus) { - public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentStatus) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs index 47772341..1417fa39 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs @@ -1,34 +1,33 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; using static EnvelopeGenerator.Common.Constants; -namespace EnvelopeGenerator.Infrastructure.Repositories -{ +namespace EnvelopeGenerator.Infrastructure.Repositories; + public class EmailTemplateRepository : CRUDRepository, IEmailTemplateRepository { private readonly IMemoryCache _cache; - public EmailTemplateRepository(EGDbContext dbContext, IMemoryCache cache) : base(dbContext, dbContext.EmailTemplate) + public EmailTemplateRepository(EGDbContext dbContext, IMemoryCache cache) : base(dbContext, dbContext.EmailTemplate) { _cache = cache; } private readonly Guid key_guid = Guid.NewGuid(); - /// - /// Retrieves an email template based on its name. - /// Utilizes in-memory caching to improve performance for the limited number of email templates available. - /// If the template is not found in the cache, it queries the database and stores the result in the cache. - /// - /// The type of the email template, which corresponds to its name. - /// - /// A task that represents the asynchronous operation. The task result contains the email template - /// if found, otherwise null. - /// - public async Task ReadByNameAsync(EmailTemplateType type) => await _cache.GetOrCreateAsync($"{type}{key_guid}", async _ + /// + /// Retrieves an email template based on its name. + /// Utilizes in-memory caching to improve performance for the limited number of email templates available. + /// If the template is not found in the cache, it queries the database and stores the result in the cache. + /// + /// The type of the email template, which corresponds to its name. + /// + /// A task that represents the asynchronous operation. The task result contains the email template + /// if found, otherwise null. + /// + public async Task ReadByNameAsync(EmailTemplateType type) => await _cache.GetOrCreateAsync($"{type}{key_guid}", async _ => await _dbSet.Where(t => t.Name == type.ToString()).FirstOrDefaultAsync()); - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs index 6bc3c4a9..c5a0dba3 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs @@ -1,13 +1,12 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeCertificateRepository : CRUDRepository, IEnvelopeCertificateRepository { - public class EnvelopeCertificateRepository : CRUDRepository, IEnvelopeCertificateRepository + public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeCertificates) { - public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeCertificates) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs index 25ff8949..153510f7 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs @@ -1,14 +1,13 @@ using DigitalData.Core.Infrastructure; using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeDocumentRepository : CRUDRepository, IEnvelopeDocumentRepository { - public class EnvelopeDocumentRepository : CRUDRepository, IEnvelopeDocumentRepository + public EnvelopeDocumentRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeDocument) { - public EnvelopeDocumentRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeDocument) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs index 97dcfc37..18ccc27e 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs @@ -1,49 +1,48 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeHistoryRepository : CRUDRepository, IEnvelopeHistoryRepository { - public class EnvelopeHistoryRepository : CRUDRepository, IEnvelopeHistoryRepository + public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeHistories) { - public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeHistories) - { - } - - private IQueryable By(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false) - { - var query = _dbSet.AsQueryable(); - - if (envelopeId is not null) - query = query.Where(eh => eh.EnvelopeId == envelopeId); - - if (userReference is not null) - query = query.Where(eh => eh.UserReference == userReference); - - if (status is not null) - query = query.Where(eh => eh.Status == status); - - if (withSender) - query = query.Include(eh => eh.Sender); - - if (withReceiver) - query = query.Include(eh => eh.Receiver); - - return query; - } - - public async Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null) => await By( - envelopeId: envelopeId, - userReference: userReference, - status: status).CountAsync(); - - public async Task> ReadAsync(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false) - => await By( - envelopeId: envelopeId, - userReference: userReference, - status: status, - withSender: withSender, - withReceiver: withReceiver).ToListAsync(); } + + private IQueryable By(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false) + { + var query = _dbSet.AsQueryable(); + + if (envelopeId is not null) + query = query.Where(eh => eh.EnvelopeId == envelopeId); + + if (userReference is not null) + query = query.Where(eh => eh.UserReference == userReference); + + if (status is not null) + query = query.Where(eh => eh.Status == status); + + if (withSender) + query = query.Include(eh => eh.Sender); + + if (withReceiver) + query = query.Include(eh => eh.Receiver); + + return query; + } + + public async Task CountAsync(int? envelopeId = null, string? userReference = null, int? status = null) => await By( + envelopeId: envelopeId, + userReference: userReference, + status: status).CountAsync(); + + public async Task> ReadAsync(int? envelopeId = null, string? userReference = null, int? status = null, bool withSender = false, bool withReceiver = false) + => await By( + envelopeId: envelopeId, + userReference: userReference, + status: status, + withSender: withSender, + withReceiver: withReceiver).ToListAsync(); } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeReceiverReadOnlyRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeReceiverReadOnlyRepository.cs index 3d037a20..5f442d64 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeReceiverReadOnlyRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeReceiverReadOnlyRepository.cs @@ -1,70 +1,69 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeReceiverReadOnlyRepository : CRUDRepository, IEnvelopeReceiverReadOnlyRepository { - public class EnvelopeReceiverReadOnlyRepository : CRUDRepository, IEnvelopeReceiverReadOnlyRepository + private readonly IEnvelopeRepository _envRepo; + + public EnvelopeReceiverReadOnlyRepository(EGDbContext dbContext, IEnvelopeRepository envelopeRepository) : base(dbContext, dbContext.EnvelopeReceiverReadOnlys) { - private readonly IEnvelopeRepository _envRepo; + _envRepo = envelopeRepository; + } - public EnvelopeReceiverReadOnlyRepository(EGDbContext dbContext, IEnvelopeRepository envelopeRepository) : base(dbContext, dbContext.EnvelopeReceiverReadOnlys) - { - _envRepo = envelopeRepository; - } + protected override IQueryable ReadOnly() + { + return base.ReadOnly() + //TODO: add again when EnvelopeId data type is standardized + //.Include(erro => erro.Envelope) + .Include(erro => erro.Receiver); + } - protected override IQueryable ReadOnly() - { - return base.ReadOnly() - //TODO: add again when EnvelopeId data type is standardized - //.Include(erro => erro.Envelope) - .Include(erro => erro.Receiver); - } + public async override Task> ReadAllAsync() + { + var erros = await base.ReadAllAsync(); + return await IncludeEnvelope(erros); + } - public async override Task> ReadAllAsync() - { - var erros = await base.ReadAllAsync(); - return await IncludeEnvelope(erros); - } + public override async Task ReadByIdAsync(long id) + { + var erro = await _dbSet.AsNoTracking() + .Include(erro => erro.Receiver) + .Where(erro => erro.Id == id) + .FirstOrDefaultAsync(); - public override async Task ReadByIdAsync(long id) - { - var erro = await _dbSet.AsNoTracking() - .Include(erro => erro.Receiver) - .Where(erro => erro.Id == id) - .FirstOrDefaultAsync(); + return await IncludeEnvelope(erro); + } - return await IncludeEnvelope(erro); - } + //TODO: Use IQueryable.Include instead of this when ID type is clarified. + [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] + private async Task IncludeEnvelope(EnvelopeReceiverReadOnly erro) + { + erro.Envelope = await _envRepo.ReadByIdAsync((int)erro.EnvelopeId); + return erro; + } - //TODO: Use IQueryable.Include instead of this when ID type is clarified. - [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] - private async Task IncludeEnvelope(EnvelopeReceiverReadOnly erro) - { + //TODO: Use IQueryable.Include instead of this when ID type is clarified. + [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] + private async Task> IncludeEnvelope(params EnvelopeReceiverReadOnly[] erros) + { + foreach (var erro in erros) + erro.Envelope = await _envRepo.ReadByIdAsync((int) erro.EnvelopeId); + + return erros; + } + + //TODO: Use IQueryable.Include instead of this when ID type is clarified. + [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] + private async Task IncludeEnvelope(T erros) + where T : IEnumerable + { + foreach (var erro in erros) erro.Envelope = await _envRepo.ReadByIdAsync((int)erro.EnvelopeId); - return erro; - } - //TODO: Use IQueryable.Include instead of this when ID type is clarified. - [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] - private async Task> IncludeEnvelope(params EnvelopeReceiverReadOnly[] erros) - { - foreach (var erro in erros) - erro.Envelope = await _envRepo.ReadByIdAsync((int) erro.EnvelopeId); - - return erros; - } - - //TODO: Use IQueryable.Include instead of this when ID type is clarified. - [Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")] - private async Task IncludeEnvelope(T erros) - where T : IEnumerable - { - foreach (var erro in erros) - erro.Envelope = await _envRepo.ReadByIdAsync((int)erro.EnvelopeId); - - return erros; - } + return erros; } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs index 40783bf2..5efbe348 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs @@ -1,65 +1,64 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeRepository : CRUDRepository, IEnvelopeRepository { - public class EnvelopeRepository : CRUDRepository, IEnvelopeRepository + public EnvelopeRepository(EGDbContext dbContext) : base(dbContext, dbContext.Envelopes) { - public EnvelopeRepository(EGDbContext dbContext) : base(dbContext, dbContext.Envelopes) - { - } + } - public async Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) - { - var query = _dbSet.AsNoTracking(); + public async Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) + { + var query = _dbSet.AsNoTracking(); - if (documents) - if (documentReceiverElement) - query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); - else - query = query.Include(e => e.Documents); + if (documents) + if (documentReceiverElement) + query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); + else + query = query.Include(e => e.Documents); - if (history) - query = query.Include(e => e.History); + if (history) + query = query.Include(e => e.History); - return await query.ToListAsync(); - } + return await query.ToListAsync(); + } - public async Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false) - { - var query = _dbSet.AsNoTracking().Where(e => e.Uuid == uuid); + public async Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false) + { + var query = _dbSet.AsNoTracking().Where(e => e.Uuid == uuid); - if (withAll || withDocuments) - if (withAll || withDocumentReceiverElement) - query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); - else - query = query.Include(e => e.Documents); + if (withAll || withDocuments) + if (withAll || withDocumentReceiverElement) + query = query.Include(e => e.Documents!).ThenInclude(d => d.Elements); + else + query = query.Include(e => e.Documents); - if (withAll || withUser) - query = query.Include(e => e.User!); + if (withAll || withUser) + query = query.Include(e => e.User!); - if (withAll || withHistory) - query = query.Include(e => e.History); + if (withAll || withHistory) + query = query.Include(e => e.History); - return await query.FirstOrDefaultAsync(); - } + return await query.FirstOrDefaultAsync(); + } - public async Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses) - { - var query = _dbSet.AsNoTracking().Where(e => e.UserId == userId); + public async Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses) + { + var query = _dbSet.AsNoTracking().Where(e => e.UserId == userId); - if (min_status is not null) - query = query.Where(e => e.Status >= min_status); + if (min_status is not null) + query = query.Where(e => e.Status >= min_status); - if (max_status is not null) - query = query.Where(e => e.Status <= max_status); + if (max_status is not null) + query = query.Where(e => e.Status <= max_status); - foreach (var ignore_status in ignore_statuses) - query = query.Where(e => e.Status != ignore_status); + foreach (var ignore_status in ignore_statuses) + query = query.Where(e => e.Status != ignore_status); - return await query.ToListAsync(); - } + return await query.ToListAsync(); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs index 5bc9f6c5..3ab4488f 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs @@ -1,13 +1,12 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeTypeRepository : CRUDRepository, IEnvelopeTypeRepository { - public class EnvelopeTypeRepository : CRUDRepository, IEnvelopeTypeRepository + public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeTypes) { - public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeTypes) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs index 9bfb26e4..8d5f471b 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs @@ -1,87 +1,86 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class EnvelopeReceiverRepository : CRUDRepository, IEnvelopeReceiverRepository { - public class EnvelopeReceiverRepository : CRUDRepository, IEnvelopeReceiverRepository + public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeReceivers) { - public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeReceivers) - { - } + } - private IQueryable ReadWhere(string? uuid = null, string? signature = null, bool withEnvelope = false, bool withReceiver = false, bool readOnly = true) - { - var query = readOnly ? _dbSet.AsNoTracking() : _dbSet; + private IQueryable ReadWhere(string? uuid = null, string? signature = null, bool withEnvelope = false, bool withReceiver = false, bool readOnly = true) + { + var query = readOnly ? _dbSet.AsNoTracking() : _dbSet; - if (uuid is not null) - query = query.Where(er => er.Envelope != null && er.Envelope.Uuid == uuid); + if (uuid is not null) + query = query.Where(er => er.Envelope != null && er.Envelope.Uuid == uuid); - if (signature is not null) - query = query.Where(er => er.Receiver != null && er.Receiver.Signature == signature); + if (signature is not null) + query = query.Where(er => er.Receiver != null && er.Receiver.Signature == signature); - if (withEnvelope) - query = query - .Include(er => er.Envelope).ThenInclude(e => e!.Documents!).ThenInclude(d => d.Elements!.Where(e => signature == null || e.Receiver!.Signature == signature)) - .Include(er => er.Envelope).ThenInclude(e => e!.History) - .Include(er => er.Envelope).ThenInclude(e => e!.User); + if (withEnvelope) + query = query + .Include(er => er.Envelope).ThenInclude(e => e!.Documents!).ThenInclude(d => d.Elements!.Where(e => signature == null || e.Receiver!.Signature == signature)) + .Include(er => er.Envelope).ThenInclude(e => e!.History) + .Include(er => er.Envelope).ThenInclude(e => e!.User); - if (withReceiver) - query = query.Include(er => er.Receiver); - return query; - } + if (withReceiver) + query = query.Include(er => er.Receiver); + return query; + } - public async Task> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true) - => await ReadWhere(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync(); + public async Task> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true) + => await ReadWhere(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync(); - public async Task> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true) - => await ReadWhere(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync(); + public async Task> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true) + => await ReadWhere(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync(); - public async Task ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) - => await ReadWhere(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).FirstOrDefaultAsync(); + public async Task ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true) + => await ReadWhere(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).FirstOrDefaultAsync(); - public async Task ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true) - => await ReadWhere(uuid: uuid, signature: signature, readOnly: readOnly) - .Select(er => er.AccessCode) - .FirstOrDefaultAsync(); - - public async Task CountAsync(string uuid, string signature) => await ReadWhere(uuid: uuid, signature: signature).CountAsync(); - - private IQueryable ReadById(int envelopeId, int receiverId, bool readOnly = true) - { - var query = readOnly ? _dbSet.AsNoTracking() : _dbSet; - return query.Where(er => er.EnvelopeId == envelopeId && er.ReceiverId == receiverId); - } - - public async Task ReadByIdAsync(int envelopeId, int receiverId, bool readOnly = true) - => await ReadById(envelopeId: envelopeId, receiverId: receiverId, readOnly: readOnly) - .FirstOrDefaultAsync(); - - public async Task ReadAccessCodeByIdAsync(int envelopeId, int receiverId, bool readOnly = true) - => await ReadById(envelopeId: envelopeId, receiverId: receiverId, readOnly: readOnly) + public async Task ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true) + => await ReadWhere(uuid: uuid, signature: signature, readOnly: readOnly) .Select(er => er.AccessCode) .FirstOrDefaultAsync(); - public async Task> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses) - { - var query = _dbSet.AsNoTracking().Where(er => er.Envelope!.User!.Username == username); + public async Task CountAsync(string uuid, string signature) => await ReadWhere(uuid: uuid, signature: signature).CountAsync(); - if (min_status is not null) - query = query.Where(er => er.Envelope!.Status >= min_status); - - if (max_status is not null) - query = query.Where(er => er.Envelope!.Status <= max_status); - - foreach (var ignore_status in ignore_statuses) - query = query.Where(er => er.Envelope!.Status != ignore_status); - - return await query.Include(er => er.Envelope).Include(er => er.Receiver).ToListAsync(); - } - - public async Task ReadLastByReceiver(string email) - { - return await _dbSet.Where(er => er.Receiver!.EmailAddress == email).OrderBy(er => er.EnvelopeId).LastOrDefaultAsync(); - } + private IQueryable ReadById(int envelopeId, int receiverId, bool readOnly = true) + { + var query = readOnly ? _dbSet.AsNoTracking() : _dbSet; + return query.Where(er => er.EnvelopeId == envelopeId && er.ReceiverId == receiverId); } + + public async Task ReadByIdAsync(int envelopeId, int receiverId, bool readOnly = true) + => await ReadById(envelopeId: envelopeId, receiverId: receiverId, readOnly: readOnly) + .FirstOrDefaultAsync(); + + public async Task ReadAccessCodeByIdAsync(int envelopeId, int receiverId, bool readOnly = true) + => await ReadById(envelopeId: envelopeId, receiverId: receiverId, readOnly: readOnly) + .Select(er => er.AccessCode) + .FirstOrDefaultAsync(); + + public async Task> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses) + { + var query = _dbSet.AsNoTracking().Where(er => er.Envelope!.User!.Username == username); + + if (min_status is not null) + query = query.Where(er => er.Envelope!.Status >= min_status); + + if (max_status is not null) + query = query.Where(er => er.Envelope!.Status <= max_status); + + foreach (var ignore_status in ignore_statuses) + query = query.Where(er => er.Envelope!.Status != ignore_status); + + return await query.Include(er => er.Envelope).Include(er => er.Receiver).ToListAsync(); + } + + public async Task ReadLastByReceiver(string email) + { + return await _dbSet.Where(er => er.Receiver!.EmailAddress == email).OrderBy(er => er.EnvelopeId).LastOrDefaultAsync(); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs index bccb6c1b..89f795c2 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs @@ -1,37 +1,36 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; using Microsoft.EntityFrameworkCore; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class ReceiverRepository : CRUDRepository, IReceiverRepository { - public class ReceiverRepository : CRUDRepository, IReceiverRepository + public ReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.Receivers) { - public ReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.Receivers) - { - } - - protected IQueryable ReadBy(string? emailAddress = null, string? signature = null, bool withLastUsedName = true) - { - IQueryable query = _dbSet.AsNoTracking(); - - if(emailAddress is not null) - query = query.Where(r => r.EmailAddress == emailAddress); - - if(signature is not null) - query = query.Where(r => r.Signature == signature); - - // envelope receivers are ignored (with '[JsonIgnore]' attribute). The reson to add them is to get the las used receiver name - if (withLastUsedName) - { - query = query.Include(r => r.EnvelopeReceivers!.OrderByDescending(er => er.EnvelopeId).Take(1)); - } - - return query; - } - - public async Task ReadByAsync(string? emailAddress = null, string? signature = null) => await ReadBy(emailAddress, signature).FirstOrDefaultAsync(); - - public async override Task> ReadAllAsync() => await ReadBy().ToListAsync(); } + + protected IQueryable ReadBy(string? emailAddress = null, string? signature = null, bool withLastUsedName = true) + { + IQueryable query = _dbSet.AsNoTracking(); + + if(emailAddress is not null) + query = query.Where(r => r.EmailAddress == emailAddress); + + if(signature is not null) + query = query.Where(r => r.Signature == signature); + + // envelope receivers are ignored (with '[JsonIgnore]' attribute). The reson to add them is to get the las used receiver name + if (withLastUsedName) + { + query = query.Include(r => r.EnvelopeReceivers!.OrderByDescending(er => er.EnvelopeId).Take(1)); + } + + return query; + } + + public async Task ReadByAsync(string? emailAddress = null, string? signature = null) => await ReadBy(emailAddress, signature).FirstOrDefaultAsync(); + + public async override Task> ReadAllAsync() => await ReadBy().ToListAsync(); } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs index 04bb30fa..4b9f8f22 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs @@ -1,13 +1,12 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; +using EnvelopeGenerator.Application.Contracts.Repositories; -namespace EnvelopeGenerator.Infrastructure.Repositories +namespace EnvelopeGenerator.Infrastructure.Repositories; + +public class UserReceiverRepository : CRUDRepository, IUserReceiverRepository { - public class UserReceiverRepository : CRUDRepository, IUserReceiverRepository + public UserReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.UserReceivers) { - public UserReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.UserReceivers) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/DocumentController.cs b/EnvelopeGenerator.Web/Controllers/DocumentController.cs index 4283997e..67f722a4 100644 --- a/EnvelopeGenerator.Web/Controllers/DocumentController.cs +++ b/EnvelopeGenerator.Web/Controllers/DocumentController.cs @@ -1,10 +1,10 @@ using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; -using EnvelopeGenerator.Application.Contracts; using Microsoft.AspNetCore.Authorization; using EnvelopeGenerator.Extensions; using static EnvelopeGenerator.Common.Constants; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers { diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index 671ec61b..376e1a2d 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -1,5 +1,4 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Authorization; @@ -7,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using System.Text.Encodings.Web; using static EnvelopeGenerator.Common.Constants; using EnvelopeGenerator.Extensions; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers { diff --git a/EnvelopeGenerator.Web/Controllers/HomeController.cs b/EnvelopeGenerator.Web/Controllers/HomeController.cs index f6128743..11c9af8e 100644 --- a/EnvelopeGenerator.Web/Controllers/HomeController.cs +++ b/EnvelopeGenerator.Web/Controllers/HomeController.cs @@ -1,5 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Common; +using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication; @@ -20,6 +19,7 @@ using Newtonsoft.Json; using EnvelopeGenerator.Application.DTOs; using DigitalData.Core.Client; using OtpNet; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers; @@ -62,7 +62,10 @@ public class HomeController : ViewControllerBase ViewData["UserCulture"] = _cultures[UserLanguage]; - return View(); + return View(new MainViewModel() + { + Title = _configuration["MainPageTitle"] + }); } [HttpGet("EnvelopeKey/{envelopeReceiverId}")] @@ -134,18 +137,23 @@ public class HomeController : ViewControllerBase ViewData["UserCulture"] = _cultures[UserLanguage]; return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId).ThenAsync( - Success: er => View() + SuccessAsync: async er => { + if (User.IsInRole(ReceiverRole.FullyAuth)) + return await CreateShowEnvelopeView(envelopeReceiverId, er); + else + return View() .WithData("EnvelopeKey", envelopeReceiverId) .WithData("TFAEnabled", er.Envelope!.TFAEnabled) .WithData("HasPhoneNumber", er.HasPhoneNumber) .WithData("SenderEmail", er.Envelope.User!.Email) - .WithData("EnvelopeTitle", er.Envelope.Title), - Fail: IActionResult (messages, notices) => - { - _logger.LogNotice(notices); - Response.StatusCode = StatusCodes.Status401Unauthorized; - return this.ViewEnvelopeNotFound(); - }); + .WithData("EnvelopeTitle", er.Envelope.Title); + }, + Fail: IActionResult (messages, notices) => + { + _logger.LogNotice(notices); + Response.StatusCode = StatusCodes.Status401Unauthorized; + return this.ViewEnvelopeNotFound(); + }); } catch(Exception ex) { @@ -154,6 +162,63 @@ public class HomeController : ViewControllerBase } } + private async Task CreateShowEnvelopeView(string envelopeReceiverId, EnvelopeReceiverDto er) + { + try + { + ViewData["UserCulture"] = _cultures[UserLanguage]; + ViewData["EnvelopeKey"] = envelopeReceiverId; + + envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId); + (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); + + if (uuid is null || signature is null) + { + _logger.LogEnvelopeError(uuid: uuid, signature: signature, message: _localizer[WebKey.WrongEnvelopeReceiverId]); + return Unauthorized(); + } + + _logger.LogInformation("Envelope UUID: [{uuid}]\nReceiver Signature: [{signature}]", uuid, signature); + + //check access code + EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); + + //check rejection + var rejRcvrs = await _historyService.ReadRejectingReceivers(er.Envelope!.Id); + if (rejRcvrs.Any()) + { + ViewBag.IsExt = !rejRcvrs.Contains(er.Receiver); //external if the current user is not rejected + return View("EnvelopeRejected", er); + } + + //check if it has already signed + if (await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress)) + return View("EnvelopeSigned"); + + if (er.Envelope.Documents?.FirstOrDefault() is EnvelopeDocumentDto doc && doc.ByteData is not null) + { + ViewData["DocumentBytes"] = doc.ByteData; + } + else + { + _logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document byte-data was found in ENVELOPE_DOCUMENT table."); + return this.ViewDocumentNotFound(); + } + + await HttpContext.SignInEnvelopeAsync(er, ReceiverRole.FullyAuth); + + //add PSPDFKit licence key + ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"]; + + return View("ShowEnvelope", er); + } + catch (Exception ex) + { + _logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex); + return this.ViewInnerServiceError(); + } + } + #region TFA Views [NonAction] private async Task TFAViewAsync(bool viaSms, EnvelopeReceiverSecretDto er_secret, string envelopeReceiverId) @@ -287,6 +352,10 @@ public class HomeController : ViewControllerBase } var er_secret = er_secret_res.Data; + // show envelope if already logged in + if (User.IsInRole(ReceiverRole.FullyAuth)) + return await CreateShowEnvelopeView(envelopeReceiverId, er_secret); + if (auth.HasMulti) { return Unauthorized(); @@ -317,46 +386,18 @@ public class HomeController : ViewControllerBase .WithData("EnvelopeTitle", er_secret.Envelope.Title) .WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value); } + + await HttpContext.SignInEnvelopeAsync(er_secret, ReceiverRole.FullyAuth); - //continue the process without important data to minimize security errors. - EnvelopeReceiverDto er = er_secret; - - //check rejection - var rejRcvrs = await _historyService.ReadRejectingReceivers(er.Envelope!.Id); - if(rejRcvrs.Any()) - { - ViewBag.IsExt = !rejRcvrs.Contains(er.Receiver); //external if the current user is not rejected - return View("EnvelopeRejected", er); - } - - //check if it has already signed - if (await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress)) - return View("EnvelopeSigned"); - - if (er.Envelope.Documents?.FirstOrDefault() is EnvelopeDocumentDto doc && doc.ByteData is not null) - { - ViewData["DocumentBytes"] = doc.ByteData; - } - else - { - _logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document byte-data was found in ENVELOPE_DOCUMENT table."); - return this.ViewDocumentNotFound(); - } - - await HttpContext.SignInEnvelopeAsync(er, ReceiverRole.FullyAuth); - - //add PSPDFKit licence key - ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"]; - - return View("ShowEnvelope", er); + return await CreateShowEnvelopeView(envelopeReceiverId, er_secret); } catch (Exception ex) { _logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex); return this.ViewInnerServiceError(); } - } - + } + [Authorize(Roles = ReceiverRole.FullyAuth)] [HttpGet("EnvelopeKey/{envelopeReceiverId}/Success")] public async Task EnvelopeSigned(string envelopeReceiverId) diff --git a/EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs b/EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs index c541b0d1..1b50ce0d 100644 --- a/EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs +++ b/EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/EnvelopeGenerator.Web/Controllers/TFARegController.cs b/EnvelopeGenerator.Web/Controllers/TFARegController.cs index 04832945..97132f76 100644 --- a/EnvelopeGenerator.Web/Controllers/TFARegController.cs +++ b/EnvelopeGenerator.Web/Controllers/TFARegController.cs @@ -1,5 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Web.Models; +using EnvelopeGenerator.Web.Models; using Ganss.Xss; using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Extensions; @@ -9,11 +8,14 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Extensions; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Authorization; +using static EnvelopeGenerator.Common.Constants; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers; //TODO: Add authorization as well as limiting the link duration (intermediate token with different role) or sign it -[Route("tfa")] public class TFARegController : ViewControllerBase { private readonly IEnvelopeReceiverService _envRcvService; @@ -29,8 +31,9 @@ public class TFARegController : ViewControllerBase _params = tfaRegParamsOptions.Value; } + //TODO: move under auth route [Authorize] - [HttpGet("{envelopeReceiverId}")] + [HttpGet("tfa/{envelopeReceiverId}")] public async Task Reg(string envelopeReceiverId) { try @@ -84,4 +87,20 @@ public class TFARegController : ViewControllerBase return this.ViewInnerServiceError(); } } + + [Authorize(Roles = ReceiverRole.FullyAuth)] + [HttpPost("auth/logout")] + public async Task LogOut() + { + try + { + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + return Ok(); + } + catch(Exception ex) + { + _logger.LogError(ex, "{message}", ex.Message); + return this.ViewInnerServiceError(); + } + } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs index 0117f542..e9b27a37 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs @@ -1,7 +1,7 @@ -using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using DigitalData.Core.API; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers.Test { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs index afa8fddd..0dbe820d 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentReceiverElementController.cs @@ -1,16 +1,13 @@ -using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; -namespace EnvelopeGenerator.Web.Controllers.Test +namespace EnvelopeGenerator.Web.Controllers.Test; + +public class TestDocumentReceiverElementController : TestControllerBase { - public class TestDocumentReceiverElementController : TestControllerBase + public TestDocumentReceiverElementController(ILogger logger, IDocumentReceiverElementService service) : base(logger, service) { - public TestDocumentReceiverElementController(ILogger logger, IDocumentReceiverElementService service) : base(logger, service) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs index 7f00ebef..ab5d0478 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestDocumentStatusController.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs index 9577d504..47a943f1 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEmailTemplateController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Mvc; diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs index 8ae92c8e..a7f8778a 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeCertificateController.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs index ea2b25f7..24118798 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeController.cs @@ -1,8 +1,8 @@ -using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Extensions; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers.Test { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs index 74e06892..f1a1c952 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeDocumentController.cs @@ -1,16 +1,13 @@ -using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; -namespace EnvelopeGenerator.Web.Controllers.Test +namespace EnvelopeGenerator.Web.Controllers.Test; + +public class TestEnvelopeDocumentController : TestControllerBase { - public class TestEnvelopeDocumentController : TestControllerBase + public TestEnvelopeDocumentController(ILogger logger, IEnvelopeDocumentService service) : base(logger, service) { - public TestEnvelopeDocumentController(ILogger logger, IEnvelopeDocumentService service) : base(logger, service) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs index f233fd2b..c840b2fe 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeHistoryController.cs @@ -1,37 +1,35 @@ using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.AspNetCore.Mvc; -namespace EnvelopeGenerator.Web.Controllers.Test +namespace EnvelopeGenerator.Web.Controllers.Test; + +public class TestEnvelopeHistoryController : CRUDControllerBase { - public class TestEnvelopeHistoryController : CRUDControllerBase + public TestEnvelopeHistoryController(ILogger logger, IEnvelopeHistoryService service) : base(logger, service) { - public TestEnvelopeHistoryController(ILogger logger, IEnvelopeHistoryService service) : base(logger, service) - { - } - - [HttpGet("Count")] - public async Task Count(int? envelopeId = null, string? userReference = null, int? status = null) - { - return Ok(await _service.CountAsync(envelopeId, userReference, status)); - } - - [HttpGet("is-ac-req")] - public async Task AccessCodeAlreadyRequested(int envelopeId, string userReference) - { - return Ok(await _service.AccessCodeAlreadyRequested(envelopeId, userReference)); - } - - [HttpGet] - public async Task GetAsyncWith(int? envelopeId = null, string? userReference = null, int? status = null) - { - return Ok(await _service.ReadAsync(envelopeId: envelopeId, userReference: userReference, status: status)); - } - - [NonAction] - public override Task GetAll() => base.GetAll(); } + + [HttpGet("Count")] + public async Task Count(int? envelopeId = null, string? userReference = null, int? status = null) + { + return Ok(await _service.CountAsync(envelopeId, userReference, status)); + } + + [HttpGet("is-ac-req")] + public async Task AccessCodeAlreadyRequested(int envelopeId, string userReference) + { + return Ok(await _service.AccessCodeAlreadyRequested(envelopeId, userReference)); + } + + [HttpGet] + public async Task GetAsyncWith(int? envelopeId = null, string? userReference = null, int? status = null) + { + return Ok(await _service.ReadAsync(envelopeId: envelopeId, userReference: userReference, status: status)); + } + + [NonAction] + public override Task GetAll() => base.GetAll(); } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs index 47f958b2..5b0327eb 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using Microsoft.AspNetCore.Mvc; using System.Net; diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs index 9c95ff17..be8362c5 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs @@ -1,10 +1,10 @@ using DigitalData.Core.API; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Extensions; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Mvc; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using EnvelopeGenerator.Application.Contracts.Services; namespace EnvelopeGenerator.Web.Controllers.Test { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs index bb45ce8d..93cc9253 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeTypeController.cs @@ -1,16 +1,13 @@ -using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; -namespace EnvelopeGenerator.Web.Controllers.Test +namespace EnvelopeGenerator.Web.Controllers.Test; + +public class TestEnvelopeTypeController : TestControllerBase { - public class TestEnvelopeTypeController : TestControllerBase + public TestEnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) : base(logger, service) { - public TestEnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) : base(logger, service) - { - } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestMessagingController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestMessagingController.cs index ac4555e1..0682ea70 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestMessagingController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestMessagingController.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Web.Controllers.Test diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs index ff1a6a4f..85fe012b 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestReceiverController.cs @@ -1,5 +1,5 @@ using DigitalData.Core.API; -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Domain.Entities; diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs index 1d0f0195..98af1632 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestUserReceiverController.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index d64f6c49..4ad7af34 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -5,7 +5,7 @@ enable enable EnvelopeGenerator.Web - 2.10.4 + 2.11.0 Digital Data GmbH Digital Data GmbH EnvelopeGenerator.Web @@ -13,8 +13,8 @@ digital data envelope generator web EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly. Assets\icon.ico - 2.10.4 - 2.10.4 + 2.11.0 + 2.11.0 Copyright © 2024 Digital Data GmbH. All rights reserved. diff --git a/EnvelopeGenerator.Web/Models/CustomImages.cs b/EnvelopeGenerator.Web/Models/CustomImages.cs new file mode 100644 index 00000000..da0d6502 --- /dev/null +++ b/EnvelopeGenerator.Web/Models/CustomImages.cs @@ -0,0 +1,6 @@ +namespace EnvelopeGenerator.Web.Models; + +public class CustomImages : Dictionary +{ + public new Image this[string key] => TryGetValue(key, out var img) && img is not null ? img : new(); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Models/Image.cs b/EnvelopeGenerator.Web/Models/Image.cs new file mode 100644 index 00000000..5c993e27 --- /dev/null +++ b/EnvelopeGenerator.Web/Models/Image.cs @@ -0,0 +1,10 @@ +namespace EnvelopeGenerator.Web.Models; + +public class Image +{ + public string Src { get; init; } = string.Empty; + + public Dictionary Classes { get; init; } = new(); + + public string GetClassIn(string page) => Classes.TryGetValue(page, out var cls) && cls is not null ? cls : string.Empty; +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Models/Logo.cs b/EnvelopeGenerator.Web/Models/Logo.cs deleted file mode 100644 index 7b92d8a3..00000000 --- a/EnvelopeGenerator.Web/Models/Logo.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace EnvelopeGenerator.Web.Models -{ - public class Logo - { - public string Src { get; init; } = string.Empty; - - public string LockedPageClass { get; init; } = string.Empty; - - public string ShowPageClass { get; init; } = string.Empty; - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Models/MainViewModel.cs b/EnvelopeGenerator.Web/Models/MainViewModel.cs new file mode 100644 index 00000000..f69b01f6 --- /dev/null +++ b/EnvelopeGenerator.Web/Models/MainViewModel.cs @@ -0,0 +1,6 @@ +namespace EnvelopeGenerator.Web.Models; + +public class MainViewModel +{ + public string? Title { get; init; } +} diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs index 35b12185..9c61127c 100644 --- a/EnvelopeGenerator.Web/Program.cs +++ b/EnvelopeGenerator.Web/Program.cs @@ -1,4 +1,3 @@ -using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Services; using EnvelopeGenerator.Web.Services; using Microsoft.EntityFrameworkCore; @@ -15,7 +14,7 @@ using EnvelopeGenerator.Application; using DigitalData.EmailProfilerDispatcher; using EnvelopeGenerator.Infrastructure; using EnvelopeGenerator.Web.Sanitizers; -using EnvelopeGenerator.Application.Extensions; +using EnvelopeGenerator.Application.Contracts.Services; var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); logger.Info("Logging initialized!"); @@ -162,7 +161,7 @@ try builder.Services.AddMemoryCache(); - builder.ConfigureBySection(); + builder.ConfigureBySection(); var app = builder.Build(); diff --git a/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs b/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs index 8dcd4d61..4cd175e2 100644 --- a/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs +++ b/EnvelopeGenerator.Web/Services/EnvelopeOldService.cs @@ -1,4 +1,4 @@ -using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Common; using System.Text; diff --git a/EnvelopeGenerator.Web/Views/Home/EnvelopeLocked.cshtml b/EnvelopeGenerator.Web/Views/Home/EnvelopeLocked.cshtml index 008209a2..59824058 100644 --- a/EnvelopeGenerator.Web/Views/Home/EnvelopeLocked.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/EnvelopeLocked.cshtml @@ -4,7 +4,7 @@ @{ //TODO: Create view model var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; - var logo = _logoOpt.Value; + var cImg = _cImgOpt.Value; ViewData["Title"] = _localizer[WebKey.DocProtected]; var userCulture = ViewData["UserCulture"] as Culture; string codeType = ViewData["CodeType"] is string _codeType ? _codeType : "accessCode"; @@ -24,7 +24,7 @@
diff --git a/EnvelopeGenerator.Web/Views/Home/Main.cshtml b/EnvelopeGenerator.Web/Views/Home/Main.cshtml index 0cad22d5..801ecb7f 100644 --- a/EnvelopeGenerator.Web/Views/Home/Main.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/Main.cshtml @@ -1,6 +1,7 @@ @{ + @model MainViewModel var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; - var logo = _logoOpt.Value; + var cImg = _cImgOpt.Value; ViewData["Title"] = _localizer["Home"]; var userCulture = ViewData["UserCulture"] as Culture; } @@ -8,12 +9,15 @@
- +
-

signFlow

+ @if(Model.Title is string title) + { +

@title

+ }

@($"{envelope?.Title}".TrySanitize(_sanitizer))

@if (isReadOnly) diff --git a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml index 5a19cc58..0d07d11e 100644 --- a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml +++ b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml @@ -11,5 +11,5 @@ @inject HighlightHtmlSanitizer _hlSanitizer @inject Microsoft.AspNetCore.Http.IHttpContextAccessor _accessor @inject Cultures _cultures -@inject IOptions _logoOpt +@inject IOptions _cImgOpt @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers \ No newline at end of file diff --git a/EnvelopeGenerator.Web/appsettings.json b/EnvelopeGenerator.Web/appsettings.json index 0fb9d4ea..59f07e6a 100644 --- a/EnvelopeGenerator.Web/appsettings.json +++ b/EnvelopeGenerator.Web/appsettings.json @@ -103,10 +103,20 @@ "Platforms": [ "javascript" ] } ], - "Logo": { - "Src": "/img/digital_data.svg", - "ShowPageClass": "dd-show-logo", - "LockedPageClass": "dd-locked-logo" + "CustomImages": { + "App": { + "Src": "/img/DD_signFLOW_LOGO.png", + "Classes": { + "Main": "signFlow-logo" + } + }, + "Company": { + "Src": "/img/digital_data.svg", + "Classes": { + "Show": "dd-show-logo", + "Locked": "dd-locked-logo" + } + } }, "DispatcherParams": { "SendingProfile": 1, @@ -131,5 +141,13 @@ }, "TFARegParams": { "TimeLimit": "00:30:00" - } -} \ No newline at end of file + }, + "DbTriggerParams": { + "Envelope": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ], + "EnvelopeHistory": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ], + "EmailOut": [ "TBEMLP_EMAIL_OUT_AFT_INS", "TBEMLP_EMAIL_OUT_AFT_UPD" ], + "EnvelopeReceiverReadOnly": [ "TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD" ], + "Receiver": [] + }, + "MainPageTitle": null +} diff --git a/EnvelopeGenerator.Web/wwwroot/css/logo.css b/EnvelopeGenerator.Web/wwwroot/css/logo.css index 86ce775a..ee066cf2 100644 --- a/EnvelopeGenerator.Web/wwwroot/css/logo.css +++ b/EnvelopeGenerator.Web/wwwroot/css/logo.css @@ -30,4 +30,8 @@ .cursor-show-logo { width: 3rem; } +} + +.signFlow-logo { + width: 9rem; } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/css/logo.min.css b/EnvelopeGenerator.Web/wwwroot/css/logo.min.css index a1da6147..6b9a4f97 100644 --- a/EnvelopeGenerator.Web/wwwroot/css/logo.min.css +++ b/EnvelopeGenerator.Web/wwwroot/css/logo.min.css @@ -1 +1 @@ -.dd-locked-logo{width:13rem;padding-top:1rem}.dd-show-logo{width:9rem;position:absolute;right:0;margin:0 2rem 0 0;padding:0;top:0}.cursor-locked-logo{width:9rem;padding-top:1rem}.cursor-show-logo{width:6rem}@media(max-width:767px){.dd-show-logo{width:5rem;margin-right:0}.cursor-show-logo{width:3rem}} \ No newline at end of file +.dd-locked-logo{width:13rem;padding-top:1rem}.dd-show-logo{width:9rem;position:absolute;right:0;margin:0 2rem 0 0;padding:0;top:0}.cursor-locked-logo{width:9rem;padding-top:1rem}.cursor-show-logo{width:6rem}@media(max-width:767px){.dd-show-logo{width:5rem;margin-right:0}.cursor-show-logo{width:3rem}}.signFlow-logo{width:9rem} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/img/DD_signFLOW_LOGO.png b/EnvelopeGenerator.Web/wwwroot/img/DD_signFLOW_LOGO.png new file mode 100644 index 00000000..3915f137 Binary files /dev/null and b/EnvelopeGenerator.Web/wwwroot/img/DD_signFLOW_LOGO.png differ diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js b/EnvelopeGenerator.Web/wwwroot/js/app.js index bddb55b8..883f171f 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js @@ -211,6 +211,9 @@ class App { // Show the modal Comp.ShareBackdrop.show(); break; + case 'LOGOUT': + await logout(); + break; } } diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.min.js b/EnvelopeGenerator.Web/wwwroot/js/app.min.js index bd2d1384..ba32108f 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.min.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.min.js @@ -1,3 +1,3 @@ const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Network=new Network;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await Annotation.createAnnotations(this.currentDocument,this.Instance);const n=await this.Network.openDocument(this.envelopeKey);if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht geöffnet werden!",icon:"error"})}catch(i){}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await Annotation.createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=Annotation.createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/EnvelopeKey/${this.envelopeKey}/Success`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`
${localized.rejectionReasonQ}
`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(` Request failed: ${t} - `)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>Annotation.isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>Annotation.isCityField(n));for(var i of e)if(!IS_MOBILE_DEVICE&&!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`
${localized.sigAgree}
`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await Annotation.getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await Annotation.deleteAnnotations(this.Instance)}return n}} \ No newline at end of file + `)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>Annotation.isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>Annotation.isCityField(n));for(var i of e)if(!IS_MOBILE_DEVICE&&!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`
${localized.sigAgree}
`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await Annotation.getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await Annotation.deleteAnnotations(this.Instance)}return n}} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/network.js b/EnvelopeGenerator.Web/wwwroot/js/network.js index 8153c853..ab10e929 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/network.js +++ b/EnvelopeGenerator.Web/wwwroot/js/network.js @@ -194,4 +194,16 @@ async function setLanguage(language) { else if (!response.ok) return Promise.reject('Failed to set language'); }); +} + +async function logout() { + return await fetch(`/auth/logout`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }).then(res => { + if (res.ok) + window.location.href = "/"; + }); } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/network.min.js b/EnvelopeGenerator.Web/wwwroot/js/network.min.js index c6806615..6666c294 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/network.min.js +++ b/EnvelopeGenerator.Web/wwwroot/js/network.min.js @@ -1 +1 @@ -async function setLangAsync(n,t){document.getElementById("selectedFlag").className="fi "+t+" me-2";await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}})}async function setLanguage(n){const t=await fetch("/lang",{method:"GET",headers:{"Content-Type":"application/json"}}).then(n=>n.json()).then(t=>t.includes(n)).catch(()=>!1);if(t)return await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{if(n.redirected)window.location.href=n.url;else if(!n.ok)return Promise.reject("Failed to set language")})}class Network{async getEnvelope(n){return this.getRequest(`/api/envelope/${n}`).then(this.wrapJsonResponse.bind(this))}async postEnvelope(n,t,i){return this.postRequest(`/api/envelope/${n}?index=${t}`,i).then(this.wrapJsonResponse.bind(this))}async getDocument(n,t){return this.getRequest(`/api/document/${n}?index=${t}`).then(this.wrapBinaryResponse.bind(this))}async openDocument(n){return this.postRequest(`/api/document/${n}`,{}).then(this.wrapJsonResponse.bind(this))}withCSRFToken(n){const t=getCSRFToken;let i=n.headers;return n.headers={...i,...t},n}getCSRFToken(){const n=document.getElementsByName("__RequestVerificationToken")[0].value;return{"X-XSRF-TOKEN":n}}getRequest(n,t){const r=this.getCSRFToken(),i={credentials:"include",method:"GET",headers:{...r}};return t!==undefined&&(i.body=JSON.stringify(t)),fetch(n,i)}postRequest(n,t){const i=this.getCSRFToken(),r={credentials:"include",method:"POST",headers:{...i,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(t)};return fetch(n,r)}async wrapJsonResponse(n){return await this.wrapResponse(n,async n=>await n.json())}async wrapBinaryResponse(n){return await this.wrapResponse(n,async n=>await n.arrayBuffer())}async wrapResponse(n,t){let i;if(n.status===200){const r=await t(n);i=new WrappedResponse(r,null)}else if(n.status===403){const t=await n.json();i=new WrappedResponse(null,t)}else i=new WrappedResponse(null,null);return i}}class WrappedResponse{constructor(n,t){this.data=n;this.error=t;this.fatal=n===null&&t===null}} \ No newline at end of file +async function setLangAsync(n,t){document.getElementById("selectedFlag").className="fi "+t+" me-2";await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}})}async function setLanguage(n){const t=await fetch("/lang",{method:"GET",headers:{"Content-Type":"application/json"}}).then(n=>n.json()).then(t=>t.includes(n)).catch(()=>!1);if(t)return await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{if(n.redirected)window.location.href=n.url;else if(!n.ok)return Promise.reject("Failed to set language")})}async function logout(){return await fetch(`/auth/logout`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{n.ok&&(window.location.href="/")})}class Network{async getEnvelope(n){return this.getRequest(`/api/envelope/${n}`).then(this.wrapJsonResponse.bind(this))}async postEnvelope(n,t,i){return this.postRequest(`/api/envelope/${n}?index=${t}`,i).then(this.wrapJsonResponse.bind(this))}async getDocument(n,t){return this.getRequest(`/api/document/${n}?index=${t}`).then(this.wrapBinaryResponse.bind(this))}async openDocument(n){return this.postRequest(`/api/document/${n}`,{}).then(this.wrapJsonResponse.bind(this))}withCSRFToken(n){const t=getCSRFToken;let i=n.headers;return n.headers={...i,...t},n}getCSRFToken(){const n=document.getElementsByName("__RequestVerificationToken")[0].value;return{"X-XSRF-TOKEN":n}}getRequest(n,t){const r=this.getCSRFToken(),i={credentials:"include",method:"GET",headers:{...r}};return t!==undefined&&(i.body=JSON.stringify(t)),fetch(n,i)}postRequest(n,t){const i=this.getCSRFToken(),r={credentials:"include",method:"POST",headers:{...i,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(t)};return fetch(n,r)}async wrapJsonResponse(n){return await this.wrapResponse(n,async n=>await n.json())}async wrapBinaryResponse(n){return await this.wrapResponse(n,async n=>await n.arrayBuffer())}async wrapResponse(n,t){let i;if(n.status===200){const r=await t(n);i=new WrappedResponse(r,null)}else if(n.status===403){const t=await n.json();i=new WrappedResponse(null,t)}else i=new WrappedResponse(null,null);return i}}class WrappedResponse{constructor(n,t){this.data=n;this.error=t;this.fatal=n===null&&t===null}} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/ui.js b/EnvelopeGenerator.Web/wwwroot/js/ui.js index 8d92422e..df127c46 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/ui.js +++ b/EnvelopeGenerator.Web/wwwroot/js/ui.js @@ -89,6 +89,26 @@ icon: ` `, + }, + { + type: 'custom', + id: 'button-logout', + className: 'button-logout', + title: 'logout', + onPress() { + callback('LOGOUT') + }, + icon: ` + + + ` + }, + { + type: 'custom', + id: 'mock', + className: 'mock', + title: 'Mock', + icon: `` } ]; } diff --git a/EnvelopeGenerator.Web/wwwroot/js/ui.min.js b/EnvelopeGenerator.Web/wwwroot/js/ui.min.js index 1407adb7..6eb1d326 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/ui.min.js +++ b/EnvelopeGenerator.Web/wwwroot/js/ui.min.js @@ -1,7 +1,10 @@ class UI{static allowedToolbarItems=["sidebar-thumbnails","sidebar-document-ouline","sidebar-bookmarks","pager","pan","zoom-out","zoom-in","zoom-mode","spacer","search","export-pdf"];static Instance static loadPSPDFKit(n,t,i,r){return UI.Instance=PSPDFKit.load({inlineWorkers:!1,locale:r,licenseKey:i,styleSheets:["/css/site.css"],container:t,document:n,annotationPresets:UI.getPresets(),electronicSignatures:{creationModes:["DRAW","TYPE","IMAGE"]},initialViewState:new PSPDFKit.ViewState({sidebarMode:PSPDFKit.SidebarMode.THUMBNAILS}),isEditableAnnotation:function(n){return n.isSignature||n.description=="FRAME"?!1:!0},customRenderers:{Annotation:UI.annotationRenderer}}),UI.Instance}static addToolbarItems(n,t){var i=n.toolbarItems.filter(n=>UI.allowedToolbarItems.includes(n.type));i=IS_READONLY?i.concat(UI.getReadOnlyItems(t)):i.concat(UI.getWritableItems(t));IS_DESKTOP_SIZE||IS_READONLY||(i=i.concat(UI.getMobileWritableItems(t)));n.setToolbarItems(i)}static annotationRenderer(){return null}static createElementFromHTML(n){const t=document.createElement("div");return t.innerHTML=n.trim(),t.firstChild}static getWritableItems=function(n){return[{type:"custom",id:"button-share",className:"button-share",title:"Teilen",onPress(){n("SHARE")},icon:` - `}]};static getReadOnlyItems=function(n){return[{type:"custom",id:"button-copy-url",className:"button-copy-url",title:"Teilen",onPress(){n("COPY_URL")},icon:` + `},{type:"custom",id:"button-logout",className:"button-logout",title:"logout",onPress(){n("LOGOUT")},icon:` + + + `},{type:"custom",id:"mock",className:"mock",title:"Mock",icon:``}]};static getReadOnlyItems=function(n){return[{type:"custom",id:"button-copy-url",className:"button-copy-url",title:"Teilen",onPress(){n("COPY_URL")},icon:` `}]};static getMobileWritableItems=function(n){return[{type:"custom",id:"button-finish",className:"button-finish",onPress(){n("FINISH")},icon:`