8 Commits

2677 changed files with 23464 additions and 48789 deletions

2
.gitignore vendored
View File

@@ -363,5 +363,3 @@ MigrationBackup/
FodyWeavers.xsd
/EnvelopeGenerator.Web/.config/dotnet-tools.json
/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/.vscode
/EnvelopeGenerator.Tests.Application/Services/BugFixTests.cs
/EnvelopeGenerator.Tests.Application/annotations.json

View File

@@ -1,33 +0,0 @@
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
///
/// </summary>
public class AuthenticatorParams
{
/// <summary>
/// Default value is 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789012345678901234567890123456789'
/// </summary>
public string CharPool { get; init; } = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789012345678901234567890123456789";
//TODO: Increase the DefaultTotpSecretKeyLength (e.g. to 32) but make sure that the QR code is generated correctly and can be scanned by the authenticator.
/// <summary>
/// Default value is 20
/// </summary>
public int DefaultTotpSecretKeyLength { get; init; } = 20;
/// <summary>
/// Default value is
/// </summary>
public string TotpIssuer { get; init; } = "signFlow";
/// <summary>
/// 0 is user email, 1 is secret key and 2 is issuer.
/// </summary>
public string TotpUrlFormat { get; init; } = "otpauth://totp/{0}?secret={1}&issuer={2}";
/// <summary>
/// Default value is 20.
/// </summary>
public int TotpQRPixelsPerModule { get; init; } = 20;
}

View File

@@ -1,8 +0,0 @@
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
///
/// </summary>
public class DbTriggerParams : Dictionary<string, ICollection<string>>
{
}

View File

@@ -0,0 +1,13 @@
namespace EnvelopeGenerator.Application.Configurations
{
public class DispatcherConfig
{
public int SendingProfile { get; init; } = 1;
public string AddedWho { get; init; } = "DDEnvelopGenerator";
public int ReminderTypeId { get; init; } = 202377;
public string EmailAttmt1 { get; init; } = string.Empty;
}
}

View File

@@ -1,27 +0,0 @@
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
///
/// </summary>
public class DispatcherParams
{
/// <summary>
/// Default value is 1
/// </summary>
public int SendingProfile { get; init; } = 1;
/// <summary>
/// Defalt value is 'DDEnvelopGenerator'
/// </summary>
public string AddedWho { get; init; } = "DDEnvelopGenerator";
/// <summary>
/// Default value is 202377
/// </summary>
public int ReminderTypeId { get; init; } = 202377;
/// <summary>
/// Default value is string.Empty
/// </summary>
public string EmailAttmt1 { get; init; } = string.Empty;
}

View File

@@ -1,37 +0,0 @@
using DigitalData.Core.Client.Interface;
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
/// https://www.gtx-messaging.com/en/api-docs/sms-rest-api/
/// </summary>
public class GtxMessagingParams : IHttpClientOptions
{
/// <summary>
///
/// </summary>
public required string Uri { get; init; }
/// <summary>
///
/// </summary>
public string? Path { get; init; }
/// <summary>
///
/// </summary>
public Dictionary<string, object>? Headers { get; init; }
/// <summary>
///
/// </summary>
public Dictionary<string, object?>? QueryParams { get; init; }
/// <summary>
/// Default value is 'to'
/// </summary>
public string RecipientQueryParamName { get; init; } = "to";
/// <summary>
/// Default value is 'text'
/// </summary>
public string MessageQueryParamName { get; init; } = "text";
}

View File

@@ -0,0 +1,7 @@
namespace EnvelopeGenerator.Application.Configurations
{
public class MailConfig
{
public required Dictionary<string, string> Placeholders { get; init; }
}
}

View File

@@ -1,12 +0,0 @@
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
///
/// </summary>
public class MailParams
{
/// <summary>
///
/// </summary>
public required Dictionary<string, string> Placeholders { get; init; }
}

View File

@@ -1,81 +0,0 @@
using OtpNet;
using System.Globalization;
namespace EnvelopeGenerator.Application.Configurations;
/// <summary>
///
/// </summary>
public class TotpSmsParams
{
/// <summary>
/// The unit is second.
/// </summary>
public int TotpStep { get; init; } = 90;
/// <summary>
/// Default value is 'Ihr 2FA-Passwort lautet {0}. Gültig bis {1}'
/// </summary>
public string Format { get; init; } = "Ihr 2FA-Passwort lautet {0}. Gültig bis {1}";
/// <summary>
///
/// </summary>
public ExpirationHandler Expiration { get; init; } = new();
/// <summary>
/// Default value is VerificationWindow.RfcSpecifiedNetworkDelay
/// </summary>
public VerificationWindow? TotpVerificationWindow { get; private init; } = VerificationWindow.RfcSpecifiedNetworkDelay;
private IEnumerable<int>? _tvwParams;
/// <summary>
///
/// </summary>
public IEnumerable<int>? TotpVerificationWindowParams
{
get => _tvwParams;
init
{
_tvwParams = value;
if(_tvwParams is not null)
TotpVerificationWindow = new(previous: _tvwParams.ElementAtOrDefault(0), future: _tvwParams.ElementAtOrDefault(0));
}
}
/// <summary>
///
/// </summary>
public class ExpirationHandler
{
/// <summary>
/// Default value is 'e{0}_r{1}_sms_code_expiration'
/// </summary>
public string CacheKeyFormat { get; init; } = "e{0}_r{1}_sms_code_expiration";
/// <summary>
/// Default value is HH:mm:ss
/// </summary>
public string Format { get; init; } = "HH:mm:ss";
/// <summary>
/// Default value is 'de-DE'
/// </summary>
public string CultureName
{
get => _cultureInfo.Name;
init => _cultureInfo = new(value);
}
/// <summary>
/// Default value is 'de-DE'
/// </summary>
private CultureInfo _cultureInfo = new("de-DE");
/// <summary>
/// Default value is 'de-DE'
/// </summary>
public CultureInfo CultureInfo => _cultureInfo;
}
}

View File

@@ -0,0 +1,17 @@
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<ConfigDto, Config, int>
{
Task<DataResult<ConfigDto>> ReadFirstAsync();
Task<ConfigDto> ReadDefaultAsync();
Task<string> ReadDefaultSignatureHost();
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IDocumentReceiverElementService : IBasicCRUDService<DocumentReceiverElementDto, DocumentReceiverElement, int>
{
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IDocumentStatusService : IBasicCRUDService<DocumentStatusDto, DocumentStatus, int>
{
}
}

View File

@@ -0,0 +1,13 @@
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<EmailTemplateDto, EmailTemplate, int>
{
Task<DataResult<EmailTemplateDto>> ReadByNameAsync(EmailTemplateType type);
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IEnvelopeCertificateService : IBasicCRUDService<EnvelopeCertificateDto, EnvelopeCertificate, int>
{
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IEnvelopeDocumentService : IBasicCRUDService<EnvelopeDocumentDto, EnvelopeDocument, int>
{
}
}

View File

@@ -0,0 +1,28 @@
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<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>
{
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null);
Task<bool> AccessCodeAlreadyRequested(int envelopeId, string userReference);
Task<bool> IsSigned(int envelopeId, string userReference);
Task<bool> IsRejected(int envelopeId, string? userReference = null);
Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false);
Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null);
Task<IEnumerable<ReceiverReadDto>> ReadRejectingReceivers(int envelopeId);
Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null);
}
}

View File

@@ -0,0 +1,17 @@
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<DataResult<int>> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType);
Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto);
Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>
{
}
}

View File

@@ -0,0 +1,34 @@
using DigitalData.Core.Abstractions.Application;
using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDto, EnvelopeReceiver, (int Envelope, int Receiver)>
{
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false);
Task<DataResult<IEnumerable<EnvelopeReceiverSecretDto>>> ReadSecretByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true);
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true);
Task<DataResult<EnvelopeReceiverDto>> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true);
Task<DataResult<EnvelopeReceiverDto>> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true);
Task<DataResult<string>> ReadAccessCodeByIdAsync(int envelopeId, int receiverId);
Task<DataResult<bool>> VerifyAccessCodeAsync(string uuid, string signature, string accessCode);
Task<DataResult<bool>> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode);
Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
Task<DataResult<string?>> ReadLastUsedReceiverNameByMail(string mail);
}
}

View File

@@ -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
{
public interface IEnvelopeService : IBasicCRUDService<EnvelopeDto, Envelope, int>
{
Task<DataResult<IEnumerable<EnvelopeDto>>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false);
Task<DataResult<EnvelopeDto>> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false);
Task<DataResult<IEnumerable<EnvelopeDto>>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[]ignore_statuses);
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IEnvelopeTypeService : IBasicCRUDService<EnvelopeTypeDto, EnvelopeType, int>
{
}
}

View File

@@ -0,0 +1,24 @@
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IJWTService<TClaimValue>
{
public static SymmetricSecurityKey GenerateSecurityKey(int byteSize = 32)
{
using var rng = RandomNumberGenerator.Create();
var randomBytes = new byte[byteSize];
rng.GetBytes(randomBytes);
var securityKey = new SymmetricSecurityKey(randomBytes);
return securityKey;
}
string GenerateToken(TClaimValue claimValue);
JwtSecurityToken? ReadSecurityToken(string token);
}
}

View File

@@ -0,0 +1,14 @@
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<ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>
{
public Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null);
public Task<Result> DeleteByAsync(string? emailAddress = null, string? signature = null);
}
}

View File

@@ -0,0 +1,10 @@
using DigitalData.Core.Abstractions.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts
{
public interface IUserReceiverService : IBasicCRUDService<UserReceiverDto, UserReceiver, int>
{
}
}

View File

@@ -1,17 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IConfigRepository : ICRUDRepository<Config, int>
{
/// <summary>
///
/// </summary>
/// <returns></returns>
Task<Config?> ReadFirstAsync();
}

View File

