From 88530678305d70ad35d48738815e313b85028e99 Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Thu, 16 Apr 2020 18:43:40 +0100 Subject: [PATCH] Added custom `json-string` format to AJV validator no issue - the value of `mobiledoc` when submitting a page/post via the API must be JSON, but we don't validate this - this results in url-utils throwing an error, which ends up being a 500 - this commit adds a custom format to AJV to validate it is valid JSON - also updates tests with bad JSON - 'a' --- .../canary/utils/validators/input/schemas/pages.json | 1 + .../canary/utils/validators/input/schemas/posts.json | 1 + .../api/canary/utils/validators/utils/json-schema.js | 12 +++++++++++- .../api/v2/utils/validators/input/schemas/pages.json | 1 + .../api/v2/utils/validators/input/schemas/posts.json | 1 + .../api/v2/utils/validators/utils/json-schema.js | 12 +++++++++++- .../api/canary/utils/validators/input/pages_spec.js | 2 +- .../api/canary/utils/validators/input/posts_spec.js | 2 +- .../unit/api/v2/utils/validators/input/pages_spec.js | 2 +- .../unit/api/v2/utils/validators/input/posts_spec.js | 2 +- .../unit/api/v3/utils/validators/input/pages_spec.js | 2 +- .../unit/api/v3/utils/validators/input/posts_spec.js | 2 +- 12 files changed, 32 insertions(+), 8 deletions(-) diff --git a/core/server/api/canary/utils/validators/input/schemas/pages.json b/core/server/api/canary/utils/validators/input/schemas/pages.json index 7c0ea6323d..46b59a882e 100644 --- a/core/server/api/canary/utils/validators/input/schemas/pages.json +++ b/core/server/api/canary/utils/validators/input/schemas/pages.json @@ -19,6 +19,7 @@ }, "mobiledoc": { "type": ["string", "null"], + "format": "json-string", "maxLength": 1000000000 }, "html": { diff --git a/core/server/api/canary/utils/validators/input/schemas/posts.json b/core/server/api/canary/utils/validators/input/schemas/posts.json index 58145ccfda..a34db4884c 100644 --- a/core/server/api/canary/utils/validators/input/schemas/posts.json +++ b/core/server/api/canary/utils/validators/input/schemas/posts.json @@ -19,6 +19,7 @@ }, "mobiledoc": { "type": ["string", "null"], + "format": "json-string", "maxLength": 1000000000 }, "html": { diff --git a/core/server/api/canary/utils/validators/utils/json-schema.js b/core/server/api/canary/utils/validators/utils/json-schema.js index b355239ddc..a9949298e4 100644 --- a/core/server/api/canary/utils/validators/utils/json-schema.js +++ b/core/server/api/canary/utils/validators/utils/json-schema.js @@ -5,7 +5,17 @@ const common = require('../../../../../lib/common'); const ajv = new Ajv({ allErrors: true, - useDefaults: true + useDefaults: true, + formats: { + 'json-string': (data) => { + try { + JSON.parse(data); + return true; + } catch (e) { + return false; + } + } + } }); stripKeyword(ajv); diff --git a/core/server/api/v2/utils/validators/input/schemas/pages.json b/core/server/api/v2/utils/validators/input/schemas/pages.json index 7c0ea6323d..46b59a882e 100644 --- a/core/server/api/v2/utils/validators/input/schemas/pages.json +++ b/core/server/api/v2/utils/validators/input/schemas/pages.json @@ -19,6 +19,7 @@ }, "mobiledoc": { "type": ["string", "null"], + "format": "json-string", "maxLength": 1000000000 }, "html": { diff --git a/core/server/api/v2/utils/validators/input/schemas/posts.json b/core/server/api/v2/utils/validators/input/schemas/posts.json index 30047da93c..6c27253957 100644 --- a/core/server/api/v2/utils/validators/input/schemas/posts.json +++ b/core/server/api/v2/utils/validators/input/schemas/posts.json @@ -19,6 +19,7 @@ }, "mobiledoc": { "type": ["string", "null"], + "format": "json-string", "maxLength": 1000000000 }, "html": { diff --git a/core/server/api/v2/utils/validators/utils/json-schema.js b/core/server/api/v2/utils/validators/utils/json-schema.js index b355239ddc..a9949298e4 100644 --- a/core/server/api/v2/utils/validators/utils/json-schema.js +++ b/core/server/api/v2/utils/validators/utils/json-schema.js @@ -5,7 +5,17 @@ const common = require('../../../../../lib/common'); const ajv = new Ajv({ allErrors: true, - useDefaults: true + useDefaults: true, + formats: { + 'json-string': (data) => { + try { + JSON.parse(data); + return true; + } catch (e) { + return false; + } + } + } }); stripKeyword(ajv); diff --git a/test/unit/api/canary/utils/validators/input/pages_spec.js b/test/unit/api/canary/utils/validators/input/pages_spec.js index 218075c128..1db3478d1f 100644 --- a/test/unit/api/canary/utils/validators/input/pages_spec.js +++ b/test/unit/api/canary/utils/validators/input/pages_spec.js @@ -140,7 +140,7 @@ describe('Unit: canary/utils/validators/input/pages', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'], diff --git a/test/unit/api/canary/utils/validators/input/posts_spec.js b/test/unit/api/canary/utils/validators/input/posts_spec.js index 335b28f28c..ccf843b623 100644 --- a/test/unit/api/canary/utils/validators/input/posts_spec.js +++ b/test/unit/api/canary/utils/validators/input/posts_spec.js @@ -140,7 +140,7 @@ describe('Unit: canary/utils/validators/input/posts', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'], diff --git a/test/unit/api/v2/utils/validators/input/pages_spec.js b/test/unit/api/v2/utils/validators/input/pages_spec.js index 94992dbb80..afbab6ec0e 100644 --- a/test/unit/api/v2/utils/validators/input/pages_spec.js +++ b/test/unit/api/v2/utils/validators/input/pages_spec.js @@ -140,7 +140,7 @@ describe('Unit: v2/utils/validators/input/pages', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'], diff --git a/test/unit/api/v2/utils/validators/input/posts_spec.js b/test/unit/api/v2/utils/validators/input/posts_spec.js index 3300fd8c67..9079ed5ddd 100644 --- a/test/unit/api/v2/utils/validators/input/posts_spec.js +++ b/test/unit/api/v2/utils/validators/input/posts_spec.js @@ -140,7 +140,7 @@ describe('Unit: v2/utils/validators/input/posts', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'], diff --git a/test/unit/api/v3/utils/validators/input/pages_spec.js b/test/unit/api/v3/utils/validators/input/pages_spec.js index 4805a83a92..0f6b154f8d 100644 --- a/test/unit/api/v3/utils/validators/input/pages_spec.js +++ b/test/unit/api/v3/utils/validators/input/pages_spec.js @@ -140,7 +140,7 @@ describe('Unit: v3/utils/validators/input/pages', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'], diff --git a/test/unit/api/v3/utils/validators/input/posts_spec.js b/test/unit/api/v3/utils/validators/input/posts_spec.js index 4f7aa04563..08cdc16e0d 100644 --- a/test/unit/api/v3/utils/validators/input/posts_spec.js +++ b/test/unit/api/v3/utils/validators/input/posts_spec.js @@ -140,7 +140,7 @@ describe('Unit: v3/utils/validators/input/posts', function () { const fieldMap = { title: [123, new Date(), _.repeat('a', 2001)], slug: [123, new Date(), _.repeat('a', 192)], - mobiledoc: [123, new Date()], + mobiledoc: [123, new Date(), 'a'], feature_image: [123, new Date(), 'random words'], featured: [123, new Date(), 'abc'], status: [123, new Date(), 'abc'],