@dwp/govuk-casa 8.0.0-alpha1 → 8.0.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 (79) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +1 -1
  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 +2 -1
  6. package/dist/casa.js +3 -1
  7. package/dist/lib/CasaTemplateLoader.d.ts +11 -3
  8. package/dist/lib/CasaTemplateLoader.js +38 -2
  9. package/dist/lib/JourneyContext.d.ts +51 -8
  10. package/dist/lib/JourneyContext.js +73 -147
  11. package/dist/lib/MutableRouter.d.ts +19 -19
  12. package/dist/lib/MutableRouter.js +30 -23
  13. package/dist/lib/Plan.d.ts +41 -6
  14. package/dist/lib/Plan.js +84 -17
  15. package/dist/lib/ValidationError.d.ts +6 -2
  16. package/dist/lib/ValidationError.js +7 -0
  17. package/dist/lib/ValidatorFactory.d.ts +72 -13
  18. package/dist/lib/ValidatorFactory.js +33 -14
  19. package/dist/lib/configuration-ingestor.d.ts +262 -0
  20. package/dist/lib/configuration-ingestor.js +464 -0
  21. package/dist/lib/configure.d.ts +39 -154
  22. package/dist/lib/configure.js +35 -59
  23. package/dist/lib/dirname.cjs +1 -1
  24. package/dist/lib/dirname.d.cts +2 -0
  25. package/dist/lib/end-session.d.ts +4 -3
  26. package/dist/lib/end-session.js +30 -8
  27. package/dist/lib/field.d.ts +53 -55
  28. package/dist/lib/field.js +96 -54
  29. package/dist/lib/index.d.ts +14 -0
  30. package/dist/lib/index.js +54 -0
  31. package/dist/lib/logger.d.ts +2 -1
  32. package/dist/lib/logger.js +3 -4
  33. package/dist/lib/nunjucks-filters.d.ts +11 -11
  34. package/dist/lib/nunjucks-filters.js +22 -36
  35. package/dist/lib/nunjucks.d.ts +7 -6
  36. package/dist/lib/nunjucks.js +6 -6
  37. package/dist/lib/utils.d.ts +26 -0
  38. package/dist/lib/utils.js +70 -1
  39. package/dist/lib/validators/dateObject.js +1 -1
  40. package/dist/lib/validators/email.js +1 -1
  41. package/dist/lib/validators/inArray.js +1 -1
  42. package/dist/lib/validators/index.js +0 -22
  43. package/dist/lib/validators/postalAddressObject.js +7 -3
  44. package/dist/lib/validators/required.js +1 -1
  45. package/dist/lib/waypoint-url.d.ts +13 -7
  46. package/dist/lib/waypoint-url.js +13 -7
  47. package/dist/middleware/body-parser.d.ts +2 -1
  48. package/dist/middleware/body-parser.js +20 -11
  49. package/dist/middleware/csrf.d.ts +1 -1
  50. package/dist/middleware/csrf.js +2 -2
  51. package/dist/middleware/data.d.ts +1 -2
  52. package/dist/middleware/data.js +19 -15
  53. package/dist/middleware/dirname.cjs +1 -1
  54. package/dist/middleware/dirname.d.cts +2 -0
  55. package/dist/middleware/gather-fields.d.ts +3 -2
  56. package/dist/middleware/gather-fields.js +14 -7
  57. package/dist/middleware/i18n.d.ts +1 -1
  58. package/dist/middleware/i18n.js +16 -11
  59. package/dist/middleware/post.d.ts +3 -1
  60. package/dist/middleware/post.js +24 -9
  61. package/dist/middleware/pre.js +15 -2
  62. package/dist/middleware/progress-journey.js +15 -17
  63. package/dist/middleware/sanitise-fields.js +15 -10
  64. package/dist/middleware/session.d.ts +2 -1
  65. package/dist/middleware/session.js +65 -52
  66. package/dist/middleware/skip-waypoint.js +10 -7
  67. package/dist/middleware/steer-journey.d.ts +3 -2
  68. package/dist/middleware/steer-journey.js +26 -8
  69. package/dist/middleware/validate-fields.js +15 -21
  70. package/dist/mjs/esm-wrapper.js +18 -7
  71. package/dist/routes/ancillary.d.ts +8 -1
  72. package/dist/routes/ancillary.js +7 -1
  73. package/dist/routes/dirname.cjs +1 -1
  74. package/dist/routes/dirname.d.cts +2 -0
  75. package/dist/routes/journey.js +20 -24
  76. package/dist/routes/static.js +10 -9
  77. package/package.json +41 -22
  78. package/views/casa/errors/static.njk +11 -0
  79. package/views/casa/layouts/main.njk +3 -3
