Refaktorierung für HTML-Sanitization mit neuer Sanitizer-Klasse.

- Bestehende Sanitization überarbeitet.
- Injektionsmethode für flexible Konfiguration implementiert.
- Wichtige Abschnitte in `show-envelope` hervorgehoben.
This commit is contained in:
Developer 02 2024-07-18 10:52:39 +02:00
parent 1c2df71e0f
commit 43ae15b71c
9 changed files with 61 additions and 18 deletions

View File

@ -145,10 +145,10 @@
<value>Englisch</value> <value>Englisch</value>
</data> </data>
<data name="EnvelopeInfo1" xml:space="preserve"> <data name="EnvelopeInfo1" xml:space="preserve">
<value>Sie müssen {0} Vorgang unterzeichen. Bitte prüfen Sie die Seite {1}.</value> <value>Sie müssen {0} Vorgang unterzeichen. &lt;span class="highlight highlight-envelope-info-1"&gt;Bitte prüfen Sie die Seite {1}&lt;/span&gt;.</value>
</data> </data>
<data name="EnvelopeInfo2" xml:space="preserve"> <data name="EnvelopeInfo2" xml:space="preserve">
<value>Erstellt am {0} von {1}. Sie können den Absender über &lt;a href="mailto:{2}?subject={3}&amp;body=Sehr%20geehrter%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt; kontaktieren.</value> <value>Erstellt am {0} von {1}. Sie können den Absender über &lt;span class="highlight highlight-envelope-info-2"&gt;&lt;a href="mailto:{2}?subject={3}&amp;body=Sehr%20geehrter%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt;&lt;/span&gt; kontaktieren.</value>
</data> </data>
<data name="Finalize" xml:space="preserve"> <data name="Finalize" xml:space="preserve">
<value>Abschließen</value> <value>Abschließen</value>

View File

@ -145,10 +145,10 @@
<value>English</value> <value>English</value>
</data> </data>
<data name="EnvelopeInfo1" xml:space="preserve"> <data name="EnvelopeInfo1" xml:space="preserve">
<value>You have to sign {0} process. Please check page {1}.</value> <value>You have to sign {0} process. &lt;span class="highlight highlight-envelope-info-1"&gt;Please check page {1}&lt;/span&gt;.</value>
</data> </data>
<data name="EnvelopeInfo2" xml:space="preserve"> <data name="EnvelopeInfo2" xml:space="preserve">
<value>Created on {0} by {1}. You can contact the sender via &lt;a href="mailto:{2}?subject={3}&amp;body=Dear%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt;.</value> <value>Created on {0} by {1}. You can contact the sender via &lt;span class="highlight highlight-envelope-info-2"&gt;&lt;a href="mailto:{2}?subject={3}&amp;body=Dear%20{4}%20{5},%0A%0A%0A"&gt;{6}&lt;/a&gt;&lt;/span&gt;.</value>
</data> </data>
<data name="Finalize" xml:space="preserve"> <data name="Finalize" xml:space="preserve">
<value>Finalize</value> <value>Finalize</value>

View File

@ -16,6 +16,7 @@ using Microsoft.Extensions.Options;
using EnvelopeGenerator.Application; using EnvelopeGenerator.Application;
using DigitalData.EmailProfilerDispatcher; using DigitalData.EmailProfilerDispatcher;
using EnvelopeGenerator.Infrastructure; using EnvelopeGenerator.Infrastructure;
using EnvelopeGenerator.Web.Sanitizers;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Logging initialized!"); logger.Info("Logging initialized!");
@ -126,11 +127,15 @@ try
builder.Services.AddSingleton(HtmlEncoder.Default); builder.Services.AddSingleton(HtmlEncoder.Default);
builder.Services.AddSingleton(UrlEncoder.Default); builder.Services.AddSingleton(UrlEncoder.Default);
builder.Services.AddSingleton(_ => builder.Services.AddSanitizer<HtmlSanitizer>();
builder.Services.AddSanitizer<HighlightHtmlSanitizer>(s =>
{ {
var sanitizer = new HtmlSanitizer(); s.AllowedTags.Add("a");
//configure sanitzer s.AllowedAttributes.Add("href");
return sanitizer; s.AllowedAttributes.Add("class");
s.AllowedClasses.Add("highlight");
s.AllowedClasses.Add("highlight-envelope-info-1");
s.AllowedClasses.Add("highlight-envelope-info-2");
}); });
// Register the FlagIconCssClass instance as a singleton // Register the FlagIconCssClass instance as a singleton

