123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- 'use strict';
- 'require view';
- 'require rpc';
- 'require poll';
- 'require dom';
- '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');
- return (new Date(timestamp * 1000)).toUTCString() + ' (' + 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({
- 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', 'tunnel.png') }),
- '\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
- });
|