@@ -1,46 +1,26 @@
1
1
  /**
2
- *
3
- * @typedef {Object} SessionOptions
4
- * @property {string} [name=casasession] Session name
5
- * @property {string} [secret=secret] Encryption secret
6
- * @property {number} [ttl=3600] Session ttl (seconds)
7
- * @property {boolean} [secure=false] Whether to use secure session cookies
8
- * @property {boolean|string} [cookieSameSite=true] SameSite setting (true (Strict), false (no value), Strict, Lax, None, default true)
9
- * @property {object} [store] Session store (default MemoryStore)
10
- */
11
- /**
12
- * @typedef {Object} GlobalHook Hook configuration
13
- * @property {string} hook Hook name in format `<router>.<hook>`
14
- * @property {function} middleware Middleware function to insert at the hook point
15
- * @property {string|RegExp} [path=undefined] Hook only triggered if route path matches this string/regexp (optional, default /./)
2
+ * @typedef {import('express').RequestHandler} ExpressRequestHandler
16
3
  */
17
4
  /**
18
- * @typedef {Object} PageHook (extends GlobalHook)
19
- * @property {string} hook Hook name (without a scope prefix)
20
- * @property {function} middleware Middleware function to insert at the hook point
5
+ * @typedef {import('./index').MutableRouter} MutableRouter
21
6
  */
22
7
  /**
23
- * @typedef {Object} Page Page configuration. A Page is the interactive representation of a waypoint
24
- * @property {string} waypoint The waypoint with which this page is associated
25
- * @property {string} view Template path
26
- * @property {PageHook[]} hooks Page-specific hooks
27
- * @property {PageField[]} fields Fields to be managed on this page
8
+ * @typedef {import('./configuration-ingestor').ConfigurationOptions} ConfigurationOptions
28
9
  */
29
10
  /**
30
- * @typedef {Object} ConfigureResult Result of a call to configure() function
31
- * @property {nunjucks.Environment} nunjucksEnv Nunjucks environment to attach to other ExpressJS app instances
32
- * @property {MutableRouter} staticRouter ExpressJS Router instance which serves all static assets
33
- * @property {MutableRouter} ancillaryRouter ExpressJS app instance which serves all ancillary routes
34
- * @property {MutableRouter} journeyRouter ExpressJS app instance which serves page routes for each waypoint in a user's journey
35
- * @property {express.RequestHandler[]} preMiddleware Middleware mounted before anything else
36
- * @property {express.RequestHandler[]} postMiddleware Middleware mounted after everything else
37
- * @property {express.RequestHandler[]} csrfMiddleware Collection of middleware useful for pages containing forms
38
- * @property {express.RequestHandler} sessionMiddleware Session middleware
39
- * @property {express.RequestHandler[]} cookieParserMiddleware Cookie-parsing middleware (configured to match that of session middleware)
40
- * @property {express.RequestHandler[]} i18nMiddleware I18n preparation middleware
41
- * @property {express.RequestHandler} bodyParserMiddleware Body parsing middleware
42
- * @property {express.RequestHandler[]} csrfMiddleware CSRF middleware
43
- * @property {function} mount Function used to mount all CASA artifacts onto an ExpressJS app instance
11
+ * @typedef {object} ConfigureResult Result of a call to configure() function
12
+ * @property {nunjucks.Environment} nunjucksEnv Nunjucks environment
13
+ * @property {MutableRouter} staticRouter Router handling all static assets
14
+ * @property {MutableRouter} ancillaryRouter Router handling ancillary routes
15
+ * @property {MutableRouter} journeyRouter Router handling all waypoint requests
16
+ * @property {ExpressRequestHandler[]} preMiddleware Middleware mounted before anything else
17
+ * @property {ExpressRequestHandler[]} postMiddleware Middleware mounted after everything else
18
+ * @property {ExpressRequestHandler[]} csrfMiddleware CSRF get/set middleware (useful for forms)
19
+ * @property {ExpressRequestHandler} sessionMiddleware Session middleware
20
+ * @property {ExpressRequestHandler[]} cookieParserMiddleware Cookie-parsing middleware
21
+ * @property {ExpressRequestHandler[]} i18nMiddleware I18n preparation middleware
22
+ * @property {ExpressRequestHandler} bodyParserMiddleware Body parsing middleware
23
+ * @property {Function} mount Function used to mount all CASA artifacts onto an ExpressJS app
44
24
  */
