/** * configuration.js - Copyright(C) 2021 Donald Zou [https://github.com/donaldzou] * Under Apache-2.0 License */ /** * This will load peers data from server * @param search */ function load_data(search){ startProgressBar(); let result = ''; $.ajax({ method: "GET", url: "/get_config/"+conf_name+"?search="+encodeURIComponent(search), headers:{ "Content-Type": "application/json" }, success: function (response){ removeNoResponding(); peers = response.peer_data; if (response.listen_port === "" && response.status === "stopped"){ $("config_info_alert").append(''); } if (response.conf_address === "N/A"){ $("config_info_alert").append(''); } let $conf_status_btn = $("#conf_status_btn"); if (response.checked === "checked"){ $conf_status_btn.html(' ON'); }else{ $conf_status_btn.html(' OFF'); } $("#sort_by_dropdown option").removeAttr("selected"); $("#sort_by_dropdown option[value="+response.sort_tag+"]").attr("selected", "selected"); $(".interval-btn-group button").removeClass("active"); $("button[data-refresh-interval="+response.dashboard_refresh_interval+"]").addClass("active"); $(".display-btn-group button").removeClass("active"); $("button[data-display-mode="+response.peer_display_mode+"]").addClass("active"); $("#conf_status").html(response.status+''); $("#conf_connected_peers").html(response.running_peer); $("#conf_total_data_usage").html(response.total_data_usage[0] +" GB"); $("#conf_total_data_received").html(response.total_data_usage[2] +" GB"); $("#conf_total_data_sent").html(response.total_data_usage[1]+" GB"); $("#conf_public_key").html(response.public_key); $("#conf_listen_port").html(response.listen_port === "" ? "N/A":response.listen_port); $("#conf_address").html(response.conf_address); $(".info h6").removeClass("info_loading"); $conf_status_btn.removeClass("info_loading"); if (response.peer_data.length === 0){ $(".peer_list").html('

Oops! No peers found ‘︿’

'); }else{ let display_mode = response.peer_display_mode === "list" ? "col-12" : "col-sm-6 col-lg-4"; response.peer_data.forEach(function(peer){ let total_r = 0; let total_s = 0; total_r += peer.cumu_receive; total_s += peer.cumu_sent; let spliter = '
'; let peer_name = '
' + '
'+ (peer.name === "" ? "Untitled" : peer.name) +'
' + '
' + '
'; let peer_transfer = '

'+ roundN(peer.total_receive + total_r, 4) +' GB

'+ roundN(peer.total_sent + total_s, 4) +' GB

'; let peer_key = '
PEERCLICK TO COPY
'+peer.id+'
'; let peer_allowed_ip = '
ALLOWED IP
'+peer.allowed_ip+'
'; let peer_latest_handshake = '
LATEST HANDSHAKE
'+peer.latest_handshake+'
'; let peer_endpoint = '
END POINT
'+peer.endpoint+'
'; let peer_control = '

'; if (peer.private_key !== ""){ peer_control += ''; } peer_control += '
'; let html = '
' + '
' + '
' + '
' + peer_name + spliter + peer_transfer + peer_key + peer_allowed_ip + peer_latest_handshake + spliter + peer_endpoint + spliter + peer_control + '
' + '
' + '
' + '
'; result += html; }); $(".peer_list").html(result); if (response.dashboard_refresh_interval !== load_interval){ load_interval = response.dashboard_refresh_interval; clearInterval(load_timeout); load_timeout = setInterval(function (){ load_data($('#search_peer_textbox').val()); }, response.dashboard_refresh_interval); } } $(".dot.dot-running").attr("title","Peer Connected").tooltip(); $(".dot.dot-stopped").attr("title","Peer Disconnected").tooltip(); $("i[data-toggle='tooltip']").tooltip(); endProgressBar(); } }).fail(function(){ noResponding(); }); } function noResponding(){ $(".no-response").addClass("active"); setTimeout(function (){ $(".no-response").addClass("show"); $("#right_body").addClass("no-responding"); $(".navbar").addClass("no-responding"); },10); } function removeNoResponding(){ $(".no-response").removeClass("show"); $("#right_body").removeClass("no-responding"); $(".navbar").removeClass("no-responding"); setTimeout(function (){ $(".no-response").removeClass("active"); },1010); } $("[data-toggle='tooltip']").tooltip(); $("[data-toggle='popover']").popover(); let $body = $("body"); let $progress_bar = $(".progress-bar"); let available_ips = []; let $save_peer = $("#save_peer"); $(".add_btn").on("click", function(){ $addModal.toggle(); }); /** * Round Transfer number into 4 digits * @param value * @param digits * @returns {number} */ function roundN(value, digits) { let tenToN = 10 ** digits; return (Math.round(value * tenToN)) / tenToN; } /** * Start Progress Bar */ function startProgressBar(){ $progress_bar.css("width","0%") .css("opacity", "100") .css("background", "rgb(255,69,69)") .css("background", "linear-gradient(145deg, rgba(255,69,69,1) 0%, rgba(0,115,186,1) 100%)") .css("width","25%"); setTimeout(function(){ stillLoadingProgressBar(); },300); } /** * Still Loading Progress Bar */ function stillLoadingProgressBar(){ $progress_bar.css("transition", "3s ease-in-out").css("width", "75%"); } /** * End Progress Bae */ function endProgressBar(){ $progress_bar.css("transition", "0.3s ease-in-out").css("width","100%"); setTimeout(function(){ $progress_bar.css("opacity", "0"); },250); } /** * Show toast * @param msg */ function showToast(msg) { $('#alertToast').toast('show'); $('#alertToast .toast-body').html(msg); } /** * When configuration switch got click */ $body.on("click", ".switch", function (){ $(this).siblings($(".spinner-border")).css("display", "inline-block"); $(this).remove(); location.replace("/switch/"+$(this).attr('id')); }); /** * Generate Private and Public key for a new peer */ function generate_key(){ let keys = wireguard.generateKeypair(); $("#private_key").val(keys.privateKey); $("#public_key").val(keys.publicKey); $("#add_peer_alert").addClass("d-none"); $("#re_generate_key i").removeClass("rotating"); $("#enable_preshare_key").val(keys.presharedKey); } /** * Generate Public key when private got change */ $("#private_key").on("change",function(){ if ($(this).val().length === 44){ $("#re_generate_key i").addClass("rotating"); $("#public_key").val(wireguard.generatePublicKey($("#private_key").val())); }else{ $("#public_key").removeAttr("disabled").val(""); } }); /** * Trigger IP badge and item * @param ip */ function trigger_ip(ip){ let $ip_ele = $(".available-ip-item[data-ip='"+ip+"']"); if ($ip_ele.html()){ if ($ip_ele.hasClass("active")){ $ip_ele.removeClass("active"); $("#selected_ip_list .badge[data-ip='"+ip+"']").remove(); }else{ $ip_ele.addClass("active"); $("#selected_ip_list").append(''+ip+'') } } } /** * Get all available IP for this configuration */ function get_available_ip(){ $.ajax({ "url": "/available_ips/"+$save_peer.attr("conf_id"), "method": "GET", }).done(function (res) { available_ips = res; let $list_group = $("#available_ip_modal .modal-body .list-group"); $list_group.html(""); $("#allowed_ips").val(available_ips[0]); available_ips.forEach((ip) => $list_group.append(''+ip+'')); }); } $("#available_ip_modal").on("show.bs.modal", () => { $('#add_modal').addClass("ip_modal_open"); }).on("hidden.bs.modal", function () { $('#add_modal').removeClass("ip_modal_open"); let ips = []; let $selected_ip_list = $("#selected_ip_list"); $selected_ip_list.children().each(function(){ ips.push($(this).data("ip")); }); ips.forEach((ele) => trigger_ip(ele)); }) /** * When IP Badge got click */ $body.on("click", ".available-ip-badge", function(){ $(".available-ip-item[data-ip='"+$(this).data("ip")+"']").removeClass("active"); $(this).remove(); }) /** * When available ip item got click */ $body.on("click", ".available-ip-item", function () { trigger_ip($(this).data("ip")); }); let $ipModal = new bootstrap.Modal(document.getElementById('available_ip_modal'), { keyboard: false, backdrop: 'static' }); $("#search_available_ip").on("click", function () { $ipModal.toggle(); let $allowed_ips = $("#allowed_ips"); if ($allowed_ips.val().length > 0){ let s = $allowed_ips.val().split(","); for (let i = 0; i < s.length; i++){ s[i] = s[i].trim(); trigger_ip(s[i]); } } }).tooltip(); $("#confirm_ip").on("click", () => { $ipModal.toggle(); let ips = []; let $selected_ip_list = $("#selected_ip_list"); $selected_ip_list.children().each(function(){ ips.push($(this).data("ip")); }); $("#allowed_ips").val(ips.join(", ")); ips.forEach((ele) => trigger_ip(ele)); }); $("#allowed_ips").on("keyup", function(){ let s = clean_ip($(this).val()); s = s.split(","); if (available_ips.includes(s[s.length - 1])){ $("#allowed_ips_indicator").removeClass().addClass("text-success") .html(''); }else{ $("#allowed_ips_indicator").removeClass().addClass("text-warning") .html(''); } }) $('#add_modal').on('show.bs.modal', function (event) { generate_key(); get_available_ip(); }).on('hide.bs.modal', function(){ $("#allowed_ips_indicator").html(''); }); $("#re_generate_key").on("click",function (){ $("#public_key").attr("disabled","disabled"); $("#re_generate_key i").addClass("rotating"); generate_key(); }); let $addModal = new bootstrap.Modal(document.getElementById('add_modal'), { keyboard: false, backdrop: 'static' }); function clean_ip(val){ let clean_ip = val.split(','); for (let i = 0; i < clean_ip.length; i++) clean_ip[i] = clean_ip[i].trim(' '); return clean_ip.filter(Boolean).join(","); } $("#new_add_amount").on("keyup", function(){ let $bulk_amount_validation = $("#bulk_amount_validation"); // $(this).removeClass("is-valid").addClass("is-invalid"); if ($(this).val().length > 0){ if (isNaN($(this).val())){ $(this).removeClass("is-valid").addClass("is-invalid"); $bulk_amount_validation.html("Please enter a valid integer"); }else if ($(this).val() > available_ips.length){ $(this).removeClass("is-valid").addClass("is-invalid"); $bulk_amount_validation.html(`Cannot create more than ${available_ips.length} peers.`); }else if ($(this).val() < 1){ $(this).removeClass("is-valid").addClass("is-invalid"); $bulk_amount_validation.html("Please enter at least 1 or more."); }else{ $(this).removeClass("is-invalid").addClass("is-valid"); } }else{ $(this).removeClass("is-invalid").removeClass("is-valid"); } }); function bulk_add_peers() { let $new_add_amount = $("#new_add_amount"); $save_peer.attr("disabled","disabled"); $save_peer.html("Adding "+$new_add_amount.val()+" peers..."); let $new_add_DNS = $("#new_add_DNS"); $new_add_DNS.val(clean_ip($new_add_DNS.val())); let $new_add_endpoint_allowed_ip = $("#new_add_endpoint_allowed_ip"); $new_add_endpoint_allowed_ip.val(clean_ip($new_add_endpoint_allowed_ip.val())); let $new_add_MTU = $("#new_add_MTU"); let $new_add_keep_alive = $("#new_add_keep_alive"); let $enable_preshare_key = $("#enable_preshare_key"); let data_list = [$new_add_DNS, $new_add_endpoint_allowed_ip,$new_add_MTU, $new_add_keep_alive]; if ($new_add_amount.val() > 0 && !$new_add_amount.hasClass("is-invalid")){ if ($new_add_DNS.val() !== "" && $new_add_endpoint_allowed_ip.val() !== ""){ let conf = $save_peer.attr('conf_id'); let keys = []; for (let i = 0; i < $new_add_amount.val(); i++) { keys.push(wireguard.generateKeypair()); } $.ajax({ method: "POST", url: "/add_peer_bulk/"+conf, headers:{ "Content-Type": "application/json" }, data: JSON.stringify({ "DNS": $new_add_DNS.val(), "endpoint_allowed_ip": $new_add_endpoint_allowed_ip.val(), "MTU": $new_add_MTU.val(), "keep_alive": $new_add_keep_alive.val(), "enable_preshared_key": $enable_preshare_key.prop("checked"), "keys": keys, "amount": $new_add_amount.val() }), success: function (response){ if(response !== "true"){ $("#add_peer_alert").html(response).removeClass("d-none"); data_list.forEach((ele) => ele.removeAttr("disabled")); $save_peer.removeAttr("disabled").html("Save"); } else{ load_data(""); data_list.forEach((ele) => ele.removeAttr("disabled")); $("#add_peer_form").trigger("reset"); $save_peer.removeAttr("disabled").html("Save"); showToast($new_add_amount.val()+" peers added successful!"); $addModal.toggle(); } } }); }else{ $("#add_peer_alert").html("Please fill in all required box.").removeClass("d-none"); $save_peer.removeAttr("disabled"); $save_peer.html("Add"); } }else{ $save_peer.removeAttr("disabled").html("Add"); } } $save_peer.on("click",function(){ let $bulk_add = $("#bulk_add"); if ($bulk_add.prop("checked")){ if (!$("#new_add_amount").hasClass("is-invalid")){ bulk_add_peers() } }else { let $public_key = $("#public_key"); let $private_key = $("#private_key"); let $allowed_ips = $("#allowed_ips"); $allowed_ips.val(clean_ip($allowed_ips.val())); let $new_add_DNS = $("#new_add_DNS"); $new_add_DNS.val(clean_ip($new_add_DNS.val())); let $new_add_endpoint_allowed_ip = $("#new_add_endpoint_allowed_ip"); $new_add_endpoint_allowed_ip.val(clean_ip($new_add_endpoint_allowed_ip.val())); let $new_add_name = $("#new_add_name"); let $new_add_MTU = $("#new_add_MTU"); let $new_add_keep_alive = $("#new_add_keep_alive"); let $enable_preshare_key = $("#enable_preshare_key"); $(this).attr("disabled","disabled"); $(this).html("Adding..."); if ($allowed_ips.val() !== "" && $public_key.val() !== "" && $new_add_DNS.val() !== "" && $new_add_endpoint_allowed_ip.val() !== ""){ let conf = $(this).attr('conf_id'); let data_list = [$private_key, $allowed_ips, $new_add_name, $new_add_DNS, $new_add_endpoint_allowed_ip,$new_add_MTU, $new_add_keep_alive]; data_list.forEach((ele) => ele.attr("disabled", "disabled")); $.ajax({ method: "POST", url: "/add_peer/"+conf, headers:{ "Content-Type": "application/json" }, data: JSON.stringify({ "private_key":$private_key.val(), "public_key":$public_key.val(), "allowed_ips": $allowed_ips.val(), "name":$new_add_name.val(), "DNS": $new_add_DNS.val(), "endpoint_allowed_ip": $new_add_endpoint_allowed_ip.val(), "MTU": $new_add_MTU.val(), "keep_alive": $new_add_keep_alive.val(), "enable_preshared_key": $enable_preshare_key.prop("checked"), "preshared_key": $enable_preshare_key.val() }), success: function (response){ if(response !== "true"){ $("#add_peer_alert").html(response).removeClass("d-none"); data_list.forEach((ele) => ele.removeAttr("disabled")); $save_peer.removeAttr("disabled").html("Save"); } else{ load_data(""); data_list.forEach((ele) => ele.removeAttr("disabled")); $("#add_peer_form").trigger("reset"); $save_peer.removeAttr("disabled").html("Save"); showToast("Add peer successful!"); $addModal.toggle(); } } }); }else{ $("#add_peer_alert").html("Please fill in all required box.").removeClass("d-none"); $(this).removeAttr("disabled"); $(this).html("Add"); } } }); // QR Code let qrcodeModal = new bootstrap.Modal(document.getElementById('qrcode_modal'), { keyboard: false }); $body.on("click", ".btn-qrcode-peer", function (){ let src = $(this).attr('img_src'); $.ajax({ "url": src, "method": "GET" }).done(function(res){ $("#qrcode_img").attr('src', res); qrcodeModal.toggle(); }); }); // Delete Peer Modal let deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), { keyboard: false, backdrop: 'static' }); $body.on("click", ".btn-delete-peer", function(){ let peer_id = $(this).attr("id"); $("#delete_peer").attr("peer_id", peer_id); deleteModal.toggle(); }); $("#delete_peer").on("click",function(){ $(this).attr("disabled","disabled"); $(this).html("Deleting..."); let peer_id = $(this).attr("peer_id"); let config = $(this).attr("conf_id"); let peer_ids = [peer_id]; deletePeers(config, peer_ids); }); function deletePeers(config, peer_ids){ $.ajax({ method: "POST", url: "/remove_peer/"+config, headers:{ "Content-Type": "application/json" }, data: JSON.stringify({"action": "delete", "peer_ids": peer_ids}), success: function (response){ if(response !== "true"){ if (deleteModal._isShown) { $("#remove_peer_alert").html(response+$("#add_peer_alert").html()) .removeClass("d-none"); } if (deleteBulkModal._isShown){ $("#bulk_remove_peer_alert").html(response+$("#bulk_remove_peer_alert").html()) .removeClass("d-none"); } } else{ if (deleteModal._isShown) { deleteModal.toggle() } if (deleteBulkModal._isShown){ $("#confirm_delete_bulk_peers").removeAttr("disabled").html("Delete"); $("#selected_peer_list").html(''); $(".delete-bulk-peer-item.active").removeClass('active'); deleteBulkModal.toggle(); } load_data($('#search_peer_textbox').val()); $('#alertToast').toast('show'); $('#alertToast .toast-body').html("Peer deleted!"); $("#delete_peer").removeAttr("disabled").html("Delete"); } } }); } // Peer Setting Modal let settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), { keyboard: false, backdrop: 'static' }); $body.on("click", ".btn-setting-peer", function(){ startProgressBar(); let peer_id = $(this).attr("id"); $("#save_peer_setting").attr("peer_id", peer_id); $.ajax({ method: "POST", url: "/get_peer_data/"+$("#setting_modal").attr("conf_id"), headers:{ "Content-Type": "application/json" }, data: JSON.stringify({"id": peer_id}), success: function(response){ let peer_name = ((response.name === "") ? "Untitled Peer" : response.name); $("#setting_modal .peer_name").html(peer_name); $("#setting_modal #peer_name_textbox").val(response.name); $("#setting_modal #peer_private_key_textbox").val(response.private_key); $("#setting_modal #peer_DNS_textbox").val(response.DNS); $("#setting_modal #peer_allowed_ip_textbox").val(response.allowed_ip); $("#setting_modal #peer_endpoint_allowed_ips").val(response.endpoint_allowed_ip); $("#setting_modal #peer_mtu").val(response.mtu); $("#setting_modal #peer_keep_alive").val(response.keep_alive); $("#setting_modal #peer_preshared_key_textbox").val(response.preshared_key); settingModal.toggle(); endProgressBar(); } }); }); $('#setting_modal').on('hidden.bs.modal', function (event) { $("#setting_peer_alert").addClass("d-none"); }); $("#peer_private_key_textbox").on("change",function(){ let $save_peer_setting = $("#save_peer_setting"); if ($(this).val().length > 0){ $.ajax({ "url": "/check_key_match/"+$save_peer_setting.attr("conf_id"), "method": "POST", "headers":{"Content-Type": "application/json"}, "data": JSON.stringify({ "private_key": $("#peer_private_key_textbox").val(), "public_key": $save_peer_setting.attr("peer_id") }) }).done(function(res){ if(res.status === "failed"){ $("#setting_peer_alert").html(res.status).removeClass("d-none"); }else{ $("#setting_peer_alert").addClass("d-none"); } }); } }); $("#save_peer_setting").on("click",function (){ $(this).attr("disabled","disabled"); $(this).html("Saving..."); let $peer_DNS_textbox = $("#peer_DNS_textbox"); let $peer_allowed_ip_textbox = $("#peer_allowed_ip_textbox"); let $peer_endpoint_allowed_ips = $("#peer_endpoint_allowed_ips"); let $peer_name_textbox = $("#peer_name_textbox"); let $peer_private_key_textbox = $("#peer_private_key_textbox"); let $peer_preshared_key_textbox = $("#peer_preshared_key_textbox"); let $peer_mtu = $("#peer_mtu"); let $peer_keep_alive = $("#peer_keep_alive"); if ($peer_DNS_textbox.val() !== "" && $peer_allowed_ip_textbox.val() !== "" && $peer_endpoint_allowed_ips.val() !== ""){ let peer_id = $(this).attr("peer_id"); let conf_id = $(this).attr("conf_id"); let data_list = [$peer_name_textbox, $peer_DNS_textbox, $peer_private_key_textbox, $peer_preshared_key_textbox, $peer_allowed_ip_textbox, $peer_endpoint_allowed_ips, $peer_mtu, $peer_keep_alive]; data_list.forEach((ele) => ele.attr("disabled","disabled")); $.ajax({ method: "POST", url: "/save_peer_setting/"+conf_id, headers:{ "Content-Type": "application/json" }, data: JSON.stringify({ id: peer_id, name: $peer_name_textbox.val(), DNS: $peer_DNS_textbox.val(), private_key: $peer_private_key_textbox.val(), allowed_ip: $peer_allowed_ip_textbox.val(), endpoint_allowed_ip: $peer_endpoint_allowed_ips.val(), MTU: $peer_mtu.val(), keep_alive: $peer_keep_alive.val(), preshared_key: $peer_preshared_key_textbox.val() }), success: function (response){ if (response.status === "failed"){ $("#setting_peer_alert").html(response.msg).removeClass("d-none"); }else{ settingModal.toggle(); load_data($('#search_peer_textbox').val()); $('#alertToast').toast('show'); $('#alertToast .toast-body').html("Peer Saved!"); } $("#save_peer_setting").removeAttr("disabled").html("Save"); data_list.forEach((ele) => ele.removeAttr("disabled")); } }); }else{ $("#setting_peer_alert").html("Please fill in all required box.").removeClass("d-none"); $("#save_peer_setting").removeAttr("disabled").html("Save"); } }); $(".peer_private_key_textbox_switch").on("click",function (){ let $peer_private_key_textbox = $("#peer_private_key_textbox"); let mode = (($peer_private_key_textbox.attr('type') === 'password') ? "text":"password"); let icon = (($peer_private_key_textbox.attr('type') === 'password') ? "bi bi-eye-slash-fill":"bi bi-eye-fill"); $peer_private_key_textbox.attr('type',mode); $(".peer_private_key_textbox_switch i").removeClass().addClass(icon); }); // Search Peer let typingTimer; let doneTypingInterval = 200; let $input = $('#search_peer_textbox'); $input.on('keyup', function () { clearTimeout(typingTimer); typingTimer = setTimeout(doneTyping, doneTypingInterval); }); $input.on('keydown', function () { clearTimeout(typingTimer); }); function doneTyping () { load_data($input.val()); } // Sorting $body.on("change", "#sort_by_dropdown", function (){ $.ajax({ method:"POST", data: JSON.stringify({'sort':$("#sort_by_dropdown option:selected").val()}), headers:{"Content-Type": "application/json"}, url: "/update_dashboard_sort", success: function (res){ load_data($('#search_peer_textbox').val()); } }); }); // Click key to copy animation $body.on("mouseenter", ".key", function(){ let label = $(this).parent().siblings().children()[1]; label.style.opacity = "100"; }).on("mouseout", ".key", function(){ let label = $(this).parent().siblings().children()[1]; label.style.opacity = "0"; setTimeout(function (){ label.innerHTML = "CLICK TO COPY"; },200); }).on("click", ".key", function(){ var label = $(this).parent().siblings().children()[1]; copyToClipboard($(this)); label.innerHTML = "COPIED!"; }); /** * CopyToClipboard * @param element */ function copyToClipboard(element) { let $temp = $(""); $body.append($temp); $temp.val($(element).text()).trigger( "select" ); document.execCommand("copy"); $temp.remove(); } // Update Interval $body.on("click", ".update_interval", function(){ $(".interval-btn-group button").removeClass("active"); let _new = $(this); _new.addClass("active"); let interval = $(this).data("refresh-interval"); $.ajax({ method:"POST", data: "interval="+$(this).data("refresh-interval"), url: "/update_dashboard_refresh_interval", success: function (res){ if (res === "true"){ load_interval = interval; clearInterval(load_timeout); load_timeout = setInterval(function (){ load_data($('#search_peer_textbox').val()); }, interval); showToast("Refresh Interval set to "+Math.round(interval/1000)+" seconds"); }else{ $(".interval-btn-group button").removeClass("active"); $('.interval-btn-group button[data-refresh-interval="'+load_interval+'"]').addClass("active"); showToast("Refresh Interval set unsuccessful"); } } }); }); // Refresh Button $body.on("click", ".refresh", function (){ load_data($('#search_peer_textbox').val()); }); // Switch display mode $body.on("click", ".display_mode", function(){ $(".display-btn-group button").removeClass("active"); $(this).addClass("active"); let display_mode = $(this).data("display-mode"); $.ajax({ method:"GET", url: "/switch_display_mode/"+$(this).data("display-mode"), success: function (res){ if (res === "true"){ if (display_mode === "list"){ Array($(".peer_list").children()).forEach(function(child){ $(child).removeClass().addClass("col-12"); }); showToast("Displaying as List"); }else{ Array($(".peer_list").children()).forEach(function(child){ $(child).removeClass().addClass("col-sm-6 col-lg-4"); }); showToast("Displaying as Grids"); } } } }); }); // Toggle bulk add mode $("#bulk_add").on("change", function (){ let hide = $(".non-bulk").find("input"); let amount = $("#new_add_amount"); if ($(this).prop("checked") === true){ for(let i = 0; i < hide.length; i++){ $(hide[i]).attr("disabled", "disabled"); } amount.removeAttr("disabled"); } else{ for(let i = 0; i < hide.length; i++){ if ($(hide[i]).attr('id') !== "public_key"){ $(hide[i]).removeAttr("disabled"); } } amount.attr("disabled", "disabled"); } }); // Configuration sub menu let $setting_btn_menu = $(".setting_btn_menu"); $setting_btn_menu.css("top", ($setting_btn_menu.height() + 54)*(-1)); let $setting_btn = $(".setting_btn"); $setting_btn.on("click", function(){ if ($setting_btn_menu.hasClass("show")){ $setting_btn_menu.removeClass("showing"); setTimeout(function(){ $setting_btn_menu.removeClass("show"); }, 201); }else{ $setting_btn_menu.addClass("show"); setTimeout(function(){ $setting_btn_menu.addClass("showing"); },10); } }) $("html").on("click", function(r){ if (document.querySelector(".setting_btn") !== r.target){ if (!document.querySelector(".setting_btn").contains(r.target)){ if (!document.querySelector(".setting_btn_menu").contains(r.target)){ $setting_btn_menu.removeClass("showing"); setTimeout(function(){ $setting_btn_menu.removeClass("show"); }, 310); } } } }); // Delete peers by bulk let deleteBulkModal = new bootstrap.Modal(document.getElementById('delete_bulk_modal'), { keyboard: false, backdrop: 'static' }); $("#delete_peers_by_bulk_btn").on("click", () => { let $delete_bulk_modal_list = $("#delete_bulk_modal .list-group"); $delete_bulk_modal_list.html(''); peers.forEach((peer) => { let name = "" if (peer["name"] === "") { name = "Untitled Peer"; } else { name = peer["name"]; } $delete_bulk_modal_list.append(''+name+'
'+peer['id']+'
'); }); deleteBulkModal.toggle(); }); function toggleBulkIP(element){ let $selected_peer_list = $("#selected_peer_list"); let id = element.data("id"); let name = element.data("name") === "" ? "Untitled Peer" : element.data("name"); if (element.hasClass("active")){ element.removeClass("active"); $("#selected_peer_list .badge[data-id='"+id+"']").remove(); }else{ element.addClass("active"); $selected_peer_list.append(''+name+' - '+id+'') } } $body.on("click", ".delete-bulk-peer-item", function(){ toggleBulkIP($(this)); }).on("click", ".delete-peer-bulk-badge", function(){ toggleBulkIP($(".delete-bulk-peer-item[data-id='" + $(this).data("id") + "']")); }); let $selected_peer_list = document.getElementById("selected_peer_list"); let changeObserver = new MutationObserver(function(mutationsList, observer){ if ($selected_peer_list.hasChildNodes()){ $("#confirm_delete_bulk_peers").removeAttr("disabled"); }else{ $("#confirm_delete_bulk_peers").attr("disabled", "disabled"); } }); changeObserver.observe($selected_peer_list, { attributes: true, childList: true, characterData: true }) let confirm_delete_bulk_peers_interval = undefined; $("#confirm_delete_bulk_peers").on("click", function(){ let btn = $(this); if (confirm_delete_bulk_peers_interval !== undefined){ clearInterval(confirm_delete_bulk_peers_interval); confirm_delete_bulk_peers_interval = undefined; btn.html("Delete"); }else{ let timer = 5; btn.html(`Deleting in ${timer} secs... Click to cancel`); confirm_delete_bulk_peers_interval = setInterval(function(){ timer -= 1; btn.html(`Deleting in ${timer} secs... Click to cancel`); if (timer === 0){ btn.html(`Deleting...`); btn.attr("disabled", "disabled"); let ips = []; $selected_peer_list.childNodes.forEach((ele) => ips.push(ele.dataset.id)); deletePeers(btn.data("conf"), ips); clearInterval(confirm_delete_bulk_peers_interval); confirm_delete_bulk_peers_interval = undefined; } }, 1000) } }); $("#select_all_delete_bulk_peers").on("click", function(){ $(".delete-bulk-peer-item").each(function(){ if (!$(this).hasClass("active")) { toggleBulkIP($(this)); } }); }); $(deleteBulkModal._element).on("hidden.bs.modal", function(){ $(".delete-bulk-peer-item").each(function(){ if ($(this).hasClass("active")) { toggleBulkIP($(this)); } }); }); // Download Peers function download_one_config(conf){ let link = document.createElement('a'); link.download = conf.filename; let blob = new Blob([conf.content], {type: 'text/conf'}); link.href = window.URL.createObjectURL(blob); link.click(); } function download_all_config(confs){ wireguard.generateZipFiles(confs); } $body.on("click", ".btn-download-peer", function(e){ e.preventDefault(); let link = $(this).attr("href"); $.ajax({ "url": link, "method": "GET", success: function(res){ download_one_config(res); } }); }); $("#download_all_peers").on("click", function(){ $.ajax({ "url": $(this).data("url"), "method": "GET", success: function(res){ if (res.peers.length > 0){ download_all_config(res); } } }); });