Compare commits

...

5 Commits

11 changed files with 66 additions and 12 deletions

View File

@@ -141,4 +141,10 @@
<data name="LockedTitle" xml:space="preserve">
<value>Dokument erfordert einen Zugriffscode</value>
</data>
<data name="UnexpectedError" xml:space="preserve">
<value>Ein unerwarteter Fehler ist aufgetreten.</value>
</data>
<data name="WrongAccessCode" xml:space="preserve">
<value>Ungültiger Zugangscode.</value>
</data>
</root>

View File

@@ -141,4 +141,10 @@
<data name="LockedTitle" xml:space="preserve">
<value>Document requires an access code</value>
</data>
<data name="UnexpectedError" xml:space="preserve">
<value>An unexpected error has occurred.</value>
</data>
<data name="WrongAccessCode" xml:space="preserve">
<value>Invalid access code.</value>
</data>
</root>

View File

@@ -154,10 +154,19 @@ namespace EnvelopeGenerator.Web.Controllers
return this.ViewDocumentNotFound();
}
var claims = new List<Claim> { new(ClaimTypes.NameIdentifier, uuid), new(ClaimTypes.Hash, signature) };
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 { };
var authProperties = new AuthenticationProperties {
AllowRefresh = false,
IsPersistent = false
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
@@ -179,14 +188,19 @@ namespace EnvelopeGenerator.Web.Controllers
else
{
database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); //for history
return Unauthorized();
Response.StatusCode = StatusCodes.Status401Unauthorized;
return View("EnvelopeLocked")
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
}
},
Fail: (messages, notices) =>
{
_logger.LogNotice(notices);
return Unauthorized();
Response.StatusCode = StatusCodes.Status401Unauthorized;
return View("EnvelopeLocked")
.WithData("UserLanguage", UserLanguage ?? _cultures.Default.Language)
.WithData("ErrorMessage", _localizer[WebKey.WrongAccessCode].Value);
});
}
catch(Exception ex)

View File

@@ -0,0 +1,13 @@
namespace EnvelopeGenerator.Web
{
/// <summary>
/// Provides custom claim types for envelope-related information.
/// </summary>
public static class EnvelopeClaimTypes
{
/// <summary>
/// Claim type for the title of an envelope.
/// </summary>
public static readonly string Title = $"Envelope{nameof(Title)}";
}
}

View File

@@ -58,9 +58,8 @@ try
{
//remove option for Test*Controller
options.Conventions.Add(new RemoveIfControllerConvention()
.AndIf(_ => !builder.IsDevOrDiP())
.AndIf(c => c.ControllerName.StartsWith("Test"))
.AndIf(_ => !config.GetValue<bool>("EnableTestControllers")));
.AndIf(_ => !builder.IsDevOrDiP() || !config.GetValue<bool>("EnableTestControllers")));
}).AddJsonOptions(q =>
{
// Prevents serialization error when serializing SvgBitmap in EnvelopeReceiver
@@ -129,7 +128,8 @@ try
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = context =>

View File

@@ -24,6 +24,12 @@
<div class="input">
<label class="visually-hidden" for="access_code">@_localizer[WebKey.LockedTitle]</label>
<input type="password" id="access_code" class="form-control" name="access_code" placeholder="@_localizer[WebKey.LockedAccessCode]" required="required">
<div id="access-code-error-message" class="text-danger" style="height: 20px;">
@if (ViewData["ErrorMessage"] is string errMsg)
{
@_sanitizer.Sanitize(errMsg)
}
</div>
</div>
<div class="button">
<button type="submit" class="btn btn-primary">@_localizer[WebKey.LocakedOpen]</button>

View File

@@ -22,6 +22,7 @@
<script src="~/lib/pspdfkit/pspdfkit.js" asp-append-version="true"></script>
<script src="~/lib/bootstrap-cookie-consent-settings-main/bootstrap-cookie-consent-settings.js" asp-append-version="true"></script>
<script src="~/js/util.js" asp-append-version="true"></script>
<script src="~/js/api.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
<main role="main">
<partial name="_CookieConsentPartial" />

View File

@@ -16,5 +16,6 @@
public static readonly string LockedAccessCode = nameof(LockedAccessCode);
public static readonly string LockedFooterTitle = nameof(LockedFooterTitle);
public static readonly string LockedFooterBody = nameof(LockedFooterBody);
public static readonly string WrongAccessCode = nameof(WrongAccessCode);
}
}

View File

@@ -16,11 +16,11 @@
},
"AdminPassword": "dd",
"PSPDFKitLicenseKey_SignFlow": "y8VgCpBgUfNlpKJZC-GwjpPs-S-KFBHv4RywfHbqpBAbO0XxRuWDaMGZtIaMrXBDlndlJLk---Ve93xjI_ZR4sbFymf4Ot97yTYUMeDdL2LYXhspkEnSAtkXf9zqepNL1v_0DMibjpqXFQMkVB1y3D5xdnOg-iJuCCZEMhZ780qg04_H_nmx63uSgxjN0GJxC8YvsbnRcUZ2l_idImMvWL0HMqB5B7oEpNenasA0RK0uapFRTa7NIQok0phpTHZYKB4qvj7od2yxlytGB7qBl4-lwT70DSQ9mrLkCWbuzZ9cV9D8fDzdFXr6WoZdOYpkrUadRbsy2bhPq_ukxszDWN4JGhebo0XKUK_YfgvSlS7lFOxHNblHeC9B7gZ8T-VuQ_z1QA2JYRf1dmhSuclnW00diShIg-N0I79PWGsQE4j40XtVpyWcN9uT9hMuiRpL0LzHV4YgsgBrgKgs_moqL7f0L4-MwaS25Dx4Wcz4ttKaerLavwMM4CJHI3DNqTC5UUEG6EViFxBQtrmuAS7kiw2nWjvXO7kUA24NARtsRCphjWE4l6wSMdh7kpqhfbV7_hdb5xXYGALNPkv8En6zPpFIew8DDcOH9dgxfKMI34LLhkEWqovZW_7fXNJTEIHVpR0DSPbZrmyEwkECnbDcNzjyFk2M1fzstJj_dSotyZvS57XJK2DgojbRgXL9pncs",
"UseCSPInDev": false,
"UseCSPInDev": true,
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
"default-src 'self'",
"script-src 'self' 'nonce-{0}' blob: data:",
"style-src 'self'",
"script-src 'self' 'nonce-{0}' 'unsafe-inline' 'unsafe-eval' blob: data:",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https: blob:",
"font-src 'self'",
"connect-src 'self' http://localhost:* https://localhost:* ws://localhost:* wss://localhost:* blob:",

View File

@@ -0,0 +1,7 @@
const submitForm = async form => await fetch(form.action, {
method: form.method,
body: new FormData(form),
headers: {
"X-Requested-With": "XMLHttpRequest"
}
})

View File

@@ -123,4 +123,4 @@
return annotationPresets
}
}
}