update
This commit is contained in:
parent
8d59d617f1
commit
0e610cba16
@ -1,433 +0,0 @@
|
||||
/**
|
||||
* Base configuration interface with common properties for all services
|
||||
*/
|
||||
export interface IBaseConfig {
|
||||
/**
|
||||
* Unique identifier for this configuration
|
||||
* Used to track configuration versions and changes
|
||||
*/
|
||||
id?: string;
|
||||
|
||||
/**
|
||||
* Configuration version
|
||||
* Used for migration between different config formats
|
||||
*/
|
||||
version?: string;
|
||||
|
||||
/**
|
||||
* Environment this configuration is intended for
|
||||
* (development, test, production, etc.)
|
||||
*/
|
||||
environment?: 'development' | 'test' | 'staging' | 'production';
|
||||
|
||||
/**
|
||||
* Display name for this configuration
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Whether this configuration is enabled
|
||||
* Services with disabled configuration shouldn't start
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Logging configuration
|
||||
*/
|
||||
logging?: {
|
||||
/**
|
||||
* Minimum log level to output
|
||||
*/
|
||||
level?: 'error' | 'warn' | 'info' | 'debug';
|
||||
|
||||
/**
|
||||
* Whether to include structured data in logs
|
||||
*/
|
||||
structured?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to enable correlation tracking in logs
|
||||
*/
|
||||
correlationTracking?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Base database configuration
|
||||
*/
|
||||
export interface IDatabaseConfig {
|
||||
/**
|
||||
* Database connection string or URL
|
||||
*/
|
||||
connectionString?: string;
|
||||
|
||||
/**
|
||||
* Database host
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Database port
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Database name
|
||||
*/
|
||||
database?: string;
|
||||
|
||||
/**
|
||||
* Database username
|
||||
*/
|
||||
username?: string;
|
||||
|
||||
/**
|
||||
* Database password
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* SSL configuration for database connection
|
||||
*/
|
||||
ssl?: boolean | {
|
||||
/**
|
||||
* Whether to reject unauthorized SSL connections
|
||||
*/
|
||||
rejectUnauthorized?: boolean;
|
||||
|
||||
/**
|
||||
* Path to CA certificate file
|
||||
*/
|
||||
ca?: string;
|
||||
|
||||
/**
|
||||
* Path to client certificate file
|
||||
*/
|
||||
cert?: string;
|
||||
|
||||
/**
|
||||
* Path to client key file
|
||||
*/
|
||||
key?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection pool configuration
|
||||
*/
|
||||
pool?: {
|
||||
/**
|
||||
* Minimum number of connections in pool
|
||||
*/
|
||||
min?: number;
|
||||
|
||||
/**
|
||||
* Maximum number of connections in pool
|
||||
*/
|
||||
max?: number;
|
||||
|
||||
/**
|
||||
* Connection idle timeout in milliseconds
|
||||
*/
|
||||
idleTimeoutMillis?: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Base TLS configuration interface
|
||||
*/
|
||||
export interface ITlsConfig {
|
||||
/**
|
||||
* Whether to enable TLS
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* The domain name for the certificate
|
||||
*/
|
||||
domain?: string;
|
||||
|
||||
/**
|
||||
* Path to certificate file
|
||||
*/
|
||||
certPath?: string;
|
||||
|
||||
/**
|
||||
* Path to private key file
|
||||
*/
|
||||
keyPath?: string;
|
||||
|
||||
/**
|
||||
* Path to CA certificate file
|
||||
*/
|
||||
caPath?: string;
|
||||
|
||||
/**
|
||||
* Minimum TLS version to support
|
||||
*/
|
||||
minVersion?: 'TLSv1.2' | 'TLSv1.3';
|
||||
|
||||
/**
|
||||
* Whether to auto-renew certificates
|
||||
*/
|
||||
autoRenew?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to reject unauthorized certificates
|
||||
*/
|
||||
rejectUnauthorized?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base retry configuration interface
|
||||
*/
|
||||
export interface IRetryConfig {
|
||||
/**
|
||||
* Maximum number of retry attempts
|
||||
*/
|
||||
maxAttempts?: number;
|
||||
|
||||
/**
|
||||
* Base delay between retries in milliseconds
|
||||
*/
|
||||
baseDelay?: number;
|
||||
|
||||
/**
|
||||
* Maximum delay between retries in milliseconds
|
||||
*/
|
||||
maxDelay?: number;
|
||||
|
||||
/**
|
||||
* Backoff factor for exponential backoff
|
||||
*/
|
||||
backoffFactor?: number;
|
||||
|
||||
/**
|
||||
* Specific error codes that should trigger retries
|
||||
*/
|
||||
retryableErrorCodes?: string[];
|
||||
|
||||
/**
|
||||
* Whether to add jitter to retry delays
|
||||
*/
|
||||
useJitter?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base rate limiting configuration interface
|
||||
*/
|
||||
export interface IRateLimitConfig {
|
||||
/**
|
||||
* Whether rate limiting is enabled
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Maximum number of operations per period
|
||||
*/
|
||||
maxPerPeriod?: number;
|
||||
|
||||
/**
|
||||
* Time period in milliseconds
|
||||
*/
|
||||
periodMs?: number;
|
||||
|
||||
/**
|
||||
* Whether to apply per key (e.g., domain, user, etc.)
|
||||
*/
|
||||
perKey?: boolean;
|
||||
|
||||
/**
|
||||
* Number of burst tokens allowed
|
||||
*/
|
||||
burstTokens?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic HTTP server configuration
|
||||
*/
|
||||
export interface IHttpServerConfig {
|
||||
/**
|
||||
* Whether the HTTP server is enabled
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Host to bind to
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Port to listen on
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Path prefix for all routes
|
||||
*/
|
||||
basePath?: string;
|
||||
|
||||
/**
|
||||
* CORS configuration
|
||||
*/
|
||||
cors?: boolean | {
|
||||
/**
|
||||
* Allowed origins
|
||||
*/
|
||||
origins?: string[];
|
||||
|
||||
/**
|
||||
* Allowed methods
|
||||
*/
|
||||
methods?: string[];
|
||||
|
||||
/**
|
||||
* Allowed headers
|
||||
*/
|
||||
headers?: string[];
|
||||
|
||||
/**
|
||||
* Whether to allow credentials
|
||||
*/
|
||||
credentials?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* TLS configuration
|
||||
*/
|
||||
tls?: ITlsConfig;
|
||||
|
||||
/**
|
||||
* Maximum request body size in bytes
|
||||
*/
|
||||
maxBodySize?: number;
|
||||
|
||||
/**
|
||||
* Request timeout in milliseconds
|
||||
*/
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic queue configuration
|
||||
*/
|
||||
export interface IQueueConfig {
|
||||
/**
|
||||
* Type of storage for the queue
|
||||
*/
|
||||
storageType?: 'memory' | 'disk' | 'redis';
|
||||
|
||||
/**
|
||||
* Path for persistent storage
|
||||
*/
|
||||
persistentPath?: string;
|
||||
|
||||
/**
|
||||
* Redis configuration for queue
|
||||
*/
|
||||
redis?: {
|
||||
/**
|
||||
* Redis host
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Redis port
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Redis password
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* Redis database number
|
||||
*/
|
||||
db?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Maximum size of the queue
|
||||
*/
|
||||
maxSize?: number;
|
||||
|
||||
/**
|
||||
* Maximum number of retry attempts
|
||||
*/
|
||||
maxRetries?: number;
|
||||
|
||||
/**
|
||||
* Base delay between retries in milliseconds
|
||||
*/
|
||||
baseRetryDelay?: number;
|
||||
|
||||
/**
|
||||
* Maximum delay between retries in milliseconds
|
||||
*/
|
||||
maxRetryDelay?: number;
|
||||
|
||||
/**
|
||||
* Check interval for processing in milliseconds
|
||||
*/
|
||||
checkInterval?: number;
|
||||
|
||||
/**
|
||||
* Maximum number of parallel processes
|
||||
*/
|
||||
maxParallelProcessing?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic monitoring configuration
|
||||
*/
|
||||
export interface IMonitoringConfig {
|
||||
/**
|
||||
* Whether monitoring is enabled
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Metrics collection interval in milliseconds
|
||||
*/
|
||||
metricsInterval?: number;
|
||||
|
||||
/**
|
||||
* Whether to expose Prometheus metrics
|
||||
*/
|
||||
exposePrometheus?: boolean;
|
||||
|
||||
/**
|
||||
* Port for Prometheus metrics
|
||||
*/
|
||||
prometheusPort?: number;
|
||||
|
||||
/**
|
||||
* Whether to collect detailed metrics
|
||||
*/
|
||||
detailedMetrics?: boolean;
|
||||
|
||||
/**
|
||||
* Alert thresholds
|
||||
*/
|
||||
alertThresholds?: Record<string, number>;
|
||||
|
||||
/**
|
||||
* Notification configuration
|
||||
*/
|
||||
notifications?: {
|
||||
/**
|
||||
* Whether to send notifications
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Email address to send notifications to
|
||||
*/
|
||||
email?: string;
|
||||
|
||||
/**
|
||||
* Webhook URL to send notifications to
|
||||
*/
|
||||
webhook?: string;
|
||||
};
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
|
||||
/**
|
||||
* MIGRATION GUIDE:
|
||||
* ================
|
||||
* The IEmailConfig and IMtaConfig interfaces are deprecated.
|
||||
* Please use IUnifiedEmailServerOptions from '../mail/routing/classes.unified.email.server.js' instead.
|
||||
*
|
||||
* Example migration:
|
||||
*
|
||||
* OLD:
|
||||
* ```typescript
|
||||
* const config: IEmailConfig = {
|
||||
* ports: [25, 587],
|
||||
* hostname: 'mail.example.com',
|
||||
* domainRules: [...],
|
||||
* defaultMode: 'forward'
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* NEW:
|
||||
* ```typescript
|
||||
* const config: IUnifiedEmailServerOptions = {
|
||||
* ports: [25, 587],
|
||||
* hostname: 'mail.example.com',
|
||||
* domains: ['example.com'],
|
||||
* domainRules: [...],
|
||||
* defaultMode: 'forward'
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* The new interface consolidates all email configuration into a single, cleaner structure.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Email processing modes
|
||||
*/
|
||||
export type EmailProcessingMode = 'forward' | 'mta' | 'process';
|
||||
|
||||
/**
|
||||
* Domain rule for email routing
|
||||
*/
|
||||
export interface IDomainRule {
|
||||
/**
|
||||
* Pattern to match (e.g., "*@example.com")
|
||||
*/
|
||||
pattern: string;
|
||||
|
||||
/**
|
||||
* Processing mode
|
||||
*/
|
||||
mode: EmailProcessingMode;
|
||||
|
||||
/**
|
||||
* Target server for forwarding mode
|
||||
*/
|
||||
target?: {
|
||||
/**
|
||||
* Target server hostname or IP
|
||||
*/
|
||||
server: string;
|
||||
|
||||
/**
|
||||
* Target server port
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Whether to use TLS for forwarding
|
||||
*/
|
||||
useTls?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* MTA options for mta mode
|
||||
*/
|
||||
mtaOptions?: {
|
||||
/**
|
||||
* Domain for MTA
|
||||
*/
|
||||
domain?: string;
|
||||
|
||||
/**
|
||||
* Whether to sign with DKIM
|
||||
*/
|
||||
dkimSign?: boolean;
|
||||
|
||||
/**
|
||||
* DKIM options
|
||||
*/
|
||||
dkimOptions?: {
|
||||
/**
|
||||
* Domain name for DKIM
|
||||
*/
|
||||
domainName: string;
|
||||
|
||||
/**
|
||||
* Key selector
|
||||
*/
|
||||
keySelector: string;
|
||||
|
||||
/**
|
||||
* Private key
|
||||
*/
|
||||
privateKey?: string;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether to scan content in process mode
|
||||
*/
|
||||
contentScanning?: boolean;
|
||||
|
||||
/**
|
||||
* Content scanners to apply
|
||||
*/
|
||||
scanners?: Array<{
|
||||
/**
|
||||
* Scanner type
|
||||
*/
|
||||
type: 'spam' | 'virus' | 'attachment';
|
||||
|
||||
/**
|
||||
* Threshold for scanner
|
||||
*/
|
||||
threshold?: number;
|
||||
|
||||
/**
|
||||
* Action to take
|
||||
*/
|
||||
action: 'tag' | 'reject';
|
||||
|
||||
/**
|
||||
* Blocked file extensions for attachment scanner
|
||||
*/
|
||||
blockedExtensions?: string[];
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Email transformations to apply
|
||||
*/
|
||||
transformations?: Array<{
|
||||
/**
|
||||
* Transformation type
|
||||
*/
|
||||
type: 'addHeader';
|
||||
|
||||
/**
|
||||
* Header name
|
||||
*/
|
||||
header?: string;
|
||||
|
||||
/**
|
||||
* Header value
|
||||
*/
|
||||
value?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
@ -1,194 +0,0 @@
|
||||
/**
|
||||
* Email Port Mapping Configuration
|
||||
*
|
||||
* Centralizes the logic for mapping external email ports to internal ports
|
||||
* when running behind SmartProxy
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default email port mapping
|
||||
* Maps external ports to internal ports for SmartProxy forwarding
|
||||
*/
|
||||
export const DEFAULT_EMAIL_PORT_MAPPING: Record<number, number> = {
|
||||
25: 10025, // SMTP - Standard email delivery port
|
||||
587: 10587, // Submission - Authenticated submission port
|
||||
465: 10465, // SMTPS - Implicit TLS submission port
|
||||
2525: 12525 // Alternative SMTP port (often used for testing)
|
||||
};
|
||||
|
||||
/**
|
||||
* Email port configuration
|
||||
*/
|
||||
export interface IEmailPortConfig {
|
||||
/**
|
||||
* External port number
|
||||
*/
|
||||
external: number;
|
||||
|
||||
/**
|
||||
* Internal port number (where the email server actually listens)
|
||||
*/
|
||||
internal: number;
|
||||
|
||||
/**
|
||||
* Port description
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* TLS mode for this port
|
||||
*/
|
||||
tlsMode: 'none' | 'starttls' | 'implicit';
|
||||
|
||||
/**
|
||||
* Whether authentication is required on this port
|
||||
*/
|
||||
requireAuth?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard email port configurations
|
||||
*/
|
||||
export const EMAIL_PORT_CONFIGS: Record<number, Omit<IEmailPortConfig, 'internal'>> = {
|
||||
25: {
|
||||
external: 25,
|
||||
description: 'SMTP - Standard email delivery',
|
||||
tlsMode: 'starttls',
|
||||
requireAuth: false
|
||||
},
|
||||
587: {
|
||||
external: 587,
|
||||
description: 'Submission - Authenticated email submission',
|
||||
tlsMode: 'starttls',
|
||||
requireAuth: true
|
||||
},
|
||||
465: {
|
||||
external: 465,
|
||||
description: 'SMTPS - Implicit TLS submission',
|
||||
tlsMode: 'implicit',
|
||||
requireAuth: true
|
||||
},
|
||||
2525: {
|
||||
external: 2525,
|
||||
description: 'Alternative SMTP - Often used for testing',
|
||||
tlsMode: 'starttls',
|
||||
requireAuth: false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Map external ports to internal ports
|
||||
* @param externalPorts Array of external ports
|
||||
* @param customMapping Optional custom port mapping
|
||||
* @returns Array of internal ports
|
||||
*/
|
||||
export function mapEmailPorts(
|
||||
externalPorts: number[],
|
||||
customMapping?: Record<number, number>
|
||||
): number[] {
|
||||
const mapping = { ...DEFAULT_EMAIL_PORT_MAPPING, ...customMapping };
|
||||
|
||||
return externalPorts.map(port => {
|
||||
// Use custom mapping if available, otherwise add 10000 to the port
|
||||
return mapping[port] || port + 10000;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full port configuration including internal port mapping
|
||||
* @param externalPort External port number
|
||||
* @param customMapping Optional custom port mapping
|
||||
* @returns Full port configuration
|
||||
*/
|
||||
export function getEmailPortConfig(
|
||||
externalPort: number,
|
||||
customMapping?: Record<number, number>
|
||||
): IEmailPortConfig | undefined {
|
||||
const config = EMAIL_PORT_CONFIGS[externalPort];
|
||||
if (!config) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const mapping = { ...DEFAULT_EMAIL_PORT_MAPPING, ...customMapping };
|
||||
const internalPort = mapping[externalPort] || externalPort + 10000;
|
||||
|
||||
return {
|
||||
...config,
|
||||
internal: internalPort
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SmartProxy routes for email ports
|
||||
* @param externalPorts Array of external ports to handle
|
||||
* @param hostname Hostname for the email server
|
||||
* @param customMapping Optional custom port mapping
|
||||
* @returns Array of SmartProxy route configurations
|
||||
*/
|
||||
export function generateEmailProxyRoutes(
|
||||
externalPorts: number[],
|
||||
_hostname: string,
|
||||
customMapping?: Record<number, number>
|
||||
): plugins.smartproxy.IRouteConfig[] {
|
||||
const routes: plugins.smartproxy.IRouteConfig[] = [];
|
||||
|
||||
for (const externalPort of externalPorts) {
|
||||
const config = getEmailPortConfig(externalPort, customMapping);
|
||||
if (!config) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create route for this email port
|
||||
const route: plugins.smartproxy.IRouteConfig = {
|
||||
name: `email-${config.description.toLowerCase().replace(/\s+/g, '-')}`,
|
||||
match: {
|
||||
ports: [externalPort]
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: 'localhost',
|
||||
port: config.internal
|
||||
},
|
||||
tls: {
|
||||
// For SMTP/Submission ports, use passthrough to let email server handle STARTTLS
|
||||
// For SMTPS (465), SmartProxy handles TLS termination
|
||||
mode: config.tlsMode === 'implicit' ? 'terminate' : 'passthrough',
|
||||
certificate: config.tlsMode === 'implicit' ? 'auto' : undefined
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
routes.push(route);
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate email port configuration
|
||||
* @param ports Array of ports to validate
|
||||
* @throws Error if invalid ports are specified
|
||||
*/
|
||||
export function validateEmailPorts(ports: number[]): void {
|
||||
const invalidPorts = ports.filter(port => {
|
||||
// Check if port is a valid number
|
||||
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Warn about non-standard ports
|
||||
if (!EMAIL_PORT_CONFIGS[port]) {
|
||||
console.warn(`Port ${port} is not a standard email port. Supported standard ports are: ${Object.keys(EMAIL_PORT_CONFIGS).join(', ')}`);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (invalidPorts.length > 0) {
|
||||
throw new Error(`Invalid email ports specified: ${invalidPorts.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Type imports to avoid circular dependencies
|
||||
import type * as plugins from '../plugins.js';
|
@ -1,54 +0,0 @@
|
||||
import type { IBaseConfig, IHttpServerConfig, IDatabaseConfig } from './base.config.js';
|
||||
import type { ISmsConfig } from './sms.config.js';
|
||||
|
||||
/**
|
||||
* Platform service configuration
|
||||
* Root configuration that includes all service configurations
|
||||
*/
|
||||
export interface IPlatformConfig extends IBaseConfig {
|
||||
/**
|
||||
* HTTP server configuration
|
||||
*/
|
||||
server?: IHttpServerConfig;
|
||||
|
||||
/**
|
||||
* Database configuration
|
||||
*/
|
||||
database?: IDatabaseConfig;
|
||||
|
||||
/**
|
||||
* Email service configuration
|
||||
* @deprecated - Use IUnifiedEmailServerOptions in DcRouter instead
|
||||
*/
|
||||
email?: any;
|
||||
|
||||
/**
|
||||
* SMS service configuration
|
||||
*/
|
||||
sms?: ISmsConfig;
|
||||
|
||||
/**
|
||||
* Path configuration
|
||||
*/
|
||||
paths?: {
|
||||
/**
|
||||
* Data directory path
|
||||
*/
|
||||
dataDir?: string;
|
||||
|
||||
/**
|
||||
* Logs directory path
|
||||
*/
|
||||
logsDir?: string;
|
||||
|
||||
/**
|
||||
* Temporary directory path
|
||||
*/
|
||||
tempDir?: string;
|
||||
|
||||
/**
|
||||
* Email templates directory path
|
||||
*/
|
||||
emailTemplatesDir?: string;
|
||||
};
|
||||
}
|
@ -1,770 +0,0 @@
|
||||
import type { ValidationSchema } from './validator.js';
|
||||
|
||||
/**
|
||||
* Base TLS configuration schema
|
||||
*/
|
||||
export const tlsConfigSchema: ValidationSchema = {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
certPath: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
keyPath: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
caPath: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
minVersion: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['TLSv1.2', 'TLSv1.3'],
|
||||
default: 'TLSv1.2'
|
||||
},
|
||||
autoRenew: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
rejectUnauthorized: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* HTTP server configuration schema
|
||||
*/
|
||||
export const httpServerSchema: ValidationSchema = {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
host: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '0.0.0.0'
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 3000,
|
||||
min: 1,
|
||||
max: 65535
|
||||
},
|
||||
basePath: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
cors: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
tls: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: tlsConfigSchema
|
||||
},
|
||||
maxBodySize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 1024 * 1024 // 1MB
|
||||
},
|
||||
timeout: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 30000 // 30 seconds
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Rate limit configuration schema
|
||||
*/
|
||||
export const rateLimitSchema: ValidationSchema = {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
maxPerPeriod: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 100,
|
||||
min: 1
|
||||
},
|
||||
periodMs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 60000, // 1 minute
|
||||
min: 1000
|
||||
},
|
||||
perKey: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
burstTokens: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 5,
|
||||
min: 0
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Queue configuration schema
|
||||
*/
|
||||
export const queueSchema: ValidationSchema = {
|
||||
storageType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['memory', 'disk', 'redis'],
|
||||
default: 'memory'
|
||||
},
|
||||
persistentPath: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
redis: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
host: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'localhost'
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 6379,
|
||||
min: 1,
|
||||
max: 65535
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
db: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 0,
|
||||
min: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
maxSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 10000,
|
||||
min: 1
|
||||
},
|
||||
maxRetries: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 3,
|
||||
min: 0
|
||||
},
|
||||
baseRetryDelay: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 1000, // 1 second
|
||||
min: 1
|
||||
},
|
||||
maxRetryDelay: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 60000, // 1 minute
|
||||
min: 1
|
||||
},
|
||||
checkInterval: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 1000, // 1 second
|
||||
min: 100
|
||||
},
|
||||
maxParallelProcessing: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 5,
|
||||
min: 1
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SMS service configuration schema
|
||||
*/
|
||||
export const smsConfigSchema: ValidationSchema = {
|
||||
apiGatewayApiToken: {
|
||||
type: 'string',
|
||||
required: true
|
||||
},
|
||||
defaultSender: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
rateLimit: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
...rateLimitSchema,
|
||||
maxPerRecipientPerDay: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 10,
|
||||
min: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
provider: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['gateway', 'twilio', 'other'],
|
||||
default: 'gateway'
|
||||
},
|
||||
config: {
|
||||
type: 'object',
|
||||
required: false
|
||||
},
|
||||
fallback: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['gateway', 'twilio', 'other']
|
||||
},
|
||||
config: {
|
||||
type: 'object',
|
||||
required: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
verification: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
codeLength: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 6,
|
||||
min: 4,
|
||||
max: 10
|
||||
},
|
||||
expirationSeconds: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 300, // 5 minutes
|
||||
min: 60
|
||||
},
|
||||
maxAttempts: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 3,
|
||||
min: 1
|
||||
},
|
||||
cooldownSeconds: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 60, // 1 minute
|
||||
min: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* MTA configuration schema
|
||||
*/
|
||||
export const mtaConfigSchema: ValidationSchema = {
|
||||
smtp: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 25,
|
||||
min: 1,
|
||||
max: 65535
|
||||
},
|
||||
hostname: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'mta.lossless.one'
|
||||
},
|
||||
maxSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 10 * 1024 * 1024, // 10MB
|
||||
min: 1024
|
||||
}
|
||||
}
|
||||
},
|
||||
tls: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: tlsConfigSchema
|
||||
},
|
||||
outbound: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
concurrency: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 5,
|
||||
min: 1
|
||||
},
|
||||
retries: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
max: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 3,
|
||||
min: 0
|
||||
},
|
||||
delay: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 300000, // 5 minutes
|
||||
min: 1000
|
||||
},
|
||||
useBackoff: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
},
|
||||
rateLimit: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: rateLimitSchema
|
||||
},
|
||||
warmup: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
ipAddresses: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
targetDomains: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
items: {
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
allocationPolicy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'balanced'
|
||||
},
|
||||
fallbackPercentage: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 50,
|
||||
min: 0,
|
||||
max: 100
|
||||
}
|
||||
}
|
||||
},
|
||||
reputation: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
updateFrequency: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 24 * 60 * 60 * 1000, // 1 day
|
||||
min: 60000
|
||||
},
|
||||
alertThresholds: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
minReputationScore: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 70,
|
||||
min: 0,
|
||||
max: 100
|
||||
},
|
||||
maxComplaintRate: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 0.1, // 0.1%
|
||||
min: 0,
|
||||
max: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
security: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
useDkim: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
verifyDkim: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
verifySpf: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
verifyDmarc: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
enforceDmarc: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
useTls: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
requireValidCerts: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
securityLogLevel: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['info', 'warn', 'error'],
|
||||
default: 'warn'
|
||||
},
|
||||
checkIPReputation: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
scanContent: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
maliciousContentAction: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['tag', 'quarantine', 'reject'],
|
||||
default: 'tag'
|
||||
},
|
||||
threatScoreThreshold: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 50,
|
||||
min: 0,
|
||||
max: 100
|
||||
},
|
||||
rejectHighRiskIPs: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
},
|
||||
domains: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
local: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
default: ['lossless.one']
|
||||
},
|
||||
autoCreateDnsRecords: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
dkimSelector: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'mta'
|
||||
}
|
||||
}
|
||||
},
|
||||
queue: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: queueSchema
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Email service configuration schema
|
||||
*/
|
||||
export const emailConfigSchema: ValidationSchema = {
|
||||
useMta: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
mtaConfig: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: mtaConfigSchema
|
||||
},
|
||||
templateConfig: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
from: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'no-reply@lossless.one'
|
||||
},
|
||||
replyTo: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'support@lossless.one'
|
||||
},
|
||||
footerHtml: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
footerText: {
|
||||
type: 'string',
|
||||
required: false
|
||||
}
|
||||
}
|
||||
},
|
||||
loadTemplatesFromDir: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
templatesDir: {
|
||||
type: 'string',
|
||||
required: false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Database configuration schema
|
||||
*/
|
||||
export const databaseConfigSchema: ValidationSchema = {
|
||||
connectionString: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
host: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'localhost'
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 5432,
|
||||
min: 1,
|
||||
max: 65535
|
||||
},
|
||||
database: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
required: false
|
||||
},
|
||||
ssl: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
pool: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
min: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 2,
|
||||
min: 1
|
||||
},
|
||||
max: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 10,
|
||||
min: 1
|
||||
},
|
||||
idleTimeoutMillis: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
default: 30000,
|
||||
min: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Platform service configuration schema
|
||||
*/
|
||||
export const platformConfigSchema: ValidationSchema = {
|
||||
id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'platform-service-config'
|
||||
},
|
||||
version: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '1.0.0'
|
||||
},
|
||||
environment: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['development', 'test', 'staging', 'production'],
|
||||
default: 'production'
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'PlatformService'
|
||||
},
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
logging: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
level: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
enum: ['error', 'warn', 'info', 'debug'],
|
||||
default: 'info'
|
||||
},
|
||||
structured: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
correlationTracking: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
},
|
||||
server: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: httpServerSchema
|
||||
},
|
||||
database: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: databaseConfigSchema
|
||||
},
|
||||
email: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: emailConfigSchema
|
||||
},
|
||||
sms: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: smsConfigSchema
|
||||
},
|
||||
paths: {
|
||||
type: 'object',
|
||||
required: false,
|
||||
schema: {
|
||||
dataDir: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'data'
|
||||
},
|
||||
logsDir: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'logs'
|
||||
},
|
||||
tempDir: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'temp'
|
||||
},
|
||||
emailTemplatesDir: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: 'templates/email'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -1,86 +0,0 @@
|
||||
import type { IBaseConfig, IRateLimitConfig } from './base.config.js';
|
||||
|
||||
/**
|
||||
* SMS service configuration
|
||||
*/
|
||||
export interface ISmsConfig extends IBaseConfig {
|
||||
/**
|
||||
* API token for the gateway service
|
||||
*/
|
||||
apiGatewayApiToken: string;
|
||||
|
||||
/**
|
||||
* Default sender ID or phone number
|
||||
*/
|
||||
defaultSender?: string;
|
||||
|
||||
/**
|
||||
* SMS rate limiting
|
||||
*/
|
||||
rateLimit?: IRateLimitConfig & {
|
||||
/**
|
||||
* Maximum messages per recipient per day
|
||||
*/
|
||||
maxPerRecipientPerDay?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* SMS provider configuration
|
||||
*/
|
||||
provider?: {
|
||||
/**
|
||||
* Provider type
|
||||
*/
|
||||
type?: 'gateway' | 'twilio' | 'other';
|
||||
|
||||
/**
|
||||
* Provider-specific configuration
|
||||
*/
|
||||
config?: Record<string, any>;
|
||||
|
||||
/**
|
||||
* Fallback provider configuration
|
||||
*/
|
||||
fallback?: {
|
||||
/**
|
||||
* Whether to use fallback provider
|
||||
*/
|
||||
enabled?: boolean;
|
||||
|
||||
/**
|
||||
* Provider type
|
||||
*/
|
||||
type?: 'gateway' | 'twilio' | 'other';
|
||||
|
||||
/**
|
||||
* Provider-specific configuration
|
||||
*/
|
||||
config?: Record<string, any>;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Verification code settings
|
||||
*/
|
||||
verification?: {
|
||||
/**
|
||||
* Code length
|
||||
*/
|
||||
codeLength?: number;
|
||||
|
||||
/**
|
||||
* Code expiration time in seconds
|
||||
*/
|
||||
expirationSeconds?: number;
|
||||
|
||||
/**
|
||||
* Maximum number of attempts
|
||||
*/
|
||||
maxAttempts?: number;
|
||||
|
||||
/**
|
||||
* Cooldown period in seconds
|
||||
*/
|
||||
cooldownSeconds?: number;
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user