Compare commits
8 Commits
e95cf24af7
...
7d3ee1331d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d3ee1331d | ||
|
|
cd5b90a1e2 | ||
|
|
ac861f5fa0 | ||
|
|
c1d8f817bb | ||
|
|
da28a7332b | ||
|
|
bfd4e6a8ed | ||
|
|
b4e0e4b6b2 | ||
|
|
e37caf5c8f |
@@ -0,0 +1,13 @@
|
||||
namespace EnvelopeGenerator.Application.Configurations
|
||||
{
|
||||
public class DispatcherConfig
|
||||
{
|
||||
public int SendingProfile { get; init; } = 1;
|
||||
|
||||
public string AddedWho { get; init; } = "DDEnvelopGenerator";
|
||||
|
||||
public int ReminderTypeId { get; init; } = 202377;
|
||||
|
||||
public string EmailAttmt1 { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace EnvelopeGenerator.Application.Configurations
|
||||
{
|
||||
public class MailConfig
|
||||
{
|
||||
public required Dictionary<string, string> Placeholders { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Common;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts
|
||||
@@ -8,6 +9,9 @@ namespace EnvelopeGenerator.Application.Contracts
|
||||
public interface IEnvelopeMailService : IEmailOutService
|
||||
{
|
||||
Task<DataResult<int>> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType);
|
||||
|
||||
Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto);
|
||||
|
||||
Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,18 @@
|
||||
using DigitalData.UserManager.Application.MappingProfiles;
|
||||
using EnvelopeGenerator.Application.Contracts;
|
||||
using EnvelopeGenerator.Application.MappingProfiles;
|
||||
using EnvelopeGenerator.Application.Configurations;
|
||||
using EnvelopeGenerator.Application.Services;
|
||||
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||
using EnvelopeGenerator.Infrastructure.Repositories;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace EnvelopeGenerator.Application
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services)
|
||||
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration dispatcherConfigSection, IConfiguration mailConfigSection)
|
||||
{
|
||||
//Inject CRUD Service and repositoriesad
|
||||
services.AddScoped<IConfigRepository, ConfigRepository>();
|
||||
@@ -48,7 +50,14 @@ namespace EnvelopeGenerator.Application
|
||||
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
||||
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
|
||||
|
||||
services.Configure<DispatcherConfig>(dispatcherConfigSection);
|
||||
services.Configure<MailConfig>(mailConfigSection);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration config) => services.AddEnvelopeGenerator(
|
||||
dispatcherConfigSection: config.GetSection("DispatcherConfig"),
|
||||
mailConfigSection: config.GetSection("MailConfig"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,16 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||
{
|
||||
public record EnvelopeReceiverReadOnlyCreateDto(
|
||||
long EnvelopeId,
|
||||
string ReceiverMail,
|
||||
DateTime DateValid)
|
||||
{
|
||||
[JsonIgnore]
|
||||
public long? EnvelopeId { get; set; } = null;
|
||||
|
||||
[JsonIgnore]
|
||||
public string? AddedWho { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime AddedWhen { get; } = DateTime.Now;
|
||||
};
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace EnvelopeGenerator.Application
|
||||
{
|
||||
public class DispatcherConfig
|
||||
{
|
||||
public int SendingProfile { get; init; } = 1;
|
||||
|
||||
public string AddedWho { get; init; } = "DDEnvelopGenerator";
|
||||
|
||||
public int ReminderTypeId { get; init; } = 202377;
|
||||
|
||||
public string EmailAttmt1 { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,15 @@ using DigitalData.Core.DTO;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
|
||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
||||
using DigitalData.UserManager.Application;
|
||||
using EnvelopeGenerator.Application.Contracts;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using EnvelopeGenerator.Common;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using static EnvelopeGenerator.Common.Constants;
|
||||
using EnvelopeGenerator.Extensions;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||
using EnvelopeGenerator.Application.Configurations;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services
|
||||
{
|
||||
@@ -21,39 +21,50 @@ namespace EnvelopeGenerator.Application.Services
|
||||
private readonly IEnvelopeReceiverService _envRcvService;
|
||||
private readonly DispatcherConfig _dConfig;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Dictionary<string, string> _placeholders;
|
||||
|
||||
public EnvelopeMailService(IEmailOutRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherConfig> dispatcherConfigOptions, IConfigService configService) : base(repository, mapper)
|
||||
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherConfig> dispatcherConfigOptions, IConfigService configService, IOptions<MailConfig> mailConfig) : base(repository, mapper)
|
||||
{
|
||||
_tempService = tempService;
|
||||
_envRcvService = envelopeReceiverService;
|
||||
_dConfig = dispatcherConfigOptions.Value;
|
||||
_configService = configService;
|
||||
_placeholders = mailConfig.Value.Placeholders;
|
||||
}
|
||||
|
||||
//TODO: create ioptions and implement TemplatePlaceHolderAttribute instead of this method
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null, EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
{
|
||||
Dictionary<string, string> placeholders = new() {
|
||||
{ "[NAME_PORTAL]", "signFlow" },
|
||||
{ "[SIGNATURE_TYPE]" , "signieren"},
|
||||
{ "[REASON]", string.Empty } };
|
||||
|
||||
if (accessCode is not null)
|
||||
placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||
|
||||
if(envelopeReceiverDto is not null && envelopeReceiverDto.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||
if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||
{
|
||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/envelope/{erId}";
|
||||
placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)];
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
|
||||
return placeholders;
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: Constants.EmailTemplateType.DocumentAccessCodeReceived);
|
||||
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||
{
|
||||
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||
{
|
||||
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMail(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||
var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId();
|
||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||
}
|
||||
|
||||
return _placeholders;
|
||||
}
|
||||
|
||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: Constants.EmailTemplateType.DocumentAccessCodeReceived);
|
||||
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, Constants.EmailTemplateType tempType)
|
||||
{
|
||||
@@ -93,8 +104,43 @@ namespace EnvelopeGenerator.Application.Services
|
||||
|
||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||
|
||||
//TODO: remove the requirement to add the models using reflections
|
||||
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
||||
dto, dto.Envelope.User!, dto.Envelope);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto)
|
||||
{
|
||||
var tempSerResult = await _tempService.ReadByNameAsync(Constants.EmailTemplateType.DocumentShared);
|
||||
if (tempSerResult.IsFailed)
|
||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{Constants.EmailTemplateType.DocumentShared}' template cannot found.");
|
||||
var temp = tempSerResult.Data;
|
||||
|
||||
var mail = new EmailOutCreateDto()
|
||||
{
|
||||
EmailAddress = dto.ReceiverMail,
|
||||
EmailSubj = temp.Subject,
|
||||
EmailBody = temp.Body,
|
||||
//TODO: remove int casting when all
|
||||
ReferenceId = (int) dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||
ReferenceString = dto.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||
//receiver_name = receiver.name,
|
||||
//receiver_access_code = receiver.access_code,
|
||||
//sender_adress = envelope.user.email,
|
||||
//sender_name = envelope.user.full_name,
|
||||
//envelope_title = envelope.title,
|
||||
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||
SendingProfile = _dConfig.SendingProfile,
|
||||
EntityId = null,
|
||||
WfId = (int)EnvelopeStatus.EnvelopeShared,
|
||||
WfReference = null,
|
||||
AddedWho = _dConfig.AddedWho,
|
||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||
};
|
||||
|
||||
var placeholders = await CreatePlaceholders(readOnlyDto: dto);
|
||||
|
||||
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
SignatureConfirmed = 2006
|
||||
DocumentRejected = 2007
|
||||
EnvelopeShared = 2008
|
||||
EnvelopeViewed = 2009
|
||||
MessageInvitationSent = 3001 ' Wird von Trigger verwendet
|
||||
MessageAccessCodeSent = 3002
|
||||
MessageConfirmationSent = 3003
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
|
||||
public static string? GetAuthEnvelopeTitle(this ControllerBase controller) => controller.User.FindFirstValue(EnvelopeClaimTypes.Title);
|
||||
|
||||
public static int? GetAuthEnvelopeId(this ControllerBase controller)
|
||||
{
|
||||
var env_id_str = controller.User.FindFirstValue(EnvelopeClaimTypes.Id);
|
||||
return int.TryParse(env_id_str, out int env_id) ? env_id : null;
|
||||
}
|
||||
|
||||
//TODO: integrate localizer for ready-to-use views
|
||||
public static ViewResult ViewError(this Controller controller, ErrorViewModel errorViewModel) => controller.View("_Error", errorViewModel);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ using EnvelopeGenerator.Web.Models;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||
using static EnvelopeGenerator.Common.Constants;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Ganss.Xss;
|
||||
|
||||
namespace EnvelopeGenerator.Web.Controllers
|
||||
@@ -200,14 +199,15 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document was found.");
|
||||
return this.ViewDocumentNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
var claims = new List<Claim> {
|
||||
new(ClaimTypes.NameIdentifier, uuid),
|
||||
new(ClaimTypes.Hash, signature),
|
||||
new(ClaimTypes.Name, er.Name ?? string.Empty),
|
||||
new(ClaimTypes.Email, er.Receiver.EmailAddress),
|
||||
new(EnvelopeClaimTypes.Title, er.Envelope.Title)
|
||||
new(EnvelopeClaimTypes.Title, er.Envelope.Title),
|
||||
new(EnvelopeClaimTypes.Id, er.Envelope.Id.ToString())
|
||||
};
|
||||
|
||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
@@ -5,6 +5,7 @@ using EnvelopeGenerator.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace EnvelopeGenerator.Web.Controllers
|
||||
{
|
||||
@@ -16,10 +17,16 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
|
||||
private readonly IEnvelopeReceiverReadOnlyService _erroService;
|
||||
|
||||
public ReadOnlyController(ILogger<ReadOnlyController> logger, IEnvelopeReceiverReadOnlyService erroService)
|
||||
private readonly IEnvelopeMailService _mailService;
|
||||
|
||||
private readonly IEnvelopeHistoryService _histService;
|
||||
|
||||
public ReadOnlyController(ILogger<ReadOnlyController> logger, IEnvelopeReceiverReadOnlyService erroService, IEnvelopeMailService mailService, IEnvelopeHistoryService histService)
|
||||
{
|
||||
_logger = logger;
|
||||
_erroService = erroService;
|
||||
_mailService = mailService;
|
||||
_histService = histService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -39,22 +46,55 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
if (authReceiverMail is null)
|
||||
{
|
||||
_logger.LogError("Email clam is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||
|
||||
return Unauthorized();
|
||||
}
|
||||
createDto.AddedWho = authReceiverMail;
|
||||
|
||||
return await _erroService.CreateAsync(createDto: createDto).ThenAsync(
|
||||
Success: id => Ok(id),
|
||||
Fail: IActionResult (msg, ntc) =>
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
});
|
||||
var envelopeId = this.GetAuthEnvelopeId();
|
||||
if (envelopeId is null)
|
||||
{
|
||||
_logger.LogError("Envelope Id clam is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
createDto.AddedWho = authReceiverMail;
|
||||
createDto.EnvelopeId = envelopeId;
|
||||
|
||||
// create entity
|
||||
var creation_res = await _erroService.CreateAsync(createDto: createDto);
|
||||
|
||||
if (creation_res.IsFailed)
|
||||
{
|
||||
_logger.LogNotice(creation_res);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
//read new entity
|
||||
var read_res = await _erroService.ReadByIdAsync(creation_res.Data);
|
||||
if (read_res.IsFailed)
|
||||
{
|
||||
_logger.LogNotice(creation_res);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
var new_erro = read_res.Data;
|
||||
|
||||
//send email two receiver
|
||||
return await _mailService.SendAsync(new_erro).ThenAsync(Success: res =>
|
||||
{
|
||||
//TODO: remove casting after change the id type
|
||||
_histService.RecordAsync((int) createDto.EnvelopeId, createDto.AddedWho, Common.Constants.EnvelopeStatus.EnvelopeShared);
|
||||
return Ok();
|
||||
},
|
||||
|
||||
Fail: IActionResult (msg, ntc) =>
|
||||
{
|
||||
_logger.LogNotice(ntc);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("key/{readOnlyId}")]
|
||||
public IActionResult CreateLink(long readOnlyId) => Ok(
|
||||
Request.Headers["Origin"].ToString() + "/EnvelopeKey/" + readOnlyId.EncodeEnvelopeReceiverId());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,10 @@
|
||||
/// Claim type for the title of an envelope.
|
||||
/// </summary>
|
||||
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)}";
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ try
|
||||
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
||||
|
||||
// Add envelope generator services
|
||||
builder.Services.AddEnvelopeGenerator();
|
||||
builder.Services.AddEnvelopeGenerator(config);
|
||||
|
||||
builder.Services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
@@ -157,8 +157,6 @@ try
|
||||
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
builder.ConfigureBySection<DispatcherConfig>();
|
||||
|
||||
builder.ConfigureBySection<Logo>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
{
|
||||
var dateTimeSt = string.Empty;
|
||||
if (ViewData["ReadOnly"] is EnvelopeReceiverReadOnlyDto readOnly)
|
||||
dateTimeSt = readOnly.DateValid.ToLongDateString() + " - " + readOnly.DateValid.ToShortTimeString();
|
||||
dateTimeSt = readOnly.DateValid.ToLongDateString();
|
||||
<h6>@string.Format(_localizer["ReadOnlyMessage"], receiver_name, dateTimeSt)</h6>
|
||||
}
|
||||
else
|
||||
|
||||
@@ -135,5 +135,12 @@
|
||||
"Src": "/img/digital_data.svg",
|
||||
"ShowPageClass": "dd-show-logo",
|
||||
"LockedPageClass": "dd-locked-logo"
|
||||
},
|
||||
"MailConfig": {
|
||||
"Placeholders": {
|
||||
"[NAME_PORTAL]": "signFlow",
|
||||
"[SIGNATURE_TYPE]": "signieren",
|
||||
"[REASON]": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user