perf(core): Lazyload security audit reporters (#7696)
Also converting to service. Followup to https://github.com/n8n-io/n8n/pull/7663
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import config from '@/config';
|
||||
import { audit } from '@/audit';
|
||||
import { CREDENTIALS_REPORT } from '@/audit/constants';
|
||||
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
|
||||
import { CREDENTIALS_REPORT } from '@/security-audit/constants';
|
||||
import { getRiskSection } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
@@ -11,8 +11,12 @@ import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { ExecutionDataRepository } from '@db/repositories/executionData.repository';
|
||||
|
||||
let securityAuditService: SecurityAuditService;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
securityAuditService = new SecurityAuditService(Container.get(WorkflowRepository));
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -54,7 +58,7 @@ test('should report credentials not in any use', async () => {
|
||||
Container.get(WorkflowRepository).save(workflowDetails),
|
||||
]);
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
const testAudit = await securityAuditService.run(['credentials']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -99,7 +103,7 @@ test('should report credentials not in active use', async () => {
|
||||
|
||||
await Container.get(WorkflowRepository).save(workflowDetails);
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
const testAudit = await securityAuditService.run(['credentials']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -167,7 +171,7 @@ test('should report credential in not recently executed workflow', async () => {
|
||||
workflowData: workflow,
|
||||
});
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
const testAudit = await securityAuditService.run(['credentials']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -236,7 +240,7 @@ test('should not report credentials in recently executed workflow', async () =>
|
||||
workflowData: workflow,
|
||||
});
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
const testAudit = await securityAuditService.run(['credentials']);
|
||||
|
||||
expect(testAudit).toBeEmptyArray();
|
||||
});
|
||||
@@ -1,18 +1,22 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { audit } from '@/audit';
|
||||
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
|
||||
import {
|
||||
DATABASE_REPORT,
|
||||
SQL_NODE_TYPES,
|
||||
SQL_NODE_TYPES_WITH_QUERY_PARAMS,
|
||||
} from '@/audit/constants';
|
||||
} from '@/security-audit/constants';
|
||||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
let securityAuditService: SecurityAuditService;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
securityAuditService = new SecurityAuditService(Container.get(WorkflowRepository));
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -56,7 +60,7 @@ test('should report expressions in queries', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['database']);
|
||||
const testAudit = await securityAuditService.run(['database']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -111,7 +115,7 @@ test('should report expressions in query params', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['database']);
|
||||
const testAudit = await securityAuditService.run(['database']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -163,7 +167,7 @@ test('should report unused query params', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['database']);
|
||||
const testAudit = await securityAuditService.run(['database']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -183,7 +187,7 @@ test('should report unused query params', async () => {
|
||||
test('should not report non-database node', async () => {
|
||||
await saveManualTriggerWorkflow();
|
||||
|
||||
const testAudit = await audit(['database']);
|
||||
const testAudit = await securityAuditService.run(['database']);
|
||||
|
||||
expect(testAudit).toBeEmptyArray();
|
||||
});
|
||||
@@ -1,13 +1,17 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { audit } from '@/audit';
|
||||
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/constants';
|
||||
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
|
||||
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/security-audit/constants';
|
||||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
let securityAuditService: SecurityAuditService;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
securityAuditService = new SecurityAuditService(Container.get(WorkflowRepository));
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -48,7 +52,7 @@ test('should report filesystem interaction nodes', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['filesystem']);
|
||||
const testAudit = await securityAuditService.run(['filesystem']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -68,7 +72,7 @@ test('should report filesystem interaction nodes', async () => {
|
||||
test('should not report non-filesystem-interaction node', async () => {
|
||||
await saveManualTriggerWorkflow();
|
||||
|
||||
const testAudit = await audit(['filesystem']);
|
||||
const testAudit = await securityAuditService.run(['filesystem']);
|
||||
|
||||
expect(testAudit).toBeEmptyArray();
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { audit } from '@/audit';
|
||||
import { INSTANCE_REPORT, WEBHOOK_VALIDATOR_NODE_TYPES } from '@/audit/constants';
|
||||
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
|
||||
import { INSTANCE_REPORT, WEBHOOK_VALIDATOR_NODE_TYPES } from '@/security-audit/constants';
|
||||
import {
|
||||
getRiskSection,
|
||||
saveManualTriggerWorkflow,
|
||||
@@ -9,15 +9,19 @@ import {
|
||||
simulateUpToDateInstance,
|
||||
} from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { toReportTitle } from '@/audit/utils';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
import config from '@/config';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
let securityAuditService: SecurityAuditService;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
securityAuditService = new SecurityAuditService(Container.get(WorkflowRepository));
|
||||
|
||||
simulateUpToDateInstance();
|
||||
});
|
||||
|
||||
@@ -56,7 +60,7 @@ test('should report webhook lacking authentication', async () => {
|
||||
|
||||
await Container.get(WorkflowRepository).save(details);
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -103,10 +107,12 @@ test('should not report webhooks having basic or header auth', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
if (Array.isArray(testAudit)) fail('audit is empty');
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
|
||||
if (Array.isArray(testAudit)) fail('Audit is empty');
|
||||
|
||||
const report = testAudit[toReportTitle('instance')];
|
||||
|
||||
if (!report) {
|
||||
fail('Expected test audit to have instance risk report');
|
||||
}
|
||||
@@ -164,7 +170,7 @@ test('should not report webhooks validated by direct children', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
if (Array.isArray(testAudit)) fail('audit is empty');
|
||||
|
||||
const report = testAudit[toReportTitle('instance')];
|
||||
@@ -180,7 +186,7 @@ test('should not report webhooks validated by direct children', async () => {
|
||||
test('should not report non-webhook node', async () => {
|
||||
await saveManualTriggerWorkflow();
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
if (Array.isArray(testAudit)) fail('audit is empty');
|
||||
|
||||
const report = testAudit[toReportTitle('instance')];
|
||||
@@ -197,7 +203,7 @@ test('should not report non-webhook node', async () => {
|
||||
test('should report outdated instance when outdated', async () => {
|
||||
simulateOutdatedInstanceOnce();
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -215,7 +221,7 @@ test('should report outdated instance when outdated', async () => {
|
||||
});
|
||||
|
||||
test('should not report outdated instance when up to date', async () => {
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
if (Array.isArray(testAudit)) fail('audit is empty');
|
||||
|
||||
const report = testAudit[toReportTitle('instance')];
|
||||
@@ -231,7 +237,7 @@ test('should not report outdated instance when up to date', async () => {
|
||||
test('should report security settings', async () => {
|
||||
config.set('diagnostics.enabled', true);
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
const testAudit = await securityAuditService.run(['instance']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -1,8 +1,8 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Container } from 'typedi';
|
||||
import { audit } from '@/audit';
|
||||
import { OFFICIAL_RISKY_NODE_TYPES, NODES_REPORT } from '@/audit/constants';
|
||||
import { toReportTitle } from '@/audit/utils';
|
||||
import { SecurityAuditService } from '@/security-audit/SecurityAudit.service';
|
||||
import { OFFICIAL_RISKY_NODE_TYPES, NODES_REPORT } from '@/security-audit/constants';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { CommunityPackagesService } from '@/services/communityPackages.service';
|
||||
@@ -18,8 +18,12 @@ mockInstance(NodeTypes);
|
||||
const communityPackagesService = mockInstance(CommunityPackagesService);
|
||||
Container.set(CommunityPackagesService, communityPackagesService);
|
||||
|
||||
let securityAuditService: SecurityAuditService;
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
||||
securityAuditService = new SecurityAuditService(Container.get(WorkflowRepository));
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -59,7 +63,7 @@ test('should report risky official nodes', async () => {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const testAudit = await audit(['nodes']);
|
||||
const testAudit = await securityAuditService.run(['nodes']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -80,10 +84,12 @@ test('should not report non-risky official nodes', async () => {
|
||||
communityPackagesService.getAllInstalledPackages.mockResolvedValue(MOCK_PACKAGE);
|
||||
await saveManualTriggerWorkflow();
|
||||
|
||||
const testAudit = await audit(['nodes']);
|
||||
const testAudit = await securityAuditService.run(['nodes']);
|
||||
|
||||
if (Array.isArray(testAudit)) return;
|
||||
|
||||
const report = testAudit[toReportTitle('nodes')];
|
||||
|
||||
if (!report) return;
|
||||
|
||||
for (const section of report.sections) {
|
||||
@@ -94,7 +100,7 @@ test('should not report non-risky official nodes', async () => {
|
||||
test('should report community nodes', async () => {
|
||||
communityPackagesService.getAllInstalledPackages.mockResolvedValue(MOCK_PACKAGE);
|
||||
|
||||
const testAudit = await audit(['nodes']);
|
||||
const testAudit = await securityAuditService.run(['nodes']);
|
||||
|
||||
const section = getRiskSection(
|
||||
testAudit,
|
||||
@@ -1,9 +1,9 @@
|
||||
import nock from 'nock';
|
||||
import config from '@/config';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { toReportTitle } from '@/audit/utils';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
import * as constants from '@/constants';
|
||||
import type { Risk } from '@/audit/types';
|
||||
import type { Risk } from '@/security-audit/types';
|
||||
import type { InstalledNodes } from '@db/entities/InstalledNodes';
|
||||
import type { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
Reference in New Issue
Block a user