@dwp/govuk-casa 8.5.2 → 8.7.0

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.
@@ -91,9 +91,9 @@ export function validateSessionName(name?: string | undefined): string;
91
91
  * Validates and sanitises sessions secure flag.
92
92
  *
93
93
  * @access private
94
- * @param {boolean} [secure=false] Session secure flag.
94
+ * @param {boolean} [secure] Session secure flag.
95
95
  * @throws {ReferenceError} For missing value type.
96
- * @throws {TypeError} For invalid value.
96
+ * @throws {TypeError} For invalid or missing value.
97
97
  * @returns {string} Name.
98
98
  */
99
99
  export function validateSessionSecure(secure?: boolean | undefined): string;
@@ -190,12 +190,15 @@ exports.validateSessionName = validateSessionName;
190
190
  * Validates and sanitises sessions secure flag.
191
191
  *
192
192
  * @access private
193
- * @param {boolean} [secure=false] Session secure flag.
193
+ * @param {boolean} [secure] Session secure flag.
194
194
  * @throws {ReferenceError} For missing value type.
195
- * @throws {TypeError} For invalid value.
195
+ * @throws {TypeError} For invalid or missing value.
196
196
  * @returns {string} Name.
197
197
  */
198
- function validateSessionSecure(secure = false) {
198
+ function validateSessionSecure(secure) {
199
+ if (secure === undefined) {
200
+ throw new Error('Session secure flag must be explicitly defined (session.secure)');
201
+ }
199
202
  if (typeof secure !== 'boolean') {
200
203
  throw new TypeError('Session secure flag must be boolean (session.secure)');
201
204
  }
@@ -3,15 +3,15 @@
3
3
  *
4
4
  * @memberof module:@dwp/govuk-casa
5
5
  * @param {string} name Field name
6
- * @param {object} opts Options
6
+ * @param {object} [opts] Options
7
7
  * @param {boolean} [opts.optional=false] Whether this field is optional
8
8
  * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
9
9
  * @returns {PageField} A PageField
10
10
  */
11
- export default function field(name: string, opts: {
11
+ export default function field(name: string, opts?: {
12
12
  optional?: boolean | undefined;
13
13
  persist?: boolean | undefined;
14
- }): PageField;
14
+ } | undefined): PageField;
15
15
  /**
16
16
  * This class is not exposed via the public API. Instances should instead be
17
17
  * instantiated through the `field()` factory function.
@@ -23,14 +23,14 @@ export class PageField {
23
23
  * Create a field.
24
24
  *
25
25
  * @param {string} name Field name
26
- * @param {object} opts Options
26
+ * @param {object} [opts] Options
27
27
  * @param {boolean} [opts.optional=false] Whether this field is optional
28
28
  * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
29
29
  */
30
30
  constructor(name: string, { optional, persist }?: {
31
31
  optional?: boolean | undefined;
32
32
  persist?: boolean | undefined;
33
- });
33
+ } | undefined);
34
34
  /**
35
35
  * Clone this field.
36
36
  *
@@ -68,32 +68,56 @@ export class PageField {
68
68
  * @throws {SyntaxError} When the name is invalid in some way
69
69
  */
70
70
  rename(name: string): PageField;
71
+ /**
72
+ * Get validators
73
+ *
74
+ * @returns {Validator[]} A list containing all validators.
75
+ */
76
+ getValidators(): Validator[];
71
77
  /**
72
78
  * Add/get value validators
73
79
  * Some validators will include a `sanitise()` method which will be run at the
74
80
  * same time as other "processors".
75
81
  *
76
82
  * @param {Validator[]} items Validation functions
77
- * @returns {PageField | Validator[]} Chain or return all validators
83
+ * @returns {PageField} Chain - Deprecated: this currently gets all validators if
84
+ * empty or missing, in v9 this functionality will removed in favour of the
85
+ * function getValidators().
78
86
  */
