@dwp/govuk-casa 8.10.2 → 8.11.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.
@@ -38,6 +38,13 @@ export function resolveMiddlewareHooks(hookName: string, path: string, hooks?: H
38
38
  * @returns {string} The stringified input
39
39
  */
40
40
  export function stringifyInput(input: any, fallback: string, ...args: any[]): string;
41
+ /**
42
+ * Coerce an input to an integer.
43
+ *
44
+ * @param {any} input Input to be coerced.
45
+ * @returns {number|undefined} The number as an integer or `undefined`.
46
+ */
47
+ export function coerceInputToInteger(input: any): number | undefined;
41
48
  /**
42
49
  * Strip whitespace from a string.
43
50
  *
package/dist/lib/utils.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * @typedef {import('../casa').GlobalHook | import('../casa').PageHook} Hook
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.validateWaypoint = exports.validateView = exports.validateUrlPath = exports.validateHookPath = exports.validateHookName = exports.notProto = exports.stripWhitespace = exports.stringifyInput = exports.resolveMiddlewareHooks = exports.isStringable = exports.isEmpty = void 0;
7
+ exports.validateWaypoint = exports.validateView = exports.validateUrlPath = exports.validateHookPath = exports.validateHookName = exports.notProto = exports.stripWhitespace = exports.coerceInputToInteger = exports.stringifyInput = exports.resolveMiddlewareHooks = exports.isStringable = exports.isEmpty = void 0;
8
8
  /**
9
9
  * Determine if value is empty. Recurse over objects.
10
10
  *
@@ -67,6 +67,16 @@ function stringifyInput(input, fallback) {
67
67
  return isStringable(input) ? String(input) : fb;
68
68
  }
69
69
  exports.stringifyInput = stringifyInput;
70
+ /**
71
+ * Coerce an input to an integer.
72
+ *
73
+ * @param {any} input Input to be coerced.
74
+ * @returns {number|undefined} The number as an integer or `undefined`.
75
+ */
76
+ function coerceInputToInteger(input) {
77
+ return Number.isNaN(Number(input)) ? undefined : Math.floor(Number(input));
78
+ }
79
+ exports.coerceInputToInteger = coerceInputToInteger;
70
80
  /**
71
81
  * Strip whitespace from a string.
72
82
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.js"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ declare namespace _default {
7
7
  export { regex };
8
8
  export { required };
9
9
  export { strlen };
10
+ export { range };
10
11
  export { wordCount };
11
12
  }
12
13
  export default _default;
@@ -18,4 +19,5 @@ import postalAddressObject from './postalAddressObject.js';
18
19
  import regex from './regex.js';
19
20
  import required from './required.js';
20
21
  import strlen from './strlen.js';
22
+ import range from './range.js';
21
23
  import wordCount from './wordCount.js';
@@ -11,6 +11,7 @@ const postalAddressObject_js_1 = __importDefault(require("./postalAddressObject.
11
11
  const regex_js_1 = __importDefault(require("./regex.js"));
12
12
  const required_js_1 = __importDefault(require("./required.js"));
13
13
  const strlen_js_1 = __importDefault(require("./strlen.js"));
14
+ const range_js_1 = __importDefault(require("./range.js"));
14
15
  const wordCount_js_1 = __importDefault(require("./wordCount.js"));
15
16
  /**
16
17
  * @namespace Validators
@@ -24,6 +25,7 @@ exports.default = {
24
25
  regex: regex_js_1.default,
25
26
  required: required_js_1.default,
26
27
  strlen: strlen_js_1.default,
28
+ range: range_js_1.default,
27
29
  wordCount: wordCount_js_1.default,
28
30
  };
29
31
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/validators/index.js"],"names":[],"mappings":";;;;;AAAA,oEAAyC;AACzC,0DAA+B;AAC/B,8DAAmC;AACnC,wDAA6B;AAC7B,sFAA2D;AAC3D,0DAA+B;AAC/B,gEAAqC;AACrC,4DAAiC;AACjC,kEAAuC;AAEvC;;GAEG;AACH,kBAAe;IACb,UAAU,EAAV,uBAAU;IACV,KAAK,EAAL,kBAAK;IACL,OAAO,EAAP,oBAAO;IACP,IAAI,EAAJ,iBAAI;IACJ,mBAAmB,EAAnB,gCAAmB;IACnB,KAAK,EAAL,kBAAK;IACL,QAAQ,EAAR,qBAAQ;IACR,MAAM,EAAN,mBAAM;IACN,SAAS,EAAT,sBAAS;CACV,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/validators/index.js"],"names":[],"mappings":";;;;;AAAA,oEAAyC;AACzC,0DAA+B;AAC/B,8DAAmC;AACnC,wDAA6B;AAC7B,sFAA2D;AAC3D,0DAA+B;AAC/B,gEAAqC;AACrC,4DAAiC;AACjC,0DAA+B;AAC/B,kEAAuC;AAEvC;;GAEG;AACH,kBAAe;IACb,UAAU,EAAV,uBAAU;IACV,KAAK,EAAL,kBAAK;IACL,OAAO,EAAP,oBAAO;IACP,IAAI,EAAJ,iBAAI;IACJ,mBAAmB,EAAnB,gCAAmB;IACnB,KAAK,EAAL,kBAAK;IACL,QAAQ,EAAR,qBAAQ;IACR,MAAM,EAAN,mBAAM;IACN,KAAK,EAAL,kBAAK;IACL,SAAS,EAAT,sBAAS;CACV,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @access private
3
+ * @typedef {import('../../casa').ErrorMessageConfig} ErrorMessageConfig
4
+ */
5
+ /**
6
+ * @typedef {object} RangeConfigOptions
7
+ * @property {ErrorMessageConfig} errorMsgMax Error message to use on max failure
8
+ * @property {ErrorMessageConfig} errorMsgMin Error message to use on min failure
9
+ * @property {number} max Maximum integer value
10
+ * @property {number} min Minimum integer value
11
+ */
12
+ /**
13
+ * Test if an integer is within a provided range.
14
+ *
15
+ * See {@link RangeConfigOptions} for `make()` options.
16
+ *
17
+ * @memberof Validators
18
+ * @augments ValidatorFactory
19
+ */
20
+ export default class Range extends ValidatorFactory {
21
+ name: string;
22
+ validate(inputValue: any, dataContext?: {}): ValidationError[];
23
+ sanitise(value: any): string | undefined;
24
+ }
25
+ export type ErrorMessageConfig = import('../../casa').ErrorMessageConfig;
26
+ export type RangeConfigOptions = {
27
+ /**
28
+ * Error message to use on max failure
29
+ */
30
+ errorMsgMax: ErrorMessageConfig;
31
+ /**
32
+ * Error message to use on min failure
33
+ */
34
+ errorMsgMin: ErrorMessageConfig;
35
+ /**
36
+ * Maximum integer value
37
+ */
38
+ max: number;
39
+ /**
40
+ * Minimum integer value
41
+ */
42
+ min: number;
43
+ };
44
+ import ValidatorFactory from '../ValidatorFactory.js';
45
+ import ValidationError from '../ValidationError.js';
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /* eslint-disable class-methods-use-this */
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const ValidatorFactory_js_1 = __importDefault(require("../ValidatorFactory.js"));
8
+ const ValidationError_js_1 = __importDefault(require("../ValidationError.js"));
9
+ const utils_js_1 = require("../utils.js");
10
+ /**
11
+ * @access private
12
+ * @typedef {import('../../casa').ErrorMessageConfig} ErrorMessageConfig
13
+ */
14
+ /**
15
+ * @typedef {object} RangeConfigOptions
16
+ * @property {ErrorMessageConfig} errorMsgMax Error message to use on max failure
17
+ * @property {ErrorMessageConfig} errorMsgMin Error message to use on min failure
18
+ * @property {number} max Maximum integer value
19
+ * @property {number} min Minimum integer value
20
+ */
21
+ /**
22
+ * Test if an integer is within a provided range.
23
+ *
24
+ * See {@link RangeConfigOptions} for `make()` options.
25
+ *
26
+ * @memberof Validators
27
+ * @augments ValidatorFactory
28
+ */
29
+ class Range extends ValidatorFactory_js_1.default {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.name = 'range';
33
+ }
34
+ validate(inputValue, dataContext = {}) {
35
+ const { errorMsgMax = {
36
+ inline: 'validation:rule.range.max.inline',
37
+ summary: 'validation:rule.range.max.summary',
38
+ }, errorMsgMin = {
39
+ inline: 'validation:rule.range.min.inline',
40
+ summary: 'validation:rule.range.min.summary',
41
+ }, min = Number.MIN_VALUE, max = Number.MAX_VALUE, } = this.config;
42
+ let errorMsg;
43
+ let valid = true;
44
+ if (inputValue > max) {
45
+ valid = false;
46
+ errorMsg = errorMsgMax;
47
+ }
48
+ if (inputValue < min) {
49
+ valid = false;
50
+ errorMsg = errorMsgMin;
51
+ }
52
+ return valid ? [] : [ValidationError_js_1.default.make({ errorMsg, dataContext })];
53
+ }
54
+ sanitise(value) {
55
+ var _a;
56
+ // treat an empty string as undefined
57
+ // when user submits empty form, it stores an empty string
58
+ if (value !== '' && value !== undefined) {
59
+ // add to custom validator docs to ensure not to return a falsy value as it doesn't show on screen
60
+ return (_a = (0, utils_js_1.coerceInputToInteger)(value)) === null || _a === void 0 ? void 0 : _a.toString();
61
+ }
62
+ return undefined;
63
+ }
64
+ }
65
+ exports.default = Range;
66
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../../src/lib/validators/range.js"],"names":[],"mappings":";AAAA,2CAA2C;;;;;AAE3C,iFAAsD;AACtD,+EAAoD;AACpD,0CAAmD;AAEnD;;;GAGG;AAEH;;;;;;GAMG;AAEH;;;;;;;GAOG;AACH,MAAqB,KAAM,SAAQ,6BAAgB;IAAnD;;QACE,SAAI,GAAG,OAAO,CAAC;IAyCjB,CAAC;IAvCC,QAAQ,CAAC,UAAU,EAAE,WAAW,GAAG,EAAE;QACnC,MAAM,EACJ,WAAW,GAAG;YACZ,MAAM,EAAE,kCAAkC;YAC1C,OAAO,EAAE,mCAAmC;SAC7C,EACD,WAAW,GAAG;YACZ,MAAM,EAAE,kCAAkC;YAC1C,OAAO,EAAE,mCAAmC;SAC7C,EACD,GAAG,GAAG,MAAM,CAAC,SAAS,EACtB,GAAG,GAAG,MAAM,CAAC,SAAS,GACvB,GAAG,IAAI,CAAC,MAAM,CAAC;QAEhB,IAAI,QAAQ,CAAC;QACb,IAAI,KAAK,GAAG,IAAI,CAAC;QAEjB,IAAI,UAAU,GAAG,GAAG,EAAE;YACpB,KAAK,GAAG,KAAK,CAAC;YACd,QAAQ,GAAG,WAAW,CAAC;SACxB;QAED,IAAI,UAAU,GAAG,GAAG,EAAE;YACpB,KAAK,GAAG,KAAK,CAAC;YACd,QAAQ,GAAG,WAAW,CAAC;SACxB;QAED,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,4BAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,QAAQ,CAAC,KAAK;;QACZ,qCAAqC;QACrC,0DAA0D;QAC1D,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,SAAS,EAAE;YACvC,kGAAkG;YAClG,OAAO,MAAA,IAAA,+BAAoB,EAAC,KAAK,CAAC,0CAAE,QAAQ,EAAE,CAAC;SAChD;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AA1CD,wBA0CC"}
@@ -1 +1 @@
1
- export default function csrfMiddleware(): any[];
1
+ export default function csrfMiddleware(): import("csrf-sync").CsrfSynchronisedProtection[];
@@ -1,26 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const csurf_1 = __importDefault(require("csurf"));
3
+ const csrf_sync_1 = require("csrf-sync");
7
4
  // 2 middleware: one to generate the csrf token and check its validity (POST
