From 6d56967a0f00c8de311e4c9055287593c0a08d70 Mon Sep 17 00:00:00 2001 From: Donald Cheng Hong Zou Date: Sat, 8 Jan 2022 15:26:17 -0500 Subject: [PATCH] Getting ready for v3.0 --- README.md | 54 +++++---- src/dashboard.py | 23 ++-- src/static/css/dashboard.css | 78 ++++++++++++- src/static/css/dashboard.min.css | 2 +- src/static/js/configuration.js | 177 ++++++++++++++++++++++++++--- src/static/js/configuration.min.js | 2 +- src/templates/configuration.html | 68 +++++++---- 7 files changed, 335 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index cad7393..2c3a8c2 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,9 @@ -
- -> Hi! I'm planning the next major update for this project, please let me know if you have any suggestions or feature requests ;) You can create an issue with the "Feature request" template. Cheers! - -### Help Wanted - -> If anyone know a better way to distribute releases of python application other than GitHub, please let me know in #103! - -> Please provide your OS name and version if you can run the dashboard on it perfectly in #31, since I only tested on Ubuntu. Thank you! - -

WGDashboard

WGDashboard

+

@@ -24,19 +14,25 @@

Monitoring WireGuard is not convinient, need to login into server and type wg show. That's why this platform is being created, to view all configurations and manage them in a easier way.

Note: This project is not affiliate to the official WireGuard Project ;)

