@dwp/govuk-casa 9.3.5 → 9.4.1
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/dist/casa.d.ts +2 -1
- package/dist/casa.js +20 -8
- package/dist/casa.js.map +1 -1
- package/dist/core-plugins/edit-snapshot/src/configure.d.ts +6 -0
- package/dist/core-plugins/edit-snapshot/src/configure.js +30 -0
- package/dist/core-plugins/edit-snapshot/src/configure.js.map +1 -0
- package/dist/core-plugins/edit-snapshot/src/index.d.ts +5 -0
- package/dist/core-plugins/edit-snapshot/src/index.js +12 -0
- package/dist/core-plugins/edit-snapshot/src/index.js.map +1 -0
- package/dist/core-plugins/edit-snapshot/src/post-steer-hook.d.ts +2 -0
- package/dist/core-plugins/edit-snapshot/src/post-steer-hook.js +23 -0
- package/dist/core-plugins/edit-snapshot/src/post-steer-hook.js.map +1 -0
- package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.d.ts +2 -0
- package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.js +33 -0
- package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.js.map +1 -0
- package/dist/core-plugins/edit-snapshot/src/utils.d.ts +6 -0
- package/dist/core-plugins/edit-snapshot/src/utils.js +38 -0
- package/dist/core-plugins/edit-snapshot/src/utils.js.map +1 -0
- package/dist/core-plugins/index.d.ts +1 -0
- package/dist/core-plugins/index.js +10 -0
- package/dist/core-plugins/index.js.map +1 -0
- package/dist/lib/CasaTemplateLoader.js +0 -1
- package/dist/lib/CasaTemplateLoader.js.map +1 -1
- package/dist/lib/JourneyContext.d.ts +11 -6
- package/dist/lib/JourneyContext.js +17 -9
- package/dist/lib/JourneyContext.js.map +1 -1
- package/dist/lib/MutableRouter.d.ts +1 -1
- package/dist/lib/MutableRouter.js +0 -1
- package/dist/lib/MutableRouter.js.map +1 -1
- package/dist/lib/Plan.d.ts +3 -3
- package/dist/lib/ValidationError.d.ts +1 -1
- package/dist/lib/ValidationError.js +1 -1
- package/dist/lib/ValidatorFactory.js +0 -3
- package/dist/lib/ValidatorFactory.js.map +1 -1
- package/dist/lib/configuration-ingestor.d.ts +75 -14
- package/dist/lib/configuration-ingestor.js +119 -26
- package/dist/lib/configuration-ingestor.js.map +1 -1
- package/dist/lib/configure.js.map +1 -1
- package/dist/lib/context-id-generators.js +1 -1
- package/dist/lib/context-id-generators.js.map +1 -1
- package/dist/lib/field.d.ts +8 -8
- package/dist/lib/field.js +6 -10
- package/dist/lib/field.js.map +1 -1
- package/dist/lib/index.js +17 -7
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/nunjucks-filters.d.ts +5 -1
- package/dist/lib/nunjucks-filters.js +13 -1
- package/dist/lib/nunjucks-filters.js.map +1 -1
- package/dist/lib/utils.js +8 -5
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/validators/dateObject.d.ts +1 -1
- package/dist/lib/validators/dateObject.js +0 -2
- package/dist/lib/validators/dateObject.js.map +1 -1
- package/dist/lib/validators/email.js +1 -2
- package/dist/lib/validators/email.js.map +1 -1
- package/dist/lib/validators/inArray.js +0 -1
- package/dist/lib/validators/inArray.js.map +1 -1
- package/dist/lib/validators/nino.js +0 -1
- package/dist/lib/validators/nino.js.map +1 -1
- package/dist/lib/validators/postalAddressObject.js +5 -5
- package/dist/lib/validators/postalAddressObject.js.map +1 -1
- package/dist/lib/validators/range.js +0 -1
- package/dist/lib/validators/range.js.map +1 -1
- package/dist/lib/validators/regex.js +0 -1
- package/dist/lib/validators/regex.js.map +1 -1
- package/dist/lib/validators/required.js +0 -1
- package/dist/lib/validators/required.js.map +1 -1
- package/dist/lib/validators/strlen.js +0 -1
- package/dist/lib/validators/strlen.js.map +1 -1
- package/dist/lib/validators/wordCount.js +0 -1
- package/dist/lib/validators/wordCount.js.map +1 -1
- package/dist/lib/waypoint-url.d.ts +4 -5
- package/dist/lib/waypoint-url.js +4 -5
- package/dist/lib/waypoint-url.js.map +1 -1
- package/dist/middleware/body-parser.d.ts +26 -4
- package/dist/middleware/body-parser.js +31 -0
- package/dist/middleware/body-parser.js.map +1 -1
- package/dist/middleware/csrf.d.ts +15 -1
- package/dist/middleware/csrf.js +13 -3
- package/dist/middleware/csrf.js.map +1 -1
- package/dist/middleware/data.d.ts +21 -4
- package/dist/middleware/data.js +33 -4
- package/dist/middleware/data.js.map +1 -1
- package/dist/middleware/gather-fields.js +1 -1
- package/dist/middleware/i18n.d.ts +11 -2
- package/dist/middleware/i18n.js +14 -3
- package/dist/middleware/i18n.js.map +1 -1
- package/dist/middleware/post.d.ts +3 -1
- package/dist/middleware/post.js +5 -0
- package/dist/middleware/post.js.map +1 -1
- package/dist/middleware/session.d.ts +27 -8
- package/dist/middleware/session.js +39 -12
- package/dist/middleware/session.js.map +1 -1
- package/dist/mjs/esm-wrapper.js +1 -0
- package/dist/routes/journey.js +2 -3
- package/dist/routes/journey.js.map +1 -1
- package/package.json +33 -33
- package/src/casa.js +4 -0
- package/src/core-plugins/edit-snapshot/src/configure.js +30 -0
- package/src/core-plugins/edit-snapshot/src/index.js +7 -0
- package/src/core-plugins/edit-snapshot/src/post-steer-hook.js +22 -0
- package/src/core-plugins/edit-snapshot/src/pre-steer-hook.js +43 -0
- package/src/core-plugins/edit-snapshot/src/utils.js +53 -0
- package/src/core-plugins/index.js +2 -0
- package/src/lib/CasaTemplateLoader.js +0 -1
- package/src/lib/JourneyContext.js +23 -11
- package/src/lib/MutableRouter.js +0 -1
- package/src/lib/ValidationError.js +1 -1
- package/src/lib/ValidatorFactory.js +0 -3
- package/src/lib/configuration-ingestor.js +116 -19
- package/src/lib/configure.js +2 -2
- package/src/lib/context-id-generators.js +1 -1
- package/src/lib/field.js +7 -10
- package/src/lib/nunjucks-filters.js +15 -1
- package/src/lib/utils.js +9 -5
- package/src/lib/validators/dateObject.js +1 -2
- package/src/lib/validators/email.js +1 -2
- package/src/lib/validators/inArray.js +0 -1
- package/src/lib/validators/nino.js +0 -1
- package/src/lib/validators/postalAddressObject.js +5 -5
- package/src/lib/validators/range.js +0 -2
- package/src/lib/validators/regex.js +0 -1
- package/src/lib/validators/required.js +0 -1
- package/src/lib/validators/strlen.js +0 -1
- package/src/lib/validators/wordCount.js +0 -1
- package/src/lib/waypoint-url.js +4 -5
- package/src/middleware/body-parser.js +34 -0
- package/src/middleware/csrf.js +13 -3
- package/src/middleware/data.js +37 -5
- package/src/middleware/gather-fields.js +1 -1
- package/src/middleware/i18n.js +15 -3
- package/src/middleware/post.js +6 -0
- package/src/middleware/session.js +24 -5
- package/src/routes/journey.js +6 -4
|
@@ -12,9 +12,10 @@ const combineMerge = (target, source, options) => {
|
|
|
12
12
|
const destination = target.slice();
|
|
13
13
|
|
|
14
14
|
for (let index = 0; index < source.length; index++) {
|
|
15
|
-
const item = source[index];
|
|
16
15
|
// ESLint disabled as `index` is only an integer
|
|
17
16
|
/* eslint-disable security/detect-object-injection */
|
|
17
|
+
const item = source[index];
|
|
18
|
+
|
|
18
19
|
if (typeof destination[index] === "undefined") {
|
|
19
20
|
destination[index] = options.cloneUnlessOtherwiseSpecified(item, options);
|
|
20
21
|
} else if (options.isMergeableObject(item)) {
|
|
@@ -30,10 +31,18 @@ const combineMerge = (target, source, options) => {
|
|
|
30
31
|
// Allows objects to be deepmerged and retain their type, without becoming [object Object]
|
|
31
32
|
// ref: https://github.com/jonschlinkert/is-plain-object/blob/master/is-plain-object.js
|
|
32
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @param {any} o Value to test
|
|
36
|
+
* @returns {boolean} True if an object
|
|
37
|
+
*/
|
|
33
38
|
function isObject(o) {
|
|
34
39
|
return Object.prototype.toString.call(o) === "[object Object]";
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @param {any} o Value to test
|
|
44
|
+
* @returns {boolean} True if a plain object or array
|
|
45
|
+
*/
|
|
37
46
|
function isPlainObjectOrArray(o) {
|
|
38
47
|
if (Array.isArray(o)) {
|
|
39
48
|
return true;
|
|
@@ -52,12 +61,17 @@ function isPlainObjectOrArray(o) {
|
|
|
52
61
|
return Object.hasOwn(prot, "isPrototypeOf");
|
|
53
62
|
}
|
|
54
63
|
|
|
64
|
+
/**
|
|
65
|
+
* @param {...any} objects Objects to merge
|
|
66
|
+
* @returns {object} Merged object
|
|
67
|
+
*/
|
|
55
68
|
function mergeObjects(...objects) {
|
|
56
69
|
return deepmergeAll([Object.create(null), ...objects], {
|
|
57
70
|
arrayMerge: combineMerge,
|
|
58
71
|
isMergeableObject: isPlainObjectOrArray,
|
|
59
72
|
});
|
|
60
73
|
}
|
|
74
|
+
|
|
61
75
|
/**
|
|
62
76
|
* Determine whether a value exists in a list.
|
|
63
77
|
*
|
package/src/lib/utils.js
CHANGED
|
@@ -48,7 +48,6 @@ export function isStringable(value) {
|
|
|
48
48
|
* @access private
|
|
49
49
|
*/
|
|
50
50
|
export function resolveMiddlewareHooks(hookName, path, hooks = []) {
|
|
51
|
-
/* eslint-disable-next-line max-len */
|
|
52
51
|
const pathMatch = (h) =>
|
|
53
52
|
h.path === undefined ||
|
|
54
53
|
(h.path instanceof RegExp && h.path.test(path)) ||
|
|
@@ -119,10 +118,15 @@ export function stripWhitespace(value, options) {
|
|
|
119
118
|
throw new TypeError("nested must be a string");
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
// This approach avoids using `/s+$/` regex, which triggers the
|
|
122
|
+
// `sonarjs/slow-regex` eslint rule
|
|
123
|
+
let newValue = value.replace(/^\s+/, opts.leading);
|
|
124
|
+
if (newValue.match(/\s$/)) {
|
|
125
|
+
newValue = `${newValue.trimEnd()}${opts.trailing}`;
|
|
126
|
+
}
|
|
127
|
+
newValue = newValue.replace(/\s+/g, opts.nested);
|
|
128
|
+
|
|
129
|
+
return newValue;
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
/* ------------------------------------------------ validation / sanitisation */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable class-methods-use-this */
|
|
2
1
|
import { DateTime } from "luxon";
|
|
3
2
|
import lodash from "lodash";
|
|
4
3
|
import ValidationError from "../ValidationError.js";
|
|
@@ -102,7 +101,7 @@ export default class DateObject extends ValidatorFactory {
|
|
|
102
101
|
if (test.flags.every((v) => v === true)) {
|
|
103
102
|
formats = [...formats, ...test.formats];
|
|
104
103
|
}
|
|
105
|
-
}
|
|
104
|
+
}
|
|
106
105
|
|
|
107
106
|
if (typeof value === "object") {
|
|
108
107
|
formats.find((format) => {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable class-methods-use-this */
|
|
2
1
|
import validatorPkg from "validator";
|
|
3
2
|
import ValidationError from "../ValidationError.js";
|
|
4
3
|
import ValidatorFactory from "../ValidatorFactory.js";
|
|
@@ -34,7 +33,7 @@ export default class Email extends ValidatorFactory {
|
|
|
34
33
|
let isValid;
|
|
35
34
|
try {
|
|
36
35
|
isValid = isEmail(value);
|
|
37
|
-
} catch
|
|
36
|
+
} catch {
|
|
38
37
|
isValid = false;
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable class-methods-use-this */
|
|
2
1
|
import lodash from "lodash";
|
|
3
2
|
import ValidationError from "../ValidationError.js";
|
|
4
3
|
import ValidatorFactory from "../ValidatorFactory.js";
|
|
@@ -83,7 +82,6 @@ export default class PostalAddressObject extends ValidatorFactory {
|
|
|
83
82
|
...this.config,
|
|
84
83
|
};
|
|
85
84
|
|
|
86
|
-
/* eslint-disable-next-line require-jsdoc */
|
|
87
85
|
const objectifyError = (err) =>
|
|
88
86
|
typeof err === "string"
|
|
89
87
|
? {
|
|
@@ -105,12 +103,14 @@ export default class PostalAddressObject extends ValidatorFactory {
|
|
|
105
103
|
const errorMsgs = [];
|
|
106
104
|
|
|
107
105
|
if (typeof value === "object") {
|
|
108
|
-
const reAddr = /^[
|
|
109
|
-
const reAddrLine1 =
|
|
106
|
+
const reAddr = /^[a-z0-9\-,.&#()/\\:;'" ]{2,}$/i;
|
|
107
|
+
const reAddrLine1 = /^(\d+|[a-z0-9\-,.&#()/\\:;'" ]{2,})$/i;
|
|
110
108
|
// UK Postcode regex taken from the dwp java pc checker
|
|
111
109
|
// https://github.com/dwp/postcode-format-validation
|
|
110
|
+
/* eslint-disable sonarjs/regex-complexity */
|
|
112
111
|
const rePostcode =
|
|
113
|
-
/^(?![QVX])[A-Z]((?![IJZ])[A-Z]
|
|
112
|
+
/^(?![QVX])[A-Z]((?![IJZ])[A-Z]\d((\d?)|([ABEHMNPRVWXY]?))|(\d(\d?|[ABCDEFGHJKPSTUW]?))) ?\d((?![CIKMOV])[A-Z]){2}$|^(BFPO) ?\d{1,4}$/i;
|
|
113
|
+
/* eslint-enable sonarjs/regex-complexity */
|
|
114
114
|
|
|
115
115
|
// [required, regex, strlenmax, error message]
|
|
116
116
|
const attributes = {
|
package/src/lib/waypoint-url.js
CHANGED
|
@@ -61,14 +61,13 @@ const sanitiseWaypointWithAllowedParams = (w) => {
|
|
|
61
61
|
* });
|
|
62
62
|
*
|
|
63
63
|
* @param {object} obj Options
|
|
64
|
-
* @param {string} [obj.waypoint
|
|
65
|
-
* @param {string} [obj.mountUrl
|
|
64
|
+
* @param {string} [obj.waypoint] Waypoint. Default is `""`
|
|
65
|
+
* @param {string} [obj.mountUrl] Mount URL. Default is `"/"`
|
|
66
66
|
* @param {JourneyContext} [obj.journeyContext] JourneyContext
|
|
67
|
-
* @param {boolean} [obj.edit
|
|
68
|
-
* `false`
|
|
67
|
+
* @param {boolean} [obj.edit] Turn edit mode on or off. Default is `false`
|
|
69
68
|
* @param {string} [obj.editOrigin] Edit mode original URL
|
|
70
69
|
* @param {boolean} [obj.skipTo] Skip to this waypoint from the current one
|
|
71
|
-
* @param {string} [obj.routeName
|
|
70
|
+
* @param {string} [obj.routeName] Plan route name; next | prev. Default is
|
|
72
71
|
* `next`
|
|
73
72
|
* @returns {string} URL
|
|
74
73
|
*/
|
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { urlencoded as expressBodyParser } from "express";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
5
|
+
* @access private
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import("express").Request} Request
|
|
10
|
+
* @access private
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import("express").Response} Response
|
|
15
|
+
* @access private
|
|
16
|
+
*/
|
|
17
|
+
|
|
3
18
|
const rProto = /__proto__/i;
|
|
4
19
|
const rPrototype = /prototype[='"[\]]/i;
|
|
5
20
|
const rConstructor = /constructor[='"[\]]/i;
|
|
6
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Verify request body.
|
|
24
|
+
*
|
|
25
|
+
* @param {Request} req HTTP request
|
|
26
|
+
* @param {Response} res HTTP response
|
|
27
|
+
* @param {Buffer} buf Buffer
|
|
28
|
+
* @param {string} encoding Character encoding
|
|
29
|
+
* @returns {void}
|
|
30
|
+
* @throws {Error} For invalid bodies
|
|
31
|
+
*/
|
|
7
32
|
export function verifyBody(req, res, buf, encoding) {
|
|
8
33
|
const body = decodeURI(buf.toString(encoding)).replace(
|
|
9
34
|
/[\s\u200B-\u200D\uFEFF]/g,
|
|
@@ -20,6 +45,15 @@ export function verifyBody(req, res, buf, encoding) {
|
|
|
20
45
|
}
|
|
21
46
|
}
|
|
22
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Body parsing middleware.
|
|
50
|
+
*
|
|
51
|
+
* @param {object} opts Options
|
|
52
|
+
* @param {number} opts.formMaxParams Max number of parameters that should be
|
|
53
|
+
* parsed
|
|
54
|
+
* @param {number} opts.formMaxBytes Max bytes that should be read
|
|
55
|
+
* @returns {RequestHandler[]} Middleware functions
|
|
56
|
+
*/
|
|
23
57
|
export default function bodyParserMiddleware({ formMaxParams, formMaxBytes }) {
|
|
24
58
|
return [
|
|
25
59
|
expressBodyParser({
|
package/src/middleware/csrf.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { csrfSync } from "csrf-sync";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
5
|
+
* @access private
|
|
6
|
+
*/
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Data middleware.
|
|
10
|
+
*
|
|
11
|
+
* 2 middleware: one to generate the csrf token and check its validity (POST
|
|
12
|
+
* only), and one to provide that token to templates via the `casa.csrfToken`
|
|
13
|
+
* variable.
|
|
14
|
+
*
|
|
15
|
+
* @returns {RequestHandler[]} Middleware functions
|
|
16
|
+
*/
|
|
7
17
|
export default function csrfMiddleware() {
|
|
8
18
|
const { csrfSynchronisedProtection } = csrfSync({
|
|
9
19
|
getTokenFromRequest: (req) => req.body._csrf,
|
package/src/middleware/data.js
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
// Decorates the request with some contextual data about the user's journey
|
|
2
|
-
// through the application. This is used by downstream middleware and templates.
|
|
3
|
-
|
|
4
1
|
import JourneyContext from "../lib/JourneyContext.js";
|
|
5
2
|
import { validateUrlPath } from "../lib/utils.js";
|
|
6
3
|
import waypointUrl from "../lib/waypoint-url.js";
|
|
7
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
7
|
+
* @access private
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import("../casa.js").Plan} Plan
|
|
12
|
+
* @access private
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {import("../casa.js").ContextEventHandler} ContextEventHandler
|
|
17
|
+
* @access private
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {import("../casa.js").ContextIdGenerator} ContextIdGenerator
|
|
22
|
+
* @access private
|
|
23
|
+
*/
|
|
24
|
+
|
|
8
25
|
const editOrigin = (req) => {
|
|
9
26
|
if (Object.hasOwn(req.query, "editorigin")) {
|
|
10
27
|
return waypointUrl({ waypoint: req.query.editorigin });
|
|
@@ -15,6 +32,19 @@ const editOrigin = (req) => {
|
|
|
15
32
|
return "";
|
|
16
33
|
};
|
|
17
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Data middleware.
|
|
37
|
+
*
|
|
38
|
+
* Decorates the request with some contextual data about the user's journey
|
|
39
|
+
* through the application. This is used by downstream middleware and
|
|
40
|
+
* templates.
|
|
41
|
+
*
|
|
42
|
+
* @param {object} opts Options
|
|
43
|
+
* @param {Plan} opts.plan CASA Plan
|
|
44
|
+
* @param {ContextEventHandler[]} opts.events Event handlers
|
|
45
|
+
* @param {ContextIdGenerator} opts.contextIdGenerator Content ID generator
|
|
46
|
+
* @returns {RequestHandler[]} Middleware functions
|
|
47
|
+
*/
|
|
18
48
|
export default function dataMiddleware({ plan, events, contextIdGenerator }) {
|
|
19
49
|
return [
|
|
20
50
|
(req, res, next) => {
|
|
@@ -36,8 +66,10 @@ export default function dataMiddleware({ plan, events, contextIdGenerator }) {
|
|
|
36
66
|
|
|
37
67
|
// Edit mode
|
|
38
68
|
editMode:
|
|
39
|
-
(Object.hasOwn(req.query, "edit") &&
|
|
40
|
-
|
|
69
|
+
(Object.hasOwn(req.query, "edit") &&
|
|
70
|
+
Object.hasOwn(req.query, "editorigin")) ||
|
|
71
|
+
(Object.hasOwn(req.body, "edit") &&
|
|
72
|
+
Object.hasOwn(req.body, "editorigin")),
|
|
41
73
|
editOrigin: editOrigin(req),
|
|
42
74
|
};
|
|
43
75
|
|
|
@@ -20,7 +20,7 @@ import { REQUEST_PHASE_GATHER } from "../lib/constants.js";
|
|
|
20
20
|
*
|
|
21
21
|
* @param {object} obj Options
|
|
22
22
|
* @param {string} obj.waypoint Waypoint
|
|
23
|
-
* @param {PageField[]} [obj.fields
|
|
23
|
+
* @param {PageField[]} [obj.fields] Fields. Default is `[]`
|
|
24
24
|
* @returns {Array} Array of middleware
|
|
25
25
|
*/
|
|
26
26
|
export default ({ waypoint, fields = [] }) => [
|
package/src/middleware/i18n.js
CHANGED
|
@@ -3,9 +3,14 @@ import { LanguageDetector, handle } from "i18next-http-middleware";
|
|
|
3
3
|
import { resolve, basename } from "node:path";
|
|
4
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
5
|
import deepmerge from "deepmerge";
|
|
6
|
-
import
|
|
6
|
+
import { load as jsYamlLoad } from "js-yaml";
|
|
7
7
|
import logger from "../lib/logger.js";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
11
|
+
* @access private
|
|
12
|
+
*/
|
|
13
|
+
|
|
9
14
|
const log = logger("middleware:i18n");
|
|
10
15
|
|
|
11
16
|
const loadJson = (file) => {
|
|
@@ -17,7 +22,7 @@ const loadJson = (file) => {
|
|
|
17
22
|
};
|
|
18
23
|
|
|
19
24
|
/* eslint-disable-next-line security/detect-non-literal-fs-filename */
|
|
20
|
-
const loadYaml = (file) =>
|
|
25
|
+
const loadYaml = (file) => jsYamlLoad(readFileSync(file, "utf8"));
|
|
21
26
|
|
|
22
27
|
const extract = (file) => {
|
|
23
28
|
const ext = /.yaml$/i.test(file) ? ".yaml" : ".json";
|
|
@@ -63,6 +68,14 @@ const loadResources = (languages, directories) => {
|
|
|
63
68
|
return store;
|
|
64
69
|
};
|
|
65
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Internationalisation middleware.
|
|
73
|
+
*
|
|
74
|
+
* @param {object} opts Options
|
|
75
|
+
* @param {string[]} [opts.languages] Language codes
|
|
76
|
+
* @param {string[]} [opts.directories] Source translations directories
|
|
77
|
+
* @returns {RequestHandler[]} Middleware functions
|
|
78
|
+
*/
|
|
66
79
|
export default function i18nMiddleware({
|
|
67
80
|
languages = ["en", "cy"],
|
|
68
81
|
directories = [],
|
|
@@ -95,7 +108,6 @@ export default function i18nMiddleware({
|
|
|
95
108
|
return [
|
|
96
109
|
(req, res, next) => {
|
|
97
110
|
if (!req.session.language) {
|
|
98
|
-
/* eslint-disable-next-line prefer-destructuring */
|
|
99
111
|
req.session.language = languages[0];
|
|
100
112
|
}
|
|
101
113
|
if (req?.query.lang && languages.includes(req.query.lang)) {
|
package/src/middleware/post.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// 2 middleware: one as a fallback 404 handler, one to handle thrown errors
|
|
2
2
|
import logger from "../lib/logger.js";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
6
|
+
* @access private
|
|
7
|
+
*/
|
|
8
|
+
|
|
4
9
|
const log = logger("middleware:post");
|
|
5
10
|
|
|
11
|
+
/** @returns {RequestHandler[]} Middleware functions */
|
|
6
12
|
export default function postMiddleware() {
|
|
7
13
|
return [
|
|
8
14
|
(req, res) => {
|
|
@@ -5,6 +5,11 @@ import expressSession, { MemoryStore } from "express-session";
|
|
|
5
5
|
import logger from "../lib/logger.js";
|
|
6
6
|
import { validateUrlPath } from "../lib/utils.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import("express").RequestHandler} RequestHandler
|
|
10
|
+
* @access private
|
|
11
|
+
*/
|
|
12
|
+
|
|
8
13
|
const log = logger("middleware:session");
|
|
9
14
|
|
|
10
15
|
const sessionExpiryMiddleware =
|
|
@@ -51,7 +56,7 @@ const sessionExpiryMiddleware =
|
|
|
51
56
|
referrer: req.originalUrl,
|
|
52
57
|
lang: language,
|
|
53
58
|
});
|
|
54
|
-
|
|
59
|
+
|
|
55
60
|
res.redirect(
|
|
56
61
|
302,
|
|
57
62
|
validateUrlPath(`${req.baseUrl}/session-timeout`) +
|
|
@@ -66,10 +71,24 @@ const sessionExpiryMiddleware =
|
|
|
66
71
|
}
|
|
67
72
|
};
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Produces three middleware functions:
|
|
76
|
+
*
|
|
77
|
+
* - Set the session cookie
|
|
78
|
+
* - Parse request cookies
|
|
79
|
+
* - Handle expiry of server-side session
|
|
80
|
+
*
|
|
81
|
+
* @param {object} opts Options
|
|
82
|
+
* @param {RequestHandler} opts.cookieParserMiddleware Cookie parsing middleware
|
|
83
|
+
* @param {string} opts.secret Session encryption secret
|
|
84
|
+
* @param {string} opts.name Session cookie name
|
|
85
|
+
* @param {boolean} opts.secure Secure cookies only
|
|
86
|
+
* @param {number} opts.ttl Session data time-to-live
|
|
87
|
+
* @param {boolean | string} [opts.cookieSameSite] Cooke SameSite setting
|
|
88
|
+
* @param {string} [opts.cookiePath] Cookie path
|
|
89
|
+
* @param {object} [opts.store] Storage instance
|
|
90
|
+
* @returns {RequestHandler[]} Middleware functions
|
|
91
|
+
*/
|
|
73
92
|
export default function sessionMiddleware({
|
|
74
93
|
cookieParserMiddleware,
|
|
75
94
|
secret,
|
package/src/routes/journey.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable object-curly-newline,max-len */
|
|
2
1
|
import MutableRouter from "../lib/MutableRouter.js";
|
|
3
2
|
import skipWaypointMiddlewareFactory from "../middleware/skip-waypoint.js";
|
|
4
3
|
import steerJourneyMiddlewareFactory from "../middleware/steer-journey.js";
|
|
@@ -44,7 +43,10 @@ const renderMiddlewareFactory = (view, contextFactory) => [
|
|
|
44
43
|
// Common template variables for both GET and POST requests
|
|
45
44
|
inEditMode: req.casa.editMode,
|
|
46
45
|
editOriginUrl: req.casa.editOrigin,
|
|
47
|
-
editCancelUrl: generateEditCancelUrl(
|
|
46
|
+
editCancelUrl: generateEditCancelUrl(
|
|
47
|
+
req.casa.editOrigin,
|
|
48
|
+
req.casa.waypoint,
|
|
49
|
+
),
|
|
48
50
|
activeContextId: req.casa.journeyContext.identity.id,
|
|
49
51
|
...contextFactory(req),
|
|
50
52
|
},
|
|
@@ -73,8 +75,8 @@ const generateGovukErrors = (errors, req) =>
|
|
|
73
75
|
}));
|
|
74
76
|
|
|
75
77
|
const generateEditCancelUrl = (editOrigin, waypoint) => {
|
|
76
|
-
const url = new URL(editOrigin,
|
|
77
|
-
url.searchParams.set(
|
|
78
|
+
const url = new URL(editOrigin, "https://placeholder.test/");
|
|
79
|
+
url.searchParams.set("editcancel", waypoint);
|
|
78
80
|
return `${url.pathname}${url.search}`;
|
|
79
81
|
};
|
|
80
82
|
|