hof 20.0.0-beta.2 → 20.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/automate-publish.yml +1 -1
- package/.github/workflows/automate-tag.yml +1 -1
- package/README.md +329 -256
- package/build/lib/mkdir.js +2 -2
- package/components/date/index.js +37 -26
- package/components/date/templates/date.html +3 -3
- package/components/emailer/index.js +49 -41
- package/components/emailer/transports/debug.js +1 -2
- package/components/index.js +2 -1
- package/components/notify/index.js +60 -0
- package/components/notify/notify.js +25 -0
- package/components/summary/index.js +18 -0
- package/config/hof-defaults.js +5 -3
- package/config/rate-limits.js +20 -0
- package/config/sanitisation-rules.js +29 -0
- package/controller/base-controller.js +26 -8
- package/controller/controller.js +11 -15
- package/frontend/govuk-template/build/config.js +1 -1
- package/frontend/template-mixins/mixins/template-mixins.js +12 -9
- package/frontend/template-mixins/partials/forms/checkbox-group.html +12 -3
- package/frontend/template-mixins/partials/forms/input-text-date.html +1 -1
- package/frontend/template-mixins/partials/forms/input-text-group.html +3 -3
- package/frontend/template-mixins/partials/forms/option-group.html +12 -3
- package/frontend/template-mixins/partials/forms/select.html +3 -3
- package/frontend/template-mixins/partials/forms/textarea-group.html +3 -3
- package/frontend/template-mixins/partials/mixins/panel.html +1 -2
- package/frontend/template-partials/translations/src/en/errors.json +12 -0
- package/frontend/template-partials/views/partials/form.html +2 -1
- package/frontend/template-partials/views/rate-limit-error.html +10 -0
- package/frontend/themes/gov-uk/client-js/govuk-cookies.js +43 -44
- package/frontend/themes/gov-uk/client-js/index.js +2 -2
- package/frontend/themes/gov-uk/client-js/skip-to-main.js +18 -17
- package/frontend/themes/gov-uk/styles/govuk.scss +4 -0
- package/frontend/themes/gov-uk/styles/modules/_validation.scss +2 -2
- package/frontend/toolkit/assets/javascript/form-focus.js +10 -1
- package/frontend/toolkit/assets/javascript/validation.js +6 -1
- package/index.js +9 -4
- package/lib/router.js +2 -1
- package/lib/settings.js +9 -8
- package/middleware/errors.js +32 -0
- package/middleware/index.js +2 -1
- package/middleware/rate-limiter.js +98 -0
- package/package.json +6 -6
- package/sandbox/apps/sandbox/fields.js +11 -12
- package/sandbox/apps/sandbox/index.js +1 -5
- package/sandbox/assets/scss/app.scss +0 -52
- package/sandbox/package.json +2 -0
- package/sandbox/public/css/app.css +4908 -4965
- package/sandbox/public/js/bundle.js +79 -65
- package/sandbox/server.js +5 -0
- package/sandbox/yarn.lock +25 -1
- package/transpiler/lib/write-files.js +1 -2
- package/utilities/helpers/index.js +16 -1
- package/wizard/index.js +1 -0
- package/.nyc_output/65af88d9-aebe-4d1b-a21d-6fbf7f2bbda4.json +0 -1
- package/.nyc_output/processinfo/65af88d9-aebe-4d1b-a21d-6fbf7f2bbda4.json +0 -1
- package/.nyc_output/processinfo/index.json +0 -1
- package/.vscode/settings.json +0 -6
- package/sandbox/.env +0 -1
@@ -146,9 +146,10 @@ module.exports = {
|
|
146
146
|
};
|
147
147
|
|
148
148
|
},{}],2:[function(require,module,exports){
|
149
|
+
/* eslint-disable no-undef, no-param-reassign, no-unused-vars */
|
149
150
|
(function () {
|
150
|
-
|
151
|
-
|
151
|
+
'use strict';
|
152
|
+
const root = this;
|
152
153
|
if(typeof root.GOVUK === 'undefined') { root.GOVUK = {}; }
|
153
154
|
|
154
155
|
/*
|
@@ -167,37 +168,35 @@ module.exports = {
|
|
167
168
|
GOVUK.cookie('hobnob', null);
|
168
169
|
*/
|
169
170
|
GOVUK.cookie = function (name, value, options) {
|
170
|
-
if(typeof value !== 'undefined'){
|
171
|
+
if(typeof value !== 'undefined') {
|
171
172
|
if(value === false || value === null) {
|
172
173
|
return GOVUK.setCookie(name, '', { days: -1 });
|
173
|
-
} else {
|
174
|
-
return GOVUK.setCookie(name, value, options);
|
175
174
|
}
|
176
|
-
|
177
|
-
return GOVUK.getCookie(name);
|
175
|
+
return GOVUK.setCookie(name, value, options);
|
178
176
|
}
|
177
|
+
return GOVUK.getCookie(name);
|
179
178
|
};
|
180
179
|
GOVUK.setCookie = function (name, value, options) {
|
181
180
|
if(typeof options === 'undefined') {
|
182
181
|
options = {};
|
183
182
|
}
|
184
|
-
|
183
|
+
let cookieString = name + '=' + value + '; path=/';
|
185
184
|
if (options.days) {
|
186
|
-
|
185
|
+
const date = new Date();
|
187
186
|
date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000));
|
188
|
-
cookieString = cookieString +
|
187
|
+
cookieString = cookieString + '; expires=' + date.toGMTString();
|
189
188
|
}
|
190
|
-
if (document.location.protocol
|
191
|
-
cookieString = cookieString +
|
189
|
+
if (document.location.protocol === 'https:') {
|
190
|
+
cookieString = cookieString + '; Secure';
|
192
191
|
}
|
193
192
|
document.cookie = cookieString;
|
194
193
|
};
|
195
194
|
GOVUK.getCookie = function (name) {
|
196
|
-
|
197
|
-
|
198
|
-
for(
|
199
|
-
|
200
|
-
while (cookie.charAt(0)
|
195
|
+
const nameEQ = name + '=';
|
196
|
+
const cookies = document.cookie.split(';');
|
197
|
+
for(let i = 0, len = cookies.length; i < len; i++) {
|
198
|
+
let cookie = cookies[i];
|
199
|
+
while (cookie.charAt(0) === ' ') {
|
201
200
|
cookie = cookie.substring(1, cookie.length);
|
202
201
|
}
|
203
202
|
if (cookie.indexOf(nameEQ) === 0) {
|
@@ -208,33 +207,33 @@ module.exports = {
|
|
208
207
|
};
|
209
208
|
}).call(this);
|
210
209
|
(function () {
|
211
|
-
'use strict'
|
212
|
-
|
213
|
-
if (typeof root.GOVUK === 'undefined') { root.GOVUK = {} }
|
210
|
+
'use strict';
|
211
|
+
const root = this;
|
212
|
+
if (typeof root.GOVUK === 'undefined') { root.GOVUK = {}; }
|
214
213
|
|
215
214
|
GOVUK.addCookieMessage = function () {
|
216
|
-
|
215
|
+
const message = document.getElementById('global-cookie-message');
|
217
216
|
|
218
|
-
|
217
|
+
const hasCookieMessage = (message && GOVUK.cookie('seen_cookie_message') === null);
|
219
218
|
|
220
219
|
if (hasCookieMessage) {
|
221
|
-
message.style.display = 'block'
|
222
|
-
GOVUK.cookie('seen_cookie_message', 'yes', { days: 28 })
|
220
|
+
message.style.display = 'block';
|
221
|
+
GOVUK.cookie('seen_cookie_message', 'yes', { days: 28 });
|
223
222
|
|
224
223
|
document.addEventListener('DOMContentLoaded', function (event) {
|
225
224
|
if (GOVUK.analytics && typeof GOVUK.analytics.trackEvent === 'function') {
|
226
225
|
GOVUK.analytics.trackEvent('cookieBanner', 'Cookie banner shown', {
|
227
226
|
value: 1,
|
228
227
|
nonInteraction: true
|
229
|
-
})
|
228
|
+
});
|
230
229
|
}
|
231
|
-
})
|
232
|
-
}
|
233
|
-
}
|
230
|
+
});
|
231
|
+
}
|
232
|
+
};
|
234
233
|
}).call(this)
|
235
234
|
;
|
236
|
-
(function() {
|
237
|
-
|
235
|
+
(function () {
|
236
|
+
'use strict';
|
238
237
|
|
239
238
|
// add cookie message
|
240
239
|
if (window.GOVUK && GOVUK.addCookieMessage) {
|
@@ -242,35 +241,35 @@ module.exports = {
|
|
242
241
|
}
|
243
242
|
|
244
243
|
// header navigation toggle
|
245
|
-
if (document.querySelectorAll && document.addEventListener){
|
246
|
-
|
247
|
-
|
248
|
-
for(i=0,_i=els.length; i<_i; i++){
|
249
|
-
els[i].addEventListener('click', function(e){
|
244
|
+
if (document.querySelectorAll && document.addEventListener) {
|
245
|
+
const els = document.querySelectorAll('.js-header-toggle');
|
246
|
+
let i; let _i;
|
247
|
+
for(i = 0, _i = els.length; i < _i; i++) {
|
248
|
+
els[i].addEventListener('click', function (e) {
|
250
249
|
e.preventDefault();
|
251
|
-
|
252
|
-
|
253
|
-
|
250
|
+
const target = document.getElementById(this.getAttribute('href').substr(1));
|
251
|
+
const targetClass = target.getAttribute('class') || '';
|
252
|
+
const sourceClass = this.getAttribute('class') || '';
|
254
253
|
|
255
|
-
if(targetClass.indexOf('js-visible') !== -1){
|
254
|
+
if(targetClass.indexOf('js-visible') !== -1) {
|
256
255
|
target.setAttribute('class', targetClass.replace(/(^|\s)js-visible(\s|$)/, ''));
|
257
256
|
} else {
|
258
|
-
target.setAttribute('class', targetClass +
|
257
|
+
target.setAttribute('class', targetClass + ' js-visible');
|
259
258
|
}
|
260
|
-
if(sourceClass.indexOf('js-visible') !== -1){
|
259
|
+
if(sourceClass.indexOf('js-visible') !== -1) {
|
261
260
|
this.setAttribute('class', sourceClass.replace(/(^|\s)js-visible(\s|$)/, ''));
|
262
261
|
} else {
|
263
|
-
this.setAttribute('class', sourceClass +
|
262
|
+
this.setAttribute('class', sourceClass + ' js-visible');
|
264
263
|
}
|
265
|
-
this.setAttribute('aria-expanded', this.getAttribute('aria-expanded') !==
|
266
|
-
target.setAttribute('aria-hidden', target.getAttribute('aria-hidden') ===
|
264
|
+
this.setAttribute('aria-expanded', this.getAttribute('aria-expanded') !== 'true');
|
265
|
+
target.setAttribute('aria-hidden', target.getAttribute('aria-hidden') === 'false');
|
267
266
|
});
|
268
267
|
}
|
269
268
|
}
|
270
269
|
}).call(this);
|
271
270
|
|
272
271
|
},{}],3:[function(require,module,exports){
|
273
|
-
/* eslint-disable no-var */
|
272
|
+
/* eslint-disable no-var, vars-on-top, no-unused-vars */
|
274
273
|
'use strict';
|
275
274
|
|
276
275
|
var toolkit = require('../../../toolkit');
|
@@ -280,7 +279,7 @@ var formFocus = toolkit.formFocus;
|
|
280
279
|
var characterCount = toolkit.characterCount;
|
281
280
|
var validation = toolkit.validation;
|
282
281
|
|
283
|
-
var GOVUK = require('govuk-frontend')
|
282
|
+
var GOVUK = require('govuk-frontend');
|
284
283
|
GOVUK.initAll();
|
285
284
|
window.GOVUK = GOVUK;
|
286
285
|
var skipToMain = require('./skip-to-main');
|
@@ -299,23 +298,24 @@ helpers.documentReady(validation);
|
|
299
298
|
|
300
299
|
},{"../../../toolkit":11,"./cookieSettings":1,"./govuk-cookies":2,"./skip-to-main":4,"govuk-frontend":12}],4:[function(require,module,exports){
|
301
300
|
const skipToMain = function () {
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
}
|
316
|
-
}
|
317
|
-
}
|
318
|
-
|
301
|
+
const skipToMainLink = document.getElementById('skip-to-main');
|
302
|
+
const firstControlId = skipToMainLink.hash.split('#')[1] ? skipToMainLink.hash.split('#')[1] : 'main-content';
|
303
|
+
if(firstControlId === 'main-content') {
|
304
|
+
skipToMainLink.setAttribute('href', '#main-content');
|
305
|
+
}
|
306
|
+
if(firstControlId) {
|
307
|
+
// eslint-disable-next-line no-unused-vars
|
308
|
+
skipToMainLink.onclick = function (e) {
|
309
|
+
// here timeout added just to make this functionality asynchronous
|
310
|
+
// to focus on form as well as non form contents
|
311
|
+
setTimeout(() => {
|
312
|
+
const firstControl = document.getElementById(firstControlId);
|
313
|
+
firstControl.focus();
|
314
|
+
}, 10);
|
315
|
+
};
|
316
|
+
}
|
317
|
+
};
|
318
|
+
skipToMain();
|
319
319
|
|
320
320
|
},{}],5:[function(require,module,exports){
|
321
321
|
/* eslint-disable max-len, no-var, no-use-before-define, no-param-reassign, vars-on-top, radix */
|
@@ -492,11 +492,20 @@ function formFocus() {
|
|
492
492
|
var labels;
|
493
493
|
var summaries;
|
494
494
|
|
495
|
-
|
495
|
+
var editMode = getElementFromSummaryLink && getEditPath === 'edit';
|
496
|
+
|
497
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink) && editMode) {
|
496
498
|
document.getElementById(getElementFromSummaryLink).focus();
|
499
|
+
}
|
500
|
+
|
501
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink + '-group') && editMode) {
|
497
502
|
document.getElementById(getElementFromSummaryLink + '-group').scrollIntoView();
|
498
503
|
}
|
499
504
|
|
505
|
+
if (document.getElementById(getElementFromSummaryLink + '-day') && forms.length === 1 && editMode) {
|
506
|
+
document.getElementById(getElementFromSummaryLink + '-day').focus();
|
507
|
+
}
|
508
|
+
|
500
509
|
if (forms.length > 0) {
|
501
510
|
labels = document.getElementsByTagName('label');
|
502
511
|
if (labels) {
|
@@ -790,7 +799,12 @@ function clicked(e) {
|
|
790
799
|
}
|
791
800
|
|
792
801
|
if (inputs) {
|
793
|
-
inputs[0].
|
802
|
+
if (inputs[0].getAttribute('type') === 'hidden') {
|
803
|
+
var getVisibleElements = group.querySelectorAll('input[type=text]');
|
804
|
+
getVisibleElements[0].focus();
|
805
|
+
} else {
|
806
|
+
inputs[0].focus();
|
807
|
+
}
|
794
808
|
}
|
795
809
|
}
|
796
810
|
}
|
package/sandbox/server.js
CHANGED
package/sandbox/yarn.lock
CHANGED
@@ -111,7 +111,7 @@ chalk@^4.1.0:
|
|
111
111
|
ansi-styles "^4.1.0"
|
112
112
|
supports-color "^7.1.0"
|
113
113
|
|
114
|
-
chokidar@^3.5.2:
|
114
|
+
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2:
|
115
115
|
version "3.5.3"
|
116
116
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
117
117
|
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
@@ -287,6 +287,11 @@ got@^9.6.0:
|
|
287
287
|
to-readable-stream "^1.0.0"
|
288
288
|
url-parse-lax "^3.0.0"
|
289
289
|
|
290
|
+
govuk-frontend@3.14:
|
291
|
+
version "3.14.0"
|
292
|
+
resolved "https://registry.yarnpkg.com/govuk-frontend/-/govuk-frontend-3.14.0.tgz#d3a9c54437c08f5188f87b1f4480ba60e95c8eb6"
|
293
|
+
integrity sha512-y7FTuihCSA8Hty+e9h0uPhCoNanCAN+CLioNFlPmlbeHXpbi09VMyxTcH+XfnMPY4Cp++7096v0rLwwdapTXnA==
|
294
|
+
|
290
295
|
graceful-fs@^4.1.2:
|
291
296
|
version "4.2.10"
|
292
297
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
@@ -317,6 +322,11 @@ ignore-by-default@^1.0.1:
|
|
317
322
|
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
318
323
|
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
|
319
324
|
|
325
|
+
immutable@^4.0.0:
|
326
|
+
version "4.1.0"
|
327
|
+
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
|
328
|
+
integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
|
329
|
+
|
320
330
|
import-lazy@^2.1.0:
|
321
331
|
version "2.1.0"
|
322
332
|
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
|
@@ -599,6 +609,15 @@ responselike@^1.0.2:
|
|
599
609
|
dependencies:
|
600
610
|
lowercase-keys "^1.0.0"
|
601
611
|
|
612
|
+
sass@^1.53.0:
|
613
|
+
version "1.53.0"
|
614
|
+
resolved "https://registry.yarnpkg.com/sass/-/sass-1.53.0.tgz#eab73a7baac045cc57ddc1d1ff501ad2659952eb"
|
615
|
+
integrity sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==
|
616
|
+
dependencies:
|
617
|
+
chokidar ">=3.0.0 <4.0.0"
|
618
|
+
immutable "^4.0.0"
|
619
|
+
source-map-js ">=0.6.2 <2.0.0"
|
620
|
+
|
602
621
|
semver-diff@^3.1.1:
|
603
622
|
version "3.1.1"
|
604
623
|
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
|
@@ -628,6 +647,11 @@ signal-exit@^3.0.2:
|
|
628
647
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
629
648
|
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
630
649
|
|
650
|
+
"source-map-js@>=0.6.2 <2.0.0":
|
651
|
+
version "1.0.2"
|
652
|
+
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
653
|
+
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
654
|
+
|
631
655
|
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.2:
|
632
656
|
version "4.2.3"
|
633
657
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
const fs = require('fs');
|
4
4
|
const path = require('path');
|
5
|
-
const mkdir = require('mkdirp').sync;
|
6
5
|
const rm = require('rimraf').sync;
|
7
6
|
|
8
7
|
const debug = require('debug')('hof:transpiler');
|
@@ -16,7 +15,7 @@ module.exports = (dir, data) => {
|
|
16
15
|
const outputDir = path.resolve(dir, '..', lang);
|
17
16
|
rm(outputDir);
|
18
17
|
debug(`Emptied directory ${outputDir}`);
|
19
|
-
|
18
|
+
fs.mkdirSync(outputDir);
|
20
19
|
debug(`Made directory ${outputDir}`);
|
21
20
|
Object.keys(data[lang]).forEach(namespace => {
|
22
21
|
fs.writeFileSync(path.resolve(outputDir, `${namespace}.json`), JSON.stringify(data[lang][namespace], null, ' '));
|
@@ -94,7 +94,7 @@ module.exports = class Helpers {
|
|
94
94
|
/**
|
95
95
|
* utility function which returns undefined on
|
96
96
|
* failed translations instead of returning the key
|
97
|
-
* @param {Function} translate - the translate
|
97
|
+
* @param {Function} translate - the translate function
|
98
98
|
* @param {String} key - the key to translate
|
99
99
|
* @returns {String|undefined} the string result if successful, undefined if not
|
100
100
|
*/
|
@@ -131,4 +131,19 @@ module.exports = class Helpers {
|
|
131
131
|
`pages.${key}.header`
|
132
132
|
]) || key;
|
133
133
|
}
|
134
|
+
/**
|
135
|
+
* utility function which returns true or false on
|
136
|
+
* forks depending on whether a value exists on the page
|
137
|
+
* @param {Object} req - an http request object
|
138
|
+
* @param {Object} res - an http response object
|
139
|
+
* @param {Function|Object} condition - a field condition that is either a function or object
|
140
|
+
* @returns {Boolean} the boolean result of whether a field value is set on the page or session for a fork
|
141
|
+
*/
|
142
|
+
static isFieldValueInPageOrSessionValid(req, res, condition) {
|
143
|
+
return _.isFunction(condition) ?
|
144
|
+
condition(req, res) :
|
145
|
+
condition.value === (req.form.values[condition.field] ||
|
146
|
+
(!Object.keys(req.form.values).includes(condition.field) &&
|
147
|
+
_.get(req, `form.historicalValues[${condition.field}]`)));
|
148
|
+
}
|
134
149
|
};
|
package/wizard/index.js
CHANGED
@@ -69,6 +69,7 @@ const Wizard = (steps, fields, setts) => {
|
|
69
69
|
options.confirmStep = settings.confirmStep;
|
70
70
|
options.clearSession = options.clearSession || false;
|
71
71
|
options.fieldsConfig = _.cloneDeep(fields);
|
72
|
+
options.sanitiseInputs = settings.sanitiseInputs;
|
72
73
|
|
73
74
|
options.defaultFormatters = [].concat(settings.formatters);
|
74
75
|
|