Compare commits
20 Commits
refactor/a
...
web-multi-
| Author | SHA1 | Date | |
|---|---|---|---|
| 297ab458c7 | |||
| 0e270e3182 | |||
| bcf55f7906 | |||
| 489b2d0917 | |||
| 63fbdc3bd5 | |||
| aaf1f75aa7 | |||
| cdca639e4f | |||
| ab57dd4cee | |||
| 745e9c7bfe | |||
| 670c8ed87c | |||
| 91eb5d1e64 | |||
| 9f59a17f63 | |||
| 2a0f7f99d6 | |||
| ec674b6e80 | |||
| 10f23170fd | |||
| 0ec823ec9e | |||
| 06884fe809 | |||
| c2d5bd65aa | |||
| cfcd43b0ed | |||
| f41199c389 |
@@ -19,20 +19,20 @@ namespace EnvelopeGenerator.API.Controllers;
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
/// Initialisiert eine neue Instanz der <see cref="EmailTemplateController"/>-Klasse.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="mapper">
|
/// <param name="mediator">
|
||||||
/// <param name="repository">
|
/// Die Mediator-Instanz, die zum Senden von Befehlen und Abfragen verwendet wird.
|
||||||
/// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird.
|
|
||||||
/// </param>
|
/// </param>
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize(Policy = AuthPolicy.Sender)]
|
[Authorize(Policy = AuthPolicy.Sender)]
|
||||||
public class EmailTemplateController(IMapper mapper, IRepository<EmailTemplate> repository, IMediator mediator) : ControllerBase
|
public class EmailTemplateController(IMediator mediator) : ControllerBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ruft E-Mail-Vorlagen basierend auf der angegebenen Abfrage ab.
|
/// Ruft E-Mail-Vorlagen basierend auf der angegebenen Abfrage ab.
|
||||||
/// Gibt alles zurück, wenn keine Id- oder Typ-Informationen eingegeben wurden.
|
/// Gibt alles zurück, wenn keine Id- oder Typ-Informationen eingegeben wurden.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="emailTemplate">Die Abfrageparameter zum Abrufen von E-Mail-Vorlagen.</param>
|
/// <param name="emailTemplate">Die Abfrageparameter zum Abrufen von E-Mail-Vorlagen.</param>
|
||||||
|
/// <param name="cancel"></param>
|
||||||
/// <returns>Gibt HTTP-Antwort zurück</returns>
|
/// <returns>Gibt HTTP-Antwort zurück</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Sample request:
|
/// Sample request:
|
||||||
@@ -43,18 +43,10 @@ public class EmailTemplateController(IMapper mapper, IRepository<EmailTemplate>
|
|||||||
/// <response code="401">Wenn der Benutzer nicht authentifiziert ist.</response>
|
/// <response code="401">Wenn der Benutzer nicht authentifiziert ist.</response>
|
||||||
/// <response code="404">Wenn die gesuchte Abfrage nicht gefunden wird.</response>
|
/// <response code="404">Wenn die gesuchte Abfrage nicht gefunden wird.</response>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> Get([FromQuery] ReadEmailTemplateQuery? emailTemplate = null)
|
public async Task<IActionResult> Get([FromQuery] ReadEmailTemplateQuery emailTemplate, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (emailTemplate is null || (emailTemplate.Id is null && emailTemplate.Type is null))
|
var result = await mediator.Send(emailTemplate, cancel);
|
||||||
{
|
return Ok(result);
|
||||||
var temps = await repository.Query.ToListAsync();
|
|
||||||
return Ok(mapper.Map<IEnumerable<EmailTemplateDto>>(temps));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var temp = await mediator.Send(emailTemplate);
|
|
||||||
return temp is null ? NotFound() : Ok(temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class ReadOnlyController : ControllerBase
|
|||||||
/// <param name="createDto">Creation payload.</param>
|
/// <param name="createDto">Creation payload.</param>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||||
|
[Obsolete("Use MediatR")]
|
||||||
public async Task<IActionResult> CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto)
|
public async Task<IActionResult> CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto)
|
||||||
{
|
{
|
||||||
var authReceiverMail = User.GetReceiverMailOfReceiver();
|
var authReceiverMail = User.GetReceiverMailOfReceiver();
|
||||||
|
|||||||
@@ -13,25 +13,30 @@ public record EmailTemplateDto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required string Name { get; init; }
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
|
/// Das Datum und die Uhrzeit, wann die Vorlage hinzugefügt wurde.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime AddedWhen { get; init; }
|
public DateTime AddedWhen { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
|
/// Der Inhalt (Body) der E-Mail-Vorlage. Kann null sein.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Body { get; init; }
|
public string? Body { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
|
/// Der Betreff der E-Mail-Vorlage. Kann null sein.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Subject { get; init; }
|
public string? Subject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Der Sprachcode der E-Mail-Vorlage.
|
||||||
|
/// </summary>
|
||||||
|
public string LangCode { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
|
/// Das Datum und die Uhrzeit, wann die Vorlage zuletzt geändert wurde. Kann null sein.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? ChangedWhen { get; init; }
|
public DateTime? ChangedWhen { get; set; }
|
||||||
};
|
};
|
||||||
@@ -6,6 +6,7 @@ using EnvelopeGenerator.Domain.Entities;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
using EnvelopeGenerator.Domain.Constants;
|
||||||
using DigitalData.Core.Exceptions;
|
using DigitalData.Core.Exceptions;
|
||||||
|
using EnvelopeGenerator.Application.Common.Extensions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.EmailTemplates.Queries;
|
namespace EnvelopeGenerator.Application.EmailTemplates.Queries;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ namespace EnvelopeGenerator.Application.EmailTemplates.Queries;
|
|||||||
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
|
/// Stellt eine Abfrage dar, um eine E-Mail-Vorlage zu lesen.
|
||||||
/// Diese Klasse erbt von <see cref="IEmailTemplateQuery"/>.
|
/// Diese Klasse erbt von <see cref="IEmailTemplateQuery"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ReadEmailTemplateQuery : IEmailTemplateQuery, IRequest<EmailTemplateDto>
|
public record ReadEmailTemplateQuery : IEmailTemplateQuery, IRequest<IEnumerable<EmailTemplateDto>>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
/// Die eindeutige Kennung der E-Mail-Vorlage (optional).
|
||||||
@@ -34,12 +35,51 @@ public record ReadEmailTemplateQuery : IEmailTemplateQuery, IRequest<EmailTempla
|
|||||||
/// 9 - DocumentRejected_REC_2 (für sonstige Empfänger): Mail an andere Empfänger (Brief), 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EmailTemplateType? Type { get; set; }
|
public EmailTemplateType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string? LangCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, EmailTemplateDto>
|
public static class ReadEmailTemplateQueryExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="langCode"></param>
|
||||||
|
/// <param name="cancel"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<EmailTemplateDto?> ReadEmailTemplateAsync(this ISender sender, int id, string langCode, CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
var result = await sender.Send(new ReadEmailTemplateQuery { Id = id, LangCode = langCode }, cancel);
|
||||||
|
return result.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="langCode"></param>
|
||||||
|
/// <param name="cancel"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<EmailTemplateDto?> ReadEmailTemplateAsync(this ISender sender, EmailTemplateType type, string langCode, CancellationToken cancel = default)
|
||||||
|
{
|
||||||
|
var result = await sender.Send(new ReadEmailTemplateQuery { Type = type, LangCode = langCode }, cancel);
|
||||||
|
return result.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQuery, IEnumerable<EmailTemplateDto>>
|
||||||
{
|
{
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
@@ -65,14 +105,21 @@ public class ReadEmailTemplateQueryHandler : IRequestHandler<ReadEmailTemplateQu
|
|||||||
/// <param name="cancel"></param>
|
/// <param name="cancel"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="InvalidOperationException"></exception>
|
/// <exception cref="InvalidOperationException"></exception>
|
||||||
public async Task<EmailTemplateDto> Handle(ReadEmailTemplateQuery request, CancellationToken cancel)
|
public async Task<IEnumerable<EmailTemplateDto>> Handle(ReadEmailTemplateQuery request, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
var query = request.Id is int id
|
var query = _repo.Query;
|
||||||
? _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();
|
if (request.Id is int id)
|
||||||
|
query = query.Where(temp => temp.Id == id);
|
||||||
|
|
||||||
return _mapper.Map<EmailTemplateDto>(entity);
|
if (request.Type is EmailTemplateType type)
|
||||||
|
query = query.Where(temp => temp.Name == type.ToString());
|
||||||
|
|
||||||
|
if (request.LangCode is string langCode)
|
||||||
|
query = query.Where(temp => temp.LangCode == langCode);
|
||||||
|
|
||||||
|
var entity = await query.ToListAsync(cancel);
|
||||||
|
|
||||||
|
return _mapper.Map<IEnumerable<EmailTemplateDto>>(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
|
|||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using DigitalData.Core.Abstraction.Application.DTO;
|
using DigitalData.Core.Abstraction.Application.DTO;
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
using EnvelopeGenerator.Domain.Constants;
|
||||||
using EnvelopeGenerator.Application.Common.Configurations;
|
using EnvelopeGenerator.Application.Common.Configurations;
|
||||||
@@ -12,6 +11,7 @@ using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
|
|||||||
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly;
|
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly;
|
||||||
using EnvelopeGenerator.Application.Common.Extensions;
|
using EnvelopeGenerator.Application.Common.Extensions;
|
||||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services;
|
namespace EnvelopeGenerator.Application.Services;
|
||||||
|
|
||||||
@@ -21,170 +21,170 @@ namespace EnvelopeGenerator.Application.Services;
|
|||||||
[Obsolete("Use MediatR")]
|
[Obsolete("Use MediatR")]
|
||||||
public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
public class EnvelopeMailService : EmailOutService, IEnvelopeMailService
|
||||||
{
|
{
|
||||||
private readonly IEmailTemplateService _tempService;
|
private readonly IEmailTemplateService _tempService;
|
||||||
private readonly IEnvelopeReceiverService _envRcvService;
|
private readonly IEnvelopeReceiverService _envRcvService;
|
||||||
private readonly DispatcherParams _dConfig;
|
private readonly DispatcherParams _dConfig;
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly Dictionary<string, string> _placeholders;
|
private readonly Dictionary<string, string> _placeholders;
|
||||||
private readonly IAuthenticator _authenticator;
|
private readonly ISender _sender;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="repository"></param>
|
/// <param name="repository"></param>
|
||||||
/// <param name="mapper"></param>
|
/// <param name="mapper"></param>
|
||||||
/// <param name="tempService"></param>
|
/// <param name="tempService"></param>
|
||||||
/// <param name="envelopeReceiverService"></param>
|
/// <param name="envelopeReceiverService"></param>
|
||||||
/// <param name="dispatcherConfigOptions"></param>
|
/// <param name="dispatcherConfigOptions"></param>
|
||||||
/// <param name="configService"></param>
|
/// <param name="configService"></param>
|
||||||
/// <param name="mailConfig"></param>
|
/// <param name="mailConfig"></param>
|
||||||
/// <param name="authenticator"></param>
|
/// <param name="sender"></param>
|
||||||
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, IAuthenticator authenticator) : base(repository, mapper)
|
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherParams> dispatcherConfigOptions, IConfigService configService, IOptions<MailParams> mailConfig, ISender sender) : base(repository, mapper)
|
||||||
{
|
{
|
||||||
_tempService = tempService;
|
_tempService = tempService;
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
_dConfig = dispatcherConfigOptions.Value;
|
_dConfig = dispatcherConfigOptions.Value;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_placeholders = new Dictionary<string, string>(mailConfig.Value.Placeholders);
|
_placeholders = new Dictionary<string, string>(mailConfig.Value.Placeholders);
|
||||||
_authenticator = authenticator;
|
_sender = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
|
||||||
if (accessCode is not null)
|
|
||||||
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
|
||||||
|
|
||||||
if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
|
||||||
{
|
{
|
||||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).ToEnvelopeKey();
|
if (accessCode is not null)
|
||||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||||
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
|
||||||
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
if (envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||||
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
{
|
||||||
|
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).ToEnvelopeKey();
|
||||||
|
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||||
|
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;
|
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||||
}
|
|
||||||
|
|
||||||
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.ReadLastUsedReceiverNameByMailAsync(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
|
||||||
var erReadOnlyId = (readOnlyDto.Id).ToEnvelopeKey();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="tempType"></param>
|
|
||||||
/// <param name="optionalPlaceholders"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, EmailTemplateType tempType, Dictionary<string, object>? optionalPlaceholders = null)
|
|
||||||
{
|
|
||||||
var tempSerResult = await _tempService.ReadByNameAsync(tempType);
|
|
||||||
if (tempSerResult.IsFailed)
|
|
||||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, DigitalData.Core.Abstraction.Application.DTO.Flag.DataIntegrityIssue, $"The email cannot send because '{tempType}' template cannot found.");
|
|
||||||
var temp = tempSerResult.Data;
|
|
||||||
|
|
||||||
var mail = new EmailOutCreateDto()
|
|
||||||
{
|
{
|
||||||
EmailAddress = dto.Receiver!.EmailAddress,
|
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||||
EmailSubj = temp.Subject,
|
{
|
||||||
EmailBody = temp.Body,
|
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMailAsync(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||||
//email_type = envelope_status,
|
var erReadOnlyId = (readOnlyDto.Id).ToEnvelopeKey();
|
||||||
//message = envelope_message,
|
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||||
ReferenceId = dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||||
ReferenceString = dto!.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||||
//receiver_name = receiver.name,
|
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||||
//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.MessageAccessCodeSent,
|
|
||||||
WfReference = null,
|
|
||||||
AddedWho = _dConfig.AddedWho,
|
|
||||||
EmailAttmt1 = _dConfig.EmailAttmt1
|
|
||||||
};
|
|
||||||
|
|
||||||
//get acccess code
|
return _placeholders;
|
||||||
var acResult = await _envRcvService.ReadAccessCodeByIdAsync(envelopeId: dto.EnvelopeId, receiverId: dto.ReceiverId);
|
}
|
||||||
if (acResult.IsFailed)
|
|
||||||
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
|
||||||
var accessCode = acResult.Data;
|
|
||||||
|
|
||||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
|
||||||
|
|
||||||
// Add optional place holders.
|
/// <summary>
|
||||||
if (optionalPlaceholders is not null)
|
///
|
||||||
foreach (var oph in optionalPlaceholders)
|
/// </summary>
|
||||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
/// <param name="dto"></param>
|
||||||
|
/// <param name="tempType"></param>
|
||||||
|
/// <param name="optionalPlaceholders"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, EmailTemplateType tempType, Dictionary<string, object>? optionalPlaceholders = null)
|
||||||
|
{
|
||||||
|
var tempSerResult = await _tempService.ReadByNameAsync(tempType);
|
||||||
|
if (tempSerResult.IsFailed)
|
||||||
|
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{tempType}' template cannot found.");
|
||||||
|
var temp = tempSerResult.Data;
|
||||||
|
|
||||||
//TODO: remove the requirement to add the models using reflections
|
var mail = new EmailOutCreateDto()
|
||||||
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
{
|
||||||
dto, dto.Envelope.User!, dto.Envelope);
|
EmailAddress = dto.Receiver!.EmailAddress,
|
||||||
}
|
EmailSubj = temp.Subject,
|
||||||
|
EmailBody = temp.Body,
|
||||||
|
//email_type = envelope_status,
|
||||||
|
//message = envelope_message,
|
||||||
|
ReferenceId = 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.MessageAccessCodeSent,
|
||||||
|
WfReference = null,
|
||||||
|
AddedWho = _dConfig.AddedWho,
|
||||||
|
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
//get acccess code
|
||||||
///
|
var acResult = await _envRcvService.ReadAccessCodeByIdAsync(envelopeId: dto.EnvelopeId, receiverId: dto.ReceiverId);
|
||||||
/// </summary>
|
if (acResult.IsFailed)
|
||||||
/// <param name="dto"></param>
|
return acResult.ToFail<int>().Notice(LogLevel.Error, "Therefore, access code cannot be sent");
|
||||||
/// <param name="optionalPlaceholders"></param>
|
var accessCode = acResult.Data;
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary<string, object>? optionalPlaceholders = null)
|
|
||||||
{
|
|
||||||
var tempSerResult = await _tempService.ReadByNameAsync(EmailTemplateType.DocumentShared);
|
|
||||||
if (tempSerResult.IsFailed)
|
|
||||||
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{EmailTemplateType.DocumentShared}' template cannot found.");
|
|
||||||
var temp = tempSerResult.Data;
|
|
||||||
|
|
||||||
var mail = new EmailOutCreateDto()
|
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||||
{
|
|
||||||
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);
|
// Add optional place holders.
|
||||||
|
if (optionalPlaceholders is not null)
|
||||||
|
foreach (var oph in optionalPlaceholders)
|
||||||
|
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||||
|
|
||||||
// Add optional place holders.
|
//TODO: remove the requirement to add the models using reflections
|
||||||
if (optionalPlaceholders is not null)
|
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders,
|
||||||
foreach (var oph in optionalPlaceholders)
|
dto, dto.Envelope.User!, dto.Envelope);
|
||||||
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
}
|
||||||
|
|
||||||
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
/// <summary>
|
||||||
}
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dto"></param>
|
||||||
|
/// <param name="optionalPlaceholders"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary<string, object>? optionalPlaceholders = null)
|
||||||
|
{
|
||||||
|
var tempSerResult = await _tempService.ReadByNameAsync(EmailTemplateType.DocumentShared);
|
||||||
|
if (tempSerResult.IsFailed)
|
||||||
|
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{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);
|
||||||
|
|
||||||
|
// Add optional place holders.
|
||||||
|
if (optionalPlaceholders is not null)
|
||||||
|
foreach (var oph in optionalPlaceholders)
|
||||||
|
placeholders[oph.Key] = oph.Value.ToString() ?? "NULL";
|
||||||
|
|
||||||
|
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dto"></param>
|
/// <param name="dto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: EmailTemplateType.DocumentAccessCodeReceived);
|
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: EmailTemplateType.DocumentAccessCodeReceived);
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using DigitalData.Core.Abstractions.Interfaces;
|
||||||
using DigitalData.Core.Abstractions.Interfaces;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
using EnvelopeGenerator.Domain.Interfaces.Auditing;
|
||||||
|
#if NETFRAMEWORK
|
||||||
|
using System;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Domain.Entities
|
namespace EnvelopeGenerator.Domain.Entities
|
||||||
{
|
{
|
||||||
@@ -24,6 +26,10 @@ namespace EnvelopeGenerator.Domain.Entities
|
|||||||
[Column("SUBJECT", TypeName = "nvarchar(512)")]
|
[Column("SUBJECT", TypeName = "nvarchar(512)")]
|
||||||
public string Subject { get; set; }
|
public string Subject { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Column("LANG_CODE", TypeName = "varchar(5)")]
|
||||||
|
public string LangCode { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||||
[DefaultValue("GETDATE()")]
|
[DefaultValue("GETDATE()")]
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class EnvelopeController : ViewControllerBase
|
|||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
[Obsolete("Use MediatR")]
|
[Obsolete("Use MediatR")]
|
||||||
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IAuthenticator authenticator, IReceiverService receiverService, IEnvelopeSmsHandler envelopeSmsService, IMediator mediator) : base(logger, cultures, localizer)
|
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, MultiCulture cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService, IAuthenticator authenticator, IReceiverService receiverService, IEnvelopeSmsHandler envelopeSmsService, IMediator mediator) : base(logger, cultures, localizer)
|
||||||
{
|
{
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
_historyService = historyService;
|
_historyService = historyService;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class HomeController : ViewControllerBase
|
|||||||
{
|
{
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
public HomeController(IConfiguration configuration, ILogger<HomeController> logger, Cultures cultures, IStringLocalizer<Resource> localizer) : base(logger, cultures, localizer)
|
public HomeController(IConfiguration configuration, ILogger<HomeController> logger, MultiCulture cultures, IStringLocalizer<Resource> localizer) : base(logger, cultures, localizer)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
private readonly IStringLocalizer<Resource> _localizer;
|
private readonly IStringLocalizer<Resource> _localizer;
|
||||||
|
|
||||||
private readonly Cultures _cultures;
|
private readonly MultiCulture _cultures;
|
||||||
|
|
||||||
public LocalizationController(IStringLocalizer<Resource> localizer, Cultures cultures, ILogger<LocalizationController> logger)
|
public LocalizationController(IStringLocalizer<Resource> localizer, MultiCulture cultures, ILogger<LocalizationController> logger)
|
||||||
{
|
{
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
_cultures = cultures;
|
_cultures = cultures;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class TFARegController : ViewControllerBase
|
|||||||
private readonly TFARegParams _params;
|
private readonly TFARegParams _params;
|
||||||
|
|
||||||
[Obsolete("Use MediatR")]
|
[Obsolete("Use MediatR")]
|
||||||
public TFARegController(ILogger<TFARegController> logger, Cultures cultures, IStringLocalizer<Resource> localizer, IEnvelopeReceiverService erService, IAuthenticator authenticator, IReceiverService receiverService, IOptions<TFARegParams> tfaRegParamsOptions) : base(logger, cultures, localizer)
|
public TFARegController(ILogger<TFARegController> logger, MultiCulture cultures, IStringLocalizer<Resource> localizer, IEnvelopeReceiverService erService, IAuthenticator authenticator, IReceiverService receiverService, IOptions<TFARegParams> tfaRegParamsOptions) : base(logger, cultures, localizer)
|
||||||
{
|
{
|
||||||
_envRcvService = erService;
|
_envRcvService = erService;
|
||||||
_authenticator = authenticator;
|
_authenticator = authenticator;
|
||||||
|
|||||||
@@ -1,34 +1,22 @@
|
|||||||
using DigitalData.Core.Abstraction.Application.DTO;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using EnvelopeGenerator.Application.EmailTemplates.Queries;
|
||||||
using EnvelopeGenerator.Domain.Constants;
|
|
||||||
using EnvelopeGenerator.Application.Common.Dto;
|
|
||||||
using EnvelopeGenerator.Application.Common.Interfaces.Services;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers.Test;
|
namespace EnvelopeGenerator.Web.Controllers.Test;
|
||||||
|
|
||||||
[Obsolete("Use MediatR")]
|
public class TestEmailTemplateController : ControllerBase
|
||||||
public class TestEmailTemplateController : TestControllerBase<IEmailTemplateService, EmailTemplateDto, EmailTemplate, int>
|
|
||||||
{
|
{
|
||||||
public TestEmailTemplateController(ILogger<TestEmailTemplateController> logger, IEmailTemplateService service) : base(logger, service)
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public TestEmailTemplateController(IMediator mediator)
|
||||||
{
|
{
|
||||||
|
_mediator = mediator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Obsolete("Use MediatR")]
|
public virtual async Task<IActionResult> GetAll([FromQuery] ReadEmailTemplateQuery query, CancellationToken cancel)
|
||||||
public virtual async Task<IActionResult> GetAll([FromQuery] string? tempType = null)
|
|
||||||
{
|
{
|
||||||
return tempType is null
|
var res = await _mediator.Send(query, cancel);
|
||||||
? await base.GetAll()
|
return Ok(res);
|
||||||
: await _service.ReadByNameAsync((EmailTemplateType)Enum.Parse(typeof(EmailTemplateType), tempType)).ThenAsync(
|
|
||||||
Success: Ok,
|
|
||||||
Fail: IActionResult (messages, notices) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(notices);
|
|
||||||
return NotFound(messages);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonAction]
|
|
||||||
public override Task<IActionResult> GetAll() => base.GetAll();
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
using AngleSharp.Common;
|
using AngleSharp.Common;
|
||||||
using DigitalData.Core.API;
|
using DigitalData.Core.API;
|
||||||
using EnvelopeGenerator.Application.Resources;
|
using EnvelopeGenerator.Application.Resources;
|
||||||
|
using EnvelopeGenerator.Web.Extensions;
|
||||||
using EnvelopeGenerator.Web.Models;
|
using EnvelopeGenerator.Web.Models;
|
||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers.Test
|
namespace EnvelopeGenerator.Web.Controllers.Test
|
||||||
{
|
{
|
||||||
@@ -12,21 +15,30 @@ namespace EnvelopeGenerator.Web.Controllers.Test
|
|||||||
public class TestLocalizerController : ControllerBase
|
public class TestLocalizerController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IStringLocalizer _localizer;
|
private readonly IStringLocalizer _localizer;
|
||||||
private readonly Cultures _cultures;
|
private readonly MultiCulture _cultures;
|
||||||
|
|
||||||
public TestLocalizerController(IStringLocalizer<Resource> localizer, Cultures cultures)
|
public TestLocalizerController(IStringLocalizer<Resource> localizer, MultiCulture cultures)
|
||||||
{
|
{
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
_cultures = cultures;
|
_cultures = cultures;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet("{key}")]
|
||||||
public IActionResult Localize([FromQuery] string key = "de_DE") => Ok(_localizer[key]);
|
public IActionResult Localize([FromRoute] string key) => Ok(_localizer[key]);
|
||||||
|
|
||||||
[HttpGet("fi-class")]
|
[HttpGet("fi-class")]
|
||||||
public IActionResult GetFIClass(string? lang = null) => lang is null ? Ok(_cultures.FIClasses) : Ok(_cultures[lang]?.FIClass);
|
public IActionResult GetFIClass(string? lang = null) => lang is null ? Ok(_cultures.FIClasses) : Ok(_cultures[lang]?.FIClass);
|
||||||
|
|
||||||
[HttpGet("culture")]
|
[HttpGet("culture")]
|
||||||
public IActionResult GetCultures(string? lang = null) => lang is null ? Ok(_cultures) : Ok(_cultures[lang]);
|
public IActionResult GetCultures(string? lang = null) => lang is null ? Ok(_cultures) : Ok(_cultures[lang]);
|
||||||
|
|
||||||
|
[HttpGet("culture/accept-language")]
|
||||||
|
public IActionResult GetCultureByAcceptLanguage()
|
||||||
|
=> HttpContext.GetCultureByAcceptLanguage()?.Name is string culture
|
||||||
|
? Ok(culture)
|
||||||
|
: NotFound();
|
||||||
|
|
||||||
|
[HttpGet("culture/user")]
|
||||||
|
public IActionResult GetUserCulture() => Request.Cookies.GetCulture() is string cult ? Ok(cult) : NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ namespace EnvelopeGenerator.Web.Controllers;
|
|||||||
public class ViewControllerBase : Controller
|
public class ViewControllerBase : Controller
|
||||||
{
|
{
|
||||||
protected readonly ILogger _logger;
|
protected readonly ILogger _logger;
|
||||||
protected readonly Cultures _cultures;
|
protected readonly MultiCulture _cultures;
|
||||||
protected readonly IStringLocalizer<Resource> _localizer;
|
protected readonly IStringLocalizer<Resource> _localizer;
|
||||||
|
|
||||||
public ViewControllerBase(ILogger logger, Cultures cultures, IStringLocalizer<Resource> localizer)
|
public ViewControllerBase(ILogger logger, MultiCulture cultures, IStringLocalizer<Resource> localizer)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cultures = cultures;
|
_cultures = cultures;
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ using EnvelopeGenerator.Application.Common.Dto.Receiver;
|
|||||||
using EnvelopeGenerator.Web.Models;
|
using EnvelopeGenerator.Web.Models;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Globalization;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Extensions;
|
namespace EnvelopeGenerator.Web.Extensions;
|
||||||
@@ -58,8 +60,19 @@ public static class WebExtensions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Cookie
|
#region Cookie
|
||||||
public static string? GetCulture(this IRequestCookieCollection cookies)
|
public static string GetCulture(this IRequestCookieCollection cookies)
|
||||||
=> cookies[CookieRequestCultureProvider.DefaultCookieName];
|
{
|
||||||
|
var cookieValue = cookies[CookieRequestCultureProvider.DefaultCookieName];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(cookieValue))
|
||||||
|
{
|
||||||
|
var culture = CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures.FirstOrDefault().Value;
|
||||||
|
if (!string.IsNullOrEmpty(culture))
|
||||||
|
return culture;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CultureInfo.CurrentUICulture.Name;
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetCulture(this IResponseCookies cookies, string culture)
|
public static void SetCulture(this IResponseCookies cookies, string culture)
|
||||||
{
|
{
|
||||||
@@ -116,4 +129,31 @@ public static class WebExtensions
|
|||||||
Body = "Bitte kontaktieren Sie das IT-Team."
|
Body = "Bitte kontaktieren Sie das IT-Team."
|
||||||
});
|
});
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region HttpContext
|
||||||
|
public static CultureInfo? GetCultureByAcceptLanguage(this HttpContext context)
|
||||||
|
{
|
||||||
|
var acceptLanguage = context.Request.Headers.AcceptLanguage.ToString();
|
||||||
|
if (string.IsNullOrWhiteSpace(acceptLanguage))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach (var value in acceptLanguage.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
||||||
|
{
|
||||||
|
var cultureName = value.Split(';', 2)[0];
|
||||||
|
if (string.IsNullOrWhiteSpace(cultureName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new CultureInfo(cultureName);
|
||||||
|
}
|
||||||
|
catch (CultureNotFoundException)
|
||||||
|
{
|
||||||
|
// ignore invalid cultures and continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,9 @@ namespace EnvelopeGenerator.Web.Middleware;
|
|||||||
public class CultureMiddleware
|
public class CultureMiddleware
|
||||||
{
|
{
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly Cultures _cultures;
|
private readonly MultiCulture _cultures;
|
||||||
|
|
||||||
public CultureMiddleware(RequestDelegate next, IOptions<Cultures> culturesOpt)
|
public CultureMiddleware(RequestDelegate next, IOptions<MultiCulture> culturesOpt)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_cultures = culturesOpt.Value;
|
_cultures = culturesOpt.Value;
|
||||||
@@ -22,11 +22,15 @@ public class CultureMiddleware
|
|||||||
var cookieName = CookieRequestCultureProvider.DefaultCookieName;
|
var cookieName = CookieRequestCultureProvider.DefaultCookieName;
|
||||||
var cookieValue = context.Request.Cookies[cookieName];
|
var cookieValue = context.Request.Cookies[cookieName];
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(cookieValue))
|
if (!_cultures.Languages.Contains(cookieValue))
|
||||||
{
|
{
|
||||||
context.Response.Cookies.SetCulture(_cultures.Default.Language);
|
var requestCulture = context.GetCultureByAcceptLanguage()?.Name;
|
||||||
CultureInfo.CurrentCulture = new CultureInfo(_cultures.Default.Language);
|
var culture = _cultures.GetOrDefault(requestCulture);
|
||||||
CultureInfo.CurrentUICulture = new CultureInfo(_cultures.Default.Language);
|
var cultureInfo = culture.Info ?? new CultureInfo(culture.Language);
|
||||||
|
|
||||||
|
context.Response.Cookies.SetCulture(culture.Language);
|
||||||
|
CultureInfo.CurrentCulture = cultureInfo;
|
||||||
|
CultureInfo.CurrentUICulture = cultureInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _next(context);
|
await _next(context);
|
||||||
|
|||||||
@@ -4,15 +4,20 @@ namespace EnvelopeGenerator.Web.Models
|
|||||||
{
|
{
|
||||||
public class Culture
|
public class Culture
|
||||||
{
|
{
|
||||||
private string _language = string.Empty;
|
private string _language = null!;
|
||||||
public string Language { get => _language;
|
|
||||||
init {
|
public required string Language
|
||||||
|
{
|
||||||
|
get => _language;
|
||||||
|
init
|
||||||
|
{
|
||||||
_language = value;
|
_language = value;
|
||||||
Info = new(value);
|
Info = new(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public string FIClass { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
public CultureInfo? Info { get; init; }
|
public string FIClass { get; init; } = null!;
|
||||||
|
|
||||||
|
public CultureInfo Info { get; init; } = null!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
namespace EnvelopeGenerator.Web.Models
|
namespace EnvelopeGenerator.Web.Models
|
||||||
{
|
{
|
||||||
public class Cultures : List<Culture>
|
public class MultiCulture : List<Culture>
|
||||||
{
|
{
|
||||||
public IEnumerable<string> Languages => this.Select(c => c.Language);
|
public IEnumerable<string> Languages => this.Select(c => c.Language);
|
||||||
|
|
||||||
public IEnumerable<string> FIClasses => this.Select(c => c.FIClass);
|
public IEnumerable<string> FIClasses => this.Select(c => c.FIClass);
|
||||||
|
|
||||||
public Culture Default => this.First();
|
public Culture Default => this.First();
|
||||||
|
|
||||||
public Culture? this[string? language] => language is null ? null : this.Where(c => c.Language == language).FirstOrDefault();
|
public Culture GetOrDefault(string? language) => this[language] ?? Default;
|
||||||
|
|
||||||
|
public Culture? this[string? language] => language is null ? null : this.FirstOrDefault(c => string.Equals(c.Language, language, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,8 +165,8 @@ try
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Register the FlagIconCssClass instance as a singleton
|
// Register the FlagIconCssClass instance as a singleton
|
||||||
builder.Services.Configure<Cultures>(config.GetSection("Cultures"));
|
builder.Services.Configure<MultiCulture>(config.GetSection("Cultures"));
|
||||||
builder.Services.AddSingleton(sp => sp.GetRequiredService<IOptions<Cultures>>().Value);
|
builder.Services.AddSingleton(sp => sp.GetRequiredService<IOptions<MultiCulture>>().Value);
|
||||||
|
|
||||||
// Register mail services
|
// Register mail services
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
@@ -230,7 +230,7 @@ try
|
|||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
var cultures = app.Services.GetRequiredService<Cultures>();
|
var cultures = app.Services.GetRequiredService<MultiCulture>();
|
||||||
if (!cultures.Any())
|
if (!cultures.Any())
|
||||||
throw new InvalidOperationException(@"Languages section is missing in the appsettings. Please configure like following.
|
throw new InvalidOperationException(@"Languages section is missing in the appsettings. Please configure like following.
|
||||||
Language is both a name of the culture and the name of the resx file such as Resource.de-DE.resx
|
Language is both a name of the culture and the name of the resx file such as Resource.de-DE.resx
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
<p>
|
<p>
|
||||||
<small class="text-body-secondary">
|
<small class="text-body-secondary">
|
||||||
@Html.Raw(_localizer.EnvelopeInfo2().Format(
|
@Html.Raw(_localizer.EnvelopeInfo2().Format(
|
||||||
envelope?.AddedWhen.ToString(userCulture?.Info?.DateTimeFormat),
|
envelope?.AddedWhen.ToString(userCulture?.Info.DateTimeFormat),
|
||||||
$"{sender?.Prename} {sender?.Name}",
|
$"{sender?.Prename} {sender?.Name}",
|
||||||
sender?.Email,
|
sender?.Email,
|
||||||
envelope?.Title,
|
envelope?.Title,
|
||||||
@@ -216,6 +216,6 @@
|
|||||||
var documentBase64String = Convert.ToBase64String(documentBytes);
|
var documentBase64String = Convert.ToBase64String(documentBytes);
|
||||||
var envelopeKey = ViewData["EnvelopeKey"] as string;
|
var envelopeKey = ViewData["EnvelopeKey"] as string;
|
||||||
|
|
||||||
@:document.addEventListener("DOMContentLoaded", async () => await new App("@envelopeKey", @Html.Raw(envelopeReceiverJson), B64ToBuff("@Html.Raw(documentBase64String)"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info?.TwoLetterISOLanguageName").init())
|
@:document.addEventListener("DOMContentLoaded", async () => await new App("@envelopeKey", @Html.Raw(envelopeReceiverJson), B64ToBuff("@Html.Raw(documentBase64String)"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info.TwoLetterISOLanguageName").init())
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -7,6 +7,6 @@
|
|||||||
@using Microsoft.Extensions.Options
|
@using Microsoft.Extensions.Options
|
||||||
@inject IStringLocalizer<Resource> _localizer
|
@inject IStringLocalizer<Resource> _localizer
|
||||||
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor _accessor
|
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor _accessor
|
||||||
@inject Cultures _cultures
|
@inject MultiCulture _cultures
|
||||||
@inject IOptions<CustomImages> _cImgOpt
|
@inject IOptions<CustomImages> _cImgOpt
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
Reference in New Issue
Block a user