79
- validators(items?: Validator[]): PageField | Validator[];
87
+ validators(items?: Validator[]): PageField;
88
+ /**
89
+ * Get processors
90
+ *
91
+ * @returns {FieldProcessorFunction[]} A list containing all processors.
92
+ */
93
+ getProcessors(): FieldProcessorFunction[];
80
94
  /**
81
95
  * Add/get value pre-processors
82
96
  * This is most often used to sanitise values to a particular data type.
83
97
  *
84
98
  * @param {FieldProcessorFunction[]} items Processor functions
85
- * @returns {PageField | FieldProcessorFunction[]} Chain or return all processors
99
+ * @returns {PageField} Chain - Deprecated: this currently gets all processors if
100
+ * empty or missing, in v9 this functionality will removed in favour of the
101
+ * function getProcessors().
102
+ */
103
+ processors(items?: FieldProcessorFunction[]): PageField;
104
+ /**
105
+ * Get conditions
106
+ *
107
+ * @returns {ValidatorConditionFunction[]} A list containing all conditions.
86
108
  */
87
- processors(items?: FieldProcessorFunction[]): PageField | FieldProcessorFunction[];
109
+ getConditions(): ValidatorConditionFunction[];
88
110
  /**
89
111
  * Add/get conditions
90
112
  * All conditions must be met in order for this field to be considered
91
113
  * "actionable".
92
114
  *
93
115
  * @param {ValidatorConditionFunction[]} items Condition functions
94
- * @returns {PageField | ValidatorConditionFunction[]} Chain or return all conditions
116
+ * @returns {PageField} Chain - Deprecated: this currently gets all conditions if
117
+ * empty or missing, in v9 this functionality will removed in favour of the
118
+ * function getConditions().
95
119
  */
96
- conditions(items?: ValidatorConditionFunction[]): PageField | ValidatorConditionFunction[];
120
+ conditions(items?: ValidatorConditionFunction[]): PageField;
97
121
  /**
98
122
  * Run all validators and return array of errors, if applicable.
99
123
  *
package/dist/lib/field.js CHANGED
@@ -18,6 +18,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.PageField = void 0;
19
19
  const lodash_1 = __importDefault(require("lodash"));
20
20
  const utils_js_1 = require("./utils.js");
21
+ const logger_js_1 = __importDefault(require("./logger.js"));
22
+ const log = (0, logger_js_1.default)('lib:field');
21
23
  const { isFunction } = lodash_1.default;
22
24
  /**
23
25
  * @access private
@@ -58,7 +60,7 @@ class PageField {
58
60
  * Create a field.
59
61
  *
60
62
  * @param {string} name Field name
61
- * @param {object} opts Options
63
+ * @param {object} [opts] Options
62
64
  * @param {boolean} [opts.optional=false] Whether this field is optional
63
65
  * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
64
66
  */
@@ -98,6 +100,7 @@ class PageField {
98
100
  complexFieldProperty: undefined,
99
101
  }, "f");
100
102
  // Apply name
103
+ /* eslint-disable-next-line security/detect-non-literal-fs-filename */
101
104
  this.rename(name);
102
105
  }
103
106
  /**
@@ -110,14 +113,14 @@ class PageField {
110
113
  optional: __classPrivateFieldGet(this, _PageField_meta, "f").optional,
111
114
  persist: __classPrivateFieldGet(this, _PageField_meta, "f").persist,
112
115
  });
113
- if (this.validators()) {
114
- clone.validators(this.validators());
116
+ if (this.getValidators()) {
117
+ clone.validators(this.getValidators());
115
118
  }
116
- if (this.conditions()) {
117
- clone.conditions(this.conditions());
119
+ if (this.getConditions()) {
120
+ clone.conditions(this.getConditions());
118
121
  }
119
- if (this.processors()) {
120
- clone.processors(this.processors());
122
+ if (this.getProcessors()) {
123
+ clone.processors(this.getProcessors());
121
124
  }
122
125
  return clone;
123
126
  }
@@ -193,46 +196,79 @@ class PageField {
193
196
  }
194
197
  return this;
195
198
  }
199
+ /**
200
+ * Get validators
201
+ *
202
+ * @returns {Validator[]} A list containing all validators.
203
+ */
204
+ getValidators() {
205
+ return __classPrivateFieldGet(this, _PageField_validators, "f");
206
+ }
196
207
  /**
197
208
  * Add/get value validators
198
209
  * Some validators will include a `sanitise()` method which will be run at the
199
210
  * same time as other "processors".
200
211
  *
201
212
  * @param {Validator[]} items Validation functions
202
- * @returns {PageField | Validator[]} Chain or return all validators
213
+ * @returns {PageField} Chain - Deprecated: this currently gets all validators if
214
+ * empty or missing, in v9 this functionality will removed in favour of the
215
+ * function getValidators().
203
216
  */
