diff --git a/server/routes/transforms.ts b/server/routes/transforms.ts index 22092703d..30ed9d263 100644 --- a/server/routes/transforms.ts +++ b/server/routes/transforms.ts @@ -112,9 +112,14 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab validate: { params: schema.object({ index: schema.string({ - pattern: /^[^A-Z-_"*+/\\|?#<>][^A-Z"*+/\\|?#<>]*$/, - minLength: 1, - maxLength: 100000, + validate: (value) => { + const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/; + if (value !== value.toLowerCase() || value.startsWith("_") || value.startsWith("-") || invalidCharactersPattern.test(value)) { + return "Invalid index name."; + } + + return undefined; + }, }), }), query: schema.object({ @@ -123,9 +128,7 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab ...(dataSourceEnabled ? { dataSourceId: schema.string({ - minLength: 1, maxLength: 100000, - pattern: "^[a-zA-Z0-9_-]+$", }), } : {}), @@ -157,9 +160,19 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab enabled_at: schema.maybe(schema.any()), description: schema.maybe(schema.string()), source_index: schema.string({ - pattern: /^[^A-Z-_"*+/\\|?#<>][^A-Z"*+/\\|?#<>]*$/, - minLength: 1, - maxLength: 100000, + validate: (value) => { + const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/; + if ( + value !== value.toLowerCase() || + value.startsWith("_") || + value.startsWith("-") || + invalidCharactersPattern.test(value) + ) { + return "Invalid index name."; + } + + return undefined; + }, }), data_selection_query: schema.object({ match_all: schema.object({ @@ -167,9 +180,19 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab }), }), target_index: schema.string({ - pattern: /^[^A-Z-_"*+/\\|?#<>][^A-Z"*+/\\|?#<>]*$/, - minLength: 1, - maxLength: 100000, + validate: (value) => { + const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/; + if ( + value !== value.toLowerCase() || + value.startsWith("_") || + value.startsWith("-") || + invalidCharactersPattern.test(value) + ) { + return "Invalid index name."; + } + + return undefined; + }, }), page_size: schema.number(), groups: schema.arrayOf( @@ -188,9 +211,7 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab ...(dataSourceEnabled ? { dataSourceId: schema.string({ - minLength: 1, maxLength: 100000, - pattern: "^[a-zA-Z0-9_-]+$", }), } : {}), diff --git a/server/services/TransformService.test.ts b/server/services/TransformService.test.ts new file mode 100644 index 000000000..7c7208b5f --- /dev/null +++ b/server/services/TransformService.test.ts @@ -0,0 +1,56 @@ +import { schema } from "@osd/config-schema"; + +describe("Index Name Validation", () => { + const validateSchema = schema.object({ + indexName: schema.string({ + validate: (value) => { + const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/; + if (value !== value.toLowerCase() || value.startsWith("_") || value.startsWith("-") || invalidCharactersPattern.test(value)) { + return "Invalid index name."; + } + + return undefined; + }, + }), + dataSourceId: schema.maybe(schema.string()), + }); + + const validateQuery = (indexName: string) => { + try { + validateSchema.validate({ indexName }); + return undefined; + } catch (e) { + return e.message; + } + }; + + it("should fail validation for index names with uppercase letters", () => { + const errorMessage = validateQuery("IndexNameWithUppercase"); + expect(errorMessage).toBe("[indexName]: Invalid index name."); + }); + + it("should fail validation for index names starting with an underscore", () => { + const errorMessage = validateQuery("_indexname"); + expect(errorMessage).toBe("[indexName]: Invalid index name."); + }); + + it("should fail validation for index names starting with a hyphen", () => { + const errorMessage = validateQuery("-indexname"); + expect(errorMessage).toBe("[indexName]: Invalid index name."); + }); + + it("should fail validation for index names containing invalid characters", () => { + const errorMessage = validateQuery("********************************"); + expect(errorMessage).toBe("[indexName]: Invalid index name."); + }); + + it("should pass validation for valid index names", () => { + const errorMessage = validateQuery("valid_index-name123"); + expect(errorMessage).toBeUndefined(); + }); + + it("should fail validation for index names containing spaces", () => { + const errorMessage = validateQuery("invalid index"); + expect(errorMessage).toBe("[indexName]: Invalid index name."); + }); +});