@@ -1,11 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IDocumentReceiverElementRepository : ICRUDRepository<DocumentReceiverElement, int>
{
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IDocumentStatusRepository : ICRUDRepository<DocumentStatus, int>
{
}

View File

@@ -1,19 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEmailTemplateRepository : ICRUDRepository<EmailTemplate, int>
{
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
Task<EmailTemplate?> ReadByNameAsync(EmailTemplateType type);
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public interface IEnvelopeCertificateRepository : ICRUDRepository<EnvelopeCertificate, int>
{
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeDocumentRepository : ICRUDRepository<EnvelopeDocument, int>
{
}

View File

@@ -1,32 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeHistoryRepository : ICRUDRepository<EnvelopeHistory, long>
{
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <param name="status"></param>
/// <returns></returns>
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, Constants.EnvelopeStatus? status = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <param name="status"></param>
/// <param name="withSender"></param>
/// <param name="withReceiver"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeHistory>> ReadAsync(int? envelopeId = null, string? userReference = null, Constants.EnvelopeStatus? status = null, bool withSender = false, bool withReceiver = false);
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeReceiverReadOnlyRepository : ICRUDRepository<EnvelopeReceiverReadOnly, long>
{
}

View File

@@ -1,96 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeReceiverRepository : ICRUDRepository<EnvelopeReceiver, (int Envelope, int Receiver)>
{
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeReceiver>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="signature"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeReceiver>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<EnvelopeReceiver?> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<string?> ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<int> CountAsync(string uuid, string signature);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="receiverId"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<EnvelopeReceiver?> ReadByIdAsync(int envelopeId, int receiverId, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="receiverId"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<string?> ReadAccessCodeByIdAsync(int envelopeId, int receiverId, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="username"></param>
/// <param name="min_status"></param>
/// <param name="max_status"></param>
/// <param name="ignore_statuses"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeReceiver>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
/// <summary>
///
/// </summary>
/// <param name="email"></param>
/// <param name="id"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<EnvelopeReceiver?> ReadLastByReceiverAsync(string? email = null, int? id = null, string? signature = null);
}

View File

@@ -1,42 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeRepository : ICRUDRepository<Envelope, int>
{
/// <summary>
///
/// </summary>
/// <param name="documents"></param>
/// <param name="history"></param>
/// <param name="documentReceiverElement"></param>
/// <returns></returns>
Task<IEnumerable<Envelope>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="withDocuments"></param>
/// <param name="withHistory"></param>
/// <param name="withDocumentReceiverElement"></param>
/// <param name="withUser"></param>
/// <param name="withAll"></param>
/// <returns></returns>
Task<Envelope?> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false);
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <param name="min_status"></param>
/// <param name="max_status"></param>
/// <param name="ignore_statuses"></param>
/// <returns></returns>
Task<IEnumerable<Envelope>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IEnvelopeTypeRepository : ICRUDRepository<EnvelopeType, int>
{
}

View File

@@ -1,19 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Repositories;
/// <summary>
///
/// </summary>
[Obsolete("Use IRepository")]
public interface IReceiverRepository : ICRUDRepository<Receiver, int>
{
/// <summary>
///
/// </summary>
/// <param name="emailAddress"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<Receiver?> ReadByAsync(string? emailAddress = null, string? signature = null);
}

View File

@@ -1,18 +0,0 @@
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
///
/// </summary>
public interface IDocumentExecutor
{
/// <summary>
///
/// </summary>
/// <param name="base64"></param>
/// <param name="envelope_uuid"></param>
/// <param name="cancellation"></param>
/// <returns></returns>
Task<EnvelopeDocument> CreateDocumentAsync(string base64, string envelope_uuid, CancellationToken cancellation = default);
}

View File

@@ -1,21 +0,0 @@
using Dapper;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
///
/// </summary>
public interface IEnvelopeExecutor : ISQLExecutor
{
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="tfaEnabled"></param>
/// <param name="cancellation"></param>
/// <returns></returns>
Task<Envelope> CreateEnvelopeAsync(int userId, string title = "", string message = "", bool tfaEnabled = false, CancellationToken cancellation = default);
}

View File

@@ -1,20 +0,0 @@
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
///
/// </summary>
public interface IEnvelopeReceiverExecutor
{
/// <summary>
///
/// </summary>
/// <param name="envelope_uuid"></param>
/// <param name="emailAddress"></param>
/// <param name="salutation"></param>
/// <param name="phone"></param>
/// <param name="cancellation"></param>
/// <returns></returns>
Task<EnvelopeReceiver?> AddEnvelopeReceiverAsync(string envelope_uuid, string emailAddress, string? salutation = null, string? phone = null, CancellationToken cancellation = default);
}

View File

@@ -1,70 +0,0 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Provides methods for executing common queries on a given entity type.
/// This interface abstracts away the direct usage of ORM libraries (such as Entity Framework) for querying data
/// and provides asynchronous and synchronous operations for querying a collection or single entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity being queried.</typeparam>
public interface IQuery<TEntity>
{
/// <summary>
/// Asynchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> FirstOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> SingleOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a list of entities.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the list of entities.</returns>
public Task<IEnumerable<TEntity>> ToListAsync();
/// <summary>
/// Asynchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the first entity.</returns>
public Task<TEntity> FirstAsync();
/// <summary>
/// Asynchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the single entity.</returns>
public Task<TEntity> SingleAsync();
/// <summary>
/// Synchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>The first entity or a default value.</returns>
public TEntity? FirstOrDefault();
/// <summary>
/// Synchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>The single entity or a default value.</returns>
public TEntity? SingleOrDefault();
/// <summary>
/// Synchronously retrieves a list of entities.
/// </summary>
/// <returns>The list of entities.</returns>
public IEnumerable<TEntity> ToList();
/// <summary>
/// Synchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The first entity.</returns>
public TEntity First();
/// <summary>
/// Synchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The single entity.</returns>
public TEntity Single();
}

View File

@@ -1,20 +0,0 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Represents a raw SQL query contract.
/// </summary>
public interface ISQL
{
/// <summary>
/// Gets the raw SQL query string.
/// </summary>
string Raw { get; }
}
/// <summary>
/// Represents a typed SQL query contract for a specific entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity associated with the SQL query.</typeparam>
public interface ISQL<TEntity> : ISQL
{
}

View File

@@ -1,27 +0,0 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Defines methods for executing raw SQL queries or custom SQL query classes and returning query executors for further operations.
/// Provides abstraction for raw SQL execution as well as mapping the results to <typeparamref name="TEntity"/> objects.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
public interface ISQLExecutor<TEntity>: ISQLExecutor
{
/// <summary>
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <param name="sql">The raw SQL query to execute.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <param name="parameters">Optional parameters for the SQL query.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
IQuery<TEntity> Execute(string sql, CancellationToken cancellation = default, params object[] parameters);
/// <summary>
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <param name="parameters">Optional parameters for the SQL query.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
IQuery<TEntity> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<TEntity>;
}

View File

@@ -1,29 +0,0 @@
using Dapper;
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
///
/// </summary>
public interface ISQLExecutor
{
/// <summary>
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
/// <param name="sql">The raw SQL query to execute.</param>
/// <param name="parameters">Parameters for the SQL query.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default);
/// <summary>
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
/// </summary>
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
/// <param name="parameters">Parameters for the SQL query.</param>
/// <param name="cancellation">Optional cancellation token for the operation.</param>
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL;
}

View File

@@ -1,63 +0,0 @@
using OtpNet;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
public interface IAuthenticator
{
/// <summary>
///
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
string GenerateCode(int length);
/// <summary>
///
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
string GenerateTotpSecretKey(int? length = null);
/// <summary>
///
/// </summary>
/// <param name="userEmail"></param>
/// <param name="secretKey"></param>
/// <param name="issuer"></param>
/// <param name="totpUrlFormat"></param>
/// <param name="pixelsPerModule"></param>
/// <returns></returns>
byte[] GenerateTotpQrCode(string userEmail, string secretKey, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null);
/// <summary>
///
/// </summary>
/// <param name="userEmail"></param>
/// <param name="length"></param>
/// <param name="issuer"></param>
/// <param name="totpUrlFormat"></param>
/// <param name="pixelsPerModule"></param>
/// <returns></returns>
byte[] GenerateTotpQrCode(string userEmail, int? length = null, string? issuer = null, string? totpUrlFormat = null, int? pixelsPerModule = null);
/// <summary>
///
/// </summary>
/// <param name="secretKey"></param>
/// <param name="step"></param>
/// <returns></returns>
string GenerateTotp(string secretKey, int step = 30);
/// <summary>
///
/// </summary>
/// <param name="totpCode"></param>
/// <param name="secretKey"></param>
/// <param name="step"></param>
/// <param name="window"></param>
/// <returns></returns>
bool VerifyTotp(string totpCode, string secretKey, int step = 30, VerificationWindow? window = null);
}

View File

@@ -1,31 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IConfigService : IReadService<ConfigDto, Config, int>
{
/// <summary>
///
/// </summary>
/// <returns></returns>
Task<DataResult<ConfigDto>> ReadFirstAsync();
/// <summary>
///
/// </summary>
/// <returns></returns>
Task<ConfigDto> ReadDefaultAsync();
/// <summary>
///
/// </summary>
/// <returns></returns>
Task<string> ReadDefaultSignatureHost();
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IDocumentReceiverElementService : IBasicCRUDService<DocumentReceiverElementDto, DocumentReceiverElement, int>
{
}

View File

@@ -1,12 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IDocumentStatusService : IBasicCRUDService<DocumentStatusDto, DocumentStatus, int>
{
}

View File

@@ -1,21 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEmailTemplateService : IBasicCRUDService<EmailTemplateDto, EmailTemplate, int>
{
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
Task<DataResult<EmailTemplateDto>> ReadByNameAsync(EmailTemplateType type);
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeCertificateService : IBasicCRUDService<EnvelopeCertificateDto, EnvelopeCertificate, int>
{
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeDocumentService : IBasicCRUDService<EnvelopeDocumentDto, EnvelopeDocument, int>
{
}

View File

@@ -1,85 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Domain.Entities;
using static EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeHistoryService : ICRUDService<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>
{
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <param name="status"></param>
/// <returns></returns>
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, EnvelopeStatus? status = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <returns></returns>
Task<bool> AccessCodeAlreadyRequested(int envelopeId, string userReference);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <returns></returns>
Task<bool> IsSigned(int envelopeId, string userReference);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <returns></returns>
Task<bool> IsRejected(int envelopeId, string? userReference = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <param name="referenceType"></param>
/// <param name="status"></param>
/// <param name="withSender"></param>
/// <param name="withReceiver"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, EnvelopeStatus? status = null, bool withSender = false, bool withReceiver = false);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <returns></returns>
Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <returns></returns>
Task<IEnumerable<ReceiverReadDto>> ReadRejectingReceivers(int envelopeId);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="userReference"></param>
/// <param name="status"></param>
/// <param name="comment"></param>
/// <returns></returns>
Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null);
}

View File

@@ -1,45 +0,0 @@
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeMailService : IEmailOutService
{
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverDto"></param>
/// <param name="tempType"></param>
/// <param name="optionalPlaceholders"></param>
/// <returns></returns>
Task<DataResult<int>> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType, Dictionary<string, object>? optionalPlaceholders = null);
/// <summary>
///
/// </summary>
/// <param name="dto"></param>
/// <param name="optionalPlaceholders"></param>
/// <returns></returns>
Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary<string, object>? optionalPlaceholders = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverDto"></param>
/// <returns></returns>
Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverDto"></param>
/// <returns></returns>
Task<DataResult<int>> SendTFAQrCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>
{
}

View File

@@ -1,148 +0,0 @@
using CommandDotNet;
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.Envelopes;
using EnvelopeGenerator.Application.Receivers.Queries.Read;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDto, EnvelopeReceiver, (int Envelope, int Receiver)>
{
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<string?>>> ReadAccessCodeByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true);
/// <summary>
///
/// </summary>
/// <param name="signature"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<DataResult<EnvelopeReceiverDto>> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<DataResult<EnvelopeReceiverSecretDto>> ReadWithSecretByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverId"></param>
/// <param name="withEnvelope"></param>
/// <param name="withReceiver"></param>
/// <param name="readOnly"></param>
/// <returns></returns>
Task<DataResult<EnvelopeReceiverDto>> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true);
/// <summary>
///
/// </summary>
/// <param name="envelopeId"></param>
/// <param name="receiverId"></param>
/// <returns></returns>
Task<DataResult<string>> ReadAccessCodeByIdAsync(int envelopeId, int receiverId);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="signature"></param>
/// <param name="accessCode"></param>
/// <returns></returns>
Task<DataResult<bool>> VerifyAccessCodeAsync(string uuid, string signature, string accessCode);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverId"></param>
/// <param name="accessCode"></param>
/// <returns></returns>
[Command("verify-access-code-async-by-id")]
Task<DataResult<bool>> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverId"></param>
/// <returns></returns>
Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
/// <summary>
///
/// </summary>
/// <param name="username"></param>
/// <param name="min_status"></param>
/// <param name="max_status"></param>
/// <param name="envelopeQuery"></param>
/// <param name="receiverQuery"></param>
/// <param name="ignore_statuses"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeReceiverDto>>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, EnvelopeQuery? envelopeQuery = null, ReadReceiverQuery? receiverQuery = null, params int[] ignore_statuses);
/// <summary>
///
/// </summary>
/// <param name="mail"></param>
/// <param name="id"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<DataResult<string>> ReadLastUsedReceiverNameByMailAsync(string? mail = null, int? id = null, string? signature = null);
/// <summary>
///
/// </summary>
/// <param name="envelopeReceiverId"></param>
/// <param name="message"></param>
/// <returns></returns>
Task<DataResult<SmsResponse>> SendSmsAsync(string envelopeReceiverId, string message);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeReceiverSecretDto>>> ReadWithSecretByUuidAsync(string uuid);
}

View File

@@ -1,44 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeService : IBasicCRUDService<EnvelopeDto, Envelope, int>
{
/// <summary>
///
/// </summary>
/// <param name="documents"></param>
/// <param name="history"></param>
/// <param name="documentReceiverElement"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeDto>>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false);
/// <summary>
///
/// </summary>
/// <param name="uuid"></param>
/// <param name="withDocuments"></param>
/// <param name="withHistory"></param>
/// <param name="withDocumentReceiverElement"></param>
/// <param name="withUser"></param>
/// <param name="withAll"></param>
/// <returns></returns>
Task<DataResult<EnvelopeDto>> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false);
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <param name="min_status"></param>
/// <param name="max_status"></param>
/// <param name="ignore_statuses"></param>
/// <returns></returns>
Task<DataResult<IEnumerable<EnvelopeDto>>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses);
}

View File

@@ -1,26 +0,0 @@
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.Messaging;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
public interface IEnvelopeSmsHandler
{
/// <summary>
/// If expiration is passed then, sends sms and returns smsResponse and up-to-date expiration; otherwise send expiration.
/// </summary>
/// <param name="er_secret"></param>
/// <param name="cToken"></param>
/// <returns></returns>
Task<(SmsResponse? SmsResponse, DateTime Expiration)> SendTotpAsync(EnvelopeReceiverSecretDto er_secret, CancellationToken cToken = default);
/// <summary>
///
/// </summary>
/// <param name="totpCode"></param>
/// <param name="secretKey"></param>
/// <returns></returns>
bool VerifyTotp(string totpCode, string secretKey);
}

View File

@@ -1,13 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IEnvelopeTypeService : IBasicCRUDService<EnvelopeTypeDto, EnvelopeType, int>
{
}

View File

@@ -1,29 +0,0 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Contracts.Services;
/// <summary>
///
/// </summary>
[Obsolete("Use MediatR")]
public interface IReceiverService : ICRUDService<ReceiverCreateDto, ReceiverReadDto, Receiver, int>
{
/// <summary>
///
/// </summary>
/// <param name="emailAddress"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null);
/// <summary>
///
/// </summary>
/// <param name="emailAddress"></param>
/// <param name="signature"></param>
/// <returns></returns>
Task<Result> DeleteByAsync(string? emailAddress = null, string? signature = null);
}

View File

@@ -1,23 +0,0 @@
using EnvelopeGenerator.Application.DTOs.Messaging;
namespace EnvelopeGenerator.Application.Contracts.Services;
//TODO: move to DigitalData.Core
/// <summary>
///
/// </summary>
public interface ISmsSender
{
/// <summary>
///
/// </summary>
string ServiceProvider { get; }
/// <summary>
///
/// </summary>
/// <param name="recipient"></param>
/// <param name="message"></param>
/// <returns></returns>
Task<SmsResponse> SendSmsAsync(string recipient, string message);
}

View File

@@ -0,0 +1,63 @@
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;
namespace EnvelopeGenerator.Application
{
public static class DIExtensions
{
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration dispatcherConfigSection, IConfiguration mailConfigSection)
{
//Inject CRUD Service and repositoriesad
services.AddScoped<IConfigRepository, ConfigRepository>();
services.AddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
services.AddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
services.AddScoped<IConfigRepository, ConfigRepository>();
services.AddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
services.AddScoped<IDocumentStatusRepository, DocumentStatusRepository>();
services.AddScoped<IEmailTemplateRepository, EmailTemplateRepository>();
services.AddScoped<IEnvelopeRepository, EnvelopeRepository>();
services.AddScoped<IEnvelopeCertificateRepository, EnvelopeCertificateRepository>();
services.AddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
services.AddScoped<IEnvelopeHistoryRepository, EnvelopeHistoryRepository>();
services.AddScoped<IEnvelopeReceiverRepository, EnvelopeReceiverRepository>();
services.AddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
services.AddScoped<IReceiverRepository, ReceiverRepository>();
services.AddScoped<IUserReceiverRepository, UserReceiverRepository>();
services.AddScoped<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyRepository>();
services.AddScoped<IConfigService, ConfigService>();
services.AddScoped<IDocumentReceiverElementService, DocumentReceiverElementService>();
services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
services.AddScoped<IEnvelopeHistoryService, EnvelopeHistoryService>();
services.AddScoped<IDocumentStatusService, DocumentStatusService>();
services.AddScoped<IEmailTemplateService, EmailTemplateService>();
services.AddScoped<IEnvelopeService, EnvelopeService>();
services.AddScoped<IEnvelopeCertificateService, EnvelopeCertificateService>();
services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
services.AddScoped<IEnvelopeReceiverService, EnvelopeReceiverService>();
services.AddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
services.AddScoped<IReceiverService, ReceiverService>();
services.AddScoped<IUserReceiverService, UserReceiverService>();
services.AddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
//Auto mapping profiles
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
services.Configure<DispatcherConfig>(dispatcherConfigSection);
services.Configure<MailConfig>(mailConfigSection);
return services;
}
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration config) => services.AddEnvelopeGenerator(
dispatcherConfigSection: config.GetSection("DispatcherConfig"),
mailConfigSection: config.GetSection("MailConfig"));
}
}

View File

@@ -1,30 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing configuration settings.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class ConfigDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets or sets the sending profile identifier.
/// </summary>
public int SendingProfile { get; set; }
/// <summary>
/// Gets or sets the signature host URL or name.
/// </summary>
public required string SignatureHost { get; set; }
/// <summary>
/// Gets or sets the name of the external program.
/// </summary>
public string? ExternalProgramName { get; set; }
/// <summary>
/// Gets or sets the path where exports will be saved.
/// </summary>
public string? ExportPath { get; set; }
public record ConfigDto(
string DocumentPath,
int SendingProfile,
string SignatureHost,
string ExternalProgramName,
string ExportPath,
string DocumentPathDmz,
string ExportPathDmz,
string DocumentPathMoveAftsend) : IUnique<int>
{
[JsonIgnore]
[Obsolete("Configuration does not have an ID; it represents a single table in the database.")]
public int Id => throw new InvalidOperationException("This configuration does not support an ID as it represents a single row in the database.");
};
}

View File

@@ -1,95 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing a positioned element assigned to a document receiver.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class DocumentReceiverElementDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets or sets the unique identifier of the element.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the identifier of the associated document.
/// </summary>
public int DocumentId { get; set; }
/// <summary>
/// Gets or sets the identifier of the receiver.
/// </summary>
public int ReceiverId { get; set; }
/// <summary>
/// Gets or sets the type of the element.
/// </summary>
public int ElementType { get; set; }
/// <summary>
/// Gets or sets the X coordinate of the element.
/// </summary>
public double X { get; set; }
/// <summary>
/// Gets or sets the Y coordinate of the element.
/// </summary>
public double Y { get; set; }
/// <summary>
/// Gets or sets the width of the element.
/// </summary>
public double Width { get; set; }
/// <summary>
/// Gets or sets the height of the element.
/// </summary>
public double Height { get; set; }
/// <summary>
/// Gets or sets the page number where the element appears.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the element is required.
/// </summary>
public bool Required { get; set; }
/// <summary>
/// Gets or sets the tooltip text for the element.
/// </summary>
public string? Tooltip { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the element is read-only.
/// </summary>
public bool ReadOnly { get; set; }
/// <summary>
/// Gets or sets the annotation index for ordering or reference.
/// </summary>
public int AnnotationIndex { get; set; }
/// <summary>
/// Gets or sets the timestamp when the element was added.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Gets or sets the timestamp when the element was last changed, if applicable.
/// </summary>
public DateTime? ChangedWhen { get; set; }
/// <summary>
/// Gets or sets the top position of the element (in layout terms).
/// </summary>
public double Top { get; set; }
/// <summary>
/// Gets or sets the left position of the element (in layout terms).
/// </summary>
public double Left { get; set; }
public record DocumentReceiverElementDto(
int Id,
int DocumentId,
int ReceiverId,
int ElementType,
double X,
double Y,
double Width,
double Height,
int Page,
bool Required,
string? Tooltip,
bool ReadOnly,
int AnnotationIndex,
DateTime AddedWhen,
DateTime? ChangedWhen,
double Top,
double Left
): IUnique<int>;
}

View File

@@ -1,50 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing the status of a document for a specific receiver.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class DocumentStatusDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets or sets the unique identifier of the document status entry.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the ID of the associated envelope.
/// </summary>
public int EnvelopeId { get; set; }
/// <summary>
/// Gets or sets the ID of the receiver associated with this status.
/// </summary>
public int ReceiverId { get; set; }
/// <summary>
/// Gets or sets the current status code.
/// </summary>
public int Status { get; set; }
/// <summary>
/// Gets or sets the timestamp when the status was changed.
/// </summary>
public DateTime? StatusChangedWhen { get; set; }
/// <summary>
/// Gets or sets the timestamp when this record was added.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Gets or sets the timestamp when this record was last changed.
/// </summary>
public DateTime? ChangedWhen { get; set; }
/// <summary>
/// Gets or sets the display value associated with the status.
/// </summary>
public string? Value { get; set; }
public record DocumentStatusDto(
int Id,
int EnvelopeId,
int ReceiverId,
int Status,
DateTime? StatusChangedWhen,
string Value,
DateTime AddedWhen,
DateTime? ChangedWhen) : IUnique<int>;
}

View File

@@ -1,31 +1,10 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record EmailTemplateDto
{
/// <summary>
///
/// </summary>
public int Id{ get; init; }
/// <summary>
///
/// </summary>
public required string Name { get; init; }
/// <summary>
///
/// </summary>
public required string Body { get; set; }
/// <summary>
///
/// </summary>
public required string Subject { get; set; }
};
public record EmailTemplateDto(
int Id,
string Name,
string Body,
string Subject) : IUnique<int>;
}

