diff --git a/Lombiq.JsonEditor.Test.UI/Extensions/TestCaseUITestContextExtensions.cs b/Lombiq.JsonEditor.Test.UI/Extensions/TestCaseUITestContextExtensions.cs index 3655c33..310353e 100644 --- a/Lombiq.JsonEditor.Test.UI/Extensions/TestCaseUITestContextExtensions.cs +++ b/Lombiq.JsonEditor.Test.UI/Extensions/TestCaseUITestContextExtensions.cs @@ -10,7 +10,7 @@ namespace Lombiq.JsonEditor.Tests.UI.Extensions; public static class TestCaseUITestContextExtensions { - private const string SampleContentItemId = "4xapn6ykttkk6wbbwgg1aaxqda"; + private const string SampleContentItemId = "jsonexamplepage00000000000"; private const string HelloValue = "hello"; private const string WorldValue = "world"; private const string TestField = "testField"; diff --git a/Lombiq.JsonEditor/Recipes/JsonEditor.Sample.recipe.json b/Lombiq.JsonEditor/Recipes/JsonEditor.Sample.recipe.json index 171c3ab..d0fa457 100644 --- a/Lombiq.JsonEditor/Recipes/JsonEditor.Sample.recipe.json +++ b/Lombiq.JsonEditor/Recipes/JsonEditor.Sample.recipe.json @@ -96,8 +96,8 @@ "name": "content", "data": [ { - "ContentItemId": "4xapn6ykttkk6wbbwgg1aaxqda", - "ContentItemVersionId": "4av5ed2m18bxzzzpxv211g60ng", + "ContentItemId": "jsonexamplepage00000000000", + "ContentItemVersionId": "[js:uuid()]", "ContentType": "JsonExamplePage", "DisplayText": null, "Latest": true, @@ -105,7 +105,7 @@ "ModifiedUtc": "2021-08-23T17:08:18.0374586Z", "PublishedUtc": "2021-08-23T17:08:18.0394636Z", "CreatedUtc": "2021-08-23T16:14:03.9040848Z", - "Owner": "4yhqbehqdk0707whhrj0b5rt51", + "Owner": null, "Author": "admin", "JsonExamplePage": { "JsonExampleField": { diff --git a/Lombiq.JsonEditor/Services/JsonEditorContentSecurityPolicyProvider.cs b/Lombiq.JsonEditor/Services/JsonEditorContentSecurityPolicyProvider.cs new file mode 100644 index 0000000..e9fe6bd --- /dev/null +++ b/Lombiq.JsonEditor/Services/JsonEditorContentSecurityPolicyProvider.cs @@ -0,0 +1,41 @@ +using Lombiq.HelpfulLibraries.AspNetCore.Security; +using Lombiq.JsonEditor.Constants; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using static Lombiq.HelpfulLibraries.AspNetCore.Security.ContentSecurityPolicyDirectives; +using static Lombiq.HelpfulLibraries.AspNetCore.Security.ContentSecurityPolicyDirectives.CommonValues; + +namespace Lombiq.JsonEditor.Services; + +/// +/// Permits blob: data: access to the on pages that include the script. +/// +public class JsonEditorContentSecurityPolicyProvider : ResourceManagerContentSecurityPolicyProvider +{ + protected override string ResourceType => "script"; + protected override string ResourceName => ResourceNames.Library; + protected override IReadOnlyCollection DirectiveNameChain { get; } = new[] { WorkerSrc, ScriptSrc }; + protected override string DirectiveValue => $"{Blob} {Data}"; + + protected override ValueTask ThenUpdateAsync( + IDictionary securityPolicies, + HttpContext context, + bool resourceExists) + { + // Fixes "[Severe] blob:https://localhost:9391/6a0aeee0-8ec7-449c-86b4-7668d046d24c 0 Refused to load the + // script 'data:application/javascript;base64,...' because it violates the following Content Security Policy + // directive" error. + if (resourceExists) + { + securityPolicies[ScriptSrc] = IContentSecurityPolicyProvider + .GetDirective(securityPolicies, ScriptSrc) + .MergeWordSets(DirectiveValue); + } + + return ValueTask.CompletedTask; + } +} diff --git a/Lombiq.JsonEditor/Startup.cs b/Lombiq.JsonEditor/Startup.cs index 98ea666..eaad775 100644 --- a/Lombiq.JsonEditor/Startup.cs +++ b/Lombiq.JsonEditor/Startup.cs @@ -2,6 +2,7 @@ using Lombiq.JsonEditor.Constants; using Lombiq.JsonEditor.Drivers; using Lombiq.JsonEditor.Fields; +using Lombiq.JsonEditor.Services; using Lombiq.JsonEditor.Settings; using Lombiq.JsonEditor.TagHelpers; using Microsoft.AspNetCore.Builder; @@ -46,6 +47,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddOrchardServices(); services.AddScoped(); + services.AddContentSecurityPolicyProvider(); } public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) =>