Skip to content

Commit

Permalink
DFC 319/AUT-2459 - Add GOVUK One Login Analytics Package (#1522)
Browse files Browse the repository at this point in the history
* Add analytics package to auth repo - intial set up

* Add OPL template and script

* Add ga4 on page load to base.njk file

* Add taxonomy

* Add taxonomy values

* Add static taxonomy values

* WIP

* Add changes for dyanamic content id's

* Add WIP resend codes

* Add add password reset and resend code content ids

* WIP- add unhappy path page content ids OPL tracker

* Add dev app changes - required for docker containers

* Add http status ok

* Update yarn lock and update content id

* Add GA4 OPL tracker and remove unused code

* Add UA implementation

* Refine UA implementation

* Update to v0.0.10 analytics package

* Add additional taxonomy level 2 and content id's

* Remove console.logs for debugging

* Remove commented out code

* Refactor and tidy code

* Reduce pollution from linting

* Run yarn pretty

* Remove unused console.log

* Address unit testing and refactor contact us OPL tracker

* Revent application.js changes

* Apply loggedin and dynamic attributes to GA4 tracker

* Remove duplicate OPL component

* Correct application.js changes from PR review

* apply application.js changes

* Reduce linting bloat

* Remove the linting bloat and add amendments from PR Review

* Update read.me, run yarn pretty

* Apply yarn pretty blocker

* Add unit test correction

* Add amends from yarn pretty fix

* Add OPL to missing pages, including error pages

* Remove unused variables

* Remove docker-compose change introduced, revert code

* Add PR amendments

* yarn run pretty amend

* Add PR amendments

* Revery docker-compose.yml

* DFC-319: Update analytics package to latest

* [DFC-319] - Update build scripts with new package name

* Un-uglify showpassword

* Remove env variable instructions from readme, include in variable file build files

* Correct GA4 object formatting

* Restructure local variables to getter functions

* Remove set variables from nunjucks files, reduce duplication of variable setting from controllers

* Remove comments and add whitespacing where specified, revert docker yml file

* Address feedback re endblock spacing

* Update package.json with updated frontend analytics package

* Revert ci changes made, implement build vars change

* Correct resend-mfa account creation

* Apply amendments re removing special characters, CSP amend, and optional chaining replacement

---------

Co-authored-by: di-aholme <[email protected]>
  • Loading branch information
Joanneyoung01 and di-aholme authored May 15, 2024
1 parent 696822a commit a5e483d
Show file tree
Hide file tree
Showing 87 changed files with 754 additions and 459 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"build-sass": "rm -rf dist/public/style.css && sass --load-path=node_modules/govuk-frontend/govuk --no-source-map --quiet-deps src/assets/scss/application.scss dist/public/style.css --style compressed",
"clean": "rm -rf dist node_modules logs.json",
"clean-modules": "rm -rf node_modules",
"copy-assets": "mkdir -p dist && copyfiles -u 1 src/**/*.njk dist/ src/locales/**/** dist/ src/config/*.txt dist/ && copyfiles -u 3 src/assets/javascript/*.js dist/public/scripts -e **/all.js && cp node_modules/govuk-frontend/govuk/all.js dist/public/scripts",
"copy-assets": "mkdir -p dist && copyfiles -u 1 src/**/*.njk dist/ src/locales/**/** dist/ src/config/*.txt dist/ && copyfiles -u 3 src/assets/javascript/*.js dist/public/scripts -e **/all.js && cp node_modules/govuk-frontend/govuk/all.js dist/public/scripts && cp node_modules/@govuk-one-login/frontend-analytics/lib/analytics.js dist/public/scripts",
"dev": "tsc && concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run watch-node\"",
"dummy-server": "node dev-app.js | pino-pretty",
"depcheck": "depcheck",
Expand Down Expand Up @@ -64,6 +64,7 @@
"@aws-sdk/client-kms": "^3.366.0",
"@govuk-one-login/frontend-language-toggle": "^1.1.0",
"@govuk-one-login/frontend-passthrough-headers": "^0.0.3",
"@govuk-one-login/frontend-analytics": "1.0.3",
"@otplib/core": "^12.0.1",
"@otplib/plugin-base32-enc-dec": "^12.0.1",
"aws-sdk": "^2.1356.0",
Expand Down
25 changes: 25 additions & 0 deletions scripts/_create_env_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,31 @@ class EnvFileSection(TypedDict):
},
},
},
{
"header": "Analytics",
"variables": {
"GA4_DISABLED": {
"value": "false",
"comment": "GA4 Enablement",
},
"UA_DISABLED": {
"value": "false",
"comment": "Univeral Analytics",
},
"UNIVERSAL_ANALYTICS_GTM_CONTAINER_ID": {
"value": "GTM-TK92W68",
"comment": "Universal Analytics Container Id",
},
"GOOGLE_ANALYTICS_4_GTM_CONTAINER_ID": {
"value": "GTM-KD86CMZ",
"comment": "Listen port for frontend nodemon",
},
"ANALYTICS_COOKIE_DOMAIN": {
"value": "localhost",
"comment": "Analytics cookie domain where cookie is set",
},
},
},
]

