diff --git a/src/dashboard.py b/src/dashboard.py index 7ca3d68..2d572c9 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -519,6 +519,7 @@ Flask Functions # Before request @app.before_request def auth_req(): + sem.acquire(timeout=1) conf = get_dashboard_conf() req = conf.get("Server", "auth_req") session['update'] = UPDATE @@ -535,6 +536,10 @@ def auth_req(): else: session['message'] = "" conf.clear() + try: + sem.release() + except RuntimeError as e: + print("RuntimeError: cannot release un-acquired lock") return redirect(url_for("signin")) else: if request.endpoint in ['signin', 'signout', 'auth', 'settings', 'update_acct', 'update_pwd', @@ -836,6 +841,7 @@ def get_conf(config_name): config = get_dashboard_conf() sort = config.get("Server", "dashboard_sort") peer_display_mode = config.get("Peers", "peer_display_mode") + wg_ip = config.get("Peers","remote_endpoint") if "Address" not in config_interface: conf_address = "N/A" else: @@ -849,7 +855,7 @@ def get_conf(config_name): "listen_port": get_conf_listen_port(config_name), "running_peer": get_conf_running_peer_number(config_name), "conf_address": conf_address, - "wg_ip": config.get("Peers","remote_endpoint"), + "wg_ip": wg_ip, "sort_tag": sort, "dashboard_refresh_interval": int(config.get("Server", "dashboard_refresh_interval")), "peer_display_mode": peer_display_mode @@ -858,7 +864,7 @@ def get_conf(config_name): conf_data['checked'] = "nope" else: conf_data['checked'] = "checked" - print(config.get("Peers","remote_endpoint")) + print(wg_ip) config.clear() return jsonify(conf_data) # return render_template('get_conf.html', conf_data=conf_data, wg_ip=config.get("Peers","remote_endpoint"), sort_tag=sort, diff --git a/src/static/css/dashboard.css b/src/static/css/dashboard.css index 630262a..e89cf5e 100644 --- a/src/static/css/dashboard.css +++ b/src/static/css/dashboard.css @@ -379,5 +379,6 @@ main{ #conf_status_btn.info_loading{ height: 38px; border-radius: 5px; - animation: loading 2s infinite ease-in-out; -} \ No newline at end of file + animation: loading 3s infinite ease-in-out; +} + diff --git a/src/static/css/dashboard.min.css b/src/static/css/dashboard.min.css new file mode 100644 index 0000000..8df3ac2 --- /dev/null +++ b/src/static/css/dashboard.min.css @@ -0,0 +1 @@ +@-webkit-keyframes rotating{0%{-webkit-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotating{0%{-ms-transform:rotate(0deg);-moz-transform:rotate(0deg);-webkit-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-ms-transform:rotate(360deg);-moz-transform:rotate(360deg);-webkit-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading{0%,to{background-color:#dfdfdf}50%{background-color:#adadad}}@-moz-keyframes loading{0%,to{background-color:#dfdfdf}50%{background-color:#adadad}}body{font-size:.875rem}.feather{width:16px;height:16px;vertical-align:text-bottom}.sidebar{position:fixed;top:0;bottom:0;left:0;z-index:100;padding:48px 0 0;box-shadow:inset -1px 0 0 rgba(0,0,0,.1)}.sidebar-sticky{position:relative;top:0;height:calc(100vh - 48px);padding-top:.5rem;overflow-x:hidden;overflow-y:auto}@supports ((position:-webkit-sticky) or (position:sticky)){.sidebar-sticky{position:-webkit-sticky;position:sticky}}.sidebar .nav-link{font-weight:500;color:#333;transition:.2s cubic-bezier(.82,-.07,0,1.01)}.nav-link:hover{padding-left:30px}.sidebar .nav-link .feather{margin-right:4px;color:#999}.sidebar .nav-link.active{color:#007bff}.sidebar .nav-link.active .feather,.sidebar .nav-link:hover .feather{color:inherit}.sidebar-heading{font-size:.75rem;text-transform:uppercase}.navbar-brand{padding-top:.75rem;padding-bottom:.75rem;font-size:1rem;background-color:rgba(0,0,0,.25);box-shadow:inset -1px 0 0 rgba(0,0,0,.25)}.navbar .navbar-toggler{top:.25rem;right:1rem}.navbar .form-control{padding:.75rem 1rem;border-width:0;border-radius:0}.form-control-dark{color:#fff;background-color:rgba(255,255,255,.1);border-color:rgba(255,255,255,.1)}.form-control-dark:focus{border-color:transparent;box-shadow:0 0 0 3px rgba(255,255,255,.25)}.dot{width:10px;height:10px;border-radius:50px;display:inline-block;margin-left:10px}.dot-running{background-color:#28a745!important;box-shadow:0 0 0 .2rem #28a74545}.h6-dot-running{margin-left:.3rem}.dot-stopped{background-color:#6c757d!important}.card-running{border-color:#28a745}.info h6{line-break:anywhere;transition:.2s ease-in-out}.info .row .col-sm{display:flex;flex-direction:column}.info .row .col-sm small{display:flex}.info .row .col-sm small strong:last-child(1){margin-left:auto!important}.btn-control{border:0!important;padding:0 1rem 0 0}.btn-control:active,.btn-control:focus{background-color:transparent!important;border:0!important;box-shadow:none}.share_peer_btn_group .btn-control{padding:0 0 0 1rem}.btn-control:hover{background:#fff}.btn-delete-peer:hover{color:#dc3545}.btn-setting-peer:hover{color:#007bff}.btn-download-peer:hover{color:#17a2b8}.login-container{padding:2rem}@media (max-width:992px){.card-col{margin-bottom:1rem}}.switch{font-size:2rem}.switch:hover{text-decoration:none}.btn-group-label:hover{color:#007bff;border-color:#007bff;background:#fff}@media (max-width:768px){.peer_data_group{text-align:left}}.index-switch{text-align:right}main{margin-bottom:3rem}.peer_list{margin-bottom:7rem}@media (max-width:768px){.add_btn{bottom:1.5rem!important}.peer_list{margin-bottom:4rem!important}}.add_btn{position:fixed;bottom:3rem;right:2rem;z-index:99;border-radius:100px!important;padding:10px 20px;box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}.rotating::before{-webkit-animation:rotating .75s linear infinite;-moz-animation:rotating .75s linear infinite;-ms-animation:rotating .75s linear infinite;-o-animation:rotating .75s linear infinite;animation:rotating .75s linear infinite}.peer_private_key_textbox_switch{position:absolute;right:2rem;transform:translateY(-28px);font-size:1.2rem;cursor:pointer}#peer_private_key_textbox,#private_key,#public_key{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.progress-bar{transition:.3s ease-in-out}.key{transition:.2s ease-in-out;cursor:pointer}.key:hover{color:#007bff}.card,.form-control{border-radius:10px}.peer_list .card .button-group{height:22px}.btn{border-radius:8px}.modal-content{border-radius:10px}.tooltip-inner{font-size:.8rem}#conf_status_btn,.conf_card{transition:.2s ease-in-out}.conf_card:hover{border-color:#007bff;cursor:pointer}.info_loading{animation:loading 2s infinite ease-in-out;border-radius:5px;height:19px;transition:.3s ease-in-out}#conf_status_btn.info_loading{height:38px;border-radius:5px;animation:loading 3s infinite ease-in-out} \ No newline at end of file diff --git a/src/static/js/configuration.js b/src/static/js/configuration.js index 8f27d03..7d85ef1 100644 --- a/src/static/js/configuration.js +++ b/src/static/js/configuration.js @@ -1,5 +1,10 @@ let $body = $("body"); +function roundN(value, digits) { + let tenToN = 10 ** digits; + return (Math.round(value * tenToN)) / tenToN; +} + // Progress Bar let $progress_bar = $(".progress-bar"); function startProgressBar(){ @@ -13,9 +18,11 @@ function startProgressBar(){ stillLoadingProgressBar(); },300); } + function stillLoadingProgressBar(){ $progress_bar.css("transition", "3s ease-in-out").css("width", "75%"); } + function endProgressBar(){ $progress_bar.css("transition", "0.3s ease-in-out").css("width","100%"); setTimeout(function(){ @@ -433,7 +440,7 @@ $body.on("click", ".display_mode", function(){ Array($(".peer_list").children()).forEach(function(child){ $(child).removeClass().addClass("col-sm-6 col-lg-4"); }); - showToast("Displaying as Grid"); + showToast("Displaying as Grids"); } } } diff --git a/src/static/js/configuration.min.js b/src/static/js/configuration.min.js new file mode 100644 index 0000000..2d4032c --- /dev/null +++ b/src/static/js/configuration.min.js @@ -0,0 +1 @@ +let $body=$("body");function roundN(value,digits){let tenToN=10**digits;return Math.round(value*tenToN)/tenToN}let $progress_bar=$(".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)}function stillLoadingProgressBar(){$progress_bar.css("transition","3s ease-in-out").css("width","75%")}function endProgressBar(){$progress_bar.css("transition","0.3s ease-in-out").css("width","100%");setTimeout(function(){$progress_bar.css("opacity","0")},250)}function showToast(msg){$("#alertToast").toast("show");$("#alertToast .toast-body").html(msg)}$body.on("click",".switch",function(){$(this).siblings($(".spinner-border")).css("display","inline-block");$(this).remove();location.replace("/switch/"+$(this).attr("id"))});function generate_key(){$.ajax({url:"/generate_peer",method:"GET"}).done(function(res){$("#private_key").val(res.private_key);$("#public_key").val(res.public_key);$("#preshare_key").val(res.preshared_key);$("#add_peer_alert").addClass("d-none");$("#re_generate_key i").removeClass("rotating")})}function generate_public_key(){$.ajax({url:"/generate_public_key",method:"POST",headers:{"Content-Type":"application/json"},data:JSON.stringify({private_key:$("#private_key").val()})}).done(function(res){if(res.status==="failed"){$("#add_peer_alert").html(res.msg).removeClass("d-none")}else{$("#add_peer_alert").addClass("d-none")}$("#public_key").val(res.data);$("#re_generate_key i").removeClass("rotating")})}$("#private_key").on("change",function(){if($(this).val().length>0){$("#re_generate_key i").addClass("rotating");generate_public_key()}else{$("#public_key").removeAttr("disabled").val("")}});$("#add_modal").on("show.bs.modal",function(event){generate_key()});$("#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});$(".add_btn").on("click",function(){addModal.toggle()});$("#save_peer").on("click",function(){let $public_key=$("#public_key");let $private_key=$("#private_key");let $allowed_ips=$("#allowed_ips");let $new_add_DNS=$("#new_add_DNS");let $new_add_endpoint_allowed_ip=$("#new_add_endpoint_allowed_ip");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("Saving...");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")}),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("");addModal.toggle()}}})}else{$("#add_peer_alert").html("Please fill in all required box.").removeClass("d-none");$(this).removeAttr("disabled");$(this).html("Save")}});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()})});let deleteModal=new bootstrap.Modal(document.getElementById("delete_modal"),{keyboard:false});$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");$.ajax({method:"POST",url:"/remove_peer/"+config,headers:{"Content-Type":"application/json"},data:JSON.stringify({action:"delete",peer_id:peer_id}),success:function(response){if(response!=="true"){$("#remove_peer_alert").html(response+$("#add_peer_alert").html()).removeClass("d-none")}else{deleteModal.toggle();load_data($("#search_peer_textbox").val());$("#alertToast").toast("show");$("#alertToast .toast-body").html("Peer deleted!");$("#delete_peer").removeAttr("disabled").html("Delete")}}})});let settingModal=new bootstrap.Modal(document.getElementById("setting_modal"),{keyboard:false});$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)});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())}$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())}})});$body.on("mouseenter",".key",function(){let label=$(this).parent().siblings().children()[1];label.style.opacity="100"});$body.on("mouseout",".key",function(){let label=$(this).parent().siblings().children()[1];label.style.opacity="0";setTimeout(function(){label.innerHTML="CLICK TO COPY"},200)});$body.on("click",".key",function(){var label=$(this).parent().siblings().children()[1];copyToClipboard($(this));label.innerHTML="COPIED!"});function copyToClipboard(element){let $temp=$("");$body.append($temp);$temp.val($(element).text()).trigger("select");document.execCommand("copy");$temp.remove()}$body.on("click",".update_interval",function(){let prev=$(".interval-btn-group.active button");$(".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/1e3)+" seconds")}else{$(".interval-btn-group button").removeClass("active");$('.interval-btn-group button[data-refresh-interval="'+load_interval+'"]').addClass("active");showToast("Refresh Interval set unsuccessful")}}})});$body.on("click",".refresh",function(){load_data($("#search_peer_textbox").val())});$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")}}}})}); \ No newline at end of file diff --git a/src/static/js/tools.js b/src/static/js/tools.js index a16a277..5459e7e 100644 --- a/src/static/js/tools.js +++ b/src/static/js/tools.js @@ -14,12 +14,7 @@ $(".conf_dropdown").change(function (){ } }) }); - - // Ping Tools - - - $(".send_ping").click(function (){ $(this).attr("disabled","disabled") $(this).html("Pinging...") diff --git a/src/static/js/tools.min.js b/src/static/js/tools.min.js new file mode 100644 index 0000000..feb0362 --- /dev/null +++ b/src/static/js/tools.min.js @@ -0,0 +1 @@ +$(".ip_dropdown").change(function(){$(".modal.show .btn").removeAttr("disabled")});$(".conf_dropdown").change(function(){$(".modal.show .ip_dropdown").html('