@dwp/govuk-casa 8.1.0 → 8.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +2 -0
- package/dist/assets/css/casa-ie8.css +1 -1
- package/dist/assets/css/casa.css +1 -1
- package/dist/casa.d.ts +214 -0
- package/dist/casa.js +103 -0
- package/dist/lib/JourneyContext.d.ts +15 -27
- package/dist/lib/JourneyContext.js +25 -15
- package/dist/lib/configuration-ingestor.d.ts +16 -144
- package/dist/lib/configuration-ingestor.js +25 -95
- package/dist/lib/configure.d.ts +6 -77
- package/dist/lib/configure.js +58 -39
- package/dist/lib/nunjucks.d.ts +1 -6
- package/dist/lib/nunjucks.js +1 -3
- package/dist/lib/utils.d.ts +13 -10
- package/dist/lib/utils.js +40 -8
- package/dist/lib/waypoint-url.js +8 -2
- package/dist/middleware/body-parser.js +1 -1
- package/dist/middleware/data.d.ts +1 -2
- package/dist/middleware/data.js +12 -2
- package/dist/middleware/post.d.ts +1 -3
- package/dist/middleware/post.js +2 -2
- package/dist/middleware/pre.d.ts +1 -1
- package/dist/middleware/pre.js +5 -4
- package/dist/middleware/progress-journey.d.ts +1 -2
- package/dist/middleware/progress-journey.js +2 -2
- package/dist/middleware/session.d.ts +1 -2
- package/dist/middleware/session.js +7 -5
- package/dist/middleware/skip-waypoint.d.ts +1 -2
- package/dist/middleware/skip-waypoint.js +2 -2
- package/dist/middleware/steer-journey.d.ts +1 -2
- package/dist/middleware/steer-journey.js +2 -2
- package/dist/middleware/strip-proxy-path.d.ts +4 -0
- package/dist/middleware/strip-proxy-path.js +52 -0
- package/dist/middleware/validate-fields.d.ts +1 -2
- package/dist/middleware/validate-fields.js +2 -1
- package/dist/routes/journey.d.ts +1 -2
- package/dist/routes/journey.js +8 -8
- package/dist/routes/static.d.ts +1 -6
- package/dist/routes/static.js +6 -6
- package/package.json +25 -23
- package/views/casa/components/journey-form/README.md +3 -0
- package/views/casa/components/journey-form/template.njk +1 -1
- package/views/casa/partials/scripts.njk +1 -1
- package/views/casa/partials/styles.njk +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Strip any "proxy path" prefix present on the request URL
|
|
3
|
+
//
|
|
4
|
+
// The default "mountUrl" will be match whatever path that the CASA app
|
|
5
|
+
// instance will be mounted onto. So if you mount on `/a/b/c` then all
|
|
6
|
+
// URLs generated for the browser will be prefixed with `/a/b/c`.
|
|
7
|
+
//
|
|
8
|
+
// Defining a `mountUrl` will change that behaviour into a "proxy mode".
|
|
9
|
+
// This mode assumes you have a forwarding proxy that will alter
|
|
10
|
+
// the incoming request paths from `mountUrl` to the original path you
|
|
11
|
+
// have mounted this CASA app instance onto.
|
|
12
|
+
//
|
|
13
|
+
// For example, if you mount the app on `/a/b/c/x`, but want the browser
|
|
14
|
+
// URLs to just use the `/x` prefix, then pass a `mountUrl` of `/x`.
|
|
15
|
+
//
|
|
16
|
+
// See docs in `docs/guides/setup-behind-a-proxy.md`
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const logger_js_1 = __importDefault(require("../lib/logger.js"));
|
|
22
|
+
const log = (0, logger_js_1.default)('casa:middleware:strip-proxy-path');
|
|
23
|
+
exports.default = ({ mountUrl = '/', }) => [
|
|
24
|
+
(req, res, next) => {
|
|
25
|
+
// Assume everything before `mountUrl` is the proxy path prefix and remove it
|
|
26
|
+
const originalBaseUrl = req.baseUrl;
|
|
27
|
+
req.baseUrl = mountUrl.replace(/\/$/, '');
|
|
28
|
+
// If the app has been mounted directly on the specific `mountUrl`, then
|
|
29
|
+
// there's nothing we need to do and can let this request pass-through.
|
|
30
|
+
if (req.baseUrl === originalBaseUrl) {
|
|
31
|
+
next();
|
|
32
|
+
}
|
|
33
|
+
else if (req.__CASA_BASE_URL_REWRITTEN__) {
|
|
34
|
+
delete req.__CASA_BASE_URL_REWRITTEN__;
|
|
35
|
+
next();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Strip the proxy path prefix from the original URL so that
|
|
39
|
+
// subsequnt middleware sees the URL path as though proxy wasn't there.
|
|
40
|
+
// req.url will already have the proxy prefix and mountUrl removed.
|
|
41
|
+
/* eslint-disable security/detect-non-literal-regexp */
|
|
42
|
+
log.trace(`req.originalUrl before proxy stripping: ${req.originalUrl}`);
|
|
43
|
+
req.originalUrl = req.originalUrl.replace(new RegExp(`^/.+?${mountUrl}`), mountUrl);
|
|
44
|
+
log.trace(`req.originalUrl after proxy stripping: ${req.originalUrl}`);
|
|
45
|
+
/* eslint-enable security/detect-non-literal-regexp */
|
|
46
|
+
// Issuing this call will re-run this same middleware, so we use this
|
|
47
|
+
// `__CASA_BASE_URL_REWRITTEN__` flag to prevent recursion.
|
|
48
|
+
req.__CASA_BASE_URL_REWRITTEN__ = true;
|
|
49
|
+
req.app.handle(req, res, next);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
declare function _default({ waypoint, fields,
|
|
1
|
+
declare function _default({ waypoint, fields, plan, }: {
|
|
2
2
|
waypoint: any;
|
|
3
3
|
fields?: any[] | undefined;
|
|
4
|
-
mountUrl: any;
|
|
5
4
|
plan: any;
|
|
6
5
|
}): ((req: any, res: any, next: any) => any)[];
|
|
7
6
|
export default _default;
|
|
@@ -16,9 +16,10 @@ const updateContext = ({ waypoint, errors = null, journeyContext, session, }) =>
|
|
|
16
16
|
// Save to session
|
|
17
17
|
JourneyContext_js_1.default.putContext(session, journeyContext);
|
|
18
18
|
};
|
|
19
|
-
exports.default = ({ waypoint, fields = [],
|
|
19
|
+
exports.default = ({ waypoint, fields = [], plan, }) => [
|
|
20
20
|
(req, res, next) => {
|
|
21
21
|
var _a, _b;
|
|
22
|
+
const mountUrl = `${req.baseUrl}/`;
|
|
22
23
|
let errors = [];
|
|
23
24
|
for (let i = 0, l = fields.length; i < l; i++) {
|
|
24
25
|
/* eslint-disable security/detect-object-injection */
|
package/dist/routes/journey.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export default function journeyRouter({ globalHooks, pages, plan, csrfMiddleware,
|
|
1
|
+
export default function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, }: {
|
|
2
2
|
globalHooks: any;
|
|
3
3
|
pages: any;
|
|
4
4
|
plan: any;
|
|
5
5
|
csrfMiddleware: any;
|
|
6
|
-
mountUrl: any;
|
|
7
6
|
}): MutableRouter;
|
|
8
7
|
import MutableRouter from "../lib/MutableRouter.js";
|
package/dist/routes/journey.js
CHANGED
|
@@ -29,13 +29,14 @@ const renderMiddlewareFactory = (view, contextFactory) => [
|
|
|
29
29
|
});
|
|
30
30
|
},
|
|
31
31
|
];
|
|
32
|
-
function journeyRouter({ globalHooks, pages, plan, csrfMiddleware,
|
|
32
|
+
function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, }) {
|
|
33
33
|
// Router
|
|
34
34
|
const router = new MutableRouter_js_1.default();
|
|
35
35
|
// Special "_" route which handles redirecting the user between sub-apps
|
|
36
36
|
// /app1/_/?refmount=app2&route=prev
|
|
37
37
|
router.all('/_', (req, res) => {
|
|
38
38
|
var _a, _b;
|
|
39
|
+
const mountUrl = `${req.baseUrl}/`;
|
|
39
40
|
const refmount = (_a = req.query) === null || _a === void 0 ? void 0 : _a.refmount;
|
|
40
41
|
const route = (_b = req.query) === null || _b === void 0 ? void 0 : _b.route;
|
|
41
42
|
log.trace(`App root ${mountUrl}: refmount = ${refmount}, route = ${route}`);
|
|
@@ -75,7 +76,6 @@ function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, })
|
|
|
75
76
|
];
|
|
76
77
|
pages.forEach((page) => {
|
|
77
78
|
const { waypoint, view, hooks: pageHooks = [], fields } = page;
|
|
78
|
-
const formUrl = (0, waypoint_url_js_1.default)({ mountUrl, waypoint });
|
|
79
79
|
const waypointPath = `/${waypoint}`;
|
|
80
80
|
let commonWaypointMiddleware = [
|
|
81
81
|
(req, res, next) => {
|
|
@@ -88,17 +88,17 @@ function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, })
|
|
|
88
88
|
log.info(`Configuring "${waypoint}" as a skippable waypoint`);
|
|
89
89
|
commonWaypointMiddleware = [
|
|
90
90
|
...commonWaypointMiddleware,
|
|
91
|
-
...(0, skip_waypoint_js_1.default)({
|
|
91
|
+
...(0, skip_waypoint_js_1.default)({ waypoint }),
|
|
92
92
|
];
|
|
93
93
|
}
|
|
94
|
-
router.get(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint,
|
|
95
|
-
formUrl,
|
|
94
|
+
router.get(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]), renderMiddlewareFactory(view, (req) => ({
|
|
95
|
+
formUrl: (0, waypoint_url_js_1.default)({ mountUrl: `${req.baseUrl}/`, waypoint }),
|
|
96
96
|
formData: req.casa.journeyContext.getDataForPage(waypoint),
|
|
97
97
|
})));
|
|
98
|
-
router.post(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint,
|
|
98
|
+
router.post(waypointPath, ...commonMiddleware, ...commonWaypointMiddleware, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presteer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, steer_journey_js_1.default)({ waypoint, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.poststeer', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.presanitise', waypointPath, [...globalHooks, ...pageHooks]), ...(0, sanitise_fields_js_1.default)({ waypoint, fields }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.postsanitise', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.pregather', waypointPath, [...globalHooks, ...pageHooks]), ...(0, gather_fields_js_1.default)({ waypoint, fields }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.postgather', waypointPath, [...globalHooks, ...pageHooks]), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.prevalidate', waypointPath, [...globalHooks, ...pageHooks]), ...(0, validate_fields_js_1.default)({ waypoint, fields, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.postvalidate', waypointPath, [...globalHooks, ...pageHooks]),
|
|
99
99
|
// If there were validation errors, jump out of this route and into the
|
|
100
100
|
// next, where the errors will be rendered
|
|
101
|
-
(req, res, next) => (req.casa.journeyContext.hasValidationErrorsForPage(waypoint) ? next('route') : next()), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.preredirect', waypointPath, [...globalHooks, ...pageHooks]), ...(0, progress_journey_js_1.default)({ waypoint, plan
|
|
101
|
+
(req, res, next) => (req.casa.journeyContext.hasValidationErrorsForPage(waypoint) ? next('route') : next()), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.preredirect', waypointPath, [...globalHooks, ...pageHooks]), ...(0, progress_journey_js_1.default)({ waypoint, plan }));
|
|
102
102
|
router.post(waypointPath, ...(0, utils_js_1.resolveMiddlewareHooks)('journey.prerender', waypointPath, [...globalHooks, ...pageHooks]), renderMiddlewareFactory(view, (req) => {
|
|
103
103
|
var _a;
|
|
104
104
|
const errors = (_a = req.casa.journeyContext.getValidationErrorsForPageByField(waypoint)) !== null && _a !== void 0 ? _a : Object.create(null);
|
|
@@ -114,7 +114,7 @@ function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, })
|
|
|
114
114
|
href: errors[k][0].fieldHref, /* eslint-disable-line security/detect-object-injection */
|
|
115
115
|
}));
|
|
116
116
|
return {
|
|
117
|
-
formUrl,
|
|
117
|
+
formUrl: (0, waypoint_url_js_1.default)({ mountUrl: `${req.baseUrl}/`, waypoint }),
|
|
118
118
|
formData: req.body,
|
|
119
119
|
formErrors: Object.keys(errors).length ? errors : null,
|
|
120
120
|
formErrorsGovukArray: govukErrors.length ? govukErrors : null,
|
package/dist/routes/static.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {object} StaticOptions Options to configure static router
|
|
3
|
-
* @property {string} [mountUrl=/] URL prefix for govuk-frontend static assets (optional, default /)
|
|
4
3
|
* @property {number} [maxAge=3600000] Cache TTL for all assets (optional, default 1 hour)
|
|
5
4
|
*/
|
|
6
5
|
/**
|
|
@@ -9,15 +8,11 @@
|
|
|
9
8
|
* @param {StaticOptions} options Options
|
|
10
9
|
* @returns {MutableRouter} ExpressJS Router instance
|
|
11
10
|
*/
|
|
12
|
-
export default function staticRouter({
|
|
11
|
+
export default function staticRouter({ maxAge, }?: StaticOptions): MutableRouter;
|
|
13
12
|
/**
|
|
14
13
|
* Options to configure static router
|
|
15
14
|
*/
|
|
16
15
|
export type StaticOptions = {
|
|
17
|
-
/**
|
|
18
|
-
* )
|
|
19
|
-
*/
|
|
20
|
-
mountUrl?: string | undefined;
|
|
21
16
|
/**
|
|
22
17
|
* Cache TTL for all assets (optional, default 1 hour)
|
|
23
18
|
*/
|
package/dist/routes/static.js
CHANGED
|
@@ -10,11 +10,11 @@ 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 utils_js_1 = require("../lib/utils.js");
|
|
13
14
|
const { static: ExpressStatic } = express_1.default; // CommonJS
|
|
14
15
|
const oneDay = 86400000;
|
|
15
16
|
/**
|
|
16
17
|
* @typedef {object} StaticOptions Options to configure static router
|
|
17
|
-
* @property {string} [mountUrl=/] URL prefix for govuk-frontend static assets (optional, default /)
|
|
18
18
|
* @property {number} [maxAge=3600000] Cache TTL for all assets (optional, default 1 hour)
|
|
19
19
|
*/
|
|
20
20
|
/**
|
|
@@ -23,7 +23,7 @@ const oneDay = 86400000;
|
|
|
23
23
|
* @param {StaticOptions} options Options
|
|
24
24
|
* @returns {MutableRouter} ExpressJS Router instance
|
|
25
25
|
*/
|
|
26
|
-
function staticRouter({
|
|
26
|
+
function staticRouter({ maxAge = 3600000, } = {}) {
|
|
27
27
|
const router = new MutableRouter_js_1.default();
|
|
28
28
|
const notFoundHandler = (req, res, next) => {
|
|
29
29
|
// Fall through to a general purpose error handler
|
|
@@ -52,16 +52,16 @@ function staticRouter({ mountUrl = '/', maxAge = 3600000, }) {
|
|
|
52
52
|
// The CASA CSS source contains the placeholder `~~~CASA_MOUNT_URL~~~` which
|
|
53
53
|
// must be replaced with the dynamic `mountUrl` to ensure govuk-frontend
|
|
54
54
|
// assets are served from the correct location.
|
|
55
|
-
const casaCss = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa.css'), { encoding: 'utf8' })
|
|
56
|
-
const casaCssIe8 = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa-ie8.css'), { encoding: 'utf8' })
|
|
55
|
+
const casaCss = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa.css'), { encoding: 'utf8' });
|
|
56
|
+
const casaCssIe8 = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa-ie8.css'), { encoding: 'utf8' });
|
|
57
57
|
// The static middleware will only server GET/HEAD requests, so we can mount
|
|
58
58
|
// the middleware using `use()` rather than resorting to `get()`
|
|
59
59
|
const govukFrontendDirectory = (0, path_1.resolve)((0, module_1.createRequire)(dirname_cjs_1.default).resolve('govuk-frontend'), '../../');
|
|
60
60
|
router.use('/govuk/assets/js/all.js', ExpressStatic(`${govukFrontendDirectory}/govuk/all.js`, staticConfig));
|
|
61
61
|
router.use('/govuk/assets', ExpressStatic(`${govukFrontendDirectory}/govuk/assets`, staticConfig));
|
|
62
62
|
router.use('/govuk/assets', notFoundHandler);
|
|
63
|
-
router.
|
|
64
|
-
router.
|
|
63
|
+
router.get('/casa/assets/css/casa.css', setHeaders, (req, res) => res.send(casaCss.replace(/~~~CASA_MOUNT_URL~~~/g, (0, utils_js_1.validateUrlPath)(`${req.baseUrl}/`))));
|
|
64
|
+
router.get('/casa/assets/css/casa-ie8.css', setHeaders, (req, res) => res.send(casaCssIe8.replace(/~~~CASA_MOUNT_URL~~~/g, (0, utils_js_1.validateUrlPath)(`${req.baseUrl}/`))));
|
|
65
65
|
router.use('/casa/assets', notFoundHandler);
|
|
66
66
|
return router;
|
|
67
67
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwp/govuk-casa",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.2",
|
|
4
4
|
"description": "A framework for building GOVUK Collect-And-Submit-Applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,50 +43,52 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"cookie-parser": "1.4.6",
|
|
45
45
|
"csurf": "1.11.0",
|
|
46
|
-
"debug": "4.3.
|
|
46
|
+
"debug": "4.3.4",
|
|
47
47
|
"deepmerge": "4.2.2",
|
|
48
|
-
"express": "4.
|
|
49
|
-
"express-session": "1.17.
|
|
48
|
+
"express": "4.18.1",
|
|
49
|
+
"express-session": "1.17.3",
|
|
50
50
|
"govuk-frontend": "4.0.1",
|
|
51
51
|
"graphlib": "2.1.8",
|
|
52
52
|
"helmet": "5.0.2",
|
|
53
|
-
"i18next": "21.
|
|
53
|
+
"i18next": "21.8.2",
|
|
54
54
|
"i18next-http-middleware": "3.2.0",
|
|
55
55
|
"js-yaml": "4.1.0",
|
|
56
56
|
"lodash": "4.17.21",
|
|
57
|
-
"luxon": "2.
|
|
57
|
+
"luxon": "2.4.0",
|
|
58
58
|
"nunjucks": "3.2.3",
|
|
59
|
+
"path-to-regexp": "6.2.1",
|
|
59
60
|
"uuid": "8.3.2",
|
|
60
61
|
"validator": "13.7.0"
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|
|
63
|
-
"@babel/core": "7.17.
|
|
64
|
+
"@babel/core": "7.17.12",
|
|
64
65
|
"@babel/eslint-parser": "7.17.0",
|
|
65
|
-
"@babel/preset-env": "7.
|
|
66
|
-
"@commitlint/config-conventional": "
|
|
66
|
+
"@babel/preset-env": "7.17.12",
|
|
67
|
+
"@commitlint/config-conventional": "17.0.0",
|
|
67
68
|
"@dwp/casa-spiderplan": "2.4.0",
|
|
68
69
|
"@dwp/casa-spiderplan-a11y-plugin": "0.1.4",
|
|
69
70
|
"@dwp/casa-spiderplan-zap-plugin": "0.1.1",
|
|
70
71
|
"@dwp/eslint-config-base": "6.0.0",
|
|
71
72
|
"@types/express": "4.17.13",
|
|
72
|
-
"@types/node": "17.0.
|
|
73
|
+
"@types/node": "17.0.34",
|
|
73
74
|
"@types/nunjucks": "3.2.1",
|
|
74
75
|
"babel-eslint": "10.1.0",
|
|
75
|
-
"c8": "7.11.
|
|
76
|
+
"c8": "7.11.3",
|
|
76
77
|
"chai": "4.3.6",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
78
|
+
"cheerio": "1.0.0-rc.10",
|
|
79
|
+
"commitlint": "17.0.0",
|
|
80
|
+
"eslint": "8.15.0",
|
|
79
81
|
"eslint-plugin-no-unsafe-regex": "1.0.0",
|
|
80
|
-
"eslint-plugin-security": "1.
|
|
81
|
-
"eslint-plugin-sonarjs": "0.
|
|
82
|
-
"fast-check": "2.
|
|
83
|
-
"husky": "
|
|
84
|
-
"mocha": "
|
|
85
|
-
"sass": "1.
|
|
86
|
-
"sinon": "
|
|
82
|
+
"eslint-plugin-security": "1.5.0",
|
|
83
|
+
"eslint-plugin-sonarjs": "0.13.0",
|
|
84
|
+
"fast-check": "2.25.0",
|
|
85
|
+
"husky": "8.0.1",
|
|
86
|
+
"mocha": "10.0.0",
|
|
87
|
+
"sass": "1.51.0",
|
|
88
|
+
"sinon": "14.0.0",
|
|
87
89
|
"sinon-chai": "3.7.0",
|
|
88
|
-
"standard-version": "9.
|
|
89
|
-
"supertest": "6.2.
|
|
90
|
-
"typescript": "4.6.
|
|
90
|
+
"standard-version": "9.5.0",
|
|
91
|
+
"supertest": "6.2.3",
|
|
92
|
+
"typescript": "4.6.4"
|
|
91
93
|
}
|
|
92
94
|
}
|
|
@@ -4,6 +4,8 @@ Component to wrap your form inputs in a `<form>` that contains all the required
|
|
|
4
4
|
|
|
5
5
|
A "Continue" button (and "Cancel" link if in edit mode) will also be added.
|
|
6
6
|
|
|
7
|
+
- [1.3.5: Identify Input Purpose](https://www.w3.org/WAI/WCAG21/Understanding/identify-input-purpose.html)
|
|
8
|
+
- [<form>: The Form element - autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-autocomplete)
|
|
7
9
|
## Example usage
|
|
8
10
|
|
|
9
11
|
```nunjucks
|
|
@@ -49,6 +51,7 @@ Note that the submit button is configured to prevent double-clicks and avoid dup
|
|
|
49
51
|
| Name | Type | Required | Description |
|
|
50
52
|
|------|------|----------|-------------|
|
|
51
53
|
| `formUrl` | string | Yes | The form's "action", available in a `formUrl` template variable |
|
|
54
|
+
| `autoComplete` | string | No | Allows you to override the autocomplete paramater - the default value is 'off'
|
|
52
55
|
| `csrfToken` | string | Yes | Token used to protect form from CSRF (available to user's templates via the global `casa.csrfToken` variable) |
|
|
53
56
|
| `inEditMode` | boolean | No | Toggle edit-mode of the form (available to page templates using default GET/POST handlers via the local `inEditMode` variable) |
|
|
54
57
|
| `editOriginUrl` | string | No | Absolute URL to the page from which the edit request came (defaults to `review`) (available to user's templates using default GET/POST handlers via the local `editOriginUrl` variable) |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{% from "govuk/components/button/macro.njk" import govukButton %}
|
|
2
2
|
|
|
3
|
-
<form action="{{ params.formUrl }}" method="post" autocomplete="off" novalidate class="casa-journey-form">
|
|
3
|
+
<form action="{{ params.formUrl }}" method="post" autocomplete="{{ params.autoComplete | default('off', true) }}" novalidate class="casa-journey-form">
|
|
4
4
|
<input type="hidden" name="_csrf" value="{{ params.csrfToken }}" />
|
|
5
5
|
{% if params.inEditMode %}<input type="hidden" name="edit" value="true" />{% endif %}
|
|
6
6
|
{% if params.inEditMode and params.editOriginUrl %}<input type="hidden" name="editorigin" value="{{ params.editOriginUrl }}" />{% endif %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- CASA -->
|
|
2
|
-
<script src="{{ casa.
|
|
2
|
+
<script src="{{ casa.staticMountUrl }}govuk/assets/js/all.js?{{ casaVersion }}"></script>
|
|
3
3
|
<script nonce="{{ cspNonce }}">
|
|
4
4
|
window.GOVUKFrontend.initAll();
|
|
5
5
|
if (window.history.replaceState) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- CASA -->
|
|
2
|
-
<!--[if gt IE 8]><!--><link href="{{ casa.
|
|
2
|
+
<!--[if gt IE 8]><!--><link href="{{ casa.staticMountUrl }}casa/assets/css/casa.css?{{ casaVersion }}" rel="stylesheet" /><!--<![endif]-->
|
|
3
3
|
<!--[if lte IE 8]>
|
|
4
|
-
<link href="{{ casa.
|
|
4
|
+
<link href="{{ casa.staticMountUrl }}casa/assets/css/casa-ie8.css?{{ casaVersion }}" rel="stylesheet" />
|
|
5
5
|
<![endif]-->
|
|
6
6
|
<!-- /CASA -->
|