Compare commits
81 Commits
a59d4836d4
...
web-multi-
| Author | SHA1 | Date | |
|---|---|---|---|
| f41199c389 | |||
| 03e3e0eaf4 | |||
| c8ca1ef22a | |||
| d31916eab8 | |||
| ee7c92ff5b | |||
| 89db852705 | |||
| c674a450d8 | |||
| 910a870ddf | |||
| e2afbc5a62 | |||
| 0fb94decdd | |||
| 2c81583831 | |||
| 47eade57a3 | |||
| d094fe14da | |||
| 0dc356726b | |||
| b227eb4051 | |||
| de36e29743 | |||
| 6291712291 | |||
| 73527a97d7 | |||
| ff094ebfe1 | |||
| 1c948fcbf8 | |||
| eba40acd4d | |||
| 5cb3465e12 | |||
| 2c43fdbaed | |||
| eb96842122 | |||
| a8cb8f935c | |||
| 387456659d | |||
| 17e3a67fe5 | |||
| 632723de5a | |||
| 6611b92fdb | |||
| 5baa28bac8 | |||
| c965975f82 | |||
| d480dd3a36 | |||
| ae7f0b80f3 | |||
| ef7c9c2b97 | |||
| 27f0aae8e0 | |||
| 1b10162c85 | |||
| bd0426dbee | |||
| b1551537c8 | |||
| 95b2ab5aed | |||
| ebed51b46a | |||
| 0d2425c9cf | |||
| c6c8747d23 | |||
| eb345a0e4d | |||
| 1b95b9d7e0 | |||
| d99193979f | |||
| 8742ea6025 | |||
| 2b8edc697a | |||
| 7c88d4ed4b | |||
| a6be907307 | |||
| 2fcea78574 | |||
| e8e428f935 | |||
| 9450ed3486 | |||
| 583a07c646 | |||
| 51ad4fbc2c | |||
| 50ac7570ea | |||
| 5465996563 | |||
| 1b840f4ae3 | |||
| 3923a3b403 | |||
| ada621ac46 | |||
| abbe6a26a9 | |||
| 3066dac541 | |||
| b1aa6d6639 | |||
| 31fe1c34f2 | |||
| d7644bfe07 | |||
| 4759b16a85 | |||
| cfdfb43631 | |||
| 6254bb6e3f | |||
| f995fa9fc3 | |||
| c2fefe798d | |||
| 849a282ec5 | |||
| 6b23dcdba7 | |||
| a60d0f63e2 | |||
| 2481059b49 | |||
| 6334097d5e | |||
| 9baa126c8c | |||
| 1ef46013cd | |||
| 72dffd1043 | |||
| eda30472b9 | |||
| 75846573da | |||
| f59c0d90ad | |||
| cf40449112 |
@@ -6,19 +6,19 @@ using EnvelopeGenerator.Application.Common.Notifications.DocSigned;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
|
||||
using EnvelopeGenerator.Application.Histories.Queries;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.GeneratorAPI.Extensions;
|
||||
using EnvelopeGenerator.API.Extensions;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Manages annotations and signature lifecycle for envelopes.
|
||||
/// </summary>
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class AnnotationController : ControllerBase
|
||||
@@ -54,19 +54,13 @@ public class AnnotationController : ControllerBase
|
||||
/// </summary>
|
||||
/// <param name="psPdfKitAnnotation">Annotation payload.</param>
|
||||
/// <param name="cancel">Cancellation token.</param>
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
[HttpPost]
|
||||
[Obsolete("This endpoint is for PSPDF Kit.")]
|
||||
[Obsolete("PSPDF Kit will no longer be used.")]
|
||||
public async Task<IActionResult> CreateOrUpdate([FromBody] PsPdfKitAnnotation? psPdfKitAnnotation = null, CancellationToken cancel = default)
|
||||
{
|
||||
var signature = User.GetAuthReceiverSignature();
|
||||
var uuid = User.GetAuthEnvelopeUuid();
|
||||
|
||||
if (signature is null || uuid is null)
|
||||
{
|
||||
_logger.LogError("Authorization failed: authenticated user does not have a valid signature or envelope UUID.");
|
||||
return Unauthorized("User authentication is incomplete. Missing required claims for processing this request.");
|
||||
}
|
||||
var signature = User.GetReceiverSignatureOfReceiver();
|
||||
var uuid = User.GetEnvelopeUuidOfReceiver();
|
||||
|
||||
var envelopeReceiver = await _mediator.ReadEnvelopeReceiverAsync(uuid, signature, cancel).ThrowIfNull(Exceptions.NotFound);
|
||||
|
||||
@@ -93,20 +87,14 @@ public class AnnotationController : ControllerBase
|
||||
/// Rejects the document for the current receiver.
|
||||
/// </summary>
|
||||
/// <param name="reason">Optional rejection reason.</param>
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
[HttpPost("reject")]
|
||||
[Obsolete("Use MediatR")]
|
||||
public async Task<IActionResult> Reject([FromBody] string? reason = null)
|
||||
{
|
||||
var signature = User.GetAuthReceiverSignature();
|
||||
var uuid = User.GetAuthEnvelopeUuid();
|
||||
var mail = User.GetAuthReceiverMail();
|
||||
if (uuid is null || signature is null || mail is null)
|
||||
{
|
||||
_logger.LogEnvelopeError(uuid: uuid, signature: signature,
|
||||
message: @$"Unauthorized POST request in api\\envelope\\reject. One of claims, Envelope, signature or mail ({mail}) is null.");
|
||||
return Unauthorized();
|
||||
}
|
||||
var signature = User.GetReceiverSignatureOfReceiver();
|
||||
var uuid = User.GetEnvelopeUuidOfReceiver();
|
||||
var mail = User.GetReceiverMailOfReceiver();
|
||||
|
||||
var envRcvRes = await _envelopeReceiverService.ReadByUuidSignatureAsync(uuid: uuid, signature: signature);
|
||||
|
||||
|
||||
@@ -1,104 +1,27 @@
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.UserManager.Application.Contracts;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using EnvelopeGenerator.API.Controllers.Interfaces;
|
||||
using EnvelopeGenerator.API.Models;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus.
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public partial class AuthController : ControllerBase
|
||||
public partial class AuthController(IOptions<AuthTokenKeys> authTokenKeyOptions, IAuthorizationService authService) : ControllerBase, IAuthController
|
||||
{
|
||||
private readonly ILogger<AuthController> _logger;
|
||||
[Obsolete("Use MediatR")]
|
||||
private readonly IUserService _userService;
|
||||
private readonly IDirectorySearchService _dirSearchService;
|
||||
private readonly AuthTokenKeys authTokenKeys = authTokenKeyOptions.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AuthController"/> class.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger instance.</param>
|
||||
/// <param name="userService">The user service instance.</param>
|
||||
/// <param name="dirSearchService">The directory search service instance.</param>
|
||||
[Obsolete("Use MediatR")]
|
||||
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
|
||||
{
|
||||
_logger = logger;
|
||||
_userService = userService;
|
||||
_dirSearchService = dirSearchService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
|
||||
/// </summary>
|
||||
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
|
||||
/// <returns>
|
||||
/// Gibt eine HTTP 200 oder 401.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Sample request:
|
||||
///
|
||||
/// POST /api/auth?cookie=true
|
||||
/// {
|
||||
/// "username": "MaxMustermann",
|
||||
/// "password": "Geheim123!"
|
||||
/// }
|
||||
///
|
||||
/// POST /api/auth?cookie=true
|
||||
/// {
|
||||
/// "id": "1",
|
||||
/// "password": "Geheim123!"
|
||||
/// }
|
||||
///
|
||||
/// </remarks>
|
||||
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
|
||||
{
|
||||
// added to configure open API (swagger and scalar)
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
|
||||
/// </summary>
|
||||
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||
/// <returns>
|
||||
/// Gibt eine HTTP 200 oder 401.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Sample request:
|
||||
///
|
||||
/// POST /api/auth/form
|
||||
/// {
|
||||
/// "username": "MaxMustermann",
|
||||
/// "password": "Geheim123!"
|
||||
/// }
|
||||
///
|
||||
/// </remarks>
|
||||
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
[Route("form")]
|
||||
public Task<IActionResult> Login([FromForm] Login login)
|
||||
{
|
||||
// added to configure open API (swagger and scalar)
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public IAuthorizationService AuthService { get; } = authService;
|
||||
|
||||
/// <summary>
|
||||
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
|
||||
@@ -114,13 +37,19 @@ public partial class AuthController : ControllerBase
|
||||
/// </remarks>
|
||||
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
|
||||
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||
[Authorize]
|
||||
[Authorize(Policy = AuthPolicy.SenderOrReceiver)]
|
||||
[HttpPost("logout")]
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
if (await this.IsUserInPolicyAsync(AuthPolicy.Sender))
|
||||
Response.Cookies.Delete(authTokenKeys.Cookie);
|
||||
else if (await this.IsUserInPolicyAsync(AuthPolicy.ReceiverOrReceiverTFA))
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
else
|
||||
return Unauthorized();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
@@ -136,9 +65,12 @@ public partial class AuthController : ControllerBase
|
||||
/// </remarks>
|
||||
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
|
||||
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
|
||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||
[HttpGet("check")]
|
||||
[Authorize]
|
||||
[HttpGet]
|
||||
public IActionResult IsAuthenticated() => Ok();
|
||||
public IActionResult Check(string? role = null)
|
||||
=> role is not null && !User.IsInRole(role)
|
||||
? Unauthorized()
|
||||
: Ok();
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
using EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes configuration data required by the client applications.
|
||||
@@ -22,6 +22,7 @@ public class ConfigController(IOptionsMonitor<AnnotationParams> annotationParams
|
||||
/// Returns annotation configuration that was previously rendered by MVC.
|
||||
/// </summary>
|
||||
[HttpGet("Annotations")]
|
||||
[Obsolete("PSPDF Kit will no longer be used.")]
|
||||
public IActionResult GetAnnotationParams()
|
||||
{
|
||||
return Ok(_annotationParams.AnnotationJSObject);
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for extracting user information from a <see cref="ClaimsPrincipal"/>.
|
||||
/// </summary>
|
||||
public static class ControllerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the user's ID from the claims. Returns null if the ID is not found or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The user's ID as an integer, or null if not found or invalid.</returns>
|
||||
public static int? GetIdOrDefault(this ClaimsPrincipal user)
|
||||
=> int.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier) ?? user.FindFirstValue("sub"), out int result)
|
||||
? result : null;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's ID from the claims. Throws an exception if the ID is missing or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The user's ID as an integer.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the user ID claim is missing or invalid.</exception>
|
||||
public static int GetId(this ClaimsPrincipal user)
|
||||
=> user.GetIdOrDefault()
|
||||
?? throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the username from the claims, if available.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The username as a string, or null if not found.</returns>
|
||||
public static string? GetUsernameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Name)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's surname (last name) from the claims, if available.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The surname as a string, or null if not found.</returns>
|
||||
public static string? GetNameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Surname)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's given name (first name) from the claims, if available.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The given name as a string, or null if not found.</returns>
|
||||
public static string? GetPrenameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.GivenName)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's email address from the claims, if available.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The email address as a string, or null if not found.</returns>
|
||||
public static string? GetEmailOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Email)?.Value;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using DigitalData.Core.Exceptions;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
|
||||
using EnvelopeGenerator.API.Controllers.Interfaces;
|
||||
using EnvelopeGenerator.API.Extensions;
|
||||
using EnvelopeGenerator.Application.Documents.Queries;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to envelope documents for authenticated receivers.
|
||||
@@ -14,30 +14,50 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of the <see cref="DocumentController"/> class.
|
||||
/// </remarks>
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class DocumentController(IMediator mediator, ILogger<DocumentController> logger) : ControllerBase
|
||||
public class DocumentController(IMediator mediator, IAuthorizationService authService) : ControllerBase, IAuthController
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the document bytes for the specified envelope receiver key.
|
||||
///
|
||||
/// </summary>
|
||||
public IAuthorizationService AuthService => authService;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the document bytes receiver.
|
||||
/// </summary>
|
||||
/// <param name="query">Encoded envelope key.</param>
|
||||
/// <param name="cancel">Cancellation token.</param>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetDocument(ReadEnvelopeReceiverQuery query, CancellationToken cancel)
|
||||
[Authorize(Policy = AuthPolicy.SenderOrReceiver)]
|
||||
public async Task<IActionResult> GetDocument(CancellationToken cancel, [FromQuery] ReadDocumentQuery? query = null)
|
||||
{
|
||||
var envRcv = await mediator.Send(query, cancel).FirstAsync(Exceptions.NotFound);
|
||||
|
||||
var byteData = envRcv.Envelope?.Documents?.FirstOrDefault()?.ByteData;
|
||||
|
||||
if (byteData is null || byteData.Length == 0)
|
||||
// Sender: expects query with envelope key
|
||||
if (await this.IsUserInPolicyAsync(AuthPolicy.Sender))
|
||||
{
|
||||
logger.LogError("Document byte data is null or empty for envelope-receiver entity:\n{envelopeKey}.",
|
||||
envRcv.ToJson(Format.Json.ForDiagnostics));
|
||||
throw new NotFoundException("Document is empty.");
|
||||
if (query is null)
|
||||
return BadRequest("Missing document query.");
|
||||
|
||||
var senderDoc = await mediator.Send(query, cancel);
|
||||
return senderDoc.ByteData is byte[] senderDocByte
|
||||
? File(senderDocByte, "application/octet-stream")
|
||||
: NotFound("Document is empty.");
|
||||
}
|
||||
|
||||
return File(byteData, "application/octet-stream");
|
||||
// Receiver: resolve envelope id from claims
|
||||
if (await this.IsUserInPolicyAsync(AuthPolicy.Receiver))
|
||||
{
|
||||
if (query is not null)
|
||||
return BadRequest("Query parameters are not allowed for receiver role.");
|
||||
|
||||
var envelopeId = User.GetEnvelopeIdOfReceiver();
|
||||
var receiverDoc = await mediator.Send(new ReadDocumentQuery { EnvelopeId = envelopeId }, cancel);
|
||||
return receiverDoc.ByteData is byte[] receiverDocByte
|
||||
? File(receiverDocByte, "application/octet-stream")
|
||||
: NotFound("Document is empty.");
|
||||
}
|
||||
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,33 @@
|
||||
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 EnvelopeGenerator.Application.EmailTemplates.Commands;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MediatR;
|
||||
using System.Threading.Tasks;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Application.EmailTemplates.Queries;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing temp templates.
|
||||
/// Steuerung zur Verwaltung von E-Mail-Vorlagen.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||
/// </remarks>
|
||||
/// <param name="mapper">
|
||||
/// <param name="repository">
|
||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||
/// </param>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class EmailTemplateController : ControllerBase
|
||||
[Authorize(Policy = AuthPolicy.Sender)]
|
||||
public class EmailTemplateController(IMapper mapper, IRepository<EmailTemplate> repository, IMediator mediator) : ControllerBase
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IRepository<EmailTemplate> _repository;
|
||||
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
/// <summary>
|
||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||
/// </summary>
|
||||
/// <param name="mapper">
|
||||
/// <param name="repository">
|
||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||
/// </param>
|
||||
[Obsolete("Use MediatR")]
|
||||
public EmailTemplateController(IMapper mapper, IRepository<EmailTemplate> repository, IMediator mediator)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_repository = repository;
|
||||
_mediator = mediator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ruft E-Mail-Vorlagen basierend auf der angegebenen Abfrage ab.
|
||||
/// Gibt alles zurück, wenn keine Id- oder Typ-Informationen eingegeben wurden.
|
||||
@@ -63,12 +47,12 @@ public class EmailTemplateController : ControllerBase
|
||||
{
|
||||
if (emailTemplate is null || (emailTemplate.Id is null && emailTemplate.Type is null))
|
||||
{
|
||||
var temps = await _repository.Query.ToListAsync();
|
||||
return Ok(_mapper.Map<IEnumerable<EmailTemplateDto>>(temps));
|
||||
var temps = await repository.Query.ToListAsync();
|
||||
return Ok(mapper.Map<IEnumerable<EmailTemplateDto>>(temps));
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = await _mediator.Send(emailTemplate);
|
||||
var temp = await mediator.Send(emailTemplate);
|
||||
return temp is null ? NotFound() : Ok(temp);
|
||||
}
|
||||
}
|
||||
@@ -77,40 +61,17 @@ public class EmailTemplateController : ControllerBase
|
||||
/// Updates an temp template or resets it if no update command is provided.
|
||||
/// Aktualisiert eine E-Mail-Vorlage oder setzt sie zurück, wenn kein Aktualisierungsbefehl angegeben ist.
|
||||
/// </summary>
|
||||
/// <param name="temp">Die E-Mail-Vorlagenabfrage.</param>
|
||||
/// <param name="update">Der Aktualisierungsbefehl für die E-Mail-Vorlage.
|
||||
/// Wird auf Standardwert aktualisiert, wenn die Anfrage ohne http-Body gesendet wird.
|
||||
/// </param>
|
||||
/// <returns>Gibt HTTP-Antwort zurück</returns>
|
||||
/// <remarks>
|
||||
/// Sample request:
|
||||
/// PUT /api/EmailTemplate
|
||||
/// {
|
||||
/// "emailTemplateId": 123,
|
||||
/// "newContent": "Updated content"
|
||||
/// }
|
||||
/// </remarks>
|
||||
/// <param name="update"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
/// <response code="200">Wenn die E-Mail-Vorlage erfolgreich aktualisiert oder zurückgesetzt wird.</response>
|
||||
/// <response code="400">Wenn die Abfrage ohne einen String gesendet wird.</response>
|
||||
/// <response code="401">Wenn der Benutzer nicht authentifiziert ist.</response>
|
||||
/// <response code="404">Wenn die gesuchte Abfrage nicht gefunden wird.</response>
|
||||
[HttpPut]
|
||||
public async Task<IActionResult> Update([FromQuery] EmailTemplateQuery? temp = null, [FromBody] UpdateEmailTemplateCommand? update = null)
|
||||
public async Task<IActionResult> Update([FromBody] UpdateEmailTemplateCommand update, CancellationToken cancel)
|
||||
{
|
||||
if (update is null)
|
||||
{
|
||||
await _mediator.Send(new ResetEmailTemplateCommand(temp));
|
||||
return Ok();
|
||||
}
|
||||
else if (temp is null)
|
||||
{
|
||||
return BadRequest("No both id and type");
|
||||
}
|
||||
else
|
||||
{
|
||||
update.EmailTemplateQuery = temp;
|
||||
await _mediator.Send(update);
|
||||
return Ok();
|
||||
}
|
||||
await mediator.Send(update, cancel);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using EnvelopeGenerator.API.Extensions;
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Dieser Controller stellt Endpunkte für die Verwaltung von Umschlägen bereit.
|
||||
|
||||
@@ -3,7 +3,7 @@ using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
|
||||
using EnvelopeGenerator.Application.EnvelopeReceivers.Queries;
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||
using EnvelopeGenerator.API.Models;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -13,8 +13,9 @@ using System.Data;
|
||||
using EnvelopeGenerator.Application.Common.SQL;
|
||||
using EnvelopeGenerator.Application.Common.Dto.Receiver;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.SQLExecutor;
|
||||
using EnvelopeGenerator.API.Extensions;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller für die Verwaltung von Umschlagempfängern.
|
||||
@@ -65,16 +66,7 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
|
||||
{
|
||||
var username = User.GetUsernameOrDefault();
|
||||
|
||||
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.GetUsernameOrDefault(), User.GetNameOrDefault(), User.GetPrenameOrDefault(), User.GetEmailOrDefault());
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
envelopeReceiver = envelopeReceiver with { Username = username };
|
||||
envelopeReceiver = envelopeReceiver with { Username = User.GetUsername() };
|
||||
|
||||
var result = await _mediator.Send(envelopeReceiver);
|
||||
|
||||
@@ -225,18 +217,14 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
using (SqlConnection conn = new(_cnnStr))
|
||||
{
|
||||
conn.Open();
|
||||
var formattedSQL_hist = string.Format(sql_hist, envelope.Uuid.ToSqlParam(), 1003.ToSqlParam(), userId.ToSqlParam());
|
||||
using (SqlCommand cmd = new SqlCommand(formattedSQL_hist, conn))
|
||||
{
|
||||
cmd.CommandType = CommandType.Text;
|
||||
var formattedSQL_hist = string.Format(sql_hist, envelope.Uuid.ToSqlParam(), 1003.ToSqlParam(), User.GetId().ToSqlParam());
|
||||
using SqlCommand cmd = new(formattedSQL_hist, conn);
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
bool outSuccess = reader.GetBoolean(0);
|
||||
}
|
||||
}
|
||||
using SqlDataReader reader = cmd.ExecuteReader();
|
||||
if (reader.Read())
|
||||
{
|
||||
bool outSuccess = reader.GetBoolean(0);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -6,7 +6,7 @@ using EnvelopeGenerator.Application.Histories.Queries;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Dieser Controller stellt Endpunkte für den Zugriff auf die Umschlaghistorie bereit.
|
||||
@@ -113,6 +113,6 @@ public class HistoryController : ControllerBase
|
||||
public async Task<IActionResult> GetAllAsync([FromQuery] ReadHistoryQuery historyQuery, CancellationToken cancel)
|
||||
{
|
||||
var history = await _mediator.Send(historyQuery, cancel).ThrowIfEmpty(Exceptions.NotFound);
|
||||
return Ok((historyQuery.OnlyLast ?? false) ? history.MaxBy(h => h.AddedWhen) : history);
|
||||
return Ok((historyQuery.OnlyLast) ? history.MaxBy(h => h.AddedWhen) : history);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace EnvelopeGenerator.API.Controllers.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IAuthController
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
IAuthorizationService AuthService { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
ClaimsPrincipal User { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class AuthControllerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="controller"></param>
|
||||
/// <param name="policyName"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<bool> IsUserInPolicyAsync(this IAuthController controller, string policyName)
|
||||
{
|
||||
var result = await controller.AuthService.AuthorizeAsync(controller.User, policyName);
|
||||
return result.Succeeded;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using DigitalData.Core.API;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
using EnvelopeGenerator.CommonServices;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Controller für die Verwaltung der Lokalisierung und Spracheinstellungen.
|
||||
@@ -19,7 +19,7 @@ public class LocalizationController : ControllerBase
|
||||
private static readonly Guid L_KEY = Guid.NewGuid();
|
||||
|
||||
private readonly ILogger<LocalizationController> _logger;
|
||||
private readonly IStringLocalizer<Model> _mLocalizer;
|
||||
private readonly IStringLocalizer<Resource> _mLocalizer;
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
private readonly IMemoryCache _cache;
|
||||
|
||||
@@ -34,7 +34,7 @@ public class LocalizationController : ControllerBase
|
||||
ILogger<LocalizationController> logger,
|
||||
IStringLocalizer<Resource> localizer,
|
||||
IMemoryCache memoryCache,
|
||||
IStringLocalizer<Model> _modelLocalizer)
|
||||
IStringLocalizer<Resource> _modelLocalizer)
|
||||
{
|
||||
_logger = logger;
|
||||
_localizer = localizer;
|
||||
|
||||
@@ -2,12 +2,12 @@ using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.GeneratorAPI.Extensions;
|
||||
using EnvelopeGenerator.API.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Manages read-only envelope sharing flows.
|
||||
@@ -37,22 +37,17 @@ public class ReadOnlyController : ControllerBase
|
||||
/// </summary>
|
||||
/// <param name="createDto">Creation payload.</param>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
public async Task<IActionResult> CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto)
|
||||
{
|
||||
var authReceiverMail = User.GetAuthReceiverMail();
|
||||
var authReceiverMail = User.GetReceiverMailOfReceiver();
|
||||
if (authReceiverMail is null)
|
||||
{
|
||||
_logger.LogError("EmailAddress claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
var envelopeId = User.GetAuthEnvelopeId();
|
||||
if (envelopeId is null)
|
||||
{
|
||||
_logger.LogError("Envelope Id claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||
return Unauthorized();
|
||||
}
|
||||
var envelopeId = User.GetEnvelopeIdOfReceiver();
|
||||
|
||||
createDto.AddedWho = authReceiverMail;
|
||||
createDto.EnvelopeId = envelopeId;
|
||||
|
||||
@@ -3,8 +3,7 @@ using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.GeneratorAPI.Extensions;
|
||||
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||
using EnvelopeGenerator.API.Models;
|
||||
using Ganss.Xss;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
@@ -13,7 +12,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes endpoints for registering and managing two-factor authentication for envelope receivers.
|
||||
@@ -112,7 +111,7 @@ public class TfaRegistrationController : ControllerBase
|
||||
/// <summary>
|
||||
/// Logs out the envelope receiver from cookie authentication.
|
||||
/// </summary>
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
[HttpPost("auth/logout")]
|
||||
public async Task<IActionResult> LogOutAsync()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using EnvelopeGenerator.API.Models;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace EnvelopeGenerator.API.Documentation;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed class AuthProxyDocumentFilter : IDocumentFilter
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="swaggerDoc"></param>
|
||||
/// <param name="context"></param>
|
||||
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
|
||||
{
|
||||
const string path = "/api/auth";
|
||||
|
||||
var loginSchema = context.SchemaGenerator.GenerateSchema(typeof(Login), context.SchemaRepository);
|
||||
var loginExample = new OpenApiObject
|
||||
{
|
||||
["password"] = new OpenApiString(""),
|
||||
["username"] = new OpenApiString("")
|
||||
};
|
||||
|
||||
var operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Proxy login (auth-hub)",
|
||||
Description = "Proxies the request to the auth service. Add query parameter `cookie=true|false`.",
|
||||
Tags = [new() { Name = "Auth" }],
|
||||
Parameters =
|
||||
{
|
||||
new OpenApiParameter
|
||||
{
|
||||
Name = "cookie",
|
||||
In = ParameterLocation.Query,
|
||||
Required = false,
|
||||
Schema = new OpenApiSchema { Type = "boolean", Default = new OpenApiBoolean(true) },
|
||||
Example = new OpenApiBoolean(true),
|
||||
Description = "If true, auth service sets the auth cookie."
|
||||
}
|
||||
},
|
||||
RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Required = true,
|
||||
Content =
|
||||
{
|
||||
["application/json"] = new OpenApiMediaType { Schema = loginSchema, Example = loginExample },
|
||||
["multipart/form-data"] = new OpenApiMediaType { Schema = loginSchema, Example = loginExample }
|
||||
}
|
||||
},
|
||||
Responses =
|
||||
{
|
||||
["200"] = new OpenApiResponse { Description = "OK (proxied response)" },
|
||||
["401"] = new OpenApiResponse { Description = "Unauthorized" }
|
||||
}
|
||||
};
|
||||
|
||||
swaggerDoc.Paths[path] = new OpenApiPathItem
|
||||
{
|
||||
Operations =
|
||||
{
|
||||
[OperationType.Post] = operation
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI
|
||||
namespace EnvelopeGenerator.API;
|
||||
|
||||
/// <summary>
|
||||
/// Provides custom claim types for envelope-related information.
|
||||
/// </summary>
|
||||
public static class EnvelopeClaimTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides custom claim types for envelope-related information.
|
||||
/// Claim type for the title of an envelope.
|
||||
/// </summary>
|
||||
public static class EnvelopeClaimTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Claim type for the title of an envelope.
|
||||
/// </summary>
|
||||
public static readonly string Title = $"Envelope{nameof(Title)}";
|
||||
public static readonly string Title = $"Envelope{nameof(Title)}";
|
||||
|
||||
/// <summary>
|
||||
/// Claim type for the ID of an envelope.
|
||||
/// </summary>
|
||||
public static readonly string Id = $"Envelope{nameof(Id)}";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Claim type for the ID of an envelope.
|
||||
/// </summary>
|
||||
public static readonly string Id = $"Envelope{nameof(Id)}";
|
||||
}
|
||||
@@ -17,6 +17,17 @@
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="ClientApp\**" />
|
||||
<Content Remove="ClientApp\**" />
|
||||
<EmbeddedResource Remove="ClientApp\**" />
|
||||
<None Remove="ClientApp\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="yarp.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.Scalar" Version="1.1.8" />
|
||||
<PackageReference Include="DigitalData.Auth.Client" Version="1.3.7" />
|
||||
@@ -28,6 +39,7 @@
|
||||
<PackageReference Include="Scalar.AspNetCore" Version="2.2.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher.Abstraction" Version="3.2.0" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
|
||||
@@ -49,41 +61,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="ClientApp\" />
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.CommonServices\EnvelopeGenerator.CommonServices.vbproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\chunk-35PBLQEP.js">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\chunk-IUSOII6E.js">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\favicon.ico">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\index.html">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\login\index.html">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\main-ZN7C4PGY.js">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\polyfills-N6LQB2YD.js">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ClientApp\envelope-generator-ui\dist\envelope-generator-ui\browser\styles-S5ZWIC2V.css">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,55 +1,69 @@
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Extensions;
|
||||
namespace EnvelopeGenerator.API.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides helper methods for working with envelope-specific authentication claims.
|
||||
/// </summary>
|
||||
public static class EnvelopeAuthExtensions
|
||||
public static class ReceiverClaimExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a claim value by type.
|
||||
/// </summary>
|
||||
/// <param name="user">The current claims principal.</param>
|
||||
/// <param name="claimType">The claim type to resolve.</param>
|
||||
/// <returns>The claim value or null when missing.</returns>
|
||||
public static string? GetClaimValue(this ClaimsPrincipal user, string claimType) => user.FindFirstValue(claimType);
|
||||
private static string GetRequiredClaimOfReceiver(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
var value = user.FindFirstValue(claimType);
|
||||
if (value is not null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var identity = user.Identity;
|
||||
var principalName = identity?.Name ?? "(anonymous)";
|
||||
var authType = identity?.AuthenticationType ?? "(none)";
|
||||
var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
|
||||
var message = $"Required claim '{claimType}' is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated envelope UUID from the claims.
|
||||
/// </summary>
|
||||
public static string? GetAuthEnvelopeUuid(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
public static string GetEnvelopeUuidOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.NameIdentifier);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated receiver signature from the claims.
|
||||
/// </summary>
|
||||
public static string? GetAuthReceiverSignature(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Hash);
|
||||
public static string GetReceiverSignatureOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.Hash);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated receiver display name from the claims.
|
||||
/// </summary>
|
||||
public static string? GetAuthReceiverName(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Name);
|
||||
public static string GetReceiverNameOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.Name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated receiver email address from the claims.
|
||||
/// </summary>
|
||||
public static string? GetAuthReceiverMail(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Email);
|
||||
public static string GetReceiverMailOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(ClaimTypes.Email);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated envelope title from the claims.
|
||||
/// </summary>
|
||||
public static string? GetAuthEnvelopeTitle(this ClaimsPrincipal user) => user.FindFirstValue(EnvelopeClaimTypes.Title);
|
||||
public static string GetEnvelopeTitleOfReceiver(this ClaimsPrincipal user) => user.GetRequiredClaimOfReceiver(EnvelopeClaimTypes.Title);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authenticated envelope identifier from the claims.
|
||||
/// </summary>
|
||||
public static int? GetAuthEnvelopeId(this ClaimsPrincipal user)
|
||||
public static int GetEnvelopeIdOfReceiver(this ClaimsPrincipal user)
|
||||
{
|
||||
var envIdStr = user.FindFirstValue(EnvelopeClaimTypes.Id);
|
||||
return int.TryParse(envIdStr, out var envId) ? envId : null;
|
||||
var envIdStr = user.GetRequiredClaimOfReceiver(EnvelopeClaimTypes.Id);
|
||||
if (!int.TryParse(envIdStr, out var envId))
|
||||
{
|
||||
throw new InvalidOperationException($"Claim '{EnvelopeClaimTypes.Id}' is not a valid integer.");
|
||||
}
|
||||
|
||||
return envId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,4 +98,4 @@ public static class EnvelopeAuthExtensions
|
||||
new ClaimsPrincipal(claimsIdentity),
|
||||
authProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
EnvelopeGenerator.API/Extensions/SenderClaimExtensions.cs
Normal file
95
EnvelopeGenerator.API/Extensions/SenderClaimExtensions.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace EnvelopeGenerator.API.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for extracting user information from a <see cref="ClaimsPrincipal"/>.
|
||||
/// </summary>
|
||||
public static class SenderClaimExtensions
|
||||
{
|
||||
private static string GetRequiredClaimOfSender(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
var value = user.FindFirstValue(claimType);
|
||||
if (value is not null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var identity = user.Identity;
|
||||
var principalName = identity?.Name ?? "(anonymous)";
|
||||
var authType = identity?.AuthenticationType ?? "(none)";
|
||||
var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
|
||||
var message = $"Required claim '{claimType}' is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
private static string GetRequiredClaimOfSender(this ClaimsPrincipal user, params string[] claimTypes)
|
||||
{
|
||||
string? value = null;
|
||||
|
||||
foreach (var claimType in claimTypes)
|
||||
{
|
||||
value = user.FindFirstValue(claimType);
|
||||
if (value is not null)
|
||||
return value;
|
||||
}
|
||||
|
||||
var identity = user.Identity;
|
||||
var principalName = identity?.Name ?? "(anonymous)";
|
||||
var authType = identity?.AuthenticationType ?? "(none)";
|
||||
var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
|
||||
var message = $"Required claim among [{string.Join(", ", claimTypes)}] is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's ID from the claims. Throws an exception if the ID is missing or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The user's ID as an integer.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the user ID claim is missing or invalid.</exception>
|
||||
public static int GetId(this ClaimsPrincipal user)
|
||||
{
|
||||
var idValue = user.GetRequiredClaimOfSender(ClaimTypes.NameIdentifier, "sub");
|
||||
|
||||
if (!int.TryParse(idValue, out var result))
|
||||
{
|
||||
throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the username from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The username as a string.</returns>
|
||||
public static string GetUsername(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's surname (last name) from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The surname as a string.</returns>
|
||||
public static string GetName(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Surname);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's given name (first name) from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The given name as a string.</returns>
|
||||
public static string GetPrename(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.GivenName);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's email address from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The email address as a string.</returns>
|
||||
public static string GetEmail(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Email);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Middleware;
|
||||
namespace EnvelopeGenerator.API.Middleware;
|
||||
|
||||
using DigitalData.Core.Exceptions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public record Auth(string? AccessCode = null, string? SmsCode = null, string? AuthenticatorCode = null, bool UserSelectSMS = default)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the keys and default values used for authentication token handling
|
||||
@@ -24,5 +24,5 @@ public class AuthTokenKeys
|
||||
/// <summary>
|
||||
/// Gets the expected audience value for the authentication token.
|
||||
/// </summary>
|
||||
public string Audience { get; init; } = "sign-flow-gen.digitaldata.works";
|
||||
public string Audience { get; init; } = "sign-flow.digitaldata.works";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models
|
||||
namespace EnvelopeGenerator.API.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a hyperlink for contact purposes with various HTML attributes.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class Culture
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class Cultures : List<Culture>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class CustomImages : Dictionary<string, Image>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class ErrorViewModel
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class Image
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Repräsentiert ein Login-Modell mit erforderlichem Passwort und optionaler ID und Benutzername.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
public class MainViewModel
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
public record Annotation : IAnnotation
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
public class AnnotationParams
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
/// <summary>
|
||||
/// The Background is an annotation for the PSPDF Kit. However, it has no function.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
public record Color
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models.PsPdfKitAnnotation;
|
||||
namespace EnvelopeGenerator.API.Models.PsPdfKitAnnotation;
|
||||
|
||||
public interface IAnnotation
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Models;
|
||||
namespace EnvelopeGenerator.API.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the parameters for two-factor authentication (2FA) registration.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using DigitalData.Core.API;
|
||||
using DigitalData.Core.Application;
|
||||
using EnvelopeGenerator.Infrastructure;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -11,11 +12,11 @@ using DigitalData.UserManager.DependencyInjection;
|
||||
using EnvelopeGenerator.Application;
|
||||
using DigitalData.Auth.Client;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||
using EnvelopeGenerator.API.Models;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using DigitalData.Core.Abstractions.Security.Extensions;
|
||||
using EnvelopeGenerator.GeneratorAPI.Middleware;
|
||||
using EnvelopeGenerator.API.Middleware;
|
||||
using NLog.Web;
|
||||
using NLog;
|
||||
|
||||
@@ -26,6 +27,8 @@ try
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Configuration.AddJsonFile("yarp.json", optional: true, reloadOnChange: true);
|
||||
|
||||
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
|
||||
if (!builder.Environment.IsDevelopment())
|
||||
@@ -39,6 +42,8 @@ try
|
||||
var deferredProvider = new DeferredServiceProvider();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
|
||||
|
||||
// CORS Policy
|
||||
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
|
||||
@@ -89,7 +94,7 @@ try
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
}
|
||||
},
|
||||
@@ -102,6 +107,8 @@ try
|
||||
{
|
||||
options.IncludeXmlComments(xmlFile);
|
||||
}
|
||||
|
||||
options.DocumentFilter<EnvelopeGenerator.API.Documentation.AuthProxyDocumentFilter>();
|
||||
});
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
@@ -170,6 +177,16 @@ try
|
||||
options.SlidingExpiration = true;
|
||||
});
|
||||
|
||||
builder.Services.AddAuthorizationBuilder()
|
||||
.AddPolicy(AuthPolicy.SenderOrReceiver, policy =>
|
||||
policy.RequireRole(Role.Sender, Role.Receiver.Full))
|
||||
.AddPolicy(AuthPolicy.Sender, policy =>
|
||||
policy.RequireRole(Role.Sender))
|
||||
.AddPolicy(AuthPolicy.Receiver, policy =>
|
||||
policy.RequireRole(Role.Receiver.Full))
|
||||
.AddPolicy(AuthPolicy.ReceiverTFA, policy =>
|
||||
policy.RequireRole(Role.Receiver.TFA));
|
||||
|
||||
// User manager
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
builder.Services.AddUserManager<EGDbContext>();
|
||||
@@ -241,6 +258,7 @@ try
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapReverseProxy();
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
}
|
||||
},
|
||||
"AuthClientParams": {
|
||||
"Url": "https://localhost:7192/auth-hub",
|
||||
"Url": "http://172.24.12.39:9090/auth-hub",
|
||||
"PublicKeys": [
|
||||
{
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "sign-flow-gen.digitaldata.works"
|
||||
"Audience": "sign-flow.digitaldata.works"
|
||||
}
|
||||
],
|
||||
"RetryDelay": "00:00:05"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"AllowedOrigins": [ "http://localhost:4200" ],
|
||||
"AllowedOrigins": [ "http://localhost:4200", "http://172.24.12.39:9090", "https://localhost:8088", "http://localhost:5131", "http://localhost:7192" ],
|
||||
"ConnectionStrings": {
|
||||
"Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;",
|
||||
"DbMigrationTest": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM_DATA_MIGR_TEST;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"
|
||||
@@ -24,11 +24,11 @@
|
||||
}
|
||||
},
|
||||
"AuthClientParams": {
|
||||
"Url": "https://localhost:7192/auth-hub",
|
||||
"Url": "http://172.24.12.39:9090/auth-hub",
|
||||
"PublicKeys": [
|
||||
{
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "sign-flow-gen.digitaldata.works"
|
||||
"Audience": "sign-flow.digitaldata.works"
|
||||
}
|
||||
],
|
||||
"RetryDelay": "00:00:05"
|
||||
@@ -37,7 +37,7 @@
|
||||
"Cookie": "AuthToken",
|
||||
"QueryString": "AuthToken",
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "work-flow.digitaldata.works"
|
||||
"Audience": "sign-flow.digitaldata.works"
|
||||
},
|
||||
"PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==",
|
||||
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="3em" height="2.5em" viewBox="0 0 24 24" style="stroke: #a9a8ad;">
|
||||
<path opacity="0.5" d="M15.9998 2L14.9998 2C12.1714 2 10.7576 2.00023 9.87891 2.87891C9.00023 3.75759 9.00023 5.1718 9.00023 8.00023L9.00023 16.0002C9.00023 18.8287 9.00023 20.2429 9.87891 21.1215C10.7574 22 12.1706 22 14.9976 22L14.9998 22L15.9998 22C18.8282 22 20.2424 22 21.1211 21.1213C21.9998 20.2426 21.9998 18.8284 21.9998 16L21.9998 8L21.9998 7.99998C21.9998 5.17157 21.9998 3.75736 21.1211 2.87868C20.2424 2 18.8282 2 15.9998 2Z" fill="#1C274C"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.25098 11.999C1.25098 11.5848 1.58676 11.249 2.00098 11.249L13.9735 11.249L12.0129 9.56845C11.6984 9.29889 11.662 8.82541 11.9315 8.51092C12.2011 8.19642 12.6746 8.16 12.9891 8.42957L16.4891 11.4296C16.6553 11.5721 16.751 11.7801 16.751 11.999C16.751 12.218 16.6553 12.426 16.4891 12.5685L12.9891 15.5685C12.6746 15.838 12.2011 15.8016 11.9315 15.4871C11.662 15.1726 11.6984 14.6991 12.0129 14.4296L13.9735 12.749L2.00098 12.749C1.58676 12.749 1.25098 12.4132 1.25098 11.999Z" fill="#1C274C"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 264 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
25
EnvelopeGenerator.API/yarp.json
Normal file
25
EnvelopeGenerator.API/yarp.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"ReverseProxy": {
|
||||
"Routes": {
|
||||
"auth-login": {
|
||||
"ClusterId": "auth-hub",
|
||||
"Match": {
|
||||
"Path": "/api/auth",
|
||||
"Methods": [ "POST" ]
|
||||
},
|
||||
"Transforms": [
|
||||
{ "PathSet": "/api/auth/sign-flow" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"Clusters": {
|
||||
"auth-hub": {
|
||||
"Destinations": {
|
||||
"primary": {
|
||||
"Address": "http://172.24.12.39:9090"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TCommand"></typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class CreateCommandHandler<TCommand, TEntity> : IRequestHandler<TCommand, TEntity>
|
||||
where TCommand : class, IRequest<TEntity>
|
||||
where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected readonly IRepository<TEntity> Repository;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public CreateCommandHandler(IRepository<TEntity> repository)
|
||||
{
|
||||
Repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public Task<TEntity> Handle(TCommand request, CancellationToken cancel) => Repository.CreateAsync(request, cancel);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using MediatR;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TUpdateDto"></typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public abstract record UpdateCommand<TUpdateDto, TEntity> : IRequest where TUpdateDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TUpdateDto Update { get; init; } = null!;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Expression<Func<TEntity, bool>> BuildQueryExpression();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TCommand"></typeparam>
|
||||
/// <typeparam name="TUpdateDto"></typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class UpdateCommandHandler<TCommand, TUpdateDto, TEntity> : IRequestHandler<TCommand>
|
||||
where TUpdateDto : class
|
||||
where TEntity : class
|
||||
where TCommand : UpdateCommand<TUpdateDto, TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected readonly IRepository<TEntity> Repository;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public UpdateCommandHandler(IRepository<TEntity> repository)
|
||||
{
|
||||
Repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public Task Handle(TCommand request, CancellationToken cancel)
|
||||
=> Repository.UpdateAsync(request.Update, request.BuildQueryExpression(), cancel);
|
||||
}
|
||||
@@ -1,31 +1,37 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
namespace EnvelopeGenerator.Application.Common.Dto;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Dto
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record EmailTemplateDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public record EmailTemplateDto
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Id{ get; init; }
|
||||
public int Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Name { get; init; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Body { get; set; }
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; init; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public required string Subject { get; set; }
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Body { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Subject { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
|
||||
/// </summary>
|
||||
public DateTime? ChangedWhen { get; init; }
|
||||
};
|
||||
@@ -28,8 +28,8 @@ public class MappingProfile : Profile
|
||||
CreateMap<EmailTemplate, EmailTemplateDto>();
|
||||
CreateMap<Envelope, EnvelopeDto>();
|
||||
CreateMap<Document, DocumentDto>();
|
||||
CreateMap<Domain.Entities.History, HistoryDto>();
|
||||
CreateMap<Domain.Entities.History, HistoryCreateDto>();
|
||||
CreateMap<Domain.Entities.History, HistoryDto>().ForMember(dest => dest.ActionDate, opt => opt.MapFrom(src => src.ChangedWhen));
|
||||
CreateMap<Domain.Entities.History, HistoryCreateDto>().ForMember(dest => dest.ActionDate, opt => opt.MapFrom(src => src.ChangedWhen));
|
||||
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverDto>();
|
||||
CreateMap<Domain.Entities.EnvelopeReceiver, EnvelopeReceiverSecretDto>();
|
||||
CreateMap<EnvelopeType, EnvelopeTypeDto>();
|
||||
@@ -44,15 +44,15 @@ public class MappingProfile : Profile
|
||||
CreateMap<EmailTemplateDto, EmailTemplate>();
|
||||
CreateMap<EnvelopeDto, Envelope>();
|
||||
CreateMap<DocumentDto, Document>();
|
||||
CreateMap<HistoryDto, Domain.Entities.History>();
|
||||
CreateMap<HistoryCreateDto, Domain.Entities.History>();
|
||||
CreateMap<HistoryDto, Domain.Entities.History>().ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(src => src.ActionDate));
|
||||
CreateMap<HistoryCreateDto, Domain.Entities.History>().ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(src => src.ActionDate));
|
||||
CreateMap<EnvelopeReceiverDto, Domain.Entities.EnvelopeReceiver>();
|
||||
CreateMap<EnvelopeTypeDto, EnvelopeType>();
|
||||
CreateMap<ReceiverDto, Domain.Entities.Receiver>().ForMember(rcv => rcv.EnvelopeReceivers, rcvReadDto => rcvReadDto.Ignore());
|
||||
CreateMap<EnvelopeReceiverReadOnlyCreateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, Domain.Entities.EnvelopeReceiverReadOnly>();
|
||||
CreateMap<AnnotationCreateDto, ElementAnnotation>()
|
||||
.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
|
||||
.MapAddedWhen();
|
||||
|
||||
// Messaging mappings
|
||||
// for GTX messaging
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for applying auditing timestamps during AutoMapper mappings.
|
||||
/// </summary>
|
||||
public static class AutoMapperAuditingExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps <see cref="IHasAddedWhen.AddedWhen"/> to the current UTC time.
|
||||
/// </summary>
|
||||
public static IMappingExpression<TSource, TDestination> MapAddedWhen<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
|
||||
where TDestination : IHasAddedWhen
|
||||
=> expression.ForMember(dest => dest.AddedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
|
||||
|
||||
/// <summary>
|
||||
/// Maps <see cref="IHasChangedWhen.ChangedWhen"/> to the current UTC time.
|
||||
/// </summary>
|
||||
public static IMappingExpression<TSource, TDestination> MapChangedWhen<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
|
||||
where TDestination : IHasChangedWhen
|
||||
=> expression.ForMember(dest => dest.ChangedWhen, opt => opt.MapFrom(_ => DateTime.UtcNow));
|
||||
}
|
||||
@@ -3,8 +3,19 @@ using System.Text;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="envelopeReceiverId"></param>
|
||||
/// <param name="exception"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
|
||||
{
|
||||
var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
|
||||
@@ -18,6 +29,15 @@ namespace EnvelopeGenerator.Application.Common.Extensions
|
||||
logger.Log(LogLevel.Error, exception, sb.AppendLine(exception.Message).ToString(), args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="signature"></param>
|
||||
/// <param name="exception"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="args"></param>
|
||||
public static void LogEnvelopeError(this ILogger logger, string? uuid, string? signature = null, Exception? exception = null, string? message = null, params object?[] args)
|
||||
{
|
||||
var sb = new StringBuilder($"Envelope Uuid: {uuid}");
|
||||
@@ -34,6 +54,11 @@ namespace EnvelopeGenerator.Application.Common.Extensions
|
||||
logger.Log(LogLevel.Error, exception, sb.ToString(), args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelopeReceiverTuple"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToTitle(this (string? UUID, string? Signature) envelopeReceiverTuple)
|
||||
{
|
||||
return $"UUID is {envelopeReceiverTuple.UUID} and signature is {envelopeReceiverTuple.Signature}";
|
||||
|
||||
@@ -2,16 +2,42 @@
|
||||
using Microsoft.Extensions.Localization;
|
||||
using System.Text.Encodings.Web;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Common.Extensions
|
||||
namespace EnvelopeGenerator.Application.Common.Extensions;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class XSSExtensions
|
||||
{
|
||||
public static class XSSExtensions
|
||||
{
|
||||
public static string? TryEncode(this string? value, UrlEncoder encoder) => value is null ? value : encoder.Encode(value);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <returns></returns>
|
||||
public static string? TryEncode(this string? value, UrlEncoder encoder) => value is null ? value : encoder.Encode(value);
|
||||
|
||||
public static string? TryEncode(this LocalizedString? value, UrlEncoder encoder) => value is null ? null : encoder.Encode(value);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <returns></returns>
|
||||
public static string? TryEncode(this LocalizedString? value, UrlEncoder encoder) => value is null ? null : encoder.Encode(value);
|
||||
|
||||
public static string? TrySanitize(this string? html, HtmlSanitizer sanitizer) => html is null ? html : sanitizer.Sanitize(html);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="html"></param>
|
||||
/// <param name="sanitizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string? TrySanitize(this string? html, HtmlSanitizer sanitizer) => html is null ? html : sanitizer.Sanitize(html);
|
||||
|
||||
public static string? TrySanitize(this LocalizedString? html, HtmlSanitizer sanitizer) => html is null ? null : sanitizer.Sanitize(html);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="html"></param>
|
||||
/// <param name="sanitizer"></param>
|
||||
/// <returns></returns>
|
||||
public static string? TrySanitize(this LocalizedString? html, HtmlSanitizer sanitizer) => html is null ? null : sanitizer.Sanitize(html);
|
||||
}
|
||||
@@ -1,12 +1,31 @@
|
||||
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using EnvelopeGenerator.Application.Common.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public record CreateDocStatusCommand : ModifyDocStatusCommandBase
|
||||
public record CreateDocStatusCommand : ModifyDocStatusCommandBase, IRequest<DocumentStatus>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets timestamp when this record was added. Returns the StatusChangedWhen value.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen => StatusChangedWhen;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateDocStatusCommandHandler : CreateCommandHandler<CreateDocStatusCommand, DocumentStatus>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public CreateDocStatusCommandHandler(IRepository<DocumentStatus> repository) : base(repository)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.DocStatus.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
@@ -16,10 +17,12 @@ public class MappingProfile : Profile
|
||||
{
|
||||
CreateMap<CreateDocStatusCommand, DocumentStatus>()
|
||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore());
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
||||
.MapAddedWhen();
|
||||
|
||||
CreateMap<UpdateDocStatusCommand, DocumentStatus>()
|
||||
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore());
|
||||
.ForMember(dest => dest.Receiver, opt => opt.Ignore())
|
||||
.MapChangedWhen();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
using DigitalData.Core.Exceptions;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Documents.Queries;
|
||||
|
||||
@@ -12,14 +13,14 @@ namespace EnvelopeGenerator.Application.Documents.Queries;
|
||||
/// </summary>
|
||||
/// <param name="Id">The unique identifier of the document. Optional.</param>
|
||||
/// <param name="EnvelopeId">The identifier of the envelope associated with the document. Optional.</param>
|
||||
public record ReadDocumentQuery(int? Id = null, int? EnvelopeId = null) : IRequest<DocumentDto?>
|
||||
public record ReadDocumentQuery(int? Id = null, int? EnvelopeId = null) : IRequest<DocumentDto>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles queries for reading <see cref="Document"/> data based on either the document ID or the envelope ID.
|
||||
/// </summary>
|
||||
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, DocumentDto?>
|
||||
public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, DocumentDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// TempRepo for accessing <see cref="Document"/> entities.
|
||||
@@ -50,20 +51,19 @@ public class ReadDocumentQueryHandler : IRequestHandler<ReadDocumentQuery, Docum
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown when neither <see cref="ReadDocumentQuery.Id"/> nor <see cref="ReadDocumentQuery.EnvelopeId"/> is provided.
|
||||
/// </exception>
|
||||
public async Task<DocumentDto?> Handle(ReadDocumentQuery query, CancellationToken cancel)
|
||||
public async Task<DocumentDto> Handle(ReadDocumentQuery query, CancellationToken cancel)
|
||||
{
|
||||
if (query.Id is not null)
|
||||
{
|
||||
var doc = await _repo.ReadOnly().Where(d => d.Id == query.Id).FirstOrDefaultAsync(cancel);
|
||||
var doc = await _repo.Query.Where(d => d.Id == query.Id).FirstOrDefaultAsync(cancel);
|
||||
return _mapper.Map<DocumentDto>(doc);
|
||||
}
|
||||
else if (query.EnvelopeId is not null)
|
||||
{
|
||||
var doc = await _repo.ReadOnly().Where(d => d.EnvelopeId == query.EnvelopeId).FirstOrDefaultAsync(cancel);
|
||||
var doc = await _repo.Query.Where(d => d.EnvelopeId == query.EnvelopeId).FirstOrDefaultAsync(cancel);
|
||||
return _mapper.Map<DocumentDto>(doc);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"Invalid {nameof(ReadDocumentQuery)}: either {nameof(query.Id)} or {nameof(query.EnvelopeId)} must be provided.");
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using EnvelopeGenerator.Domain;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
|
||||
|
||||
/// <summary>
|
||||
/// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte.
|
||||
/// Erbt von <see cref="EmailTemplateQuery"/> und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage.<br/><br/>
|
||||
/// Beispiele:<br/>
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
|
||||
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.<br/>
|
||||
/// </summary>
|
||||
public record ResetEmailTemplateCommand : EmailTemplateQuery, IRequest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="orginal"></param>
|
||||
public ResetEmailTemplateCommand(EmailTemplateQuery? orginal = null) : base(orginal ?? new())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id">Die optionale ID der E-Mail-Vorlage, die zurückgesetzt werden soll.</param>
|
||||
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional).</param>
|
||||
public ResetEmailTemplateCommand(int? Id = null, EmailTemplateType? Type = null) : base(Id, Type)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -1,11 +1,38 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using MediatR;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset;
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte.
|
||||
/// Erbt von <see cref="IEmailTemplateQuery"/> und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage.<br/><br/>
|
||||
/// </summary>
|
||||
public record ResetEmailTemplateCommand : IEmailTemplateQuery, IRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
||||
/// </summary>
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:<br/>
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
|
||||
/// 7 - DocumentRejected_ADM (für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 8 - DocumentRejected_REC (für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </summary>
|
||||
public EmailTemplateType? Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -41,7 +68,7 @@ public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTempla
|
||||
foreach (var temp in temps)
|
||||
{
|
||||
var def = Defaults.Where(t => t.Name == temp.Name).FirstOrDefault();
|
||||
if(def is not null)
|
||||
if (def is not null)
|
||||
await _repository.UpdateAsync(def, t => t.Id == temp.Id, cancel);
|
||||
}
|
||||
}
|
||||
@@ -113,4 +140,4 @@ public class ResetEmailTemplateCommandHandler : IRequestHandler<ResetEmailTempla
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using MediatR;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zum Aktualisieren einer E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
/// <param name="Body">
|
||||
/// (Optional)Der neue Inhalt des E-Mail-Textkörpers. Wenn null, bleibt der vorhandene Inhalt unverändert.
|
||||
/// </param>
|
||||
/// <param name="Subject">
|
||||
/// (Optional) Der neue Betreff der E-Mail. Wenn null, bleibt der vorhandene Betreff unverändert.
|
||||
/// </param>
|
||||
public record UpdateEmailTemplateCommand(string? Body = null, string? Subject = null) : IRequest
|
||||
{
|
||||
/// <param>
|
||||
/// Die Abfrage, die die E-Mail-Vorlage darstellt, die aktualisiert werden soll.
|
||||
/// </param>
|
||||
[JsonIgnore]
|
||||
public EmailTemplateQuery? EmailTemplateQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public DateTime ChangedWhen { get; init; } = DateTime.Now;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Update;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateEmailTemplateCommandHandler : IRequestHandler<UpdateEmailTemplateCommand>
|
||||
{
|
||||
private readonly IRepository<EmailTemplate> _repository;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository, IMapper mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
/// <exception cref="NotFoundException"></exception>
|
||||
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
|
||||
public async Task Handle(UpdateEmailTemplateCommand request, CancellationToken cancel)
|
||||
{
|
||||
EmailTemplateDto? tempDto;
|
||||
|
||||
if (request.EmailTemplateQuery?.Id is int id)
|
||||
{
|
||||
var temp = await _repository.ReadOnly().Where(t => t.Id == id).FirstOrDefaultAsync(cancel);
|
||||
tempDto = _mapper.Map<EmailTemplateDto>(temp);
|
||||
}
|
||||
else if (request!.EmailTemplateQuery!.Type is EmailTemplateType type)
|
||||
{
|
||||
var temp = await _repository.ReadOnly().Where(t => t.Name == type.ToString()).FirstOrDefaultAsync(cancel);
|
||||
tempDto = _mapper.Map<EmailTemplateDto>(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Both id and type is null. Id: " + request.EmailTemplateQuery.Id +". Type: " + request.EmailTemplateQuery.Type.ToString());
|
||||
}
|
||||
|
||||
if (tempDto == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (request.Body is not null)
|
||||
tempDto.Body = request.Body;
|
||||
|
||||
if (request.Subject is not null)
|
||||
tempDto.Subject = request.Subject;
|
||||
|
||||
await _repository.UpdateAsync(tempDto, t => t.Id == tempDto.Id, cancel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using EnvelopeGenerator.Application.Common.Commands;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Body"></param>
|
||||
/// <param name="Subject"></param>
|
||||
public record EmailTemplateUpdateDto(string Body, string Subject);
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zum Aktualisieren einer E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
public record UpdateEmailTemplateCommand : UpdateCommand<EmailTemplateUpdateDto, EmailTemplate>, IEmailTemplateQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
||||
/// </summary>
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:<br/>
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
|
||||
/// 7 - DocumentRejected_ADM (für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 8 - DocumentRejected_REC (für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </summary>
|
||||
public EmailTemplateType? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Expression<Func<EmailTemplate, bool>> BuildQueryExpression()
|
||||
=> Id is int id
|
||||
? temp => temp.Id == id
|
||||
: temp => temp!.Name == Type.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateEmailTemplateCommandHandler : UpdateCommandHandler<UpdateEmailTemplateCommand, EmailTemplateUpdateDto, EmailTemplate>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repository"></param>
|
||||
public UpdateEmailTemplateCommandHandler(IRepository<EmailTemplate> repository) : base(repository)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates;
|
||||
|
||||
/// <summary>
|
||||
/// Repräsentiert eine Abfrage für E-Mail-Vorlagen, die für Absender und Empfänger von Umschlägen verwendet werden.
|
||||
/// Die Standardkultur ist "de-DE".
|
||||
/// </summary>
|
||||
/// <param name="Id">Die eindeutige Kennung der E-Mail-Vorlage (optional).</param>
|
||||
/// <param name="Type">Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.
|
||||
/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.
|
||||
/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.
|
||||
/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </param>
|
||||
public record EmailTemplateQuery(int? Id = null, EmailTemplateType? Type = null)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Schnittstelle für Abfragen von E-Mail-Vorlagen dar, die für Absender und Empfänger von Umschlägen verwendet werden.
|
||||
/// Die Standardkultur ist "de-DE".
|
||||
/// </summary>
|
||||
public interface IEmailTemplateQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
||||
/// </summary>
|
||||
int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:<br/>
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
|
||||
/// 7 - DocumentRejected_ADM (für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 8 - DocumentRejected_REC (für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </summary>
|
||||
EmailTemplateType? Type { get; set; }
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
using EnvelopeGenerator.Application.Common.Extensions;
|
||||
using EnvelopeGenerator.Application.EmailTemplates.Commands;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public class MappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public MappingProfile()
|
||||
{
|
||||
CreateMap<EmailTemplate, ReadEmailTemplateResponse>();
|
||||
CreateMap<EmailTemplate, EmailTemplateDto>();
|
||||
|
||||
CreateMap<EmailTemplateUpdateDto, EmailTemplate>()
|
||||
.MapChangedWhen();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
|
||||
/// Diese Klasse erbt von <see cref="EmailTemplateQuery"/>.
|
||||
/// </summary>
|
||||
public record ReadEmailTemplateQuery : EmailTemplateQuery, IRequest<ReadEmailTemplateResponse?>
|
||||
{
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Application.Common.Interfaces.Repositories;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using MediatR;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, ReadEmailTemplateResponse?>
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
|
||||
private readonly IEmailTemplateRepository _repository;
|
||||
|
||||
/// <summary>
|
||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||
/// </summary>
|
||||
/// <param name="mapper">
|
||||
/// <param name="repository">
|
||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||
/// </param>
|
||||
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
|
||||
public ReadEmailTemplateQueryHandler(IMapper mapper, IEmailTemplateRepository repository)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
[Obsolete("Use IRepository")]
|
||||
public async Task<ReadEmailTemplateResponse?> Handle(ReadEmailTemplateQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var temp = request.Id is int id
|
||||
? await _repository.ReadByIdAsync(id)
|
||||
: request.Type is EmailTemplateType type
|
||||
? await _repository.ReadByNameAsync(type)
|
||||
: throw new InvalidOperationException("Either a valid integer ID or a valid EmailTemplateType must be provided in the request.");
|
||||
|
||||
var res = _mapper.Map<ReadEmailTemplateResponse>(temp);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries.Read;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt die Antwort für eine Abfrage von E-Mail-Vorlagen bereit.
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name des Typs
|
||||
/// </summary>
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
|
||||
/// </summary>
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
|
||||
/// </summary>
|
||||
public string? Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
|
||||
/// </summary>
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using AutoMapper;
|
||||
using MediatR;
|
||||
using EnvelopeGenerator.Application.Common.Dto;
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using DigitalData.Core.Exceptions;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries;
|
||||
|
||||
/// <summary>
|
||||
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
|
||||
/// Diese Klasse erbt von <see cref="IEmailTemplateQuery"/>.
|
||||
/// </summary>
|
||||
public record ReadEmailTemplateQuery : IEmailTemplateQuery, IRequest<EmailTemplateDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
||||
/// </summary>
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Typ der E-Mail-Vorlage, z. B. <see cref="EmailTemplateType"/> (optional). Beispiele:<br/>
|
||||
/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.<br/>
|
||||
/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.<br/>
|
||||
/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.<br/>
|
||||
/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.<br/>
|
||||
/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.<br/>
|
||||
/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.<br/>
|
||||
/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.<br/>
|
||||
/// 7 - DocumentRejected_ADM (für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 8 - DocumentRejected_REC (für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.<br/>
|
||||
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
|
||||
/// </summary>
|
||||
public EmailTemplateType? Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, EmailTemplateDto>
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private readonly IRepository<EmailTemplate> _repo;
|
||||
|
||||
/// <summary>
|
||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||
/// </summary>
|
||||
/// <param name="mapper">
|
||||
/// <param name="repo">
|
||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
||||
/// </param>
|
||||
public ReadEmailTemplateQueryHandler(IMapper mapper, IRepository<EmailTemplate> repo)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public async Task<EmailTemplateDto> Handle(ReadEmailTemplateQuery request, CancellationToken cancel)
|
||||
{
|
||||
var query = request.Id is int id
|
||||
? _repo.Query.Where(temp => temp.Id == id)
|
||||
: _repo.Query.Where(temp => temp.Name == request.Type!.ToString());
|
||||
|
||||
var entity = await query.FirstOrDefaultAsync(cancel) ?? throw new NotFoundException();
|
||||
|
||||
return _mapper.Map<EmailTemplateDto>(entity);
|
||||
}
|
||||
}
|
||||
@@ -67,10 +67,11 @@ public static class Extensions
|
||||
/// <param name="key"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<EnvelopeReceiverDto?> ReadEnvelopeReceiverAsync(this IMediator mediator, string key, CancellationToken cancel = default)
|
||||
public static async Task<EnvelopeReceiverDto?> ReadEnvelopeReceiverAsync(this IMediator mediator, string key, CancellationToken cancel = default)
|
||||
{
|
||||
var q = new ReadEnvelopeReceiverQuery() { Key = key };
|
||||
return mediator.Send(q, cancel).Then(envRcvs => envRcvs.FirstOrDefault());
|
||||
var envRcvs = await mediator.Send(q, cancel);
|
||||
return envRcvs.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,12 +82,13 @@ public static class Extensions
|
||||
/// <param name="signature"></param>
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<EnvelopeReceiverDto?> ReadEnvelopeReceiverAsync(this IMediator mediator, string uuid, string signature, CancellationToken cancel = default)
|
||||
public static async Task<EnvelopeReceiverDto?> ReadEnvelopeReceiverAsync(this IMediator mediator, string uuid, string signature, CancellationToken cancel = default)
|
||||
{
|
||||
var q = new ReadEnvelopeReceiverQuery();
|
||||
q.Envelope.Uuid = uuid;
|
||||
q.Receiver.Signature = signature;
|
||||
return mediator.Send(q, cancel).Then(envRcvs => envRcvs.FirstOrDefault());
|
||||
var envRcvs = await mediator.Send(q, cancel);
|
||||
return envRcvs.FirstOrDefault();
|
||||
}
|
||||
/// <summary>
|
||||
/// Verarbeitet <see cref="ReadEnvelopeReceiverQuery"/> und liefert passende <see cref="EnvelopeReceiverDto"/>-Ergebnisse.
|
||||
|
||||
@@ -68,6 +68,6 @@ public class ReceiverAlreadySignedQueryHandler : IRequestHandler<ReceiverAlready
|
||||
/// <returns></returns>
|
||||
public async Task<bool> Handle(ReceiverAlreadySignedQuery request, CancellationToken cancel = default)
|
||||
{
|
||||
return await _repo.ReadOnly().Where(request).Where(h => h.Status == EnvelopeStatus.DocumentSigned).AnyAsync(cancel);
|
||||
return await _repo.Query.Where(request).Where(h => h.Status == EnvelopeStatus.DocumentSigned).AnyAsync(cancel);
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand,
|
||||
if(request.UserReference is null)
|
||||
{
|
||||
var receivers = await _erRepo
|
||||
.ReadOnly()
|
||||
.Query
|
||||
.Where(request)
|
||||
.Include(er => er.Receiver)
|
||||
.ToListAsync(cancel);
|
||||
|
||||
@@ -67,6 +67,7 @@ public class CreateReceiverCommandHandler : IRequestHandler<CreateReceiverComman
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="repo"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public CreateReceiverCommandHandler(IRepository<Receiver> repo, IMapper mapper)
|
||||
{
|
||||
_repo = repo;
|
||||
@@ -81,7 +82,7 @@ public class CreateReceiverCommandHandler : IRequestHandler<CreateReceiverComman
|
||||
/// <returns></returns>
|
||||
public async Task<(ReceiverDto Receiver, bool AlreadyExists)> Handle(CreateReceiverCommand request, CancellationToken cancel)
|
||||
{
|
||||
var receiver = await _repo.ReadOnly()
|
||||
var receiver = await _repo.Query
|
||||
.Where(r => r.EmailAddress == request.EmailAddress)
|
||||
.SingleOrDefaultAsync(cancel);
|
||||
|
||||
|
||||
15
EnvelopeGenerator.Domain/Constants/AuthPolicy.cs
Normal file
15
EnvelopeGenerator.Domain/Constants/AuthPolicy.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace EnvelopeGenerator.Domain.Constants
|
||||
{
|
||||
public static class AuthPolicy
|
||||
{
|
||||
public const string SenderOrReceiver = nameof(SenderOrReceiver) + nameof(AuthPolicy);
|
||||
|
||||
public const string ReceiverOrReceiverTFA = nameof(ReceiverOrReceiverTFA) + nameof(AuthPolicy);
|
||||
|
||||
public const string Sender = nameof(Sender) + nameof(AuthPolicy);
|
||||
|
||||
public const string Receiver = nameof(Receiver) + nameof(AuthPolicy);
|
||||
|
||||
public const string ReceiverTFA = nameof(ReceiverTFA) + nameof(AuthPolicy);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace EnvelopeGenerator.Domain.Constants
|
||||
{
|
||||
public static class ReceiverRole
|
||||
{
|
||||
public const string PreAuth = "PreAuth";
|
||||
public const string FullyAuth = "FullyAuth";
|
||||
}
|
||||
}
|
||||
23
EnvelopeGenerator.Domain/Constants/Role.cs
Normal file
23
EnvelopeGenerator.Domain/Constants/Role.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Constants
|
||||
{
|
||||
public static class Role
|
||||
{
|
||||
[Obsolete("Use Receiver.TFA")]
|
||||
public const string ReceiverTFA = Receiver.TFA;
|
||||
|
||||
[Obsolete("Use Receiver.Full")]
|
||||
public const string ReceiverFull = Receiver.Full;
|
||||
|
||||
public static class Receiver
|
||||
{
|
||||
public const string TFA = "EGReceiverTFA";
|
||||
public const string Full = "EGReceiver";
|
||||
}
|
||||
|
||||
public const string Sender = "EGSender";
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,22 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_CONFIG", Schema = "dbo")]
|
||||
public class Config
|
||||
{
|
||||
[Column("SENDING_PROFILE", TypeName = "int")]
|
||||
[Required]
|
||||
public int SendingProfile { get; set; }
|
||||
[Table("TBSIG_CONFIG", Schema = "dbo")]
|
||||
public class Config
|
||||
{
|
||||
[Column("SENDING_PROFILE", TypeName = "int")]
|
||||
[Required]
|
||||
public int SendingProfile { get; set; }
|
||||
|
||||
[Column("SIGNATURE_HOST", TypeName = "nvarchar(128)")]
|
||||
[Required]
|
||||
public string SignatureHost { get; set; }
|
||||
[Column("SIGNATURE_HOST", TypeName = "nvarchar(128)")]
|
||||
[Required]
|
||||
public string SignatureHost { get; set; }
|
||||
|
||||
[Column("EXTERNAL_PROGRAM_NAME", TypeName = "nvarchar(30)")]
|
||||
public string ExternalProgramName { get; set; }
|
||||
[Column("EXTERNAL_PROGRAM_NAME", TypeName = "nvarchar(30)")]
|
||||
public string ExternalProgramName { get; set; }
|
||||
|
||||
[Column("EXPORT_PATH", TypeName = "nvarchar(256)")]
|
||||
public string ExportPath { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[Column("EXPORT_PATH", TypeName = "nvarchar(256)")]
|
||||
public string ExportPath { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using System;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
#if NETFRAMEWORK
|
||||
using System.Drawing;
|
||||
using System.Collections.Generic;
|
||||
@@ -8,81 +11,77 @@ using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_ENVELOPE_DOCUMENT", Schema = "dbo")]
|
||||
public class Document : IHasEnvelope
|
||||
{
|
||||
public Document()
|
||||
[Table("TBSIG_ENVELOPE_DOCUMENT", Schema = "dbo")]
|
||||
public class Document : IHasEnvelope, IHasAddedWhen
|
||||
{
|
||||
public Document()
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
Elements = Enumerable.Empty<Signature>().ToList();
|
||||
Elements = Enumerable.Empty<Signature>().ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
#if NETFRAMEWORK
|
||||
= 0;
|
||||
#endif
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("BYTE_DATA", TypeName = "varbinary(max)")]
|
||||
public byte[]
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
ByteData { get; set; }
|
||||
|
||||
#region File
|
||||
[Column("FILENAME", TypeName = "nvarchar(256)")]
|
||||
public string Filename { get; set; }
|
||||
|
||||
[Column("FILEPATH", TypeName = "nvarchar(256)")]
|
||||
public string Filepath { get; set; }
|
||||
|
||||
[Column("FILENAME_ORIGINAL", TypeName = "nvarchar(256)")]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
FileNameOriginal { get; set; }
|
||||
#endregion
|
||||
|
||||
public virtual List<Signature>
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Elements { get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public bool IsTempFile { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Bitmap Thumbnail { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public int PageCount { get; set; }
|
||||
#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
#if NETFRAMEWORK
|
||||
= 0;
|
||||
#endif
|
||||
|
||||
[Column("BYTE_DATA", TypeName = "varbinary(max)")]
|
||||
public byte[]
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ByteData { get; set; }
|
||||
|
||||
#region File
|
||||
[Column("FILENAME", TypeName = "nvarchar(256)")]
|
||||
public string Filename { get; set; }
|
||||
|
||||
[Column("FILEPATH", TypeName = "nvarchar(256)")]
|
||||
public string Filepath { get; set; }
|
||||
|
||||
[Column("FILENAME_ORIGINAL", TypeName = "nvarchar(256)")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
FileNameOriginal { get; set; }
|
||||
#endregion
|
||||
|
||||
public virtual List<Signature>
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Elements { get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public bool IsTempFile { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Bitmap Thumbnail { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public int PageCount { get; set; }
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,65 +1,62 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using DigitalData.Core.Abstractions.Interfaces;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_DOCUMENT_STATUS", Schema = "dbo")]
|
||||
public class DocumentStatus : IHasEnvelope, IHasReceiver, IEntity
|
||||
{
|
||||
public DocumentStatus()
|
||||
[Table("TBSIG_DOCUMENT_STATUS", Schema = "dbo")]
|
||||
public class DocumentStatus : IHasEnvelope, IHasReceiver, IEntity, IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
// TODO: * check Form Application and remove default value
|
||||
public DocumentStatus()
|
||||
{
|
||||
// TODO: * check Form Application and remove default value
|
||||
#if NETFRAMEWORK
|
||||
Status = Constants.DocumentStatus.Created;
|
||||
Status = Constants.DocumentStatus.Created;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
[Required]
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public Constants.DocumentStatus Status { get; set; }
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public Constants.DocumentStatus Status { get; set; }
|
||||
|
||||
[Column("VALUE", TypeName = "nvarchar(max)")]
|
||||
public string Value { get; set; }
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if NET
|
||||
?
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("VALUE", TypeName = "nvarchar(max)")]
|
||||
public string Value { get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
Envelope { get; set; }
|
||||
|
||||
[ForeignKey("ReceiverId")]
|
||||
public virtual Receiver
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("ReceiverId")]
|
||||
public virtual Receiver
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Receiver { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,92 +1,85 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT_ANNOTATION")]
|
||||
public class ElementAnnotation
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID", TypeName = "bigint")]
|
||||
public long Id { get; set; }
|
||||
[Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT_ANNOTATION")]
|
||||
public class ElementAnnotation : IHasAddedWhen, IUpdateAuditable
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID", TypeName = "bigint")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ELEMENT_ID", TypeName = "int")]
|
||||
public int ElementId { get; set; }
|
||||
[Required]
|
||||
[Column("ELEMENT_ID", TypeName = "int")]
|
||||
public int ElementId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("NAME", TypeName = "nvarchar(100)")]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[Column("NAME", TypeName = "nvarchar(100)")]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("VALUE", TypeName = "nvarchar(max)")]
|
||||
public string Value { get; set; }
|
||||
[Required]
|
||||
[Column("VALUE", TypeName = "nvarchar(max)")]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("TYPE", TypeName = "nvarchar(50)")]
|
||||
public string Type { get; set; }
|
||||
[Required]
|
||||
[Column("TYPE", TypeName = "nvarchar(50)")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[Column("POSITION_X", TypeName = "float")]
|
||||
public double
|
||||
#if NET
|
||||
?
|
||||
[Column("POSITION_X", TypeName = "float")]
|
||||
public double
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
X { get; set; }
|
||||
X { get; set; }
|
||||
|
||||
[Column("POSITION_Y", TypeName = "float")]
|
||||
public double
|
||||
#if NET
|
||||
?
|
||||
[Column("POSITION_Y", TypeName = "float")]
|
||||
public double
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Y { get; set; }
|
||||
Y { get; set; }
|
||||
|
||||
[Column("WIDTH", TypeName = "float")]
|
||||
public double
|
||||
#if NET
|
||||
?
|
||||
[Column("WIDTH", TypeName = "float")]
|
||||
public double
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Width { get; set; }
|
||||
Width { get; set; }
|
||||
|
||||
[Column("HEIGHT", TypeName = "float")]
|
||||
public double
|
||||
#if NET
|
||||
?
|
||||
[Column("HEIGHT", TypeName = "float")]
|
||||
public double
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Height { get; set; }
|
||||
Height { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO", TypeName = "nvarchar(100)")]
|
||||
[StringLength(100)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
[Column("CHANGED_WHO", TypeName = "nvarchar(100)")]
|
||||
[StringLength(100)]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
ChangedWho { get; set; }
|
||||
|
||||
[ForeignKey("ElementId")]
|
||||
public virtual Signature
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("ElementId")]
|
||||
public virtual Signature
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Element { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
Element { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,44 +1,39 @@
|
||||
using DigitalData.Core.Abstractions.Interfaces;
|
||||
using System;
|
||||
using DigitalData.Core.Abstractions.Interfaces;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_EMAIL_TEMPLATE", Schema = "dbo")]
|
||||
public class EmailTemplate : IEntity
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
[Table("TBSIG_EMAIL_TEMPLATE", Schema = "dbo")]
|
||||
public class EmailTemplate : IEntity, IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("NAME", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
[Column("NAME", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("BODY", TypeName = "nvarchar(max)")]
|
||||
public string Body { get; set; }
|
||||
[Column("BODY", TypeName = "nvarchar(max)")]
|
||||
public string Body { get; set; }
|
||||
|
||||
[Column("SUBJECT", TypeName = "nvarchar(512)")]
|
||||
public string Subject { get; set; }
|
||||
[Column("SUBJECT", TypeName = "nvarchar(512)")]
|
||||
public string Subject { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
[Required]
|
||||
[Column("LANG_CODE", TypeName = "varchar(5)")]
|
||||
public string LangCode { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime ChangedWhen { get; set; }
|
||||
}
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,208 +1,205 @@
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using System;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_ENVELOPE", Schema = "dbo")]
|
||||
public class Envelope
|
||||
{
|
||||
public Envelope()
|
||||
[Table("TBSIG_ENVELOPE", Schema = "dbo")]
|
||||
public class Envelope : IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
// TODO: * Check the Form App and remove the default value
|
||||
public Envelope()
|
||||
{
|
||||
// TODO: * Check the Form App and remove the default value
|
||||
#if NETFRAMEWORK
|
||||
Id = 0;
|
||||
Status = EnvelopeStatus.EnvelopeCreated;
|
||||
Uuid = Guid.NewGuid().ToString();
|
||||
Message = My.Resources.Envelope.Please_read_and_sign_this_document;
|
||||
Title= string.Empty;
|
||||
Comment = string.Empty;
|
||||
Language = "de-DE";
|
||||
SendReminderEmails = false;
|
||||
FirstReminderDays = 0;
|
||||
ReminderIntervalDays = 0;
|
||||
CertificationType = (int)Constants.CertificationType.AdvancedElectronicSignature;
|
||||
UseAccessCode = false;
|
||||
Documents = Enumerable.Empty<Document>().ToList();
|
||||
Histories = Enumerable.Empty<History>().ToList();
|
||||
EnvelopeReceivers = Enumerable.Empty<EnvelopeReceiver>().ToList();
|
||||
Id = 0;
|
||||
Status = EnvelopeStatus.EnvelopeCreated;
|
||||
Uuid = Guid.NewGuid().ToString();
|
||||
Message = My.Resources.Envelope.Please_read_and_sign_this_document;
|
||||
Title = string.Empty;
|
||||
Comment = string.Empty;
|
||||
Language = "de-DE";
|
||||
SendReminderEmails = false;
|
||||
FirstReminderDays = 0;
|
||||
ReminderIntervalDays = 0;
|
||||
CertificationType = (int)Constants.CertificationType.AdvancedElectronicSignature;
|
||||
UseAccessCode = false;
|
||||
Documents = Enumerable.Empty<Document>().ToList();
|
||||
Histories = Enumerable.Empty<History>().ToList();
|
||||
EnvelopeReceivers = Enumerable.Empty<EnvelopeReceiver>().ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USER_ID")]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public EnvelopeStatus Status { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
[Column("MESSAGE", TypeName = "nvarchar(max)")]
|
||||
public string Message { get; set; }
|
||||
|
||||
[Column("EXPIRES_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ExpiresWhen { get; set; }
|
||||
|
||||
[Column("EXPIRES_WARNING_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ExpiresWarningWhen { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("TITLE", TypeName = "nvarchar(128)")]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Title
|
||||
{ get; set; }
|
||||
|
||||
[Column("COMMENT", TypeName = "nvarchar(128)")]
|
||||
public string Comment { get; set; }
|
||||
|
||||
[Column("CONTRACT_TYPE")]
|
||||
public int? ContractType { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public string ContractTypeTranslated => My.Resources.Model.ResourceManager.GetString(ContractType.ToString());
|
||||
#endif
|
||||
|
||||
[Column("LANGUAGE", TypeName = "nvarchar(5)")]
|
||||
public string Language { get; set; }
|
||||
|
||||
[Column("SEND_REMINDER_EMAILS")]
|
||||
public bool SendReminderEmails { get; set; }
|
||||
|
||||
[Column("FIRST_REMINDER_DAYS")]
|
||||
public int? FirstReminderDays { get; set; }
|
||||
|
||||
[Column("REMINDER_INTERVAL_DAYS")]
|
||||
public int? ReminderIntervalDays { get; set; }
|
||||
|
||||
[Column("ENVELOPE_TYPE")]
|
||||
public int? EnvelopeTypeId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
public bool ReadOnly => EnvelopeTypeId == 2;
|
||||
|
||||
[Column("CERTIFICATION_TYPE")]
|
||||
public int? CertificationType { get; set; }
|
||||
|
||||
[Column("USE_ACCESS_CODE")]
|
||||
public bool UseAccessCode { get; set; }
|
||||
|
||||
[Column("FINAL_EMAIL_TO_CREATOR")]
|
||||
public int? FinalEmailToCreator { get; set; }
|
||||
|
||||
[Column("FINAL_EMAIL_TO_RECEIVERS")]
|
||||
public int? FinalEmailToReceivers { get; set; }
|
||||
|
||||
[Column("EXPIRES_WHEN_DAYS")]
|
||||
public int? ExpiresWhenDays { get; set; }
|
||||
|
||||
[Column("EXPIRES_WARNING_WHEN_DAYS")]
|
||||
public int? ExpiresWarningWhenDays { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public User User { get; set; }
|
||||
|
||||
[Column("TFA_ENABLED")]
|
||||
public bool TfaEnabled { get; set; }
|
||||
#if NETFRAMEWORK
|
||||
= false;
|
||||
#endif
|
||||
|
||||
[NotMapped]
|
||||
[Column("DOC_RESULT")]
|
||||
public byte[]
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
DocResult
|
||||
{ get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeTypeId")]
|
||||
public virtual EnvelopeType
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Type
|
||||
{ get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public string CURRENT_WORK_APP { get; set; } = "signFLOW GUI";
|
||||
|
||||
[NotMapped]
|
||||
public bool IsAlreadySent => Status > EnvelopeStatus.EnvelopeSaved;
|
||||
#endif
|
||||
|
||||
public List<Document>
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Documents
|
||||
{ get; set; }
|
||||
|
||||
public List<History>
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Histories
|
||||
{ get; set; }
|
||||
|
||||
public List<EnvelopeReceiver>
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
EnvelopeReceivers
|
||||
{ get; set; }
|
||||
|
||||
//#if NETFRAMEWORK
|
||||
/// <summary>
|
||||
/// Validates whether the receiver and document data are complete.
|
||||
/// </summary>
|
||||
public List<string> ValidateReceiverDocumentData()
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
if (!Documents?.Any() ?? true)
|
||||
errors.Add(My.Resources.Envelope.Missing_Documents);
|
||||
|
||||
if (!EnvelopeReceivers?.Any() ?? true)
|
||||
errors.Add(My.Resources.Envelope.Missing_Receivers);
|
||||
|
||||
if (EnvelopeReceivers?.Any(r => !r.HasEmailAndName) ?? false)
|
||||
errors.Add(My.Resources.Envelope.Incomplete_Receivers);
|
||||
|
||||
return errors;
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USER_ID")]
|
||||
public int UserId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public EnvelopeStatus Status { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
[Column("MESSAGE", TypeName = "nvarchar(max)")]
|
||||
public string Message { get; set; }
|
||||
|
||||
[Column("EXPIRES_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ExpiresWhen { get; set; }
|
||||
|
||||
[Column("EXPIRES_WARNING_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ExpiresWarningWhen { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("TITLE", TypeName = "nvarchar(128)")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Title { get; set; }
|
||||
|
||||
[Column("COMMENT", TypeName = "nvarchar(128)")]
|
||||
public string Comment { get; set; }
|
||||
|
||||
[Column("CONTRACT_TYPE")]
|
||||
public int? ContractType { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public string ContractTypeTranslated => My.Resources.Model.ResourceManager.GetString(ContractType.ToString());
|
||||
#endif
|
||||
|
||||
[Column("LANGUAGE", TypeName = "nvarchar(5)")]
|
||||
public string Language { get; set; }
|
||||
|
||||
[Column("SEND_REMINDER_EMAILS")]
|
||||
public bool SendReminderEmails { get; set; }
|
||||
|
||||
[Column("FIRST_REMINDER_DAYS")]
|
||||
public int? FirstReminderDays { get; set; }
|
||||
|
||||
[Column("REMINDER_INTERVAL_DAYS")]
|
||||
public int? ReminderIntervalDays { get; set; }
|
||||
|
||||
[Column("ENVELOPE_TYPE")]
|
||||
public int? EnvelopeTypeId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
public bool ReadOnly => EnvelopeTypeId == 2;
|
||||
|
||||
[Column("CERTIFICATION_TYPE")]
|
||||
public int? CertificationType { get; set; }
|
||||
|
||||
[Column("USE_ACCESS_CODE")]
|
||||
public bool UseAccessCode { get; set; }
|
||||
|
||||
[Column("FINAL_EMAIL_TO_CREATOR")]
|
||||
public int? FinalEmailToCreator { get; set; }
|
||||
|
||||
[Column("FINAL_EMAIL_TO_RECEIVERS")]
|
||||
public int? FinalEmailToReceivers { get; set; }
|
||||
|
||||
[Column("EXPIRES_WHEN_DAYS")]
|
||||
public int? ExpiresWhenDays { get; set; }
|
||||
|
||||
[Column("EXPIRES_WARNING_WHEN_DAYS")]
|
||||
public int? ExpiresWarningWhenDays { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public User User { get; set; }
|
||||
|
||||
[Column("TFA_ENABLED")]
|
||||
public bool TfaEnabled { get; set; }
|
||||
#if NETFRAMEWORK
|
||||
= false;
|
||||
#endif
|
||||
|
||||
[NotMapped]
|
||||
[Column("DOC_RESULT")]
|
||||
public byte[]
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
DocResult
|
||||
{ get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeTypeId")]
|
||||
public virtual EnvelopeType
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Type { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public string CURRENT_WORK_APP { get; set; } = "signFLOW GUI";
|
||||
|
||||
[NotMapped]
|
||||
public bool IsAlreadySent => Status > EnvelopeStatus.EnvelopeSaved;
|
||||
#endif
|
||||
|
||||
public List<Document>
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Documents { get; set; }
|
||||
|
||||
public List<History>
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Histories { get; set; }
|
||||
|
||||
public List<EnvelopeReceiver>
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
EnvelopeReceivers { get; set; }
|
||||
|
||||
//#if NETFRAMEWORK
|
||||
/// <summary>
|
||||
/// Validates whether the receiver and document data are complete.
|
||||
/// </summary>
|
||||
public List<string> ValidateReceiverDocumentData()
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
if (!Documents?.Any() ?? true)
|
||||
errors.Add(My.Resources.Envelope.Missing_Documents);
|
||||
|
||||
if (!EnvelopeReceivers?.Any() ?? true)
|
||||
errors.Add(My.Resources.Envelope.Missing_Receivers);
|
||||
|
||||
if (EnvelopeReceivers?.Any(r => !r.HasEmailAndName) ?? false)
|
||||
errors.Add(My.Resources.Envelope.Incomplete_Receivers);
|
||||
|
||||
return errors;
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,104 +1,94 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using DigitalData.Core.Abstractions.Interfaces;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
|
||||
public class EnvelopeReceiver : IHasEnvelope, IHasReceiver, IEntity
|
||||
{
|
||||
public EnvelopeReceiver()
|
||||
[Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")]
|
||||
public class EnvelopeReceiver : IHasEnvelope, IHasReceiver, IEntity, IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
public EnvelopeReceiver()
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
CompanyName = string.Empty;
|
||||
CompanyName = string.Empty;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("SEQUENCE")]
|
||||
public int Sequence { get; set; }
|
||||
[Required]
|
||||
[Column("SEQUENCE")]
|
||||
public int Sequence { get; set; }
|
||||
|
||||
[Column("NAME", TypeName = "nvarchar(128)")]
|
||||
public string Name { get; set; }
|
||||
[Column("NAME", TypeName = "nvarchar(128)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("JOB_TITLE", TypeName = "nvarchar(128)")]
|
||||
public string JobTitle { get; set; }
|
||||
[Column("JOB_TITLE", TypeName = "nvarchar(128)")]
|
||||
public string JobTitle { get; set; }
|
||||
|
||||
[Column("COMPANY_NAME", TypeName = "nvarchar(128)")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
[Column("COMPANY_NAME", TypeName = "nvarchar(128)")]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
CompanyName { get; set; }
|
||||
CompanyName { get; set; }
|
||||
|
||||
[Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")]
|
||||
public string PrivateMessage { get; set; }
|
||||
[Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")]
|
||||
public string PrivateMessage { get; set; }
|
||||
|
||||
[Column("ACCESS_CODE", TypeName = "nvarchar(64)")]
|
||||
public string AccessCode { get; set; }
|
||||
[Column("ACCESS_CODE", TypeName = "nvarchar(64)")]
|
||||
public string AccessCode { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime ChangedWhen { get; set; }
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("PHONE_NUMBER")]
|
||||
[StringLength(20)]
|
||||
[RegularExpression(@"^\+[0-9]+$", ErrorMessage = "Phone number must start with '+' followed by digits.")]
|
||||
public string PhoneNumber { get; set; }
|
||||
[Column("PHONE_NUMBER")]
|
||||
[StringLength(20)]
|
||||
[RegularExpression(@"^\+[0-9]+$", ErrorMessage = "Phone number must start with '+' followed by digits.")]
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Tuple<int, int> Id => Tuple.Create(EnvelopeId, ReceiverId);
|
||||
[NotMapped]
|
||||
public Tuple<int, int> Id => Tuple.Create(EnvelopeId, ReceiverId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasPhoneNumber => !string.IsNullOrWhiteSpace(PhoneNumber);
|
||||
[NotMapped]
|
||||
public bool HasPhoneNumber => !string.IsNullOrWhiteSpace(PhoneNumber);
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public Envelope
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public Envelope
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
Envelope { get; set; }
|
||||
|
||||
[ForeignKey("ReceiverId")]
|
||||
public Receiver
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("ReceiverId")]
|
||||
public Receiver
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Receiver { get; set; }
|
||||
Receiver { get; set; }
|
||||
|
||||
#region Model of old serice
|
||||
[NotMapped]
|
||||
public Constants.ReceiverStatus Status { get; set; }
|
||||
#region Model of old serice
|
||||
[NotMapped]
|
||||
public Constants.ReceiverStatus Status { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasId => Id.Item1 > 0 && Id.Item2 > 0;
|
||||
[NotMapped]
|
||||
public bool HasId => Id.Item1 > 0 && Id.Item2 > 0;
|
||||
|
||||
[NotMapped]
|
||||
public bool HasEmailAndName =>
|
||||
!string.IsNullOrWhiteSpace(Receiver.EmailAddress) &&
|
||||
!string.IsNullOrWhiteSpace(Name);
|
||||
[NotMapped]
|
||||
public bool HasEmailAndName =>
|
||||
!string.IsNullOrWhiteSpace(Receiver.EmailAddress) &&
|
||||
!string.IsNullOrWhiteSpace(Name);
|
||||
#endregion
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
{
|
||||
[Table("TBSIG_ENVELOPE_RECEIVER_READ_ONLY")]
|
||||
public class EnvelopeReceiverReadOnly
|
||||
public class EnvelopeReceiverReadOnly : IHasChangedWhen, ICreationAuditable
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
@@ -42,16 +41,12 @@ namespace EnvelopeGenerator.Domain.Entities
|
||||
|
||||
[Column("ADDED_WHEN")]
|
||||
[Required]
|
||||
public DateTime
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
AddedWhen { get; set; }
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO")]
|
||||
[StringLength(100)]
|
||||
public string
|
||||
#if NET
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
|
||||
@@ -1,84 +1,73 @@
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using System;
|
||||
using DigitalData.UserManager.Domain.Entities;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using DigitalData.Core.Abstractions.Interfaces;
|
||||
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_ENVELOPE_HISTORY", Schema = "dbo")]
|
||||
public class History : IHasEnvelope, IHasReceiver, IEntity
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public long Id { get; set; }
|
||||
[Table("TBSIG_ENVELOPE_HISTORY", Schema = "dbo")]
|
||||
public class History : IHasEnvelope, IHasReceiver, IEntity, IHasAddedWhen, IHasChangedWhen
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
[Required]
|
||||
[Column("ENVELOPE_ID")]
|
||||
public int EnvelopeId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USER_REFERENCE", TypeName = "nvarchar(128)")]
|
||||
public string UserReference { get; set; }
|
||||
[Required]
|
||||
[Column("USER_REFERENCE", TypeName = "nvarchar(128)")]
|
||||
public string UserReference { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public EnvelopeStatus Status { get; set; }
|
||||
[Required]
|
||||
[Column("STATUS")]
|
||||
public EnvelopeStatus Status { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("ACTION_DATE", TypeName = "datetime")]
|
||||
public DateTime? ActionDate { get; set; } = DateTime.Now;
|
||||
|
||||
[Column("COMMENT", TypeName = "nvarchar(max)")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
[Column("ACTION_DATE", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("COMMENT", TypeName = "nvarchar(max)")]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
Comment { get; set; }
|
||||
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("EnvelopeId")]
|
||||
public virtual Envelope
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
Envelope { get; set; }
|
||||
|
||||
[ForeignKey("UserReference")]
|
||||
public virtual User
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("UserReference")]
|
||||
public virtual User
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Sender { get; set; }
|
||||
Sender { get; set; }
|
||||
|
||||
[ForeignKey("UserReference")]
|
||||
public virtual Receiver
|
||||
#if NET
|
||||
?
|
||||
[ForeignKey("UserReference")]
|
||||
public virtual Receiver
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Receiver { get; set; }
|
||||
Receiver { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public string StatusTranslated => My.Resources.Model.ResourceManager.GetString(Status.ToString());
|
||||
[NotMapped]
|
||||
public string StatusTranslated => My.Resources.Model.ResourceManager.GetString(Status.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,50 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Drawing;
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_RECEIVER", Schema = "dbo")]
|
||||
public class Receiver
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
[Table("TBSIG_RECEIVER", Schema = "dbo")]
|
||||
public class Receiver : IHasAddedWhen
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required, EmailAddress]
|
||||
[Column("EMAIL_ADDRESS", TypeName = "nvarchar(250)")]
|
||||
[StringLength(250)]
|
||||
public string EmailAddress { get; set; }
|
||||
[Required, EmailAddress]
|
||||
[Column("EMAIL_ADDRESS", TypeName = "nvarchar(250)")]
|
||||
[StringLength(250)]
|
||||
public string EmailAddress { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("SIGNATURE", TypeName = "nvarchar(64)")]
|
||||
public string Signature { get; set; }
|
||||
[Required]
|
||||
[Column("SIGNATURE", TypeName = "nvarchar(64)")]
|
||||
public string Signature { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("TOTP_SECRET_KEY", TypeName = "nvarchar(MAX)")]
|
||||
public string TotpSecretkey { get; set; }
|
||||
[Column("TOTP_SECRET_KEY", TypeName = "nvarchar(MAX)")]
|
||||
public string TotpSecretkey { get; set; }
|
||||
|
||||
[Column("TFA_REG_DEADLINE", TypeName = "datetime")]
|
||||
public DateTime? TfaRegDeadline { get; set; }
|
||||
[Column("TFA_REG_DEADLINE", TypeName = "datetime")]
|
||||
public DateTime? TfaRegDeadline { get; set; }
|
||||
|
||||
public List<EnvelopeReceiver> EnvelopeReceivers { get; set; }
|
||||
public List<EnvelopeReceiver> EnvelopeReceivers { get; set; }
|
||||
|
||||
public string GetSignature() => EmailAddress.ToUpperInvariant().GetChecksum();
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
public string GetSignature() => EmailAddress.ToUpperInvariant().GetChecksum();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,134 +1,130 @@
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using System;
|
||||
using EnvelopeGenerator.Domain.Interfaces;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Entities
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
[Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")]
|
||||
public class Signature : ISignature, IHasReceiver
|
||||
{
|
||||
public Signature()
|
||||
[Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")]
|
||||
public class Signature : ISignature, IHasReceiver, IHasAddedWhen, IUpdateAuditable
|
||||
{
|
||||
// TODO: * Check the Form App and remove the default value
|
||||
public Signature()
|
||||
{
|
||||
// TODO: * Check the Form App and remove the default value
|
||||
#if NETFRAMEWORK
|
||||
Id = -1;
|
||||
Required = false;
|
||||
ReadOnly = false;
|
||||
AnnotationIndex = 0;
|
||||
Id = -1;
|
||||
Required = false;
|
||||
ReadOnly = false;
|
||||
AnnotationIndex = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("DOCUMENT_ID")]
|
||||
public int DocumentId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ELEMENT_TYPE")]
|
||||
[DefaultValue(0)]
|
||||
public int ElementType { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("POSITION_X")]
|
||||
[DefaultValue(0)]
|
||||
public double X { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("POSITION_Y")]
|
||||
[DefaultValue(0)]
|
||||
public double Y { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("WIDTH")]
|
||||
[DefaultValue(0)]
|
||||
public double Width { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("HEIGHT")]
|
||||
[DefaultValue(0)]
|
||||
public double Height { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("PAGE")]
|
||||
[DefaultValue(1)]
|
||||
public int Page { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("REQUIRED")]
|
||||
[DefaultValue(false)]
|
||||
public bool Required { get; set; }
|
||||
|
||||
[Column("TOOLTIP")]
|
||||
public string Tooltip { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("READ_ONLY")]
|
||||
[DefaultValue(false)]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ANNOTATION_INDEX")]
|
||||
[DefaultValue(0)]
|
||||
public int AnnotationIndex { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO", TypeName = "nvarchar(100)")]
|
||||
public string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
ChangedWho
|
||||
{ get; set; }
|
||||
|
||||
[ForeignKey("DocumentId")]
|
||||
public virtual Document Document { get; set; }
|
||||
|
||||
[ForeignKey("ReceiverId")]
|
||||
public virtual Receiver
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Receiver
|
||||
{ get; set; }
|
||||
|
||||
public virtual IEnumerable<ElementAnnotation>
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Annotations
|
||||
{ get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public double Top => Math.Round(Y, 5);
|
||||
|
||||
[NotMapped]
|
||||
public double Left => Math.Round(X, 5);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Column("GUID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("DOCUMENT_ID")]
|
||||
public int DocumentId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("RECEIVER_ID")]
|
||||
public int ReceiverId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ELEMENT_TYPE")]
|
||||
[DefaultValue(0)]
|
||||
public int ElementType { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("POSITION_X")]
|
||||
[DefaultValue(0)]
|
||||
public double X { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("POSITION_Y")]
|
||||
[DefaultValue(0)]
|
||||
public double Y { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("WIDTH")]
|
||||
[DefaultValue(0)]
|
||||
public double Width { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("HEIGHT")]
|
||||
[DefaultValue(0)]
|
||||
public double Height { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("PAGE")]
|
||||
[DefaultValue(1)]
|
||||
public int Page { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("REQUIRED")]
|
||||
[DefaultValue(false)]
|
||||
public bool Required { get; set; }
|
||||
|
||||
[Column("TOOLTIP")]
|
||||
public string Tooltip { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("READ_ONLY")]
|
||||
[DefaultValue(false)]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ANNOTATION_INDEX")]
|
||||
[DefaultValue(0)]
|
||||
public int AnnotationIndex { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime? AddedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
[Column("CHANGED_WHO", TypeName = "nvarchar(100)")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
|
||||
[ForeignKey("DocumentId")]
|
||||
public virtual Document Document { get; set; }
|
||||
|
||||
[ForeignKey("ReceiverId")]
|
||||
public virtual Receiver
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Receiver { get; set; }
|
||||
|
||||
public virtual IEnumerable<ElementAnnotation>
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Annotations { get; set; }
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[NotMapped]
|
||||
public double Top => Math.Round(Y, 5);
|
||||
|
||||
[NotMapped]
|
||||
public double Left => Math.Round(X, 5);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface ICreationAuditable : IHasAddedWhen, IHasAddedWho
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface IHasAddedWhen
|
||||
{
|
||||
DateTime AddedWhen { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface IHasAddedWho
|
||||
{
|
||||
string AddedWho { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#if NETFRAMEWORK
|
||||
using System;
|
||||
#endif
|
||||
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface IHasChangedWhen
|
||||
{
|
||||
DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface IHasChangedWho
|
||||
{
|
||||
string
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces.Auditing
|
||||
{
|
||||
public interface IUpdateAuditable : IHasChangedWhen, IHasChangedWho
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,11 @@
|
||||
namespace EnvelopeGenerator.Domain.Interfaces
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
#endif
|
||||
|
||||
public interface IHasEnvelope
|
||||
{
|
||||
#if NET
|
||||
public
|
||||
#endif
|
||||
public interface IHasEnvelope
|
||||
{
|
||||
Entities.Envelope
|
||||
#if NET
|
||||
?
|
||||
#if nullable
|
||||
?
|
||||
#endif
|
||||
Envelope { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user