hof 20.0.0-beta.8 → 21.0.0-instrumentation-beta.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.nyc_output/4d5a4574-78fc-4fcb-9412-3658f6ce33ff.json +1 -0
- package/.nyc_output/processinfo/4d5a4574-78fc-4fcb-9412-3658f6ce33ff.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/components/date/index.js +1 -3
- package/components/date/templates/date.html +12 -15
- package/components/index.js +1 -0
- package/components/notify/index.js +60 -0
- package/components/notify/notify.js +25 -0
- package/config/sanitisation-rules.js +20 -17
- package/controller/base-controller.js +5 -3
- package/controller/controller.js +0 -39
- package/frontend/govuk-template/build/config.js +2 -2
- package/frontend/govuk-template/build/index.js +2 -2
- package/frontend/govuk-template/govuk_template.html +109 -0
- package/frontend/govuk-template/index.js +4 -4
- package/frontend/template-mixins/mixins/template-mixins.js +9 -20
- package/frontend/template-mixins/partials/forms/checkbox.html +4 -4
- package/frontend/template-mixins/partials/forms/input-submit.html +1 -1
- package/frontend/template-mixins/partials/forms/input-text-group.html +9 -12
- package/frontend/template-mixins/partials/forms/option-group.html +26 -33
- package/frontend/template-mixins/partials/forms/select.html +5 -10
- package/frontend/template-mixins/partials/forms/textarea-group.html +6 -15
- package/frontend/template-mixins/partials/mixins/panel.html +4 -3
- package/frontend/template-partials/views/accessibility.html +4 -4
- package/frontend/template-partials/views/cookies.html +1 -1
- package/frontend/template-partials/views/layout.html +22 -22
- package/frontend/template-partials/views/partials/back.html +1 -1
- package/frontend/template-partials/views/partials/bullet-list.html +1 -1
- package/frontend/template-partials/views/partials/confirmation-alert.html +3 -4
- package/frontend/template-partials/views/partials/continue.html +1 -1
- package/frontend/template-partials/views/partials/cookie-banner.html +24 -27
- package/frontend/template-partials/views/partials/cookie-settings-radio.html +6 -6
- package/frontend/template-partials/views/partials/external-link.html +1 -1
- package/frontend/template-partials/views/partials/form.html +1 -1
- package/frontend/template-partials/views/partials/maincontent-left.html +4 -4
- package/frontend/template-partials/views/partials/navigation.html +6 -7
- package/frontend/template-partials/views/partials/session-cookies-table.html +6 -6
- package/frontend/template-partials/views/partials/table.html +7 -7
- package/frontend/template-partials/views/partials/validation-list.html +2 -2
- package/frontend/template-partials/views/partials/validation-summary.html +13 -14
- package/frontend/template-partials/views/session-timeout.html +1 -1
- package/frontend/themes/gov-uk/client-js/cookieSettings.js +1 -1
- package/frontend/themes/gov-uk/client-js/index.js +0 -7
- package/frontend/themes/gov-uk/styles/_cookie-banner.scss +1 -51
- package/frontend/themes/gov-uk/styles/modules/_validation.scss +3 -3
- package/frontend/themes/gov-uk/views/partials/form.html +9 -0
- package/frontend/themes/gov-uk/views/partials/forms/option-group.html +28 -0
- package/frontend/themes/gov-uk/views/partials/mixins/panel.html +3 -0
- package/frontend/themes/gov-uk/views/partials/validation-summary.html +24 -0
- package/frontend/toolkit/assets/javascript/character-count.js +4 -4
- package/frontend/toolkit/assets/javascript/form-focus.js +10 -1
- package/frontend/toolkit/assets/javascript/validation.js +6 -1
- package/frontend/toolkit/assets/stylesheets/modules/_validation.scss +3 -3
- package/index.js +1 -6
- package/lib/settings.js +2 -18
- package/middleware/errors.js +3 -0
- package/middleware/monitor.js +20 -0
- package/middleware/not-found.js +3 -0
- package/middleware/rate-limiter.js +0 -1
- package/package.json +5 -4
- package/sandbox/apps/sandbox/fields.js +11 -23
- package/sandbox/apps/sandbox/index.js +1 -5
- package/sandbox/apps/sandbox/translations/src/en/fields.json +6 -9
- package/sandbox/apps/sandbox/translations/src/en/journey.json +1 -4
- package/sandbox/apps/sandbox/translations/src/en/pages.json +29 -2
- package/sandbox/apps/sandbox/translations/src/en/validation.json +1 -1
- package/sandbox/apps/sandbox/views/confirmation.html +15 -0
- package/sandbox/assets/js/index.js +1 -1
- package/sandbox/assets/scss/app.scss +16 -68
- package/sandbox/package.json +1 -4
- package/sandbox/yarn.lock +0 -767
- package/wizard/index.js +13 -0
- package/.nyc_output/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
- package/.nyc_output/processinfo/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
- package/.vscode/settings.json +0 -6
- package/frontend/govuk-template/build/govuk_template.html +0 -104
- package/frontend/govuk-template/govuk_template_generated.html +0 -104
- package/frontend/template-mixins/partials/forms/checkbox-group.html +0 -38
- package/frontend/template-mixins/partials/forms/input-text-date.html +0 -37
- package/frontend/themes/gov-uk/client-js/govuk-cookies.js +0 -121
- package/frontend/themes/gov-uk/client-js/skip-to-main.js +0 -19
- package/sandbox/.env +0 -1
- package/sandbox/apps/sandbox/translations/en/default.json +0 -203
- package/sandbox/public/css/app.css +0 -9439
- package/sandbox/public/images/icons/icon-caret-left.png +0 -0
- package/sandbox/public/images/icons/icon-complete.png +0 -0
- package/sandbox/public/images/icons/icon-cross-remove-sign.png +0 -0
- package/sandbox/public/js/bundle.js +0 -35644
@@ -1,3 +1,3 @@
|
|
1
|
-
<ul
|
2
|
-
|
1
|
+
<ul>
|
2
|
+
{{$validation-list}}{{/validation-list}}
|
3
3
|
</ul>
|
@@ -1,25 +1,24 @@
|
|
1
1
|
{{#errorlist.length}}
|
2
|
-
<div class="
|
2
|
+
<div class="validation-summary" tabindex="-1">
|
3
3
|
{{$errorlist-title}}
|
4
4
|
|
5
5
|
{{#errorLength.single}}
|
6
|
-
<h2
|
6
|
+
<h2 id="error-summary-title">{{#t}}errorlist.title.single{{/t}}</h2>
|
7
7
|
{{/errorLength.single}}
|
8
8
|
{{#errorLength.multiple}}
|
9
|
-
<h2
|
9
|
+
<h2 id="error-summary-title">{{#t}}errorlist.title.multiple{{/t}}</h2>
|
10
10
|
{{/errorLength.multiple}}
|
11
11
|
|
12
12
|
{{/errorlist-title}}
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
</div>
|
13
|
+
|
14
|
+
{{<partials-validation-list}}
|
15
|
+
{{$validation-list}}
|
16
|
+
{{#errorlist}}
|
17
|
+
{{#message}}
|
18
|
+
<li><a href="#{{key}}">{{ message }}</a></li>
|
19
|
+
{{/message}}
|
20
|
+
{{/errorlist}}
|
21
|
+
{{/validation-list}}
|
22
|
+
{{/partials-validation-list}}
|
24
23
|
</div>
|
25
24
|
{{/errorlist.length}}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{{<error}}
|
2
2
|
{{$content}}
|
3
3
|
<p>{{{content.message}}}</p>
|
4
|
-
<a href="{{startLink}}" class="
|
4
|
+
<a href="{{startLink}}" class="button" role="button">{{#t}}buttons.start-again{{/t}}</a>
|
5
5
|
{{/content}}
|
6
6
|
{{/error}}
|
@@ -35,7 +35,7 @@ function showCookieBannerSubmitted() {
|
|
35
35
|
document.getElementById('cookie-banner-info').style.display = 'none';
|
36
36
|
document.getElementById('cookie-banner-actions').style.display = 'none';
|
37
37
|
var cookieBannerSubmitted = document.getElementById('cookie-banner-submitted');
|
38
|
-
cookieBannerSubmitted.style.display = '
|
38
|
+
cookieBannerSubmitted.style.display = 'flex';
|
39
39
|
cookieBannerSubmitted.focus();
|
40
40
|
}
|
41
41
|
|
@@ -8,14 +8,7 @@ var formFocus = toolkit.formFocus;
|
|
8
8
|
var characterCount = toolkit.characterCount;
|
9
9
|
var validation = toolkit.validation;
|
10
10
|
|
11
|
-
var GOVUK = require('govuk-frontend');
|
12
|
-
// eslint-disable-next-line no-unused-vars
|
13
|
-
var skipToMain = require('./skip-to-main');
|
14
|
-
// eslint-disable-next-line no-unused-vars
|
15
|
-
var cookie = require('./govuk-cookies');
|
16
11
|
var cookieSettings = require('./cookieSettings');
|
17
|
-
GOVUK.initAll();
|
18
|
-
window.GOVUK = GOVUK;
|
19
12
|
|
20
13
|
toolkit.detailsSummary();
|
21
14
|
|
@@ -10,6 +10,7 @@
|
|
10
10
|
}
|
11
11
|
|
12
12
|
#cookie-banner {
|
13
|
+
max-width: 960px;
|
13
14
|
margin: 0 15px;
|
14
15
|
p {
|
15
16
|
margin: 0;
|
@@ -61,54 +62,3 @@
|
|
61
62
|
height: fit-content;
|
62
63
|
}
|
63
64
|
}
|
64
|
-
|
65
|
-
// the following are additional hof specific govuk cookie banner styling
|
66
|
-
.govuk-banner--success {
|
67
|
-
border-color: #00703c;
|
68
|
-
color: #00703c;
|
69
|
-
}
|
70
|
-
|
71
|
-
.govuk-banner {
|
72
|
-
border: 5px solid #1d70b8;
|
73
|
-
font-size: 0;
|
74
|
-
margin-bottom: 30px;
|
75
|
-
padding: 10px;
|
76
|
-
}
|
77
|
-
|
78
|
-
.govuk-banner__icon{
|
79
|
-
display: inline-block;
|
80
|
-
}
|
81
|
-
|
82
|
-
.govuk-banner__message {
|
83
|
-
font-family: "GDS Transport", Arial, sans-serif;
|
84
|
-
-webkit-font-smoothing: antialiased;
|
85
|
-
font-weight: 400;
|
86
|
-
font-size: 1rem;
|
87
|
-
line-height: 1.25;
|
88
|
-
color: #0b0c0c;
|
89
|
-
display: block;
|
90
|
-
overflow: hidden;
|
91
|
-
display: inline-block;
|
92
|
-
margin-left: 10px;
|
93
|
-
}
|
94
|
-
|
95
|
-
.govuk-banner__assistive {
|
96
|
-
position: absolute !important;
|
97
|
-
width: 1px !important;
|
98
|
-
height: 1px !important;
|
99
|
-
margin: 0 !important;
|
100
|
-
padding: 0 !important;
|
101
|
-
overflow: hidden !important;
|
102
|
-
clip: rect(0 0 0 0) !important;
|
103
|
-
clip-path: inset(50%) !important;
|
104
|
-
border: 0 !important;
|
105
|
-
white-space: nowrap !important;
|
106
|
-
}
|
107
|
-
|
108
|
-
.cookie-table-holder > table > tbody > tr > td:first-child{
|
109
|
-
font-weight:bold;
|
110
|
-
}
|
111
|
-
|
112
|
-
.js-enabled #global-cookie-message {
|
113
|
-
display: none;
|
114
|
-
}
|
@@ -22,7 +22,7 @@
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
|
25
|
-
.
|
25
|
+
.validation-error {
|
26
26
|
box-sizing: border-box;
|
27
27
|
padding-left: $gutter-half - $validation-bdr-size;
|
28
28
|
border-left: $validation-bdr-size-lg solid $error-colour;
|
@@ -36,7 +36,7 @@
|
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
-
.
|
39
|
+
.error-message {
|
40
40
|
display: block;
|
41
41
|
@include media(tablet) {
|
42
42
|
margin-bottom: 0.5em;
|
@@ -46,6 +46,6 @@
|
|
46
46
|
}
|
47
47
|
|
48
48
|
.invalid-input,
|
49
|
-
.
|
49
|
+
.validation-error .date-input {
|
50
50
|
border: $validation-bdr-size solid $error-colour;
|
51
51
|
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<form action="" method="POST" {{$encoding}}{{/encoding}} autocomplete="off" novalidate="true" spellcheck="false">
|
2
|
+
{{$intro}}
|
3
|
+
{{#intro}}<p>{{intro}}</p>{{/intro}}
|
4
|
+
{{/intro}}
|
5
|
+
{{$form}}{{/form}}
|
6
|
+
{{#csrf-token}}
|
7
|
+
<input type="hidden" name="x-csrf-token" value="{{csrf-token}}" />
|
8
|
+
{{/csrf-token}}
|
9
|
+
</form>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div id="{{key}}-group" class="form-group{{#className}} {{className}} {{/className}}{{#formGroupClassName}} {{formGroupClassName}}{{/formGroupClassName}}{{#error}} validation-error{{/error}}">
|
2
|
+
<fieldset role="{{role}}"{{#ariaRequired}} aria-required="true"{{/ariaRequired}}{{#hint}} aria-describedby="{{key}}-hint"{{/hint}}>
|
3
|
+
<legend>
|
4
|
+
<span{{#legendClassName}} class="{{legendClassName}}"{{/legendClassName}}>{{legend}}</span>
|
5
|
+
{{#hint}}<span id="{{key}}-hint" class="form-hint">{{hint}}</span>{{/hint}}
|
6
|
+
{{#error}}<span id="{{key}}-error" class="error-message">{{error.message}}</span>{{/error}}
|
7
|
+
</legend>
|
8
|
+
{{#options}}
|
9
|
+
<div class="multiple-choice">
|
10
|
+
<input
|
11
|
+
type="{{type}}"
|
12
|
+
name="{{key}}"
|
13
|
+
id="{{key}}-{{value}}"
|
14
|
+
value="{{value}}"
|
15
|
+
{{#toggle}} data-toggle="{{toggle}}"{{/toggle}}
|
16
|
+
{{#selected}} checked="checked"{{/selected}}
|
17
|
+
{{^error}}{{#optionHint}} aria-describedby="{{key}}-{{value}}-hint"{{/optionHint}}{{^optionHint}}{{#hint}} aria-describedby="{{key}}-hint"{{/hint}}{{/optionHint}}{{/error}}
|
18
|
+
{{#error}} aria-describedby="{{key}}-error" aria-invalid="true"{{/error}}
|
19
|
+
>
|
20
|
+
<label class="block-label" for="{{key}}-{{value}}">
|
21
|
+
{{{label}}}
|
22
|
+
{{#optionHint}}<span id="{{key}}-{{value}}-hint" class="form-hint">{{optionHint}}</span>{{/optionHint}}
|
23
|
+
</label>
|
24
|
+
</div>
|
25
|
+
{{#renderChild}}{{/renderChild}}
|
26
|
+
{{/options}}
|
27
|
+
</fieldset>
|
28
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{{#errorlist.length}}
|
2
|
+
<div class="validation-summary error-summary" tabindex="-1">
|
3
|
+
{{$errorlist-title}}
|
4
|
+
|
5
|
+
{{#errorLength.single}}
|
6
|
+
<h2>{{#t}}errorlist.title.single{{/t}}</h2>
|
7
|
+
{{/errorLength.single}}
|
8
|
+
{{#errorLength.multiple}}
|
9
|
+
<h2>{{#t}}errorlist.title.multiple{{/t}}</h2>
|
10
|
+
{{/errorLength.multiple}}
|
11
|
+
|
12
|
+
{{/errorlist-title}}
|
13
|
+
|
14
|
+
{{<partials-validation-list}}
|
15
|
+
{{$validation-list}}
|
16
|
+
{{#errorlist}}
|
17
|
+
{{#message}}
|
18
|
+
<li><a href="#{{key}}">{{ message }}</a></li>
|
19
|
+
{{/message}}
|
20
|
+
{{/errorlist}}
|
21
|
+
{{/validation-list}}
|
22
|
+
{{/partials-validation-list}}
|
23
|
+
</div>
|
24
|
+
{{/errorlist.length}}
|
@@ -30,12 +30,12 @@ CharacterCount.prototype.updateCount = function () {
|
|
30
30
|
this.$maxlengthHint.innerHTML = 'You have ' + number + characterNoun + remainderSuffix;
|
31
31
|
|
32
32
|
if (currentLength >= this.maxLength + 1) {
|
33
|
-
helpers.removeClass(this.$maxlengthHint, '
|
34
|
-
helpers.addClass(this.$maxlengthHint, '
|
33
|
+
helpers.removeClass(this.$maxlengthHint, 'form-hint');
|
34
|
+
helpers.addClass(this.$maxlengthHint, 'error-message');
|
35
35
|
helpers.addClass(this.$textarea, 'textarea-error');
|
36
36
|
} else {
|
37
|
-
helpers.addClass(this.$maxlengthHint, '
|
38
|
-
helpers.removeClass(this.$maxlengthHint, '
|
37
|
+
helpers.addClass(this.$maxlengthHint, 'form-hint');
|
38
|
+
helpers.removeClass(this.$maxlengthHint, 'error-message');
|
39
39
|
helpers.removeClass(this.$textarea, 'textarea-error');
|
40
40
|
}
|
41
41
|
};
|
@@ -71,11 +71,20 @@ function formFocus() {
|
|
71
71
|
var labels;
|
72
72
|
var summaries;
|
73
73
|
|
74
|
-
|
74
|
+
var editMode = getElementFromSummaryLink && getEditPath === 'edit';
|
75
|
+
|
76
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink) && editMode) {
|
75
77
|
document.getElementById(getElementFromSummaryLink).focus();
|
78
|
+
}
|
79
|
+
|
80
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink + '-group') && editMode) {
|
76
81
|
document.getElementById(getElementFromSummaryLink + '-group').scrollIntoView();
|
77
82
|
}
|
78
83
|
|
84
|
+
if (document.getElementById(getElementFromSummaryLink + '-day') && forms.length === 1 && editMode) {
|
85
|
+
document.getElementById(getElementFromSummaryLink + '-day').focus();
|
86
|
+
}
|
87
|
+
|
79
88
|
if (forms.length > 0) {
|
80
89
|
labels = document.getElementsByTagName('label');
|
81
90
|
if (labels) {
|
@@ -24,7 +24,12 @@ function clicked(e) {
|
|
24
24
|
}
|
25
25
|
|
26
26
|
if (inputs) {
|
27
|
-
inputs[0].
|
27
|
+
if (inputs[0].getAttribute('type') === 'hidden') {
|
28
|
+
var getVisibleElements = group.querySelectorAll('input[type=text]');
|
29
|
+
getVisibleElements[0].focus();
|
30
|
+
} else {
|
31
|
+
inputs[0].focus();
|
32
|
+
}
|
28
33
|
}
|
29
34
|
}
|
30
35
|
}
|
@@ -22,7 +22,7 @@
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
|
25
|
-
.
|
25
|
+
.validation-error {
|
26
26
|
box-sizing: border-box;
|
27
27
|
padding-left: $gutter-half - $validation-bdr-size;
|
28
28
|
border-left: $validation-bdr-size-lg solid $error-colour;
|
@@ -36,7 +36,7 @@
|
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
39
|
-
.
|
39
|
+
.error-message {
|
40
40
|
display: block;
|
41
41
|
@include media(tablet) {
|
42
42
|
margin-bottom: 0.5em;
|
@@ -46,6 +46,6 @@
|
|
46
46
|
}
|
47
47
|
|
48
48
|
.invalid-input,
|
49
|
-
.
|
49
|
+
.validation-error .date-input {
|
50
50
|
border: $validation-bdr-size solid $error-colour;
|
51
51
|
}
|
package/index.js
CHANGED
@@ -79,7 +79,7 @@ const getContentSecurityPolicy = (config, res) => {
|
|
79
79
|
fontSrc: ['fonts.gstatic.com '],
|
80
80
|
scriptSrc: ['www.google-analytics.com', 'ssl.google-analytics.com'],
|
81
81
|
imgSrc: ['www.google-analytics.com', 'ssl.gstatic.com'],
|
82
|
-
connectSrc: ['www.google-analytics.com']
|
82
|
+
connectSrc: ['https://www.google-analytics.com', 'https://region1.google-analytics.com']
|
83
83
|
};
|
84
84
|
|
85
85
|
if (config.gaTagId) {
|
@@ -120,8 +120,6 @@ const getContentSecurityPolicy = (config, res) => {
|
|
120
120
|
* @param options.getTerms {boolean} Optional boolean - whether to mount the /terms endpoint
|
121
121
|
* @param options.getCookies {boolean} Optional boolean - whether to mount the /cookies endpoint
|
122
122
|
* @param options.noCache {boolean} Optional boolean - whether to disable caching
|
123
|
-
* @param options.getAccessibilityStatement {boolean} Optional boolean - whether to mount the
|
124
|
-
* /accessibility-statement endpoint
|
125
123
|
*
|
126
124
|
* @returns {object} A new HOF application using the configuration supplied in options
|
127
125
|
*/
|
@@ -211,9 +209,6 @@ function bootstrap(options) {
|
|
211
209
|
app.use(hofMiddleware.rateLimiter(config, 'requests'));
|
212
210
|
}
|
213
211
|
|
214
|
-
// Set up routing so <YOUR-SITE-URL>/assets are served from /node_modules/govuk-frontend/govuk/assets
|
215
|
-
app.use('/assets', express.static(path.join(__dirname, '/node_modules/govuk-frontend/govuk/assets')));
|
216
|
-
|
217
212
|
if (config.getAccessibility === true) {
|
218
213
|
deprecate(
|
219
214
|
'`getAccessibility` option is deprecated and may be removed in future versions.',
|
package/lib/settings.js
CHANGED
@@ -7,22 +7,7 @@ const hoganExpressStrict = require('hogan-express-strict');
|
|
7
7
|
const expressPartialTemplates = require('express-partial-templates');
|
8
8
|
const bodyParser = require('body-parser');
|
9
9
|
|
10
|
-
|
11
|
-
try {
|
12
|
-
if (fs.existsSync(dir)) {
|
13
|
-
return true;
|
14
|
-
}
|
15
|
-
return false;
|
16
|
-
} catch(err) {
|
17
|
-
throw new Error(`${err}: Cannot check if the directory path exists`);
|
18
|
-
}
|
19
|
-
};
|
20
|
-
|
21
|
-
const filterEmptyViews = views => {
|
22
|
-
return views.filter(view => dirExists(view));
|
23
|
-
};
|
24
|
-
|
25
|
-
module.exports = async (app, config) => {
|
10
|
+
module.exports = (app, config) => {
|
26
11
|
const viewEngine = config.viewEngine || 'html';
|
27
12
|
|
28
13
|
app.use((req, res, next) => {
|
@@ -32,8 +17,7 @@ module.exports = async (app, config) => {
|
|
32
17
|
|
33
18
|
app.use(config.theme());
|
34
19
|
|
35
|
-
const
|
36
|
-
const viewPaths = [].concat(filteredViews);
|
20
|
+
const viewPaths = [].concat(config.theme.views);
|
37
21
|
app.set('view engine', viewEngine);
|
38
22
|
app.enable('view cache');
|
39
23
|
|
package/middleware/errors.js
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
'use strict';
|
3
3
|
|
4
4
|
const rateLimitsConfig = require('../config/rate-limits');
|
5
|
+
const monitor = require('./monitor');
|
5
6
|
|
6
7
|
const errorTitle = code => `${code}_ERROR`;
|
7
8
|
const errorMsg = code => `There is a ${code}_ERROR`;
|
@@ -89,6 +90,8 @@ module.exports = options => {
|
|
89
90
|
baseUrl: returnBaseUrl(req.path)
|
90
91
|
};
|
91
92
|
|
93
|
+
monitor(req, res, err.status);
|
94
|
+
|
92
95
|
if (logger && logger.error) {
|
93
96
|
logger.error(err.message || err.error, err);
|
94
97
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
'use strict';
|
2
|
+
const Prometheus = require('prom-client');
|
3
|
+
|
4
|
+
let responseTimeInMs = 0;
|
5
|
+
|
6
|
+
const httpRequestDurationMicroseconds = new Prometheus.Histogram({
|
7
|
+
name: 'http_request_duration_ms',
|
8
|
+
help: 'Duration of HTTP requests in ms',
|
9
|
+
labelNames: ['method', 'route', 'code'],
|
10
|
+
buckets: [0.10, 5, 15, 50, 100, 200, 300, 400, 500] // buckets for response time from 0.1ms to 500ms
|
11
|
+
});
|
12
|
+
|
13
|
+
module.exports = function (req, res, status) {
|
14
|
+
const startTime = Date.now();
|
15
|
+
httpRequestDurationMicroseconds
|
16
|
+
.labels(req.method, req.url, status)
|
17
|
+
.observe(responseTimeInMs);
|
18
|
+
const endTime = Date.now();
|
19
|
+
responseTimeInMs = endTime - startTime;
|
20
|
+
};
|
package/middleware/not-found.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
'use strict';
|
2
|
+
const monitor = require('./monitor');
|
2
3
|
|
3
4
|
const getTranslations = translate => {
|
4
5
|
const translations = {
|
@@ -26,6 +27,8 @@ module.exports = options => {
|
|
26
27
|
logger.warn(`Cannot find: ${req.url}`);
|
27
28
|
}
|
28
29
|
|
30
|
+
monitor(req, res, '404');
|
31
|
+
|
29
32
|
res.status(404).render('404', {
|
30
33
|
title: translations.title,
|
31
34
|
description: translations.description,
|
@@ -4,7 +4,6 @@ const redis = require('redis');
|
|
4
4
|
const config = require('./../config/hof-defaults');
|
5
5
|
|
6
6
|
module.exports = (options, rateLimitType) => {
|
7
|
-
// eslint-disable-next-line no-console
|
8
7
|
const logger = options.logger || { log: (func, msg) => console[func](msg) };
|
9
8
|
const rateLimits = options.rateLimits[rateLimitType];
|
10
9
|
const timestampName = `${rateLimitType}TimeStamp`;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "hof",
|
3
3
|
"description": "A bootstrap for HOF projects",
|
4
|
-
"version": "
|
4
|
+
"version": "21.0.0-instrumentation-beta.0",
|
5
5
|
"license": "MIT",
|
6
6
|
"main": "index.js",
|
7
7
|
"author": "HomeOffice",
|
@@ -23,7 +23,7 @@
|
|
23
23
|
"scripts": {
|
24
24
|
"test": "yarn run unit && yarn run test:cookie-banner && yarn run test:functional && yarn run test:client && yarn run test:lint",
|
25
25
|
"unit": "LOG_LEVEL=error nyc _mocha \"test/**/*.spec.js\" \"sandbox/test/**/*.spec.js\"",
|
26
|
-
"unit:nocov": "LOG_LEVEL=error mocha
|
26
|
+
"unit:nocov": "LOG_LEVEL=error mocha",
|
27
27
|
"test:lint": "eslint . --config ./node_modules/eslint-config-hof/default.js",
|
28
28
|
"test:functional": "funkie mocha ./test/functional-tests --exit",
|
29
29
|
"test:client": "karma start test/frontend/toolkit/karma.conf.js",
|
@@ -57,7 +57,6 @@
|
|
57
57
|
"findup": "^0.1.5",
|
58
58
|
"glob": "^7.2.0",
|
59
59
|
"govuk-elements-sass": "^3.1.3",
|
60
|
-
"govuk-frontend": "3.14",
|
61
60
|
"govuk_template_mustache": "^0.26.0",
|
62
61
|
"helmet": "^3.22.0",
|
63
62
|
"hogan-express-strict": "^0.5.4",
|
@@ -72,13 +71,15 @@
|
|
72
71
|
"minimatch": "^3.0.3",
|
73
72
|
"minimist": "^1.2.6",
|
74
73
|
"mixwith": "^0.1.1",
|
75
|
-
"moment": "^2.29.
|
74
|
+
"moment": "^2.29.4",
|
76
75
|
"morgan": "^1.10.0",
|
77
76
|
"mustache": "^2.3.0",
|
78
77
|
"nodemailer": "^6.6.3",
|
79
78
|
"nodemailer-ses-transport": "^1.5.0",
|
80
79
|
"nodemailer-smtp-transport": "^2.7.4",
|
81
80
|
"nodemailer-stub-transport": "^1.1.0",
|
81
|
+
"notifications-node-client": "^5.1.1",
|
82
|
+
"prom-client": "^14.0.1",
|
82
83
|
"redis": "^3.1.2",
|
83
84
|
"reqres": "^3.0.1",
|
84
85
|
"request": "^2.79.0",
|
@@ -8,25 +8,16 @@ module.exports = {
|
|
8
8
|
'landing-page-radio': {
|
9
9
|
mixin: 'radio-group',
|
10
10
|
validate: ['required'],
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
className: ['govuk-radios--inline'],
|
11
|
+
legend: {
|
12
|
+
className: 'visuallyhidden'
|
13
|
+
},
|
15
14
|
options: ['basic-form', 'complex-form', 'build-your-own-form']
|
16
15
|
},
|
17
16
|
name: {
|
18
17
|
validate: ['required', 'notUrl', { type: 'maxlength', arguments: 200 }],
|
19
|
-
// need to remove this for the heading to go
|
20
|
-
labelClassName: ['govuk-label--l'],
|
21
|
-
isPageHeading: 'true'
|
22
18
|
},
|
23
|
-
|
24
|
-
|
25
|
-
validate: [
|
26
|
-
'required',
|
27
|
-
'date',
|
28
|
-
{ type: 'after', arguments: ['1900'] }
|
29
|
-
]
|
19
|
+
dateOfBirth: dateComponent('dateOfBirth', {
|
20
|
+
validate: ['required', 'before', { type: 'after', arguments: ['1900'] }]
|
30
21
|
}),
|
31
22
|
building: {
|
32
23
|
validate: ['required', 'notUrl', { type: 'maxlength', arguments: 100 }]
|
@@ -46,7 +37,6 @@ module.exports = {
|
|
46
37
|
formatter: ['removespaces', 'uppercase']
|
47
38
|
},
|
48
39
|
incomeTypes: {
|
49
|
-
isPageHeading: 'true',
|
50
40
|
mixin: 'checkbox-group',
|
51
41
|
labelClassName: 'visuallyhidden',
|
52
42
|
validate: ['required'],
|
@@ -59,9 +49,11 @@ module.exports = {
|
|
59
49
|
]
|
60
50
|
},
|
61
51
|
countryOfHearing: {
|
62
|
-
isPageHeading: 'true',
|
63
52
|
mixin: 'radio-group',
|
64
53
|
validate: ['required'],
|
54
|
+
legend: {
|
55
|
+
className: 'visuallyhidden'
|
56
|
+
},
|
65
57
|
options: [
|
66
58
|
'englandAndWales',
|
67
59
|
'scotland',
|
@@ -69,8 +61,6 @@ module.exports = {
|
|
69
61
|
]
|
70
62
|
},
|
71
63
|
email: {
|
72
|
-
isPageHeading: 'true',
|
73
|
-
labelClassName: ['govuk-label--l'],
|
74
64
|
validate: ['required', 'email']
|
75
65
|
},
|
76
66
|
phone: {
|
@@ -82,7 +72,6 @@ module.exports = {
|
|
82
72
|
},
|
83
73
|
countrySelect: {
|
84
74
|
mixin: 'select',
|
85
|
-
isPageHeading: 'true',
|
86
75
|
className: ['typeahead'],
|
87
76
|
options:[''].concat(require('homeoffice-countries').allCountries),
|
88
77
|
legend: {
|
@@ -92,15 +81,14 @@ module.exports = {
|
|
92
81
|
},
|
93
82
|
complaintDetails: {
|
94
83
|
mixin: 'textarea',
|
84
|
+
labelClassName: 'visuallyhidden',
|
95
85
|
// we want to ignore default formatters as we want
|
96
86
|
// to preserve white space
|
97
|
-
isPageHeading: 'true',
|
98
87
|
'ignore-defaults': true,
|
99
88
|
// apply the other default formatters
|
100
89
|
formatter: ['trim', 'hyphens'],
|
101
|
-
labelClassName: ['govuk-label--l'],
|
102
90
|
// attributes here are passed to the field element
|
103
|
-
validate: ['required', { type: 'maxlength', arguments:
|
91
|
+
validate: ['required', { type: 'maxlength', arguments: 5000 }],
|
104
92
|
attributes: [{
|
105
93
|
attribute: 'rows',
|
106
94
|
value: 8
|
@@ -108,7 +96,7 @@ module.exports = {
|
|
108
96
|
},
|
109
97
|
appealStages: {
|
110
98
|
mixin: 'select',
|
111
|
-
|
99
|
+
labelClassName: 'visuallyhidden',
|
112
100
|
validate: ['required'],
|
113
101
|
options: [{
|
114
102
|
value: '',
|
@@ -30,11 +30,7 @@ module.exports = {
|
|
30
30
|
},
|
31
31
|
'/dob': {
|
32
32
|
fields: ['dateOfBirth'],
|
33
|
-
next: '/address'
|
34
|
-
locals: {
|
35
|
-
step: 'dob',
|
36
|
-
labelClassName: 'govuk-input'
|
37
|
-
}
|
33
|
+
next: '/address'
|
38
34
|
},
|
39
35
|
'/address': {
|
40
36
|
fields: ['building', 'street', 'townOrCity', 'postcode'],
|
@@ -1,7 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"landing-page-radio": {
|
3
3
|
"legend": "Which form would you like to explore?",
|
4
|
-
"hint": "Choose one of the options below and press continue.",
|
5
4
|
"options": {
|
6
5
|
"basic-form": {
|
7
6
|
"label": "Basic form"
|
@@ -15,10 +14,10 @@
|
|
15
14
|
}
|
16
15
|
},
|
17
16
|
"name": {
|
18
|
-
"label": "
|
17
|
+
"label": "Full name"
|
19
18
|
},
|
20
19
|
"dateOfBirth": {
|
21
|
-
"legend": "
|
20
|
+
"legend": "Date of birth",
|
22
21
|
"hint": "For example, 31 10 1990"
|
23
22
|
},
|
24
23
|
"building": {
|
@@ -56,7 +55,7 @@
|
|
56
55
|
}
|
57
56
|
},
|
58
57
|
"countryOfHearing": {
|
59
|
-
"
|
58
|
+
"label": "Country of hearing",
|
60
59
|
"options": {
|
61
60
|
"englandAndWales": {
|
62
61
|
"label": "England and Wales"
|
@@ -70,7 +69,7 @@
|
|
70
69
|
}
|
71
70
|
},
|
72
71
|
"email" : {
|
73
|
-
"label": "
|
72
|
+
"label": "Email address"
|
74
73
|
},
|
75
74
|
"phone": {
|
76
75
|
"label": "Phone number",
|
@@ -80,16 +79,14 @@
|
|
80
79
|
"legend": "International phone number"
|
81
80
|
},
|
82
81
|
"complaintDetails": {
|
83
|
-
"label": "Complaint details"
|
84
|
-
"hint": "Briefly summarise your complaint. Include anything that can help our investigation."
|
82
|
+
"label": "Complaint details"
|
85
83
|
},
|
86
84
|
"countrySelect": {
|
87
|
-
"label": "
|
85
|
+
"label": "Select a country",
|
88
86
|
"hint": "Start to type the country name and options will appear"
|
89
87
|
},
|
90
88
|
"appealStages": {
|
91
89
|
"label": "Appeal stage",
|
92
|
-
"hint": "Choose an appeal stage from the drop down menu",
|
93
90
|
"options": {
|
94
91
|
"null": "Select..."
|
95
92
|
}
|