Files
CDN-APP-INSIDER/routes/Dpanel/API/Update-Setup-Admin.js
Dinawo 51d11a6c36
Some checks failed
continuous-integration/drone/push Build is failing
Update v1.1.0-beta.1
2024-12-21 18:16:25 +01:00

173 lines
6.6 KiB
JavaScript

const express = require('express');
const fs = require('fs');
const path = require('path');
const router = express.Router();
const bodyParser = require('body-parser');
const { logger } = require('../../../config/logs');
// Utilitaires pour la gestion des services
const services = {
fileCleanup: require('../../../services/fileCleanupService'),
reportManager: require('../../../services/reportService')
};
router.use(bodyParser.json());
// Fonction de nettoyage des objets
function clean(obj) {
for (let propName in obj) {
if (obj[propName] === null || obj[propName] === undefined || obj[propName] === '') {
delete obj[propName];
} else if (typeof obj[propName] === 'object') {
clean(obj[propName]);
if (Object.keys(obj[propName]).length === 0) {
delete obj[propName];
}
}
}
}
// Validation des IPs
function validateIP(ip) {
if (!ip) return false;
if (ip.includes('/')) {
const [addr, bits] = ip.split('/');
const bitsNum = parseInt(bits);
if (isIPv4(addr)) {
return bitsNum >= 0 && bitsNum <= 32;
} else if (isIPv6(addr)) {
return bitsNum >= 0 && bitsNum <= 128;
}
return false;
}
return isIPv4(ip) || isIPv6(ip);
}
function isIPv4(ip) {
const ipv4Regex = /^\d{1,3}(\.\d{1,3}){3}$/;
if (!ipv4Regex.test(ip)) return false;
const parts = ip.split('.');
return parts.every(part => {
const num = parseInt(part);
return num >= 0 && num <= 255;
});
}
function isIPv6(ip) {
const ipv6Regex = /^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
return ipv6Regex.test(ip);
}
// Fonction pour activer ou désactiver un service
async function handleServices(newConfig, oldConfig) {
if (!newConfig.services) return;
for (const [serviceName, serviceConfig] of Object.entries(newConfig.services)) {
const service = services[serviceName];
if (!service) {
logger.warn(`Service ${serviceName} not found`);
continue;
}
const oldServiceConfig = oldConfig?.services?.[serviceName] || {};
const wasEnabled = oldServiceConfig.enabled === 'on'; // ancien état
const isEnabled = serviceConfig.enabled === 'on'; // nouvel état
try {
logger.info(`Processing service ${serviceName}: wasEnabled=${wasEnabled}, isEnabled=${isEnabled}`);
if (isEnabled && !wasEnabled) {
await service.updateConfig(serviceConfig);
await service.start();
} else if (!isEnabled && wasEnabled) {
await service.stop();
} else if (isEnabled && wasEnabled &&
JSON.stringify(serviceConfig) !== JSON.stringify(oldServiceConfig)) {
await service.stop();
await service.updateConfig(serviceConfig);
await service.start();
}
} catch (error) {
logger.error(`Error handling service ${serviceName}:`, error);
throw error;
}
}
}
// Mise à jour de la configuration et gestion des services
async function handleServicesUpdate(newConfig, oldConfig) {
if (!newConfig.services) return;
for (const [serviceName, serviceConfig] of Object.entries(newConfig.services)) {
const oldServiceConfig = oldConfig?.services?.[serviceName] || {};
await handleServices(serviceName, serviceConfig, oldServiceConfig);
}
}
// Route principale pour mettre à jour la configuration
router.post('/', async (req, res) => {
try {
const setupPath = path.join(__dirname, '../../../data', 'setup.json');
const oldConfig = JSON.parse(fs.readFileSync(setupPath, 'utf-8'))[0];
// Validation et traitement des IPs autorisées
if (req.body.allowedIps) {
let ipsToProcess = Array.isArray(req.body.allowedIps) ? req.body.allowedIps : req.body.allowedIps[""] || [];
req.body.allowedIps = ipsToProcess.filter(ip => validateIP(ip.trim())).map(ip => ip.trim());
}
['ldap', 'discord'].forEach(service => {
if (req.body[service] && !req.body[service].enabled) {
req.body[service] = { enabled: 'off' };
}
});
// Traitement des services
if (req.body.services) {
for (const [key, value] of Object.entries(req.body.services)) {
if (typeof value === 'string') {
req.body.services[key] = { enabled: 'off', schedule: value }; // Par défaut 'off' et ajouter un schedule si nécessaire
}
// Si l'état n'est pas 'on' ou 'off', on le met à 'off'
if (value.enabled !== 'on' && value.enabled !== 'off') {
req.body.services[key].enabled = 'off';
}
}
}
// Traitement des logs
if (req.body.logs) {
req.body.logs = {
enabled: req.body.logs.enabled || "on",
excludePaths: Array.isArray(req.body.logs.excludePaths) ? req.body.logs.excludePaths : [],
includeOnly: Array.isArray(req.body.logs.includeOnly) ? req.body.logs.includeOnly : [],
levels: Array.isArray(req.body.logs.levels) ? req.body.logs.levels : []
};
}
// Fusion des anciennes et nouvelles configurations
const newConfig = { ...oldConfig, ...req.body };
clean(newConfig);
// Mise à jour des services
await handleServicesUpdate(newConfig, oldConfig);
// Sauvegarde de la nouvelle configuration
fs.writeFileSync(setupPath, JSON.stringify([newConfig], null, 2));
res.status(200).json({ message: 'Configuration mise à jour avec succès.' });
} catch (error) {
logger.error('Erreur lors de la mise à jour de la configuration:', error);
res.status(500).json({ error: 'Erreur interne du serveur.' });
}
});
module.exports = router;