Merge pull request #14336 from Budibase/BUDI-8509/search-api-validation-for-filters-with-logical-operators

Add search filter api validation
This commit is contained in:
Adria Navarro 2024-08-07 15:08:47 +02:00 committed by GitHub
commit fd685ad48c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 3 deletions

View File

@ -2769,6 +2769,39 @@ describe.each([
},
}).toFindNothing()
})
!isInMemory &&
it("validates conditions that are not objects", async () => {
await expect(
expectQuery({
$and: {
conditions: [{ equal: { age: 10 } }, "invalidCondition" as any],
},
}).toFindNothing()
).rejects.toThrow(
'Invalid body - "query.$and.conditions[1]" must be of type object'
)
})
!isInMemory &&
it("validates $and without conditions", async () => {
await expect(
expectQuery({
$and: {
conditions: [
{ equal: { age: 10 } },
{
$and: {
conditions: undefined as any,
},
},
],
},
}).toFindNothing()
).rejects.toThrow(
'Invalid body - "query.$and.conditions[1].$and.conditions" is required'
)
})
})
!isLucene &&

View File

@ -1,6 +1,11 @@
import { auth, permissions } from "@budibase/backend-core"
import { DataSourceOperation } from "../../../constants"
import { Table, WebhookActionType } from "@budibase/types"
import {
EmptyFilterOption,
SearchFilters,
Table,
WebhookActionType,
} from "@budibase/types"
import Joi, { CustomValidator } from "joi"
import { ValidSnippetNameRegex, helpers } from "@budibase/shared-core"
import sdk from "../../../sdk"
@ -84,7 +89,12 @@ export function datasourceValidator() {
}
function filterObject() {
return Joi.object({
const conditionalFilteringObject = () =>
Joi.object({
conditions: Joi.array().items(Joi.link("#schema")).required(),
})
const filtersValidators: Record<keyof SearchFilters, any> = {
string: Joi.object().optional(),
fuzzy: Joi.object().optional(),
range: Joi.object().optional(),
@ -95,8 +105,17 @@ function filterObject() {
oneOf: Joi.object().optional(),
contains: Joi.object().optional(),
notContains: Joi.object().optional(),
containsAny: Joi.object().optional(),
allOr: Joi.boolean().optional(),
}).unknown(true)
onEmptyFilter: Joi.string()
.optional()
.valid(...Object.values(EmptyFilterOption)),
$and: conditionalFilteringObject(),
$or: conditionalFilteringObject(),
fuzzyOr: Joi.forbidden(),
documentType: Joi.forbidden(),
}
return Joi.object(filtersValidators).unknown(true).id("schema")
}
export function internalSearchValidator() {