feat(core): reimplement blocking workflow updates on interim changes (#4446)

* 📘 Update request type

* 📘 Update FE types

*  Adjust store

*  Set received hash

*  Send and load hash

*  Make helper more flexible

* 🗃️ Add new field to entity

* 🚨 Add check to endpoint

* 🧪 Add tests

*  Add `forceSave` flag

* 🐛 Fix workflow update failing on new workflow

* 🧪 Add more tests

*  Move check to `updateWorkflow()`

*  Refactor to accommodate latest changes

* 🧪 Refactor tests to keep them passing

*  Improve syntax
This commit is contained in:
Iván Ovejero
2022-10-31 10:35:24 +01:00
committed by GitHub
parent 263e6f30da
commit 46905fd2cb
12 changed files with 394 additions and 44 deletions

View File

@@ -183,6 +183,7 @@ EEWorkflowController.patch(
'/:id(\\d+)',
ResponseHelper.send(async (req: WorkflowRequest.Update) => {
const { id: workflowId } = req.params;
const forceSave = req.query.forceSave === 'true';
const updateData = new WorkflowEntity();
const { tags, ...rest } = req.body;
@@ -193,6 +194,7 @@ EEWorkflowController.patch(
updateData,
workflowId,
tags,
forceSave,
);
const { id, ...remainder } = updatedWorkflow;

View File

@@ -121,6 +121,7 @@ export class EEWorkflowsService extends WorkflowsService {
workflow: WorkflowEntity,
workflowId: string,
tags?: string[],
forceSave?: boolean,
): Promise<WorkflowEntity> {
const previousVersion = await EEWorkflowsService.get({ id: parseInt(workflowId, 10) });
if (!previousVersion) {
@@ -128,13 +129,13 @@ export class EEWorkflowsService extends WorkflowsService {
}
const allCredentials = await EECredentials.getAll(user);
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
workflow = WorkflowHelpers.validateWorkflowCredentialUsage(
workflow,
previousVersion,
allCredentials,
);
} catch (error) {
console.log(error);
throw new ResponseHelper.ResponseError(
'Invalid workflow credentials - make sure you have access to all credentials and try again.',
undefined,
@@ -142,6 +143,6 @@ export class EEWorkflowsService extends WorkflowsService {
);
}
return super.updateWorkflow(user, workflow, workflowId, tags);
return super.updateWorkflow(user, workflow, workflowId, tags, forceSave);
}
}

View File

@@ -52,6 +52,7 @@ export class WorkflowsService {
workflow: WorkflowEntity,
workflowId: string,
tags?: string[],
forceSave?: boolean,
): Promise<WorkflowEntity> {
const shared = await Db.collections.SharedWorkflow.findOne({
relations: ['workflow'],
@@ -74,6 +75,14 @@ export class WorkflowsService {
);
}
if (!forceSave && workflow.hash !== shared.workflow.hash) {
throw new ResponseHelper.ResponseError(
`Workflow ID ${workflowId} cannot be saved because it was changed by another user.`,
undefined,
400,
);
}
// check credentials for old format
await WorkflowHelpers.replaceInvalidCredentials(workflow);
@@ -118,7 +127,9 @@ export class WorkflowsService {
await validateEntity(workflow);
}
await Db.collections.Workflow.update(workflowId, workflow);
const { hash, ...rest } = workflow;
await Db.collections.Workflow.update(workflowId, rest);
if (tags && !config.getEnv('workflowTagsDisabled')) {
const tablePrefix = config.getEnv('database.tablePrefix');