diff --git a/applications/luci-app-ocserv/htdocs/luci-static/resources/view/ocserv/users.js b/applications/luci-app-ocserv/htdocs/luci-static/resources/view/ocserv/users.js index 2cb4e5690a..d37c2c1ca6 100644 --- a/applications/luci-app-ocserv/htdocs/luci-static/resources/view/ocserv/users.js +++ b/applications/luci-app-ocserv/htdocs/luci-static/resources/view/ocserv/users.js @@ -68,7 +68,9 @@ return L.view.extend({ device: entry?.device, time: entry?.time || entry['connected-at'], cipher: entry?.cipher, - status: entry?.status + status: entry?.status, + tx: entry?._TX || entry?.TX || entry?.tx, + rx: entry?._RX || entry?.RX || entry?.rx }; }, @@ -151,7 +153,7 @@ return L.view.extend({ if (users.length === 0) { table.appendChild( E('div', { 'class': 'tr placeholder' }, [ - E('div', { 'class': 'td', 'colspan': 10 }, + E('div', { 'class': 'td', 'colspan': 13 }, E('em', _('Collecting data...'))) ]) ); diff --git a/applications/luci-app-ocserv/htdocs/luci-static/resources/view/status/include/80_ocserv.js b/applications/luci-app-ocserv/htdocs/luci-static/resources/view/status/include/80_ocserv.js index 615ba92346..6a88657443 100644 --- a/applications/luci-app-ocserv/htdocs/luci-static/resources/view/status/include/80_ocserv.js +++ b/applications/luci-app-ocserv/htdocs/luci-static/resources/view/status/include/80_ocserv.js @@ -39,9 +39,8 @@ return baseclass.extend({ return users; } catch (e) { - // Fall back to text parsing for non-JSON output - console.warn('JSON parsing failed, falling back to text parsing:', e.message); - return this.parseUsersText(output); + console.error('Failed to parse JSON:', e.message); + return users; } }, @@ -56,35 +55,12 @@ return baseclass.extend({ device: entry?.device, time: entry?.time || entry['connected-at'], cipher: entry?.cipher, - status: entry?.status + status: entry?.status, + tx: entry?._TX || entry?.TX || entry?.tx, + rx: entry?._RX || entry?.RX || entry?.rx }; }, - parseUsersText: function(output) { - const users = []; - if (!output) return users; - - const lines = output.split('\n'); - for (let line of lines) { - // Parse: id user group vpn_ip ip device time cipher status - const match = line.match(/^\s*(\d+)\s+([-_\w]+)\s+([().*\-_\w]+)\s+([:.\-_\w]+)\s+([:.\-_\w]+)\s+([:.\-_\w]+)\s+([:.\-_\w]+)\s+([():.\-_\w]+)\s+([:.\-_\w]+)/); - if (match) { - users.push({ - id: match[1], - user: match[2], - group: match[3], - vpn_ip: match[4], - ip: match[5], - device: match[6], - time: match[7], - cipher: match[8], - status: match[9] - }); - } - } - return users; - }, - handleDisconnect: function(id) { return L.resolveDefault( fs.exec('/usr/bin/occtl', ['disconnect', 'id', id]), @@ -100,7 +76,7 @@ return baseclass.extend({ load: function() { return L.resolveDefault( - fs.exec('/usr/bin/occtl', ['show', 'users']).then(res => res.stdout), + fs.exec('/usr/bin/occtl', ['--json', 'show', 'users']).then(res => res.stdout), '' ); }, @@ -118,6 +94,8 @@ return baseclass.extend({ E('div', { 'class': 'th' }, _('Time')), E('div', { 'class': 'th' }, _('Cipher')), E('div', { 'class': 'th' }, _('Status')), + E('div', { 'class': 'th' }, _('Tx')), + E('div', { 'class': 'th' }, _('Rx')), E('div', { 'class': 'th' }, '\u00a0') ]) ]); @@ -141,7 +119,9 @@ return baseclass.extend({ E('div', { 'class': 'td' }, user.time), E('div', { 'class': 'td' }, user.cipher), E('div', { 'class': 'td' }, user.status), - E('div', { 'class': 'td' }, + E('div', { 'class': 'td' }, user.tx), + E('div', { 'class': 'td' }, user.rx), + E('div', { 'class': 'td' }, E('button', { 'class': 'cbi-button cbi-button-remove', 'click': L.bind(this.handleDisconnect, this, user.id) @@ -151,9 +131,6 @@ return baseclass.extend({ } } - return E('div', { 'class': 'cbi-section' }, [ - E('legend', _('Active OpenConnect Users')), - table - ]); + return table; } });