204
217
  validators(items = []) {
205
218
  if (!items.length) {
206
- return __classPrivateFieldGet(this, _PageField_validators, "f");
219
+ log.warn('Calling validators() to get all validators is deprecated, please use getValidators()');
220
+ return this.getValidators();
207
221
  }
208
222
  __classPrivateFieldSet(this, _PageField_validators, [...__classPrivateFieldGet(this, _PageField_validators, "f"), ...(items.flat())], "f");
209
223
  return this;
210
224
  }
225
+ /**
226
+ * Get processors
227
+ *
228
+ * @returns {FieldProcessorFunction[]} A list containing all processors.
229
+ */
230
+ getProcessors() {
231
+ return __classPrivateFieldGet(this, _PageField_processors, "f");
232
+ }
211
233
  /**
212
234
  * Add/get value pre-processors
213
235
  * This is most often used to sanitise values to a particular data type.
214
236
  *
215
237
  * @param {FieldProcessorFunction[]} items Processor functions
216
- * @returns {PageField | FieldProcessorFunction[]} Chain or return all processors
238
+ * @returns {PageField} Chain - Deprecated: this currently gets all processors if
239
+ * empty or missing, in v9 this functionality will removed in favour of the
240
+ * function getProcessors().
217
241
  */
218
242
  processors(items = []) {
219
243
  if (!items.length) {
220
- return __classPrivateFieldGet(this, _PageField_processors, "f");
244
+ log.warn('Calling processors() to get all processors is deprecated, please use getProcessors()');
245
+ return this.getProcessors();
221
246
  }
222
247
  __classPrivateFieldSet(this, _PageField_processors, [...__classPrivateFieldGet(this, _PageField_processors, "f"), ...(items.flat())], "f");
223
248
  return this;
224
249
  }
250
+ /**
251
+ * Get conditions
252
+ *
253
+ * @returns {ValidatorConditionFunction[]} A list containing all conditions.
254
+ */
255
+ getConditions() {
256
+ return __classPrivateFieldGet(this, _PageField_conditions, "f");
257
+ }
225
258
  /**
226
259
  * Add/get conditions
227
260
  * All conditions must be met in order for this field to be considered
228
261
  * "actionable".
229
262
  *
230
263
  * @param {ValidatorConditionFunction[]} items Condition functions
231
- * @returns {PageField | ValidatorConditionFunction[]} Chain or return all conditions
264
+ * @returns {PageField} Chain - Deprecated: this currently gets all conditions if
265
+ * empty or missing, in v9 this functionality will removed in favour of the
266
+ * function getConditions().
232
267
  */
233
268
  conditions(items = []) {
234
269
  if (!items.length) {
235
- return __classPrivateFieldGet(this, _PageField_conditions, "f");
270
+ log.warn('Calling conditions() to get all conditions is deprecated, please use getConditions()');
271
+ return this.getConditions();
236
272
  }
237
273
  __classPrivateFieldSet(this, _PageField_conditions, [...__classPrivateFieldGet(this, _PageField_conditions, "f"), ...(items.flat())], "f");
238
274
  return this;
@@ -361,7 +397,7 @@ class PageField {
361
397
  * @returns {PageField} Chain
362
398
  */
363
399
  if(...args) {
364
- return this.conditions(...args);
400
+ return this.conditions(args);
365
401
  }
366
402
  }
367
403
  exports.PageField = PageField;
@@ -371,7 +407,7 @@ _PageField_name = new WeakMap(), _PageField_processors = new WeakMap(), _PageFie
371
407
  *
372
408
  * @memberof module:@dwp/govuk-casa
373
409
  * @param {string} name Field name
374
- * @param {object} opts Options
410
+ * @param {object} [opts] Options
375
411
  * @param {boolean} [opts.optional=false] Whether this field is optional
376
412
  * @param {boolean} [opts.persist=true] Whether this field will persist in `req.body`
377
413
  * @returns {PageField} A PageField
@@ -9,25 +9,24 @@
9
9
  * edit: true,
10
10
  * editOrigin: '/somewhere/else'
11
11
  * })