8
5
  // only), and one to provide that token to templates via the `casa.csrfToken`
9
6
  // variable.
10
7
  function csrfMiddleware() {
8
+ const { csrfSynchronisedProtection } = (0, csrf_sync_1.csrfSync)({
9
+ getTokenFromRequest: (req) => req.body._csrf,
10
+ });
11
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
- }),
12
+ csrfSynchronisedProtection,
24
13
  (req, res, next) => {
25
14
  var _a;
26
15
  res.locals.casa = Object.assign(Object.assign({}, (_a = res.locals) === null || _a === void 0 ? void 0 : _a.casa), { csrfToken: req.csrfToken() });
@@ -1 +1 @@
1
- {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/middleware/csrf.js"],"names":[],"mappings":";;;;;AAAA,kDAA0B;AAE1B,4EAA4E;AAC5E,6EAA6E;AAC7E,YAAY;AAEZ,SAAwB,cAAc;IACpC,OAAO;QACL,IAAA,eAAK,EAAC;YACJ,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,SAAS;YACrB,oBAAoB;YACpB,6EAA6E;YAC7E,2CAA2C;YAC3C,0CAA0C;YAC1C,2BAA2B;YAC3B,kBAAkB;YAClB,6CAA6C;YAC7C,KAAK;SACN,CAAC;QACF,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;;YACjB,GAAG,CAAC,MAAM,CAAC,IAAI,mCACV,MAAA,GAAG,CAAC,MAAM,0CAAE,IAAI,KACnB,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAC3B,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;KACF,CAAC;AACJ,CAAC;AAtBD,iCAsBC"}
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/middleware/csrf.js"],"names":[],"mappings":";;AAAA,yCAAqC;AAErC,4EAA4E;AAC5E,6EAA6E;AAC7E,YAAY;AAEZ,SAAwB,cAAc;IACpC,MAAM,EAAE,0BAA0B,EAAE,GAAG,IAAA,oBAAQ,EAAC;QAC9C,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;KAC7C,CAAC,CAAC;IACH,OAAO;QACL,0BAA0B;QAC1B,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;;YACjB,GAAG,CAAC,MAAM,CAAC,IAAI,mCACV,MAAA,GAAG,CAAC,MAAM,0CAAE,IAAI,KACnB,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAC3B,CAAC;YACF,IAAI,EAAE,CAAC;QACT,CAAC;KACF,CAAC;AACJ,CAAC;AAdD,iCAcC"}
@@ -77,5 +77,16 @@
77
77
  "summary": "Mae gwerth yn rhy hir"
78
78
  }
79
79
  }
