@dwp/govuk-casa 7.0.6 → 8.0.0-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +22 -17
  3. package/dist/{casa → assets}/css/casa-ie8.css +1 -1
  4. package/dist/assets/css/casa.css +1 -0
  5. package/dist/casa.d.ts +11 -0
  6. package/dist/casa.js +46 -0
  7. package/dist/lib/CasaTemplateLoader.d.ts +29 -0
  8. package/dist/lib/CasaTemplateLoader.js +74 -0
  9. package/dist/lib/JourneyContext.d.ts +297 -0
  10. package/dist/lib/JourneyContext.js +581 -0
  11. package/dist/lib/MutableRouter.d.ts +155 -0
  12. package/dist/lib/MutableRouter.js +277 -0
  13. package/dist/lib/Plan.d.ts +154 -0
  14. package/dist/lib/Plan.js +442 -0
  15. package/dist/lib/ValidationError.d.ts +74 -0
  16. package/dist/lib/ValidationError.js +159 -0
  17. package/dist/lib/ValidatorFactory.d.ts +83 -0
  18. package/dist/lib/ValidatorFactory.js +106 -0
  19. package/dist/lib/configuration-ingestor.d.ts +262 -0
  20. package/dist/lib/configuration-ingestor.js +490 -0
  21. package/dist/lib/configure.d.ts +90 -0
  22. package/dist/lib/configure.js +192 -0
  23. package/dist/lib/dirname.cjs +1 -0
  24. package/dist/lib/dirname.d.cts +2 -0
  25. package/dist/lib/end-session.d.ts +13 -0
  26. package/dist/lib/end-session.js +43 -0
  27. package/dist/lib/field.d.ts +77 -0
  28. package/dist/lib/field.js +255 -0
  29. package/dist/lib/index.d.ts +14 -0
  30. package/dist/lib/index.js +54 -0
  31. package/dist/lib/logger.d.ts +9 -0
  32. package/dist/lib/logger.js +18 -0
  33. package/dist/lib/nunjucks-filters.d.ts +26 -0
  34. package/dist/lib/nunjucks-filters.js +90 -0
  35. package/dist/lib/nunjucks.d.ts +23 -0
  36. package/dist/lib/nunjucks.js +49 -0
  37. package/dist/lib/utils.d.ts +48 -0
  38. package/dist/lib/utils.js +111 -0
  39. package/dist/lib/validators/dateObject.d.ts +4 -0
  40. package/dist/lib/validators/dateObject.js +135 -0
  41. package/dist/lib/validators/email.d.ts +4 -0
  42. package/dist/lib/validators/email.js +46 -0
  43. package/dist/lib/validators/inArray.d.ts +4 -0
  44. package/dist/lib/validators/inArray.js +60 -0
  45. package/dist/lib/validators/index.d.ts +21 -0
  46. package/dist/lib/validators/index.js +47 -0
  47. package/dist/lib/validators/nino.d.ts +4 -0
  48. package/dist/lib/validators/nino.js +46 -0
  49. package/dist/lib/validators/postalAddressObject.d.ts +4 -0
  50. package/dist/lib/validators/postalAddressObject.js +123 -0
  51. package/dist/lib/validators/regex.d.ts +4 -0
  52. package/dist/lib/validators/regex.js +40 -0
  53. package/dist/lib/validators/required.d.ts +4 -0
  54. package/dist/lib/validators/required.js +56 -0
  55. package/dist/lib/validators/strlen.d.ts +4 -0
  56. package/dist/lib/validators/strlen.js +51 -0
  57. package/dist/lib/validators/wordCount.d.ts +5 -0
  58. package/dist/lib/validators/wordCount.js +54 -0
  59. package/dist/lib/waypoint-url.d.ts +23 -0
  60. package/dist/lib/waypoint-url.js +52 -0
  61. package/dist/middleware/body-parser.d.ts +1 -0
  62. package/dist/middleware/body-parser.js +24 -0
  63. package/dist/middleware/csrf.d.ts +1 -0
  64. package/dist/middleware/csrf.js +31 -0
  65. package/dist/middleware/data.d.ts +5 -0
  66. package/dist/middleware/data.js +53 -0
  67. package/dist/middleware/dirname.cjs +1 -0
  68. package/dist/middleware/dirname.d.cts +2 -0
  69. package/dist/middleware/gather-fields.d.ts +6 -0
  70. package/dist/middleware/gather-fields.js +48 -0
  71. package/dist/middleware/i18n.d.ts +4 -0
  72. package/dist/middleware/i18n.js +88 -0
  73. package/dist/middleware/post.d.ts +3 -0
  74. package/dist/middleware/post.js +57 -0
  75. package/dist/middleware/pre.d.ts +3 -0
  76. package/dist/middleware/pre.js +51 -0
  77. package/dist/middleware/progress-journey.d.ts +6 -0
  78. package/dist/middleware/progress-journey.js +80 -0
  79. package/dist/middleware/sanitise-fields.d.ts +5 -0
  80. package/dist/middleware/sanitise-fields.js +53 -0
  81. package/dist/middleware/session.d.ts +11 -0
  82. package/dist/middleware/session.js +121 -0
  83. package/dist/middleware/skip-waypoint.d.ts +5 -0
  84. package/dist/middleware/skip-waypoint.js +43 -0
  85. package/dist/middleware/steer-journey.d.ts +7 -0
  86. package/dist/middleware/steer-journey.js +62 -0
  87. package/dist/middleware/validate-fields.d.ts +7 -0
  88. package/dist/middleware/validate-fields.js +67 -0
  89. package/dist/mjs/esm-wrapper.js +11 -0
  90. package/dist/mjs/package.json +3 -0
  91. package/dist/package.json +3 -0
  92. package/dist/routes/ancillary.d.ts +11 -0
  93. package/dist/routes/ancillary.js +27 -0
  94. package/dist/routes/dirname.cjs +1 -0
  95. package/dist/routes/dirname.d.cts +2 -0
  96. package/dist/routes/journey.d.ts +8 -0
  97. package/dist/routes/journey.js +127 -0
  98. package/dist/routes/static.d.ts +26 -0
  99. package/dist/routes/static.js +68 -0
  100. package/package.json +64 -89
  101. package/views/casa/components/checkboxes/template.njk +4 -1
  102. package/views/casa/components/date-input/template.njk +3 -3
  103. package/views/casa/components/journey-form/README.md +3 -1
  104. package/views/casa/components/journey-form/template.njk +1 -1
  105. package/views/casa/components/postal-address-object/template.njk +5 -5
  106. package/views/casa/components/radios/template.njk +1 -1
  107. package/views/casa/errors/static.njk +11 -0
  108. package/views/casa/layouts/journey.njk +26 -9
  109. package/views/casa/layouts/main.njk +7 -20
  110. package/views/casa/partials/scripts.njk +8 -3
  111. package/views/casa/partials/styles.njk +2 -2
  112. package/casa.js +0 -208
  113. package/definitions/review-page.js +0 -60
  114. package/dist/casa/css/casa.css +0 -1
  115. package/dist/casa/js/casa.js +0 -1
  116. package/index.d.ts +0 -121
  117. package/lib/ConfigIngestor.js +0 -588
  118. package/lib/GatherModifier.js +0 -14
  119. package/lib/I18n.js +0 -160
  120. package/lib/JourneyContext.d.ts +0 -97
  121. package/lib/JourneyContext.js +0 -552
  122. package/lib/JourneyMap.js +0 -233
  123. package/lib/JourneyRoad.js +0 -330
  124. package/lib/Logger.js +0 -59
  125. package/lib/PageDictionary.d.ts +0 -11
  126. package/lib/PageDirectory.js +0 -77
  127. package/lib/Plan.js +0 -423
  128. package/lib/RoadConverter.js +0 -153
  129. package/lib/UserJourney.js +0 -8
  130. package/lib/Util.js +0 -227
  131. package/lib/Validation.js +0 -20
  132. package/lib/bootstrap/end-session.js +0 -44
  133. package/lib/bootstrap/load-definitions.js +0 -64
  134. package/lib/commonBodyParser.js +0 -15
  135. package/lib/enums.js +0 -6
  136. package/lib/gather-modifiers/index.js +0 -7
  137. package/lib/gather-modifiers/trimPostalAddressObject.js +0 -75
  138. package/lib/gather-modifiers/trimWhitespace.js +0 -16
  139. package/lib/utils/createGetRequest.d.ts +0 -5
  140. package/lib/utils/createGetRequest.js +0 -59
  141. package/lib/utils/index.js +0 -11
  142. package/lib/utils/parseRequest.d.ts +0 -5
  143. package/lib/utils/parseRequest.js +0 -72
  144. package/lib/utils/sanitise.js +0 -74
  145. package/lib/utils/validate.js +0 -32
  146. package/lib/validation/ArrayObjectField.js +0 -49
  147. package/lib/validation/ObjectField.js +0 -53
  148. package/lib/validation/SimpleField.d.ts +0 -11
  149. package/lib/validation/SimpleField.js +0 -46
  150. package/lib/validation/ValidationError.d.ts +0 -14
  151. package/lib/validation/ValidationError.js +0 -170
  152. package/lib/validation/ValidatorFactory.d.ts +0 -32
  153. package/lib/validation/ValidatorFactory.js +0 -91
  154. package/lib/validation/index.js +0 -22
  155. package/lib/validation/processor/flattenErrorArray.js +0 -24
  156. package/lib/validation/processor/queue.js +0 -214
  157. package/lib/validation/processor.js +0 -84
  158. package/lib/validation/rules/README.md +0 -3
  159. package/lib/validation/rules/ValidationRules.d.ts +0 -22
  160. package/lib/validation/rules/dateObject.js +0 -156
  161. package/lib/validation/rules/email.js +0 -44
  162. package/lib/validation/rules/inArray.js +0 -61
  163. package/lib/validation/rules/index.js +0 -23
  164. package/lib/validation/rules/nino.js +0 -48
  165. package/lib/validation/rules/optional.js +0 -14
  166. package/lib/validation/rules/postalAddressObject.js +0 -142
  167. package/lib/validation/rules/regex.js +0 -39
  168. package/lib/validation/rules/required.js +0 -57
  169. package/lib/validation/rules/strlen.js +0 -57
  170. package/lib/validation/rules/wordCount.js +0 -61
  171. package/lib/view-filters/formatDateObject.js +0 -35
  172. package/lib/view-filters/includes.js +0 -10
  173. package/lib/view-filters/index.js +0 -23
  174. package/lib/view-filters/mergeObjectsDeep.js +0 -21
  175. package/lib/view-filters/renderAsAttributes.js +0 -33
  176. package/middleware/errors/404.js +0 -12
  177. package/middleware/errors/catch-all.js +0 -27
  178. package/middleware/errors/index.js +0 -9
  179. package/middleware/headers/config-defaults.js +0 -57
  180. package/middleware/headers/headers.js +0 -40
  181. package/middleware/headers/index.js +0 -9
  182. package/middleware/i18n/i18n.js +0 -56
  183. package/middleware/i18n/index.js +0 -16
  184. package/middleware/index.js +0 -55
  185. package/middleware/mount/index.js +0 -9
  186. package/middleware/mount/mount.js +0 -10
  187. package/middleware/nunjucks/environment.js +0 -57
  188. package/middleware/nunjucks/index.js +0 -8
  189. package/middleware/page/csrf.js +0 -37
  190. package/middleware/page/edit-mode.js +0 -52
  191. package/middleware/page/gather.js +0 -75
  192. package/middleware/page/index.js +0 -103
  193. package/middleware/page/journey-continue.js +0 -157
  194. package/middleware/page/journey-rails.js +0 -102
  195. package/middleware/page/prepare-request.js +0 -77
  196. package/middleware/page/render.js +0 -75
  197. package/middleware/page/skip.js +0 -72
  198. package/middleware/page/utils.js +0 -206
  199. package/middleware/page/validate.js +0 -67
  200. package/middleware/session/expiry.js +0 -95
  201. package/middleware/session/genid.js +0 -18
  202. package/middleware/session/index.js +0 -18
  203. package/middleware/session/init.js +0 -25
  204. package/middleware/session/seed.js +0 -50
  205. package/middleware/session/timeout.js +0 -5
  206. package/middleware/static/asset-versions.js +0 -23
  207. package/middleware/static/index.js +0 -104
  208. package/middleware/static/prepare-assets.js +0 -51
  209. package/middleware/static/serve-assets.js +0 -58
  210. package/middleware/variables/index.js +0 -12
  211. package/middleware/variables/variables.js +0 -35
  212. package/src/browserconfig.xml +0 -5
  213. package/src/js/casa.js +0 -132
  214. package/src/scss/_casaElements.scss +0 -11
  215. package/src/scss/_casaGovukTemplateJinjaPolyfill.scss +0 -39
  216. package/src/scss/_casaMountUrl.scss +0 -8
  217. package/src/scss/casa-ie8.scss +0 -3
  218. package/src/scss/casa.scss +0 -14
  219. package/test/unit/templates/README.md +0 -5
  220. package/test/utils/BaseTestWaypoint.js +0 -106
  221. package/test/utils/concatWaypoints.js +0 -26
  222. package/test/utils/index.js +0 -6
  223. package/test/utils/testTraversal.js +0 -90
  224. package/views/casa/partials/cookie_message.njk +0 -3
  225. package/views/casa/partials/phase_banner_alpha.njk +0 -8
  226. package/views/casa/partials/phase_banner_beta.njk +0 -8
  227. package/views/casa/review/page-block.njk +0 -8
  228. package/views/casa/review/review.njk +0 -47
