Files
dcrouter/ts/opsserver/handlers/config.handler.ts
Juergen Kunz 7bd94884f4 update
2025-06-29 18:47:44 +00:00

163 lines
4.9 KiB
TypeScript

import * as plugins from '../../plugins.js';
import type { OpsServer } from '../classes.opsserver.js';
import * as interfaces from '../../../ts_interfaces/index.js';
import { requireAdminIdentity } from '../helpers/guards.js';
export class ConfigHandler {
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(): void {
// Get Configuration Handler
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetConfiguration>(
'getConfiguration',
async (dataArg, toolsArg) => {
const config = await this.getConfiguration(dataArg.section);
return {
config,
section: dataArg.section,
};
}
)
);
// Update Configuration Handler
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateConfiguration>(
'updateConfiguration',
async (dataArg, toolsArg) => {
try {
// Require admin access to update configuration
await requireAdminIdentity(this.opsServerRef.adminHandler, dataArg);
const updatedConfig = await this.updateConfiguration(dataArg.section, dataArg.config);
return {
updated: true,
config: updatedConfig,
};
} catch (error) {
if (error instanceof plugins.typedrequest.TypedResponseError) {
throw error;
}
return {
updated: false,
config: null,
};
}
}
)
);
}
private async getConfiguration(section?: string): Promise<{
email: {
enabled: boolean;
ports: number[];
maxMessageSize: number;
rateLimits: {
perMinute: number;
perHour: number;
perDay: number;
};
domains?: string[];
};
dns: {
enabled: boolean;
port: number;
nameservers: string[];
caching: boolean;
ttl: number;
};
proxy: {
enabled: boolean;
httpPort: number;
httpsPort: number;
maxConnections: number;
};
security: {
blockList: string[];
rateLimit: boolean;
spamDetection: boolean;
tlsRequired: boolean;
};
}> {
const dcRouter = this.opsServerRef.dcRouterRef;
// Get email domains if email server is configured
let emailDomains: string[] = [];
if (dcRouter.emailServer && dcRouter.emailServer.domainRegistry) {
emailDomains = dcRouter.emailServer.domainRegistry.getAllDomains();
} else if (dcRouter.options.emailConfig?.domains) {
// Fallback: get domains from email config options
emailDomains = dcRouter.options.emailConfig.domains.map(d =>
typeof d === 'string' ? d : d.domain
);
}
return {
email: {
enabled: !!dcRouter.emailServer,
ports: dcRouter.emailServer ? [25, 465, 587, 2525] : [],
maxMessageSize: 10 * 1024 * 1024, // 10MB default
rateLimits: {
perMinute: 10,
perHour: 100,
perDay: 1000,
},
domains: emailDomains,
},
dns: {
enabled: !!dcRouter.dnsServer,
port: 53,
nameservers: dcRouter.options.dnsNsDomains || [],
caching: true,
ttl: 300,
},
proxy: {
enabled: !!dcRouter.smartProxy,
httpPort: 80,
httpsPort: 443,
maxConnections: 1000,
},
security: {
blockList: [],
rateLimit: true,
spamDetection: true,
tlsRequired: false,
},
};
}
private async updateConfiguration(section: string, config: any): Promise<any> {
// TODO: Implement actual configuration updates
// This would involve:
// 1. Validating the configuration changes
// 2. Applying them to the running services
// 3. Persisting them to storage
// 4. Potentially restarting affected services
// For now, just validate and return the config
if (section === 'email' && config.maxMessageSize && config.maxMessageSize < 1024) {
throw new Error('Maximum message size must be at least 1KB');
}
if (section === 'dns' && config.ttl && (config.ttl < 0 || config.ttl > 86400)) {
throw new Error('DNS TTL must be between 0 and 86400 seconds');
}
if (section === 'proxy' && config.maxConnections && config.maxConnections < 1) {
throw new Error('Maximum connections must be at least 1');
}
// In a real implementation, apply the changes here
// For now, return the current configuration
const currentConfig = await this.getConfiguration(section);
return currentConfig;
}
}