This commit is contained in:
Philipp Kunz 2025-05-28 11:39:46 +00:00
parent 8d59d617f1
commit 0e610cba16
6 changed files with 0 additions and 1696 deletions

View File

@ -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;
};
}

View File

@ -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;
}>;
}

View File

@ -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';

View File

@ -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;
};
}

View File

@ -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'
}
}
}
};

View File

@ -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;
};
}