@dwp/govuk-casa 8.8.0 → 8.9.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/assets/css/casa-ie8.css +1 -1
- package/dist/assets/css/casa.css +1 -1
- package/dist/casa.d.ts +23 -12
- package/dist/casa.js +8 -1
- package/dist/casa.js.map +1 -1
- package/dist/lib/CasaTemplateLoader.d.ts +1 -1
- package/dist/lib/JourneyContext.d.ts +12 -3
- package/dist/lib/JourneyContext.js +19 -5
- package/dist/lib/JourneyContext.js.map +1 -1
- package/dist/lib/MutableRouter.d.ts +1 -1
- package/dist/lib/Plan.d.ts +2 -3
- package/dist/lib/Plan.js +1 -5
- package/dist/lib/Plan.js.map +1 -1
- package/dist/lib/constants.d.ts +9 -0
- package/dist/lib/constants.js +13 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/index.d.ts +13 -13
- package/dist/lib/nunjucks.d.ts +1 -1
- package/dist/lib/validators/dateObject.d.ts +2 -2
- package/dist/lib/validators/email.d.ts +2 -2
- package/dist/lib/validators/inArray.d.ts +2 -2
- package/dist/lib/validators/index.d.ts +9 -9
- package/dist/lib/validators/nino.d.ts +2 -2
- package/dist/lib/validators/postalAddressObject.d.ts +2 -2
- package/dist/lib/validators/regex.d.ts +2 -2
- package/dist/lib/validators/required.d.ts +2 -2
- package/dist/lib/validators/strlen.d.ts +2 -2
- package/dist/lib/validators/wordCount.d.ts +2 -2
- package/dist/lib/waypoint-url.js +39 -9
- package/dist/lib/waypoint-url.js.map +1 -1
- package/dist/middleware/gather-fields.js +9 -2
- package/dist/middleware/gather-fields.js.map +1 -1
- package/dist/middleware/progress-journey.js +6 -2
- package/dist/middleware/progress-journey.js.map +1 -1
- package/dist/middleware/steer-journey.js +1 -0
- package/dist/middleware/steer-journey.js.map +1 -1
- package/dist/middleware/validate-fields.js +6 -1
- package/dist/middleware/validate-fields.js.map +1 -1
- package/dist/mjs/esm-wrapper.js +1 -0
- package/dist/routes/ancillary.d.ts +1 -1
- package/dist/routes/journey.d.ts +1 -1
- package/dist/routes/static.d.ts +1 -1
- package/package.json +18 -18
- package/src/casa.js +10 -0
- package/src/lib/JourneyContext.js +19 -5
- package/src/lib/Plan.js +1 -6
- package/src/lib/constants.js +9 -0
- package/src/lib/waypoint-url.js +42 -9
- package/src/middleware/gather-fields.js +9 -2
- package/src/middleware/progress-journey.js +6 -2
- package/src/middleware/steer-journey.js +1 -0
- package/src/middleware/validate-fields.js +6 -1
package/dist/lib/waypoint-url.js
CHANGED
|
@@ -14,6 +14,31 @@ const reUrlProtocolExtract = /^url:\/\/(.+)$/i;
|
|
|
14
14
|
* @returns {string} Sanitised waypoint
|
|
15
15
|
*/
|
|
16
16
|
const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g, '/');
|
|
17
|
+
/**
|
|
18
|
+
* Sanitise a waypoint string, with allowed URL parameters:
|
|
19
|
+
* contextid = JourneyContext ID
|
|
20
|
+
*
|
|
21
|
+
* @access private
|
|
22
|
+
* @param {string} w Waypoint and potential URL parameters
|
|
23
|
+
* @returns {string} Sanitised waypoint
|
|
24
|
+
*/
|
|
25
|
+
const sanitiseWaypointWithAllowedParams = (w) => {
|
|
26
|
+
// Extract URL params
|
|
27
|
+
const parts = w.split('?');
|
|
28
|
+
if (parts.length !== 2) {
|
|
29
|
+
return sanitiseWaypoint(w);
|
|
30
|
+
}
|
|
31
|
+
const [waypoint, rawParams] = parts;
|
|
32
|
+
const urlSearchParams = new URLSearchParams(rawParams);
|
|
33
|
+
// Strip all but those parameters allowed
|
|
34
|
+
const validatedUrlSearchParams = new URLSearchParams();
|
|
35
|
+
for (const pk of ['contextid']) {
|
|
36
|
+
if (urlSearchParams.has(pk)) {
|
|
37
|
+
validatedUrlSearchParams.set(pk, urlSearchParams.get(pk));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return `${sanitiseWaypoint(waypoint)}?${validatedUrlSearchParams.toString()}`.replace(/\?$/, '');
|
|
41
|
+
};
|
|
17
42
|
/**
|
|
18
43
|
* Generate a URL pointing at a particular waypoint.
|
|
19
44
|
*
|
|
@@ -42,13 +67,18 @@ function waypointUrl({ waypoint = '', mountUrl = '/', journeyContext, edit = fal
|
|
|
42
67
|
// - This will generate a link to the root handler "_" for the given mount path
|
|
43
68
|
if (String(waypoint).substr(0, 7) === 'url:///') {
|
|
44
69
|
const m = waypoint.match(reUrlProtocolExtract);
|
|
45
|
-
const u = new URL(m[1], 'https://placeholder.test/');
|
|
70
|
+
const u = new URL(sanitiseWaypointWithAllowedParams(m[1]), 'https://placeholder.test/');
|
|
46
71
|
url.pathname = `${sanitiseWaypoint(u.pathname)}/_/`;
|
|
47
|
-
url.searchParams.
|
|
48
|
-
url.searchParams.
|
|
72
|
+
url.searchParams.set('refmount', `url://${mountUrl}`);
|
|
73
|
+
url.searchParams.set('route', routeName);
|
|
74
|
+
for (const [uk, uv] of u.searchParams.entries()) {
|
|
75
|
+
url.searchParams.append(uk, uv);
|
|
76
|
+
}
|
|
49
77
|
}
|
|
50
78
|
else {
|
|
51
|
-
|
|
79
|
+
const u = new URL(sanitiseWaypointWithAllowedParams(`${mountUrl}${waypoint}`), 'https://placeholder.test/');
|
|
80
|
+
url.pathname = u.pathname;
|
|
81
|
+
url.search = u.search;
|
|
52
82
|
}
|
|
53
83
|
// Attach context ID as query parameter for non-default contexts.
|
|
54
84
|
// To avoid messy URLs with duplicated content, this parameter will _not_ be
|
|
@@ -57,19 +87,19 @@ function waypointUrl({ waypoint = '', mountUrl = '/', journeyContext, edit = fal
|
|
|
57
87
|
if (journeyContext
|
|
58
88
|
&& !journeyContext.isDefault()
|
|
59
89
|
&& journeyContext.identity.id
|
|
60
|
-
&& !mountUrl.includes(journeyContext.identity.id)) {
|
|
61
|
-
url.searchParams.
|
|
90
|
+
&& !mountUrl.includes(`/${journeyContext.identity.id}/`)) {
|
|
91
|
+
url.searchParams.set('contextid', journeyContext.identity.id);
|
|
62
92
|
}
|
|
63
93
|
// Attach edit mode flag
|
|
64
94
|
if (edit === true) {
|
|
65
|
-
url.searchParams.
|
|
95
|
+
url.searchParams.set('edit', 'true');
|
|
66
96
|
}
|
|
67
97
|
if (edit && editOrigin) {
|
|
68
|
-
url.searchParams.
|
|
98
|
+
url.searchParams.set('editorigin', sanitiseWaypointWithAllowedParams(editOrigin));
|
|
69
99
|
}
|
|
70
100
|
// Skipto
|
|
71
101
|
if (skipTo) {
|
|
72
|
-
url.searchParams.
|
|
102
|
+
url.searchParams.set('skipto', sanitiseWaypointWithAllowedParams(skipTo));
|
|
73
103
|
}
|
|
74
104
|
return `${sanitiseWaypoint(url.pathname)}${url.search}`;
|
|
75
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waypoint-url.js","sourceRoot":"","sources":["../../src/lib/waypoint-url.js"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sBAAsB;AACtB,MAAM,oBAAoB,GAAG,iBAAiB,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAwB,WAAW,CAAC,EAClC,QAAQ,GAAG,EAAE,EACb,QAAQ,GAAG,GAAG,EACd,cAAc,EACd,IAAI,GAAG,KAAK,EACZ,UAAU,EACV,MAAM,EACN,SAAS,GAAG,MAAM,GACnB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACrB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAEhD,yBAAyB;IACzB,+EAA+E;IAC/E,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,EAAE;QAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAE/C,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"waypoint-url.js","sourceRoot":"","sources":["../../src/lib/waypoint-url.js"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sBAAsB;AACtB,MAAM,oBAAoB,GAAG,iBAAiB,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErF;;;;;;;GAOG;AACH,MAAM,iCAAiC,GAAG,CAAC,CAAC,EAAE,EAAE;IAC9C,qBAAqB;IACrB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QACtB,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC;KAC5B;IACD,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IACpC,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,SAAS,CAAC,CAAC;IAEvD,yCAAyC;IACzC,MAAM,wBAAwB,GAAG,IAAI,eAAe,EAAE,CAAC;IACvD,KAAK,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE;QAC9B,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC3B,wBAAwB,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;SAC3D;KACF;IAED,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,wBAAwB,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACnG,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAwB,WAAW,CAAC,EAClC,QAAQ,GAAG,EAAE,EACb,QAAQ,GAAG,GAAG,EACd,cAAc,EACd,IAAI,GAAG,KAAK,EACZ,UAAU,EACV,MAAM,EACN,SAAS,GAAG,MAAM,GACnB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACrB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAEhD,yBAAyB;IACzB,+EAA+E;IAC/E,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,EAAE;QAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAE/C,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACxF,GAAG,CAAC,QAAQ,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAEpD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC,CAAC;QACtD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE;YAC/C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SACjC;KACF;SAAM;QACL,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,iCAAiC,CAAC,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC,EAAE,2BAA2B,CAAC,CAAC;QAC5G,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC1B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;KACvB;IAED,iEAAiE;IACjE,4EAA4E;IAC5E,yEAAyE;IACzE,2DAA2D;IAC3D,IACE,cAAc;WACX,CAAC,cAAc,CAAC,SAAS,EAAE;WAC3B,cAAc,CAAC,QAAQ,CAAC,EAAE;WAC1B,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EACxD;QACA,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;KAC/D;IAED,wBAAwB;IACxB,IAAI,IAAI,KAAK,IAAI,EAAE;QACjB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC;IAED,IAAI,IAAI,IAAI,UAAU,EAAE;QACtB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,iCAAiC,CAAC,UAAU,CAAC,CAAC,CAAC;KACnF;IAED,SAAS;IACT,IAAI,MAAM,EAAE;QACV,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,iCAAiC,CAAC,MAAM,CAAC,CAAC,CAAC;KAC3E;IAED,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC;AA1DD,8BA0DC"}
|
|
@@ -8,6 +8,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
11
|
+
const constants_js_1 = require("../lib/constants.js");
|
|
11
12
|
/**
|
|
12
13
|
* @access private
|
|
13
14
|
* @typedef {import('../lib/field').PageField} PageField
|
|
@@ -38,10 +39,16 @@ exports.default = ({ waypoint, fields = [], }) => [
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
/* eslint-enable security/detect-object-injection */
|
|
41
|
-
// Update data and validation context in the current request, and store
|
|
42
|
+
// Update data and validation context in the current request, and store.
|
|
43
|
+
// The validation state is removed here because we must assume the gathered
|
|
44
|
+
// data is invalid until proven otherwise when the validation step is run.
|
|
42
45
|
req.casa.journeyContext.setDataForPage(waypoint, persistentBody);
|
|
43
46
|
req.casa.journeyContext.removeValidationStateForPage(waypoint);
|
|
44
|
-
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext
|
|
47
|
+
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext, {
|
|
48
|
+
userInfo: {
|
|
49
|
+
casaRequestPhase: constants_js_1.REQUEST_PHASE_GATHER,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
45
52
|
next();
|
|
46
53
|
},
|
|
47
54
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gather-fields.js","sourceRoot":"","sources":["../../src/middleware/gather-fields.js"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,iCAAiC;AACjC,wDAAwD;AACxD,mEAAmE;;;;;AAEnE,iFAAsD;
|
|
1
|
+
{"version":3,"file":"gather-fields.js","sourceRoot":"","sources":["../../src/middleware/gather-fields.js"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,iCAAiC;AACjC,wDAAwD;AACxD,mEAAmE;;;;;AAEnE,iFAAsD;AACtD,sDAA2D;AAE3D;;;GAGG;AAEH;;;;;;;;;;GAUG;AACH,kBAAe,CAAC,EACd,QAAQ,EACR,MAAM,GAAG,EAAE,GACZ,EAAE,EAAE,CAAC;IACJ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjB,0EAA0E;QAC1E,qEAAqE;QACrE,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,2BAAc,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAEtF,4CAA4C;QAC5C,iEAAiE;QACjE,qDAAqD;QACrD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;gBACxE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aAC/D;SACF;QACD,oDAAoD;QAEpD,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACjE,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;QAC/D,2BAAc,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE;YAC9D,QAAQ,EAAE;gBACR,gBAAgB,EAAE,mCAAoB;aACvC;SACF,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC;CACF,CAAC"}
|
|
@@ -10,9 +10,14 @@ const Plan_js_1 = __importDefault(require("../lib/Plan.js"));
|
|
|
10
10
|
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
11
11
|
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
12
12
|
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
13
|
+
const constants_js_1 = require("../lib/constants.js");
|
|
13
14
|
const log = (0, logger_js_1.default)('middleware:progress-journey');
|
|
14
15
|
const saveAndRedirect = (session, journeyContext, url, res, next) => {
|
|
15
|
-
JourneyContext_js_1.default.putContext(session, journeyContext
|
|
16
|
+
JourneyContext_js_1.default.putContext(session, journeyContext, {
|
|
17
|
+
userInfo: {
|
|
18
|
+
casaRequestPhase: constants_js_1.REQUEST_PHASE_REDIRECT,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
16
21
|
session.save((err) => {
|
|
17
22
|
if (err) {
|
|
18
23
|
next(err);
|
|
@@ -63,7 +68,6 @@ exports.default = ({ waypoint, plan, }) => [
|
|
|
63
68
|
if (Plan_js_1.default.isExitNode(nextWaypoint)) {
|
|
64
69
|
log.trace(`Next waypoint is an exit node; clearing validation state on ${nextWaypoint}`);
|
|
65
70
|
req.casa.journeyContext.clearValidationErrorsForPage(nextWaypoint);
|
|
66
|
-
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext);
|
|
67
71
|
}
|
|
68
72
|
// Construct the next url
|
|
69
73
|
const nextUrl = (0, waypoint_url_js_1.default)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress-journey.js","sourceRoot":"","sources":["../../src/middleware/progress-journey.js"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,wEAAwE;AACxE,cAAc;;;;;AAEd,6DAAkC;AAClC,iFAAsD;AACtD,6EAAiD;AACjD,iEAAsC;
|
|
1
|
+
{"version":3,"file":"progress-journey.js","sourceRoot":"","sources":["../../src/middleware/progress-journey.js"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,wEAAwE;AACxE,cAAc;;;;;AAEd,6DAAkC;AAClC,iFAAsD;AACtD,6EAAiD;AACjD,iEAAsC;AACtC,sDAA6D;AAE7D,MAAM,GAAG,GAAG,IAAA,mBAAM,EAAC,6BAA6B,CAAC,CAAC;AAElD,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IAClE,2BAAc,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE;QACjD,QAAQ,EAAE;YACR,gBAAgB,EAAE,qCAAsB;SACzC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,IAAI,GAAG,EAAE;YACP,IAAI,CAAC,GAAG,CAAC,CAAC;SACX;QACD,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,kBAAe,CAAC,EACd,QAAQ,EACR,IAAI,GACL,EAAE,EAAE,CAAC;IACJ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjB,8DAA8D;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzD,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACxB,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3C,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CACjD,CAAC;QACF,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QACxD,GAAG,CAAC,KAAK,CAAC,kBAAkB,YAAY,iBAAiB,SAAS,uBAAuB,QAAQ,oBAAoB,YAAY,EAAE,CAAC,CAAC;QAErI,YAAY;QACZ,sEAAsE;QACtE,wEAAwE;QACxE,yEAAyE;QACzE,yEAAyE;QACzE,oCAAoC;QACpC,EAAE;QACF,yEAAyE;QACzE,yEAAyE;QACzE,4BAA4B;QAC5B,EAAE;QACF,yEAAyE;QACzE,2EAA2E;QAC3E,mBAAmB;QACnB,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE;YAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;YACtE,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACxC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3D,MAAM,WAAW,GAAG,IAAA,yBAAW,EAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAEpF,GAAG,CAAC,KAAK,CAAC,sCAAsC,WAAW,EAAE,CAAC,CAAC;YAE/D,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;SACtF;QAED,kEAAkE;QAClE,yEAAyE;QACzE,uDAAuD;QACvD,0EAA0E;QAC1E,oDAAoD;QACpD,yEAAyE;QACzE,gCAAgC;QAChC,wBAAwB;QACxB,sCAAsC;QACtC,8EAA8E;QAC9E,IAAI,iBAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE;YACjC,GAAG,CAAC,KAAK,CAAC,+DAA+D,YAAY,EAAE,CAAC,CAAC;YACzF,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;SACpE;QAED,yBAAyB;QACzB,MAAM,OAAO,GAAG,IAAA,yBAAW,EAAC;YAC1B,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG;YAC3B,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;YACvC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,mBAAmB;QACnB,GAAG,CAAC,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACnF,CAAC;CACF,CAAC"}
|
|
@@ -59,6 +59,7 @@ exports.default = ({ waypoint, plan, }) => [
|
|
|
59
59
|
});
|
|
60
60
|
res.locals.casa.journeyPreviousUrl = prevRoute.target ? (0, waypoint_url_js_1.default)({
|
|
61
61
|
mountUrl,
|
|
62
|
+
journeyContext: req.casa.journeyContext,
|
|
62
63
|
waypoint: prevRoute.target,
|
|
63
64
|
routeName: 'prev',
|
|
64
65
|
edit: req.casa.editMode,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"steer-journey.js","sourceRoot":"","sources":["../../src/middleware/steer-journey.js"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,+BAA+B;;;;;AAE/B,6EAAiD;AACjD,iEAAsC;AAEtC,MAAM,GAAG,GAAG,IAAA,mBAAM,EAAC,0BAA0B,CAAC,CAAC;AAE/C;;;GAGG;AAEH;;;;;;;;GAQG;AACH,kBAAe,CAAC,EACd,QAAQ,EACR,IAAI,GACL,EAAE,EAAE,CAAC;IACJ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjB,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC;QAEnC,yEAAyE;QACzE,2CAA2C;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzD,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;YACtC,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnD,GAAG,CAAC,KAAK,CAAC,wBAAwB,QAAQ,8CAA8C,UAAU,GAAG,CAAC,CAAC;YAEvG,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAA,yBAAW,EAAC;gBACnC,QAAQ,EAAE,UAAU;gBACpB,QAAQ;gBACR,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;gBACvC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ;gBACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;aAChC,CAAC,CAAC,CAAC;SACL;QAED,YAAY;QACZ,kEAAkE;QAClE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE;YACrB,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;YAE5F,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,eAAe,EAAE;gBAC3C,GAAG,CAAC,KAAK,CAAC,qDAAqD,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBACvF,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBAC1B,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;aACjC;SACF;QAED,yEAAyE;QACzE,4EAA4E;QAC5E,4EAA4E;QAC5E,gEAAgE;QAEhE,oCAAoC;QACpC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE;YACnE,aAAa,EAAE,QAAQ;YACvB,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,wBAAwB;SACtD,CAAC,CAAC;QACH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,yBAAW,EAAC;YAClE,QAAQ;YACR,QAAQ,EAAE,SAAS,CAAC,MAAM;YAC1B,SAAS,EAAE,MAAM;YACjB,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;SAChC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEf,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"steer-journey.js","sourceRoot":"","sources":["../../src/middleware/steer-journey.js"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,+BAA+B;;;;;AAE/B,6EAAiD;AACjD,iEAAsC;AAEtC,MAAM,GAAG,GAAG,IAAA,mBAAM,EAAC,0BAA0B,CAAC,CAAC;AAE/C;;;GAGG;AAEH;;;;;;;;GAQG;AACH,kBAAe,CAAC,EACd,QAAQ,EACR,IAAI,GACL,EAAE,EAAE,CAAC;IACJ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjB,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC;QAEnC,yEAAyE;QACzE,2CAA2C;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzD,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;YACtC,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnD,GAAG,CAAC,KAAK,CAAC,wBAAwB,QAAQ,8CAA8C,UAAU,GAAG,CAAC,CAAC;YAEvG,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAA,yBAAW,EAAC;gBACnC,QAAQ,EAAE,UAAU;gBACpB,QAAQ;gBACR,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;gBACvC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ;gBACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;aAChC,CAAC,CAAC,CAAC;SACL;QAED,YAAY;QACZ,kEAAkE;QAClE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE;YACrB,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;YAE5F,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,eAAe,EAAE;gBAC3C,GAAG,CAAC,KAAK,CAAC,qDAAqD,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBACvF,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBAC1B,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;aACjC;SACF;QAED,yEAAyE;QACzE,4EAA4E;QAC5E,4EAA4E;QAC5E,gEAAgE;QAEhE,oCAAoC;QACpC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE;YACnE,aAAa,EAAE,QAAQ;YACvB,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,wBAAwB;SACtD,CAAC,CAAC;QACH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,yBAAW,EAAC;YAClE,QAAQ;YACR,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;YACvC,QAAQ,EAAE,SAAS,CAAC,MAAM;YAC1B,SAAS,EAAE,MAAM;YACjB,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;SAChC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEf,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF,CAAC"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
// Validate the data captured in the journey context
|
|
7
7
|
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
8
|
+
const constants_js_1 = require("../lib/constants.js");
|
|
8
9
|
const updateContext = ({ waypoint, errors = null, journeyContext, session, }) => {
|
|
9
10
|
// Set validation state
|
|
10
11
|
if (errors === null) {
|
|
@@ -14,7 +15,11 @@ const updateContext = ({ waypoint, errors = null, journeyContext, session, }) =>
|
|
|
14
15
|
journeyContext.setValidationErrorsForPage(waypoint, errors);
|
|
15
16
|
}
|
|
16
17
|
// Save to session
|
|
17
|
-
JourneyContext_js_1.default.putContext(session, journeyContext
|
|
18
|
+
JourneyContext_js_1.default.putContext(session, journeyContext, {
|
|
19
|
+
userInfo: {
|
|
20
|
+
casaRequestPhase: constants_js_1.REQUEST_PHASE_VALIDATE,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
18
23
|
};
|
|
19
24
|
exports.default = ({ waypoint, fields = [], plan, }) => [
|
|
20
25
|
(req, res, next) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-fields.js","sourceRoot":"","sources":["../../src/middleware/validate-fields.js"],"names":[],"mappings":";;;;;AAAA,oDAAoD;AACpD,iFAAsD;
|
|
1
|
+
{"version":3,"file":"validate-fields.js","sourceRoot":"","sources":["../../src/middleware/validate-fields.js"],"names":[],"mappings":";;;;;AAAA,oDAAoD;AACpD,iFAAsD;AACtD,sDAA6D;AAE7D,MAAM,aAAa,GAAG,CAAC,EACrB,QAAQ,EACR,MAAM,GAAG,IAAI,EACb,cAAc,EACd,OAAO,GACR,EAAE,EAAE;IACH,uBAAuB;IACvB,IAAI,MAAM,KAAK,IAAI,EAAE;QACnB,cAAc,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;KACvD;SAAM;QACL,cAAc,CAAC,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;KAC7D;IAED,kBAAkB;IAClB,2BAAc,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE;QACjD,QAAQ,EAAE;YACR,gBAAgB,EAAE,qCAAsB;SACzC;KACF,CAAC,CAAC;AACL,CAAC,CAAA;AAED,kBAAe,CAAC,EACd,QAAQ,EACR,MAAM,GAAG,EAAE,EACX,IAAI,GACL,EAAE,EAAE,CAAC;IACJ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;;QACjB,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC;QAEnC,uEAAuE;QACvE,2CAA2C;QAC3C,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC7C,qDAAqD;YACrD,yEAAyE;YACzE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YAC7B,MAAM,UAAU,GAAG,MAAA,MAAA,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,0CAAG,QAAQ,CAAC,0CAAG,SAAS,CAAC,CAAC;YAEzE,2BAA2B;YAC3B,MAAM,OAAO,GAAG;gBACd,SAAS;gBACT,UAAU;gBACV,QAAQ;gBACR,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;aACxC,CAAC;YACF,oDAAoD;YAEpD,MAAM,GAAG;gBACP,GAAG,MAAM;gBACT,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC;aAC5C,CAAC;SACH;QAED,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAClB,aAAa,CAAC;gBACZ,QAAQ;gBACR,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,QAAQ;gBACR,IAAI;gBACJ,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;aACxC,CAAC,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;SACf;QAED,0EAA0E;QAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC;QAC3D,IAAI,WAAW,EAAE;YACf,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC;SAC1B;QAED,qDAAqD;QACrD,aAAa,CAAC;YACZ,MAAM;YACN,QAAQ;YACR,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,QAAQ;YACR,IAAI;YACJ,cAAc,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc;SACxC,CAAC,CAAC;QAEH,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CACF,CAAC"}
|
package/dist/mjs/esm-wrapper.js
CHANGED
|
@@ -9,6 +9,7 @@ export const { Plan } = casa;
|
|
|
9
9
|
export const { ValidationError } = casa;
|
|
10
10
|
export const { ValidatorFactory } = casa;
|
|
11
11
|
export const { configure } = casa;
|
|
12
|
+
export const { constants } = casa;
|
|
12
13
|
export const { endSession } = casa;
|
|
13
14
|
export const { field } = casa;
|
|
14
15
|
export const { nunjucksFilters } = casa;
|
package/dist/routes/journey.d.ts
CHANGED
package/dist/routes/static.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwp/govuk-casa",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.1",
|
|
4
4
|
"description": "A framework for building GOVUK Collect-And-Submit-Applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"views/**/*"
|
|
21
21
|
],
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": "^
|
|
24
|
-
"npm": "^8.0.0"
|
|
23
|
+
"node": "^16.0.0 || ^18.0.0 || ^20.0.0",
|
|
24
|
+
"npm": "^8.0.0 || ^9.0.0"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"pipeline": "npm run coverage && npm run lint",
|
|
@@ -55,48 +55,48 @@
|
|
|
55
55
|
"deepmerge": "4.3.1",
|
|
56
56
|
"express": "4.18.2",
|
|
57
57
|
"express-session": "1.17.3",
|
|
58
|
-
"govuk-frontend": "4.
|
|
59
|
-
"helmet": "6.
|
|
60
|
-
"i18next": "22.4.
|
|
58
|
+
"govuk-frontend": "4.6.0",
|
|
59
|
+
"helmet": "6.1.5",
|
|
60
|
+
"i18next": "22.4.15",
|
|
61
61
|
"i18next-http-middleware": "3.3.0",
|
|
62
62
|
"js-yaml": "4.1.0",
|
|
63
63
|
"lodash": "4.17.21",
|
|
64
64
|
"luxon": "3.3.0",
|
|
65
|
-
"nunjucks": "3.2.
|
|
65
|
+
"nunjucks": "3.2.4",
|
|
66
66
|
"path-to-regexp": "6.2.1",
|
|
67
67
|
"uuid": "9.0.0",
|
|
68
68
|
"validator": "13.9.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@babel/core": "7.21.
|
|
71
|
+
"@babel/core": "7.21.5",
|
|
72
72
|
"@babel/eslint-parser": "7.21.3",
|
|
73
|
-
"@babel/preset-env": "7.21.
|
|
74
|
-
"@ckeditor/jsdoc-plugins": "
|
|
75
|
-
"@commitlint/config-conventional": "17.
|
|
73
|
+
"@babel/preset-env": "7.21.5",
|
|
74
|
+
"@ckeditor/jsdoc-plugins": "37.0.1",
|
|
75
|
+
"@commitlint/config-conventional": "17.6.1",
|
|
76
76
|
"@dwp/casa-spiderplan": "2.5.4",
|
|
77
77
|
"@dwp/casa-spiderplan-a11y-plugin": "0.1.10",
|
|
78
78
|
"@dwp/casa-spiderplan-zap-plugin": "0.1.6",
|
|
79
79
|
"@dwp/eslint-config-base": "6.1.1",
|
|
80
80
|
"@types/express": "4.17.17",
|
|
81
|
-
"@types/node": "18.
|
|
81
|
+
"@types/node": "18.16.3",
|
|
82
82
|
"@types/nunjucks": "3.2.2",
|
|
83
83
|
"c8": "7.13.0",
|
|
84
84
|
"chai": "4.3.7",
|
|
85
85
|
"cheerio": "1.0.0-rc.12",
|
|
86
|
-
"commitlint": "17.
|
|
86
|
+
"commitlint": "17.6.1",
|
|
87
87
|
"docdash": "2.0.1",
|
|
88
|
-
"eslint": "8.
|
|
88
|
+
"eslint": "8.39.0",
|
|
89
89
|
"eslint-plugin-no-unsafe-regex": "1.0.0",
|
|
90
90
|
"eslint-plugin-security": "1.7.1",
|
|
91
91
|
"eslint-plugin-sonarjs": "0.19.0",
|
|
92
|
-
"fast-check": "3.8.
|
|
92
|
+
"fast-check": "3.8.1",
|
|
93
93
|
"jsdoc": "4.0.2",
|
|
94
94
|
"jsdoc-tsimport-plugin": "1.0.5",
|
|
95
95
|
"mocha": "10.2.0",
|
|
96
|
-
"sass": "1.
|
|
97
|
-
"sinon": "15.0.
|
|
96
|
+
"sass": "1.62.1",
|
|
97
|
+
"sinon": "15.0.4",
|
|
98
98
|
"sinon-chai": "3.7.0",
|
|
99
99
|
"supertest": "6.3.3",
|
|
100
|
-
"typescript": "
|
|
100
|
+
"typescript": "5.0.4"
|
|
101
101
|
}
|
|
102
102
|
}
|
package/src/casa.js
CHANGED
|
@@ -10,6 +10,7 @@ import MutableRouter from './lib/MutableRouter.js';
|
|
|
10
10
|
import waypointUrl from './lib/waypoint-url.js';
|
|
11
11
|
import endSession from './lib/end-session.js';
|
|
12
12
|
import * as nunjucksFilters from './lib/nunjucks-filters.js';
|
|
13
|
+
import * as constants from './lib/constants.js';
|
|
13
14
|
|
|
14
15
|
/** @module @dwp/govuk-casa */
|
|
15
16
|
export {
|
|
@@ -28,6 +29,9 @@ export {
|
|
|
28
29
|
|
|
29
30
|
// Nunjucks filters
|
|
30
31
|
nunjucksFilters,
|
|
32
|
+
|
|
33
|
+
// Constants
|
|
34
|
+
constants,
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
/* ----------------------------------------------------------------- Typedefs */
|
|
@@ -42,6 +46,7 @@ export {
|
|
|
42
46
|
* @property {JourneyContext} journeyContext Context including changes
|
|
43
47
|
* @property {JourneyContext} previousContext Context prior to changes
|
|
44
48
|
* @property {object} session Request session object
|
|
49
|
+
* @property {ContextEventUserInfo} userInfo User-space information pass-through
|
|
45
50
|
*/
|
|
46
51
|
|
|
47
52
|
/**
|
|
@@ -50,6 +55,11 @@ export {
|
|
|
50
55
|
* @returns {void}
|
|
51
56
|
*/
|
|
52
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @typedef {object} ContextEventUserInfo
|
|
60
|
+
* @property {symbol} [casaRequestPhase] Request phase at which event is triggered
|
|
61
|
+
*/
|
|
62
|
+
|
|
53
63
|
/**
|
|
54
64
|
* @typedef {object} ContextEvent
|
|
55
65
|
* @property {string} waypoint Waypoint to watch for changes
|
|
@@ -358,7 +358,7 @@ export default class JourneyContext {
|
|
|
358
358
|
purge(waypoints = []) {
|
|
359
359
|
const newData = Object.create(null);
|
|
360
360
|
const newValidation = Object.create(null);
|
|
361
|
-
const toKeep = Object.keys(this
|
|
361
|
+
const toKeep = Object.keys(this.#data).filter((w) => !waypoints.includes(w));
|
|
362
362
|
|
|
363
363
|
// ESLint disabled as `i` is an integer
|
|
364
364
|
/* eslint-disable security/detect-object-injection */
|
|
@@ -367,7 +367,6 @@ export default class JourneyContext {
|
|
|
367
367
|
newValidation[toKeep[i]] = this.#validation[toKeep[i]];
|
|
368
368
|
}
|
|
369
369
|
/* eslint-enable security/detect-object-injection */
|
|
370
|
-
|
|
371
370
|
this.#data = { ...newData };
|
|
372
371
|
this.#validation = { ...newValidation };
|
|
373
372
|
}
|
|
@@ -408,12 +407,16 @@ export default class JourneyContext {
|
|
|
408
407
|
/**
|
|
409
408
|
* Execute all listeners for the given event.
|
|
410
409
|
*
|
|
410
|
+
* The `userInfo` parameter is simply passed straight through to the event
|
|
411
|
+
* listeners.
|
|
412
|
+
*
|
|
411
413
|
* @param {object} params Params
|
|
412
414
|
* @param {string} params.event Event (waypoint-change | context-change)
|
|
413
415
|
* @param {object} params.session Session
|
|
416
|
+
* @param {ContextEventUserInfo|object} [params.userInfo] Pass-through info
|
|
414
417
|
* @returns {JourneyContext} Chain
|
|
415
418
|
*/
|
|
416
|
-
applyEventListeners({ event, session }) {
|
|
419
|
+
applyEventListeners({ event, session, userInfo }) {
|
|
417
420
|
if (!this.#eventListeners.length) {
|
|
418
421
|
return this;
|
|
419
422
|
}
|
|
@@ -450,7 +453,12 @@ export default class JourneyContext {
|
|
|
450
453
|
|
|
451
454
|
if (runHandler) {
|
|
452
455
|
log.trace(logMessage);
|
|
453
|
-
handler({
|
|
456
|
+
handler({
|
|
457
|
+
journeyContext: this,
|
|
458
|
+
previousContext,
|
|
459
|
+
session,
|
|
460
|
+
userInfo,
|
|
461
|
+
});
|
|
454
462
|
}
|
|
455
463
|
}
|
|
456
464
|
/* eslint-enable security/detect-object-injection */
|
|
@@ -641,10 +649,12 @@ export default class JourneyContext {
|
|
|
641
649
|
*
|
|
642
650
|
* @param {object} session Request session
|
|
643
651
|
* @param {JourneyContext} context Context
|
|
652
|
+
* @param {object} options Options
|
|
653
|
+
* @param {ContextEventUserInfo|object} [options.userInfo] Pass-through event info
|
|
644
654
|
* @returns {void}
|
|
645
655
|
* @throws {TypeError} When session is not a valid type, or context has no ID
|
|
646
656
|
*/
|
|
647
|
-
static putContext(session, context) {
|
|
657
|
+
static putContext(session, context, options = {}) {
|
|
648
658
|
if (!isObject(session)) {
|
|
649
659
|
throw new TypeError('Session must be an object');
|
|
650
660
|
} else if (!(context instanceof JourneyContext)) {
|
|
@@ -659,14 +669,18 @@ export default class JourneyContext {
|
|
|
659
669
|
}
|
|
660
670
|
|
|
661
671
|
// Apply context events
|
|
672
|
+
const { userInfo = undefined } = options;
|
|
673
|
+
|
|
662
674
|
context.applyEventListeners({
|
|
663
675
|
event: 'waypoint-change',
|
|
664
676
|
session,
|
|
677
|
+
userInfo,
|
|
665
678
|
});
|
|
666
679
|
|
|
667
680
|
context.applyEventListeners({
|
|
668
681
|
event: 'context-change',
|
|
669
682
|
session,
|
|
683
|
+
userInfo,
|
|
670
684
|
});
|
|
671
685
|
|
|
672
686
|
const list = new Map(session.journeyContextList);
|
package/src/lib/Plan.js
CHANGED
|
@@ -24,11 +24,6 @@ const log = logger('lib:plan');
|
|
|
24
24
|
* @typedef {import('../casa').PlanArbiter} PlanArbiter
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* @access private
|
|
29
|
-
* @typedef {import('@dagrejs/graphlib').Graph} Graph
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
27
|
/**
|
|
33
28
|
* @typedef {object} PlanConstructorOptions
|
|
34
29
|
* @property {boolean} [validateBeforeRouteCondition=true] Check page validity before conditions
|
|
@@ -567,7 +562,7 @@ export default class Plan {
|
|
|
567
562
|
target = arbiter({
|
|
568
563
|
targets: target.map((t) => makeRouteObject(self.dgraph, t)),
|
|
569
564
|
journeyContext: context,
|
|
570
|
-
|
|
565
|
+
travereOptions: options,
|
|
571
566
|
});
|
|
572
567
|
target = target.map((r) => ({ v: r.source, w: r.target, name: r.name }));
|
|
573
568
|
} else {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* General-purpose references to the different request lifecycle phases.
|
|
3
|
+
*/
|
|
4
|
+
export const REQUEST_PHASE_STEER = Symbol('steer');
|
|
5
|
+
export const REQUEST_PHASE_SANITISE = Symbol('sanitise');
|
|
6
|
+
export const REQUEST_PHASE_GATHER = Symbol('gather');
|
|
7
|
+
export const REQUEST_PHASE_VALIDATE = Symbol('validate');
|
|
8
|
+
export const REQUEST_PHASE_REDIRECT = Symbol('redirect');
|
|
9
|
+
export const REQUEST_PHASE_RENDER = Symbol('render');
|
package/src/lib/waypoint-url.js
CHANGED
|
@@ -15,6 +15,34 @@ const reUrlProtocolExtract = /^url:\/\/(.+)$/i
|
|
|
15
15
|
*/
|
|
16
16
|
const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g, '/');
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Sanitise a waypoint string, with allowed URL parameters:
|
|
20
|
+
* contextid = JourneyContext ID
|
|
21
|
+
*
|
|
22
|
+
* @access private
|
|
23
|
+
* @param {string} w Waypoint and potential URL parameters
|
|
24
|
+
* @returns {string} Sanitised waypoint
|
|
25
|
+
*/
|
|
26
|
+
const sanitiseWaypointWithAllowedParams = (w) => {
|
|
27
|
+
// Extract URL params
|
|
28
|
+
const parts = w.split('?');
|
|
29
|
+
if (parts.length !== 2) {
|
|
30
|
+
return sanitiseWaypoint(w);
|
|
31
|
+
}
|
|
32
|
+
const [waypoint, rawParams] = parts;
|
|
33
|
+
const urlSearchParams = new URLSearchParams(rawParams);
|
|
34
|
+
|
|
35
|
+
// Strip all but those parameters allowed
|
|
36
|
+
const validatedUrlSearchParams = new URLSearchParams();
|
|
37
|
+
for (const pk of ['contextid']) {
|
|
38
|
+
if (urlSearchParams.has(pk)) {
|
|
39
|
+
validatedUrlSearchParams.set(pk, urlSearchParams.get(pk));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return `${sanitiseWaypoint(waypoint)}?${validatedUrlSearchParams.toString()}`.replace(/\?$/, '');
|
|
44
|
+
}
|
|
45
|
+
|
|
18
46
|
/**
|
|
19
47
|
* Generate a URL pointing at a particular waypoint.
|
|
20
48
|
*
|
|
@@ -53,13 +81,18 @@ export default function waypointUrl({
|
|
|
53
81
|
if (String(waypoint).substr(0, 7) === 'url:///') {
|
|
54
82
|
const m = waypoint.match(reUrlProtocolExtract);
|
|
55
83
|
|
|
56
|
-
const u = new URL(m[1], 'https://placeholder.test/');
|
|
84
|
+
const u = new URL(sanitiseWaypointWithAllowedParams(m[1]), 'https://placeholder.test/');
|
|
57
85
|
url.pathname = `${sanitiseWaypoint(u.pathname)}/_/`;
|
|
58
86
|
|
|
59
|
-
url.searchParams.
|
|
60
|
-
url.searchParams.
|
|
87
|
+
url.searchParams.set('refmount', `url://${mountUrl}`);
|
|
88
|
+
url.searchParams.set('route', routeName);
|
|
89
|
+
for (const [uk, uv] of u.searchParams.entries()) {
|
|
90
|
+
url.searchParams.append(uk, uv);
|
|
91
|
+
}
|
|
61
92
|
} else {
|
|
62
|
-
|
|
93
|
+
const u = new URL(sanitiseWaypointWithAllowedParams(`${mountUrl}${waypoint}`), 'https://placeholder.test/');
|
|
94
|
+
url.pathname = u.pathname;
|
|
95
|
+
url.search = u.search;
|
|
63
96
|
}
|
|
64
97
|
|
|
65
98
|
// Attach context ID as query parameter for non-default contexts.
|
|
@@ -70,23 +103,23 @@ export default function waypointUrl({
|
|
|
70
103
|
journeyContext
|
|
71
104
|
&& !journeyContext.isDefault()
|
|
72
105
|
&& journeyContext.identity.id
|
|
73
|
-
&& !mountUrl.includes(journeyContext.identity.id)
|
|
106
|
+
&& !mountUrl.includes(`/${journeyContext.identity.id}/`)
|
|
74
107
|
) {
|
|
75
|
-
url.searchParams.
|
|
108
|
+
url.searchParams.set('contextid', journeyContext.identity.id);
|
|
76
109
|
}
|
|
77
110
|
|
|
78
111
|
// Attach edit mode flag
|
|
79
112
|
if (edit === true) {
|
|
80
|
-
url.searchParams.
|
|
113
|
+
url.searchParams.set('edit', 'true');
|
|
81
114
|
}
|
|
82
115
|
|
|
83
116
|
if (edit && editOrigin) {
|
|
84
|
-
url.searchParams.
|
|
117
|
+
url.searchParams.set('editorigin', sanitiseWaypointWithAllowedParams(editOrigin));
|
|
85
118
|
}
|
|
86
119
|
|
|
87
120
|
// Skipto
|
|
88
121
|
if (skipTo) {
|
|
89
|
-
url.searchParams.
|
|
122
|
+
url.searchParams.set('skipto', sanitiseWaypointWithAllowedParams(skipTo));
|
|
90
123
|
}
|
|
91
124
|
|
|
92
125
|
return `${sanitiseWaypoint(url.pathname)}${url.search}`;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// - Remove validation date of JourneyContext so it can re-evaluted
|
|
5
5
|
|
|
6
6
|
import JourneyContext from '../lib/JourneyContext.js';
|
|
7
|
+
import { REQUEST_PHASE_GATHER } from '../lib/constants.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @access private
|
|
@@ -41,10 +42,16 @@ export default ({
|
|
|
41
42
|
}
|
|
42
43
|
/* eslint-enable security/detect-object-injection */
|
|
43
44
|
|
|
44
|
-
// Update data and validation context in the current request, and store
|
|
45
|
+
// Update data and validation context in the current request, and store.
|
|
46
|
+
// The validation state is removed here because we must assume the gathered
|
|
47
|
+
// data is invalid until proven otherwise when the validation step is run.
|
|
45
48
|
req.casa.journeyContext.setDataForPage(waypoint, persistentBody);
|
|
46
49
|
req.casa.journeyContext.removeValidationStateForPage(waypoint);
|
|
47
|
-
JourneyContext.putContext(req.session, req.casa.journeyContext
|
|
50
|
+
JourneyContext.putContext(req.session, req.casa.journeyContext, {
|
|
51
|
+
userInfo: {
|
|
52
|
+
casaRequestPhase: REQUEST_PHASE_GATHER,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
48
55
|
|
|
49
56
|
next();
|
|
50
57
|
},
|
|
@@ -6,11 +6,16 @@ import Plan from '../lib/Plan.js';
|
|
|
6
6
|
import JourneyContext from '../lib/JourneyContext.js';
|
|
7
7
|
import waypointUrl from '../lib/waypoint-url.js';
|
|
8
8
|
import logger from '../lib/logger.js';
|
|
9
|
+
import { REQUEST_PHASE_REDIRECT } from '../lib/constants.js';
|
|
9
10
|
|
|
10
11
|
const log = logger('middleware:progress-journey');
|
|
11
12
|
|
|
12
13
|
const saveAndRedirect = (session, journeyContext, url, res, next) => {
|
|
13
|
-
JourneyContext.putContext(session, journeyContext
|
|
14
|
+
JourneyContext.putContext(session, journeyContext, {
|
|
15
|
+
userInfo: {
|
|
16
|
+
casaRequestPhase: REQUEST_PHASE_REDIRECT,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
14
19
|
|
|
15
20
|
session.save((err) => {
|
|
16
21
|
if (err) {
|
|
@@ -73,7 +78,6 @@ export default ({
|
|
|
73
78
|
if (Plan.isExitNode(nextWaypoint)) {
|
|
74
79
|
log.trace(`Next waypoint is an exit node; clearing validation state on ${nextWaypoint}`);
|
|
75
80
|
req.casa.journeyContext.clearValidationErrorsForPage(nextWaypoint);
|
|
76
|
-
JourneyContext.putContext(req.session, req.casa.journeyContext);
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
// Construct the next url
|