diff --git a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs index 2dc76824..721d7524 100644 --- a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs +++ b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs @@ -1,9 +1,11 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record ConfigDto( string DocumentPath, int SendingProfile, diff --git a/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs index aff23a33..04b9d0ad 100644 --- a/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs +++ b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record DocumentReceiverElementDto( int Id, int DocumentId, diff --git a/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs index b24724ef..a098746a 100644 --- a/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs +++ b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record DocumentStatusDto( int Id, int EnvelopeId, diff --git a/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs index 8eaa798f..e22a4844 100644 --- a/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record EmailTemplateDto( int Id, string Name, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs index 34d38990..49852dce 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeCertificateDto( int Id, int EnvelopeId, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs index a9422f02..97ca20c2 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeDocumentDto ( int Id, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs index e0bbe042..6a038d83 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs @@ -2,9 +2,11 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; using DigitalData.UserManager.Application.DTOs.User; using EnvelopeGenerator.Domain.Entities; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeDto() : IUnique { public int Id { get; set; } diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryCreateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryCreateDto.cs index 92264d05..731b33a1 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryCreateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryCreateDto.cs @@ -1,5 +1,8 @@ -namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory +using Microsoft.AspNetCore.Mvc; + +namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeHistoryCreateDto( int EnvelopeId, string UserReference, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs index 0de3f3fb..3d5e15dc 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs @@ -2,10 +2,12 @@ using DigitalData.Core.DTO; using DigitalData.UserManager.Application.DTOs.User; using EnvelopeGenerator.Application.DTOs.Receiver; +using Microsoft.AspNetCore.Mvc; using static EnvelopeGenerator.Common.Constants; namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeHistoryDto( long Id, int EnvelopeId, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs index 64c5b869..5bbf3891 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs @@ -1,8 +1,10 @@ using DigitalData.Core.Abstractions; using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)> { public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId); diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs index 49625eee..0ab1ac58 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs @@ -1,7 +1,9 @@ using EnvelopeGenerator.Application.DTOs.Receiver; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto() { public EnvelopeDto? Envelope { get; set; } diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs index 9470766e..df380980 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs @@ -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 string? AccessCode { get; init; } diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyCreateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyCreateDto.cs index 434b9fd9..2cb09b81 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyCreateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyCreateDto.cs @@ -1,8 +1,10 @@ -using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeReceiverReadOnlyCreateDto( DateTime DateValid) { diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyDto.cs index 88417d66..b2427694 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyDto.cs @@ -1,7 +1,9 @@ using EnvelopeGenerator.Application.DTOs.Receiver; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeReceiverReadOnlyDto( long Id, long EnvelopeId, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyUpdateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyUpdateDto.cs index 356524a2..532caee1 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyUpdateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverReadOnly/EnvelopeReceiverReadOnlyUpdateDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeReceiverReadOnlyUpdateDto( long Id, DateTime DateValid, diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs index f7f55ac3..05be1eac 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record EnvelopeTypeDto( int Id, string Title, diff --git a/EnvelopeGenerator.Application/DTOs/Messaging/GtxMessagingResponse.cs b/EnvelopeGenerator.Application/DTOs/Messaging/GtxMessagingResponse.cs index e198038c..33feb685 100644 --- a/EnvelopeGenerator.Application/DTOs/Messaging/GtxMessagingResponse.cs +++ b/EnvelopeGenerator.Application/DTOs/Messaging/GtxMessagingResponse.cs @@ -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 { } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/Messaging/SmsResponse.cs b/EnvelopeGenerator.Application/DTOs/Messaging/SmsResponse.cs index 1d82020b..3977cc1a 100644 --- a/EnvelopeGenerator.Application/DTOs/Messaging/SmsResponse.cs +++ b/EnvelopeGenerator.Application/DTOs/Messaging/SmsResponse.cs @@ -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 required bool Ok { get; init; } diff --git a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverCreateDto.cs b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverCreateDto.cs index 54b90b4b..b5605c94 100644 --- a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverCreateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverCreateDto.cs @@ -1,9 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; using System.Security.Cryptography; using System.Text; namespace EnvelopeGenerator.Application.DTOs.Receiver { + [ApiExplorerSettings(IgnoreApi = true)] public record ReceiverCreateDto([EmailAddress] string EmailAddress, string? TotpSecretkey = null) { public string Signature => sha256HexOfMail.Value; diff --git a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs index 7759885a..41e380c8 100644 --- a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs +++ b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs @@ -2,10 +2,12 @@ using DigitalData.Core.DTO; using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using Microsoft.AspNetCore.Mvc; using System.Text.Json.Serialization; namespace EnvelopeGenerator.Application.DTOs.Receiver; +[ApiExplorerSettings(IgnoreApi = true)] public record ReceiverReadDto( int Id, string EmailAddress, diff --git a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs index 88482822..f4d89410 100644 --- a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs @@ -1,5 +1,7 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs.Receiver; +[ApiExplorerSettings(IgnoreApi = true)] public record ReceiverUpdateDto(int Id, string? TotpSecretkey = null, DateTime? TfaRegDeadline = null) : IUnique; \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs index 8630838a..5a46789f 100644 --- a/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs +++ b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs @@ -1,7 +1,9 @@ using DigitalData.Core.Abstractions; +using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.Application.DTOs { + [ApiExplorerSettings(IgnoreApi = true)] public record UserReceiverDto( int Id, int UserId, diff --git a/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEnvelopeTemplateCommand.cs b/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEnvelopeTemplateCommand.cs new file mode 100644 index 00000000..79ce1295 --- /dev/null +++ b/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEnvelopeTemplateCommand.cs @@ -0,0 +1,22 @@ +using EnvelopeGenerator.Common; + +namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset; + +/// +/// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte. +/// Erbt von und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage. +/// +/// Die optionale ID der E-Mail-Vorlage, die zurückgesetzt werden soll. +/// Der Typ der E-Mail-Vorlage, z. B. (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. +/// +public record ResetEnvelopeTemplateCommand(int? Id, Constants.EmailTemplateType? Type) : EmailTemplateQuery(Id, Type); diff --git a/EnvelopeGenerator.Application/EmailTemplates/Commands/Update/UpdateEmailTemplateCommand.cs b/EnvelopeGenerator.Application/EmailTemplates/Commands/Update/UpdateEmailTemplateCommand.cs new file mode 100644 index 00000000..63d2a7fd --- /dev/null +++ b/EnvelopeGenerator.Application/EmailTemplates/Commands/Update/UpdateEmailTemplateCommand.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update; + + +/// +/// Befehl zum Aktualisieren einer E-Mail-Vorlage. +/// +/// +/// (Optional)Der neue Inhalt des E-Mail-Textkörpers. Wenn null, bleibt der vorhandene Inhalt unverändert. +/// +/// +/// (Optional) Der neue Betreff der E-Mail. Wenn null, bleibt der vorhandene Betreff unverändert. +/// +public record UpdateEmailTemplateCommand(string? Body = null, string? Subject = null) +{ + /// + /// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll. + /// + [JsonIgnore] + public EmailTemplateQuery? EmailTemplateQuery { get; set; } +} diff --git a/EnvelopeGenerator.Application/EmailTemplates/EmailTemplateQuery.cs b/EnvelopeGenerator.Application/EmailTemplates/EmailTemplateQuery.cs new file mode 100644 index 00000000..00f390a3 --- /dev/null +++ b/EnvelopeGenerator.Application/EmailTemplates/EmailTemplateQuery.cs @@ -0,0 +1,24 @@ +using EnvelopeGenerator.Common; + +namespace EnvelopeGenerator.Application.EmailTemplates; + +/// +/// 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". +/// +/// Die eindeutige Kennung der E-Mail-Vorlage (optional). +/// Der Typ der E-Mail-Vorlage, z. B. (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. +/// +public record EmailTemplateQuery(int? Id = null, Constants.EmailTemplateType? Type = null) +{ +} diff --git a/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQuery.cs b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQuery.cs new file mode 100644 index 00000000..0c82bab2 --- /dev/null +++ b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQuery.cs @@ -0,0 +1,10 @@ +namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read; + + +/// +/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen. +/// Diese Klasse erbt von . +/// +public record ReadEmailTemplateQuery : EmailTemplateQuery +{ +} diff --git a/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateResponse.cs b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateResponse.cs new file mode 100644 index 00000000..3234c86a --- /dev/null +++ b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateResponse.cs @@ -0,0 +1,20 @@ +namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read; + +/// +/// Stellt die Antwort für eine Abfrage von E-Mail-Vorlagen bereit. +/// +/// Die eindeutige Kennung der E-Mail-Vorlage. +/// Der Typ der E-Mail-Vorlage. +/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde. +/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein. +/// Der Betreff der E-Mail-Vorlage. Kann null sein. +/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein. +public record ReadEmailTemplateResponse( + int Id, + int Type, + DateTime AddedWhen, + string? Body = null, + string? Subject = null, + DateTime? ChangedWhen = null) +{ +} diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index c8b0b4a5..3fe00e17 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -1,9 +1,11 @@  - net7.0 + net7.0;net8.0;net9.0 enable enable + true + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml @@ -17,6 +19,7 @@ + diff --git a/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommand.cs b/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommand.cs new file mode 100644 index 00000000..7000950d --- /dev/null +++ b/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommand.cs @@ -0,0 +1,59 @@ +using MediatR; +using System.ComponentModel.DataAnnotations; + +namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create; + +/// +/// Befehl zur Erstellung eines Umschlags. +/// +/// Der Titel des Umschlags. Dies ist ein Pflichtfeld. +/// Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld. +/// Das mit dem Umschlag verknüpfte Dokument. Dies ist ein Pflichtfeld. +/// Eine Sammlung von Empfängern, die den Umschlag erhalten. Dies ist ein Pflichtfeld. +/// Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false. +public record CreateEnvelopeReceiverCommand( + [Required] string Title, + [Required] string Message, + [Required] DocumentCreateCommand Document, + [Required] IEnumerable Receivers, + bool TFAEnabled = false + ) : IRequest; + +#region DTOs +/// +/// Signaturposition auf einem Dokument. +/// +/// X-Position +/// Y-Position +/// Seite, auf der sie sich befindet +public record Signature([Required] int X, [Required] int Y, [Required] int Page); + +/// +/// DTO für Empfänger, die erstellt oder abgerufen werden sollen. +/// Wenn nicht, wird sie erstellt und mit einer Signatur versehen. +/// +/// Unterschriften auf Dokumenten. +/// Der Name, mit dem der Empfänger angesprochen werden soll. Bei Null oder keinem Wert wird der zuletzt verwendete Name verwendet. +/// Sollte mit Vorwahl geschrieben werden +public record ReceiverGetOrCreateCommand([Required] IEnumerable Signatures, string? Salution = null, string? PhoneNumber = null) +{ + private string _emailAddress = string.Empty; + + /// + /// E-Mail-Adresse des Empfängers. + /// + [Required] + public required string EmailAddress { get => _emailAddress.ToLower(); init => _emailAddress = _emailAddress.ToLower(); } +}; + +/// +/// DTO zum Erstellen eines Dokuments. +/// +/// +/// Die Dokumentdaten im Byte-Array-Format. Wird verwendet, wenn das Dokument als Roh-Binärdaten bereitgestellt wird. +/// +/// +/// Die Dokumentdaten im Base64-String-Format. Wird verwendet, wenn das Dokument als Base64-codierter String bereitgestellt wird. +/// +public record DocumentCreateCommand(byte[]? DataAsByte = null, string? DataAsBase64 = null); +#endregion \ No newline at end of file diff --git a/EnvelopeGenerator.Application/EnvelopeReceivers/EnvelopeReceiverQuery.cs b/EnvelopeGenerator.Application/EnvelopeReceivers/EnvelopeReceiverQuery.cs new file mode 100644 index 00000000..93f171f4 --- /dev/null +++ b/EnvelopeGenerator.Application/EnvelopeReceivers/EnvelopeReceiverQuery.cs @@ -0,0 +1,47 @@ +using EnvelopeGenerator.Application.Histories; + +namespace EnvelopeGenerator.Application.EnvelopeReceivers; + +/// +/// Stellt eine Abfrage für einen Envelope-Empfänger dar. +/// +/// Der Status der Abfrage, optional. +public record EnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null); + +/// +/// Repräsentiert den Status eines Umschlags und dessen Beziehung zum Empfänger. (vgl. auch +/// 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. +/// Der minimale Statuswert, der berücksichtigt werden soll. +/// Der maximale Statuswert, der berücksichtigt werden soll. +/// Eine Liste von Statuswerten, die ignoriert werden sollen. +/// +public record EnvelopeStatusQuery( + int? Min = null, + int? Max = null, + int[]? Ignore = null) +{ +} diff --git a/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverQuery.cs b/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverQuery.cs new file mode 100644 index 00000000..3abf9d84 --- /dev/null +++ b/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverQuery.cs @@ -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; + +/// +/// Repräsentiert eine Abfrage zum Lesen eines Envelope-Empfängers. +/// +/// +/// Diese Abfrage kombiniert Informationen über einen Umschlag () +/// und einen Empfänger (), um eine vollständige Antwort +/// () zu generieren. +/// Die Antwort enthält Details wie den Status, die Zuordnung zwischen Umschlag und Empfänger +/// sowie zusätzliche Metadaten. +/// +/// Umschlag oder Empfängerstatus. +public record ReadEnvelopeReceiverQuery(EnvelopeStatusQuery? Status = null) : EnvelopeReceiverQuery(Status), IRequest +{ + /// + /// Der Umschlag, der mit dem Empfänger verknüpft ist. + /// + public ReadEnvelopeQuery? Envelope { get; init; } + + /// + /// Der Empfänger, der mit dem Umschlag verknüpft ist. + /// + public ReadReceiverQuery? Receiver { get; init; } +}; diff --git a/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverResponse.cs b/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverResponse.cs new file mode 100644 index 00000000..dd9c482b --- /dev/null +++ b/EnvelopeGenerator.Application/EnvelopeReceivers/Queries/Read/ReadEnvelopeReceiverResponse.cs @@ -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; + +/// +/// Repräsentiert die Antwort für das Lesen eines Envelope-Empfängers. +/// +/// +/// 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. +/// +/// Die eindeutige Kennung des Benutzers, der den Empfänger erstellt hat. +/// Der Status des Empfängers als numerischer Wert. +public record ReadEnvelopeReceiverResponse(int UserId, int Status) +{ + /// + /// Gibt die zusammengesetzte Kennung des Empfängers zurück, bestehend aus der Umschlags-ID und der Empfänger-ID. + /// + /// + /// Diese Eigenschaft kombiniert die eindeutige Kennung des Umschlags (EnvelopeId) und die des Empfängers (ReceiverId) + /// zu einer einzigen, leicht zugänglichen Struktur. + /// + [NotMapped] + public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId); + + /// + /// Die eindeutige Kennung des zugehörigen Umschlags. + /// + [Required] + public int EnvelopeId { get; init; } + + /// + /// Die eindeutige Kennung des Empfängers. + /// + [Required] + public int ReceiverId { get; init; } + + /// + /// Die Reihenfolge des Empfängers innerhalb des Umschlags. + /// + public int Sequence { get; init; } + + /// + /// Der Name des Empfängers. Kann als Platzhalter verwendet werden. + /// + [TemplatePlaceholder("[NAME_RECEIVER]")] + public string? Name { get; init; } + + /// + /// Die Berufsbezeichnung des Empfängers. + /// + public string? JobTitle { get; init; } + + /// + /// Der Firmenname des Empfängers. + /// + public string? CompanyName { get; init; } + + /// + /// Eine private Nachricht, die mit dem Empfänger verknüpft ist. + /// + public string? PrivateMessage { get; init; } + + /// + /// Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde. + /// + public DateTime AddedWhen { get; init; } + + /// + /// Das Datum und die Uhrzeit, wann der Empfänger zuletzt geändert wurde (falls vorhanden). + /// + public DateTime? ChangedWhen { get; init; } + + /// + /// Gibt an, ob der Empfänger eine Telefonnummer hat. + /// + public bool HasPhoneNumber { get; init; } + + /// + /// Die zugehörigen Umschlagsdaten. + /// + [Required] + public required ReadEnvelopeResponse Envelope { get; init; } + + /// + /// Die Liste der Empfängerinformationen. + /// + [Required] + public IEnumerable Receiver { get; init; } = new List(); +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Envelopes/EnvelopeQuery.cs b/EnvelopeGenerator.Application/Envelopes/EnvelopeQuery.cs new file mode 100644 index 00000000..6c30fab4 --- /dev/null +++ b/EnvelopeGenerator.Application/Envelopes/EnvelopeQuery.cs @@ -0,0 +1,16 @@ +using MediatR; + +namespace EnvelopeGenerator.Application.Envelopes; + +/// +/// Repräsentiert eine Abfrage für Umschläge. +/// +/// Die eindeutige Kennung des Umschlags. +/// Der Status des Umschlags. +/// Die universell eindeutige Kennung des Umschlags. +public record EnvelopeQuery( + int? Id = null, + int? Status = null, + string? Uuid = null) : IRequest +{ +}; \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeQuery.cs b/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeQuery.cs new file mode 100644 index 00000000..30092482 --- /dev/null +++ b/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeQuery.cs @@ -0,0 +1,8 @@ +namespace EnvelopeGenerator.Application.Envelopes.Queries.Read; + +/// +/// Stellt eine Abfrage zum Lesen von Briefumschlägen dar. +/// +public record ReadEnvelopeQuery : EnvelopeQuery +{ +} diff --git a/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeResponse.cs b/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeResponse.cs new file mode 100644 index 00000000..5644d251 --- /dev/null +++ b/EnvelopeGenerator.Application/Envelopes/Queries/Read/ReadEnvelopeResponse.cs @@ -0,0 +1,36 @@ +using EnvelopeGenerator.Common; + +namespace EnvelopeGenerator.Application.Envelopes.Queries.Read; + +/// +/// Repräsentiert die Antwort für das Lesen eines Umschlags. +/// +/// Die eindeutige Kennung des Umschlags. +/// Die Kennung des Benutzers, der den Umschlag erstellt hat. +/// Der Status des Umschlags als numerischer Wert. +/// Die universelle eindeutige Kennung (UUID) des Umschlags. +/// Eine optionale Nachricht, die mit dem Umschlag verknüpft ist. +/// Das Datum und die Uhrzeit, wann der Umschlag hinzugefügt wurde. +/// Das Datum und die Uhrzeit, wann der Umschlag zuletzt geändert wurde (falls vorhanden). +/// Ein optionaler Titel des Umschlags. +/// Die Sprache, die mit dem Umschlag verknüpft ist. +/// Gibt an, ob die Zwei-Faktor-Authentifizierung (TFA) aktiviert ist. +/// Das Benutzerobjekt, das mit dem Umschlag verknüpft ist. +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) +{ + /// + /// Gibt den Namen des Status zurück, der dem numerischen Statuswert entspricht. + /// + public string StatusName => ((Constants.EnvelopeStatus)Status).ToString(); +} diff --git a/EnvelopeGenerator.Application/Envelopes/Queries/ReceiverName/ReadReceiverNameQuery.cs b/EnvelopeGenerator.Application/Envelopes/Queries/ReceiverName/ReadReceiverNameQuery.cs new file mode 100644 index 00000000..fe114dd8 --- /dev/null +++ b/EnvelopeGenerator.Application/Envelopes/Queries/ReceiverName/ReadReceiverNameQuery.cs @@ -0,0 +1,13 @@ +using EnvelopeGenerator.Application.Receivers.Queries.Read; + +namespace EnvelopeGenerator.Application.Envelopes.Queries.ReceiverName; + +/// +/// Eine Abfrage, um die zuletzt verwendete Anrede eines Empfängers zu ermitteln, +/// damit diese für zukünftige Umschläge wiederverwendet werden kann. +/// +/// Der Umschlag, für den die Anrede des Empfängers ermittelt werden soll. +/// Gibt an, ob nur die zuletzt verwendete Anrede zurückgegeben werden soll. +public record ReadReceiverNameQuery(EnvelopeQuery? Envelope = null, bool OnlyLast = true) : ReadReceiverQuery +{ +} diff --git a/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQuery.cs b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQuery.cs new file mode 100644 index 00000000..2f8ba313 --- /dev/null +++ b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQuery.cs @@ -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; + +/// +/// Repräsentiert eine Abfrage für die Verlaufshistorie eines Umschlags. +/// +/// Die eindeutige Kennung des Umschlags. +/// Die Abfrage, die den Umschlag beschreibt. +/// Die Abfrage, die den Empfänger beschreibt. +/// 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. +/// Abfrage zur Steuerung, ob nur der aktuelle Status oder der gesamte Datensatz zurückgegeben wird. +public record ReadHistoryQuery( + int EnvelopeId, + ReadEnvelopeQuery? Envelope = null, + ReadReceiverQuery? Receiver = null, + Constants.ReferenceType? Related = null, + bool? OnlyLast = true); \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverQuery.cs b/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverQuery.cs new file mode 100644 index 00000000..4e62b083 --- /dev/null +++ b/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverQuery.cs @@ -0,0 +1,10 @@ +namespace EnvelopeGenerator.Application.Receivers.Queries.Read; + +/// +/// Stellt eine Abfrage dar, um die Details eines Empfängers zu lesen. +/// Diese Abfrage erbt von und wird verwendet, +/// um spezifische Informationen über einen Empfänger abzurufen. +/// +public record ReadReceiverQuery : ReceiverQuery +{ +} diff --git a/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverResponse.cs b/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverResponse.cs new file mode 100644 index 00000000..10eb1b87 --- /dev/null +++ b/EnvelopeGenerator.Application/Receivers/Queries/Read/ReadReceiverResponse.cs @@ -0,0 +1,12 @@ +namespace EnvelopeGenerator.Application.Receivers.Queries.Read; + +/// +/// Repräsentiert die Antwort auf eine Abfrage, um einen Empfänger zu lesen. +/// +/// Die eindeutige Identifikationsnummer des Empfängers. +/// Die E-Mail-Adresse des Empfängers. +/// Das Datum und die Uhrzeit, wann der Empfänger hinzugefügt wurde. +/// Die Signatur des Empfängers. +public record ReadReceiverResponse(int Id, string EmailAddress, DateTime AddedWhen, string Signature) +{ +} diff --git a/EnvelopeGenerator.Application/Receivers/ReceiverQuery.cs b/EnvelopeGenerator.Application/Receivers/ReceiverQuery.cs new file mode 100644 index 00000000..a9d90965 --- /dev/null +++ b/EnvelopeGenerator.Application/Receivers/ReceiverQuery.cs @@ -0,0 +1,9 @@ +namespace EnvelopeGenerator.Application.Receivers; + +/// +/// Empfänger des Umschlags +/// +/// ID des Empfängers +/// E-Mail Adresse des Empfängers +/// Eindeutige Signatur des Empfängers +public record ReceiverQuery(int? Id = null, string? EmailAddress = null, string? Signature = null); \ No newline at end of file diff --git a/EnvelopeGenerator.Common/Constants.vb b/EnvelopeGenerator.Common/Constants.vb index 4b3d7a33..8b222b0f 100644 --- a/EnvelopeGenerator.Common/Constants.vb +++ b/EnvelopeGenerator.Common/Constants.vb @@ -32,7 +32,7 @@ 'TODO: standardize in xwiki Public Enum ReferenceType - Receiver + Receiver = 0 Sender System Unknown @@ -94,13 +94,16 @@ End Enum Public Enum EmailTemplateType - DocumentReceived + DocumentReceived = 0 DocumentSigned DocumentDeleted DocumentCompleted DocumentAccessCodeReceived DocumentShared TotpSecret + DocumentRejected_ADM + DocumentRejected_REC + DocumentRejected_REC_2 End Enum Public Enum EncodeType diff --git a/EnvelopeGenerator.Common/Entities/EmailData.vb b/EnvelopeGenerator.Common/Entities/EmailData.vb index 54f115a9..79afc476 100644 --- a/EnvelopeGenerator.Common/Entities/EmailData.vb +++ b/EnvelopeGenerator.Common/Entities/EmailData.vb @@ -31,7 +31,7 @@ Public Class EmailData EmailSubject = String.Empty EmailType = pStatus - Message = pEnvelope.Message + Message = TextToHtml(pEnvelope.Message) ReferenceID = pEnvelope.Id ReferenceString = pEnvelope.Uuid ReceiverName = pReceiver.Name @@ -40,6 +40,22 @@ Public Class EmailData SenderName = pEnvelope.User.FullName EnvelopeTitle = pEnvelope.Title End Sub + Public Function TextToHtml(input As String) As String + If String.IsNullOrEmpty(input) Then Return "" + + ' HTML-Encodierung der Sonderzeichen + Dim encoded As String = System.Net.WebUtility.HtmlEncode(input) + + ' Tabs in   umwandeln (z.B. 4 non-breaking spaces) + encoded = encoded.Replace(vbTab, "    ") + + ' Zeilenumbrüche in
umwandeln + encoded = encoded.Replace(vbCrLf, "
") ' Windows + encoded = encoded.Replace(vbCr, "
") ' Mac alt + encoded = encoded.Replace(vbLf, "
") ' Unix/Linux + + Return encoded + End Function ''' ''' Constructor for sending email to creator diff --git a/EnvelopeGenerator.Common/Models/ReceiverModel.vb b/EnvelopeGenerator.Common/Models/ReceiverModel.vb index d969c415..6630b3ef 100644 --- a/EnvelopeGenerator.Common/Models/ReceiverModel.vb +++ b/EnvelopeGenerator.Common/Models/ReceiverModel.vb @@ -57,7 +57,8 @@ Public Class ReceiverModel Public Function Insert(pReceiver As EnvelopeReceiver, pTransaction As SqlTransaction) As Boolean Try - Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{pReceiver.GetSignature()}'" + Dim oSignature As String = pReceiver.GetSignature() + Dim oCheck = $"SELECT COUNT(GUID) FROM [dbo].[TBSIG_RECEIVER] WHERE SIGNATURE = '{oSignature}'" Dim oExists = Database.GetScalarValue(oCheck) If oExists = 0 Then @@ -77,7 +78,7 @@ Public Class ReceiverModel Return False End If Else - Logger.Warn($"Receiver [{pReceiver.Email}] already existing! Check collecting not existing Receivers!") + Logger.Warn($"Receiver [{pReceiver.Email}] already existing! SignatureID: {oSignature} Check SQL {oCheck}") Return True End If Catch ex As Exception diff --git a/EnvelopeGenerator.Common/Models/UserModel.vb b/EnvelopeGenerator.Common/Models/UserModel.vb index 04f64995..99469b1e 100644 --- a/EnvelopeGenerator.Common/Models/UserModel.vb +++ b/EnvelopeGenerator.Common/Models/UserModel.vb @@ -70,9 +70,9 @@ Public Class UserModel End Try End Function - Public Function SelectUserId() As Integer + Public Function SelectUserId(oUserName As String) As Integer Try - Dim oUserId As Integer = Database.GetScalarValue($"SELECT GUID FROM TBDD_USER WHERE USERNAME = '{Environment.UserName}'") + Dim oUserId As Integer = Database.GetScalarValue($"SELECT GUID FROM TBDD_USER WHERE USERNAME = '{oUserName}'") Return oUserId Catch ex As Exception diff --git a/EnvelopeGenerator.Common/My Project/AssemblyInfo.vb b/EnvelopeGenerator.Common/My Project/AssemblyInfo.vb index cadf8f09..be0af8bd 100644 --- a/EnvelopeGenerator.Common/My Project/AssemblyInfo.vb +++ b/EnvelopeGenerator.Common/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' indem Sie "*" wie unten gezeigt eingeben: ' - - + + diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index 50561806..7827d6d6 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -1,7 +1,7 @@ - net7.0 + net7.0;net8.0;net9.0 enable enable diff --git a/EnvelopeGenerator.Form/EnvelopeGenerator.Form.vbproj b/EnvelopeGenerator.Form/EnvelopeGenerator.Form.vbproj index 2f6c16a4..d499ac6c 100644 --- a/EnvelopeGenerator.Form/EnvelopeGenerator.Form.vbproj +++ b/EnvelopeGenerator.Form/EnvelopeGenerator.Form.vbproj @@ -77,8 +77,8 @@ - - ..\packages\DigitalData.Controls.DocumentViewer.1.9.7\lib\net462\DigitalData.Controls.DocumentViewer.dll + + ..\packages\DigitalData.Controls.DocumentViewer.1.9.8\lib\net462\DigitalData.Controls.DocumentViewer.dll ..\..\2_DLL Projekte\DDMonorepo\GUIs.Common\bin\Debug\DigitalData.GUIs.Common.dll @@ -116,9 +116,6 @@ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll - - ..\packages\EnvelopeGenerator.Common.2.4.2\lib\net462\EnvelopeGenerator.Common.dll - ..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll @@ -186,6 +183,9 @@ ..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.wia.gateway.dll True + + P:\Projekte DIGITAL DATA\DIGITAL DATA - Entwicklung\DLL_Bibliotheken\Limilabs\Mail.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll @@ -337,6 +337,12 @@ Form + + frmGhostMode.vb + + + Form + frmMain.vb @@ -397,6 +403,18 @@ frmFieldEditor.vb Designer + + frmGhostMode.vb + + + frmGhostMode.vb + + + frmGhostMode.vb + + + frmGhostMode.vb + frmMain.vb @@ -464,10 +482,7 @@ - - - PreserveNewest - + @@ -475,6 +490,10 @@ {6EA0C51F-C2B1-4462-8198-3DE0B32B74F8} EnvelopeGenerator.Common + + {6ea0c51f-c2b1-4462-8198-3de0b32b74f8} + EnvelopeGenerator.Common + diff --git a/EnvelopeGenerator.Form/Images/circle.svg b/EnvelopeGenerator.Form/Images/circle.svg deleted file mode 100644 index e0d1b515..00000000 --- a/EnvelopeGenerator.Form/Images/circle.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/EnvelopeGenerator.Form/ModuleSettings.vb b/EnvelopeGenerator.Form/ModuleSettings.vb index 12a3caa6..fa1a810b 100644 --- a/EnvelopeGenerator.Form/ModuleSettings.vb +++ b/EnvelopeGenerator.Form/ModuleSettings.vb @@ -17,4 +17,9 @@ Module ModuleSettings Public SQL_REP_ENV_USER_Y As String = "" Public SQL_REP_ENV_USER_ALL As String = "" Public DT_CHARTS As DataTable + Public MyLogger As Logger + Public USER_GHOST_MODE_USRNAME As String = "" + Public USER_GHOST_MODE_ACTIVE As Boolean = False + Public MyUserModel As UserModel + Public MyState As State End Module diff --git a/EnvelopeGenerator.Form/frmEnvelopeEditor.vb b/EnvelopeGenerator.Form/frmEnvelopeEditor.vb index 0e07e699..c0e90966 100644 --- a/EnvelopeGenerator.Form/frmEnvelopeEditor.vb +++ b/EnvelopeGenerator.Form/frmEnvelopeEditor.vb @@ -122,7 +122,7 @@ Partial Public Class frmEnvelopeEditor Catch ex As Exception MsgBox("File might already be open?", MsgBoxStyle.Exclamation) Me.Cursor = Cursors.Default - Exit Sub + Exit For End Try @@ -421,29 +421,7 @@ Partial Public Class frmEnvelopeEditor MsgBox(Resources.Envelope.Envelope_could_not_be_sent, MsgBoxStyle.Critical, Text) Else If MsgBox(Resources.Envelope.Envelope_Invitations_Sent, MsgBoxStyle.Information Or MsgBoxStyle.OkOnly, Text) = MsgBoxResult.Ok Then - 'If DOCUMENT_PATH_MOVE_AFTSEND <> String.Empty Then - ' If My.Settings.NetUse_PW <> String.Empty And My.Settings.NetUse_Usr <> String.Empty Then - ' Dim oDecrypted = Decryption.Decrypt(My.Settings.NetUse_PW) - ' For Each odoc In Controller.Envelope.Documents 'envelope ist leer! - ' Directory2Delete = "" - ' If CopyFileWithNetUse(odoc.Filepath, DOCUMENT_PATH_MOVE_AFTSEND, My.Settings.NetUse_Usr, My.Settings.NetUse_PW) = False Then - ' BarStaticItem1.Caption = "ERROR while copying files to DMZ! Check Your log!" - ' End If - ' If Directory2Delete <> String.Empty Then - ' Logger.Debug("Now Deleting SourcePath: {0} ...", Directory2Delete) - ' Try - ' System.IO.Directory.Delete(Directory2Delete, True) - ' Logger.Debug("Successfully deleted Sourcepath!") - ' Catch ex As Exception - ' Logger.Warn("Unexpected Error while deleting SourcePath {0}", Directory2Delete) - ' Logger.Warn("ErrorMessage: {0}", ex.Message) - ' End Try - ' End If - ' Next - ' End If - - 'End If Me.Close() End If End If @@ -568,10 +546,6 @@ Partial Public Class frmEnvelopeEditor RibbonPageGroupAddSignature_Enabled() End Sub Dim CellValueChanged As Boolean = False - Private Sub ViewReceivers_ColumnPositionChanged(sender As Object, e As EventArgs) Handles ViewReceivers.ColumnPositionChanged - - - End Sub Private Sub ViewReceivers_CellValueChanged(sender As Object, e As Views.Base.CellValueChangedEventArgs) Handles ViewReceivers.CellValueChanged If e.Column.FieldName = COL_EMAIL And CellValueChanged = False Then @@ -587,17 +561,22 @@ Partial Public Class frmEnvelopeEditor Dim oEmailAdress As String = DirectCast(e.Value.ToString.ToLower, String) oEmailAdress = Trim(oEmailAdress) If IsValidEmailAddress(oEmailAdress) = True Then + Dim oAccessCode As String = "" Dim oLastName As String = Controller.GetLastNameByEmailAdress(oEmailAdress) - Dim oAccessCode As String = Helpers.GetAccessCode() + 'oAccessCode = Helpers.GetAccessCode() Dim oPhoneNumber As String = Controller.GetLastPhoneByEmailAdress(oEmailAdress) ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_EMAIL), oEmailAdress) ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_NAME), oLastName) - ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_CODE), oAccessCode) + CheckAccesscode(e.RowHandle, oAccessCode) + ' ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_CODE), oAccessCode) If Envelope.TFA_Enabled AndAlso DEF_TF_ENABLED_WITH_PHONE Then ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_PHONE), oPhoneNumber) End If + If ViewReceivers.GetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_CODE)) = String.Empty Then + CheckAccesscode(e.RowHandle, oAccessCode) + End If Else - Dim oMsg = Resources.Envelope.Error_email_Validation + Dim oMsg = Resources.Envelope.Error_email_Validation oMsg = oMsg.Replace("@Mail", oEmailAdress) MsgBox(oMsg, MsgBoxStyle.Exclamation, Text) ViewReceivers.DeleteRow(ViewReceivers.FocusedRowHandle) @@ -620,6 +599,12 @@ Partial Public Class frmEnvelopeEditor CellValueChanged = False End If End Sub + Private Function CheckAccesscode(pRowHandle As Integer, pAccessCode As String) As Boolean + If pAccessCode = "" Then + pAccessCode = Helpers.GetAccessCode() + ViewReceivers.SetRowCellValue(pRowHandle, ViewReceivers.Columns.Item(COL_CODE), pAccessCode) + End If + End Function Private Function IsValidEmailAddress(pEmailAddress As String) As Boolean Try If pEmailAddress.Contains("@") Then diff --git a/EnvelopeGenerator.Form/frmFieldEditor.Designer.vb b/EnvelopeGenerator.Form/frmFieldEditor.Designer.vb index 9481a496..d5377e93 100644 --- a/EnvelopeGenerator.Form/frmFieldEditor.Designer.vb +++ b/EnvelopeGenerator.Form/frmFieldEditor.Designer.vb @@ -282,6 +282,7 @@ ' 'frmFieldEditor ' + Me.Appearance.Options.UseFont = True resources.ApplyResources(Me, "$this") Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.Controls.Add(Me.SplitContainerControl1) diff --git a/EnvelopeGenerator.Form/frmFieldEditor.resx b/EnvelopeGenerator.Form/frmFieldEditor.resx index 5eba2d41..5fcb652a 100644 --- a/EnvelopeGenerator.Form/frmFieldEditor.resx +++ b/EnvelopeGenerator.Form/frmFieldEditor.resx @@ -123,7 +123,7 @@ - 0, 132 + 0, 59 Fill @@ -132,7 +132,7 @@ 0, 0 - 199, 526 + 199, 600 @@ -142,7 +142,7 @@ ThumbnailEx2 - GdPicture14.ThumbnailEx, GdPicture.NET.14, Version=14.1.0.152, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb + GdPicture14.ThumbnailEx, GdPicture.NET.14, Version=14.3.3.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb SplitContainerControl1.Panel1 @@ -172,7 +172,7 @@ 0, 0 - 916, 526 + 917, 600 3 @@ -181,7 +181,7 @@ DocumentViewer1 - DigitalData.Controls.DocumentViewer.DocumentViewer, DigitalData.Controls.DocumentViewer, Version=1.9.2.0, Culture=neutral, PublicKeyToken=null + DigitalData.Controls.DocumentViewer.DocumentViewer, DigitalData.Controls.DocumentViewer, Version=1.9.8.0, Culture=neutral, PublicKeyToken=null SplitContainerControl1.Panel2 @@ -205,7 +205,7 @@ 1 - 1125, 526 + 1126, 600 15 @@ -397,7 +397,7 @@ Combo - 1125, 132 + 1126, 88 ribbonControl1 @@ -427,7 +427,7 @@ 0, 0 - 1125, 0 + 1126, 0 barDockControlTop @@ -445,10 +445,10 @@ Bottom - 0, 658 + 0, 659 - 1125, 0 + 1126, 0 barDockControlBottom @@ -469,7 +469,7 @@ 0, 0 - 0, 658 + 0, 659 barDockControlLeft @@ -487,10 +487,10 @@ Right - 1125, 0 + 1126, 0 - 0, 658 + 0, 659 barDockControlRight @@ -511,7 +511,7 @@ 6, 13 - 1125, 658 + 1689, 988 Segoe UI, 8.25pt diff --git a/EnvelopeGenerator.Form/frmGhostMode.Designer.vb b/EnvelopeGenerator.Form/frmGhostMode.Designer.vb new file mode 100644 index 00000000..50ad2c1b --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.Designer.vb @@ -0,0 +1,125 @@ + +Partial Class frmGhostMode + Inherits System.Windows.Forms.Form + + 'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen. + + Protected Overrides Sub Dispose(ByVal disposing As Boolean) + Try + If disposing AndAlso components IsNot Nothing Then + components.Dispose() + End If + Finally + MyBase.Dispose(disposing) + End Try + End Sub + + 'Wird vom Windows Form-Designer benötigt. + Private components As System.ComponentModel.IContainer + + 'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich. + 'Das Bearbeiten ist mit dem Windows Form-Designer möglich. + 'Das Bearbeiten mit dem Code-Editor ist nicht möglich. + + Private Sub InitializeComponent() + Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmGhostMode)) + Me.RibbonControl1 = New DevExpress.XtraBars.Ribbon.RibbonControl() + Me.BarButtonItem1 = New DevExpress.XtraBars.BarButtonItem() + Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage() + Me.RibbonPageGroup1 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup() + Me.RibbonStatusBar1 = New DevExpress.XtraBars.Ribbon.RibbonStatusBar() + Me.GridControl1 = New DevExpress.XtraGrid.GridControl() + Me.GridView1 = New DevExpress.XtraGrid.Views.Grid.GridView() + CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.GridControl1, System.ComponentModel.ISupportInitialize).BeginInit() + CType(Me.GridView1, System.ComponentModel.ISupportInitialize).BeginInit() + Me.SuspendLayout() + ' + 'RibbonControl1 + ' + Me.RibbonControl1.ExpandCollapseItem.Id = 0 + Me.RibbonControl1.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl1.ExpandCollapseItem, Me.RibbonControl1.SearchEditItem, Me.BarButtonItem1}) + resources.ApplyResources(Me.RibbonControl1, "RibbonControl1") + Me.RibbonControl1.MaxItemId = 2 + Me.RibbonControl1.Name = "RibbonControl1" + Me.RibbonControl1.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1}) + Me.RibbonControl1.ShowApplicationButton = DevExpress.Utils.DefaultBoolean.[False] + Me.RibbonControl1.StatusBar = Me.RibbonStatusBar1 + ' + 'BarButtonItem1 + ' + resources.ApplyResources(Me.BarButtonItem1, "BarButtonItem1") + Me.BarButtonItem1.Id = 1 + Me.BarButtonItem1.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem1.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage) + Me.BarButtonItem1.Name = "BarButtonItem1" + ' + 'RibbonPage1 + ' + Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageGroup1}) + Me.RibbonPage1.Name = "RibbonPage1" + resources.ApplyResources(Me.RibbonPage1, "RibbonPage1") + ' + 'RibbonPageGroup1 + ' + Me.RibbonPageGroup1.ItemLinks.Add(Me.BarButtonItem1) + Me.RibbonPageGroup1.Name = "RibbonPageGroup1" + resources.ApplyResources(Me.RibbonPageGroup1, "RibbonPageGroup1") + ' + 'RibbonStatusBar1 + ' + resources.ApplyResources(Me.RibbonStatusBar1, "RibbonStatusBar1") + Me.RibbonStatusBar1.Name = "RibbonStatusBar1" + Me.RibbonStatusBar1.Ribbon = Me.RibbonControl1 + ' + 'GridControl1 + ' + resources.ApplyResources(Me.GridControl1, "GridControl1") + Me.GridControl1.MainView = Me.GridView1 + Me.GridControl1.Name = "GridControl1" + Me.GridControl1.ViewCollection.AddRange(New DevExpress.XtraGrid.Views.Base.BaseView() {Me.GridView1}) + ' + 'GridView1 + ' + Me.GridView1.Appearance.EvenRow.BackColor = System.Drawing.Color.LightBlue + Me.GridView1.Appearance.EvenRow.Options.UseBackColor = True + Me.GridView1.GridControl = Me.GridControl1 + Me.GridView1.Name = "GridView1" + Me.GridView1.OptionsBehavior.AllowAddRows = DevExpress.Utils.DefaultBoolean.[False] + Me.GridView1.OptionsBehavior.AllowDeleteRows = DevExpress.Utils.DefaultBoolean.[False] + Me.GridView1.OptionsBehavior.AllowFixedGroups = DevExpress.Utils.DefaultBoolean.[True] + Me.GridView1.OptionsBehavior.AllowGroupExpandAnimation = DevExpress.Utils.DefaultBoolean.[True] + Me.GridView1.OptionsBehavior.Editable = False + Me.GridView1.OptionsClipboard.CopyColumnHeaders = DevExpress.Utils.DefaultBoolean.[False] + Me.GridView1.OptionsView.ColumnAutoWidth = False + Me.GridView1.OptionsView.EnableAppearanceEvenRow = True + Me.GridView1.OptionsView.ShowAutoFilterRow = True + Me.GridView1.OptionsView.ShowErrorPanel = DevExpress.Utils.DefaultBoolean.[True] + Me.GridView1.OptionsView.ShowViewCaption = True + resources.ApplyResources(Me.GridView1, "GridView1") + ' + 'frmGhostMode + ' + resources.ApplyResources(Me, "$this") + Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font + Me.Controls.Add(Me.GridControl1) + Me.Controls.Add(Me.RibbonStatusBar1) + Me.Controls.Add(Me.RibbonControl1) + Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow + Me.Name = "frmGhostMode" + Me.TopMost = True + CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.GridControl1, System.ComponentModel.ISupportInitialize).EndInit() + CType(Me.GridView1, System.ComponentModel.ISupportInitialize).EndInit() + Me.ResumeLayout(False) + Me.PerformLayout() + + End Sub + + Friend WithEvents RibbonControl1 As DevExpress.XtraBars.Ribbon.RibbonControl + Friend WithEvents RibbonPage1 As DevExpress.XtraBars.Ribbon.RibbonPage + Friend WithEvents RibbonPageGroup1 As DevExpress.XtraBars.Ribbon.RibbonPageGroup + Friend WithEvents RibbonStatusBar1 As DevExpress.XtraBars.Ribbon.RibbonStatusBar + Friend WithEvents BarButtonItem1 As DevExpress.XtraBars.BarButtonItem + Friend WithEvents GridControl1 As DevExpress.XtraGrid.GridControl + Friend WithEvents GridView1 As DevExpress.XtraGrid.Views.Grid.GridView +End Class diff --git a/EnvelopeGenerator.Form/frmGhostMode.en-US.resx b/EnvelopeGenerator.Form/frmGhostMode.en-US.resx new file mode 100644 index 00000000..08655b78 --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.en-US.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Activate ghost mode + + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40 + LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl + dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAAIEAAAC77u/ + PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi + IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv + MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh + Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg + MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z + ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5HcmVlbntmaWxsOiMwMzlD + MjM7fQoJLkJsYWNre2ZpbGw6IzcyNzI3Mjt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh + Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntkaXNwbGF5Om5vbmU7fQoJLnN0M3tk + aXNwbGF5OmlubGluZTtmaWxsOiNGRkIxMTU7fQoJLnN0NHtkaXNwbGF5OmlubGluZTt9Cgkuc3Q1e2Rp + c3BsYXk6aW5saW5lO29wYWNpdHk6MC43NTt9Cgkuc3Q2e2Rpc3BsYXk6aW5saW5lO29wYWNpdHk6MC41 + O30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMDM5QzIzO30KCS5zdDh7ZGlzcGxheTppbmxpbmU7 + ZmlsbDojRDExQzFDO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7ZmlsbDojMTE3N0Q3O30KCS5zdDEwe2Rp + c3BsYXk6aW5saW5lO2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+DQogIDxnIGlkPSJSb2xlIj4NCiAgICA8 + cGF0aCBkPSJNNCwydjE2YzAsNi42LDUuNCwxMiwxMiwxMnMxMi01LjQsMTItMTJWMkg0eiBNMTEsOWMx + LjcsMCwzLDEuMywzLDNIOEM4LDEwLjMsOS4zLDksMTEsOXogTTE2LDI0ICAgYy0zLjMsMC02LTIuNy02 + LTZjMCwxLjEsMi43LDIsNiwyczYtMC45LDYtMkMyMiwyMS4zLDE5LjMsMjQsMTYsMjR6IE0xOCwxMmMw + LTEuNywxLjMtMywzLTNzMywxLjMsMywzSDE4eiIgY2xhc3M9IlllbGxvdyIgLz4NCiAgPC9nPg0KPC9z + dmc+Cw== + + + + Actions + + + + 965, 146 + + + 0, 146 + + + Please choose a ghost user + + + 965, 341 + + \ No newline at end of file diff --git a/EnvelopeGenerator.Form/frmGhostMode.en.resx b/EnvelopeGenerator.Form/frmGhostMode.en.resx new file mode 100644 index 00000000..dfaf29a7 --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.en.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Actions + + + Please select a ghost user + + + Activate ghost mode + + + Start + + \ No newline at end of file diff --git a/EnvelopeGenerator.Form/frmGhostMode.fr.resx b/EnvelopeGenerator.Form/frmGhostMode.fr.resx new file mode 100644 index 00000000..bcbe5cd4 --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.fr.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Actions + + + Veuillez sélectionner un utilisateur fantôme + + + Activer le Mode Fantôme + + + Démarrer + + \ No newline at end of file diff --git a/EnvelopeGenerator.Form/frmGhostMode.resx b/EnvelopeGenerator.Form/frmGhostMode.resx new file mode 100644 index 00000000..86b5d401 --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ghost Modus aktivieren + + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40 + LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl + dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAAIEAAAC77u/ + PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi + IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv + MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh + Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg + MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z + ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5HcmVlbntmaWxsOiMwMzlD + MjM7fQoJLkJsYWNre2ZpbGw6IzcyNzI3Mjt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh + Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntkaXNwbGF5Om5vbmU7fQoJLnN0M3tk + aXNwbGF5OmlubGluZTtmaWxsOiNGRkIxMTU7fQoJLnN0NHtkaXNwbGF5OmlubGluZTt9Cgkuc3Q1e2Rp + c3BsYXk6aW5saW5lO29wYWNpdHk6MC43NTt9Cgkuc3Q2e2Rpc3BsYXk6aW5saW5lO29wYWNpdHk6MC41 + O30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMDM5QzIzO30KCS5zdDh7ZGlzcGxheTppbmxpbmU7 + ZmlsbDojRDExQzFDO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7ZmlsbDojMTE3N0Q3O30KCS5zdDEwe2Rp + c3BsYXk6aW5saW5lO2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+DQogIDxnIGlkPSJSb2xlIj4NCiAgICA8 + cGF0aCBkPSJNNCwydjE2YzAsNi42LDUuNCwxMiwxMiwxMnMxMi01LjQsMTItMTJWMkg0eiBNMTEsOWMx + LjcsMCwzLDEuMywzLDNIOEM4LDEwLjMsOS4zLDksMTEsOXogTTE2LDI0ICAgYy0zLjMsMC02LTIuNy02 + LTZjMCwxLjEsMi43LDIsNiwyczYtMC45LDYtMkMyMiwyMS4zLDE5LjMsMjQsMTYsMjR6IE0xOCwxMmMw + LTEuNywxLjMtMywzLTNzMywxLjMsMywzSDE4eiIgY2xhc3M9IlllbGxvdyIgLz4NCiAgPC9nPg0KPC9z + dmc+Cw== + + + + + 0, 0 + + + Aktionen + + + Start + + + 965, 146 + + + 0, 487 + + + 965, 22 + + + RibbonStatusBar1 + + + DevExpress.XtraBars.Ribbon.RibbonStatusBar, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + $this + + + 1 + + + RibbonControl1 + + + DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + $this + + + 2 + + + + Fill + + + 0, 146 + + + Bitte wählen Sie einen Ghost User + + + 965, 341 + + + + 9 + + + GridControl1 + + + DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + $this + + + 0 + + + True + + + 6, 13 + + + 965, 509 + + + Calibri, 8.25pt + + + CenterParent + + + BarButtonItem1 + + + DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + RibbonPage1 + + + DevExpress.XtraBars.Ribbon.RibbonPage, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + RibbonPageGroup1 + + + DevExpress.XtraBars.Ribbon.RibbonPageGroup, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + GridView1 + + + DevExpress.XtraGrid.Views.Grid.GridView, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + + frmGhostMode + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/EnvelopeGenerator.Form/frmGhostMode.vb b/EnvelopeGenerator.Form/frmGhostMode.vb new file mode 100644 index 00000000..04bcb107 --- /dev/null +++ b/EnvelopeGenerator.Form/frmGhostMode.vb @@ -0,0 +1,59 @@ +Public Class frmGhostMode + Private Sub frmGhostMode_Load(sender As Object, e As EventArgs) Handles Me.Load + Dim oSQL = "SELECT T.USERNAME,T.NAME, T.[PRENAME],T.EMAIL FROM TBDD_USER T ORDER BY USERNAME" + Dim DT_USER = DB_DD_ECM.GetDatatable(oSQL) + + Try + If Not IsNothing(DT_USER) Then + GridControl1.DataSource = DT_USER + MyLogger.Info($"Received [{DT_USER.Rows.Count}] Ghost-Users to select!") + End If + + + Catch ex As Exception + MsgBox("Error Load_Users:" & vbNewLine & ex.Message) + End Try + End Sub + + Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick + + Set_GhostUser() + End Sub + + Private Sub GridView1_DoubleClick(sender As Object, e As EventArgs) Handles GridView1.DoubleClick + Set_GhostUser() + End Sub + + Sub Set_GhostUser() + Dim oFocusedUserName + Try + oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("UserName")) + If IsNothing(oFocusedUserName) Then + oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USERNAME")) + End If + If IsNothing(oFocusedUserName) Then + oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USER_NAME")) + End If + If IsNothing(oFocusedUserName) Then + oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USER")) + End If + Catch ex As Exception + oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("UserName")) + If IsNothing(oFocusedUserName) Then + MsgBox(ex.Message, MsgBoxStyle.Critical) + Exit Sub + End If + End Try + If oFocusedUserName <> String.Empty Then + Dim result As MsgBoxResult = MsgBox("Do You really want to activate the Ghost-Mode?", MsgBoxStyle.YesNo, "") + 'wenn Speichern ja + If result = MsgBoxResult.Yes Then + USER_GHOST_MODE_USRNAME = oFocusedUserName + USER_GHOST_MODE_ACTIVE = True + Me.Close() + End If + Else + MsgBox("Please choose an user for ghostmode!", MsgBoxStyle.Information) + End If + End Sub +End Class \ No newline at end of file diff --git a/EnvelopeGenerator.Form/frmMain.Designer.vb b/EnvelopeGenerator.Form/frmMain.Designer.vb index 7d92b57f..e5262c8c 100644 --- a/EnvelopeGenerator.Form/frmMain.Designer.vb +++ b/EnvelopeGenerator.Form/frmMain.Designer.vb @@ -102,6 +102,7 @@ Partial Class frmMain Me.RefreshTimer = New System.Windows.Forms.Timer(Me.components) Me.SaveFileDialog1 = New System.Windows.Forms.SaveFileDialog() Me.XtraSaveFileDialog1 = New DevExpress.XtraEditors.XtraSaveFileDialog(Me.components) + Me.BarStaticItemGhost = New DevExpress.XtraBars.BarStaticItem() CType(Me.SplitContainerControl1, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.SplitContainerControl1.Panel1, System.ComponentModel.ISupportInitialize).BeginInit() Me.SplitContainerControl1.Panel1.SuspendLayout() @@ -321,9 +322,9 @@ Partial Class frmMain Me.RibbonControl.ExpandCollapseItem.Id = 0 Me.RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.ImageIndex"), Integer) Me.RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex = CType(resources.GetObject("RibbonControl.ExpandCollapseItem.ImageOptions.LargeImageIndex"), Integer) - Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.btnCreateEnvelope, Me.btnEditEnvelope, Me.btnDeleteEnvelope, Me.BarButtonItem1, Me.txtRefreshLabel, Me.btnShowDocument, Me.btnContactReceiver, Me.txtEnvelopeIdLabel, Me.btnOpenLogDirectory, Me.BarCheckItem1, Me.bsitmInfo, Me.bbtnitmEB, Me.bbtnitmInfoMail, Me.BarButtonItem2, Me.BarButtonItem3, Me.BarButtonItem4}) + Me.RibbonControl.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl.ExpandCollapseItem, Me.RibbonControl.SearchEditItem, Me.btnCreateEnvelope, Me.btnEditEnvelope, Me.btnDeleteEnvelope, Me.BarButtonItem1, Me.txtRefreshLabel, Me.btnShowDocument, Me.btnContactReceiver, Me.txtEnvelopeIdLabel, Me.btnOpenLogDirectory, Me.BarCheckItem1, Me.bsitmInfo, Me.bbtnitmEB, Me.bbtnitmInfoMail, Me.BarButtonItem2, Me.BarButtonItem3, Me.BarButtonItem4, Me.BarStaticItemGhost}) resources.ApplyResources(Me.RibbonControl, "RibbonControl") - Me.RibbonControl.MaxItemId = 19 + Me.RibbonControl.MaxItemId = 20 Me.RibbonControl.Name = "RibbonControl" Me.RibbonControl.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1, Me.RibbonPage2}) Me.RibbonControl.ShowApplicationButton = DevExpress.Utils.DefaultBoolean.[False] @@ -515,6 +516,7 @@ Partial Class frmMain ' 'RibbonStatusBar ' + Me.RibbonStatusBar.ItemLinks.Add(Me.BarStaticItemGhost) Me.RibbonStatusBar.ItemLinks.Add(Me.txtRefreshLabel) Me.RibbonStatusBar.ItemLinks.Add(Me.txtEnvelopeIdLabel) Me.RibbonStatusBar.ItemLinks.Add(Me.bsitmInfo) @@ -753,6 +755,19 @@ Partial Class frmMain ' Me.XtraSaveFileDialog1.FileName = "XtraSaveFileDialog1" ' + 'BarStaticItemGhost + ' + resources.ApplyResources(Me.BarStaticItemGhost, "BarStaticItemGhost") + Me.BarStaticItemGhost.Id = 19 + Me.BarStaticItemGhost.ItemAppearance.Normal.BackColor = System.Drawing.Color.Yellow + Me.BarStaticItemGhost.ItemAppearance.Normal.Font = CType(resources.GetObject("BarStaticItemGhost.ItemAppearance.Normal.Font"), System.Drawing.Font) + Me.BarStaticItemGhost.ItemAppearance.Normal.ForeColor = System.Drawing.Color.Black + Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseBackColor = True + Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseFont = True + Me.BarStaticItemGhost.ItemAppearance.Normal.Options.UseForeColor = True + Me.BarStaticItemGhost.Name = "BarStaticItemGhost" + Me.BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Never + ' 'frmMain ' resources.ApplyResources(Me, "$this") @@ -878,4 +893,5 @@ Partial Class frmMain Friend WithEvents XtraSaveFileDialog1 As DevExpress.XtraEditors.XtraSaveFileDialog Friend WithEvents RibbonPageGroupFunctions As DevExpress.XtraBars.Ribbon.RibbonPageGroup Friend WithEvents BarButtonItem4 As DevExpress.XtraBars.BarButtonItem + Friend WithEvents BarStaticItemGhost As DevExpress.XtraBars.BarStaticItem End Class diff --git a/EnvelopeGenerator.Form/frmMain.resx b/EnvelopeGenerator.Form/frmMain.resx index c83fef0d..8d2b9ef6 100644 --- a/EnvelopeGenerator.Form/frmMain.resx +++ b/EnvelopeGenerator.Form/frmMain.resx @@ -123,7 +123,7 @@ - 0, 160 + 0, 158 Fill @@ -850,6 +850,12 @@ R3JlZW4iIC8+DQogIDwvZz4NCjwvc3ZnPgs= + + GhostMode active + + + Tahoma, 8.25pt, style=Bold + 0, 0 @@ -872,7 +878,7 @@ Einstellungen - 1090, 160 + 1090, 158 0, 660 @@ -905,7 +911,7 @@ 2 - 1088, 467 + 1088, 469 2 @@ -923,7 +929,7 @@ 0 - 1088, 467 + 1088, 469 Offene Umschläge @@ -941,7 +947,7 @@ 0 - 1090, 490 + 1090, 492 3 @@ -1202,7 +1208,7 @@ 17, 37 - 131, 13 + 120, 13 0 @@ -1451,7 +1457,7 @@ 1 - 1090, 500 + 1090, 502 5 @@ -1469,16 +1475,16 @@ 0 - 17, 54 + 193, 17 - 17, 91 + 316, 17 PDF Files|*.pdf - 17, 128 + 452, 17 True @@ -1927,6 +1933,12 @@ DevExpress.XtraEditors.XtraSaveFileDialog, DevExpress.XtraDialogs.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + + BarStaticItemGhost + + + DevExpress.XtraBars.BarStaticItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a + frmMain diff --git a/EnvelopeGenerator.Form/frmMain.vb b/EnvelopeGenerator.Form/frmMain.vb index 31b22f28..5e3cf9cf 100644 --- a/EnvelopeGenerator.Form/frmMain.vb +++ b/EnvelopeGenerator.Form/frmMain.vb @@ -512,6 +512,21 @@ Public Class frmMain End If bbtnitmEB.Enabled = False RefreshTimer.Start() + If USER_GHOST_MODE_ACTIVE Then + frmGhostMode.ShowDialog() + If USER_GHOST_MODE_USRNAME <> "" Then + MyUserModel = New UserModel(MyState) + MyState.UserId = MyUserModel.SelectUserId(USER_GHOST_MODE_USRNAME) + Dim oUser = MyUserModel.SelectUser() + If oUser IsNot Nothing Then + MyUserModel.CheckUserLogin(oUser) + BarStaticItemGhost.Caption = $"GhostMode active: {USER_GHOST_MODE_USRNAME} - End signFLOW to quit mode" + BarStaticItemGhost.Visibility = DevExpress.XtraBars.BarItemVisibility.Always + LoadEnvelopeData() + End If + MYUSER = oUser + End If + End If End Sub Private Sub bbtnitmInfoMail_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitmInfoMail.ItemClick diff --git a/EnvelopeGenerator.Form/frmSplashScreen.Designer.vb b/EnvelopeGenerator.Form/frmSplashScreen.Designer.vb index 21d62435..bee7ff51 100644 --- a/EnvelopeGenerator.Form/frmSplashScreen.Designer.vb +++ b/EnvelopeGenerator.Form/frmSplashScreen.Designer.vb @@ -28,6 +28,7 @@ Partial Class frmSplashScreen Me.lblVersion = New System.Windows.Forms.Label() Me.pbStatus = New System.Windows.Forms.ProgressBar() Me.lblStatus = New System.Windows.Forms.Label() + Me.lblGhostMode = New DevExpress.XtraEditors.LabelControl() CType(Me.PictureEdit1.Properties, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' @@ -88,17 +89,30 @@ Partial Class frmSplashScreen Me.lblStatus.Text = "{Status}" Me.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter ' + 'lblGhostMode + ' + Me.lblGhostMode.Appearance.BackColor = System.Drawing.Color.Yellow + Me.lblGhostMode.Appearance.Options.UseBackColor = True + Me.lblGhostMode.Location = New System.Drawing.Point(654, 243) + Me.lblGhostMode.Name = "lblGhostMode" + Me.lblGhostMode.Size = New System.Drawing.Size(92, 13) + Me.lblGhostMode.TabIndex = 10 + Me.lblGhostMode.Text = "GhostModus active" + Me.lblGhostMode.Visible = False + ' 'frmSplashScreen ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(800, 303) + Me.Controls.Add(Me.lblGhostMode) Me.Controls.Add(Me.lblCopyright) Me.Controls.Add(Me.lblVersion) Me.Controls.Add(Me.lblStatus) Me.Controls.Add(Me.pbStatus) Me.Controls.Add(Me.PictureEdit1) Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None + Me.KeyPreview = True Me.Name = "frmSplashScreen" Me.ShowIcon = False Me.ShowInTaskbar = False @@ -115,4 +129,5 @@ Partial Class frmSplashScreen Friend WithEvents lblVersion As Label Friend WithEvents pbStatus As ProgressBar Friend WithEvents lblStatus As Label + Friend WithEvents lblGhostMode As DevExpress.XtraEditors.LabelControl End Class diff --git a/EnvelopeGenerator.Form/frmSplashScreen.resx b/EnvelopeGenerator.Form/frmSplashScreen.resx index 8487129c..3b8d22e1 100644 --- a/EnvelopeGenerator.Form/frmSplashScreen.resx +++ b/EnvelopeGenerator.Form/frmSplashScreen.resx @@ -121,7 +121,7 @@ iVBORw0KGgoAAAANSUhEUgAAAyAAAADICAYAAAAQj4UaAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL - DwAACw8BkvkDpQAASudJREFUeF7tvWusZNd5nukfcpSOmmre3Wp2s3lrdpNUk01RPxIk6iBBIjFxMBPZ + DQAACw0B7QfALAAASudJREFUeF7tvWusZNd5nukfcpSOmmre3Wp2s3lrdpNUk01RPxIk6iBBIjFxMBPZ DGxLEyB2M8ggkegAsSRElikHEsnBJFZrRjZtxZIpZaIZRy2AloGxrAHIRKIQRIqVGJ6AsJEAAwgDOzNJ HCBSLsqfynmq+HV9tepd+1KnLnufen88OKf2rfa67HPed3/rW+t7PnffoxNjjDHGGLNb/n4L/9t9l6b8 vXsX+ewBn1ngkSkvCH79hy9NXr5yafKbz1yavHr10uRfv/jo5Pe//Ohk8uoMfmcb+ziGYznnc4/q663C diff --git a/EnvelopeGenerator.Form/frmSplashScreen.vb b/EnvelopeGenerator.Form/frmSplashScreen.vb index fd957a63..e8545a40 100644 --- a/EnvelopeGenerator.Form/frmSplashScreen.vb +++ b/EnvelopeGenerator.Form/frmSplashScreen.vb @@ -25,7 +25,7 @@ Public Class frmSplashScreen Dim oLogPath = IO.Path.Combine(Application.LocalUserAppDataPath, "Log") CurrLogConfig = New LogConfig(LogConfig.PathType.CustomPath, oLogPath, CompanyName:="Digital Data", ProductName:="Envelope Generator") Logger = CurrLogConfig.GetLogger() - + MyLogger = Logger Try ConfigManager = New ConfigManager(Of Config)(CurrLogConfig, Application.UserAppDataPath, Application.CommonAppDataPath, Application.StartupPath) @@ -60,25 +60,25 @@ Public Class frmSplashScreen End Sub Private Sub Worker_DoWork(sender As Object, e As DoWorkEventArgs) Handles Worker.DoWork - Dim oState As State = DirectCast(e.Argument, State) + MyState = DirectCast(e.Argument, State) Worker.ReportProgress(20, "Initializing Database") Thread.Sleep(300) - Dim oConnectionString = MSSQLServer.DecryptConnectionString(oState.Config.ConnectionString) - oState.Database = New MSSQLServer(oState.LogConfig, oConnectionString) + Dim oConnectionString = MSSQLServer.DecryptConnectionString(MyState.Config.ConnectionString) + MyState.Database = New MSSQLServer(MyState.LogConfig, oConnectionString) - If oState.Database?.DBInitialized = False Then + If MyState.Database?.DBInitialized = False Then Throw New ApplicationException("Could not connect to the database. Application will close!") Else - DB_DD_ECM = oState.Database + DB_DD_ECM = MyState.Database End If Worker.ReportProgress(40, "Initializing Configuration") Thread.Sleep(300) Dim oSQl = "SELECT * FROM TBDD_SQL_COMMANDS" - Dim oDT = oState.Database.GetDatatable(oSQl) + Dim oDT = MyState.Database.GetDatatable(oSQl) For Each oROW As DataRow In oDT.Rows If oROW.Item("TITLE") = "REPORT ENV USER THIS_MONTH" Then SQL_REP_ENV_USER_TM = oROW.Item("SQL_COMMAND") @@ -92,39 +92,39 @@ Public Class frmSplashScreen Next oSQl = "SELECT * FROM TBSIG_CHART" - DT_CHARTS = oState.Database.GetDatatable(oSQl) + DT_CHARTS = MyState.Database.GetDatatable(oSQl) - Dim ConfigModel = New ConfigModel(oState) - oState.DbConfig = ConfigModel.LoadConfiguration() - DEF_TF_ENABLED = oState.DbConfig.Default_TFA_Enabled - DEF_TF_ENABLED_WITH_PHONE = oState.DbConfig.Default_TFA_WithPhone + Dim ConfigModel = New ConfigModel(MyState) + MyState.DbConfig = ConfigModel.LoadConfiguration() + DEF_TF_ENABLED = MyState.DbConfig.Default_TFA_Enabled + DEF_TF_ENABLED_WITH_PHONE = MyState.DbConfig.Default_TFA_WithPhone ' DOCUMENT_PATH_MOVE_AFTSEND = oState.DbConfig.DOCUMENT_PATH_MOVE_AFTSEND Worker.ReportProgress(60, "Initializing User") - Dim oKey = oState.Database.GetScalarValue("SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE' and ACTIVE = 1") - Thread.Sleep(300) + Dim oKey = MyState.Database.GetScalarValue("SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE' and ACTIVE = 1") + Thread.Sleep(300) If oKey.ToString <> String.Empty Then MS_GDPICTUREKEY = oKey End If - Dim oUserModel = New UserModel(oState) - oState.UserId = oUserModel.SelectUserId() + MyUserModel = New UserModel(MyState) + MyState.UserId = MyUserModel.SelectUserId(Environment.UserName) - Dim oUser = oUserModel.SelectUser() + Dim oUser = MyUserModel.SelectUser() Worker.ReportProgress(80, "Initializing Rights") Thread.Sleep(300) ' This checks for module access and admin rights If oUser IsNot Nothing Then - oUserModel.CheckUserLogin(oUser) + MyUserModel.CheckUserLogin(oUser) End If MYUSER = oUser Worker.ReportProgress(100, "Starting Application") Thread.Sleep(300) - oState.User = oUser + MyState.User = oUser - e.Result = oState + e.Result = MyState End Sub Private Sub Worker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles Worker.ProgressChanged @@ -174,4 +174,14 @@ Public Class frmSplashScreen End Try End Sub + Private Sub frmSplashScreen_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown + If Not IsNothing(MYUSER) Then + If MYUSER.IsAdmin Then + If e.KeyCode = Keys.Escape Then + USER_GHOST_MODE_ACTIVE = True + lblGhostMode.Visible = True + End If + End If + End If + End Sub End Class \ No newline at end of file diff --git a/EnvelopeGenerator.Form/packages.config b/EnvelopeGenerator.Form/packages.config index ee5069d7..2b9ea36e 100644 --- a/EnvelopeGenerator.Form/packages.config +++ b/EnvelopeGenerator.Form/packages.config @@ -1,7 +1,7 @@  - + @@ -12,7 +12,6 @@ - diff --git a/EnvelopeGenerator.GeneratorAPI/.config/dotnet-tools.json b/EnvelopeGenerator.GeneratorAPI/.config/dotnet-tools.json new file mode 100644 index 00000000..0280531d --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "9.0.3", + "commands": [ + "dotnet-ef" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs index 8d790429..5ce1ce7a 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs @@ -7,17 +7,27 @@ using Microsoft.AspNetCore.Mvc; using System.Security.Claims; using DigitalData.UserManager.Application.DTOs.Auth; using Microsoft.AspNetCore.Authorization; +using EnvelopeGenerator.GeneratorAPI.Models; namespace EnvelopeGenerator.GeneratorAPI.Controllers { + /// + /// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus. + /// [Route("api/[controller]")] [ApiController] - public class AuthController : ControllerBase + public partial class AuthController : ControllerBase { private readonly ILogger _logger; private readonly IUserService _userService; private readonly IDirectorySearchService _dirSearchService; + /// + /// Initializes a new instance of the class. + /// + /// The logger instance. + /// The user service instance. + /// The directory search service instance. public AuthController(ILogger logger, IUserService userService, IDirectorySearchService dirSearchService) { _logger = logger; @@ -25,10 +35,37 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers _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") + /// + /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben. + /// + /// Benutzeranmeldedaten (Benutzername und Passwort). + /// Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet. + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth?cookie=true + /// { + /// "username": "MaxMustermann", + /// "password": "Geheim123!" + /// } + /// + /// POST /api/auth?cookie=true + /// { + /// "id": "1", + /// "password": "Geheim123!" + /// } + /// + /// + /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. + /// Unbefugt. Ungültiger Benutzername oder Passwort. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [AllowAnonymous] - [HttpPost("login")] - public async Task Login([FromBody] LogInDto login) + [HttpPost] + public async Task Login([FromBody] Login login, [FromQuery] bool cookie = false) { try { @@ -48,13 +85,13 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers // Create claims var claims = new List - { - new (ClaimTypes.NameIdentifier, user.Id.ToString()), - new (ClaimTypes.Name, user.Username), - new (ClaimTypes.Surname, user.Name!), - new (ClaimTypes.GivenName, user.Prename!), - new (ClaimTypes.Email, user.Email!), - }; + { + new (ClaimTypes.NameIdentifier, user.Id.ToString()), + new (ClaimTypes.Name, user.Username), + new (ClaimTypes.Surname, user.Name!), + new (ClaimTypes.GivenName, user.Prename!), + new (ClaimTypes.Email, user.Email!), + }; // Create claimsIdentity var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); @@ -75,13 +112,58 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers return Ok(); } - catch(Exception ex) + catch (Exception ex) { _logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message); return StatusCode(StatusCodes.Status500InternalServerError); } } + /// + /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben. + /// + /// Benutzeranmeldedaten (Benutzername und Passwort). + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth/form + /// { + /// "username": "MaxMustermann", + /// "password": "Geheim123!" + /// } + /// + /// + /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. + /// Unbefugt. Ungültiger Benutzername oder Passwort. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [AllowAnonymous] + [HttpPost] + [Route("form")] + public async Task Login([FromForm] Login login) + { + return await Login(login, true); + } + + /// + /// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie) + /// + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth/logout + /// + /// + /// Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat. + /// Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [Authorize] [HttpPost("logout")] public async Task Logout() @@ -98,8 +180,22 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers } } - [AllowAnonymous] - [HttpGet("check")] - public IActionResult IsAuthenticated() => Ok(User.Identity?.IsAuthenticated ?? false); + /// + /// Prüft, ob der Benutzer ein autorisiertes Token hat. + /// + /// Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401 + /// + /// Sample request: + /// + /// GET /api/auth + /// + /// + /// Wenn es einen autorisierten Cookie gibt. + /// Wenn kein Cookie vorhanden ist oder nicht autorisierte. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [Authorize] + [HttpGet] + public IActionResult IsAuthenticated() => Ok(); } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EmailTemplateController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EmailTemplateController.cs new file mode 100644 index 00000000..fa4fb84a --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EmailTemplateController.cs @@ -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; + +/// +/// Controller for managing email templates. +/// Steuerung zur Verwaltung von E-Mail-Vorlagen. +/// +[Route("api/[controller]")] +[ApiController] +[Authorize] +public class EmailTemplateController : ControllerBase +{ + private readonly IMapper _mapper; + + /// + /// Initialisiert eine neue Instanz der -Klasse. + /// + /// + /// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird. + /// + public EmailTemplateController(IMapper mapper) + { + _mapper = mapper; + } + + /// + /// Ruft E-Mail-Vorlagen basierend auf der angegebenen Abfrage ab. + /// Gibt alles zurück, wenn keine Id- oder Typ-Informationen eingegeben wurden. + /// + /// Die Abfrageparameter zum Abrufen von E-Mail-Vorlagen. + /// Gibt HTTP-Antwort zurück + /// + /// Sample request: + /// GET /api/EmailTemplate?emailTemplateId=123 + /// + /// Wenn die E-Mail-Vorlagen erfolgreich abgerufen werden. + /// Wenn die Abfrageparameter ungültig sind. + /// Wenn der Benutzer nicht authentifiziert ist. + /// Wenn die gesuchte Abfrage nicht gefunden wird. + [HttpGet] + public IActionResult Get([FromQuery] ReadEmailTemplateQuery? emailTemplate = null) + { + // Implementation logic here + return Ok(); // Placeholder for actual implementation + } + + /// + /// 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. + /// + /// Die E-Mail-Vorlagenabfrage. + /// Der Aktualisierungsbefehl für die E-Mail-Vorlage. + /// Wird auf Standardwert aktualisiert, wenn die Anfrage ohne http-Body gesendet wird. + /// + /// Gibt HTTP-Antwort zurück + /// + /// Sample request: + /// PUT /api/EmailTemplate + /// { + /// "emailTemplateId": 123, + /// "newContent": "Updated content" + /// } + /// + /// Wenn die E-Mail-Vorlage erfolgreich aktualisiert oder zurückgesetzt wird. + /// Wenn die Abfrage ohne einen String gesendet wird. + /// Wenn der Benutzer nicht authentifiziert ist. + /// Wenn die gesuchte Abfrage nicht gefunden wird. + [HttpPut] + public IActionResult Update([FromQuery] EmailTemplateQuery email, [FromBody] UpdateEmailTemplateCommand? update = null) + { + if (update is null) + { + var reset = _mapper.Map(email); + // Logic for resetting the email template + } + else + { + update.EmailTemplateQuery = email; + // Logic for updating the email template + } + + return Ok(); // Placeholder for actual implementation + } +} diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs index a7835d66..049c0186 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs @@ -1,52 +1,78 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts.Services; +using EnvelopeGenerator.Application.Envelopes.Queries.Read; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace EnvelopeGenerator.GeneratorAPI.Controllers +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Dieser Controller stellt Endpunkte für die Verwaltung von Umschlägen bereit. +/// +/// +/// 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. +/// +[Route("api/[controller]")] +[ApiController] +[Authorize] +public class EnvelopeController : ControllerBase { - [Route("api/[controller]")] - [ApiController] - [Authorize] - public class EnvelopeController : ControllerBase + private readonly ILogger _logger; + private readonly IEnvelopeService _envelopeService; + + /// + /// Erstellt eine neue Instanz des EnvelopeControllers. + /// + /// Der Logger, der für das Protokollieren von Informationen verwendet wird. + /// Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist. + public EnvelopeController(ILogger logger, IEnvelopeService envelopeService) { - private readonly ILogger _logger; - private readonly IEnvelopeService _envelopeService; + _logger = logger; + _envelopeService = envelopeService; + } - public EnvelopeController(ILogger logger, IEnvelopeService envelopeService) + /// + /// Ruft eine Liste von Umschlägen basierend auf dem Benutzer und den angegebenen Statusfiltern ab. + /// + /// + /// Eine IActionResult-Instanz, die die abgerufenen Umschläge oder einen Fehlerstatus enthält. + /// Die Anfrage war erfolgreich, und die Umschläge werden zurückgegeben. + /// Die Anfrage war fehlerhaft oder unvollständig. + /// Der Benutzer ist nicht authentifiziert. + /// Der Benutzer hat keine Berechtigung, auf die Ressource zuzugreifen. + /// Ein unerwarteter Fehler ist aufgetreten. + [Authorize] + [HttpGet] + public async Task GetAsync([FromQuery] ReadEnvelopeQuery envelope) + { + try { - _logger = logger; - _envelopeService = envelopeService; - } - - [Authorize] - [HttpGet] - public async Task GetCurrentAsync( - [FromQuery] int? min_status = null, - [FromQuery] int? max_status = null, - [FromQuery] params int[] ignore_statuses) - { - try + if (User.GetId() is int intId) + return await _envelopeService.ReadByUserAsync(intId, min_status: envelope.Status, max_status: envelope.Status).ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return StatusCode(StatusCodes.Status500InternalServerError); + }); + else { - if (User.GetId() is int intId) - 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); + _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); } } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } -} \ No newline at end of file +} diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs index 38184e9a..dd8e828a 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs @@ -1,98 +1,165 @@ using DigitalData.Core.DTO; 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.Mvc; -namespace EnvelopeGenerator.GeneratorAPI.Controllers +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Controller für die Verwaltung von Umschlagempfängern. +/// +/// +/// Dieser Controller bietet Endpunkte für das Abrufen und Verwalten von Umschlagempfängerdaten. +/// +[Route("api/[controller]")] +[Authorize] +[ApiController] +public class EnvelopeReceiverController : ControllerBase { - [Route("api/[controller]")] - [Authorize] - [ApiController] - public class EnvelopeReceiverController : ControllerBase + private readonly ILogger _logger; + + private readonly IEnvelopeReceiverService _erService; + + private readonly IMediator _mediator; + + /// + /// Konstruktor für den EnvelopeReceiverController. + /// + /// Logger-Instanz zur Protokollierung von Informationen und Fehlern. + /// Service zur Verwaltung von Umschlagempfängern. + /// Mediator-Instanz zur Verarbeitung von Befehlen und Abfragen. + public EnvelopeReceiverController(ILogger logger, IEnvelopeReceiverService envelopeReceiverService, IMediator mediator) { - private readonly ILogger _logger; - private readonly IEnvelopeReceiverService _erService; + _logger = logger; + _erService = envelopeReceiverService; + _mediator = mediator; + } - public EnvelopeReceiverController(ILogger logger, IEnvelopeReceiverService envelopeReceiverService) + /// + /// Ruft eine Liste von Umschlagempfängern basierend auf den angegebenen Abfrageparametern ab. + /// + /// Die Abfrageparameter für die Filterung von Umschlagempfängern. + /// Eine HTTP-Antwort mit der Liste der gefundenen Umschlagempfänger oder einem Fehlerstatus. + /// + /// 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. + /// + /// Die Liste der Umschlagempfänger wurde erfolgreich abgerufen. + /// Wenn kein autorisierter Token vorhanden ist + /// Ein unerwarteter Fehler ist aufgetreten. + [Authorize] + [HttpGet] + public async Task GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver) + { + try { - _logger = logger; - _erService = envelopeReceiverService; - } - - [HttpGet] - public async Task GetEnvelopeReceiver([FromQuery] int? min_status = null, [FromQuery] int? max_status = null, [FromQuery] int[]? ignore_status = null) - { - try + var username = User.GetUsername(); + + if (username is null) { - var username = User.GetUsername(); - - 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(); - - 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 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); + _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); } - } - [HttpGet("secret")] - [Authorize] - public async Task GetSecretAsync([FromQuery] string uuid) - { - try - { - return await _erService.ReadWithSecretByUuidAsync(uuid: uuid).ThenAsync( + return await _erService.ReadByUsernameAsync(username: username).ThenAsync( Success: Ok, Fail: IActionResult (msg, 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) + { + _logger.LogError(ex, "An unexpected error occurred. {message}", ex.Message); + return new StatusCodeResult(StatusCodes.Status500InternalServerError); } } + + /// + /// Ruft den Namen des zuletzt verwendeten Empfängers basierend auf der angegebenen E-Mail-Adresse ab. + /// + /// Die Abfrage, die die E-Mail-Adresse des Empfängers enthält. + /// Eine HTTP-Antwort mit dem Namen des Empfängers oder einem Fehlerstatus. + /// + /// Dieser Endpunkt ermöglicht es, den Namen des zuletzt verwendeten Empfängers basierend auf der E-Mail-Adresse abzurufen. + /// + /// Der Name des Empfängers wurde erfolgreich abgerufen. + /// Wenn kein autorisierter Token vorhanden ist + /// Kein Empfänger gefunden. + /// Ein unerwarteter Fehler ist aufgetreten. + [Authorize] + [HttpGet("salute")] + public async Task 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); + } + } + + /// + /// Datenübertragungsobjekt mit Informationen zu Umschlägen, Empfängern und Unterschriften. + /// + /// + /// Token to cancel the operation + /// HTTP-Antwort + /// + /// 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 + /// } + /// + /// + /// Envelope-Erstellung und Sendeprozessbefehl erfolgreich + /// Wenn ein Fehler im HTTP-Body auftritt + /// Wenn kein autorisierter Token vorhanden ist + /// Es handelt sich um einen unerwarteten Fehler. Die Protokolle sollten überprüft werden. + [Authorize] + [HttpPost] + public async Task CreateAsync([FromBody] CreateEnvelopeReceiverCommand createEnvelopeQuery, CancellationToken cancellationToken) + { + await _mediator.Send(createEnvelopeQuery, cancellationToken); + return Accepted(); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs index 3708cf08..bf2ea067 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs @@ -1,43 +1,40 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts.Services; -using Microsoft.AspNetCore.Http; 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]")] - [ApiController] - public class EnvelopeTypeController : ControllerBase + private readonly ILogger _logger; + private readonly IEnvelopeTypeService _service; + + public EnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) { - private readonly ILogger _logger; - private readonly IEnvelopeTypeService _service; + _logger = logger; + _service = service; + } - public EnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) + [HttpGet] + public async Task GetAllAsync() + { + try { - _logger = logger; - _service = service; + return await _service.ReadAllAsync().ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError); + }); } - - [HttpGet] - public async Task GetAllAsync() + catch (Exception ex) { - try - { - 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); - } + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs index ce0abab4..0569bf0d 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs @@ -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.Mvc; -using System; using static EnvelopeGenerator.Common.Constants; -namespace EnvelopeGenerator.GeneratorAPI.Controllers + +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Dieser Controller stellt Endpunkte für den Zugriff auf die Umschlaghistorie bereit. +/// +[Route("api/[controller]")] +[ApiController] +[Authorize] +public class HistoryController : ControllerBase { - [Route("api/[controller]")] - [ApiController] - [Authorize] - public class HistoryController : ControllerBase + private readonly ILogger _logger; + + private readonly IEnvelopeHistoryService _service; + + /// + /// Konstruktor für den HistoryController. + /// + /// Der Logger, der für das Protokollieren von Informationen verwendet wird. + /// Der Dienst, der für die Verarbeitung der Umschlaghistorie verantwortlich ist. + public HistoryController(ILogger logger, IEnvelopeHistoryService service) { - private readonly ILogger _logger; - - private readonly IEnvelopeHistoryService _service; - - public HistoryController(ILogger 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() - .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 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); - } + _logger = logger; + _service = service; } -} \ No newline at end of file + + /// + /// 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. + /// + /// + /// + [HttpGet("related")] + [Authorize] + public IActionResult GetReferenceTypes() + { + // Enum zu Schlüssel-Wert-Paar + var referenceTypes = Enum.GetValues(typeof(ReferenceType)) + .Cast() + .ToDictionary(rt => + { + var key = rt.ToString(); + var keyAsCamelCase = char.ToLower(key[0]) + key[1..]; + return keyAsCamelCase; + }, rt => (int)rt); + + return Ok(referenceTypes); + } + + /// + /// 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 + /// + /// + /// 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. + /// + /// Gibt die HTTP-Antwort zurück. + /// + [HttpGet("status")] + [Authorize] + public IActionResult GetEnvelopeStatus([FromQuery] ReferenceType? related = null) + { + // Enum zu Schlüssel-Wert-Paar + var referenceTypes = Enum.GetValues(typeof(EnvelopeStatus)) + .Cast() + .ToDictionary(rt => + { + var key = rt.ToString(); + var keyAsCamelCase = char.ToLower(key[0]) + key[1..]; + return keyAsCamelCase; + }, rt => (int)rt); + + return Ok(referenceTypes); + } + + /// + /// Ruft die gesamte Umschlaghistorie basierend auf den angegebenen Abfrageparametern ab. + /// + /// Die Abfrageparameter, die die Filterkriterien für die Umschlaghistorie definieren. + /// Eine Liste von Historieneinträgen, die den angegebenen Kriterien entsprechen, oder nur der letzte Eintrag. + /// Die Anfrage war erfolgreich, und die Umschlaghistorie wird zurückgegeben. + /// Die Anfrage war ungültig oder unvollständig. + /// Der Benutzer ist nicht authentifiziert. + /// Der Benutzer hat keine Berechtigung, auf die Ressource zuzugreifen. + /// Ein unerwarteter Fehler ist aufgetreten. + [HttpGet] + [Authorize] + public async Task 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); + } +} diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/LocalizationController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/LocalizationController.cs index 2636d67c..b0919211 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/LocalizationController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/LocalizationController.cs @@ -6,85 +6,115 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Localization; -namespace EnvelopeGenerator.GeneratorAPI.Controllers +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Controller für die Verwaltung der Lokalisierung und Spracheinstellungen. +/// +[ApiExplorerSettings(IgnoreApi = true)] +[Route("api/[controller]")] +[ApiController] +public class LocalizationController : ControllerBase { - [Route("api/[controller]")] - [ApiController] - public class LocalizationController : ControllerBase + private static readonly Guid L_KEY = Guid.NewGuid(); + + private readonly ILogger _logger; + private readonly IStringLocalizer _mLocalizer; + private readonly IStringLocalizer _localizer; + private readonly IMemoryCache _cache; + + /// + /// Konstruktor für den . + /// + /// Logger für die Protokollierung. + /// Lokalisierungsdienst für Ressourcen. + /// Speicher-Cache für die Zwischenspeicherung von Daten. + /// Lokalisierungsdienst für Modelle. + public LocalizationController( + ILogger logger, + IStringLocalizer localizer, + IMemoryCache memoryCache, + IStringLocalizer _modelLocalizer) { - private static readonly Guid L_KEY = Guid.NewGuid(); + _logger = logger; + _localizer = localizer; + _cache = memoryCache; + _mLocalizer = _modelLocalizer; + } - private readonly ILogger _logger; - private readonly IStringLocalizer _mLocalizer; - private readonly IStringLocalizer _localizer; - private readonly IMemoryCache _cache; + /// + /// Ruft alle lokalisierten Daten ab. + /// + /// Eine Liste aller lokalisierten Daten. + [HttpGet] + public IActionResult GetAll() => Ok(_cache.GetOrCreate(Language ?? string.Empty + L_KEY, _ => _mLocalizer.ToDictionary())); - public LocalizationController( - ILogger logger, - IStringLocalizer localizer, - IMemoryCache memoryCache, - IStringLocalizer _modelLocalizer) + /// + /// Ruft die aktuelle Sprache ab. + /// + /// Die aktuelle Sprache oder ein NotFound-Ergebnis, wenn keine Sprache gesetzt ist. + [HttpGet("lang")] + public IActionResult GetLanguage() => Language is null ? NotFound() : Ok(Language); + + /// + /// Setzt die Sprache. + /// + /// Die zu setzende Sprache. + /// Ein Ok-Ergebnis, wenn die Sprache erfolgreich gesetzt wurde, oder ein BadRequest-Ergebnis, wenn die Eingabe ungültig ist. + [HttpPost("lang")] + public IActionResult SetLanguage([FromQuery] string language) + { + if (string.IsNullOrEmpty(language)) + return BadRequest(); + + Language = language; + return Ok(); + } + + /// + /// Löscht die aktuelle Sprache. + /// + /// Ein Ok-Ergebnis, wenn die Sprache erfolgreich gelöscht wurde. + [HttpDelete("lang")] + public IActionResult DeleteLanguage() + { + Language = null; + return Ok(); + } + + /// + /// Eigenschaft für die Verwaltung der aktuellen Sprache über Cookies. + /// + private string? Language + { + get { - _logger = logger; - _localizer = localizer; - _cache = memoryCache; - _mLocalizer = _modelLocalizer; + var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName]; + + if (string.IsNullOrEmpty(cookieValue)) + return null; + + var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures[0]; + return culture?.Value ?? null; } - - [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) + set { - if (string.IsNullOrEmpty(language)) - return BadRequest(); - - Language = language; - return Ok(); - } - - [HttpDelete("lang")] - public IActionResult DeleteLanguage() - { - Language = null; - return Ok(); - } - - private string? Language - { - get + if (value is null) + Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName); + else { - var cookieValue = Request.Cookies[CookieRequestCultureProvider.DefaultCookieName]; - - 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() { - var cookieOptions = new CookieOptions() - { - Expires = DateTimeOffset.UtcNow.AddYears(1), - Secure = false, - SameSite = SameSiteMode.Strict, - HttpOnly = true - }; + Expires = DateTimeOffset.UtcNow.AddYears(1), + Secure = false, + SameSite = SameSiteMode.Strict, + HttpOnly = true + }; - Response.Cookies.Append( - CookieRequestCultureProvider.DefaultCookieName, - CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)), - cookieOptions); - } + Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(value)), + cookieOptions); } } } diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs index f8c11be2..9920b5de 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs @@ -2,88 +2,97 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts.Services; using EnvelopeGenerator.Application.DTOs.Receiver; +using EnvelopeGenerator.Application.Receivers.Queries.Read; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace EnvelopeGenerator.GeneratorAPI.Controllers +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Controller für die Verwaltung von Empfängern. +/// +/// +/// 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. +/// +[Route("api/[controller]")] +[ApiController] +[Authorize] +public class ReceiverController : CRUDControllerBaseWithErrorHandling { - [Route("api/[controller]")] - [ApiController] - [Authorize] - public class ReceiverController : CRUDControllerBaseWithErrorHandling + /// + /// Initialisiert eine neue Instanz des -Controllers. + /// + /// Der Logger für die Protokollierung. + /// Der Dienst für Empfängeroperationen. + public ReceiverController(ILogger logger, IReceiverService service) : base(logger, service) { - public ReceiverController(ILogger logger, IReceiverService service) : base(logger, service) - { - } - - [HttpGet] - public async Task 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 Create(ReceiverCreateDto createDto) - { - if (!ModelState.IsValid) - return BadRequest(ModelState); - - return await base.Create(createDto); - } - - [HttpDelete] - public async Task 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 GetAll() => base.GetAll(); - - [NonAction] - public override Task Delete([FromRoute] int id) => base.Delete(id); - - [NonAction] - public override Task Update(ReceiverUpdateDto updateDto) => base.Update(updateDto); - #endregion } -} \ No newline at end of file + + /// + /// Ruft eine Liste von Empfängern ab, basierend auf den angegebenen Abfrageparametern. + /// + /// Die Abfrageparameter, einschließlich E-Mail-Adresse und Signatur. + /// Eine Liste von Empfängern oder ein Fehlerstatus. + [HttpGet] + public async Task 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 + /// + /// Diese Methode ist deaktiviert und wird nicht verwendet. + /// + [NonAction] + public override Task GetAll() => base.GetAll(); + + /// + /// Diese Methode ist deaktiviert und wird nicht verwendet. + /// + [NonAction] + public override Task Delete([FromRoute] int id) => base.Delete(id); + + /// + /// Diese Methode ist deaktiviert und wird nicht verwendet. + /// + [NonAction] + public override Task Update(ReceiverUpdateDto updateDto) => base.Update(updateDto); + + /// + /// Diese Methode ist deaktiviert und wird nicht verwendet. + /// + [NonAction] + public override Task Create(ReceiverCreateDto createDto) + { + return base.Create(createDto); + } + + /// + /// Diese Methode ist deaktiviert und wird nicht verwendet. + /// + [NonAction] + public override Task GetById([FromRoute] int id) + { + return base.GetById(id); + } + #endregion +} diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index 51efca53..e20cd48a 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -1,16 +1,29 @@  - net7.0 + net9.0 enable enable + true + EnvelopeGenerator.GeneratorAPI + + Digital Data GmbH + Digital Data GmbH + EnvelopeGenerator.GeneratorAPI + 1.2.0 + 1.2.0 + 1.2.0 + Copyright © 2025 Digital Data GmbH. All rights reserved. + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + - - + + + diff --git a/EnvelopeGenerator.GeneratorAPI/Models/Login.cs b/EnvelopeGenerator.GeneratorAPI/Models/Login.cs new file mode 100644 index 00000000..7aaeea50 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Models/Login.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace EnvelopeGenerator.GeneratorAPI.Models; + +/// +/// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername. +/// +/// Das erforderliche Passwort für das Login. +/// Die optionale ID des Benutzers. +/// Der optionale Benutzername. +public record Login([Required] string Password, int? Id = null, string? Username = null) +{ +} diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index 5d734ea5..1ff1f7c4 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -7,6 +7,8 @@ using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using System.Globalization; +using Scalar.AspNetCore; +using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); @@ -31,8 +33,53 @@ builder.Services.AddCors(options => // Swagger 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 var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json."); builder.Services.AddDbContext(options => options.UseSqlServer(connStr)); @@ -60,15 +107,20 @@ builder.Services.AddDirectorySearchService(); builder.Services.AddCookieBasedLocalizer() ; // Envelope generator serives -builder.Services.AddEnvelopeGenerator(config); +builder.Services + .AddEnvelopeGeneratorRepositories() + .AddEnvelopeGeneratorServices(config); var app = builder.Build(); +app.MapOpenApi(); + // Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) +if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue("UseSwagger"))) { app.UseSwagger(); app.UseSwaggerUI(); + app.MapScalarApiReference(); } // Set CORS policy diff --git a/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet7Win64.pubxml b/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet7Win64.pubxml new file mode 100644 index 00000000..99e4e6ad --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet7Win64.pubxml @@ -0,0 +1,22 @@ + + + + + Package + Release + Any CPU + + true + false + 4fdae4ba-f512-444a-9e18-111047d3ef02 + P:\Install .Net\0 DD - Smart UP\signFLOW\Gen\Api\net7\win64\$(Version)\$(Version).zip + true + SignFlowGen + <_TargetId>IISWebDeployPackage + net7.0 + win-x64 + true + + \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet9Win64.pubxml b/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet9Win64.pubxml new file mode 100644 index 00000000..8d3b72df --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Properties/PublishProfiles/IISProfileNet9Win64.pubxml @@ -0,0 +1,22 @@ + + + + + Package + Release + Any CPU + + true + false + 4fdae4ba-f512-444a-9e18-111047d3ef02 + P:\Install .Net\0 DD - Smart UP\signFLOW\Gen\Api\net9\win64\$(Version)\$(Version).zip + true + SignFlowGen + <_TargetId>IISWebDeployPackage + net9.0 + win-x64 + true + + \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/appsettings.json b/EnvelopeGenerator.GeneratorAPI/appsettings.json index 0f469f84..734a3dcb 100644 --- a/EnvelopeGenerator.GeneratorAPI/appsettings.json +++ b/EnvelopeGenerator.GeneratorAPI/appsettings.json @@ -1,4 +1,6 @@ { + "UseSwagger": true, + "DiPMode": true, "Logging": { "LogLevel": { "Default": "Information", diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index 892bbe5a..9f46ea48 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -1,7 +1,7 @@  - net7.0 + net7.0;net8.0;net9.0 enable enable diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 4afba015..7f65cc86 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -1,7 +1,7 @@  - net7.0 + net7.0;net8.0;net9.0 enable enable EnvelopeGenerator.Web diff --git a/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet7.pubxml b/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet7.pubxml new file mode 100644 index 00000000..9ef04907 --- /dev/null +++ b/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet7.pubxml @@ -0,0 +1,20 @@ + + + + + Package + Release + Any CPU + + true + false + 5e0e17c0-ff5a-4246-bf87-1add85376a27 + P:\Install .Net\0 DD - Smart UP\signFLOW\Web\net7\$(Version)\EnvelopeGenerator.Web.zip + true + EnvelopeGenerator + <_TargetId>IISWebDeployPackage + net7.0 + + \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet9Win64.pubxml b/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet9Win64.pubxml new file mode 100644 index 00000000..b1213f08 --- /dev/null +++ b/EnvelopeGenerator.Web/Properties/PublishProfiles/IISProfileNet9Win64.pubxml @@ -0,0 +1,22 @@ + + + + + Package + Release + Any CPU + + true + false + 5e0e17c0-ff5a-4246-bf87-1add85376a27 + P:\Install .Net\0 DD - Smart UP\signFLOW\Web\net9\win64\$(Version)\EnvelopeGenerator.Web.zip + true + EnvelopeGenerator + <_TargetId>IISWebDeployPackage + net9.0 + win-x64 + true + + \ No newline at end of file