View File

@@ -1,50 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing certificate information for an envelope.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeCertificateDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets the unique identifier of the certificate.
/// </summary>
public int Id { get; init; }
/// <summary>
/// Gets the envelope ID associated with the certificate.
/// </summary>
public int EnvelopeId { get; init; }
/// <summary>
/// Gets the UUID of the envelope.
/// </summary>
public string EnvelopeUuid { get; init; } = string.Empty;
/// <summary>
/// Gets the subject of the envelope.
/// </summary>
public string EnvelopeSubject { get; init; } = string.Empty;
/// <summary>
/// Gets the ID of the creator of the envelope.
/// </summary>
public int CreatorId { get; init; }
/// <summary>
/// Gets the name of the creator.
/// </summary>
public string CreatorName { get; init; } = string.Empty;
/// <summary>
/// Gets the email address of the creator.
/// </summary>
public string CreatorEmail { get; init; } = string.Empty;
/// <summary>
/// Gets the current status of the envelope.
/// </summary>
public int EnvelopeStatus { get; init; }
public record EnvelopeCertificateDto(
int Id,
int EnvelopeId,
string EnvelopeUuid,
string EnvelopeSubject,
int CreatorId,
string CreatorName,
string CreatorEmail,
int EnvelopeStatus) : IUnique<int>;
}

