diff --git a/package.json b/package.json index 547666e..5358523 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "dependencies": { "@api.global/typedrequest": "^3.0.19", + "@api.global/typedrequest-interfaces": "^3.0.19", "@api.global/typedserver": "^3.0.74", "@api.global/typedsocket": "^3.0.0", "@apiclient.xyz/cloudflare": "^6.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 943eb0b..8ef0ce0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@api.global/typedrequest': specifier: ^3.0.19 version: 3.1.10 + '@api.global/typedrequest-interfaces': + specifier: ^3.0.19 + version: 3.0.19 '@api.global/typedserver': specifier: ^3.0.74 version: 3.0.74 @@ -5353,8 +5356,10 @@ snapshots: '@push.rocks/taskbuffer': 3.1.7 transitivePeerDependencies: - '@nuxt/kit' + - bufferutil - react - supports-color + - utf-8-validate - vue '@hapi/hoek@9.3.0': {} @@ -5695,7 +5700,6 @@ snapshots: - '@mongodb-js/zstd' - '@nuxt/kit' - aws-crt - - bufferutil - encoding - gcp-metadata - kerberos @@ -5704,7 +5708,6 @@ snapshots: - snappy - socks - supports-color - - utf-8-validate - vue '@push.rocks/smartarchive@3.0.8': diff --git a/readme.example.md b/readme.example.md deleted file mode 100644 index ec63271..0000000 --- a/readme.example.md +++ /dev/null @@ -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: "
This is an automated message from Example Inc.
", - 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. \ No newline at end of file diff --git a/readme.opsserver.md b/readme.opsserver.md new file mode 100644 index 0000000..31d6431 --- /dev/null +++ b/readme.opsserver.md @@ -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