From 5bf6a0c6eff6d18a42d5ae1775f09d360f9f1fcf Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Fri, 4 Mar 2022 08:08:07 +0500 Subject: implement PersistentKeepalive as a parameter It's a unique parameter in many ways compared to the others. First, it's optional, and has a default value. Second, I don't want it to be visible at all times, which is why I hid it under the "Show advanced parameters" checkbox. Hence a lot of changes. --- assets/js/main.js | 153 +++++++++++++++++++++++++++++++++++++++++++++++------- index.html | 19 ++++++- 2 files changed, 153 insertions(+), 19 deletions(-) diff --git a/assets/js/main.js b/assets/js/main.js index d5be55f..79cc4e2 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,10 +1,21 @@ var iface = 'wg0'; -var persistent_keepalive = 25; function parse_placeholder(val) { return true; } +function parse_positive_integer(src) { + var val = parseInt(src); + if (isNaN(val) || val < 1) { + throw new Error('Cannot parse as a positive integer.'); + } + return val; +} + +function parse_keepalive(src) { + return parse_positive_integer(src); +} + function parse_endpoint(val) { val = val.trim(); if (val.length == 0) { @@ -104,15 +115,32 @@ Input.prototype.error_id = function() { return this.input_id() + '_error'; } +Input.prototype.container_id = function() { + return this.input_id() + '_container'; +} + Input.prototype.value = function() { return $(this.input_id()).val(); } +Input.prototype.has_value = function() { + return this.value().length > 0; +} + Input.prototype.set = function(value) { $(this.input_id()).val(value); } +Input.prototype.show = function() { + $(this.container_id()).show(); +} + +Input.prototype.hide = function() { + $(this.container_id()).hide(); +} + Input.prototype.show_error = function(msg) { + this.show(); $(this.error_id()).text(msg); $(this.error_id()).show(); } @@ -125,6 +153,8 @@ var Value = function(name, parser) { this.name = name; this.input = new Input(name); this.parser = parser; + this.optional = false; + this.advanced = false; this.value = null; this.error = null; @@ -132,20 +162,46 @@ var Value = function(name, parser) { Value.prototype.parse = function() { try { - this.value = this.parser(this.input.value()); - this.input.hide_error(); + var value = this.input.value(); + if (!this.optional || value.length > 0) { + value = this.parser(value); + } + this.set_value(value); return true; } catch (err) { - this.error = err.message; - this.input.show_error(this.error); + this.set_error(err.message); return false; } } +Value.prototype.set_value = function(value) { + this.value = value; + this.error = null; + this.input.hide_error(); +} + +Value.prototype.set_error = function(msg) { + this.value = null; + this.error = msg; + this.input.show_error(this.error); +} + +Value.prototype.is_set = function() { + return this.input.has_value(); +} + Value.prototype.set = function(value) { this.input.set(value); } +Value.prototype.show = function() { + this.input.show(); +} + +Value.prototype.hide = function() { + this.input.hide(); +} + var Endpoint = function(name) { Value.call(this, name, parse_endpoint); } @@ -174,6 +230,15 @@ var IPv6 = function(name) { IPv6.prototype = Object.create(Value.prototype); IPv6.prototype.constructor = IPv6; +var Keepalive = function(name) { + Value.call(this, name, parse_keepalive); + this.optional = true; + this.advanced = true; +} + +Keepalive.prototype = Object.create(Value.prototype); +Keepalive.prototype.constructor = Keepalive; + var Data = function() { this.server_public = new Key('server_public'); this.server_endpoint = new Endpoint('server_endpoint'); @@ -182,6 +247,7 @@ var Data = function() { this.client_private = new Key('client_private'); this.client_ipv4 = new IPv4('client_ipv4'); this.client_ipv6 = new IPv6('client_ipv6'); + this.keepalive = new Keepalive('keepalive'); this.values = [ this.server_public, @@ -190,7 +256,8 @@ var Data = function() { this.client_public, this.client_private, this.client_ipv4, - this.client_ipv6 + this.client_ipv6, + this.keepalive ]; } @@ -231,10 +298,12 @@ Data.prototype.parse = function() { success = false; } }); - if (!success) { - this.show_error(); - } else { + if (success) { + if (!$('#advanced_params').prop('checked')) + this.hide_advanced(); this.hide_error(); + } else { + this.show_error(); } return success; } @@ -248,6 +317,22 @@ Data.prototype.hide_error = function() { $('#params_error').hide(); } +Data.prototype.show_advanced = function() { + this.values.forEach(function(value) { + if (!value.advanced) + return; + value.show(); + }); +} + +Data.prototype.hide_advanced = function() { + this.values.forEach(function(value) { + if (!value.advanced) + return; + value.hide(); + }); +} + function format_pre_text(text) { return $('
').text(text);
 }
