Restore UI

This commit is contained in:
2024-03-18 19:06:10 +02:00
parent 5109de5c9a
commit 715494fa5f
4 changed files with 347 additions and 510 deletions

176
templates/base.html Executable file → Normal file
View File

@ -1,113 +1,93 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>{% block title %}Dashboard{% endblock %}</title> <title>{% block title %}Dashboard{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='layout.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='layout.css') }}">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.border {
border: 0px solid black;
}
.content {
padding: 10px;
}
.form-field {
margin: 5px;
width: 100%;
}
</style>
<!-- Script to make the Menu link work -->
<!-- Just stripped down version of the js/ui.js script for the side-menu layout -->
<script>
function getElements() {
return {
menu: document.getElementById('nav'),
menuLink: document.getElementById('menuLink')
};
}
function toggleClass(element, className) {
var classes = element.className.split(/\s+/);
var length = classes.length;
var i = 0;
for (; i < length; i++) {
if (classes[i] === className) {
classes.splice(i, 1);
break;
}
}
// The className is not found
if (length === classes.length) {
classes.push(className);
}
element.className = classes.join(' ');
}
function toggleMenu() {
var active = 'active';
var elements = getElements();
toggleClass(elements.menu, active);
}
// function handleEvent(e) {
// var elements = getElements();
// if (e.target.id === elements.menuLink.id) {
// toggleMenu();
// e.preventDefault();
// } else if (elements.menu.className.indexOf('active') !== -1) {
// toggleMenu();
// }
// }
// document.addEventListener('DOMContentLoaded', function () {
// document.addEventListener('click', handleEvent);
// });
</script>
</head> </head>
<body> <body>
<div class="pure-g"> <div id="layout" class="content pure-g">
<div class="pure-u-2-24 border" style="background: rgb(37, 42, 58);"> <div id="nav" class="pure-u-1-3">
<div class="content"> <a href="#" id="menuLink" class="nav-menu-button">Menu</a>
<div class="nav-inner">
<h1 onclick="location.href='/';" style="cursor:pointer;" class="pure-button">OutFleet {{VERSION}} <div class="nav-inner">
</h1> <button onclick="location.href='/';" style="cursor:pointer;" class="primary-button pure-button">OutFleet v.{{ VERSION }}</button>
<ul class="pure-menu-list">
<li class="pure-menu-item"><a href="/" class="pure-menu-link">Servers</a></li> <div class="pure-menu custom-restricted-width">
<li class="pure-menu-item"><a href="/clients" class="pure-menu-link">Clients</a></li> <ul class="pure-menu-list">
<li class="pure-menu-item"><a href="/sync" class="pure-menu-link">Sync status</a></li> <li class="pure-menu-item"><a href="/" class="pure-menu-link">Servers</a></li>
</ul> <li class="pure-menu-item"><a href="/clients" class="pure-menu-link">Clients</a></li>
</div> <li class="pure-menu-item"><a href="/sync" class="pure-menu-link">Sync status</a></li>
</div> </ul>
</div> {{ VERSION }}
<div class="pure-u-22-24 border">
<div class="content">
{% block content %}{% endblock %}
</div> </div>
</div> </div>
</div> </div>
{% block content %}{% endblock %}
</div>
<!-- Script to make the Menu link work -->
<!-- Just stripped down version of the js/ui.js script for the side-menu layout -->
<script>
function getElements() {
return {
menu: document.getElementById('nav'),
menuLink: document.getElementById('menuLink')
};
}
function toggleClass(element, className) {
var classes = element.className.split(/\s+/);
var length = classes.length;
var i = 0;
{% if nt %} for (; i < length; i++) {
<label> if (classes[i] === className) {
<input type="checkbox" class="alertCheckbox" autocomplete="off" /> classes.splice(i, 1);
<div class="alert {% if nl == 'error' %}error{% else %}success{% endif %}"> break;
<span class="alertText">{{nt}} }
<br class="clear" /></span> }
</div> // The className is not found
</label> if (length === classes.length) {
{% endif %} classes.push(className);
}
element.className = classes.join(' ');
}
function toggleMenu() {
var active = 'active';
var elements = getElements();
toggleClass(elements.menu, active);
}
function handleEvent(e) {
var elements = getElements();
if (e.target.id === elements.menuLink.id) {
toggleMenu();
e.preventDefault();
} else if (elements.menu.className.indexOf('active') !== -1) {
toggleMenu();
}
}
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('click', handleEvent);
});
</script>
{% if nt %}
<label>
<input type="checkbox" class="alertCheckbox" autocomplete="off" />
<div class="alert {% if nl == 'error' %}error{% else %}success{% endif %}">
<span class="alertText">{{nt}}
<br class="clear"/></span>
</div>
</label>
{% endif %}
</body> </body>
</html> </html>