45
25
  /**
46
26
  * Configure some middleware for use in creating a new CASA app.
@@ -48,158 +28,63 @@
48
28
  * `mountUrl` is used to ensure the CSS content uses the correct reference to
49
29
  * static assets in the `govuk-frontend` module.
50
30
  *
51
- * @param {Object} config Configuration options
52
- * @param {string} [config.mountUrl=/] URL path used to serve static assets from and generate links (optional, default /)
53
- * @param {string} [config.serviceName=common.serviceName] Service name (i18n key) to display in header (optional, default common:serviceName)
54
- * @param {string[]} [config.views=[]] Array of directories in which Nunjucks templates will be searched for (optional, default [])
55
- * @param {SessionOptions} [config.session] Session configuration
56
- * @param {Page[]} [config.pages=[]] Pages the represent waypoints in the Plan (optional, default [])
57
- * @param {GlobalHook[]} [config.hooks=[]] Hooks to apply (optional, default [])
58
- * @param {Object[]} [config.plugins=[]] Plugins(optional, default [])
59
- * @param {I18nOptions[]} [config.i18n] I18n configuration
60
- * @param {Plan} config.plan CASA Plan
61
- * @param {ContextEvent[]} [config.events=[]] Handlers for JourneyContext events
31
+ * @param {ConfigurationOptions} config Configuration options
62
32
  * @returns {ConfigureResult} Result
63
33
  */
64
- export default function configure(config?: {
65
- mountUrl?: string | undefined;
66
- serviceName?: string | undefined;
67
- views?: string[] | undefined;
68
- session?: SessionOptions | undefined;
69
- pages?: Page[] | undefined;
70
- hooks?: GlobalHook[] | undefined;
71
- plugins?: Object[] | undefined;
72
- i18n?: any[] | undefined;
73
- plan: any;
74
- events?: any[] | undefined;
75
- }): ConfigureResult;
76
- export type SessionOptions = {
77
- /**
78
- * Session name
79
- */
80
- name?: string | undefined;
81
- /**
82
- * Encryption secret
83
- */
84
- secret?: string | undefined;
85
- /**
86
- * Session ttl (seconds)
87
- */
88
- ttl?: number | undefined;
89
- /**
90
- * Whether to use secure session cookies
91
- */
92
- secure?: boolean | undefined;
93
- /**
94
- * SameSite setting (true (Strict), false (no value), Strict, Lax, None, default true)
95
- */
96
- cookieSameSite?: string | boolean | undefined;
97
- /**
98
- * Session store (default MemoryStore)
99
- */
100
- store?: object | undefined;
101
- };
102
- /**
103
- * Hook configuration
104
- */
105
- export type GlobalHook = {
106
- /**
107
- * Hook name in format `<router>.<hook>`
108
- */
109
- hook: string;
110
- /**
111
- * Middleware function to insert at the hook point
112
- */
113
- middleware: Function;
114
- /**
115
- * Hook only triggered if route path matches this string/regexp (optional, default /./)
116
- */
117
- path?: string | RegExp | undefined;
118
- };
119
- /**
120
- * (extends GlobalHook)
121
- */
122
- export type PageHook = {
123
- /**
124
- * Hook name (without a scope prefix)
125
- */
126
- hook: string;
127
- /**
128
- * Middleware function to insert at the hook point
129
- */
130
- middleware: Function;
131
- };
132
- /**
133
- * Page configuration. A Page is the interactive representation of a waypoint
134
- */
135
- export type Page = {
136
- /**
137
- * The waypoint with which this page is associated
138
- */
139
- waypoint: string;
140
- /**
141
- * Template path
142
- */
143
- view: string;
144
- /**
145
- * Page-specific hooks
146
- */
147
- hooks: PageHook[];
148
- /**
149
- * Fields to be managed on this page
150
- */
151
- fields: any[];
152
- };
34
+ export default function configure(config?: ConfigurationOptions): ConfigureResult;
35
+ export type ExpressRequestHandler = import('express').RequestHandler;
36
+ export type MutableRouter = import('./index').MutableRouter;
37
+ export type ConfigurationOptions = import('./configuration-ingestor').ConfigurationOptions;
153
38
  /**
154
39
  * Result of a call to configure() function
155
40
  */
