Validate query names to avoid parentheses

This commit is contained in:
Andrew Kingston 2023-07-24 12:02:24 +01:00
parent 7019fda4bf
commit 869cb0777b
3 changed files with 25 additions and 9 deletions

View File

@ -14,8 +14,9 @@
Tab, Tab,
Modal, Modal,
ModalContent, ModalContent,
notifications,
Divider,
} from "@budibase/bbui" } from "@budibase/bbui"
import { notifications, Divider } from "@budibase/bbui"
import ExtraQueryConfig from "./ExtraQueryConfig.svelte" import ExtraQueryConfig from "./ExtraQueryConfig.svelte"
import IntegrationQueryEditor from "components/integration/index.svelte" import IntegrationQueryEditor from "components/integration/index.svelte"
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte" import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
@ -28,6 +29,7 @@
import KeyValueBuilder from "./KeyValueBuilder.svelte" import KeyValueBuilder from "./KeyValueBuilder.svelte"
import { fieldsToSchema, schemaToFields } from "helpers/data/utils" import { fieldsToSchema, schemaToFields } from "helpers/data/utils"
import AccessLevelSelect from "./AccessLevelSelect.svelte" import AccessLevelSelect from "./AccessLevelSelect.svelte"
import { ValidQueryNameRegex } from "@budibase/shared-core"
export let query export let query
@ -47,6 +49,7 @@
let saveModal let saveModal
let override = false let override = false
let navigateTo = null let navigateTo = null
let nameError = null
// seed the transformer // seed the transformer
if (query && !query.transformer) { if (query && !query.transformer) {
@ -77,7 +80,7 @@
$: queryConfig = integrationInfo?.query $: queryConfig = integrationInfo?.query
$: shouldShowQueryConfig = queryConfig && query.queryVerb $: shouldShowQueryConfig = queryConfig && query.queryVerb
$: readQuery = query.queryVerb === "read" || query.readable $: readQuery = query.queryVerb === "read" || query.readable
$: queryInvalid = !query.name || (readQuery && data.length === 0) $: queryInvalid = !query.name || nameError || (readQuery && data.length === 0)
//Cast field in query preview response to number if specified by schema //Cast field in query preview response to number if specified by schema
$: { $: {
@ -139,9 +142,10 @@
queryStr = JSON.stringify(query) queryStr = JSON.stringify(query)
} }
notifications.success("Query saved successfully")
return response return response
} catch (error) { } catch (error) {
notifications.error("Error saving query") notifications.error(error.message || "Error saving query")
} }
} }
</script> </script>
@ -183,8 +187,14 @@
value={query.name} value={query.name}
on:input={e => { on:input={e => {
let newValue = e.target.value || "" let newValue = e.target.value || ""
query.name = newValue.trim() if (newValue.match(ValidQueryNameRegex)) {
query.name = newValue.trim()
nameError = null
} else {
nameError = "Invalid query name"
}
}} }}
error={nameError}
/> />
</div> </div>
{#if queryConfig} {#if queryConfig}
@ -250,9 +260,9 @@
size="L" size="L"
/> />
</div> </div>
<Body size="S" <Body size="S">
>Add a JavaScript function to transform the query result.</Body Add a JavaScript function to transform the query result.
> </Body>
<CodeMirrorEditor <CodeMirrorEditor
height={200} height={200}
label="Transformer" label="Transformer"
@ -264,13 +274,12 @@
</div> </div>
<div class="viewer-controls"> <div class="viewer-controls">
<Heading size="S">Results</Heading> <Heading size="S">Results</Heading>
<ButtonGroup gap="XS"> <ButtonGroup gap="S">
<Button <Button
cta cta
disabled={queryInvalid} disabled={queryInvalid}
on:click={async () => { on:click={async () => {
await saveQuery() await saveQuery()
notifications.success(`Query saved successfully`)
// Go to the correct URL if we just created a new query // Go to the correct URL if we just created a new query
if (!query._rev) { if (!query._rev) {
$goto(`../../${query._id}`) $goto(`../../${query._id}`)

View File

@ -10,6 +10,7 @@ import { events, context, utils, constants } from "@budibase/backend-core"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { QueryEvent } from "../../../threads/definitions" import { QueryEvent } from "../../../threads/definitions"
import { Query } from "@budibase/types" import { Query } from "@budibase/types"
import { ValidQueryNameRegex } from "@budibase/shared-core"
const Runner = new Thread(ThreadType.QUERY, { const Runner = new Thread(ThreadType.QUERY, {
timeoutMs: env.QUERY_THREAD_TIMEOUT || 10000, timeoutMs: env.QUERY_THREAD_TIMEOUT || 10000,
@ -84,6 +85,11 @@ export async function save(ctx: any) {
const db = context.getAppDB() const db = context.getAppDB()
const query = ctx.request.body const query = ctx.request.body
// Validate query name
if (!query?.name.match(ValidQueryNameRegex)) {
ctx.throw(400, "Invalid query name")
}
const datasource = await sdk.datasources.get(query.datasourceId) const datasource = await sdk.datasources.get(query.datasourceId)
let eventFn let eventFn

View File

@ -94,3 +94,4 @@ export enum BuilderSocketEvent {
} }
export const SocketSessionTTL = 60 export const SocketSessionTTL = 60
export const ValidQueryNameRegex = /^[^()]*$/