View File

@@ -1,35 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing a document within an envelope, including optional binary data and form elements.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeDocumentDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets or sets the unique identifier of the document.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the envelope ID to which the document belongs.
/// </summary>
public int EnvelopeId { get; set; }
/// <summary>
/// Gets or sets the date and time when the document was added.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Gets or sets the binary data of the document, if available.
/// </summary>
public byte[]? ByteData { get; set; }
/// <summary>
/// Gets or sets the collection of elements associated with the document for receiver interactions, if any.
/// </summary>
public IEnumerable<DocumentReceiverElementDto>? Elements { get; set; }
public record EnvelopeDocumentDto
(
int Id,
int EnvelopeId,
DateTime AddedWhen,
byte[]? ByteData = null,
IEnumerable<DocumentReceiverElementDto>? Elements = null
) : IUnique<int>;
}

View File

@@ -1,120 +1,67 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using DigitalData.Core.Abstractions;
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using DigitalData.UserManager.Application.DTOs.User;
using EnvelopeGenerator.Domain.Entities;
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record EnvelopeDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
///
/// </summary>
public int Id { get; set; }
public record EnvelopeDto() : IUnique<int>
{
public int Id { get; set; }
/// <summary>
///
/// </summary>
public int UserId { get; set; }
public int UserId { get; set; }
/// <summary>
///
/// </summary>
public int Status { get; set; }
public int Status { get; set; }
/// <summary>
/// Default value is string.Empty
/// </summary>
public string StatusName { get; set; } = string.Empty;
public string StatusName { get; set; }
/// <summary>
/// Default value is string.Empty
/// </summary>
public string Uuid { get; set; } = string.Empty;
public string Uuid { get; set; }
/// <summary>
/// Default value is string.Empty
/// </summary>
[TemplatePlaceholder("[MESSAGE]")]
public string Message { get; set; } = string.Empty;
[TemplatePlaceholder("[MESSAGE]")]
public string Message { get; set; }
public DateTime? ExpiresWhen { get; set; }
public DateTime? ExpiresWarningWhen { get; set; }
public DateTime AddedWhen { get; set; }
public DateTime? ChangedWhen { get; set; }
/// <summary>
///
/// </summary>
public DateTime AddedWhen { get; set; }
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
public string Title { get; set; }
/// <summary>
///
/// </summary>
public DateTime? ChangedWhen { get; set; }
public int? ContractType { get; set; }
/// <summary>
/// Default value is string.Empty
/// </summary>
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
public string Title { get; set; } = string.Empty;
public string Language { get; set; }
/// <summary>
///
/// </summary>
public int? ContractType { get; set; }
public bool? SendReminderEmails { get; set; }
/// <summary>
/// Default value is 'de-DE'
/// </summary>
public string Language { get; set; } = "de-DE";
public int? FirstReminderDays { get; set; }
/// <summary>
///
/// </summary>
public int? EnvelopeTypeId { get; set; }
public int? ReminderIntervalDays { get; set; }
/// <summary>
///
/// </summary>
public int? CertificationType { get; set; }
public int? EnvelopeTypeId { get; set; }
/// <summary>
///
/// </summary>
public bool? UseAccessCode { get; set; }
public int? CertificationType { get; set; }
/// <summary>
///
/// </summary>
public bool TFAEnabled { get; init; }
public bool? UseAccessCode { get; set; }
/// <summary>
///
/// </summary>
public UserReadDto? User { get; set; }
public int? FinalEmailToCreator { get; set; }
/// <summary>
///
/// </summary>
public EnvelopeType? EnvelopeType { get; set; }
public int? FinalEmailToReceivers { get; set; }
/// <summary>
///
/// </summary>
public string? EnvelopeTypeTitle { get; set; }
public int? ExpiresWhenDays { get; set; }
/// <summary>
///
/// </summary>
public bool IsAlreadySent { get; set; }
public int? ExpiresWarningWhenDays { get; set; }
/// <summary>
///
/// </summary>
public byte[]? DocResult { get; init; }
public bool DmzMoved { get; set; }
public UserReadDto? User { get; set; }
public EnvelopeType? EnvelopeType { get; set; }
/// <summary>
///
/// </summary>
public IEnumerable<EnvelopeDocumentDto>? Documents { get; set; }
public string? EnvelopeTypeTitle { get; set; }
public bool IsAlreadySent { get; set; }
public string? StatusTranslated { get; set; }
public string? ContractTypeTranslated { get; set; }
public IEnumerable<EnvelopeDocumentDto>? Documents { get; set; }
}
}

View File