12
- *
13
12
  * @memberof module:@dwp/govuk-casa
14
13
  * @param {object} obj Options
15
- * @param {string} obj.waypoint Waypoint
16
- * @param {string} obj.mountUrl Mount URL
17
- * @param {JourneyContext} obj.journeyContext JourneyContext
18
- * @param {boolean} obj.edit Turn edit mode on or off
19
- * @param {string} obj.editOrigin Edit mode original URL
20
- * @param {boolean} obj.skipTo Skip to this waypoint from the current one
21
- * @param {string} obj.routeName Plan route name; next | prev
14
+ * @param {string} [obj.waypoint=""] Waypoint
15
+ * @param {string} [obj.mountUrl="/"] Mount URL
16
+ * @param {JourneyContext} [obj.journeyContext] JourneyContext
17
+ * @param {boolean} [obj.edit=false] Turn edit mode on or off
18
+ * @param {string} [obj.editOrigin] Edit mode original URL
19
+ * @param {boolean} [obj.skipTo] Skip to this waypoint from the current one
20
+ * @param {string} [obj.routeName=next] Plan route name; next | prev
22
21
  * @returns {string} URL
23
22
  */
24
23
  export default function waypointUrl({ waypoint, mountUrl, journeyContext, edit, editOrigin, skipTo, routeName, }?: {
25
- waypoint: string;
26
- mountUrl: string;
27
- journeyContext: JourneyContext;
28
- edit: boolean;
29
- editOrigin: string;
30
- skipTo: boolean;
31
- routeName: string;
24
+ waypoint?: string | undefined;
25
+ mountUrl?: string | undefined;
26
+ journeyContext?: import("./JourneyContext").default | undefined;
27
+ edit?: boolean | undefined;
28
+ editOrigin?: string | undefined;
29
+ skipTo?: boolean | undefined;
30
+ routeName?: string | undefined;
32
31
  }): string;
33
32
  export type JourneyContext = import('./index').JourneyContext;
@@ -25,16 +25,15 @@ const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g,
25
25
  * edit: true,
26
26
  * editOrigin: '/somewhere/else'
27
27
  * })
28
- *
29
28
  * @memberof module:@dwp/govuk-casa
30
29
  * @param {object} obj Options
31
- * @param {string} obj.waypoint Waypoint
32
- * @param {string} obj.mountUrl Mount URL
33
- * @param {JourneyContext} obj.journeyContext JourneyContext
34
- * @param {boolean} obj.edit Turn edit mode on or off
35
- * @param {string} obj.editOrigin Edit mode original URL
36
- * @param {boolean} obj.skipTo Skip to this waypoint from the current one
37
- * @param {string} obj.routeName Plan route name; next | prev
30
+ * @param {string} [obj.waypoint=""] Waypoint
31
+ * @param {string} [obj.mountUrl="/"] Mount URL
32
+ * @param {JourneyContext} [obj.journeyContext] JourneyContext
33
+ * @param {boolean} [obj.edit=false] Turn edit mode on or off
34
+ * @param {string} [obj.editOrigin] Edit mode original URL
35
+ * @param {boolean} [obj.skipTo] Skip to this waypoint from the current one
36
+ * @param {string} [obj.routeName=next] Plan route name; next | prev
38
37
  * @returns {string} URL
39
38
  */
40
39
  function waypointUrl({ waypoint = '', mountUrl = '/', journeyContext, edit = false, editOrigin, skipTo, routeName = 'next', } = Object.create(null)) {
@@ -20,4 +20,4 @@
20
20
  }
21
21
  }
22
22
  }
23
- }
23
+ }
@@ -12,4 +12,4 @@
12
12
  "address4": "Sir",