DEFAULT_USER_VARIABLE_LOOKUP = {
Expand Down
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import { accountInterventionRouter } from "./components/account-intervention/pas
import { permanentlyBlockedRouter } from "./components/account-intervention/permanently-blocked/permanently-blocked-router";
import { temporarilyBlockedRouter } from "./components/account-intervention/temporarily-blocked/temporarily-blocked-router";
import { resetPassword2FAAuthAppRouter } from "./components/reset-password-2fa-auth-app/reset-password-2fa-auth-app-routes";
import { setGTM } from "./middleware/analytics-middleware";
import { setCurrentUrlMiddleware } from "./middleware/current-url-middleware";

const APP_VIEWS = [
Expand Down Expand Up @@ -168,6 +169,7 @@ async function createApp(): Promise<express.Application> {
app.use("/public", express.static(path.join(__dirname, "public")));
app.set("view engine", configureNunjucks(app, APP_VIEWS));
app.use(setLocalVarsMiddleware);
app.use(setGTM);

i18next
.use(Backend)
Expand Down
50 changes: 23 additions & 27 deletions src/assets/javascript/application.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
function initFeedbackRadioButtons() {
var feedbackRadioButtons = Array.prototype.slice.call(
document.querySelectorAll('input[name="feedbackContact"]')
);
var container = document.querySelector("#contact-details-container");
feedbackRadioButtons.forEach(function (element) {
element.addEventListener(
"click",
function (event) {
if (event.target.value === "true") {
container.classList.remove("govuk-!-display-none");
} else {
container.classList.add("govuk-!-display-none");
var elements = container.getElementsByTagName("input");
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == "text") {
elements[i].value = "";
document.querySelectorAll('input[name="feedbackContact"]')
);
var container = document.querySelector("#contact-details-container");
feedbackRadioButtons.forEach(function (element) {
element.addEventListener(
"click",
function (event) {
if (event.target.value === "true") {
container.classList.remove("govuk-!-display-none");
} else {
container.classList.add("govuk-!-display-none");
var elements = container.getElementsByTagName("input");
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == "text") {
elements[i].value = "";
}
}
}
}
}.bind(this)
);
});
Expand Down Expand Up @@ -50,21 +50,17 @@ function initEnterPhoneNumber() {
}
}

window.DI = window.DI || {};
window.DI.analyticsUa = window.DI.analyticsUa || {};
(function (w) {
"use strict";
function appInit(trackingId, analyticsCookieDomain) {
function appInit() {
window.GOVUKFrontend.initAll();
var cookies = window.GOVSignIn.Cookies(trackingId, analyticsCookieDomain);
var cookies = window.GOVSignIn.Cookies();

if (cookies.hasConsentForAnalytics()) {
if (window.DI.analyticsGa4.cookie.hasConsentForAnalytics()) {
cookies.initAnalytics();
}

if (cookies.isOnCookiesPage()) {
cookies.cookiesPageInit();
} else {
cookies.cookieBannerInit();
}
}

initFeedbackRadioButtons();
Expand All @@ -80,5 +76,5 @@ function initEnterPhoneNumber() {
}
}

w.GOVSignIn.appInit = appInit;
})(window);
w.DI.analyticsUa.init = appInit;
})(window);
190 changes: 2 additions & 188 deletions src/assets/javascript/cookies.js
Original file line number Diff line number Diff line change
@@ -1,96 +1,10 @@
"use strict";

var cookies = function (trackingId, analyticsCookieDomain) {
var COOKIES_PREFERENCES_SET = "cookies_preferences_set";
var COOKIES_HISTORY_LENGTH = "chl";
var cookiesAccepted = document.querySelector("#cookies-accepted");
var cookiesRejected = document.querySelector("#cookies-rejected");
var hideCookieBanner = document.querySelectorAll(".cookie-hide-button");
var cookieBannerContainer = document.querySelector(".govuk-cookie-banner");
var cookieBanner = document.querySelector("#cookies-banner-main");
var acceptCookies = document.querySelector('button[name="cookiesAccept"]');
var rejectCookies = document.querySelector('button[name="cookiesReject"]');

function cookieBannerInit() {
acceptCookies.addEventListener(
"click",
function (event) {
event.preventDefault();
setBannerCookieConsent(true);
}.bind(this)
);

rejectCookies.addEventListener(
"click",
function (event) {
event.preventDefault();
setBannerCookieConsent(false);
}.bind(this)
);

var hideButtons = Array.prototype.slice.call(hideCookieBanner);
hideButtons.forEach(function (element) {
element.addEventListener(
"click",
function (event) {
event.preventDefault();
hideElement(cookieBannerContainer);
}.bind(this)
);
});

var hasCookiesPolicy = getCookie(COOKIES_PREFERENCES_SET);

if (!hasCookiesPolicy) {
showElement(cookieBannerContainer);
}
}

function setBannerCookieConsent(analyticsConsent) {
setCookie(
COOKIES_PREFERENCES_SET,
{ analytics: analyticsConsent },
{ days: 365 }
);

hideElement(cookieBanner);

if (analyticsConsent) {
showElement(cookiesAccepted);
initAnalytics();
} else {
showElement(cookiesRejected);
}
}

function cookiesPageInit() {
document.querySelector("#cookie-preferences-form").hidden = false;
var chl = getCookie(COOKIES_HISTORY_LENGTH);
if (! chl || chl === "0" ) {
setCookie(
COOKIES_HISTORY_LENGTH,
window.history.length
);
}
document.querySelector("#go-back-link").onclick = function() {
var chl = getCookie(COOKIES_HISTORY_LENGTH);
if (chl && !isNaN(chl)) {
var backCount = (window.history.length - chl) + 1;
window.history.go(-(Math.abs(backCount)));
setCookie(COOKIES_HISTORY_LENGTH, 0);
}
};
}

function hasConsentForAnalytics() {
var cookieConsent = JSON.parse(getCookie(COOKIES_PREFERENCES_SET));
return cookieConsent ? cookieConsent.analytics : false;
}
var cookies = function () {

function initAnalytics() {
loadGtmScript();
window.DI.analyticsGa4.loadGtmScript(window.DI.analyticsGa4.uaContainerId);
initGtm();
initLinkerHandlers();
}

function pushLanguageToDataLayer() {
Expand All @@ -114,16 +28,6 @@ var cookies = function (trackingId, analyticsCookieDomain) {
}
}

function loadGtmScript() {
var gtmScriptTag = document.createElement("script");
gtmScriptTag.type = "text/javascript";
gtmScriptTag.setAttribute("async", "true");
gtmScriptTag.setAttribute(
"src",
"https://www.googletagmanager.com/gtm.js?id=" + trackingId
);
document.documentElement.firstChild.appendChild(gtmScriptTag);
}

function initGtm() {
window.dataLayer = [
Expand Down Expand Up @@ -153,39 +57,6 @@ var cookies = function (trackingId, analyticsCookieDomain) {
gtag({ "gtm.start": new Date().getTime(), event: "gtm.js" });
}

function initLinkerHandlers() {
var submitButton = document.querySelector('button[type="submit"]');
var pageForm = document.getElementById("form-tracking");

if (submitButton && pageForm) {
submitButton.addEventListener("click", function () {
if (window.ga && window.gaplugins) {
var tracker = ga.getAll()[0];
var linker = new window.gaplugins.Linker(tracker);
var destinationLink = linker.decorate(pageForm.action);
pageForm.action = destinationLink;
}
});
}

var trackLink = document.getElementById("track-link");

if (trackLink) {
trackLink.addEventListener("click", function (e) {
e.preventDefault();

if (window.ga && window.gaplugins) {
var tracker = ga.getAll()[0];
var linker = new window.gaplugins.Linker(tracker);
var destinationLink = linker.decorate(trackLink.href);
window.location.href = destinationLink;
} else {
window.location.href = trackLink.href;
}
});
}
}

function generateSessionJourney(journey, status) {
return {
sessionjourney: {
Expand Down Expand Up @@ -236,64 +107,7 @@ var cookies = function (trackingId, analyticsCookieDomain) {
return JOURNEY_DATA_LAYER_PATHS[url];
}

function getCookie(name) {
var nameEQ = name + "=";
var cookies = document.cookie.split(";");
for (var i = 0, len = cookies.length; i < len; i++) {
var cookie = cookies[i];
while (cookie.charAt(0) === " ") {
cookie = cookie.substring(1, cookie.length);
}
if (cookie.indexOf(nameEQ) === 0) {
return decodeURIComponent(cookie.substring(nameEQ.length));
}
}
return null;
}

function setCookie(name, values, options) {
if (typeof options === "undefined") {
options = {};
}

var cookieString = name + "=" + JSON.stringify(values);
if (options.days) {
var date = new Date();
date.setTime(date.getTime() + options.days * 24 * 60 * 60 * 1000);
cookieString =
cookieString +
"; expires=" +
date.toGMTString() +
"; path=/;" +
" domain=" +
analyticsCookieDomain +
";";
}

if (document.location.protocol === "https:") {
cookieString = cookieString + "; Secure";
}

document.cookie = cookieString;
}

function hideElement(el) {
el.style.display = "none";
}

function showElement(el) {
el.style.display = "block";
}

function isOnCookiesPage() {
return window.location.pathname.indexOf("cookies") !== -1;
}

return {
cookieBannerInit,
isOnCookiesPage,
cookiesPageInit,
hasConsentForAnalytics,
initAnalytics,
};
};
Expand Down
2 changes: 2 additions & 0 deletions src/components/account-created/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@
}) }}
{% endif %}
</form>

{{ga4OnPageLoad({ nonce: scriptNonce, statusCode: "200", englishPageTitle: pageTitleName, taxonomyLevel1: "authentication", taxonomyLevel2: "create account", contentId: "6857e410-75b8-4807-b475-3f24fc96c9de", loggedInStatus: false, dynamic: false })}}
{% endblock %}
2 changes: 2 additions & 0 deletions src/components/account-creation/resend-mfa-code/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@
}) }}

</form>

{{ga4OnPageLoad({ nonce: scriptNonce, statusCode: "200", englishPageTitle: pageTitleName, taxonomyLevel1: "authentication", taxonomyLevel2: "create account", contentId: "8247477c-3e33-4dae-9528-22e7ed44efb3", loggedInStatus: false, dynamic:false })}}
{% endblock %}
Loading

0 comments on commit a5e483d

Please sign in to comment.