diff --git a/DigitalData.Core.API/CSPMiddleware.cs b/DigitalData.Core.API/CSPMiddleware.cs
new file mode 100644
index 0000000..63ab642
--- /dev/null
+++ b/DigitalData.Core.API/CSPMiddleware.cs
@@ -0,0 +1,47 @@
+namespace DigitalData.Core.API
+{
+ ///
+ /// Middleware to add Content Security Policy (CSP) headers to the HTTP response.
+ ///
+ public class CSPMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly string _policy;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The next middleware in the request pipeline.
+ /// The CSP policy string with placeholders for nonces.
+ public CSPMiddleware(RequestDelegate next, string policy)
+ {
+ _next = next;
+ _policy = policy;
+ }
+
+ ///
+ /// Invokes the middleware to add the CSP header to the response.
+ ///
+ /// The HTTP context.
+ /// A task that represents the completion of request processing.
+ public async Task Invoke(HttpContext context)
+ {
+ // Generate a nonce (number used once) for inline scripts and styles
+ var nonce = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
+
+ // Store the nonce in the context items for later use
+ context.Items["csp-nonce"] = nonce;
+
+ // Add the CSP header to the response
+ context.Response.OnStarting(() =>
+ {
+ context.Response.Headers.Add("Content-Security-Policy",
+ string.Format(_policy, nonce));
+ return Task.CompletedTask;
+ });
+
+ // Call the next middleware in the pipeline
+ await _next(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.API/DIExtensions.cs b/DigitalData.Core.API/DIExtensions.cs
new file mode 100644
index 0000000..02b4c25
--- /dev/null
+++ b/DigitalData.Core.API/DIExtensions.cs
@@ -0,0 +1,23 @@
+using Microsoft.AspNetCore.Builder;
+
+namespace DigitalData.Core.API
+{
+ ///
+ /// Provides extension methods for adding middleware to the application's request pipeline.
+ ///
+ public static class DIExtensions
+ {
+ ///
+ /// Adds the to the application's request pipeline to include
+ /// Content Security Policy (CSP) headers in the HTTP response.
+ ///
+ /// The application builder.
+ ///
+ /// The CSP policy string with placeholders. The first format parameter {0} will be replaced
+ /// by the nonce value.
+ ///
+ /// The application builder with the CSP middleware added.
+ public static IApplicationBuilder UseCSPMiddleware(this IApplicationBuilder app, string policy)
+ => app.UseMiddleware(policy);
+ }
+}
\ No newline at end of file
diff --git a/DigitalData.Core.DTO/DTOExtensions.cs b/DigitalData.Core.DTO/DTOExtensions.cs
index daad4ce..4db2175 100644
--- a/DigitalData.Core.DTO/DTOExtensions.cs
+++ b/DigitalData.Core.DTO/DTOExtensions.cs
@@ -1,5 +1,4 @@
using Microsoft.Extensions.Logging;
-using System.Diagnostics;
using System.Text;
namespace DigitalData.Core.DTO
@@ -63,6 +62,10 @@ namespace DigitalData.Core.DTO
return result;
}
+ public static bool HasFlag(this IEnumerable notices, Enum flag) => notices.Any(n => n.Flag?.ToString() == flag.ToString());
+
+ public static bool HasAnyFlag(this IEnumerable notices, params Enum[] flags) => flags.Any(f => notices.HasFlag(f));
+
public static I Then(this Result result, Func Success, Func, List, I> Fail)
{
return result.IsSuccess ? Success() : Fail(result.Messages, result.Notices);