feat(ts_interfaces): add TypedRequest interfaces for admin and configuration requests
fix(dependencies): include @api.global/typedrequest-interfaces in package.json chore(docs): create OpsServer implementation plan in readme.opsserver.md
This commit is contained in:
@ -25,6 +25,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@api.global/typedrequest": "^3.0.19",
|
"@api.global/typedrequest": "^3.0.19",
|
||||||
|
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||||
"@api.global/typedserver": "^3.0.74",
|
"@api.global/typedserver": "^3.0.74",
|
||||||
"@api.global/typedsocket": "^3.0.0",
|
"@api.global/typedsocket": "^3.0.0",
|
||||||
"@apiclient.xyz/cloudflare": "^6.4.1",
|
"@apiclient.xyz/cloudflare": "^6.4.1",
|
||||||
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@ -11,6 +11,9 @@ importers:
|
|||||||
'@api.global/typedrequest':
|
'@api.global/typedrequest':
|
||||||
specifier: ^3.0.19
|
specifier: ^3.0.19
|
||||||
version: 3.1.10
|
version: 3.1.10
|
||||||
|
'@api.global/typedrequest-interfaces':
|
||||||
|
specifier: ^3.0.19
|
||||||
|
version: 3.0.19
|
||||||
'@api.global/typedserver':
|
'@api.global/typedserver':
|
||||||
specifier: ^3.0.74
|
specifier: ^3.0.74
|
||||||
version: 3.0.74
|
version: 3.0.74
|
||||||
@ -5353,8 +5356,10 @@ snapshots:
|
|||||||
'@push.rocks/taskbuffer': 3.1.7
|
'@push.rocks/taskbuffer': 3.1.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@nuxt/kit'
|
- '@nuxt/kit'
|
||||||
|
- bufferutil
|
||||||
- react
|
- react
|
||||||
- supports-color
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@hapi/hoek@9.3.0': {}
|
'@hapi/hoek@9.3.0': {}
|
||||||
@ -5695,7 +5700,6 @@ snapshots:
|
|||||||
- '@mongodb-js/zstd'
|
- '@mongodb-js/zstd'
|
||||||
- '@nuxt/kit'
|
- '@nuxt/kit'
|
||||||
- aws-crt
|
- aws-crt
|
||||||
- bufferutil
|
|
||||||
- encoding
|
- encoding
|
||||||
- gcp-metadata
|
- gcp-metadata
|
||||||
- kerberos
|
- kerberos
|
||||||
@ -5704,7 +5708,6 @@ snapshots:
|
|||||||
- snappy
|
- snappy
|
||||||
- socks
|
- socks
|
||||||
- supports-color
|
- supports-color
|
||||||
- utf-8-validate
|
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@push.rocks/smartarchive@3.0.8':
|
'@push.rocks/smartarchive@3.0.8':
|
||||||
|
@ -1,494 +0,0 @@
|
|||||||
# DCRouter Email Configuration Example
|
|
||||||
|
|
||||||
This document provides a comprehensive example of configuring the UnifiedEmailServer in DCRouter for various email routing scenarios.
|
|
||||||
|
|
||||||
## Basic Configuration
|
|
||||||
|
|
||||||
Here's a complete example of a email configuration for the UnifiedEmailServer:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { IEmailConfig, EmailProcessingMode, IDomainRule } from './ts/config/email.config.js';
|
|
||||||
|
|
||||||
const emailConfig: IEmailConfig = {
|
|
||||||
// Basic server settings
|
|
||||||
useEmail: true,
|
|
||||||
behindSmartProxy: false,
|
|
||||||
hostname: "mail.example.com",
|
|
||||||
ports: [25, 587, 465],
|
|
||||||
|
|
||||||
// Default processing settings
|
|
||||||
defaultMode: "forward" as EmailProcessingMode,
|
|
||||||
defaultServer: "smtp.internal-relay.example.com",
|
|
||||||
defaultPort: 25,
|
|
||||||
defaultTls: true,
|
|
||||||
|
|
||||||
// TLS configuration
|
|
||||||
tls: {
|
|
||||||
certPath: "/path/to/tls/certificate.pem",
|
|
||||||
keyPath: "/path/to/tls/key.pem",
|
|
||||||
caPath: "/path/to/tls/ca.pem",
|
|
||||||
minVersion: "TLSv1.2",
|
|
||||||
ciphers: "HIGH:!aNULL:!MD5:!RC4"
|
|
||||||
},
|
|
||||||
|
|
||||||
// Email size and connection limits
|
|
||||||
maxMessageSize: 25 * 1024 * 1024, // 25MB
|
|
||||||
|
|
||||||
// Authentication settings
|
|
||||||
auth: {
|
|
||||||
required: true,
|
|
||||||
methods: ["PLAIN", "LOGIN"],
|
|
||||||
users: [
|
|
||||||
{ username: "user1", password: "securepassword1" },
|
|
||||||
{ username: "user2", password: "securepassword2" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Domain routing rules
|
|
||||||
domainRules: [
|
|
||||||
// Process emails for your primary domain via MTA
|
|
||||||
{
|
|
||||||
pattern: "*@example.com",
|
|
||||||
mode: "mta" as EmailProcessingMode,
|
|
||||||
mtaOptions: {
|
|
||||||
domain: "example.com",
|
|
||||||
dkimSign: true,
|
|
||||||
dkimOptions: {
|
|
||||||
domainName: "example.com",
|
|
||||||
keySelector: "mail"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Forward support emails to help desk
|
|
||||||
{
|
|
||||||
pattern: "*@support.example.com",
|
|
||||||
mode: "forward" as EmailProcessingMode,
|
|
||||||
target: {
|
|
||||||
server: "helpdesk.example.com",
|
|
||||||
port: 25,
|
|
||||||
useTls: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Scan marketing emails for content and attachments
|
|
||||||
{
|
|
||||||
pattern: "*@marketing.example.com",
|
|
||||||
mode: "process" as EmailProcessingMode,
|
|
||||||
contentScanning: true,
|
|
||||||
scanners: [
|
|
||||||
{
|
|
||||||
type: "attachment",
|
|
||||||
action: "reject",
|
|
||||||
blockedExtensions: [".exe", ".zip", ".js", ".vbs", ".bat"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "spam",
|
|
||||||
threshold: 5.0,
|
|
||||||
action: "tag"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
transformations: [
|
|
||||||
{
|
|
||||||
type: "addHeader",
|
|
||||||
header: "X-Scanned-By",
|
|
||||||
value: "DCRouter Content Scanner"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Forward all other emails to a backup server
|
|
||||||
{
|
|
||||||
pattern: "*@*",
|
|
||||||
mode: "forward" as EmailProcessingMode,
|
|
||||||
target: {
|
|
||||||
server: "backup-smtp.example.com",
|
|
||||||
port: 587,
|
|
||||||
useTls: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
// Queue configuration
|
|
||||||
queue: {
|
|
||||||
storageType: "memory",
|
|
||||||
ttl: 86400000, // 24 hours
|
|
||||||
maxItems: 10000,
|
|
||||||
checkInterval: 60000 // 1 minute
|
|
||||||
},
|
|
||||||
|
|
||||||
// Template configuration
|
|
||||||
templateConfig: {
|
|
||||||
from: "noreply@example.com",
|
|
||||||
replyTo: "support@example.com",
|
|
||||||
footerHtml: "<p>This is an automated message from Example Inc.</p>",
|
|
||||||
footerText: "This is an automated message from Example Inc."
|
|
||||||
},
|
|
||||||
|
|
||||||
// IP warmup configuration
|
|
||||||
serverConfig: {
|
|
||||||
delivery: {
|
|
||||||
concurrency: 10,
|
|
||||||
rateLimit: {
|
|
||||||
rate: 100,
|
|
||||||
interval: 60000 // 1 minute
|
|
||||||
},
|
|
||||||
retries: {
|
|
||||||
max: 3,
|
|
||||||
delay: 300000, // 5 minutes
|
|
||||||
useBackoff: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
security: {
|
|
||||||
useDkim: true,
|
|
||||||
verifyDkim: true,
|
|
||||||
verifySpf: true,
|
|
||||||
verifyDmarc: true,
|
|
||||||
enforceDmarc: true,
|
|
||||||
useTls: true,
|
|
||||||
requireValidCerts: true,
|
|
||||||
securityLogLevel: "info",
|
|
||||||
checkIPReputation: true,
|
|
||||||
scanContent: true,
|
|
||||||
maliciousContentAction: "tag",
|
|
||||||
threatScoreThreshold: 7.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Initializing the UnifiedEmailServer
|
|
||||||
|
|
||||||
Here's how to initialize the UnifiedEmailServer with the configuration:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { UnifiedEmailServer, IUnifiedEmailServerOptions } from './ts/mail/routing/classes.unified.email.server.js';
|
|
||||||
|
|
||||||
// Convert EmailConfig to UnifiedEmailServerOptions
|
|
||||||
const serverOptions: IUnifiedEmailServerOptions = {
|
|
||||||
ports: emailConfig.ports || [25],
|
|
||||||
hostname: emailConfig.hostname || 'localhost',
|
|
||||||
banner: `${emailConfig.hostname} ESMTP DCRouter`,
|
|
||||||
|
|
||||||
// Authentication
|
|
||||||
auth: emailConfig.auth,
|
|
||||||
|
|
||||||
// TLS
|
|
||||||
tls: emailConfig.tls,
|
|
||||||
|
|
||||||
// Message limits
|
|
||||||
maxMessageSize: emailConfig.maxMessageSize || 10 * 1024 * 1024, // 10MB default
|
|
||||||
maxClients: 100,
|
|
||||||
|
|
||||||
// Domain routing
|
|
||||||
domainRules: emailConfig.domainRules || [],
|
|
||||||
defaultMode: emailConfig.defaultMode || 'forward',
|
|
||||||
defaultServer: emailConfig.defaultServer,
|
|
||||||
defaultPort: emailConfig.defaultPort,
|
|
||||||
defaultTls: emailConfig.defaultTls,
|
|
||||||
|
|
||||||
// Deliverability options
|
|
||||||
ipWarmupConfig: {
|
|
||||||
enabled: true,
|
|
||||||
ipAddresses: ['198.51.100.1', '198.51.100.2', '198.51.100.3'],
|
|
||||||
targetDomains: ['gmail.com', 'yahoo.com', 'outlook.com'],
|
|
||||||
allocationPolicy: 'balanced'
|
|
||||||
},
|
|
||||||
|
|
||||||
reputationMonitorConfig: {
|
|
||||||
enabled: true,
|
|
||||||
domains: ['example.com', 'marketing.example.com'],
|
|
||||||
alertThresholds: {
|
|
||||||
bounceRate: 0.05, // 5%
|
|
||||||
complaintRate: 0.001 // 0.1%
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create and start the server
|
|
||||||
const emailServer = new UnifiedEmailServer(serverOptions);
|
|
||||||
emailServer.start().then(() => {
|
|
||||||
console.log('UnifiedEmailServer started successfully');
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error('Failed to start UnifiedEmailServer:', error);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use Case Examples
|
|
||||||
|
|
||||||
### 1. Forwarding Email Gateway (SMTP Proxy)
|
|
||||||
|
|
||||||
Configure DCRouter to forward emails for specific domains to internal mail servers:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const forwardingRules: IDomainRule[] = [
|
|
||||||
// Main corporate domain - forward to Exchange
|
|
||||||
{
|
|
||||||
pattern: "*@corp.example.com",
|
|
||||||
mode: "forward" as EmailProcessingMode,
|
|
||||||
target: {
|
|
||||||
server: "exchange.internal",
|
|
||||||
port: 25,
|
|
||||||
useTls: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Marketing domain - forward to Marketing mail server
|
|
||||||
{
|
|
||||||
pattern: "*@marketing.example.com",
|
|
||||||
mode: "forward" as EmailProcessingMode,
|
|
||||||
target: {
|
|
||||||
server: "marketing-mail.internal",
|
|
||||||
port: 25,
|
|
||||||
useTls: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Outbound MTA with DKIM Signing and IP Warmup
|
|
||||||
|
|
||||||
Configure DCRouter as an outbound mail transfer agent with DKIM signing and IP warmup:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// MTA configuration with DKIM signing
|
|
||||||
const mtaRule: IDomainRule = {
|
|
||||||
pattern: "*@outbound.example.com",
|
|
||||||
mode: "mta" as EmailProcessingMode,
|
|
||||||
mtaOptions: {
|
|
||||||
domain: "outbound.example.com",
|
|
||||||
dkimSign: true,
|
|
||||||
dkimOptions: {
|
|
||||||
domainName: "outbound.example.com",
|
|
||||||
keySelector: "mail2023"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// IP Warmup configuration
|
|
||||||
const ipWarmupConfig = {
|
|
||||||
enabled: true,
|
|
||||||
ipAddresses: ['203.0.113.1', '203.0.113.2'],
|
|
||||||
targetDomains: ['gmail.com', 'yahoo.com', 'hotmail.com', 'aol.com'],
|
|
||||||
allocationPolicy: 'progressive',
|
|
||||||
fallbackPercentage: 20
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Content Scanning and Security Gateway
|
|
||||||
|
|
||||||
Configure DCRouter to scan emails for malicious content and enforce security policies:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const securityRule: IDomainRule = {
|
|
||||||
pattern: "*@*",
|
|
||||||
mode: "process" as EmailProcessingMode,
|
|
||||||
contentScanning: true,
|
|
||||||
scanners: [
|
|
||||||
// Scan for malicious attachments
|
|
||||||
{
|
|
||||||
type: "attachment",
|
|
||||||
action: "reject",
|
|
||||||
blockedExtensions: [".exe", ".dll", ".bat", ".vbs", ".js", ".cmd", ".scr", ".com", ".pif"]
|
|
||||||
},
|
|
||||||
// Scan for spam
|
|
||||||
{
|
|
||||||
type: "spam",
|
|
||||||
threshold: 6.0,
|
|
||||||
action: "tag"
|
|
||||||
},
|
|
||||||
// Scan for viruses
|
|
||||||
{
|
|
||||||
type: "virus",
|
|
||||||
action: "reject"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
transformations: [
|
|
||||||
// Add scanning headers
|
|
||||||
{
|
|
||||||
type: "addHeader",
|
|
||||||
header: "X-Security-Scanned",
|
|
||||||
value: "DCRouter Security Gateway"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Configure security settings
|
|
||||||
const securityConfig = {
|
|
||||||
useDkim: true,
|
|
||||||
verifyDkim: true,
|
|
||||||
verifySpf: true,
|
|
||||||
verifyDmarc: true,
|
|
||||||
enforceDmarc: true,
|
|
||||||
checkIPReputation: true,
|
|
||||||
scanContent: true,
|
|
||||||
maliciousContentAction: "quarantine",
|
|
||||||
threatScoreThreshold: 5.0,
|
|
||||||
rejectHighRiskIPs: true,
|
|
||||||
securityLogLevel: "warn"
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Multi-Tenant Email Server
|
|
||||||
|
|
||||||
Configure DCRouter to handle emails for multiple domains with different processing rules:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const multiTenantRules: IDomainRule[] = [
|
|
||||||
// Tenant 1: Process locally
|
|
||||||
{
|
|
||||||
pattern: "*@tenant1.example.org",
|
|
||||||
mode: "mta" as EmailProcessingMode,
|
|
||||||
mtaOptions: {
|
|
||||||
domain: "tenant1.example.org",
|
|
||||||
dkimSign: true,
|
|
||||||
dkimOptions: {
|
|
||||||
domainName: "tenant1.example.org",
|
|
||||||
keySelector: "t1mail"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Tenant 2: Forward to their server
|
|
||||||
{
|
|
||||||
pattern: "*@tenant2.example.org",
|
|
||||||
mode: "forward" as EmailProcessingMode,
|
|
||||||
target: {
|
|
||||||
server: "mail.tenant2.com",
|
|
||||||
port: 587,
|
|
||||||
useTls: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Tenant 3: Process with content scanning
|
|
||||||
{
|
|
||||||
pattern: "*@tenant3.example.org",
|
|
||||||
mode: "process" as EmailProcessingMode,
|
|
||||||
contentScanning: true,
|
|
||||||
scanners: [
|
|
||||||
{
|
|
||||||
type: "attachment",
|
|
||||||
action: "tag",
|
|
||||||
blockedExtensions: [".zip", ".rar", ".7z"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using the Bounce Management System
|
|
||||||
|
|
||||||
DCRouter includes a sophisticated bounce management system. Here's how to use it:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Get an instance of the UnifiedEmailServer
|
|
||||||
const emailServer = new UnifiedEmailServer(serverOptions);
|
|
||||||
|
|
||||||
// Check if an email is on the suppression list
|
|
||||||
const isSuppressed = emailServer.isEmailSuppressed('user@example.com');
|
|
||||||
|
|
||||||
// Get suppression information
|
|
||||||
const suppressionInfo = emailServer.getSuppressionInfo('user@example.com');
|
|
||||||
if (suppressionInfo) {
|
|
||||||
console.log(`Suppressed due to: ${suppressionInfo.reason}`);
|
|
||||||
console.log(`Suppressed since: ${new Date(suppressionInfo.timestamp)}`);
|
|
||||||
if (suppressionInfo.expiresAt) {
|
|
||||||
console.log(`Suppression expires: ${new Date(suppressionInfo.expiresAt)}`);
|
|
||||||
} else {
|
|
||||||
console.log('Suppression is permanent');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an email to the suppression list
|
|
||||||
emailServer.addToSuppressionList(
|
|
||||||
'problem-user@example.com',
|
|
||||||
'Manual suppression due to user request',
|
|
||||||
Date.now() + (30 * 24 * 60 * 60 * 1000) // Expires in 30 days
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove an email from the suppression list
|
|
||||||
emailServer.removeFromSuppressionList('reactivated-user@example.com');
|
|
||||||
|
|
||||||
// Get all suppressed emails
|
|
||||||
const suppressionList = emailServer.getSuppressionList();
|
|
||||||
console.log(`There are ${suppressionList.length} suppressed email addresses`);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using the IP Warmup System
|
|
||||||
|
|
||||||
DCRouter's IP warmup system helps gradually build sender reputation for new IP addresses:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Add a new IP to warmup
|
|
||||||
emailServer.addIPToWarmup('198.51.100.4');
|
|
||||||
|
|
||||||
// Get warmup status for all IPs
|
|
||||||
const warmupStatus = emailServer.getIPWarmupStatus();
|
|
||||||
console.log('IP Warmup Status:', warmupStatus);
|
|
||||||
|
|
||||||
// Get warmup status for a specific IP
|
|
||||||
const specificIPStatus = emailServer.getIPWarmupStatus('198.51.100.1');
|
|
||||||
console.log(`Warmup day: ${specificIPStatus.day}`);
|
|
||||||
console.log(`Daily limit: ${specificIPStatus.dailyLimit}`);
|
|
||||||
console.log(`Emails sent today: ${specificIPStatus.sentToday}`);
|
|
||||||
|
|
||||||
// Update IP metrics based on feedback from mailbox providers
|
|
||||||
emailServer.updateIPWarmupMetrics('198.51.100.1', {
|
|
||||||
openRate: 0.25, // 25% open rate
|
|
||||||
bounceRate: 0.02, // 2% bounce rate
|
|
||||||
complaintRate: 0.001 // 0.1% complaint rate
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if an IP can send more emails today
|
|
||||||
if (emailServer.canIPSendMoreToday('198.51.100.1')) {
|
|
||||||
console.log('IP can send more emails today');
|
|
||||||
} else {
|
|
||||||
console.log('IP has reached its daily sending limit');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the IP allocation policy
|
|
||||||
emailServer.setIPAllocationPolicy('volume-based');
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sender Reputation Monitoring
|
|
||||||
|
|
||||||
Monitor and manage your domain reputation with these features:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Add a domain to monitoring
|
|
||||||
emailServer.addDomainToMonitoring('newdomain.example.com');
|
|
||||||
|
|
||||||
// Get reputation data for a specific domain
|
|
||||||
const reputationData = emailServer.getDomainReputationData('example.com');
|
|
||||||
console.log(`Reputation score: ${reputationData.score}`);
|
|
||||||
console.log(`Bounce rate: ${reputationData.bounceRate}`);
|
|
||||||
console.log(`Complaint rate: ${reputationData.complaintRate}`);
|
|
||||||
|
|
||||||
// Get a summary of all domains
|
|
||||||
const summary = emailServer.getReputationSummary();
|
|
||||||
console.log('Domain reputation summary:', summary);
|
|
||||||
|
|
||||||
// Record a custom engagement event
|
|
||||||
emailServer.recordReputationEvent('example.com', {
|
|
||||||
type: 'open',
|
|
||||||
count: 15
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating Configuration at Runtime
|
|
||||||
|
|
||||||
DCRouter allows updating configurations dynamically without restarting:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Update domain rules
|
|
||||||
const newRules: IDomainRule[] = [
|
|
||||||
// New rules here
|
|
||||||
];
|
|
||||||
emailServer.updateDomainRules(newRules);
|
|
||||||
|
|
||||||
// Update server options
|
|
||||||
emailServer.updateOptions({
|
|
||||||
maxMessageSize: 50 * 1024 * 1024, // 50MB
|
|
||||||
maxClients: 200,
|
|
||||||
defaultServer: 'new-relay.example.com'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
This example configuration covers a wide range of use cases from simple forwarding to advanced security scanning, IP warmup, and reputation management, showcasing DCRouter's versatility as an email routing and processing solution.
|
|
308
readme.opsserver.md
Normal file
308
readme.opsserver.md
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
# DCRouter OpsServer Implementation Plan
|
||||||
|
|
||||||
|
**Command to reread CLAUDE.md: `cat /home/philkunz/.claude/CLAUDE.md`**
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document outlines the implementation plan for adding a TypedRequest-based API to the DCRouter OpsServer, following the patterns established in the cloudly project. The goal is to create a type-safe, reactive management dashboard with real-time statistics and monitoring capabilities.
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
The implementation follows a clear separation of concerns:
|
||||||
|
- **Backend**: TypedRequest handlers in OpsServer
|
||||||
|
- **Frontend**: Reactive web components with Smartstate
|
||||||
|
- **Communication**: Type-safe requests via TypedRequest pattern
|
||||||
|
- **State Management**: Centralized state with reactive updates
|
||||||
|
|
||||||
|
## Implementation Phases
|
||||||
|
|
||||||
|
### Phase 1: Interface Definition ✓
|
||||||
|
|
||||||
|
Create TypeScript interfaces for all API operations:
|
||||||
|
|
||||||
|
#### Directory Structure ✓
|
||||||
|
```
|
||||||
|
ts_interfaces/
|
||||||
|
plugins.ts # TypedRequest interfaces import
|
||||||
|
data/ # Data type definitions
|
||||||
|
auth.ts # IIdentity interface
|
||||||
|
stats.ts # Server, Email, DNS, Security types
|
||||||
|
index.ts # Exports
|
||||||
|
requests/ # Request interfaces
|
||||||
|
admin.ts # Authentication requests
|
||||||
|
config.ts # Configuration management
|
||||||
|
logs.ts # Log retrieval with IVirtualStream
|
||||||
|
stats.ts # Statistics endpoints
|
||||||
|
index.ts # Exports
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Key Interfaces Defined ✓
|
||||||
|
- **Server Statistics**
|
||||||
|
- [x] `IReq_GetServerStatistics` - Server metrics with history
|
||||||
|
|
||||||
|
- **Email Operations**
|
||||||
|
- [x] `IReq_GetEmailStatistics` - Email delivery stats
|
||||||
|
- [x] `IReq_GetQueueStatus` - Queue monitoring
|
||||||
|
|
||||||
|
- **DNS Management**
|
||||||
|
- [x] `IReq_GetDnsStatistics` - DNS query metrics
|
||||||
|
|
||||||
|
- **Rate Limiting**
|
||||||
|
- [x] `IReq_GetRateLimitStatus` - Rate limit info
|
||||||
|
|
||||||
|
- **Security Metrics**
|
||||||
|
- [x] `IReq_GetSecurityMetrics` - Security stats and trends
|
||||||
|
- [x] `IReq_GetActiveConnections` - Connection monitoring
|
||||||
|
|
||||||
|
- **Logging**
|
||||||
|
- [x] `IReq_GetRecentLogs` - Paginated log retrieval
|
||||||
|
- [x] `IReq_GetLogStream` - Real-time log streaming with IVirtualStream
|
||||||
|
|
||||||
|
- **Configuration**
|
||||||
|
- [x] `IReq_GetConfiguration` - Read config
|
||||||
|
- [x] `IReq_UpdateConfiguration` - Update config
|
||||||
|
|
||||||
|
- **Authentication**
|
||||||
|
- [x] `IReq_AdminLoginWithUsernameAndPassword` - Admin login
|
||||||
|
- [x] `IReq_AdminLogout` - Logout
|
||||||
|
- [x] `IReq_VerifyIdentity` - Token verification
|
||||||
|
|
||||||
|
- **Health Check**
|
||||||
|
- [x] `IReq_GetHealthStatus` - Service health monitoring
|
||||||
|
|
||||||
|
### Phase 2: Backend Implementation
|
||||||
|
|
||||||
|
#### 2.1 Enhance OpsServer (`ts/opsserver/classes.opsserver.ts`)
|
||||||
|
|
||||||
|
- [ ] Add TypedRouter initialization
|
||||||
|
- [ ] Use TypedServer's built-in typedrouter
|
||||||
|
- [ ] CORS is already handled by TypedServer
|
||||||
|
- [ ] Add handler registration method
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Example structure following cloudly pattern
|
||||||
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||||
|
|
||||||
|
constructor(private dcRouterRef: DcRouter) {
|
||||||
|
// Add our typedrouter to the dcRouter's main typedrouter
|
||||||
|
this.dcRouterRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async start() {
|
||||||
|
// TypedServer already has a built-in typedrouter at /typedrequest
|
||||||
|
this.server = new plugins.typedserver.utilityservers.UtilityWebsiteServer({
|
||||||
|
domain: 'localhost',
|
||||||
|
feedMetadata: null,
|
||||||
|
serveDir: paths.distServe,
|
||||||
|
});
|
||||||
|
|
||||||
|
// The server's typedrouter is automatically available
|
||||||
|
// Add the main dcRouter typedrouter to the server's typedrouter
|
||||||
|
this.server.typedrouter.addTypedRouter(this.dcRouterRef.typedrouter);
|
||||||
|
|
||||||
|
this.setupHandlers();
|
||||||
|
await this.server.start(3000);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: TypedServer automatically provides the `/typedrequest` endpoint with its built-in typedrouter. We just need to add our routers to it using the `addTypedRouter()` method.
|
||||||
|
|
||||||
|
#### Hierarchical TypedRouter Structure
|
||||||
|
|
||||||
|
Following cloudly's pattern, we'll use a hierarchical router structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
TypedServer (built-in typedrouter at /typedrequest)
|
||||||
|
└── DcRouter.typedrouter (main router)
|
||||||
|
└── OpsServer.typedrouter (ops-specific handlers)
|
||||||
|
├── StatsHandler.typedrouter
|
||||||
|
├── ConfigHandler.typedrouter
|
||||||
|
└── SecurityHandler.typedrouter
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows clean separation of concerns while keeping all handlers accessible through the single `/typedrequest` endpoint.
|
||||||
|
|
||||||
|
#### 2.2 Create Handler Classes
|
||||||
|
|
||||||
|
Create modular handlers in `ts/opsserver/handlers/`:
|
||||||
|
|
||||||
|
- [ ] `stats.handler.ts` - Server and performance statistics
|
||||||
|
- [ ] `email.handler.ts` - Email-related operations
|
||||||
|
- [ ] `dns.handler.ts` - DNS management statistics
|
||||||
|
- [ ] `security.handler.ts` - Security and reputation metrics
|
||||||
|
- [ ] `config.handler.ts` - Configuration management
|
||||||
|
|
||||||
|
Each handler should:
|
||||||
|
- Have its own typedrouter that gets added to OpsServer's router
|
||||||
|
- Access the main DCRouter instance
|
||||||
|
- Register handlers using TypedHandler instances
|
||||||
|
- Format responses according to interfaces
|
||||||
|
- Handle errors gracefully
|
||||||
|
|
||||||
|
Example handler structure:
|
||||||
|
```typescript
|
||||||
|
export class StatsHandler {
|
||||||
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||||
|
|
||||||
|
constructor(private opsServerRef: OpsServer) {
|
||||||
|
// Add this handler's router to the parent
|
||||||
|
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||||
|
this.registerHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerHandlers() {
|
||||||
|
this.typedrouter.addTypedHandler(
|
||||||
|
new plugins.typedrequest.TypedHandler<IReq_GetServerStatistics>(
|
||||||
|
'getServerStatistics',
|
||||||
|
async (dataArg, toolsArg) => {
|
||||||
|
const stats = await this.collectServerStats();
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 3: Frontend State Management
|
||||||
|
|
||||||
|
#### 3.1 Set up Smartstate (`ts_web/appstate.ts`)
|
||||||
|
|
||||||
|
- [ ] Initialize Smartstate instance
|
||||||
|
- [ ] Create state parts with appropriate persistence
|
||||||
|
- [ ] Define initial state structures
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// State structure example
|
||||||
|
interface IStatsState {
|
||||||
|
serverStats: IRes_ServerStatistics | null;
|
||||||
|
emailStats: IRes_EmailStatistics | null;
|
||||||
|
dnsStats: IRes_DnsStatistics | null;
|
||||||
|
lastUpdated: number;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 State Parts to Create
|
||||||
|
|
||||||
|
- [ ] `statsState` - Runtime statistics (soft persistence)
|
||||||
|
- [ ] `configState` - Configuration data (soft persistence)
|
||||||
|
- [ ] `uiState` - UI preferences (persistent)
|
||||||
|
- [ ] `loginState` - Authentication state (persistent) *if needed*
|
||||||
|
|
||||||
|
### Phase 4: Frontend Integration
|
||||||
|
|
||||||
|
#### 4.1 API Client Setup (`ts_web/api/clients.ts`)
|
||||||
|
|
||||||
|
- [ ] Create TypedRequest instances for each endpoint
|
||||||
|
- [ ] Configure base URL handling
|
||||||
|
- [ ] Add error interceptors
|
||||||
|
- [ ] Implement retry logic
|
||||||
|
|
||||||
|
#### 4.2 Create Actions (`ts_web/state/actions.ts`)
|
||||||
|
|
||||||
|
- [ ] `fetchAllStatsAction` - Batch fetch all statistics
|
||||||
|
- [ ] `refreshServerStatsAction` - Update server stats only
|
||||||
|
- [ ] `refreshEmailStatsAction` - Update email stats only
|
||||||
|
- [ ] `setAutoRefreshAction` - Toggle auto-refresh
|
||||||
|
- [ ] Error handling actions
|
||||||
|
|
||||||
|
#### 4.3 Update Dashboard Component (`ts_web/elements/ops-dashboard.ts`)
|
||||||
|
|
||||||
|
- [ ] Subscribe to state changes
|
||||||
|
- [ ] Implement reactive UI updates
|
||||||
|
- [ ] Add refresh controls
|
||||||
|
- [ ] Create sub-components for different stat types
|
||||||
|
- [ ] Implement auto-refresh timer
|
||||||
|
|
||||||
|
### Phase 5: Component Structure
|
||||||
|
|
||||||
|
Create modular components in `ts_web/elements/components/`:
|
||||||
|
|
||||||
|
- [ ] `server-stats.ts` - Server statistics display
|
||||||
|
- [ ] `email-stats.ts` - Email metrics visualization
|
||||||
|
- [ ] `dns-stats.ts` - DNS statistics
|
||||||
|
- [ ] `rate-limit-display.ts` - Rate limiting status
|
||||||
|
- [ ] `security-metrics.ts` - Security dashboard
|
||||||
|
- [ ] `log-viewer.ts` - Real-time log display
|
||||||
|
|
||||||
|
### Phase 6: Optional Enhancements
|
||||||
|
|
||||||
|
#### 6.1 Authentication (if required)
|
||||||
|
- [ ] Simple token-based authentication
|
||||||
|
- [ ] Login component
|
||||||
|
- [ ] Protected route handling
|
||||||
|
- [ ] Session management
|
||||||
|
|
||||||
|
#### 6.2 Real-time Updates (future)
|
||||||
|
- [ ] WebSocket integration for live stats
|
||||||
|
- [ ] Push notifications for critical events
|
||||||
|
- [ ] Event streaming for logs
|
||||||
|
|
||||||
|
## Technical Stack
|
||||||
|
|
||||||
|
### Dependencies to Use
|
||||||
|
- `@api.global/typedserver` - Server with built-in typedrouter at `/typedrequest`
|
||||||
|
- `@api.global/typedrequest` - TypedRouter and TypedHandler classes
|
||||||
|
- `@design.estate/dees-domtools` - Frontend TypedRequest client
|
||||||
|
- `@push.rocks/smartstate` - State management
|
||||||
|
- `@design.estate/dees-element` - Web components
|
||||||
|
- `@design.estate/dees-catalog` - UI components
|
||||||
|
|
||||||
|
### Existing Dependencies to Leverage
|
||||||
|
- Current DCRouter instance and statistics
|
||||||
|
- Existing error handling patterns
|
||||||
|
- Logger infrastructure
|
||||||
|
- Security modules
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
1. **Start with interfaces** - Define all types first
|
||||||
|
2. **Implement one handler** - Start with server stats
|
||||||
|
3. **Create minimal frontend** - Test with one endpoint
|
||||||
|
4. **Iterate** - Add more handlers and UI components
|
||||||
|
5. **Polish** - Add error handling, loading states, etc.
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
- [ ] Unit tests for handlers
|
||||||
|
- [ ] Integration tests for API endpoints
|
||||||
|
- [ ] Frontend component tests
|
||||||
|
- [ ] End-to-end testing with real DCRouter instance
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
- Type-safe communication between frontend and backend
|
||||||
|
- Real-time statistics display
|
||||||
|
- Responsive and reactive UI
|
||||||
|
- Clean, maintainable code structure
|
||||||
|
- Consistent with cloudly patterns
|
||||||
|
- Easy to extend with new features
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Follow existing code conventions in the project
|
||||||
|
- Use pnpm for all package management
|
||||||
|
- Ensure all tests pass before marking complete
|
||||||
|
- Document any deviations from the plan
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Progress Status
|
||||||
|
|
||||||
|
### Completed ✓
|
||||||
|
- **Phase 1: Interface Definition** - All TypedRequest interfaces created following cloudly pattern
|
||||||
|
- Created proper TypedRequest interfaces with `method`, `request`, and `response` properties
|
||||||
|
- Used `IVirtualStream` for log streaming
|
||||||
|
- Added `@api.global/typedrequest-interfaces` dependency
|
||||||
|
- All interfaces compile successfully
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
- Phase 2: Backend Implementation - Enhance OpsServer and create handlers
|
||||||
|
- Phase 3: Frontend State Management - Set up Smartstate
|
||||||
|
- Phase 4: Frontend Integration - Create API clients and update dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This plan is a living document. Update it as implementation progresses.*
|
@ -0,0 +1,9 @@
|
|||||||
|
export * from './plugins.js';
|
||||||
|
|
||||||
|
// Data types
|
||||||
|
import * as data from './data/index.js';
|
||||||
|
export { data };
|
||||||
|
|
||||||
|
// Request interfaces
|
||||||
|
import * as requests from './requests/index.js';
|
||||||
|
export { requests };
|
6
ts_interfaces/plugins.ts
Normal file
6
ts_interfaces/plugins.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// @apiglobal scope
|
||||||
|
import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
|
||||||
|
|
||||||
|
export {
|
||||||
|
typedrequestInterfaces
|
||||||
|
}
|
46
ts_interfaces/requests/admin.ts
Normal file
46
ts_interfaces/requests/admin.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import * as plugins from '../plugins.js';
|
||||||
|
import * as authInterfaces from '../data/auth.js';
|
||||||
|
|
||||||
|
// Admin Login
|
||||||
|
export interface IReq_AdminLoginWithUsernameAndPassword extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_AdminLoginWithUsernameAndPassword
|
||||||
|
> {
|
||||||
|
method: 'adminLoginWithUsernameAndPassword';
|
||||||
|
request: {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Admin Logout
|
||||||
|
export interface IReq_AdminLogout extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_AdminLogout
|
||||||
|
> {
|
||||||
|
method: 'adminLogout';
|
||||||
|
request: {
|
||||||
|
identity: authInterfaces.IIdentity;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Identity
|
||||||
|
export interface IReq_VerifyIdentity extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_VerifyIdentity
|
||||||
|
> {
|
||||||
|
method: 'verifyIdentity';
|
||||||
|
request: {
|
||||||
|
identity: authInterfaces.IIdentity;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
valid: boolean;
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
};
|
||||||
|
}
|
35
ts_interfaces/requests/config.ts
Normal file
35
ts_interfaces/requests/config.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import * as plugins from '../plugins.js';
|
||||||
|
import * as authInterfaces from '../data/auth.js';
|
||||||
|
|
||||||
|
// Get Configuration
|
||||||
|
export interface IReq_GetConfiguration extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetConfiguration
|
||||||
|
> {
|
||||||
|
method: 'getConfiguration';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
section?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
config: any;
|
||||||
|
section?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Configuration
|
||||||
|
export interface IReq_UpdateConfiguration extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_UpdateConfiguration
|
||||||
|
> {
|
||||||
|
method: 'updateConfiguration';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
section: string;
|
||||||
|
config: any;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
updated: boolean;
|
||||||
|
config: any;
|
||||||
|
};
|
||||||
|
}
|
4
ts_interfaces/requests/index.ts
Normal file
4
ts_interfaces/requests/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './admin.js';
|
||||||
|
export * from './config.js';
|
||||||
|
export * from './logs.js';
|
||||||
|
export * from './stats.js';
|
44
ts_interfaces/requests/logs.ts
Normal file
44
ts_interfaces/requests/logs.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import * as plugins from '../plugins.js';
|
||||||
|
import * as authInterfaces from '../data/auth.js';
|
||||||
|
import * as statsInterfaces from '../data/stats.js';
|
||||||
|
|
||||||
|
// Get Recent Logs
|
||||||
|
export interface IReq_GetRecentLogs extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetRecentLogs
|
||||||
|
> {
|
||||||
|
method: 'getRecentLogs';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
level?: 'debug' | 'info' | 'warn' | 'error';
|
||||||
|
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
search?: string;
|
||||||
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
logs: statsInterfaces.ILogEntry[];
|
||||||
|
total: number;
|
||||||
|
hasMore: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Log Stream
|
||||||
|
export interface IReq_GetLogStream extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetLogStream
|
||||||
|
> {
|
||||||
|
method: 'getLogStream';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
follow?: boolean;
|
||||||
|
filters?: {
|
||||||
|
level?: string[];
|
||||||
|
category?: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
logStream: plugins.typedrequestInterfaces.IVirtualStream;
|
||||||
|
};
|
||||||
|
}
|
162
ts_interfaces/requests/stats.ts
Normal file
162
ts_interfaces/requests/stats.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import * as plugins from '../plugins.js';
|
||||||
|
import * as authInterfaces from '../data/auth.js';
|
||||||
|
import * as statsInterfaces from '../data/stats.js';
|
||||||
|
|
||||||
|
// Server Statistics
|
||||||
|
export interface IReq_GetServerStatistics extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetServerStatistics
|
||||||
|
> {
|
||||||
|
method: 'getServerStatistics';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
includeHistory?: boolean;
|
||||||
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
stats: statsInterfaces.IServerStats;
|
||||||
|
history?: Array<{
|
||||||
|
timestamp: number;
|
||||||
|
value: number;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Email Statistics
|
||||||
|
export interface IReq_GetEmailStatistics extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetEmailStatistics
|
||||||
|
> {
|
||||||
|
method: 'getEmailStatistics';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
|
domain?: string;
|
||||||
|
includeDetails?: boolean;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
stats: statsInterfaces.IEmailStats;
|
||||||
|
domainBreakdown?: {
|
||||||
|
[domain: string]: statsInterfaces.IEmailStats;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNS Statistics
|
||||||
|
export interface IReq_GetDnsStatistics extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetDnsStatistics
|
||||||
|
> {
|
||||||
|
method: 'getDnsStatistics';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
|
domain?: string;
|
||||||
|
includeQueryTypes?: boolean;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
stats: statsInterfaces.IDnsStats;
|
||||||
|
domainBreakdown?: {
|
||||||
|
[domain: string]: statsInterfaces.IDnsStats;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rate Limit Status
|
||||||
|
export interface IReq_GetRateLimitStatus extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetRateLimitStatus
|
||||||
|
> {
|
||||||
|
method: 'getRateLimitStatus';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
domain?: string;
|
||||||
|
ip?: string;
|
||||||
|
includeBlocked?: boolean;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
limits: statsInterfaces.IRateLimitInfo[];
|
||||||
|
globalLimit?: {
|
||||||
|
current: number;
|
||||||
|
limit: number;
|
||||||
|
remaining: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security Metrics
|
||||||
|
export interface IReq_GetSecurityMetrics extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetSecurityMetrics
|
||||||
|
> {
|
||||||
|
method: 'getSecurityMetrics';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
|
includeDetails?: boolean;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
metrics: statsInterfaces.ISecurityMetrics;
|
||||||
|
trends?: {
|
||||||
|
spam: Array<{ timestamp: number; value: number }>;
|
||||||
|
malware: Array<{ timestamp: number; value: number }>;
|
||||||
|
phishing: Array<{ timestamp: number; value: number }>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active Connections
|
||||||
|
export interface IReq_GetActiveConnections extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetActiveConnections
|
||||||
|
> {
|
||||||
|
method: 'getActiveConnections';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
protocol?: 'smtp' | 'smtps' | 'http' | 'https';
|
||||||
|
state?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
connections: statsInterfaces.IConnectionInfo[];
|
||||||
|
summary: {
|
||||||
|
total: number;
|
||||||
|
byProtocol: {
|
||||||
|
[protocol: string]: number;
|
||||||
|
};
|
||||||
|
byState: {
|
||||||
|
[state: string]: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue Status
|
||||||
|
export interface IReq_GetQueueStatus extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetQueueStatus
|
||||||
|
> {
|
||||||
|
method: 'getQueueStatus';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
queueName?: string;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
queues: statsInterfaces.IQueueStatus[];
|
||||||
|
totalItems: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Health Check
|
||||||
|
export interface IReq_GetHealthStatus extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetHealthStatus
|
||||||
|
> {
|
||||||
|
method: 'getHealthStatus';
|
||||||
|
request: {
|
||||||
|
identity?: authInterfaces.IIdentity;
|
||||||
|
detailed?: boolean;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
health: statsInterfaces.IHealthStatus;
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user