// ========== DNS MANAGEMENT ========== (function () { // Restart DNS service via backend proxy (backend handles auth automatically) async function restartDnsService(dnsId) { const response = await secureFetch(`/api/v1/dns/restart/${dnsId}`, { method: 'POST' }); const result = await response.json(); if (!result.success) { throw new Error(result.error || 'Restart failed'); } return result; } // Event delegation for DNS restart buttons (dynamic cards) document.querySelector('.top')?.addEventListener('click', async (e) => { const restartBtn = e.target.closest('[id$="-restart"]'); if (!restartBtn) return; const dnsId = restartBtn.id.replace('-restart', ''); if (!SITE.dnsServers[dnsId]) return; if (!confirm(`Restart ${dnsId.toUpperCase()} service?`)) return; try { await withButton(restartBtn, '...', () => restartDnsService(dnsId)); setTimeout(window.refreshAll, DC.DELAYS.RELOAD); } catch (e) { showNotification('Restart failed: ' + e.message, 'error'); } }); // DNS Update buttons async function updateDnsServer(dnsId, serverIp) { const btn = document.getElementById(`${dnsId}-update`); const originalText = btn?.textContent || '⬆️'; try { // First check for updates btn.textContent = '🔍'; btn.disabled = true; btn.title = 'Checking for updates...'; const checkResponse = await fetch(`/api/v1/dns/check-update?server=${encodeURIComponent(serverIp)}`); const checkResult = await checkResponse.json(); if (!checkResult.success) { throw new Error(checkResult.error || 'Failed to check for updates'); } if (!checkResult.updateAvailable) { btn.textContent = '✅'; btn.title = `Already on latest version (${checkResult.currentVersion})`; showNotification(`${dnsId.toUpperCase()} is already up to date! Current version: ${checkResult.currentVersion}`, 'info'); setTimeout(() => { btn.textContent = originalText; btn.disabled = false; btn.title = 'Update DNS server'; }, 3000); return; } // Update available - confirm with user const confirmUpdate = confirm( `Update available for ${dnsId.toUpperCase()}!\n\n` + `Current: ${checkResult.currentVersion}\n` + `New: ${checkResult.updateVersion}\n\n` + (checkResult.updateTitle ? `${checkResult.updateTitle}\n\n` : '') + `The DNS server will restart during the update.\nProceed?` ); if (!confirmUpdate) { btn.textContent = originalText; btn.disabled = false; btn.title = 'Update DNS server'; return; } // Perform the update btn.textContent = '🔄'; btn.title = 'Updating...'; const updateResponse = await secureFetch(`/api/v1/dns/update?server=${encodeURIComponent(serverIp)}`, { method: 'POST' }); const updateResult = await updateResponse.json(); if (!updateResult.success) { throw new Error(updateResult.error || 'Update failed'); } if (updateResult.manualUpdateRequired) { // Technitium v14+ doesn't support auto-install via API btn.textContent = '⬆️'; btn.title = `Update available: ${updateResult.newVersion}`; const downloadInfo = updateResult.downloadLink ? `\nDownload: ${updateResult.downloadLink}` : ''; const instructionsInfo = updateResult.instructionsLink ? `\nInstructions: ${updateResult.instructionsLink}` : ''; showNotification(`${dnsId.toUpperCase()} update requires manual installation. Current: ${updateResult.previousVersion} → ${updateResult.newVersion}. Please update manually on the host machine.`, 'warning', 8000); btn.disabled = false; return; } btn.textContent = '✅'; btn.title = 'Updated successfully!'; showNotification(`${dnsId.toUpperCase()} updated successfully! ${updateResult.previousVersion} → ${updateResult.newVersion}. Server is restarting...`, 'success'); // Refresh after delay for server restart setTimeout(() => { btn.textContent = originalText; btn.disabled = false; btn.title = 'Update DNS server'; window.refreshAll(); }, 10000); } catch (error) { console.error('DNS update error:', error); btn.textContent = '❌'; btn.title = 'Update failed'; showNotification(`Failed to update ${dnsId.toUpperCase()}: ${error.message}`, 'error'); setTimeout(() => { btn.textContent = originalText; btn.disabled = false; btn.title = 'Update DNS server'; }, 3000); } } // Event delegation for DNS update buttons (dynamic cards) document.querySelector('.top')?.addEventListener('click', (e) => { const updateBtn = e.target.closest('[id$="-update"]'); if (!updateBtn) return; const dnsId = updateBtn.id.replace('-update', ''); if (!SITE.dnsServers[dnsId]) return; updateDnsServer(dnsId, SITE.dnsServers[dnsId]?.ip); }); // ===== DNS SETTINGS MODAL ===== // Inject modal HTML injectModal('dns-settings-modal', `