Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix executions bulk deletion #5074

Merged
merged 1 commit into from
Jan 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 27 additions & 53 deletions packages/cli/src/executions/executions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import {
jsonParse,
Workflow,
} from 'n8n-workflow';
import { FindOperator, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm';
import { FindConditions, FindOperator, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm';
import * as ActiveExecutions from '@/ActiveExecutions';
import config from '@/config';
import { User } from '@/databases/entities/User';
import type { User } from '@/databases/entities/User';
import type { ExecutionEntity } from '@db/entities/ExecutionEntity';
import {
IExecutionFlattedResponse,
IExecutionResponse,
Expand Down Expand Up @@ -199,7 +200,7 @@ export class ExecutionsService {
.map(({ id }) => id),
);

const findWhere = { workflowId: In(sharedWorkflowIds) };
const findWhere: FindConditions<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };

const rangeQuery: string[] = [];
const rangeQueryParams: {
Expand Down Expand Up @@ -452,66 +453,39 @@ export class ExecutionsService {
throw new Error('Either "deleteBefore" or "ids" must be present in the request body');
}

const binaryDataManager = BinaryDataManager.getInstance();

// delete executions by date, if user may access the underlying workflows
const where: FindConditions<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };

if (deleteBefore) {
const filters: IDataObject = {
startedAt: LessThanOrEqual(deleteBefore),
};

let query = Db.collections.Execution.createQueryBuilder()
.select('id')
.where({
...filters,
workflowId: In(sharedWorkflowIds),
});

if (requestFilters) {
query = query.andWhere(requestFilters);
}

const executions = await query.getMany();

if (!executions.length) return;

const idsToDelete = executions.map(({ id }) => id);

await Promise.all(
idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)),
);

await Db.collections.Execution.delete({ id: In(idsToDelete) });

return;
}

// delete executions by IDs, if user may access the underlying workflows

if (ids) {
const executions = await Db.collections.Execution.find({
where: {
id: In(ids),
workflowId: In(sharedWorkflowIds),
},
});
// delete executions by date, if user may access the underlying workflows
where.startedAt = LessThanOrEqual(deleteBefore);
Object.assign(where, requestFilters);
} else if (ids) {
// delete executions by IDs, if user may access the underlying workflows
where.id = In(ids);
} else return;

const executions = await Db.collections.Execution.find({
select: ['id'],
where,
});

if (!executions.length) {
if (!executions.length) {
if (ids) {
LoggerProxy.error('Failed to delete an execution due to insufficient permissions', {
userId: req.user.id,
executionIds: ids,
});
return;
}
return;
}

const idsToDelete = executions.map(({ id }) => id);
const idsToDelete = executions.map(({ id }) => id);

await Promise.all(
idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)),
);
const binaryDataManager = BinaryDataManager.getInstance();
await Promise.all(
idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)),
);

await Db.collections.Execution.delete(idsToDelete);
}
await Db.collections.Execution.delete(idsToDelete);
}
}