new structure
This commit is contained in:
parent
a70ae78a93
commit
d1426afec5
File diff suppressed because it is too large
Load Diff
|
|
@ -26,15 +26,15 @@ export class BlocklistChecker {
|
||||||
* Batch-check whether a sender is blocked for each recipient.
|
* Batch-check whether a sender is blocked for each recipient.
|
||||||
* Uses a single batch DynamoDB call for efficiency.
|
* Uses a single batch DynamoDB call for efficiency.
|
||||||
*/
|
*/
|
||||||
async batchCheckBlockedSenders(
|
async batchCheckBlockedSenders(
|
||||||
recipients: string[],
|
recipients: string[],
|
||||||
sender: string,
|
senders: string[], // <-- Geändert zu Array
|
||||||
workerName: string,
|
workerName: string,
|
||||||
): Promise<Record<string, boolean>> {
|
): Promise<Record<string, boolean>> {
|
||||||
const patternsByRecipient =
|
const patternsByRecipient = await this.dynamodb.batchGetBlockedPatterns(recipients);
|
||||||
await this.dynamodb.batchGetBlockedPatterns(recipients);
|
|
||||||
|
|
||||||
const senderClean = extractAddress(sender);
|
// Alle übergebenen Adressen bereinigen
|
||||||
|
const sendersClean = senders.map(s => extractAddress(s)).filter(Boolean);
|
||||||
const result: Record<string, boolean> = {};
|
const result: Record<string, boolean> = {};
|
||||||
|
|
||||||
for (const recipient of recipients) {
|
for (const recipient of recipients) {
|
||||||
|
|
@ -42,10 +42,10 @@ export class BlocklistChecker {
|
||||||
let isBlocked = false;
|
let isBlocked = false;
|
||||||
|
|
||||||
for (const pattern of patterns) {
|
for (const pattern of patterns) {
|
||||||
|
for (const senderClean of sendersClean) {
|
||||||
if (picomatch.isMatch(senderClean, pattern.toLowerCase())) {
|
if (picomatch.isMatch(senderClean, pattern.toLowerCase())) {
|
||||||
log(
|
log(
|
||||||
`⛔ BLOCKED: Sender ${senderClean} matches pattern '${pattern}' ` +
|
`⛔ BLOCKED: Sender ${senderClean} matches pattern '${pattern}' for inbox ${recipient}`,
|
||||||
`for inbox ${recipient}`,
|
|
||||||
'WARNING',
|
'WARNING',
|
||||||
workerName,
|
workerName,
|
||||||
);
|
);
|
||||||
|
|
@ -53,10 +53,10 @@ export class BlocklistChecker {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isBlocked) break;
|
||||||
|
}
|
||||||
result[recipient] = isBlocked;
|
result[recipient] = isBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
import { createTransport } from 'nodemailer';
|
import { createTransport } from 'nodemailer';
|
||||||
import type { ParsedMail } from 'mailparser';
|
import type { ParsedMail } from 'mailparser';
|
||||||
import type { DynamoDBHandler, EmailRule } from '../aws/dynamodb.js';
|
|
||||||
import type { SESHandler } from '../aws/ses.js';
|
import type { SESHandler } from '../aws/ses.js';
|
||||||
import { extractBodyParts } from './parser.js';
|
import { extractBodyParts } from './parser.js';
|
||||||
import { config, isInternalAddress } from '../config.js';
|
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
// Wir nutzen MailComposer direkt für das Erstellen der Raw Bytes
|
// Wir nutzen MailComposer direkt für das Erstellen der Raw Bytes
|
||||||
import MailComposer from 'nodemailer/lib/mail-composer/index.js';
|
import MailComposer from 'nodemailer/lib/mail-composer/index.js';
|
||||||
|
import { DynamoDBHandler, EmailRule } from '../aws/dynamodb.js';
|
||||||
|
import { config, isInternalAddress } from '../config.js';
|
||||||
|
|
||||||
export type MetricsCallback = (action: 'autoreply' | 'forward', domain: string) => void;
|
export type MetricsCallback = (action: 'autoreply' | 'forward', domain: string) => void;
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { config, loadDomains } from './config.js';
|
||||||
import { log } from './logger.js';
|
import { log } from './logger.js';
|
||||||
import { startMetricsServer, type MetricsCollector } from './metrics.js';
|
import { startMetricsServer, type MetricsCollector } from './metrics.js';
|
||||||
import { startHealthServer } from './health.js';
|
import { startHealthServer } from './health.js';
|
||||||
import { UnifiedWorker } from './worker/index.js';
|
import { UnifiedWorker } from './worker/unified-worker.js';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Banner
|
// Banner
|
||||||
|
|
@ -8,8 +8,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createTransport, type Transporter } from 'nodemailer';
|
import { createTransport, type Transporter } from 'nodemailer';
|
||||||
import { config } from '../config.js';
|
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
|
import { config } from '../config.js';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Permanent error detection
|
// Permanent error detection
|
||||||
|
|
@ -9,9 +9,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SQSHandler } from '../aws/sqs.js';
|
import type { SQSHandler } from '../aws/sqs.js';
|
||||||
import type { MessageProcessor } from './message-processor.js';
|
|
||||||
import type { MetricsCollector } from '../metrics.js';
|
import type { MetricsCollector } from '../metrics.js';
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
|
import { MessageProcessor } from './message-processor.js';
|
||||||
|
|
||||||
export interface DomainPollerStats {
|
export interface DomainPollerStats {
|
||||||
domain: string;
|
domain: string;
|
||||||
|
|
@ -19,15 +19,12 @@ import type { SESHandler } from '../aws/ses.js';
|
||||||
import type { DynamoDBHandler } from '../aws/dynamodb.js';
|
import type { DynamoDBHandler } from '../aws/dynamodb.js';
|
||||||
import type { EmailDelivery } from '../smtp/delivery.js';
|
import type { EmailDelivery } from '../smtp/delivery.js';
|
||||||
import type { MetricsCollector } from '../metrics.js';
|
import type { MetricsCollector } from '../metrics.js';
|
||||||
import {
|
|
||||||
parseEmail,
|
|
||||||
isProcessedByWorker,
|
|
||||||
BounceHandler,
|
|
||||||
RulesProcessor,
|
|
||||||
BlocklistChecker,
|
|
||||||
} from '../email/index.js';
|
|
||||||
import { domainToBucketName } from '../config.js';
|
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
|
import { BlocklistChecker } from '../email/blocklist.js';
|
||||||
|
import { BounceHandler } from '../email/bounce-handler.js';
|
||||||
|
import { parseEmail, isProcessedByWorker } from '../email/parser.js';
|
||||||
|
import { RulesProcessor } from '../email/rules-processor.js';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Processor
|
// Processor
|
||||||
|
|
@ -182,9 +179,17 @@ export class MessageProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. BLOCKLIST CHECK
|
// 6. BLOCKLIST CHECK
|
||||||
|
const sendersToCheck: string[] = [];
|
||||||
|
if (fromAddrFinal) sendersToCheck.push(fromAddrFinal);
|
||||||
|
|
||||||
|
const headerFrom = parsedFinal?.from?.text;
|
||||||
|
if (headerFrom && !sendersToCheck.includes(headerFrom)) {
|
||||||
|
sendersToCheck.push(headerFrom);
|
||||||
|
}
|
||||||
|
|
||||||
const blockedByRecipient = await this.blocklist.batchCheckBlockedSenders(
|
const blockedByRecipient = await this.blocklist.batchCheckBlockedSenders(
|
||||||
recipients,
|
recipients,
|
||||||
fromAddrFinal,
|
sendersToCheck, // <-- Array übergeben
|
||||||
workerName,
|
workerName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -8,13 +8,17 @@
|
||||||
* - Graceful shutdown
|
* - Graceful shutdown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { S3Handler, SQSHandler, SESHandler, DynamoDBHandler } from '../aws/index.js';
|
import { DynamoDBHandler } from '../aws/dynamodb';
|
||||||
import { EmailDelivery } from '../smtp/index.js';
|
import { S3Handler} from '../aws/s3.js';
|
||||||
|
import { SQSHandler} from '../aws/sqs.js'
|
||||||
|
import { SESHandler } from '../aws/ses';
|
||||||
|
import { EmailDelivery } from '../smtp/delivery.js';
|
||||||
import { MessageProcessor } from './message-processor.js';
|
import { MessageProcessor } from './message-processor.js';
|
||||||
import { DomainPoller, type DomainPollerStats } from './domain-poller.js';
|
import { DomainPoller, type DomainPollerStats } from './domain-poller.js';
|
||||||
import type { MetricsCollector } from '../metrics.js';
|
import type { MetricsCollector } from '../metrics.js';
|
||||||
import { log } from '../logger.js';
|
import { log } from '../logger.js';
|
||||||
|
|
||||||
|
|
||||||
export class UnifiedWorker {
|
export class UnifiedWorker {
|
||||||
private pollers: DomainPoller[] = [];
|
private pollers: DomainPoller[] = [];
|
||||||
private processor: MessageProcessor;
|
private processor: MessageProcessor;
|
||||||
Loading…
Reference in New Issue