Skip to content

Commit

Permalink
EYQB-660: Updated to add in new MS Clarity tracking tag (#376)
Browse files Browse the repository at this point in the history
* 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] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
sam-c-dfe and github-actions[bot] authored Sep 26, 2024
1 parent cba60d4 commit 1bafe69
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -15,4 +15,9 @@ public string GtmTag
{
get { return configuration.GetValue<string>("GTM:Tag") ?? ""; }
}

public string ClarityTag
{
get { return configuration.GetValue<string>("Clarity:Tag") ?? ""; }
}
}
2 changes: 1 addition & 1 deletion src/Dfe.EarlyYearsQualification.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
builder.Services.AddSingleton<IFuzzyAdapter, FuzzyAdapter>();
builder.Services.AddSingleton<IDateTimeAdapter, DateTimeAdapter>();
builder.Services.AddSingleton<IDateQuestionModelValidator, DateQuestionModelValidator>();
builder.Services.AddTransient<GtmConfiguration>();
builder.Services.AddTransient<TrackingConfiguration>();
builder.Services.AddSingleton<IPlaceholderUpdater, PlaceholderUpdater>();
builder.Services.AddSingleton<ICheckServiceAccessKeysHelper, CheckServiceAccessKeysHelper>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
21 changes: 15 additions & 6 deletions src/Dfe.EarlyYearsQualification.Web/Views/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
@using Dfe.EarlyYearsQualification.Web.Helpers
@using GovUk.Frontend.AspNetCore
@inject GtmConfiguration GtmConfiguration
@inject TrackingConfiguration TrackingConfiguration

<!DOCTYPE html>
<html class="govuk-template" lang="en">

@{
var gtmTag = GtmConfiguration.GtmTag;
var gtmTag = TrackingConfiguration.GtmTag;
var clarityTag = TrackingConfiguration.ClarityTag;
}

<head>
Expand All @@ -18,16 +19,24 @@
@Html.GovUkFrontendStyleImports()
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
@{
if (GtmConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag))
if (TrackingConfiguration.UseCookies)
{
<script src="~/js/gtm/head-script.js" asp-append-version="true" id="ga-script" data-ga-tag=@gtmTag></script>
if (!string.IsNullOrEmpty(gtmTag))
{
<script src="~/js/gtm/head-script.js" asp-append-version="true" id="ga-script" data-ga-tag=@gtmTag></script>
}

if (!string.IsNullOrEmpty(clarityTag))
{
<script src="~/js/clarity/head-script.js" asp-append-version="true" id="clarity-script" data-clarity-tag=@clarityTag></script>
}
}
}
</head>