287
templates/clients.html Executable file → Normal file
View File

@ -2,190 +2,173 @@
{% block content %} {% block content %}
<div class="pure-u-3-24"> <div id="list" class="pure-u-1-3" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
<div class="server-item"> <div class="server-item pure-g">
<h1 class="server-content-title">Clients</h1> <h1 class="server-content-title">Clients</h1>
</div> </div>
<div onclick="location.href='/clients?add_client=True';" class="server-item server-add ">
<div class="">
+
</div>
</div>
{% for client, values in CLIENTS.items() %} {% for client, values in CLIENTS.items() %}
<div onclick="location.href='/clients?selected_client={{ client }}';" <div class="server-item server-item-{% if client == selected_client %}unread{% else %}selected{% endif %} pure-g">
class="server-item server-item-{% if client == selected_client %}unread{% else %}selected{% endif %} "> <div class="pure-u-3-4" onclick="location.href='/clients?selected_client={{ client }}';">
<div class="">
<h5 class="server-name">{{ values["name"] }}</h5> <h5 class="server-name">{{ values["name"] }}</h5>
<h4 class="server-info">Allowed {{ values["servers"]|length }} server{% if values["servers"]|length >1 <h4 class="server-info">Allowed {{ values["servers"]|length }} server{% if values["servers"]|length >1 %}s{%endif%}</h4>
%}s{%endif%}</h4>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
<div onclick="location.href='/clients?add_client=True';" class="server-item server-add pure-g">
<div class="pure-u-1">
+
</div>
</div>
</div> </div>
<div class="pure-u-20-24">
{% if add_client %}
<div class="server-content-header"> {% if add_client %}
<div class=""> <div class="pure-u-1-3">
<h1 class="server-content-title">Add new client</h1> <div class="server-content-header pure-g">
<div class="pure-u-1-2">
<h1 class="server-content-title">Add new client</h1>
</div>
</div> </div>
</div> <div class="server-content-body">
<div class="server-content-body">
<form action="/add_client" class="pure-form pure-form-stacked" method="POST"> <form action="/add_client" class="pure-form pure-form-stacked" method="POST">
<fieldset> <fieldset>
<input type="text" class="form-field pure-u-8-24" name="name" required placeholder="Name" /> <div class="pure-g">
<input type="text" class="form-field pure-u-8-24" name="comment" placeholder="Comment" /> <div class="pure-u-1 pure-u-md-1-3">
{% for server in SERVERS %} <input type="text" class="pure-u-23-24" name="name" required placeholder="Name"/>
<label class="pure-checkbox" for="option{{loop.index0}}"> </div>
<input type="checkbox" id="option{{loop.index0}}" name="servers" <div class="pure-u-1 pure-u-md-1-3">
value="{{server.info()['local_server_id']}}">{{server.info()["name"]}}</label> <input type="text" class="pure-u-23-24" name="comment" placeholder="Comment"/>
{% endfor %} </div>
<button type="submit" class="pure-button pure-button-primary button">Add client</button> <div class="pure-checkbox">
{% for server in SERVERS %}
<label class="pure-checkbox" for="option{{loop.index0}}">{{server.info()["name"]}}
<input type="checkbox" id="option{{loop.index0}}" name="servers" value="{{server.info()['local_server_id']}}"></label>
{% endfor %}
</div>
</div>
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Add</button>
</fieldset> </fieldset>
</form> </form>
</div> </div>
{% endif %}
{% if selected_client and not add_client %}
{% set client = CLIENTS[selected_client] %}
<div class="pure-g">
<div class="pure-u-1">
<div class="server-content-header">
<div class="">
<h1 class="server-content-title">{{client['name']}}</h1>
<h4 class="server-info">{{ selected_client }}</h4>
{% if client['comment'] != "" %}<h4 class="server-info">{{ client['comment'] }}</h4>{% endif %}
</div>
</div>
</div>
</div> </div>
<div class="pure-g"> {% endif %}
<div class="pure-u-6-24">
<div class="server-content-body">
<form action="/add_client" class="pure-form pure-form-aligned" method="POST">
<fieldset>
<div class=""> {% if selected_client and not add_client %}
<input type="text" class="form-field" name="name" required value="{{client['name']}}" /> {% set client = CLIENTS[selected_client] %}
<input type="hidden" class="form-field" name="old_name" required
value="{{client['name']}}" />
</div>
<div class="">
<input type="text" class="form-field" name="comment" value="{{client['comment']}}" />
</div>
<input type="hidden" class="form-field" name="user_id" value="{{selected_client}}" />
<div class="pure-checkbox"> <div class="pure-u-1-2">
<p>Allow access to:</p> <div class="server-content-header pure-g">
{% for server in SERVERS %} <div class="pure-u-1-2">
<label class="pure-checkbox" for="option{{loop.index0}}"> <h1 class="server-content-title">{{client['name']}}</h1>
<input {% if server.info()['local_server_id'] in client['servers'] %}checked{%endif%} <h4 class="server-info">{{ client['comment'] }}</h4>
type="checkbox" id="option{{loop.index0}}" name="servers" <h4 class="server-info">id {{ selected_client }}</h4>
value="{{server.info()['local_server_id']}}">{{server.info()["name"]}}
{% if server.info()['local_server_id'] in client['servers'] %} ( Used {% for key in
server.data["keys"] %}{% if key.name == client['name'] %}{{ (key.used_bytes if
key.used_bytes else 0) | filesizeformat }}{% endif %}{% endfor %}){%endif%}</label>
{% endfor %}
</div>
<button type="submit" class="pure-button pure-button-primary button">Save and Apply</button>
</fieldset>
</form>
<form action="/del_client" class="pure-form pure-form-stacked" method="POST">
<input type="hidden" name="name" required value="{{client['name']}}" />
<input type="hidden" name="user_id" value="{{selected_client}}" />
<label for="really" class="pure-radio">
<button type="submit" id="really"
class="pure-button pure-button-primary delete-button button">Delete Client 🔒<input
type="checkbox" id="agree" name="agree" required></button></label>
</form>
</div> </div>
</div> </div>
<div style="" class="pure-u-18-24"> <div class="server-content-body">
<div class="pure-u-9-24"> <form action="/add_client" class="pure-form pure-form-stacked" method="POST">
<div> <fieldset>
<h3>Invite text</h3> <div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3">
<input type="text" class="pure-u-1" name="name" required value="{{client['name']}}"/>
<input type="hidden" class="pure-u-1" name="old_name" required value="{{client['name']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<input type="text" class="pure-u-1" name="comment" value="{{client['comment']}}"/>
</div>
<input type="hidden" class="pure-u-1" name="user_id" value="{{selected_client}}"/>
<textarea style="width: 96%; height: 360px; resize:none" disabled> <div class="pure-checkbox">
<p>Allow access to:</p>
{% for server in SERVERS %}
<label class="pure-checkbox" for="option{{loop.index0}}">{{server.info()["name"]}}{% if server.info()['local_server_id'] in client['servers'] %} ( Used {% for key in server.data["keys"] %}{% if key.name == client['name'] %}{{ (key.used_bytes if key.used_bytes else 0) | filesizeformat }}{% endif %}{% endfor %}){%endif%}
<input
{% if server.info()['local_server_id'] in client['servers'] %}checked{%endif%}
type="checkbox" id="option{{loop.index0}}" name="servers" value="{{server.info()['local_server_id']}}"></label>
{% endfor %}
</div>
</div>
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Save and apply</button>
</fieldset>
</form>
<div>
<h3>Invite text</h3><hr>
<textarea style="width: 100%; rows=10">
Install OutLine VPN. Copy and paste below keys to OutLine client. Install OutLine VPN. Copy and paste below keys to OutLine client.
Same keys will work simultaneously on many devices. Same keys will work simultaneously on many devices.
{% for server in SERVERS -%} {% for server in SERVERS -%}
{% if server.info()['local_server_id'] in client['servers'] %} {% if server.info()['local_server_id'] in client['servers'] %}
{{server.info()['name']}} {{server.info()['name']}}
```{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ ```{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ dynamic_hostname }}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{% endfor %}```
dynamic_hostname
}}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{%
endfor %}```
{% endif %} {% endif %}
{%- endfor -%} {%- endfor -%}</textarea>
</textarea>
</div>
</div>
<div class="pure-u-14-24">
</div>
</div> </div>
<hr>
<div style="padding-top: 15px; padding-bottom: 15px">
<div class="pure-u-1">
<h3>Dynamic Access Keys</h3>
<table class="pure-table">
<thead>
<tr>
<th>Server</th>
<th>Dynamic</th>
</tr>
</thead>
<tbody>
{% for server in SERVERS %}
{% if server.info()['local_server_id'] in client['servers'] %}
<tr>
<td>{{ server.info()['name'] }}</td>
<td>
<p style="font-size: 10pt">{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ dynamic_hostname }}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% endif %}{% endfor %}</p>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div> </div>
<div class="pure-g"> <div class="pure-u-1 pure-u-md-1">
<div class="pure-u-1 content"> <h3>SS Links</h3>
<h3>Dynamic Access Keys</h3> <table class="pure-table">
<table class="pure-table" style="width: 100%"> <thead>
<thead> <tr>
<tr> <th>Server</th>
<th>Server</th> <th>SSlink</th>
<th>Dynamic</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {% for server in SERVERS %}
{% for server in SERVERS %} {% if server.info()['local_server_id'] in client['servers'] %}
{% if server.info()['local_server_id'] in client['servers'] %} <tr>
<tr> <td>{{ server.info()['name'] }}</td>
<td>{{ server.info()['name'] }}</td> <td>
<td style="font-size: 10pt"> <pre style="font-size: 10pt">{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}{{ key.access_url }}{% endif %}{% endfor %}</pre>
{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}ssconf://{{ </td>
dynamic_hostname </tr>
}}/dynamic/{{server.info()['name']}}/{{selected_client}}#{{server.info()['comment']}}{% {% endif %}
endif %}{% endfor %} {% endfor %}
</td> </tbody>
</tr> </table>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
<div class="pure-u-1 content">
<h3>SS Links</h3>
<table class="pure-table" style="width: 100%">
<thead>
<tr>
<th>Server</th>
<th>SSlink</th>
</tr>
</thead>
<tbody>
{% for server in SERVERS %}
{% if server.info()['local_server_id'] in client['servers'] %}
<tr>
<td>{{ server.info()['name'] }}</td>
<td style="font-size: 10pt">
{% for key in server.data["keys"] %}{% if key.key_id == client['name'] %}{{
key.access_url }}{% endif %}{% endfor %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div> </div>
{% endif %} <hr>
</div> </div>
<form action="/del_client" class="pure-form pure-form-stacked" method="POST">
<input type="hidden" class="pure-u-1" name="name" required value="{{client['name']}}"/>
<input type="hidden" class="pure-u-1" name="user_id" value="{{selected_client}}"/>
<button type="submit" class="pure-button button-error pure-input-1 ">Delete</button>
</form>
</div>
</div>
{% endif %}
{% endblock %} {% endblock %}

349
templates/index.html Executable file → Normal file
View File

@ -1,261 +1,150 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div class="pure-g">
<div class="pure-u-4-24"> <div id="list" class="pure-u-1-3" xmlns="http://www.w3.org/1999/html">
<div class="server-item "> <div class="server-item pure-g">
<h1 class="server-content-title">Servers</h1> <h1 class="server-content-title">Servers</h1>
</div> </div>
{% for server in SERVERS %} {% for server in SERVERS %}
{% set list_ns = namespace(total_bytes=0) %} {% set list_ns = namespace(total_bytes=0) %}
{% for key in server.data["keys"] %} {% for key in server.data["keys"] %}
{% if key.used_bytes %} {% if key.used_bytes %}
{% set list_ns.total_bytes = list_ns.total_bytes + key.used_bytes %} {% set list_ns.total_bytes = list_ns.total_bytes + key.used_bytes %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<div <div class="server-item server-item-{% if loop.index0 == selected_server|int %}unread{% else %}selected{% endif %} pure-g">
class="server-item server-item-{% if loop.index0 == selected_server|int %}unread{% else %}selected{% endif %} "> <div class="pure-u-3-4" onclick="location.href='/?selected_server={{loop.index0}}';">
<div onclick="location.href='/?selected_server={{loop.index0}}';"> <h5 class="server-name">{{ server.info()["name"] }}</h5>
<h5 class="server-name">{{ server.info()["name"] }}</h5> <h4 class="server-info">{{ '/'.join(server.info()["url"].split('/')[0:-1]) }}</h4>
<h4 class="server-info">API {{ '/'.join(server.info()["url"].split('/')[0:-1]).split("://")[1] }}</h4> <h4 class="server-info">Port {{ server.info()["port_for_new_access_keys"] }}</h4>
<h4 class="server-info">Client Port: {{ server.info()["port_for_new_access_keys"] }}</h4> <h4 class="server-info">Hostname {{ server.info()["hostname_for_access_keys"] }}</h4>
<h4 class="server-info">Hostname: {{ server.info()["hostname_for_access_keys"] }}</h4> <h4 class="server-info">Traffic: {{ list_ns.total_bytes | filesizeformat }}</h4>
<h4 class="server-info">Traffic: {{ list_ns.total_bytes | filesizeformat }}</h4> <h4 class="server-info">v.{{ server.info()["version"] }}</h4>
<h4 class="server-info">Version: {{ server.info()["version"] }}</h4> <p class="server-comment">
<p class="server-comment"> {{ server.info()["comment"] }}
{{ server.info()["comment"] }} </p>
</p>
</div>
</div>
{% endfor %}
{% for broken_server in BROKEN_SERVERS %}
{% set config = broken_server["config"] %}
{% set error = broken_server["error"] %}
<div class="server-item server-item-broken">
<div onclick="location.href='/?selected_server={{ broken_server['id'] }}&broken=true';">
<h5 class="server-name">{{ config.get("name", "None") }}</h5>
<h4 class="server-info">API {{ '/'.join(config.get("url", "None").split('/')[0:-1]).split("://")[1] }}
</h4>
<h4 class="server-info">Client Port: N/D</h4>
<h4 class="server-info">Hostname: N/D</h4>
<h4 class="server-info">Traffic: N/D</h4>
<h4 class="server-info">Version: N/D</h4>
<p class="server-comment">
{{ config.get("comment", "None") }}
</p>
<div style="padding: 5px; color: #6a4545; background-color: #f6e9e9; border-radius: 5px;">
{{ error }}
</div>
</div>
</div>
{% endfor %}
<div onclick="location.href='/?add_server=True';" class="server-item server-add ">
<div class="">
+
</div>
</div> </div>
</div> </div>
{% endfor %}
<div onclick="location.href='/?add_server=True';" class="server-item server-add pure-g">
<div class="pure-u-1">
+
</div>
</div>
<div class="pure-u-19-24"> </div>
{% if add_server %}
<div class="server-content-header"> {% if add_server %}
<div class=""> <div class="pure-u-1-3">
<div class="server-content-header pure-g">
<div class="pure-u-1-2">
<h1 class="server-content-title">Add new server</h1> <h1 class="server-content-title">Add new server</h1>
</div> </div>
</div> </div>
<div class="server-content-body"> <div class="server-content-body">
<form action="/add_server" class="pure-form pure-form-stacked" method="POST"> <form action="/add_server" class="pure-form pure-form-stacked" method="POST">
<fieldset> <fieldset>
<div class=""> <div class="pure-g">
<div class="form-field"> <div class="pure-u-1 pure-u-md-1-3">
<input type="text" class="form-field" name="url" placeholder="Server management URL" /> <input type="text" class="pure-u-23-24" name="url" placeholder="Server management URL"/>
</div>
<div class="form-field">
<input type="text" class="form-field" name="cert" placeholder="Certificate" />
</div>
<div class="form-field">
<input type="text" class="form-field" name="comment" placeholder="Comment" />
</div>
</div> </div>
<button type="submit" class="pure-button pure-button-primary button">Add server</button> <div class="pure-u-1 pure-u-md-1-3">
</fieldset> <input type="text"class="pure-u-23-24" name="cert" placeholder="Certificate"/>
</form> </div>
</div> <div class="pure-u-1 pure-u-md-1-3">
<input type="text" class="pure-u-23-24" name="comment" placeholder="Comment"/>
</div>
</div>
<button type="submit" class="pure-button pure-input-1 pure-button-primary">Add</button>
</fieldset>
</form>
</div> </div>
</div>
{% endif %}
{% endif %}
{% if SERVERS|length != 0 and not add_server %} {% if SERVERS|length != 0 and not add_server %}
{% if selected_server is none %} {% if selected_server is none %}
{% set server = SERVERS[0] %} {% set server = SERVERS[0] %}
{% else %} {% else %}
{% set server = SERVERS[selected_server|int] %} {% set server = SERVERS[selected_server|int] %}
{% endif %} {% endif %}
<div id="main" class="pure-u-1">
<div class="pure-u-19-24"> <div class="server-content">
{% if not is_broken %} <div class="server-content-header pure-g">
<div class=""> <div class="pure-u-1-2">
<div class="server-content"> <h1 class="server-content-title">{{server.info()["name"]}}</h1>
<div class="server-content-header "> <p class="server-content-subtitle">
<div class=""> <span>v.{{server.info()["version"]}} {{server.info()["local_server_id"]}}</span>
<h1 class="server-content-title">{{server.info()["name"]}}</h1> </p>
<p class="server-content-subtitle">
<span>v.{{server.info()["version"]}} {{server.info()["local_server_id"]}}</span>
</p>
</div>
</div> </div>
{% set ns = namespace(total_bytes=0) %} </div>
{% for key in SERVERS[selected_server|int].data["keys"] %}
{% set ns = namespace(total_bytes=0) %}
{% for key in SERVERS[selected_server|int].data["keys"] %}
{% if key.used_bytes %} {% if key.used_bytes %}
{% set ns.total_bytes = ns.total_bytes + key.used_bytes %} {% set ns.total_bytes = ns.total_bytes + key.used_bytes %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<div class="server-content-body"> <div class="server-content-body">
<h3>Clients: {{ server.info()['keys']|length }}</h3> <h3>Clients: {{ server.info()['keys']|length }}</h3>
<h3>Total traffic: {{ ns.total_bytes | filesizeformat }}</h3> <h3>Total traffic: {{ ns.total_bytes | filesizeformat }}</h3>
<form class="pure-form pure-form-aligned" method="POST"> <form class="pure-form pure-form-stacked" method="POST">
<fieldset> <fieldset>
<div class=""> <div class="pure-g">
<div class=""> <div class="pure-u-1 pure-u-md-1-3">
<label for="name">Server Name</br>Must be unique. Used for Dynamic Link <label for="name">Server Name</br> Note that this will not be reflected on the devices of the users that you invited to connect to it.</label>
generation.</label> <input type="text" id="name" class="pure-u-23-24" name="name" value="{{server.info()['name']}}"/>
<input class="form-field" type="text" id="name" class="" name="name"
value="{{server.info()['name']}}" />
</div>
<div class="">
<label for="comment">Comment</br>Will be used as "Server name" in client
app.</label>
<input class="form-field" type="text" id="comment" class="" name="comment"
value="{{server.info()['comment']}}" />
</div>
<div class="">
<label for="port_for_new_access_keys">Port For New Access Keys</label>
<input class="form-field" type="text" id="port_for_new_access_keys" class=""
name="port_for_new_access_keys"
value="{{server.info()['port_for_new_access_keys']}}" />
</div>
<div class="">
<label for="hostname_for_access_keys">Hostname For Access Keys</label>
<input class="form-field" type="text" id="hostname_for_access_keys" class=""
name="hostname_for_access_keys"
value="{{server.info()['hostname_for_access_keys']}}" />
</div>
<div class="">
<label for="url">Server URL</label>
<input class="form-field" type="text" disabled id="url" class="" name="url"
value="{{server.info()['url']}}" />
</div>
<div class="">
<label for="cert">Server Access Certificate</label>
<input class="form-field" type="text" disabled id="cert" class="" name="cert"
value="{{server.info()['cert']}}" />
</div>
<div class="">
Created {{format_timestamp(server.info()['created_timestamp_ms']) }}
</div>
<input class="form-field" type="hidden" readonly id="server_id" class=""
name="server_id" value="{{server.info()['local_server_id']}}" />
</div>
<p>Share anonymous metrics</p>
<label for="metrics_enabled" class="pure-radio">
<input type="radio" id="metrics_enabled" name="metrics" value="True" {% if
server.info()['metrics_enabled']==True %}checked{% endif %} /> Enable
</label>
<label for="metrics_disabled" class="pure-radio">
<input type="radio" id="metrics_disabled" name="metrics" value="False" {% if
server.info()['metrics_enabled']==False %}checked{% endif %} /> Disable
</label>
<button type="submit" class="pure-button pure-button-primary button">Save and apply</button>
</fieldset>
</form>
<form action="/del_server" method="post">
<input type="hidden" id="really" value="{{ server.info()[" local_server_id"] }}">
<label for="really" class="pure-radio">
<button type="submit" id="delete_server"
class="pure-button pure-button-primary delete-button button">Delete
Server 🔒<input type="checkbox" id="agree" name="agree" required></button></label>
</form>
</div> </div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="comment">Comment</br>This value will be used as "Server name" in client app.</label>
<input type="text" id="comment" class="pure-u-23-24" name="comment" value="{{server.info()['comment']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="port_for_new_access_keys">Port For New Access Keys</label>
<input type="text" id="port_for_new_access_keys" class="pure-u-23-24" name="port_for_new_access_keys" value="{{server.info()['port_for_new_access_keys']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="hostname_for_access_keys">Hostname For Access Keys</label>
<input type="text" id="hostname_for_access_keys" class="pure-u-23-24" name="hostname_for_access_keys" value="{{server.info()['hostname_for_access_keys']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="url">Server URL</label>
<input type="text" readonly id="url" class="pure-u-23-24" name="url" value="{{server.info()['url']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="cert">Server Access Certificate</label>
<input type="text" readonly id="cert" class="pure-u-23-24" name="cert" value="{{server.info()['cert']}}"/>
</div>
<div class="pure-u-1 pure-u-md-1-3">
<label for="created_timestamp_ms">Created</label>
<input type="text" readonly id="created_timestamp_ms" class="pure-u-23-24" name="created_timestamp_ms" value="{{format_timestamp(server.info()['created_timestamp_ms']) }}"/>
</div>
<input type="hidden" readonly id="server_id" class="pure-u-23-24" name="server_id" value="{{server.info()['local_server_id']}}"/>
</div>
<p>Share anonymous metrics</p>
<label for="metrics_enabled" class="pure-radio">
<input type="radio" id="metrics_enabled" name="metrics" value="True" {% if server.info()['metrics_enabled'] == True %}checked{% endif %} /> Enable
</label>
<label for="metrics_disabled" class="pure-radio">
<input type="radio" id="metrics_disabled" name="metrics" value="False" {% if server.info()['metrics_enabled'] == False %}checked{% endif %} /> Disable
</label>
<button type="submit" class="pure-button pure-button-primary button">Save and apply</button>
</fieldset>
</form>
<form action="/del_server" method="post">
<input type="hidden" name="local_server_id" value="{{ server.info()["local_server_id"] }}">
<button type="submit" class="pure-button pure-button-primary delete-button button">Delete Server</button>
<input type="checkbox" id="agree" name="agree" required>
</form>
</div> </div>
</div> </div>
{% else %}
{% for server in BROKEN_SERVERS %}
{% if server["id"] == selected_server %}
{% set config_block = server["config"] %}
{% endif %}
{% endfor %}
{{config_block}} {{id}}
<div class="">
<div class="server-content">
<div class="server-content-header ">
<div class="">
<h1 class="server-content-title">{{config_block["name"]}}</h1>
</div>
</div>
<div class="server-content-body">
<form class="pure-form pure-form-aligned" method="POST">
<fieldset>
<div class="">
<div class="">
<label for="name">Server Name</br>Must be unique. Used for Dynamic Link
generation.</label>
<input class="form-field" disabled type="text" id="name" class="" name="name"
value="No connection" />
</div>
<div class="">
<label for="comment">Comment</br>Will be used as "Server name" in client
app.</label>
<input class="form-field" type="text" id="comment" class="" name="comment"
value="{{config_block['comment']}}" />
</div>
<div class="">
<label for="port_for_new_access_keys">Port For New Access Keys</label>
<input disabled class="form-field" type="text" id="port_for_new_access_keys"
class="" name="port_for_new_access_keys" value="No connection" />
</div>
<div class="">
<label for="hostname_for_access_keys">Hostname For Access Keys</label>
<input disabled class="form-field" type="text" id="hostname_for_access_keys"
class="" name="hostname_for_access_keys" value="No connection" />
</div>
<div class="">
<label for="url">Server URL</label>
<input class="form-field" type="text" id="url" class="" name="url"
value="{{config_block['url']}}" />
</div>
<div class="">
<label for="cert">Server Access Certificate</label>
<input class="form-field" type="text" id="cert" class="" name="cert"
value="{{config_block['cert']}}" />
</div>
<input class="form-field" readonly id="server_id" class=""
name="server_id" value="{{ selected_server }}" />
</div>
</fieldset>
</form>
<form action="/del_server" method="post">
<input type="hidden" id="really" value="{{ selected_server }}">
<label for="really" class="pure-radio">
<button type="submit" id="delete_server"
class="pure-button pure-button-primary delete-button button">Delete
Server 🔒<input type="checkbox" id="agree" name="agree" required></button></label>
</form>
</div>
</div>
</div>
{% endif %}
</div> </div>
{% endif %} {% endif %}
</div>
{% endblock %} {% endblock %}

39
templates/sync.html Executable file → Normal file
View File

@ -1,32 +1,17 @@
{% extends "base.html" %} <h1>Last sync log</h1>
{% block content %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script> -->
<script>hljs.highlightAll();</script>
<h1>Last logs</h1>
<form action="/sync" class="pure-form pure-form-stacked" method="POST"> <form action="/sync" class="pure-form pure-form-stacked" method="POST">
<button type="submit" class="pure-button pure-button-primary button">Sync now</button> <p>Wipe ALL keys on ALL servers?</p>
<p>Also wipe ALL keys on ALL servers? Use in case of inconsistency.</p> <label for="no_wipe" class="pure-radio">
<label for="no_wipe" class="pure-radio"> <input type="radio" id="no_wipe" name="wipe" value="no_wipe" checked /> No
<input type="radio" id="no_wipe" name="wipe" value="no_wipe" checked /> No </label>
</label> <label for="do_wipe" class="pure-radio">
<label for="do_wipe" class="pure-radio"> <input type="radio" id="do_wipe" name="wipe" value="all" /> Yes
<input type="radio" id="do_wipe" name="wipe" value="all" /> Yes </label>
</label> <button type="submit" class="pure-button button-error pure-input-1 ">Sync now</button>
</form>
</form> <pre>
<code>
<pre style="height: 600px; overflow: scroll;">
<code class="language-c">
{% for line in lines %}{{ line }}{% endfor %} {% for line in lines %}{{ line }}{% endfor %}
</code> </code>
</pre> </pre>
{% endblock %}