@@ -1,34 +1,9 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
/// <summary>
/// Data Transfer Object for creating a new envelope history record.
/// </summary>
public class EnvelopeHistoryCreateDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
{
/// <summary>
/// Gets or sets the identifier of the envelope.
/// </summary>
public int EnvelopeId { get; set; }
/// <summary>
/// Gets or sets the user reference associated with the action.
/// </summary>
public required string UserReference { get; set; }
/// <summary>
/// Gets or sets the status of the envelope at the time of the action.
/// </summary>
public int Status { get; set; }
/// <summary>
/// Gets or sets the date and time when the action occurred.
/// </summary>
public DateTime? ActionDate { get; set; }
/// <summary>
/// Gets or sets an optional comment related to the action.
/// </summary>
public string? Comment { get; set; }
public record EnvelopeHistoryCreateDto(
int EnvelopeId,
string UserReference,
int Status,
DateTime? ActionDate,
string? Comment = null);
}

View File

@@ -1,69 +1,21 @@
using DigitalData.UserManager.Application.DTOs.User;
using DigitalData.Core.Abstractions;
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.DTOs.User;
using EnvelopeGenerator.Application.DTOs.Receiver;
using static EnvelopeGenerator.Domain.Constants;
using static EnvelopeGenerator.Common.Constants;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
/// <summary>
/// Data Transfer Object representing the history of an envelope, including status, sender, receiver, and related metadata.
/// </summary>
public record EnvelopeHistoryDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
{
/// <summary>
/// Unique identifier for the envelope history entry.
/// </summary>
public long Id { get; set; }
/// <summary>
/// Identifier of the associated envelope.
/// </summary>
public int EnvelopeId { get; set; }
/// <summary>
/// Reference string for the user related to this history entry.
/// </summary>
public required string UserReference { get; set; }
/// <summary>
/// Status code of the envelope at this history point.
/// </summary>
public int Status { get; set; }
/// <summary>
/// Human-readable name of the status.
/// </summary>
public string? StatusName { get; set; }
/// <summary>
/// Date and time when this history entry was added.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Date and time when an action was performed, if applicable.
/// </summary>
public DateTime? ActionDate { get; set; }
/// <summary>
/// Information about the sender associated with this history entry.
/// </summary>
public UserCreateDto? Sender { get; set; }
/// <summary>
/// Information about the receiver associated with this history entry.
/// </summary>
public ReceiverReadDto? Receiver { get; set; }
/// <summary>
/// Type of reference for this history entry.
/// </summary>
public ReferenceType ReferenceType { get; set; }
/// <summary>
/// Optional comment related to this history entry.
/// </summary>
public string? Comment { get; set; }
/// <inheritdoc/>
public override int GetHashCode() => Id.GetHashCode();
};
public record EnvelopeHistoryDto(
long Id,
int EnvelopeId,
string UserReference,
int Status,
string? StatusName,
DateTime AddedWhen,
DateTime? ActionDate,
UserCreateDto? Sender,
ReceiverReadDto? Receiver,
ReferenceType ReferenceType,
string? Comment = null) : BaseDTO<long>(Id), IUnique<long>;
}

View File

@@ -1,67 +1,29 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record EnvelopeReceiverBasicDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
{
/// <summary>
///
/// </summary>
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)>
{
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
/// <summary>
///
/// </summary>
public int EnvelopeId { get; init; }
public int EnvelopeId { get; init; }
/// <summary>
///
/// </summary>
public int ReceiverId { get; init; }
public int ReceiverId { get; init; }
/// <summary>
///
/// </summary>
public int Sequence { get; init; }
public int Sequence { get; init; }
/// <summary>
///
/// </summary>
[TemplatePlaceholder("[NAME_RECEIVER]")]
public string? Name { get; init; }
[TemplatePlaceholder("[NAME_RECEIVER]")]
public string? Name { get; init; }
/// <summary>
///
/// </summary>
public string? JobTitle { get; init; }
public string? JobTitle { get; init; }
/// <summary>
///
/// </summary>
public string? CompanyName { get; init; }
public string? CompanyName { get; init; }
/// <summary>
///
/// </summary>
public string? PrivateMessage { get; init; }
public string? PrivateMessage { get; init; }
/// <summary>
///
/// </summary>
public DateTime AddedWhen { get; init; }
public DateTime AddedWhen { get; init; }
/// <summary>
///
/// </summary>
public DateTime? ChangedWhen { get; init; }
/// <summary>
///
/// </summary>
public bool HasPhoneNumber { get; init; }
public DateTime? ChangedWhen { get; init; }
}
}

View File

@@ -1,22 +1,11 @@
using EnvelopeGenerator.Application.DTOs.Receiver;
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
{
/// <summary>
///
/// </summary>
public EnvelopeDto? Envelope { get; set; }
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
{
public EnvelopeDto? Envelope { get; set; }
/// <summary>
///
/// </summary>
public ReceiverReadDto? Receiver { get; set; }
public ReceiverReadDto? Receiver { get; set; }
}
}

View File

@@ -1,20 +1,4 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record EnvelopeReceiverSecretDto : EnvelopeReceiverDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
{
/// <summary>
///
/// </summary>
public string? AccessCode { get; init; }
/// <summary>
///
/// </summary>
public string? PhoneNumber { get; init; }
public record EnvelopeReceiverSecretDto(string? AccessCode) : EnvelopeReceiverDto;
}

View File

@@ -1,39 +1,22 @@
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
/// <summary>
///
/// </summary>
/// <param name="DateValid"></param>
[ApiExplorerSettings(IgnoreApi = true)]
public record EnvelopeReceiverReadOnlyCreateDto(
DateTime DateValid)
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
{
/// <summary>
///
/// </summary>
[EmailAddress]
[Required]
public required string ReceiverMail { get; init; }
public record EnvelopeReceiverReadOnlyCreateDto(
DateTime DateValid)
{
[EmailAddress]
[Required]
public required string ReceiverMail { get; init; }
/// <summary>
/// Default value is null
/// </summary>
[JsonIgnore]
public long? EnvelopeId { get; set; } = null;
[JsonIgnore]
public long? EnvelopeId { get; set; } = null;
/// <summary>
///
/// </summary>
[JsonIgnore]
public string? AddedWho { get; set; }
[JsonIgnore]
public string? AddedWho { get; set; }
/// <summary>
/// Default value is DateTime.Now
/// </summary>
[JsonIgnore]
public DateTime AddedWhen { get; } = DateTime.Now;
};
[JsonIgnore]
public DateTime AddedWhen { get; } = DateTime.Now;
};
}

View File

@@ -1,63 +1,16 @@
using EnvelopeGenerator.Application.DTOs.Receiver;
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
/// <summary>
/// Represents a read-only Data Transfer Object (DTO) for an envelope receiver.
/// Contains information about the receiver, associated envelope, and audit details.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeReceiverReadOnlyDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
{
/// <summary>
/// Gets or inits the unique identifier of the envelope receiver.
/// </summary>
public long Id { get; init; }
/// <summary>
/// Gets or inits the identifier of the associated envelope.
/// </summary>
public long EnvelopeId { get; init; }
/// <summary>
/// Gets or inits the email address of the receiver.
/// </summary>
public required string ReceiverMail { get; set; }
/// <summary>
/// Gets or inits the date until which the receiver is valid.
/// </summary>
public DateTime DateValid { get; set; }
/// <summary>
/// Gets or inits the date and time when the receiver was added.
/// </summary>
public DateTime AddedWhen { get; init; }
/// <summary>
/// Gets or inits the user who added the receiver.
/// Default value is 'unknown'.
/// </summary>
public string AddedWho { get; init; } = "Unknown";
/// <summary>
/// Gets or inits the associated envelope details.
/// </summary>
public EnvelopeDto? Envelope { get; set; }
/// <summary>
/// Gets or inits the user who last changed the receiver, if any.
/// </summary>
public string? ChangedWho { get; set; }
/// <summary>
/// Gets or inits the date and time when the receiver was last changed, if any.
/// </summary>
public DateTime? ChangedWhen { get; set; }
/// <summary>
/// Gets or inits the associated receiver details.
/// </summary>
public ReceiverReadDto? Receiver { get; set; }
public record EnvelopeReceiverReadOnlyDto(
long Id,
long EnvelopeId,
string ReceiverMail,
DateTime DateValid,
DateTime AddedWhen,
string AddedWho,
EnvelopeDto? Envelope = null,
string? ChangedWho = null,
DateTime? ChangedWhen = null,
ReceiverReadDto? Receiver = null);
}

View File

@@ -1,31 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
/// <summary>
/// Data Transfer Object for updating a read-only envelope receiver.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeReceiverReadOnlyUpdateDto
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
{
/// <summary>
/// Gets or sets the unique identifier of the envelope receiver.
/// </summary>
public long Id { get; init; }
/// <summary>
/// Gets or sets the date when the envelope receiver becomes valid.
/// </summary>
public DateTime DateValid { get; set; }
/// <summary>
/// Gets or sets the name of the user who made the change.
/// Default value is unknown.
/// </summary>
public string ChangedWho { get; set; } = "Unknown";
/// <summary>
/// Gets or sets the date and time when the change was made.
/// </summary>
public DateTime ChangedWhen { get; set; } = DateTime.Now;
public record EnvelopeReceiverReadOnlyUpdateDto(
long Id,
DateTime DateValid,
string ChangedWho) : IUnique<long>
{
public DateTime ChangedWhen { get; } = DateTime.Now;
};
}

View File

