luci-mod-status: correctness fixes

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
This commit is contained in:
Paul Donald
2026-05-26 17:26:30 +03:00
parent 2708c78089
commit 0b9e8b4f52
7 changed files with 25 additions and 16 deletions
@@ -237,6 +237,7 @@ return view.extend({
local_wifi.signal = -10; local_wifi.signal = -10;
local_wifi.ssid = 'Local Interface'; local_wifi.ssid = 'Local Interface';
q = Math.min((local_wifi.signal + 110) / 70 * 100, 100);
this.add_wifi_to_graph(chan_analysis, local_wifi, scanCache, center_channels, chan_width); this.add_wifi_to_graph(chan_analysis, local_wifi, scanCache, center_channels, chan_width);
rows.push([ rows.push([
@@ -258,8 +259,8 @@ return view.extend({
results.push(scanCache[k].data); results.push(scanCache[k].data);
results.sort(function(a, b) { results.sort(function(a, b) {
if (a.channel - b.channel) if (a.channel !== b.channel)
return 1; return a.channel - b.channel;
if (a.ssid < b.ssid) if (a.ssid < b.ssid)
return -1; return -1;
@@ -270,6 +271,8 @@ return view.extend({
return -1; return -1;
else if (a.bssid > b.bssid) else if (a.bssid > b.bssid)
return 1; return 1;
return 0;
}); });
for (let res of results) { for (let res of results) {
@@ -39,6 +39,7 @@ return view.extend({
return fs.exec_direct('/bin/dmesg', [ '-r' ]).then(logdata => { return fs.exec_direct('/bin/dmesg', [ '-r' ]).then(logdata => {
let loglines = []; let loglines = [];
let lastSeverity = null; let lastSeverity = null;
let lastTime = null;
logdata.trim().split(/\n/).forEach(line => { logdata.trim().split(/\n/).forEach(line => {
const priorityMatch = line.match(/^<(\w+)>/); const priorityMatch = line.match(/^<(\w+)>/);
@@ -49,6 +50,8 @@ return view.extend({
const cleanLine = line.replace(/^<\w+>/, ''); const cleanLine = line.replace(/^<\w+>/, '');
const timeMatch = cleanLine.match(/^\[\s*(\d+(?:\.\d+)?)\]/); const timeMatch = cleanLine.match(/^\[\s*(\d+(?:\.\d+)?)\]/);
const time = timeMatch ? parseFloat(timeMatch[1]) : null; const time = timeMatch ? parseFloat(timeMatch[1]) : null;
if (time != null)
lastTime = time;
if (!isCont) { if (!isCont) {
lastSeverity = parseInt(tag, 10); // update severity lastSeverity = parseInt(tag, 10); // update severity
@@ -57,7 +60,7 @@ return view.extend({
loglines.push({ loglines.push({
severity: isCont ? lastSeverity : parseInt(tag, 10), severity: isCont ? lastSeverity : parseInt(tag, 10),
isCont, isCont,
time, time: time != null ? time : lastTime,
text: cleanLine text: cleanLine
}); });
}); });
@@ -84,12 +87,10 @@ return view.extend({
// Filter by severity // Filter by severity
loglines = loglines.filter(entry => { loglines = loglines.filter(entry => {
if (!entry.isCont) { if (this.invertMinSeverity)
if (!this.invertMinSeverity) return entry.severity < this.minSeverity;
return (entry.severity >= this.minSeverity); else
else return entry.severity >= this.minSeverity;
return (entry.severity < this.minSeverity);
}
}); });
// Filter by text // Filter by text
@@ -69,7 +69,7 @@ function renderbox(ifc, ipv6, dhcpv6_stats) {
E('div', {}, renderBadge( E('div', {}, renderBadge(
L.resource('icons/%s.svg').format(dev ? dev.getType() : 'ethernet_disabled'), null, L.resource('icons/%s.svg').format(dev ? dev.getType() : 'ethernet_disabled'), null,
_('Device'), dev ? dev.getI18n() : '-', _('Device'), dev ? dev.getI18n() : '-',
_('MAC address'), dev.getMAC()) _('MAC address'), dev ? dev.getMAC() : '')
) )
]) ])
]); ]);
@@ -88,6 +88,9 @@ return baseclass.extend({
return E('em', _('No active leases found')); return E('em', _('No active leases found'));
const machints = host_hints.getMACHints(false); const machints = host_hints.getMACHints(false);
const isReadonlyView = !L.hasViewPermission(); const isReadonlyView = !L.hasViewPermission();
this.isMACStatic = Object.create(null);
this.isDUIDStatic = Object.create(null);
this.isDUIDIAIDStatic = Object.create(null);
for (const host of uci.sections('dhcp', 'host')) { for (const host of uci.sections('dhcp', 'host')) {
@@ -205,7 +205,7 @@ return baseclass.extend({
for (let i = 0; i < radios_networks_hints.length; i++) { for (let i = 0; i < radios_networks_hints.length; i++) {
tasks.push(L.resolveDefault(radios_networks_hints[i].getAssocList(), []).then(L.bind((net, list) => { tasks.push(L.resolveDefault(radios_networks_hints[i].getAssocList(), []).then(L.bind((net, list) => {
net.assoclist = list.sort((a, b) => { return a.mac > b.mac }); net.assoclist = list.sort((a, b) => a.mac.localeCompare(b.mac));
}, this, radios_networks_hints[i]))); }, this, radios_networks_hints[i])));
if (hasWPS && uci.get('wireless', radios_networks_hints[i].sid, 'wps_pushbutton') == '1') { if (hasWPS && uci.get('wireless', radios_networks_hints[i].sid, 'wps_pushbutton') == '1') {
@@ -233,7 +233,7 @@ return baseclass.extend({
const table = E('div', { 'class': 'network-status-table' }); const table = E('div', { 'class': 'network-status-table' });
for (let i = 0; i < radios.sort((a, b) => { a.getName() > b.getName() }).length; i++) for (let i = 0; i < radios.sort((a, b) => a.getName().localeCompare(b.getName())).length; i++)
table.appendChild(this.renderbox(radios[i], table.appendChild(this.renderbox(radios[i],
networks.filter(net => { return net.getWifiDeviceName() == radios[i].getName() }))); networks.filter(net => { return net.getWifiDeviceName() == radios[i].getName() })));
@@ -66,6 +66,7 @@ return view.extend({
const cmp_addr = address || target; const cmp_addr = address || target;
if (!cmp_addr) continue; if (!cmp_addr) continue;
if (typeof cmp_mask !== 'number') continue;
if (applyMask(cmp_addr, cmp_mask, v6) !== applyMask(addr, cmp_mask, v6) || mask < cmp_mask) if (applyMask(cmp_addr, cmp_mask, v6) !== applyMask(addr, cmp_mask, v6) || mask < cmp_mask)
continue; continue;
@@ -85,7 +86,7 @@ return view.extend({
const res = []; const res = [];
for (const line of nbs.trim().split(/\n/)) { for (const line of nbs.trim().split(/\n/)) {
const [, addr = null, f = [], state = null] = line.match(/^([0-9a-f:.]+) (.+) (\S+) *$/); const [, addr = null, f = [], state = null] = (line.match(/^([0-9a-f:.]+) (.+) (\S+) *$/) || []);
const flags = f?.trim?.().split?.(/\s+/); const flags = f?.trim?.().split?.(/\s+/);
let vendor; let vendor;
@@ -120,7 +121,7 @@ return view.extend({
const res = []; const res = [];
for (const line of routes.trim().split(/\n/)) { for (const line of routes.trim().split(/\n/)) {
const [, type = 'unicast', d, f = [] ] = line.match(/^(?:([a-z_]+|\d+) )?(default|[0-9a-f:./]+) (.+)$/); const [, type = 'unicast', d, f = [] ] = (line.match(/^(?:([a-z_]+|\d+) )?(default|[0-9a-f:./]+) (.+)$/) || []);
const dest = d == 'default' ? (v6 ? '::/0' : '0.0.0.0/0') : d; const dest = d == 'default' ? (v6 ? '::/0' : '0.0.0.0/0') : d;
const flags = f?.trim?.().split?.(/\s+/); const flags = f?.trim?.().split?.(/\s+/);
@@ -67,6 +67,7 @@ return view.extend({
const cmp_addr = address || target; const cmp_addr = address || target;
if (!cmp_addr) continue; if (!cmp_addr) continue;
if (typeof cmp_mask !== 'number') continue;
if (applyMask(cmp_addr, cmp_mask, v6) !== applyMask(addr, cmp_mask, v6) || mask < cmp_mask) if (applyMask(cmp_addr, cmp_mask, v6) !== applyMask(addr, cmp_mask, v6) || mask < cmp_mask)
continue; continue;
@@ -94,10 +95,10 @@ return view.extend({
for (const n of this.parseJSON(nbs)) { for (const n of this.parseJSON(nbs)) {
let vendor; let vendor;
if (n.dst.match(/^fe[89a-f][0-9a-f]:/)) if (n.dst?.match(/^fe[89a-f][0-9a-f]:/))
continue; continue;
if (n.state.find(f => {return f == 'FAILED'})) if ((n.state || []).some(f => f === 'FAILED'))
continue; continue;
for (let mac in macs) { for (let mac in macs) {