mirror of
https://github.com/openwrt/luci.git
synced 2025-12-21 17:04:35 +04:00
191 lines
4.9 KiB
JavaScript
191 lines
4.9 KiB
JavaScript
'use strict';
|
|
'require view';
|
|
'require rpc';
|
|
'require poll';
|
|
'require dom';
|
|
'require uci';
|
|
'require ui';
|
|
|
|
|
|
var callGetWgInstances = rpc.declare({
|
|
object: 'luci.wireguard',
|
|
method: 'getWgInstances'
|
|
});
|
|
|
|
function timestampToStr(timestamp) {
|
|
if (timestamp < 1)
|
|
return _('Never', 'No WireGuard peer handshake yet');
|
|
|
|
var seconds = (Date.now() / 1000) - timestamp;
|
|
var ago;
|
|
|
|
if (seconds < 60)
|
|
ago = _('%ds ago').format(seconds);
|
|
else if (seconds < 3600)
|
|
ago = _('%dm ago').format(seconds / 60);
|
|
else if (seconds < 86401)
|
|
ago = _('%dh ago').format(seconds / 3600);
|
|
else
|
|
ago = _('over a day ago');
|
|
|
|
const date = new Date(timestamp * 1000);
|
|
const sys = uci.get('system', '@system[0]');
|
|
|
|
return new Intl.DateTimeFormat(undefined, {
|
|
dateStyle: 'medium',
|
|
timeStyle: (!sys?.clock_timestyle) ? 'long' : 'full',
|
|
hourCycle: (!sys?.clock_hourcycle) ? undefined : sys.clock_hourcycle,
|
|
timeZone: sys?.zonename?.replaceAll(' ', '_') || 'UTC',
|
|
}).format(date) + ' (' + ago + ')';
|
|
}
|
|
|
|
function handleInterfaceDetails(iface) {
|
|
ui.showModal(_('Instance Details'), [
|
|
ui.itemlist(E([]), [
|
|
_('Name'), iface.name,
|
|
_('Public Key'), E('code', [ iface.public_key ]),
|
|
_('Listen Port'), iface.listen_port,
|
|
_('Firewall Mark'), iface.fwmark != 'off' ? iface.fwmark : E('em', _('none'))
|
|
]),
|
|
E('div', { 'class': 'right' }, [
|
|
E('button', {
|
|
'class': 'btn cbi-button',
|
|
'click': ui.hideModal
|
|
}, [ _('Dismiss') ])
|
|
])
|
|
]);
|
|
}
|
|
|
|
function handlePeerDetails(peer) {
|
|
ui.showModal(_('Peer Details'), [
|
|
ui.itemlist(E([]), [
|
|
_('Description'), peer.name,
|
|
_('Public Key'), E('code', [ peer.public_key ]),
|
|
_('Endpoint'), peer.endpoint,
|
|
_('Allowed IPs'), (Array.isArray(peer.allowed_ips) && peer.allowed_ips.length) ? peer.allowed_ips.join(', ') : E('em', _('none')),
|
|
_('Received Data'), '%1024mB'.format(peer.transfer_rx),
|
|
_('Transmitted Data'), '%1024mB'.format(peer.transfer_tx),
|
|
_('Latest Handshake'), timestampToStr(+peer.latest_handshake),
|
|
_('Keep-Alive'), (peer.persistent_keepalive != 'off') ? _('every %ds', 'WireGuard keep alive interval').format(+peer.persistent_keepalive) : E('em', _('none')),
|
|
]),
|
|
E('div', { 'class': 'right' }, [
|
|
E('button', {
|
|
'class': 'btn cbi-button',
|
|
'click': ui.hideModal
|
|
}, [ _('Dismiss') ])
|
|
])
|
|
]);
|
|
}
|
|
|
|
function renderPeerTable(instanceName, peers) {
|
|
var t = new L.ui.Table(
|
|
[
|
|
_('Peer'),
|
|
_('Endpoint'),
|
|
_('Data Received'),
|
|
_('Data Transmitted'),
|
|
_('Latest Handshake')
|
|
],
|
|
{
|
|
id: 'peers-' + instanceName
|
|
},
|
|
E('em', [
|
|
_('No peers connected')
|
|
])
|
|
);
|
|
|
|
t.update(peers.map(function(peer) {
|
|
return [
|
|
[
|
|
peer.name || '',
|
|
E('div', {
|
|
'style': 'cursor:pointer',
|
|
'click': ui.createHandlerFn(this, handlePeerDetails, peer)
|
|
}, [
|
|
E('p', [
|
|
peer.name ? E('span', [ peer.name ]) : E('em', [ _('Untitled peer') ])
|
|
]),
|
|
E('span', {
|
|
'class': 'ifacebadge hide-sm',
|
|
'data-tooltip': _('Public key: %h', 'Tooltip displaying full WireGuard peer public key').format(peer.public_key)
|
|
}, [
|
|
E('code', [ peer.public_key.replace(/^(.{5}).+(.{6})$/, '$1…$2') ])
|
|
])
|
|
])
|
|
],
|
|
peer.endpoint,
|
|
[ +peer.transfer_rx, '%1024mB'.format(+peer.transfer_rx) ],
|
|
[ +peer.transfer_tx, '%1024mB'.format(+peer.transfer_tx) ],
|
|
[ +peer.latest_handshake, timestampToStr(+peer.latest_handshake) ]
|
|
];
|
|
}));
|
|
|
|
return t.render();
|
|
}
|
|
|
|
return view.extend({
|
|
load() {
|
|
return Promise.all([
|
|
uci.load('system'),
|
|
])
|
|
},
|
|
|
|
renderIfaces: function(ifaces) {
|
|
var res = [
|
|
E('h2', [ _('WireGuard Status') ])
|
|
];
|
|
|
|
for (var instanceName in ifaces) {
|
|
res.push(
|
|
E('h3', [ _('Instance "%h"', 'WireGuard instance heading').format(instanceName) ]),
|
|
E('p', {
|
|
'style': 'cursor:pointer',
|
|
'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName])
|
|
}, [
|
|
E('span', { 'class': 'ifacebadge' }, [
|
|
E('img', { 'src': L.resource('icons', 'wireguard.svg'), 'style': 'width:32px;height:32px' }),
|
|
'\xa0',
|
|
instanceName
|
|
]),
|
|
E('span', { 'style': 'opacity:.8' }, [
|
|
' · ',
|
|
_('Port %d', 'WireGuard listen port').format(ifaces[instanceName].listen_port),
|
|
' · ',
|
|
E('code', { 'click': '' }, [ ifaces[instanceName].public_key ])
|
|
])
|
|
]),
|
|
renderPeerTable(instanceName, ifaces[instanceName].peers)
|
|
);
|
|
}
|
|
|
|
if (res.length == 1)
|
|
res.push(E('p', { 'class': 'center', 'style': 'margin-top:5em' }, [
|
|
E('em', [ _('No WireGuard interfaces configured.') ])
|
|
]));
|
|
|
|
return E([], res);
|
|
},
|
|
|
|
render: function() {
|
|
poll.add(L.bind(function () {
|
|
return callGetWgInstances().then(L.bind(function(ifaces) {
|
|
dom.content(
|
|
document.querySelector('#view'),
|
|
this.renderIfaces(ifaces)
|
|
);
|
|
}, this));
|
|
}, this), 5);
|
|
|
|
return E([], [
|
|
E('h2', [ _('WireGuard Status') ]),
|
|
E('p', { 'class': 'center', 'style': 'margin-top:5em' }, [
|
|
E('em', [ _('Loading data…') ])
|
|
])
|
|
]);
|
|
},
|
|
|
|
handleReset: null,
|
|
handleSaveApply: null,
|
|
handleSave: null
|
|
});
|