@@ -1,85 +1,21 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Data Transfer Object representing a type of envelope with its configuration settings.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class EnvelopeTypeDto
namespace EnvelopeGenerator.Application.DTOs
{
/// <summary>
/// Gets or sets the unique identifier of the envelope type.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the title of the envelope type.
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the language code used in this envelope type.
/// </summary>
public string Language { get; set; } = "de-DE";
/// <summary>
/// Gets or sets the number of days after which the envelope expires.
/// </summary>
public int? ExpiresDays { get; set; }
/// <summary>
/// Gets or sets the certification type identifier.
/// </summary>
public int? CertificationType { get; set; }
/// <summary>
/// Gets or sets a value indicating whether an access code is required.
/// </summary>
public bool? UseAccessCode { get; set; }
/// <summary>
/// Gets or sets the final email template ID to be sent to the creator.
/// </summary>
public int? FinalEmailToCreator { get; set; }
/// <summary>
/// Gets or sets the final email template ID to be sent to the receivers.
/// </summary>
public int? FinalEmailToReceivers { get; set; }
/// <summary>
/// Gets or sets the timestamp when this envelope type was added.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Gets or sets the timestamp when this envelope type was last changed.
/// </summary>
public DateTime? ChangedWhen { get; set; }
/// <summary>
/// Gets or sets the number of days before expiry when a warning should be sent.
/// </summary>
public int? ExpiresWarningDays { get; set; }
/// <summary>
/// Gets or sets a value indicating whether reminder emails should be sent.
/// </summary>
public bool? SendReminderEmails { get; set; }
/// <summary>
/// Gets or sets the number of days before the first reminder is sent.
/// </summary>
public int? FirstReminderDays { get; set; }
/// <summary>
/// Gets or sets the interval in days between reminder emails.
/// </summary>
public int? ReminderIntervalDays { get; set; }
/// <summary>
/// Gets or sets the contract type associated with the envelope type.
/// </summary>
public int? ContractType { get; set; }
public record EnvelopeTypeDto(
int Id,
string Title,
string Language,
int? ExpiresDays,
int? CertificationType,
bool? UseAccessCode,
int? FinalEmailToCreator,
int? FinalEmailToReceivers,
DateTime AddedWhen,
DateTime? ChangedWhen,
int? ExpiresWarningDays,
bool? SendReminderEmails,
int? FirstReminderDays,
int? ReminderIntervalDays,
int? ContractType) : IUnique<int>;
}

View File

@@ -1,68 +0,0 @@
using AutoMapper;
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
using EnvelopeGenerator.Application.DTOs.Messaging;
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.DTOs;
/// <summary>
/// Represents the AutoMapper profile configuration for mapping between
/// domain entities and data transfer objects (DTOs) used within the EnvelopeGenerator application.
/// </summary>
public class MappingProfile : Profile
{
/// <summary>
/// Initializes a new instance of the <see cref="MappingProfile"/> class.
/// Configures the mappings between entities and DTOs used throughout the application.
/// </summary>
public MappingProfile()
{
// Entity to DTO mappings
CreateMap<Config, ConfigDto>();
CreateMap<DocumentReceiverElement, DocumentReceiverElementDto>();
CreateMap<DocumentStatus, DocumentStatusDto>();
CreateMap<EmailTemplate, EmailTemplateDto>();
CreateMap<Envelope, EnvelopeDto>();
CreateMap<EnvelopeCertificate, EnvelopeCertificateDto>();
CreateMap<EnvelopeDocument, EnvelopeDocumentDto>();
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryDto>();
CreateMap<Domain.Entities.EnvelopeHistory, EnvelopeHistoryCreateDto>();
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverDto>();
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverSecretDto>();
CreateMap<EnvelopeType, EnvelopeTypeDto>();
CreateMap<Domain.Entities.Receiver, ReceiverReadDto>();
CreateMap<Domain.Entities.Receiver, ReceiverCreateDto>();
CreateMap<Domain.Entities.Receiver, ReceiverUpdateDto>();
CreateMap<Domain.Entities.EnvelopeReceiverReadOnly, EnvelopeReceiverReadOnlyDto>();
// DTO to Entity mappings
CreateMap<ConfigDto, Config>();
CreateMap<DocumentReceiverElementDto, DocumentReceiverElement>();
CreateMap<DocumentStatusDto, DocumentStatus>();
CreateMap<EmailTemplateDto, EmailTemplate>();
CreateMap<EnvelopeDto, Envelope>();
CreateMap<EnvelopeCertificateDto, EnvelopeCertificate>();
CreateMap<EnvelopeDocumentDto, EnvelopeDocument>();
CreateMap<EnvelopeHistoryDto, Domain.Entities.EnvelopeHistory>();
CreateMap<EnvelopeHistoryCreateDto, Domain.Entities.EnvelopeHistory>();
CreateMap<EnvelopeReceiverDto, Domain.Entities.EnvelopeReceiver>();
CreateMap<EnvelopeTypeDto, EnvelopeType>();
CreateMap<ReceiverReadDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
CreateMap<ReceiverCreateDto, Domain.Entities.Receiver>();
CreateMap<ReceiverUpdateDto, Domain.Entities.Receiver>();
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverBasicDto>();
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
// Messaging mappings
// for GTX messaging
CreateMap<GtxMessagingResponse, SmsResponse>()
.ConstructUsing(gtxRes => gtxRes.Ok()
? new SmsResponse() { Ok = true }
: new SmsResponse() { Ok = false, Errors = gtxRes });
}
}

View File

@@ -1,9 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.Messaging;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class GtxMessagingResponse : Dictionary<string, object?> { }

View File

@@ -1,25 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace EnvelopeGenerator.Application.DTOs.Messaging;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record SmsResponse
{
/// <summary>
///
/// </summary>
public required bool Ok { get; init; }
/// <summary>
/// Returns !Ok
/// </summary>
public bool Failed => !Ok;
/// <summary>
///
/// </summary>
public dynamic? Errors { get; init; }
}

View File

@@ -1,53 +1,21 @@
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using System.Security.Cryptography;
using System.Text;
namespace EnvelopeGenerator.Application.DTOs.Receiver;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public record ReceiverCreateDto
namespace EnvelopeGenerator.Application.DTOs.Receiver
{
/// <summary>
///
/// </summary>
public ReceiverCreateDto()
public record ReceiverCreateDto([EmailAddress] string EmailAddress)
{
_sha256HexOfMail = new(() =>
public string Signature => sha256HexOfMail.Value;
private readonly Lazy<string> sha256HexOfMail = new(() =>
{
var bytes_arr = Encoding.UTF8.GetBytes(EmailAddress!.ToUpper());
var bytes_arr = Encoding.UTF8.GetBytes(EmailAddress.ToUpper());
var hash_arr = SHA256.HashData(bytes_arr);
var hexa_str = BitConverter.ToString(hash_arr);
return hexa_str.Replace("-", string.Empty);
});
}
/// <summary>
///
/// </summary>
[EmailAddress]
public required string EmailAddress { get; init; }
/// <summary>
///
/// </summary>
public string? TotpSecretkey { get; init; }
/// <summary>
/// var bytes_arr = Encoding.UTF8.GetBytes(EmailAddress.ToUpper());<br/>
/// var hash_arr = SHA256.HashData(bytes_arr);
/// var hexa_str = BitConverter.ToString(hash_arr);
/// return hexa_str.Replace("-", string.Empty);
/// </summary>
public string Signature => _sha256HexOfMail.Value;
private readonly Lazy<string> _sha256HexOfMail;
/// <summary>
/// Default value is DateTime.Now
/// </summary>
public DateTime AddedWhen { get; } = DateTime.Now;
};
public DateTime AddedWhen { get; } = DateTime.Now;
};
}

View File

@@ -1,62 +1,19 @@
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.DTO;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.DTOs.Receiver;
/// <summary>
///
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class ReceiverReadDto
namespace EnvelopeGenerator.Application.DTOs.Receiver
{
/// <summary>
///
/// </summary>
public int Id { get; set; }
/// <summary>
///
/// </summary>
public required string EmailAddress { get; set; }
/// <summary>
///
/// </summary>
public required string Signature { get; set; }
/// <summary>
///
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
///
/// </summary>
[JsonIgnore]
public IEnumerable<EnvelopeReceiverBasicDto>? EnvelopeReceivers { get; set; }
/// <summary>
///
/// </summary>
public string? LastUsedName => EnvelopeReceivers?.LastOrDefault()?.Name;
/// <summary>
///
/// </summary>
public string? TotpSecretkey { get; set; } = null;
/// <summary>
///
/// </summary>
public DateTime? TfaRegDeadline { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetHashCode()
public record ReceiverReadDto(
int Id,
string EmailAddress,
string Signature,
DateTime AddedWhen
) : BaseDTO<int>(Id)
{
return Id.GetHashCode();
}
[JsonIgnore]
public IEnumerable<EnvelopeReceiverBasicDto>? EnvelopeReceivers { get; init; }
public string? LastUsedName => EnvelopeReceivers?.LastOrDefault()?.Name;
};
}

View File

@@ -1,27 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs.Receiver;
/// <summary>
/// Data Transfer Object for updating a receiver's information.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
public class ReceiverUpdateDto
namespace EnvelopeGenerator.Application.DTOs.Receiver
{
/// <summary>
/// Gets or sets the unique identifier of the receiver.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the TOTP (Time-based One-Time Password) secret key.
/// Optional.
/// </summary>
public string? TotpSecretkey { get; set; }
/// <summary>
/// Gets or sets the deadline for two-factor authentication registration.
/// Optional.
/// </summary>
public DateTime? TfaRegDeadline { get; set; }
public record ReceiverUpdateDto(int Id) : IUnique<int>;
}

View File

@@ -0,0 +1,13 @@
using DigitalData.Core.Abstractions;
namespace EnvelopeGenerator.Application.DTOs
{
public record UserReceiverDto(
int Id,
int UserId,
int ReceiverId,
string Name,
string CompanyName,
string JobTitle,
DateTime AddedWhen) : IUnique<int>;
}

View File

