@dwp/govuk-casa 8.0.0-alpha2 → 8.0.0-beta1
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 +3 -1
- package/dist/lib/CasaTemplateLoader.d.ts +6 -2
- package/dist/lib/CasaTemplateLoader.js +4 -1
- package/dist/lib/JourneyContext.d.ts +37 -6
- package/dist/lib/JourneyContext.js +21 -6
- package/dist/lib/MutableRouter.js +3 -1
- package/dist/lib/Plan.d.ts +37 -4
- package/dist/lib/Plan.js +63 -6
- package/dist/lib/ValidationError.d.ts +6 -2
- package/dist/lib/ValidationError.js +3 -0
- package/dist/lib/ValidatorFactory.d.ts +72 -19
- package/dist/lib/ValidatorFactory.js +33 -20
- package/dist/lib/configuration-ingestor.d.ts +262 -0
- package/dist/lib/configuration-ingestor.js +490 -0
- package/dist/lib/configure.d.ts +26 -140
- package/dist/lib/configure.js +16 -43
- package/dist/lib/dirname.d.cts +2 -0
- package/dist/lib/end-session.d.ts +2 -1
- package/dist/lib/end-session.js +24 -7
- package/dist/lib/field.d.ts +38 -45
- package/dist/lib/field.js +56 -34
- package/dist/lib/index.d.ts +14 -0
- package/dist/lib/index.js +54 -0
- package/dist/lib/logger.d.ts +2 -1
- package/dist/lib/logger.js +2 -3
- package/dist/lib/utils.d.ts +18 -2
- package/dist/lib/utils.js +54 -2
- package/dist/lib/waypoint-url.d.ts +2 -1
- package/dist/lib/waypoint-url.js +3 -0
- package/dist/middleware/body-parser.js +2 -2
- package/dist/middleware/data.d.ts +1 -2
- package/dist/middleware/data.js +4 -8
- package/dist/middleware/dirname.d.cts +2 -0
- package/dist/middleware/gather-fields.d.ts +2 -1
- package/dist/middleware/gather-fields.js +3 -0
- package/dist/middleware/post.js +6 -6
- package/dist/middleware/sanitise-fields.js +4 -4
- package/dist/middleware/session.d.ts +2 -1
- package/dist/middleware/session.js +2 -2
- package/dist/middleware/steer-journey.d.ts +2 -1
- package/dist/middleware/steer-journey.js +3 -0
- package/dist/routes/ancillary.d.ts +8 -1
- package/dist/routes/ancillary.js +7 -0
- package/dist/routes/dirname.d.cts +2 -0
- package/dist/routes/journey.js +9 -2
- package/dist/routes/static.js +4 -3
- package/package.json +27 -17
- package/views/casa/layouts/main.njk +2 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Just used to collate type information for intellisense. This should not get
|
|
4
|
+
* imported anywhere in code, other than JSDoc references.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.waypointUrl = exports.ValidatorFactory = exports.ValidationError = exports.utils = exports.Plan = exports.MutableRouter = exports.JourneyContext = exports.PageField = exports.field = exports.endSession = exports.configurationIngestor = exports.configure = exports.CasaTemplateLoader = void 0;
|
|
30
|
+
const CasaTemplateLoader_js_1 = __importDefault(require("./CasaTemplateLoader.js"));
|
|
31
|
+
exports.CasaTemplateLoader = CasaTemplateLoader_js_1.default;
|
|
32
|
+
const configure_js_1 = __importDefault(require("./configure.js"));
|
|
33
|
+
exports.configure = configure_js_1.default;
|
|
34
|
+
const configuration_ingestor_js_1 = __importDefault(require("./configuration-ingestor.js"));
|
|
35
|
+
exports.configurationIngestor = configuration_ingestor_js_1.default;
|
|
36
|
+
const end_session_js_1 = __importDefault(require("./end-session.js"));
|
|
37
|
+
exports.endSession = end_session_js_1.default;
|
|
38
|
+
const field_js_1 = __importStar(require("./field.js"));
|
|
39
|
+
exports.field = field_js_1.default;
|
|
40
|
+
Object.defineProperty(exports, "PageField", { enumerable: true, get: function () { return field_js_1.PageField; } });
|
|
41
|
+
const JourneyContext_js_1 = __importDefault(require("./JourneyContext.js"));
|
|
42
|
+
exports.JourneyContext = JourneyContext_js_1.default;
|
|
43
|
+
const MutableRouter_js_1 = __importDefault(require("./MutableRouter.js"));
|
|
44
|
+
exports.MutableRouter = MutableRouter_js_1.default;
|
|
45
|
+
const Plan_js_1 = __importDefault(require("./Plan.js"));
|
|
46
|
+
exports.Plan = Plan_js_1.default;
|
|
47
|
+
const ValidationError_js_1 = __importDefault(require("./ValidationError.js"));
|
|
48
|
+
exports.ValidationError = ValidationError_js_1.default;
|
|
49
|
+
const ValidatorFactory_js_1 = __importDefault(require("./ValidatorFactory.js"));
|
|
50
|
+
exports.ValidatorFactory = ValidatorFactory_js_1.default;
|
|
51
|
+
const waypoint_url_js_1 = __importDefault(require("./waypoint-url.js"));
|
|
52
|
+
exports.waypointUrl = waypoint_url_js_1.default;
|
|
53
|
+
const utils = __importStar(require("./utils.js"));
|
|
54
|
+
exports.utils = utils;
|
package/dist/lib/logger.d.ts
CHANGED
package/dist/lib/logger.js
CHANGED
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const debug_1 = __importDefault(require("debug"));
|
|
7
7
|
const casaDebugger = (0, debug_1.default)('casa');
|
|
8
|
-
|
|
8
|
+
exports.default = (ns) => {
|
|
9
9
|
const logger = casaDebugger.extend(ns);
|
|
10
10
|
return {
|
|
11
11
|
trace: logger.extend('trace'),
|
|
@@ -15,5 +15,4 @@ function default_1(ns) {
|
|
|
15
15
|
error: logger.extend('error'),
|
|
16
16
|
fatal: logger.extend('fatal'),
|
|
17
17
|
};
|
|
18
|
-
}
|
|
19
|
-
exports.default = default_1;
|
|
18
|
+
};
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('./configuration-ingestor').GlobalHook} GlobalHook
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('./configuration-ingestor').PageHook} PageHook
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {GlobalHook | PageHook} Hook
|
|
9
|
+
*/
|
|
1
10
|
/**
|
|
2
11
|
* Test is a value can be stringifed (numbers or strings)
|
|
3
12
|
*
|
|
@@ -27,6 +36,13 @@ export function isEmpty(val: any): boolean;
|
|
|
27
36
|
* @param {string} hookName Hook name (including scope prefix)
|
|
28
37
|
* @param {string} path URL path to match (relative to mountUrl)
|
|
29
38
|
* @param {Hook[]} hooks Hooks to be applied at the page level
|
|
30
|
-
* @returns {
|
|
39
|
+
* @returns {Function[]} An array of middleware that should be applied
|
|
31
40
|
*/
|
|
32
|
-
export function resolveMiddlewareHooks(hookName: string, path: string, hooks?:
|
|
41
|
+
export function resolveMiddlewareHooks(hookName: string, path: string, hooks?: Hook[]): Function[];
|
|
42
|
+
export function validateWaypoint(waypoint: any): void;
|
|
43
|
+
export function validateView(view: any): void;
|
|
44
|
+
export function validateHookName(hookName: any): void;
|
|
45
|
+
export function validateHookPath(path: any): void;
|
|
46
|
+
export type GlobalHook = import('./configuration-ingestor').GlobalHook;
|
|
47
|
+
export type PageHook = import('./configuration-ingestor').PageHook;
|
|
48
|
+
export type Hook = GlobalHook | PageHook;
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import('./configuration-ingestor').GlobalHook} GlobalHook
|
|
4
|
+
*/
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveMiddlewareHooks = exports.isEmpty = exports.stringifyInput = exports.isStringable = void 0;
|
|
6
|
+
exports.validateHookPath = exports.validateHookName = exports.validateView = exports.validateWaypoint = exports.resolveMiddlewareHooks = exports.isEmpty = exports.stringifyInput = exports.isStringable = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('./configuration-ingestor').PageHook} PageHook
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {GlobalHook | PageHook} Hook
|
|
12
|
+
*/
|
|
4
13
|
/**
|
|
5
14
|
* Test is a value can be stringifed (numbers or strings)
|
|
6
15
|
*
|
|
@@ -49,7 +58,7 @@ exports.isEmpty = isEmpty;
|
|
|
49
58
|
* @param {string} hookName Hook name (including scope prefix)
|
|
50
59
|
* @param {string} path URL path to match (relative to mountUrl)
|
|
51
60
|
* @param {Hook[]} hooks Hooks to be applied at the page level
|
|
52
|
-
* @returns {
|
|
61
|
+
* @returns {Function[]} An array of middleware that should be applied
|
|
53
62
|
*/
|
|
54
63
|
function resolveMiddlewareHooks(hookName, path, hooks = []) {
|
|
55
64
|
/* eslint-disable-next-line max-len */
|
|
@@ -57,3 +66,46 @@ function resolveMiddlewareHooks(hookName, path, hooks = []) {
|
|
|
57
66
|
return hooks.filter((h) => h.hook === hookName).filter(pathMatch).map((h) => h.middleware);
|
|
58
67
|
}
|
|
59
68
|
exports.resolveMiddlewareHooks = resolveMiddlewareHooks;
|
|
69
|
+
/* ------------------------------------------------ validation / sanitisation */
|
|
70
|
+
function validateWaypoint(waypoint) {
|
|
71
|
+
if (typeof waypoint !== 'string') {
|
|
72
|
+
throw new TypeError('Waypoint must be a string');
|
|
73
|
+
}
|
|
74
|
+
if (!waypoint.length) {
|
|
75
|
+
throw new SyntaxError('Waypoint must not be empty');
|
|
76
|
+
}
|
|
77
|
+
if (waypoint.match(/[^/a-z0-9_-]/)) {
|
|
78
|
+
throw new SyntaxError('Waypoint must contain only a-z, 0-9, -, _ and / characters');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.validateWaypoint = validateWaypoint;
|
|
82
|
+
function validateView(view) {
|
|
83
|
+
if (typeof view !== 'string') {
|
|
84
|
+
throw new TypeError('View must be a string');
|
|
85
|
+
}
|
|
86
|
+
if (!view.length) {
|
|
87
|
+
throw new SyntaxError('View must not be empty');
|
|
88
|
+
}
|
|
89
|
+
if (!view.match(/^[a-z0-9/_-]+\.njk$/i)) {
|
|
90
|
+
throw new SyntaxError('View must contain only a-z, 0-9, -, _ and / characters, and end in .njk');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.validateView = validateView;
|
|
94
|
+
function validateHookName(hookName) {
|
|
95
|
+
if (typeof hookName !== 'string') {
|
|
96
|
+
throw new TypeError('Hook name must be a string');
|
|
97
|
+
}
|
|
98
|
+
if (!hookName.length) {
|
|
99
|
+
throw new SyntaxError('Hook name must not be empty');
|
|
100
|
+
}
|
|
101
|
+
if (!hookName.match(/^([a-z]+\.|)[a-z]+$/i)) {
|
|
102
|
+
throw new SyntaxError('Hook name must match either <scope>.<hookname> or <hookname> formats');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.validateHookName = validateHookName;
|
|
106
|
+
function validateHookPath(path) {
|
|
107
|
+
if (typeof path !== 'string' && !(path instanceof RegExp)) {
|
|
108
|
+
throw new TypeError('Hook path must be a string or RegExp');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.validateHookPath = validateHookPath;
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
export default function waypointUrl({ waypoint, mountUrl, journeyContext, edit, editOrigin, skipTo, routeName, }?: {
|
|
15
15
|
waypoint: string;
|
|
16
16
|
mountUrl: string;
|
|
17
|
-
journeyContext:
|
|
17
|
+
journeyContext: JourneyContext;
|
|
18
18
|
edit: boolean;
|
|
19
19
|
editOrigin: string;
|
|
20
20
|
skipTo: boolean;
|
|
21
21
|
routeName: string;
|
|
22
22
|
}): string;
|
|
23
|
+
export type JourneyContext = import('./index').JourneyContext;
|
package/dist/lib/waypoint-url.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import('./index').JourneyContext} JourneyContext
|
|
4
|
+
*/
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const reUrlProtocolExtract = /^url:\/\/(.+)$/i;
|
|
4
7
|
const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g, '/');
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const express_1 = require("express");
|
|
4
4
|
function bodyParserMiddleware() {
|
|
5
5
|
const rProto = /__proto__/i;
|
|
6
|
-
const rPrototype = /prototype[=[\]]/i;
|
|
7
|
-
const rConstructor = /constructor[=[\]]/i;
|
|
6
|
+
const rPrototype = /prototype[='"[\]]/i;
|
|
7
|
+
const rConstructor = /constructor[='"[\]]/i;
|
|
8
8
|
return [
|
|
9
9
|
(0, express_1.urlencoded)({
|
|
10
10
|
extended: true,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export default function dataMiddleware({ plan, mountUrl,
|
|
1
|
+
export default function dataMiddleware({ plan, mountUrl, events, }: {
|
|
2
2
|
plan: any;
|
|
3
3
|
mountUrl: any;
|
|
4
|
-
serviceName: any;
|
|
5
4
|
events: any;
|
|
6
5
|
}): ((req: any, res: any, next: any) => void)[];
|
package/dist/middleware/data.js
CHANGED
|
@@ -18,7 +18,7 @@ const editOrigin = (req) => {
|
|
|
18
18
|
}
|
|
19
19
|
return '';
|
|
20
20
|
};
|
|
21
|
-
function dataMiddleware({ plan, mountUrl,
|
|
21
|
+
function dataMiddleware({ plan, mountUrl, events, }) {
|
|
22
22
|
return [
|
|
23
23
|
(req, res, next) => {
|
|
24
24
|
/* ------------------------------------------------ Request decorations */
|
|
@@ -37,18 +37,14 @@ function dataMiddleware({ plan, mountUrl, serviceName, events, }) {
|
|
|
37
37
|
// CASA and userland templates
|
|
38
38
|
res.locals.casa = {
|
|
39
39
|
mountUrl,
|
|
40
|
-
serviceName,
|
|
41
40
|
};
|
|
42
41
|
res.locals.locale = req.language;
|
|
43
42
|
// Used by govuk-frontend template
|
|
44
43
|
// - req.language is provided by i18n-http-middleware
|
|
45
44
|
res.locals.htmlLang = req.language;
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
// req.session.language
|
|
50
|
-
// req.editOriginUrl
|
|
51
|
-
// req.inEditMode
|
|
45
|
+
// Function for building URLs. This will be curried with the `mountUrl`
|
|
46
|
+
// and `journeyContext` for convenience
|
|
47
|
+
res.locals.waypointUrl = (args) => (0, waypoint_url_js_1.default)(Object.assign({ mountUrl, journeyContext: req.casa.journeyContext }, args));
|
|
52
48
|
// req.editSearchParams
|
|
53
49
|
next();
|
|
54
50
|
},
|
|
@@ -8,6 +8,9 @@ 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
|
+
/**
|
|
12
|
+
* @typedef {import('../lib/field').PageField} PageField
|
|
13
|
+
*/
|
|
11
14
|
/**
|
|
12
15
|
* Gather the field data from `req.body` into the current JourneyContext
|
|
13
16
|
* - Store in the current session
|
package/dist/middleware/post.js
CHANGED
|
@@ -26,31 +26,31 @@ function postMiddleware({ mountUrl, }) {
|
|
|
26
26
|
// CSRF token is invalid in some way
|
|
27
27
|
if ((err === null || err === void 0 ? void 0 : err.code) === 'EBADCSRFTOKEN') {
|
|
28
28
|
log.info('CSRF validation has failed. This may be caused by the user submitting a stale form from a previous session [EBADCSRFTOKEN]');
|
|
29
|
-
return res.status(403).render(TEMPLATE);
|
|
29
|
+
return res.status(403).render(TEMPLATE, { errorCode: 'bad_csrf_token' });
|
|
30
30
|
}
|
|
31
31
|
// Body parsing verification check failed
|
|
32
32
|
if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.verify.failed') {
|
|
33
33
|
log.info('Body parser verification has failed. This has been caused by the user submitting a payload containing invalid data [entity.verify.failed]');
|
|
34
|
-
return res.status(403).render(TEMPLATE);
|
|
34
|
+
return res.status(403).render(TEMPLATE, { errorCode: 'invalid_payload' });
|
|
35
35
|
}
|
|
36
36
|
// Too many parameters submitted
|
|
37
37
|
if ((err === null || err === void 0 ? void 0 : err.type) === 'parameters.too.many') {
|
|
38
38
|
log.info('The request contains more parameters than is currently allowed [parameters.too.many]');
|
|
39
|
-
return res.status(413).render(TEMPLATE);
|
|
39
|
+
return res.status(413).render(TEMPLATE, { errorCode: 'parameter_limit_exceeded' });
|
|
40
40
|
}
|
|
41
41
|
// Overall payload too large
|
|
42
42
|
if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.too.large') {
|
|
43
43
|
log.info(`The request payload is too large. Received ${err.length}b with a maximum of ${err.limit}b [parameters.too.many]`);
|
|
44
|
-
return res.status(413).render(TEMPLATE);
|
|
44
|
+
return res.status(413).render(TEMPLATE, { errorCode: 'payload_size_exceeded' });
|
|
45
45
|
}
|
|
46
46
|
// Unaccept request method
|
|
47
47
|
if ((err === null || err === void 0 ? void 0 : err.code) === 'unaccepted_request_method') {
|
|
48
48
|
log.info(err.message);
|
|
49
|
-
return res.status(400).render(TEMPLATE);
|
|
49
|
+
return res.status(400).render(TEMPLATE, { errorCode: 'unaccepted_request_method' });
|
|
50
50
|
}
|
|
51
51
|
// Unknown error
|
|
52
52
|
log.error(`Unknown error: ${err.message}; stacktrace: ${err.stack}`);
|
|
53
|
-
return res.render(TEMPLATE);
|
|
53
|
+
return res.status(200).render(TEMPLATE);
|
|
54
54
|
},
|
|
55
55
|
];
|
|
56
56
|
}
|
|
@@ -11,10 +11,10 @@ const field_js_1 = __importDefault(require("../lib/field.js"));
|
|
|
11
11
|
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
12
12
|
exports.default = ({ waypoint, fields = [], }) => {
|
|
13
13
|
// Add some common, transient fields to ensure they survive beyond this sanitisation process
|
|
14
|
-
fields.push((0, field_js_1.default)('_csrf', { persist: false }).processor((
|
|
15
|
-
fields.push((0, field_js_1.default)('contextid', { persist: false }).processor((
|
|
16
|
-
fields.push((0, field_js_1.default)('edit', { persist: false }).processor((
|
|
17
|
-
fields.push((0, field_js_1.default)('editorigin', { persist: false }).processor((
|
|
14
|
+
fields.push((0, field_js_1.default)('_csrf', { persist: false }).processor((value) => String(value)));
|
|
15
|
+
fields.push((0, field_js_1.default)('contextid', { persist: false }).processor((value) => String(value)));
|
|
16
|
+
fields.push((0, field_js_1.default)('edit', { persist: false }).processor((value) => String(value)));
|
|
17
|
+
fields.push((0, field_js_1.default)('editorigin', { persist: false }).processor((value) => String(value)));
|
|
18
18
|
// Middleware
|
|
19
19
|
return [
|
|
20
20
|
(req, res, next) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, store, }: {
|
|
1
|
+
export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, cookiePath, store, }: {
|
|
2
2
|
cookieParserMiddleware: any;
|
|
3
3
|
secret: any;
|
|
4
4
|
name: any;
|
|
@@ -6,5 +6,6 @@ export default function sessionMiddleware({ cookieParserMiddleware, secret, name
|
|
|
6
6
|
ttl: any;
|
|
7
7
|
mountUrl?: string | undefined;
|
|
8
8
|
cookieSameSite?: boolean | undefined;
|
|
9
|
+
cookiePath?: string | undefined;
|
|
9
10
|
store?: any;
|
|
10
11
|
}): any[];
|
|
@@ -32,10 +32,10 @@ const log = (0, logger_js_1.default)('middleware:session');
|
|
|
32
32
|
// - set the session cookie
|
|
33
33
|
// - parse request cookies
|
|
34
34
|
// - handle expiry of server-side session
|
|
35
|
-
function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, store = new express_session_1.MemoryStore(), }) {
|
|
35
|
+
function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, cookiePath = '/', store = new express_session_1.MemoryStore(), }) {
|
|
36
36
|
const commonCookieOptions = {
|
|
37
37
|
httpOnly: true,
|
|
38
|
-
path:
|
|
38
|
+
path: cookiePath,
|
|
39
39
|
secure,
|
|
40
40
|
};
|
|
41
41
|
if (cookieSameSite !== false) {
|
|
@@ -8,6 +8,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
8
8
|
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
9
9
|
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
10
10
|
const log = (0, logger_js_1.default)('middleware:steer-journey');
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {import('../lib/Plan')} Plan
|
|
13
|
+
*/
|
|
11
14
|
/**
|
|
12
15
|
* This sits in front of all other journey middleware and prevents the user from
|
|
13
16
|
* "jumping ahead" in the Plan.
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an instance of the ancillary router.
|
|
3
|
+
*
|
|
4
|
+
* @param {Object} options = Optiona
|
|
5
|
+
* @param {number} options.sessionTtl Session timeout (seconds)
|
|
6
|
+
* @returns {MutableRouter} Mutable router
|
|
7
|
+
*/
|
|
1
8
|
export default function ancillaryRouter({ sessionTtl, }: {
|
|
2
|
-
sessionTtl:
|
|
9
|
+
sessionTtl: number;
|
|
3
10
|
}): MutableRouter;
|
|
4
11
|
import MutableRouter from "../lib/MutableRouter.js";
|
package/dist/routes/ancillary.js
CHANGED
|
@@ -4,6 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
|
|
7
|
+
/**
|
|
8
|
+
* Create an instance of the ancillary router.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} options = Optiona
|
|
11
|
+
* @param {number} options.sessionTtl Session timeout (seconds)
|
|
12
|
+
* @returns {MutableRouter} Mutable router
|
|
13
|
+
*/
|
|
7
14
|
function ancillaryRouter({ sessionTtl, }) {
|
|
8
15
|
// Router
|
|
9
16
|
const router = new MutableRouter_js_1.default();
|
package/dist/routes/journey.js
CHANGED
|
@@ -80,13 +80,20 @@ function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, })
|
|
|
80
80
|
const { waypoint, view, hooks: pageHooks = [], fields } = page;
|
|
81
81
|
const formUrl = (0, waypoint_url_js_1.default)({ mountUrl, waypoint });
|
|
82
82
|
const waypointPath = `/${waypoint}`;
|
|
83
|
-
|
|
83
|
+
let commonWaypointMiddleware = [
|
|
84
84
|
(req, res, next) => {
|
|
85
85
|
req.casa.waypoint = waypoint;
|
|
86
|
+
res.locals.casa.waypoint = waypoint;
|
|
86
87
|
next();
|
|
87
88
|
},
|
|
88
|
-
...(0, skip_waypoint_js_1.default)({ mountUrl, waypoint }),
|
|
89
89
|
];
|
|
90
|
+
if (plan.isSkippable(waypoint)) {
|
|
91
|
+
log.info(`Configuring "${waypoint}" as a skippable waypoint`);
|
|
92
|
+
commonWaypointMiddleware = [
|
|
93
|
+
...commonWaypointMiddleware,
|
|
94
|
+
...(0, skip_waypoint_js_1.default)({ mountUrl, waypoint }),
|
|
95
|
+
];
|
|
96
|
+
}
|
|
90
97
|
router.get(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint, mountUrl, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]), renderMiddlewareFactory(view, (req) => ({
|
|
91
98
|
formUrl,
|
|
92
99
|
formData: req.casa.journeyContext.getDataForPage(waypoint),
|
package/dist/routes/static.js
CHANGED
|
@@ -3,13 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const express_1 = require("express");
|
|
6
|
+
const express_1 = __importDefault(require("express"));
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const url_1 = require("url");
|
|
9
9
|
const path_1 = require("path");
|
|
10
10
|
const module_1 = require("module");
|
|
11
11
|
const dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
|
|
12
12
|
const MutableRouter_js_1 = __importDefault(require("../lib/MutableRouter.js"));
|
|
13
|
+
const { static: ExpressStatic } = express_1.default; // CommonJS
|
|
13
14
|
const oneDay = 86400000;
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {object} StaticOptions Options to configure static router
|
|
@@ -56,8 +57,8 @@ function staticRouter({ mountUrl = '/', maxAge = 3600000, }) {
|
|
|
56
57
|
// The static middleware will only server GET/HEAD requests, so we can mount
|
|
57
58
|
// the middleware using `use()` rather than resorting to `get()`
|
|
58
59
|
const govukFrontendDirectory = (0, path_1.resolve)((0, module_1.createRequire)(dirname_cjs_1.default).resolve('govuk-frontend'), '../../');
|
|
59
|
-
router.use('/govuk/assets/js/all.js', (
|
|
60
|
-
router.use('/govuk/assets', (
|
|
60
|
+
router.use('/govuk/assets/js/all.js', ExpressStatic(`${govukFrontendDirectory}/govuk/all.js`, staticConfig));
|
|
61
|
+
router.use('/govuk/assets', ExpressStatic(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
|
|
61
62
|
router.use('/govuk/assets', notFoundHandler);
|
|
62
63
|
router.use('/casa/assets/css/casa.css', setHeaders, (req, res) => res.send(casaCss));
|
|
63
64
|
router.use('/casa/assets/css/casa-ie8.css', setHeaders, (req, res) => res.send(casaCssIe8));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwp/govuk-casa",
|
|
3
|
-
"version": "8.0.0-
|
|
3
|
+
"version": "8.0.0-beta1",
|
|
4
4
|
"description": "A framework for building GOVUK Collect-And-Submit-Applications",
|
|
5
5
|
"main": "dist/casa.js",
|
|
6
6
|
"module": "dist/mjs/casa.js",
|
|
@@ -18,58 +18,68 @@
|
|
|
18
18
|
"node": ">=14.17.2"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
+
"pipeline": "npm test && npm run test:e2e && npm run lint",
|
|
21
22
|
"test": "mocha './tests/**/*.test.js'",
|
|
22
23
|
"test:e2e": "spiderplan --worker-init ./tests/e2e/worker-init.js --language en ./tests/e2e/personas/**/*.yaml",
|
|
24
|
+
"test:combined": "npm test; npm run test:e2e",
|
|
25
|
+
"lint": "eslint .",
|
|
26
|
+
"coverage": "c8 npm run test:combined",
|
|
23
27
|
"build": "npm run build:prepare && npm run build:sources && npm run build:css-assets",
|
|
24
28
|
"build:prepare": "rm -rf dist/* && mkdir -p dist/assets/js/ && mkdir -p dist/assets/css/",
|
|
25
29
|
"build:sources": "tsc -p tsconfig-cjs.json && ./scripts/fixup.sh",
|
|
26
30
|
"build:css-assets": "node scripts/compile-sass.js",
|
|
27
|
-
"prepare": "npm run build"
|
|
31
|
+
"prepare": "npm run build",
|
|
32
|
+
"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"
|
|
28
33
|
},
|
|
29
34
|
"keywords": [],
|
|
30
35
|
"author": "DWP Digital",
|
|
31
36
|
"license": "ISC",
|
|
32
37
|
"type": "module",
|
|
33
38
|
"dependencies": {
|
|
34
|
-
"cookie-parser": "1.4.
|
|
39
|
+
"cookie-parser": "1.4.6",
|
|
35
40
|
"csurf": "1.11.0",
|
|
36
|
-
"debug": "4.3.
|
|
41
|
+
"debug": "4.3.3",
|
|
37
42
|
"deepmerge": "4.2.2",
|
|
38
43
|
"express": "4.17.1",
|
|
39
44
|
"express-session": "1.17.2",
|
|
40
45
|
"govuk-frontend": "3.14.0",
|
|
41
46
|
"graphlib": "2.1.8",
|
|
42
47
|
"helmet": "4.6.0",
|
|
43
|
-
"i18next": "21.
|
|
48
|
+
"i18next": "21.6.0",
|
|
44
49
|
"i18next-http-middleware": "3.1.4",
|
|
45
50
|
"js-yaml": "4.1.0",
|
|
46
51
|
"lodash": "4.17.21",
|
|
47
|
-
"luxon": "2.
|
|
52
|
+
"luxon": "2.1.1",
|
|
48
53
|
"nunjucks": "3.2.3",
|
|
49
54
|
"uuid": "8.3.2",
|
|
50
|
-
"validator": "^13.
|
|
55
|
+
"validator": "^13.7.0"
|
|
51
56
|
},
|
|
52
57
|
"devDependencies": {
|
|
53
|
-
"@babel/core": "7.
|
|
54
|
-
"@babel/eslint-parser": "7.
|
|
55
|
-
"@babel/preset-env": "7.
|
|
58
|
+
"@babel/core": "7.16.0",
|
|
59
|
+
"@babel/eslint-parser": "7.16.3",
|
|
60
|
+
"@babel/preset-env": "7.16.4",
|
|
61
|
+
"@commitlint/config-conventional": "15.0.0",
|
|
56
62
|
"@dwp/casa-spiderplan": "2.0.0",
|
|
57
63
|
"@dwp/casa-spiderplan-a11y-plugin": "0.1.3",
|
|
58
64
|
"@dwp/casa-spiderplan-zap-plugin": "0.1.1",
|
|
59
|
-
"@dwp/commitlint-config-base": "1.2.0",
|
|
60
65
|
"@dwp/eslint-config-base": "5.0.1",
|
|
61
66
|
"@types/express": "4.17.13",
|
|
62
|
-
"@types/node": "16.11.
|
|
67
|
+
"@types/node": "16.11.12",
|
|
63
68
|
"@types/nunjucks": "3.2.0",
|
|
64
69
|
"babel-eslint": "10.1.0",
|
|
70
|
+
"c8": "7.10.0",
|
|
65
71
|
"chai": "4.3.4",
|
|
66
|
-
"commitlint": "
|
|
72
|
+
"commitlint": "15.0.0",
|
|
67
73
|
"eslint": "7.32.0",
|
|
68
74
|
"eslint-plugin-no-unsafe-regex": "1.0.0",
|
|
69
|
-
"eslint-plugin-sonarjs": "0.
|
|
70
|
-
"
|
|
75
|
+
"eslint-plugin-sonarjs": "0.11.0",
|
|
76
|
+
"fast-check": "2.20.0",
|
|
77
|
+
"husky": "7.0.4",
|
|
71
78
|
"mocha": "9.1.3",
|
|
72
|
-
"sass": "1.
|
|
73
|
-
"
|
|
79
|
+
"sass": "1.44.0",
|
|
80
|
+
"sinon": "12.0.1",
|
|
81
|
+
"sinon-chai": "3.7.0",
|
|
82
|
+
"supertest": "6.1.6",
|
|
83
|
+
"typescript": "4.5.3"
|
|
74
84
|
}
|
|
75
85
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{# Harcoding content for the skip link as t() may not be availble on some error pages #}
|
|
11
11
|
{{ govukSkipLink({
|
|
12
12
|
href: '#main-content',
|
|
13
|
-
text:
|
|
13
|
+
text: "Neidio i'r prif gynnwys" if locale === 'cy' else 'Skip to main content'
|
|
14
14
|
}) }}
|
|
15
15
|
{% endblock %}
|
|
16
16
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{% block header %}
|
|
19
19
|
{{ govukHeader({
|
|
20
20
|
assetsPath: assetPath + "/images",
|
|
21
|
-
serviceName: t(
|
|
21
|
+
serviceName: t('common:serviceName') if t else '',
|
|
22
22
|
serviceUrl: casa.mountUrl,
|
|
23
23
|
homepageUrl: "https://www.gov.uk/"
|
|
24
24
|
}) }}
|