Files
p2ns/includes/admin/admin-frontend/ui/local-dns.js
T

251 lines
14 KiB
JavaScript

// Local DNS UI functions
function openLocalDnsModal(editIndex = -1) {
const modal = document.getElementById('localDnsModal');
const title = document.getElementById('local-dns-title');
const nameInput = document.getElementById('local-name');
const typeSelect = document.getElementById('local-type');
const ttlInput = document.getElementById('local-ttl');
const submitBtn = document.getElementById('local-submit');
if (!modal || !title || !nameInput || !typeSelect || !ttlInput || !submitBtn) return;
nameInput.value = '';
typeSelect.value = 'A';
ttlInput.value = 3600;
if (window.updateLocalForm) updateLocalForm();
if (editIndex >= 0) {
const rec = window.localDnsData?.find(r => r.index === editIndex);
if (rec) {
nameInput.value = rec.name;
typeSelect.value = rec.type;
if (window.updateLocalForm) updateLocalForm(rec);
ttlInput.value = rec.ttl;
title.textContent = 'Edit Local DNS Record';
submitBtn.textContent = 'Update';
window.editLocalIndex = editIndex;
}
} else {
title.textContent = 'Add Local DNS Record';
submitBtn.textContent = 'Add';
window.editLocalIndex = -1;
}
modal.showModal();
}
function updateLocalForm(rec = null) {
const typeEl = document.getElementById('local-type');
const fields = document.getElementById('local-value-fields');
if (!typeEl || !fields) return;
const type = typeEl.value;
fields.innerHTML = '';
let inputHtml = '';
switch (type) {
case 'A':
case 'AAAA':
inputHtml = `<input id="local-data" placeholder="IP Address" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'CNAME':
inputHtml = `<input id="local-data" placeholder="Target Domain" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'TXT':
inputHtml = `<input id="local-data" placeholder="Text" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'MX':
inputHtml = `<input id="local-preference" type="number" placeholder="Preference" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-exchange" placeholder="Exchange" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'SRV':
inputHtml = `<input id="local-priority" type="number" placeholder="Priority" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-weight" type="number" placeholder="Weight" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-port" type="number" placeholder="Port" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-target" placeholder="Target" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'SOA':
inputHtml = `<input id="local-mname" placeholder="Primary Name Server" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-rname" placeholder="Responsible Person" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-serial" type="number" placeholder="Serial" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-refresh" type="number" placeholder="Refresh" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-retry" type="number" placeholder="Retry" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-expire" type="number" placeholder="Expire" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-minimum" type="number" placeholder="Minimum TTL" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'CAA':
inputHtml = `<input id="local-flags" type="number" placeholder="Flags" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-tag" placeholder="Tag (e.g., issue, issuewild, iodef)" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-value" placeholder="Value" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
case 'NS':
case 'PTR':
inputHtml = `<input id="local-data" placeholder="Name Server" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
default:
inputHtml = `<input id="local-data" placeholder="Record Data" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
break;
}
fields.innerHTML = inputHtml;
if (rec) {
switch (type) {
case 'MX':
const prefEl = document.getElementById('local-preference');
const exchEl = document.getElementById('local-exchange');
if (prefEl) prefEl.value = rec.preference || '';
if (exchEl) exchEl.value = rec.exchange || '';
break;
case 'SRV':
const priEl = document.getElementById('local-priority');
const weightEl = document.getElementById('local-weight');
const portEl = document.getElementById('local-port');
const targetEl = document.getElementById('local-target');
if (priEl) priEl.value = rec.priority || '';
if (weightEl) weightEl.value = rec.weight || '';
if (portEl) portEl.value = rec.port || '';
if (targetEl) targetEl.value = rec.target || '';
break;
case 'SOA':
const mnameEl = document.getElementById('local-mname');
const rnameEl = document.getElementById('local-rname');
const serialEl = document.getElementById('local-serial');
const refreshEl = document.getElementById('local-refresh');
const retryEl = document.getElementById('local-retry');
const expireEl = document.getElementById('local-expire');
const minimumEl = document.getElementById('local-minimum');
if (mnameEl) mnameEl.value = rec.mname || '';
if (rnameEl) rnameEl.value = rec.rname || '';
if (serialEl) serialEl.value = rec.serial || '';
if (refreshEl) refreshEl.value = rec.refresh || '';
if (retryEl) retryEl.value = rec.retry || '';
if (expireEl) expireEl.value = rec.expire || '';
if (minimumEl) minimumEl.value = rec.minimum || '';
break;
case 'CAA':
const flagsEl = document.getElementById('local-flags');
const tagEl = document.getElementById('local-tag');
const valueEl = document.getElementById('local-value');
if (flagsEl) flagsEl.value = rec.flags || '';
if (tagEl) tagEl.value = rec.tag || '';
if (valueEl) valueEl.value = rec.value || '';
break;
default:
const dataEl = document.getElementById('local-data');
if (dataEl) dataEl.value = rec.data || rec.value || '';
break;
}
}
}
async function submitLocalDns(buttonElement) {
if (!buttonElement) return;
const originalText = buttonElement.innerHTML;
buttonElement.disabled = true;
buttonElement.innerHTML = 'Saving... <span class="inline-block animate-spin rounded-full h-4 w-4 border-t-2 border-white ml-2"></span>';
try {
const nameEl = document.getElementById('local-name');
const typeEl = document.getElementById('local-type');
const ttlEl = document.getElementById('local-ttl');
if (!nameEl || !typeEl || !ttlEl) return;
const name = nameEl.value;
const type = typeEl.value;
const ttl = parseInt(ttlEl.value) || 3600;
let record = { name, type, ttl, class: 'IN' };
switch (type) {
case 'MX':
const prefEl = document.getElementById('local-preference');
const exchEl = document.getElementById('local-exchange');
record.preference = parseInt(prefEl?.value) || 10;
record.exchange = exchEl?.value || '';
break;
case 'SRV':
record.priority = parseInt(document.getElementById('local-priority')?.value) || 0;
record.weight = parseInt(document.getElementById('local-weight')?.value) || 0;
record.port = parseInt(document.getElementById('local-port')?.value) || 0;
record.target = document.getElementById('local-target')?.value || '';
break;
case 'SOA':
record.mname = document.getElementById('local-mname')?.value || '';
record.rname = document.getElementById('local-rname')?.value || '';
record.serial = parseInt(document.getElementById('local-serial')?.value) || 0;
record.refresh = parseInt(document.getElementById('local-refresh')?.value) || 0;
record.retry = parseInt(document.getElementById('local-retry')?.value) || 0;
record.expire = parseInt(document.getElementById('local-expire')?.value) || 0;
record.minimum = parseInt(document.getElementById('local-minimum')?.value) || 0;
break;
case 'CAA':
record.flags = parseInt(document.getElementById('local-flags')?.value) || 0;
record.tag = document.getElementById('local-tag')?.value || '';
record.value = document.getElementById('local-value')?.value || '';
break;
default:
record.data = document.getElementById('local-data')?.value || '';
break;
}
const isEdit = window.editLocalIndex >= 0;
const url = isEdit ? '/api/update-local-dns' : '/api/add-local-dns';
const body = isEdit ? JSON.stringify({ index: window.editLocalIndex, record }) : JSON.stringify(record);
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body
});
if (!response.ok) {
throw new Error(await response.text());
}
if (window.showNotification) window.showNotification(isEdit ? 'Record updated successfully' : 'Record added successfully');
const modal = document.getElementById('localDnsModal');
if (modal) modal.close();
if (window.genericFetch) window.genericFetch('local-dns', true);
} catch (err) {
console.error('Failed to submit local DNS record:', err);
if (window.showNotification) window.showNotification('Failed to submit record: ' + err.message, 'error');
} finally {
buttonElement.disabled = false;
buttonElement.innerHTML = originalText;
}
}
function editLocalDns(index) {
openLocalDnsModal(index);
}
function deleteLocalDns(index) {
if (window.showConfirm) {
window.showConfirm('Delete this record?', async () => {
try {
const response = await fetch('/api/delete-local-dns', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ index })
});
if (!response.ok) {
throw new Error(await response.text());
}
if (window.showNotification) window.showNotification('Record deleted successfully');
if (window.genericFetch) window.genericFetch('local-dns', true);
} catch (err) {
console.error('Failed to delete local DNS record:', err);
if (window.showNotification) window.showNotification('Failed to delete record: ' + err.message, 'error');
}
});
}
}
async function toggleVersionPreference(domain, isPublic) {
try {
const version = isPublic ? 'public' : 'p2p';
const response = await fetch('/api/update-version-preference', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ domain, version })
});
if (!response.ok) {
throw new Error(await response.text());
}
if (window.showNotification) window.showNotification(`Version preference for ${domain} set to ${version}`);
if (window.genericFetch) window.genericFetch('dns-conflicts', true);
} catch (err) {
console.error('Failed to update version preference:', err);
if (window.showNotification) window.showNotification('Failed to update version preference: ' + err.message, 'error');
}
}
window.openLocalDnsModal = openLocalDnsModal;
window.updateLocalForm = updateLocalForm;
window.submitLocalDns = submitLocalDns;
window.editLocalDns = editLocalDns;
window.deleteLocalDns = deleteLocalDns;
window.toggleVersionPreference = toggleVersionPreference;