@@ -1,67 +0,0 @@
using EnvelopeGenerator.Application.Configurations;
using EnvelopeGenerator.Application.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using DigitalData.Core.Client;
using QRCoder;
using EnvelopeGenerator.Application.Contracts.Services;
using System.Reflection;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
namespace EnvelopeGenerator.Application;
/// <summary>
/// Extensions method for dependency injection
/// </summary>
public static class DependencyInjection
{
/// <summary>
/// Adds all required services for envelope generator application
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
/// <returns></returns>
[Obsolete("Use MediatR")]
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config)
{
//Inject CRUD Service and repositoriesad
services.TryAddScoped<IConfigService, ConfigService>();
services.TryAddScoped<IDocumentReceiverElementService, DocumentReceiverElementService>();
services.TryAddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
services.TryAddScoped<IEnvelopeHistoryService, EnvelopeHistoryService>();
services.TryAddScoped<IDocumentStatusService, DocumentStatusService>();
services.TryAddScoped<IEmailTemplateService, EmailTemplateService>();
services.TryAddScoped<IEnvelopeService, EnvelopeService>();
services.TryAddScoped<IEnvelopeCertificateService, EnvelopeCertificateService>();
services.TryAddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
services.TryAddScoped<IEnvelopeReceiverService, EnvelopeReceiverService>();
services.TryAddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
services.TryAddScoped<IReceiverService, ReceiverService>();
services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
//Auto mapping profiles
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddAutoMapper(typeof(DigitalData.UserManager.Application.DIExtensions));
services.Configure<DispatcherParams>(config.GetSection(nameof(DispatcherParams)));
services.Configure<MailParams>(config.GetSection(nameof(MailParams)));
services.Configure<AuthenticatorParams>(config.GetSection(nameof(AuthenticatorParams)));
services.Configure<TotpSmsParams>(config.GetSection(nameof(TotpSmsParams)));
services.Configure<DbTriggerParams>(config.GetSection(nameof(DbTriggerParams)));
services.AddHttpClientService<GtxMessagingParams>(config.GetSection(nameof(GtxMessagingParams)));
services.TryAddSingleton<ISmsSender, GTXSmsSender>();
services.TryAddSingleton<IEnvelopeSmsHandler, EnvelopeSmsHandler>();
services.TryAddSingleton<IAuthenticator, Authenticator>();
services.TryAddSingleton<QRCodeGenerator>();
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
cfg.RegisterServicesFromAssembly(typeof(CreateEnvelopeReceiverCommandHandler).Assembly);
});
return services;
}
}

View File

@@ -1,18 +0,0 @@
using AutoMapper;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
///
/// </summary>
public class ReadDocumentMappingProfile : Profile
{
/// <summary>
///
/// </summary>
public ReadDocumentMappingProfile()
{
CreateMap<EnvelopeDocument, ReadDocumentResponse>();
}
}

View File

@@ -1,12 +0,0 @@
using MediatR;
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
/// Represents a query to read a document based on its unique identifier or associated envelope identifier.
/// </summary>
/// <param name="Id">The unique identifier of the document. Optional.</param>
/// <param name="EnvelopeId">The identifier of the envelope associated with the document. Optional.</param>
public record ReadDocumentQuery(int? Id = null, int? EnvelopeId = null) : IRequest<ReadDocumentResponse?>
{
}

View File

@@ -1,48 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
/// Handles queries for reading <see cref="EnvelopeDocument"/> data based on either the document ID or the envelope ID.
/// </summary>
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, ReadDocumentResponse?>
{
/// <summary>
/// Repository for accessing <see cref="EnvelopeDocument"/> entities.
/// </summary>
private readonly IRepository<EnvelopeDocument> _repo;
/// <summary>
/// Initializes a new instance of the <see cref="ReadDocumentQueryHandler"/> class.
/// </summary>
/// <param name="envelopeDocumentRepository">The repository used to access <see cref="EnvelopeDocument"/> entities.</param>
public ReadDocumentQueryHandler(IRepository<EnvelopeDocument> envelopeDocumentRepository)
{
_repo = envelopeDocumentRepository;
}
/// <summary>
/// Handles the <see cref="ReadDocumentQuery"/> and returns a <see cref="ReadDocumentResponse"/> based on the provided identifiers.
/// </summary>
/// <param name="query">The query containing the document ID or envelope ID to search for.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>
/// A <see cref="ReadDocumentResponse"/> if a matching document is found; otherwise, <c>null</c>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided.
/// </exception>
[Obsolete("Use MediatR")]
public async Task<ReadDocumentResponse?> Handle(ReadDocumentQuery query, CancellationToken cancellationToken)
{
if (query.Id is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.Id == query.Id);
else if (query.EnvelopeId is not null)
return await _repo.ReadOrDefaultAsync<ReadDocumentResponse>(d => d.EnvelopeId == query.EnvelopeId);
throw new InvalidOperationException(
$"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided.");
}
}

View File

@@ -1,12 +0,0 @@
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
/// Represents the response for reading a document.
/// </summary>
public class ReadDocumentResponse : ReadDocumentResponseBase
{
/// <summary>
/// The binary data of the document, if available.
/// </summary>
public byte[]? ByteData { get; init; }
}

View File

@@ -1,22 +0,0 @@
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
/// <summary>
/// Represents the response for reading a document.
/// </summary>
public class ReadDocumentResponseBase
{
/// <summary>
/// The unique identifier of the document.
/// </summary>
public int Guid { get; init; }
/// <summary>
/// The identifier of the associated envelope.
/// </summary>
public int EnvelopeId { get; init; }
/// <summary>
/// The date and time when the document was added.
/// </summary>
public DateTime AddedWhen { get; init; }
}

View File

@@ -1,40 +0,0 @@
using EnvelopeGenerator.Domain;
using MediatR;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
/// <summary>
/// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte.
/// Erbt von <see cref="EmailTemplateQuery"/> und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage.<br/><br/>
/// Beispiele:<br/>
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.<br/>
/// </summary>
public record ResetEmailTemplateCommand : EmailTemplateQuery, IRequest
{
/// <summary>
///
/// </summary>
/// <param name="orginal"></param>
public ResetEmailTemplateCommand(EmailTemplateQuery? orginal = null) : base(orginal ?? new())
{
}
/// <summary>
///
/// </summary>
/// <param name="Id">Die optionale ID der E-Mail-Vorlage, die zurückgesetzt werden soll.</param>
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="Constants.EmailTemplateType"/> (optional).</param>
public ResetEmailTemplateCommand(int? Id = null, Constants.EmailTemplateType? Type = null) : base(Id, Type)
{
}
};

View File

@@ -1,114 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
/// <summary>
///
/// </summary>
public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTemplateCommand>
{
private readonly IRepository<EmailTemplate> _repository;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
public ResetEmailTemplateCommandHandler(IRepository<EmailTemplate> repository)
{
_repository = repository;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public async Task Handle(ResetEmailTemplateCommand request, CancellationToken cancel)
{
var temps = request.Id is not null
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Id == request.Id, cancel)
: request.Type is not null
? await _repository.ReadAllAsync<EmailTemplateDto>(t => t.Name == request.Type.ToString(), cancel)
: await _repository.ReadAllAsync<EmailTemplateDto>(cancellation: cancel);
foreach (var temp in temps)
{
var def = Defaults.Where(t => t.Name == temp.Name).FirstOrDefault();
if(def is not null)
await _repository.UpdateAsync(def, t => t.Id == temp.Id, cancel);
}
}
/// <summary>
///
/// </summary>
public static readonly IEnumerable<EmailTemplateDto> Defaults = new List<EmailTemplateDto>()
{
new(){
Id = 1,
Name = "DocumentReceived",
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat Ihnen ein Dokument zum [SIGNATURE_TYPE] gesendet.<br />\r\n<br />\r\nÜber den folgenden Link können Sie das Dokument einsehen und elektronisch unterschreiben: <a href=\"[LINK_TO_DOCUMENT]\">[LINK_TO_DOCUMENT_TEXT]</a><br />\r\n<br />\r\n[MESSAGE]<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "Dokument erhalten: '[DOCUMENT_TITLE]'"
},
new(){
Id = 2,
Name = "DocumentDeleted",
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat den Umschlag <B><I>'[DOCUMENT_TITLE]'</I></B> gelöscht/zurückgezogen.<br /><p>\rBegründung: <br /> <I>[REASON]</I> <p>\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "Umschlag zurückgezogen: '[DOCUMENT_TITLE]'"
},
new(){
Id = 3,
Name = "DocumentSigned",
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br />\r\nhiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B>.<br />\r\nWenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "Dokument unterschrieben: '[DOCUMENT_TITLE]'"
},
new(){
Id = 4,
Name = "DocumentCompleted",
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br />\r\nDer Signaturvorgang <B><I>'[DOCUMENT_TITLE]'</I></B> wurde erfolgreich abgeschlossen.<br />\r\n<br />\r\nSie erhalten das Dokument mit einem detaillierten Ergebnisbericht als Anhang zu dieser EmailAddress.<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "Umschlag abgeschlossen: '[DOCUMENT_TITLE]'"
},
new(){
Id = 5,
Name = "DocumentAccessCodeReceived",
Body = "Guten Tag [NAME_RECEIVER],<br />\r\n<br /><B><I>\r\n[NAME_SENDER]</I></B> hat Ihnen ein Dokument zum [SIGNATURE_TYPE] gesendet. <br />\r\n<br />\r\nVerwenden Sie den folgenden Zugriffscode, um das Dokument einzusehen:<br />\r\n<br />\r\n[DOCUMENT_ACCESS_CODE]<br />\r\n<br />\r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "Zugriffscode für Dokument erhalten: '[DOCUMENT_TITLE]'"
},
new(){
Id = 6,
Name = "DocumentRejected_ADM",
Body = "Guten Tag [NAME_SENDER],<p><B><I>[NAME_RECEIVER]</I></B> hat den Umschlag <B><I>'[DOCUMENT_TITLE]'</I></B> mit folgendem Grund abgelehnt: <p>\r\n[REASON] \r\n<p>Der Umschlag wurde auf den Status Rejected gesetzt. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang zurückgezogen"
},
new(){
Id = 9,
Name = "DocumentRejected_REC",
Body = "Guten Tag [NAME_RECEIVER],\r\n<p>Hiermit bestätigen wir Ihnen die Ablehnung des Unterzeichnungsvorganges <B><I>'[DOCUMENT_TITLE]'</I></B>!<p>Der Vertragsinhaber <B><I>[NAME_SENDER]</I></B> wurde über die Ablehnung informiert. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "'[DOCUMENT_TITLE]' - Bestätigung Ablehnung"
},
new(){
Id = 10,
Name = "DocumentRejected_REC_2",
Body = "Guten Tag [NAME_RECEIVER],\r\n<p>Der Unterzeichnungsvorganges <B><I>'[DOCUMENT_TITLE]'</I></B> wurde durch einen anderen Vertragspartner abgelehnt! Ihre notwendige Unterzeichnung wurde verworfen.<p> Der Vertragsinhaber <B><I>[NAME_SENDER]</I></B> wird sich bei Bedarf mit Ihnen in Verbindung setzen. <p> \r\nMit freundlichen Grüßen<br />\r\n<br />\r\n[NAME_PORTAL]",
Subject = "'[DOCUMENT_TITLE]' - Unterzeichnungsvorgang abgelehnt."
},
new(){
Id = 11,
Name = "DocumentShared",
Body = "Guten Tag,<br /> <br /><B><I> [NAME_RECEIVER]</I></B> hat Ihnen ein Dokument zum Ansehen gesendet.<br /> <br /> Über den folgenden Link können Sie das Dokument einsehen: <a href=\"[LINK_TO_DOCUMENT]\">[LINK_TO_DOCUMENT_TEXT]</a><br /> <br /> <br /> Mit freundlichen Grüßen<br /> <br /> [NAME_PORTAL]",
Subject = "Dokument geteilt: '[DOCUMENT_TITLE]'"
},
new(){
Id = 12,
Name = "TotpSecret",
Body = "Guten Tag,<br /> <br />Sie können auf Ihren Zwei-Faktor-Authentifizierungscode zugreifen, indem Sie den unten stehenden QR-Code mit einer beliebigen Authentifizierungs-App auf Ihrem Telefon scannen (Google Authenticator, Microsoft Authenticator usw.). Dieser Code ist bis zum [TFA_EXPIRATION] gültig.<br /> <br /> <img src=\"data:image/png;base64,[TFA_QR_CODE]\" style=\"width: 13rem; height: 13rem;\"><br /> <br />\r\n<br /> Mit freundlichen Grüßen<br /> <br /> [NAME_PORTAL]",
Subject = "2-Faktor-Verifizierung QR-Code"
}
};
}

