Compare commits
4 Commits
d077a66796
...
f509cc8b3b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f509cc8b3b | ||
|
|
290a1dd522 | ||
|
|
2c147f44b7 | ||
|
|
3fd2f90f65 |
@@ -1,5 +1,6 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||
@@ -15,10 +16,14 @@ namespace EnvelopeGenerator.Application.Contracts
|
||||
|
||||
Task<bool> IsSigned(int envelopeId, string userReference);
|
||||
|
||||
Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null);
|
||||
Task<bool> IsRejected(int envelopeId, string? userReference = null);
|
||||
|
||||
Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false);
|
||||
|
||||
Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null);
|
||||
|
||||
Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null);
|
||||
Task<IEnumerable<ReceiverDto>> ReadRejectingReceivers(int envelopeId);
|
||||
|
||||
Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null);
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,5 @@ namespace EnvelopeGenerator.Application.DTOs
|
||||
bool IsAlreadySent,
|
||||
string? StatusTranslated,
|
||||
string? ContractTypeTranslated,
|
||||
IEnumerable<EnvelopeDocumentDto>? Documents,
|
||||
IEnumerable<EnvelopeHistoryDto>? History);
|
||||
IEnumerable<EnvelopeDocumentDto>? Documents);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.UserManager.Application.DTOs.User;
|
||||
using static EnvelopeGenerator.Common.Constants;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||
@@ -13,5 +14,5 @@ namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory
|
||||
UserCreateDto? Sender,
|
||||
ReceiverDto? Receiver,
|
||||
ReferenceType ReferenceType,
|
||||
string? Comment = null);
|
||||
string? Comment = null) : BaseDTO<long>(Id);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace EnvelopeGenerator.Application.DTOs
|
||||
{
|
||||
public record ReceiverDto(
|
||||
int Id,
|
||||
string EmailAddress,
|
||||
string Signature,
|
||||
DateTime AddedWhen
|
||||
);
|
||||
) : BaseDTO<int>(Id);
|
||||
}
|
||||
@@ -102,9 +102,9 @@ namespace EnvelopeGenerator.Application
|
||||
/// <returns>The receiver signature.</returns>
|
||||
public static string? GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
|
||||
|
||||
public static void LogEnvelopeError(this ILogger logger, string envelopeEeceiverId, Exception? exception = null, string? message = null, params object?[] args)
|
||||
public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
|
||||
{
|
||||
var sb = new StringBuilder().AppendLine(envelopeEeceiverId.DecodeEnvelopeReceiverId().ToTitle());
|
||||
var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
|
||||
|
||||
if (message is not null)
|
||||
sb.AppendLine(message);
|
||||
|
||||
@@ -135,6 +135,12 @@
|
||||
<data name="DocProtected" xml:space="preserve">
|
||||
<value>Dokument geschützt</value>
|
||||
</data>
|
||||
<data name="DocRejected" xml:space="preserve">
|
||||
<value>Dokument abgelehnt</value>
|
||||
</data>
|
||||
<data name="DocSigned" xml:space="preserve">
|
||||
<value>Dokument unterschrieben</value>
|
||||
</data>
|
||||
<data name="en-US" xml:space="preserve">
|
||||
<value>Englisch</value>
|
||||
</data>
|
||||
@@ -174,8 +180,20 @@
|
||||
<data name="Rejection" xml:space="preserve">
|
||||
<value>Ablehnung</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1" xml:space="preserve">
|
||||
<value>Ihre Ablehnung wurde weitergeleitet!</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1_ext" xml:space="preserve">
|
||||
<value>Vorgang abgebrochen!</value>
|
||||
</data>
|
||||
<data name="RejectionInfo2" xml:space="preserve">
|
||||
<value>Sie können bei Bedarf mit {0}, <a href="mailto:{1}?subject={2}&body=Sehr geehrte(r)%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen.</value>
|
||||
</data>
|
||||
<data name="RejectionInfo2_ext" xml:space="preserve">
|
||||
<value>Das Vorgang wurde von einer der beteiligten Parteien abgelehnt. Sie können bei Bedarf mit {0}, <a href="mailto:{1}?subject={2}&body=Sehr geehrte(r)%20{0},%0A%0A%0A">{1}</a> Kontakt aufnehmen.</value>
|
||||
</data>
|
||||
<data name="RejectionReasonQ" xml:space="preserve">
|
||||
<value>Warum lehnen Sie den Vertrag ab?</value>
|
||||
<value>Bitte geben Sie einen Grund an:</value>
|
||||
</data>
|
||||
<data name="SigAgree" xml:space="preserve">
|
||||
<value>Durch Klick auf Abschließen stimme ich zu, dass die abgebildete und übermittelte Signatur als elektronische Darstellung meiner Signatur in den Fällen gelten, in denen ich sie auf Dokumenten, einschließlich rechtsgültiger Verträge verwende.</value>
|
||||
|
||||
@@ -135,6 +135,12 @@
|
||||
<data name="DocProtected" xml:space="preserve">
|
||||
<value>Document protected</value>
|
||||
</data>
|
||||
<data name="DocRejected" xml:space="preserve">
|
||||
<value>Document rejected</value>
|
||||
</data>
|
||||
<data name="DocSigned" xml:space="preserve">
|
||||
<value>Document signed</value>
|
||||
</data>
|
||||
<data name="en-US" xml:space="preserve">
|
||||
<value>English</value>
|
||||
</data>
|
||||
@@ -174,8 +180,20 @@
|
||||
<data name="Rejection" xml:space="preserve">
|
||||
<value>Rejection</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1" xml:space="preserve">
|
||||
<value>Your rejection has been forwarded!</value>
|
||||
</data>
|
||||
<data name="RejectionInfo1_ext" xml:space="preserve">
|
||||
<value>Process canceled!</value>
|
||||
</data>
|
||||
<data name="RejectionInfo2" xml:space="preserve">
|
||||
<value>You can contact {0}, <a href="mailto:{1}?subject={2}&body=Dear%20{0},%0A%0A%0A">{1}</a> if required.</value>
|
||||
</data>
|
||||
<data name="RejectionInfo2_ext" xml:space="preserve">
|
||||
<value>The process has been rejected by one of the parties involved. You can contact {0}, <a href="mailto:{1}?subject={2}&body=Dear%20{0},%0A%0A%0A">{1}</a> if required.</value>
|
||||
</data>
|
||||
<data name="RejectionReasonQ" xml:space="preserve">
|
||||
<value>Why do you reject the contract?</value>
|
||||
<value>Please give a reason:</value>
|
||||
</data>
|
||||
<data name="SigAgree" xml:space="preserve">
|
||||
<value>By clicking on Finalize, I agree that the signature shown and submitted is an electronic representation of my signature in cases where I use it on documents, including legally binding contracts.</value>
|
||||
|
||||
@@ -8,6 +8,7 @@ using static EnvelopeGenerator.Common.Constants;
|
||||
using EnvelopeGenerator.Application.Resources;
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||
using EnvelopeGenerator.Application.DTOs;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Services
|
||||
{
|
||||
@@ -50,20 +51,33 @@ namespace EnvelopeGenerator.Application.Services
|
||||
status: (int)EnvelopeStatus.DocumentRejected) > 0;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null)
|
||||
public async Task<IEnumerable<EnvelopeHistoryDto>> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false)
|
||||
{
|
||||
var histDTOs = _mapper.MapOrThrow<IEnumerable<EnvelopeHistoryDto>>(
|
||||
await _repository.ReadAsync(
|
||||
envelopeId: envelopeId,
|
||||
userReference: userReference,
|
||||
status: status));
|
||||
status: status,
|
||||
withSender: withSender,
|
||||
withReceiver: withReceiver));
|
||||
return referenceType is null ? histDTOs : histDTOs.Where(h => h.ReferenceType == referenceType);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<EnvelopeHistoryDto>> ReadRejectedAsync(int envelopeId, string? userReference = null) =>
|
||||
await ReadAsync(envelopeId: envelopeId, userReference: userReference, status: (int)EnvelopeStatus.DocumentRejected);
|
||||
await ReadAsync(envelopeId: envelopeId, userReference: userReference, status: (int)EnvelopeStatus.DocumentRejected, withReceiver:true);
|
||||
|
||||
public async Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null) =>
|
||||
//TODO: use IQueryable in repository to incerease the performance
|
||||
public async Task<IEnumerable<ReceiverDto>> ReadRejectingReceivers(int envelopeId)
|
||||
{
|
||||
var envelopes = await ReadRejectedAsync(envelopeId);
|
||||
return envelopes is null
|
||||
? Enumerable.Empty<ReceiverDto>()
|
||||
: envelopes
|
||||
.Where(eh => eh?.Receiver != null)
|
||||
.Select(eh => eh.Receiver!);
|
||||
}
|
||||
|
||||
public async Task<DataResult<long>> RecordAsync(int envelopeId, string userReference, EnvelopeStatus status, string? comment = null) =>
|
||||
await CreateAsync(new (EnvelopeId: envelopeId, UserReference: userReference, Status: (int)status, ActionDate: DateTime.Now, Comment: comment))
|
||||
.ThenAsync(
|
||||
Success: id => Result.Success(id),
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="DigitalData.Core.Domain">
|
||||
<HintPath>..\..\WebCoreModules\DigitalData.Core.Domain\bin\Debug\net7.0\DigitalData.Core.Domain.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DigitalData.UserManager.Domain">
|
||||
<HintPath>..\..\WebUserManager\DigitalData.UserManager.Domain\bin\Debug\net7.0\DigitalData.UserManager.Domain.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Application;
|
||||
using EnvelopeGenerator.Application.Contracts;
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Common;
|
||||
using EnvelopeGenerator.Web.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@@ -134,7 +133,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
if (envRcvRes.IsFailed)
|
||||
{
|
||||
_logger.LogNotice(envRcvRes.Notices);
|
||||
return Unauthorized();
|
||||
return Unauthorized("you are not authirized");
|
||||
}
|
||||
|
||||
return await _histService.RecordAsync(envRcvRes.Data.EnvelopeId, userReference: mail, EnvelopeStatus.DocumentRejected, comment: reason).ThenAsync(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using EnvelopeGenerator.Application.Contracts;
|
||||
using EnvelopeGenerator.Application.Services;
|
||||
using EnvelopeGenerator.Common;
|
||||
using EnvelopeGenerator.Web.Services;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
@@ -71,7 +70,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception:ex, message: _localizer[WebKey.UnexpectedError]);
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception:ex, message: _localizer[WebKey.UnexpectedError]);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
@@ -105,7 +104,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex);
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
@@ -118,7 +117,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
||||
(string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
||||
|
||||
if(uuid is null || signature is null)
|
||||
if (uuid is null || signature is null)
|
||||
{
|
||||
_logger.LogEnvelopeError(uuid: uuid, signature: signature, message: _localizer[WebKey.WrongEnvelopeReceiverId]);
|
||||
return Unauthorized();
|
||||
@@ -126,89 +125,100 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
|
||||
_logger.LogInformation($"Envelope UUID: [{uuid}]\nReceiver Signature: [{signature}]");
|
||||
|
||||
return await _envRcvService.VerifyAccessCodeAsync(uuid: uuid, signature: signature, accessCode: access_code).ThenAsync(
|
||||
SuccessAsync: async isVerified =>
|
||||
{
|
||||
EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId);
|
||||
if (isVerified)
|
||||
//check access code
|
||||
EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId);
|
||||
var verification = await _envRcvService.VerifyAccessCodeAsync(uuid: uuid, signature: signature, accessCode: access_code);
|
||||
if (verification.IsFailed)
|
||||
{
|
||||
_logger.LogNotice(verification.Notices);
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
return View("EnvelopeLocked")
|
||||
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
|
||||
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
|
||||
}
|
||||
else if (verification.IsWrong())
|
||||
{
|
||||
database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); //for history
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
return View("EnvelopeLocked")
|
||||
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
|
||||
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||
}
|
||||
|
||||
//show envelope
|
||||
database.Services.actionService.EnterCorrectAccessCode(response.Envelope, response.Receiver); //for history
|
||||
return await _envRcvService.ReadByUuidSignatureAsync(uuid: uuid, signature: signature).ThenAsync<EnvelopeReceiverDto, IActionResult>(
|
||||
SuccessAsync: async er =>
|
||||
{
|
||||
database.Services.actionService.EnterCorrectAccessCode(response.Envelope, response.Receiver); //for history
|
||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||
//check rejection
|
||||
var rejRcvrs = await _historyService.ReadRejectingReceivers(er.Envelope!.Id);
|
||||
if(rejRcvrs.Any())
|
||||
{
|
||||
ViewBag.IsExt = !rejRcvrs.Contains(er.Receiver); //external if the current user is not rejected
|
||||
return View("EnvelopeRejected", er);
|
||||
}
|
||||
|
||||
return await _envRcvService.ReadByUuidSignatureAsync(uuid: uuid, signature: signature).ThenAsync<EnvelopeReceiverDto, IActionResult>(
|
||||
SuccessAsync: async er =>
|
||||
{
|
||||
if(await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress))
|
||||
return View("EnvelopeSigned");
|
||||
//check if it has already signed
|
||||
if (await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress))
|
||||
return View("EnvelopeSigned");
|
||||
|
||||
if (response.Envelope.Documents.Count > 0)
|
||||
{
|
||||
var document = await envelopeOldService.GetDocument(response.Envelope.Documents[0].Id, envelopeReceiverId);
|
||||
byte[] bytes = await envelopeOldService.GetDocumentContents(document);
|
||||
ViewData["DocumentBytes"] = bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.ViewDocumentNotFound();
|
||||
}
|
||||
if (response.Envelope.Documents.Count > 0)
|
||||
{
|
||||
var document = await envelopeOldService.GetDocument(response.Envelope.Documents[0].Id, envelopeReceiverId);
|
||||
byte[] bytes = await envelopeOldService.GetDocumentContents(document);
|
||||
ViewData["DocumentBytes"] = bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document was found.");
|
||||
return this.ViewDocumentNotFound();
|
||||
}
|
||||
|
||||
var claims = new List<Claim> {
|
||||
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)
|
||||
};
|
||||
};
|
||||
|
||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
var authProperties = new AuthenticationProperties {
|
||||
AllowRefresh = false,
|
||||
IsPersistent = false
|
||||
};
|
||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
var authProperties = new AuthenticationProperties
|
||||
{
|
||||
AllowRefresh = false,
|
||||
IsPersistent = false
|
||||
};
|
||||
|
||||
await HttpContext.SignInAsync(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(claimsIdentity),
|
||||
authProperties);
|
||||
await HttpContext.SignInAsync(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(claimsIdentity),
|
||||
authProperties);
|
||||
|
||||
//add PSPDFKit licence key
|
||||
ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"];
|
||||
ViewData["UserCulture"] = _cultures[UserLanguage];
|
||||
//add PSPDFKit licence key
|
||||
ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"];
|
||||
ViewData["UserCulture"] = _cultures[UserLanguage];
|
||||
|
||||
return View("ShowEnvelope", er);
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
return View("ShowEnvelope", er);
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); //for history
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
return View("EnvelopeLocked")
|
||||
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
|
||||
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
}
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
return View("EnvelopeLocked")
|
||||
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
|
||||
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
|
||||
});
|
||||
);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex);
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("EnvelopeKey/{envelopeReceiverId}/Success")]
|
||||
public async Task<IActionResult> EnvelopeSigned(string envelopeReceiverId)
|
||||
{
|
||||
@@ -237,11 +247,42 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex);
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("EnvelopeKey/{envelopeReceiverId}/Rejected")]
|
||||
public async Task<IActionResult> EnvelopeRejected(string envelopeReceiverId)
|
||||
{
|
||||
try
|
||||
{
|
||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
||||
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId).ThenAsync(
|
||||
SuccessAsync: async (er) =>
|
||||
{
|
||||
ViewData["UserCulture"] = _cultures[UserLanguage];
|
||||
return await _historyService.IsRejected(envelopeId: er.EnvelopeId)
|
||||
? View(er)
|
||||
: Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked");
|
||||
|
||||
},
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpGet("IsAuthenticated")]
|
||||
public IActionResult IsAuthenticated()
|
||||
|
||||
73
EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml
Normal file
73
EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml
Normal file
@@ -0,0 +1,73 @@
|
||||
@{
|
||||
ViewData["Title"] = _localizer[WebKey.DocRejected];
|
||||
}
|
||||
@{
|
||||
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
|
||||
}
|
||||
@using DigitalData.Core.DTO;
|
||||
@using EnvelopeGenerator.Application.DTOs;
|
||||
@using Newtonsoft.Json
|
||||
@using Newtonsoft.Json.Serialization
|
||||
@model EnvelopeReceiverDto;
|
||||
<partial name="_CookieConsentPartial" />
|
||||
@{
|
||||
var userCulture = ViewData["UserCulture"] as Culture;
|
||||
var envelope = Model.Envelope;
|
||||
var document = Model.Envelope?.Documents?.FirstOrDefault();
|
||||
var sender = Model.Envelope?.User;
|
||||
var isExt = ViewBag.IsExt ?? false;
|
||||
}
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
<div class="icon rejected">
|
||||
<svg height="100" width="100" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 500 520" xml:space="preserve">
|
||||
<polygon style="fill:#F4B2B0;" points="27.959,164.583 27.959,160.534 172.263,14.827 172.263,164.583 "/>
|
||||
<g>
|
||||
<path style="fill:#B3404A;" d="M459.181,264.152c-5.593-5.981-14.975-6.295-20.956-0.703c-5.981,5.593-6.295,14.976-0.703,20.956
|
||||
c20.435,21.854,31.69,50.379,31.69,80.317c0,64.859-52.766,117.623-117.623,117.623c-64.859,0-117.623-52.766-117.623-117.623
|
||||
s52.765-117.623,117.623-117.623c8.187,0,14.827-6.638,14.827-14.827c0-8.189-6.639-14.827-14.827-14.827
|
||||
c-81.208,0-147.276,66.068-147.276,147.276c0,14.953,2.248,29.389,6.41,42.997H42.786v-167.54c0-8.189-6.638-14.827-14.827-14.827
|
||||
s-14.827,6.638-14.827,14.827v182.366c0,8.189,6.638,14.827,14.827,14.827h195.559c25.359,44.53,73.265,74.626,128.072,74.626
|
||||
c81.208,0,147.276-66.068,147.276-147.276C498.866,327.236,484.772,291.519,459.181,264.152z"/>
|
||||
<path style="fill:#B3404A;" d="M394.597,0H172.263c-0.178,0-0.353,0.021-0.529,0.027c-0.172,0.006-0.344,0.013-0.516,0.025
|
||||
c-0.636,0.044-1.268,0.117-1.889,0.242c-0.021,0.004-0.04,0.012-0.061,0.015c-0.608,0.126-1.202,0.299-1.787,0.5
|
||||
c-0.159,0.053-0.314,0.111-0.471,0.171c-0.577,0.219-1.143,0.463-1.689,0.752c-0.024,0.013-0.049,0.022-0.073,0.034
|
||||
c-0.565,0.304-1.103,0.657-1.626,1.033c-0.135,0.098-0.268,0.197-0.4,0.299c-0.519,0.4-1.023,0.824-1.49,1.296L17.428,150.099
|
||||
c-0.348,0.351-0.676,0.719-0.984,1.1c-0.212,0.261-0.399,0.534-0.59,0.805c-0.086,0.123-0.182,0.239-0.264,0.363
|
||||
c-0.219,0.331-0.415,0.673-0.603,1.017c-0.042,0.076-0.09,0.147-0.13,0.222c-0.187,0.353-0.35,0.713-0.506,1.078
|
||||
c-0.033,0.077-0.073,0.151-0.105,0.23c-0.141,0.345-0.259,0.697-0.374,1.048c-0.034,0.107-0.077,0.211-0.11,0.317
|
||||
c-0.096,0.325-0.172,0.654-0.246,0.984c-0.033,0.142-0.073,0.28-0.101,0.424c-0.059,0.304-0.096,0.609-0.136,0.915
|
||||
c-0.022,0.173-0.055,0.344-0.073,0.519c-0.028,0.302-0.034,0.605-0.044,0.907c-0.006,0.168-0.025,0.334-0.025,0.501v4.051
|
||||
c0,8.189,6.638,14.827,14.827,14.827h144.304c8.189,0,14.827-6.638,14.827-14.827V29.653h192.681v143.315
|
||||
c0,8.189,6.639,14.827,14.827,14.827s14.827-6.638,14.827-14.827V14.827C409.423,6.638,402.786,0,394.597,0z M59.498,149.757
|
||||
l91.096-91.982l6.842-6.908v98.89H59.498z"/>
|
||||
</g>
|
||||
<polygon style="fill:#F4B2B0;" points="425.039,404.045 384.233,363.241 425.039,322.435 392.394,289.792 351.59,330.597
|
||||
310.786,289.792 278.14,322.435 318.946,363.241 278.14,404.045 310.786,436.689 351.59,395.885 392.394,436.689 "/>
|
||||
<path style="fill:#B3404A;" d="M392.395,451.515c-3.932,0-7.702-1.563-10.484-4.343l-30.32-30.322l-30.32,30.322
|
||||
c-5.791,5.788-15.176,5.79-20.969,0l-32.645-32.644c-2.78-2.78-4.343-6.552-4.343-10.484s1.563-7.704,4.343-10.484l30.32-30.32
|
||||
l-30.32-30.32c-2.78-2.78-4.343-6.552-4.343-10.484c0-3.932,1.563-7.704,4.343-10.484l32.645-32.644
|
||||
c5.793-5.79,15.178-5.788,20.969,0l30.32,30.322l30.32-30.322c2.781-2.78,6.552-4.343,10.484-4.343s7.704,1.563,10.484,4.343
|
||||
l32.644,32.644c5.79,5.79,5.79,15.178,0,20.968l-30.32,30.32l30.32,30.32c5.79,5.79,5.79,15.178,0,20.968l-32.644,32.644
|
||||
C400.099,449.954,396.327,451.515,392.395,451.515z M299.11,404.045l11.676,11.676l30.32-30.322c5.791-5.79,15.176-5.79,20.969,0
|
||||
l30.32,30.322l11.676-11.676l-30.322-30.32c-5.79-5.79-5.79-15.178,0-20.969l30.322-30.32l-11.676-11.676l-30.32,30.322
|
||||
c-5.791,5.79-15.176,5.79-20.969,0l-30.32-30.322l-11.676,11.676l30.32,30.32c5.79,5.79,5.79,15.178,0,20.969L299.11,404.045z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1>@_localizer[isExt ? WebKey.RejectionInfo1_ext : WebKey.RejectionInfo1].TrySanitize(_sanitizer)</h1>
|
||||
</header>
|
||||
<section class="text-center">
|
||||
<div class="card-body p-0 m-0 ms-4">
|
||||
<p class="card-text p-0 m-0">
|
||||
<small class="text-body-secondary">
|
||||
@Html.Raw(string.Format(_localizer[isExt ? WebKey.RejectionInfo2_ext : WebKey.RejectionInfo2],
|
||||
$"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer),
|
||||
sender?.Email.TrySanitize(_sanitizer),
|
||||
envelope?.Title.TrySanitize(_sanitizer)))
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<footer class="container" id="page-footer">© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
||||
@@ -1,5 +1,5 @@
|
||||
@{
|
||||
ViewData["Title"] = "Dokument unterschrieben";
|
||||
ViewData["Title"] = _localizer[WebKey.DocSigned];
|
||||
}
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"]</title>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/lib/sweetalert2/sweetalert2.min.css" />
|
||||
@@ -17,6 +17,10 @@
|
||||
<link rel="stylesheet" href="~/lib/flag-icons-main/css/flag-icons.min.css" asp-append-version="true" />
|
||||
</head>
|
||||
<body>
|
||||
@if (ViewData["EnvelopeKey"] is string envelopeKey)
|
||||
{
|
||||
<script>const ENV_KEY = "@envelopeKey.TrySanitize(_sanitizer)"</script>
|
||||
}
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/popper/dist/umd/popper.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
public static readonly string LockedFooterBody = nameof(LockedFooterBody);
|
||||
public static readonly string WrongAccessCode = nameof(WrongAccessCode);
|
||||
public static readonly string SignDoc = nameof(SignDoc);
|
||||
public static readonly string DocRejected = nameof(DocRejected);
|
||||
public static readonly string DocSigned = nameof(DocSigned);
|
||||
public static readonly string DocProtected = nameof(DocProtected);
|
||||
public static readonly string Complete = nameof(Complete);
|
||||
public static readonly string EnvelopeInfo1 = nameof(EnvelopeInfo1);
|
||||
@@ -26,5 +28,9 @@
|
||||
public static readonly string Reject = nameof(Reject);
|
||||
public static readonly string and = nameof(and);
|
||||
public static readonly string Hello = nameof(Hello);
|
||||
}
|
||||
public static readonly string RejectionInfo1 = nameof(RejectionInfo1);
|
||||
public static readonly string RejectionInfo2 = nameof(RejectionInfo2);
|
||||
public static readonly string RejectionInfo1_ext = nameof(RejectionInfo1_ext);
|
||||
public static readonly string RejectionInfo2_ext = nameof(RejectionInfo2_ext);
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,11 @@ body {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.page header .icon.rejected {
|
||||
background-color: #e4d8d5;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.page .form {
|
||||
max-width: 30rem;
|
||||
margin: 2rem auto;
|
||||
|
||||
@@ -9,11 +9,19 @@ class API {
|
||||
return `/api/envelope/reject`;
|
||||
}
|
||||
|
||||
static get REJECT_REDIR_URL(){
|
||||
return `/envelopekey/${API.ENV_KEY}/rejected`;
|
||||
}
|
||||
|
||||
static __XSRF_TOKEN
|
||||
static get XSRF_TOKEN() {
|
||||
API.__XSRF_TOKEN ??= document.getElementsByName('__RequestVerificationToken')[0].value;
|
||||
return API.__XSRF_TOKEN;
|
||||
}
|
||||
|
||||
static get ENV_KEY(){
|
||||
return ENV_KEY ?? document.querySelector('meta[name="env-key"]').getAttribute('content');
|
||||
}
|
||||
}
|
||||
|
||||
const submitForm = async form => await fetch(form.action, {
|
||||
@@ -38,4 +46,8 @@ const createRequest = async (method, url, body, contentType) => {
|
||||
|
||||
const createPost = (url, body, contentType) => createRequest('POST', url, body, contentType);
|
||||
|
||||
const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JSON);
|
||||
const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JSON);
|
||||
|
||||
const redirect = (url) => window.location.href = url;
|
||||
|
||||
const redirRejected = () => redirect(API.REJECT_REDIR_URL);
|
||||
@@ -28,10 +28,9 @@ $('.btn_reject').click(_ =>
|
||||
if (!result.isConfirmed)
|
||||
return;
|
||||
const res = result.value;
|
||||
console.log(res)
|
||||
if (res.ok) {
|
||||
alert('rejected')
|
||||
redirRejected()
|
||||
}
|
||||
else
|
||||
alert('fail')
|
||||
Swal.showValidationMessage(`Request failed: ${res.message}`);
|
||||
}));
|
||||
Reference in New Issue
Block a user