diff --git a/packages/backend/src/graphql/mutations/create-flow.ts b/packages/backend/src/graphql/mutations/create-flow.ts index 5e015fe2..30c0968f 100644 --- a/packages/backend/src/graphql/mutations/create-flow.ts +++ b/packages/backend/src/graphql/mutations/create-flow.ts @@ -1,3 +1,4 @@ +import App from '../../models/app'; import Step from '../../models/step'; import Context from '../../types/express/context'; @@ -16,15 +17,20 @@ const createFlow = async ( const connectionId = params?.input?.connectionId; const appKey = params?.input?.triggerAppKey; + await App.findOneByKey(appKey); + const flow = await context.currentUser.$relatedQuery('flows').insert({ name: 'Name your flow', }); if (connectionId) { - await context.currentUser + const hasConnection = await context.currentUser .$relatedQuery('connections') - .findById(connectionId) - .throwIfNotFound(); + .findById(connectionId); + + if (!hasConnection) { + throw new Error('The connection does not exist!'); + } } await Step.query().insert({ diff --git a/packages/backend/src/graphql/mutations/create-step.ts b/packages/backend/src/graphql/mutations/create-step.ts index 80ba0a1c..7ee065d4 100644 --- a/packages/backend/src/graphql/mutations/create-step.ts +++ b/packages/backend/src/graphql/mutations/create-step.ts @@ -1,3 +1,4 @@ +import App from '../../models/app'; import Context from '../../types/express/context'; type Params = { @@ -23,6 +24,14 @@ const createStep = async ( ) => { const { input } = params; + if (input.appKey && input.key) { + await App.checkAppAndAction(input.appKey, input.key); + } + + if (input.appKey && !input.key) { + await App.findOneByKey(input.appKey); + } + const flow = await context.currentUser .$relatedQuery('flows') .findOne({ diff --git a/packages/backend/src/graphql/mutations/execute-flow.ts b/packages/backend/src/graphql/mutations/execute-flow.ts index 5caeaa77..6b25960b 100644 --- a/packages/backend/src/graphql/mutations/execute-flow.ts +++ b/packages/backend/src/graphql/mutations/execute-flow.ts @@ -13,11 +13,13 @@ const executeFlow = async ( context: Context ) => { const { stepId } = params.input; - const { executionStep } = await testRun({ stepId }); const untilStep = await context.currentUser .$relatedQuery('steps') - .findById(stepId); + .findById(stepId) + .throwIfNotFound(); + + const { executionStep } = await testRun({ stepId }); if (executionStep.isFailed) { throw new Error(JSON.stringify(executionStep.errorDetails)); diff --git a/packages/backend/src/graphql/mutations/update-step.ts b/packages/backend/src/graphql/mutations/update-step.ts index 0c5adbed..11398287 100644 --- a/packages/backend/src/graphql/mutations/update-step.ts +++ b/packages/backend/src/graphql/mutations/update-step.ts @@ -1,4 +1,5 @@ import { IJSONObject } from '@automatisch/types'; +import App from '../../models/app'; import Step from '../../models/step'; import Context from '../../types/express/context'; @@ -32,6 +33,24 @@ const updateStep = async ( }) .throwIfNotFound(); + if (input.connection.id) { + const hasConnection = await context.currentUser + .$relatedQuery('connections') + .findById(input.connection?.id); + + if (!hasConnection) { + throw new Error('The connection does not exist!'); + } + } + + if (step.isTrigger) { + await App.checkAppAndTrigger(input.appKey, input.key); + } + + if (step.isAction) { + await App.checkAppAndAction(input.appKey, input.key); + } + step = await Step.query() .patchAndFetchById(input.id, { key: input.key, diff --git a/packages/backend/src/helpers/get-app.ts b/packages/backend/src/helpers/get-app.ts index 52f73894..436965d4 100644 --- a/packages/backend/src/helpers/get-app.ts +++ b/packages/backend/src/helpers/get-app.ts @@ -22,7 +22,11 @@ const apps = fs return apps; }, {} as TApps); -async function getDefaultExport(appKey: string) { +async function getAppDefaultExport(appKey: string) { + if (!Object.prototype.hasOwnProperty.call(apps, appKey)) { + throw new Error(`An application with the "${appKey}" key couldn't be found.`); + } + return (await apps[appKey]).default; } @@ -31,7 +35,7 @@ function stripFunctions(data: C): C { } const getApp = async (appKey: string, stripFuncs = true) => { - let appData: IApp = cloneDeep(await getDefaultExport(appKey)); + let appData: IApp = cloneDeep(await getAppDefaultExport(appKey)); if (appData.auth) { appData = addAuthenticationSteps(appData); diff --git a/packages/backend/src/models/app.ts b/packages/backend/src/models/app.ts index 998566a1..d50d3426 100644 --- a/packages/backend/src/models/app.ts +++ b/packages/backend/src/models/app.ts @@ -36,6 +36,26 @@ class App { return appInfoConverter(rawAppData); } + + static async checkAppAndAction(appKey: string, actionKey: string): Promise { + const app = await this.findOneByKey(appKey); + + const hasAction = app.actions?.find(action => action.key === actionKey); + + if (!hasAction) { + throw new Error(`${app.name} does not have an action with the "${actionKey}" key!`); + } + } + + static async checkAppAndTrigger(appKey: string, triggerKey: string): Promise { + const app = await this.findOneByKey(appKey); + + const hasTrigger = app.triggers?.find(trigger => trigger.key === triggerKey); + + if (!hasTrigger) { + throw new Error(`${app.name} does not have a trigger with the "${triggerKey}" key!`); + } + } } export default App;