156
41
  export type ConfigureResult = {
157
42
  /**
158
- * Nunjucks environment to attach to other ExpressJS app instances
43
+ * Nunjucks environment
159
44
  */
160
- nunjucksEnv: any;
45
+ nunjucksEnv: nunjucks.Environment;
161
46
  /**
162
- * ExpressJS Router instance which serves all static assets
47
+ * Router handling all static assets
163
48
  */
164
- staticRouter: any;
49
+ staticRouter: MutableRouter;
165
50
  /**
166
- * ExpressJS app instance which serves all ancillary routes
51
+ * Router handling ancillary routes
167
52
  */
168
- ancillaryRouter: any;
53
+ ancillaryRouter: MutableRouter;
169
54
  /**
170
- * ExpressJS app instance which serves page routes for each waypoint in a user's journey
55
+ * Router handling all waypoint requests
171
56
  */
172
- journeyRouter: any;
57
+ journeyRouter: MutableRouter;
173
58
  /**
174
59
  * Middleware mounted before anything else
175
60
  */
176
- preMiddleware: any[];
61
+ preMiddleware: ExpressRequestHandler[];
177
62
  /**
178
63
  * Middleware mounted after everything else
179
64
  */
180
- postMiddleware: any[];
65
+ postMiddleware: ExpressRequestHandler[];
181
66
  /**
182
- * Collection of middleware useful for pages containing forms
67
+ * CSRF get/set middleware (useful for forms)
183
68
  */
184
- csrfMiddleware: any[];
69
+ csrfMiddleware: ExpressRequestHandler[];
185
70
  /**
186
71
  * Session middleware
187
72
  */
188
- sessionMiddleware: any;
73
+ sessionMiddleware: ExpressRequestHandler;
189
74
  /**
190
- * Cookie-parsing middleware (configured to match that of session middleware)
75
+ * Cookie-parsing middleware
191
76
  */
192
- cookieParserMiddleware: any[];
77
+ cookieParserMiddleware: ExpressRequestHandler[];
193
78
  /**
194
79
  * I18n preparation middleware
195
80
  */
196
- i18nMiddleware: any[];
81
+ i18nMiddleware: ExpressRequestHandler[];
197
82
  /**
198
83
  * Body parsing middleware
199
84
  */
200
- bodyParserMiddleware: any;
85
+ bodyParserMiddleware: ExpressRequestHandler;
201
86
  /**
202
- * Function used to mount all CASA artifacts onto an ExpressJS app instance
87
+ * Function used to mount all CASA artifacts onto an ExpressJS app
203
88
  */
204
89
  mount: Function;
205
90
  };
@@ -3,10 +3,12 @@ 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 dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
7
6
  const express_session_1 = require("express-session");
8
7
  const path_1 = require("path");
9
8
  const module_1 = require("module");
9
+ const cookie_parser_1 = __importDefault(require("cookie-parser"));
10
+ const dirname_cjs_1 = __importDefault(require("./dirname.cjs"));
11
+ const configuration_ingestor_js_1 = __importDefault(require("./configuration-ingestor.js"));
10
12
  const nunjucks_js_1 = __importDefault(require("./nunjucks.js"));
11
13
  const static_js_1 = __importDefault(require("../routes/static.js"));
12
14
  const ancillary_js_1 = __importDefault(require("../routes/ancillary.js"));
@@ -14,54 +16,33 @@ const journey_js_1 = __importDefault(require("../routes/journey.js"));
14
16
  const pre_js_1 = __importDefault(require("../middleware/pre.js"));
15
17
  const post_js_1 = __importDefault(require("../middleware/post.js"));
16
18
  const session_js_1 = __importDefault(require("../middleware/session.js"));
17
- const cookie_parser_1 = __importDefault(require("cookie-parser"));
18
19
  const i18n_js_1 = __importDefault(require("../middleware/i18n.js"));
19
20
  const data_js_1 = __importDefault(require("../middleware/data.js"));
20
21
  const body_parser_js_1 = __importDefault(require("../middleware/body-parser.js"));
21
22
  const csrf_js_1 = __importDefault(require("../middleware/csrf.js"));
22
23
  /**
23
- *
24
- * @typedef {Object} SessionOptions
25
- * @property {string} [name=casasession] Session name
26
- * @property {string} [secret=secret] Encryption secret
27
- * @property {number} [ttl=3600] Session ttl (seconds)
28
- * @property {boolean} [secure=false] Whether to use secure session cookies
29
- * @property {boolean|string} [cookieSameSite=true] SameSite setting (true (Strict), false (no value), Strict, Lax, None, default true)
30
- * @property {object} [store] Session store (default MemoryStore)
24
+ * @typedef {import('express').RequestHandler} ExpressRequestHandler
31
25
  */
