Compare commits
24 Commits
396c6014fb
...
178ec9226d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
178ec9226d | ||
|
|
0147f525fa | ||
|
|
f0ed6137d1 | ||
|
|
b4ab2c4423 | ||
|
|
5715343651 | ||
|
|
6550be0235 | ||
|
|
99b0dba79f | ||
|
|
2f8d5f1fc8 | ||
|
|
6969f5f93e | ||
|
|
7bbed3890e | ||
|
|
98290c7b28 | ||
|
|
d55006fdda | ||
|
|
b2cc0cb65a | ||
|
|
049827a133 | ||
|
|
b02ab585cb | ||
|
|
c8a5a8627d | ||
|
|
ecf0771f9e | ||
|
|
02c7040b39 | ||
|
|
2cb5d0c0d5 | ||
|
|
9f186afdff | ||
|
|
ec76014ce7 | ||
|
|
e7bc43b339 | ||
|
|
26be8d4565 | ||
|
|
17902c4824 |
@@ -4,6 +4,8 @@
|
|||||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
<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>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using EnvelopeGenerator.Application.Envelopes;
|
||||||
|
using EnvelopeGenerator.Application.Receivers;
|
||||||
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.EnvelopeHistories;
|
||||||
|
|
||||||
|
/// <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="Status">Die Abfrage, die den Status des Umschlags beschreibt.</param>
|
||||||
|
public record EnvelopeHistoryQuery<TEnvelopeQuery, TReceiverQuery>(int EnvelopeId, TEnvelopeQuery? Envelope, TReceiverQuery? Receiver = null, StatusQuery? Status = null)
|
||||||
|
where TEnvelopeQuery : EnvelopeQuery
|
||||||
|
where TReceiverQuery : ReceiverQuery
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt den Referenztyp des Umschlags an.
|
||||||
|
/// Wenn der Benutzer des Umschlags definiert ist, wird der Referenztyp als Empfänger betrachtet.
|
||||||
|
/// Andernfalls, wenn ein Empfänger definiert ist, wird der Referenztyp ebenfalls als Empfänger betrachtet.
|
||||||
|
/// Ist keiner von beiden definiert, wird der Referenztyp als System betrachtet.
|
||||||
|
/// </summary>
|
||||||
|
public ReferenceType ReferenceType =>
|
||||||
|
Envelope?.Sender is not null
|
||||||
|
? ReferenceType.Receiver
|
||||||
|
: Receiver is not null
|
||||||
|
? ReferenceType.Receiver
|
||||||
|
: ReferenceType.System;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.EnvelopeHistories.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="Status">Die Abfrage, die den Status des Umschlags beschreibt.</param>
|
||||||
|
public record ReadEnvelopeHistoryQuery(
|
||||||
|
int EnvelopeId,
|
||||||
|
ReadEnvelopeQuery? Envelope = null,
|
||||||
|
ReadReceiverQuery? Receiver = null,
|
||||||
|
StatusQuery? Status = null)
|
||||||
|
: EnvelopeHistoryQuery<ReadEnvelopeQuery, ReadReceiverQuery>(EnvelopeId, Envelope, Receiver, Status);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.EnvelopeHistories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch <see cref="Common.Constants.EnvelopeStatus"/>
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item><description><c>Invalid</c> (0): Ungültiger Status.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeCreated</c> (1001): Der Umschlag wurde erstellt.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeSaved</c> (1002): Der Umschlag wurde gespeichert.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeQueued</c> (1003): Der Umschlag wurde zur Verarbeitung eingeplant.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeSent</c> (1004): Der Umschlag wurde versendet. (Nicht verwendet)</description></item>
|
||||||
|
/// <item><description><c>EnvelopePartlySigned</c> (1005): Der Umschlag wurde teilweise unterschrieben.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeCompletelySigned</c> (1006): Der Umschlag wurde vollständig unterschrieben.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeReportCreated</c> (1007): Ein Abschlussbericht wurde für den Umschlag erstellt.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeArchived</c> (1008): Der Umschlag wurde archiviert.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeDeleted</c> (1009): Der Umschlag wurde gelöscht.</description></item>
|
||||||
|
/// <item><description><c>AccessCodeRequested</c> (2001): Der Zugriffscode wurde angefordert.</description></item>
|
||||||
|
/// <item><description><c>AccessCodeCorrect</c> (2002): Der Zugriffscode war korrekt.</description></item>
|
||||||
|
/// <item><description><c>AccessCodeIncorrect</c> (2003): Der Zugriffscode war falsch.</description></item>
|
||||||
|
/// <item><description><c>DocumentOpened</c> (2004): Das Dokument wurde geöffnet.</description></item>
|
||||||
|
/// <item><description><c>DocumentSigned</c> (2005): Ein Dokument wurde unterschrieben.</description></item>
|
||||||
|
/// <item><description><c>SignatureConfirmed</c> (2006): Die Signatur wurde bestätigt.</description></item>
|
||||||
|
/// <item><description><c>DocumentRejected</c> (2007): Ein Dokument wurde abgelehnt.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeShared</c> (2008): Der Umschlag wurde geteilt.</description></item>
|
||||||
|
/// <item><description><c>EnvelopeViewed</c> (2009): Der Umschlag wurde angesehen.</description></item>
|
||||||
|
/// <item><description><c>DocumentForwarded</c> (4001): Das Dokument wurde weitergeleitet.</description></item>
|
||||||
|
/// <item><description><c>MessageInvitationSent</c> (3001): Einladung wurde gesendet (vom Trigger verwendet).</description></item>
|
||||||
|
/// <item><description><c>MessageAccessCodeSent</c> (3002): Zugriffscode wurde gesendet.</description></item>
|
||||||
|
/// <item><description><c>MessageConfirmationSent</c> (3003): Bestätigungsnachricht wurde gesendet.</description></item>
|
||||||
|
/// <item><description><c>MessageDeletionSent</c> (3004): Löschbenachrichtigung wurde gesendet.</description></item>
|
||||||
|
/// <item><description><c>MessageCompletionSent</c> (3005): Abschlussbenachrichtigung wurde gesendet.</description></item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
public record StatusQuery(
|
||||||
|
int? Min = null,
|
||||||
|
int? Max = null,
|
||||||
|
int[]? Ignore = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -3,6 +3,22 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
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] DocumentCreateDto Document,
|
||||||
|
[Required] IEnumerable<ReceiverGetOrCreateDto> Receivers,
|
||||||
|
bool TFAEnabled = false
|
||||||
|
) : IRequest;
|
||||||
|
|
||||||
#region DTOs
|
#region DTOs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signaturposition auf einem Dokument.
|
/// Signaturposition auf einem Dokument.
|
||||||
@@ -17,9 +33,9 @@ public record Signature([Required] int X, [Required] int Y, [Required] int Page)
|
|||||||
/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen.
|
/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Signatures">Unterschriften auf Dokumenten.</param>
|
/// <param name="Signatures">Unterschriften auf Dokumenten.</param>
|
||||||
/// <param name="Name">Der Name, mit dem der Käufer angesprochen werden soll. Bei Null oder keinem Wert wird der zuletzt verwendete Name verwendet.</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>
|
/// <param name="PhoneNumber">Sollte mit Vorwahl geschrieben werden</param>
|
||||||
public record ReceiverGetOrCreateDto([Required] IEnumerable<Signature> Signatures, string? Name = null, string? PhoneNumber = null)
|
public record ReceiverGetOrCreateDto([Required] IEnumerable<Signature> Signatures, string? Salution = null, string? PhoneNumber = null)
|
||||||
{
|
{
|
||||||
private string _emailAddress = string.Empty;
|
private string _emailAddress = string.Empty;
|
||||||
|
|
||||||
@@ -27,26 +43,17 @@ public record ReceiverGetOrCreateDto([Required] IEnumerable<Signature> Signature
|
|||||||
/// E-Mail-Adresse des Empfängers.
|
/// E-Mail-Adresse des Empfängers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public required string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress.ToLower(); }
|
public required string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress = _emailAddress.ToLower(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO für die Erstellung eines Dokuments.
|
/// DTO zum Erstellen eines Dokuments.
|
||||||
/// </summary>
|
/// </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 DocumentCreateDto(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
public record DocumentCreateDto(byte[]? DataAsByte = null, string? DataAsBase64 = null);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Befehl zur Erstellung eines Umschlags.
|
|
||||||
/// </summary>
|
|
||||||
public record CreateEnvelopeCommand(
|
|
||||||
[Required] string Title,
|
|
||||||
[Required] string Message,
|
|
||||||
[Required] DocumentCreateDto Document,
|
|
||||||
[Required] IEnumerable<ReceiverGetOrCreateDto> Receivers,
|
|
||||||
string Language = "de-DE",
|
|
||||||
DateTime? ExpiresWhen = null,
|
|
||||||
DateTime? ExpiresWarningWhen = null,
|
|
||||||
int ContractType = (int)Common.Constants.ContractType.Contract,
|
|
||||||
bool TFAEnabled = false
|
|
||||||
) : IRequest;
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
using EnvelopeGenerator.Application.EnvelopeHistories;
|
||||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers;
|
||||||
|
|
||||||
@@ -9,8 +8,4 @@ namespace EnvelopeGenerator.Application.EnvelopeReceivers;
|
|||||||
/// <param name="MinStatus"></param>
|
/// <param name="MinStatus"></param>
|
||||||
/// <param name="MaxStatus"></param>
|
/// <param name="MaxStatus"></param>
|
||||||
/// <param name="IgnoreStatus"></param>
|
/// <param name="IgnoreStatus"></param>
|
||||||
/// <param name="Receiver"></param>
|
public record EnvelopeReceiverQuery(StatusQuery Status);
|
||||||
public record EnvelopeReceiverQuery(
|
|
||||||
int? MinStatus = null,
|
|
||||||
int? MaxStatus = null,
|
|
||||||
int[]? IgnoreStatus = null);
|
|
||||||
@@ -1,15 +1,30 @@
|
|||||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
using EnvelopeGenerator.Application.EnvelopeHistories;
|
||||||
|
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
using EnvelopeGenerator.Application.Receivers.Queries.Read;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stellt eine Abfrage zum Lesen eines Envelope-Empfängers dar.
|
/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ReadEnvelopeReceiverQuery : EnvelopeReceiverQuery, IRequest<ReadEnvelopeReceiverResponse>
|
/// <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(StatusQuery Status) : EnvelopeReceiverQuery(Status), IRequest<ReadEnvelopeReceiverResponse>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Der Umschlag, der mit dem Empfänger verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
public ReadEnvelopeQuery? Envelope { get; init; }
|
public ReadEnvelopeQuery? Envelope { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Empfänger, der mit dem Umschlag verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
public ReadReceiverQuery? Receiver { get; init; }
|
public ReadReceiverQuery? Receiver { get; init; }
|
||||||
};
|
};
|
||||||
@@ -7,40 +7,88 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stellt eine Antwort auf die Abfrage zum Lesen eines Envelope-Empfängers dar.
|
/// Repräsentiert die Antwort für das Lesen eines Envelope-Empfängers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Receiver">Der angeforderte Empfänger.</param>
|
/// <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)
|
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]
|
[NotMapped]
|
||||||
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die eindeutige Kennung des zugehörigen Umschlags.
|
||||||
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int EnvelopeId { get; init; }
|
public int EnvelopeId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die eindeutige Kennung des Empfängers.
|
||||||
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int ReceiverId { get; init; }
|
public int ReceiverId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Reihenfolge des Empfängers innerhalb des Umschlags.
|
||||||
|
/// </summary>
|
||||||
public int Sequence { get; init; }
|
public int Sequence { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Name des Empfängers. Kann als Platzhalter verwendet werden.
|
||||||
|
/// </summary>
|
||||||
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
[TemplatePlaceholder("[NAME_RECEIVER]")]
|
||||||
public string? Name { get; init; }
|
public string? Name { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Berufsbezeichnung des Empfängers.
|
||||||
|
/// </summary>
|
||||||
public string? JobTitle { get; init; }
|
public string? JobTitle { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Firmenname des Empfängers.
|
||||||
|
/// </summary>
|
||||||
public string? CompanyName { get; init; }
|
public string? CompanyName { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eine private Nachricht, die mit dem Empfänger verknüpft ist.
|
||||||
|
/// </summary>
|
||||||
public string? PrivateMessage { get; init; }
|
public string? PrivateMessage { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde.
|
||||||
|
/// </summary>
|
||||||
public DateTime AddedWhen { get; init; }
|
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; }
|
public DateTime? ChangedWhen { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt an, ob der Empfänger eine Telefonnummer hat.
|
||||||
|
/// </summary>
|
||||||
public bool HasPhoneNumber { get; init; }
|
public bool HasPhoneNumber { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die zugehörigen Umschlagsdaten.
|
||||||
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public required ReadEnvelopeResponse Envelope { get; init; }
|
public required ReadEnvelopeResponse Envelope { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die Liste der Empfängerinformationen.
|
||||||
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public IEnumerable<ReadReceiverResponse> Receiver { get; init; } = new List<ReadReceiverResponse>();
|
public IEnumerable<ReadReceiverResponse> Receiver { get; init; } = new List<ReadReceiverResponse>();
|
||||||
}
|
}
|
||||||
@@ -6,15 +6,27 @@ namespace EnvelopeGenerator.Application.Envelopes;
|
|||||||
/// Repräsentiert eine Abfrage für Umschläge.
|
/// Repräsentiert eine Abfrage für Umschläge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
/// <param name="Id">Die eindeutige Kennung des Umschlags.</param>
|
||||||
/// <param name="UserId">Die Kennung des Benutzers, der den Umschlag erstellt hat.</param>
|
/// <param name="Sender">Absender des Schreibens</param>
|
||||||
/// <param name="Username">Der Benutzername des Benutzers, der den Umschlag erstellt hat.</param>
|
|
||||||
/// <param name="Email">Die E-Mail-Adresse des Benutzers, der den Umschlag erstellt hat.</param>
|
|
||||||
/// <param name="Status">Der Status des Umschlags.</param>
|
/// <param name="Status">Der Status des Umschlags.</param>
|
||||||
/// <param name="Uuid">Die universell eindeutige Kennung des Umschlags.</param>
|
/// <param name="Uuid">Die universell eindeutige Kennung des Umschlags.</param>
|
||||||
public record EnvelopeQuery(
|
public record EnvelopeQuery(
|
||||||
int? Id = null,
|
int? Id = null,
|
||||||
int? UserId = null,
|
SenderQuery? Sender = null,
|
||||||
string? Username = null,
|
|
||||||
string? Email = null,
|
|
||||||
int? Status = null,
|
int? Status = null,
|
||||||
string? Uuid = null) : IRequest;
|
string? Uuid = null) : IRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Die eindeutige Kennung des Benutzers.
|
||||||
|
/// </summary>
|
||||||
|
public int? SenderId => Sender?.Id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Benutzername des Absenders.
|
||||||
|
/// </summary>
|
||||||
|
public string? SenderUsername => Sender?.Username;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Die E-Mail-Adresse des Benutzers.
|
||||||
|
/// </summary>
|
||||||
|
public string? SenderEmail => Sender?.Username;
|
||||||
|
};
|
||||||
@@ -2,7 +2,35 @@
|
|||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
namespace EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||||
|
|
||||||
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>
|
||||||
|
/// 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();
|
public string StatusName => ((Constants.EnvelopeStatus)Status).ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
11
EnvelopeGenerator.Application/Envelopes/SenderQuery.cs
Normal file
11
EnvelopeGenerator.Application/Envelopes/SenderQuery.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Envelopes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repräsentiert eine Abfrage für einen Absender.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Die eindeutige Kennung des Absenders.</param>
|
||||||
|
/// <param name="Username">Der Benutzername des Absenders.</param>
|
||||||
|
/// <param name="Email">Die E-Mail-Adresse des Absenders.</param>
|
||||||
|
public record SenderQuery(int? Id = null, string? Username = null, string? Email = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
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
|
public record ReadReceiverQuery : ReceiverQuery
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
namespace EnvelopeGenerator.Application.Receivers.Queries.Read;
|
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)
|
public record ReadReceiverResponse(int Id, string EmailAddress, DateTime AddedWhen, string Signature)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,12 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
|||||||
/// "password": "Geheim123!"
|
/// "password": "Geheim123!"
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
/// POST /api/auth?cookie=true
|
||||||
|
/// {
|
||||||
|
/// "id": "1",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// </remarks>
|
/// </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="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>
|
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.EnvelopeHistories;
|
||||||
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]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
@@ -13,23 +28,36 @@ public class EnvelopeController : ControllerBase
|
|||||||
private readonly ILogger<EnvelopeController> _logger;
|
private readonly ILogger<EnvelopeController> _logger;
|
||||||
private readonly IEnvelopeService _envelopeService;
|
private readonly IEnvelopeService _envelopeService;
|
||||||
|
|
||||||
|
/// <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)
|
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_envelopeService = envelopeService;
|
_envelopeService = envelopeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft eine Liste von Umschlägen basierend auf dem Benutzer und den angegebenen Statusfiltern ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="status">Die Statusfilter, die für die Abfrage verwendet werden sollen.</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]
|
[Authorize]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetAsync(
|
public async Task<IActionResult> GetAsync(
|
||||||
[FromQuery] int? min_status = null,
|
[FromQuery] StatusQuery status)
|
||||||
[FromQuery] int? max_status = null,
|
|
||||||
[FromQuery] params int[] ignore_statuses)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (User.GetId() is int intId)
|
if (User.GetId() is int intId)
|
||||||
return await _envelopeService.ReadByUserAsync(intId, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses).ThenAsync(
|
return await _envelopeService.ReadByUserAsync(intId, min_status: status.Min, max_status: status.Max, ignore_statuses: status.Ignore ?? Array.Empty<int>()).ThenAsync(
|
||||||
Success: Ok,
|
Success: Ok,
|
||||||
Fail: IActionResult (msg, ntc) =>
|
Fail: IActionResult (msg, ntc) =>
|
||||||
{
|
{
|
||||||
@@ -38,7 +66,7 @@ public class EnvelopeController : ControllerBase
|
|||||||
});
|
});
|
||||||
else
|
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.");
|
_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 StatusCode(StatusCodes.Status500InternalServerError);
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,153 +1,161 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||||
|
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries.Read;
|
||||||
using MediatR;
|
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;
|
||||||
|
_erService = envelopeReceiverService;
|
||||||
|
_mediator = mediator;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly IEnvelopeReceiverService _erService;
|
/// <summary>
|
||||||
|
/// Ruft eine Liste von Umschlagempfängern basierend auf den angegebenen Abfrageparametern ab.
|
||||||
private readonly IMediator _mediator;
|
/// </summary>
|
||||||
|
/// <param name="envelopeReceiver">Die Abfrageparameter, die den Status und andere Filterkriterien enthalten.</param>
|
||||||
public EnvelopeReceiverController(ILogger<EnvelopeReceiverController> logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator)
|
/// <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="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger = logger;
|
var username = User.GetUsername();
|
||||||
_erService = envelopeReceiverService;
|
|
||||||
_mediator = mediator;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
if (username is null)
|
||||||
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, min_status: envelopeReceiver.Status.Min, max_status: envelopeReceiver.Status.Min, ignore_statuses: envelopeReceiver.Status.Ignore ?? Array.Empty<int>()).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)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "{message}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
/// <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"
|
|
||||||
/// }
|
|
||||||
/// ],
|
|
||||||
/// "language": "de-DE",
|
|
||||||
/// "expiresWhen": "2025-12-31T23:59:59Z",
|
|
||||||
/// "expiresWarningWhen": "2025-12-24T23:59:59Z",
|
|
||||||
/// "contractType": 1,
|
|
||||||
/// "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] CreateEnvelopeCommand createEnvelopeQuery, CancellationToken cancellationToken)
|
|
||||||
{
|
{
|
||||||
await _mediator.Send(createEnvelopeQuery, cancellationToken);
|
_logger.LogError(ex, "An unexpected error occurred. {message}", ex.Message);
|
||||||
return Accepted();
|
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft den Namen des letzten verwendeten Empfängers basierend auf der angegebenen E-Mail-Adresse ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mail">Die E-Mail-Adresse des Empfängers.</param>
|
||||||
|
/// <returns>Eine HTTP-Antwort mit dem Namen des Empfängers oder einem Fehlerstatus.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Dieser Endpunkt ermöglicht es, den Namen des letzten Empfängers abzurufen, der mit der angegebenen E-Mail-Adresse verknüpft ist.
|
||||||
|
/// Wenn kein Empfänger gefunden wird, wird ein leerer String zurückgegeben.
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Der Name des Empfängers wurde erfolgreich abgerufen.</response>
|
||||||
|
/// <response code="404">Kein Empfänger mit der angegebenen E-Mail-Adresse gefunden.</response>
|
||||||
|
/// <response code="500">Ein unerwarteter Fehler ist aufgetreten.</response>
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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,86 @@
|
|||||||
using EnvelopeGenerator.Application.Contracts.Services;
|
using EnvelopeGenerator.Application.Contracts.Services;
|
||||||
|
using EnvelopeGenerator.Application.EnvelopeHistories.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 bietet Endpunkte für den Zugriff auf die Verlaufshistorie von Umschlägen.
|
||||||
|
/// </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 Verlaufshistorie verantwortlich ist.</param>
|
||||||
|
public HistoryController(ILogger<HistoryController> logger, IEnvelopeHistoryService service)
|
||||||
{
|
{
|
||||||
private readonly ILogger<HistoryController> _logger;
|
_logger = logger;
|
||||||
|
_service = service;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly IEnvelopeHistoryService _service;
|
/// <summary>
|
||||||
|
/// Ruft die verfügbaren Referenztypen ab und gibt sie als Schlüssel-Wert-Paare zurück.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Ein Ok-Ergebnis mit einem Wörterbuch, das die Referenztypen als Schlüssel-Wert-Paare enthält.</returns>
|
||||||
|
[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);
|
||||||
|
|
||||||
public HistoryController(ILogger<HistoryController> logger, IEnvelopeHistoryService service)
|
return Ok(referenceTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruft die gesamte Verlaufshistorie von Umschlägen basierend auf den angegebenen Abfrageparametern ab.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="history">Die Abfrageparameter, die die Filterkriterien für die Verlaufshistorie definieren.</param>
|
||||||
|
/// <returns>Eine Liste von Verlaufseinträgen, die den angegebenen Kriterien entsprechen.</returns>
|
||||||
|
[HttpGet]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<IActionResult> GetAllAsync([FromQuery] ReadEnvelopeHistoryQuery history)
|
||||||
|
{
|
||||||
|
ReferenceType? refTypEnum = history.ReferenceType;
|
||||||
|
bool withReceiver = false;
|
||||||
|
bool withSender = false;
|
||||||
|
|
||||||
|
switch (refTypEnum)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
case ReferenceType.Receiver:
|
||||||
_service = service;
|
withReceiver = true;
|
||||||
|
break;
|
||||||
|
case ReferenceType.Sender:
|
||||||
|
withSender = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("reference-type")]
|
var histories = await _service.ReadAsync(
|
||||||
[Authorize]
|
envelopeId: history.EnvelopeId,
|
||||||
public IActionResult GetReferenceTypes()
|
//userReference: history.r,
|
||||||
{
|
referenceType: refTypEnum,
|
||||||
// Enum to Key-Value pair
|
withSender: withSender,
|
||||||
var referenceTypes = Enum.GetValues(typeof(ReferenceType))
|
withReceiver: withReceiver);
|
||||||
.Cast<ReferenceType>()
|
|
||||||
.ToDictionary(rt =>
|
|
||||||
{
|
|
||||||
var key = rt.ToString();
|
|
||||||
var keyAsCamelCase = char.ToLower(key[0]) + key[1..];
|
|
||||||
return keyAsCamelCase;
|
|
||||||
}, rt => (int)rt);
|
|
||||||
|
|
||||||
return Ok(referenceTypes);
|
return Ok(histories);
|
||||||
}
|
|
||||||
|
|
||||||
[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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,85 +6,114 @@ 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>
|
||||||
|
[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
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
<FileVersion>1.1.0</FileVersion>
|
<FileVersion>1.1.0</FileVersion>
|
||||||
<AssemblyVersion>1.1.0</AssemblyVersion>
|
<AssemblyVersion>1.1.0</AssemblyVersion>
|
||||||
<PackageOutputPath>Copyright © 2025 Digital Data GmbH. All rights reserved.</PackageOutputPath>
|
<PackageOutputPath>Copyright © 2025 Digital Data GmbH. All rights reserved.</PackageOutputPath>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,13 +3,11 @@
|
|||||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Anmeldedatenmodell
|
/// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <summary lang="en-US">
|
/// <param name="Password">Das erforderliche Passwort für das Login.</param>
|
||||||
/// Login data model
|
/// <param name="Id">Die optionale ID des Benutzers.</param>
|
||||||
/// </summary>
|
/// <param name="Username">Der optionale Benutzername.</param>
|
||||||
/// <param name="Username">Active Directory user name</param>
|
public record Login([Required] string Password, int? Id = null, string? Username = null)
|
||||||
/// <param name="Password">Active Directory password</param>
|
|
||||||
public record Login([Required]string Username, [Required] string Password)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,11 @@ builder.Services.AddSwaggerGen(options =>
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
|
||||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
foreach (var xmlFile in xmlFiles)
|
||||||
|
{
|
||||||
|
options.IncludeXmlComments(xmlFile);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
builder.Services.AddOpenApi();
|
builder.Services.AddOpenApi();
|
||||||
// DbContext
|
// DbContext
|
||||||
|
|||||||
Reference in New Issue
Block a user