03-11-2023
This commit is contained in:
parent
b08f13a7fd
commit
0b6eecc534
@ -1,4 +1,4 @@
|
|||||||
Public Class EnvelopeResponse
|
Public Class EnvelopeResponse
|
||||||
Public Property Envelope As Envelope
|
Public Property Envelope As Envelope
|
||||||
Public Property ReceiverId As Integer
|
Public Property Receiver As EnvelopeReceiver
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
12
EnvelopeGenerator.Web/Constants.cs
Normal file
12
EnvelopeGenerator.Web/Constants.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace EnvelopeGenerator.Web
|
||||||
|
{
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
public enum ErrorType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
ServerError,
|
||||||
|
FilesystemError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
using DigitalData.Modules.Logging;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using DigitalData.Modules.Logging;
|
||||||
using EnvelopeGenerator.Common;
|
using EnvelopeGenerator.Common;
|
||||||
using EnvelopeGenerator.Web.Services;
|
using EnvelopeGenerator.Web.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
using System.Reflection.Metadata;
|
using static EnvelopeGenerator.Web.Constants;
|
||||||
using static EnvelopeGenerator.Web.Handler.FileHandler;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
@ -24,15 +24,16 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/document/{envelopeKey}")]
|
[Route("api/document/{envelopeKey}")]
|
||||||
[IgnoreAntiforgeryToken]
|
|
||||||
public async Task<IActionResult> Get(string envelopeKey)
|
public async Task<IActionResult> Get(string envelopeKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.Info("Handling file download.");
|
logger.Info("Handling file download.");
|
||||||
|
|
||||||
|
// Validate Envelope Key
|
||||||
EnvelopeResponse r = api.EnsureValidEnvelopeKey(envelopeKey);
|
EnvelopeResponse r = api.EnsureValidEnvelopeKey(envelopeKey);
|
||||||
|
|
||||||
|
// Load document info
|
||||||
var Request = ControllerContext.HttpContext.Request;
|
var Request = ControllerContext.HttpContext.Request;
|
||||||
var document = api.GetDocument(Request, envelopeKey);
|
var document = api.GetDocument(Request, envelopeKey);
|
||||||
|
|
||||||
@ -43,6 +44,15 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
// Return the document as bytes
|
// Return the document as bytes
|
||||||
return File(bytes, "application/octet-stream");
|
return File(bytes, "application/octet-stream");
|
||||||
}
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.Error(e);
|
||||||
|
return Problem(
|
||||||
|
statusCode: 500,
|
||||||
|
detail: e.Message,
|
||||||
|
type: ErrorType.ServerError.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Better error handling & reporting
|
// Better error handling & reporting
|
||||||
@ -57,25 +67,46 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/document/{envelopeKey}")]
|
[Route("api/document/{envelopeKey}")]
|
||||||
[IgnoreAntiforgeryToken]
|
|
||||||
public async Task<IActionResult> Update(string envelopeKey)
|
public async Task<IActionResult> Update(string envelopeKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.Info("Handling file update.");
|
logger.Info("Handling file update.");
|
||||||
|
|
||||||
api.EnsureValidEnvelopeKey(envelopeKey);
|
// Validate Envelope Key
|
||||||
|
EnvelopeResponse r = api.EnsureValidEnvelopeKey(envelopeKey);
|
||||||
|
|
||||||
|
// Load Document info
|
||||||
var Request = ControllerContext.HttpContext.Request;
|
var Request = ControllerContext.HttpContext.Request;
|
||||||
var document = api.GetDocument(Request, envelopeKey);
|
var document = api.GetDocument(Request, envelopeKey);
|
||||||
|
|
||||||
|
// Try to update the document with new data
|
||||||
if (!await api.UpdateDocument(Request.Body, document.Filepath))
|
if (!await api.UpdateDocument(Request.Body, document.Filepath))
|
||||||
{
|
{
|
||||||
throw new IOException("Document could not be saved to disk!");
|
throw new IOException("Document could not be saved to disk!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add history entry
|
||||||
|
database.InsertHistoryEntry(new EnvelopeHistoryEntry()
|
||||||
|
{
|
||||||
|
ActionDescription = "Dokument wurde signiert",
|
||||||
|
ActionDate = DateTime.Now,
|
||||||
|
ActionType = EnvelopeHistoryActionType.Signed,
|
||||||
|
EnvelopeId = r.Envelope.Id,
|
||||||
|
UserReference = r.Receiver.Email
|
||||||
|
});
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.Error(e);
|
||||||
|
return Problem(
|
||||||
|
statusCode: 500,
|
||||||
|
detail: e.Message,
|
||||||
|
type: ErrorType.ServerError.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Better error handling & reporting
|
// Better error handling & reporting
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
using EnvelopeGenerator.Common;
|
using DigitalData.Modules.Logging;
|
||||||
|
using EnvelopeGenerator.Common;
|
||||||
using EnvelopeGenerator.Web.Services;
|
using EnvelopeGenerator.Web.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NLog;
|
using NLog;
|
||||||
using static EnvelopeGenerator.Web.Handler.FileHandler;
|
using static EnvelopeGenerator.Web.Constants;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
@ -23,7 +24,6 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/envelope/{envelopeKey}")]
|
[Route("api/envelope/{envelopeKey}")]
|
||||||
[IgnoreAntiforgeryToken]
|
|
||||||
public IActionResult Get(string envelopeKey)
|
public IActionResult Get(string envelopeKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -50,16 +50,13 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/envelope/{envelopeKey}")]
|
[Route("api/envelope/{envelopeKey}")]
|
||||||
[IgnoreAntiforgeryToken]
|
|
||||||
public async Task<IActionResult> Update(string envelopeKey)
|
public async Task<IActionResult> Update(string envelopeKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.Info("Handling envelope saving.");
|
logger.Info("Handling envelope saving.");
|
||||||
|
|
||||||
api.EnsureValidEnvelopeKey(envelopeKey);
|
EnvelopeResponse r = api.EnsureValidEnvelopeKey(envelopeKey);
|
||||||
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
|
||||||
|
|
||||||
var Request = ControllerContext.HttpContext.Request;
|
var Request = ControllerContext.HttpContext.Request;
|
||||||
var document = api.GetDocument(Request, envelopeKey);
|
var document = api.GetDocument(Request, envelopeKey);
|
||||||
@ -71,13 +68,10 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
throw new ArgumentNullException("AnnotationData");
|
throw new ArgumentNullException("AnnotationData");
|
||||||
}
|
}
|
||||||
|
|
||||||
State state = api.GetState(logging.LogConfig, database.MSSQL);
|
database.InsertDocumentStatus(new DocumentStatus()
|
||||||
DocumentStatusModel model = new(state);
|
|
||||||
|
|
||||||
model.InsertOrUpdate(new DocumentStatus()
|
|
||||||
{
|
{
|
||||||
EnvelopeId = r.Envelope.Id,
|
EnvelopeId = r.Envelope.Id,
|
||||||
ReceiverId = r.ReceiverId,
|
ReceiverId = r.Receiver.Id,
|
||||||
Value = annotationData,
|
Value = annotationData,
|
||||||
Status = Common.Constants.DocumentStatus.Signed
|
Status = Common.Constants.DocumentStatus.Signed
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,75 +0,0 @@
|
|||||||
using DigitalData.Modules.Logging;
|
|
||||||
using EnvelopeGenerator.Common;
|
|
||||||
using EnvelopeGenerator.Web.Services;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using static EnvelopeGenerator.Common.Constants;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
|
||||||
{
|
|
||||||
public class HistoryController : Controller
|
|
||||||
{
|
|
||||||
private readonly DatabaseService database;
|
|
||||||
private readonly LoggingService logging;
|
|
||||||
private readonly Logger logger;
|
|
||||||
private readonly ApiService api;
|
|
||||||
|
|
||||||
public HistoryController(DatabaseService database, LoggingService logging, ApiService api)
|
|
||||||
{
|
|
||||||
this.database = database;
|
|
||||||
this.logging = logging;
|
|
||||||
this.logger = logging.LogConfig.GetLoggerFor(GetType().Name);
|
|
||||||
this.api = api;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("api/history/{envelopeKey}")]
|
|
||||||
[IgnoreAntiforgeryToken]
|
|
||||||
public IActionResult Create(string envelopeKey, [FromBody] ActionObject action)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var Request = ControllerContext.HttpContext.Request;
|
|
||||||
|
|
||||||
api.EnsureValidEnvelopeKey(envelopeKey);
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
|
||||||
var receiver = r.Envelope.Receivers.Where(receiver => receiver.Id == r.ReceiverId).SingleOrDefault();
|
|
||||||
|
|
||||||
if (receiver == null)
|
|
||||||
{
|
|
||||||
return BadRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
string actionTypeString = action.actionType;
|
|
||||||
string actionDescription = action.actionDescription;
|
|
||||||
|
|
||||||
if (!Enum.TryParse<EnvelopeHistoryActionType>(actionTypeString, out var actionType))
|
|
||||||
{
|
|
||||||
return BadRequest();
|
|
||||||
};
|
|
||||||
|
|
||||||
database.InsertHistoryEntry(new EnvelopeHistoryEntry()
|
|
||||||
{
|
|
||||||
ActionDescription = actionDescription,
|
|
||||||
ActionDate = DateTime.Now,
|
|
||||||
ActionType = actionType,
|
|
||||||
EnvelopeId = r.Envelope.Id,
|
|
||||||
UserReference = receiver.Email
|
|
||||||
});
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error(e);
|
|
||||||
return Problem(statusCode: 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ActionObject
|
|
||||||
{
|
|
||||||
public string actionType { get; set; }
|
|
||||||
public string actionDescription { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,281 +0,0 @@
|
|||||||
using DigitalData.Modules.Database;
|
|
||||||
using DigitalData.Modules.Logging;
|
|
||||||
using EnvelopeGenerator.Common;
|
|
||||||
using EnvelopeGenerator.Common.My.Resources;
|
|
||||||
using EnvelopeGenerator.Web.Services;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using System.IO.Pipelines;
|
|
||||||
using System.Reflection.Metadata.Ecma335;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Handler
|
|
||||||
{
|
|
||||||
public class FileHandler
|
|
||||||
{
|
|
||||||
public class PostResult
|
|
||||||
{
|
|
||||||
readonly bool Ok = true;
|
|
||||||
readonly string ErrorMessage = "";
|
|
||||||
readonly ErrorType ErrorType = ErrorType.None;
|
|
||||||
|
|
||||||
public PostResult()
|
|
||||||
{
|
|
||||||
Ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PostResult(ErrorType errorType, string errorMessage)
|
|
||||||
{
|
|
||||||
Ok = false;
|
|
||||||
ErrorType = errorType;
|
|
||||||
ErrorMessage = errorMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum ErrorType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
ServerError,
|
|
||||||
FilesystemError
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// URL: GET /api/envelope/{envelopeKey}
|
|
||||||
///
|
|
||||||
/// Returns a
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IResult HandleGetEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
|
|
||||||
{
|
|
||||||
var logger = logging.LogConfig.GetLogger("FileHandler");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.Info("Handling envelope loading.");
|
|
||||||
|
|
||||||
// Load Envelope from EnvelopeKey
|
|
||||||
string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request);
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
|
||||||
|
|
||||||
// Return the envelope and additional data as json
|
|
||||||
return Results.Json(r);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// Better error handling & reporting
|
|
||||||
logger.Error(e);
|
|
||||||
return Results.Problem(e.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// URL: GET /api/document/{envelopeKey}?index={documentIndex}
|
|
||||||
///
|
|
||||||
/// Returns a document for the supplied EnvelopeKey and Document Id / Index
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>file buffer of the requested document</returns>
|
|
||||||
public async Task<IResult> HandleGetDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
|
|
||||||
{
|
|
||||||
var logger = logging.LogConfig.GetLogger("FileHandler");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.Info("Handling file download.");
|
|
||||||
|
|
||||||
// Load Envelope from EnvelopeKey
|
|
||||||
string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request);
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
|
||||||
|
|
||||||
// Get the document Index
|
|
||||||
int documentId = EnsureValidDocumentIndex(logger, ctx.Request);
|
|
||||||
var document = GetDocument(r.Envelope, documentId);
|
|
||||||
|
|
||||||
// Load the document from disk
|
|
||||||
var bytes = await File.ReadAllBytesAsync(document.Filepath);
|
|
||||||
logger.Info("Serving file, size: [{0}]", bytes.Length);
|
|
||||||
|
|
||||||
// Return the document as bytes
|
|
||||||
return Results.File(bytes);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// Better error handling & reporting
|
|
||||||
logger.Error(e);
|
|
||||||
return Results.Problem(
|
|
||||||
statusCode: 500,
|
|
||||||
detail: e.Message,
|
|
||||||
type: ErrorType.ServerError.ToString());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IResult> HandlePostDocument(HttpContext ctx, DatabaseService database, LoggingService logging)
|
|
||||||
{
|
|
||||||
var logger = logging.LogConfig.GetLogger("FileHandler");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.Info("Handling file upload.");
|
|
||||||
|
|
||||||
// Load Envelope from EnvelopeKey
|
|
||||||
string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request);
|
|
||||||
EnvelopeResponse response = database.LoadEnvelope(envelopeKey);
|
|
||||||
|
|
||||||
// Get the document Index
|
|
||||||
int documentId = EnsureValidDocumentIndex(logger, ctx.Request);
|
|
||||||
var document = GetDocument(response.Envelope, documentId);
|
|
||||||
|
|
||||||
using FileStream fs = new(document.Filepath, FileMode.Open);
|
|
||||||
await ctx.Request.Body.CopyToAsync(fs);
|
|
||||||
fs.Flush();
|
|
||||||
|
|
||||||
return Results.Ok();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// Better error handling & reporting
|
|
||||||
logger.Error(e);
|
|
||||||
return Results.Problem(
|
|
||||||
statusCode: 500,
|
|
||||||
detail: e.Message,
|
|
||||||
type: ErrorType.ServerError.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IResult> HandlePostEnvelope(HttpContext ctx, DatabaseService database, LoggingService logging)
|
|
||||||
{
|
|
||||||
var logger = logging.LogConfig.GetLogger("FileHandler");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logger.Info("Handling envelope saving.");
|
|
||||||
|
|
||||||
// Load Envelope from EnvelopeKey
|
|
||||||
string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request);
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
|
||||||
|
|
||||||
// Get the document Index
|
|
||||||
int documentId = EnsureValidDocumentIndex(logger, ctx.Request);
|
|
||||||
var document = GetDocument(r.Envelope, documentId);
|
|
||||||
|
|
||||||
string? annotationData = await EnsureValidAnnotationData(logger, ctx.Request);
|
|
||||||
|
|
||||||
if (annotationData == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("AnnotationData");
|
|
||||||
}
|
|
||||||
|
|
||||||
State state = GetState(logging.LogConfig, database.MSSQL);
|
|
||||||
DocumentStatusModel model = new(state);
|
|
||||||
|
|
||||||
model.InsertOrUpdate(new DocumentStatus()
|
|
||||||
{
|
|
||||||
EnvelopeId = r.Envelope.Id,
|
|
||||||
ReceiverId = r.ReceiverId,
|
|
||||||
Value = annotationData,
|
|
||||||
Status = Common.Constants.DocumentStatus.Signed
|
|
||||||
});
|
|
||||||
|
|
||||||
return Results.Ok();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// Better error handling & reporting
|
|
||||||
logger.Error(e);
|
|
||||||
return Results.Problem(
|
|
||||||
statusCode: 500,
|
|
||||||
detail: e.Message,
|
|
||||||
type: ErrorType.ServerError.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Private
|
|
||||||
|
|
||||||
|
|
||||||
private State GetState(LogConfig LogConfig, MSSQLServer Database)
|
|
||||||
{
|
|
||||||
return new State
|
|
||||||
{
|
|
||||||
LogConfig = LogConfig,
|
|
||||||
Database = Database,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private int EnsureValidDocumentIndex(Logger logger, HttpRequest request)
|
|
||||||
{
|
|
||||||
if (request.Query.TryGetValue("index", out StringValues documentIndexString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return int.Parse(documentIndexString.First());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("DocumentIndex", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("DocumentIndex");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EnsureValidEnvelopeKey(Logger logger, HttpRequest request)
|
|
||||||
{
|
|
||||||
logger.Debug("Parsing EnvelopeKey..");
|
|
||||||
var envelopeKey = request.RouteValues["envelopeKey"] as string;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(envelopeKey))
|
|
||||||
throw new ArgumentNullException("EnvelopeKey");
|
|
||||||
|
|
||||||
Tuple<string, string> result = Helpers.DecodeEnvelopeReceiverId(envelopeKey);
|
|
||||||
logger.Debug("EnvelopeUUID: [{0}]", result.Item1);
|
|
||||||
logger.Debug("ReceiverSignature: [{0}]", result.Item2);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(result.Item1))
|
|
||||||
throw new ArgumentNullException("EnvelopeUUID");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(result.Item2))
|
|
||||||
throw new ArgumentNullException("ReceiverSignature");
|
|
||||||
|
|
||||||
return envelopeKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string?> EnsureValidAnnotationData(Logger logger, HttpRequest request)
|
|
||||||
{
|
|
||||||
logger.Debug("Parsing AnnotationData..");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using MemoryStream ms = new();
|
|
||||||
await request.BodyReader.CopyToAsync(ms);
|
|
||||||
var bytes = ms.ToArray();
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(bytes);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private EnvelopeDocument GetDocument(Common.Envelope envelope, int documentId)
|
|
||||||
{
|
|
||||||
var document = envelope.Documents.
|
|
||||||
Where(d => d.Id == documentId).
|
|
||||||
FirstOrDefault();
|
|
||||||
|
|
||||||
if (document == null)
|
|
||||||
throw new ArgumentException("DocumentId");
|
|
||||||
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -7,8 +7,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
<meta http-equiv="content-type" content="text/html; 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" />
|
||||||
|
|
||||||
|
|
||||||
<base href="~/" />
|
<base href="~/" />
|
||||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||||
<link href="css/site.css" rel="stylesheet" />
|
<link href="css/site.css" rel="stylesheet" />
|
||||||
@ -30,5 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="_framework/blazor.server.js"></script>
|
<script src="_framework/blazor.server.js"></script>
|
||||||
|
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -254,12 +254,12 @@ class Annotation {
|
|||||||
|
|
||||||
class Network {
|
class Network {
|
||||||
public getEnvelope(envelopeKey: string): Promise<any> {
|
public getEnvelope(envelopeKey: string): Promise<any> {
|
||||||
return fetch(`/api/envelope/${envelopeKey}`, { credentials: "include" })
|
return fetch(`/api/envelope/${envelopeKey}`, this.withCSRFToken({ credentials: "include" }))
|
||||||
.then(res => res.json());
|
.then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDocument(envelopeKey: string, documentId: number): Promise<ArrayBuffer> {
|
public getDocument(envelopeKey: string, documentId: number): Promise<ArrayBuffer> {
|
||||||
return fetch(`/api/document/${envelopeKey}?index=${documentId}`, { credentials: "include" })
|
return fetch(`/api/document/${envelopeKey}?index=${documentId}`, this.withCSRFToken({ credentials: "include" }))
|
||||||
.then(res => res.arrayBuffer());
|
.then(res => res.arrayBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ class Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.debug("PostDocument/Calling url: " + url)
|
console.debug("PostDocument/Calling url: " + url)
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then((res: Response) => {
|
.then((res: Response) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -291,7 +291,7 @@ class Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.debug("PostEnvelope/Calling url: " + url)
|
console.debug("PostEnvelope/Calling url: " + url)
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then((res: Response) => {
|
.then((res: Response) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -319,7 +319,7 @@ class Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.debug("PostHistory/Calling url: " + url)
|
console.debug("PostHistory/Calling url: " + url)
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then((res: Response) => {
|
.then((res: Response) => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -329,6 +329,14 @@ class Network {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private withCSRFToken(options: RequestInit): RequestInit {
|
||||||
|
const token = (document.getElementsByName("__RequestVerificationToken")[0] as any).value;
|
||||||
|
let headers = options.headers;
|
||||||
|
options.headers = { ...headers, 'X-XSRF-TOKEN': token };
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
private handleResponse(res: Response) {
|
private handleResponse(res: Response) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
console.log(`Request failed with status ${res.status}`)
|
console.log(`Request failed with status ${res.status}`)
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using DigitalData.Modules.Logging;
|
using DigitalData.Modules.Logging;
|
||||||
using EnvelopeGenerator.Common;
|
using EnvelopeGenerator.Common;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using System.Reflection;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -39,9 +40,9 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
if (string.IsNullOrEmpty(result.Item2))
|
if (string.IsNullOrEmpty(result.Item2))
|
||||||
throw new ArgumentNullException("ReceiverSignature");
|
throw new ArgumentNullException("ReceiverSignature");
|
||||||
|
|
||||||
EnvelopeResponse r = database.LoadEnvelope(envelopeKey);
|
EnvelopeResponse response = database.LoadEnvelope(envelopeKey);
|
||||||
|
|
||||||
return r;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string?> EnsureValidAnnotationData(HttpRequest request)
|
public async Task<string?> EnsureValidAnnotationData(HttpRequest request)
|
||||||
@ -118,10 +119,6 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public State GetState(LogConfig LogConfig, MSSQLServer Database)
|
public State GetState(LogConfig LogConfig, MSSQLServer Database)
|
||||||
{
|
{
|
||||||
return new State
|
return new State
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
private ReceiverModel receiverModel;
|
private ReceiverModel receiverModel;
|
||||||
private ElementModel elementModel;
|
private ElementModel elementModel;
|
||||||
private HistoryModel historyModel;
|
private HistoryModel historyModel;
|
||||||
|
private DocumentStatusModel documentStatusModel;
|
||||||
private readonly LogConfig _logConfig;
|
private readonly LogConfig _logConfig;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
@ -56,6 +56,7 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
receiverModel = new(state);
|
receiverModel = new(state);
|
||||||
elementModel = new(state);
|
elementModel = new(state);
|
||||||
historyModel = new(state);
|
historyModel = new(state);
|
||||||
|
documentStatusModel = new(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnvelopeResponse LoadEnvelope(string pEnvelopeKey)
|
public EnvelopeResponse LoadEnvelope(string pEnvelopeKey)
|
||||||
@ -65,11 +66,28 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
var receiverSignature = result.Item2;
|
var receiverSignature = result.Item2;
|
||||||
var receiverId = receiverModel.GetReceiverIdBySignature(receiverSignature);
|
var receiverId = receiverModel.GetReceiverIdBySignature(receiverSignature);
|
||||||
|
|
||||||
Envelope envelope = envelopeModel.GetByUuid(envelopeUuid);
|
Envelope? envelope = envelopeModel.GetByUuid(envelopeUuid);
|
||||||
|
|
||||||
|
if (envelope == null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("Envelope not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (envelope.Receivers == null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("Receivers for envelope not loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
EnvelopeReceiver? receiver = envelope.Receivers.Where(r => r.Id == receiverId).SingleOrDefault();
|
||||||
|
|
||||||
|
if (receiver == null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("Receiver not found");
|
||||||
|
}
|
||||||
|
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
ReceiverId = receiverId,
|
Receiver = receiver,
|
||||||
Envelope = envelope
|
Envelope = envelope
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -89,5 +107,10 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
return historyModel.Insert(historyEntry);
|
return historyModel.Insert(historyEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool InsertDocumentStatus(DocumentStatus documentStatus)
|
||||||
|
{
|
||||||
|
return documentStatusModel.InsertOrUpdate(documentStatus);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,14 @@
|
|||||||
|
var __assign = (this && this.__assign) || function () {
|
||||||
|
__assign = Object.assign || function(t) {
|
||||||
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||||
|
s = arguments[i];
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||||
|
t[p] = s[p];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
return __assign.apply(this, arguments);
|
||||||
|
};
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
@ -101,7 +112,7 @@ var App = /** @class */ (function () {
|
|||||||
return [4 /*yield*/, App.Instance.create(annotations)];
|
return [4 /*yield*/, App.Instance.create(annotations)];
|
||||||
case 7:
|
case 7:
|
||||||
createdAnnotations = _b.sent();
|
createdAnnotations = _b.sent();
|
||||||
description = "Umschlag wurde geöffnet";
|
description = "Umschlag wurde ge<EFBFBD>ffnet";
|
||||||
return [4 /*yield*/, App.Network.postHistory(App.envelopeKey, ActionType.Seen, description)];
|
return [4 /*yield*/, App.Network.postHistory(App.envelopeKey, ActionType.Seen, description)];
|
||||||
case 8:
|
case 8:
|
||||||
_b.sent();
|
_b.sent();
|
||||||
@ -127,10 +138,10 @@ var App = /** @class */ (function () {
|
|||||||
case 2:
|
case 2:
|
||||||
result = _b.sent();
|
result = _b.sent();
|
||||||
if (result == true) {
|
if (result == true) {
|
||||||
alert("Dokument zurückgesetzt!");
|
alert("Dokument zur<EFBFBD>ckgesetzt!");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert("Fehler beim Zurücksetzen des Dokuments!");
|
alert("Fehler beim Zur<EFBFBD>cksetzen des Dokuments!");
|
||||||
}
|
}
|
||||||
return [3 /*break*/, 5];
|
return [3 /*break*/, 5];
|
||||||
case 3: return [4 /*yield*/, App.handleFinish(null)];
|
case 3: return [4 /*yield*/, App.handleFinish(null)];
|
||||||
@ -141,7 +152,7 @@ var App = /** @class */ (function () {
|
|||||||
alert("Dokument erfolgreich signiert!");
|
alert("Dokument erfolgreich signiert!");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert("Fehler beim Abschließen des Dokuments!");
|
alert("Fehler beim Abschlie<EFBFBD>en des Dokuments!");
|
||||||
}
|
}
|
||||||
return [3 /*break*/, 5];
|
return [3 /*break*/, 5];
|
||||||
case 5: return [2 /*return*/];
|
case 5: return [2 /*return*/];
|
||||||
@ -216,7 +227,7 @@ var App = /** @class */ (function () {
|
|||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var result;
|
var result;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) {
|
if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zur<EFBFBD>cksetzen?")) {
|
||||||
result = App.Annotation.deleteAnnotations(App.Instance);
|
result = App.Annotation.deleteAnnotations(App.Instance);
|
||||||
return [2 /*return*/, true];
|
return [2 /*return*/, true];
|
||||||
}
|
}
|
||||||
@ -336,11 +347,11 @@ var Network = /** @class */ (function () {
|
|||||||
function Network() {
|
function Network() {
|
||||||
}
|
}
|
||||||
Network.prototype.getEnvelope = function (envelopeKey) {
|
Network.prototype.getEnvelope = function (envelopeKey) {
|
||||||
return fetch("/api/envelope/".concat(envelopeKey), { credentials: "include" })
|
return fetch("/api/envelope/".concat(envelopeKey), this.withCSRFToken({ credentials: "include" }))
|
||||||
.then(function (res) { return res.json(); });
|
.then(function (res) { return res.json(); });
|
||||||
};
|
};
|
||||||
Network.prototype.getDocument = function (envelopeKey, documentId) {
|
Network.prototype.getDocument = function (envelopeKey, documentId) {
|
||||||
return fetch("/api/document/".concat(envelopeKey, "?index=").concat(documentId), { credentials: "include" })
|
return fetch("/api/document/".concat(envelopeKey, "?index=").concat(documentId), this.withCSRFToken({ credentials: "include" }))
|
||||||
.then(function (res) { return res.arrayBuffer(); });
|
.then(function (res) { return res.arrayBuffer(); });
|
||||||
};
|
};
|
||||||
Network.prototype.postDocument = function (envelopeKey, documentId, buffer) {
|
Network.prototype.postDocument = function (envelopeKey, documentId, buffer) {
|
||||||
@ -351,7 +362,7 @@ var Network = /** @class */ (function () {
|
|||||||
body: buffer
|
body: buffer
|
||||||
};
|
};
|
||||||
console.debug("PostDocument/Calling url: " + url);
|
console.debug("PostDocument/Calling url: " + url);
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -369,7 +380,7 @@ var Network = /** @class */ (function () {
|
|||||||
body: jsonString
|
body: jsonString
|
||||||
};
|
};
|
||||||
console.debug("PostEnvelope/Calling url: " + url);
|
console.debug("PostEnvelope/Calling url: " + url);
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -394,7 +405,7 @@ var Network = /** @class */ (function () {
|
|||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
};
|
};
|
||||||
console.debug("PostHistory/Calling url: " + url);
|
console.debug("PostHistory/Calling url: " + url);
|
||||||
return fetch(url, options)
|
return fetch(url, this.withCSRFToken(options))
|
||||||
.then(this.handleResponse)
|
.then(this.handleResponse)
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@ -404,6 +415,12 @@ var Network = /** @class */ (function () {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Network.prototype.withCSRFToken = function (options) {
|
||||||
|
var token = document.getElementsByName("__RequestVerificationToken")[0].value;
|
||||||
|
var headers = options.headers;
|
||||||
|
options.headers = __assign(__assign({}, headers), { 'X-XSRF-TOKEN': token });
|
||||||
|
return options;
|
||||||
|
};
|
||||||
Network.prototype.handleResponse = function (res) {
|
Network.prototype.handleResponse = function (res) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
console.log("Request failed with status ".concat(res.status));
|
console.log("Request failed with status ".concat(res.status));
|
||||||
@ -435,7 +452,7 @@ var UI = /** @class */ (function () {
|
|||||||
type: "custom",
|
type: "custom",
|
||||||
id: "button-reset",
|
id: "button-reset",
|
||||||
className: "button-reset",
|
className: "button-reset",
|
||||||
title: "Zurücksetzen",
|
title: "Zur<EFBFBD>cksetzen",
|
||||||
onPress: function () {
|
onPress: function () {
|
||||||
callback("RESET");
|
callback("RESET");
|
||||||
},
|
},
|
||||||
@ -445,7 +462,7 @@ var UI = /** @class */ (function () {
|
|||||||
type: "custom",
|
type: "custom",
|
||||||
id: "button-finish",
|
id: "button-finish",
|
||||||
className: "button-finish",
|
className: "button-finish",
|
||||||
title: "Abschließen",
|
title: "Abschlie<EFBFBD>en",
|
||||||
onPress: function () {
|
onPress: function () {
|
||||||
callback("FINISH");
|
callback("FINISH");
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user