mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-10-04 02:20:12 +02:00
Feature adding and UI adjustment
Added Preshared-Key to all configuration
This commit is contained in:
parent
f9e4fafe9f
commit
f2750de153
186
src/dashboard.py
186
src/dashboard.py
@ -235,11 +235,11 @@ def get_all_peers_data(config_name):
|
|||||||
for i in conf_peer_data['Peers']:
|
for i in conf_peer_data['Peers']:
|
||||||
search = db.search(peers.id == i['PublicKey'])
|
search = db.search(peers.id == i['PublicKey'])
|
||||||
if not search:
|
if not search:
|
||||||
db.insert({
|
new_data = {
|
||||||
"id": i['PublicKey'],
|
"id": i['PublicKey'],
|
||||||
"private_key": "",
|
"private_key": "",
|
||||||
"DNS": config.get("Peers", "peer_global_DNS"),
|
"DNS": config.get("Peers", "peer_global_DNS"),
|
||||||
"endpoint_allowed_ip": config.get("Peers","peer_endpoint_allowed_ip"),
|
"endpoint_allowed_ip": config.get("Peers", "peer_endpoint_allowed_ip"),
|
||||||
"name": "",
|
"name": "",
|
||||||
"total_receive": 0,
|
"total_receive": 0,
|
||||||
"total_sent": 0,
|
"total_sent": 0,
|
||||||
@ -250,9 +250,13 @@ def get_all_peers_data(config_name):
|
|||||||
"allowed_ip": "N/A",
|
"allowed_ip": "N/A",
|
||||||
"traffic": [],
|
"traffic": [],
|
||||||
"mtu": config.get("Peers", "peer_mtu"),
|
"mtu": config.get("Peers", "peer_mtu"),
|
||||||
"keepalive": config.get("Peers","peer_keep_alive"),
|
"keepalive": config.get("Peers", "peer_keep_alive"),
|
||||||
"remote_endpoint":config.get("Peers","remote_endpoint")
|
"remote_endpoint": config.get("Peers", "remote_endpoint"),
|
||||||
})
|
"preshared_key": ""
|
||||||
|
}
|
||||||
|
if "PresharedKey" in i.keys():
|
||||||
|
new_data["preshared_key"] = i["PresharedKey"]
|
||||||
|
db.insert(new_data)
|
||||||
else:
|
else:
|
||||||
# Update database since V2.2
|
# Update database since V2.2
|
||||||
update_db = {}
|
update_db = {}
|
||||||
@ -270,6 +274,11 @@ def get_all_peers_data(config_name):
|
|||||||
update_db['keepalive'] = config.get("Peers","peer_keep_alive")
|
update_db['keepalive'] = config.get("Peers","peer_keep_alive")
|
||||||
if "remote_endpoint" not in search[0]:
|
if "remote_endpoint" not in search[0]:
|
||||||
update_db['remote_endpoint'] = config.get("Peers","remote_endpoint")
|
update_db['remote_endpoint'] = config.get("Peers","remote_endpoint")
|
||||||
|
if "preshared_key" not in search[0]:
|
||||||
|
if "PresharedKey" in i.keys():
|
||||||
|
update_db['preshared_key'] = i["PresharedKey"]
|
||||||
|
else:
|
||||||
|
update_db['preshared_key'] = ""
|
||||||
db.update(update_db, peers.id == i['PublicKey'])
|
db.update(update_db, peers.id == i['PublicKey'])
|
||||||
# Remove peers no longer exist in WireGuard configuration file
|
# Remove peers no longer exist in WireGuard configuration file
|
||||||
db_key = list(map(lambda a: a['id'], db.all()))
|
db_key = list(map(lambda a: a['id'], db.all()))
|
||||||
@ -288,7 +297,7 @@ def get_all_peers_data(config_name):
|
|||||||
try:
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
pass
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Frontend Related Functions
|
Frontend Related Functions
|
||||||
@ -308,7 +317,10 @@ def get_peers(config_name, search, sort_t):
|
|||||||
else:
|
else:
|
||||||
result = sorted(result, key=lambda d: d[sort_t])
|
result = sorted(result, key=lambda d: d[sort_t])
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -353,7 +365,10 @@ def get_conf_total_data(config_name):
|
|||||||
upload_total = round(upload_total, 4)
|
upload_total = round(upload_total, 4)
|
||||||
download_total = round(download_total, 4)
|
download_total = round(download_total, 4)
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return [total, upload_total, download_total]
|
return [total, upload_total, download_total]
|
||||||
|
|
||||||
# Get configuration status
|
# Get configuration status
|
||||||
@ -384,11 +399,14 @@ def get_conf_list():
|
|||||||
def gen_private_key():
|
def gen_private_key():
|
||||||
gen = subprocess.check_output('wg genkey > private_key.txt && wg pubkey < private_key.txt > public_key.txt',
|
gen = subprocess.check_output('wg genkey > private_key.txt && wg pubkey < private_key.txt > public_key.txt',
|
||||||
shell=True)
|
shell=True)
|
||||||
|
gen_psk = subprocess.check_output('wg genpsk', shell=True)
|
||||||
|
preshare_key = gen_psk.decode("UTF-8").strip()
|
||||||
|
print(gen_psk.decode("UTF-8").strip())
|
||||||
private = open('private_key.txt')
|
private = open('private_key.txt')
|
||||||
private_key = private.readline().strip()
|
private_key = private.readline().strip()
|
||||||
public = open('public_key.txt')
|
public = open('public_key.txt')
|
||||||
public_key = public.readline().strip()
|
public_key = public.readline().strip()
|
||||||
data = {"private_key": private_key, "public_key": public_key}
|
data = {"private_key": private_key, "public_key": public_key, "preshared_key": preshare_key}
|
||||||
private.close()
|
private.close()
|
||||||
public.close()
|
public.close()
|
||||||
os.remove('private_key.txt')
|
os.remove('private_key.txt')
|
||||||
@ -423,11 +441,17 @@ def checkKeyMatch(private_key, public_key, config_name):
|
|||||||
match = db.search(peers.id == result['data'])
|
match = db.search(peers.id == result['data'])
|
||||||
if len(match) != 1 or result['data'] != public_key:
|
if len(match) != 1 or result['data'] != public_key:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return {'status': 'failed', 'msg': 'Please check your private key, it does not match with the public key.'}
|
return {'status': 'failed', 'msg': 'Please check your private key, it does not match with the public key.'}
|
||||||
else:
|
else:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return {'status': 'success'}
|
return {'status': 'success'}
|
||||||
|
|
||||||
# Check if there is repeated allowed IP
|
# Check if there is repeated allowed IP
|
||||||
@ -442,11 +466,17 @@ def check_repeat_allowed_IP(public_key, ip, config_name):
|
|||||||
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
|
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
|
||||||
if len(existed_ip) != 0:
|
if len(existed_ip) != 0:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
|
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
|
||||||
else:
|
else:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return {'status': 'success'}
|
return {'status': 'success'}
|
||||||
|
|
||||||
|
|
||||||
@ -457,7 +487,6 @@ Flask Functions
|
|||||||
# Before request
|
# Before request
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def auth_req():
|
def auth_req():
|
||||||
|
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
conf.read(dashboard_conf)
|
conf.read(dashboard_conf)
|
||||||
req = conf.get("Server", "auth_req")
|
req = conf.get("Server", "auth_req")
|
||||||
@ -715,12 +744,16 @@ def update_dashbaord_sort():
|
|||||||
# Update configuration refresh interval
|
# Update configuration refresh interval
|
||||||
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
|
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
|
||||||
def update_dashboard_refresh_interval():
|
def update_dashboard_refresh_interval():
|
||||||
|
preset_interval = ["5000", "10000", "30000", "60000"]
|
||||||
|
if request.form["interval"] in preset_interval:
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
|
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
|
||||||
config.write(open(dashboard_conf, "w"))
|
config.write(open(dashboard_conf, "w"))
|
||||||
config.clear()
|
config.clear()
|
||||||
return "true"
|
return "true"
|
||||||
|
else:
|
||||||
|
return "false"
|
||||||
|
|
||||||
# Configuration Page
|
# Configuration Page
|
||||||
@app.route('/configuration/<config_name>', methods=['GET'])
|
@app.route('/configuration/<config_name>', methods=['GET'])
|
||||||
@ -819,46 +852,78 @@ def add_peer(config_name):
|
|||||||
allowed_ips = data['allowed_ips']
|
allowed_ips = data['allowed_ips']
|
||||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||||
DNS = data['DNS']
|
DNS = data['DNS']
|
||||||
|
enable_preshared_key = data["enable_preshared_key"]
|
||||||
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:
|
if len(public_key) == 0 or len(DNS) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "Please fill in all required box."
|
return "Please fill in all required box."
|
||||||
if type(keys) != list:
|
if type(keys) != list:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return config_name + " is not running."
|
return config_name + " is not running."
|
||||||
if public_key in keys:
|
if public_key in keys:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "Public key already exist."
|
return "Public key already exist."
|
||||||
if len(db.search(peers.allowed_ip.matches(allowed_ips))) != 0:
|
if len(db.search(peers.allowed_ip.matches(allowed_ips))) != 0:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "Allowed IP already taken by another peer."
|
return "Allowed IP already taken by another peer."
|
||||||
if not check_DNS(DNS):
|
if not check_DNS(DNS):
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "DNS formate is incorrect. Example: 1.1.1.1"
|
return "DNS formate is incorrect. Example: 1.1.1.1"
|
||||||
if not check_Allowed_IPs(endpoint_allowed_ip):
|
if not check_Allowed_IPs(endpoint_allowed_ip):
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "Endpoint Allowed IPs format is incorrect."
|
return "Endpoint Allowed IPs format is incorrect."
|
||||||
if len(data['MTU']) != 0:
|
if len(data['MTU']) != 0:
|
||||||
try:
|
try:
|
||||||
mtu = int(data['MTU'])
|
mtu = int(data['MTU'])
|
||||||
except:
|
except:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "MTU format is not correct."
|
return "MTU format is not correct."
|
||||||
if len(data['keep_alive']) != 0:
|
if len(data['keep_alive']) != 0:
|
||||||
try:
|
try:
|
||||||
keep_alive = int(data['keep_alive'])
|
keep_alive = int(data['keep_alive'])
|
||||||
except:
|
except:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "Persistent Keepalive format is not correct."
|
return "Persistent Keepalive format is not correct."
|
||||||
try:
|
try:
|
||||||
|
if enable_preshared_key == True:
|
||||||
|
key = subprocess.check_output("wg genpsk > tmp_psk.txt", shell=True)
|
||||||
|
status = subprocess.check_output(
|
||||||
|
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips + " preshared-key " + "tmp_psk.txt", shell=True,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
os.remove("tmp_psk.txt")
|
||||||
|
elif enable_preshared_key == False:
|
||||||
status = subprocess.check_output(
|
status = subprocess.check_output(
|
||||||
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips, shell=True,
|
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips, shell=True,
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
@ -868,11 +933,17 @@ def add_peer(config_name):
|
|||||||
"endpoint_allowed_ip": endpoint_allowed_ip},
|
"endpoint_allowed_ip": endpoint_allowed_ip},
|
||||||
peers.id == public_key)
|
peers.id == public_key)
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "true"
|
return "true"
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return exc.output.strip()
|
return exc.output.strip()
|
||||||
|
|
||||||
# Remove peer
|
# Remove peer
|
||||||
@ -898,11 +969,17 @@ def remove_peer(config_name):
|
|||||||
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)
|
||||||
db.remove(peers.id == delete_key)
|
db.remove(peers.id == delete_key)
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return "true"
|
return "true"
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return exc.output.strip()
|
return exc.output.strip()
|
||||||
|
|
||||||
# Save peer settings
|
# Save peer settings
|
||||||
@ -915,6 +992,7 @@ def save_peer_setting(config_name):
|
|||||||
DNS = data['DNS']
|
DNS = data['DNS']
|
||||||
allowed_ip = data['allowed_ip']
|
allowed_ip = data['allowed_ip']
|
||||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||||
|
preshared_key = data['preshared_key']
|
||||||
sem.acquire(timeout=1)
|
sem.acquire(timeout=1)
|
||||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
||||||
peers = Query()
|
peers = Query()
|
||||||
@ -922,37 +1000,66 @@ def save_peer_setting(config_name):
|
|||||||
check_ip = check_repeat_allowed_IP(id, allowed_ip, config_name)
|
check_ip = check_repeat_allowed_IP(id, allowed_ip, config_name)
|
||||||
if not check_IP_with_range(endpoint_allowed_ip):
|
if not check_IP_with_range(endpoint_allowed_ip):
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
|
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
|
||||||
if not check_DNS(DNS):
|
if not check_DNS(DNS):
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
|
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
|
||||||
if len(data['MTU']) != 0:
|
if len(data['MTU']) != 0:
|
||||||
try:
|
try:
|
||||||
mtu = int(data['MTU'])
|
mtu = int(data['MTU'])
|
||||||
except:
|
except:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
|
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
|
||||||
if len(data['keep_alive']) != 0:
|
if len(data['keep_alive']) != 0:
|
||||||
try:
|
try:
|
||||||
keep_alive = int(data['keep_alive'])
|
keep_alive = int(data['keep_alive'])
|
||||||
except:
|
except:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
|
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
|
||||||
if private_key != "":
|
if private_key != "":
|
||||||
check_key = checkKeyMatch(private_key, id, config_name)
|
check_key = checkKeyMatch(private_key, id, config_name)
|
||||||
if check_key['status'] == "failed":
|
if check_key['status'] == "failed":
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify(check_key)
|
return jsonify(check_key)
|
||||||
if check_ip['status'] == "failed":
|
if check_ip['status'] == "failed":
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify(check_ip)
|
return jsonify(check_ip)
|
||||||
try:
|
try:
|
||||||
|
tmp_psk = open("tmp_edit_psk.txt", "w+")
|
||||||
|
tmp_psk.write(preshared_key)
|
||||||
|
tmp_psk.close()
|
||||||
|
change_psk = subprocess.check_output("wg set " + config_name + " peer " + id + " preshared-key tmp_edit_psk.txt", shell=True, stderr=subprocess.STDOUT)
|
||||||
|
if change_psk.decode("UTF-8") != "":
|
||||||
|
db.close()
|
||||||
|
try:
|
||||||
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
|
return jsonify({"status": "failed", "msg": change_psk.decode("UTF-8")})
|
||||||
if allowed_ip == "":
|
if allowed_ip == "":
|
||||||
allowed_ip = '""'
|
allowed_ip = '""'
|
||||||
allowed_ip = allowed_ip.replace(" ", "")
|
allowed_ip = allowed_ip.replace(" ", "")
|
||||||
@ -962,24 +1069,36 @@ def save_peer_setting(config_name):
|
|||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
if change_ip.decode("UTF-8") != "":
|
if change_ip.decode("UTF-8") != "":
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
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,
|
{"name": name, "private_key": private_key,
|
||||||
"DNS": DNS, "endpoint_allowed_ip": endpoint_allowed_ip,
|
"DNS": DNS, "endpoint_allowed_ip": endpoint_allowed_ip,
|
||||||
"mtu": data['MTU'],
|
"mtu": data['MTU'],
|
||||||
"keepalive":data['keep_alive']},
|
"keepalive":data['keep_alive'], "preshared_key": preshared_key},
|
||||||
peers.id == id)
|
peers.id == id)
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "success", "msg": ""})
|
return jsonify({"status": "success", "msg": ""})
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
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:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
||||||
|
|
||||||
# Get peer settings
|
# Get peer settings
|
||||||
@ -994,8 +1113,12 @@ def get_peer_name(config_name):
|
|||||||
db.close()
|
db.close()
|
||||||
data = {"name": result[0]['name'], "allowed_ip": result[0]['allowed_ip'], "DNS": result[0]['DNS'],
|
data = {"name": result[0]['name'], "allowed_ip": result[0]['allowed_ip'], "DNS": result[0]['DNS'],
|
||||||
"private_key": result[0]['private_key'], "endpoint_allowed_ip": result[0]['endpoint_allowed_ip'],
|
"private_key": result[0]['private_key'], "endpoint_allowed_ip": result[0]['endpoint_allowed_ip'],
|
||||||
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive']}
|
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive'], "preshared_key": result[0]["preshared_key"]}
|
||||||
|
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
|
|
||||||
# Generate a private key
|
# Generate a private key
|
||||||
@ -1039,6 +1162,7 @@ def generate_qrcode(config_name):
|
|||||||
MTU = peer['mtu']
|
MTU = peer['mtu']
|
||||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||||
keepalive = peer['keepalive']
|
keepalive = peer['keepalive']
|
||||||
|
preshared_key = peer["preshared_key"]
|
||||||
conf = {
|
conf = {
|
||||||
"public_key": public_key,
|
"public_key": public_key,
|
||||||
"listen_port": listen_port,
|
"listen_port": listen_port,
|
||||||
@ -1049,16 +1173,29 @@ def generate_qrcode(config_name):
|
|||||||
"mtu": MTU,
|
"mtu": MTU,
|
||||||
"endpoint_allowed_ip": endpoint_allowed_ip,
|
"endpoint_allowed_ip": endpoint_allowed_ip,
|
||||||
"keepalive": keepalive,
|
"keepalive": keepalive,
|
||||||
|
"preshared_key": preshared_key
|
||||||
}
|
}
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
return render_template("qrcode.html", i=conf)
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
|
|
||||||
|
result = "[Interface]\nPrivateKey = "+conf['private_key']+"\nAddress = "+conf['allowed_ip']+"\nMTU = "+conf['mtu']+"\nDNS = "+conf['DNS']\
|
||||||
|
+"\n\n[Peer]\nPublicKey = "+conf['public_key']+"\nAllowedIPs = "+conf['endpoint_allowed_ip']+"\nPersistentKeepalive = "+conf['keepalive']+"\nEndpoint = "+conf['endpoint']
|
||||||
|
if preshared_key != "":
|
||||||
|
result += "\nPresharedKey = "+preshared_key
|
||||||
|
|
||||||
|
return render_template("qrcode.html", i=result)
|
||||||
else:
|
else:
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return redirect("/configuration/" + config_name)
|
return redirect("/configuration/" + config_name)
|
||||||
# Download configuration file
|
# Download configuration file
|
||||||
@app.route('/<config_name>', methods=['GET'])
|
@app.route('/download/<config_name>', methods=['GET'])
|
||||||
def download(config_name):
|
def download(config_name):
|
||||||
print(request.headers.get('User-Agent'))
|
print(request.headers.get('User-Agent'))
|
||||||
id = request.args.get('id')
|
id = request.args.get('id')
|
||||||
@ -1080,6 +1217,7 @@ def download(config_name):
|
|||||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||||
keepalive = peer['keepalive']
|
keepalive = peer['keepalive']
|
||||||
filename = peer['name']
|
filename = peer['name']
|
||||||
|
preshared_key = peer["preshared_key"]
|
||||||
if len(filename) == 0:
|
if len(filename) == 0:
|
||||||
filename = "Untitled_Peers"
|
filename = "Untitled_Peers"
|
||||||
else:
|
else:
|
||||||
@ -1094,11 +1232,17 @@ def download(config_name):
|
|||||||
filename = "Untitled_Peer"
|
filename = "Untitled_Peer"
|
||||||
filename = "".join(filename.split(' '))
|
filename = "".join(filename.split(' '))
|
||||||
filename = filename + "_" + config_name
|
filename = filename + "_" + config_name
|
||||||
|
psk = ""
|
||||||
|
if preshared_key != "":
|
||||||
|
psk = "\nPresharedKey = "+preshared_key
|
||||||
|
|
||||||
def generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive):
|
def generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive):
|
||||||
yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\nMTU = " + MTU + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + endpoint+ "\nPersistentKeepalive = " + keepalive
|
yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\nMTU = " + MTU + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + endpoint+ "\nPersistentKeepalive = " + keepalive + psk
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return app.response_class(generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive),
|
return app.response_class(generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive),
|
||||||
mimetype='text/conf',
|
mimetype='text/conf',
|
||||||
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
||||||
@ -1106,7 +1250,7 @@ def download(config_name):
|
|||||||
db.close()
|
db.close()
|
||||||
return redirect("/configuration/" + config_name)
|
return redirect("/configuration/" + config_name)
|
||||||
|
|
||||||
# Switch peer displate mode
|
# Switch peer display mode
|
||||||
@app.route('/switch_display_mode/<mode>', methods=['GET'])
|
@app.route('/switch_display_mode/<mode>', methods=['GET'])
|
||||||
def switch_display_mode(mode):
|
def switch_display_mode(mode):
|
||||||
if mode in ['list','grid']:
|
if mode in ['list','grid']:
|
||||||
@ -1126,7 +1270,7 @@ Dashboard Tools Related
|
|||||||
def get_ping_ip():
|
def get_ping_ip():
|
||||||
config = request.form['config']
|
config = request.form['config']
|
||||||
sem.acquire(timeout=1)
|
sem.acquire(timeout=1)
|
||||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
db = TinyDB(os.path.join(db_path, config + ".json"))
|
||||||
|
|
||||||
html = ""
|
html = ""
|
||||||
for i in db.all():
|
for i in db.all():
|
||||||
@ -1141,7 +1285,10 @@ def get_ping_ip():
|
|||||||
html += "<option value=" + endpoint[0] + ">" + endpoint[0] + "</option>"
|
html += "<option value=" + endpoint[0] + ">" + endpoint[0] + "</option>"
|
||||||
html += "</optgroup>"
|
html += "</optgroup>"
|
||||||
db.close()
|
db.close()
|
||||||
|
try:
|
||||||
sem.release()
|
sem.release()
|
||||||
|
except RuntimeError as e:
|
||||||
|
print("RuntimeError: cannot release un-acquired lock")
|
||||||
return html
|
return html
|
||||||
|
|
||||||
# Ping IP
|
# Ping IP
|
||||||
@ -1261,12 +1408,3 @@ if __name__ == "__main__":
|
|||||||
wg_conf_path = config.get("Server", "wg_conf_path")
|
wg_conf_path = config.get("Server", "wg_conf_path")
|
||||||
config.clear()
|
config.clear()
|
||||||
app.run(host=app_ip, debug=False, port=app_port)
|
app.run(host=app_ip, debug=False, port=app_port)
|
||||||
else:
|
|
||||||
init_dashboard()
|
|
||||||
update = check_update()
|
|
||||||
config = configparser.ConfigParser(strict=False)
|
|
||||||
config.read(dashboard_conf)
|
|
||||||
app_ip = config.get("Server", "app_ip")
|
|
||||||
app_port = config.get("Server", "app_port")
|
|
||||||
wg_conf_path = config.get("Server", "wg_conf_path")
|
|
||||||
config.clear()
|
|
@ -134,6 +134,7 @@ body {
|
|||||||
|
|
||||||
.info h6{
|
.info h6{
|
||||||
line-break: anywhere;
|
line-break: anywhere;
|
||||||
|
transition: 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info .row .col-sm{
|
.info .row .col-sm{
|
||||||
@ -291,6 +292,10 @@ main{
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#peer_private_key_textbox, #private_key, #public_key{
|
||||||
|
font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
||||||
|
}
|
||||||
|
|
||||||
.progress-bar{
|
.progress-bar{
|
||||||
transition: 0.3s ease-in-out;
|
transition: 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
@ -323,3 +328,56 @@ main{
|
|||||||
.modal-content{
|
.modal-content{
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip-inner{
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes loading {
|
||||||
|
0%{
|
||||||
|
background-color: #dfdfdf;
|
||||||
|
}
|
||||||
|
50%{
|
||||||
|
background-color: #adadad;
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
background-color: #dfdfdf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes loading {
|
||||||
|
0%{
|
||||||
|
background-color: #dfdfdf;
|
||||||
|
}
|
||||||
|
50%{
|
||||||
|
background-color: #adadad;
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
background-color: #dfdfdf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.conf_card{
|
||||||
|
transition: 0.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: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#conf_status_btn{
|
||||||
|
transition: 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#conf_status_btn.info_loading{
|
||||||
|
height: 38px;
|
||||||
|
border-radius: 5px;
|
||||||
|
animation: loading 2s infinite ease-in-out;
|
||||||
|
}
|
@ -1,5 +1,38 @@
|
|||||||
|
let $body = $("body");
|
||||||
|
|
||||||
|
// Progress Bar
|
||||||
|
let $progress_bar = $(".progress-bar")
|
||||||
|
function startProgressBar(){
|
||||||
|
$progress_bar.css("width","0%")
|
||||||
|
$progress_bar.css("opacity", "100")
|
||||||
|
$progress_bar.css("background", "rgb(255,69,69)")
|
||||||
|
$progress_bar.css("background", "linear-gradient(145deg, rgba(255,69,69,1) 0%, rgba(0,115,186,1) 100%)")
|
||||||
|
$progress_bar.css("width","25%")
|
||||||
|
setTimeout(function(){
|
||||||
|
stillLoadingProgressBar();
|
||||||
|
},300)
|
||||||
|
}
|
||||||
|
function stillLoadingProgressBar(){
|
||||||
|
$progress_bar.css("transition", "3s ease-in-out")
|
||||||
|
$progress_bar.css("width", "75%")
|
||||||
|
}
|
||||||
|
function endProgressBar(){
|
||||||
|
$progress_bar.css("transition", "0.3s ease-in-out")
|
||||||
|
$progress_bar.css("width","100%")
|
||||||
|
setTimeout(function(){
|
||||||
|
$progress_bar.css("opacity", "0")
|
||||||
|
},250)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function showToast(msg) {
|
||||||
|
$('#alertToast').toast('show');
|
||||||
|
$('#alertToast .toast-body').html(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Config Toggle
|
// Config Toggle
|
||||||
$("body").on("click", ".switch", function (){
|
$body.on("click", ".switch", function (){
|
||||||
$(this).siblings($(".spinner-border")).css("display", "inline-block");
|
$(this).siblings($(".spinner-border")).css("display", "inline-block");
|
||||||
$(this).remove()
|
$(this).remove()
|
||||||
location.replace("/switch/"+$(this).attr('id'));
|
location.replace("/switch/"+$(this).attr('id'));
|
||||||
@ -13,6 +46,7 @@ function generate_key(){
|
|||||||
}).done(function(res){
|
}).done(function(res){
|
||||||
$("#private_key").val(res.private_key)
|
$("#private_key").val(res.private_key)
|
||||||
$("#public_key").val(res.public_key)
|
$("#public_key").val(res.public_key)
|
||||||
|
$("#preshare_key").val(res.preshared_key)
|
||||||
$("#add_peer_alert").addClass("d-none");
|
$("#add_peer_alert").addClass("d-none");
|
||||||
$("#re_generate_key i").removeClass("rotating")
|
$("#re_generate_key i").removeClass("rotating")
|
||||||
})
|
})
|
||||||
@ -36,7 +70,7 @@ function generate_public_key(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add Peer
|
// Add Peer
|
||||||
$("#private_key").change(function(){
|
$("#private_key").on("change",function(){
|
||||||
if ($("#private_key").val().length > 0){
|
if ($("#private_key").val().length > 0){
|
||||||
$("#re_generate_key i").addClass("rotating")
|
$("#re_generate_key i").addClass("rotating")
|
||||||
generate_public_key()
|
generate_public_key()
|
||||||
@ -53,7 +87,15 @@ $("#re_generate_key").click(function (){
|
|||||||
$("#re_generate_key i").addClass("rotating")
|
$("#re_generate_key i").addClass("rotating")
|
||||||
generate_key()
|
generate_key()
|
||||||
})
|
})
|
||||||
$("#save_peer").click(function(){
|
let addModal = new bootstrap.Modal(document.getElementById('add_modal'), {
|
||||||
|
keyboard: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$(".add_btn").on("click", function(){
|
||||||
|
addModal.toggle();
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#save_peer").on("click",function(){
|
||||||
$(this).attr("disabled","disabled")
|
$(this).attr("disabled","disabled")
|
||||||
$(this).html("Saving...")
|
$(this).html("Saving...")
|
||||||
|
|
||||||
@ -77,7 +119,8 @@ $("#save_peer").click(function(){
|
|||||||
"DNS": $("#new_add_DNS").val(),
|
"DNS": $("#new_add_DNS").val(),
|
||||||
"endpoint_allowed_ip": $("#new_add_endpoint_allowed_ip").val(),
|
"endpoint_allowed_ip": $("#new_add_endpoint_allowed_ip").val(),
|
||||||
"MTU": $("#new_add_MTU").val(),
|
"MTU": $("#new_add_MTU").val(),
|
||||||
"keep_alive": $("#new_add_keep_alive").val()
|
"keep_alive": $("#new_add_keep_alive").val(),
|
||||||
|
"enable_preshared_key": $("#enable_preshare_key").prop("checked"),
|
||||||
}),
|
}),
|
||||||
success: function (response){
|
success: function (response){
|
||||||
if(response != "true"){
|
if(response != "true"){
|
||||||
@ -90,7 +133,8 @@ $("#save_peer").click(function(){
|
|||||||
$("#save_peer").html("Save")
|
$("#save_peer").html("Save")
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
location.reload();
|
load_data("");
|
||||||
|
addModal.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -106,7 +150,7 @@ var qrcodeModal = new bootstrap.Modal(document.getElementById('qrcode_modal'), {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// QR Code
|
// QR Code
|
||||||
$("body").on("click", ".btn-qrcode-peer", function (){
|
$body.on("click", ".btn-qrcode-peer", function (){
|
||||||
var src = $(this).attr('img_src');
|
var src = $(this).attr('img_src');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
"url": src,
|
"url": src,
|
||||||
@ -122,7 +166,7 @@ var deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), {
|
|||||||
keyboard: false
|
keyboard: false
|
||||||
});
|
});
|
||||||
|
|
||||||
$("body").on("click", ".btn-delete-peer", function(){
|
$body.on("click", ".btn-delete-peer", function(){
|
||||||
var peer_id = $(this).attr("id");
|
var peer_id = $(this).attr("id");
|
||||||
$("#delete_peer").attr("peer_id", peer_id);
|
$("#delete_peer").attr("peer_id", peer_id);
|
||||||
deleteModal.toggle();
|
deleteModal.toggle();
|
||||||
@ -161,7 +205,7 @@ $("#delete_peer").click(function(){
|
|||||||
var settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), {
|
var settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), {
|
||||||
keyboard: false
|
keyboard: false
|
||||||
})
|
})
|
||||||
$("body").on("click", ".btn-setting-peer", function(){
|
$body.on("click", ".btn-setting-peer", function(){
|
||||||
startProgressBar()
|
startProgressBar()
|
||||||
var peer_id = $(this).attr("id");
|
var peer_id = $(this).attr("id");
|
||||||
$("#save_peer_setting").attr("peer_id", peer_id);
|
$("#save_peer_setting").attr("peer_id", peer_id);
|
||||||
@ -182,6 +226,7 @@ $("body").on("click", ".btn-setting-peer", function(){
|
|||||||
$("#setting_modal #peer_endpoint_allowed_ips").val(response['endpoint_allowed_ip'])
|
$("#setting_modal #peer_endpoint_allowed_ips").val(response['endpoint_allowed_ip'])
|
||||||
$("#setting_modal #peer_mtu").val(response['mtu'])
|
$("#setting_modal #peer_mtu").val(response['mtu'])
|
||||||
$("#setting_modal #peer_keep_alive").val(response['keep_alive'])
|
$("#setting_modal #peer_keep_alive").val(response['keep_alive'])
|
||||||
|
$("#setting_modal #peer_preshared_key_textbox").val(response["preshared_key"])
|
||||||
settingModal.toggle();
|
settingModal.toggle();
|
||||||
endProgressBar()
|
endProgressBar()
|
||||||
}
|
}
|
||||||
@ -223,7 +268,7 @@ $("#save_peer_setting").click(function (){
|
|||||||
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 = [
|
var data_list = [
|
||||||
$("#peer_name_textbox"), $("#peer_DNS_textbox"), $("#peer_private_key_textbox"),
|
$("#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")
|
$("#peer_allowed_ip_textbox"), $("#peer_endpoint_allowed_ips"), $("#peer_mtu"), $("#peer_keep_alive")
|
||||||
]
|
]
|
||||||
for (var i = 0; i < data_list.length; i++){
|
for (var i = 0; i < data_list.length; i++){
|
||||||
@ -243,7 +288,8 @@ $("#save_peer_setting").click(function (){
|
|||||||
allowed_ip: $("#peer_allowed_ip_textbox").val(),
|
allowed_ip: $("#peer_allowed_ip_textbox").val(),
|
||||||
endpoint_allowed_ip: $("#peer_endpoint_allowed_ips").val(),
|
endpoint_allowed_ip: $("#peer_endpoint_allowed_ips").val(),
|
||||||
MTU: $("#peer_mtu").val(),
|
MTU: $("#peer_mtu").val(),
|
||||||
keep_alive: $("#peer_keep_alive").val()
|
keep_alive: $("#peer_keep_alive").val(),
|
||||||
|
preshared_key: $("#peer_preshared_key_textbox").val()
|
||||||
}),
|
}),
|
||||||
success: function (response){
|
success: function (response){
|
||||||
if (response['status'] === "failed"){
|
if (response['status'] === "failed"){
|
||||||
@ -296,7 +342,7 @@ function doneTyping () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sorting
|
// Sorting
|
||||||
$("body").on("change", "#sort_by_dropdown", function (){
|
$body.on("change", "#sort_by_dropdown", function (){
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:"POST",
|
method:"POST",
|
||||||
data: JSON.stringify({'sort':$("#sort_by_dropdown option:selected").val()}),
|
data: JSON.stringify({'sort':$("#sort_by_dropdown option:selected").val()}),
|
||||||
@ -309,11 +355,11 @@ $("body").on("change", "#sort_by_dropdown", function (){
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Click key to copy
|
// Click key to copy
|
||||||
$("body").on("mouseenter", ".key", function(){
|
$body.on("mouseenter", ".key", function(){
|
||||||
var label = $(this).parent().siblings().children()[1]
|
var label = $(this).parent().siblings().children()[1]
|
||||||
label.style.opacity = "100"
|
label.style.opacity = "100"
|
||||||
})
|
})
|
||||||
$("body").on("mouseout", ".key", function(){
|
$body.on("mouseout", ".key", function(){
|
||||||
var label = $(this).parent().siblings().children()[1]
|
var label = $(this).parent().siblings().children()[1]
|
||||||
label.style.opacity = "0"
|
label.style.opacity = "0"
|
||||||
setTimeout(function (){
|
setTimeout(function (){
|
||||||
@ -321,39 +367,54 @@ $("body").on("mouseout", ".key", function(){
|
|||||||
},200)
|
},200)
|
||||||
|
|
||||||
});
|
});
|
||||||
$("body").on("click", ".key", function(){
|
$body.on("click", ".key", function(){
|
||||||
var label = $(this).parent().siblings().children()[1]
|
var label = $(this).parent().siblings().children()[1]
|
||||||
copyToClipboard($(this))
|
copyToClipboard($(this))
|
||||||
label.innerHTML = "COPIED!"
|
label.innerHTML = "COPIED!"
|
||||||
})
|
})
|
||||||
function copyToClipboard(element) {
|
function copyToClipboard(element) {
|
||||||
var $temp = $("<input>");
|
var $temp = $("<input>");
|
||||||
$("body").append($temp);
|
$body.append($temp);
|
||||||
$temp.val($(element).text()).select();
|
$temp.val($(element).text()).select();
|
||||||
document.execCommand("copy");
|
document.execCommand("copy");
|
||||||
$temp.remove();
|
$temp.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Interval
|
// Update Interval
|
||||||
$("body").on("click", ".update_interval", function(){
|
$body.on("click", ".update_interval", function(){
|
||||||
|
let prev = $(".interval-btn-group.active button");
|
||||||
$(".interval-btn-group button").removeClass("active");
|
$(".interval-btn-group button").removeClass("active");
|
||||||
$(this).addClass("active");
|
let _new = $(this)
|
||||||
|
_new.addClass("active");
|
||||||
|
let interval = $(this).data("refresh-interval");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:"POST",
|
method:"POST",
|
||||||
data: "interval="+$(this).data("refresh-interval"),
|
data: "interval="+$(this).data("refresh-interval"),
|
||||||
url: "/update_dashboard_refresh_interval",
|
url: "/update_dashboard_refresh_interval",
|
||||||
success: function (res){
|
success: function (res){
|
||||||
|
if (res === "true"){
|
||||||
load_data($('#search_peer_textbox').val())
|
load_interval = interval;
|
||||||
|
clearInterval(load_timeout);
|
||||||
|
load_timeout = setInterval(function (){
|
||||||
|
load_data($('#search_peer_textbox').val());
|
||||||
|
}, interval);
|
||||||
|
showToast("Refresh Interval set to "+Math.round(interval/1000)+" seconds");
|
||||||
|
}else{
|
||||||
|
$(".interval-btn-group button").removeClass("active");
|
||||||
|
$('.interval-btn-group button[data-refresh-interval="'+load_interval+'"]').addClass("active");
|
||||||
|
showToast("Refresh Interval set unsuccessful");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
$("body").on("click", ".refresh", function (){
|
$body.on("click", ".refresh", function (){
|
||||||
load_data($('#search_peer_textbox').val());
|
load_data($('#search_peer_textbox').val());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Switch display mode
|
// Switch display mode
|
||||||
$("body").on("click", ".display_mode", function(){
|
$body.on("click", ".display_mode", function(){
|
||||||
$(".display-btn-group button").removeClass("active");
|
$(".display-btn-group button").removeClass("active");
|
||||||
$(this).addClass("active");
|
$(this).addClass("active");
|
||||||
let display_mode = $(this).data("display-mode");
|
let display_mode = $(this).data("display-mode");
|
||||||
@ -361,16 +422,25 @@ $("body").on("click", ".display_mode", function(){
|
|||||||
method:"GET",
|
method:"GET",
|
||||||
url: "/switch_display_mode/"+$(this).data("display-mode"),
|
url: "/switch_display_mode/"+$(this).data("display-mode"),
|
||||||
success: function (res){
|
success: function (res){
|
||||||
// load_data($('#search_peer_textbox').val())
|
if (res === "true"){
|
||||||
if (display_mode === "list"){
|
if (display_mode === "list"){
|
||||||
Array($(".peer_list").children()).forEach(function(child){
|
Array($(".peer_list").children()).forEach(function(child){
|
||||||
$(child).removeClass().addClass("col-12");
|
$(child).removeClass().addClass("col-12");
|
||||||
})
|
})
|
||||||
|
showToast("Displaying as List");
|
||||||
}else{
|
}else{
|
||||||
Array($(".peer_list").children()).forEach(function(child){
|
Array($(".peer_list").children()).forEach(function(child){
|
||||||
$(child).removeClass().addClass("col-sm-6 col-lg-4");
|
$(child).removeClass().addClass("col-sm-6 col-lg-4");
|
||||||
})
|
});
|
||||||
|
showToast("Displaying as Grid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Pre-share key
|
||||||
|
// $("#enable_preshare_key").on("change", function(){
|
||||||
|
// $(".preshare_key_container").css("display", $(".preshare_key_container").css("display") === "none" ? "block":"none");
|
||||||
|
//
|
||||||
|
// })
|
@ -8,7 +8,7 @@
|
|||||||
{% include "sidebar.html" %}
|
{% include "sidebar.html" %}
|
||||||
<div class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
|
<div class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" id="search_peer_textbox" placeholder="Search Peer..." value="" style="display: none">
|
<input type="text" class="form-control" id="search_peer_textbox" placeholder="Search Peer..." value="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="config_body">
|
<div id="config_body">
|
||||||
@ -21,8 +21,8 @@
|
|||||||
<h1 class="mb-3"><samp id="conf_name">{{ title }}</samp></h1>
|
<h1 class="mb-3"><samp id="conf_name">{{ title }}</samp></h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<small class="text-muted"><strong>ACTION</strong></small><br>
|
<small class="text-muted"><strong>SWITCH</strong></small><br>
|
||||||
<div id="conf_status_btn"></div>
|
<div id="conf_status_btn" class="info_loading"></div>
|
||||||
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
|
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
|
||||||
<span class="sr-only">Loading...</span>
|
<span class="sr-only">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
@ -30,23 +30,23 @@
|
|||||||
<div class="w-100"></div>
|
<div class="w-100"></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<small class="text-muted"><strong>STATUS</strong></small>
|
<small class="text-muted"><strong>STATUS</strong></small>
|
||||||
<h6 style="text-transform: uppercase;" id="conf_status"></h6>
|
<h6 style="text-transform: uppercase;" id="conf_status" class="info_loading"></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<small class="text-muted"><strong>CONNECTED PEERS</strong></small>
|
<small class="text-muted"><strong>CONNECTED PEERS</strong></small>
|
||||||
<h6 style="text-transform: uppercase;" id="conf_connected_peers"></h6>
|
<h6 style="text-transform: uppercase;" id="conf_connected_peers" class="info_loading"></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<small class="text-muted"><strong>TOTAL DATA USAGE</strong></small>
|
<small class="text-muted"><strong>TOTAL DATA USAGE</strong></small>
|
||||||
<h6 style="text-transform: uppercase;" id="conf_total_data_usage"></h6>
|
<h6 style="text-transform: uppercase;" id="conf_total_data_usage" class="info_loading"></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
|
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
|
||||||
<h6 style="text-transform: uppercase;" id="conf_total_data_received"></h6>
|
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading"></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<small class="text-muted"><strong>TOTAL SENT</strong></small>
|
<small class="text-muted"><strong>TOTAL SENT</strong></small>
|
||||||
<h6 style="text-transform: uppercase;" id="conf_total_data_sent"></h6>
|
<h6 style="text-transform: uppercase;" id="conf_total_data_sent" class="info_loading"></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-100"></div>
|
<div class="w-100"></div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
@ -54,15 +54,15 @@
|
|||||||
<strong>PUBLIC KEY</strong>
|
<strong>PUBLIC KEY</strong>
|
||||||
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong>
|
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong>
|
||||||
</small>
|
</small>
|
||||||
<h6><samp class="key" id="conf_public_key"></samp></h6>
|
<h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<small class="text-muted"><strong>LISTEN PORT</strong></small>
|
<small class="text-muted"><strong>LISTEN PORT</strong></small>
|
||||||
<h6 style="text-transform: uppercase;"><samp id="conf_listen_port"></samp></h6>
|
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_listen_port"></samp></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<small class="text-muted"><strong>ADDRESS</strong></small>
|
<small class="text-muted"><strong>ADDRESS</strong></small>
|
||||||
<h6 style="text-transform: uppercase;"><samp id="conf_address"></samp></h6>
|
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp></h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -100,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary add_btn" data-toggle="modal" data-target="#add_modal">
|
<button type="button" class="btn btn-primary add_btn">
|
||||||
<i class="bi bi-plus-circle-fill" style=""></i> Add Peer
|
<i class="bi bi-plus-circle-fill" style=""></i> Add Peer
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -134,7 +134,7 @@
|
|||||||
<label for="private_key">Private Key</label>
|
<label for="private_key">Private Key</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" id="private_key" aria-describedby="public_key">
|
<input type="text" class="form-control" id="private_key" aria-describedby="private_key">
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button type="button" class="btn btn-danger" id="re_generate_key"><i class="bi bi-arrow-repeat"></i></button>
|
<button type="button" class="btn btn-danger" id="re_generate_key"><i class="bi bi-arrow-repeat"></i></button>
|
||||||
</div>
|
</div>
|
||||||
@ -181,6 +181,12 @@
|
|||||||
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}">
|
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="enable_preshare_key" name="enable_preshare_key" value="enable_psk">
|
||||||
|
<label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -233,11 +239,15 @@
|
|||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mb-3">
|
||||||
<label for="peer_private_key_textbox" class="form-label">Private Key <code>(Required for QR Code and download)</code></label>
|
<label for="peer_private_key_textbox" class="form-label">Private Key <code>(Required for QR Code and download)</code></label>
|
||||||
<input type="password" class="form-control" id="peer_private_key_textbox" style="padding-right: 40px">
|
<input type="password" class="form-control" id="peer_private_key_textbox" style="padding-right: 40px">
|
||||||
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
|
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="peer_preshared_key_textbox" class="form-label">Pre-Shared Key</label>
|
||||||
|
<input type="text" class="form-control" id="peer_preshared_key_textbox">
|
||||||
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -307,7 +317,7 @@
|
|||||||
<div class="position-fixed top-0 right-0 p-3" style="z-index: 5; right: 0; top: 50px;">
|
<div class="position-fixed top-0 right-0 p-3" style="z-index: 5; right: 0; top: 50px;">
|
||||||
<div id="alertToast" class="toast hide" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
|
<div id="alertToast" class="toast hide" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
|
||||||
<div class="toast-header">
|
<div class="toast-header">
|
||||||
<strong class="mr-auto">Wireguard Dashboard</strong>
|
<strong class="mr-auto">WGDashboard</strong>
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
@ -319,35 +329,16 @@
|
|||||||
{% include "tools.html" %}
|
{% include "tools.html" %}
|
||||||
</body>
|
</body>
|
||||||
{% include "footer.html" %}
|
{% include "footer.html" %}
|
||||||
|
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
||||||
<script>
|
<script>
|
||||||
|
function roundN(value, digits) {
|
||||||
|
var tenToN = 10 ** digits;
|
||||||
|
return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
|
||||||
|
}
|
||||||
let load_timeout;
|
let load_timeout;
|
||||||
let load_interval = 0;
|
let load_interval = 0;
|
||||||
var conf_name = "{{ conf_data['name'] }}"
|
let conf_name = "{{ conf_data['name'] }}"
|
||||||
$(".sb-"+conf_name+"-url").addClass("active");
|
$(".sb-"+conf_name+"-url").addClass("active");
|
||||||
// Progress Bar
|
|
||||||
let bar = $(".progress-bar")
|
|
||||||
function startProgressBar(){
|
|
||||||
bar.css("width","0%")
|
|
||||||
bar.css("opacity", "100")
|
|
||||||
bar.css("background", "rgb(255,69,69)")
|
|
||||||
bar.css("background", "linear-gradient(145deg, rgba(255,69,69,1) 0%, rgba(0,115,186,1) 100%)")
|
|
||||||
bar.css("width","25%")
|
|
||||||
setTimeout(function(){
|
|
||||||
stillLoadingProgressBar();
|
|
||||||
},300)
|
|
||||||
}
|
|
||||||
function stillLoadingProgressBar(){
|
|
||||||
bar.css("transition", "3s ease-in-out")
|
|
||||||
bar.css("width", "75%")
|
|
||||||
}
|
|
||||||
function endProgressBar(){
|
|
||||||
bar.css("transition", "0.3s ease-in-out")
|
|
||||||
bar.css("width","100%")
|
|
||||||
setTimeout(function(){
|
|
||||||
bar.css("opacity", "0")
|
|
||||||
},250)
|
|
||||||
|
|
||||||
}
|
|
||||||
function load_data(search){
|
function load_data(search){
|
||||||
startProgressBar()
|
startProgressBar()
|
||||||
let result = '';
|
let result = '';
|
||||||
@ -382,22 +373,35 @@
|
|||||||
|
|
||||||
$("#conf_status").html(response["status"]+'<span class="dot dot-'+response["status"]+'"></span>');
|
$("#conf_status").html(response["status"]+'<span class="dot dot-'+response["status"]+'"></span>');
|
||||||
$("#conf_connected_peers").html(response["running_peer"]);
|
$("#conf_connected_peers").html(response["running_peer"]);
|
||||||
$("#conf_total_data_usage").html(response["total_data_usage"][0]+" GB");
|
$("#conf_total_data_usage").html(response["total_data_usage"][0] +" GB");
|
||||||
$("#conf_total_data_received").html(response["total_data_usage"][1]+" GB");
|
$("#conf_total_data_received").html(response["total_data_usage"][2] +" GB");
|
||||||
$("#conf_total_data_sent").html(response["total_data_usage"][2]+" GB");
|
$("#conf_total_data_sent").html(response["total_data_usage"][1]+" GB");
|
||||||
$("#conf_public_key").html(response["public_key"]);
|
$("#conf_public_key").html(response["public_key"]);
|
||||||
$("#conf_listen_port").html(response["listen_port"] === "" ? "N/A":response["listen_port"]);
|
$("#conf_listen_port").html(response["listen_port"] === "" ? "N/A":response["listen_port"]);
|
||||||
$("#conf_address").html(response["conf_address"]);
|
$("#conf_address").html(response["conf_address"]);
|
||||||
|
$(".info h6").removeClass("info_loading");
|
||||||
|
$("#conf_status_btn").removeClass("info_loading")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (response["peer_data"].length === 0){
|
if (response["peer_data"].length === 0){
|
||||||
$(".peer_list").html('<div class="col-12" style="text-align: center; margin-top: 1.5rem"><h3 class="text-muted">Oops! No peers found ‘︿’</h3></div>');
|
$(".peer_list").html('<div class="col-12" style="text-align: center; margin-top: 1.5rem"><h3 class="text-muted">Oops! No peers found ‘︿’</h3></div>');
|
||||||
}else{
|
}else{
|
||||||
let display_mode = response["peer_display_mode"] === "list" ? "col-12" : "col-sm-6 col-lg-4";
|
let display_mode = response["peer_display_mode"] === "list" ? "col-12" : "col-sm-6 col-lg-4";
|
||||||
response["peer_data"].forEach(function(peer){
|
response["peer_data"].forEach(function(peer){
|
||||||
|
let total_r = 0;
|
||||||
|
let total_s = 0;
|
||||||
|
for (let i = 0; i < peer["traffic"].length; i++){
|
||||||
|
total_r += peer["traffic"][i]["total_receive"];
|
||||||
|
total_s += peer["traffic"][i]["total_sent"];
|
||||||
|
}
|
||||||
let spliter = '<div class="w-100"></div>';
|
let spliter = '<div class="w-100"></div>';
|
||||||
let peer_name = '<div class="col-sm"><h4>'+ (peer["name"] === "" ? "Untitled" : peer["name"]) +'</h4></div>';
|
let peer_name =
|
||||||
let peer_status = '<div class="col-6"><small class="text-muted"><strong>STATUS</strong></small> <h6 style="text-transform: uppercase;" class="mb-2 h6-dot-'+peer["status"]+'"><span class="dot dot-'+peer["status"]+'" style="margin-left: 0 !important;margin-top: 5px"></span></h6></div>'
|
'<div class="col-sm display" style="display: flex; align-items: center; margin-bottom: 0.2rem">' +
|
||||||
let peer_transfer = '<div class="col-6 peer_data_group" style="text-align: right"> <small class="text-muted"><strong>TRANSFER</strong></small> <p class="text-primary" style="text-transform: uppercase; margin-bottom: 0;"><small><i class="bi bi-arrow-down-right"></i>'+peer["total_receive"]+' GB</small></p> <p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> '+peer["total_sent"]+' GB</small></p> </div>'
|
'<h5 style="margin: 0;">'+ (peer["name"] === "" ? "Untitled" : peer["name"]) +'</h5>' +
|
||||||
|
'<h6 style="text-transform: uppercase; margin: 0; margin-left: auto !important;"><span class="dot dot-'+peer["status"]+'" style="margin-left: auto !important;" data-toggle="tooltip" data-placement="left" title="Peer Running"></span></h6>' +
|
||||||
|
'</div>';
|
||||||
|
let peer_transfer = '<div class="col-12 peer_data_group" style="text-align: right; display: flex; margin-bottom: 0.5rem"><p class="text-primary" style="text-transform: uppercase; margin-bottom: 0; margin-right: 1rem"><small><i class="bi bi-arrow-down-right"></i> '+ roundN(peer["total_receive"] + total_r, 4) +' GB</small></p> <p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> '+ roundN(peer["total_sent"] + total_s, 4) +' GB</small></p> </div>'
|
||||||
let peer_key = '<div class="col-sm"><small class="text-muted" style="display: flex"><strong>PEER</strong><strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small> <h6><samp class="ml-auto key">'+peer["id"]+'</samp></h6></div>';
|
let peer_key = '<div class="col-sm"><small class="text-muted" style="display: flex"><strong>PEER</strong><strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small> <h6><samp class="ml-auto key">'+peer["id"]+'</samp></h6></div>';
|
||||||
let peer_allowed_ip = '<div class="col-sm"><small class="text-muted"><strong>ALLOWED IP</strong></small><h6 style="text-transform: uppercase;">'+peer["allowed_ip"]+'</h6></div>';
|
let peer_allowed_ip = '<div class="col-sm"><small class="text-muted"><strong>ALLOWED IP</strong></small><h6 style="text-transform: uppercase;">'+peer["allowed_ip"]+'</h6></div>';
|
||||||
let peer_latest_handshake = '<div class="col-sm"> <small class="text-muted"><strong>LATEST HANDSHAKE</strong></small> <h6 style="text-transform: uppercase;">'+peer['latest_handshake']+'</h6> </div>';
|
let peer_latest_handshake = '<div class="col-sm"> <small class="text-muted"><strong>LATEST HANDSHAKE</strong></small> <h6 style="text-transform: uppercase;">'+peer['latest_handshake']+'</h6> </div>';
|
||||||
@ -413,7 +417,6 @@
|
|||||||
'<div class="row">'
|
'<div class="row">'
|
||||||
+ peer_name
|
+ peer_name
|
||||||
+ spliter
|
+ spliter
|
||||||
+ peer_status
|
|
||||||
+ peer_transfer
|
+ peer_transfer
|
||||||
+ peer_key
|
+ peer_key
|
||||||
+ peer_allowed_ip
|
+ peer_allowed_ip
|
||||||
@ -437,17 +440,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{#$("#config_body").html(response);#}
|
{#$("#config_body").html(response);#}
|
||||||
$("#search_peer_textbox").css("display", "block")
|
$(".dot.dot-running").attr("title","Peer Running").tooltip();
|
||||||
|
$(".dot.dot-stopped").attr("title","Peer Stopped").tooltip();
|
||||||
|
{#$("#search_peer_textbox").css("display", "block")#}
|
||||||
endProgressBar()
|
endProgressBar()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
$(function(){
|
$(function(){
|
||||||
load_data($('#search_peer_textbox').val());
|
load_data($('#search_peer_textbox').val());
|
||||||
{#setInterval(function(){#}
|
|
||||||
{# load_data($('#search_peer_textbox').val());#}
|
|
||||||
{#}, {{dashboard_refresh_interval}})#}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
|
||||||
</html>
|
</html>
|
@ -14,12 +14,12 @@
|
|||||||
<p class="text-muted">You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".</p>
|
<p class="text-muted">You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for i in conf%}
|
{% for i in conf%}
|
||||||
<div class="card mt-3">
|
<div class="card mt-3 conf_card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col card-col">
|
<div class="col card-col">
|
||||||
<small class="text-muted"><strong>CONFIGURATION</strong></small>
|
<small class="text-muted"><strong>CONFIGURATION</strong></small>
|
||||||
<a href="/configuration/{{i['conf']}}">
|
<a href="/configuration/{{i['conf']}}" class="conf_link">
|
||||||
<h6 class="card-title" style="margin:0 !important;">{{i['conf']}}</h6>
|
<h6 class="card-title" style="margin:0 !important;">{{i['conf']}}</h6>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -51,11 +51,18 @@
|
|||||||
</body>
|
</body>
|
||||||
{% include "footer.html" %}
|
{% include "footer.html" %}
|
||||||
<script>
|
<script>
|
||||||
$('.switch').click(function() {
|
|
||||||
|
$('.switch').on("click", function() {
|
||||||
$(this).siblings($(".spinner-border")).css("display", "inline-block")
|
$(this).siblings($(".spinner-border")).css("display", "inline-block")
|
||||||
$(this).remove()
|
$(this).remove()
|
||||||
location.replace("/switch/"+$(this).attr('id'))
|
location.replace("/switch/"+$(this).attr('id'))
|
||||||
});
|
});
|
||||||
$(".sb-home-url").addClass("active")
|
$(".sb-home-url").addClass("active");
|
||||||
|
|
||||||
|
$(".card-body").on("click", function(handle){
|
||||||
|
if ($(handle.target).attr("class") !== "bi bi-toggle2-off" && $(handle.target).attr("class") !== "bi bi-toggle2-on") {
|
||||||
|
window.open($(this).find("a").attr("href"), "_self");
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
@ -1 +1 @@
|
|||||||
{{ qrcode("[Interface]\nPrivateKey = "+i['private_key']+"\nAddress = "+i['allowed_ip']+"\nMTU = "+i['mtu']+"\nDNS = "+i['DNS']+"\n\n[Peer]\nPublicKey = "+i['public_key']+"\nAllowedIPs = "+i['endpoint_allowed_ip']+"\nPersistentKeepalive = "+i['keepalive']+"\nEndpoint = "+i['endpoint']) }}
|
{{ qrcode(i) }}
|
Loading…
Reference in New Issue
Block a user