diff --git a/.github/workflows/deploy-preprod.yml b/.github/workflows/deploy-preprod.yml index a1eee2c465..57e2504ded 100644 --- a/.github/workflows/deploy-preprod.yml +++ b/.github/workflows/deploy-preprod.yml @@ -17,6 +17,7 @@ jobs: id: version run: | if [ -z "${{ github.event.inputs.version }}" ]; then + git pull release_version=$(cat lerna.json | jq -r '.version') else release_version=${{ github.event.inputs.version }} diff --git a/.github/workflows/release-master.yml b/.github/workflows/release-master.yml index 20a48f5802..41af142bfc 100644 --- a/.github/workflows/release-master.yml +++ b/.github/workflows/release-master.yml @@ -134,6 +134,7 @@ jobs: - name: Get the latest budibase release version id: version run: | + git pull release_version=$(cat lerna.json | jq -r '.version') echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml index 9ff7dc1ddc..df4070806f 100644 --- a/charts/budibase/templates/app-service-deployment.yaml +++ b/charts/budibase/templates/app-service-deployment.yaml @@ -212,11 +212,24 @@ spec: image: budibase/apps:{{ .Values.globals.appVersion }} imagePullPolicy: Always livenessProbe: + httpGet: + path: /health + port: {{ .Values.services.apps.port }} + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 3 + readinessProbe: httpGet: path: /health port: {{ .Values.services.apps.port }} initialDelaySeconds: 5 periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 3 + name: bbapps ports: - containerPort: {{ .Values.services.apps.port }} diff --git a/charts/budibase/templates/worker-service-deployment.yaml b/charts/budibase/templates/worker-service-deployment.yaml index f998e5dfb9..f48d19689b 100644 --- a/charts/budibase/templates/worker-service-deployment.yaml +++ b/charts/budibase/templates/worker-service-deployment.yaml @@ -202,11 +202,23 @@ spec: image: budibase/worker:{{ .Values.globals.appVersion }} imagePullPolicy: Always livenessProbe: + httpGet: + path: /health + port: {{ .Values.services.worker.port }} + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 3 + readinessProbe: httpGet: path: /health port: {{ .Values.services.worker.port }} initialDelaySeconds: 5 periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 3 name: bbworker ports: - containerPort: {{ .Values.services.worker.port }} diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml index ed4ff014a9..ccbbf9878e 100644 --- a/charts/budibase/values.yaml +++ b/charts/budibase/values.yaml @@ -343,6 +343,7 @@ couchdb: ## Configure liveness and readiness probe values ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + # FOR COUCHDB livenessProbe: enabled: true failureThreshold: 3 diff --git a/lerna.json b/lerna.json index 85a8ed3fcb..c46d1c496d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.4.27-alpha.12", + "version": "2.4.40", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 48b5694fa5..18c8c9aa65 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -24,7 +24,7 @@ "dependencies": { "@budibase/nano": "10.1.2", "@budibase/pouchdb-replication-stream": "1.2.10", - "@budibase/types": "2.4.27-alpha.12", + "@budibase/types": "^2.4.40", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-cloudfront-sign": "2.2.0", diff --git a/packages/backend-core/src/blacklist/blacklist.ts b/packages/backend-core/src/blacklist/blacklist.ts new file mode 100644 index 0000000000..1fbb4683f9 --- /dev/null +++ b/packages/backend-core/src/blacklist/blacklist.ts @@ -0,0 +1,54 @@ +import dns from "dns" +import net from "net" +import env from "../environment" +import { promisify } from "util" + +let blackListArray: string[] | undefined +const performLookup = promisify(dns.lookup) + +async function lookup(address: string): Promise { + if (!net.isIP(address)) { + // need this for URL parsing simply + if (!address.startsWith("http")) { + address = `https://${address}` + } + address = new URL(address).hostname + } + const addresses = await performLookup(address, { + all: true, + }) + return addresses.map(addr => addr.address) +} + +export async function refreshBlacklist() { + const blacklist = env.BLACKLIST_IPS + const list = blacklist?.split(",") || [] + let final: string[] = [] + for (let addr of list) { + const trimmed = addr.trim() + if (!net.isIP(trimmed)) { + const addresses = await lookup(trimmed) + final = final.concat(addresses) + } else { + final.push(trimmed) + } + } + blackListArray = final +} + +export async function isBlacklisted(address: string): Promise { + if (!blackListArray) { + await refreshBlacklist() + } + if (blackListArray?.length === 0) { + return false + } + // no need for DNS + let ips: string[] + if (!net.isIP(address)) { + ips = await lookup(address) + } else { + ips = [address] + } + return !!blackListArray?.find(addr => ips.includes(addr)) +} diff --git a/packages/backend-core/src/blacklist/index.ts b/packages/backend-core/src/blacklist/index.ts new file mode 100644 index 0000000000..b5123eed3e --- /dev/null +++ b/packages/backend-core/src/blacklist/index.ts @@ -0,0 +1 @@ +export * from "./blacklist" diff --git a/packages/backend-core/src/blacklist/tests/blacklist.spec.ts b/packages/backend-core/src/blacklist/tests/blacklist.spec.ts new file mode 100644 index 0000000000..23a8dd1454 --- /dev/null +++ b/packages/backend-core/src/blacklist/tests/blacklist.spec.ts @@ -0,0 +1,46 @@ +import { refreshBlacklist, isBlacklisted } from ".." +import env from "../../environment" + +describe("blacklist", () => { + beforeAll(async () => { + env._set( + "BLACKLIST_IPS", + "www.google.com,192.168.1.1, 1.1.1.1,2.2.2.2/something" + ) + await refreshBlacklist() + }) + + it("should blacklist 192.168.1.1", async () => { + expect(await isBlacklisted("192.168.1.1")).toBe(true) + }) + + it("should allow 192.168.1.2", async () => { + expect(await isBlacklisted("192.168.1.2")).toBe(false) + }) + + it("should blacklist www.google.com", async () => { + expect(await isBlacklisted("www.google.com")).toBe(true) + }) + + it("should handle a complex domain", async () => { + expect( + await isBlacklisted("https://www.google.com/derp/?something=1") + ).toBe(true) + }) + + it("should allow www.microsoft.com", async () => { + expect(await isBlacklisted("www.microsoft.com")).toBe(false) + }) + + it("should blacklist an IP that needed trimming", async () => { + expect(await isBlacklisted("1.1.1.1")).toBe(true) + }) + + it("should blacklist 1.1.1.1/something", async () => { + expect(await isBlacklisted("1.1.1.1/something")).toBe(true) + }) + + it("should blacklist 2.2.2.2", async () => { + expect(await isBlacklisted("2.2.2.2")).toBe(true) + }) +}) diff --git a/packages/backend-core/src/environment.ts b/packages/backend-core/src/environment.ts index f1c96c7fec..5718494fc4 100644 --- a/packages/backend-core/src/environment.ts +++ b/packages/backend-core/src/environment.ts @@ -104,6 +104,7 @@ const environment = { SMTP_PORT: parseInt(process.env.SMTP_PORT || ""), SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS, DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING, + BLACKLIST_IPS: process.env.BLACKLIST_IPS, /** * Enable to allow an admin user to login using a password. * This can be useful to prevent lockout when configuring SSO. diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index a6d5423756..30072196ba 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -26,6 +26,7 @@ export * as utils from "./utils" export * as errors from "./errors" export * as timers from "./timers" export { default as env } from "./environment" +export * as blacklist from "./blacklist" export { SearchParams } from "./db" // Add context to tenancy for backwards compatibility // only do this for external usages to prevent internal diff --git a/packages/bbui/package.json b/packages/bbui/package.json index cd0bafb66f..3e2068c811 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,8 +38,8 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "1.2.1", - "@budibase/shared-core": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", + "@budibase/shared-core": "^2.4.40", + "@budibase/string-templates": "^2.4.40", "@spectrum-css/accordion": "3.0.24", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", diff --git a/packages/builder/package.json b/packages/builder/package.json index 781d0221df..b30dae3c48 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "license": "GPL-3.0", "private": true, "scripts": { @@ -58,11 +58,11 @@ } }, "dependencies": { - "@budibase/bbui": "2.4.27-alpha.12", - "@budibase/client": "2.4.27-alpha.12", - "@budibase/frontend-core": "2.4.27-alpha.12", - "@budibase/shared-core": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", + "@budibase/bbui": "^2.4.40", + "@budibase/client": "^2.4.40", + "@budibase/frontend-core": "^2.4.40", + "@budibase/shared-core": "^2.4.40", + "@budibase/string-templates": "^2.4.40", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/free-brands-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", diff --git a/packages/builder/src/builderStore/componentUtils.js b/packages/builder/src/builderStore/componentUtils.js index a9425da742..16b972058e 100644 --- a/packages/builder/src/builderStore/componentUtils.js +++ b/packages/builder/src/builderStore/componentUtils.js @@ -163,7 +163,12 @@ export const getComponentSettings = componentType => { def.settings ?.filter(setting => setting.section) .forEach(section => { - settings = settings.concat(section.settings || []) + settings = settings.concat( + (section.settings || []).map(setting => ({ + ...setting, + section: section.name, + })) + ) }) } componentSettingCache[componentType] = settings diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index f47fb8a086..eb9c618c24 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -32,8 +32,8 @@ import { getSchemaForTable } from "builderStore/dataBinding" import { Utils } from "@budibase/frontend-core" import { TriggerStepID, ActionStepID } from "constants/backend/automations" - import { cloneDeep } from "lodash/fp" import { onMount } from "svelte" + import { cloneDeep } from "lodash/fp" export let block export let testData @@ -214,8 +214,6 @@ function saveFilters(key) { const filters = LuceneUtils.buildLuceneQuery(tempFilters) const defKey = `${key}-def` - inputData[key] = filters - inputData[defKey] = tempFilters onChange({ detail: filters }, key) // need to store the builder definition in the automation onChange({ detail: tempFilters }, defKey) diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte index c14455b7fc..1080fc7305 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte @@ -95,8 +95,11 @@ } const onChange = (e, field, type) => { - value[field] = coerce(e.detail, type) - dispatch("change", value) + let newValue = { + ...value, + [field]: coerce(e.detail, type), + } + dispatch("change", newValue) } const onChangeSetting = (e, field) => { diff --git a/packages/builder/src/components/design/settings/controls/PropertyControl.svelte b/packages/builder/src/components/design/settings/controls/PropertyControl.svelte index e190805654..3fb3e13a94 100644 --- a/packages/builder/src/components/design/settings/controls/PropertyControl.svelte +++ b/packages/builder/src/components/design/settings/controls/PropertyControl.svelte @@ -8,6 +8,7 @@ import { onDestroy } from "svelte" export let label = "" + export let labelHidden = false export let componentInstance = {} export let control = null export let key = "" @@ -76,10 +77,10 @@
- {#if label} + {#if label && !labelHidden} {/if}
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsSection.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsSection.svelte index c21094c7f2..8fa0af45ed 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsSection.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ComponentSettingsSection.svelte @@ -133,6 +133,7 @@ type={setting.type} control={getComponentForSetting(setting)} label={setting.label} + labelHidden={setting.labelHidden} key={setting.key} value={componentInstance[setting.key]} defaultValue={setting.defaultValue} diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ConditionalUIDrawer.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ConditionalUIDrawer.svelte index 855c42173b..db6e66b87b 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ConditionalUIDrawer.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/settings/ConditionalUIDrawer.svelte @@ -62,7 +62,7 @@ type: "text", }) $: settingOptions = settings.map(setting => ({ - label: setting.label, + label: makeLabel(setting), value: setting.key, })) $: conditions.forEach(link => { @@ -71,6 +71,15 @@ } }) + const makeLabel = setting => { + const { section, label } = setting + if (section) { + return label ? `${section} - ${label}` : section + } else { + return label + } + } + const getSettingDefinition = key => { return settings.find(setting => setting.key === key) } diff --git a/packages/cli/package.json b/packages/cli/package.json index 27b522d69c..0c9d74b53d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "dist/index.js", "bin": { @@ -29,9 +29,9 @@ "outputPath": "build" }, "dependencies": { - "@budibase/backend-core": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", - "@budibase/types": "2.4.27-alpha.12", + "@budibase/backend-core": "^2.4.40", + "@budibase/string-templates": "^2.4.40", + "@budibase/types": "^2.4.40", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 9ee70c8a17..786220d31c 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4389,6 +4389,8 @@ "name": "On row click", "settings": [ { + "label": "Behaviour", + "labelHidden": true, "type": "radio", "key": "clickBehaviour", "sendEvents": true, @@ -4406,6 +4408,8 @@ ] }, { + "label": "Actions", + "labelHidden": true, "type": "event", "key": "onClick", "nested": true, @@ -4442,7 +4446,7 @@ { "type": "radio", "key": "titleButtonClickBehaviour", - "label": "Click behaviour", + "label": "Behaviour", "dependsOn": "showTitleButton", "defaultValue": "actions", "info": "New row side panel is only compatible with internal or SQL tables", @@ -4460,6 +4464,8 @@ { "label": "On click", "type": "event", + "label": "On click", + "labelHidden": true, "key": "onClickTitleButton", "nested": true, "dependsOn": { diff --git a/packages/client/package.json b/packages/client/package.json index 21ad1c8dfb..f5f13ef4f1 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,11 +19,11 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "2.4.27-alpha.12", - "@budibase/frontend-core": "2.4.27-alpha.12", - "@budibase/shared-core": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", - "@budibase/types": "2.4.27-alpha.12", + "@budibase/bbui": "^2.4.40", + "@budibase/frontend-core": "^2.4.40", + "@budibase/shared-core": "^2.4.40", + "@budibase/string-templates": "^2.4.40", + "@budibase/types": "^2.4.40", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 5891f1dedc..6f5783c239 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,13 +1,13 @@ { "name": "@budibase/frontend-core", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "2.4.27-alpha.12", - "@budibase/shared-core": "2.4.27-alpha.12", + "@budibase/bbui": "^2.4.40", + "@budibase/shared-core": "^2.4.40", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 078a431367..3d922974ac 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index c30c2807b8..050d042bd6 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -44,12 +44,12 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "2.4.27-alpha.12", - "@budibase/client": "2.4.27-alpha.12", - "@budibase/pro": "2.4.27-alpha.12", - "@budibase/shared-core": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", - "@budibase/types": "2.4.27-alpha.12", + "@budibase/backend-core": "^2.4.40", + "@budibase/client": "^2.4.40", + "@budibase/pro": "2.4.40", + "@budibase/shared-core": "^2.4.40", + "@budibase/string-templates": "^2.4.40", + "@budibase/types": "^2.4.40", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/automations/automationUtils.ts b/packages/server/src/automations/automationUtils.ts index 478acc8fab..44de2e7d6b 100644 --- a/packages/server/src/automations/automationUtils.ts +++ b/packages/server/src/automations/automationUtils.ts @@ -107,7 +107,7 @@ export function substituteLoopStep(hbsString: string, substitute: string) { let pointer = 0, openPointer = 0, closedPointer = 0 - while (pointer < hbsString.length) { + while (pointer < hbsString?.length) { openPointer = hbsString.indexOf(open, pointer) closedPointer = hbsString.indexOf(closed, pointer) + 2 if (openPointer < 0 || closedPointer < 0) { diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index a21c8e7d54..90107dfd4e 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -156,7 +156,7 @@ class InternalBuilder { const rawFnc = `${fnc}Raw` // @ts-ignore query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [ - `%${value}%`, + `%${value.toLowerCase()}%`, ]) } } @@ -202,7 +202,7 @@ class InternalBuilder { let statement = "" for (let i in value) { if (typeof value[i] === "string") { - value[i] = `%"${value[i]}"%` + value[i] = `%"${value[i].toLowerCase()}"%` } else { value[i] = `%${value[i]}%` } @@ -238,7 +238,7 @@ class InternalBuilder { const rawFnc = `${fnc}Raw` // @ts-ignore query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [ - `${value}%`, + `${value.toLowerCase()}%`, ]) } }) diff --git a/packages/server/src/integrations/rest.ts b/packages/server/src/integrations/rest.ts index c24636a5fd..dc63b961c4 100644 --- a/packages/server/src/integrations/rest.ts +++ b/packages/server/src/integrations/rest.ts @@ -19,6 +19,7 @@ import { formatBytes } from "../utilities" import { performance } from "perf_hooks" import FormData from "form-data" import { URLSearchParams } from "url" +import { blacklist } from "@budibase/backend-core" const BodyTypes = { NONE: "none", @@ -398,6 +399,9 @@ class RestIntegration implements IntegrationBase { this.startTimeMs = performance.now() const url = this.getUrl(path, queryString, pagination, paginationValues) + if (await blacklist.isBlacklisted(url)) { + throw new Error("Cannot connect to URL.") + } const response = await fetch(url, input) return await this.parseResponse(response, pagination) } diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index 2b9a0f1f10..bd1497bdc7 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -351,7 +351,7 @@ describe("SQL query builder", () => { }) ) expect(query).toEqual({ - bindings: [10, "%20%", "%25%", `%"John"%`, `%"Mary"%`], + bindings: [10, "%20%", "%25%", `%"john"%`, `%"mary"%`], sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where (LOWER([${TABLE_NAME}].[age]) LIKE @p1 AND LOWER([${TABLE_NAME}].[age]) LIKE @p2) and (LOWER([${TABLE_NAME}].[name]) LIKE @p3 AND LOWER([${TABLE_NAME}].[name]) LIKE @p4)) as [${TABLE_NAME}]`, }) }) @@ -402,7 +402,7 @@ describe("SQL query builder", () => { }) ) expect(query).toEqual({ - bindings: [10, "%20%", `%"John"%`], + bindings: [10, "%20%", `%"john"%`], sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where NOT (LOWER([${TABLE_NAME}].[age]) LIKE @p1) and NOT (LOWER([${TABLE_NAME}].[name]) LIKE @p2)) as [${TABLE_NAME}]`, }) }) @@ -453,7 +453,7 @@ describe("SQL query builder", () => { }) ) expect(query).toEqual({ - bindings: [10, "%20%", "%25%", `%"John"%`, `%"Mary"%`], + bindings: [10, "%20%", "%25%", `%"john"%`, `%"mary"%`], sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where (LOWER([${TABLE_NAME}].[age]) LIKE @p1 OR LOWER([${TABLE_NAME}].[age]) LIKE @p2) and (LOWER([${TABLE_NAME}].[name]) LIKE @p3 OR LOWER([${TABLE_NAME}].[name]) LIKE @p4)) as [${TABLE_NAME}]`, }) }) @@ -531,7 +531,7 @@ describe("SQL query builder", () => { }) ) expect(query).toEqual({ - bindings: ["John%", limit], + bindings: ["john%", limit], sql: `select * from (select * from \`${tableName}\` where LOWER(\`${tableName}\`.\`name\`) LIKE ? limit ?) as \`${tableName}\``, }) }) @@ -549,7 +549,7 @@ describe("SQL query builder", () => { }) ) expect(query).toEqual({ - bindings: [limit, "John%"], + bindings: [limit, "john%"], sql: `select * from (select top (@p0) * from [${tableName}] where LOWER([${tableName}].[name]) LIKE @p1) as [${tableName}]`, }) }) @@ -591,4 +591,49 @@ describe("SQL query builder", () => { sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"dob\" < $1 limit $2) as \"${TABLE_NAME}\"`, }) }) + + it("should lowercase the values for Oracle LIKE statements", () => { + let query = new Sql(SqlClient.ORACLE, limit)._query( + generateReadJson({ + filters: { + string: { + name: "John", + }, + }, + }) + ) + expect(query).toEqual({ + bindings: ["john%", limit], + sql: `select * from (select * from (select * from \"test\" where LOWER(\"test\".\"name\") LIKE :1) where rownum <= :2) \"test\"`, + }) + + query = new Sql(SqlClient.ORACLE, limit)._query( + generateReadJson({ + filters: { + contains: { + age: [20, 25], + name: ["John", "Mary"], + }, + }, + }) + ) + expect(query).toEqual({ + bindings: ["%20%", "%25%", `%"john"%`, `%"mary"%`, limit], + sql: `select * from (select * from (select * from \"test\" where (LOWER(\"test\".\"age\") LIKE :1 AND LOWER(\"test\".\"age\") LIKE :2) and (LOWER(\"test\".\"name\") LIKE :3 AND LOWER(\"test\".\"name\") LIKE :4)) where rownum <= :5) \"test\"`, + }) + + query = new Sql(SqlClient.ORACLE, limit)._query( + generateReadJson({ + filters: { + fuzzy: { + name: "Jo", + }, + }, + }) + ) + expect(query).toEqual({ + bindings: [`%jo%`, limit], + sql: `select * from (select * from (select * from \"test\" where LOWER(\"test\".\"name\") LIKE :1) where rownum <= :2) \"test\"`, + }) + }) }) diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index cf2f70830f..5fe177d095 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1290,14 +1290,14 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.12.tgz#655367eaa16a8bf1a28ff38eb0ab2127decb5b23" - integrity sha512-qCszwPDuYvMYZLl54T82ZrpM5xHD6nTEzPAkPQFrZIDtkW1dfKd2z+E2OirIOYb1CRN4GwrnIDjR0+u231Qo5w== +"@budibase/backend-core@2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.40.tgz#770158f360bcb30251aa2e50b0df40052e8ae3ce" + integrity sha512-ISN5100YjUwaJV5FJGr/4jccbottPhcp9CVBVxw90r0qKtlLVkG3zMRKJ9brSo3qx0Q8H3f1n7MrII3xoRyk3A== dependencies: "@budibase/nano" "10.1.2" "@budibase/pouchdb-replication-stream" "1.2.10" - "@budibase/types" "2.4.27-alpha.12" + "@budibase/types" "^2.4.40" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -1429,14 +1429,14 @@ pouchdb-promise "^6.0.4" through2 "^2.0.0" -"@budibase/pro@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.12.tgz#c3f74e4ef04ea1355bdc1333dd033f4a47087ac2" - integrity sha512-Hl/zalqmtlINgylFqQz3zWG/4dTXm/Skck2Q/j69gyqy0DotWXfRko03CbDQCyHGWhM/oXXiYJK54HIkn+kOTw== +"@budibase/pro@2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.40.tgz#2c1812fe35344ce8edf1401f2d8e4f289066c841" + integrity sha512-6ZXEv2J/AdaOAa2i/2XVDdCbgn2V//MN9LHx1/tr6ixcP/nCnBXjnBXrYqLrXsHcB6IiFXJwjOtirSrn3eXyuA== dependencies: - "@budibase/backend-core" "2.4.27-alpha.12" + "@budibase/backend-core" "2.4.40" "@budibase/string-templates" "2.3.20" - "@budibase/types" "2.4.27-alpha.12" + "@budibase/types" "2.4.40" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -1475,10 +1475,10 @@ lodash "^4.17.20" vm2 "^3.9.4" -"@budibase/types@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.12.tgz#4c0dd66434f52c41080c17b810262ff8f195cb6c" - integrity sha512-mpzlQM49WWQyWnysFcMkJDD3jY6Wf5HG7R8/eb5PRbSWx92+17g0iCbhuaswfCJdz0GIi73hebmvaFeuQ/glMg== +"@budibase/types@2.4.40", "@budibase/types@^2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.40.tgz#12d02240e6d31f47a91eb93c971f0f835da6f950" + integrity sha512-3rk626nhpeH88l4WzU7bjG4fo8SDELSEuko7Jb+DmZdEGxrP+5NVCyNTswndXa7oSuvmg/Wg17W/aatCBNCkxA== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/shared-core/package.json b/packages/shared-core/package.json index 34d090ba0e..e8df9745a3 100644 --- a/packages/shared-core/package.json +++ b/packages/shared-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/shared-core", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Shared data utils", "main": "dist/cjs/src/index.js", "types": "dist/mjs/src/index.d.ts", @@ -20,7 +20,7 @@ "dev:builder": "yarn prebuild && concurrently \"tsc -p tsconfig.build.json --watch\" \"tsc -p tsconfig-cjs.build.json --watch\"" }, "dependencies": { - "@budibase/types": "2.4.27-alpha.12" + "@budibase/types": "^2.4.40" }, "devDependencies": { "concurrently": "^7.6.0", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 7e78b7b2f6..d84dc3d13e 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/types/package.json b/packages/types/package.json index a6a3757ae7..ebcb090817 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase types", "main": "dist/cjs/index.js", "types": "dist/mjs/index.d.ts", diff --git a/packages/worker/package.json b/packages/worker/package.json index d905874c93..455dee2ace 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "2.4.27-alpha.12", + "version": "2.4.40", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -36,10 +36,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "2.4.27-alpha.12", - "@budibase/pro": "2.4.27-alpha.12", - "@budibase/string-templates": "2.4.27-alpha.12", - "@budibase/types": "2.4.27-alpha.12", + "@budibase/backend-core": "^2.4.40", + "@budibase/pro": "2.4.40", + "@budibase/string-templates": "^2.4.40", + "@budibase/types": "^2.4.40", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/src/api/controllers/system/tenants.ts b/packages/worker/src/api/controllers/system/tenants.ts index 151507358f..ddc6c39c0f 100644 --- a/packages/worker/src/api/controllers/system/tenants.ts +++ b/packages/worker/src/api/controllers/system/tenants.ts @@ -5,7 +5,7 @@ export async function destroy(ctx: UserCtx) { const user = ctx.user! const tenantId = ctx.params.tenantId - if (tenantId !== user.tenantId) { + if (!ctx.internal && tenantId !== user.tenantId) { ctx.throw(403, "Tenant ID does not match current user") } diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 7b589ce2a7..3e46a1117b 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -475,14 +475,14 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.27-alpha.12.tgz#655367eaa16a8bf1a28ff38eb0ab2127decb5b23" - integrity sha512-qCszwPDuYvMYZLl54T82ZrpM5xHD6nTEzPAkPQFrZIDtkW1dfKd2z+E2OirIOYb1CRN4GwrnIDjR0+u231Qo5w== +"@budibase/backend-core@2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.40.tgz#770158f360bcb30251aa2e50b0df40052e8ae3ce" + integrity sha512-ISN5100YjUwaJV5FJGr/4jccbottPhcp9CVBVxw90r0qKtlLVkG3zMRKJ9brSo3qx0Q8H3f1n7MrII3xoRyk3A== dependencies: "@budibase/nano" "10.1.2" "@budibase/pouchdb-replication-stream" "1.2.10" - "@budibase/types" "2.4.27-alpha.12" + "@budibase/types" "^2.4.40" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -564,14 +564,14 @@ pouchdb-promise "^6.0.4" through2 "^2.0.0" -"@budibase/pro@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.27-alpha.12.tgz#c3f74e4ef04ea1355bdc1333dd033f4a47087ac2" - integrity sha512-Hl/zalqmtlINgylFqQz3zWG/4dTXm/Skck2Q/j69gyqy0DotWXfRko03CbDQCyHGWhM/oXXiYJK54HIkn+kOTw== +"@budibase/pro@2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.40.tgz#2c1812fe35344ce8edf1401f2d8e4f289066c841" + integrity sha512-6ZXEv2J/AdaOAa2i/2XVDdCbgn2V//MN9LHx1/tr6ixcP/nCnBXjnBXrYqLrXsHcB6IiFXJwjOtirSrn3eXyuA== dependencies: - "@budibase/backend-core" "2.4.27-alpha.12" + "@budibase/backend-core" "2.4.40" "@budibase/string-templates" "2.3.20" - "@budibase/types" "2.4.27-alpha.12" + "@budibase/types" "2.4.40" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -592,10 +592,10 @@ lodash "^4.17.20" vm2 "^3.9.4" -"@budibase/types@2.4.27-alpha.12": - version "2.4.27-alpha.12" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.27-alpha.12.tgz#4c0dd66434f52c41080c17b810262ff8f195cb6c" - integrity sha512-mpzlQM49WWQyWnysFcMkJDD3jY6Wf5HG7R8/eb5PRbSWx92+17g0iCbhuaswfCJdz0GIi73hebmvaFeuQ/glMg== +"@budibase/types@2.4.40", "@budibase/types@^2.4.40": + version "2.4.40" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.40.tgz#12d02240e6d31f47a91eb93c971f0f835da6f950" + integrity sha512-3rk626nhpeH88l4WzU7bjG4fo8SDELSEuko7Jb+DmZdEGxrP+5NVCyNTswndXa7oSuvmg/Wg17W/aatCBNCkxA== "@cspotcode/source-map-support@^0.8.0": version "0.8.1"