@@ -293,7 +378,7 @@ QRCode.prototype.format = function() {
 
 function wg_quick_client_file(data) {
     var path = `/etc/wireguard/${iface}.conf`;
-    return new ConfigFile(path,
+    var contents =
 `# On the client, put this to
 #     ${path}
 # and either
@@ -309,8 +394,15 @@ Endpoint = ${data.server_endpoint.value}
 PublicKey = ${data.server_public.value}
 PresharedKey = ${data.preshared.value}
 AllowedIPs = ${data.client_ipv4.value.allowed_ips_client()}, ${data.client_ipv6.value.allowed_ips_client()}
-PersistentKeepalive = ${persistent_keepalive}
-`);
+`;
+
+    if (data.keepalive.is_set()) {
+        contents +=
+`PersistentKeepalive = ${data.keepalive.value}
+`;
+    }
+
+    return new ConfigFile(path, contents);
 }
 
 function wg_quick_server_file(data) {
@@ -331,7 +423,7 @@ AllowedIPs = ${data.client_ipv4.value.allowed_ips_server()}, ${data.client_ipv6.
 
 function systemd_client_netdev_file(data) {
     var path = `/etc/systemd/network/${iface}.netdev`;
-    return new ConfigFile(path,
+    var contents =
 `# On the client, you need two files. Put this into
 #     ${path}
 # and after you're done with both files, run
@@ -350,8 +442,15 @@ Endpoint = ${data.server_endpoint.value}
 PublicKey = ${data.server_public.value}
 PresharedKey = ${data.preshared.value}
 AllowedIPs = ${data.client_ipv4.value.allowed_ips_client()}, ${data.client_ipv6.value.allowed_ips_client()}
-PersistentKeepalive = ${persistent_keepalive}
-`);
+`;
+
+    if (data.keepalive.is_set()) {
+        contents +=
+`PersistentKeepalive = ${data.keepalive.value}
+`;
+    }
+
+    return new ConfigFile(path, contents);
 }
 
 function systemd_client_network_file(data) {
@@ -392,7 +491,7 @@ AllowedIPs = ${data.client_ipv4.value.allowed_ips_server()}, ${data.client_ipv6.
 
 function nmcli_client_file(data) {
     var path = `/etc/NetworkManager/system-connections/${iface}.nmconnection`;
-    return new ConfigFile(path,
+    var contents =
 `# On the client, put this to
 #     ${path}
 # and run
@@ -414,8 +513,15 @@ endpoint=${data.server_endpoint.value}
 preshared-key=${data.preshared.value}
 preshared-key-flags=0
 allowed-ips=${data.client_ipv4.value.allowed_ips_client()};${data.client_ipv6.value.allowed_ips_client()};
-persistent-keepalive=${persistent_keepalive}
+`;
+    if (data.keepalive.is_set()) {
+        contents +=
+`persistent-keepalive=${data.keepalive.value}
+`;
+    }
 
+    contents +=
+`
 [ipv4]
 address1=${data.client_ipv4.value.address()}
 method=manual
@@ -423,7 +529,9 @@ method=manual
 [ipv6]
 address1=${data.client_ipv6.value.address()}
 method=manual
-`);
+`;
+
+    return new ConfigFile(path, contents);
 }
 
 function nmcli_server_file(data) {
@@ -631,6 +739,15 @@ function form_on_submit() {
     return false;
 }
 
+function advanced_params_on_click(input) {
+    var data = new Data();
+    if (input.checked) {
+        data.show_advanced();
+    } else {
+        data.hide_advanced();
+    }
+}
+
 function main() {
     var data = new Data();
     if (data.set_from_this_url()) {
diff --git a/index.html b/index.html
index 34499c2..e285ff5 100644
--- a/index.html
+++ b/index.html
@@ -59,6 +59,14 @@ params:
         help: |
           IPv6 address to assign to the client and its netmask in the CIDR format.
         example: fd::/48
+      - id: keepalive
+        name: Keepalive
+        default: 25
+        placeholder: Seconds between keepalive packets, typically 25
+        help: |
+          Time to wait between sending keepalive packets, seconds.
+        example: 25
+        advanced: true
 ---
 

WireGuard configuration

@@ -95,7 +103,7 @@ show the configuration that can be easily consumed by the new client.

{% for param in grp.items %} -
+
@@ -110,6 +118,15 @@ show the configuration that can be easily consumed by the new client.

{% endfor %}
+
+
+
+
+ +
+
+
+
-- cgit v1.2.3