@@ -0,0 +1,47 @@
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 dateObject_js_1 = __importDefault(require("./dateObject.js"));
7
+ const email_js_1 = __importDefault(require("./email.js"));
8
+ const inArray_js_1 = __importDefault(require("./inArray.js"));
9
+ const nino_js_1 = __importDefault(require("./nino.js"));
10
+ const postalAddressObject_js_1 = __importDefault(require("./postalAddressObject.js"));
11
+ const regex_js_1 = __importDefault(require("./regex.js"));
12
+ const required_js_1 = __importDefault(require("./required.js"));
13
+ const strlen_js_1 = __importDefault(require("./strlen.js"));
14
+ const wordCount_js_1 = __importDefault(require("./wordCount.js"));
15
+ exports.default = {
16
+ dateObject: dateObject_js_1.default,
17
+ email: email_js_1.default,
18
+ inArray: inArray_js_1.default,
19
+ nino: nino_js_1.default,
20
+ postalAddressObject: postalAddressObject_js_1.default,
21
+ regex: regex_js_1.default,
22
+ required: required_js_1.default,
23
+ strlen: strlen_js_1.default,
24
+ wordCount: wordCount_js_1.default,
25
+ };
26
+ // const dateObject = require('./dateObject.js');
27
+ // const email = require('./email.js');
28
+ // const inArray = require('./inArray.js');
29
+ // const nino = require('./nino.js');
30
+ // const optional = require('./optional.js');
31
+ // const postalAddressObject = require('./postalAddressObject.js');
32
+ // const regex = require('./regex.js');
33
+ // const required = require('./required.js');
34
+ // const strlen = require('./strlen.js');
35
+ // const wordCount = require('./wordCount.js');
36
+ // module.exports = {
37
+ // dateObject,
38
+ // email,
39
+ // inArray,
40
+ // nino,
41
+ // optional,
42
+ // postalAddressObject,
43
+ // regex,
44
+ // required,
45
+ // strlen,
46
+ // wordCount,
47
+ // };
@@ -0,0 +1,4 @@
1
+ export default class Nino extends ValidatorFactory {
2
+ name: string;
3
+ }
4
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,46 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * UK National Insurance number.
9
+ *
10
+ * Config options:
11
+ * string|object errorMsg = Error message to use on validation failure
12
+ * boolean allowWhitespace = will permit input values that contain spaces.
13
+ *
14
+ * Ref:
15
+ * https://en.wikipedia.org/wiki/National_Insurance_number#Format
16
+ * https://design-system.service.gov.uk/patterns/national-insurance-numbers/
17
+ */
18
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
19
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
20
+ const utils_js_1 = require("../utils.js");
21
+ class Nino extends ValidatorFactory_js_1.default {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.name = 'nino';
25
+ }
26
+ validate(value, dataContext = {}) {
27
+ const { allowWhitespace, errorMsg = {
28
+ inline: 'validation:rule.nino.inline',
29
+ summary: 'validation:rule.nino.summary',
30
+ }, } = this.config;
31
+ if (typeof allowWhitespace !== 'undefined' && typeof allowWhitespace !== 'boolean') {
32
+ throw new TypeError(`NINO validation rule option "allowWhitespace" must been a boolean. received ${typeof allowWhitespace}`);
33
+ }
34
+ const valid = typeof value === 'string'
35
+ && value.replace((typeof allowWhitespace !== 'undefined' && allowWhitespace) ? /\u0020/g : '', '')
36
+ .match(/^(?!BG|GB|NK|KN|TN|NT|ZZ)[ABCEGHJ-PRSTW-Z][ABCEGHJ-NPRSTW-Z]\d{6}[A-D]$/i);
37
+ return valid ? [] : [ValidationError_js_1.default.make({ errorMsg, dataContext })];
38
+ }
39
+ sanitise(value) {
40
+ if (value !== undefined) {
41
+ return (0, utils_js_1.stringifyInput)(value);
42
+ }
43
+ return undefined;
44
+ }
45
+ }
46
+ exports.default = Nino;
@@ -0,0 +1,4 @@
1
+ export default class PostalAddressObject extends ValidatorFactory {
2
+ name: string;
3
+ }
4
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,123 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * Works hand in hand with the core CASA `postalAddressObject` form macro.
9
+ *
10
+ * The errors sent back from this validator are specific to each subfield. For
11
+ * example, if the field name being tested is "address", any errors related to
12
+ * the "postcode" component would be associated with "address[postcode]".
13
+ *
14
+ * Config options:
15
+ * string|object errorMsg = General error message for the entire address block
16
+ * string|object errorMsgAddress1 = Error message for address1 part
17
+ * string|object errorMsgAddress2 = Error message for address2 part
18
+ * string|object errorMsgAddress3 = Error message for address3 part
19
+ * string|object errorMsgAddress4 = Error message for address4 part
20
+ * string|object errorMsgPostcode = Error message for postcode part
21
+ * int strlenmax = Max. String length for each of the inputs appress[1-4]
22
+ * array requiredFields = Field parts required (others become optional)
23
+ */
24
+ const lodash_1 = __importDefault(require("lodash"));
25
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
26
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
27
+ const utils_js_1 = require("../utils.js");
28
+ const { isPlainObject } = lodash_1.default; // CommonjS
29
+ class PostalAddressObject extends ValidatorFactory_js_1.default {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.name = 'postalAddressObject';
33
+ }
34
+ validate(value, dataContext = {}) {
35
+ const cfg = Object.assign({ requiredFields: ['address1', 'address3', 'postcode'], strlenmax: undefined, errorMsgAddress1: {
36
+ inline: 'validation:rule.postalAddressObject.address1.inline',
37
+ summary: 'validation:rule.postalAddressObject.address1.summary',
38
+ focusSuffix: '[address1]',
39
+ }, errorMsgAddress2: {
40
+ inline: 'validation:rule.postalAddressObject.address2.inline',
41
+ summary: 'validation:rule.postalAddressObject.address2.summary',
42
+ focusSuffix: '[address2]',
43
+ }, errorMsgAddress3: {
44
+ inline: 'validation:rule.postalAddressObject.address3.inline',
45
+ summary: 'validation:rule.postalAddressObject.address3.summary',
46
+ focusSuffix: '[address3]',
47
+ }, errorMsgAddress4: {
48
+ inline: 'validation:rule.postalAddressObject.address4.inline',
49
+ summary: 'validation:rule.postalAddressObject.address4.summary',
50
+ focusSuffix: '[address4]',
51
+ }, errorMsgPostcode: {
52
+ inline: 'validation:rule.postalAddressObject.postcode.inline',
53
+ summary: 'validation:rule.postalAddressObject.postcode.summary',
54
+ focusSuffix: '[postcode]',
55
+ }, errorMsg: {
56
+ inline: 'validation:rule.postalAddressObject.group.inline',
57
+ summary: 'validation:rule.postalAddressObject.group.summary',
58
+ focusSuffix: '[address1]',
59
+ } }, this.config);
60
+ /* eslint-disable-next-line require-jsdoc */
61
+ const objectifyError = (err) => (typeof err === 'string' ? {
62
+ inline: err,
63
+ summary: err,
64
+ } : err);
65
+ // Work out required/optional parts based on config
66
+ const reqF = Object.create(null);
67
+ const reqC = cfg.requiredFields;
68
+ ['address1', 'address2', 'address3', 'address4', 'postcode'].forEach((k) => {
69
+ reqF[k] = reqC.indexOf(k) > -1;
70
+ });
71
+ let valid = true;
72
+ const errorMsgs = [];
73
+ if (typeof value === 'object') {
74
+ const reAddr = /^[^\s]+[a-z0-9\-,.&#()/\\:;'" ]+$/i;
75
+ const reAddrLine1 = /^\d+|[^\s]+[a-z0-9\-,.&#()/\\:;'" ]+$/i;
76
+ // UK Postcode regex taken from the dwp java pc checker
77
+ // https://github.com/dwp/postcode-format-validation
78
+ const pc = /^(?![QVX])[A-Z]((?![IJZ])[A-Z][0-9](([0-9]?)|([ABEHMNPRVWXY]?))|([0-9]([0-9]?|[ABCDEFGHJKPSTUW]?))) ?[0-9]((?![CIKMOV])[A-Z]){2}$|^(BFPO)[ ]?[0-9]{1,4}$/i;
79
+ const rePostcode = new RegExp(pc, 'i');
80
+ // [required, regex, strlenmax, error message]
81
+ const attributes = {
82
+ address1: [reqF.address1, reAddrLine1, cfg.strlenmax, cfg.errorMsgAddress1],
83
+ address2: [reqF.address2, reAddr, cfg.strlenmax, cfg.errorMsgAddress2],
84
+ address3: [reqF.address3, reAddr, cfg.strlenmax, cfg.errorMsgAddress3],
85
+ address4: [reqF.address4, reAddr, cfg.strlenmax, cfg.errorMsgAddress4],
86
+ postcode: [reqF.postcode, rePostcode, null, cfg.errorMsgPostcode],
87
+ };
88
+ Object.keys(attributes).forEach((k) => {
89
+ const attr = attributes[k];
90
+ const hasProperty = Object.prototype.hasOwnProperty.call(value, k);
91
+ const hasContent = hasProperty && value[k].length > 0;
92
+ const condMissingOrRegexMismatch = (attr[0] || hasContent)
93
+ && (!hasProperty || !value[k].match(attr[1]));
94
+ const condExceedStrlen = attr[2] > 0 && hasContent
95
+ && String(value[k]).length > attr[2];
96
+ if (condMissingOrRegexMismatch || condExceedStrlen) {
97
+ valid = false;
98
+ errorMsgs.push(Object.assign(Object.create(null), objectifyError(attr[3]), {
99
+ fieldKeySuffix: `[${k}]`,
100
+ }));
101
+ }
102
+ });
103
+ }
104
+ else {
105
+ valid = false;
106
+ errorMsgs.push(cfg.errorMsg);
107
+ }
108
+ // Build ValidationErrorGroup
109
+ const errorGroup = errorMsgs.map((err) => (ValidationError_js_1.default.make({ errorMsg: err, dataContext })));
110
+ return valid ? [] : [...errorGroup];
111
+ }
112
+ sanitise(value) {
113
+ // Only objects are supported
114
+ if (!isPlainObject(value)) {
115
+ return Object.create(null);
116
+ }
117
+ // Prune unrecognised attributes, and coerce to Strings
118
+ const validKeys = ['address1', 'address2', 'address3', 'address4', 'postcode'];
119
+ const pruned = Object.fromEntries(Object.entries(value).filter(([k]) => (validKeys.includes(k))).map(([k, v]) => ([k, (0, utils_js_1.stringifyInput)(v)])));
120
+ return Object.assign(Object.create(null), pruned);
121
+ }
122
+ }
123
+ exports.default = PostalAddressObject;
@@ -0,0 +1,4 @@
1
+ export default class Regex extends ValidatorFactory {
2
+ name: string;
3
+ }
4
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,40 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * Match a string pattern.
9
+ *
10
+ * Config options:
11
+ * string|object errorMsg = Error message to use on validation failure
12
+ * RegExp pattern = Regular expression to test against
13
+ * boolean invert = return reject on positive regex match
14
+ */
15
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
16
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
17
+ const utils_js_1 = require("../utils.js");
18
+ class Regex extends ValidatorFactory_js_1.default {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.name = 'regex';
22
+ }
23
+ validate(value = '', dataContext = {}) {
24
+ const invert = this.config.invert || false;
25
+ const match = value.match(this.config.pattern || /.*/);
26
+ const valid = invert ? !match : match;
27
+ const errorMsg = this.config.errorMsg || {
28
+ inline: 'validation:rule.regex.inline',
29
+ summary: 'validation:rule.regex.summary',
30
+ };
31
+ return valid ? [] : [ValidationError_js_1.default.make({ errorMsg, dataContext })];
32
+ }
33
+ sanitise(value) {
34
+ if (value !== undefined) {
35
+ return (0, utils_js_1.stringifyInput)(value);
36
+ }
37
+ return undefined;
38
+ }
39
+ }
40
+ exports.default = Regex;
@@ -0,0 +1,4 @@
1
+ export default class Required extends ValidatorFactory {
2
+ name: string;
3
+ }
4
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,56 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * Test is value is present.
9
+ *
10
+ * Value is required. The following values will fail this rule:
11
+ * (all values that satisify `isEmpty()`) plus '\s'
12
+ */
13
+ const lodash_1 = __importDefault(require("lodash"));
14
+ const utils_js_1 = require("../utils.js");
15
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
16
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
17
+ const { isPlainObject } = lodash_1.default; // CommonJS
18
+ class Required extends ValidatorFactory_js_1.default {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.name = 'required';
22
+ }
23
+ validate(value, dataContext = {}) {
24
+ const { errorMsg = {
25
+ inline: 'validation:rule.required.inline',
26
+ summary: 'validation:rule.required.summary',
27
+ }, } = this.config;
28
+ if (!(0, utils_js_1.isEmpty)(value)) {
29
+ return [];
30
+ }
31
+ return [
32
+ ValidationError_js_1.default.make({ errorMsg, dataContext }),
33
+ ];
34
+ }
35
+ sanitise(value) {
36
+ const coerce = (val) => {
37
+ const s = (0, utils_js_1.stringifyInput)(val, undefined);
38
+ return s === undefined ? undefined : s.replace(/^\s+$/, '');
39
+ };
40
+ if ((0, utils_js_1.isStringable)(value)) {
41
+ return coerce(value);
42
+ }
43
+ // Coerce all elements to Strings.
44
+ // This only supports one dimensional array, with stringable element.
45
+ if (Array.isArray(value)) {
46
+ return value.map(coerce);
47
+ }
48
+ // Coerce all elements to Strings.
49
+ // This only supports a one dimensional object, with stringable elements.
50
+ if (isPlainObject(value)) {
51
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => ([k, coerce(v)])));
52
+ }
53
+ return undefined;
54
+ }
55
+ }
56
+ exports.default = Required;
@@ -0,0 +1,4 @@
1
+ export default class Strlen extends ValidatorFactory {
2
+ name: string;
3
+ }
4
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,51 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * Test the length of a string.
9
+ *
10
+ * Config options:
11
+ * string|object errorMsgMax = Error message to use on max length failure
12
+ * string|object errorMsgMin = Error message to use on min length failure
13
+ * int max = Maximum string length allowed
14
+ * int min = Minimum string length required
15
+ */
16
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
17
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
18
+ const utils_js_1 = require("../utils.js");
19
+ class Strlen extends ValidatorFactory_js_1.default {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.name = 'strlen';
23
+ }
24
+ validate(inputValue = '', dataContext = {}) {
25
+ const { errorMsgMax = {
26
+ inline: 'validation:rule.strlen.max.inline',
27
+ summary: 'validation:rule.strlen.max.summary',
28
+ }, errorMsgMin = {
29
+ inline: 'validation:rule.strlen.min.inline',
30
+ summary: 'validation:rule.strlen.min.summary',
31
+ }, min, max, } = this.config;
32
+ let errorMsg;
33
+ let valid = true;
34
+ if (typeof max !== 'undefined' && inputValue.length > max) {
35
+ valid = false;
36
+ errorMsg = errorMsgMax;
37
+ }
38
+ if (typeof min !== 'undefined' && inputValue.length < min) {
39
+ valid = false;
40
+ errorMsg = errorMsgMin;
41
+ }
42
+ return valid ? [] : [ValidationError_js_1.default.make({ errorMsg, dataContext })];
43
+ }
44
+ sanitise(value) {
45
+ if (value !== undefined) {
46
+ return (0, utils_js_1.stringifyInput)(value);
47
+ }
48
+ return undefined;
49
+ }
50
+ }
51
+ exports.default = Strlen;
@@ -0,0 +1,5 @@
1
+ export default class WordCount extends ValidatorFactory {
2
+ name: string;
3
+ count(input: any): any;
4
+ }
5
+ import ValidatorFactory from "../ValidatorFactory.js";
@@ -0,0 +1,54 @@
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
+ /* eslint-disable class-methods-use-this */
7
+ /**
8
+ * Test the number of words in a string.
9
+ *
10
+ * Config options:
11
+ * string|object errorMsgMax = Error message to use on max length failure
12
+ * string|object errorMsgMin = Error message to use on min length failure
13
+ * int max = Maximum word count allowed
14
+ * int min = Minimum word count required
15
+ */
16
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
17
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
18
+ const utils_js_1 = require("../utils.js");
19
+ class WordCount extends ValidatorFactory_js_1.default {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.name = 'wordCount';
23
+ }
24
+ count(input) {
25
+ return (input.match(/\S+/g) || []).length;
26
+ }
27
+ validate(inputValue = '', dataContext = {}) {
28
+ const { errorMsgMax = {
29
+ inline: 'validation:rule.wordCount.max.inline',
30
+ summary: 'validation:rule.wordCount.max.summary',
31
+ }, errorMsgMin = {
32
+ inline: 'validation:rule.wordCount.min.inline',
33
+ summary: 'validation:rule.wordCount.min.summary',
34
+ }, min, max, } = this.config;
35
+ let errorMsg;
36
+ let valid = true;
37
+ if (typeof max !== 'undefined' && (inputValue.match(/\S+/g) || []).length > max) {
38
+ valid = false;
39
+ errorMsg = errorMsgMax;
40
+ }
41
+ if (typeof min !== 'undefined' && (inputValue.match(/\S+/g) || []).length < min) {
42
+ valid = false;
43
+ errorMsg = errorMsgMin;
44
+ }
45
+ return valid ? [] : [ValidationError_js_1.default.make({ errorMsg, dataContext })];
46
+ }
47
+ sanitise(value) {
48
+ if (value !== undefined) {
49
+ return (0, utils_js_1.stringifyInput)(value);
50
+ }
51
+ return undefined;
52
+ }
53
+ }
54
+ exports.default = WordCount;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Generate a URL pointing at a particular waypoint.
3
+ *
4
+ * @param {object} obj Options
5
+ * @param {string} obj.waypoint Waypoint
6
+ * @param {string} obj.mountUrl Mount URL
7
+ * @param {JourneyContext} obj.journeyContext JourneyContext
8
+ * @param {boolean} obj.edit Turn edit mode on or off
9
+ * @param {string} obj.editOrigin Edit mode original URL
10
+ * @param {boolean} obj.skipTo Skip to this waypoint from the current one
11
+ * @param {string} obj.routeName Plan route name; next | prev
12
+ * @returns {string} URL
13
+ */
14
+ export default function waypointUrl({ waypoint, mountUrl, journeyContext, edit, editOrigin, skipTo, routeName, }?: {
15
+ waypoint: string;
16
+ mountUrl: string;
17
+ journeyContext: JourneyContext;
18
+ edit: boolean;
19
+ editOrigin: string;
20
+ skipTo: boolean;
21
+ routeName: string;
22
+ }): string;
23
+ export type JourneyContext = import('./index').JourneyContext;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * @typedef {import('./index').JourneyContext} JourneyContext
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const reUrlProtocolExtract = /^url:\/\/(.+)$/i;
7
+ const sanitiseWaypoint = (w) => w.replace(/[^/a-z0-9_-]/ig, '').replace(/\/+/g, '/');
8
+ /**
9
+ * Generate a URL pointing at a particular waypoint.
10
+ *
11
+ * @param {object} obj Options
12
+ * @param {string} obj.waypoint Waypoint
13
+ * @param {string} obj.mountUrl Mount URL
14
+ * @param {JourneyContext} obj.journeyContext JourneyContext
15
+ * @param {boolean} obj.edit Turn edit mode on or off
16
+ * @param {string} obj.editOrigin Edit mode original URL
17
+ * @param {boolean} obj.skipTo Skip to this waypoint from the current one
18
+ * @param {string} obj.routeName Plan route name; next | prev
19
+ * @returns {string} URL
20
+ */
21
+ function waypointUrl({ waypoint = '', mountUrl = '/', journeyContext, edit = false, editOrigin, skipTo, routeName = 'next', } = Object.create(null)) {
22
+ const url = new URL('https://placeholder.test');
23
+ // Handle url:// protocol
24
+ // - This will generate a link to the root handler "_" for the given mount path
25
+ if (String(waypoint).substr(0, 7) === 'url:///') {
26
+ const m = waypoint.match(reUrlProtocolExtract);
27
+ const u = new URL(m[1], 'https://placeholder.test/');
28
+ url.pathname = `${sanitiseWaypoint(u.pathname)}/_/`;
29
+ url.searchParams.append('refmount', `url://${mountUrl}`);
30
+ url.searchParams.append('route', routeName);
31
+ }
32
+ else {
33
+ url.pathname = `${mountUrl}${waypoint}`;
34
+ }
35
+ // Attach context id for non-default contexts
36
+ if (journeyContext && !journeyContext.isDefault() && journeyContext.identity.id) {
37
+ url.searchParams.append('contextid', journeyContext.identity.id);
38
+ }
39
+ // Attach edit mode flag
40
+ if (edit === true) {
41
+ url.searchParams.append('edit', 'true');
42
+ }
43
+ if (edit && editOrigin) {
44
+ url.searchParams.append('editorigin', sanitiseWaypoint(editOrigin));
45
+ }
46
+ // Skipto
47
+ if (skipTo) {
48
+ url.searchParams.append('skipto', sanitiseWaypoint(skipTo));
49
+ }
50
+ return `${sanitiseWaypoint(url.pathname)}${url.search}`;
51
+ }
52
+ exports.default = waypointUrl;
@@ -0,0 +1 @@
1
+ export default function bodyParserMiddleware(): 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 bodyParserMiddleware() {
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 = bodyParserMiddleware;
@@ -0,0 +1 @@
1
+ export default function csrfMiddleware(): 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 csrfMiddleware() {
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 = csrfMiddleware;
@@ -0,0 +1,5 @@
1
+ export default function dataMiddleware({ plan, mountUrl, events, }: {
2
+ plan: any;
3
+ mountUrl: any;
4
+ events: any;
5
+ }): ((req: any, res: any, next: any) => void)[];
@@ -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 = __importDefault(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 { has } = lodash_1.default;
12
+ const editOrigin = (req) => {
13
+ if (has(req.query, 'editorigin')) {
14
+ return (0, waypoint_url_js_1.default)({ waypoint: req.query.editorigin });
15
+ }
16
+ if (has(req === null || req === void 0 ? void 0 : req.body, 'editorigin')) {
17
+ return (0, waypoint_url_js_1.default)({ waypoint: req.body.editorigin });
18
+ }
19
+ return '';
20
+ };
21
+ function dataMiddleware({ plan, mountUrl, events, }) {
22
+ return [
23
+ (req, res, next) => {
24
+ /* ------------------------------------------------ Request decorations */
25
+ // CASA
26
+ req.casa = Object.assign(Object.assign({}, req === null || req === void 0 ? void 0 : req.casa), {
27
+ // The plan
28
+ plan,
29
+ // Current journey context, loaded from session, specified by
30
+ // `contextid` request parameter
31
+ journeyContext: JourneyContext_js_1.default.extractContextFromRequest(req).addEventListeners(events),
32
+ // Edit mode
33
+ editMode: (has(req === null || req === void 0 ? void 0 : req.query, 'edit') && has(req === null || req === void 0 ? void 0 : req.query, 'editorigin')) || (has(req === null || req === void 0 ? void 0 : req.body, 'edit') && has(req === null || req === void 0 ? void 0 : req.body, 'editorigin')), editOrigin: editOrigin(req) });
34
+ // Grab chosen language from session
35
+ req.casa.journeyContext.nav.language = req.session.language;
36
+ /* ------------------------------------------------- Template variables */
37
+ // CASA and userland templates
38
+ res.locals.casa = {
39
+ mountUrl,
40
+ };
41
+ res.locals.locale = req.language;
42
+ // Used by govuk-frontend template
43
+ // - req.language is provided by i18n-http-middleware
44
+ res.locals.htmlLang = req.language;
45
+ // Function for building URLs. This will be curried with the `mountUrl`
46
+ // and `journeyContext` for convenience
47
+ res.locals.waypointUrl = (args) => (0, waypoint_url_js_1.default)(Object.assign({ mountUrl, journeyContext: req.casa.journeyContext }, args));
48
+ // req.editSearchParams
49
+ next();
50
+ },
51
+ ];
52
+ }
53
+ exports.default = dataMiddleware;