mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Reduce memory usage in credentials risk auditing (#7663)
This commit is contained in:
parent
5edf722209
commit
9fd6319583
|
@ -1,13 +1,16 @@
|
||||||
import type { FindOperator } from 'typeorm';
|
import { In, MoreThanOrEqual } from 'typeorm';
|
||||||
import { MoreThanOrEqual } from 'typeorm';
|
|
||||||
import { DateUtils } from 'typeorm/util/DateUtils';
|
import { DateUtils } from 'typeorm/util/DateUtils';
|
||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import * as Db from '@/Db';
|
import type { IWorkflowBase } from 'n8n-workflow';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
import { CREDENTIALS_REPORT } from '@/audit/constants';
|
import { CREDENTIALS_REPORT } from '@/audit/constants';
|
||||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
|
||||||
import type { Risk } from '@/audit/types';
|
import type { Risk } from '@/audit/types';
|
||||||
import { ExecutionRepository } from '@db/repositories';
|
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||||
|
import {
|
||||||
|
CredentialsRepository,
|
||||||
|
ExecutionDataRepository,
|
||||||
|
ExecutionRepository,
|
||||||
|
} from '@db/repositories';
|
||||||
|
|
||||||
async function getAllCredsInUse(workflows: WorkflowEntity[]) {
|
async function getAllCredsInUse(workflows: WorkflowEntity[]) {
|
||||||
const credsInAnyUse = new Set<string>();
|
const credsInAnyUse = new Set<string>();
|
||||||
|
@ -34,36 +37,43 @@ async function getAllCredsInUse(workflows: WorkflowEntity[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllExistingCreds() {
|
async function getAllExistingCreds() {
|
||||||
const credentials = await Db.collections.Credentials.find({ select: ['id', 'name'] });
|
const credentials = await Container.get(CredentialsRepository).find({ select: ['id', 'name'] });
|
||||||
|
|
||||||
return credentials.map(({ id, name }) => ({ kind: 'credential' as const, id, name }));
|
return credentials.map(({ id, name }) => ({ kind: 'credential' as const, id, name }));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getExecutionsInPastDays(days: number) {
|
async function getExecutedWorkflowsInPastDays(days: number): Promise<IWorkflowBase[]> {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
date.setDate(date.getDate() - days);
|
date.setDate(date.getDate() - days);
|
||||||
|
|
||||||
const utcDate = DateUtils.mixedDateToUtcDatetimeString(date) as string;
|
const executionIds = await Container.get(ExecutionRepository)
|
||||||
|
.find({
|
||||||
return Container.get(ExecutionRepository).findMultipleExecutions(
|
select: ['id'],
|
||||||
{
|
|
||||||
where: {
|
where: {
|
||||||
startedAt: MoreThanOrEqual(utcDate) as unknown as FindOperator<Date>,
|
startedAt: MoreThanOrEqual(DateUtils.mixedDateToUtcDatetimeString(date) as Date),
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
{ includeData: true },
|
.then((executions) => executions.map(({ id }) => id));
|
||||||
);
|
|
||||||
|
return Container.get(ExecutionDataRepository)
|
||||||
|
.find({
|
||||||
|
select: ['workflowData'],
|
||||||
|
where: {
|
||||||
|
executionId: In(executionIds),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((executionData) => executionData.map(({ workflowData }) => workflowData));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return IDs of credentials in workflows executed in the past n days.
|
* Return IDs of credentials in workflows executed in the past n days.
|
||||||
*/
|
*/
|
||||||
async function getCredsInRecentlyExecutedWorkflows(days: number) {
|
async function getCredsInRecentlyExecutedWorkflows(days: number) {
|
||||||
const recentExecutions = await getExecutionsInPastDays(days);
|
const executedWorkflows = await getExecutedWorkflowsInPastDays(days);
|
||||||
|
|
||||||
return recentExecutions.reduce<Set<string>>((acc, execution) => {
|
return executedWorkflows.reduce<Set<string>>((acc, { nodes }) => {
|
||||||
execution.workflowData?.nodes.forEach((node) => {
|
nodes.forEach((node) => {
|
||||||
if (node.credentials) {
|
if (node.credentials) {
|
||||||
Object.values(node.credentials).forEach((c) => {
|
Object.values(node.credentials).forEach((c) => {
|
||||||
if (c.id) acc.add(c.id);
|
if (c.id) acc.add(c.id);
|
||||||
|
|
Loading…
Reference in a new issue