From 1bafe69d8f4b54f85a5aaf493e548918a54885e0 Mon Sep 17 00:00:00 2001 From: Sam C <156680559+sam-c-dfe@users.noreply.github.com> Date: Thu, 26 Sep 2024 08:08:00 +0100 Subject: [PATCH] EYQB-660: Updated to add in new MS Clarity tracking tag (#376) * EYQB-660: Updated to add in new MS Clarity tracking tag * Updated the CSP headers in the E2E test * terraform-docs: automated action --------- Co-authored-by: github-actions[bot] --- ...figuration.cs => TrackingConfiguration.cs} | 7 +- .../Program.cs | 2 +- .../Security/SecureHeaderConfiguration.cs | 14 +++ .../Views/Shared/_Layout.cshtml | 21 ++-- .../appsettings.json | 3 + .../wwwroot/js/clarity/head-script.js | 9 ++ terraform/README.md | 1 + terraform/local.tf | 1 + terraform/variables.tf | 6 ++ .../e2e/shared/security-header-spec.cy.js | 10 +- .../Helpers/GtmConfigurationTests.cs | 66 ------------- .../Helpers/TrackingConfigurationTests.cs | 95 +++++++++++++++++++ 12 files changed, 156 insertions(+), 79 deletions(-) rename src/Dfe.EarlyYearsQualification.Web/Helpers/{GtmConfiguration.cs => TrackingConfiguration.cs} (63%) create mode 100644 src/Dfe.EarlyYearsQualification.Web/wwwroot/js/clarity/head-script.js delete mode 100644 tests/Dfe.EarlyYearsQualification.UnitTests/Helpers/GtmConfigurationTests.cs create mode 100644 tests/Dfe.EarlyYearsQualification.UnitTests/Helpers/TrackingConfigurationTests.cs diff --git a/src/Dfe.EarlyYearsQualification.Web/Helpers/GtmConfiguration.cs b/src/Dfe.EarlyYearsQualification.Web/Helpers/TrackingConfiguration.cs similarity index 63% rename from src/Dfe.EarlyYearsQualification.Web/Helpers/GtmConfiguration.cs rename to src/Dfe.EarlyYearsQualification.Web/Helpers/TrackingConfiguration.cs index 38249290..d260e438 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Helpers/GtmConfiguration.cs +++ b/src/Dfe.EarlyYearsQualification.Web/Helpers/TrackingConfiguration.cs @@ -2,7 +2,7 @@ namespace Dfe.EarlyYearsQualification.Web.Helpers; -public class GtmConfiguration(ICookiesPreferenceService cookiesPreferenceService, IConfiguration configuration) +public class TrackingConfiguration(ICookiesPreferenceService cookiesPreferenceService, IConfiguration configuration) { private readonly DfeCookie _cookie = cookiesPreferenceService.GetCookie(); @@ -15,4 +15,9 @@ public string GtmTag { get { return configuration.GetValue("GTM:Tag") ?? ""; } } + + public string ClarityTag + { + get { return configuration.GetValue("Clarity:Tag") ?? ""; } + } } \ No newline at end of file diff --git a/src/Dfe.EarlyYearsQualification.Web/Program.cs b/src/Dfe.EarlyYearsQualification.Web/Program.cs index ea2d27dc..dd5b5d90 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Program.cs +++ b/src/Dfe.EarlyYearsQualification.Web/Program.cs @@ -90,7 +90,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddTransient(); +builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/src/Dfe.EarlyYearsQualification.Web/Security/SecureHeaderConfiguration.cs b/src/Dfe.EarlyYearsQualification.Web/Security/SecureHeaderConfiguration.cs index 79da480a..e0838acc 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Security/SecureHeaderConfiguration.cs +++ b/src/Dfe.EarlyYearsQualification.Web/Security/SecureHeaderConfiguration.cs @@ -87,6 +87,18 @@ public static SecureHeadersMiddlewareConfiguration CustomConfiguration() CommandType = CspCommandType.Directive, DirectiveOrUri = "sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=" }; + + var clarityCspElement = new ContentSecurityPolicyElement + { + CommandType = CspCommandType.Uri, + DirectiveOrUri = "https://www.clarity.ms/" + }; + + var clarityConnectSourceCspElement = new ContentSecurityPolicyElement + { + CommandType = CspCommandType.Uri, + DirectiveOrUri = "https://s.clarity.ms/collect" + }; configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(backButtonShaCspElement); configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(cookiesPageShaCspElement); @@ -101,6 +113,8 @@ public static SecureHeadersMiddlewareConfiguration CustomConfiguration() configuration.ContentSecurityPolicyConfiguration.ConnectSrc.Add(ga4CspElement); configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(windowPrint); configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(challengePageShowPassword); + configuration.ContentSecurityPolicyConfiguration.ScriptSrc.Add(clarityCspElement); + configuration.ContentSecurityPolicyConfiguration.ConnectSrc.Add(clarityConnectSourceCspElement); return configuration; } diff --git a/src/Dfe.EarlyYearsQualification.Web/Views/Shared/_Layout.cshtml b/src/Dfe.EarlyYearsQualification.Web/Views/Shared/_Layout.cshtml index 294a9936..3bf782a8 100644 --- a/src/Dfe.EarlyYearsQualification.Web/Views/Shared/_Layout.cshtml +++ b/src/Dfe.EarlyYearsQualification.Web/Views/Shared/_Layout.cshtml @@ -1,12 +1,13 @@ @using Dfe.EarlyYearsQualification.Web.Helpers @using GovUk.Frontend.AspNetCore -@inject GtmConfiguration GtmConfiguration +@inject TrackingConfiguration TrackingConfiguration @{ - var gtmTag = GtmConfiguration.GtmTag; + var gtmTag = TrackingConfiguration.GtmTag; + var clarityTag = TrackingConfiguration.ClarityTag; } @@ -18,16 +19,24 @@ @Html.GovUkFrontendStyleImports() @{ - if (GtmConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag)) + if (TrackingConfiguration.UseCookies) { - + if (!string.IsNullOrEmpty(gtmTag)) + { + + } + + if (!string.IsNullOrEmpty(clarityTag)) + { + + } } } @{ - if (GtmConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag)) + if (TrackingConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag)) {