From 31bdef94cd4c58f691c8d91e33346fdd8571fa23 Mon Sep 17 00:00:00 2001 From: Daniel Lockyer Date: Wed, 1 May 2024 11:48:16 +0200 Subject: [PATCH] Handled invalid filters in members event repository fix https://linear.app/tryghost/issue/SLO-82/query-error-unexpected-character-in-filter-at-char-1 - previously, we weren't handling a parsing error, and just bubbling it back up the chain - this would result in an InternalServerError somewhere, which caused 500s - we can handle this, because it's just a bad filter - this adds handling so we return a 422 upon receiving an invalid filter --- ghost/members-api/lib/repositories/EventRepository.js | 10 +++++++++- .../test/unit/lib/repositories/event.test.js | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ghost/members-api/lib/repositories/EventRepository.js b/ghost/members-api/lib/repositories/EventRepository.js index b86ff1312a..98484299bc 100644 --- a/ghost/members-api/lib/repositories/EventRepository.js +++ b/ghost/members-api/lib/repositories/EventRepository.js @@ -777,7 +777,15 @@ module.exports = class EventRepository { } const allowList = ['data.created_at', 'data.member_id', 'data.post_id', 'type', 'id']; - const parsed = nql(filter).parse(); + let parsed; + try { + parsed = nql(filter).parse(); + } catch (e) { + throw new errors.BadRequestError({ + message: e.message + }); + } + const keys = getUsedKeys(parsed); for (const key of keys) { diff --git a/ghost/members-api/test/unit/lib/repositories/event.test.js b/ghost/members-api/test/unit/lib/repositories/event.test.js index 439aa495d3..9b2f2f6686 100644 --- a/ghost/members-api/test/unit/lib/repositories/event.test.js +++ b/ghost/members-api/test/unit/lib/repositories/event.test.js @@ -19,6 +19,12 @@ describe('EventRepository', function () { }); }); + it('throws when using invalid filter', function () { + should.throws(() => { + eventRepository.getNQLSubset('undefined'); + }, errors.BadRequestError); + }); + it('throws when using properties that aren\'t in the allowlist', function () { should.throws(() => { eventRepository.getNQLSubset('(types:1)');