Skip to content

v0.5.52

Choose a tag to compare

@github-actions github-actions released this 04 Aug 11:39

Data cleanup, DHCP lease filtering, a readable light theme

Housekeeping release. You can now delete stored history on demand instead of waiting for retention to catch up, filter DHCP leases by VLAN, and actually read the light theme.

Three of the fixes below were found while building the features rather than reported, and two of them were silently wrong in ways nobody would have noticed: VACUUM never reclaimed a single byte, and every recorded outage was shorter than the real one.

Added

  • Data Cleanup (src/db.js, src/index.js, Settings → Data Cleanup). Delete stored history on demand, scoped three ways: one router or all, by data type (traffic, ping, bandwidth, alerts and connectivity), and by age (1, 7, 30, 90, 365 days, or everything). The card shows current database size, total rows and a per-router breakdown, and a Preview tells you exactly how many rows a selection would remove before you commit to it — the preview runs the same predicate as the delete, so the two cannot disagree. The database is compacted afterwards so the space is genuinely returned to disk. Admin only, and a restricted admin cannot run a global purge, because that would delete history for routers they cannot see. Closes #77
  • DHCP lease filtering (src/collectors/dhcpLeases.js, DHCP page). Filter the lease table by DHCP server, with the interface and VLAN shown as context on each option, for example IoT DHCP · IoT · VLAN 10 (27). The issue asked for three separate filters — interface, server and VLAN — but on a real configuration they are the same axis: a DHCP server binds to exactly one interface and that interface is the VLAN, so all three select an identical set. One control covers all three. It composes with the existing text search, so you can search within a single VLAN. Leases now carry their server, interface and VLAN, joined from /ip/dhcp-server and /interface/vlan. Closes #65
  • Redesigned router picker (public/index.html, public/app.js). The topbar <select> is replaced by a popover listing each router with its host and a live status dot, so you can see what is online before switching rather than after. The active router carries a check mark, and a search box appears once you have five or more routers, matching on both label and host. Full keyboard support and ARIA listbox semantics. The mobile nav deliberately keeps its native select, because the OS picker is the better control on touch. Closes #72

Fixed

  • The light theme failed WCAG AA everywhere (public/index.html, public/app.js). All nine light palettes failed on muted text, between 1.65:1 and 2.97:1 against a 4.5:1 requirement, and cards barely separated from the page behind them at 1.06:1 to 1.16:1. Solarized also failed on main body text at 3.45:1. Muted text is now opaque and lands near 4.8:1 in every palette, main text is at least 8:1, borders reach about 1.9:1, and page backgrounds are darkened a step so cards read as cards. The default light palette was additionally inheriting dark-mode accent colours, which is why the version badge and tagline washed out. Dark mode is untouched. Closes #71
  • VACUUM reclaimed nothing (src/db.js). MikroDash runs SQLite in WAL mode, so the pages freed by a delete sit in the write-ahead log until a checkpoint — leaving VACUUM with nothing to compact and the file on disk exactly as large as before. Measured directly: 925,696 bytes before, unchanged after VACUUM, then 8,192 bytes once a wal_checkpoint(TRUNCATE) ran first. This also means the existing daily retention prune would never have returned space to the filesystem once it started firing
  • Every outage was reported shorter than it was (src/db.js, src/db-writer.js, src/index.js, src/alertSessions.js). MikroDash waits connDownThresholdSec (30 seconds by default) before declaring a router down, so a brief blip is not logged as an outage. That part is correct. The mistake was writing the database row only when that timer expired, while the insert stamped the current time itself — so the stored timestamp was when the outage was declared, not when the router actually dropped. Since downtime is measured by pairing offline and online events, every outage came out short by the threshold: about 5% error on a ten-minute outage, 67% on a 45-second one. Existing records keep their original timestamps. Closes #99
  • An idle tab sat on an empty dashboard instead of returning you to the login page (public/app.js). Once a session was gone — expired, or wiped by a container restart, since sessions are held in memory — the Socket.IO handshake was refused with a 401 and the client retried it silently forever. All three existing redirect paths were structurally unable to fire in that state: the session check lived inside the connect handler and so needed the very connection being refused, the expiry event needs a live socket, and the 401 interceptor only wraps fetch while Socket.IO polls over XMLHttpRequest. A connect_error handler now confirms with the server before redirecting, so a genuinely dead session sends you to the login page while a transient outage leaves you where you are
  • The lease list dropped fields on first connect (src/index.js). Initial state rebuilt the DHCP lease payload by hand instead of replaying the collector's own, which silently discarded any field the collector added — the new server summary among them

Changed

  • The About tab's License card is replaced by a green MIT License label on the header card, linking to the repository licence. The full MIT grant, copyright notice and warranty paragraphs were quoted inline; a link says the same thing without the wall of text. The MikroTik trademark disclaimer stays, because it is doing real protective work for a third-party project using those names. Closes #74
  • The Sign In button now uses Inter 700. It asked for weight 700 but Syne ships only 400, 600 and 800, so the browser rounded up to 800 and rendered heavy and cramped for a UI control
  • Dependency updates: geoip-lite 2.0.3, express-rate-limit 8.6.1, ip-address 10.4.0 (#100). geoip-lite 2.x declares Node 24 while the image is built on Node 20; verified before merging that it installs, loads and looks up correctly on Node 20, that the full suite passes, and that the app boots with live geo lookups working. Geo data is fresher as a result. Tracked in #101