32
26
  /**
33
- * @typedef {Object} GlobalHook Hook configuration
34
- * @property {string} hook Hook name in format `<router>.<hook>`
35
- * @property {function} middleware Middleware function to insert at the hook point
36
- * @property {string|RegExp} [path=undefined] Hook only triggered if route path matches this string/regexp (optional, default /./)
27
+ * @typedef {import('./index').MutableRouter} MutableRouter
37
28
  */
38
29
  /**
39
- * @typedef {Object} PageHook (extends GlobalHook)
40
- * @property {string} hook Hook name (without a scope prefix)
41
- * @property {function} middleware Middleware function to insert at the hook point
30
+ * @typedef {import('./configuration-ingestor').ConfigurationOptions} ConfigurationOptions
42
31
  */
43
32
  /**
44
- * @typedef {Object} Page Page configuration. A Page is the interactive representation of a waypoint
45
- * @property {string} waypoint The waypoint with which this page is associated
46
- * @property {string} view Template path
47
- * @property {PageHook[]} hooks Page-specific hooks
48
- * @property {PageField[]} fields Fields to be managed on this page
49
- */
50
- /**
51
- * @typedef {Object} ConfigureResult Result of a call to configure() function
52
- * @property {nunjucks.Environment} nunjucksEnv Nunjucks environment to attach to other ExpressJS app instances
53
- * @property {MutableRouter} staticRouter ExpressJS Router instance which serves all static assets
54
- * @property {MutableRouter} ancillaryRouter ExpressJS app instance which serves all ancillary routes
55
- * @property {MutableRouter} journeyRouter ExpressJS app instance which serves page routes for each waypoint in a user's journey
56
- * @property {express.RequestHandler[]} preMiddleware Middleware mounted before anything else
57
- * @property {express.RequestHandler[]} postMiddleware Middleware mounted after everything else
58
- * @property {express.RequestHandler[]} csrfMiddleware Collection of middleware useful for pages containing forms
59
- * @property {express.RequestHandler} sessionMiddleware Session middleware
60
- * @property {express.RequestHandler[]} cookieParserMiddleware Cookie-parsing middleware (configured to match that of session middleware)
61
- * @property {express.RequestHandler[]} i18nMiddleware I18n preparation middleware
62
- * @property {express.RequestHandler} bodyParserMiddleware Body parsing middleware
63
- * @property {express.RequestHandler[]} csrfMiddleware CSRF middleware
64
- * @property {function} mount Function used to mount all CASA artifacts onto an ExpressJS app instance
33
+ * @typedef {object} ConfigureResult Result of a call to configure() function
34
+ * @property {nunjucks.Environment} nunjucksEnv Nunjucks environment
35
+ * @property {MutableRouter} staticRouter Router handling all static assets
36
+ * @property {MutableRouter} ancillaryRouter Router handling ancillary routes
37
+ * @property {MutableRouter} journeyRouter Router handling all waypoint requests
38
+ * @property {ExpressRequestHandler[]} preMiddleware Middleware mounted before anything else
39
+ * @property {ExpressRequestHandler[]} postMiddleware Middleware mounted after everything else
40
+ * @property {ExpressRequestHandler[]} csrfMiddleware CSRF get/set middleware (useful for forms)
41
+ * @property {ExpressRequestHandler} sessionMiddleware Session middleware
42
+ * @property {ExpressRequestHandler[]} cookieParserMiddleware Cookie-parsing middleware
43
+ * @property {ExpressRequestHandler[]} i18nMiddleware I18n preparation middleware
44
+ * @property {ExpressRequestHandler} bodyParserMiddleware Body parsing middleware
45
+ * @property {Function} mount Function used to mount all CASA artifacts onto an ExpressJS app
65
46
  */