View File

@ -0,0 +1,17 @@
using Ganss.Xss;
using Microsoft.Extensions.DependencyInjection;
namespace EnvelopeGenerator.Web.Sanitizers
{
public static class DIExtensions
{
public static IServiceCollection AddSanitizer<THtmlSanitizer>(this IServiceCollection services, Action<THtmlSanitizer>? optionActions = null)
where THtmlSanitizer : HtmlSanitizer => services
.AddSingleton(serviceProvider =>
{
var sanitizer = ActivatorUtilities.CreateInstance<THtmlSanitizer>(serviceProvider);
optionActions?.Invoke(sanitizer);
return sanitizer;
});
}
}

View File

@ -0,0 +1,8 @@
using Ganss.Xss;
namespace EnvelopeGenerator.Web.Sanitizers
{
public class HighlightHtmlSanitizer : HtmlSanitizer
{
}
}

View File

@ -38,15 +38,12 @@
<div class="col p-0 m-0"> <div class="col p-0 m-0">
<div class="card-body p-0 m-0 ms-4"> <div class="card-body p-0 m-0 ms-4">
<h5 class="card-title p-0 m-0">@($"{envelope?.Title.TrySanitize(_sanitizer)}")</h5> <h5 class="card-title p-0 m-0">@($"{envelope?.Title.TrySanitize(_sanitizer)}")</h5>
<p class="card-text p-0 m-0">@(string.Format(_localizer[WebKey.EnvelopeInfo1], pages.Count(), stPageIndexes.TrySanitize(_sanitizer)))</p> <p class="card-text p-0 m-0">@Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo1], pages.Count(), stPageIndexes).TrySanitize(_hlSanitizer))</p>
<p class="card-text p-0 m-0"><small class="text-body-secondary">@Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo2], <p class="card-text p-0 m-0">
envelope?.AddedWhen.ToString(userCulture?.Info?.DateTimeFormat), <small class="text-body-secondary">
$"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer), @Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo2], envelope?.AddedWhen.ToString(userCulture?.Info?.DateTimeFormat), $"{sender?.Prename} {sender?.Name}", sender?.Email, envelope?.Title, sender?.Prename, sender?.Name, sender?.Email).TrySanitize(_hlSanitizer))
sender?.Email.TryEncode(_encoder), </small>
envelope?.Title.TryEncode(_encoder), </p>
sender?.Prename.TryEncode(_encoder),
sender?.Name.TryEncode(_encoder),
sender?.Email.TryEncode(_encoder)).TrySanitize(_sanitizer))</small></p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,10 +1,12 @@
@using EnvelopeGenerator.Web @using EnvelopeGenerator.Web
@using EnvelopeGenerator.Web.Models @using EnvelopeGenerator.Web.Models
@using EnvelopeGenerator.Web.Sanitizers
@using Microsoft.Extensions.Localization @using Microsoft.Extensions.Localization
@using EnvelopeGenerator.Application.Resources @using EnvelopeGenerator.Application.Resources
@inject IStringLocalizer<Resource> _localizer @inject IStringLocalizer<Resource> _localizer
@inject System.Text.Encodings.Web.UrlEncoder _encoder @inject System.Text.Encodings.Web.UrlEncoder _encoder
@inject Ganss.Xss.HtmlSanitizer _sanitizer @inject Ganss.Xss.HtmlSanitizer _sanitizer
@inject HighlightHtmlSanitizer _hlSanitizer
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor _accessor @inject Microsoft.AspNetCore.Http.IHttpContextAccessor _accessor
@inject Cultures _cultures @inject Cultures _cultures
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -201,7 +201,13 @@ footer#page-footer {
min-width: 4vw; min-width: 4vw;
} }
/* Additional styles for better mobile responsiveness */ .highlight {
font-weight: 700;
font-size: 13px;
}
/* styles for mobile responsiveness */
@media (max-width: 767px) { @media (max-width: 767px) {
.navbar { .navbar {
flex-direction: column; flex-direction: column;
@ -256,3 +262,11 @@ footer#page-footer {
max-width: 90%; max-width: 90%;
} }
} }
@media (max-height: 850px) {
.collapse .card-text, .collapsing .card-text {
font-size: 0.5rem; /* Font size reduced */
margin: 0rem;
padding: 0rem;
}
}

Binary file not shown.