mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-22 15:20:09 +01:00
v2.2beta almost done!!!!!
This commit is contained in:
parent
0d380672f3
commit
9d476af384
13
README.md
13
README.md
@ -20,15 +20,26 @@
|
|||||||
## 📣 What's New: Version v2.2
|
## 📣 What's New: Version v2.2
|
||||||
|
|
||||||
- 🎉 **New Features**
|
- 🎉 **New Features**
|
||||||
|
- **Add new peers**: Now you can add peers directly on dashboard, it will generate a pair of private key and public key. You can also set its DNS, endpoint allowed IPs. Both can set a default value in the setting page. [❤️ in [#44](https://github.com/donaldzou/wireguard-dashboard/issues/44)]
|
||||||
- **QR Code:** You can add the private key in peer setting of your existed peer to create a QR code. Or just create a new one, dashboard will now be able to auto generate a private key and public key ;) Don't worry, all keys will be generated on your machine, and **will delete all key files after they got generated**. [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
|
- **QR Code:** You can add the private key in peer setting of your existed peer to create a QR code. Or just create a new one, dashboard will now be able to auto generate a private key and public key ;) Don't worry, all keys will be generated on your machine, and **will delete all key files after they got generated**. [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
|
||||||
- **Peer configuration file download:** Same as QR code, you now can download the peer configuration file, so you don't need to manually input all the details on the peer machine! [❤️ in [#40](https://github.com/donaldzou/wireguard-dashboard/issues/40)]
|
- **Peer configuration file download:** Same as QR code, you now can download the peer configuration file, so you don't need to manually input all the details on the peer machine! [❤️ in [#40](https://github.com/donaldzou/wireguard-dashboard/issues/40)]
|
||||||
|
- **Search peers**: You can now search peers by their name.
|
||||||
- **Autostart on boot:** Added a tutorial on how to start the dashboard to on boot! Please read the [tutorial below](#autostart-wireguard-dashboard-on-boot). [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
|
- **Autostart on boot:** Added a tutorial on how to start the dashboard to on boot! Please read the [tutorial below](#autostart-wireguard-dashboard-on-boot). [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
|
||||||
|
- **Click to copy**: You can now click and copy all peer's public key and configuration's public key.
|
||||||
|
- And many more...
|
||||||
- 🪚 **Bug Fixed**
|
- 🪚 **Bug Fixed**
|
||||||
- When there are comments in the wireguard config file, will cause the dashboard to crash.
|
- When there are comments in the wireguard config file, will cause the dashboard to crash.
|
||||||
- Used regex to search for config files.
|
- Used regex to search for config files.
|
||||||
- **🧐 Other Changes**
|
- **🧐 Other Changes**
|
||||||
- Moved all external CSS and JavaScript file to local hosting (Except Bootstrap Icon, due to large amount of SVG files).
|
- Moved all external CSS and JavaScript file to local hosting (Except Bootstrap Icon, due to large amount of SVG files).
|
||||||
- Updated `Flask` from`v1.1.2` to `v2.0.1`, and `Jinja` from `v2.10.1` to `v3.0.1`
|
- Updated Python dependencies
|
||||||
|
- Flask: `v1.1.2 => v2.0.1`
|
||||||
|
- Jinja: `v2.10.1 => v3.0.1`
|
||||||
|
- icmplib: `v2.1.1 => v3.0.1`
|
||||||
|
- Updated CSS/JS dependencies
|
||||||
|
- Bootstrap: `v4.5.3 => v4.6.0`
|
||||||
|
- UI adjustment
|
||||||
|
- Adjusted how peers will display in larger screens, used to be 1 row per peer, now is 3 peers in 1 row.
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +66,23 @@ def is_match(regex, text):
|
|||||||
return pattern.search(text) is not None
|
return pattern.search(text) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def read_conf_file_interface(config_name):
|
||||||
|
conf_location = wg_conf_path + "/" + config_name + ".conf"
|
||||||
|
f = open(conf_location, 'r')
|
||||||
|
file = f.read().split("\n")
|
||||||
|
data = {}
|
||||||
|
peers_start = 0
|
||||||
|
for i in range(len(file)):
|
||||||
|
if not is_match("#(.*)", file[i]):
|
||||||
|
if len(file[i]) > 0:
|
||||||
|
if file[i] != "[Interface]":
|
||||||
|
tmp = re.split(r'\s*=\s*', file[i], 1)
|
||||||
|
if len(tmp) == 2:
|
||||||
|
data[tmp[0]] = tmp[1]
|
||||||
|
f.close()
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def read_conf_file(config_name):
|
def read_conf_file(config_name):
|
||||||
# Read Configuration File Start
|
# Read Configuration File Start
|
||||||
conf_location = wg_conf_path + "/" + config_name + ".conf"
|
conf_location = wg_conf_path + "/" + config_name + ".conf"
|
||||||
@ -195,7 +212,7 @@ def get_all_peers_data(config_name):
|
|||||||
"id": i['PublicKey'],
|
"id": i['PublicKey'],
|
||||||
"private_key": "",
|
"private_key": "",
|
||||||
"DNS": "1.1.1.1",
|
"DNS": "1.1.1.1",
|
||||||
"endpoint_allowed_ip":"0.0.0.0/0",
|
"endpoint_allowed_ip": "0.0.0.0/0",
|
||||||
"name": "",
|
"name": "",
|
||||||
"total_receive": 0,
|
"total_receive": 0,
|
||||||
"total_sent": 0,
|
"total_sent": 0,
|
||||||
@ -357,14 +374,23 @@ def checkAllowedIP(public_key, ip, config_name):
|
|||||||
else:
|
else:
|
||||||
return {'status': 'success'}
|
return {'status': 'success'}
|
||||||
|
|
||||||
|
|
||||||
def checkIp(ip):
|
def checkIp(ip):
|
||||||
return is_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}",ip)
|
return is_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}", ip)
|
||||||
|
|
||||||
|
|
||||||
def cleanIp(ip):
|
def cleanIp(ip):
|
||||||
return ip.replace(' ','')
|
return ip.replace(' ', '')
|
||||||
|
|
||||||
|
|
||||||
def cleanIpWithRange(ip):
|
def cleanIpWithRange(ip):
|
||||||
return cleanIp(ip).split(',')
|
return cleanIp(ip).split(',')
|
||||||
|
|
||||||
|
|
||||||
def checkIpWithRange(ip):
|
def checkIpWithRange(ip):
|
||||||
return is_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|\/)){4}(0|8|16|24|32)(,|$)", ip)
|
return is_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|\/)){4}(0|8|16|24|32)(,|$)", ip)
|
||||||
|
|
||||||
|
|
||||||
def checkAllowedIPs(ip):
|
def checkAllowedIPs(ip):
|
||||||
ip = cleanIpWithRange(ip)
|
ip = cleanIpWithRange(ip)
|
||||||
for i in ip:
|
for i in ip:
|
||||||
@ -372,8 +398,6 @@ def checkAllowedIPs(ip):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def auth_req():
|
def auth_req():
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
@ -431,8 +455,8 @@ def settings():
|
|||||||
return render_template('settings.html', conf=get_conf_list(), message=message, status=status,
|
return render_template('settings.html', conf=get_conf_list(), message=message, status=status,
|
||||||
app_ip=config.get("Server", "app_ip"), app_port=config.get("Server", "app_port"),
|
app_ip=config.get("Server", "app_ip"), app_port=config.get("Server", "app_port"),
|
||||||
required_auth=required_auth, wg_conf_path=config.get("Server", "wg_conf_path"),
|
required_auth=required_auth, wg_conf_path=config.get("Server", "wg_conf_path"),
|
||||||
peer_global_DNS=config.get("Peers","peer_global_DNS"),
|
peer_global_DNS=config.get("Peers", "peer_global_DNS"),
|
||||||
peer_endpoint_allowed_ip=config.get("Peers","peer_endpoint_allowed_ip"))
|
peer_endpoint_allowed_ip=config.get("Peers", "peer_endpoint_allowed_ip"))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/auth', methods=['POST'])
|
@app.route('/auth', methods=['POST'])
|
||||||
@ -473,6 +497,7 @@ def update_acct():
|
|||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/update_peer_default_config', methods=['POST'])
|
@app.route('/update_peer_default_config', methods=['POST'])
|
||||||
def update_peer_default_config():
|
def update_peer_default_config():
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
@ -492,13 +517,11 @@ def update_peer_default_config():
|
|||||||
# Check Endpoint Allowed IPs
|
# Check Endpoint Allowed IPs
|
||||||
ip = request.form['peer_endpoint_allowed_ip']
|
ip = request.form['peer_endpoint_allowed_ip']
|
||||||
if not checkAllowedIPs(ip):
|
if not checkAllowedIPs(ip):
|
||||||
session['message'] = "Peer Endpoint Allowed IPs Format Incorrect. Example: 192.168.1.1/32 or 192.168.1.1/32,192.168.1.2/32"
|
session[
|
||||||
|
'message'] = "Peer Endpoint Allowed IPs Format Incorrect. Example: 192.168.1.1/32 or 192.168.1.1/32,192.168.1.2/32"
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
config.set("Peers", "peer_endpoint_allowed_ip", ','.join(cleanIpWithRange(ip)))
|
config.set("Peers", "peer_endpoint_allowed_ip", ','.join(cleanIpWithRange(ip)))
|
||||||
config.set("Peers", "peer_global_DNS", request.form['peer_global_DNS'])
|
config.set("Peers", "peer_global_DNS", request.form['peer_global_DNS'])
|
||||||
try:
|
try:
|
||||||
@ -679,6 +702,8 @@ def conf(config_name):
|
|||||||
|
|
||||||
@app.route('/get_config/<config_name>', methods=['GET'])
|
@app.route('/get_config/<config_name>', methods=['GET'])
|
||||||
def get_conf(config_name):
|
def get_conf(config_name):
|
||||||
|
config_interface = read_conf_file_interface(config_name)
|
||||||
|
|
||||||
search = request.args.get('search')
|
search = request.args.get('search')
|
||||||
if len(search) == 0: search = ""
|
if len(search) == 0: search = ""
|
||||||
search = urllib.parse.unquote(search)
|
search = urllib.parse.unquote(search)
|
||||||
@ -693,12 +718,14 @@ def get_conf(config_name):
|
|||||||
"public_key": get_conf_pub_key(config_name),
|
"public_key": get_conf_pub_key(config_name),
|
||||||
"listen_port": get_conf_listen_port(config_name),
|
"listen_port": get_conf_listen_port(config_name),
|
||||||
"running_peer": get_conf_running_peer_number(config_name),
|
"running_peer": get_conf_running_peer_number(config_name),
|
||||||
|
"conf_address": config_interface['Address']
|
||||||
}
|
}
|
||||||
if conf_data['status'] == "stopped":
|
if conf_data['status'] == "stopped":
|
||||||
conf_data['checked'] = "nope"
|
conf_data['checked'] = "nope"
|
||||||
else:
|
else:
|
||||||
conf_data['checked'] = "checked"
|
conf_data['checked'] = "checked"
|
||||||
return render_template('get_conf.html', conf_data=conf_data, wg_ip=wg_ip, sort_tag=sort, dashboard_refresh_interval=int(config.get("Server", "dashboard_refresh_interval")))
|
return render_template('get_conf.html', conf_data=conf_data, wg_ip=wg_ip, sort_tag=sort,
|
||||||
|
dashboard_refresh_interval=int(config.get("Server", "dashboard_refresh_interval")))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/switch/<config_name>', methods=['GET'])
|
@app.route('/switch/<config_name>', methods=['GET'])
|
||||||
@ -731,6 +758,9 @@ def add_peer(config_name):
|
|||||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||||
DNS = data['DNS']
|
DNS = data['DNS']
|
||||||
keys = get_conf_peer_key(config_name)
|
keys = get_conf_peer_key(config_name)
|
||||||
|
if len(public_key) == 0 or len(DNS) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
|
||||||
|
return "Please fill in all required box."
|
||||||
|
|
||||||
if type(keys) != list:
|
if type(keys) != list:
|
||||||
return config_name + " is not running."
|
return config_name + " is not running."
|
||||||
if public_key in keys:
|
if public_key in keys:
|
||||||
@ -750,7 +780,8 @@ def add_peer(config_name):
|
|||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
|
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
|
||||||
get_all_peers_data(config_name)
|
get_all_peers_data(config_name)
|
||||||
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'], "endpoint_allowed_ip": endpoint_allowed_ip},
|
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'],
|
||||||
|
"endpoint_allowed_ip": endpoint_allowed_ip},
|
||||||
peers.id == public_key)
|
peers.id == public_key)
|
||||||
db.close()
|
db.close()
|
||||||
return "true"
|
return "true"
|
||||||
@ -804,7 +835,6 @@ def save_peer_setting(config_name):
|
|||||||
return jsonify(check_key)
|
return jsonify(check_key)
|
||||||
if check_ip['status'] == "failed":
|
if check_ip['status'] == "failed":
|
||||||
return jsonify(check_ip)
|
return jsonify(check_ip)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if allowed_ip == "":
|
if allowed_ip == "":
|
||||||
allowed_ip = '""'
|
allowed_ip = '""'
|
||||||
@ -815,16 +845,13 @@ def save_peer_setting(config_name):
|
|||||||
if change_ip.decode("UTF-8") != "":
|
if change_ip.decode("UTF-8") != "":
|
||||||
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
|
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
|
||||||
|
|
||||||
|
db.update(
|
||||||
db.update({"name": name, "private_key": private_key, "DNS": DNS, "endpoint_allowed_ip":endpoint_allowed_ip}, peers.id == id)
|
{"name": name, "private_key": private_key, "DNS": DNS, "endpoint_allowed_ip": endpoint_allowed_ip},
|
||||||
|
peers.id == id)
|
||||||
db.close()
|
db.close()
|
||||||
return jsonify({"status": "success", "msg": ""})
|
return jsonify({"status": "success", "msg": ""})
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
return jsonify({"status": "failed", "msg": str(exc.output.decode("UTF-8").strip())})
|
return jsonify({"status": "failed", "msg": str(exc.output.decode("UTF-8").strip())})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
||||||
|
|
||||||
@ -881,7 +908,6 @@ def download(config_name):
|
|||||||
private_key = peer['private_key']
|
private_key = peer['private_key']
|
||||||
allowed_ip = peer['allowed_ip']
|
allowed_ip = peer['allowed_ip']
|
||||||
DNS = peer['DNS']
|
DNS = peer['DNS']
|
||||||
|
|
||||||
filename = peer['name']
|
filename = peer['name']
|
||||||
if len(filename) == 0:
|
if len(filename) == 0:
|
||||||
filename = "Untitled_Peers"
|
filename = "Untitled_Peers"
|
||||||
@ -922,7 +948,6 @@ def init_dashboard():
|
|||||||
config['Account']['username'] = 'admin'
|
config['Account']['username'] = 'admin'
|
||||||
if "password" not in config['Account']:
|
if "password" not in config['Account']:
|
||||||
config['Account']['password'] = '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918'
|
config['Account']['password'] = '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918'
|
||||||
|
|
||||||
if "Server" not in config:
|
if "Server" not in config:
|
||||||
config['Server'] = {}
|
config['Server'] = {}
|
||||||
if 'wg_conf_path' not in config['Server']:
|
if 'wg_conf_path' not in config['Server']:
|
||||||
@ -939,7 +964,6 @@ def init_dashboard():
|
|||||||
config['Server']['dashboard_refresh_interval'] = '15000'
|
config['Server']['dashboard_refresh_interval'] = '15000'
|
||||||
if 'dashboard_sort' not in config['Server']:
|
if 'dashboard_sort' not in config['Server']:
|
||||||
config['Server']['dashboard_sort'] = 'status'
|
config['Server']['dashboard_sort'] = 'status'
|
||||||
|
|
||||||
if "Peers" not in config:
|
if "Peers" not in config:
|
||||||
config['Peers'] = {}
|
config['Peers'] = {}
|
||||||
if 'peer_global_DNS' not in config['Peers']:
|
if 'peer_global_DNS' not in config['Peers']:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Flask==2.0.1
|
Flask==2.0.1
|
||||||
tinydb==4.3.0
|
tinydb==4.3.0
|
||||||
ifcfg==0.21
|
ifcfg==0.21
|
||||||
icmplib==2.1.1
|
icmplib==3.0.1
|
||||||
flask-qrcode==3.0.0
|
flask-qrcode==3.0.0
|
@ -58,8 +58,17 @@ $("#re_generate_key").click(function (){
|
|||||||
})
|
})
|
||||||
|
|
||||||
$("#save_peer").click(function(){
|
$("#save_peer").click(function(){
|
||||||
if ($("#allowed_ips") !== "" && $("#public_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() != ""){
|
||||||
var conf = $(this).attr('conf_id')
|
var conf = $(this).attr('conf_id')
|
||||||
|
var data_list = [$("#private_key"), $("#allowed_ips"), $("#new_add_name"), $("#new_add_DNS"), $("#new_add_endpoint_allowed_ip")]
|
||||||
|
for (var i = 0; i < data_list.length; i++){
|
||||||
|
data_list[i].attr("disabled", "disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/add_peer/"+conf,
|
url: "/add_peer/"+conf,
|
||||||
@ -84,6 +93,9 @@ $("#save_peer").click(function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}else{
|
||||||
|
$("#add_peer_alert").html("Please fill in all required box.");
|
||||||
|
$("#add_peer_alert").removeClass("d-none");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var qrcodeModal = new bootstrap.Modal(document.getElementById('qrcode_modal'), {
|
var qrcodeModal = new bootstrap.Modal(document.getElementById('qrcode_modal'), {
|
||||||
@ -108,6 +120,8 @@ $("body").on("click", ".btn-delete-peer", function(){
|
|||||||
})
|
})
|
||||||
|
|
||||||
$("#delete_peer").click(function(){
|
$("#delete_peer").click(function(){
|
||||||
|
$(this).attr("disabled","disabled")
|
||||||
|
$(this).html("Deleting...")
|
||||||
var peer_id = $(this).attr("peer_id");
|
var peer_id = $(this).attr("peer_id");
|
||||||
var config = $(this).attr("conf_id");
|
var config = $(this).attr("conf_id");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -127,6 +141,8 @@ $("#delete_peer").click(function(){
|
|||||||
load_data($('#search_peer_textbox').val());
|
load_data($('#search_peer_textbox').val());
|
||||||
$('#alertToast').toast('show');
|
$('#alertToast').toast('show');
|
||||||
$('#alertToast .toast-body').html("Peer deleted!");
|
$('#alertToast .toast-body').html("Peer deleted!");
|
||||||
|
$("#delete_peer").removeAttr("disabled")
|
||||||
|
$("#delete_peer").html("Delete")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -189,9 +205,16 @@ $("#peer_private_key_textbox").change(function(){
|
|||||||
$("#save_peer_setting").click(function (){
|
$("#save_peer_setting").click(function (){
|
||||||
$(this).attr("disabled","disabled")
|
$(this).attr("disabled","disabled")
|
||||||
$(this).html("Saving...")
|
$(this).html("Saving...")
|
||||||
if ($("#peer_DNS_textbox").val() !== "" && $("#peer_allowed_ip_textbox").val() !== ""){
|
if ($("#peer_DNS_textbox").val() !== "" &&
|
||||||
|
$("#peer_allowed_ip_textbox").val() !== "" &&
|
||||||
|
$("#peer_endpoint_allowed_ips").val() != ""
|
||||||
|
){
|
||||||
var peer_id = $(this).attr("peer_id");
|
var peer_id = $(this).attr("peer_id");
|
||||||
var conf_id = $(this).attr("conf_id");
|
var conf_id = $(this).attr("conf_id");
|
||||||
|
var data_list = [$("#peer_name_textbox"), $("#peer_DNS_textbox"), $("#peer_private_key_textbox"), $("#peer_allowed_ip_textbox"), $("#peer_endpoint_allowed_ips")]
|
||||||
|
for (var i = 0; i < data_list.length; i++){
|
||||||
|
data_list[i].attr("disabled", "disabled")
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/save_peer_setting/"+conf_id,
|
url: "/save_peer_setting/"+conf_id,
|
||||||
@ -218,8 +241,14 @@ $("#save_peer_setting").click(function (){
|
|||||||
}
|
}
|
||||||
$("#save_peer_setting").removeAttr("disabled")
|
$("#save_peer_setting").removeAttr("disabled")
|
||||||
$("#save_peer_setting").html("Save")
|
$("#save_peer_setting").html("Save")
|
||||||
|
for (var i = 0; i < data_list.length; i++){
|
||||||
|
data_list[i].removeAttr("disabled")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}else{
|
||||||
|
$("#setting_peer_alert").html("Please fill in all required box.");
|
||||||
|
$("#setting_peer_alert").removeClass("d-none");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,7 +317,16 @@ function copyToClipboard(element) {
|
|||||||
$temp.remove();
|
$temp.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$("body").on("click", ".update_interval", function(){
|
||||||
// $(".key").mouseenter(function(){
|
$.ajax({
|
||||||
//
|
method:"POST",
|
||||||
// })
|
data: "interval="+$(this).attr("refresh-interval"),
|
||||||
|
url: "/update_dashboard_refresh_interval",
|
||||||
|
success: function (res){
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$("body").on("click", ".refresh", function (){
|
||||||
|
load_data($('#search_peer_textbox').val());
|
||||||
|
});
|
||||||
|
@ -69,14 +69,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="new_add_DNS">DNS</label>
|
<label for="new_add_DNS">DNS <code>(Required)</code></label>
|
||||||
<input type="text" class="form-control" id="new_add_DNS" value="{{ DNS }}">
|
<input type="text" class="form-control" id="new_add_DNS" value="{{ DNS }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs</label>
|
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs <code>(Required)</code></label>
|
||||||
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip" value="{{ endpoint_allowed_ip }}">
|
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip" value="{{ endpoint_allowed_ip }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -228,7 +228,6 @@
|
|||||||
|
|
||||||
function load_data(search){
|
function load_data(search){
|
||||||
startProgressBar()
|
startProgressBar()
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "/get_config/"+conf_name+"?search="+encodeURIComponent(search),
|
url: "/get_config/"+conf_name+"?search="+encodeURIComponent(search),
|
||||||
@ -237,12 +236,10 @@
|
|||||||
},
|
},
|
||||||
success: function (response){
|
success: function (response){
|
||||||
$("#config_body").html(response);
|
$("#config_body").html(response);
|
||||||
{#$("[refresh-interval={{ dashboard_refresh_interval }}]").addClass("active")#}
|
|
||||||
$("#search_peer_textbox").css("display", "block")
|
$("#search_peer_textbox").css("display", "block")
|
||||||
if (bar.css("width") !== "0%"){
|
if (bar.css("width") !== "0%"){
|
||||||
endProgressBar()
|
endProgressBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -253,19 +250,7 @@
|
|||||||
}, {{dashboard_refresh_interval}})
|
}, {{dashboard_refresh_interval}})
|
||||||
});
|
});
|
||||||
|
|
||||||
$("body").on("click", ".update_interval", function(){
|
|
||||||
$.ajax({
|
|
||||||
method:"POST",
|
|
||||||
data: "interval="+$(this).attr("refresh-interval"),
|
|
||||||
url: "/update_dashboard_refresh_interval",
|
|
||||||
success: function (res){
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
$("body").on("click", ".refresh", function (){
|
|
||||||
load_data($('#search_peer_textbox').val());
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
||||||
</html>
|
</html>
|
@ -49,6 +49,10 @@
|
|||||||
<small class="text-muted"><strong>LISTEN PORT</strong></small>
|
<small class="text-muted"><strong>LISTEN PORT</strong></small>
|
||||||
<h6 style="text-transform: uppercase;"><samp>{{conf_data['listen_port']}}</samp></h6>
|
<h6 style="text-transform: uppercase;"><samp>{{conf_data['listen_port']}}</samp></h6>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<small class="text-muted"><strong>ADDRESS</strong></small>
|
||||||
|
<h6 style="text-transform: uppercase;"><samp>{{conf_data['conf_address']}}</samp></h6>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="button-div mb-3">
|
<div class="button-div mb-3">
|
||||||
@ -66,12 +70,12 @@
|
|||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><small class="text-muted">Refresh Interval</small></label><br>
|
<label><small class="text-muted">Refresh Interval</small></label><br>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group" style="width: 100%">
|
||||||
<button type="button" class="btn btn-outline-primary btn-group-label refresh"><i class="bi bi-arrow-repeat"></i></button>
|
<button style="width: 20%" type="button" class="btn btn-outline-primary btn-group-label refresh"><i class="bi bi-arrow-repeat"></i></button>
|
||||||
<button type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 5000 %} {{ "active" }} {% endif %}" refresh-interval="5000">5s</button>
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 5000 %} {{ "active" }} {% endif %}" refresh-interval="5000">5s</button>
|
||||||
<button type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 10000 %} {{ "active" }} {% endif %}" refresh-interval="10000">10s</button>
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 10000 %} {{ "active" }} {% endif %}" refresh-interval="10000">10s</button>
|
||||||
<button type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 30000 %} {{ "active" }} {% endif %}" refresh-interval="30000">30s</button>
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 30000 %} {{ "active" }} {% endif %}" refresh-interval="30000">30s</button>
|
||||||
<button type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 60000 %} {{ "active" }} {% endif %}" refresh-interval="60000">1m</button>
|
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval {% if dashboard_refresh_interval == 60000 %} {{ "active" }} {% endif %}" refresh-interval="60000">1m</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -151,7 +155,7 @@
|
|||||||
<button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="{{ qrcode("[Interface]\nPrivateKey = "+i['private_key']+"\nAddress = "+i['allowed_ip']+"\nDNS = 1.1.1.1\n\n[Peer]\nPublicKey = "+conf_data['public_key']+"\nAllowedIPs = 0.0.0.0/0\nEndpoint = "+wg_ip+":"+conf_data['listen_port']) }}">
|
<button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="{{ qrcode("[Interface]\nPrivateKey = "+i['private_key']+"\nAddress = "+i['allowed_ip']+"\nDNS = 1.1.1.1\n\n[Peer]\nPublicKey = "+conf_data['public_key']+"\nAllowedIPs = 0.0.0.0/0\nEndpoint = "+wg_ip+":"+conf_data['listen_port']) }}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg>
|
||||||
</button>
|
</button>
|
||||||
<a href="/download/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}" type="button" class="btn btn-outline-info btn-download-peer btn-control">
|
<a href="/download/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}" class="btn btn-outline-info btn-download-peer btn-control">
|
||||||
<i class="bi bi-download"></i>
|
<i class="bi bi-download"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>Wireguard Dashboard - {{ title }}</title>
|
<title>Wireguard Dashboard | {{ title }}</title>
|
||||||
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
|
<link rel="icon" href="{{ url_for('static',filename='img/logo.png') }}"/>
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}">
|
||||||
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/dashboard.css') }}">
|
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='css/dashboard.css') }}">
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<html>
|
<html>
|
||||||
{% include "header.html" %}
|
{% with %}
|
||||||
|
{% set title="Home" %}
|
||||||
|
{% include "header.html"%}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{% include "navbar.html" %}
|
{% include "navbar.html" %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<html>
|
<html>
|
||||||
{% include "header.html" %}
|
{% with %}
|
||||||
|
{% set title="Settings" %}
|
||||||
|
{% include "header.html"%}
|
||||||
|
{% endwith %}
|
||||||
<body>
|
<body>
|
||||||
{% include "navbar.html" %}
|
{% include "navbar.html" %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
Loading…
Reference in New Issue
Block a user