diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..e414f48cb8 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Versions + +As an open source product, we will only patch the latest major version for security vulnerabilities. Previous versions of budibase will not be retroactively patched. + +## Disclosing + +You can get in touch with us regarding a vulnerability via email at community@budibase.com. + +You can also disclose via huntr.dev. If you believe you have found a vulnerability, please disclose it on huntr and let us know. + +https://huntr.dev/bounties/disclose + +This will enable us to review the vulnerability and potentially reward you for your work. diff --git a/hosting/kubernetes/envoy/envoy.yaml b/hosting/kubernetes/envoy/envoy.yaml index 0e7859d887..1041287f5e 100644 --- a/hosting/kubernetes/envoy/envoy.yaml +++ b/hosting/kubernetes/envoy/envoy.yaml @@ -33,11 +33,19 @@ static_resources: route: cluster: app-service - # special case for worker admin API + # special cases for worker admin (deprecated), global and system API + - match: { prefix: "/api/global/" } + route: + cluster: worker-service + - match: { prefix: "/api/admin/" } route: cluster: worker-service + - match: { prefix: "/api/system/" } + route: + cluster: worker-service + - match: { path: "/" } route: cluster: app-service diff --git a/lerna.json b/lerna.json index 644b6a6dca..c4ebd76a28 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.121", + "version": "0.9.123-alpha.1", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/package.json b/package.json index 05c69e54dc..f8d9d1789e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "setup": "node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev", "bootstrap": "lerna link && lerna bootstrap", "build": "lerna run build", - "initialise": "lerna run initialise", "publishdev": "lerna run publishdev", "publishnpm": "yarn build && lerna publish --force-publish", "release": "yarn build && lerna publish patch --yes --force-publish", diff --git a/packages/auth/package.json b/packages/auth/package.json index c1f0237343..57895d4dbd 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.121", + "version": "0.9.123-alpha.1", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", diff --git a/packages/auth/src/middleware/tenancy.js b/packages/auth/src/middleware/tenancy.js index b80b9a6763..19cce82273 100644 --- a/packages/auth/src/middleware/tenancy.js +++ b/packages/auth/src/middleware/tenancy.js @@ -2,12 +2,13 @@ const { setTenantId } = require("../tenancy") const ContextFactory = require("../tenancy/FunctionContext") const { buildMatcherRegex, matches } = require("./matchers") -module.exports = (allowQueryStringPatterns, noTenancyPatterns) => { +module.exports = (allowQueryStringPatterns, noTenancyPatterns, opts = {}) => { const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns) const noTenancyOptions = buildMatcherRegex(noTenancyPatterns) return ContextFactory.getMiddleware(ctx => { - const allowNoTenant = !!matches(ctx, noTenancyOptions) + const allowNoTenant = + opts.noTenancyRequired || !!matches(ctx, noTenancyOptions) const allowQs = !!matches(ctx, allowQsOptions) setTenantId(ctx, { allowQs, allowNoTenant }) }) diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 6f152c5f1c..27de8f3719 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": "0.9.121", + "version": "0.9.123-alpha.1", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/bbui/src/Table/Table.svelte b/packages/bbui/src/Table/Table.svelte index b6b61a8d04..11284b8917 100644 --- a/packages/bbui/src/Table/Table.svelte +++ b/packages/bbui/src/Table/Table.svelte @@ -3,6 +3,7 @@ import "@spectrum-css/table/dist/index-vars.css" import CellRenderer from "./CellRenderer.svelte" import SelectEditRenderer from "./SelectEditRenderer.svelte" + import { cloneDeep } from "lodash" /** * The expected schema is our normal couch schemas for our tables. @@ -197,7 +198,7 @@ const editRow = (e, row) => { e.stopPropagation() - dispatch("editrow", row) + dispatch("editrow", cloneDeep(row)) } const toggleSelectRow = row => { diff --git a/packages/builder/package.json b/packages/builder/package.json index 2e8c55c7e2..84553352c9 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.121", + "version": "0.9.123-alpha.1", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.121", - "@budibase/client": "^0.9.121", + "@budibase/bbui": "^0.9.123-alpha.1", + "@budibase/client": "^0.9.123-alpha.1", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.121", + "@budibase/string-templates": "^0.9.123-alpha.1", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index 00eaaf0249..887695d41e 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -1,6 +1,10 @@ import { cloneDeep } from "lodash/fp" import { get } from "svelte/store" -import { findComponent, findComponentPath } from "./storeUtils" +import { + findComponent, + findComponentPath, + findAllMatchingComponents, +} from "./storeUtils" import { store } from "builderStore" import { tables as tablesStore, queries as queriesStores } from "stores/backend" import { makePropSafe } from "@budibase/string-templates" @@ -18,7 +22,9 @@ export const getBindableProperties = (asset, componentId) => { const userBindings = getUserBindings() const urlBindings = getUrlBindings(asset) const deviceBindings = getDeviceBindings() + const stateBindings = getStateBindings() return [ + ...stateBindings, ...deviceBindings, ...urlBindings, ...contextBindings, @@ -256,6 +262,18 @@ const getDeviceBindings = () => { return bindings } +/** + * Gets all state bindings that are globally available. + */ +const getStateBindings = () => { + const safeState = makePropSafe("state") + return getAllStateVariables().map(key => ({ + type: "context", + runtimeBinding: `${safeState}.${makePropSafe(key)}`, + readableBinding: `State.${key}`, + })) +} + /** * Gets all bindable properties from URL parameters. */ @@ -458,3 +476,49 @@ export function runtimeToReadableBinding(bindableProperties, textWithBindings) { "readableBinding" ) } + +/** + * Returns an array of the keys of any state variables which are set anywhere + * in the app. + */ +export const getAllStateVariables = () => { + let allComponents = [] + + // Find all onClick settings in all layouts + get(store).layouts.forEach(layout => { + const components = findAllMatchingComponents( + layout.props, + c => c.onClick != null + ) + allComponents = allComponents.concat(components || []) + }) + + // Find all onClick settings in all screens + get(store).screens.forEach(screen => { + const components = findAllMatchingComponents( + screen.props, + c => c.onClick != null + ) + allComponents = allComponents.concat(components || []) + }) + + // Add state bindings for all state actions + let bindingSet = new Set() + allComponents.forEach(component => { + if (!Array.isArray(component.onClick)) { + return + } + component.onClick.forEach(action => { + if ( + action["##eventHandlerType"] === "Update State" && + action.parameters?.type === "set" && + action.parameters?.key && + action.parameters?.value + ) { + bindingSet.add(action.parameters.key) + } + }) + }) + + return Array.from(bindingSet) +} diff --git a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte index 0b63c0bd4d..740027a8fd 100644 --- a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte @@ -18,12 +18,10 @@ let exportFormat = FORMATS[0].key async function exportView() { - const filename = `export.${exportFormat}` download( `/api/views/export?view=${encodeURIComponent( view - )}&format=${exportFormat}`, - filename + )}&format=${exportFormat}` ) } diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/UpdateState.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/UpdateState.svelte new file mode 100644 index 0000000000..6c2867d4bf --- /dev/null +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/UpdateState.svelte @@ -0,0 +1,65 @@ + + +
+ +