var recordsBuffer = []; var ownerSigning = ""; var ownerEncryption = ""; var availableZones = []; var myDomains = []; var currentZone; var currentSelectedKey = -1; var keysLoaded = []; document.addEventListener('click', function (event) { closeDropdowns(); }); function closeDropdowns(except) { // Get all elements with class="dropdowns" and hide them var dropdowns = document.getElementsByClassName("dropdown is-active"); for (i = 0; i < dropdowns.length; i++) { if (dropdowns[i] != except) { dropdowns[i].classList.remove('is-active'); } } } function addRecord(record) { recordsBuffer.push(record); refreshRecordsList(); } function delRecord(index) { recordsBuffer.splice(index, 1); refreshRecordsList(); } function refreshRecordsList() { var buf = ""; if (recordsBuffer.length > 0) { buf = "\n"; } function getInput(text) { if (typeof text === "string"){ // TODO sanitize } return ''; } function makeRecord(value, index, array) { var data = value.addr; if (value.type == "MX") { data = value.priority + " " + value.host; } else if (value.type == "CNAME") { data = value.host; } else if (value.type == "TXT") { data = value.data; } else if (value.type == "SRV") { data = value.priority + " " + value.weight + " " + value.port + " " + value.host; } var text = "
" + "" + "" + "" + "" + "" + "
"; buf += text.replace("{1}", value.domain) .replace("{2}", value.type) .replace("{3}", value.ttl) .replace("{4}", data) .replace("{5}", index); } recordsBuffer.forEach(makeRecord); document.getElementById("domain_records").innerHTML = buf; } function showNewRecordDialog() { var button_positive = document.getElementById("new_record_positive_button"); button_positive.onclick = function() { checkRecord(get_record_from_dialog()); }; var button_negative = document.getElementById("new_record_negative_button"); button_negative.onclick = function() { var dialog = document.getElementById("new_record_dialog"); dialog.className = "modal"; refreshRecordsList(); } var dialog = document.getElementById("new_record_dialog"); dialog.className = "modal is-active"; } function get_record_from_dialog() { var record_name = document.getElementById("record_name").value.toLowerCase(); var record_type = document.getElementById("record_type").value; var record_ttl = parseInt(document.getElementById("record_ttl").value); var record_data = document.getElementById("record_data").value; if (record_type == "CNAME" || record_type == "NS") { return { type: record_type, domain: record_name, ttl: record_ttl, host: record_data } } else if (record_type == "MX") { var record_priority = parseInt(document.getElementById("record_priority").value); return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, host: record_data } } else if (record_type == "TXT") { return { type: record_type, domain: record_name, ttl: record_ttl, data: record_data } } else if (record_type == "SRV") { var record_priority = parseInt(document.getElementById("record_priority").value); var record_weight = parseInt(document.getElementById("record_weight").value); var record_port = parseInt(document.getElementById("record_port").value); return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, weight: record_weight, port: record_port, host: record_data } } return { type: record_type, domain: record_name, ttl: record_ttl, addr: record_data } } function clearMyDomains() { myDomains = []; } function addMyDomain(name, timestamp, data) { myDomains.push({name: name, timestamp: timestamp, data: data}); } function refreshMyDomains() { var card = '

{title}

{tags}
'; var tag = '{domain}'; var cards = ""; myDomains.forEach(function(value, index, array) { var title = value.name; var domain_data = JSON.parse(value.data); var tags = ""; if (typeof domain_data.records !== 'undefined') { domain_data.records.forEach(function(v, i, a) { if (typeof v.domain !== 'undefined') { var buf = tag.replace("{domain}", v.domain); if (typeof v.addr !== 'undefined') { buf = buf.replace("{ip}", v.addr); } else if (typeof v.host !== 'undefined') { buf = buf.replace("{ip}", v.host); } tags = tags + buf; } }); } else { tags = tag.replace("{domain}", "No records").replace("{ip}", ""); } cards = cards + card.replace("{title}", title).replace("{domain}", title).replace("{tags}", tags); }); document.getElementById("my_domains").innerHTML = cards; } function editDomain(domain, event) { myDomains.forEach(function(value, index, array) { if (domain != value.name) { return; } var title = value.name; var domain_data = JSON.parse(value.data); recordsBuffer = []; if (typeof domain_data.records !== 'undefined') { domain_data.records.forEach(function(v, i, a) { recordsBuffer.push(v); }); } document.getElementById("new_domain").value = title.replace("." + domain_data.zone, ""); if (typeof domain_data.info !== 'undefined') { document.getElementById("info_text").value = domain_data.info; } if (typeof domain_data.contacts !== 'undefined') { var count = 1; domain_data.contacts.forEach(function(v, i, a) { document.getElementById("contact" + count + "_name").value = decodeURIComponent(v.name); document.getElementById("contact" + count + "_value").value = decodeURIComponent(v.value); count = count + 1; }); } changeZone(domain_data.zone, event); refreshRecordsList(); showNewDomainDialog(); }); } function onLoad() { // Workaround for Arch Linux Webkit // https://github.com/Boscop/web-view/issues/212#issuecomment-671055663 if (typeof window.external == 'undefined' || typeof window.external.invoke == 'undefined') { window.external = { invoke: function(x) { window.webkit.messageHandlers.external.postMessage(x); } }; } external.invoke(JSON.stringify({cmd: 'loaded'})); } function openTab(element, tabName) { // Declare all variables var i, tabContent, tabLinks; // Get all elements with class="content" and hide them tabContent = document.getElementsByClassName("tab row page"); for (i = 0; i < tabContent.length; i++) { tabContent[i].className = "tab row page is-hidden"; } // Get all elements with class="tab" and remove the class "is-active" tabLinks = document.getElementsByClassName("tab is-active"); for (i = 0; i < tabLinks.length; i++) { tabLinks[i].className = "tab"; } // Show the current tab, and add an "is-active" class to the button that opened the tab document.getElementById(tabName).className = "tab row page"; element.parentElement.className = "tab is-active"; refreshRecordsList(); } function toggle(element, event) { event.stopPropagation(); closeDropdowns(element); element.classList.toggle('is-active'); } function open_link(link) { external.invoke(JSON.stringify({cmd: 'open', link: link})); } function loadKey() { external.invoke(JSON.stringify({cmd: 'loadKey'})); } function createKey() { external.invoke(JSON.stringify({cmd: 'createKey'})); } function saveKey() { external.invoke(JSON.stringify({cmd: 'saveKey'})); } function checkRecord(data) { external.invoke(JSON.stringify({cmd: 'checkRecord', data: JSON.stringify(data)})); } function recordOkay(okay) { if (okay) { addRecord(get_record_from_dialog()); // It will refresh list var dialog = document.getElementById("new_record_dialog"); dialog.className = "modal"; } else { showWarning('Record is not valid!'); } } function showNewDomainDialog() { document.getElementById("new_domain_dialog").className = "modal is-active"; } function closeDialog(name) { document.getElementById(name).className = "modal"; } function createDomain() { if (typeof currentZone == 'undefined') { showWarning("Select a domain zone first"); return; } var new_domain = document.getElementById("new_domain").value.toLowerCase(); var domain = new_domain + "." + currentZone.name; var data = {}; data.encrypted = ""; data.zone = currentZone.name; data.info = document.getElementById("info_text").value; data.records = recordsBuffer; data.contacts = getContacts(); data = JSON.stringify(data); external.invoke(JSON.stringify({cmd: 'mineDomain', name: domain, data: data, signing: ownerSigning, encryption: ownerEncryption})); } function getContacts() { var result = []; for (var x = 1; x <= 3; x++) { var name = document.getElementById("contact" + x + "_name").value; var value = document.getElementById("contact" + x + "_value").value; if (name == "" || value == "") { continue; } var obj = {}; obj.name = encodeURIComponent(name.trim()); obj.value = encodeURIComponent(value.trim()); result.push(obj); } return result; } function domainMiningStarted() { //recordsBuffer = []; //refreshRecordsList(); document.getElementById("new_domain_dialog").className = "modal"; document.getElementById("tab_domains").disabled = true; document.getElementById("domain_records").disabled = true; document.getElementById("add_record_button").disabled = true; document.getElementById("new_domain_button").disabled = true; document.getElementById("new_key_button").disabled = true; } function domainMiningUnavailable() { //recordsBuffer = []; //refreshRecordsList(); document.getElementById("new_domain_dialog").className = "modal"; document.getElementById("tab_domains").disabled = false; document.getElementById("domain_records").disabled = false; document.getElementById("add_record_button").disabled = false; document.getElementById("new_domain_button").disabled = false; document.getElementById("new_key_button").disabled = false; } function sendAction(param) { external.invoke(JSON.stringify(param)); } function onDomainChange(element) { if (typeof currentZone !== 'undefined') { var domain = element.value + "." + currentZone.name; external.invoke(JSON.stringify({cmd: 'checkDomain', name: domain})); } } function domainAvailable(available) { var input = document.getElementById("new_domain"); var button = document.getElementById("new_domain_button"); var button2 = document.getElementById("add_record_button"); if (available) { input.className = "input"; button.disabled = false button2.disabled = false } else { input.className = "input is-danger"; button.disabled = true button2.disabled = true } } function showModalDialog(text, callback) { var message = document.getElementById("modal_text"); message.textContent = text; var button_positive = document.getElementById("modal_positive_button"); button_positive.onclick = function() { callback(); dialog = document.getElementById("modal_dialog"); dialog.className = "modal"; }; var button_negative = document.getElementById("modal_negative_button"); button_negative.onclick = function() { dialog = document.getElementById("modal_dialog"); dialog.className = "modal"; } var dialog = document.getElementById("modal_dialog"); dialog.className = "modal is-active"; } function showOwnerDialog() { var dialog = document.getElementById("owner_dialog"); dialog.className = "modal is-active"; } function isValidOwner(text) { if (text.length != 64) { return false; } var regexp = /^[0-9A-F]{64}$/i; return regexp.test(text); } function ownerPositiveButton() { var signing = document.getElementById("owner_signing").value; var encryption = document.getElementById("owner_encryption").value; if (signing != "" && encryption != "") { if (isValidOwner(signing) && isValidOwner(encryption)) { ownerSigning = signing; ownerEncryption = encryption; } else { alert("Wrong owner '{}'!".replace("{}", value)); wrong = true; return; } } else { ownerSigning = ""; ownerEncryption = ""; } var dialog = document.getElementById("owner_dialog"); dialog.className = "modal"; } function ownerCancelButton() { var dialog = document.getElementById("owner_dialog"); dialog.className = "modal"; } function showContactsDialog() { var dialog = document.getElementById("contacts_dialog"); dialog.className = "modal is-active"; } function contactsPositiveButton() { var dialog = document.getElementById("contacts_dialog"); dialog.className = "modal"; } function contactsNegativeButton() { var dialog = document.getElementById("contacts_dialog"); dialog.className = "modal"; } function showDomainInfoDialog() { var dialog = document.getElementById("info_dialog"); dialog.className = "modal is-active"; } function infoPositiveButton() { var dialog = document.getElementById("info_dialog"); dialog.className = "modal"; } function infoNegativeButton() { var dialog = document.getElementById("info_dialog"); dialog.className = "modal"; } function showWarning(text) { var warning = document.getElementById("notification_warning"); var message = document.getElementById("warning_text"); message.innerHTML = text; warning.className = "notification mini is-warning"; var button = document.getElementById("warning_close"); button.onclick = function() { message.value = ""; warning.className = "notification mini is-warning is-hidden"; } setTimeout(button.onclick, 5000); } function showSuccess(text) { var warning = document.getElementById("notification_success"); var message = document.getElementById("success_text"); message.innerHTML = text; warning.className = "notification mini is-success"; var button = document.getElementById("success_close"); button.onclick = function() { message.value = ""; warning.className = "notification mini is-success is-hidden"; } } function showMiningIndicator(visible, blue) { var indicator = document.getElementById("busy_indicator"); var parent = document.getElementById("indicator_parent"); var add = ""; if (blue) { add = " busy_blue"; } if (visible) { indicator.className = 'busy_indicator' + add; parent.style.display = 'flex'; } else { indicator.className = 'busy_indicator is-hidden'; parent.style.display = 'none'; document.getElementById("tab_domains").disabled = false; document.getElementById("domain_records").disabled = false; document.getElementById("add_record_button").disabled = false; document.getElementById("new_domain_button").disabled = false; document.getElementById("new_key_button").disabled = false; } } function miningIndicatorClick(element) { showModalDialog("Do you really want to stop mining?", function() { external.invoke(JSON.stringify({cmd: 'stopMining'})); }); } function setLeftStatusBarText(text) { var bar = document.getElementById("status_bar_left"); bar.innerHTML = text; } function setRightStatusBarText(text) { var bar = document.getElementById("status_bar_right"); bar.innerHTML = text; } function addEvent(type, time, message) { var t = ""; if (type == 'warn') { t = "is-warning"; } else if (type == 'fail') { t = "is-danger"; } else if (type == 'luck') { t = "is-success"; } var html = "
{time}  {text}
"; var buf = html.replace("{type}", t).replace("{time}", time).replace("{text}", message); var tab_events = document.getElementById("tab_events"); tab_events.innerHTML = tab_events.innerHTML + buf; } function keystoreChanged(path, pub_key, hash) { if (path == '') { path = "In memory"; } var public_key_field = document.getElementById("public_key"); public_key_field.value = pub_key; public_key_field.title = path + "\n" + hash; var save_key = document.getElementById("save_key").disabled = false; var new_domain = document.getElementById("new_domain").disabled = false; } function refreshZonesList() { var buf = ""; availableZones.sort(function compare(rhs, lhs) { if (rhs.name < lhs.name) { return -1; } else if (rhs.name > lhs.name) { return 1; } else { return 0; } }); availableZones.forEach(function(value, index, array) { var note = ""; if (value.yggdrasil) { note = "*"; } var zone = value.name + note; var add_class = ""; if (typeof currentZone !== 'undefined' && currentZone.name == value.name) { add_class = "is-active"; } buf += ".{4}" .replace("{1}", value.name) .replace("{2}", add_class) .replace("{3}", value.name) .replace("{4}", zone); }); var links = document.getElementById("zones-links"); links.innerHTML = buf; if (typeof currentZone !== 'undefined') { var cur_name = document.getElementById("zones-current-name"); var name = "." + currentZone.name; if (currentZone.yggdrasil) { name = name + "*"; } cur_name.innerHTML = name; } } function zonesChanged(text) { availableZones = JSON.parse(text); refreshZonesList(); } function changeZone(zone, event) { event.stopPropagation(); closeDropdowns(); availableZones.forEach(function(value, index, array) { if (value.name == zone) { currentZone = value; } }); refreshZonesList(); } function refreshKeysMenu() { var buf = ""; keysLoaded.forEach(function(value, index, array) { var file_name = value.file_name; if (file_name == "") { file_name = "[Not saved]"; } var public = value.public; var add_class = ""; if (currentSelectedKey == index) { add_class = "is-active"; } buf += "{name}" .replace("{id}", index) .replace("{index}", index) .replace("{class}", add_class) .replace("{title}", public) .replace("{name}", file_name); }); var links = document.getElementById("keys_links"); links.innerHTML = buf; if (currentSelectedKey >= 0) { var cur_name = document.getElementById("keys_current_name"); if (keysLoaded[currentSelectedKey].file_name == "") { cur_name.innerHTML = "[Not saved]"; } else { cur_name.innerHTML = keysLoaded[currentSelectedKey].file_name; } } } function keysChanged(json) { keysLoaded = JSON.parse(json); refreshKeysMenu(); } function selectKey(index, event) { event.stopPropagation(); closeDropdowns(); if (currentSelectedKey != index) { external.invoke(JSON.stringify({cmd: 'selectKey', index: parseInt(index)})); } } function keySelected(index) { currentSelectedKey = index; refreshKeysMenu(); }