Potential fix for view search problem.

This commit is contained in:
Sam Rose 2024-10-11 15:33:33 +01:00
parent abb01ba98a
commit 33f7792522
No known key found for this signature in database
3 changed files with 41 additions and 33 deletions

View File

@ -8,6 +8,7 @@ import {
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { context } from "@budibase/backend-core" import { context } from "@budibase/backend-core"
import * as utils from "./utils"
export async function searchView( export async function searchView(
ctx: UserCtx<SearchViewRowRequest, SearchRowResponse> ctx: UserCtx<SearchViewRowRequest, SearchRowResponse>

View File

@ -16,7 +16,7 @@ import * as external from "./search/external"
import { ExportRowsParams, ExportRowsResult } from "./search/types" import { ExportRowsParams, ExportRowsResult } from "./search/types"
import { dataFilters } from "@budibase/shared-core" import { dataFilters } from "@budibase/shared-core"
import sdk from "../../index" import sdk from "../../index"
import { searchInputMapping } from "./search/utils" import { checkFilters, searchInputMapping } from "./search/utils"
import { db, features } from "@budibase/backend-core" import { db, features } from "@budibase/backend-core"
import tracer from "dd-trace" import tracer from "dd-trace"
import { getQueryableFields, removeInvalidFilters } from "./queryUtils" import { getQueryableFields, removeInvalidFilters } from "./queryUtils"
@ -92,8 +92,10 @@ export async function search(
// Enrich saved query with ephemeral query params. // Enrich saved query with ephemeral query params.
// We prevent searching on any fields that are saved as part of the query, as // We prevent searching on any fields that are saved as part of the query, as
// that could let users find rows they should not be allowed to access. // that could let users find rows they should not be allowed to access.
let viewQuery = dataFilters.buildQueryLegacy(view.query) || {} let query = await enrichSearchContext(view.query || {}, context)
delete viewQuery?.onEmptyFilter query = dataFilters.buildQueryLegacy(query) || {}
query = checkFilters(table, query)
delete query?.onEmptyFilter
const sqsEnabled = await features.flags.isEnabled("SQS") const sqsEnabled = await features.flags.isEnabled("SQS")
const supportsLogicalOperators = const supportsLogicalOperators =
@ -113,26 +115,25 @@ export async function search(
?.filter(filter => filter.field) ?.filter(filter => filter.field)
.map(filter => db.removeKeyNumbering(filter.field)) || [] .map(filter => db.removeKeyNumbering(filter.field)) || []
viewQuery ??= {}
// Carry over filters for unused fields // Carry over filters for unused fields
Object.keys(options.query).forEach(key => { Object.keys(options.query).forEach(key => {
const operator = key as Exclude<SearchFilterKey, LogicalOperator> const operator = key as Exclude<SearchFilterKey, LogicalOperator>
Object.keys(options.query[operator] || {}).forEach(field => { Object.keys(options.query[operator] || {}).forEach(field => {
if (!existingFields.includes(db.removeKeyNumbering(field))) { if (!existingFields.includes(db.removeKeyNumbering(field))) {
viewQuery![operator]![field] = options.query[operator]![field] query[operator]![field] = options.query[operator]![field]
} }
}) })
}) })
options.query = viewQuery options.query = query
} else { } else {
const conditions = viewQuery ? [viewQuery] : [] const conditions = query ? [query] : []
options.query = { options.query = {
$and: { $and: {
conditions: [...conditions, options.query], conditions: [...conditions, options.query],
}, },
} }
if (viewQuery.onEmptyFilter) { if (query.onEmptyFilter) {
options.query.onEmptyFilter = viewQuery.onEmptyFilter options.query.onEmptyFilter = query.onEmptyFilter
} }
} }
} }

View File

@ -80,11 +80,10 @@ function userColumnMapping(column: string, filters: SearchFilters) {
}) })
} }
// maps through the search parameters to check if any of the inputs are invalid export function checkFilters(
// based on the table schema, converts them to something that is valid. table: Table,
export function searchInputMapping(table: Table, options: RowSearchParams) { filters: SearchFilters
// need an internal function to loop over filters, because this takes the full options ): SearchFilters {
function checkFilters(filters: SearchFilters) {
for (let [key, column] of Object.entries(table.schema || {})) { for (let [key, column] of Object.entries(table.schema || {})) {
switch (column.type) { switch (column.type) {
case FieldType.BB_REFERENCE_SINGLE: { case FieldType.BB_REFERENCE_SINGLE: {
@ -105,10 +104,17 @@ export function searchInputMapping(table: Table, options: RowSearchParams) {
} }
} }
} }
return dataFilters.recurseLogicalOperators(filters, checkFilters) return dataFilters.recurseLogicalOperators(filters, filters =>
checkFilters(table, filters)
)
} }
// maps through the search parameters to check if any of the inputs are invalid
// based on the table schema, converts them to something that is valid.
export function searchInputMapping(table: Table, options: RowSearchParams) {
// need an internal function to loop over filters, because this takes the full options
if (options.query) { if (options.query) {
options.query = checkFilters(options.query) options.query = checkFilters(table, options.query)
} }
return options return options
} }