Started sending some serverside configuration to the client-side javascript

The information is sent via the cookie 'server_settings'. The value is a
base64-encoded json object containing the data necessary
for site-specific customization.

Also fixed a bug that was preventing the 'add new client' button from being
disabled when the client limit is reached.
This commit is contained in:
Erik Thuning 2025-03-06 14:50:12 +01:00
parent ebc430407a
commit e9f180805a
4 changed files with 46 additions and 14 deletions

@ -1,3 +1,4 @@
from base64 import b64encode
from configparser import ConfigParser
from datetime import datetime
from pathlib import Path
@ -17,7 +18,6 @@ public_paths = [login_path, callback_path]
user_cookie = 'username'
token_cookie = 'token'
access_cookie = 'access'
limit_cookie = 'max_clients'
permitted_format = re.compile('^[A-Za-z0-9-]+$')
config = ConfigParser()
@ -27,6 +27,19 @@ app = Flask(__name__)
oauth = Oauth(config['oauth'])
app.wg = WireGuard(config['wireguard'])
def prepare_frontend_settings(config):
settings = {}
for key, value in config['frontend'].items():
settings[key] = value
settings['client_limit'] = config.getint('wireguard',
'user_client_limit',
fallback=0)
json_string = json.dumps(settings)
base64_bytes = b64encode(bytes(json_string, 'utf-8'))
return base64_bytes.decode('utf-8')
frontend_settings = prepare_frontend_settings(config)
required_entitlement_list = []
if 'required_entitlement' in config['security']:
entitlement_conf = config.get('security', 'required_entitlement')
@ -72,9 +85,8 @@ def setup() -> None:
@app.after_request
def reload(response: Response) -> Response:
limit = config.getint('wireguard', 'user_client_limit', fallback=0)
response.set_cookie(limit_cookie,
str(limit),
response.set_cookie('server_settings',
frontend_settings,
secure=True,
samesite='Strict')
if app.wg.user_name:

@ -1,3 +1,13 @@
[frontend]
# The name of the instance as shown in the page title
site_name = Some Snazzy Name
# Optional:
# An absolute webserver path that returns a html fragment to replace the
# default <details> element in the topbox. The file must be located under
# the public/static/ subdirectory, and the path must begin with /static/.
topbox_content = /static/somefile.html
[wireguard]
# The name of the wireguard tunnel. Will among other things be used for
# the server config filename.

@ -14,14 +14,11 @@
<user id="banner-userid" aria-label="logged in as"></user>
</header>
<topbox>
<details class="instructions" open>
<details open>
<summary>Instructions</summary>
<ol>
<li>
<a href="https://serviceportalen.su.se/sv-se/article/1319269"
target="_blank">
Install WireGuard (opens in a new tab) on the client device.
</a>
Install WireGuard on the client device.
</li>
<li>
Create a client configuration by clicking the

@ -107,10 +107,10 @@
configs_parent.insertBefore(template, child);
}
}
update_create_button();
});
});
update_create_button();
}
function display_edit_form(config_id, config) {
@ -215,14 +215,13 @@
function update_create_button() {
const visible_configs = document.querySelectorAll('configs > config');
const cookies = get_cookies();
const max_clients = cookies['max_clients'];
const max_clients = sessionStorage.getItem('max_clients');
let button_disabled = false;
let button_message = "Add a client";
let button_message = 'Add a client';
if(max_clients > 0 && visible_configs.length >= max_clients) {
button_disabled = true;
button_message = "Limit of "+max_clients+" clients reached";
button_message = 'Limit of '+max_clients+' clients reached';
}
const button = document.querySelector('button#create-config');
button.disabled = button_disabled;
@ -233,6 +232,20 @@
try {
const configs = await make_api_request('GET', '/configs/');
const cookies = get_cookies();
const settings = JSON.parse(atob(cookies['server_settings']));
sessionStorage.setItem('max_clients', settings['client_limit']);
document.querySelector('head > title')
.textContent = settings['site_name'];
if('topbox_content' in settings) {
fetch(settings['topbox_content'])
.then((response) => response.text())
.then((data) => {
const template = document.createElement('template');
template.innerHTML = data;
document.querySelector('topbox > details')
.replaceWith(template.content.cloneNode(true));
});
}
document.querySelector('user#banner-userid')
.textContent = cookies['username'];
document.querySelector('button#create-config')