13
13
  "postcode": "Cod post"
14
14
  }
15
- }
15
+ }
@@ -5,4 +5,4 @@
5
5
  "containsErrors": "Mae'r dudalen hon yn cynnwys gwallau",
6
6
  "changeLink": "Newid"
7
7
  }
8
- }
8
+ }
@@ -78,4 +78,4 @@
78
78
  }
79
79
  }
80
80
  }
81
- }
81
+ }
@@ -20,4 +20,4 @@
20
20
  }
21
21
  }
22
22
  }
23
- }
23
+ }
@@ -5,4 +5,4 @@
5
5
  "containsErrors": "This page contains errors",
6
6
  "changeLink": "Change"
7
7
  }
8
- }
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwp/govuk-casa",
3
- "version": "8.5.2",
3
+ "version": "8.7.0",
4
4
  "description": "A framework for building GOVUK Collect-And-Submit-Applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,23 +19,28 @@
19
19
  "views/**/*"
20
20
  ],
21
21
  "engines": {
22
- "node": ">=14.17.2"
22
+ "node": "^14.0.0 || ^16.0.0 || ^18.0.0",
23
+ "npm": "^8.0.0"
23
24
  },
24
25
  "scripts": {
25
26
  "pipeline": "npm run coverage && npm run lint",
27
+ "coverage": "c8 npm test",
28
+ "test": "npm run test:unit && npm run test:e2e",
26
29
  "test:unit": "mocha './tests/**/*.test.js'",
27
30
  "test:e2e": "spiderplan --worker-init ./tests/e2e/worker-init.js --language en ./tests/e2e/personas/**/*.yaml",
28
- "test": "npm run test:unit && npm run test:e2e",
31
+ "test:dast": "spiderplan --worker-init ./tests/e2e/worker-init.js --language en ./tests/e2e/personas/**/traversal.yaml --workers 1 --zap --zap-proxy 'http://localhost:8080/' --zap-target-hostname 'host.docker.internal'",
32
+ "test:dast:report": "curl -s --header 'X-ZAP-Api-Key: secret' http://localhost:8080/OTHER/core/other/htmlreport > gl-dast-report.html",
33
+ "test:dast:setup": "docker run --rm --name casa-dast -d -u zap -p 8080:8080 -i owasp/zap2docker-stable zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.addrs.addr.name=\".*\" -config api.addrs.addr.regex=true -config api.key=secret; npm run test:dast:ready-check",
34
+ "test:dast:ready-check": "while [ \"$(curl -Is -o /dev/null -w %{response_code} http://localhost:8080/)\" -ne \"200\" ]; do sleep 1; echo 'Waiting for ZAP to start ...'; done",
35
+ "test:dast:teardown": "docker stop casa-dast",
29
36
  "lint": "eslint .",
30
- "coverage": "c8 npm test",
31
37
  "build": "npm run build:prepare && npm run build:sources && npm run build:css-assets",
32
38
  "build:prepare": "rm -rf dist/* && mkdir -p dist/assets/js/ && mkdir -p dist/assets/css/",
33
39
  "build:sources": "tsc -p tsconfig-cjs.json && ./scripts/fixup.sh",
34
40
  "build:css-assets": "node scripts/compile-sass.js",
35
41
  "build:api-docs": "npx jsdoc -c ./jsdoc.json -d ./docs/api/ --debug -P '' -r -R ./README.md --verbose -t ./node_modules/docdash ./src",
36
42
  "prepare": "npm run build",
37
- "upgrade-deps": "OD=$(npm outdated --long --parseable); echo \"$OD\" | grep ':devDependencies:' | awk -F: '{ print $4 }' | xargs npm i -DE; echo \"$OD\" | grep ':dependencies:' | awk -F: '{ print $4 }' | xargs npm i -E",
38
- "standard-version": "node scripts/standard-version.js"
43
+ "upgrade-deps": "OD=$(npm outdated --long --parseable); echo \"$OD\" | grep ':devDependencies:' | awk -F: '{ print $4 }' | xargs npm i -DE; echo \"$OD\" | grep ':dependencies:' | awk -F: '{ print $4 }' | xargs npm i -E"
39
44
  },
