BREAKING CHANGE(smartmta): Rebrand package to @push.rocks/smartmta, add consolidated email security verification and IPC handler

This commit is contained in:
2026-02-10 16:25:55 +00:00
parent 199b9b79d2
commit 8293663619
17 changed files with 1183 additions and 383 deletions

View File

@@ -2,6 +2,7 @@ import * as plugins from '../plugins.js';
import * as paths from '../paths.js';
import { logger } from '../logger.js';
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.securitylogger.js';
import { RustSecurityBridge } from './classes.rustsecuritybridge.js';
import { LRUCache } from 'lru-cache';
/**
@@ -156,7 +157,7 @@ export class IPReputationChecker {
logger.log('warn', `Invalid IP address format: ${ip}`);
return this.createErrorResult(ip, 'Invalid IP address format');
}
// Check cache first
const cachedResult = this.reputationCache.get(ip);
if (cachedResult) {
@@ -166,8 +167,37 @@ export class IPReputationChecker {
});
return cachedResult;
}
// Initialize empty result
// Try Rust bridge first (parallel DNSBL via tokio — faster than Node sequential DNS)
const bridge = RustSecurityBridge.getInstance();
if (bridge.running) {
try {
const rustResult = await bridge.checkIpReputation(ip);
const result: IReputationResult = {
score: rustResult.score,
isSpam: rustResult.listed_count > 0,
isProxy: rustResult.ip_type === 'proxy',
isTor: rustResult.ip_type === 'tor',
isVPN: rustResult.ip_type === 'vpn',
blacklists: rustResult.dnsbl_results
.filter(d => d.listed)
.map(d => d.server),
timestamp: Date.now(),
};
this.reputationCache.set(ip, result);
if (this.options.enableLocalCache) {
this.saveCache().catch(error => {
logger.log('error', `Failed to save IP reputation cache: ${error.message}`);
});
}
this.logReputationCheck(ip, result);
return result;
} catch (err) {
logger.log('warn', `Rust IP reputation check failed, falling back to TS: ${(err as Error).message}`);
}
}
// Fallback: TypeScript DNSBL implementation
const result: IReputationResult = {
score: 100, // Start with perfect score
isSpam: false,
@@ -176,43 +206,43 @@ export class IPReputationChecker {
isVPN: false,
timestamp: Date.now()
};
// Check IP against DNS blacklists if enabled
if (this.options.enableDNSBL) {
const dnsblResult = await this.checkDNSBL(ip);
// Update result with DNSBL information
result.score -= dnsblResult.listCount * 10; // Subtract 10 points per blacklist
result.isSpam = dnsblResult.listCount > 0;
result.blacklists = dnsblResult.lists;
}
// Get additional IP information if enabled
if (this.options.enableIPInfo) {
const ipInfo = await this.getIPInfo(ip);
// Update result with IP info
result.country = ipInfo.country;
result.asn = ipInfo.asn;
result.org = ipInfo.org;
// Adjust score based on IP type
if (ipInfo.type === IPType.PROXY || ipInfo.type === IPType.TOR || ipInfo.type === IPType.VPN) {
result.score -= 30; // Subtract 30 points for proxies, Tor, VPNs
// Set proxy flags
result.isProxy = ipInfo.type === IPType.PROXY;
result.isTor = ipInfo.type === IPType.TOR;
result.isVPN = ipInfo.type === IPType.VPN;
}
}
// Ensure score is between 0 and 100
result.score = Math.max(0, Math.min(100, result.score));
// Update cache with result
this.reputationCache.set(ip, result);
// Save cache if enabled
if (this.options.enableLocalCache) {
// Fire and forget the save operation
@@ -220,17 +250,17 @@ export class IPReputationChecker {
logger.log('error', `Failed to save IP reputation cache: ${error.message}`);
});
}
// Log the reputation check
this.logReputationCheck(ip, result);
return result;
} catch (error) {
logger.log('error', `Error checking IP reputation for ${ip}: ${error.message}`, {
ip,
stack: error.stack
});
return this.createErrorResult(ip, error.message);
}
}