From 9d93ad300e92194f87fb43586fa3933453422c06 Mon Sep 17 00:00:00 2001 From: Iqbal Ahmed Date: Mon, 9 Sep 2024 14:31:26 +0100 Subject: [PATCH] PP-12021 Upgrade to DS v5 with CSP change - Going up to v5.6. - Updated the code as per the release notes from the design system: https://github.com/alphagov/govuk-frontend/releases - Remove the cookie banner code & analytics code - This is old and no longer required. - To get it working with DSv5 would have required work on the JS. - Decided to just remove it. - Update CSP to allow a manifest.json from 'self'. --- Gruntfile.js | 2 +- app/assets/javascripts/browsered/helpers.js | 2 +- .../browsered/web-payments/helpers.js | 2 +- .../modules/analytics-track-click.js | 21 ------ .../javascripts/modules/cookie-banner.js | 70 ------------------- .../javascripts/modules/form-card-type.js | 2 +- app/assets/sass/application.scss | 3 +- app/assets/sass/modules/cookie-message.scss | 20 ------ app/middleware/csp.js | 4 +- app/views/includes/cookie-message.njk | 5 -- app/views/includes/custom.njk | 2 +- app/views/includes/scripts.njk | 3 +- app/views/layout.njk | 30 +++----- package-lock.json | 16 ++--- package.json | 2 +- server.js | 8 +-- test/integration/charge-status.ft.test.js | 1 - test/test-helpers/html-assertions.js | 2 +- 18 files changed, 31 insertions(+), 164 deletions(-) delete mode 100644 app/assets/javascripts/modules/analytics-track-click.js delete mode 100644 app/assets/javascripts/modules/cookie-banner.js delete mode 100644 app/assets/sass/modules/cookie-message.scss delete mode 100644 app/views/includes/cookie-message.njk diff --git a/Gruntfile.js b/Gruntfile.js index af7545789..4a8634dfc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -128,7 +128,7 @@ module.exports = function (grunt) { dist: { src: ['public/javascripts/application.js', 'node_modules/promise-polyfill/dist/polyfill.min.js', - 'node_modules/govuk-frontend/govuk/all.js', + 'node_modules/govuk-frontend/dist/govuk/all.bundle.js', 'app/assets/javascripts/modules/*.js'], dest: 'public/javascripts/application.js' } diff --git a/app/assets/javascripts/browsered/helpers.js b/app/assets/javascripts/browsered/helpers.js index 80b7e1f9d..88b3e12c0 100644 --- a/app/assets/javascripts/browsered/helpers.js +++ b/app/assets/javascripts/browsered/helpers.js @@ -25,7 +25,7 @@ const initialiseAddressCountryAutocomplete = () => { const toggleButton = (button) => { if (button) { - button[button.getAttribute('disabled') ? 'removeAttribute' : 'setAttribute']('disabled', 'disabled') + button[button.hasAttribute('disabled') ? 'removeAttribute' : 'setAttribute']('disabled', 'disabled') } } diff --git a/app/assets/javascripts/browsered/web-payments/helpers.js b/app/assets/javascripts/browsered/web-payments/helpers.js index 96672e742..6f5fbd8cf 100644 --- a/app/assets/javascripts/browsered/web-payments/helpers.js +++ b/app/assets/javascripts/browsered/web-payments/helpers.js @@ -24,7 +24,7 @@ const clearErrorSummary = () => { const toggleWaiting = (paymentMethodSubmitId) => { const button = document.getElementById(paymentMethodSubmitId) - button[button.getAttribute('disabled') ? 'removeAttribute' : 'setAttribute']('disabled', 'disabled') + button[button.hasAttribute('disabled') ? 'removeAttribute' : 'setAttribute']('disabled', 'disabled') document.getElementById('spinner').classList.toggle('hidden') } diff --git a/app/assets/javascripts/modules/analytics-track-click.js b/app/assets/javascripts/modules/analytics-track-click.js deleted file mode 100644 index d38219866..000000000 --- a/app/assets/javascripts/modules/analytics-track-click.js +++ /dev/null @@ -1,21 +0,0 @@ -var analyticsTrackConfirmClick = function(){ - "use strict"; - - var init = function(analyticsId, type, paymentProvider, amount, hitPage) { - var confirm = document.getElementById('confirm'); - confirm.addEventListener('click', function(){ - ga('send', { - hitType: 'pageview', - page: hitPage, - 'dimension1': analyticsId, - 'dimension2': type, - 'dimension3': paymentProvider, - 'metric1': amount - }); - }, false); - }; - - return { - init: init - }; -}; diff --git a/app/assets/javascripts/modules/cookie-banner.js b/app/assets/javascripts/modules/cookie-banner.js deleted file mode 100644 index 90f65c7c2..000000000 --- a/app/assets/javascripts/modules/cookie-banner.js +++ /dev/null @@ -1,70 +0,0 @@ -; (function () { - 'use strict' - var root = this - if (typeof root.GOVUK === 'undefined') { root.GOVUK = {} } - - /* - Cookie methods - ============== - Usage: - Setting a cookie: - GOVUK.cookie('hobnob', 'tasty', { days: 30 }); - Reading a cookie: - GOVUK.cookie('hobnob'); - Deleting a cookie: - GOVUK.cookie('hobnob', null); - */ - root.GOVUK.cookie = function (name, value, options) { - if (typeof value !== 'undefined') { - if (value === false || value === null) { - return root.GOVUK.setCookie(name, '', { days: -1 }) - } else { - return root.GOVUK.setCookie(name, value, options) - } - } else { - return root.GOVUK.getCookie(name) - } - } - root.GOVUK.setCookie = function (name, value, options) { - if (typeof options === 'undefined') { - options = {} - } - var cookieString = name + '=' + value + '; path=/' - if (options.days) { - var date = new Date() - date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000)) - cookieString = cookieString + '; expires=' + date.toGMTString() - } - if (document.location.protocol === 'https:') { - cookieString = cookieString + '; Secure' - } - document.cookie = cookieString - } - root.GOVUK.getCookie = function (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 - } - root.GOVUK.addCookieMessage = function () { - var message = document.querySelector('.js-cookie-banner') - var hasCookieMessage = (message && root.GOVUK.cookie('seen_cookie_message') === null) - - if (hasCookieMessage) { - message.style.display = 'block' - root.GOVUK.cookie('seen_cookie_message', 'yes', { days: 28 }) - } - } - // add cookie message - if (root.GOVUK && root.GOVUK.addCookieMessage) { - root.GOVUK.addCookieMessage() - } -}).call(this) diff --git a/app/assets/javascripts/modules/form-card-type.js b/app/assets/javascripts/modules/form-card-type.js index bc95c340f..4314d13d5 100644 --- a/app/assets/javascripts/modules/form-card-type.js +++ b/app/assets/javascripts/modules/form-card-type.js @@ -1,4 +1,4 @@ -var showCardType = function() { +window.showCardType = function() { var form = document.getElementById('card-details') var acceptedCards = form.querySelector('.accepted-cards') var cardInput = form.querySelector('#card-no') diff --git a/app/assets/sass/application.scss b/app/assets/sass/application.scss index e10f98d92..2a3328460 100644 --- a/app/assets/sass/application.scss +++ b/app/assets/sass/application.scss @@ -1,11 +1,10 @@ -@import "govuk-frontend/govuk/all"; +@import "govuk-frontend/dist/govuk/all"; @import "govuk-country-and-territory-autocomplete/location-autocomplete"; @import "modules/3ds"; @import "modules/accepted-cards"; @import "modules/accessible-autocomplete"; @import "modules/button-reset"; -@import "modules/cookie-message"; @import "modules/cvc"; @import "modules/expiry-date-separator"; @import "modules/input-confirm"; diff --git a/app/assets/sass/modules/cookie-message.scss b/app/assets/sass/modules/cookie-message.scss deleted file mode 100644 index 49b861b9e..000000000 --- a/app/assets/sass/modules/cookie-message.scss +++ /dev/null @@ -1,20 +0,0 @@ -.cookie-banner { - box-sizing: border-box; - width: 100%; - - padding-top: govuk-spacing(3); - padding-right: govuk-spacing(3); - padding-bottom: govuk-spacing(3); - padding-left: govuk-spacing(3); - background-color: lighten(desaturate(govuk-colour("light-blue"), 8.46), 42.55); - - display: none; - - p { - margin: 0; - } - - @include govuk-media-query($media-type: print) { - display: none !important; - } -} diff --git a/app/middleware/csp.js b/app/middleware/csp.js index c9018bd90..709a36ce9 100644 --- a/app/middleware/csp.js +++ b/app/middleware/csp.js @@ -12,7 +12,7 @@ const allowUnsafeEvalScripts = process.env.CSP_ALLOW_UNSAFE_EVAL_SCRIPTS === 'tr const frontendUrl = process.env.FRONTEND_URL || '' // Script responsible for setting 'js-enabled' class, extends GOV.UK frontend `layout` which we have no control over // and never changes -const govUkFrontendLayoutJsEnabledScriptHash = '\'sha256-+6WnXIl4mbFTCARd8N3COQmT3bJJmo32N8q8ZSQAIcU=\'' +const govUkFrontendLayoutJsEnabledScriptHash = '\'sha256-GUQ5ad8JK5KmEWmROf3LZd9ge94daqNvd8xy9YS1iDw=\'' const CSP_NONE = ['\'none\''] const CSP_SELF = ['\'self\''] @@ -66,7 +66,7 @@ const cardDetailsCSP = helmet({ formAction: [formActionCardDetails], fontSrc: CSP_SELF, frameAncestors: CSP_SELF, - manifestSrc: CSP_NONE, + manifestSrc: CSP_SELF, mediaSrc: CSP_NONE, objectSrc: CSP_NONE, baseUri: CSP_NONE diff --git a/app/views/includes/cookie-message.njk b/app/views/includes/cookie-message.njk deleted file mode 100644 index 9aa44469a..000000000 --- a/app/views/includes/cookie-message.njk +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/app/views/includes/custom.njk b/app/views/includes/custom.njk index 23aeb3527..00379837b 100644 --- a/app/views/includes/custom.njk +++ b/app/views/includes/custom.njk @@ -8,7 +8,7 @@
- + {{ serviceName }}
diff --git a/app/views/includes/scripts.njk b/app/views/includes/scripts.njk index 8ae0103cb..04365fa04 100644 --- a/app/views/includes/scripts.njk +++ b/app/views/includes/scripts.njk @@ -54,7 +54,6 @@ confirmationForm.addEventListener('submit', function () { confirmButton.setAttribute('disabled', 'disabled') }) - analyticsTrackConfirmClick().init('{{analytics.analyticsId}}', '{{analytics.type}}', '{{analytics.paymentProvider}}', '{{analytics.amount}}', '{{hitPage}}') } {% if allowGooglePay%} window.googlePayGatewayMerchantID = '{{ googlePayGatewayMerchantID }}' @@ -67,4 +66,4 @@ {% endif %} }) - + diff --git a/app/views/layout.njk b/app/views/layout.njk index aa5827e96..e87ddd519 100644 --- a/app/views/layout.njk +++ b/app/views/layout.njk @@ -31,33 +31,23 @@
- + {{serviceName}}
@@ -66,10 +56,6 @@ {% endif %} {% endblock %} -{% block bodyStart %} - {% include "includes/cookie-message.njk" %} -{% endblock %} - {% block bodyEnd %} {# Run JavaScript at end of the , to avoid blocking the initial render. #} {% include "includes/scripts.njk" %} diff --git a/package-lock.json b/package-lock.json index 7750e2b74..396570ad8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "express": "4.19.x", "express-rate-limit": "^7.1.4", "gaap-analytics": "^3.1.0", - "govuk-frontend": "^4.8.0", + "govuk-frontend": "^5.6.0", "helmet": "^7.1.0", "hpagent": "^1.2.0", "i18n": "0.15.x", @@ -57,7 +57,7 @@ "chai-as-promised": "^7.1.1", "chai-string": "^1.4.0", "cheerio": "^1.0.0-rc.12", - "chokidar-cli": "*", + "chokidar-cli": "latest", "cypress": "^13.3.1", "dotenv": "^16.3.1", "govuk-country-and-territory-autocomplete": "^1.0.2", @@ -7850,9 +7850,9 @@ } }, "node_modules/govuk-frontend": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.8.0.tgz", - "integrity": "sha512-NOmPJxL8IYq1HSNHYKx9XY2LLTxuwb+IFASiGQO4sgJ8K7AG66SlSeqARrcetevV8zOf+i1z+MbJJ2O7//OxAw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-5.6.0.tgz", + "integrity": "sha512-yNA4bL7i7mNrg36wPNZ3RctHo9mjl82Phs8MWs1lwovxJuQ4ogEo/XWn2uB1HxkXNqgMlW4wnd0iiKgRMfxYfw==", "engines": { "node": ">= 4.2.0" } @@ -22999,9 +22999,9 @@ } }, "govuk-frontend": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.8.0.tgz", - "integrity": "sha512-NOmPJxL8IYq1HSNHYKx9XY2LLTxuwb+IFASiGQO4sgJ8K7AG66SlSeqARrcetevV8zOf+i1z+MbJJ2O7//OxAw==" + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-5.6.0.tgz", + "integrity": "sha512-yNA4bL7i7mNrg36wPNZ3RctHo9mjl82Phs8MWs1lwovxJuQ4ogEo/XWn2uB1HxkXNqgMlW4wnd0iiKgRMfxYfw==" }, "graceful-fs": { "version": "4.2.10", diff --git a/package.json b/package.json index 9175e5eb9..efc36aaeb 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "express": "4.19.x", "express-rate-limit": "^7.1.4", "gaap-analytics": "^3.1.0", - "govuk-frontend": "^4.8.0", + "govuk-frontend": "^5.6.0", "helmet": "^7.1.0", "hpagent": "^1.2.0", "i18n": "0.15.x", diff --git a/server.js b/server.js index 0cf996994..c0a6cef36 100644 --- a/server.js +++ b/server.js @@ -45,7 +45,7 @@ const publicCaching = { maxAge: oneYear } // Define app views const APP_VIEWS = [ - path.join(__dirname, 'node_modules/govuk-frontend/'), + path.join(__dirname, 'node_modules/govuk-frontend/dist/'), path.join(__dirname, '/app/views') ] @@ -58,7 +58,7 @@ function initialiseGlobalMiddleware (app) { app.set('settings', { getVersionedPath: staticify.getVersionedPath }) app.use(/\/((?!images|public|stylesheets|javascripts).)*/, loggingMiddleware()) - app.use(favicon(path.join(__dirname, '/node_modules/govuk-frontend/govuk/assets/images', 'favicon.ico'))) + app.use(favicon(path.join(__dirname, '/node_modules/govuk-frontend/dist/govuk/assets/images', 'favicon.ico'))) app.use(staticify.middleware) app.use(function (req, res, next) { @@ -140,9 +140,9 @@ function initialisePublic (app) { app.use('/stylesheets', express.static(path.join(__dirname, '/public/assets/stylesheets'), publicCaching)) if (process.env.NGINX_CACHING_ENABLED === 'true') { - app.use('/', express.static(path.join(__dirname, '/node_modules/govuk-frontend/govuk/'), publicCaching)) + app.use('/', express.static(path.join(__dirname, '/node_modules/govuk-frontend/dist/govuk/'), publicCaching)) } else { - app.use('/', express.static(path.join(__dirname, '/node_modules/govuk-frontend/govuk/'))) + app.use('/', express.static(path.join(__dirname, '/node_modules/govuk-frontend/dist/govuk/'))) } app.use('/public', express.static(path.join(__dirname, '/node_modules/@govuk-pay/pay-js-commons/'))) diff --git a/test/integration/charge-status.ft.test.js b/test/integration/charge-status.ft.test.js index 26e10a28f..c0e9edae1 100644 --- a/test/integration/charge-status.ft.test.js +++ b/test/integration/charge-status.ft.test.js @@ -96,7 +96,6 @@ describe('chargeTests', function () { expect($('#card-details #csrf').attr('value')).to.not.be.empty // eslint-disable-line expect($('#amount').text()).to.eql('£23.45') expect($('#payment-description').text()).to.contain('Payment Description') - expect($('#govuk-script-analytics')[0].children[0].data).to.contains(`init('${gatewayAccount.analyticsId}', '${gatewayAccount.type}', 'sandbox', '23.45', '')`) expect($('#card-details').attr('action')).to.eql(frontendCardDetailsPostPath) }) .end(done) diff --git a/test/test-helpers/html-assertions.js b/test/test-helpers/html-assertions.js index 863692c78..23bc5c623 100644 --- a/test/test-helpers/html-assertions.js +++ b/test/test-helpers/html-assertions.js @@ -5,7 +5,7 @@ const nunjucks = require('nunjucks') const lodash = require('lodash') // Global initialisation -const views = ['./app/views', './node_modules/govuk-frontend'] +const views = ['./app/views', './node_modules/govuk-frontend/dist'] const environment = nunjucks.configure(views) const strings = require('./../../locales/en.json')