fix: Add additional checks for disabled projects
This commit is contained in:
@@ -121,6 +121,16 @@ SMTP_DOMAIN=smtp.example.com
|
||||
# PLUNK_API_KEY=
|
||||
# PLUNK_FROM_ADDRESS=
|
||||
|
||||
# ========================================
|
||||
# OPTIONAL: Security Settings
|
||||
# ========================================
|
||||
# Controls whether projects are automatically disabled when bounce/complaint rate thresholds are exceeded
|
||||
# When enabled (default), projects exceeding security limits will be automatically suspended
|
||||
# When disabled, violations will be logged and notifications sent, but projects won't be auto-disabled
|
||||
# Recommended for self-hosters: false (manage project status manually)
|
||||
# Default: true
|
||||
# AUTO_PROJECT_DISABLE=false
|
||||
|
||||
# ========================================
|
||||
# ADVANCED (rarely needed)
|
||||
# ========================================
|
||||
|
||||
@@ -76,3 +76,11 @@ STRIPE_WEBHOOK_SECRET=
|
||||
STRIPE_PRICE_ONBOARDING= # Optional: One-time onboarding fee price ID (e.g., price_xxxxx)
|
||||
STRIPE_PRICE_EMAIL_USAGE= # Required: Metered price ID for pay-per-email billing
|
||||
STRIPE_METER_EVENT_NAME=emails # Meter event name (API key from your Stripe meter, default: emails)
|
||||
|
||||
# ==============================================================================
|
||||
# Security (Optional)
|
||||
# ==============================================================================
|
||||
# Controls whether projects are automatically disabled when bounce/complaint rate thresholds are exceeded
|
||||
# Set to 'false' to disable automatic project suspension (useful for self-hosters who manage manually)
|
||||
# Default: true (automatic project disabling enabled)
|
||||
# AUTO_PROJECT_DISABLE=true
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -187,6 +187,9 @@ services:
|
||||
PLUNK_API_KEY: ${PLUNK_API_KEY:-}
|
||||
PLUNK_FROM_ADDRESS: ${PLUNK_FROM_ADDRESS:-}
|
||||
|
||||
# Security
|
||||
AUTO_PROJECT_DISABLE: ${AUTO_PROJECT_DISABLE:-false}
|
||||
|
||||
volumes:
|
||||
# Persistent storage for application data
|
||||
- plunk_data:/app/data
|
||||
|
||||
Reference in New Issue
Block a user