1
0
Fork 0
mirror of synced 2024-06-29 19:41:03 +12:00

Merge branch 'master' into fix/multi-step-form-block

This commit is contained in:
Andrew Kingston 2024-03-19 15:15:07 +00:00 committed by GitHub
commit 57bdf4b04d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 59 additions and 22 deletions

View file

@ -1,6 +1,6 @@
import { AnyDocument, Database } from "@budibase/types" import { AnyDocument, Database } from "@budibase/types"
import { JobQueue, createQueue } from "../queue" import { JobQueue, Queue, createQueue } from "../queue"
import * as dbUtils from "../db" import * as dbUtils from "../db"
interface ProcessDocMessage { interface ProcessDocMessage {
@ -12,18 +12,26 @@ interface ProcessDocMessage {
const PERSIST_MAX_ATTEMPTS = 100 const PERSIST_MAX_ATTEMPTS = 100
let processor: DocWritethroughProcessor | undefined let processor: DocWritethroughProcessor | undefined
export const docWritethroughProcessorQueue = createQueue<ProcessDocMessage>( export class DocWritethroughProcessor {
JobQueue.DOC_WRITETHROUGH_QUEUE, private static _queue: Queue
{
jobOptions: { public static get queue() {
attempts: PERSIST_MAX_ATTEMPTS, if (!DocWritethroughProcessor._queue) {
}, DocWritethroughProcessor._queue = createQueue<ProcessDocMessage>(
} JobQueue.DOC_WRITETHROUGH_QUEUE,
) {
jobOptions: {
attempts: PERSIST_MAX_ATTEMPTS,
},
}
)
}
return DocWritethroughProcessor._queue
}
class DocWritethroughProcessor {
init() { init() {
docWritethroughProcessorQueue.process(async message => { DocWritethroughProcessor.queue.process(async message => {
try { try {
await this.persistToDb(message.data) await this.persistToDb(message.data)
} catch (err: any) { } catch (err: any) {
@ -76,7 +84,7 @@ export class DocWritethrough {
} }
async patch(data: Record<string, any>) { async patch(data: Record<string, any>) {
await docWritethroughProcessorQueue.add({ await DocWritethroughProcessor.queue.add({
dbName: this.db.name, dbName: this.db.name,
docId: this.docId, docId: this.docId,
data, data,

View file

@ -6,7 +6,7 @@ import { getDB } from "../../db"
import { import {
DocWritethrough, DocWritethrough,
docWritethroughProcessorQueue, DocWritethroughProcessor,
init, init,
} from "../docWritethrough" } from "../docWritethrough"
@ -15,7 +15,7 @@ import InMemoryQueue from "../../queue/inMemoryQueue"
const initialTime = Date.now() const initialTime = Date.now()
async function waitForQueueCompletion() { async function waitForQueueCompletion() {
const queue: InMemoryQueue = docWritethroughProcessorQueue as never const queue: InMemoryQueue = DocWritethroughProcessor.queue as never
await queue.waitForCompletion() await queue.waitForCompletion()
} }
@ -235,7 +235,7 @@ describe("docWritethrough", () => {
return acc return acc
}, {}) }, {})
} }
const queueMessageSpy = jest.spyOn(docWritethroughProcessorQueue, "add") const queueMessageSpy = jest.spyOn(DocWritethroughProcessor.queue, "add")
await config.doInTenant(async () => { await config.doInTenant(async () => {
let patches = await parallelPatch(5) let patches = await parallelPatch(5)

View file

@ -11,6 +11,7 @@
"types": ["node", "jest"], "types": ["node", "jest"],
"outDir": "dist", "outDir": "dist",
"skipLibCheck": true, "skipLibCheck": true,
"baseUrl": ".",
"paths": { "paths": {
"@budibase/types": ["../types/src"], "@budibase/types": ["../types/src"],
"@budibase/backend-core": ["../backend-core/src"], "@budibase/backend-core": ["../backend-core/src"],

View file

@ -14,22 +14,35 @@ import {
SessionCookie, SessionCookie,
JsonFieldSubType, JsonFieldSubType,
QueryResponse, QueryResponse,
QueryPreview,
QuerySchema, QuerySchema,
FieldType, FieldType,
ExecuteQueryRequest, ExecuteQueryRequest,
ExecuteQueryResponse, ExecuteQueryResponse,
Row,
QueryParameter, QueryParameter,
PreviewQueryRequest, PreviewQueryRequest,
PreviewQueryResponse, PreviewQueryResponse,
} from "@budibase/types" } from "@budibase/types"
import { ValidQueryNameRegex, utils as JsonUtils } from "@budibase/shared-core" import { ValidQueryNameRegex, utils as JsonUtils } from "@budibase/shared-core"
import { findHBSBlocks } from "@budibase/string-templates"
const Runner = new Thread(ThreadType.QUERY, { const Runner = new Thread(ThreadType.QUERY, {
timeoutMs: env.QUERY_THREAD_TIMEOUT, timeoutMs: env.QUERY_THREAD_TIMEOUT,
}) })
function validateQueryInputs(parameters: Record<string, string>) {
for (let entry of Object.entries(parameters)) {
const [key, value] = entry
if (typeof value !== "string") {
continue
}
if (findHBSBlocks(value).length !== 0) {
throw new Error(
`Parameter '${key}' input contains a handlebars binding - this is not allowed.`
)
}
}
}
export async function fetch(ctx: UserCtx) { export async function fetch(ctx: UserCtx) {
ctx.body = await sdk.queries.fetch() ctx.body = await sdk.queries.fetch()
} }
@ -123,10 +136,10 @@ function getAuthConfig(ctx: UserCtx) {
function enrichParameters( function enrichParameters(
queryParameters: QueryParameter[], queryParameters: QueryParameter[],
requestParameters: { [key: string]: string } = {} requestParameters: Record<string, string> = {}
): { ): Record<string, string> {
[key: string]: string // first check parameters are all valid
} { validateQueryInputs(requestParameters)
// make sure parameters are fully enriched with defaults // make sure parameters are fully enriched with defaults
for (let parameter of queryParameters) { for (let parameter of queryParameters) {
if (!requestParameters[parameter.name]) { if (!requestParameters[parameter.name]) {

View file

@ -408,6 +408,21 @@ describe("/queries", () => {
}, },
}) })
}) })
it("shouldn't allow handlebars to be passed as parameters", async () => {
const res = await request
.post(`/api/queries/${query._id}`)
.send({
parameters: {
a: "{{ 'test' }}",
},
})
.set(config.defaultHeaders())
.expect(400)
expect(res.body.message).toEqual(
"Parameter 'a' input contains a handlebars binding - this is not allowed."
)
})
}) })
describe("variables", () => { describe("variables", () => {

View file

@ -11,7 +11,7 @@ export interface PreviewQueryResponse {
} }
export interface ExecuteQueryRequest { export interface ExecuteQueryRequest {
parameters?: { [key: string]: string } parameters?: Record<string, string>
pagination?: any pagination?: any
} }