16.01.24
This commit is contained in:
parent
0a01bf59ef
commit
6131948f2a
@ -39,6 +39,11 @@ Public Class Helpers
|
||||
|
||||
End Function
|
||||
|
||||
Public Shared Function GetAccessCode() As String
|
||||
Return Guid.NewGuid().ToString("d").Substring(1, 6).ToUpper()
|
||||
End Function
|
||||
|
||||
|
||||
Public Shared Function ColorTypeToColor(pColorType As ColorType) As Color
|
||||
Select Case pColorType
|
||||
Case ColorType.ReceiverColor1
|
||||
|
||||
@ -7,16 +7,12 @@ Public Class TemplateService
|
||||
Private _replaceDictionary As Dictionary(Of String, String)
|
||||
|
||||
Private ReadOnly DbConfig As DbConfig
|
||||
Private ReadOnly LogConfig As LogConfig
|
||||
Private ReadOnly Logger As Logger
|
||||
Private ReadOnly EmailHtmlTemplateModel As EmailTemplateModel
|
||||
|
||||
Public Sub New(pState As State)
|
||||
MyBase.New(pState)
|
||||
|
||||
DbConfig = pState.DbConfig
|
||||
LogConfig = pState.LogConfig
|
||||
Logger = LogConfig.GetLogger()
|
||||
EmailHtmlTemplateModel = New EmailTemplateModel(pState)
|
||||
End Sub
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ Public Class EnvelopeEditorController
|
||||
Public ReadOnly EmailService As EmailService
|
||||
Public ReadOnly ActionService As ActionService
|
||||
|
||||
|
||||
Public ReadOnly Thumbnail As Thumbnail
|
||||
|
||||
Public Sub New(pState As State)
|
||||
|
||||
@ -22,6 +22,10 @@ Partial Public Class frmEnvelopeEditor
|
||||
Private Controller As EnvelopeEditorController
|
||||
Private Logger As Logger
|
||||
|
||||
Private Const COL_NAME = "Name"
|
||||
Private Const COL_EMAIL = "Email"
|
||||
Private Const COL_CODE = "AccessCode"
|
||||
|
||||
Public Property State As State
|
||||
|
||||
Public Sub New()
|
||||
@ -447,7 +451,7 @@ Partial Public Class frmEnvelopeEditor
|
||||
End Sub
|
||||
|
||||
Private Sub ViewReceivers_CellValueChanged(sender As Object, e As Views.Base.CellValueChangedEventArgs) Handles ViewReceivers.CellValueChanged
|
||||
If e.Column.FieldName = "Email" Then
|
||||
If e.Column.FieldName = COL_EMAIL Then
|
||||
If e.Value Is Nothing Then
|
||||
' Keine E-Mail-Adresse, also weg damit
|
||||
ViewReceivers.DeleteRow(ViewReceivers.FocusedRowHandle)
|
||||
@ -455,20 +459,16 @@ Partial Public Class frmEnvelopeEditor
|
||||
' Doppelte E-Mail-Adresse? TODO
|
||||
'Dim oReceivers = Controller.Envelope.Receivers
|
||||
|
||||
Dim oNameCellValue = ViewReceivers.GetRowCellValue(e.RowHandle, "Name")
|
||||
Dim oNameCellValue = ViewReceivers.GetRowCellValue(e.RowHandle, COL_NAME)
|
||||
If oNameCellValue Is Nothing Then
|
||||
Dim oEmailAdress As String = DirectCast(e.Value, String)
|
||||
Dim oLastName As String = Controller.GetLastNameByEmailAdress(oEmailAdress)
|
||||
Dim oAccessCode As String = Guid.NewGuid().ToString("d").Substring(1, 6).ToUpper()
|
||||
Dim oAccessCode As String = Helpers.GetAccessCode()
|
||||
|
||||
ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns("Name"), oLastName)
|
||||
ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns("AccessCode"), oAccessCode)
|
||||
ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_NAME), oLastName)
|
||||
ViewReceivers.SetRowCellValue(e.RowHandle, ViewReceivers.Columns.Item(COL_CODE), oAccessCode)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub RibbonControl1_Click(sender As Object, e As EventArgs) Handles RibbonControl1.Click
|
||||
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
@ -53,6 +53,12 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
envelopeService.EnsureValidEnvelopeKey(envelopeKey);
|
||||
EnvelopeResponse response = envelopeService.LoadEnvelope(envelopeKey);
|
||||
|
||||
// Again check if receiver has already signed
|
||||
if (envelopeService.ReceiverAlreadySigned(response.Envelope, response.Receiver.Id) == true)
|
||||
{
|
||||
return Problem(statusCode: 403);
|
||||
}
|
||||
|
||||
var Request = ControllerContext.HttpContext.Request;
|
||||
var document = envelopeService.GetDocument(Request, envelopeKey);
|
||||
|
||||
|
||||
@ -20,10 +20,54 @@ namespace EnvelopeGenerator.Web.Controllers
|
||||
[Route("/")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("/")]
|
||||
public IActionResult DebugEnvelopes()
|
||||
{
|
||||
try
|
||||
{
|
||||
StringValues passwordFromForm = HttpContext.Request.Form["password"];
|
||||
string passwordFromConfig = database.GetAppSetting("Config:AdminPassword");
|
||||
|
||||
if (passwordFromConfig == null)
|
||||
{
|
||||
ViewData["error"] = "No admin password configured!";
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
if (passwordFromForm.Count != 1)
|
||||
{
|
||||
ViewData["error"] = "No admin password configured!";
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
string password = passwordFromForm[0];
|
||||
|
||||
if (password == null)
|
||||
{
|
||||
ViewData["error"] = "No password supplied!";
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
if (password != passwordFromConfig)
|
||||
{
|
||||
ViewData["error"] = "Wrong Password!";
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
List<Envelope> envelopes = _envelopeService.LoadEnvelopes();
|
||||
|
||||
return View(envelopes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ViewData["error"] = "Unknown error!";
|
||||
return View("Index");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("/EnvelopeKey/{EnvelopeReceiverId}")]
|
||||
|
||||
@ -6,6 +6,7 @@ namespace EnvelopeGenerator.Web.Services
|
||||
public class DatabaseService: BaseService
|
||||
{
|
||||
public MSSQLServer MSSQL { get; set; }
|
||||
public IConfiguration Config { get; set; }
|
||||
|
||||
public State State { get; set; }
|
||||
|
||||
@ -47,12 +48,13 @@ namespace EnvelopeGenerator.Web.Services
|
||||
public readonly ModelContainer? Models;
|
||||
public readonly ServiceContainer? Services;
|
||||
|
||||
public DatabaseService(IConfiguration Config, LoggingService Logging) : base(Config, Logging)
|
||||
public DatabaseService(IConfiguration pConfig, LoggingService pLogging) : base(pConfig, pLogging)
|
||||
{
|
||||
logger = Logging.LogConfig.GetLogger();
|
||||
logger = pLogging.LogConfig.GetLogger();
|
||||
Config = pConfig;
|
||||
|
||||
logger.Debug("Establishing MSSQL Database connection..");
|
||||
MSSQL = new MSSQLServer(logConfig, Config["Config:ConnectionString"]);
|
||||
MSSQL = new MSSQLServer(logConfig, pConfig["Config:ConnectionString"]);
|
||||
|
||||
if (MSSQL.DBInitialized == true)
|
||||
{
|
||||
@ -71,6 +73,11 @@ namespace EnvelopeGenerator.Web.Services
|
||||
}
|
||||
}
|
||||
|
||||
public string? GetAppSetting(string key)
|
||||
{
|
||||
return Config[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// There is a circular dependency between state and models
|
||||
/// All models need a state object, including the config Model
|
||||
|
||||
48
EnvelopeGenerator.Web/Views/Home/DebugEnvelopes.cshtml
Normal file
48
EnvelopeGenerator.Web/Views/Home/DebugEnvelopes.cshtml
Normal file
@ -0,0 +1,48 @@
|
||||
@using EnvelopeGenerator.Common;
|
||||
@using static EnvelopeGenerator.Common.Constants;
|
||||
@{
|
||||
ViewData["Title"] = "Debug";
|
||||
}
|
||||
|
||||
@functions {
|
||||
string encodeEnvelopeKey(Envelope envelope)
|
||||
{
|
||||
var receiver = envelope.Receivers.First();
|
||||
return Helpers.EncodeEnvelopeReceiverId(envelope.Uuid, receiver.Signature);
|
||||
}
|
||||
|
||||
IEnumerable<IGrouping<EnvelopeStatus, Envelope>> groupEnvelopes(List<Envelope> envelopes)
|
||||
{
|
||||
return envelopes.GroupBy(item => item.Status).OrderBy(item => (int)item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
<div class="container">
|
||||
<section>
|
||||
@foreach (IGrouping<EnvelopeStatus, Envelope> group in groupEnvelopes((List<Envelope>)@Model))
|
||||
{
|
||||
<section>
|
||||
<h2>@group.Key.ToString() @group.Count()</h2>
|
||||
|
||||
<details>
|
||||
<summary>Show envelopes</summary>
|
||||
@foreach (Envelope envelope in @group)
|
||||
{
|
||||
|
||||
<section>
|
||||
<article class="envelope">
|
||||
<strong><a href="/EnvelopeKey/@encodeEnvelopeKey(envelope)">@envelope.Title</a></strong>
|
||||
<div><strong>Ersteller</strong> @envelope.User.Email</div>
|
||||
<div><strong>Datum</strong> @envelope.AddedWhen</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
}
|
||||
</details>
|
||||
|
||||
<hr />
|
||||
</section>
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
ViewData["Title"] = "Dokument geschützt";
|
||||
}
|
||||
|
||||
<div id="page-locked" class="container p-5">
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
<div class="icon bg-warning text-black">
|
||||
<div class="icon locked">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" fill="currentColor" class="bi bi-shield-lock" viewBox="0 0 16 16">
|
||||
<path d="M5.338 1.59a61 61 0 0 0-2.837.856.48.48 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.7 10.7 0 0 0 2.287 2.233c.346.244.652.42.893.533q.18.085.293.118a1 1 0 0 0 .101.025 1 1 0 0 0 .1-.025q.114-.034.294-.118c.24-.113.547-.29.893-.533a10.7 10.7 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56" />
|
||||
<path d="M9.5 6.5a1.5 1.5 0 0 1-1 1.415l.385 1.99a.5.5 0 0 1-.491.595h-.788a.5.5 0 0 1-.49-.595l.384-1.99a1.5 1.5 0 1 1 2-1.415" />
|
||||
@ -18,7 +18,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<form id="form-access-code" method="post">
|
||||
<form id="form-access-code" class="form" method="post">
|
||||
<div class="input">
|
||||
<label class="visually-hidden" for="access_code">Zugriffscode</label>
|
||||
<input type="password" class="form-control" name="access_code" placeholder="Zugriffscode" required="required">
|
||||
@ -37,3 +37,5 @@
|
||||
</details>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<footer class="container" id="page-footer">© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
||||
@ -2,9 +2,9 @@
|
||||
ViewData["Title"] = "Dokument unterschrieben";
|
||||
}
|
||||
|
||||
<div id="page-success" class="container p-5">
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
<div class="icon bg-success text-light">
|
||||
<div class="icon signed">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
|
||||
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z" />
|
||||
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
|
||||
@ -19,3 +19,5 @@
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="container" id="page-footer">© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
||||
@ -1,33 +1,37 @@
|
||||
@using EnvelopeGenerator.Common;
|
||||
@using static EnvelopeGenerator.Common.Constants;
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
@{
|
||||
ViewData["Title"] = "Dokument geschützt";
|
||||
}
|
||||
|
||||
@functions {
|
||||
string encodeEnvelopeKey(Envelope envelope)
|
||||
{
|
||||
var receiver = envelope.Receivers.First();
|
||||
return Helpers.EncodeEnvelopeReceiverId(envelope.Uuid, receiver.Signature);
|
||||
}
|
||||
}
|
||||
<div class="page container p-5">
|
||||
<header class="text-center">
|
||||
<div class="icon admin">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" fill="currentColor" class="bi bi-cup-hot" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6zM13 12.5a2 2 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5M2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175" />
|
||||
<path d="m4.4.8-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 3.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 6.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 9.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1>Administration</h1>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<section>
|
||||
@foreach (IGrouping<EnvelopeStatus, Envelope> group in ((List<Envelope>)@Model).GroupBy(item => item.Status).OrderBy(item => (int)item.Key))
|
||||
@if (ViewData["error"] != null)
|
||||
{
|
||||
<section>
|
||||
<h2>@group.Key.ToString()</h2>
|
||||
|
||||
<ul>
|
||||
@foreach (Envelope envelope in @group)
|
||||
{
|
||||
<li><a href="/EnvelopeKey/@encodeEnvelopeKey(envelope)">@envelope.Title</a></li>
|
||||
}
|
||||
</ul>
|
||||
<hr />
|
||||
<section class="alert alert-danger">
|
||||
@ViewData["error"]
|
||||
</section>
|
||||
}
|
||||
|
||||
<section>
|
||||
<form id="form-access-code" class="form" method="post">
|
||||
<div class="input">
|
||||
<label class="visually-hidden" for="access_code">Passwort</label>
|
||||
<input type="password" class="form-control" name="password" placeholder="Passwort" required="required">
|
||||
</div>
|
||||
|
||||
<div class="button">
|
||||
<button type="submit" class="btn btn-primary">Öffnen</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<footer class="container" id="page-footer">© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
||||
@ -10,6 +10,7 @@
|
||||
"ConnectionString": "Server=sDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;",
|
||||
"LogPath": "E:\\EnvelopeGenerator\\Logs",
|
||||
"LogDebug": true,
|
||||
"LogJson": true
|
||||
"LogJson": true,
|
||||
"AdminPassword": "dd"
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,26 +41,46 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
/* Success Page */
|
||||
.page {
|
||||
margin-top: 3rem;
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
box-shadow: rgba(9, 30, 66, 0.25) 0px 4px 8px -2px, rgba(9, 30, 66, 0.08) 0px 0px 0px 1px;
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
#page-success header .icon {
|
||||
.page section {
|
||||
max-width: 30rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page header .icon {
|
||||
display: inline-block;
|
||||
border-radius: 100px;
|
||||
padding: 15px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Locked Page */
|
||||
|
||||
#page-locked header .icon {
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
margin-bottom: 2rem;
|
||||
.page header .icon.admin {
|
||||
background-color: #331904;
|
||||
color: #fecba1;
|
||||
}
|
||||
|
||||
#form-access-code {
|
||||
.page header .icon.locked {
|
||||
background-color: #ffc107;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.page header .icon.signed {
|
||||
background-color: #146c43;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.page .form {
|
||||
max-width: 30rem;
|
||||
margin: 2rem auto;
|
||||
|
||||
@ -68,7 +88,35 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
#form-access-code > .input {
|
||||
#form-access-code > .input,
|
||||
#form-admin-password > .input {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#page-admin header .icon {
|
||||
background-color: #331904;
|
||||
color: #fecba1;
|
||||
}
|
||||
|
||||
|
||||
.envelope {
|
||||
display: block;
|
||||
border: 1px solid #eee;
|
||||
margin-bottom: 1rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
footer#page-footer {
|
||||
color: #333;
|
||||
max-width: 40rem;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
footer#page-footer a,
|
||||
footer#page-footer a:link,
|
||||
footer#page-footer a:hover,
|
||||
footer#page-footer a:visited,
|
||||
footer#page-footer a:focus {
|
||||
color: #444;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user