summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-wireguard/htdocs/luci-static
diff options
context:
space:
mode:
authorlvoegl <lvoegl@tdt.de>2021-08-31 13:48:31 +0200
committerLukas Voegl <lvoegl@tdt.de>2021-09-17 12:28:36 +0200
commit8950c9f66c5d2e6123aeb5359fc3861d2f09ca72 (patch)
treebb4f90c77acb3033ffe5754bba40387a53b5e403 /applications/luci-app-wireguard/htdocs/luci-static
parent584301a9022b79482af55cbcf6b9f54136400bf1 (diff)
luci-app-wireguard: replace luci-app-wireguard
Signed-off-by: lvoegl <lvoegl@tdt.de>
Diffstat (limited to 'applications/luci-app-wireguard/htdocs/luci-static')
-rw-r--r--applications/luci-app-wireguard/htdocs/luci-static/resources/view/wireguard/status.js214
1 files changed, 214 insertions, 0 deletions
diff --git a/applications/luci-app-wireguard/htdocs/luci-static/resources/view/wireguard/status.js b/applications/luci-app-wireguard/htdocs/luci-static/resources/view/wireguard/status.js
new file mode 100644
index 0000000000..ca4ca9fd17
--- /dev/null
+++ b/applications/luci-app-wireguard/htdocs/luci-static/resources/view/wireguard/status.js
@@ -0,0 +1,214 @@
+'use strict';
+'require view';
+'require rpc';
+'require form';
+'require poll';
+
+
+var callGetWgInstances = rpc.declare({
+ object: 'luci.wireguard_status',
+ method: 'getWgInstances'
+});
+
+function timestampToStr(timestamp) {
+ if (timestamp < 1) {
+ return _('Never');
+ }
+ var now = new Date();
+ var seconds = (now.getTime() / 1000) - timestamp;
+ var ago = '';
+ if (seconds < 60) {
+ ago = parseInt(seconds) + _('s ago');
+ } else if (seconds < 3600) {
+ ago = parseInt(seconds / 60) + _('m ago');
+ } else if (seconds < 86401) {
+ ago = parseInt(seconds / 3600) + _('h ago');
+ } else {
+ ago = _('over a day ago');
+ }
+ var t = new Date(timestamp * 1000);
+ return t.toUTCString() + ' (' + ago + ')';
+}
+
+function generatePeerOption(key, title, value) {
+ return E('div', { 'class': 'cbi-value', 'style': 'padding: 0;' }, [
+ E('label', {
+ 'class': 'cbi-value-title', 'style': 'font-weight: bold;'
+ }, title),
+ E('input', {
+ 'class': 'cbi-input-text',
+ 'data-name': key,
+ 'style': 'border: none; float: left; width: 50%;',
+ 'disabled': '',
+ 'value': value
+ })
+ ]);
+}
+
+function generatePeerTable(options, iconSrc) {
+ return E('div', { 'class': 'table cbi-section-table' }, [
+ E('div', { 'class': 'td' },
+ E('img', { 'src': iconSrc, 'class': 'tunnel-icon' })
+ ),
+ E('div', { 'class': 'td peer-options' },
+ options.filter(function (option) {
+ return option[2] != null;
+ }).map(function (option) {
+ return generatePeerOption.apply(null, option);
+ })
+ )
+ ]);
+}
+
+function getTunnelIcon(latestHandshake) {
+ var img = (new Date().getTime() / 1000 - latestHandshake) < 140 ?
+ 'tunnel' : 'tunnel_disabled';
+
+ return L.resource('icons', img + '.png');
+}
+
+function generatePeerRows(peers) {
+ var peerRows = [];
+
+ peers.forEach(function (peer) {
+ var peerData = parsePeerData(peer);
+ var iconSrc = getTunnelIcon(peer.latest_handshake);
+
+ peerRows.push(E('div', {
+ 'class': 'tr cbi-section-table-row'
+ }, [
+ E('div', {
+ 'class': 'td peer-name',
+ 'style': 'width: 25%; font-size: 0.9rem;'
+ }, peer.name),
+ E('div', { 'class': 'td', 'data-section-id': peer.name },
+ generatePeerTable(peerData, iconSrc)
+ )
+ ]));
+ });
+
+ return peerRows;
+}
+
+function parseIfaceData(iface) {
+ return [
+ ['public_key', _('Public Key'),
+ iface.public_key != '(none)' ? iface.public_key : null],
+ ['listen_port', _('Listen Port'),
+ iface.listen_port > 0 ? iface.listen_port : null],
+ ['fwmark', _('Firewall Mark'),
+ iface.fwmark != 'off' ? iface.fwmark : null]
+ ];
+}
+
+function parsePeerData(peer) {
+ return [
+ ['public_key', _('Public Key'),
+ peer.public_key],
+ ['endpoint', _('Endpoint'),
+ peer.endpoint == '(none)' ? null : peer.endpoint],
+ ['allowed_ips', _('Allowed IPs'),
+ peer.allowed_ips.length == 0 ? null : peer.allowed_ips.join('\n')],
+ ['persistent_keepalive', _('Persistent Keepalive'),
+ peer.persistent_keepalive == 'off' ? null : peer.persistent_keepalive + 's'],
+ ['latest_handshake', _('Latest Handshake'),
+ timestampToStr(peer.latest_handshake)],
+ ['transfer_rx', _('Data Received'),
+ '%1024mB'.format(peer.transfer_rx)],
+ ['transfer_tx', _('Data Transmitted'),
+ '%1024mB'.format(peer.transfer_tx)]
+ ];
+}
+
+return view.extend({
+ load: function () {
+ return callGetWgInstances();
+ },
+ poll_status: function (nodes, ifaces) {
+ Object.keys(ifaces).forEach(function (ifaceName) {
+ var iface = ifaces[ifaceName];
+
+ var section = nodes.querySelector(
+ '[data-section-id="%q"]'.format(ifaceName)
+ );
+
+ parseIfaceData(iface).forEach(function (option) {
+ if (option[2] != null) {
+ var optionEl = section.querySelector(
+ '[data-name="%q"]'.format(option[0])
+ );
+ var inputEl = optionEl.querySelector('input');
+
+ inputEl.value = option[2];
+ }
+ });
+
+ iface.peers.forEach(function (peer) {
+ var peerData = parsePeerData(peer);
+ var iconSrc = getTunnelIcon(peer.latest_handshake);
+
+ var peerSection = section.querySelector(
+ '[data-section-id="%q"]'.format(peer.name)
+ );
+ var iconEl = peerSection.querySelector('.tunnel-icon');
+ iconEl.src = iconSrc;
+
+ peerData.forEach(function (option) {
+ if (option[2]) {
+ var inputEl = peerSection.querySelector(
+ '[data-name="%q"]'.format(option[0])
+ );
+ inputEl.value = option[2];
+ }
+ })
+ });
+ });
+ },
+ render: function (ifaces) {
+ var m, s, o, ss;
+
+ m = new form.JSONMap(ifaces, _('WireGuard Status'));
+ m.tabbed = true;
+
+ var ifaceNames = Object.keys(ifaces);
+ for (var i = ifaceNames.length - 1; i >= 0; i--) {
+ var ifaceName = ifaceNames[i];
+ var iface = ifaces[ifaceName];
+
+ s = m.section(form.TypedSection, ifaceName);
+ s.tabbed = true;
+ s.anonymous = true;
+
+ var ifaceData = parseIfaceData(iface);
+ ifaceData.forEach(function (option) {
+ if (option[2] != null) {
+ o = s.option(form.Value, option[0], option[1]);
+ o.readonly = true;
+ }
+ });
+
+ o = s.option(form.SectionValue, 'peers', form.TypedSection, 'peers');
+ ss = o.subsection;
+
+ ss.render = L.bind(function (view, section_id) {
+ return E('div', { 'class': 'cbi-section' }, [
+ E('h3', _('Peers')),
+ E('div', { 'class': 'table cbi-section-table' },
+ generatePeerRows(this.peers))
+ ]);
+ }, iface, this);
+ }
+
+ return m.render().then(L.bind(function (m, nodes) {
+ poll.add(L.bind(function () {
+ return callGetWgInstances().then(
+ L.bind(this.poll_status, this, nodes)
+ );
+ }, this), 5);
+ return nodes;
+ }, this, m));
+ },
+ handleReset: null,
+ handleSaveApply: null,
+ handleSave: null
+});