Compare commits
111 Commits
b8e4dfdf26
...
bugfix/sig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c57b7e332 | ||
|
|
4bf91df85f | ||
|
|
50796b22d9 | ||
|
|
2974ddb985 | ||
|
|
54f39103e1 | ||
|
|
8b505ae39a | ||
|
|
d75da655d2 | ||
|
|
e72ea534e5 | ||
|
|
e95d1d782e | ||
|
|
32be5077f9 | ||
|
|
d80fa0b023 | ||
|
|
ea6ee11a4e | ||
|
|
13a87f29d9 | ||
|
|
5f8df74b9d | ||
|
|
ebb248969c | ||
|
|
4040741e6f | ||
|
|
4077786ef7 | ||
|
|
ba8394c749 | ||
|
|
97dcc0f0a1 | ||
|
|
8785505a91 | ||
|
|
975beff416 | ||
|
|
45d39069aa | ||
|
|
d3db1e74fa | ||
|
|
4d34eb7adc | ||
|
|
ba4a57512f | ||
|
|
11f4896556 | ||
|
|
44aeb53413 | ||
|
|
d56aa1a778 | ||
|
|
a012396dd4 | ||
|
|
42a1016607 | ||
|
|
4b616896f8 | ||
|
|
54c17f106e | ||
|
|
e171b50868 | ||
|
|
a20c2b556f | ||
|
|
a070a0f64c | ||
|
|
c0608b457c | ||
|
|
927b89554d | ||
|
|
160005e230 | ||
|
|
2848425625 | ||
|
|
c61b497ef2 | ||
|
|
1ece216a27 | ||
|
|
8f6847c060 | ||
|
|
0dc65a53b5 | ||
|
|
7b75a373bd | ||
|
|
fe252b9979 | ||
|
|
f17820e011 | ||
|
|
a21c993cb5 | ||
|
|
dd4afc5ddf | ||
|
|
c220b9e1c8 | ||
|
|
778a498e00 | ||
|
|
48240f2f30 | ||
|
|
e3dfa8dd39 | ||
|
|
6e641395d5 | ||
|
|
fbd09cb570 | ||
|
|
7389909d77 | ||
|
|
ded88383b3 | ||
|
|
1b9b51fbd2 | ||
|
|
afa6dda16f | ||
|
|
994c844f25 | ||
|
|
4551e5dc64 | ||
|
|
ff34e6afab | ||
|
|
a78912260a | ||
|
|
c1e81c546f | ||
|
|
9a950ae37d | ||
|
|
6cec82abd5 | ||
|
|
26616b4cab | ||
|
|
178ec9226d | ||
|
|
0147f525fa | ||
|
|
f0ed6137d1 | ||
|
|
b4ab2c4423 | ||
|
|
5715343651 | ||
|
|
6550be0235 | ||
|
|
99b0dba79f | ||
|
|
2f8d5f1fc8 | ||
|
|
6969f5f93e | ||
|
|
7bbed3890e | ||
|
|
98290c7b28 | ||
|
|
d55006fdda | ||
|
|
b2cc0cb65a | ||
|
|
049827a133 | ||
|
|
b02ab585cb | ||
|
|
c8a5a8627d | ||
|
|
ecf0771f9e | ||
|
|
02c7040b39 | ||
|
|
2cb5d0c0d5 | ||
|
|
9f186afdff | ||
|
|
ec76014ce7 | ||
|
|
e7bc43b339 | ||
|
|
26be8d4565 | ||
|
|
17902c4824 | ||
|
|
396c6014fb | ||
|
|
06175b0c95 | ||
|
|
5375d89d5b | ||
|
|
abd1807b18 | ||
|
|
3f33be452c | ||
|
|
9a4931781a | ||
|
|
b3a2e1559a | ||
|
|
261d1b3db9 | ||
|
|
401d03aac2 | ||
|
|
7871bf72f6 | ||
|
|
7e07afa384 | ||
|
|
251420134a | ||
|
|
701b26289b | ||
|
|
754e3ddc7a | ||
|
|
a0e8cc6989 | ||
|
|
b9f25a0ac4 | ||
|
|
f40ee49977 | ||
|
|
d08e93cbef | ||
|
|
4a48bbb3e2 | ||
|
|
9725e2a729 | ||
|
|
031f0d4cce |
@@ -7,7 +7,7 @@ using static EnvelopeGenerator.Common.Constants;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
|
||||||
public interface IEnvelopeHistoryService : ICRUDService<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>
|
public interface IEnvelopeHistoryService : ICRUDService<EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>
|
||||||
{
|
{
|
||||||
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null);
|
Task<int> CountAsync(int? envelopeId = null, string? userReference = null, int? status = null);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ using EnvelopeGenerator.Domain.Entities;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
|
||||||
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>
|
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using DigitalData.Core.Abstractions.Application;
|
using CommandDotNet;
|
||||||
|
using DigitalData.Core.Abstractions.Application;
|
||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
using EnvelopeGenerator.Application.DTOs.Messaging;
|
using EnvelopeGenerator.Application.DTOs.Messaging;
|
||||||
@@ -25,6 +26,7 @@ public interface IEnvelopeReceiverService : IBasicCRUDService<EnvelopeReceiverDt
|
|||||||
|
|
||||||
Task<DataResult<bool>> VerifyAccessCodeAsync(string uuid, string signature, string accessCode);
|
Task<DataResult<bool>> VerifyAccessCodeAsync(string uuid, string signature, string accessCode);
|
||||||
|
|
||||||
|
[Command("verify-access-code-async-by-id")]
|
||||||
Task<DataResult<bool>> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode);
|
Task<DataResult<bool>> VerifyAccessCodeAsync(string envelopeReceiverId, string accessCode);
|
||||||
|
|
||||||
Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
|
Task<DataResult<bool>> IsExisting(string envelopeReceiverId);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using EnvelopeGenerator.Domain.Entities;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Contracts.Services;
|
namespace EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
|
||||||
public interface IReceiverService : ICRUDService<ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>
|
public interface IReceiverService : ICRUDService<ReceiverCreateDto, ReceiverReadDto, Receiver, int>
|
||||||
{
|
{
|
||||||
Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null);
|
Task<DataResult<ReceiverReadDto>> ReadByAsync(string? emailAddress = null, string? signature = null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record ConfigDto(
|
public record ConfigDto(
|
||||||
string DocumentPath,
|
string DocumentPath,
|
||||||
int SendingProfile,
|
int SendingProfile,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record DocumentReceiverElementDto(
|
public record DocumentReceiverElementDto(
|
||||||
int Id,
|
int Id,
|
||||||
int DocumentId,
|
int DocumentId,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record DocumentStatusDto(
|
public record DocumentStatusDto(
|
||||||
int Id,
|
int Id,
|
||||||
int EnvelopeId,
|
int EnvelopeId,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EmailTemplateDto(
|
public record EmailTemplateDto(
|
||||||
int Id,
|
int Id,
|
||||||
string Name,
|
string Name,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeCertificateDto(
|
public record EnvelopeCertificateDto(
|
||||||
int Id,
|
int Id,
|
||||||
int EnvelopeId,
|
int EnvelopeId,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeDocumentDto
|
public record EnvelopeDocumentDto
|
||||||
(
|
(
|
||||||
int Id,
|
int Id,
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||||
using DigitalData.UserManager.Application.DTOs.User;
|
using DigitalData.UserManager.Application.DTOs.User;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeDto() : IUnique<int>
|
public record EnvelopeDto() : IUnique<int>
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeHistoryCreateDto(
|
public record EnvelopeHistoryCreateDto(
|
||||||
int EnvelopeId,
|
int EnvelopeId,
|
||||||
string UserReference,
|
string UserReference,
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using DigitalData.UserManager.Application.DTOs.User;
|
using DigitalData.UserManager.Application.DTOs.User;
|
||||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using static EnvelopeGenerator.Common.Constants;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeHistoryDto(
|
public record EnvelopeHistoryDto(
|
||||||
long Id,
|
long Id,
|
||||||
int EnvelopeId,
|
int EnvelopeId,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)>
|
public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)>
|
||||||
{
|
{
|
||||||
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
|
public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto()
|
||||||
{
|
{
|
||||||
public EnvelopeDto? Envelope { get; set; }
|
public EnvelopeDto? Envelope { get; set; }
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverSecretDto() : EnvelopeReceiverDto()
|
public record EnvelopeReceiverSecretDto() : EnvelopeReceiverDto()
|
||||||
{
|
{
|
||||||
public string? AccessCode { get; init; }
|
public string? AccessCode { get; init; }
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverReadOnlyCreateDto(
|
public record EnvelopeReceiverReadOnlyCreateDto(
|
||||||
DateTime DateValid)
|
DateTime DateValid)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverReadOnlyDto(
|
public record EnvelopeReceiverReadOnlyDto(
|
||||||
long Id,
|
long Id,
|
||||||
long EnvelopeId,
|
long EnvelopeId,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeReceiverReadOnlyUpdateDto(
|
public record EnvelopeReceiverReadOnlyUpdateDto(
|
||||||
long Id,
|
long Id,
|
||||||
DateTime DateValid,
|
DateTime DateValid,
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record EnvelopeTypeDto(
|
public record EnvelopeTypeDto(
|
||||||
int Id,
|
int Id,
|
||||||
string Title,
|
string Title,
|
||||||
|
|||||||
70
EnvelopeGenerator.Application/DTOs/MappingProfile.cs
Normal file
70
EnvelopeGenerator.Application/DTOs/MappingProfile.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
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<UserReceiver, UserReceiverDto>();
|
||||||
|
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<UserReceiverDto, UserReceiver>();
|
||||||
|
CreateMap<EnvelopeReceiverBase, 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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public class GtxMessagingResponse : Dictionary<string, object?> { }
|
public class GtxMessagingResponse : Dictionary<string, object?> { }
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.Messaging
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record SmsResponse
|
public record SmsResponse
|
||||||
{
|
{
|
||||||
public required bool Ok { get; init; }
|
public required bool Ok { get; init; }
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.Receiver
|
namespace EnvelopeGenerator.Application.DTOs.Receiver
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record ReceiverCreateDto([EmailAddress] string EmailAddress, string? TotpSecretkey = null)
|
public record ReceiverCreateDto([EmailAddress] string EmailAddress, string? TotpSecretkey = null)
|
||||||
{
|
{
|
||||||
public string Signature => sha256HexOfMail.Value;
|
public string Signature => sha256HexOfMail.Value;
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record ReceiverReadDto(
|
public record ReceiverReadDto(
|
||||||
int Id,
|
int Id,
|
||||||
string EmailAddress,
|
string EmailAddress,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
namespace EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record ReceiverUpdateDto(int Id, string? TotpSecretkey = null, DateTime? TfaRegDeadline = null) : IUnique<int>;
|
public record ReceiverUpdateDto(int Id, string? TotpSecretkey = null, DateTime? TfaRegDeadline = null) : IUnique<int>;
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
using DigitalData.Core.Abstractions;
|
using DigitalData.Core.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.DTOs
|
namespace EnvelopeGenerator.Application.DTOs
|
||||||
{
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
public record UserReceiverDto(
|
public record UserReceiverDto(
|
||||||
int Id,
|
int Id,
|
||||||
int UserId,
|
int UserId,
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using DigitalData.UserManager.Application.MappingProfiles;
|
using EnvelopeGenerator.Application.Configurations;
|
||||||
using EnvelopeGenerator.Application.MappingProfiles;
|
|
||||||
using EnvelopeGenerator.Application.Configurations;
|
|
||||||
using EnvelopeGenerator.Application.Services;
|
using EnvelopeGenerator.Application.Services;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -8,11 +6,21 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
|||||||
using DigitalData.Core.Client;
|
using DigitalData.Core.Client;
|
||||||
using QRCoder;
|
using QRCoder;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Extensions;
|
namespace EnvelopeGenerator.Application;
|
||||||
|
|
||||||
public static class DIExtensions
|
/// <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>
|
||||||
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config)
|
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config)
|
||||||
{
|
{
|
||||||
//Inject CRUD Service and repositoriesad
|
//Inject CRUD Service and repositoriesad
|
||||||
@@ -32,8 +40,8 @@ public static class DIExtensions
|
|||||||
services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
|
services.TryAddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
|
||||||
|
|
||||||
//Auto mapping profiles
|
//Auto mapping profiles
|
||||||
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
services.AddAutoMapper(Assembly.GetExecutingAssembly());
|
||||||
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
|
services.AddAutoMapper(typeof(DigitalData.UserManager.Application.DIExtensions));
|
||||||
|
|
||||||
services.Configure<DispatcherParams>(config.GetSection(nameof(DispatcherParams)));
|
services.Configure<DispatcherParams>(config.GetSection(nameof(DispatcherParams)));
|
||||||
services.Configure<MailParams>(config.GetSection(nameof(MailParams)));
|
services.Configure<MailParams>(config.GetSection(nameof(MailParams)));
|
||||||
@@ -47,6 +55,11 @@ public static class DIExtensions
|
|||||||
services.TryAddSingleton<IAuthenticator, Authenticator>();
|
services.TryAddSingleton<IAuthenticator, Authenticator>();
|
||||||
services.TryAddSingleton<QRCodeGenerator>();
|
services.TryAddSingleton<QRCodeGenerator>();
|
||||||
|
|
||||||
|
services.AddMediatR(cfg =>
|
||||||
|
{
|
||||||
|
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
||||||
|
});
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
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?>
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using DigitalData.Core.Abstractions.Infrastructure;
|
||||||
|
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>
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the response for reading a document.
|
||||||
|
/// </summary>
|
||||||
|
public class ReadDocumentResponse
|
||||||
|
{
|
||||||
|
/// <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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The binary data of the document, if available.
|
||||||
|
/// </summary>
|
||||||
|
public byte[]? ByteData { get; init; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using EnvelopeGenerator.Common;
|
||||||
|
|
||||||
|
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.
|
||||||
|
/// </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). 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 ResetEnvelopeTemplateCommand(int? Id, Constants.EmailTemplateType? Type) : EmailTemplateQuery(Id, Type);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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)
|
||||||
|
{
|
||||||
|
/// <param>
|
||||||
|
/// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll.
|
||||||
|
/// </param>
|
||||||
|
[JsonIgnore]
|
||||||
|
public EmailTemplateQuery? EmailTemplateQuery { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using EnvelopeGenerator.Common;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stellt die Antwort für eine Abfrage von E-Mail-Vorlagen bereit.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Die eindeutige Kennung der E-Mail-Vorlage.</param>
|
||||||
|
/// <param name="Type">Der Typ der E-Mail-Vorlage.</param>
|
||||||
|
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.</param>
|
||||||
|
/// <param name="Body">Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.</param>
|
||||||
|
/// <param name="Subject">Der Betreff der E-Mail-Vorlage. Kann null sein.</param>
|
||||||
|
/// <param name="ChangedWhen">Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.</param>
|
||||||
|
public record ReadEmailTemplateResponse(
|
||||||
|
int Id,
|
||||||
|
int Type,
|
||||||
|
DateTime AddedWhen,
|
||||||
|
string? Body = null,
|
||||||
|
string? Subject = null,
|
||||||
|
DateTime? ChangedWhen = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -11,18 +13,18 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||||
<PackageReference Include="DigitalData.Core.Application" Version="2.0.0" />
|
|
||||||
<PackageReference Include="DigitalData.Core.Client" Version="2.0.3" />
|
<PackageReference Include="DigitalData.Core.Client" Version="2.0.3" />
|
||||||
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
|
||||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="2.0.0" />
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||||
|
<PackageReference Include="MediatR" Version="12.5.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||||
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
|
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
|
||||||
<PackageReference Include="UserManager.Application" Version="2.0.0" />
|
<PackageReference Include="UserManager" Version="1.0.0" />
|
||||||
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -57,4 +59,25 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||||
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
|
<PackageReference Include="CommandDotNet">
|
||||||
|
<Version>7.0.5</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
|
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||||
|
<PackageReference Include="CommandDotNet">
|
||||||
|
<Version>8.1.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||||
|
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||||
|
<PackageReference Include="CommandDotNet">
|
||||||
|
<Version>8.1.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
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
|
||||||
|
) : IRequest;
|
||||||
|
|
||||||
|
#region DTOs
|
||||||
|
/// <summary>
|
||||||
|
/// Signaturposition auf einem Dokument.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="X">X-Position</param>
|
||||||
|
/// <param name="Y">Y-Position</param>
|
||||||
|
/// <param name="Page">Seite, auf der sie sich befindet</param>
|
||||||
|
public record Signature([Required] int X, [Required] int Y, [Required] int Page);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DTO für Empfänger, die erstellt oder abgerufen werden sollen.
|
||||||
|
/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Signatures">Unterschriften auf Dokumenten.</param>
|
||||||
|
/// <param name="Salution">Der Name, mit dem der Empfänger angesprochen werden soll. Bei Null oder keinem Wert wird der zuletzt verwendete Name verwendet.</param>
|
||||||
|
/// <param name="PhoneNumber">Sollte mit Vorwahl geschrieben werden</param>
|
||||||
|
public record ReceiverGetOrCreateCommand([Required] IEnumerable<Signature> Signatures, string? Salution = null, string? PhoneNumber = null)
|
||||||
|
{
|
||||||
|
private string _emailAddress = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// E-Mail-Adresse des Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public required string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress = _emailAddress.ToLower(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DTO zum Erstellen eines Dokuments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="DataAsByte">
|
||||||
|
/// Die Dokumentdaten im Byte-Array-Format. Wird verwendet, wenn das Dokument als Roh-Binärdaten bereitgestellt wird.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="DataAsBase64">
|
||||||
|
/// Die Dokumentdaten im Base64-String-Format. Wird verwendet, wenn das Dokument als Base64-codierter String bereitgestellt wird.
|
||||||
|
/// </param>
|
||||||
|
public record DocumentCreateCommand(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
||||||
|
#endregion
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using EnvelopeGenerator.Application.Histories;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stellt eine Abfrage für einen Envelope-Empfänger dar.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Status">Der Status der Abfrage, optional.</param>
|
||||||
|
public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Common.Constants.EnvelopeStatus"/>
|
||||||
|
/// Invalid (0): Ungültiger Status.
|
||||||
|
/// EnvelopeCreated (1001): Der Umschlag wurde erstellt.
|
||||||
|
/// EnvelopeSaved (1002): Der Umschlag wurde gespeichert.
|
||||||
|
/// EnvelopeQueued (1003): Der Umschlag wurde zur Verarbeitung eingeplant.
|
||||||
|
/// EnvelopeSent (1004): Der Umschlag wurde versendet. (Nicht verwendet)
|
||||||
|
/// EnvelopePartlySigned (1005): Der Umschlag wurde teilweise unterschrieben.
|
||||||
|
/// EnvelopeCompletelySigned (1006): Der Umschlag wurde vollständig unterschrieben.
|
||||||
|
/// EnvelopeReportCreated (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.
|
||||||
|
/// EnvelopeArchived (1008): Der Umschlag wurde archiviert.
|
||||||
|
/// EnvelopeDeleted (1009): Der Umschlag wurde gelöscht.
|
||||||
|
/// AccessCodeRequested (2001): Der Zugriffscode wurde angefordert.
|
||||||
|
/// AccessCodeCorrect (2002): Der Zugriffscode war korrekt.
|
||||||
|
/// AccessCodeIncorrect (2003): Der Zugriffscode war falsch.
|
||||||
|
/// DocumentOpened (2004): Das Dokument wurde geöffnet.
|
||||||
|
/// DocumentSigned (2005): Ein Dokument wurde unterschrieben.
|
||||||
|
/// SignatureConfirmed (2006): Die Signatur wurde bestätigt.
|
||||||
|
/// DocumentRejected (2007): Ein Dokument wurde abgelehnt.
|
||||||
|
/// EnvelopeShared (2008): Der Umschlag wurde geteilt.
|
||||||
|
/// EnvelopeViewed (2009): Der Umschlag wurde angesehen.
|
||||||
|
/// DocumentForwarded (4001): Das Dokument wurde weitergeleitet.
|
||||||
|
/// MessageInvitationSent (3001): Einladung wurde gesendet (vom Trigger verwendet).
|
||||||
|
/// MessageAccessCodeSent (3002): Zugriffscode wurde gesendet.
|
||||||
|
/// MessageConfirmationSent (3003): Bestätigungsnachricht wurde gesendet.
|
||||||
|
/// MessageDeletionSent (3004): Löschbenachrichtigung wurde gesendet.
|
||||||
|
/// MessageCompletionSent (3005): Abschlussbenachrichtigung wurde gesendet.
|
||||||
|
/// <param name="Min">Der minimale Statuswert, der berücksichtigt werden soll.</param>
|
||||||
|
/// <param name="Max">Der maximale Statuswert, der berücksichtigt werden soll.</param>
|
||||||
|
/// <param name="Ignore">Eine Liste von Statuswerten, die ignoriert werden sollen.</param>
|
||||||
|
/// </summary>
|
||||||
|
public record EnvelopeStatusQuery(
|
||||||
|
int? Min = null,
|
||||||
|
int? Max = null,
|
||||||
|
int[]? Ignore = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using EnvelopeGenerator.Application.Histories;
|
||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Diese Abfrage kombiniert Informationen über einen Umschlag (<see cref="ReadEnvelopeQuery"/>)
|
||||||
|
/// und einen Empfänger (<see cref="ReadReceiverQuery"/>), um eine vollständige Antwort
|
||||||
|
/// (<see cref="ReadEnvelopeReceiverResponse"/>) zu generieren.
|
||||||
|
/// Die Antwort enthält Details wie den Status, die Zuordnung zwischen Umschlag und Empfänger
|
||||||
|
/// sowie zusätzliche Metadaten.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="Status">Umschlag oder Empfängerstatus.</param>
|
||||||
|
public record ReadEnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null) : EnvelopeReceiverQuery(Status), IRequest<ReadEnvelopeReceiverResponse>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Der Umschlag, der mit dem Empfänger verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
|
public ReadEnvelopeQuery? Envelope { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Empfänger, der mit dem Umschlag verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
|
public ReadReceiverQuery? Receiver { get; init; }
|
||||||
|
};
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert die Antwort für das Lesen eines Envelope-Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Diese Klasse enthält Informationen über einen spezifischen Empfänger eines Umschlags (Envelope).
|
||||||
|
/// Sie verknüpft die Empfängerinformationen mit den zugehörigen Umschlagsdaten und bietet zusätzliche Metadaten.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="UserId">Die eindeutige Kennung des Benutzers, der den Empfänger erstellt hat.</param>
|
||||||
|
/// <param name="Status">Der Status des Empfängers als numerischer Wert.</param>
|
||||||
|
public record ReadEnvelopeReceiverResponse(int UserId, int Status)
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt die zusammengesetzte Kennung des Empfängers zurück, bestehend aus der Umschlags-ID und der Empfänger-ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Diese Eigenschaft kombiniert die eindeutige Kennung des Umschlags (EnvelopeId) und die des Empfängers (ReceiverId)
|
||||||
|
/// zu einer einzigen, leicht zugänglichen Struktur.
|
||||||
|
/// </remarks>
|
||||||
|
[NotMapped]
|
||||||
|
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die eindeutige Kennung des zugehörigen Umschlags.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public int EnvelopeId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die eindeutige Kennung des Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public int ReceiverId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Reihenfolge des Empfängers innerhalb des Umschlags.
|
||||||
|
/// </summary>
|
||||||
|
public int Sequence { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Name des Empfängers. Kann als Platzhalter verwendet werden.
|
||||||
|
/// </summary>
|
||||||
|
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
||||||
|
public string? Name { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Berufsbezeichnung des Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
public string? JobTitle { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Firmenname des Empfängers.
|
||||||
|
/// </summary>
|
||||||
|
public string? CompanyName { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eine private Nachricht, die mit dem Empfänger verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
|
public string? PrivateMessage { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime AddedWhen { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Das Datum und die Uhrzeit, wann der Empfänger zuletzt geändert wurde (falls vorhanden).
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? ChangedWhen { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt an, ob der Empfänger eine Telefonnummer hat.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasPhoneNumber { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die zugehörigen Umschlagsdaten.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public required ReadEnvelopeResponse Envelope { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Liste der Empfängerinformationen.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public IEnumerable<ReadReceiverResponse> Receiver { get; init; } = new List<ReadReceiverResponse>();
|
||||||
|
}
|
||||||
16
EnvelopeGenerator.Application/Envelopes/EnvelopeQuery.cs
Normal file
16
EnvelopeGenerator.Application/Envelopes/EnvelopeQuery.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Envelopes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert eine Abfrage für Umschläge.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
||||||
|
/// <param name="Status">Der Status des Umschlags.</param>
|
||||||
|
/// <param name="Uuid">Die universell eindeutige Kennung des Umschlags.</param>
|
||||||
|
public record EnvelopeQuery(
|
||||||
|
int? Id = null,
|
||||||
|
int? Status = null,
|
||||||
|
string? Uuid = null) : IRequest
|
||||||
|
{
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stellt eine Abfrage zum Lesen von Briefumschlägen dar.
|
||||||
|
/// </summary>
|
||||||
|
public record ReadEnvelopeQuery : EnvelopeQuery
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using EnvelopeGenerator.Common;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert die Antwort für das Lesen eines Umschlags.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
||||||
|
/// <param name="UserId">Die Kennung des Benutzers, der den Umschlag erstellt hat.</param>
|
||||||
|
/// <param name="Status">Der Status des Umschlags als numerischer Wert.</param>
|
||||||
|
/// <param name="Uuid">Die universelle eindeutige Kennung (UUID) des Umschlags.</param>
|
||||||
|
/// <param name="Message">Eine optionale Nachricht, die mit dem Umschlag verknüpft ist.</param>
|
||||||
|
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann der Umschlag hinzugefügt wurde.</param>
|
||||||
|
/// <param name="ChangedWhen">Das Datum und die Uhrzeit, wann der Umschlag zuletzt geändert wurde (falls vorhanden).</param>
|
||||||
|
/// <param name="Title">Ein optionaler Titel des Umschlags.</param>
|
||||||
|
/// <param name="Language">Die Sprache, die mit dem Umschlag verknüpft ist.</param>
|
||||||
|
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung (TFA) aktiviert ist.</param>
|
||||||
|
/// <param name="User">Das Benutzerobjekt, das mit dem Umschlag verknüpft ist.</param>
|
||||||
|
public record ReadEnvelopeResponse(
|
||||||
|
int Id,
|
||||||
|
int UserId,
|
||||||
|
int Status,
|
||||||
|
string Uuid,
|
||||||
|
string? Message,
|
||||||
|
DateTime AddedWhen,
|
||||||
|
DateTime? ChangedWhen,
|
||||||
|
string? Title,
|
||||||
|
string Language,
|
||||||
|
bool TFAEnabled,
|
||||||
|
DigitalData.UserManager.Domain.Entities.User User)
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt den Namen des Status zurück, der dem numerischen Statuswert entspricht.
|
||||||
|
/// </summary>
|
||||||
|
public string StatusName => ((Constants.EnvelopeStatus)Status).ToString();
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln,
|
||||||
|
/// damit diese für zukünftige Umschläge wiederverwendet werden kann.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Envelope">Der Umschlag, für den die Anrede des Empfängers ermittelt werden soll.</param>
|
||||||
|
/// <param name="OnlyLast">Gibt an, ob nur die zuletzt verwendete Anrede zurückgegeben werden soll.</param>
|
||||||
|
public record ReadReceiverNameQuery(EnvelopeQuery? Envelope = null, bool OnlyLast = true) : ReadReceiverQuery
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Common;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert eine Abfrage für die Verlaufshistorie eines Umschlags.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="EnvelopeId">Die eindeutige Kennung des Umschlags.</param>
|
||||||
|
/// <param name="Envelope">Die Abfrage, die den Umschlag beschreibt.</param>
|
||||||
|
/// <param name="Receiver">Die Abfrage, die den Empfänger beschreibt.</param>
|
||||||
|
/// <param name="Related">Abfrage, die angibt, worauf sich der Datensatz bezieht. Ob er sich auf den Empfänger, den Sender oder das System bezieht, wird durch 0, 1 bzw. 2 dargestellt.</param>
|
||||||
|
/// <param name="OnlyLast">Abfrage zur Steuerung, ob nur der aktuelle Status oder der gesamte Datensatz zurückgegeben wird.</param>
|
||||||
|
public record ReadHistoryQuery(
|
||||||
|
int EnvelopeId,
|
||||||
|
ReadEnvelopeQuery? Envelope = null,
|
||||||
|
ReadReceiverQuery? Receiver = null,
|
||||||
|
Constants.ReferenceType? Related = null,
|
||||||
|
bool? OnlyLast = true);
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using EnvelopeGenerator.Application.DTOs;
|
|
||||||
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.MappingProfiles
|
|
||||||
{
|
|
||||||
public class BasicDtoMappingProfile : Profile
|
|
||||||
{
|
|
||||||
public BasicDtoMappingProfile()
|
|
||||||
{
|
|
||||||
// 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<EnvelopeHistory, EnvelopeHistoryDto>();
|
|
||||||
CreateMap<EnvelopeHistory, EnvelopeHistoryCreateDto>();
|
|
||||||
CreateMap<EnvelopeReceiver, EnvelopeReceiverDto>();
|
|
||||||
CreateMap<EnvelopeReceiver, EnvelopeReceiverSecretDto>();
|
|
||||||
CreateMap<EnvelopeType, EnvelopeTypeDto>();
|
|
||||||
CreateMap<Receiver, ReceiverReadDto>();
|
|
||||||
CreateMap<Receiver, ReceiverCreateDto>();
|
|
||||||
CreateMap<Receiver, ReceiverUpdateDto>();
|
|
||||||
CreateMap<UserReceiver, UserReceiverDto>();
|
|
||||||
CreateMap<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, EnvelopeHistory>();
|
|
||||||
CreateMap<EnvelopeHistoryCreateDto, EnvelopeHistory>();
|
|
||||||
CreateMap<EnvelopeReceiverDto, EnvelopeReceiver>();
|
|
||||||
CreateMap<EnvelopeTypeDto, EnvelopeType>();
|
|
||||||
CreateMap<ReceiverReadDto, Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
|
||||||
CreateMap<ReceiverCreateDto, Receiver>();
|
|
||||||
CreateMap<ReceiverUpdateDto, Receiver>();
|
|
||||||
CreateMap<UserReceiverDto, UserReceiver>();
|
|
||||||
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
|
||||||
CreateMap<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnly>();
|
|
||||||
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly>();
|
|
||||||
|
|
||||||
// Messaging mappings
|
|
||||||
// for GTX messaging
|
|
||||||
CreateMap<GtxMessagingResponse, SmsResponse>()
|
|
||||||
.ConstructUsing(gtxRes => gtxRes.Ok()
|
|
||||||
? new SmsResponse() { Ok = true }
|
|
||||||
: new SmsResponse() { Ok = false, Errors = gtxRes });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen.
|
||||||
|
/// Diese Abfrage erbt von <see cref="ReceiverQuery"/> und wird verwendet,
|
||||||
|
/// um spezifische Informationen über einen Empfänger abzurufen.
|
||||||
|
/// </summary>
|
||||||
|
public record ReadReceiverQuery : ReceiverQuery
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert die Antwort auf eine Abfrage, um einen Empfänger zu lesen.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Die eindeutige Identifikationsnummer des Empfängers.</param>
|
||||||
|
/// <param name="EmailAddress">Die E-Mail-Adresse des Empfängers.</param>
|
||||||
|
/// <param name="AddedWhen">Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.</param>
|
||||||
|
/// <param name="Signature">Die Signatur des Empfängers.</param>
|
||||||
|
public record ReadReceiverResponse(int Id, string EmailAddress, DateTime AddedWhen, string Signature)
|
||||||
|
{
|
||||||
|
}
|
||||||
9
EnvelopeGenerator.Application/Receivers/ReceiverQuery.cs
Normal file
9
EnvelopeGenerator.Application/Receivers/ReceiverQuery.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Receivers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Empfänger des Umschlags
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">ID des Empfängers</param>
|
||||||
|
/// <param name="EmailAddress">E-Mail Adresse des Empfängers</param>
|
||||||
|
/// <param name="Signature">Eindeutige Signatur des Empfängers</param>
|
||||||
|
public record ReceiverQuery(int? Id = null, string? EmailAddress = null, string? Signature = null);
|
||||||
@@ -10,7 +10,7 @@ using EnvelopeGenerator.Application.Contracts.Services;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services;
|
namespace EnvelopeGenerator.Application.Services;
|
||||||
|
|
||||||
public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
|
public class EnvelopeHistoryService : CRUDService<IEnvelopeHistoryRepository, EnvelopeHistoryCreateDto, EnvelopeHistoryDto, EnvelopeHistory, long>, IEnvelopeHistoryService
|
||||||
{
|
{
|
||||||
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper)
|
public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper)
|
||||||
: base(repository, mapper)
|
: base(repository, mapper)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using EnvelopeGenerator.Application.Contracts.Repositories;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services;
|
namespace EnvelopeGenerator.Application.Services;
|
||||||
|
|
||||||
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
||||||
{
|
{
|
||||||
public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper)
|
public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using EnvelopeGenerator.Application.Contracts.Services;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services;
|
namespace EnvelopeGenerator.Application.Services;
|
||||||
|
|
||||||
public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>, IReceiverService
|
public class ReceiverService : CRUDService<IReceiverRepository, ReceiverCreateDto, ReceiverReadDto, Receiver, int>, IReceiverService
|
||||||
{
|
{
|
||||||
public ReceiverService(IReceiverRepository repository, IMapper mapper)
|
public ReceiverService(IReceiverRepository repository, IMapper mapper)
|
||||||
: base(repository, mapper)
|
: base(repository, mapper)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
'TODO: standardize in xwiki
|
'TODO: standardize in xwiki
|
||||||
Public Enum ReferenceType
|
Public Enum ReferenceType
|
||||||
Receiver
|
Receiver = 0
|
||||||
Sender
|
Sender
|
||||||
System
|
System
|
||||||
Unknown
|
Unknown
|
||||||
@@ -94,13 +94,16 @@
|
|||||||
End Enum
|
End Enum
|
||||||
|
|
||||||
Public Enum EmailTemplateType
|
Public Enum EmailTemplateType
|
||||||
DocumentReceived
|
DocumentReceived = 0
|
||||||
DocumentSigned
|
DocumentSigned
|
||||||
DocumentDeleted
|
DocumentDeleted
|
||||||
DocumentCompleted
|
DocumentCompleted
|
||||||
DocumentAccessCodeReceived
|
DocumentAccessCodeReceived
|
||||||
DocumentShared
|
DocumentShared
|
||||||
TotpSecret
|
TotpSecret
|
||||||
|
DocumentRejected_ADM
|
||||||
|
DocumentRejected_REC
|
||||||
|
DocumentRejected_REC_2
|
||||||
End Enum
|
End Enum
|
||||||
|
|
||||||
Public Enum EncodeType
|
Public Enum EncodeType
|
||||||
|
|||||||
@@ -2,27 +2,26 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Domain.Entities
|
namespace EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
|
[Table("TBSIG_ENVELOPE_DOCUMENT", Schema = "dbo")]
|
||||||
|
public class EnvelopeDocument : IUnique<int>
|
||||||
{
|
{
|
||||||
[Table("TBSIG_ENVELOPE_DOCUMENT", Schema = "dbo")]
|
[Key]
|
||||||
public class EnvelopeDocument : IUnique<int>
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
{
|
[Column("GUID")]
|
||||||
[Key]
|
public int Id { get; set; }
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
|
||||||
[Column("GUID")]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("ENVELOPE_ID")]
|
[Column("ENVELOPE_ID")]
|
||||||
public int EnvelopeId { get; set; }
|
public int EnvelopeId { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||||
public required DateTime AddedWhen { get; set; }
|
public required DateTime AddedWhen { get; set; }
|
||||||
|
|
||||||
[Column("BYTE_DATA", TypeName = "varbinary(max)")]
|
[Column("BYTE_DATA", TypeName = "varbinary(max)")]
|
||||||
public byte[]? ByteData { get; init; }
|
public byte[]? ByteData { get; init; }
|
||||||
|
|
||||||
public IEnumerable<DocumentReceiverElement>? Elements { get; set; }
|
public IEnumerable<DocumentReceiverElement>? Elements { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="1.0.0" />
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" />
|
||||||
<PackageReference Include="UserManager.Domain" Version="1.0.0" />
|
<PackageReference Include="UserManager.Domain" Version="3.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -156,7 +156,11 @@ Public Class EnvelopeEditorController
|
|||||||
|
|
||||||
Public Async Function CreateDocument(pDocumentFilePath As String) As Threading.Tasks.Task(Of EnvelopeDocument)
|
Public Async Function CreateDocument(pDocumentFilePath As String) As Threading.Tasks.Task(Of EnvelopeDocument)
|
||||||
Try
|
Try
|
||||||
Dim oFileInfo = New FileInfo(pDocumentFilePath)
|
Dim oFixedPath = FixPageRotation.FixPageRotation(pDocumentFilePath)
|
||||||
|
If oFixedPath <> pDocumentFilePath Then
|
||||||
|
Logger.Info("PageRotation has been reseted to 0.")
|
||||||
|
End If
|
||||||
|
Dim oFileInfo = New FileInfo(oFixedPath)
|
||||||
Dim oTempFiles As New TempFiles(State.LogConfig)
|
Dim oTempFiles As New TempFiles(State.LogConfig)
|
||||||
Dim oTempFilePath = Path.Combine(oTempFiles._TempPath, Guid.NewGuid().ToString + oFileInfo.Extension)
|
Dim oTempFilePath = Path.Combine(oTempFiles._TempPath, Guid.NewGuid().ToString + oFileInfo.Extension)
|
||||||
|
|
||||||
@@ -172,7 +176,7 @@ Public Class EnvelopeEditorController
|
|||||||
.FileNameOriginal = oFileInfo.Name,
|
.FileNameOriginal = oFileInfo.Name,
|
||||||
.Thumbnail = Thumbnail.GetThumbnailFromPDFFile(oTempFilePath),
|
.Thumbnail = Thumbnail.GetThumbnailFromPDFFile(oTempFilePath),
|
||||||
.PageCount = Thumbnail.GetPageCount(oTempFilePath),
|
.PageCount = Thumbnail.GetPageCount(oTempFilePath),
|
||||||
.Byte_Data = ReadFile(pDocumentFilePath)
|
.Byte_Data = ReadFile(oFixedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
Return oDocument
|
Return oDocument
|
||||||
|
|||||||
@@ -368,6 +368,7 @@
|
|||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Helper\Encryption.vb" />
|
<Compile Include="Helper\Encryption.vb" />
|
||||||
|
<Compile Include="Helper\FixPageRotation.vb" />
|
||||||
<Compile Include="Helper\RefreshHelper.vb" />
|
<Compile Include="Helper\RefreshHelper.vb" />
|
||||||
<Compile Include="Helper\TempFiles.vb" />
|
<Compile Include="Helper\TempFiles.vb" />
|
||||||
<Compile Include="Helper\Thumbnail.vb" />
|
<Compile Include="Helper\Thumbnail.vb" />
|
||||||
|
|||||||
48
EnvelopeGenerator.Form/Helper/FixPageRotation.vb
Normal file
48
EnvelopeGenerator.Form/Helper/FixPageRotation.vb
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
Imports System.IO
|
||||||
|
Imports GdPicture14
|
||||||
|
|
||||||
|
Public Class FixPageRotation
|
||||||
|
''' <summary>
|
||||||
|
''' Checks if there are any rotations in the document. If so, normalizes the page rotation to 0 without affecting its visual appearance.
|
||||||
|
''' Creates and uses a new document with the corrected properties.
|
||||||
|
''' Fixes the issue of annotations being rotated to match the page's rotation.
|
||||||
|
''' </summary>
|
||||||
|
''' <param name="pFilePath"></param>
|
||||||
|
''' <returns></returns>
|
||||||
|
Public Shared Function FixPageRotation(pFilePath As String) As String
|
||||||
|
|
||||||
|
Dim oFolder As String = Path.GetDirectoryName(pFilePath)
|
||||||
|
Dim oChanged As Boolean = False
|
||||||
|
|
||||||
|
Using gdpicturePDF As New GdPicturePDF()
|
||||||
|
|
||||||
|
Dim status As GdPictureStatus = gdpicturePDF.LoadFromFile(pFilePath, True)
|
||||||
|
If status = GdPictureStatus.OK Then
|
||||||
|
|
||||||
|
Dim count As Integer = gdpicturePDF.GetPageCount()
|
||||||
|
For i As Integer = 1 To count
|
||||||
|
If gdpicturePDF.SelectPage(i) = GdPictureStatus.OK Then
|
||||||
|
Dim rotation As Integer = gdpicturePDF.GetPageRotation()
|
||||||
|
If rotation <> 0 Then
|
||||||
|
gdpicturePDF.NormalizePage()
|
||||||
|
oChanged = True
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
|
||||||
|
End If
|
||||||
|
|
||||||
|
If oChanged Then
|
||||||
|
Dim newFilesPath As String = Path.Combine(oFolder, "RotationFixed_" & Path.GetFileName(pFilePath))
|
||||||
|
If gdpicturePDF.SaveToFile(newFilesPath) = GdPictureStatus.OK Then
|
||||||
|
Return newFilesPath
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
|
End Using
|
||||||
|
|
||||||
|
Return pFilePath
|
||||||
|
|
||||||
|
End Function
|
||||||
|
|
||||||
|
End Class
|
||||||
13
EnvelopeGenerator.GeneratorAPI/.config/dotnet-tools.json
Normal file
13
EnvelopeGenerator.GeneratorAPI/.config/dotnet-tools.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-ef": {
|
||||||
|
"version": "9.0.3",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-ef"
|
||||||
|
],
|
||||||
|
"rollForward": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,17 +7,27 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using DigitalData.UserManager.Application.DTOs.Auth;
|
using DigitalData.UserManager.Application.DTOs.Auth;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus.
|
||||||
|
/// </summary>
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class AuthController : ControllerBase
|
public partial class AuthController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<AuthController> _logger;
|
private readonly ILogger<AuthController> _logger;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IDirectorySearchService _dirSearchService;
|
private readonly IDirectorySearchService _dirSearchService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AuthController"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">The logger instance.</param>
|
||||||
|
/// <param name="userService">The user service instance.</param>
|
||||||
|
/// <param name="dirSearchService">The directory search service instance.</param>
|
||||||
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
|
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -25,10 +35,37 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|||||||
_dirSearchService = dirSearchService;
|
_dirSearchService = dirSearchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: When a user group is created for signFlow, add a process to check if the user is in this group (like "PM_USER")
|
/// <summary>
|
||||||
|
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||||
|
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth?cookie=true
|
||||||
|
/// {
|
||||||
|
/// "username": "MaxMustermann",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// POST /api/auth?cookie=true
|
||||||
|
/// {
|
||||||
|
/// "id": "1",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||||
|
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost("login")]
|
[HttpPost]
|
||||||
public async Task<IActionResult> Login([FromBody] LogInDto login)
|
public async Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -48,13 +85,13 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|||||||
|
|
||||||
// Create claims
|
// Create claims
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new (ClaimTypes.NameIdentifier, user.Id.ToString()),
|
new (ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
new (ClaimTypes.Name, user.Username),
|
new (ClaimTypes.Name, user.Username),
|
||||||
new (ClaimTypes.Surname, user.Name!),
|
new (ClaimTypes.Surname, user.Name!),
|
||||||
new (ClaimTypes.GivenName, user.Prename!),
|
new (ClaimTypes.GivenName, user.Prename!),
|
||||||
new (ClaimTypes.Email, user.Email!),
|
new (ClaimTypes.Email, user.Email!),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create claimsIdentity
|
// Create claimsIdentity
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
@@ -75,13 +112,58 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
|
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth/form
|
||||||
|
/// {
|
||||||
|
/// "username": "MaxMustermann",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||||
|
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost]
|
||||||
|
[Route("form")]
|
||||||
|
public async Task<IActionResult> Login([FromForm] Login login)
|
||||||
|
{
|
||||||
|
return await Login(login, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth/logout
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
|
||||||
|
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpPost("logout")]
|
[HttpPost("logout")]
|
||||||
public async Task<IActionResult> Logout()
|
public async Task<IActionResult> Logout()
|
||||||
@@ -98,8 +180,22 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
/// <summary>
|
||||||
[HttpGet("check")]
|
/// Prüft, ob der Benutzer ein autorisiertes Token hat.
|
||||||
public IActionResult IsAuthenticated() => Ok(User.Identity?.IsAuthenticated ?? false);
|
/// </summary>
|
||||||
|
/// <returns>Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// GET /api/auth
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
|
||||||
|
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult IsAuthenticated() => Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using EnvelopeGenerator.Application.EmailTemplates;
|
||||||
|
using EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
|
||||||
|
using EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
|
||||||
|
using EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller for managing email templates.
|
||||||
|
/// Steuerung zur Verwaltung von E-Mail-Vorlagen.
|
||||||
|
/// </summary>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class EmailTemplateController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mapper">
|
||||||
|
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||||
|
/// </param>
|
||||||
|
public EmailTemplateController(IMapper mapper)
|
||||||
|
{
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft E-Mail-Vorlagen basierend auf der angegebenen Abfrage ab.
|
||||||
|
/// Gibt alles zurück, wenn keine Id- oder Typ-Informationen eingegeben wurden.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="emailTemplate">Die Abfrageparameter zum Abrufen von E-Mail-Vorlagen.</param>
|
||||||
|
/// <returns>Gibt HTTP-Antwort zurück</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
/// GET /api/EmailTemplate?emailTemplateId=123
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Wenn die E-Mail-Vorlagen erfolgreich abgerufen werden.</response>
|
||||||
|
/// <response code="400">Wenn die Abfrageparameter ungültig sind.</response>
|
||||||
|
/// <response code="401">Wenn der Benutzer nicht authentifiziert ist.</response>
|
||||||
|
/// <response code="404">Wenn die gesuchte Abfrage nicht gefunden wird.</response>
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult Get([FromQuery] ReadEmailTemplateQuery? emailTemplate = null)
|
||||||
|
{
|
||||||
|
// Implementation logic here
|
||||||
|
return Ok(); // Placeholder for actual implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an email template or resets it if no update command is provided.
|
||||||
|
/// Aktualisiert eine E-Mail-Vorlage oder setzt sie zurück, wenn kein Aktualisierungsbefehl angegeben ist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="email">Die E-Mail-Vorlagenabfrage.</param>
|
||||||
|
/// <param name="update">Der Aktualisierungsbefehl für die E-Mail-Vorlage.
|
||||||
|
/// Wird auf Standardwert aktualisiert, wenn die Anfrage ohne http-Body gesendet wird.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>Gibt HTTP-Antwort zurück</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
/// PUT /api/EmailTemplate
|
||||||
|
/// {
|
||||||
|
/// "emailTemplateId": 123,
|
||||||
|
/// "newContent": "Updated content"
|
||||||
|
/// }
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Wenn die E-Mail-Vorlage erfolgreich aktualisiert oder zurückgesetzt wird.</response>
|
||||||
|
/// <response code="400">Wenn die Abfrage ohne einen String gesendet wird.</response>
|
||||||
|
/// <response code="401">Wenn der Benutzer nicht authentifiziert ist.</response>
|
||||||
|
/// <response code="404">Wenn die gesuchte Abfrage nicht gefunden wird.</response>
|
||||||
|
[HttpPut]
|
||||||
|
public IActionResult Update([FromQuery] EmailTemplateQuery email, [FromBody] UpdateEmailTemplateCommand? update = null)
|
||||||
|
{
|
||||||
|
if (update is null)
|
||||||
|
{
|
||||||
|
var reset = _mapper.Map<ResetEnvelopeTemplateCommand>(email);
|
||||||
|
// Logic for resetting the email template
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
update.EmailTemplateQuery = email;
|
||||||
|
// Logic for updating the email template
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(); // Placeholder for actual implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,52 +1,78 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dieser Controller stellt Endpunkte für die Verwaltung von Umschlägen bereit.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Die API ermöglicht das Abrufen und Verwalten von Umschlägen basierend auf Benutzerinformationen und Statusfiltern.
|
||||||
|
///
|
||||||
|
/// Mögliche Antworten:
|
||||||
|
/// - 200 OK: Die Anfrage war erfolgreich, und die angeforderten Daten werden zurückgegeben.
|
||||||
|
/// - 400 Bad Request: Die Anfrage war fehlerhaft oder unvollständig.
|
||||||
|
/// - 401 Unauthorized: Der Benutzer ist nicht authentifiziert.
|
||||||
|
/// - 403 Forbidden: Der Benutzer hat keine Berechtigung, auf die Ressource zuzugreifen.
|
||||||
|
/// - 404 Not Found: Die angeforderte Ressource wurde nicht gefunden.
|
||||||
|
/// - 500 Internal Server Error: Ein unerwarteter Fehler ist aufgetreten.
|
||||||
|
/// </remarks>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class EnvelopeController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
private readonly ILogger<EnvelopeController> _logger;
|
||||||
[ApiController]
|
private readonly IEnvelopeService _envelopeService;
|
||||||
[Authorize]
|
|
||||||
public class EnvelopeController : ControllerBase
|
/// <summary>
|
||||||
|
/// Erstellt eine neue Instanz des EnvelopeControllers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param>
|
||||||
|
/// <param name="envelopeService">Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist.</param>
|
||||||
|
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService)
|
||||||
{
|
{
|
||||||
private readonly ILogger<EnvelopeController> _logger;
|
_logger = logger;
|
||||||
private readonly IEnvelopeService _envelopeService;
|
_envelopeService = envelopeService;
|
||||||
|
}
|
||||||
|
|
||||||
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService)
|
/// <summary>
|
||||||
|
/// Ruft eine Liste von Umschlägen basierend auf dem Benutzer und den angegebenen Statusfiltern ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="envelope"></param>
|
||||||
|
/// <returns>Eine IActionResult-Instanz, die die abgerufenen Umschläge oder einen Fehlerstatus enthält.</returns>
|
||||||
|
/// <response code="200">Die Anfrage war erfolgreich, und die Umschläge werden zurückgegeben.</response>
|
||||||
|
/// <response code="400">Die Anfrage war fehlerhaft oder unvollständig.</response>
|
||||||
|
/// <response code="401">Der Benutzer ist nicht authentifiziert.</response>
|
||||||
|
/// <response code="403">Der Benutzer hat keine Berechtigung, auf die Ressource zuzugreifen.</response>
|
||||||
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAsync([FromQuery] ReadEnvelopeQuery envelope)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger = logger;
|
if (User.GetId() is int intId)
|
||||||
_envelopeService = envelopeService;
|
return await _envelopeService.ReadByUserAsync(intId, min_status: envelope.Status, max_status: envelope.Status).ThenAsync(
|
||||||
}
|
Success: Ok,
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
[Authorize]
|
{
|
||||||
[HttpGet]
|
_logger.LogNotice(ntc);
|
||||||
public async Task<IActionResult> GetCurrentAsync(
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
[FromQuery] int? min_status = null,
|
});
|
||||||
[FromQuery] int? max_status = null,
|
else
|
||||||
[FromQuery] params int[] ignore_statuses)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (User.GetId() is int intId)
|
_logger.LogError("Trotz erfolgreicher Autorisierung wurde die Benutzer-ID nicht als Ganzzahl erkannt. Dies könnte auf eine fehlerhafte Erstellung der Anspruchsliste zurückzuführen sein.");
|
||||||
return await _envelopeService.ReadByUserAsync(intId, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses).ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
});
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogError("Despite successful authorization, the 'api/envelope' route encountered an issue: the user ID is not recognized as an integer. This may be due to the removal of the ID during the creation of the claims list.");
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{Message}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,98 +1,165 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
using EnvelopeGenerator.Common.My.Resources;
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||||
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName;
|
||||||
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller für die Verwaltung von Umschlagempfängern.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Dieser Controller bietet Endpunkte für das Abrufen und Verwalten von Umschlagempfängerdaten.
|
||||||
|
/// </remarks>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class EnvelopeReceiverController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
private readonly ILogger<EnvelopeReceiverController> _logger;
|
||||||
[Authorize]
|
|
||||||
[ApiController]
|
private readonly IEnvelopeReceiverService _erService;
|
||||||
public class EnvelopeReceiverController : ControllerBase
|
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor für den EnvelopeReceiverController.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Logger-Instanz zur Protokollierung von Informationen und Fehlern.</param>
|
||||||
|
/// <param name="envelopeReceiverService">Service zur Verwaltung von Umschlagempfängern.</param>
|
||||||
|
/// <param name="mediator">Mediator-Instanz zur Verarbeitung von Befehlen und Abfragen.</param>
|
||||||
|
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator)
|
||||||
{
|
{
|
||||||
private readonly ILogger<EnvelopeReceiverController> _logger;
|
_logger = logger;
|
||||||
private readonly IEnvelopeReceiverService _erService;
|
_erService = envelopeReceiverService;
|
||||||
|
_mediator = mediator;
|
||||||
|
}
|
||||||
|
|
||||||
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService)
|
/// <summary>
|
||||||
|
/// Ruft eine Liste von Umschlagempfängern basierend auf den angegebenen Abfrageparametern ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="envelopeReceiver">Die Abfrageparameter für die Filterung von Umschlagempfängern.</param>
|
||||||
|
/// <returns>Eine HTTP-Antwort mit der Liste der gefundenen Umschlagempfänger oder einem Fehlerstatus.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Dieser Endpunkt ermöglicht es, Umschlagempfänger basierend auf dem Benutzernamen und optionalen Statusfiltern abzurufen.
|
||||||
|
/// Wenn der Benutzername nicht ermittelt werden kann, wird ein Serverfehler zurückgegeben.
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Die Liste der Umschlagempfänger wurde erfolgreich abgerufen.</response>
|
||||||
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
||||||
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger = logger;
|
var username = User.GetUsername();
|
||||||
_erService = envelopeReceiverService;
|
|
||||||
}
|
if (username is null)
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] int? min_status = null, [FromQuery] int? max_status = null, [FromQuery] int[]? ignore_status = null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var username = User.GetUsername();
|
_logger.LogError(@"Envelope Receiver dto cannot be sent because username claim is null. Potential authentication and authorization error. The value of other claims are [id: {id}], [username: {username}], [name: {name}], [prename: {prename}], [email: {email}].",
|
||||||
|
User.GetId(), User.GetUsername(), User.GetName(), User.GetPrename(), User.GetEmail());
|
||||||
if (username is null)
|
|
||||||
{
|
|
||||||
_logger.LogError(@"Envelope Receiver dto cannot be sent because username claim is null. Potential authentication and authorization error. The value of other claims are [id: {id}], [username: {username}], [name: {name}], [prename: {prename}], [email: {email}].",
|
|
||||||
User.GetId(), User.GetUsername(), User.GetName(), User.GetPrename(), User.GetEmail());
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
|
|
||||||
ignore_status ??= Array.Empty<int>();
|
|
||||||
|
|
||||||
return await _erService.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_status).ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, msg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "An unexpected error occurred. {message}", ex.Message);
|
|
||||||
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("receiver-name/{mail}")]
|
|
||||||
public async Task<IActionResult> GetReceiverName([FromRoute] string mail)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await _erService.ReadLastUsedReceiverNameByMail(mail).ThenAsync(
|
|
||||||
Success: res => res is null ? Ok(string.Empty) : Ok(res),
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
if (ntc.HasFlag(Flag.NotFound))
|
|
||||||
return NotFound();
|
|
||||||
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{message}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("secret")]
|
return await _erService.ReadByUsernameAsync(username: username).ThenAsync(
|
||||||
[Authorize]
|
|
||||||
public async Task<IActionResult> GetSecretAsync([FromQuery] string uuid)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await _erService.ReadWithSecretByUuidAsync(uuid: uuid).ThenAsync(
|
|
||||||
Success: Ok,
|
Success: Ok,
|
||||||
Fail: IActionResult (msg, ntc) =>
|
Fail: IActionResult (msg, ntc) =>
|
||||||
{
|
{
|
||||||
_logger.LogNotice(ntc);
|
_logger.LogNotice(ntc);
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
return StatusCode(StatusCodes.Status500InternalServerError, msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "{message}", ex.Message);
|
_logger.LogError(ex, "An unexpected error occurred. {message}", ex.Message);
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft den Namen des zuletzt verwendeten Empfängers basierend auf der angegebenen E-Mail-Adresse ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="receiverName">Die Abfrage, die die E-Mail-Adresse des Empfängers enthält.</param>
|
||||||
|
/// <returns>Eine HTTP-Antwort mit dem Namen des Empfängers oder einem Fehlerstatus.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Dieser Endpunkt ermöglicht es, den Namen des zuletzt verwendeten Empfängers basierend auf der E-Mail-Adresse abzurufen.
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Der Name des Empfängers wurde erfolgreich abgerufen.</response>
|
||||||
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
||||||
|
/// <response code="404">Kein Empfänger gefunden.</response>
|
||||||
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("salute")]
|
||||||
|
public async Task<IActionResult> GetReceiverName([FromQuery] ReadReceiverNameQuery receiverName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await _erService.ReadLastUsedReceiverNameByMail(receiverName.EmailAddress).ThenAsync(
|
||||||
|
Success: res => res is null ? Ok(string.Empty) : Ok(res),
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
if (ntc.HasFlag(Flag.NotFound))
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="createEnvelopeQuery"></param>
|
||||||
|
/// <param name="cancellationToken">Token to cancel the operation</param>
|
||||||
|
/// <returns>HTTP-Antwort</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/envelope
|
||||||
|
/// {
|
||||||
|
/// "title": "Vertragsdokument",
|
||||||
|
/// "message": "Bitte unterschreiben Sie dieses Dokument.",
|
||||||
|
/// "document": {
|
||||||
|
/// "dataAsBase64": "dGVzdC1iYXNlNjQtZGF0YQ=="
|
||||||
|
/// },
|
||||||
|
/// "receivers": [
|
||||||
|
/// {
|
||||||
|
/// "emailAddress": "example@example.com",
|
||||||
|
/// "signatures": [
|
||||||
|
/// {
|
||||||
|
/// "x": 100,
|
||||||
|
/// "y": 200,
|
||||||
|
/// "page": 1
|
||||||
|
/// }
|
||||||
|
/// ],
|
||||||
|
/// "name": "Max Mustermann",
|
||||||
|
/// "phoneNumber": "+49123456789"
|
||||||
|
/// }
|
||||||
|
/// ],
|
||||||
|
/// "tfaEnabled": false
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="202">Envelope-Erstellung und Sendeprozessbefehl erfolgreich</response>
|
||||||
|
/// <response code="400">Wenn ein Fehler im HTTP-Body auftritt</response>
|
||||||
|
/// <response code="401">Wenn kein autorisierter Token vorhanden ist</response>
|
||||||
|
/// <response code="500">Es handelt sich um einen unerwarteten Fehler. Die Protokolle sollten überprüft werden.</response>
|
||||||
|
[Authorize]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> CreateAsync([FromBody] CreateEnvelopeReceiverCommand createEnvelopeQuery, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await _mediator.Send(createEnvelopeQuery, cancellationToken);
|
||||||
|
return Accepted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,40 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Net.Mail;
|
|
||||||
using System.Security.Cryptography.Xml;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class EnvelopeTypeController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
private readonly ILogger<EnvelopeTypeController> _logger;
|
||||||
[ApiController]
|
private readonly IEnvelopeTypeService _service;
|
||||||
public class EnvelopeTypeController : ControllerBase
|
|
||||||
|
public EnvelopeTypeController(ILogger<EnvelopeTypeController> logger, IEnvelopeTypeService service)
|
||||||
{
|
{
|
||||||
private readonly ILogger<EnvelopeTypeController> _logger;
|
_logger = logger;
|
||||||
private readonly IEnvelopeTypeService _service;
|
_service = service;
|
||||||
|
}
|
||||||
|
|
||||||
public EnvelopeTypeController(ILogger<EnvelopeTypeController> logger, IEnvelopeTypeService service)
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAllAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger = logger;
|
return await _service.ReadAllAsync().ThenAsync(
|
||||||
_service = service;
|
Success: Ok,
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
[HttpGet]
|
|
||||||
public async Task<IActionResult> GetAllAsync()
|
|
||||||
{
|
{
|
||||||
try
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
{
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
return await _service.ReadAllAsync().ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{Message}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,73 +1,155 @@
|
|||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
|
||||||
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.Histories.Queries.Read;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System;
|
|
||||||
using static EnvelopeGenerator.Common.Constants;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|
||||||
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dieser Controller stellt Endpunkte für den Zugriff auf die Umschlaghistorie bereit.
|
||||||
|
/// </summary>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class HistoryController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
private readonly ILogger<HistoryController> _logger;
|
||||||
[ApiController]
|
|
||||||
[Authorize]
|
private readonly IEnvelopeHistoryService _service;
|
||||||
public class HistoryController : ControllerBase
|
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor für den HistoryController.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param>
|
||||||
|
/// <param name="service">Der Dienst, der für die Verarbeitung der Umschlaghistorie verantwortlich ist.</param>
|
||||||
|
public HistoryController(ILogger<HistoryController> logger, IEnvelopeHistoryService service)
|
||||||
{
|
{
|
||||||
private readonly ILogger<HistoryController> _logger;
|
_logger = logger;
|
||||||
|
_service = service;
|
||||||
private readonly IEnvelopeHistoryService _service;
|
|
||||||
|
|
||||||
public HistoryController(ILogger<HistoryController> logger, IEnvelopeHistoryService service)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("reference-type")]
|
|
||||||
[Authorize]
|
|
||||||
public IActionResult GetReferenceTypes()
|
|
||||||
{
|
|
||||||
// Enum to Key-Value pair
|
|
||||||
var referenceTypes = Enum.GetValues(typeof(ReferenceType))
|
|
||||||
.Cast<ReferenceType>()
|
|
||||||
.ToDictionary(rt =>
|
|
||||||
{
|
|
||||||
var key = rt.ToString();
|
|
||||||
var keyAsCamelCase = char.ToLower(key[0]) + key[1..];
|
|
||||||
return keyAsCamelCase;
|
|
||||||
}, rt => (int)rt);
|
|
||||||
|
|
||||||
return Ok(referenceTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Authorize]
|
|
||||||
public async Task<IActionResult> GetAllAsync([FromQuery] int? envelopeId = null, [FromQuery] string? userReference = null, [FromQuery] int? referenceType = null, [FromQuery] bool withSender = false, [FromQuery] bool withReceiver = false)
|
|
||||||
{
|
|
||||||
ReferenceType? refTypEnum = null;
|
|
||||||
|
|
||||||
if (referenceType is int refTypInt)
|
|
||||||
if (Enum.IsDefined(typeof(ReferenceType), refTypInt))
|
|
||||||
refTypEnum = (ReferenceType)refTypInt;
|
|
||||||
else
|
|
||||||
throw new ArgumentException($"The provided referenceType '{referenceType}' is not valid. It must correspond to a valid value in the {nameof(ReferenceType)} enum.");
|
|
||||||
|
|
||||||
switch(referenceType)
|
|
||||||
{
|
|
||||||
case (int)ReferenceType.Receiver:
|
|
||||||
withReceiver = true;
|
|
||||||
break;
|
|
||||||
case (int)ReferenceType.Sender:
|
|
||||||
withSender = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var histories = await _service.ReadAsync(
|
|
||||||
envelopeId: envelopeId,
|
|
||||||
userReference: userReference,
|
|
||||||
referenceType: refTypEnum,
|
|
||||||
withSender: withSender,
|
|
||||||
withReceiver: withReceiver);
|
|
||||||
|
|
||||||
return Ok(histories);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt alle möglichen Verweise auf alle möglichen Status in einem Verlaufsdatensatz zurück. (z. B. DocumentSigned bezieht sich auf Receiver.)
|
||||||
|
/// Dies wird hinzugefügt, damit Client-Anwendungen sich selbst auf dem neuesten Stand halten können.
|
||||||
|
/// 0 - Receiver:
|
||||||
|
/// Historische Datensätze, die sich auf den Status des Absenders beziehen. Sie haben Statuscodes, die mit 1* beginnen.
|
||||||
|
/// 1 - Sender:
|
||||||
|
/// Historische Datensätze über den Status der Empfänger. Diese haben Statuscodes, die mit 2* beginnen.
|
||||||
|
/// 2 - System:
|
||||||
|
/// Historische Datensätze, die sich auf den allgemeinen Zustand des Umschlags beziehen. Diese haben Statuscodes, die mit 3* beginnen.
|
||||||
|
/// 3 - Unknown:
|
||||||
|
/// Ein unbekannter Datensatz weist auf einen möglichen Mangel oder eine Unstimmigkeit im Aktualisierungsprozess der Anwendung hin.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <response code="200"></response>
|
||||||
|
[HttpGet("related")]
|
||||||
|
[Authorize]
|
||||||
|
public IActionResult GetReferenceTypes()
|
||||||
|
{
|
||||||
|
// Enum zu Schlüssel-Wert-Paar
|
||||||
|
var referenceTypes = Enum.GetValues(typeof(ReferenceType))
|
||||||
|
.Cast<ReferenceType>()
|
||||||
|
.ToDictionary(rt =>
|
||||||
|
{
|
||||||
|
var key = rt.ToString();
|
||||||
|
var keyAsCamelCase = char.ToLower(key[0]) + key[1..];
|
||||||
|
return keyAsCamelCase;
|
||||||
|
}, rt => (int)rt);
|
||||||
|
|
||||||
|
return Ok(referenceTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt alle möglichen Status in einem Verlaufsdatensatz zurück.
|
||||||
|
/// Dies wird hinzugefügt, damit Client-Anwendungen sich selbst auf dem neuesten Stand halten können.
|
||||||
|
/// 0: Invalid
|
||||||
|
/// 1001: EnvelopeCreated
|
||||||
|
/// 1002: EnvelopeSaved
|
||||||
|
/// 1003: EnvelopeQueued
|
||||||
|
/// 1004: EnvelopeSent (Nicht verwendet)
|
||||||
|
/// 1005: EnvelopePartlySigned
|
||||||
|
/// 1006: EnvelopeCompletelySigned
|
||||||
|
/// 1007: EnvelopeReportCreated
|
||||||
|
/// 1008: EnvelopeArchived
|
||||||
|
/// 1009: EnvelopeDeleted
|
||||||
|
/// 2001: AccessCodeRequested
|
||||||
|
/// 2002: AccessCodeCorrect
|
||||||
|
/// 2003: AccessCodeIncorrect
|
||||||
|
/// 2004: DocumentOpened
|
||||||
|
/// 2005: DocumentSigned
|
||||||
|
/// 4001: DocumentForwarded
|
||||||
|
/// 2006: SignatureConfirmed
|
||||||
|
/// 2007: DocumentRejected
|
||||||
|
/// 2008: EnvelopeShared
|
||||||
|
/// 2009: EnvelopeViewed
|
||||||
|
/// 3001: MessageInvitationSent (Wird von Trigger verwendet)
|
||||||
|
/// 3002: MessageAccessCodeSent
|
||||||
|
/// 3003: MessageConfirmationSent
|
||||||
|
/// 3004: MessageDeletionSent
|
||||||
|
/// 3005: MessageCompletionSent
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="related">
|
||||||
|
/// Abfrageparameter, der angibt, auf welche Referenz sich der Status bezieht.
|
||||||
|
/// 0 - Sender: Historische Datensätze, die sich auf den Status des Absenders beziehen. Sie haben Statuscodes, die mit 1* beginnen.
|
||||||
|
/// 1 - Receiver: Historische Datensätze über den Status der Empfänger. Diese haben Statuscodes, die mit 2* beginnen.
|
||||||
|
/// 2 - System: Diese werden durch Datenbank-Trigger aktualisiert und sind in den Tabellen EnvelopeHistory und EmailOut zu finden.Sie arbeiten
|
||||||
|
/// integriert mit der Anwendung EmailProfiler, um E-Mails zu versenden und haben die Codes, die mit 3* beginnen.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>Gibt die HTTP-Antwort zurück.</returns>
|
||||||
|
/// <response code="200"></response>
|
||||||
|
[HttpGet("status")]
|
||||||
|
[Authorize]
|
||||||
|
public IActionResult GetEnvelopeStatus([FromQuery] ReferenceType? related = null)
|
||||||
|
{
|
||||||
|
// Enum zu Schlüssel-Wert-Paar
|
||||||
|
var referenceTypes = Enum.GetValues(typeof(EnvelopeStatus))
|
||||||
|
.Cast<EnvelopeStatus>()
|
||||||
|
.ToDictionary(rt =>
|
||||||
|
{
|
||||||
|
var key = rt.ToString();
|
||||||
|
var keyAsCamelCase = char.ToLower(key[0]) + key[1..];
|
||||||
|
return keyAsCamelCase;
|
||||||
|
}, rt => (int)rt);
|
||||||
|
|
||||||
|
return Ok(referenceTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft die gesamte Umschlaghistorie basierend auf den angegebenen Abfrageparametern ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="history">Die Abfrageparameter, die die Filterkriterien für die Umschlaghistorie definieren.</param>
|
||||||
|
/// <returns>Eine Liste von Historieneinträgen, die den angegebenen Kriterien entsprechen, oder nur der letzte Eintrag.</returns>
|
||||||
|
/// <response code="200">Die Anfrage war erfolgreich, und die Umschlaghistorie wird zurückgegeben.</response>
|
||||||
|
/// <response code="400">Die Anfrage war ungültig oder unvollständig.</response>
|
||||||
|
/// <response code="401">Der Benutzer ist nicht authentifiziert.</response>
|
||||||
|
/// <response code="403">Der Benutzer hat keine Berechtigung, auf die Ressource zuzugreifen.</response>
|
||||||
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[HttpGet]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<IActionResult> GetAllAsync([FromQuery] ReadHistoryQuery history)
|
||||||
|
{
|
||||||
|
bool withReceiver = false;
|
||||||
|
bool withSender = false;
|
||||||
|
|
||||||
|
switch (history.Related)
|
||||||
|
{
|
||||||
|
case ReferenceType.Receiver:
|
||||||
|
withReceiver = true;
|
||||||
|
break;
|
||||||
|
case ReferenceType.Sender:
|
||||||
|
withSender = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var histories = await _service.ReadAsync(
|
||||||
|
envelopeId: history.EnvelopeId,
|
||||||
|
referenceType: history.Related,
|
||||||
|
withSender: withSender,
|
||||||
|
withReceiver: withReceiver);
|
||||||
|
|
||||||
|
return Ok(histories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,85 +6,115 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller für die Verwaltung der Lokalisierung und Spracheinstellungen.
|
||||||
|
/// </summary>
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class LocalizationController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
private static readonly Guid L_KEY = Guid.NewGuid();
|
||||||
[ApiController]
|
|
||||||
public class LocalizationController : ControllerBase
|
private readonly ILogger<LocalizationController> _logger;
|
||||||
|
private readonly IStringLocalizer<Model> _mLocalizer;
|
||||||
|
private readonly IStringLocalizer<Resource> _localizer;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Konstruktor für den <see cref="LocalizationController"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Logger für die Protokollierung.</param>
|
||||||
|
/// <param name="localizer">Lokalisierungsdienst für Ressourcen.</param>
|
||||||
|
/// <param name="memoryCache">Speicher-Cache für die Zwischenspeicherung von Daten.</param>
|
||||||
|
/// <param name="_modelLocalizer">Lokalisierungsdienst für Modelle.</param>
|
||||||
|
public LocalizationController(
|
||||||
|
ILogger<LocalizationController> logger,
|
||||||
|
IStringLocalizer<Resource> localizer,
|
||||||
|
IMemoryCache memoryCache,
|
||||||
|
IStringLocalizer<Model> _modelLocalizer)
|
||||||
{
|
{
|
||||||
private static readonly Guid L_KEY = Guid.NewGuid();
|
_logger = logger;
|
||||||
|
_localizer = localizer;
|
||||||
|
_cache = memoryCache;
|
||||||
|
_mLocalizer = _modelLocalizer;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly ILogger<LocalizationController> _logger;
|
/// <summary>
|
||||||
private readonly IStringLocalizer<Model> _mLocalizer;
|
/// Ruft alle lokalisierten Daten ab.
|
||||||
private readonly IStringLocalizer<Resource> _localizer;
|
/// </summary>
|
||||||
private readonly IMemoryCache _cache;
|
/// <returns>Eine Liste aller lokalisierten Daten.</returns>
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetAll() => Ok(_cache.GetOrCreate(Language ?? string.Empty + L_KEY, _ => _mLocalizer.ToDictionary()));
|
||||||
|
|
||||||
public LocalizationController(
|
/// <summary>
|
||||||
ILogger<LocalizationController> logger,
|
/// Ruft die aktuelle Sprache ab.
|
||||||
IStringLocalizer<Resource> localizer,
|
/// </summary>
|
||||||
IMemoryCache memoryCache,
|
/// <returns>Die aktuelle Sprache oder ein NotFound-Ergebnis, wenn keine Sprache gesetzt ist.</returns>
|
||||||
IStringLocalizer<Model> _modelLocalizer)
|
[HttpGet("lang")]
|
||||||
|
public IActionResult GetLanguage() => Language is null ? NotFound() : Ok(Language);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setzt die Sprache.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="language">Die zu setzende Sprache.</param>
|
||||||
|
/// <returns>Ein Ok-Ergebnis, wenn die Sprache erfolgreich gesetzt wurde, oder ein BadRequest-Ergebnis, wenn die Eingabe ungültig ist.</returns>
|
||||||
|
[HttpPost("lang")]
|
||||||
|
public IActionResult SetLanguage([FromQuery] string language)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(language))
|
||||||
|
return BadRequest();
|
||||||
|
|
||||||
|
Language = language;
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Löscht die aktuelle Sprache.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Ein Ok-Ergebnis, wenn die Sprache erfolgreich gelöscht wurde.</returns>
|
||||||
|
[HttpDelete("lang")]
|
||||||
|
public IActionResult DeleteLanguage()
|
||||||
|
{
|
||||||
|
Language = null;
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eigenschaft für die Verwaltung der aktuellen Sprache über Cookies.
|
||||||
|
/// </summary>
|
||||||
|
private string? Language
|
||||||
|
{
|
||||||
|
get
|
||||||
{
|
{
|
||||||
_logger = logger;
|
var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
|
||||||
_localizer = localizer;
|
|
||||||
_cache = memoryCache;
|
if (string.IsNullOrEmpty(cookieValue))
|
||||||
_mLocalizer = _modelLocalizer;
|
return null;
|
||||||
|
|
||||||
|
var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures[0];
|
||||||
|
return culture?.Value ?? null;
|
||||||
}
|
}
|
||||||
|
set
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetAll() => Ok(_cache.GetOrCreate(Language ?? string.Empty + L_KEY, _ => _mLocalizer.ToDictionary()));
|
|
||||||
|
|
||||||
[HttpGet("lang")]
|
|
||||||
public IActionResult GetLanguage() => Language is null ? NotFound() : Ok(Language);
|
|
||||||
|
|
||||||
[HttpPost("lang")]
|
|
||||||
public IActionResult SetLanguage([FromQuery] string language)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(language))
|
if (value is null)
|
||||||
return BadRequest();
|
Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);
|
||||||
|
else
|
||||||
Language = language;
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete("lang")]
|
|
||||||
public IActionResult DeleteLanguage()
|
|
||||||
{
|
|
||||||
Language = null;
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? Language
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
|
var cookieOptions = new CookieOptions()
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(cookieValue))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures[0];
|
|
||||||
return culture?.Value ?? null;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value is null)
|
|
||||||
Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
var cookieOptions = new CookieOptions()
|
Expires = DateTimeOffset.UtcNow.AddYears(1),
|
||||||
{
|
Secure = false,
|
||||||
Expires = DateTimeOffset.UtcNow.AddYears(1),
|
SameSite = SameSiteMode.Strict,
|
||||||
Secure = false,
|
HttpOnly = true
|
||||||
SameSite = SameSiteMode.Strict,
|
};
|
||||||
HttpOnly = true
|
|
||||||
};
|
|
||||||
|
|
||||||
Response.Cookies.Append(
|
Response.Cookies.Append(
|
||||||
CookieRequestCultureProvider.DefaultCookieName,
|
CookieRequestCultureProvider.DefaultCookieName,
|
||||||
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)),
|
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)),
|
||||||
cookieOptions);
|
cookieOptions);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,88 +2,97 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller für die Verwaltung von Empfängern.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Dieser Controller bietet Endpunkte für CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Löschen)
|
||||||
|
/// sowie zusätzliche Funktionen wie das Abrufen von Empfängern basierend auf E-Mail-Adresse oder Signatur.
|
||||||
|
/// </remarks>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ReceiverController : CRUDControllerBaseWithErrorHandling<IReceiverService, ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
/// <summary>
|
||||||
[ApiController]
|
/// Initialisiert eine neue Instanz des <see cref="ReceiverController"/>-Controllers.
|
||||||
[Authorize]
|
/// </summary>
|
||||||
public class ReceiverController : CRUDControllerBaseWithErrorHandling<IReceiverService, ReceiverCreateDto, ReceiverReadDto, ReceiverUpdateDto, Receiver, int>
|
/// <param name="logger">Der Logger für die Protokollierung.</param>
|
||||||
|
/// <param name="service">Der Dienst für Empfängeroperationen.</param>
|
||||||
|
public ReceiverController(ILogger<ReceiverController> logger, IReceiverService service) : base(logger, service)
|
||||||
{
|
{
|
||||||
public ReceiverController(ILogger<ReceiverController> logger, IReceiverService service) : base(logger, service)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public async Task<IActionResult> Get([FromQuery] string? emailAddress = null, [FromQuery] string? signature = null)
|
|
||||||
{
|
|
||||||
if (emailAddress is null && signature is null)
|
|
||||||
return await base.GetAll();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await _service.ReadByAsync(emailAddress: emailAddress, signature: signature).ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{Message}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
public async override Task<IActionResult> Create(ReceiverCreateDto createDto)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return BadRequest(ModelState);
|
|
||||||
|
|
||||||
return await base.Create(createDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete]
|
|
||||||
public async Task<IActionResult> Delete([FromQuery] int? id = null, [FromQuery]string? emailAddress = null, [FromQuery] string? signature = null)
|
|
||||||
{
|
|
||||||
if(id is int id_int)
|
|
||||||
return await base.Delete(id_int);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (emailAddress is not null || signature is not null)
|
|
||||||
return await _service.DeleteByAsync(emailAddress: emailAddress, signature: signature).ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (msg, ntc) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(ntc);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch(Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{Message}", ex.Message);
|
|
||||||
return StatusCode(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BadRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region REMOVED ENDPOINTS
|
|
||||||
[NonAction]
|
|
||||||
public override Task<IActionResult> GetAll() => base.GetAll();
|
|
||||||
|
|
||||||
[NonAction]
|
|
||||||
public override Task<IActionResult> Delete([FromRoute] int id) => base.Delete(id);
|
|
||||||
|
|
||||||
[NonAction]
|
|
||||||
public override Task<IActionResult> Update(ReceiverUpdateDto updateDto) => base.Update(updateDto);
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft eine Liste von Empfängern ab, basierend auf den angegebenen Abfrageparametern.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="receiver">Die Abfrageparameter, einschließlich E-Mail-Adresse und Signatur.</param>
|
||||||
|
/// <returns>Eine Liste von Empfängern oder ein Fehlerstatus.</returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> Get([FromQuery] ReadReceiverQuery receiver)
|
||||||
|
{
|
||||||
|
if (receiver.EmailAddress is null && receiver.Signature is null)
|
||||||
|
return await base.GetAll();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await _service.ReadByAsync(emailAddress: receiver.EmailAddress, signature: receiver.Signature).ThenAsync(
|
||||||
|
Success: Ok,
|
||||||
|
Fail: IActionResult (msg, ntc) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region REMOVED ENDPOINTS
|
||||||
|
/// <summary>
|
||||||
|
/// Diese Methode ist deaktiviert und wird nicht verwendet.
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> GetAll() => base.GetAll();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Diese Methode ist deaktiviert und wird nicht verwendet.
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> Delete([FromRoute] int id) => base.Delete(id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Diese Methode ist deaktiviert und wird nicht verwendet.
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> Update(ReceiverUpdateDto updateDto) => base.Update(updateDto);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Diese Methode ist deaktiviert und wird nicht verwendet.
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> Create(ReceiverCreateDto createDto)
|
||||||
|
{
|
||||||
|
return base.Create(createDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Diese Methode ist deaktiviert und wird nicht verwendet.
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
public override Task<IActionResult> GetById([FromRoute] int id)
|
||||||
|
{
|
||||||
|
return base.GetById(id);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,53 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
<TargetFrameworks>net9.0</TargetFrameworks>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<PackageId>EnvelopeGenerator.GeneratorAPI</PackageId>
|
||||||
|
<Title></Title>
|
||||||
|
<Authors>Digital Data GmbH</Authors>
|
||||||
|
<Company>Digital Data GmbH</Company>
|
||||||
|
<Product>EnvelopeGenerator.GeneratorAPI</Product>
|
||||||
|
<Version>1.2.0</Version>
|
||||||
|
<FileVersion>1.2.0</FileVersion>
|
||||||
|
<AssemblyVersion>1.2.0</AssemblyVersion>
|
||||||
|
<PackageOutputPath>Copyright © 2025 Digital Data GmbH. All rights reserved.</PackageOutputPath>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
<PackageReference Include="AspNetCore.Scalar" Version="1.1.8" />
|
||||||
<PackageReference Include="DigitalData.Core.API" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.15" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.3" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
|
||||||
|
<PackageReference Include="Scalar.AspNetCore" Version="2.1.4" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||||
|
<PackageReference Include="DigitalData.Core.DTO" Version="2.0.1" />
|
||||||
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||||
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
||||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
|
<PackageReference Include="System.DirectoryServices" Version="8.0.0" />
|
||||||
|
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.1" />
|
||||||
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="8.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||||
|
<PackageReference Include="System.DirectoryServices" Version="9.0.4" />
|
||||||
|
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.4" />
|
||||||
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="9.0.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="ClientApp\" />
|
<Folder Include="ClientApp\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
13
EnvelopeGenerator.GeneratorAPI/Models/Login.cs
Normal file
13
EnvelopeGenerator.GeneratorAPI/Models/Login.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Password">Das erforderliche Passwort für das Login.</param>
|
||||||
|
/// <param name="Id">Die optionale ID des Benutzers.</param>
|
||||||
|
/// <param name="Username">Der optionale Benutzername.</param>
|
||||||
|
public record Login([Required] string Password, int? Id = null, string? Username = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
using DigitalData.Core.API;
|
using DigitalData.Core.API;
|
||||||
using DigitalData.Core.Application;
|
using DigitalData.Core.Application;
|
||||||
using DigitalData.UserManager.Application;
|
using DigitalData.UserManager.Application;
|
||||||
using EnvelopeGenerator.Application.Extensions;
|
|
||||||
using EnvelopeGenerator.Infrastructure;
|
using EnvelopeGenerator.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using Scalar.AspNetCore;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using DigitalData.UserManager.DependencyInjection;
|
||||||
|
using EnvelopeGenerator.Application;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -31,8 +34,53 @@ builder.Services.AddCors(options =>
|
|||||||
|
|
||||||
// Swagger
|
// Swagger
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen(options =>
|
||||||
|
{
|
||||||
|
options.SwaggerDoc("v1", new OpenApiInfo
|
||||||
|
{
|
||||||
|
Version = "v1",
|
||||||
|
Title = "signFLOW Absender-API",
|
||||||
|
Description = "Eine API zur Verwaltung der Erstellung, des Versands und der Nachverfolgung von Umschlägen in der signFLOW-Anwendung.",
|
||||||
|
Contact = new OpenApiContact
|
||||||
|
{
|
||||||
|
Name = "Digital Data GmbH",
|
||||||
|
Url = new Uri("https://digitaldata.works/digitale-signatur#kontakt"),
|
||||||
|
Email = "info-flow@digitaldata.works"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Name = "Authorization",
|
||||||
|
Type = SecuritySchemeType.Http,
|
||||||
|
Scheme = "bearer",
|
||||||
|
BearerFormat = "JWT",
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Description = "JWT-Autorisierungs-Header unter Verwendung des Bearer-Schemas.",
|
||||||
|
});
|
||||||
|
|
||||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new string[] {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
|
||||||
|
foreach (var xmlFile in xmlFiles)
|
||||||
|
{
|
||||||
|
options.IncludeXmlComments(xmlFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.Services.AddOpenApi();
|
||||||
// DbContext
|
// DbContext
|
||||||
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
|
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
|
||||||
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
||||||
@@ -54,21 +102,26 @@ builder.Services.AddUserManager<EGDbContext>();
|
|||||||
|
|
||||||
// LDAP
|
// LDAP
|
||||||
builder.ConfigureBySection<DirectorySearchOptions>();
|
builder.ConfigureBySection<DirectorySearchOptions>();
|
||||||
builder.Services.AddDirectorySearchService();
|
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
||||||
|
|
||||||
// Localizer
|
// Localizer
|
||||||
builder.Services.AddCookieBasedLocalizer() ;
|
builder.Services.AddCookieBasedLocalizer() ;
|
||||||
|
|
||||||
// Envelope generator serives
|
// Envelope generator serives
|
||||||
builder.Services.AddEnvelopeGenerator(config);
|
builder.Services
|
||||||
|
.AddEnvelopeGeneratorRepositories()
|
||||||
|
.AddEnvelopeGeneratorServices(config);
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.MapOpenApi();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue<bool>("UseSwagger")))
|
||||||
{
|
{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
|
app.MapScalarApiReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set CORS policy
|
// Set CORS policy
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
|
-->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<WebPublishMethod>Package</WebPublishMethod>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<SiteUrlToLaunchAfterPublish />
|
||||||
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
|
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||||
|
<ProjectGuid>4fdae4ba-f512-444a-9e18-111047d3ef02</ProjectGuid>
|
||||||
|
<DesktopBuildPackageLocation>P:\Install .Net\0 DD - Smart UP\signFLOW\Gen\Api\net7\win64\$(Version)\$(Version).zip</DesktopBuildPackageLocation>
|
||||||
|
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||||
|
<DeployIisAppPath>SignFlowGen</DeployIisAppPath>
|
||||||
|
<_TargetId>IISWebDeployPackage</_TargetId>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<SelfContained>true</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
|
-->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<WebPublishMethod>Package</WebPublishMethod>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<SiteUrlToLaunchAfterPublish />
|
||||||
|
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||||
|
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||||
|
<ProjectGuid>4fdae4ba-f512-444a-9e18-111047d3ef02</ProjectGuid>
|
||||||
|
<DesktopBuildPackageLocation>P:\Install .Net\0 DD - Smart UP\signFLOW\Gen\Api\net9\win64\$(Version)\$(Version).zip</DesktopBuildPackageLocation>
|
||||||
|
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||||
|
<DeployIisAppPath>SignFlowGen</DeployIisAppPath>
|
||||||
|
<_TargetId>IISWebDeployPackage</_TargetId>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<SelfContained>true</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"UseSwagger": true,
|
||||||
|
"DiPMode": true,
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ using EnvelopeGenerator.Infrastructure.Repositories;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using DigitalData.Core.Infrastructure;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using DigitalData.Core.Infrastructure.AutoMapper;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Infrastructure;
|
namespace EnvelopeGenerator.Infrastructure;
|
||||||
|
|
||||||
@@ -30,13 +33,11 @@ public static class DIExtensions
|
|||||||
services.TryAddScoped<IConfigRepository, ConfigRepository>();
|
services.TryAddScoped<IConfigRepository, ConfigRepository>();
|
||||||
services.TryAddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
|
services.TryAddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
|
||||||
services.TryAddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
|
services.TryAddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
|
||||||
services.TryAddScoped<IConfigRepository, ConfigRepository>();
|
|
||||||
services.TryAddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
|
services.TryAddScoped<IDocumentReceiverElementRepository, DocumentReceiverElementRepository>();
|
||||||
services.TryAddScoped<IDocumentStatusRepository, DocumentStatusRepository>();
|
services.TryAddScoped<IDocumentStatusRepository, DocumentStatusRepository>();
|
||||||
services.TryAddScoped<IEmailTemplateRepository, EmailTemplateRepository>();
|
services.TryAddScoped<IEmailTemplateRepository, EmailTemplateRepository>();
|
||||||
services.TryAddScoped<IEnvelopeRepository, EnvelopeRepository>();
|
services.TryAddScoped<IEnvelopeRepository, EnvelopeRepository>();
|
||||||
services.TryAddScoped<IEnvelopeCertificateRepository, EnvelopeCertificateRepository>();
|
services.TryAddScoped<IEnvelopeCertificateRepository, EnvelopeCertificateRepository>();
|
||||||
services.TryAddScoped<IEnvelopeDocumentRepository, EnvelopeDocumentRepository>();
|
|
||||||
services.TryAddScoped<IEnvelopeHistoryRepository, EnvelopeHistoryRepository>();
|
services.TryAddScoped<IEnvelopeHistoryRepository, EnvelopeHistoryRepository>();
|
||||||
services.TryAddScoped<IEnvelopeReceiverRepository, EnvelopeReceiverRepository>();
|
services.TryAddScoped<IEnvelopeReceiverRepository, EnvelopeReceiverRepository>();
|
||||||
services.TryAddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
|
services.TryAddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
|
||||||
@@ -44,6 +45,20 @@ public static class DIExtensions
|
|||||||
services.TryAddScoped<IUserReceiverRepository, UserReceiverRepository>();
|
services.TryAddScoped<IUserReceiverRepository, UserReceiverRepository>();
|
||||||
services.TryAddScoped<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyRepository>();
|
services.TryAddScoped<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyRepository>();
|
||||||
|
|
||||||
|
services.AddDbRepository<EGDbContext, Config>(context => context.Configs).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, DocumentReceiverElement>(context => context.DocumentReceiverElements).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeDocument>(context => context.EnvelopeDocument).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, DocumentStatus>(context => context.DocumentStatus).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EmailTemplate>(context => context.EmailTemplate).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, Envelope>(context => context.Envelopes).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeCertificate>(context => context.EnvelopeCertificates).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeHistory>(context => context.EnvelopeHistories).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeReceiver>(context => context.EnvelopeReceivers).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeType>(context => context.EnvelopeTypes).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, Receiver>(context => context.Receivers).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, UserReceiver>(context => context.UserReceivers).UseAutoMapper();
|
||||||
|
services.AddDbRepository<EGDbContext, EnvelopeReceiverReadOnly>(context => context.EnvelopeReceiverReadOnlys).UseAutoMapper();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public class EGDbContext : DbContext, IUserManagerDbContext, IMailDbContext
|
|||||||
|
|
||||||
public DbSet<EnvelopeReceiverReadOnly> EnvelopeReceiverReadOnlys { get; set; }
|
public DbSet<EnvelopeReceiverReadOnly> EnvelopeReceiverReadOnlys { get; set; }
|
||||||
|
|
||||||
|
public DbSet<ClientUser> ClientUsers { get; set; }
|
||||||
|
|
||||||
private readonly DbTriggerParams _triggers;
|
private readonly DbTriggerParams _triggers;
|
||||||
|
|
||||||
private readonly ILogger<EGDbContext> _logger;
|
private readonly ILogger<EGDbContext> _logger;
|
||||||
|
|||||||
@@ -1,27 +1,37 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.4" />
|
||||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.Infrastructure.AutoMapper" Version="1.0.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.16" />
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.15">
|
<PackageReference Include="UserManager" Version="1.0.0" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.15" />
|
|
||||||
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.20" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.15" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using DigitalData.Core.Infrastructure;
|
using DigitalData.Core.Infrastructure;
|
||||||
using DigitalData.UserManager.Infrastructure.Repositories;
|
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using EnvelopeGenerator.Application.Contracts.Repositories;
|
using EnvelopeGenerator.Application.Contracts.Repositories;
|
||||||
|
|
||||||
|
|||||||
42
EnvelopeGenerator.Terminal/CommandManager.cs
Normal file
42
EnvelopeGenerator.Terminal/CommandManager.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using CommandDotNet;
|
||||||
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.Documents.Queries.Read;
|
||||||
|
using MediatR;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Terminal;
|
||||||
|
|
||||||
|
public class CommandManager
|
||||||
|
{
|
||||||
|
private static JsonSerializerOptions Options = new ()
|
||||||
|
{
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
private readonly IEnvelopeReceiverService _envelopeReceiverService;
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public CommandManager(IEnvelopeReceiverService envelopeReceiverService, IMediator mediator)
|
||||||
|
{
|
||||||
|
_envelopeReceiverService = envelopeReceiverService;
|
||||||
|
_mediator = mediator;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DefaultCommand]
|
||||||
|
public void Execute([Option(Description = "print envelope generator termianal version.")] bool version)
|
||||||
|
{
|
||||||
|
if(version)
|
||||||
|
Console.WriteLine($"v{Assembly.GetExecutingAssembly().GetName().Version}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Subcommand]
|
||||||
|
public IEnvelopeReceiverService EnvelopeReceiver => _envelopeReceiverService;
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
public async Task ReadDocument(IConsole console, int? id = null, int? envelopeId = null)
|
||||||
|
{
|
||||||
|
ReadDocumentQuery query = new(id, envelopeId);
|
||||||
|
var document = await _mediator.Send(query);
|
||||||
|
console.WriteLine(JsonSerializer.Serialize(document, Options));
|
||||||
|
}
|
||||||
|
}
|
||||||
55
EnvelopeGenerator.Terminal/DependencyInjection.cs
Normal file
55
EnvelopeGenerator.Terminal/DependencyInjection.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using CommandDotNet.NameCasing;
|
||||||
|
using CommandDotNet;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using CommandDotNet.IoC.MicrosoftDependencyInjection;
|
||||||
|
using EnvelopeGenerator.Infrastructure;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.Services;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using EnvelopeGenerator.Application;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Terminal;
|
||||||
|
|
||||||
|
public static class DependencyInjection
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddCommandManagerRunner(this IServiceCollection services, IConfiguration configuration, Case @case = Case.KebabCase, string connectionStringKeyName = "Default")
|
||||||
|
{
|
||||||
|
var connStr = configuration.GetConnectionString(connectionStringKeyName)
|
||||||
|
?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
|
||||||
|
|
||||||
|
services.AddDistributedSqlServerCache(options =>
|
||||||
|
{
|
||||||
|
options.ConnectionString = connStr;
|
||||||
|
options.SchemaName = "dbo";
|
||||||
|
options.TableName = "TBDD_CACHE";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add envelope generator services
|
||||||
|
services.AddEnvelopeGeneratorRepositories(options => options.UseSqlServer(connStr));
|
||||||
|
|
||||||
|
return services
|
||||||
|
.AddSingleton<CommandManager>()
|
||||||
|
.AddEnvelopeGeneratorRepositories()
|
||||||
|
.AddEnvelopeGeneratorServices(configuration)
|
||||||
|
.AddSingleton(sp =>
|
||||||
|
{
|
||||||
|
var runner = new AppRunner<CommandManager>();
|
||||||
|
runner.UseMicrosoftDependencyInjection(sp);
|
||||||
|
runner.UseNameCasing(@case);
|
||||||
|
return runner;
|
||||||
|
})
|
||||||
|
.AddScoped<IEnvelopeMailService, EnvelopeMailService>()
|
||||||
|
.AddMemoryCache()
|
||||||
|
.AddLocalization();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task<int> RunCommandManagerRunner(this IServiceProvider provider, string[] args)
|
||||||
|
{
|
||||||
|
var runner = provider.GetRequiredService<AppRunner<CommandManager>>();
|
||||||
|
return runner.RunAsync(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task<int> RunCommandManagerRunner(this IHost host, string[] args) => host.Services.RunCommandManagerRunner(args);
|
||||||
|
}
|
||||||
38
EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj
Normal file
38
EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommandDotNet" Version="7.0.5" />
|
||||||
|
<PackageReference Include="CommandDotNet.IoC.MicrosoftDependencyInjection" Version="5.0.1" />
|
||||||
|
<PackageReference Include="CommandDotNet.NameCasing" Version="4.0.2" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="7.0.20" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.3" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
19
EnvelopeGenerator.Terminal/Program.cs
Normal file
19
EnvelopeGenerator.Terminal/Program.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Terminal;
|
||||||
|
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
static async Task<int> Main(string[] args)
|
||||||
|
{
|
||||||
|
var builder = Host.CreateApplicationBuilder(args);
|
||||||
|
|
||||||
|
var config = builder.Configuration;
|
||||||
|
|
||||||
|
builder.Services.AddCommandManagerRunner(config);
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
return await app.RunCommandManagerRunner(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
208
EnvelopeGenerator.Terminal/appsettings.json
Normal file
208
EnvelopeGenerator.Terminal/appsettings.json
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
{
|
||||||
|
"DiPMode": false, //Please be careful when enabling Development in Production (DiP) mode. It allows Swagger and test controllers to be enabled in a production environment.
|
||||||
|
"EnableSwagger": true,
|
||||||
|
"EnableTestControllers": true,
|
||||||
|
"DetailedErrors": true,
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Warning",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information",
|
||||||
|
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"
|
||||||
|
},
|
||||||
|
"PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==",
|
||||||
|
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
|
||||||
|
"default-src 'self'",
|
||||||
|
"script-src 'self' 'nonce-{0}' 'unsafe-eval'",
|
||||||
|
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com:*",
|
||||||
|
"img-src 'self' data: https: blob:",
|
||||||
|
"font-src 'self' https://fonts.gstatic.com:*",
|
||||||
|
"connect-src 'self' https://nominatim.openstreetmap.org:* http://localhost:* https://localhost:* ws://localhost:* wss://localhost:* blob:",
|
||||||
|
"frame-src 'self'",
|
||||||
|
"media-src 'self'",
|
||||||
|
"object-src 'self'"
|
||||||
|
],
|
||||||
|
"AllowedOrigins": [ "https://localhost:7202", "https://digitale.unterschrift.wisag.de/" ],
|
||||||
|
"NLog": {
|
||||||
|
"throwConfigExceptions": true,
|
||||||
|
"variables": {
|
||||||
|
"logDirectory": "E:\\LogFiles\\Digital Data\\signFlow",
|
||||||
|
"logFileNamePrefix": "${shortdate}-ECM.EnvelopeGenerator.Web"
|
||||||
|
},
|
||||||
|
"targets": {
|
||||||
|
"infoLogs": {
|
||||||
|
"type": "File",
|
||||||
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||||
|
"maxArchiveDays": 30
|
||||||
|
},
|
||||||
|
"errorLogs": {
|
||||||
|
"type": "File",
|
||||||
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||||
|
"maxArchiveDays": 30
|
||||||
|
},
|
||||||
|
"criticalLogs": {
|
||||||
|
"type": "File",
|
||||||
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||||
|
"maxArchiveDays": 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Trace, Debug, Info, Warn, Error and *Fatal*
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"logger": "*",
|
||||||
|
"minLevel": "Info",
|
||||||
|
"maxLevel": "Warn",
|
||||||
|
"writeTo": "infoLogs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"logger": "*",
|
||||||
|
"level": "Error",
|
||||||
|
"writeTo": "errorLogs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"logger": "*",
|
||||||
|
"level": "Fatal",
|
||||||
|
"writeTo": "criticalLogs"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ContactLink": {
|
||||||
|
"Label": "Kontakt",
|
||||||
|
"Href": "https://digitaldata.works/",
|
||||||
|
"HrefLang": "de",
|
||||||
|
"Target": "_blank",
|
||||||
|
"Title": "Digital Data GmbH"
|
||||||
|
},
|
||||||
|
/* Resx naming format is -> Resource.language.resx (eg: Resource.de_DE.resx).
|
||||||
|
To add a new language, first you should write the required resx file.
|
||||||
|
first is the default culture name. */
|
||||||
|
"Cultures": [
|
||||||
|
{
|
||||||
|
"Language": "de-DE",
|
||||||
|
"FIClass": "fi-de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Language": "en-US",
|
||||||
|
"FIClass": "fi-us"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DisableMultiLanguage": false,
|
||||||
|
"Regexes": [
|
||||||
|
{
|
||||||
|
"Pattern": "/^\\p{L}+(?:([\\ \\-\\']|(\\.\\ ))\\p{L}+)*$/u",
|
||||||
|
"Name": "City",
|
||||||
|
"Platforms": [ ".NET" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Pattern": "/^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$/",
|
||||||
|
"Name": "City",
|
||||||
|
"Platforms": [ "javascript" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CustomImages": {
|
||||||
|
"App": {
|
||||||
|
"Src": "/img/DD_signFLOW_LOGO.png",
|
||||||
|
"Classes": {
|
||||||
|
"Main": "signFlow-logo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Company": {
|
||||||
|
"Src": "/img/digital_data.svg",
|
||||||
|
"Classes": {
|
||||||
|
"Show": "dd-show-logo",
|
||||||
|
"Locked": "dd-locked-logo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DispatcherParams": {
|
||||||
|
"SendingProfile": 1,
|
||||||
|
"AddedWho": "DDEnvelopGenerator",
|
||||||
|
"ReminderTypeId": 202377,
|
||||||
|
"EmailAttmt1": ""
|
||||||
|
},
|
||||||
|
"MailParams": {
|
||||||
|
"Placeholders": {
|
||||||
|
"[NAME_PORTAL]": "signFlow",
|
||||||
|
"[SIGNATURE_TYPE]": "signieren",
|
||||||
|
"[REASON]": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"GtxMessagingParams": {
|
||||||
|
"Uri": "https://rest.gtx-messaging.net",
|
||||||
|
"Path": "smsc/sendsms/f566f7e5-bdf2-4a9a-bf52-ed88215a432e/json",
|
||||||
|
"Headers": {},
|
||||||
|
"QueryParams": {
|
||||||
|
"from": "signFlow"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TFARegParams": {
|
||||||
|
"TimeLimit": "00:30:00"
|
||||||
|
},
|
||||||
|
"DbTriggerParams": {
|
||||||
|
"Envelope": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ],
|
||||||
|
"EnvelopeHistory": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ],
|
||||||
|
"EmailOut": [ "TBEMLP_EMAIL_OUT_AFT_INS", "TBEMLP_EMAIL_OUT_AFT_UPD" ],
|
||||||
|
"EnvelopeReceiverReadOnly": [ "TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD" ],
|
||||||
|
"Receiver": []
|
||||||
|
},
|
||||||
|
"MainPageTitle": null,
|
||||||
|
"AnnotationParams": {
|
||||||
|
"DefaultAnnotation": {
|
||||||
|
"Width": 1,
|
||||||
|
"Height": 0.5,
|
||||||
|
"MarginTop": 1
|
||||||
|
},
|
||||||
|
"Annotations": [
|
||||||
|
{
|
||||||
|
"Name": "Signature",
|
||||||
|
"MarginTop": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "PositionLabel",
|
||||||
|
"VerBoundAnnotName": "Signature",
|
||||||
|
"WidthRatio": 1.2,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": 0.22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Position",
|
||||||
|
"VerBoundAnnotName": "PositionLabel",
|
||||||
|
"WidthRatio": 1.2,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": -0.05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "CityLabel",
|
||||||
|
"VerBoundAnnotName": "Position",
|
||||||
|
"WidthRatio": 1.2,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": 0.05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "City",
|
||||||
|
"VerBoundAnnotName": "CityLabel",
|
||||||
|
"WidthRatio": 1.2,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": -0.05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "DateLabel",
|
||||||
|
"VerBoundAnnotName": "City",
|
||||||
|
"WidthRatio": 1.55,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": 0.05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Date",
|
||||||
|
"VerBoundAnnotName": "DateLabel",
|
||||||
|
"WidthRatio": 1.55,
|
||||||
|
"HeightRatio": 0.5,
|
||||||
|
"MarginTopRatio": -0.1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,15 +23,18 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
|
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
|
||||||
|
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.20" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.14.0" />
|
<PackageReference Include="NUnit" Version="3.14.0" />
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
|
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using EnvelopeGenerator.Application.Extensions;
|
|
||||||
using EnvelopeGenerator.Infrastructure;
|
using EnvelopeGenerator.Infrastructure;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using EnvelopeGenerator.Application.Services;
|
using EnvelopeGenerator.Application.Services;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using EnvelopeGenerator.Application;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Tests.Application;
|
namespace EnvelopeGenerator.Tests.Application;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using EnvelopeGenerator.Web.Models;
|
using EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ namespace EnvelopeGenerator.Web.Controllers;
|
|||||||
|
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
public class ConfigController : ControllerBase
|
public class ConfigController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly AnnotationParams _annotParams;
|
private readonly AnnotationParams _annotParams;
|
||||||
@@ -18,6 +20,6 @@ public class ConfigController : ControllerBase
|
|||||||
[HttpGet("Annotations")]
|
[HttpGet("Annotations")]
|
||||||
public IActionResult GetAnnotationParams()
|
public IActionResult GetAnnotationParams()
|
||||||
{
|
{
|
||||||
return Ok(_annotParams.AnnotationDictionary);
|
return Ok(_annotParams.AnnotationJSObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace EnvelopeGenerator.Web.Controllers.Test
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/test/[controller]")]
|
[Route("api/test/[controller]")]
|
||||||
public class TestControllerBase<TCRUDService, TDto, TEntity, TId> : BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId>
|
public class TestControllerBase<TCRUDService, TDto, TEntity, TId> : BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId>
|
||||||
where TCRUDService : ICRUDService<TDto, TDto, TDto, TEntity, TId>
|
where TCRUDService : ICRUDService<TDto, TDto, TEntity, TId>
|
||||||
where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
||||||
{
|
{
|
||||||
public TestControllerBase(ILogger logger, TCRUDService service) : base(logger, service)
|
public TestControllerBase(ILogger logger, TCRUDService service) : base(logger, service)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<PackageId>EnvelopeGenerator.Web</PackageId>
|
<PackageId>EnvelopeGenerator.Web</PackageId>
|
||||||
@@ -2101,15 +2101,16 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" />
|
<PackageReference Include="BuildBundlerMinifier2022" Version="2.9.9" />
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="2.2.1" />
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.3" />
|
||||||
<PackageReference Include="DigitalData.Core.API" Version="2.0.1" />
|
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
|
||||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="2.0.0" />
|
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||||
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||||
<PackageReference Include="DigitalData.Modules.Base" Version="1.3.8" />
|
<PackageReference Include="DigitalData.Modules.Base" Version="1.3.8" />
|
||||||
<PackageReference Include="DigitalData.Modules.Config" Version="1.3.0" />
|
<PackageReference Include="DigitalData.Modules.Config" Version="1.3.0" />
|
||||||
<PackageReference Include="DigitalData.Modules.Database" Version="2.3.5.4" />
|
<PackageReference Include="DigitalData.Modules.Database" Version="2.3.5.4" />
|
||||||
<PackageReference Include="HtmlSanitizer" Version="8.0.865" />
|
<PackageReference Include="HtmlSanitizer" Version="8.0.865" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.16" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.15">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.15">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
@@ -2131,7 +2132,6 @@
|
|||||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
||||||
<PackageReference Include="UserManager.Infrastructure" Version="2.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Models;
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
public record Annotation
|
public record Annotation : IAnnotation
|
||||||
{
|
{
|
||||||
public required string Name { get; init; }
|
public required string Name { get; init; }
|
||||||
|
|
||||||
@@ -60,6 +60,16 @@ public record Annotation
|
|||||||
public Annotation? VerBoundAnnot { get; set; }
|
public Annotation? VerBoundAnnot { get; set; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public Color? BackgroundColor { get; init; }
|
||||||
|
|
||||||
|
#region Border
|
||||||
|
public Color? BorderColor { get; init; }
|
||||||
|
|
||||||
|
public string? BorderStyle { get; init; }
|
||||||
|
|
||||||
|
public int? BorderWidth { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal Annotation Default
|
internal Annotation Default
|
||||||
{
|
{
|
||||||
@@ -1,15 +1,21 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Models;
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
public class AnnotationParams
|
public class AnnotationParams
|
||||||
{
|
{
|
||||||
|
public AnnotationParams()
|
||||||
|
{
|
||||||
|
_AnnotationJSObjectInitor = new(CreateAnnotationJSObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Background? Background { get; init; }
|
||||||
|
|
||||||
|
#region Annotation
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Annotation? DefaultAnnotation { get; init; }
|
public Annotation? DefaultAnnotation { get; init; }
|
||||||
|
|
||||||
private readonly IEnumerable<Annotation> _annots = new List<Annotation>();
|
private readonly List<Annotation> _annots = new List<Annotation>();
|
||||||
|
|
||||||
public Annotation this[string name] => _annots.First(a => a.Name == name);
|
|
||||||
|
|
||||||
public bool TryGet(string name, out Annotation annotation)
|
public bool TryGet(string name, out Annotation annotation)
|
||||||
{
|
{
|
||||||
@@ -24,34 +30,50 @@ public class AnnotationParams
|
|||||||
get => _annots;
|
get => _annots;
|
||||||
init
|
init
|
||||||
{
|
{
|
||||||
_annots = value;
|
_annots = value.ToList();
|
||||||
|
|
||||||
if (DefaultAnnotation is not null)
|
if (DefaultAnnotation is not null)
|
||||||
foreach (var annot in _annots)
|
foreach (var annot in _annots)
|
||||||
annot.Default = DefaultAnnotation;
|
annot.Default = DefaultAnnotation;
|
||||||
|
|
||||||
foreach (var annot in _annots)
|
for (int i = 0; i < _annots.Count; i++)
|
||||||
{
|
{
|
||||||
#region set bound annotations
|
#region set bound annotations
|
||||||
// horizontal
|
// horizontal
|
||||||
if (annot.HorBoundAnnotName is string horBoundAnnotName)
|
if (_annots[i].HorBoundAnnotName is string horBoundAnnotName)
|
||||||
if (TryGet(horBoundAnnotName, out var horBoundAnnot))
|
if (TryGet(horBoundAnnotName, out var horBoundAnnot))
|
||||||
annot.HorBoundAnnot = horBoundAnnot;
|
_annots[i].HorBoundAnnot = horBoundAnnot;
|
||||||
else
|
else
|
||||||
throw new InvalidOperationException($"{horBoundAnnotName} added as bound anotation. However, it is not defined.");
|
throw new InvalidOperationException($"{horBoundAnnotName} added as bound anotation. However, it is not defined.");
|
||||||
|
|
||||||
// vertical
|
// vertical
|
||||||
if (annot.VerBoundAnnotName is string verBoundAnnotName)
|
if (_annots[i].VerBoundAnnotName is string verBoundAnnotName)
|
||||||
if (TryGet(verBoundAnnotName, out var verBoundAnnot))
|
if (TryGet(verBoundAnnotName, out var verBoundAnnot))
|
||||||
annot.VerBoundAnnot = verBoundAnnot;
|
_annots[i].VerBoundAnnot = verBoundAnnot;
|
||||||
else
|
else
|
||||||
throw new InvalidOperationException($"{verBoundAnnotName} added as bound anotation. However, it is not defined.");
|
throw new InvalidOperationException($"{verBoundAnnotName} added as bound anotation. However, it is not defined.");
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationDictionary = _annots.ToDictionary(a => a.Name.ToLower(), a => a);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public Dictionary<string, Annotation> AnnotationDictionary { get; private init; } = new();
|
#region AnnotationJSObject
|
||||||
|
private Dictionary<string, IAnnotation> CreateAnnotationJSObject()
|
||||||
|
{
|
||||||
|
var dict = _annots.ToDictionary(a => a.Name.ToLower(), a => a as IAnnotation);
|
||||||
|
|
||||||
|
if (Background is not null)
|
||||||
|
{
|
||||||
|
Background.Locate(_annots);
|
||||||
|
dict.Add(Background.Name.ToLower(), Background);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Lazy<Dictionary<string, IAnnotation>> _AnnotationJSObjectInitor;
|
||||||
|
|
||||||
|
public Dictionary<string, IAnnotation> AnnotationJSObject => _AnnotationJSObjectInitor.Value;
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
58
EnvelopeGenerator.Web/Models/Annotation/Background.cs
Normal file
58
EnvelopeGenerator.Web/Models/Annotation/Background.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Background is an annotation for the PSPDF Kit. However, it has no function.
|
||||||
|
/// It is only the first annotation as a background for other annotations.
|
||||||
|
/// </summary>
|
||||||
|
public record Background : IAnnotation
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public double Margin { get; init; }
|
||||||
|
|
||||||
|
public string Name { get; } = "Background";
|
||||||
|
|
||||||
|
public double? Width { get; set; }
|
||||||
|
|
||||||
|
public double? Height { get; set; }
|
||||||
|
|
||||||
|
public double Left { get; set; }
|
||||||
|
|
||||||
|
public double Top { get; set; }
|
||||||
|
|
||||||
|
public Color? BackgroundColor { get; init; }
|
||||||
|
|
||||||
|
#region Border
|
||||||
|
public Color? BorderColor { get; init; }
|
||||||
|
|
||||||
|
public string? BorderStyle { get; init; }
|
||||||
|
|
||||||
|
public int? BorderWidth { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void Locate(IEnumerable<IAnnotation> annotations)
|
||||||
|
{
|
||||||
|
// set Top
|
||||||
|
if (annotations.MinBy(a => a.Top)?.Top is double minTop)
|
||||||
|
Top = minTop;
|
||||||
|
|
||||||
|
// set Left
|
||||||
|
if (annotations.MinBy(a => a.Left)?.Left is double minLeft)
|
||||||
|
Left = minLeft;
|
||||||
|
|
||||||
|
// set Width
|
||||||
|
if(annotations.MaxBy(a => a.GetRight())?.GetRight() is double maxRight)
|
||||||
|
Width = maxRight - Left;
|
||||||
|
|
||||||
|
// set Height
|
||||||
|
if (annotations.MaxBy(a => a.GetBottom())?.GetBottom() is double maxBottom)
|
||||||
|
Height = maxBottom - Top;
|
||||||
|
|
||||||
|
// add margins
|
||||||
|
Top -= Margin;
|
||||||
|
Left -= Margin;
|
||||||
|
Width += Margin * 2;
|
||||||
|
Height += Margin * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
EnvelopeGenerator.Web/Models/Annotation/Color.cs
Normal file
10
EnvelopeGenerator.Web/Models/Annotation/Color.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
|
public record Color
|
||||||
|
{
|
||||||
|
public int R { get; init; } = 0;
|
||||||
|
|
||||||
|
public int G { get; init; } = 0;
|
||||||
|
|
||||||
|
public int B { get; init; } = 0;
|
||||||
|
}
|
||||||
8
EnvelopeGenerator.Web/Models/Annotation/Extensions.cs
Normal file
8
EnvelopeGenerator.Web/Models/Annotation/Extensions.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static double GetRight(this IAnnotation annotation) => annotation.Left + annotation?.Width ?? 0;
|
||||||
|
|
||||||
|
public static double GetBottom(this IAnnotation annotation) => annotation.Top + annotation?.Height ?? 0;
|
||||||
|
}
|
||||||
22
EnvelopeGenerator.Web/Models/Annotation/IAnnotation.cs
Normal file
22
EnvelopeGenerator.Web/Models/Annotation/IAnnotation.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
namespace EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
|
public interface IAnnotation
|
||||||
|
{
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
double? Width { get; }
|
||||||
|
|
||||||
|
double? Height { get; }
|
||||||
|
|
||||||
|
double Left { get; }
|
||||||
|
|
||||||
|
double Top { get; }
|
||||||
|
|
||||||
|
Color? BackgroundColor { get; }
|
||||||
|
|
||||||
|
Color? BorderColor { get; }
|
||||||
|
|
||||||
|
string? BorderStyle { get; }
|
||||||
|
|
||||||
|
int? BorderWidth { get; }
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ using DigitalData.EmailProfilerDispatcher;
|
|||||||
using EnvelopeGenerator.Infrastructure;
|
using EnvelopeGenerator.Infrastructure;
|
||||||
using EnvelopeGenerator.Web.Sanitizers;
|
using EnvelopeGenerator.Web.Sanitizers;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
using EnvelopeGenerator.Application.Extensions;
|
using EnvelopeGenerator.Web.Models.Annotation;
|
||||||
|
|
||||||
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||||
logger.Info("Logging initialized!");
|
logger.Info("Logging initialized!");
|
||||||
|
|||||||
@@ -151,6 +151,21 @@
|
|||||||
},
|
},
|
||||||
"MainPageTitle": null,
|
"MainPageTitle": null,
|
||||||
"AnnotationParams": {
|
"AnnotationParams": {
|
||||||
|
"Background": {
|
||||||
|
"Margin": 0.20,
|
||||||
|
"BackgroundColor": {
|
||||||
|
"R": 222,
|
||||||
|
"G": 220,
|
||||||
|
"B": 215
|
||||||
|
},
|
||||||
|
"BorderColor": {
|
||||||
|
"R": 204,
|
||||||
|
"G": 202,
|
||||||
|
"B": 198
|
||||||
|
},
|
||||||
|
"BorderStyle": "underline",
|
||||||
|
"BorderWidth": 4
|
||||||
|
},
|
||||||
"DefaultAnnotation": {
|
"DefaultAnnotation": {
|
||||||
"Width": 1,
|
"Width": 1,
|
||||||
"Height": 0.5,
|
"Height": 0.5,
|
||||||
|
|||||||
@@ -5,6 +5,34 @@ async function createAnnotations(document, instance) {
|
|||||||
for(var element of document.elements) {
|
for(var element of document.elements) {
|
||||||
const annotParams = await getAnnotationParams(element.left, element.top);
|
const annotParams = await getAnnotationParams(element.left, element.top);
|
||||||
const page = element.page - 1
|
const page = element.page - 1
|
||||||
|
|
||||||
|
//background
|
||||||
|
if(annotParams.background){
|
||||||
|
let background = annotParams.background;
|
||||||
|
const id_background = PSPDFKit.generateInstantId();
|
||||||
|
const annotation_background = new PSPDFKit.Annotations.WidgetAnnotation({
|
||||||
|
id: id_background,
|
||||||
|
pageIndex: page,
|
||||||
|
formFieldName: id_background,
|
||||||
|
backgroundColor: background?.backgroundColor ? new PSPDFKit.Color(background.backgroundColor) : null,
|
||||||
|
blendMode: 'normal',
|
||||||
|
boundingBox: new PSPDFKit.Geometry.Rect(background),
|
||||||
|
fontSize: 8,
|
||||||
|
borderStyle: background.borderStyle,
|
||||||
|
borderWidth: background.borderWidth,
|
||||||
|
borderColor: background?.borderColor ? new PSPDFKit.Color(background.borderColor) : null
|
||||||
|
});
|
||||||
|
|
||||||
|
const formFieldBackground = new PSPDFKit.FormFields.ButtonFormField({
|
||||||
|
name: id_background,
|
||||||
|
annotationIds: PSPDFKit.Immutable.List([annotation_background.id]),
|
||||||
|
value: "",
|
||||||
|
readOnly: false
|
||||||
|
});
|
||||||
|
|
||||||
|
signatures.push(annotation_background)
|
||||||
|
signatures.push(formFieldBackground)
|
||||||
|
}
|
||||||
|
|
||||||
//signatures
|
//signatures
|
||||||
const id = PSPDFKit.generateInstantId()
|
const id = PSPDFKit.generateInstantId()
|
||||||
@@ -12,8 +40,8 @@ async function createAnnotations(document, instance) {
|
|||||||
id: id,
|
id: id,
|
||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id,
|
formFieldName: id,
|
||||||
backgroundColor: PSPDFKit.Color.YELLOW,
|
backgroundColor: PSPDFKit.Color.LIGHT_YELLOW,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.signature),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.signature),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -29,7 +57,7 @@ async function createAnnotations(document, instance) {
|
|||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_position,
|
formFieldName: id_position,
|
||||||
backgroundColor: PSPDFKit.Color.DarkBlue,
|
backgroundColor: PSPDFKit.Color.DarkBlue,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.position),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.position),
|
||||||
fontSize: 8
|
fontSize: 8
|
||||||
})
|
})
|
||||||
@@ -48,7 +76,7 @@ async function createAnnotations(document, instance) {
|
|||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_city,
|
formFieldName: id_city,
|
||||||
backgroundColor: PSPDFKit.Color.DarkBlue,
|
backgroundColor: PSPDFKit.Color.DarkBlue,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.city),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.city),
|
||||||
fontSize: 8
|
fontSize: 8
|
||||||
})
|
})
|
||||||
@@ -67,7 +95,7 @@ async function createAnnotations(document, instance) {
|
|||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_date,
|
formFieldName: id_date,
|
||||||
backgroundColor: PSPDFKit.Color.DarkBlue,
|
backgroundColor: PSPDFKit.Color.DarkBlue,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.date),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.date),
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
||||||
@@ -97,7 +125,7 @@ async function createAnnotations(document, instance) {
|
|||||||
id: id_date_label,
|
id: id_date_label,
|
||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_date_label,
|
formFieldName: id_date_label,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.datelabel),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.datelabel),
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
||||||
@@ -119,7 +147,7 @@ async function createAnnotations(document, instance) {
|
|||||||
id: id_city_label,
|
id: id_city_label,
|
||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_city_label,
|
formFieldName: id_city_label,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.citylabel),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.citylabel),
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
||||||
@@ -131,7 +159,8 @@ async function createAnnotations(document, instance) {
|
|||||||
name: id_city_label,
|
name: id_city_label,
|
||||||
annotationIds: PSPDFKit.Immutable.List([annotation_city_label.id]),
|
annotationIds: PSPDFKit.Immutable.List([annotation_city_label.id]),
|
||||||
value: "Ort",
|
value: "Ort",
|
||||||
readOnly: true
|
readOnly: true,
|
||||||
|
color: PSPDFKit.Color.BLACK
|
||||||
})
|
})
|
||||||
|
|
||||||
//position label
|
//position label
|
||||||
@@ -140,7 +169,7 @@ async function createAnnotations(document, instance) {
|
|||||||
id: id_position_label,
|
id: id_position_label,
|
||||||
pageIndex: page,
|
pageIndex: page,
|
||||||
formFieldName: id_position_label,
|
formFieldName: id_position_label,
|
||||||
blendMode: 'multiply',
|
blendMode: 'normal',
|
||||||
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.positionlabel),
|
boundingBox: new PSPDFKit.Geometry.Rect(annotParams.positionlabel),
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
backgroundColor: PSPDFKit.Color.TRANSPARENT,
|
||||||
|
|||||||
@@ -175,21 +175,21 @@ async function setLanguage(language) {
|
|||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(langs => langs.includes(language))
|
.then(langs => langs.includes(language))
|
||||||
.catch(err => false);
|
.catch(err => false);
|
||||||
|
|
||||||
if(hasLang)
|
if (hasLang)
|
||||||
return await fetch(`/lang/${language}`, {
|
return await fetch(`/lang/${language}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.redirected)
|
if (response.redirected)
|
||||||
window.location.href = response.url;
|
window.location.href = response.url;
|
||||||
else if (!response.ok)
|
else if (!response.ok)
|
||||||
return Promise.reject('Failed to set language');
|
return Promise.reject('Failed to set language');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
@@ -204,22 +204,23 @@ async function logout() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAnnotationParams(leftInInch = 0, topInInch = 0, inchToPointFactor = 72) {
|
|
||||||
return fetch(`${window.location.origin}/api/Config/Annotations`, {
|
async function getAnnotationParams(leftInInch = 0, topInInch = 0, inchToPointFactor = 72) {
|
||||||
|
|
||||||
|
const annotParams = await fetch(`${window.location.origin}/api/Config/Annotations`, {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json());
|
||||||
.then(annotParams => {
|
|
||||||
for(var key in annotParams){
|
for (var key in annotParams) {
|
||||||
var annot = annotParams[key];
|
var annot = annotParams[key];
|
||||||
annot.width *= inchToPointFactor;
|
annot.width *= inchToPointFactor;
|
||||||
annot.height *= inchToPointFactor;
|
annot.height *= inchToPointFactor;
|
||||||
annot.left += leftInInch;
|
annot.left += leftInInch - 0.7;
|
||||||
annot.left *= inchToPointFactor;
|
annot.left *= inchToPointFactor;
|
||||||
annot.top += topInInch;
|
annot.top += topInInch - 0.5;
|
||||||
annot.top *= inchToPointFactor;
|
annot.top *= inchToPointFactor;
|
||||||
}
|
}
|
||||||
return annotParams;
|
return annotParams;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
async function setLangAsync(n,t){document.getElementById("selectedFlag").className="fi "+t+" me-2";await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}})}async function setLanguage(n){const t=await fetch("/lang",{method:"GET",headers:{"Content-Type":"application/json"}}).then(n=>n.json()).then(t=>t.includes(n)).catch(()=>!1);if(t)return await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{if(n.redirected)window.location.href=n.url;else if(!n.ok)return Promise.reject("Failed to set language")})}async function logout(){return await fetch(`/auth/logout`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{n.ok&&(window.location.href="/")})}function getAnnotationParams(n=0,t=0,i=72){return fetch(`${window.location.origin}/api/Config/Annotations`,{credentials:"include",method:"GET"}).then(n=>n.json()).then(r=>{var f,u;for(f in r)u=r[f],u.width*=i,u.height*=i,u.left+=n,u.left*=i,u.top+=t,u.top*=i;return r})}class Network{async getEnvelope(n){return this.getRequest(`/api/envelope/${n}`).then(this.wrapJsonResponse.bind(this))}async postEnvelope(n,t,i){return this.postRequest(`/api/envelope/${n}?index=${t}`,i).then(this.wrapJsonResponse.bind(this))}async getDocument(n,t){return this.getRequest(`/api/document/${n}?index=${t}`).then(this.wrapBinaryResponse.bind(this))}async openDocument(n){return this.postRequest(`/api/document/${n}`,{}).then(this.wrapJsonResponse.bind(this))}withCSRFToken(n){const t=getCSRFToken;let i=n.headers;return n.headers={...i,...t},n}getCSRFToken(){const n=document.getElementsByName("__RequestVerificationToken")[0].value;return{"X-XSRF-TOKEN":n}}getRequest(n){const t=this.getCSRFToken(),i={credentials:"include",method:"GET",headers:{...t}};return fetch(n,i)}postRequest(n,t){const i=this.getCSRFToken(),r={credentials:"include",method:"POST",headers:{...i,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(t)};return fetch(n,r)}async wrapJsonResponse(n){return await this.wrapResponse(n,async n=>await n.json())}async wrapBinaryResponse(n){return await this.wrapResponse(n,async n=>await n.arrayBuffer())}async wrapResponse(n,t){let i;if(n.status===200){const r=await t(n);i=new WrappedResponse(r,null)}else if(n.status===403){const t=await n.json();i=new WrappedResponse(null,t)}else i=new WrappedResponse(null,null);return i}}class WrappedResponse{constructor(n,t){this.data=n;this.error=t;this.fatal=n===null&&t===null}}
|
async function setLangAsync(n,t){document.getElementById("selectedFlag").className="fi "+t+" me-2";await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}})}async function setLanguage(n){const t=await fetch("/lang",{method:"GET",headers:{"Content-Type":"application/json"}}).then(n=>n.json()).then(t=>t.includes(n)).catch(()=>!1);if(t)return await fetch(`/lang/${n}`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{if(n.redirected)window.location.href=n.url;else if(!n.ok)return Promise.reject("Failed to set language")})}async function logout(){return await fetch(`/auth/logout`,{method:"POST",headers:{"Content-Type":"application/json"}}).then(n=>{n.ok&&(window.location.href="/")})}async function getAnnotationParams(n=0,t=0,i=72){var f,r;const u=await fetch(`${window.location.origin}/api/Config/Annotations`,{credentials:"include",method:"GET"}).then(n=>n.json());for(f in u)r=u[f],r.width*=i,r.height*=i,r.left+=n-.7,r.left*=i,r.top+=t-.5,r.top*=i;return u}class Network{async getEnvelope(n){return this.getRequest(`/api/envelope/${n}`).then(this.wrapJsonResponse.bind(this))}async postEnvelope(n,t,i){return this.postRequest(`/api/envelope/${n}?index=${t}`,i).then(this.wrapJsonResponse.bind(this))}async getDocument(n,t){return this.getRequest(`/api/document/${n}?index=${t}`).then(this.wrapBinaryResponse.bind(this))}async openDocument(n){return this.postRequest(`/api/document/${n}`,{}).then(this.wrapJsonResponse.bind(this))}withCSRFToken(n){const t=getCSRFToken;let i=n.headers;return n.headers={...i,...t},n}getCSRFToken(){const n=document.getElementsByName("__RequestVerificationToken")[0].value;return{"X-XSRF-TOKEN":n}}getRequest(n){const t=this.getCSRFToken(),i={credentials:"include",method:"GET",headers:{...t}};return fetch(n,i)}postRequest(n,t){const i=this.getCSRFToken(),r={credentials:"include",method:"POST",headers:{...i,"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify(t)};return fetch(n,r)}async wrapJsonResponse(n){return await this.wrapResponse(n,async n=>await n.json())}async wrapBinaryResponse(n){return await this.wrapResponse(n,async n=>await n.arrayBuffer())}async wrapResponse(n,t){let i;if(n.status===200){const r=await t(n);i=new WrappedResponse(r,null)}else if(n.status===403){const t=await n.json();i=new WrappedResponse(null,t)}else i=new WrappedResponse(null,null);return i}}class WrappedResponse{constructor(n,t){this.data=n;this.error=t;this.fatal=n===null&&t===null}}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user