From cda958e0b74fb0e5c0eeeab1f85069dd96ab6cdb Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 15 Jul 2022 13:39:47 +0100 Subject: [PATCH 1/5] Fix for #6702 - remove users table as an option for automation triggers. --- .../automation/SetupPanel/AutomationBlockSetup.svelte | 3 +++ .../components/automation/SetupPanel/TableSelector.svelte | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index c149b6a00e..27ea7aab87 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -41,6 +41,7 @@ let fillWidth = true let codeBindingOpen = false + $: console.log(block) $: stepId = block.stepId $: bindings = getAvailableBindings( block || $automationStore.selectedBlock, @@ -54,6 +55,7 @@ $: schema = getSchemaForTable(tableId, { searchableSchema: true }).schema $: schemaFields = Object.values(schema || {}) $: queryLimit = tableId?.includes("datasource") ? "∞" : "1000" + $: isTrigger = block?.type === "TRIGGER" const onChange = Utils.sequential(async (e, key) => { try { @@ -261,6 +263,7 @@ /> {:else if value.customType === "table"} onChange(e, key)} /> diff --git a/packages/builder/src/components/automation/SetupPanel/TableSelector.svelte b/packages/builder/src/components/automation/SetupPanel/TableSelector.svelte index ceb28a37ca..1645ded66b 100644 --- a/packages/builder/src/components/automation/SetupPanel/TableSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/TableSelector.svelte @@ -2,10 +2,16 @@ import { tables } from "stores/backend" import { Select } from "@budibase/bbui" import { createEventDispatcher } from "svelte" + import { TableNames } from "constants" const dispatch = createEventDispatcher() export let value + export let isTrigger + + $: filteredTables = $tables.list.filter(table => { + return !isTrigger || table._id !== TableNames.USERS + }) const onChange = e => { value = e.detail @@ -16,7 +22,7 @@ - + (touched = true)} /> + {#if touched && !value} + + {/if}
diff --git a/packages/server/src/automations/utils.ts b/packages/server/src/automations/utils.ts index 1f86abc5b9..906923b2e9 100644 --- a/packages/server/src/automations/utils.ts +++ b/packages/server/src/automations/utils.ts @@ -97,7 +97,7 @@ export async function enableCronTrigger(appId: any, automation: any) { ) } // need to create cron job - if (isCronTrigger(automation)) { + if (isCronTrigger(automation) && trigger?.inputs.cron) { // make a job id rather than letting Bull decide, makes it easier to handle on way out const jobId = `${appId}_cron_${newid()}` const job: any = await queue.add( From d10e5755e7268e157abbe8f6bd1bbd2a60e5ca1b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 15 Jul 2022 14:33:34 +0100 Subject: [PATCH 3/5] Removing console log. --- .../components/automation/SetupPanel/AutomationBlockSetup.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 27ea7aab87..8b3f32a33f 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -41,7 +41,6 @@ let fillWidth = true let codeBindingOpen = false - $: console.log(block) $: stepId = block.stepId $: bindings = getAvailableBindings( block || $automationStore.selectedBlock, From c525721854834757411d9de05b4a44c0a9c689ed Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 15 Jul 2022 17:13:45 +0100 Subject: [PATCH 4/5] Fix for #6709 - Adding the option to set a role for app action, allowing users to set what level an automation can be accessed from. --- .../FlowChart/FlowChart.svelte | 3 +- .../FlowChart/FlowItem.svelte | 39 ++++++++++++++++++- .../AutomationBuilder/TestDisplay.svelte | 7 ++-- .../AutomationBuilder/TestPanel.svelte | 3 +- .../CreateAutomationModal.svelte | 3 +- .../SetupPanel/AutomationBlockSetup.svelte | 9 +++-- .../CreateWebhookDeploymentModal.svelte | 3 +- .../actions/TriggerAutomation.svelte | 3 +- .../src/constants/backend/automations.js | 28 +++++++++++++ packages/server/src/utilities/security.js | 1 + 10 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 packages/builder/src/constants/backend/automations.js diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index 9c987c89d8..05cae46cfc 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -12,6 +12,7 @@ notifications, Modal, } from "@budibase/bbui" + import { ActionStepID } from "constants/backend/automations" export let automation let testDataModal @@ -82,7 +83,7 @@ in:fly|local={{ x: 500, duration: 500 }} out:fly|local={{ x: 500, duration: 500 }} > - {#if block.stepId !== "LOOP"} + {#if block.stepId !== ActionStepID.LOOP} {/if}
diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 291575f3f2..412683721f 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -10,11 +10,15 @@ Select, ActionButton, notifications, + Label, } from "@budibase/bbui" import AutomationBlockSetup from "../../SetupPanel/AutomationBlockSetup.svelte" import CreateWebhookModal from "components/automation/Shared/CreateWebhookModal.svelte" import ActionModal from "./ActionModal.svelte" import FlowItemHeader from "./FlowItemHeader.svelte" + import RoleSelect from "components/design/settings/controls/RoleSelect.svelte" + import { ActionStepID, TriggerStepID } from "constants/backend/automations" + import { permissions } from "stores/backend" export let block export let testDataModal @@ -23,9 +27,12 @@ let actionModal let blockComplete let showLooping = false + let role + $: automationId = $automationStore.selectedAutomation?.automation._id $: showBindingPicker = - block.stepId === "CREATE_ROW" || block.stepId === "UPDATE_ROW" + block.stepId === ActionStepID.CREATE_ROW || + block.stepId === ActionStepID.UPDATE_ROW $: isTrigger = block.type === "TRIGGER" @@ -45,6 +52,32 @@ x => x.blockToLoop === block.id ) + $: setPermissions(role) + $: getPermissions(automationId) + + async function setPermissions(role) { + if (!role || !automationId) { + return + } + await permissions.save({ + level: "execute", + role, + resource: automationId, + }) + } + + async function getPermissions(automationId) { + if (!automationId) { + return + } + const perms = await permissions.forResource(automationId) + if (!perms["execute"]) { + role = "BASIC" + } else { + role = perms["execute"] + } + } + async function removeLooping() { loopingSelected = false let loopBlock = @@ -205,6 +238,10 @@ {/if} + {#if block.stepId === TriggerStepID.APP} + + + {/if} import { Icon, Divider, Tabs, Tab, TextArea, Label } from "@budibase/bbui" import FlowItemHeader from "./FlowChart/FlowItemHeader.svelte" + import { ActionStepID } from "constants/backend/automations" export let automation export let testResults @@ -10,7 +11,7 @@ let blocks function prepTestResults(results) { - return results?.steps.filter(x => x.stepId !== "LOOP" || []) + return results?.steps.filter(x => x.stepId !== ActionStepID.LOOP || []) } function textArea(results, message) { @@ -30,7 +31,7 @@ } blocks = blocks .concat(automation.definition.steps || []) - .filter(x => x.stepId !== "LOOP") + .filter(x => x.stepId !== ActionStepID.LOOP) } else if (filteredResults) { blocks = filteredResults || [] // make sure there is an ID for each block being displayed @@ -45,7 +46,7 @@
{#each blocks as block, idx}
- {#if block.stepId !== "LOOP"} + {#if block.stepId !== ActionStepID.LOOP} x.stepId !== "LOOP") + .filter(x => x.stepId !== ActionStepID.LOOP) } else if (testResults) { blocks = testResults.steps || [] } diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte index 9543a9c552..eb148534f3 100644 --- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte @@ -11,6 +11,7 @@ Body, Icon, } from "@budibase/bbui" + import { TriggerStepID } from "constants/backend/automations" let name let selectedTrigger @@ -35,7 +36,7 @@ ) automationStore.actions.addBlockToAutomation(newBlock) - if (triggerVal.stepId === "WEBHOOK") { + if (triggerVal.stepId === TriggerStepID.WEBHOOK) { webhookModal.show } diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 8b3f32a33f..8b34cf8cd2 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -30,6 +30,7 @@ import { LuceneUtils } from "@budibase/frontend-core" import { getSchemaForTable } from "builderStore/dataBinding" import { Utils } from "@budibase/frontend-core" + import { TriggerStepID, ActionStepID } from "constants/backend/automations" export let block export let testData @@ -60,7 +61,7 @@ try { if (isTestModal) { // Special case for webhook, as it requires a body, but the schema already brings back the body's contents - if (stepId === "WEBHOOK") { + if (stepId === TriggerStepID.WEBHOOK) { automationStore.actions.addTestDataToAutomation({ body: { [key]: e.detail, @@ -101,9 +102,9 @@ // Extract all outputs from all previous steps as available bindins let bindings = [] for (let idx = 0; idx < blockIdx; idx++) { - let wasLoopBlock = allSteps[idx]?.stepId === "LOOP" + let wasLoopBlock = allSteps[idx]?.stepId === ActionStepID.LOOP let isLoopBlock = - allSteps[idx]?.stepId === "LOOP" && + allSteps[idx]?.stepId === ActionStepID.LOOP && allSteps.find(x => x.blockToLoop === block.id) // If the previous block was a loop block, decerement the index so the following @@ -345,7 +346,7 @@ -{#if stepId === "WEBHOOK"} +{#if stepId === TriggerStepID.WEBHOOK} {/if} diff --git a/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte b/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte index 19cea6db65..ee6b163a3e 100644 --- a/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte +++ b/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte @@ -3,6 +3,7 @@ import { ModalContent } from "@budibase/bbui" import { onMount } from "svelte" import WebhookDisplay from "../automation/Shared/WebhookDisplay.svelte" + import { TriggerStepID } from "constants/backend/automations" let webhookUrls = [] @@ -11,7 +12,7 @@ onMount(() => { webhookUrls = automations.map(automation => { const trigger = automation.definition.trigger - if (trigger?.stepId === "WEBHOOK" && trigger.inputs) { + if (trigger?.stepId === TriggerStepID.WEBHOOK && trigger.inputs) { return { type: "Automation", name: automation.name, diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte index fa32c88d65..4f661096c5 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte @@ -2,6 +2,7 @@ import { Select, Label, Input, Checkbox } from "@budibase/bbui" import { automationStore } from "builderStore" import SaveFields from "./SaveFields.svelte" + import { TriggerStepID } from "constants/backend/automations" export let parameters = {} export let bindings = [] @@ -16,7 +17,7 @@ : AUTOMATION_STATUS.NEW $: automations = $automationStore.automations - .filter(a => a.definition.trigger?.stepId === "APP") + .filter(a => a.definition.trigger?.stepId === TriggerStepID.APP) .map(automation => { const schema = Object.entries( automation.definition.trigger.inputs.fields || {} diff --git a/packages/builder/src/constants/backend/automations.js b/packages/builder/src/constants/backend/automations.js new file mode 100644 index 0000000000..e0cd5b6405 --- /dev/null +++ b/packages/builder/src/constants/backend/automations.js @@ -0,0 +1,28 @@ +export const TriggerStepID = { + ROW_SAVED: "ROW_SAVED", + ROW_UPDATED: "ROW_UPDATED", + ROW_DELETED: "ROW_DELETED", + WEBHOOK: "WEBHOOK", + APP: "APP", + CRON: "CRON", +} + +export const ActionStepID = { + SEND_EMAIL_SMTP: "SEND_EMAIL_SMTP", + CREATE_ROW: "CREATE_ROW", + UPDATE_ROW: "UPDATE_ROW", + DELETE_ROW: "DELETE_ROW", + OUTGOING_WEBHOOK: "OUTGOING_WEBHOOK", + EXECUTE_SCRIPT: "EXECUTE_SCRIPT", + EXECUTE_QUERY: "EXECUTE_QUERY", + SERVER_LOG: "SERVER_LOG", + DELAY: "DELAY", + FILTER: "FILTER", + QUERY_ROWS: "QUERY_ROWS", + LOOP: "LOOP", + // these used to be lowercase step IDs, maintain for backwards compat + discord: "discord", + slack: "slack", + zapier: "zapier", + integromat: "integromat", +} diff --git a/packages/server/src/utilities/security.js b/packages/server/src/utilities/security.js index de5b696553..a0d9c8d57f 100644 --- a/packages/server/src/utilities/security.js +++ b/packages/server/src/utilities/security.js @@ -13,6 +13,7 @@ const { DocumentTypes } = require("../db/utils") const CURRENTLY_SUPPORTED_LEVELS = [ PermissionLevels.WRITE, PermissionLevels.READ, + PermissionLevels.EXECUTE, ] exports.getPermissionType = resourceId => { From b7894d7f9e65ba492e5fcf8d2a3cd153af96065a Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 15 Jul 2022 17:45:35 +0100 Subject: [PATCH 5/5] Fixing test case. --- packages/server/src/api/routes/tests/permissions.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/permissions.spec.js b/packages/server/src/api/routes/tests/permissions.spec.js index 2b231dbe64..b416d1c0bf 100644 --- a/packages/server/src/api/routes/tests/permissions.spec.js +++ b/packages/server/src/api/routes/tests/permissions.spec.js @@ -37,9 +37,10 @@ describe("/permission", () => { .expect("Content-Type", /json/) .expect(200) expect(res.body).toBeDefined() - expect(res.body.length).toEqual(2) + expect(res.body.length).toEqual(3) expect(res.body).toContain("read") expect(res.body).toContain("write") + expect(res.body).toContain("execute") }) })