80
+ },
81
+
82
+ "range": {
83
+ "min": {
84
+ "inline": "Mae’r gwerth yn rhy fach",
85
+ "summary": "Mae’r gwerth yn rhy fach"
86
+ },
87
+ "max": {
88
+ "inline": "Mae’r gwerth yn rhy fawr",
89
+ "summary": "Mae’r gwerth yn rhy fawr"
90
+ }
80
91
  }
81
92
  }
@@ -77,6 +77,18 @@
77
77
  "summary": "Value is too long"
78
78
  }
79
79
  },
80
+
81
+ "range": {
82
+ "min": {
83
+ "inline": "Value is too small",
84
+ "summary": "Value is too small"
85
+ },
86
+ "max": {
87
+ "inline": "Value is too large",
88
+ "summary": "Value is too large"
89
+ }
90
+ },
91
+
80
92
  "wordCount": {
81
93
  "min": {
82
94
  "inline": "Value is too short",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwp/govuk-casa",
3
- "version": "8.10.2",
3
+ "version": "8.11.0",
4
4
  "description": "A framework for building GOVUK Collect-And-Submit-Applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -48,18 +48,18 @@
48
48
  "license": "ISC",
49
49
  "type": "module",
50
50
  "dependencies": {
51
- "@dagrejs/graphlib": "2.1.12",
51
+ "@dagrejs/graphlib": "2.1.13",
52
52
  "bytes": "3.1.2",
53
53
  "cookie-parser": "1.4.6",
54
- "csurf": "1.11.0",
54
+ "csrf-sync": "4.0.1",
55
55
  "debug": "4.3.4",
56
56
  "deepmerge": "4.3.1",
57
57
  "express": "4.18.2",
58
58
  "express-session": "1.17.3",
59
59
  "govuk-frontend": "4.6.0",
60
- "helmet": "6.2.0",
61
- "i18next": "22.4.15",
62
- "i18next-http-middleware": "3.3.0",
60
+ "helmet": "7.0.0",
61
+ "i18next": "22.5.0",
62
+ "i18next-http-middleware": "3.3.1",
63
63
  "js-yaml": "4.1.0",
64
64
  "lodash": "4.17.21",
65
65
  "luxon": "3.3.0",
@@ -69,33 +69,33 @@
69
69
  "validator": "13.9.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@babel/core": "7.21.8",
72
+ "@babel/core": "7.22.1",
73
73
  "@babel/eslint-parser": "7.21.8",
74
- "@babel/preset-env": "7.21.5",
74
+ "@babel/preset-env": "7.22.2",
75
75
  "@ckeditor/jsdoc-plugins": "37.0.1",
76
76
  "@commitlint/config-conventional": "17.6.3",
77
- "@dwp/casa-spiderplan": "2.5.6",
77
+ "@dwp/casa-spiderplan": "3.1.1",
78
78
  "@dwp/casa-spiderplan-a11y-plugin": "0.1.12",
79
79
  "@dwp/casa-spiderplan-zap-plugin": "0.1.8",
80
80
  "@dwp/eslint-config-base": "6.1.1",
81
81
  "@types/express": "4.17.17",
82
- "@types/node": "18.16.8",
82
+ "@types/node": "18.16.16",
83
83
  "@types/nunjucks": "3.2.2",
84
84
  "c8": "7.13.0",
85
85
  "chai": "4.3.7",
86
86
  "cheerio": "1.0.0-rc.12",
87
87
  "commitlint": "17.6.3",
88
88
  "docdash": "2.0.1",
89
- "eslint": "8.40.0",
89
+ "eslint": "8.41.0",
90
90
  "eslint-plugin-no-unsafe-regex": "1.0.0",
91
91
  "eslint-plugin-security": "1.7.1",
92
92
  "eslint-plugin-sonarjs": "0.19.0",
93
- "fast-check": "3.8.1",
93
+ "fast-check": "3.9.0",
94
94
  "jsdoc": "4.0.2",
95
95
  "jsdoc-tsimport-plugin": "1.0.5",
96
96
  "mocha": "10.2.0",
97
97
  "sass": "1.62.1",
98
- "sinon": "15.0.4",
98
+ "sinon": "15.1.0",
99
99
  "sinon-chai": "3.7.0",
100
100
  "supertest": "6.3.3",
101
101
  "typescript": "5.0.4"
package/src/lib/utils.js CHANGED
@@ -67,6 +67,16 @@ export function stringifyInput(input, fallback) {
67
67
  return isStringable(input) ? String(input) : fb;
68
68
  }
69
69
 
70
+ /**
71
+ * Coerce an input to an integer.
72
+ *
73
+ * @param {any} input Input to be coerced.
74
+ * @returns {number|undefined} The number as an integer or `undefined`.
75
+ */
76
+ export function coerceInputToInteger(input) {
77
+ return Number.isNaN(Number(input)) ? undefined : Math.floor(Number(input));
78
+ }
79
+
70
80
  /**
71
81
  * Strip whitespace from a string.
72
82
  *
@@ -6,6 +6,7 @@ import postalAddressObject from './postalAddressObject.js';
6
6
  import regex from './regex.js';
7
7
  import required from './required.js';
8
8
  import strlen from './strlen.js';
9
+ import range from './range.js';
9
10
  import wordCount from './wordCount.js';
10
11
 
11
12
  /**
@@ -20,5 +21,6 @@ export default {
20
21
  regex,
21
22
  required,
22
23
  strlen,
24
+ range,
23
25
  wordCount,
24
26
  }
@@ -0,0 +1,70 @@
1
+ /* eslint-disable class-methods-use-this */
2
+
3
+ import ValidatorFactory from '../ValidatorFactory.js';
4
+ import ValidationError from '../ValidationError.js';
5
+ import { coerceInputToInteger } from '../utils.js';
6
+
7
+ /**
8
+ * @access private
9
+ * @typedef {import('../../casa').ErrorMessageConfig} ErrorMessageConfig
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} RangeConfigOptions
14
+ * @property {ErrorMessageConfig} errorMsgMax Error message to use on max failure
15
+ * @property {ErrorMessageConfig} errorMsgMin Error message to use on min failure
16
+ * @property {number} max Maximum integer value
17
+ * @property {number} min Minimum integer value
18
+ */
19
+
20
+ /**
21
+ * Test if an integer is within a provided range.
22
+ *
23
+ * See {@link RangeConfigOptions} for `make()` options.
24
+ *
25
+ * @memberof Validators
26
+ * @augments ValidatorFactory
27
+ */
28
+ export default class Range extends ValidatorFactory {
29
+ name = 'range';
30
+
31
+ validate(inputValue, dataContext = {}) {
32
+ const {
33
+ errorMsgMax = {
34
+ inline: 'validation:rule.range.max.inline',
35
+ summary: 'validation:rule.range.max.summary',
36
+ },
37
+ errorMsgMin = {
38
+ inline: 'validation:rule.range.min.inline',
39
+ summary: 'validation:rule.range.min.summary',
40
+ },
41
+ min = Number.MIN_VALUE,
42
+ max = Number.MAX_VALUE,
43
+ } = this.config;
44
+
45
+ let errorMsg;
46
+ let valid = true;
47
+
48
+ if (inputValue > max) {
49
+ valid = false;
50
+ errorMsg = errorMsgMax;
51
+ }
52
+
53
+ if (inputValue < min) {
54
+ valid = false;
55
+ errorMsg = errorMsgMin;
56
+ }
57
+
58
+ return valid ? [] : [ValidationError.make({ errorMsg, dataContext })];
59
+ }
60
+
61
+ sanitise(value) {
62
+ // treat an empty string as undefined
63
+ // when user submits empty form, it stores an empty string
64
+ if (value !== '' && value !== undefined) {
65
+ // add to custom validator docs to ensure not to return a falsy value as it doesn't show on screen
66
+ return coerceInputToInteger(value)?.toString();
67
+ }
68
+ return undefined;
69
+ }
70
+ }
@@ -1,23 +1,15 @@
1
- import csurf from 'csurf';
1
+ import { csrfSync } from 'csrf-sync';
2
2
 
3
3
  // 2 middleware: one to generate the csrf token and check its validity (POST
4
4
  // only), and one to provide that token to templates via the `casa.csrfToken`
5
5
  // variable.
6
6
 
7
7
  export default function csrfMiddleware() {
8
+ const { csrfSynchronisedProtection } = csrfSync({
9
+ getTokenFromRequest: (req) => req.body._csrf,
10
+ });
8
11
  return [
9
- csurf({
10
- cookie: false,
11
- sessionKey: 'session',
12
- // value: (req) => {
13
- // // Here we clear the token after extracting to maintain cleaner data. It
14
- // // is only used for this CSRF purpose.
15
- // const token = String(req.body._csrf);
16
- // delete req.body._csrf;
17
- // return token;
18
- // /* eslint-enable no-underscore-dangle */
19
- // },
20
- }),
12
+ csrfSynchronisedProtection,
21
13
  (req, res, next) => {
22
14
  res.locals.casa = {
23
15
  ...res.locals?.casa,