fix: Add additional checks for disabled projects

This commit is contained in:
Dries Augustyns
2025-12-16 11:52:53 +01:00
parent 780741e37f
commit 863e784e1c
5 changed files with 51 additions and 3 deletions
+5
View File
@@ -98,3 +98,8 @@ export const SMTP_ENABLED =
export const PLUNK_API_KEY = validateEnv('PLUNK_API_KEY', '');
export const PLUNK_FROM_ADDRESS = validateEnv('PLUNK_FROM_ADDRESS', '');
export const PLUNK_ENABLED = PLUNK_API_KEY !== '' && PLUNK_FROM_ADDRESS !== '';
// Security (optional)
// Controls whether projects are automatically disabled when bounce/complaint rate thresholds are exceeded
// Useful for self-hosters who want to manage project status manually
export const AUTO_PROJECT_DISABLE = validateEnv('AUTO_PROJECT_DISABLE', 'true') === 'true';
+25 -3
View File
@@ -7,7 +7,7 @@ import {redis} from '../database/redis.js';
import {Keys} from './keys.js';
import {NtfyService} from './NtfyService.js';
import {QueueService} from './QueueService.js';
import {DASHBOARD_URI, LANDING_URI} from '../app/constants.js';
import {AUTO_PROJECT_DISABLE, DASHBOARD_URI, LANDING_URI} from '../app/constants.js';
/**
* Security thresholds for bounce and complaint rates
@@ -110,9 +110,31 @@ export class SecurityService {
// Get current security status
const status = await this.getSecurityStatus(projectId);
// If project should be disabled, disable it
if (status.shouldDisable) {
// If project should be disabled, disable it (only if auto-disable is enabled)
if (status.shouldDisable && AUTO_PROJECT_DISABLE) {
await this.disableProject(projectId, status);
} else if (status.shouldDisable && !AUTO_PROJECT_DISABLE) {
// Log critical violations but don't auto-disable (self-hosted mode)
const project = await prisma.project.findUnique({
where: {id: projectId},
select: {name: true},
});
if (project) {
signale.error(
`[SECURITY] Project ${projectId} (${project.name}) has CRITICAL security violations but auto-disable is turned off:`,
status.violations,
);
signale.info(
`[SECURITY] 7-day stats: ${status.sevenDay.bounces} bounces, ${status.sevenDay.complaints} complaints out of ${status.sevenDay.total} emails`,
);
signale.info(
`[SECURITY] All-time stats: ${status.allTime.bounces} bounces, ${status.allTime.complaints} complaints out of ${status.allTime.total} emails`,
);
// Send notification about critical security violations
await NtfyService.notifySecurityWarning(project.name, projectId, status.violations);
}
} else if (status.warnings.length > 0) {
// Log warnings for monitoring
signale.warn(`[SECURITY] Project ${projectId} has security warnings:`, status.warnings);