const body = document.body; const themeSwitcher = document.getElementById('themeSwitcher'); // Gestion du thème function setTheme(theme) { if (theme === 'dark') { body.classList.add('dark'); } else { body.classList.remove('dark'); } localStorage.setItem('theme', theme); } const savedTheme = localStorage.getItem('theme'); if (savedTheme) { setTheme(savedTheme); } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { setTheme('dark'); } themeSwitcher.addEventListener('click', function() { if (body.classList.contains('dark')) { setTheme('light'); } else { setTheme('dark'); } }); // Gestion des formulaires LDAP et Discord function toggleForm(formId, checkbox) { const form = document.getElementById(formId); form.style.display = checkbox.checked ? 'block' : 'none'; } // Fonctions pour la gestion des IPs function addIpField() { const ipList = document.getElementById('ipList'); const newField = document.createElement('div'); newField.className = 'flex items-center space-x-2 animate'; newField.innerHTML = ` `; ipList.appendChild(newField); } function removeIpField(button) { const fieldContainer = button.parentElement; fieldContainer.classList.add('fade-out'); setTimeout(() => { fieldContainer.remove(); }, 300); } // Fonctions de validation IP 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}\.){3}\d{1,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); } // Gestionnaire pour le switch des logs et les niveaux document.addEventListener('DOMContentLoaded', function() { const logsSwitch = document.getElementById('logsEnabled'); const logsLevelsSection = document.getElementById('logsLevelsSection'); const logsPathsSection = document.getElementById('logsPathsSection'); if (logsSwitch) { logsSwitch.addEventListener('change', function() { const isEnabled = this.checked; // Activer/désactiver visuellement les sections if (logsLevelsSection) logsLevelsSection.style.opacity = isEnabled ? '1' : '0.5'; if (logsPathsSection) logsPathsSection.style.opacity = isEnabled ? '1' : '0.5'; if (!isEnabled) { // Décocher tous les niveaux de log document.querySelectorAll('input[name="logs[levels][]"]').forEach(checkbox => { checkbox.checked = false; checkbox.parentElement.classList.remove('bg-blue-600'); checkbox.parentElement.classList.add('bg-gray-700'); }); } }); } }); function toggleLogLevel(button) { if (!document.getElementById('logsEnabled').checked) { return; // Ne rien faire si les logs sont désactivés } button.classList.toggle('bg-blue-600'); button.classList.toggle('bg-gray-700'); const checkbox = button.querySelector('input[type="checkbox"]'); checkbox.checked = !checkbox.checked; } // Gestion du formulaire principal async function handleFormSubmit(e) { e.preventDefault(); // Validation des IPs const ipInputs = document.querySelectorAll('input[name="allowedIps[]"]'); let hasError = false; ipInputs.forEach(input => { input.classList.remove('ip-error'); const value = input.value.trim(); if (value && !validateIP(value)) { input.classList.add('ip-error'); hasError = true; } }); if (hasError) { Swal.fire({ icon: 'error', title: 'Erreur de validation', text: 'Veuillez vérifier le format des IPs saisies' }); return; } try { const formData = new FormData(this); const formObject = {}; // Traitement des données du formulaire formData.forEach((value, key) => { if (key.includes('[') && key.includes(']')) { const parts = key.split('['); const mainKey = parts[0]; const subKey = parts[1].replace(']', ''); if (!formObject[mainKey]) { formObject[mainKey] = {}; } if (key.endsWith('[]')) { if (!formObject[mainKey][subKey.replace('[]', '')]) { formObject[mainKey][subKey.replace('[]', '')] = []; } formObject[mainKey][subKey.replace('[]', '')].push(value); } else { formObject[mainKey][subKey] = value; } } else { formObject[key] = value; } }); // Gestion de l'état enabled/disabled des logs formObject.logs.enabled = document.getElementById('logsEnabled')?.checked ? 'on' : 'off'; // Si les logs sont désactivés if (formObject.logs.enabled === 'off') { formObject.logs = { enabled: 'off', levels: [], excludePaths: [], includeOnly: [] }; } else { // Si les logs sont activés, on s'assure d'avoir tous les champs if (!formObject.logs.levels) formObject.logs.levels = []; if (!formObject.logs.excludePaths) formObject.logs.excludePaths = []; if (!formObject.logs.includeOnly) formObject.logs.includeOnly = []; } // Gérer l'état des services if (!formObject.services) formObject.services = {}; // Service de nettoyage de fichiers formObject.services.fileCleanup = { enabled: document.getElementById('fileCleanupEnabled')?.checked ? 'on' : 'off', ...(document.getElementById('fileCleanupEnabled')?.checked && { schedule: document.getElementById('fileCleanupSchedule')?.value }) }; // Service de gestion des rapports formObject.services.reportManager = { enabled: document.getElementById('reportManagerEnabled')?.checked ? 'on' : 'off', ...(document.getElementById('reportManagerEnabled')?.checked && { schedule: document.getElementById('reportSchedule')?.value, endpoint: document.getElementById('reportEndpoint')?.value }) }; // Gérer l'état de LDAP if (!formObject.ldap) formObject.ldap = {}; formObject.ldap.enabled = document.getElementById('ldapEnabled').checked ? 'on' : 'off'; if (formObject.ldap.enabled === 'off') { delete formObject.ldap.url; delete formObject.ldap.baseDN; delete formObject.ldap.username; delete formObject.ldap.password; } // Gérer l'état de Discord if (!formObject.discord) formObject.discord = {}; formObject.discord.enabled = document.getElementById('discordEnabled').checked ? 'on' : 'off'; if (formObject.discord.enabled === 'off') { delete formObject.discord.clientID; delete formObject.discord.clientSecret; delete formObject.discord.identifyURL; delete formObject.discord.authorizedIDs; } console.log('Form data to be sent:', formObject); const response = await fetch('/api/dpanel/dashboard/admin/update-setup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formObject) }); const result = await response.json(); if (result.success) { Swal.fire({ icon: 'success', title: 'Configuration mise à jour', text: result.message }).then(() => { window.location.reload(); }); } else { throw new Error(result.message || 'Erreur lors de la mise à jour'); } } catch (error) { console.error('Erreur:', error); Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || 'Une erreur est survenue lors de la mise à jour' }); } } function showCommonPaths(type) { const paths = [ '/api/', '/auth/', '/public/', '/build-metadata', '/attachments/', '/favicon.ico', '/dpanel/' ]; const modalContent = ` `; Swal.fire({ html: modalContent, showConfirmButton: false, showCancelButton: false, background: '#1a1a1a', padding: 0 }); } function addPath(type) { const input = document.getElementById(`${type}PathInput`); const value = input.value.trim(); if (!value) return; const list = document.getElementById(`${type}PathsList`); const div = document.createElement('div'); div.className = 'flex items-center space-x-2 py-2 px-3 bg-gray-800 rounded-lg animate'; div.innerHTML = ` ${value} `; list.appendChild(div); input.value = ''; } function addSelectedPaths(type) { const checkboxes = document.querySelectorAll('.path-option input[type="checkbox"]:checked'); checkboxes.forEach(checkbox => { const input = document.getElementById(`${type}PathInput`); input.value = checkbox.value; addPath(type); }); Swal.close(); } function removePath(button) { const div = button.closest('div'); div.classList.add('fade-out'); setTimeout(() => div.remove(), 300); } // Fonction pour basculer l'affichage du formulaire de service function toggleService(serviceName) { const checkbox = document.getElementById(`${serviceName}Enabled`); const form = document.getElementById(`${serviceName}Form`); if (form) { form.style.display = checkbox.checked ? 'block' : 'none'; } } // Validation du format cron function validateCron(schedule) { const cronPattern = /^(\*|\d{1,2})(\s+(\*|\d{1,2})){4}$/; return cronPattern.test(schedule); } // Validation de l'URL function validateUrl(url) { try { new URL(url); return true; } catch { return false; } } // Initialisation au chargement de la page document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('setupForm'); if (form) { form.addEventListener('submit', async function(e) { e.preventDefault(); // Validation des IPs const ipInputs = document.querySelectorAll('input[name="allowedIps[]"]'); let hasError = false; ipInputs.forEach(input => { input.classList.remove('ip-error'); const value = input.value.trim(); if (value && !validateIP(value)) { input.classList.add('ip-error'); hasError = true; } }); if (hasError) { Swal.fire({ icon: 'error', title: 'Erreur de validation', text: 'Veuillez vérifier le format des IPs saisies' }); return; } try { // Création de l'objet de données const formObject = { domain: document.getElementById('domain').value, webhooks_discord: document.getElementById('webhooksDiscord').value, // Configuration LDAP ldap: { enabled: document.getElementById('ldapEnabled').checked ? 'on' : 'off' }, // Configuration Discord discord: { enabled: document.getElementById('discordEnabled').checked ? 'on' : 'off' }, // Configuration des services services: { fileCleanup: { enabled: document.getElementById('fileCleanupEnabled')?.checked ? 'on' : 'off', schedule: document.getElementById('fileCleanupSchedule')?.value || '' }, reportManager: { enabled: document.getElementById('reportManagerEnabled')?.checked ? 'on' : 'off', schedule: document.getElementById('reportSchedule')?.value || '', endpoint: document.getElementById('reportEndpoint')?.value || '' } }, // IPs autorisées allowedIps: Array.from(document.querySelectorAll('input[name="allowedIps[]"]')) .map(input => input.value.trim()) .filter(value => value !== '') }; // Ajout des champs LDAP si activé if (formObject.ldap.enabled === 'on') { formObject.ldap.url = document.getElementById('ldapUrl').value; formObject.ldap.baseDN = document.getElementById('ldapBaseDN').value; formObject.ldap.username = document.getElementById('ldapUsername').value; formObject.ldap.password = document.getElementById('ldapPassword').value; } // Ajout des champs Discord si activé if (formObject.discord.enabled === 'on') { formObject.discord.clientID = document.getElementById('discordClientID').value; formObject.discord.clientSecret = document.getElementById('discordClientSecret').value; formObject.discord.authorizedIDs = document.getElementById('discordAuthorizedIDs').value; } // Gestion des logs formObject.logs = { enabled: document.getElementById('logsEnabled')?.checked ? 'on' : 'off', levels: [], excludePaths: [], includeOnly: [] }; // Si les logs sont activés, ajout des configurations supplémentaires if (formObject.logs.enabled === 'on') { // Récupération des niveaux de logs sélectionnés formObject.logs.levels = Array.from(document.querySelectorAll('input[name="logs[levels][]"]:checked')) .map(input => input.value); // Récupération des chemins exclus formObject.logs.excludePaths = Array.from(document.querySelectorAll('input[name="logs[excludePaths][]"]')) .map(input => input.value.trim()) .filter(value => value !== ''); // Récupération des chemins inclus formObject.logs.includeOnly = Array.from(document.querySelectorAll('input[name="logs[includeOnly][]"]')) .map(input => input.value.trim()) .filter(value => value !== ''); } console.log('Données à envoyer:', formObject); const response = await fetch('/api/dpanel/dashboard/admin/update-setup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formObject) }); const result = await response.json(); if (result.success) { Swal.fire({ icon: 'success', title: 'Configuration mise à jour', text: result.message || 'Configuration sauvegardée avec succès' }).then(() => { window.location.reload(); }); } else { throw new Error(result.message || 'Erreur lors de la mise à jour'); } } catch (error) { console.error('Erreur:', error); Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || 'Une erreur est survenue lors de la mise à jour' }); } }); } }); // Fonctions de validation function validateCron(cron) { const cronRegex = /^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])) (\*|([0-6]))$/; return cronRegex.test(cron.trim()); } function validateUrl(url) { try { new URL(url); return true; } catch { return false; } } // Gestion des onglets document.addEventListener('DOMContentLoaded', function() { // Init des onglets const tabs = document.querySelectorAll('.tab'); tabs.forEach(tab => { tab.addEventListener('click', () => switchTab(tab)); }); // Init du thème initTheme(); // Init du formulaire initForm(); }); // Initialisation du formulaire function initForm() { // Le formulaire est déjà initialisé dans le DOMContentLoaded à la ligne 375 // Cette fonction est appelée pour des initialisations supplémentaires si nécessaire console.log('Formulaire initialisé'); } // Gestion du thème function initTheme() { const themeSwitcher = document.getElementById('themeSwitcher'); const savedTheme = localStorage.getItem('theme') || 'light'; document.documentElement.classList.toggle('dark', savedTheme === 'dark'); updateThemeIcon(savedTheme); themeSwitcher.addEventListener('click', toggleTheme); } function toggleTheme() { const isDark = document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', isDark ? 'dark' : 'light'); updateThemeIcon(isDark ? 'dark' : 'light'); } function updateThemeIcon(theme) { const icon = document.querySelector('#themeSwitcher i'); icon.className = theme === 'dark' ? 'fas fa-moon' : 'fas fa-sun'; } // Gestion des onglets function switchTab(selectedTab) { const tabs = document.querySelectorAll('.tab'); const contents = document.querySelectorAll('.tab-content'); tabs.forEach(tab => tab.classList.remove('active')); contents.forEach(content => content.classList.remove('active')); selectedTab.classList.add('active'); const targetContent = document.querySelector(`[data-tab-content="${selectedTab.dataset.tab}"]`); targetContent.classList.add('active'); } // Gestion des sections toggle function toggleSection(sectionId, checkbox) { const section = document.getElementById(sectionId); if (section) { section.style.display = checkbox.checked ? 'block' : 'none'; if (checkbox.checked) { section.classList.add('animate'); } else { section.classList.add('fade-out'); setTimeout(() => { section.classList.remove('fade-out'); section.style.display = 'none'; }, 300); } } } // Gestion des IPs function addIp() { const ipList = document.getElementById('ipList'); const newEntry = document.createElement('div'); newEntry.className = 'ip-entry flex items-center gap-2 animate'; newEntry.innerHTML = ` `; ipList.appendChild(newEntry); } function removeIp(button) { const entry = button.closest('.ip-entry'); entry.classList.add('fade-out'); setTimeout(() => entry.remove(), 300); } // Gestion des chemins function addPath(type) { const input = document.getElementById(`${type}PathInput`); const path = input.value.trim(); if (!path) return; const list = document.getElementById(`${type}PathsList`); const newEntry = document.createElement('div'); newEntry.className = 'path-entry animate'; newEntry.innerHTML = ` ${path} `; list.appendChild(newEntry); input.value = ''; } function removePath(button) { const entry = button.closest('.path-entry'); entry.classList.add('fade-out'); setTimeout(() => entry.remove(), 300); } // Gestion des niveaux de log function toggleLogLevel(button) { button.classList.toggle('active'); const checkbox = button.querySelector('input[type="checkbox"]'); checkbox.checked = !checkbox.checked; } // Chemins communs function showCommonPaths(type) { const commonPaths = [ '/api', '/auth', '/public', '/uploads', '/static', '/assets', '/images', '/temp' ]; Swal.fire({ title: 'Chemins communs', html: ` `, showConfirmButton: false, customClass: { popup: 'swal2-dark' } }); } function selectCommonPath(path, type) { const input = document.getElementById(`${type}PathInput`); input.value = path; Swal.close(); }