mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-22 15:20:09 +01:00
Merge branch 'main' into refactoring
This commit is contained in:
commit
c22e61add2
369
src/dashboard.py
369
src/dashboard.py
@ -260,7 +260,7 @@ def get_all_peers_data(config_name):
|
||||
for i in conf_peer_data['Peers']:
|
||||
search = db.search(peers.id == i['PublicKey'])
|
||||
if not search:
|
||||
db.insert({
|
||||
new_data = {
|
||||
"id": i['PublicKey'],
|
||||
"private_key": "",
|
||||
"DNS": config.get("Peers", "peer_global_DNS"),
|
||||
@ -276,8 +276,12 @@ def get_all_peers_data(config_name):
|
||||
"traffic": [],
|
||||
"mtu": config.get("Peers", "peer_mtu"),
|
||||
"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:
|
||||
# Update database since V2.2
|
||||
update_db = {}
|
||||
@ -294,7 +298,12 @@ def get_all_peers_data(config_name):
|
||||
if "keepalive" not in search[0]:
|
||||
update_db['keepalive'] = config.get("Peers", "peer_keep_alive")
|
||||
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'])
|
||||
# Remove peers no longer exist in WireGuard configuration file
|
||||
db_key = list(map(lambda a: a['id'], db.all()))
|
||||
@ -313,7 +322,7 @@ def get_all_peers_data(config_name):
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
pass
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
|
||||
|
||||
# Search for peers
|
||||
@ -335,7 +344,10 @@ def get_peers(config_name, search, sort_t):
|
||||
else:
|
||||
result = sorted(result, key=lambda d: d[sort_t])
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return result
|
||||
|
||||
|
||||
@ -381,7 +393,10 @@ def get_conf_total_data(config_name):
|
||||
upload_total = round(upload_total, 4)
|
||||
download_total = round(download_total, 4)
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return [total, upload_total, download_total]
|
||||
|
||||
|
||||
@ -411,13 +426,17 @@ def get_conf_list():
|
||||
|
||||
# Generate private key
|
||||
def gen_private_key():
|
||||
gen = subprocess.check_output('wg genkey > private_key.txt && wg pubkey < private_key.txt > public_key.txt',
|
||||
shell=True)
|
||||
gen_psk = subprocess.check_output('wg genpsk', shell=True)
|
||||
preshare_key = gen_psk.decode("UTF-8").strip()
|
||||
with open('private_key.txt', encoding='utf-8') as file_object:
|
||||
private_key = file_object.readline().strip()
|
||||
with open('public_key.txt', encoding='utf-8') as file_object:
|
||||
public_key = file_object.readline().strip()
|
||||
data = {"private_key": private_key, "public_key": public_key}
|
||||
os.remove('private_key.txt')
|
||||
os.remove('public_key.txt')
|
||||
data = {"private_key": private_key, "public_key": public_key, "preshared_key": preshare_key}
|
||||
private.close()
|
||||
public.close()
|
||||
return data
|
||||
|
||||
|
||||
@ -441,20 +460,25 @@ def f_check_key_match(private_key, public_key, config_name):
|
||||
result = gen_public_key(private_key)
|
||||
if result['status'] == 'failed':
|
||||
return result
|
||||
|
||||
sem.acquire(timeout=1)
|
||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
||||
peers = Query()
|
||||
match = db.search(peers.id == result['data'])
|
||||
if len(match) != 1 or result['data'] != public_key:
|
||||
db.close()
|
||||
sem.release()
|
||||
return {'status': 'failed', 'msg': 'Please check your private key, it does not match with the public key.'}
|
||||
|
||||
db.close()
|
||||
sem.release()
|
||||
return {'status': 'success'}
|
||||
|
||||
else:
|
||||
sem.acquire(timeout=1)
|
||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
||||
peers = Query()
|
||||
match = db.search(peers.id == result['data'])
|
||||
if len(match) != 1 or result['data'] != public_key:
|
||||
db.close()
|
||||
try:
|
||||
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.'}
|
||||
else:
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return {'status': 'success'}
|
||||
|
||||
# Check if there is repeated allowed IP
|
||||
def check_repeat_allowed_ip(public_key, ip, config_name):
|
||||
@ -464,16 +488,22 @@ def check_repeat_allowed_ip(public_key, ip, config_name):
|
||||
peer = db.search(peers.id == public_key)
|
||||
if len(peer) != 1:
|
||||
return {'status': 'failed', 'msg': 'Peer does not exist'}
|
||||
|
||||
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
|
||||
if len(existed_ip) != 0:
|
||||
db.close()
|
||||
sem.release()
|
||||
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
|
||||
|
||||
db.close()
|
||||
sem.release()
|
||||
return {'status': 'success'}
|
||||
else:
|
||||
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
|
||||
if len(existed_ip) != 0:
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
|
||||
else:
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return {'status': 'success'}
|
||||
|
||||
|
||||
"""
|
||||
@ -759,13 +789,17 @@ def update_dashbaord_sort():
|
||||
# Update configuration refresh interval
|
||||
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
|
||||
def update_dashboard_refresh_interval():
|
||||
config = configparser.ConfigParser(strict=False)
|
||||
config.read(DASHBOARD_CONF)
|
||||
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
|
||||
with open(DASHBOARD_CONF, "w", encoding='utf-8') as config_object:
|
||||
config.write(config_object)
|
||||
config.clear()
|
||||
return "true"
|
||||
preset_interval = ["5000", "10000", "30000", "60000"]
|
||||
if request.form["interval"] in preset_interval:
|
||||
config = configparser.ConfigParser(strict=False)
|
||||
config.read(dashboard_conf)
|
||||
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
|
||||
with open(DASHBOARD_CONF, "w", encoding='utf-8') as config_object:
|
||||
config.write(config_object)
|
||||
config.clear()
|
||||
return "true"
|
||||
else:
|
||||
return "false"
|
||||
|
||||
|
||||
# Configuration Page
|
||||
@ -868,55 +902,92 @@ def add_peer(config_name):
|
||||
public_key = data['public_key']
|
||||
allowed_ips = data['allowed_ips']
|
||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||
dns_addresses = data['DNS']
|
||||
DNS = data['DNS']
|
||||
enable_preshared_key = data["enable_preshared_key"]
|
||||
keys = get_conf_peer_key(config_name)
|
||||
if len(public_key) == 0 or len(dns_addresses) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "Please fill in all required box."
|
||||
if not isinstance(keys, list):
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return config_name + " is not running."
|
||||
if public_key in keys:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "Public key already exist."
|
||||
if len(db.search(peers.allowed_ip.matches(allowed_ips))) != 0:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "Allowed IP already taken by another peer."
|
||||
if not check_DNS(dns_addresses):
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "DNS formate is incorrect. Example: 1.1.1.1"
|
||||
if not check_Allowed_IPs(endpoint_allowed_ip):
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "Endpoint Allowed IPs format is incorrect."
|
||||
if len(data['MTU']) == 0 or not data['MTU'].isdigit():
|
||||
db.close()
|
||||
sem.release()
|
||||
return "MTU format is not correct."
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "MTU format is not correct."
|
||||
if len(data['keep_alive']) == 0 or not data['keep_alive'].isdigit():
|
||||
db.close()
|
||||
sem.release()
|
||||
return "Persistent Keepalive format is not correct."
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "Persistent Keepalive format is not correct."
|
||||
try:
|
||||
subprocess.run(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips}",
|
||||
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||
subprocess.run("wg-quick save " + config_name,
|
||||
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||
if enable_preshared_key == True:
|
||||
key = subprocess.check_output("wg genpsk > tmp_psk.txt", shell=True)
|
||||
status = subprocess.check_output(f"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(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips}",
|
||||
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)
|
||||
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'],
|
||||
"endpoint_allowed_ip": endpoint_allowed_ip},
|
||||
peers.id == public_key)
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "true"
|
||||
except subprocess.CalledProcessError as exc:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return exc.output.strip()
|
||||
|
||||
|
||||
@ -936,21 +1007,26 @@ def remove_peer(config_name):
|
||||
if delete_key not in keys:
|
||||
db.close()
|
||||
return "This key does not exist"
|
||||
|
||||
try:
|
||||
subprocess.run(f"wg set {config_name} peer {delete_key} remove",
|
||||
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||
subprocess.run("wg-quick save " + config_name,
|
||||
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||
db.remove(peers.id == delete_key)
|
||||
db.close()
|
||||
sem.release()
|
||||
return "true"
|
||||
except subprocess.CalledProcessError as exc:
|
||||
db.close()
|
||||
sem.release()
|
||||
return exc.output.strip()
|
||||
|
||||
else:
|
||||
try:
|
||||
remove_wg = subprocess.check_output(f"wg set {config_name} peer {delete_key} remove",
|
||||
shell=True, stderr=subprocess.STDOUT)
|
||||
save_wg = subprocess.check_output(f"wg-quick save {config_name}",
|
||||
shell=True, stderr=subprocess.STDOUT)
|
||||
db.remove(peers.id == delete_key)
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return "true"
|
||||
except subprocess.CalledProcessError as exc:
|
||||
db.close()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return exc.output.strip()
|
||||
|
||||
# Save peer settings
|
||||
@app.route('/save_peer_setting/<config_name>', methods=['POST'])
|
||||
@ -962,6 +1038,7 @@ def save_peer_setting(config_name):
|
||||
dns_addresses = data['DNS']
|
||||
allowed_ip = data['allowed_ip']
|
||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||
preshared_key = data['preshared_key']
|
||||
sem.acquire(timeout=1)
|
||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
||||
peers = Query()
|
||||
@ -969,31 +1046,60 @@ def save_peer_setting(config_name):
|
||||
check_ip = check_repeat_allowed_ip(id, allowed_ip, config_name)
|
||||
if not check_IP_with_range(endpoint_allowed_ip):
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
|
||||
if not check_DNS(dns_addresses):
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
|
||||
if len(data['MTU']) == 0 or not data['MTU'].isdigit():
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
|
||||
if len(data['keep_alive']) == 0 or not data['keep_alive'].isdigit():
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
|
||||
if private_key != "":
|
||||
check_key = f_check_key_match(private_key, id, config_name)
|
||||
if check_key['status'] == "failed":
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify(check_key)
|
||||
if check_ip['status'] == "failed":
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify(check_ip)
|
||||
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 == "":
|
||||
allowed_ip = '""'
|
||||
allowed_ip = allowed_ip.replace(" ", "")
|
||||
@ -1003,24 +1109,39 @@ def save_peer_setting(config_name):
|
||||
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||
if change_ip.decode("UTF-8") != "":
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
|
||||
db.update(
|
||||
{"name": name, "private_key": private_key,
|
||||
"DNS": dns_addresses, "endpoint_allowed_ip": endpoint_allowed_ip,
|
||||
"mtu": data['MTU'],
|
||||
"keepalive": data['keep_alive']},
|
||||
peers.id == id)
|
||||
{
|
||||
"name": name,
|
||||
"private_key": private_key,
|
||||
"DNS": dns_addresses,
|
||||
"endpoint_allowed_ip": endpoint_allowed_ip,
|
||||
"mtu": data['MTU'],
|
||||
"keepalive":data['keep_alive'], "preshared_key": preshared_key
|
||||
}, peers.id == id)
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "success", "msg": ""})
|
||||
except subprocess.CalledProcessError as exc:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
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())})
|
||||
else:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
||||
|
||||
|
||||
@ -1036,8 +1157,12 @@ def get_peer_name(config_name):
|
||||
db.close()
|
||||
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'],
|
||||
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive']}
|
||||
sem.release()
|
||||
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive'], "preshared_key": result[0]["preshared_key"]}
|
||||
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@ -1084,6 +1209,7 @@ def generate_qrcode(config_name):
|
||||
mtu_value = peer['mtu']
|
||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||
keepalive = peer['keepalive']
|
||||
preshared_key = peer["preshared_key"]
|
||||
conf = {
|
||||
"public_key": public_key,
|
||||
"listen_port": listen_port,
|
||||
@ -1094,18 +1220,31 @@ def generate_qrcode(config_name):
|
||||
"mtu": mtu_value,
|
||||
"endpoint_allowed_ip": endpoint_allowed_ip,
|
||||
"keepalive": keepalive,
|
||||
"preshared_key": preshared_key
|
||||
}
|
||||
db.close()
|
||||
sem.release()
|
||||
return render_template("qrcode.html", i=conf)
|
||||
try:
|
||||
sem.release()
|
||||
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:
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return redirect("/configuration/" + config_name)
|
||||
|
||||
|
||||
# Download configuration file
|
||||
@app.route('/<config_name>', methods=['GET'])
|
||||
@app.route('/download/<config_name>', methods=['GET'])
|
||||
def download(config_name):
|
||||
print(request.headers.get('User-Agent'))
|
||||
id = request.args.get('id')
|
||||
@ -1127,6 +1266,7 @@ def download(config_name):
|
||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||
keepalive = peer['keepalive']
|
||||
filename = peer['name']
|
||||
preshared_key = peer["preshared_key"]
|
||||
if len(filename) == 0:
|
||||
filename = "Untitled_Peers"
|
||||
else:
|
||||
@ -1141,23 +1281,24 @@ def download(config_name):
|
||||
filename = "Untitled_Peer"
|
||||
filename = "".join(filename.split(' '))
|
||||
filename = filename + "_" + config_name
|
||||
|
||||
psk = ""
|
||||
if preshared_key != "":
|
||||
psk = "\nPresharedKey = "+preshared_key
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
result = "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + \
|
||||
dns_addresses + "\nMTU = " + mtu_value + "\n\n[Peer]\nPublicKey = " + \
|
||||
public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + \
|
||||
endpoint + "\nPersistentKeepalive = " + keepalive
|
||||
|
||||
return app.response_class((yield result),
|
||||
mimetype='text/conf',
|
||||
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
||||
|
||||
endpoint + "\nPersistentKeepalive = " + keepalive + psk
|
||||
return app.response_class((yield result), mimetype='text/conf', headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
||||
db.close()
|
||||
return redirect("/configuration/" + config_name)
|
||||
|
||||
|
||||
# Switch peer displate mode
|
||||
# Switch peer display mode
|
||||
@app.route('/switch_display_mode/<mode>', methods=['GET'])
|
||||
def switch_display_mode(mode):
|
||||
if mode in ['list', 'grid']:
|
||||
@ -1181,7 +1322,7 @@ Dashboard Tools Related
|
||||
def get_ping_ip():
|
||||
config_name = request.form['config']
|
||||
sem.acquire(timeout=1)
|
||||
db = TinyDB(os.path.join(db_path, config_name + ".json"))
|
||||
db = TinyDB(os.path.join(db_path, config + ".json"))
|
||||
|
||||
html = ""
|
||||
for i in db.all():
|
||||
@ -1196,7 +1337,10 @@ def get_ping_ip():
|
||||
html += "<option value=" + endpoint[0] + ">" + endpoint[0] + "</option>"
|
||||
html += "</optgroup>"
|
||||
db.close()
|
||||
sem.release()
|
||||
try:
|
||||
sem.release()
|
||||
except RuntimeError as e:
|
||||
print("RuntimeError: cannot release un-acquired lock")
|
||||
return html
|
||||
|
||||
|
||||
@ -1326,13 +1470,4 @@ if __name__ == "__main__":
|
||||
app_port = configuration_settings.get("Server", "app_port")
|
||||
wg_conf_path = configuration_settings.get("Server", "wg_conf_path")
|
||||
configuration_settings.clear()
|
||||
app.run(host=app_ip, debug=False, port=app_port)
|
||||
else:
|
||||
init_dashboard()
|
||||
UPDATE = check_update()
|
||||
configuration_settings = configparser.ConfigParser(strict=False)
|
||||
configuration_settings.read(DASHBOARD_CONF)
|
||||
app_ip = configuration_settings.get("Server", "app_ip")
|
||||
app_port = configuration_settings.get("Server", "app_port")
|
||||
wg_conf_path = configuration_settings.get("Server", "wg_conf_path")
|
||||
configuration_settings.clear()
|
||||
app.run(host=app_ip, debug=False, port=app_port)
|
@ -134,6 +134,7 @@ body {
|
||||
|
||||
.info h6{
|
||||
line-break: anywhere;
|
||||
transition: 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.info .row .col-sm{
|
||||
@ -291,6 +292,10 @@ main{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#peer_private_key_textbox, #private_key, #public_key{
|
||||
font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
||||
}
|
||||
|
||||
.progress-bar{
|
||||
transition: 0.3s ease-in-out;
|
||||
}
|
||||
@ -322,4 +327,57 @@ main{
|
||||
|
||||
.modal-content{
|
||||
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
|
||||
$("body").on("click", ".switch", function (){
|
||||
$body.on("click", ".switch", function (){
|
||||
$(this).siblings($(".spinner-border")).css("display", "inline-block");
|
||||
$(this).remove()
|
||||
location.replace("/switch/"+$(this).attr('id'));
|
||||
@ -13,6 +46,7 @@ function generate_key(){
|
||||
}).done(function(res){
|
||||
$("#private_key").val(res.private_key)
|
||||
$("#public_key").val(res.public_key)
|
||||
$("#preshare_key").val(res.preshared_key)
|
||||
$("#add_peer_alert").addClass("d-none");
|
||||
$("#re_generate_key i").removeClass("rotating")
|
||||
})
|
||||
@ -36,7 +70,7 @@ function generate_public_key(){
|
||||
}
|
||||
|
||||
// Add Peer
|
||||
$("#private_key").change(function(){
|
||||
$("#private_key").on("change",function(){
|
||||
if ($("#private_key").val().length > 0){
|
||||
$("#re_generate_key i").addClass("rotating")
|
||||
generate_public_key()
|
||||
@ -53,7 +87,15 @@ $("#re_generate_key").click(function (){
|
||||
$("#re_generate_key i").addClass("rotating")
|
||||
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).html("Saving...")
|
||||
|
||||
@ -77,7 +119,8 @@ $("#save_peer").click(function(){
|
||||
"DNS": $("#new_add_DNS").val(),
|
||||
"endpoint_allowed_ip": $("#new_add_endpoint_allowed_ip").val(),
|
||||
"MTU": $("#new_add_MTU").val(),
|
||||
"keep_alive": $("#new_add_keep_alive").val()
|
||||
"keep_alive": $("#new_add_keep_alive").val(),
|
||||
"enable_preshared_key": $("#enable_preshare_key").prop("checked"),
|
||||
}),
|
||||
success: function (response){
|
||||
if(response != "true"){
|
||||
@ -90,7 +133,8 @@ $("#save_peer").click(function(){
|
||||
$("#save_peer").html("Save")
|
||||
}
|
||||
else{
|
||||
location.reload();
|
||||
load_data("");
|
||||
addModal.hide();
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -106,7 +150,7 @@ var qrcodeModal = new bootstrap.Modal(document.getElementById('qrcode_modal'), {
|
||||
})
|
||||
|
||||
// QR Code
|
||||
$("body").on("click", ".btn-qrcode-peer", function (){
|
||||
$body.on("click", ".btn-qrcode-peer", function (){
|
||||
var src = $(this).attr('img_src');
|
||||
$.ajax({
|
||||
"url": src,
|
||||
@ -122,7 +166,7 @@ var deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), {
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
$("body").on("click", ".btn-delete-peer", function(){
|
||||
$body.on("click", ".btn-delete-peer", function(){
|
||||
var peer_id = $(this).attr("id");
|
||||
$("#delete_peer").attr("peer_id", peer_id);
|
||||
deleteModal.toggle();
|
||||
@ -161,7 +205,7 @@ $("#delete_peer").click(function(){
|
||||
var settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), {
|
||||
keyboard: false
|
||||
})
|
||||
$("body").on("click", ".btn-setting-peer", function(){
|
||||
$body.on("click", ".btn-setting-peer", function(){
|
||||
startProgressBar()
|
||||
var peer_id = $(this).attr("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_mtu").val(response['mtu'])
|
||||
$("#setting_modal #peer_keep_alive").val(response['keep_alive'])
|
||||
$("#setting_modal #peer_preshared_key_textbox").val(response["preshared_key"])
|
||||
settingModal.toggle();
|
||||
endProgressBar()
|
||||
}
|
||||
@ -223,7 +268,7 @@ $("#save_peer_setting").click(function (){
|
||||
var peer_id = $(this).attr("peer_id");
|
||||
var conf_id = $(this).attr("conf_id");
|
||||
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")
|
||||
]
|
||||
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(),
|
||||
endpoint_allowed_ip: $("#peer_endpoint_allowed_ips").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){
|
||||
if (response['status'] === "failed"){
|
||||
@ -296,7 +342,7 @@ function doneTyping () {
|
||||
}
|
||||
|
||||
// Sorting
|
||||
$("body").on("change", "#sort_by_dropdown", function (){
|
||||
$body.on("change", "#sort_by_dropdown", function (){
|
||||
$.ajax({
|
||||
method:"POST",
|
||||
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
|
||||
$("body").on("mouseenter", ".key", function(){
|
||||
$body.on("mouseenter", ".key", function(){
|
||||
var label = $(this).parent().siblings().children()[1]
|
||||
label.style.opacity = "100"
|
||||
})
|
||||
$("body").on("mouseout", ".key", function(){
|
||||
$body.on("mouseout", ".key", function(){
|
||||
var label = $(this).parent().siblings().children()[1]
|
||||
label.style.opacity = "0"
|
||||
setTimeout(function (){
|
||||
@ -321,39 +367,54 @@ $("body").on("mouseout", ".key", function(){
|
||||
},200)
|
||||
|
||||
});
|
||||
$("body").on("click", ".key", function(){
|
||||
$body.on("click", ".key", function(){
|
||||
var label = $(this).parent().siblings().children()[1]
|
||||
copyToClipboard($(this))
|
||||
label.innerHTML = "COPIED!"
|
||||
})
|
||||
function copyToClipboard(element) {
|
||||
var $temp = $("<input>");
|
||||
$("body").append($temp);
|
||||
$body.append($temp);
|
||||
$temp.val($(element).text()).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
}
|
||||
|
||||
// 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");
|
||||
$(this).addClass("active");
|
||||
let _new = $(this)
|
||||
_new.addClass("active");
|
||||
let interval = $(this).data("refresh-interval");
|
||||
$.ajax({
|
||||
method:"POST",
|
||||
data: "interval="+$(this).data("refresh-interval"),
|
||||
url: "/update_dashboard_refresh_interval",
|
||||
success: function (res){
|
||||
|
||||
load_data($('#search_peer_textbox').val())
|
||||
if (res === "true"){
|
||||
load_interval = interval;
|
||||
clearInterval(load_timeout);
|
||||
load_timeout = setInterval(function (){
|
||||
load_data($('#search_peer_textbox').val());
|
||||
}, interval);
|
||||
showToast("Refresh Interval set to "+Math.round(interval/1000)+" seconds");
|
||||
}else{
|
||||
$(".interval-btn-group button").removeClass("active");
|
||||
$('.interval-btn-group button[data-refresh-interval="'+load_interval+'"]').addClass("active");
|
||||
showToast("Refresh Interval set unsuccessful");
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
$("body").on("click", ".refresh", function (){
|
||||
$body.on("click", ".refresh", function (){
|
||||
load_data($('#search_peer_textbox').val());
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Switch display mode
|
||||
$("body").on("click", ".display_mode", function(){
|
||||
$body.on("click", ".display_mode", function(){
|
||||
$(".display-btn-group button").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
let display_mode = $(this).data("display-mode");
|
||||
@ -361,16 +422,25 @@ $("body").on("click", ".display_mode", function(){
|
||||
method:"GET",
|
||||
url: "/switch_display_mode/"+$(this).data("display-mode"),
|
||||
success: function (res){
|
||||
// load_data($('#search_peer_textbox').val())
|
||||
if (display_mode === "list"){
|
||||
if (res === "true"){
|
||||
if (display_mode === "list"){
|
||||
Array($(".peer_list").children()).forEach(function(child){
|
||||
$(child).removeClass().addClass("col-12");
|
||||
})
|
||||
showToast("Displaying as List");
|
||||
}else{
|
||||
Array($(".peer_list").children()).forEach(function(child){
|
||||
$(child).removeClass().addClass("col-sm-6 col-lg-4");
|
||||
})
|
||||
});
|
||||
showToast("Displaying as 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" %}
|
||||
<div class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mt-4 mb-4">
|
||||
<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 id="config_body">
|
||||
@ -21,8 +21,8 @@
|
||||
<h1 class="mb-3"><samp id="conf_name">{{ title }}</samp></h1>
|
||||
</div>
|
||||
<div class="col">
|
||||
<small class="text-muted"><strong>ACTION</strong></small><br>
|
||||
<div id="conf_status_btn"></div>
|
||||
<small class="text-muted"><strong>SWITCH</strong></small><br>
|
||||
<div id="conf_status_btn" class="info_loading"></div>
|
||||
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
@ -30,23 +30,23 @@
|
||||
<div class="w-100"></div>
|
||||
<div class="col">
|
||||
<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 class="col">
|
||||
<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 class="col-sm">
|
||||
<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 class="col-sm">
|
||||
<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 class="col-sm">
|
||||
<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 class="w-100"></div>
|
||||
<div class="col-sm">
|
||||
@ -54,15 +54,15 @@
|
||||
<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>
|
||||
</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 class="col-sm">
|
||||
<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 class="col-sm">
|
||||
<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>
|
||||
@ -100,7 +100,7 @@
|
||||
</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
|
||||
</button>
|
||||
</div>
|
||||
@ -134,7 +134,7 @@
|
||||
<label for="private_key">Private Key</label>
|
||||
</div>
|
||||
<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">
|
||||
<button type="button" class="btn btn-danger" id="re_generate_key"><i class="bi bi-arrow-repeat"></i></button>
|
||||
</div>
|
||||
@ -179,6 +179,12 @@
|
||||
<div class="form-group">
|
||||
<label for="new_add_keep_alive">Persistent keepalive</label>
|
||||
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}">
|
||||
</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>
|
||||
@ -233,10 +239,14 @@
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</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>
|
||||
<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>
|
||||
</div>
|
||||
<div>
|
||||
<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">
|
||||
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
|
||||
<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>
|
||||
|
||||
@ -307,7 +317,7 @@
|
||||
<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 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">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
@ -319,35 +329,16 @@
|
||||
{% include "tools.html" %}
|
||||
</body>
|
||||
{% include "footer.html" %}
|
||||
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
||||
<script>
|
||||
function roundN(value, digits) {
|
||||
var tenToN = 10 ** digits;
|
||||
return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
|
||||
}
|
||||
let load_timeout;
|
||||
let load_interval = 0;
|
||||
var conf_name = "{{ conf_data['name'] }}"
|
||||
let conf_name = "{{ conf_data['name'] }}"
|
||||
$(".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){
|
||||
startProgressBar()
|
||||
let result = '';
|
||||
@ -382,22 +373,35 @@
|
||||
|
||||
$("#conf_status").html(response["status"]+'<span class="dot dot-'+response["status"]+'"></span>');
|
||||
$("#conf_connected_peers").html(response["running_peer"]);
|
||||
$("#conf_total_data_usage").html(response["total_data_usage"][0]+" GB");
|
||||
$("#conf_total_data_received").html(response["total_data_usage"][1]+" GB");
|
||||
$("#conf_total_data_sent").html(response["total_data_usage"][2]+" GB");
|
||||
$("#conf_total_data_usage").html(response["total_data_usage"][0] +" GB");
|
||||
$("#conf_total_data_received").html(response["total_data_usage"][2] +" GB");
|
||||
$("#conf_total_data_sent").html(response["total_data_usage"][1]+" GB");
|
||||
$("#conf_public_key").html(response["public_key"]);
|
||||
$("#conf_listen_port").html(response["listen_port"] === "" ? "N/A":response["listen_port"]);
|
||||
$("#conf_address").html(response["conf_address"]);
|
||||
$(".info h6").removeClass("info_loading");
|
||||
$("#conf_status_btn").removeClass("info_loading")
|
||||
|
||||
|
||||
|
||||
if (response["peer_data"].length === 0){
|
||||
$(".peer_list").html('<div class="col-12" style="text-align: center; margin-top: 1.5rem"><h3 class="text-muted">Oops! No peers found ‘︿’</h3></div>');
|
||||
}else{
|
||||
let display_mode = response["peer_display_mode"] === "list" ? "col-12" : "col-sm-6 col-lg-4";
|
||||
response["peer_data"].forEach(function(peer){
|
||||
let total_r = 0;
|
||||
let total_s = 0;
|
||||
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 peer_name = '<div class="col-sm"><h4>'+ (peer["name"] === "" ? "Untitled" : peer["name"]) +'</h4></div>';
|
||||
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>'
|
||||
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>'
|
||||
let peer_name =
|
||||
'<div class="col-sm display" style="display: flex; align-items: center; margin-bottom: 0.2rem">' +
|
||||
'<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_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>';
|
||||
@ -413,7 +417,6 @@
|
||||
'<div class="row">'
|
||||
+ peer_name
|
||||
+ spliter
|
||||
+ peer_status
|
||||
+ peer_transfer
|
||||
+ peer_key
|
||||
+ peer_allowed_ip
|
||||
@ -437,17 +440,16 @@
|
||||
}
|
||||
}
|
||||
{#$("#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()
|
||||
}
|
||||
})
|
||||
}
|
||||
$(function(){
|
||||
load_data($('#search_peer_textbox').val());
|
||||
{#setInterval(function(){#}
|
||||
{# load_data($('#search_peer_textbox').val());#}
|
||||
{#}, {{dashboard_refresh_interval}})#}
|
||||
});
|
||||
</script>
|
||||
<script src="{{ url_for('static',filename='js/configuration.js') }}"></script>
|
||||
|
||||
</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>
|
||||
{% endif %}
|
||||
{% for i in conf%}
|
||||
<div class="card mt-3">
|
||||
<div class="card mt-3 conf_card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col card-col">
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
@ -51,11 +51,18 @@
|
||||
</body>
|
||||
{% include "footer.html" %}
|
||||
<script>
|
||||
$('.switch').click(function() {
|
||||
|
||||
$('.switch').on("click", function() {
|
||||
$(this).siblings($(".spinner-border")).css("display", "inline-block")
|
||||
$(this).remove()
|
||||
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>
|
||||
</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