const form = document.getElementById("dnsForm"); const domainInput = document.getElementById("domainInput"); const recordDropdown = document.getElementById("recordDropdown"); const recordTrigger = document.getElementById("recordTrigger"); const recordMenu = document.getElementById("recordMenu"); const selectedRecord = document.getElementById("selectedRecord"); const selectedRecordDesc = document.getElementById("selectedRecordDesc"); const checkButton = document.getElementById("checkButton"); const errorBox = document.getElementById("errorBox"); const resultsContainer = document.getElementById("resultsContainer"); const userIpText = document.getElementById("userIpText"); let selectedRecordType = "A"; function showError(message) { errorBox.style.display = "block"; errorBox.textContent = message; } function hideError() { errorBox.style.display = "none"; errorBox.textContent = ""; } function formatDnsError(error) { if (!error) { return "DNS lookup failed."; } if ( error === "ESERVFAIL" || error === "SERVFAIL" || error.includes("server failed") ) { return "Destination DNS server did not respond with a valid answer."; } if (error.includes("No") && error.includes("record found")) { return error; } if (error.includes("Domain not found")) { return "Domain was not found."; } if (error.includes("timed out") || error.includes("TIMEOUT")) { return "DNS lookup timed out."; } return error; } function isPrivateIp(ip) { if (typeof ip !== "string") return false; const parts = ip.split(".").map(Number); if (parts.length !== 4 || parts.some(part => Number.isNaN(part))) { return false; } const a = parts[0]; const b = parts[1]; return ( a === 10 || a === 127 || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 169 && b === 254) || (a === 100 && b >= 64 && b <= 127) ); } async function copyToClipboard(text, button) { const oldText = button.textContent; function showCopied() { button.textContent = "Copied"; button.classList.add("copied"); setTimeout(() => { button.textContent = oldText; button.classList.remove("copied"); }, 1200); } function showFailed() { button.textContent = "Failed"; setTimeout(() => { button.textContent = oldText; }, 1200); } try { if (navigator.clipboard && window.isSecureContext) { await navigator.clipboard.writeText(text); showCopied(); return; } const textarea = document.createElement("textarea"); textarea.value = text; textarea.setAttribute("readonly", ""); textarea.style.position = "fixed"; textarea.style.top = "-9999px"; textarea.style.left = "-9999px"; document.body.appendChild(textarea); textarea.focus(); textarea.select(); const successful = document.execCommand("copy"); document.body.removeChild(textarea); if (successful) { showCopied(); } else { showFailed(); } } catch (err) { showFailed(); } } function createAnswersHtml(result) { if (result.status !== "success") { return `
${formatDnsError(result.error)}
`; } if (!result.answers || result.answers.length === 0) { return '
No records found.
'; } return result.answers .map(answer => { const value = typeof answer === "object" ? JSON.stringify(answer) : String(answer); const warning = isPrivateIp(value) ? `
Private / internal IP detected. This domain may be redirected by the local resolver or network.
` : ""; return `
${escapeHtml(value)}
${warning}
`; }) .join(""); } function escapeHtml(value) { return String(value) .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } function createResultCard(item, query) { const dcText = item.location.datacenter ? ` — ${item.location.datacenter}` : ""; const locationText = `${item.location.country} / ${item.location.city}${dcText}`; const isSuccess = item.result.status === "success"; return `
${escapeHtml(locationText)}
${escapeHtml(query.domain)} · ${escapeHtml(query.type)}
${escapeHtml(item.location.sourceLabel || item.location.sourceType || "DNS check")}
${isSuccess ? "success" : "error"}
${createAnswersHtml(item.result)}
Response time: ${item.gatewayTimeMs ?? "-"} ms
`; } function renderResults(results, query) { resultsContainer.innerHTML = ""; const ownedResults = results.filter(item => item.location.sourceType === "owned"); const externalResults = results.filter(item => item.location.sourceType === "external"); if (ownedResults.length > 0) { resultsContainer.insertAdjacentHTML( "beforeend", `
Our DNS checks
` ); ownedResults.forEach(item => { resultsContainer.insertAdjacentHTML("beforeend", createResultCard(item, query)); }); } if (externalResults.length > 0) { resultsContainer.insertAdjacentHTML( "beforeend", `
External DNS checks
` ); externalResults.forEach(item => { resultsContainer.insertAdjacentHTML("beforeend", createResultCard(item, query)); }); } resultsContainer.querySelectorAll(".copy-button").forEach(button => { button.addEventListener("click", () => { copyToClipboard(button.dataset.copy, button); }); }); } recordTrigger.addEventListener("click", () => { recordDropdown.classList.toggle("open"); }); recordMenu.querySelectorAll(".select-option").forEach(option => { option.addEventListener("click", () => { selectedRecordType = option.dataset.value; selectedRecord.textContent = option.dataset.value; selectedRecordDesc.textContent = option.dataset.desc; recordMenu.querySelectorAll(".select-option").forEach(item => { item.classList.remove("active"); }); option.classList.add("active"); recordDropdown.classList.remove("open"); }); }); async function loadUserIp() { if (!userIpText) return; try { const response = await fetch("/api/client-ip"); const data = await response.json(); userIpText.textContent = `Your IP: ${data.ip || "Unknown"}`; } catch (err) { userIpText.textContent = "Your IP: unavailable"; } } loadUserIp(); document.addEventListener("click", event => { if (!recordDropdown.contains(event.target)) { recordDropdown.classList.remove("open"); } }); form.addEventListener("submit", async event => { event.preventDefault(); hideError(); recordDropdown.classList.remove("open"); const domain = domainInput.value.trim().toLowerCase(); const type = selectedRecordType; if (!domain) { showError("Please enter a domain."); return; } checkButton.disabled = true; checkButton.textContent = "Checking..."; try { const response = await fetch( `/api/check?domain=${encodeURIComponent(domain)}&type=${encodeURIComponent(type)}` ); const data = await response.json(); if (!response.ok || data.status !== "success") { showError(data.error || "Request failed."); return; } renderResults(data.results, data.query); } catch (err) { showError(err.message || "Network error."); } finally { checkButton.disabled = false; checkButton.textContent = "Check DNS"; } });