770 lines
14 KiB
TypeScript
770 lines
14 KiB
TypeScript
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'
|
|
}
|
|
}
|
|
}
|
|
}; |