@dwp/govuk-casa 9.4.0 → 9.4.2
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/assets/css/casa.css +1 -1
- package/dist/assets/css/casa.css.map +1 -1
- package/dist/casa.js +17 -7
- package/dist/casa.js.map +1 -1
- package/dist/core-plugins/edit-snapshot/src/configure.d.ts +6 -1
- package/dist/core-plugins/edit-snapshot/src/configure.js +8 -0
- package/dist/core-plugins/edit-snapshot/src/configure.js.map +1 -1
- package/dist/core-plugins/edit-snapshot/src/post-steer-hook.js.map +1 -1
- package/dist/core-plugins/edit-snapshot/src/pre-steer-hook.js.map +1 -1
- package/dist/core-plugins/edit-snapshot/src/utils.js +4 -2
- package/dist/core-plugins/edit-snapshot/src/utils.js.map +1 -1
- package/dist/lib/CasaTemplateLoader.js +0 -1
- package/dist/lib/CasaTemplateLoader.js.map +1 -1
- package/dist/lib/JourneyContext.d.ts +10 -6
- package/dist/lib/JourneyContext.js +11 -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 +74 -14
- package/dist/lib/configuration-ingestor.js +115 -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 +2 -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/routes/journey.js +2 -3
- package/dist/routes/journey.js.map +1 -1
- package/package.json +31 -33
- package/src/core-plugins/edit-snapshot/src/configure.js +19 -7
- package/src/core-plugins/edit-snapshot/src/post-steer-hook.js +3 -1
- package/src/core-plugins/edit-snapshot/src/pre-steer-hook.js +14 -4
- package/src/core-plugins/edit-snapshot/src/utils.js +19 -7
- package/src/lib/CasaTemplateLoader.js +0 -1
- package/src/lib/JourneyContext.js +16 -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 +111 -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
- package/src/core-plugins/edit-snapshot/readme.md +0 -19
- package/src/core-plugins/readme.md +0 -3
|
@@ -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
|
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Edit snapshots plugin
|
|
2
|
-
|
|
3
|
-
Include the `editSnapshot` core plugin to use this feature:
|
|
4
|
-
|
|
5
|
-
```js
|
|
6
|
-
import { configure, corePlugins } from "@dwp/govuk/casa";
|
|
7
|
-
|
|
8
|
-
configure({
|
|
9
|
-
plugins: [
|
|
10
|
-
corePlugins.editSnapshot(),
|
|
11
|
-
],
|
|
12
|
-
});
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
This feature will alter the default behaviour of the "cancel" links during an editing workflow.
|
|
16
|
-
|
|
17
|
-
When the user clicks "cancel", all changes made during the current editing session will be dropped, and the state of the current journey context will be restored to a point just before editing started.
|
|
18
|
-
|
|
19
|
-
The same will also happen if the user navigates away from the editing workflow, i.e. the `edit` URL paramater is removed.
|