66
47
  /**
67
48
  * Configure some middleware for use in creating a new CASA app.
@@ -69,17 +50,7 @@ const csrf_js_1 = __importDefault(require("../middleware/csrf.js"));
69
50
  * `mountUrl` is used to ensure the CSS content uses the correct reference to
70
51
  * static assets in the `govuk-frontend` module.
71
52
  *
72
- * @param {Object} config Configuration options
73
- * @param {string} [config.mountUrl=/] URL path used to serve static assets from and generate links (optional, default /)
74
- * @param {string} [config.serviceName=common.serviceName] Service name (i18n key) to display in header (optional, default common:serviceName)
75
- * @param {string[]} [config.views=[]] Array of directories in which Nunjucks templates will be searched for (optional, default [])
76
- * @param {SessionOptions} [config.session] Session configuration
77
- * @param {Page[]} [config.pages=[]] Pages the represent waypoints in the Plan (optional, default [])
78
- * @param {GlobalHook[]} [config.hooks=[]] Hooks to apply (optional, default [])
79
- * @param {Object[]} [config.plugins=[]] Plugins(optional, default [])
80
- * @param {I18nOptions[]} [config.i18n] I18n configuration
81
- * @param {Plan} config.plan CASA Plan
82
- * @param {ContextEvent[]} [config.events=[]] Handlers for JourneyContext events
53
+ * @param {ConfigurationOptions} config Configuration options
83
54
  * @returns {ConfigureResult} Result
84
55
  */
85
56
  function configure(config = {}) {
@@ -90,18 +61,24 @@ function configure(config = {}) {
90
61
  plugin.configure(config);
91
62
  });
92
63
  // Extract config
93
- // TODO: Validate/sanitise and deep-freeze object
94
- const { mountUrl = '/', serviceName = 'common:serviceName', views = [], session = {
64
+ const { mountUrl = '/', views = [], session = {
95
65
  secret: 'secret',
96
66
  name: 'casasession',
97
67
  secure: false,
98
- ttl: 60 * 60,
68
+ ttl: 3600,
99
69
  cookieSameSite: true,
70
+ cookiePath: '/',
100
71
  store: undefined,
101
72
  }, pages = [], plan = null, hooks = [], plugins = [], events = [], i18n = {
102
73
  dirs: [],
103
74
  locales: ['en', 'cy'],
104
- }, } = config;
75
+ }, } = (0, configuration_ingestor_js_1.default)(config);
76
+ // Prepare all page hooks so they are prefixed with the `journey.` scope.
77
+ pages.forEach((page) => {
78
+ var _a;
79
+ /* eslint-disable-next-line no-param-reassign,no-return-assign */
80
+ ((_a = page === null || page === void 0 ? void 0 : page.hooks) !== null && _a !== void 0 ? _a : []).forEach((h) => h.hook = `journey.${h.hook}`);
81
+ });
105
82
  // Prepare a Nunjucks environment for rendering all templates.
106
83
  // Resolve priority: userland templates > CASA templates > GOVUK templates > Plugin templates