-## 📣 What's New: v2.3 +## 📣 What's New: v3.0 - 🎉 **New Features** - - **Update directly from `wgd.sh`:** Now you can update WGDashboard directly from the bash script. - - **Displaying Peers:** You can switch the display mode between list and table in the configuration page. + - **Add Peers by Bulk: ** Now you can add peers by bulk, just simply set the amount and click add. + - **Delete Peers by Bulk**: User can click the menu button (three-dots) on the bottom right of each configuration, and click **Delete Peers**, then select peers. + - **Added Pre-shared Key to peers:** Now each peer can add with a pre-shared key to enhance security. Previously added peers can add the pre-shared key through the peer setting button. - 🪚 **Bug Fixed** - - [Peer DNS Validation Fails #67](issues/67): Added DNS format check. [❤️ @realfian] - - [configparser.NoSectionError: No section: 'Interface' #66](issues/66): Changed permission requirement for `etc/wireguard` from `744` to `755`. [❤️ @ramalmaty] - - [Feature request: Interface not loading when information missing #73](issues/73): Fixed when Configuration Address and Listen Port is missing will crash the dashboard. [❤️ @js32] - - [Remote Peer, MTU and PersistentKeepalives added #70](pull/70): Added MTU, remote peer and Persistent Keepalive. [❤️ @realfian] - - [Fixes DNS check to support search domain #65](pull/65): Added allow input domain into DNS. [❤️@davejlong] + - [IP Sorting range issues #99](https://github.com/donaldzou/WGDashboard/issues/99) [❤️ @barryboom] + - [INvalid character written to tunnel json file #108](https://github.com/donaldzou/WGDashboard/issues/108) [❤️ @ ikidd] + - [Add IPv6 #91](https://github.com/donaldzou/WGDashboard/pull/91) [❤️ @ pgalonza] + - [Added MTU and PersistentKeepalive to QR code and download files #112](https://github.com/donaldzou/WGDashboard/pull/112) [:heart: @reafian] - **🧐 Other Changes** - - Moved Add Peer Button into the right bottom corner. + - **Key generating moved to front-end**: No longer need to use the server's WireGuard to generate keys, thanks to the `wireguard.js` from the [official repository](https://git.zx2c4.com/wireguard-tools/tree/contrib/keygen-html/wireguard.js)! + - **Peer transfer calculation**: each peer will now show all transfer amount (previously was only showing transfer amount from the last configuration start-up). + - **UI adjustment on running peers**: peers will have a new style indicating that it is running. + - **Moved from TinyDB to SQLite**: This could provide better performance and loading speed when showing peers, also avoided changing the database could crash. + - UI adjustment on the whole dashboard. + - **`wgd.sh` finally can update itself**: So now user could update the whole dashboard from `wgd.sh`, with the `update` command. + @@ -358,6 +354,24 @@ Endpoint = 0.0.0.0:51820 ## ⏰ Changelog +#### v2.3.1 - Sep 8, 2021 + +- Updated dashboard's name to **WGDashboard**!! + +#### v2.3 - Sep 8, 2021 + +- 🎉 **New Features** + - **Update directly from `wgd.sh`:** Now you can update WGDashboard directly from the bash script. + - **Displaying Peers:** You can switch the display mode between list and table in the configuration page. +- 🪚 **Bug Fixed** + - [Peer DNS Validation Fails #67](issues/67): Added DNS format check. [❤️ @realfian] + - [configparser.NoSectionError: No section: 'Interface' #66](issues/66): Changed permission requirement for `etc/wireguard` from `744` to `755`. [❤️ @ramalmaty] + - [Feature request: Interface not loading when information missing #73](issues/73): Fixed when Configuration Address and Listen Port is missing will crash the dashboard. [❤️ @js32] + - [Remote Peer, MTU and PersistentKeepalives added #70](pull/70): Added MTU, remote peer and Persistent Keepalive. [❤️ @realfian] + - [Fixes DNS check to support search domain #65](pull/65): Added allow input domain into DNS. [❤️@davejlong] +- **🧐 Other Changes** + - Moved Add Peer Button into the right bottom corner. + #### v2.2.1 - Aug 16, 2021 Bug Fixed: diff --git a/src/dashboard.py b/src/dashboard.py index 17586d7..01cec6f 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -1000,24 +1000,29 @@ def remove_peer(config_name): if get_conf_status(config_name) == "stopped": return "Your need to turn on " + config_name + " first." data = request.get_json() - delete_key = data['peer_id'] + delete_keys = data['peer_ids'] keys = get_conf_peer_key(config_name) if not isinstance(keys, list): return config_name + " is not running." - if delete_key not in keys: - return "This key does not exist" else: + sql_command = [] + wg_command = ["wg", "set", config_name] + for delete_key in delete_keys: + if delete_key not in keys: + return "This key does not exist" + sql_command.append("DELETE FROM " + config_name + " WHERE id = '"+delete_key+"';") + wg_command.append("peer") + wg_command.append(delete_key) + wg_command.append("remove") try: - remove_wg = subprocess.check_output(f"wg set {config_name} peer {delete_key} remove", + remove_wg = subprocess.check_output(" ".join(wg_command), shell=True, stderr=subprocess.STDOUT) - save_wg = subprocess.check_output(f"wg-quick save {config_name}", - shell=True, stderr=subprocess.STDOUT) - sql = "DELETE FROM " + config_name + " WHERE id = ?" - g.cur.execute(sql, (delete_key,)) + save_wg = subprocess.check_output(f"wg-quick save {config_name}", shell=True, stderr=subprocess.STDOUT) + g.cur.executescript(' '.join(sql_command)) g.db.commit() - return "true" except subprocess.CalledProcessError as exc: return exc.output.strip() + return "true" # Save peer settings diff --git a/src/static/css/dashboard.css b/src/static/css/dashboard.css index a1cac82..7782e38 100644 --- a/src/static/css/dashboard.css +++ b/src/static/css/dashboard.css @@ -241,18 +241,77 @@ main{ } .peer_list{ - margin-bottom: 4rem !important; + margin-bottom: 7rem !important; } } -.add_btn{ +.btn-manage-group{ + z-index: 99; position: fixed; bottom: 3rem; right: 2rem; + display: flex; +} + +.btn-manage-group .setting_btn_menu{ + position: absolute; + top: -124px; + background-color: white; + padding: 1rem 0; + right: 0; + box-shadow: 0 10px 20px rgb(0 0 0 / 19%), 0 6px 6px rgb(0 0 0 / 23%); + border-radius: 10px; + min-width: 200px; + display: none; + transform: translateY(-30px); + opacity: 0; + transition: all 0.3s cubic-bezier(0.58, 0.03, 0.05, 1.28); +} + +.btn-manage-group .setting_btn_menu.show{ + display: block; +} + +.setting_btn_menu.showing{ + transform: translateY(0px); + opacity: 1; +} + +.setting_btn_menu a{ + display: flex; + padding: 0.5rem 1rem; + transition: all 0.1s ease-in-out; + font-size: 1rem; + align-items: center; + cursor: pointer; +} + +.setting_btn_menu a:hover{ + background-color: #efefef; + text-decoration: none; +} + +.setting_btn_menu a i{ + margin-right: auto !important; +} + +.add_btn{ + height: 54px; z-index: 99; border-radius: 100px !important; - padding: 10px 20px; + padding: 0 14px; box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); + margin-right: 1rem; + font-size: 1.5rem; +} + +.setting_btn{ + height: 54px; + z-index: 99; + border-radius: 100px !important; + padding: 0 14px; + box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); + font-size: 1.5rem; } @@ -394,11 +453,22 @@ main{ width: 100%; } -#selected_ip_list .badge{ +#selected_ip_list .badge, #selected_peer_list .badge{ margin: 0.1rem } #add_modal.ip_modal_open{ transition: filter 0.2s ease-in-out; filter: brightness(0.5); +} + +#delete_bulk_modal .list-group a.active{ + background-color: #dc3545; + border-color: #dc3545; +} + +#selected_peer_list{ + max-height: 80px; + overflow-y: scroll; + overflow-x: hidden; } \ No newline at end of file diff --git a/src/static/css/dashboard.min.css b/src/static/css/dashboard.min.css index 7c68d69..020fdd6 100644 --- a/src/static/css/dashboard.min.css +++ b/src/static/css/dashboard.min.css @@ -1 +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}.form-control{transition:all .2s ease-in-out}.form-control:disabled{cursor:not-allowed}.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}#qrcode_img img{width:100%}#selected_ip_list .badge{margin:.1rem}#add_modal.ip_modal_open{transition:filter .2s ease-in-out;filter:brightness(.5)} \ No newline at end of file +@-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}.form-control{transition:all .2s ease-in-out}.form-control:disabled{cursor:not-allowed}.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:7rem!important}}.btn-manage-group{z-index:99;position:fixed;bottom:3rem;right:2rem;display:flex}.btn-manage-group .setting_btn_menu{position:absolute;top:-124px;background-color:#fff;padding:1rem 0;right:0;box-shadow:0 10px 20px rgb(0 0 0/19%),0 6px 6px rgb(0 0 0/23%);border-radius:10px;min-width:200px;display:none;transform:translateY(-30px);opacity:0;transition:all .3s cubic-bezier(.58,.03,.05,1.28)}.btn-manage-group .setting_btn_menu.show{display:block}.setting_btn_menu.showing{transform:translateY(0);opacity:1}.setting_btn_menu a{display:flex;padding:.5rem 1rem;transition:all .1s ease-in-out;font-size:1rem;align-items:center;cursor:pointer}.setting_btn_menu a:hover{background-color:#efefef;text-decoration:none}.setting_btn_menu a i{margin-right:auto!important}.add_btn{margin-right:1rem}.add_btn,.setting_btn{height:54px;z-index:99;border-radius:100px!important;padding:0 14px;box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23);font-size:1.5rem}.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}#qrcode_img img{width:100%}#selected_ip_list .badge,#selected_peer_list .badge{margin:.1rem}#add_modal.ip_modal_open{transition:filter .2s ease-in-out;filter:brightness(.5)}#delete_bulk_modal .list-group a.active{background-color:#dc3545;border-color:#dc3545}#selected_peer_list{max-height:80px;overflow-y:scroll;overflow-x:hidden} \ No newline at end of file diff --git a/src/static/js/configuration.js b/src/static/js/configuration.js index 3bee908..5772821 100644 --- a/src/static/js/configuration.js +++ b/src/static/js/configuration.js @@ -6,7 +6,7 @@ let available_ips = []; let $save_peer = $("#save_peer"); $(".add_btn").on("click", function(){ - addModal.toggle(); + $addModal.toggle(); }); /** @@ -157,7 +157,8 @@ $body.on("click", ".available-ip-item", function () { }); let $ipModal = new bootstrap.Modal(document.getElementById('available_ip_modal'), { - keyboard: false + keyboard: false, + backdrop: 'static' }); $("#search_available_ip").on("click", function () { @@ -209,8 +210,9 @@ $("#re_generate_key").on("click",function (){ generate_key(); }); -let addModal = new bootstrap.Modal(document.getElementById('add_modal'), { - keyboard: false +let $addModal = new bootstrap.Modal(document.getElementById('add_modal'), { + keyboard: false, + backdrop: 'static' }); function clean_ip(val){ @@ -220,8 +222,9 @@ function clean_ip(val){ } let bulk_add_peers = () => { + let $new_add_amount = $("#new_add_amount"); $save_peer.attr("disabled","disabled"); - $save_peer.html("Adding..."); + $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())); @@ -230,7 +233,6 @@ let bulk_add_peers = () => { let $new_add_MTU = $("#new_add_MTU"); let $new_add_keep_alive = $("#new_add_keep_alive"); let $enable_preshare_key = $("#enable_preshare_key"); - let $new_add_amount = $("#new_add_amount"); let data_list = [$new_add_DNS, $new_add_endpoint_allowed_ip,$new_add_MTU, $new_add_keep_alive]; if ($new_add_amount.val() > 0){ if ($new_add_DNS.val() !== "" && $new_add_endpoint_allowed_ip.val() !== ""){ @@ -263,8 +265,8 @@ let bulk_add_peers = () => { 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(); + showToast($new_add_amount.val()+" peers added successful!"); + $addModal.toggle(); } } }) @@ -334,7 +336,7 @@ $save_peer.on("click",function(){ $("#add_peer_form").trigger("reset"); $save_peer.removeAttr("disabled").html("Save"); showToast("Add peer successful!"); - addModal.toggle(); + $addModal.toggle(); } } }); @@ -366,7 +368,8 @@ $body.on("click", ".btn-qrcode-peer", function (){ // Delete Peer Modal let deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), { - keyboard: false + keyboard: false, + backdrop: 'static' }); $body.on("click", ".btn-delete-peer", function(){ @@ -380,19 +383,40 @@ $("#delete_peer").on("click",function(){ $(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_id": peer_id}), + data: JSON.stringify({"action": "delete", "peer_ids": peer_ids}), success: function (response){ if(response !== "true"){ - $("#remove_peer_alert").html(response+$("#add_peer_alert").html()).removeClass("d-none"); + 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{ - deleteModal.toggle(); + 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!"); @@ -400,11 +424,12 @@ $("#delete_peer").on("click",function(){ } } }); -}); +} // Peer Setting Modal let settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), { - keyboard: false + keyboard: false, + backdrop: 'static' }); $body.on("click", ".btn-setting-peer", function(){ startProgressBar(); @@ -638,6 +663,7 @@ $body.on("click", ".display_mode", function(){ }); }); +// Toggle bulk add mode $("#bulk_add").on("change", function (){ let hide = $(".non-bulk").find("input"); let amount = $("#new_add_amount"); @@ -655,4 +681,125 @@ $("#bulk_add").on("change", function (){ } 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) + } +}) +$body.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)); + }); }) \ No newline at end of file diff --git a/src/static/js/configuration.min.js b/src/static/js/configuration.min.js index 438a7cb..5fa6c28 100644 --- a/src/static/js/configuration.min.js +++ b/src/static/js/configuration.min.js @@ -1 +1 @@ -$("[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()});function roundN(value,digits){let tenToN=10**digits;return Math.round(value*tenToN)/tenToN}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(){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)}$("#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("")}});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+"")}}}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))});$body.on("click",".available-ip-badge",function(){$(".available-ip-item[data-ip='"+$(this).data("ip")+"']").removeClass("active");$(this).remove()});$body.on("click",".available-ip-item",function(){trigger_ip($(this).data("ip"))});let $ipModal=new bootstrap.Modal(document.getElementById("available_ip_modal"),{keyboard:false});$("#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{$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});function clean_ip(val){let clean_ip=val.split(",");for(let i=0;i{$save_peer.attr("disabled","disabled");$save_peer.html("Adding...");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 $new_add_amount=$("#new_add_amount");let data_list=[$new_add_DNS,$new_add_endpoint_allowed_ip,$new_add_MTU,$new_add_keep_alive];if($new_add_amount.val()>0){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{$("#add_peer_alert").html("Please enter 1 or more amount.").removeClass("d-none");$save_peer.removeAttr("disabled");$save_peer.html("Add")}};$save_peer.on("click",function(){let $bulk_add=$("#bulk_add");if($bulk_add.prop("checked")){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")}}});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"}).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!"});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")}}}})});$("#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'+ip+"")}}}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))});$body.on("click",".available-ip-badge",function(){$(".available-ip-item[data-ip='"+$(this).data("ip")+"']").removeClass("active");$(this).remove()});$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{$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{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){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{$("#add_peer_alert").html("Please enter 1 or more amount.").removeClass("d-none");$save_peer.removeAttr("disabled");$save_peer.html("Add")}};$save_peer.on("click",function(){let $bulk_add=$("#bulk_add");if($bulk_add.prop("checked")){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")}}});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,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")}}})}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)});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"}).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!"});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")}}}})});$("#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{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}},1e3)}});$("#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))})}); \ No newline at end of file diff --git a/src/templates/configuration.html b/src/templates/configuration.html index 3ddbcac..e6e2ec6 100644 --- a/src/templates/configuration.html +++ b/src/templates/configuration.html @@ -100,7 +100,15 @@ - + +
@@ -113,26 +121,23 @@