@dwp/govuk-casa 8.0.2 → 8.2.0

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +2 -0
  3. package/dist/assets/css/casa-ie8.css +1 -1
  4. package/dist/assets/css/casa.css +1 -1
  5. package/dist/casa.d.ts +210 -0
  6. package/dist/casa.js +107 -1
  7. package/dist/lib/CasaTemplateLoader.d.ts +7 -0
  8. package/dist/lib/JourneyContext.d.ts +15 -27
  9. package/dist/lib/JourneyContext.js +37 -16
  10. package/dist/lib/configuration-ingestor.d.ts +21 -139
  11. package/dist/lib/configuration-ingestor.js +39 -84
  12. package/dist/lib/configure.d.ts +6 -77
  13. package/dist/lib/configure.js +82 -40
  14. package/dist/lib/index.js +5 -1
  15. package/dist/lib/nunjucks.d.ts +1 -6
  16. package/dist/lib/nunjucks.js +1 -3
  17. package/dist/lib/utils.d.ts +21 -10
  18. package/dist/lib/utils.js +54 -8
  19. package/dist/lib/validators/dateObject.d.ts +1 -0
  20. package/dist/lib/validators/email.d.ts +2 -0
  21. package/dist/lib/validators/inArray.d.ts +2 -0
  22. package/dist/lib/validators/nino.d.ts +2 -0
  23. package/dist/lib/validators/postalAddressObject.d.ts +1 -0
  24. package/dist/lib/validators/regex.d.ts +2 -0
  25. package/dist/lib/validators/required.d.ts +4 -0
  26. package/dist/lib/validators/strlen.d.ts +2 -0
  27. package/dist/lib/validators/wordCount.d.ts +2 -0
  28. package/dist/lib/waypoint-url.js +8 -2
  29. package/dist/middleware/body-parser.js +1 -1
  30. package/dist/middleware/data.d.ts +1 -2
  31. package/dist/middleware/data.js +12 -2
  32. package/dist/middleware/post.d.ts +1 -3
  33. package/dist/middleware/post.js +3 -3
  34. package/dist/middleware/pre.d.ts +4 -2
  35. package/dist/middleware/pre.js +24 -5
  36. package/dist/middleware/progress-journey.d.ts +1 -2
  37. package/dist/middleware/progress-journey.js +2 -2
  38. package/dist/middleware/session.d.ts +1 -2
  39. package/dist/middleware/session.js +12 -6
  40. package/dist/middleware/skip-waypoint.d.ts +1 -2
  41. package/dist/middleware/skip-waypoint.js +2 -2
  42. package/dist/middleware/steer-journey.d.ts +1 -2
  43. package/dist/middleware/steer-journey.js +2 -2
  44. package/dist/middleware/validate-fields.d.ts +1 -2
  45. package/dist/middleware/validate-fields.js +2 -1
  46. package/dist/routes/journey.d.ts +1 -2
  47. package/dist/routes/journey.js +8 -8
  48. package/dist/routes/static.d.ts +1 -6
  49. package/dist/routes/static.js +6 -6
  50. package/package.json +32 -30
  51. package/views/casa/components/journey-form/README.md +3 -0
  52. package/views/casa/components/journey-form/template.njk +1 -1
  53. package/views/casa/partials/scripts.njk +1 -1
  54. package/views/casa/partials/styles.njk +2 -2
@@ -20,7 +20,7 @@ const saveAndRedirect = (session, journeyContext, url, res, next) => {
20
20
  res.redirect(302, url);
21
21
  });
22
22
  };