107
84
  const nunjucksEnv = (0, nunjucks_js_1.default)({
@@ -116,7 +93,7 @@ function configure(config = {}) {
116
93
  // These _must_ be added to the ExpressJS application at the start and end
117
94
  // of all other middleware respectively.
118
95
  const preMiddleware = (0, pre_js_1.default)();
119
- const postMiddleware = (0, post_js_1.default)();
96
+ const postMiddleware = (0, post_js_1.default)({ mountUrl });
120
97
  // Prepare common middleware mounted prior to the ancillaryRouter
121
98
  const cookieParserMiddleware = (0, cookie_parser_1.default)(session.secret);
122
99
  const sessionMiddleware = (0, session_js_1.default)({
@@ -126,6 +103,7 @@ function configure(config = {}) {
126
103
  name: session.name,
127
104
  ttl: session.ttl,
128
105
  cookieSameSite: session.cookieSameSite,
106
+ cookiePath: session.cookiePath,
129
107
  mountUrl,
130
108
  store: (_b = session.store) !== null && _b !== void 0 ? _b : new express_session_1.MemoryStore(),
131
109
  });
@@ -140,7 +118,6 @@ function configure(config = {}) {
140
118
  const dataMiddleware = (0, data_js_1.default)({
141
119
  plan,
142
120
  mountUrl,
143
- serviceName,
144
121
  events,
145
122
  });
146
123
  // Prepare form middleware and its constiuent parts
@@ -173,7 +150,7 @@ function configure(config = {}) {
173
150
  app.set('view engine', 'njk');
174
151
  app.use(preMiddleware);
175
152
  app.use(staticRouter.seal());
176
- app.use(sessionMiddleware); // A session is useful to all pages, so assume it is always mounted after static routes
153
+ app.use(sessionMiddleware); // A session is useful to all pages, so always mounted
177
154
  app.use(i18nMiddleware);
178
155
  app.use(bodyParserMiddleware);
179
156
  app.use(dataMiddleware);
@@ -194,21 +171,20 @@ function configure(config = {}) {
194
171
  staticRouter,
195
172
  ancillaryRouter,
196
173
  journeyRouter,
197
- // Form middleware. Should be used wherever form pages are built.
174
+ // CSRF middleware. Should be used wherever form pages are built.
198
175
  csrfMiddleware,
199
176
  // Other middleware
200
177
  // These may be used by the application author to build other custom routes
201
178
  cookieParserMiddleware,
202
179
  sessionMiddleware,
203
180
  bodyParserMiddleware,
204
- csrfMiddleware,
205
181
  i18nMiddleware,
206
182
  dataMiddleware,
207
183
  // Mount function
208
184
  mount,
209
185
  };
210
186
  // Bootstrap all plugins
211
- plugins.filter(p => p.bootstrap).forEach((plugin) => plugin === null || plugin === void 0 ? void 0 : plugin.bootstrap(configOutput));
187
+ plugins.filter((p) => p.bootstrap).forEach((plugin) => plugin === null || plugin === void 0 ? void 0 : plugin.bootstrap(configOutput));
212
188
  // Finished configuration
213
189
  return configOutput;
214
190
  }
@@ -1 +1 @@
1
- module.exports = __dirname;
1
+ module.exports = __dirname;
@@ -0,0 +1,2 @@
1
+ declare const _exports: string;
2
+ export = _exports;
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * A convenience for ending the current session, but retaining some data in it,
3
- * like the current language.
3
+ * like the current language. It persists an empty session before regenerating
4
+ * a new ID.
4
5
  *
5
6
  * Note: this will not remove the session from server-side storage, which will
6
7
  * instead be left up to the storage mechanism to clean up.
7
8
  *
8
- * @param {Object} req HTTP request
9
+ * @param {object} req HTTP request
9
10
  * @param {Function} next Chain
10
11
  * @returns {void}
11
12
  */
12
- export default function endSession(req: Object, next: Function): void;
13
+ export default function endSession(req: object, next: Function): void;
@@ -1,24 +1,46 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const logger_js_1 = __importDefault(require("./logger.js"));
7
+ const log = (0, logger_js_1.default)('lib:end-session');
3
8
  /**
4
9
  * A convenience for ending the current session, but retaining some data in it,
5
- * like the current language.
10
+ * like the current language. It persists an empty session before regenerating
11
+ * a new ID.
6
12
  *
7
13
  * Note: this will not remove the session from server-side storage, which will
8
14
  * instead be left up to the storage mechanism to clean up.
9
15
  *
10
- * @param {Object} req HTTP request
16
+ * @param {object} req HTTP request
11
17
  * @param {Function} next Chain
12
18
  * @returns {void}
13
19
  */
14
20
  function endSession(req, next) {
15
- const language = req.session.language;
16
- req.session.regenerate((err) => {
17
- if (err) {
18
- return next(err);
21
+ const { language } = req.session;
22
+ Object.entries(req.session).forEach(([k]) => {
23
+ if (!['cookie'].includes(k)) {
24
+ // ESLint disabled as `Object.entries()` returns "own" properties, and
25
+ // all values are being null'd, so not assigned any user-controlled values
26
+ /* eslint-disable-next-line security/detect-object-injection */
27
+ req.session[k] = null;
19
28
  }
20
- req.session.language = language;
21
- req.session.save(next);
29
+ });
30
+ req.session.save((saveErr) => {
31
+ if (saveErr) {
32
+ log.error(saveErr);
33
+ }
34
+ req.session.regenerate((err) => {
35
+ if (err) {
36
+ log.error(err);
37
+ next(err);
38
+ }
39
+ else {
40
+ req.session.language = language;
41
+ req.session.save(next);
42
+ }
43
+ });
22
44
  });
23
45
  }
24
46
  exports.default = endSession;
@@ -5,16 +5,40 @@ export class PageField {
5
5
  * For complex fields, we need may need to drill into an object to extract the
6
6
  * value.
7
7
  *
8
- * @param {Object} obj Object from which to extract the value
9
- * @returns {any}
8
+ * @param {object} obj Object from which to extract the value
9
+ * @returns {any} Value extracted from object
10
+ * @throws {Error} When run on a complex field
10
11
  */
11
- getValue(obj?: Object): any;
12
+ getValue(obj?: object): any;
12
13
  putValue(obj: any, value: any): PageField;
13
14
  get name(): string;
14
- get meta(): Object;
15
- validators(...items: any[]): PageField | Validator[];
16
- processors(...items: any[]): Function[] | PageField;
17
- conditions(...items: any[]): Function[] | PageField;
15
+ get meta(): object;
16
+ /**
17
+ * Add/get value validators
18
+ * Some validators will include a `sanitise()` method which will be run at the
19
+ * same time as other "processors".
20
+ *
21
+ * @param {ValidateFunction[]} items Validation functions
22
+ * @returns {PageField | ValidateFunction[]} Chain or return all validators
23
+ */
24
+ validators(items?: ValidateFunction[]): PageField | ValidateFunction[];
25
+ /**
26
+ * Add/get value pre-processors
27
+ * This is most often used to sanitise values to a particular data type.
28
+ *
29
+ * @param {ProcessorFunction[]} items Processor functions
30
+ * @returns {PageField | ProcessorFunction[]} Chain or return all processors
31
+ */
32
+ processors(items?: ProcessorFunction[]): PageField | ProcessorFunction[];
33
+ /**
34
+ * Add/get conditions
35
+ * All conditions must be met in order for this field to be considered
36
+ * "actionable".
37
+ *
38
+ * @param {ConditionFunction[]} items Condition functions
39
+ * @returns {PageField | ConditionFunction[]} Chain or return all conditions
40
+ */
41
+ conditions(items?: ConditionFunction[]): PageField | ConditionFunction[];
18
42
  /**
19
43
  * Run all validators and return array of errors, if applicable.
20
44
  *
@@ -22,58 +46,32 @@ export class PageField {
22
46
  * @param {ValidateContext} context Contextual information
23
47
  * @returns {ValidationError[]} Errors, or an empty array if all valid
24
48
  */
25
- runValidators(value: any, context: ValidateContext): any[];
49
+ runValidators(value: any, context: any): ValidationError[];
26
50
  applyProcessors(value: any): any;
27
51
  /**
28
52
  * Apply all conditions to get the resulting boolean
29
53
  *
30
- * @param {Object} params Parameters
31
- * @param {string} fieldValue Field value
32
- * @param {string} waypoint Waypoint
33
- * @param {object} journeyContext JourneyContext
34
- * @returns {boolean}
54
+ * @param {object} params Parameters
55
+ * @param {string} params.fieldValue Field value
56
+ * @param {string} params.waypoint Waypoint
57
+ * @param {object} params.journeyContext JourneyContext
58
+ * @returns {boolean} True if all conditions pass
35
59
  */
36
- testConditions({ fieldValue, waypoint, journeyContext }: Object): boolean;
37
- validator(...args: any[]): PageField | Validator[];
38
- processor(...args: any[]): Function[] | PageField;
39
- condition(...args: any[]): Function[] | PageField;
40
- if(...args: any[]): Function[] | PageField;
60
+ testConditions({ fieldValue, waypoint, journeyContext }: {
61
+ fieldValue: string;
62
+ waypoint: string;
63
+ journeyContext: object;
64
+ }): boolean;
65
+ validator(validator: any): any[] | PageField;
66
+ processor(processor: any): PageField | ProcessorFunction[];
67
+ condition(condition: any): PageField | ConditionFunction[];
68
+ if(...args: any[]): PageField | ConditionFunction[];
41
69
  #private;
42
70
  }
43
- export type Validator = {
44
- /**
45
- * Validation function
46
- */
47
- validate: ValidateFunction;
48
- /**
49
- * Sanitise a given value to make it suitable for this validator
50
- */
51
- sanitise: SanitiseFunction;
52
- /**
53
- * Configuration
54
- */
55
- config: Object;
56
- /**
57
- * Validator name
58
- */
59
- name: string;
60
- };
61
- export type ValidateFunction = (value: any, context: ValidateContext) => any[];
62
- export type SanitiseFunction = (value: any) => any;
63
- /**
64
- * Context passed to validate function
65
- */
66
- export type ValidateContext = {
67
- /**
68
- * Journey context
69
- */
70
- journeyContext: any;
71
- /**
72
- * Waypoint
73
- */
74
- waypoint: string;
75
- /**
76
- * Name of field being processed
77
- */
78
- fieldName: string;
79
- };
71
+ export type JourneyContext = import('./index').JourneyContext;
72
+ export type Validator = import('./index').Validator;
73
+ export type ValidateFunction = import('./index').ValidateFunction;
74
+ export type ValidateContext = import('./index').ValidateContext;
75
+ export type ValidationError = import('./index').ValidationError;
76
+ export type ProcessorFunction = (value: any) => any;
77
+ export type ConditionFunction = (context: Object, fieldName: string, fieldValue: any, waypoint: string, waypointId: string, journeyContext: JourneyContext) => boolean;