From 16be6f94733953c0f9e4d067fb9260dab21ec603 Mon Sep 17 00:00:00 2001 From: Federico Morreale Date: Thu, 5 Oct 2023 17:18:10 +0200 Subject: [PATCH 1/3] fix: add default limit to search query Signed-off-by: Federico Morreale --- .changeset/twelve-snakes-sell.md | 5 +++++ plugins/search-backend/src/service/router.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/twelve-snakes-sell.md diff --git a/.changeset/twelve-snakes-sell.md b/.changeset/twelve-snakes-sell.md new file mode 100644 index 0000000000..7f91b2910f --- /dev/null +++ b/.changeset/twelve-snakes-sell.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +Set the default length limit to search query to 100. To override it, define `search.maxTermLength` in the config file. diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index dca632dfaf..54ac49f724 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -63,6 +63,7 @@ export type RouterOptions = { }; const defaultMaxPageLimit = 100; +const defaultMaxTermLength = 100; const allowedLocationProtocols = ['http:', 'https:']; /** @@ -77,8 +78,11 @@ export async function createRouter( const maxPageLimit = config.getOptionalNumber('search.maxPageLimit') ?? defaultMaxPageLimit; + const maxTermLength = + config.getOptionalNumber('search.maxTermLength') ?? defaultMaxTermLength; + const requestSchema = z.object({ - term: z.string().default(''), + term: z.string().max(maxTermLength).default(''), filters: jsonObjectSchema.optional(), types: z .array(z.string().refine(type => Object.keys(types).includes(type))) From 8be6c23b6c4fe11bb42bf671840ce0ae89731112 Mon Sep 17 00:00:00 2001 From: Federico Morreale Date: Thu, 5 Oct 2023 17:22:19 +0200 Subject: [PATCH 2/3] fix: add maxTermLength to config.d.ts Signed-off-by: Federico Morreale --- plugins/search-backend/config.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/search-backend/config.d.ts b/plugins/search-backend/config.d.ts index 3dbdf78dfe..25ae59d273 100644 --- a/plugins/search-backend/config.d.ts +++ b/plugins/search-backend/config.d.ts @@ -22,6 +22,11 @@ export interface Config { */ maxPageLimit?: number; + /** + * Sets the maximum term length for the search string. Defaults to 100. + */ + maxTermLength?: number; + /** * Options related to the search integration with the Backstage permissions system */ From d2e8e10f3a44c4d16a05082e293dd73aab8f6cac Mon Sep 17 00:00:00 2001 From: Federico Morreale Date: Thu, 5 Oct 2023 17:42:02 +0200 Subject: [PATCH 3/3] add tests Signed-off-by: Federico Morreale --- plugins/search-backend/src/service/router.test.ts | 15 ++++++++++++++- plugins/search-backend/src/service/router.ts | 10 +++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index 7ec8603307..73523f2b62 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -60,7 +60,7 @@ describe('createRouter', () => { }, config: new ConfigReader({ permissions: { enabled: false }, - search: { maxPageLimit: 200 }, + search: { maxPageLimit: 200, maxTermLength: 20 }, }), permissions: mockPermissionEvaluator, logger, @@ -162,6 +162,19 @@ describe('createRouter', () => { }); }); + it('should reject term length over configured max', async () => { + const response = await request(app).get( + `/query?term=HelloWorld1234567890!`, + ); + + expect(response.status).toEqual(400); + expect(response.body).toMatchObject({ + error: { + message: /The term length "21" is greater than "20"/i, + }, + }); + }); + it('removes backend-only properties from search documents', async () => { mockSearchEngine.query.mockResolvedValue({ results: [ diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 54ac49f724..876cb5d103 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -82,7 +82,15 @@ export async function createRouter( config.getOptionalNumber('search.maxTermLength') ?? defaultMaxTermLength; const requestSchema = z.object({ - term: z.string().max(maxTermLength).default(''), + term: z + .string() + .refine( + term => term.length <= maxTermLength, + term => ({ + message: `The term length "${term.length}" is greater than "${maxTermLength}"`, + }), + ) + .default(''), filters: jsonObjectSchema.optional(), types: z .array(z.string().refine(type => Object.keys(types).includes(type)))