View File

@@ -1,29 +0,0 @@
using MediatR;
using System.Text.Json.Serialization;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
/// <summary>
/// Befehl zum Aktualisieren einer E-Mail-Vorlage.
/// </summary>
/// <param name="Body">
/// (Optional)Der neue Inhalt des E-Mail-Textkörpers. Wenn null, bleibt der vorhandene Inhalt unverändert.
/// </param>
/// <param name="Subject">
/// (Optional) Der neue Betreff der E-Mail. Wenn null, bleibt der vorhandene Betreff unverändert.
/// </param>
public record UpdateEmailTemplateCommand(string? Body = null, string? Subject = null) : IRequest
{
/// <param>
/// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll.
/// </param>
[JsonIgnore]
public EmailTemplateQuery? EmailTemplateQuery { get; set; }
/// <summary>
///
/// </summary>
[JsonIgnore]
public DateTime ChangedWhen { get; init; } = DateTime.Now;
}

View File

@@ -1,65 +0,0 @@
using DigitalData.Core.Abstraction.Application.Repository;
using EnvelopeGenerator.Application.DTOs;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
/// <summary>
///
/// </summary>
public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemplateCommand>
{
private readonly IRepository<EmailTemplate> _repository;
/// <summary>
///
/// </summary>
/// <param name="repository"></param>
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository)
{
_repository = repository;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="NotFoundException"></exception>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
{
EmailTemplateDto? temp;
if (request.EmailTemplateQuery?.Id is int id)
{
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Id == id, single: false, cancel);
}
else if (request!.EmailTemplateQuery!.Type is Constants.EmailTemplateType type)
{
temp = await _repository.ReadOrDefaultAsync<EmailTemplateDto>(t => t.Name == type.ToString(), single: false, cancel);
}
else
{
throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id +". Type: " + request.EmailTemplateQuery.Type.ToString());
}
if (temp == null)
{
throw new NotFoundException();
}
if (request.Body is not null)
temp.Body = request.Body;
if (request.Subject is not null)
temp.Subject = request.Subject;
await _repository.UpdateAsync(temp, t => t.Id == temp.Id, cancel);
}
}

View File

@@ -1,24 +0,0 @@
using EnvelopeGenerator.Domain;
namespace EnvelopeGenerator.Application.EmailTemplates;
/// <summary>
/// Repräsentiert eine Abfrage für E-Mail-Vorlagen, die für Absender und Empfänger von Umschlägen verwendet werden.
/// Die Standardkultur ist "de-DE".
/// </summary>
/// <param name="Id">Die eindeutige Kennung der E-Mail-Vorlage (optional).</param>
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="Constants.EmailTemplateType"/> (optional). Beispiele:
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
/// </param>
public record EmailTemplateQuery(int? Id = null, Constants.EmailTemplateType? Type = null)
{
}

View File

@@ -1,23 +0,0 @@
using AutoMapper;
using EnvelopeGenerator.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
/// <summary>
///
/// </summary>
public class ReadEmailTemplateMappingProfile : Profile
{
/// <summary>
///
/// </summary>
public ReadEmailTemplateMappingProfile()
{
CreateMap<EmailTemplate, ReadEmailTemplateResponse>();
}
}

View File

@@ -1,12 +0,0 @@
using MediatR;
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
/// <summary>
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
/// Diese Klasse erbt von <see cref="EmailTemplateQuery"/>.
/// </summary>
public record ReadEmailTemplateQuery : EmailTemplateQuery, IRequest<ReadEmailTemplateResponse?>
{
}

View File

@@ -1,52 +0,0 @@
using AutoMapper;
using EnvelopeGenerator.Application.Contracts.Repositories;
using EnvelopeGenerator.Domain;
using MediatR;
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
/// <summary>
///
/// </summary>
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, ReadEmailTemplateResponse?>
{
private readonly IMapper _mapper;
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
private readonly IEmailTemplateRepository _repository;
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
/// </summary>
/// <param name="mapper">
/// <param name="repository">
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
/// </param>
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public ReadEmailTemplateQueryHandler(IMapper mapper, IEmailTemplateRepository repository)
{
_mapper = mapper;
_repository = repository;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
[Obsolete("Use IRepository")]
public async Task<ReadEmailTemplateResponse?> Handle(ReadEmailTemplateQuery request, CancellationToken cancellationToken)
{
var temp = request.Id is int id
? await _repository.ReadByIdAsync(id)
: request.Type is Constants.EmailTemplateType type
? await _repository.ReadByNameAsync(type)
: throw new InvalidOperationException("Either a valid integer ID or a valid EmailTemplateType must be provided in the request.");
var res = _mapper.Map<ReadEmailTemplateResponse>(temp);
return res;
}
}

View File

@@ -1,37 +0,0 @@
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
/// <summary>
/// Stellt die Antwort für eine Abfrage von E-Mail-Vorlagen bereit.
/// </summary>
public class ReadEmailTemplateResponse
{
/// <summary>
/// Die eindeutige Kennung der E-Mail-Vorlage.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Name des Typs
/// </summary>
public required string Name { get; set; }
/// <summary>
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
/// </summary>
public DateTime AddedWhen { get; set; }
/// <summary>
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
/// </summary>
public string? Body { get; set; }
/// <summary>
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
/// </summary>
public string? Subject { get; set; }
/// <summary>
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
/// </summary>
public DateTime? ChangedWhen { get; set; }
}

View File

@@ -1,86 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\Model.Designer.vb" />
</ItemGroup>
<ItemGroup>
<None Remove="Resources\Model.Designer.vb" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.3.4" />
<PackageReference Include="DigitalData.Core.Client" Version="2.1.0" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.1.1" />
<PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
<PackageReference Include="Otp.NET" Version="1.4.0" />
<PackageReference Include="QRCoder" Version="1.6.0" />
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
<PackageReference Include="UserManager" Version="1.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.0.0" />
<PackageReference Include="DigitalData.Core.Application" Version="2.0.0" />
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.0" />
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
<PackageReference Include="UserManager.Application" Version="2.0.0" />
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
<ProjectReference Include="..\EnvelopeGenerator.Extensions\EnvelopeGenerator.Extensions.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EnvelopeGenerator.Extensions\EnvelopeGenerator.Extensions.csproj" />
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Model.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Model.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Model.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Model.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Model.en.resx">
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<LastGenOutput>Model.en.Designer.vb</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Model.resx">
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<LastGenOutput>Model.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Resource.de-DE.resx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Resource.en-US.resx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.3" />
<PackageReference Include="CommandDotNet">
<Version>7.0.5</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
<PackageReference Include="CommandDotNet">
<Version>8.1.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
<PackageReference Include="CommandDotNet">
<Version>8.1.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Model.en.resx">
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<LastGenOutput>Model.en.Designer.vb</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Model.resx">
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<LastGenOutput>Model.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Resource.de-DE.resx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Resource.en-US.resx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -1,21 +0,0 @@
using EnvelopeGenerator.Application.Envelopes.Commands;
using MediatR;
using System.ComponentModel.DataAnnotations;
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
/// <summary>
/// Befehl zur Erstellung eines Umschlags.
/// </summary>
/// <param name="Title">Der Titel des Umschlags. Dies ist ein Pflichtfeld.</param>
/// <param name="Message">Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld.</param>
/// <param name="Document">Das mit dem Umschlag verknüpfte Dokument. Dies ist ein Pflichtfeld.</param>
/// <param name="Receivers">Eine Sammlung von Empfängern, die den Umschlag erhalten. Dies ist ein Pflichtfeld.</param>
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false.</param>
public record CreateEnvelopeReceiverCommand(
[Required] string Title,
[Required] string Message,
[Required] DocumentCreateCommand Document,
[Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers,
bool TFAEnabled = false
) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest<CreateEnvelopeReceiverResponse>;

Some files were not shown because too many files have changed in this diff Show More