40
45
  "keywords": [],
41
46
  "author": "DWP Digital",
@@ -48,52 +53,49 @@
48
53
  "deepmerge": "4.2.2",
49
54
  "express": "4.18.2",
50
55
  "express-session": "1.17.3",
51
- "govuk-frontend": "4.3.1",
56
+ "govuk-frontend": "4.4.0",
52
57
  "graphlib": "2.1.8",
53
- "helmet": "5.1.1",
54
- "i18next": "21.10.0",
58
+ "helmet": "6.0.0",
59
+ "i18next": "22.0.6",
55
60
  "i18next-http-middleware": "3.2.1",
56
61
  "js-yaml": "4.1.0",
57
62
  "lodash": "4.17.21",
58
- "luxon": "2.5.0",
63
+ "luxon": "3.1.0",
59
64
  "nunjucks": "3.2.3",
60
65
  "path-to-regexp": "6.2.1",
61
- "uuid": "8.3.2",
66
+ "uuid": "9.0.0",
62
67
  "validator": "13.7.0"
63
68
  },
64
69
  "devDependencies": {
65
- "@babel/core": "7.19.6",
70
+ "@babel/core": "7.20.2",
66
71
  "@babel/eslint-parser": "7.19.1",
67
- "@babel/preset-env": "7.19.4",
68
- "@ckeditor/jsdoc-plugins": "30.5.0",
69
- "@commitlint/config-conventional": "17.1.0",
70
- "@dwp/casa-spiderplan": "2.4.1",
71
- "@dwp/casa-spiderplan-a11y-plugin": "0.1.4",
72
+ "@babel/preset-env": "7.20.2",
73
+ "@ckeditor/jsdoc-plugins": "31.1.9",
74
+ "@commitlint/config-conventional": "17.3.0",
75
+ "@dwp/casa-spiderplan": "2.5.1",
76
+ "@dwp/casa-spiderplan-a11y-plugin": "0.1.5",
72
77
  "@dwp/casa-spiderplan-zap-plugin": "0.1.1",
73
78
  "@dwp/eslint-config-base": "6.0.0",
74
79
  "@types/express": "4.17.14",
75
- "@types/node": "18.11.8",
80
+ "@types/node": "18.11.9",
76
81
  "@types/nunjucks": "3.2.1",
77
- "babel-eslint": "10.1.0",
78
82
  "c8": "7.12.0",
79
- "chai": "4.3.6",
83
+ "chai": "4.3.7",
80
84
  "cheerio": "1.0.0-rc.12",
81
- "commitlint": "17.1.2",
82
- "docdash": "1.2.0",
83
- "eslint": "8.26.0",
85
+ "commitlint": "17.3.0",
86
+ "docdash": "2.0.0",
87
+ "eslint": "8.28.0",
84
88
  "eslint-plugin-no-unsafe-regex": "1.0.0",
85
89
  "eslint-plugin-security": "1.5.0",
86
90
  "eslint-plugin-sonarjs": "0.16.0",
87
91
  "fast-check": "3.3.0",
88
- "husky": "8.0.1",
89
- "jsdoc": "3.6.11",
92
+ "jsdoc": "4.0.0",
90
93
  "jsdoc-tsimport-plugin": "1.0.5",
91
94
  "mocha": "10.1.0",
92
- "sass": "1.55.0",
93
- "sinon": "14.0.1",
95
+ "sass": "1.56.1",
96
+ "sinon": "14.0.2",
94
97
  "sinon-chai": "3.7.0",
95
- "standard-version": "9.5.0",
96
98
  "supertest": "6.3.1",
97
- "typescript": "4.8.4"
99
+ "typescript": "4.9.3"
98
100
  }
99
101
  }
@@ -99,4 +99,4 @@ You can also pass a locale:
99
99
  ```
100
100
  ```
101
101
  1 Ionawr 1980
102
- ```
102
+ ```
@@ -46,4 +46,4 @@
46
46
  }) %}
47
47
  {% block journey_form %}{% endblock %}
48
48
  {% endcall %}
49
- {% endblock %}
49
+ {% endblock %}