Complete email router implementation and documentation

- Cleaned up interface definitions to only include implemented features
- Updated readme.md with comprehensive route-based configuration examples
- Added common email routing patterns and troubleshooting guide
- Removed legacy DomainRouter and IDomainRule interfaces
- Updated all imports and exports to use new EmailRouter system
- Verified build and core functionality tests pass

The match/action pattern implementation is now complete and production-ready.
This commit is contained in:
2025-05-28 14:12:50 +00:00
parent 191c4160c1
commit e1a7b3e8f7
5 changed files with 240 additions and 483 deletions

342
readme.md
View File

@ -97,13 +97,17 @@ const router = new DcRouter({
emailConfig: {
ports: [25, 587, 465],
hostname: 'mail.example.com',
domainRules: [
routes: [
{
pattern: '*@example.com',
mode: 'mta',
mtaOptions: {
domain: 'example.com',
dkimSign: true
name: 'local-mail',
match: { recipients: '*@example.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'normal'
}
}
}
],
@ -203,10 +207,11 @@ interface IDcRouterOptions {
emailConfig?: {
ports: number[];
hostname: string;
domainRules: IDomainRule[];
defaultMode: EmailProcessingMode;
routes: IEmailRoute[]; // Route-based configuration
auth?: IAuthConfig;
tls?: ITlsConfig;
maxMessageSize?: number;
rateLimits?: IRateLimitConfig;
};
// DNS server configuration
@ -259,102 +264,186 @@ interface IRouteConfig {
## Email System
### Email Processing Modes
### Email Route Actions
#### **Forward Mode**
Routes emails to external SMTP servers with optional authentication and TLS.
#### **Forward Action**
Routes emails to external SMTP servers.
```typescript
{
pattern: '*@company.com',
mode: 'forward',
target: {
server: 'internal-mail.company.com',
port: 25,
useTls: true,
auth: {
username: 'relay-user',
password: 'relay-pass'
name: 'forward-to-internal',
match: { recipients: '*@company.com' },
action: {
type: 'forward',
forward: {
host: 'internal-mail.company.com',
port: 25,
auth: {
username: 'relay-user',
password: 'relay-pass'
},
addHeaders: {
'X-Forwarded-By': 'dcrouter'
}
}
}
}
```
#### **MTA Mode**
Full Mail Transfer Agent functionality with DKIM signing and delivery queues.
#### **Process Action**
Full Mail Transfer Agent functionality with scanning and delivery queues.
```typescript
{
pattern: '*@notifications.company.com',
mode: 'mta',
mtaOptions: {
domain: 'notifications.company.com',
dkimSign: true,
dkimOptions: {
domainName: 'notifications.company.com',
keySelector: 'mail',
privateKey: fs.readFileSync('./dkim-private.key', 'utf8')
},
queueConfig: {
maxRetries: 3,
retryDelay: 300000
name: 'process-notifications',
match: { recipients: '*@notifications.company.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'priority'
}
}
}
```
#### **Process Mode**
Store-and-forward with content scanning and transformations.
#### **Deliver Action**
Local delivery for mailbox storage.
```typescript
{
pattern: '*@marketing.company.com',
mode: 'process',
contentScanning: true,
scanners: [
{
type: 'spam',
threshold: 5.0,
action: 'tag'
},
{
type: 'virus',
action: 'reject'
name: 'deliver-local',
match: { recipients: '*@marketing.company.com' },
action: {
type: 'deliver'
}
}
```
#### **Reject Action**
Reject emails with custom SMTP responses.
```typescript
{
name: 'reject-spam',
match: {
senders: '*@spam-domain.com',
sizeRange: { min: 1000000 } // > 1MB
},
action: {
type: 'reject',
reject: {
code: 550,
message: 'Message rejected due to policy'
}
],
transformations: [
{
type: 'addHeader',
header: 'X-Marketing-Campaign',
value: 'auto-processed'
}
]
}
}
```
### Common Email Routing Patterns
#### **IP-Based Relay**
Allow internal networks to relay through the server:
```typescript
{
name: 'office-relay',
priority: 100,
match: { clientIp: ['192.168.0.0/16', '10.0.0.0/8'] },
action: {
type: 'forward',
forward: { host: 'internal-mail.company.com', port: 25 }
}
}
```
#### **Domain-Based Routing**
Route different domains to different servers:
```typescript
{
name: 'partner-domain',
match: { recipients: '*@partner.com' },
action: {
type: 'forward',
forward: { host: 'partner-mail.com', port: 587 }
}
}
```
#### **Authentication-Based Processing**
Different handling for authenticated vs unauthenticated senders:
```typescript
{
name: 'authenticated-users',
match: { authenticated: true },
action: {
type: 'process',
process: { scan: false, dkim: true, queue: 'priority' }
}
},
{
name: 'unauthenticated-reject',
match: { authenticated: false },
action: {
type: 'reject',
reject: { code: 550, message: 'Authentication required' }
}
}
```
#### **Content-Based Filtering**
Filter based on size, subject, or headers:
```typescript
{
name: 'large-email-reject',
match: { sizeRange: { min: 25000000 } }, // > 25MB
action: {
type: 'reject',
reject: { code: 552, message: 'Message too large' }
}
},
{
name: 'priority-emails',
match: {
headers: { 'X-Priority': 'high' },
subject: /urgent|emergency/i
},
action: {
type: 'process',
process: { queue: 'priority' }
}
}
```
### Email Security Features
#### **DKIM, SPF, DMARC**
#### **Route Matching Patterns**
**Glob Pattern Matching**
```typescript
// Automatic DKIM signing
const dkimOptions = {
domainName: 'example.com',
keySelector: 'mail',
privateKey: dkimPrivateKey,
algorithm: 'rsa-sha256'
};
// Email address patterns
match: { recipients: '*@example.com' } // All addresses at domain
match: { recipients: 'admin@*' } // Admin at any domain
match: { senders: ['*@trusted.com', '*@partner.com'] } // Multiple patterns
// SPF record validation
const spfPolicy = 'v=spf1 include:_spf.google.com ~all';
// CIDR IP matching
match: { clientIp: '192.168.0.0/16' } // Private subnet
match: { clientIp: ['10.0.0.0/8', '172.16.0.0/12'] } // Multiple ranges
// DMARC policy enforcement
const dmarcPolicy = {
policy: 'quarantine',
alignment: {
spf: 'relaxed',
dkim: 'strict'
// Header matching
match: {
headers: {
'X-Priority': 'high',
'Subject': /urgent|emergency/i
}
};
}
// Size and content matching
match: {
sizeRange: { min: 1000, max: 5000000 }, // 1KB to 5MB
hasAttachments: true,
subject: /invoice|receipt/i
}
```
#### **Content Scanning**
@ -630,50 +719,64 @@ const router = new DcRouter({
certPath: './certs/mail-cert.pem'
},
// Domain routing rules
domainRules: [
// Transactional emails via MTA
// Email routing rules
routes: [
// Relay from office network
{
pattern: '*@notifications.example.com',
mode: 'mta',
mtaOptions: {
domain: 'notifications.example.com',
dkimSign: true,
dkimOptions: {
domainName: 'notifications.example.com',
keySelector: 'mail',
privateKey: dkimKey
name: 'office-relay',
priority: 100,
match: { clientIp: '192.168.0.0/16' },
action: {
type: 'forward',
forward: {
host: 'internal-mail.example.com',
port: 25
}
}
},
// Transactional emails via processing
{
name: 'notifications',
priority: 50,
match: { recipients: '*@notifications.example.com' },
action: {
type: 'process',
process: {
scan: true,
dkim: true,
queue: 'priority'
}
}
},
// Internal emails forwarded to Exchange
{
pattern: '*@example.com',
mode: 'forward',
target: {
server: 'exchange.internal.example.com',
port: 25,
useTls: true
name: 'internal-mail',
priority: 25,
match: { recipients: '*@example.com' },
action: {
type: 'forward',
forward: {
host: 'exchange.internal.example.com',
port: 25
}
}
},
// Marketing emails with content scanning
// Default reject
{
pattern: '*@marketing.example.com',
mode: 'process',
contentScanning: true,
scanners: [
{ type: 'spam', threshold: 5.0, action: 'tag' },
{ type: 'virus', action: 'reject' }
]
name: 'default-reject',
match: { recipients: '*' },
action: {
type: 'reject',
reject: {
code: 550,
message: 'Relay denied'
}
}
}
],
// Default fallback
defaultMode: 'forward',
defaultServer: 'backup-mail.example.com',
defaultPort: 25
]
},
// DNS server for ACME challenges
@ -754,6 +857,33 @@ dig TXT mail._domainkey.your-domain.com
dig TXT your-domain.com
```
#### Email Routing Issues
**Route Not Matching**
- Check route priority order (higher priority = evaluated first)
- Verify glob patterns: `*@example.com` matches domain, `admin@*` matches user
- Test CIDR notation: `192.168.0.0/16` includes all 192.168.x.x addresses
- Confirm authentication state matches your expectations
**Common Route Patterns**
```typescript
// Debug route to log all traffic
{
name: 'debug-all',
priority: 1000,
match: { recipients: '*' },
action: { type: 'process', process: { scan: false } }
}
// Catch-all reject (should be lowest priority)
{
name: 'default-reject',
priority: 0,
match: { recipients: '*' },
action: { type: 'reject', reject: { code: 550, message: 'No route' } }
}
```
#### DNS Issues
```bash
# Test DNS server