@dwp/govuk-casa 7.0.6 → 8.0.0-alpha1
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/README.md +22 -17
- package/dist/{casa → assets}/css/casa-ie8.css +1 -1
- package/dist/assets/css/casa.css +1 -0
- package/dist/casa.d.ts +10 -0
- package/dist/casa.js +44 -0
- package/dist/lib/CasaTemplateLoader.d.ts +19 -0
- package/dist/lib/CasaTemplateLoader.js +57 -0
- package/dist/lib/JourneyContext.d.ts +255 -0
- package/dist/lib/JourneyContext.js +681 -0
- package/dist/lib/MutableRouter.d.ts +155 -0
- package/dist/lib/MutableRouter.js +272 -0
- package/dist/lib/Plan.d.ts +119 -0
- package/dist/lib/Plan.js +382 -0
- package/dist/lib/ValidationError.d.ts +70 -0
- package/dist/lib/ValidationError.js +156 -0
- package/dist/lib/ValidatorFactory.d.ts +24 -0
- package/dist/lib/ValidatorFactory.js +87 -0
- package/dist/lib/configure.d.ts +205 -0
- package/dist/lib/configure.js +215 -0
- package/dist/lib/dirname.cjs +1 -0
- package/dist/lib/end-session.d.ts +12 -0
- package/dist/lib/end-session.js +24 -0
- package/dist/lib/field.d.ts +79 -0
- package/dist/lib/field.js +223 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.js +19 -0
- package/dist/lib/nunjucks-filters.d.ts +26 -0
- package/dist/lib/nunjucks-filters.js +112 -0
- package/dist/lib/nunjucks.d.ts +22 -0
- package/dist/lib/nunjucks.js +49 -0
- package/dist/lib/utils.d.ts +22 -0
- package/dist/lib/utils.js +44 -0
- package/dist/lib/validators/dateObject.d.ts +4 -0
- package/dist/lib/validators/dateObject.js +135 -0
- package/dist/lib/validators/email.d.ts +4 -0
- package/dist/lib/validators/email.js +46 -0
- package/dist/lib/validators/inArray.d.ts +4 -0
- package/dist/lib/validators/inArray.js +60 -0
- package/dist/lib/validators/index.d.ts +21 -0
- package/dist/lib/validators/index.js +47 -0
- package/dist/lib/validators/nino.d.ts +4 -0
- package/dist/lib/validators/nino.js +46 -0
- package/dist/lib/validators/postalAddressObject.d.ts +4 -0
- package/dist/lib/validators/postalAddressObject.js +123 -0
- package/dist/lib/validators/regex.d.ts +4 -0
- package/dist/lib/validators/regex.js +40 -0
- package/dist/lib/validators/required.d.ts +4 -0
- package/dist/lib/validators/required.js +56 -0
- package/dist/lib/validators/strlen.d.ts +4 -0
- package/dist/lib/validators/strlen.js +51 -0
- package/dist/lib/validators/wordCount.d.ts +5 -0
- package/dist/lib/validators/wordCount.js +54 -0
- package/dist/lib/waypoint-url.d.ts +17 -0
- package/dist/lib/waypoint-url.js +46 -0
- package/dist/middleware/body-parser.d.ts +1 -0
- package/dist/middleware/body-parser.js +24 -0
- package/dist/middleware/csrf.d.ts +1 -0
- package/dist/middleware/csrf.js +31 -0
- package/dist/middleware/data.d.ts +6 -0
- package/dist/middleware/data.js +53 -0
- package/dist/middleware/dirname.cjs +1 -0
- package/dist/middleware/gather-fields.d.ts +5 -0
- package/dist/middleware/gather-fields.js +39 -0
- package/dist/middleware/i18n.d.ts +4 -0
- package/dist/middleware/i18n.js +87 -0
- package/dist/middleware/post.d.ts +1 -0
- package/dist/middleware/post.js +42 -0
- package/dist/middleware/pre.d.ts +3 -0
- package/dist/middleware/pre.js +38 -0
- package/dist/middleware/progress-journey.d.ts +6 -0
- package/dist/middleware/progress-journey.js +82 -0
- package/dist/middleware/sanitise-fields.d.ts +5 -0
- package/dist/middleware/sanitise-fields.js +48 -0
- package/dist/middleware/session.d.ts +10 -0
- package/dist/middleware/session.js +115 -0
- package/dist/middleware/skip-waypoint.d.ts +5 -0
- package/dist/middleware/skip-waypoint.js +40 -0
- package/dist/middleware/steer-journey.d.ts +6 -0
- package/dist/middleware/steer-journey.js +44 -0
- package/dist/middleware/validate-fields.d.ts +7 -0
- package/dist/middleware/validate-fields.js +76 -0
- package/dist/mjs/esm-wrapper.js +10 -0
- package/dist/mjs/package.json +3 -0
- package/dist/package.json +3 -0
- package/dist/routes/ancillary.d.ts +4 -0
- package/dist/routes/ancillary.js +19 -0
- package/dist/routes/dirname.cjs +1 -0
- package/dist/routes/journey.d.ts +8 -0
- package/dist/routes/journey.js +130 -0
- package/dist/routes/static.d.ts +26 -0
- package/dist/routes/static.js +67 -0
- package/package.json +45 -86
- package/views/casa/components/checkboxes/template.njk +4 -1
- package/views/casa/components/date-input/template.njk +3 -3
- package/views/casa/components/journey-form/README.md +3 -1
- package/views/casa/components/journey-form/template.njk +1 -1
- package/views/casa/components/postal-address-object/template.njk +5 -5
- package/views/casa/components/radios/template.njk +1 -1
- package/views/casa/layouts/journey.njk +26 -9
- package/views/casa/layouts/main.njk +6 -19
- package/views/casa/partials/scripts.njk +8 -3
- package/views/casa/partials/styles.njk +2 -2
- package/casa.js +0 -208
- package/definitions/review-page.js +0 -60
- package/dist/casa/css/casa.css +0 -1
- package/dist/casa/js/casa.js +0 -1
- package/index.d.ts +0 -121
- package/lib/ConfigIngestor.js +0 -588
- package/lib/GatherModifier.js +0 -14
- package/lib/I18n.js +0 -160
- package/lib/JourneyContext.d.ts +0 -97
- package/lib/JourneyContext.js +0 -552
- package/lib/JourneyMap.js +0 -233
- package/lib/JourneyRoad.js +0 -330
- package/lib/Logger.js +0 -59
- package/lib/PageDictionary.d.ts +0 -11
- package/lib/PageDirectory.js +0 -77
- package/lib/Plan.js +0 -423
- package/lib/RoadConverter.js +0 -153
- package/lib/UserJourney.js +0 -8
- package/lib/Util.js +0 -227
- package/lib/Validation.js +0 -20
- package/lib/bootstrap/end-session.js +0 -44
- package/lib/bootstrap/load-definitions.js +0 -64
- package/lib/commonBodyParser.js +0 -15
- package/lib/enums.js +0 -6
- package/lib/gather-modifiers/index.js +0 -7
- package/lib/gather-modifiers/trimPostalAddressObject.js +0 -75
- package/lib/gather-modifiers/trimWhitespace.js +0 -16
- package/lib/utils/createGetRequest.d.ts +0 -5
- package/lib/utils/createGetRequest.js +0 -59
- package/lib/utils/index.js +0 -11
- package/lib/utils/parseRequest.d.ts +0 -5
- package/lib/utils/parseRequest.js +0 -72
- package/lib/utils/sanitise.js +0 -74
- package/lib/utils/validate.js +0 -32
- package/lib/validation/ArrayObjectField.js +0 -49
- package/lib/validation/ObjectField.js +0 -53
- package/lib/validation/SimpleField.d.ts +0 -11
- package/lib/validation/SimpleField.js +0 -46
- package/lib/validation/ValidationError.d.ts +0 -14
- package/lib/validation/ValidationError.js +0 -170
- package/lib/validation/ValidatorFactory.d.ts +0 -32
- package/lib/validation/ValidatorFactory.js +0 -91
- package/lib/validation/index.js +0 -22
- package/lib/validation/processor/flattenErrorArray.js +0 -24
- package/lib/validation/processor/queue.js +0 -214
- package/lib/validation/processor.js +0 -84
- package/lib/validation/rules/README.md +0 -3
- package/lib/validation/rules/ValidationRules.d.ts +0 -22
- package/lib/validation/rules/dateObject.js +0 -156
- package/lib/validation/rules/email.js +0 -44
- package/lib/validation/rules/inArray.js +0 -61
- package/lib/validation/rules/index.js +0 -23
- package/lib/validation/rules/nino.js +0 -48
- package/lib/validation/rules/optional.js +0 -14
- package/lib/validation/rules/postalAddressObject.js +0 -142
- package/lib/validation/rules/regex.js +0 -39
- package/lib/validation/rules/required.js +0 -57
- package/lib/validation/rules/strlen.js +0 -57
- package/lib/validation/rules/wordCount.js +0 -61
- package/lib/view-filters/formatDateObject.js +0 -35
- package/lib/view-filters/includes.js +0 -10
- package/lib/view-filters/index.js +0 -23
- package/lib/view-filters/mergeObjectsDeep.js +0 -21
- package/lib/view-filters/renderAsAttributes.js +0 -33
- package/middleware/errors/404.js +0 -12
- package/middleware/errors/catch-all.js +0 -27
- package/middleware/errors/index.js +0 -9
- package/middleware/headers/config-defaults.js +0 -57
- package/middleware/headers/headers.js +0 -40
- package/middleware/headers/index.js +0 -9
- package/middleware/i18n/i18n.js +0 -56
- package/middleware/i18n/index.js +0 -16
- package/middleware/index.js +0 -55
- package/middleware/mount/index.js +0 -9
- package/middleware/mount/mount.js +0 -10
- package/middleware/nunjucks/environment.js +0 -57
- package/middleware/nunjucks/index.js +0 -8
- package/middleware/page/csrf.js +0 -37
- package/middleware/page/edit-mode.js +0 -52
- package/middleware/page/gather.js +0 -75
- package/middleware/page/index.js +0 -103
- package/middleware/page/journey-continue.js +0 -157
- package/middleware/page/journey-rails.js +0 -102
- package/middleware/page/prepare-request.js +0 -77
- package/middleware/page/render.js +0 -75
- package/middleware/page/skip.js +0 -72
- package/middleware/page/utils.js +0 -206
- package/middleware/page/validate.js +0 -67
- package/middleware/session/expiry.js +0 -95
- package/middleware/session/genid.js +0 -18
- package/middleware/session/index.js +0 -18
- package/middleware/session/init.js +0 -25
- package/middleware/session/seed.js +0 -50
- package/middleware/session/timeout.js +0 -5
- package/middleware/static/asset-versions.js +0 -23
- package/middleware/static/index.js +0 -104
- package/middleware/static/prepare-assets.js +0 -51
- package/middleware/static/serve-assets.js +0 -58
- package/middleware/variables/index.js +0 -12
- package/middleware/variables/variables.js +0 -35
- package/src/browserconfig.xml +0 -5
- package/src/js/casa.js +0 -132
- package/src/scss/_casaElements.scss +0 -11
- package/src/scss/_casaGovukTemplateJinjaPolyfill.scss +0 -39
- package/src/scss/_casaMountUrl.scss +0 -8
- package/src/scss/casa-ie8.scss +0 -3
- package/src/scss/casa.scss +0 -14
- package/test/unit/templates/README.md +0 -5
- package/test/utils/BaseTestWaypoint.js +0 -106
- package/test/utils/concatWaypoints.js +0 -26
- package/test/utils/index.js +0 -6
- package/test/utils/testTraversal.js +0 -90
- package/views/casa/partials/cookie_message.njk +0 -3
- package/views/casa/partials/phase_banner_alpha.njk +0 -8
- package/views/casa/partials/phase_banner_beta.njk +0 -8
- package/views/casa/review/page-block.njk +0 -8
- package/views/casa/review/review.njk +0 -47
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function _default(): import("connect").NextHandleFunction[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const express_1 = require("express");
|
|
4
|
+
function default_1() {
|
|
5
|
+
const rProto = /__proto__/i;
|
|
6
|
+
const rPrototype = /prototype[=[\]]/i;
|
|
7
|
+
const rConstructor = /constructor[=[\]]/i;
|
|
8
|
+
return [
|
|
9
|
+
(0, express_1.urlencoded)({
|
|
10
|
+
extended: true,
|
|
11
|
+
type: 'application/x-www-form-urlencoded',
|
|
12
|
+
inflate: true,
|
|
13
|
+
parameterLimit: 25,
|
|
14
|
+
limit: 1024 * 50,
|
|
15
|
+
verify: (req, res, buf, encoding) => {
|
|
16
|
+
const body = decodeURI(buf.toString(encoding));
|
|
17
|
+
if (rProto.test(body) || rPrototype.test(body) || rConstructor.test(body)) {
|
|
18
|
+
throw new Error('Request body verification failed');
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
exports.default = default_1;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function _default(): any[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const csurf_1 = __importDefault(require("csurf"));
|
|
7
|
+
// 2 middleware: one to generate the csrf token and check its validity (POST
|
|
8
|
+
// only), and one to provide that token to templates via the `casa.csrfToken`
|
|
9
|
+
// variable.
|
|
10
|
+
function default_1() {
|
|
11
|
+
return [
|
|
12
|
+
(0, csurf_1.default)({
|
|
13
|
+
cookie: false,
|
|
14
|
+
sessionKey: 'session',
|
|
15
|
+
// value: (req) => {
|
|
16
|
+
// // Here we clear the token after extracting to maintain cleaner data. It
|
|
17
|
+
// // is only used for this CSRF purpose.
|
|
18
|
+
// const token = String(req.body._csrf);
|
|
19
|
+
// delete req.body._csrf;
|
|
20
|
+
// return token;
|
|
21
|
+
// /* eslint-enable no-underscore-dangle */
|
|
22
|
+
// },
|
|
23
|
+
}),
|
|
24
|
+
(req, res, next) => {
|
|
25
|
+
var _a;
|
|
26
|
+
res.locals.casa = Object.assign(Object.assign({}, (_a = res.locals) === null || _a === void 0 ? void 0 : _a.casa), { csrfToken: req.csrfToken() });
|
|
27
|
+
next();
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
exports.default = default_1;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Decorates the request with some contextual data about the user's journey
|
|
3
|
+
// through the application. This is used by downstream middleware and templates.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const lodash_1 = require("lodash");
|
|
9
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
10
|
+
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
11
|
+
const editOrigin = (req) => {
|
|
12
|
+
if ((0, lodash_1.has)(req.query, 'editorigin')) {
|
|
13
|
+
return (0, waypoint_url_js_1.default)({ waypoint: req.query.editorigin });
|
|
14
|
+
}
|
|
15
|
+
else if ((0, lodash_1.has)(req === null || req === void 0 ? void 0 : req.body, 'editorigin')) {
|
|
16
|
+
return (0, waypoint_url_js_1.default)({ waypoint: req.body.editorigin });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
function default_1({ plan, mountUrl, serviceName, events, }) {
|
|
20
|
+
return [
|
|
21
|
+
(req, res, next) => {
|
|
22
|
+
/* ------------------------------------------------ Request decorations */
|
|
23
|
+
// CASA
|
|
24
|
+
req.casa = Object.assign(Object.assign({}, req === null || req === void 0 ? void 0 : req.casa), {
|
|
25
|
+
// The plan
|
|
26
|
+
plan,
|
|
27
|
+
// Current journey context, loaded from session, specified by
|
|
28
|
+
// `contextid` request parameter
|
|
29
|
+
journeyContext: JourneyContext_js_1.default.extractContextFromRequest(req).addEventListeners(events),
|
|
30
|
+
// Edit mode attributes
|
|
31
|
+
editMode: (0, lodash_1.has)(req.query, 'edit') || (0, lodash_1.has)(req === null || req === void 0 ? void 0 : req.body, 'edit'), editOrigin: editOrigin(req) });
|
|
32
|
+
/* ------------------------------------------------- Template variables */
|
|
33
|
+
// CASA and userland templates
|
|
34
|
+
res.locals.casa = {
|
|
35
|
+
mountUrl,
|
|
36
|
+
serviceName,
|
|
37
|
+
};
|
|
38
|
+
res.locals.locale = req.language;
|
|
39
|
+
// Used by govuk-frontend template
|
|
40
|
+
// - req.language is provided by i18n-http-middleware
|
|
41
|
+
res.locals.htmlLang = req.language;
|
|
42
|
+
// res.locals.makeLink
|
|
43
|
+
// res.locals.casa.journeyPreviousUrl
|
|
44
|
+
// req.session.journeyContext
|
|
45
|
+
// req.session.language
|
|
46
|
+
// req.editOriginUrl
|
|
47
|
+
// req.inEditMode
|
|
48
|
+
// req.editSearchParams
|
|
49
|
+
next();
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
exports.default = default_1;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = __dirname;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Gather the field data from `req.body` into the current JourneyContext
|
|
3
|
+
// - Store in the current session
|
|
4
|
+
// - Update the user's journey context with the new data
|
|
5
|
+
// - Remove validation date of JourneyContext so it can re-evaluted
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
11
|
+
/**
|
|
12
|
+
* @param {Object} obj
|
|
13
|
+
* @param {string} obj.waypoint Waypoint
|
|
14
|
+
* @param {PageField[]} [obj.fields=[]] Fields
|
|
15
|
+
*/
|
|
16
|
+
exports.default = ({ waypoint, fields = [], }) => [
|
|
17
|
+
(req, res, next) => {
|
|
18
|
+
// Store a copy of the journey context before modifying it. This is useful
|
|
19
|
+
// for any comparison work that may be done in subseqent middleware.
|
|
20
|
+
req.casa.archivedJourneyContext = JourneyContext_js_1.default.fromContext(req.casa.journeyContext);
|
|
21
|
+
// Ignore data for any non-persistent fields
|
|
22
|
+
const persistentBody = Object.create(null);
|
|
23
|
+
for (let i = 0, l = fields.length; i < l; i++) {
|
|
24
|
+
if (fields[i].meta.persist && fields[i].getValue(req.body) !== undefined) {
|
|
25
|
+
persistentBody[fields[i].name] = fields[i].getValue(req.body);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Update data and validation context in the current request, and store
|
|
29
|
+
req.casa.journeyContext.setDataForPage(waypoint, persistentBody);
|
|
30
|
+
req.casa.journeyContext.removeValidationStateForPage(waypoint);
|
|
31
|
+
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext);
|
|
32
|
+
// TODO: Once feature we might like here is to invalidate specific pages
|
|
33
|
+
// based on the change that has just happened, to force those pages to be
|
|
34
|
+
// visited again. The main use case is to cater for a change in content on
|
|
35
|
+
// those pages that fundamentally alter the context of the question being asked,
|
|
36
|
+
// and so should be asked again. For example, "Your address" vs "You and your partner's address"
|
|
37
|
+
next();
|
|
38
|
+
}
|
|
39
|
+
];
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const i18next_1 = __importDefault(require("i18next"));
|
|
7
|
+
const i18next_http_middleware_1 = require("i18next-http-middleware");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const deepmerge_1 = __importDefault(require("deepmerge"));
|
|
11
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
12
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
13
|
+
const log = (0, logger_js_1.default)('middleware.i18n');
|
|
14
|
+
const loadJson = (file) => {
|
|
15
|
+
// Strip out newlines (this is a legacy feature which we're keeping for
|
|
16
|
+
// backwards compatibility).
|
|
17
|
+
let json = (0, fs_1.readFileSync)(file, 'utf8');
|
|
18
|
+
return JSON.parse(json.replace(/[\r\n]/g, ''));
|
|
19
|
+
};
|
|
20
|
+
const loadYaml = (file) => {
|
|
21
|
+
return js_yaml_1.default.load((0, fs_1.readFileSync)(file, 'utf8'));
|
|
22
|
+
};
|
|
23
|
+
const extract = (file) => {
|
|
24
|
+
const ext = /.yaml$/i.test(file) ? '.yaml' : '.json';
|
|
25
|
+
const data = ext === '.yaml' ? loadYaml(file) : loadJson(file);
|
|
26
|
+
return {
|
|
27
|
+
ns: (0, path_1.basename)(file, ext),
|
|
28
|
+
data,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const loadResources = (languages, directories) => {
|
|
32
|
+
const store = Object.create(null);
|
|
33
|
+
languages.forEach((language) => {
|
|
34
|
+
store[language] = Object.create(null);
|
|
35
|
+
directories.forEach((dir) => {
|
|
36
|
+
dir = (0, path_1.resolve)(dir, language);
|
|
37
|
+
if (!(0, fs_1.existsSync)(dir))
|
|
38
|
+
return;
|
|
39
|
+
log.info('Loading %s language from %s ...', language, dir);
|
|
40
|
+
(0, fs_1.readdirSync)(dir).forEach((file) => {
|
|
41
|
+
const { ns, data } = extract((0, path_1.resolve)(dir, file));
|
|
42
|
+
if (store[language][ns] === undefined) {
|
|
43
|
+
store[language][ns] = Object.create(null);
|
|
44
|
+
}
|
|
45
|
+
store[language][ns] = (0, deepmerge_1.default)(store[language][ns], data);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
return store;
|
|
50
|
+
};
|
|
51
|
+
function default_1({ languages = ['en', 'cy'], directories = [], }) {
|
|
52
|
+
// Load _all_ translations, from all directories into memory.
|
|
53
|
+
const resources = loadResources(languages, directories);
|
|
54
|
+
// Configure i18next
|
|
55
|
+
const i18nInstance = i18next_1.default.createInstance();
|
|
56
|
+
i18nInstance
|
|
57
|
+
.use(i18next_http_middleware_1.LanguageDetector)
|
|
58
|
+
.init({
|
|
59
|
+
initImmediate: false,
|
|
60
|
+
supportedLngs: languages,
|
|
61
|
+
fallbackLng: false,
|
|
62
|
+
defaultNS: 'common',
|
|
63
|
+
// debug: true,
|
|
64
|
+
// All translation resources
|
|
65
|
+
resources,
|
|
66
|
+
// LanguageDetector options
|
|
67
|
+
detection: {
|
|
68
|
+
lookupQuerystring: 'lang',
|
|
69
|
+
lookupSession: 'language',
|
|
70
|
+
order: ['querystring', 'session'],
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
// 2 middleware: one to read/set the session language, and one to enhance the req/res objects with i18n features
|
|
74
|
+
return [
|
|
75
|
+
(req, res, next) => {
|
|
76
|
+
if (!req.session.language) {
|
|
77
|
+
req.session.language = languages[0];
|
|
78
|
+
}
|
|
79
|
+
if ((req === null || req === void 0 ? void 0 : req.query.lang) && languages.includes(req.query.lang)) {
|
|
80
|
+
req.session.language = String(req.query.lang);
|
|
81
|
+
}
|
|
82
|
+
next();
|
|
83
|
+
},
|
|
84
|
+
(0, i18next_http_middleware_1.handle)(i18nInstance),
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
exports.default = default_1;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function _default(): ((err: any, req: any, res: any, next: any) => any)[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
// 2 middleware: one as a fallback 404 handler, one to handle thrown errors
|
|
7
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
8
|
+
const log = (0, logger_js_1.default)('middleware:post');
|
|
9
|
+
function default_1() {
|
|
10
|
+
return [
|
|
11
|
+
(req, res, next) => {
|
|
12
|
+
res.render('casa/errors/404.njk');
|
|
13
|
+
},
|
|
14
|
+
(err, req, res, next) => {
|
|
15
|
+
// CSRF token is invalid in some way
|
|
16
|
+
if ((err === null || err === void 0 ? void 0 : err.code) === 'EBADCSRFTOKEN') {
|
|
17
|
+
log.info('CSRF validation has failed. This may be caused by the user submitting a stale form from a previous session [EBADCSRFTOKEN]');
|
|
18
|
+
return res.status(403).render('casa/errors/500.njk');
|
|
19
|
+
}
|
|
20
|
+
// Body parsing verification check failed
|
|
21
|
+
if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.verify.failed') {
|
|
22
|
+
log.info('Body parser verification has failed. This has been caused by the user submitting a payload containing invalid data [entity.verify.failed]');
|
|
23
|
+
return res.status(403).render('casa/errors/500.njk');
|
|
24
|
+
}
|
|
25
|
+
// Too many parameters submitted
|
|
26
|
+
if ((err === null || err === void 0 ? void 0 : err.type) === 'parameters.too.many') {
|
|
27
|
+
log.info('The request contains more parameters than is currently allowed [parameters.too.many]');
|
|
28
|
+
return res.status(413).render('casa/errors/500.njk');
|
|
29
|
+
}
|
|
30
|
+
// Overall payload too large
|
|
31
|
+
if ((err === null || err === void 0 ? void 0 : err.type) === 'entity.too.large') {
|
|
32
|
+
log.info(`The request payload is too large. Received ${err.length}b with a maximum of ${err.limit}b [parameters.too.many]`);
|
|
33
|
+
return res.status(413).render('casa/errors/500.njk');
|
|
34
|
+
}
|
|
35
|
+
// Unknown error
|
|
36
|
+
log.error(`Unknown error: ${err.message}; stacktrace: ${err.stack}`);
|
|
37
|
+
res.render('casa/errors/500.njk');
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
exports.default = default_1;
|
|
42
|
+
;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
const helmet_1 = __importDefault(require("helmet"));
|
|
8
|
+
exports.default = () => [
|
|
9
|
+
// Prevent caching response in any intermediaries by default, in case it
|
|
10
|
+
// contains sensitive data.
|
|
11
|
+
// The `no-store` setting is to specifically disable the bfcache and prevent
|
|
12
|
+
// possible leakage of information.
|
|
13
|
+
(req, res, next) => {
|
|
14
|
+
res.set('cache-control', 'no-cache, no-store, must-revalidate, private');
|
|
15
|
+
res.set('pragma', 'no-cache');
|
|
16
|
+
res.set('expires', 0);
|
|
17
|
+
res.set('x-robots-tag', 'noindex, nofollow');
|
|
18
|
+
next();
|
|
19
|
+
},
|
|
20
|
+
// Generate nonces ready for use in Content-Security-Policy header and
|
|
21
|
+
// govuk-frontend template. This same none can be used wherever required.
|
|
22
|
+
(req, res, next) => {
|
|
23
|
+
res.locals.cspNonce = (0, crypto_1.randomBytes)(16).toString("hex");
|
|
24
|
+
next();
|
|
25
|
+
},
|
|
26
|
+
// Helmet suite of headers
|
|
27
|
+
(0, helmet_1.default)({
|
|
28
|
+
// Allows GA which is typically used, and a known inline script nonce
|
|
29
|
+
contentSecurityPolicy: {
|
|
30
|
+
useDefaults: true,
|
|
31
|
+
directives: {
|
|
32
|
+
"script-src": ["'self'", "www.google-analytics.com", "www.googletagmanager.com", (req, res) => `'nonce-${res.locals.cspNonce}'`],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
// // Require referrer to aid navigation
|
|
36
|
+
// referrerPolicy: 'no-referrer, same-origin',
|
|
37
|
+
}),
|
|
38
|
+
];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Determine where to take the user next
|
|
3
|
+
// We assume that the waypoint has been validated prior to reaching this
|
|
4
|
+
// middleware.
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const Plan_js_1 = __importDefault(require("../lib/Plan.js"));
|
|
10
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
11
|
+
const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
|
|
12
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
13
|
+
const log = (0, logger_js_1.default)('middleware:progress-journey');
|
|
14
|
+
const saveAndRedirect = (session, journeyContext, url, res, next) => {
|
|
15
|
+
JourneyContext_js_1.default.putContext(session, journeyContext);
|
|
16
|
+
session.save((err) => {
|
|
17
|
+
if (err)
|
|
18
|
+
next(err);
|
|
19
|
+
res.redirect(302, url);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
exports.default = ({ waypoint, plan, mountUrl, }) => [
|
|
23
|
+
(req, res, next) => {
|
|
24
|
+
// Determine the next available waypoint after the current one
|
|
25
|
+
const traversed = plan.traverse(req.casa.journeyContext);
|
|
26
|
+
const currentIndex = traversed.indexOf(waypoint);
|
|
27
|
+
const nextIndex = Math.max(currentIndex < 0 ? traversed.length - 1 : 0, Math.min(currentIndex + 1, traversed.length - 1));
|
|
28
|
+
const nextWaypoint = traversed[nextIndex];
|
|
29
|
+
log.trace(`currentIndex = ${currentIndex}, nextIndex = ${nextIndex}, currentWaypoint = ${waypoint}, nextWaypoint = ${nextWaypoint}`);
|
|
30
|
+
// TODO: edit mode ---------- !!! considering the dependency graph instead, which will invalidate pages, meaning we can keep sticky mode as the default - the below, redirecting back to origin is fine to leave as is, because the next traversal in steer-journey will put the user on the right waypoint
|
|
31
|
+
// When in edit mode, these are the options for redirecting:
|
|
32
|
+
// - Try sending straight back to editOrigin - if it can't be reached, the "rails" middleware will redirect the user accordingly
|
|
33
|
+
//
|
|
34
|
+
// TODO: if the edit origin is on another sub-app, only that plan will get travsersed, so the user might miss out on forms in between.
|
|
35
|
+
// Or it might be on the same app, but a Plan exists in the middle of this plan, so need to be sure to travsrse that plan fully too.
|
|
36
|
+
// It's looking more likely that we'll need Plans to talk with each other, but that's a headache.
|
|
37
|
+
// Keep it simple.
|
|
38
|
+
// Restrict the functionality. Don't allow this scenario. Devs will need to resort to waya around it. Wait for community to build things and see what solutions emerge for doption into this framework.
|
|
39
|
+
// Edit mode
|
|
40
|
+
// Attempt to take the user back to their original URL. We rely on the
|
|
41
|
+
// `steer-journey` middleware to prevent the user going too far ahead in
|
|
42
|
+
// their permitted journey.
|
|
43
|
+
// Keep the edit mode on this redirect. This means the user can keep
|
|
44
|
+
// "jumping" ahead in the journey until they get back to the original URL.
|
|
45
|
+
if (req.casa.editMode && req.casa.editOrigin) {
|
|
46
|
+
// TODO: Need tyo detect if we're already on the editOrigin on this request.
|
|
47
|
+
// If so, need to fall through so we can get directed to the next waypoint in the journey
|
|
48
|
+
const url = new URL(req.casa.editOrigin, 'https://placeholder.test/');
|
|
49
|
+
url.searchParams.append('edit', 'true');
|
|
50
|
+
url.searchParams.append('editorigin', req.casa.editOrigin);
|
|
51
|
+
const redirectUrl = (0, waypoint_url_js_1.default)({ waypoint: url.pathname }) + url.search.toString();
|
|
52
|
+
log.debug(`Edit mode detected; redirecting to ${redirectUrl}`);
|
|
53
|
+
return saveAndRedirect(req.session, req.casa.journeyContext, redirectUrl, res, next);
|
|
54
|
+
}
|
|
55
|
+
// If the next URL is an "exit node", we need to flag that node as
|
|
56
|
+
// being validated so that subsequent traversals of this journey continue
|
|
57
|
+
// correctly to any waypoints leading on from this one.
|
|
58
|
+
// This effectively says that the other Plan linked to by the exit node is
|
|
59
|
+
// complete, but of course that may not be the case.
|
|
60
|
+
// It would be prudent for developers to add a conditions to the route to
|
|
61
|
+
// check is this is the case, eg
|
|
62
|
+
// setRoute('a', 'b');
|
|
63
|
+
// setRoute('b', 'url:///otherapp/')
|
|
64
|
+
// setRoute('url:////otherapp/', 'c', (r, c) => checkIfOtherAppIsFinished())
|
|
65
|
+
if (Plan_js_1.default.isExitNode(nextWaypoint)) {
|
|
66
|
+
log.trace(`Next waypoint is an exit node; clearing validation state on ${nextWaypoint}`);
|
|
67
|
+
req.casa.journeyContext.clearValidationErrorsForPage(nextWaypoint);
|
|
68
|
+
JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext);
|
|
69
|
+
}
|
|
70
|
+
// Construct the next url
|
|
71
|
+
const nextUrl = (0, waypoint_url_js_1.default)({
|
|
72
|
+
waypoint: nextWaypoint,
|
|
73
|
+
mountUrl,
|
|
74
|
+
journeyContext: req.casa.journeyContext,
|
|
75
|
+
edit: req.casa.editMode,
|
|
76
|
+
editOrigin: req.casa.editOrigin,
|
|
77
|
+
});
|
|
78
|
+
// Save and move on
|
|
79
|
+
log.trace(`Redirecting to ${nextUrl}`);
|
|
80
|
+
saveAndRedirect(req.session, req.casa.journeyContext, nextUrl, res, next);
|
|
81
|
+
},
|
|
82
|
+
];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Sanitise the fields submitted from a form
|
|
3
|
+
// - Coerce each field to its correct type
|
|
4
|
+
// - Remove an extraneous fields that are not know to the application
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
10
|
+
const field_js_1 = __importDefault(require("../lib/field.js"));
|
|
11
|
+
const JourneyContext_js_1 = __importDefault(require("../lib/JourneyContext.js"));
|
|
12
|
+
exports.default = ({ waypoint, fields = [], }) => {
|
|
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((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
|
+
// Middleware
|
|
19
|
+
return [
|
|
20
|
+
(req, res, next) => {
|
|
21
|
+
// First, prune all undefined, or unknown fields from `req.body` (i.e.
|
|
22
|
+
// those that do not have an entry in `fields`)
|
|
23
|
+
const prunedBody = Object.create(null);
|
|
24
|
+
for (let i = 0, l = fields.length; i < l; i++) {
|
|
25
|
+
if (lodash_1.default.has(req.body, fields[i].name) && req.body[fields[i].name] !== undefined) {
|
|
26
|
+
prunedBody[fields[i].name] = req.body[fields[i].name];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// TODO: the journey context passed to the processors and conditions, with data set to the "prunedBody"
|
|
30
|
+
const journeyContext = JourneyContext_js_1.default.fromContext(req.casa.journeyContext);
|
|
31
|
+
journeyContext.setDataForPage(waypoint, prunedBody);
|
|
32
|
+
// const journeyContext = {};
|
|
33
|
+
// Second, prune any fields that do not pass the validation conditional,
|
|
34
|
+
// and process those that do.
|
|
35
|
+
const sanitisedBody = Object.create(null);
|
|
36
|
+
for (let i = 0, l = fields.length; i < l; i++) {
|
|
37
|
+
const field = fields[i];
|
|
38
|
+
let fieldValue = field.getValue(prunedBody); // prunedBody[field.name];
|
|
39
|
+
if (fieldValue !== undefined && field.testConditions({ fieldValue, waypoint, journeyContext })) {
|
|
40
|
+
field.putValue(sanitisedBody, field.applyProcessors(fieldValue));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Finally, write the sanitised body back to the request object
|
|
44
|
+
req.body = sanitisedBody;
|
|
45
|
+
next();
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default function _default({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, store, }: {
|
|
2
|
+
cookieParserMiddleware: any;
|
|
3
|
+
secret: any;
|
|
4
|
+
name: any;
|
|
5
|
+
secure: any;
|
|
6
|
+
ttl: any;
|
|
7
|
+
mountUrl?: string | undefined;
|
|
8
|
+
cookieSameSite?: boolean | undefined;
|
|
9
|
+
store?: any;
|
|
10
|
+
}): any[];
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
// A last-modified cookie is used to control whether the end user sees a
|
|
26
|
+
// session-timeout page, or they are simply given a new session without
|
|
27
|
+
// interrupting their journey.
|
|
28
|
+
const express_session_1 = __importStar(require("express-session"));
|
|
29
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
30
|
+
const log = (0, logger_js_1.default)('middleware:session');
|
|
31
|
+
// 3 middleware:
|
|
32
|
+
// - set the session cookie
|
|
33
|
+
// - parse request cookies
|
|
34
|
+
// - handle expiry of server-side session
|
|
35
|
+
function default_1({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, store = new express_session_1.MemoryStore(), }) {
|
|
36
|
+
const commonCookieOptions = {
|
|
37
|
+
httpOnly: true,
|
|
38
|
+
path: '/',
|
|
39
|
+
secure,
|
|
40
|
+
};
|
|
41
|
+
if (cookieSameSite !== false) {
|
|
42
|
+
commonCookieOptions.sameSite = cookieSameSite === true ? 'Strict' : cookieSameSite;
|
|
43
|
+
}
|
|
44
|
+
const ttlGrace = 1800; // user will see session-timeout if session expires within 30mins
|
|
45
|
+
const touchCookieName = `${name}.t`;
|
|
46
|
+
const touchCookieOptions = Object.assign(Object.assign({}, commonCookieOptions), { maxAge: (ttl + ttlGrace) * 1000, signed: true });
|
|
47
|
+
const touchCookie = (res) => {
|
|
48
|
+
// Touch cookie expiry is 3a short period after the session ttl. This gives
|
|
49
|
+
// a small period of time where a user will see the session-timeout message,
|
|
50
|
+
// which is important to avoid the confusion of simply being redirected back
|
|
51
|
+
// to the start of their journey.
|
|
52
|
+
res.cookie(touchCookieName, (new Date(Date.now())).toUTCString(), touchCookieOptions);
|
|
53
|
+
};
|
|
54
|
+
const removeCookie = (res) => {
|
|
55
|
+
res.clearCookie(touchCookieName, touchCookieOptions);
|
|
56
|
+
};
|
|
57
|
+
return [
|
|
58
|
+
(0, express_session_1.default)({
|
|
59
|
+
secret: secret,
|
|
60
|
+
name: name,
|
|
61
|
+
saveUninitialized: false,
|
|
62
|
+
resave: false,
|
|
63
|
+
cookie: Object.assign(Object.assign({}, commonCookieOptions), { maxAge: null }),
|
|
64
|
+
store,
|
|
65
|
+
}),
|
|
66
|
+
cookieParserMiddleware,
|
|
67
|
+
(req, res, next) => {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
let lastModified = Date.parse(String((_a = req.signedCookies[touchCookieName]) !== null && _a !== void 0 ? _a : '1970-01-01T00:00:00+0000'));
|
|
70
|
+
lastModified = isNaN(lastModified) ? 0 : Math.floor(lastModified * 0.001); // convert to seconds
|
|
71
|
+
const age = Math.floor(Date.now() * 0.001) - lastModified;
|
|
72
|
+
if (lastModified === 0) {
|
|
73
|
+
// New session, or grace period cookie no longer available after
|
|
74
|
+
// expiring; generate a new session, and create grace-period cookie.
|
|
75
|
+
// This will invalidate any CSRF tokens, so by letting the request POST
|
|
76
|
+
// requests through the user may see a 500 error response.
|
|
77
|
+
log.info('Session is new, or grace period has expired. Regenerating session.');
|
|
78
|
+
req.session.regenerate((err) => {
|
|
79
|
+
if (err)
|
|
80
|
+
return next(err);
|
|
81
|
+
touchCookie(res);
|
|
82
|
+
if (req.method === 'POST') {
|
|
83
|
+
log.info('The CSRF token for this POST request will now be invalid for this regenerated session. Redirecting to app mount point.');
|
|
84
|
+
res.redirect(302, mountUrl);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
next();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else if (age > ttl) {
|
|
92
|
+
// Cookie has become stale and server session will have been removed;
|
|
93
|
+
// redirect to session-timeout
|
|
94
|
+
log.info('Session has timed out within grace period. Destroying session and redirecting to timeout page.');
|
|
95
|
+
const language = (_b = req.session.language) !== null && _b !== void 0 ? _b : 'en';
|
|
96
|
+
req.session.destroy((err) => {
|
|
97
|
+
if (err)
|
|
98
|
+
return next(err);
|
|
99
|
+
removeCookie(res);
|
|
100
|
+
const params = new URLSearchParams({
|
|
101
|
+
referrer: req.originalUrl,
|
|
102
|
+
lang: language,
|
|
103
|
+
});
|
|
104
|
+
res.redirect(302, `${mountUrl}session-timeout?${params.toString()}`);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Touch cookie and continue
|
|
109
|
+
touchCookie(res);
|
|
110
|
+
next();
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
exports.default = default_1;
|