23
- exports.default = ({ waypoint, plan, mountUrl, }) => [
23
+ exports.default = ({ waypoint, plan, }) => [
24
24
  (req, res, next) => {
25
25
  // Determine the next available waypoint after the current one
26
26
  const traversed = plan.traverse(req.casa.journeyContext);
@@ -68,7 +68,7 @@ exports.default = ({ waypoint, plan, mountUrl, }) => [
68
68
  // Construct the next url
69
69
  const nextUrl = (0, waypoint_url_js_1.default)({
70
70
  waypoint: nextWaypoint,
71
- mountUrl,
71
+ mountUrl: `${req.baseUrl}/`,
72
72
  journeyContext: req.casa.journeyContext,
73
73
  edit: req.casa.editMode,
74
74
  editOrigin: req.casa.editOrigin,
@@ -1,10 +1,9 @@
1
- export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl, cookieSameSite, cookiePath, store, }: {
1
+ export default function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, cookieSameSite, cookiePath, store, }: {
2
2
  cookieParserMiddleware: any;
3
3
  secret: any;
4
4
  name: any;
5
5
  secure: any;
6
6
  ttl: any;
7
- mountUrl?: string | undefined;
8
7
  cookieSameSite?: boolean | undefined;
9
8
  cookiePath?: string | undefined;
10
9
  store?: any;
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -27,8 +31,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
27
31
  // interrupting their journey.
28
32
  const express_session_1 = __importStar(require("express-session"));
29
33
  const logger_js_1 = __importDefault(require("../lib/logger.js"));
34
+ const utils_js_1 = require("../lib/utils.js");
30
35
  const log = (0, logger_js_1.default)('middleware:session');
31
- const sessionExpiryMiddleware = (mountUrl, ttl, getCookie, touchCookie, removeCookie) => (req, res, next) => {
36
+ const sessionExpiryMiddleware = (ttl, getCookie, touchCookie, removeCookie) => (req, res, next) => {
32
37
  var _a;
33
38
  const lastModified = getCookie(req);
34
39
  const age = Math.floor(Date.now() * 0.001) - lastModified;
@@ -46,7 +51,7 @@ const sessionExpiryMiddleware = (mountUrl, ttl, getCookie, touchCookie, removeCo
46
51
  touchCookie(res);
47
52
  if (req.method === 'POST') {
48
53
  log.info('The CSRF token for this POST request will now be invalid for this regenerated session. Redirecting to app mount point.');
49
- res.redirect(302, mountUrl);
54
+ res.redirect(302, (0, utils_js_1.validateUrlPath)(`${req.baseUrl}/`));
50
55
  }
51
56
  else {
52
57
  next();
@@ -69,7 +74,8 @@ const sessionExpiryMiddleware = (mountUrl, ttl, getCookie, touchCookie, removeCo
69
74
  referrer: req.originalUrl,
70
75
  lang: language,
71
76
  });
72
- res.redirect(302, `${mountUrl}session-timeout?${params.toString()}`);
77
+ /* eslint-disable-next-line prefer-template */
78
+ res.redirect(302, (0, utils_js_1.validateUrlPath)(`${req.baseUrl}/session-timeout`) + `?${params.toString()}`);
73
79
  }
74
80
  });
75
81
  }
@@ -83,7 +89,7 @@ const sessionExpiryMiddleware = (mountUrl, ttl, getCookie, touchCookie, removeCo
83
89
  // - set the session cookie
84
90
  // - parse request cookies
85
91
  // - handle expiry of server-side session
86
- function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, mountUrl = '/', cookieSameSite = true, cookiePath = '/', store = new express_session_1.MemoryStore(), }) {
92
+ function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl, cookieSameSite = true, cookiePath = '/', store = new express_session_1.MemoryStore(), }) {
87
93
  const commonCookieOptions = {
88
94
  httpOnly: true,
89
95
  path: cookiePath,
@@ -122,7 +128,7 @@ function sessionMiddleware({ cookieParserMiddleware, secret, name, secure, ttl,
122
128
  store,
123
129
  }),
124
130
  cookieParserMiddleware,
125
- sessionExpiryMiddleware(mountUrl, ttl, getCookie, touchCookie, removeCookie),
131
+ sessionExpiryMiddleware(ttl, getCookie, touchCookie, removeCookie),
126
132
  ];
127
133
  }
128
134
  exports.default = sessionMiddleware;
@@ -1,5 +1,4 @@
1
- declare function _default({ waypoint, mountUrl, }: {
1
+ declare function _default({ waypoint, }: {
2
2
  waypoint: any;
3
- mountUrl: any;
4
3
  }): ((req: any, res: any, next: any) => any)[];
5
4
  export default _default;
@@ -10,7 +10,7 @@ const waypoint_url_js_1 = __importDefault(require("../lib/waypoint-url.js"));
10
10
  const logger_js_1 = __importDefault(require("../lib/logger.js"));
11
11
  const { has } = lodash_1.default;
12
12
  const log = (0, logger_js_1.default)('middleware:skip-waypoint');
13
- exports.default = ({ waypoint, mountUrl, }) => [
13
+ exports.default = ({ waypoint, }) => [
14
14
  (req, res, next) => {
15
15
  if (!has(req.query, 'skipto')) {
16
16
  return next();
@@ -24,7 +24,7 @@ exports.default = ({ waypoint, mountUrl, }) => [
24
24
  });
25
25
  JourneyContext_js_1.default.putContext(req.session, req.casa.journeyContext);
26
26
  const redirectUrl = (0, waypoint_url_js_1.default)({
27
- mountUrl,
27
+ mountUrl: `${req.baseUrl}/`,
28
28
  waypoint: skipTo,
29
29
  edit: req.casa.editMode,
30
30
  editOrigin: req.casa.editOrigin,
@@ -1,7 +1,6 @@
1
- declare function _default({ waypoint, plan, mountUrl, }: {
1
+ declare function _default({ waypoint, plan, }: {
2
2
  waypoint: string;
3
3
  plan: Plan;
4
- mountUrl: string;
5
4
  }): void;
6
5
  export default _default;
7
6
  export type Plan = typeof import("../lib/Plan");
@@ -18,11 +18,11 @@ const log = (0, logger_js_1.default)('middleware:steer-journey');
18
18
  * @param {object} obj Options
19
19
  * @param {string} obj.waypoint Current waypoint
20
20
  * @param {Plan} obj.plan CASA Plan
21
- * @param {string} obj.mountUrl Mount URL
22
21
  * @returns {void}
23
22
  */
24
- exports.default = ({ waypoint, plan, mountUrl, }) => [
23
+ exports.default = ({ waypoint, plan, }) => [
25
24
  (req, res, next) => {
25
+ const mountUrl = `${req.baseUrl}/`;
26
26
  // If the requested waypoint doesn't exist in the traversed journey, send
27
27
  // the user back to the last good waypoint.
28
28
  const traversed = plan.traverse(req.casa.journeyContext);
@@ -1,7 +1,6 @@
1
- declare function _default({ waypoint, fields, mountUrl, plan, }: {
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 = [], mountUrl, plan, }) => [
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 */
@@ -1,8 +1,7 @@
1
- export default function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, }: {
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";
@@ -29,13 +29,14 @@ const renderMiddlewareFactory = (view, contextFactory) => [
29
29
  });
30
30
  },
31
31
  ];
32
- function journeyRouter({ globalHooks, pages, plan, csrfMiddleware, mountUrl, }) {
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)({ mountUrl, waypoint }),
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, 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) => ({
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, mountUrl, 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, mountUrl, plan }), ...(0, utils_js_1.resolveMiddlewareHooks)('journey.postvalidate', waypointPath, [...globalHooks, ...pageHooks]),
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, mountUrl }));
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,
@@ -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({ mountUrl, maxAge, }: StaticOptions): MutableRouter;
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
  */
@@ -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({ mountUrl = '/', maxAge = 3600000, }) {
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' }).replace(/~~~CASA_MOUNT_URL~~~/g, mountUrl);
56
- const casaCssIe8 = (0, fs_1.readFileSync)((0, path_1.resolve)(dirname_cjs_1.default, '../../dist/assets/css/casa-ie8.css'), { encoding: 'utf8' }).replace(/~~~CASA_MOUNT_URL~~~/g, mountUrl);
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.use('/casa/assets/css/casa.css', setHeaders, (req, res) => res.send(casaCss));
64
- router.use('/casa/assets/css/casa-ie8.css', setHeaders, (req, res) => res.send(casaCssIe8));
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.0.2",
3
+ "version": "8.2.0",
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.3",
46
+ "debug": "4.3.4",
47
47
  "deepmerge": "4.2.2",
48
- "express": "4.17.2",
49
- "express-session": "1.17.2",
50
- "govuk-frontend": "4.0.0",
48
+ "express": "4.18.1",
49
+ "express-session": "1.17.3",
50
+ "govuk-frontend": "4.0.1",
51
51
  "graphlib": "2.1.8",
52
- "helmet": "5.0.1",
53
- "i18next": "21.6.6",
54
- "i18next-http-middleware": "3.1.5",
52
+ "helmet": "5.0.2",
53
+ "i18next": "21.8.2",
54
+ "i18next-http-middleware": "3.2.0",
55
55
  "js-yaml": "4.1.0",
56
56
  "lodash": "4.17.21",
57
- "luxon": "2.3.0",
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.16.7",
64
- "@babel/eslint-parser": "7.16.5",
65
- "@babel/preset-env": "7.16.8",
66
- "@commitlint/config-conventional": "16.0.0",
67
- "@dwp/casa-spiderplan": "2.0.0",
68
- "@dwp/casa-spiderplan-a11y-plugin": "0.1.3",
64
+ "@babel/core": "7.17.12",
65
+ "@babel/eslint-parser": "7.17.0",
66
+ "@babel/preset-env": "7.17.12",
67
+ "@commitlint/config-conventional": "17.0.0",
68
+ "@dwp/casa-spiderplan": "2.4.0",
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.8",
73
+ "@types/node": "17.0.34",
73
74
  "@types/nunjucks": "3.2.1",
74
75
  "babel-eslint": "10.1.0",
75
- "c8": "7.11.0",
76
- "chai": "4.3.4",
77
- "commitlint": "16.0.2",
78
- "eslint": "8.6.0",
76
+ "c8": "7.11.3",
77
+ "chai": "4.3.6",
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.4.0",
81
- "eslint-plugin-sonarjs": "0.11.0",
82
- "fast-check": "2.21.0",
83
- "husky": "7.0.4",
84
- "mocha": "9.1.3",
85
- "sass": "1.48.0",
86
- "sinon": "12.0.1",
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.3.2",
89
- "supertest": "6.2.1",
90
- "typescript": "4.5.4"
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.mountUrl }}govuk/assets/js/all.js?{{ casaVersion }}"></script>
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.mountUrl }}casa/assets/css/casa.css?{{ casaVersion }}" rel="stylesheet" /><!--<![endif]-->
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.mountUrl }}casa/assets/css/casa-ie8.css?{{ casaVersion }}" rel="stylesheet" />
4
+ <link href="{{ casa.staticMountUrl }}casa/assets/css/casa-ie8.css?{{ casaVersion }}" rel="stylesheet" />
5
5
  <![endif]-->
6
6
  <!-- /CASA -->