<body>
@{
if (GtmConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag))
if (TrackingConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag))
{
<!-- Google Tag Manager (noscript) -->
<noscript>
Expand Down Expand Up @@ -61,7 +70,7 @@
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", false)
@{
if (GtmConfiguration.UseCookies && !string.IsNullOrEmpty(GtmConfiguration.GtmTag))
if (TrackingConfiguration.UseCookies && !string.IsNullOrEmpty(gtmTag))
{
<script src="~/js/gtm/form-handler.js" asp-append-version="true"></script>
}
Expand Down
3 changes: 3 additions & 0 deletions src/Dfe.EarlyYearsQualification.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
"GTM": {
"Tag": ""
},
"Clarity": {
"Tag": ""
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- Microsoft Clarity -->
let tag = document.getElementById('clarity-script').getAttribute('data-clarity-tag');
let encodedTag = encodeURIComponent(tag);
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", encodedTag);
<!-- End Microsoft Clarity -->
1 change: 1 addition & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ This module provisions a new Azure Resource Group that assembles together the in
| <a name="input_admin_email_address"></a> [admin\_email\_address](#input\_admin\_email\_address) | Email Address of the Admin | `string` | n/a | yes |
| <a name="input_asp_sku"></a> [asp\_sku](#input\_asp\_sku) | SKU name for the App Service Plan | `string` | `"S1"` | no |
| <a name="input_azure_region"></a> [azure\_region](#input\_azure\_region) | Name of the Azure region to deploy resources | `string` | `"westeurope"` | no |
| <a name="input_clarity_tag"></a> [clarity\_tag](#input\_clarity\_tag) | The Microsoft Clarity tag | `string` | `""` | no |
| <a name="input_contentful_delivery_api_key"></a> [contentful\_delivery\_api\_key](#input\_contentful\_delivery\_api\_key) | Contentful delivery API key | `string` | n/a | yes |
| <a name="input_contentful_preview_api_key"></a> [contentful\_preview\_api\_key](#input\_contentful\_preview\_api\_key) | Contentful preview API key | `string` | n/a | yes |
| <a name="input_contentful_space_id"></a> [contentful\_space\_id](#input\_contentful\_space\_id) | Contentful space ID | `string` | n/a | yes |
Expand Down
1 change: 1 addition & 0 deletions terraform/local.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ locals {
"ServiceAccess__Keys__2" = var.webapp_access_key_1
"ServiceAccess__Keys__3" = var.webapp_access_key_2
"GTM__Tag" = var.gtm_tag
"Clarity__Tag" = var.clarity_tag
}

webapp_slot_app_settings = {
Expand Down
6 changes: 6 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,9 @@ variable "gtm_tag" {
description = "The Google Analytics tag"
type = string
}

variable "clarity_tag" {
default = ""
description = "The Microsoft Clarity tag"
type = string
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("A spec that checks for security headers in the response", () => {
);
expect(response.headers).to.have.property(
"content-security-policy",
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com;block-all-mixed-content;upgrade-insecure-requests;"
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js https://www.clarity.ms/;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com https://s.clarity.ms/collect;block-all-mixed-content;upgrade-insecure-requests;"
);
expect(response.headers).to.have.property(
"cross-origin-resource-policy",
Expand Down Expand Up @@ -62,7 +62,7 @@ describe("A spec that checks for security headers in the response", () => {
);
expect(response.headers).to.have.property(
"content-security-policy",
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com;block-all-mixed-content;upgrade-insecure-requests;"
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js https://www.clarity.ms/;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com https://s.clarity.ms/collect;block-all-mixed-content;upgrade-insecure-requests;"
);
expect(response.headers).to.have.property(
"cross-origin-resource-policy",
Expand Down Expand Up @@ -96,7 +96,7 @@ describe("A spec that checks for security headers in the response", () => {
);
expect(response.headers).to.have.property(
"content-security-policy",
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com;block-all-mixed-content;upgrade-insecure-requests;"
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js https://www.clarity.ms/;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com https://s.clarity.ms/collect;block-all-mixed-content;upgrade-insecure-requests;"
);
expect(response.headers).to.have.property(
"cross-origin-resource-policy",
Expand Down Expand Up @@ -139,7 +139,7 @@ describe("A spec that checks for security headers in the response", () => {
);
expect(response.headers).to.have.property(
"content-security-policy",
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com;block-all-mixed-content;upgrade-insecure-requests;"
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js https://www.clarity.ms/;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com https://s.clarity.ms/collect;block-all-mixed-content;upgrade-insecure-requests;"
);
expect(response.headers).to.have.property(
"cross-origin-resource-policy",
Expand Down Expand Up @@ -176,7 +176,7 @@ describe("A spec that checks for security headers in the response", () => {
);
expect(response.headers).to.have.property(
"content-security-policy",
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com;block-all-mixed-content;upgrade-insecure-requests;"
"script-src 'self' 'sha256-2eCA8tPChvVMeSRvRNqlmBco1wRmAKXWVzJ8Vpb9S6Y=' 'sha256-VAoCuOmBv4C4V/WthoGzlhYyYpWir44ETG7WKh+3kG8=' 'sha256-Om9RNNoMrdmIZzT4Oo7KaozVNUg6zYxVQuq3CPld2Ms=' 'unsafe-hashes' 'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=' 'sha256-l5MP+9OapFXGxjKMNj/89ExAW2TvAFFoADrbsmtSJXo=' 'sha256-lD2YLKoqlgPJ6bMRB0gZKeUdZqwszfrRSmAnzX0TSls=' 'sha256-1f+6vEGZewP7dkvrYIBD4bqMLOhumfg10mwfKd2jU7I=' 'sha256-LBWtLNxa0f5+6KBUNLCp8JXVP7YuPtJtEt1Ku3cCKdY=' https://www.googletagmanager.com/gtm.js https://www.googletagmanager.com/gtag/js https://www.clarity.ms/;object-src 'self';frame-ancestors https://app.contentful.com;connect-src *.google-analytics.com https://s.clarity.ms/collect;block-all-mixed-content;upgrade-insecure-requests;"
);
expect(response.headers).to.have.property(
"cross-origin-resource-policy",
Expand Down

This file was deleted.

Loading

0 comments on commit 1bafe69

Please sign in to comment.