Bug bash 2026-09-19: 17 bugs fixed and verified (BUGS.md)
Widgets: a bad pattern no longer silences every widget; malformed layouts load. Shell: lost session returns to login at once; tab titles; Escape closes menus and dialogs. Files: names are one path segment; unsaved edits ask before page/machine/tab changes; only folders that opened are remembered. Terminals: unique default names; 64-char names. API: queries capped at 10 000 values; 32 streams per client, 512 in all; only /embed/widget is frameable. ZFS sensors: one unprivileged zpool list, no sudo journal spam. Phone: 36 px inputs; dataset rows as wide as their cells. Machines: valid name pattern. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
36de4ad4a1
commit
8ee2a2d293
@@ -111,3 +111,94 @@ rejected. Duplicate machine add refused. Unicode + spaces in file names round-tr
|
||||
Upload byte-exact. Terminal scrollback survives switching. Offline node: switcher and
|
||||
header show it, pages show the reason. Remote terminals, logs, tasks and files through
|
||||
the proxy all work on all three nodes.
|
||||
|
||||
|
||||
# Bug bash — 2026-09-19
|
||||
|
||||
Found by driving a scratch instance (same binary, its own state, real fleet behind it) in
|
||||
headless Chromium at 1440 px and iPhone size: a sweep of every page on every machine for
|
||||
page errors, failed requests, overflow and small tap targets; then scripted use of every
|
||||
feature — terminal tabs, Files in a throwaway folder, Processes (killing a process the
|
||||
test spawned), Monitors customisation and widgets, Services, Cron, Updates, Disks,
|
||||
Machines, Settings, embeds, machine switching, session loss — and a hostile pass over the
|
||||
API. Host-changing actions (service control, cron edits, upgrades, power) were opened but
|
||||
not executed. Every fix below was re-checked by the same script that found it.
|
||||
|
||||
## Bugs — all ✅ fixed and verified
|
||||
|
||||
1. ✅ **One widget with a bad pattern silenced every custom widget.** They share one stream;
|
||||
`fan.[` made the whole query a 400, so all of them showed "…" forever with no reason
|
||||
given. The picker now asks the API before adding and shows its answer; a bad pattern
|
||||
already saved shows a notice instead of dots.
|
||||
2. ✅ **A saved layout of the wrong shape could not be loaded** ("could not load layout",
|
||||
and the page could no longer be customised). `normalize()` now accepts anything.
|
||||
3. ✅ **A lost session left pages saying "unauthenticated"** for up to 30 s. A 401 from the hub
|
||||
now returns to the login form at once, and logging in returns to the same page. (A 401
|
||||
relayed from a managed machine is that machine rejecting the hub, and doesn't.)
|
||||
4. ✅ **The machine-name rule in "Add a machine" was an invalid regular expression** under the
|
||||
browser's `v` mode, so it validated nothing and logged a console error on every render.
|
||||
5. ✅ **Two terminals opened in the same minute got the same name** ("shell 09:45" twice).
|
||||
Now "shell 09:45 (2)".
|
||||
6. ✅ **Names had no length limit** — a 328-character terminal tab, a 5000-character token
|
||||
name. 64 characters, refused with a reason; token names also refuse `/ \ < > "`.
|
||||
7. ✅ **"+ file", "+ folder" and Rename accepted `../x` and `a/b`**, quietly acting outside the
|
||||
folder on screen. A name is now one path segment; Move… is how things go elsewhere.
|
||||
8. ✅ **Unsaved file edits were thrown away without a word** when you picked another page or
|
||||
machine, or closed the tab. All three now ask; Cancel keeps you where you were.
|
||||
9. ✅ **A mistyped path in Files was remembered**, so a reload landed on the error. Only a
|
||||
folder that opened is remembered.
|
||||
10. ✅ **Escape closed nothing**: the machine menu, the file menu, the Power dialog, the widget
|
||||
picker. It closes all four.
|
||||
11. ✅ **Reset on Monitors removed every custom widget with no confirmation.** It asks, and
|
||||
says how many.
|
||||
12. ✅ **A few bytes of query bought 27 MB of answer** (`{"k0":"*",…×400}` with `full=1`) — and a
|
||||
read-only token is public on the demo page. A query may return 10 000 values (thirty
|
||||
whole machines); past that it is a 400 that says so.
|
||||
13. ✅ **No ceiling on live streams**: 300 from one token were accepted. 32 per client address,
|
||||
512 in all, then a 429 that says so; closed streams free their places.
|
||||
14. ✅ **Anything under `/embed/` lost the anti-framing headers**, not just the widget page.
|
||||
Only `/embed/widget` is frameable.
|
||||
15. ✅ **The new ZFS sensors ran three `sudo` commands a minute on every machine** — including
|
||||
`core`, which has the tools and no pool — and each wrote three lines to the journal:
|
||||
most of `hamlab.service`'s log was that. Pools are now read with one unprivileged
|
||||
`zpool list`; a source that finds nothing is asked again ten times less often; and
|
||||
the installer's quiet list covers `zpool|zfs list|status`.
|
||||
16. ✅ **Phone: the filter boxes on Processes and Files, the path box and the "/" crumb were
|
||||
under 30 px.** 36 px like every other control.
|
||||
17. ✅ **Disks → datasets on a phone: rows ended 50 px before their own cells** when scrolled
|
||||
sideways (`min-width` was less than the columns add up to).
|
||||
|
||||
Also: tab titles now say where you are ("Services · grid — Ham Lab"), so history and open
|
||||
tabs can be told apart.
|
||||
|
||||
## Checked and fine
|
||||
|
||||
Terminal focus after every switch/close/return; scrollback after reload; exited shells;
|
||||
30 tabs with the + still reachable; re-fit on resize; Back/Forward; unknown machine or page
|
||||
in the URL; wrong password; XSS through terminal, token and file names (all rendered as
|
||||
text); hidden files, filter, symlinks (broken ones marked), binary files, upload and
|
||||
replace, folder delete needing the typed name, root toggle; process sort, filter and
|
||||
Terminate (asks first); themes; password-change validation; duplicate or unreachable
|
||||
machine; hub terminals not leaking into another machine's page; CORS only on sensor paths;
|
||||
token list never exposing hashes; cookie flags; deep nesting, empty bodies, odd methods
|
||||
and `every=` values on the sensor API; phone drawer, key bar and picker.
|
||||
|
||||
## Quality of life — noted, not done
|
||||
|
||||
- **Selections aren't in the URL.** Services, Cron and Disks forget what was selected on
|
||||
reload, and can't be linked to. `#/grid/services/nginx.service` would fix both.
|
||||
- **Browser Back with unsaved file edits** still leaves without asking (page and machine
|
||||
changes ask; Back needs the history entry put back on Cancel).
|
||||
- **Prompts are browser `prompt()`/`confirm()` boxes** — rename, new file, delete, token
|
||||
name. They work, and look nothing like the rest of the console, worst on a phone.
|
||||
- **Two step token creation** (name, then patterns) wants to be one small dialog, with the
|
||||
patterns pickable from the catalog like the widget picker.
|
||||
- **Widgets can't be edited**, only removed and re-added; no way to change a title or type.
|
||||
- **The Widgets gallery has no search**, and 300+ tiles on `grid` is a long scroll.
|
||||
- **A custom widget's sparkline starts empty for states and counts** (no history kept for
|
||||
the background status sensors — only the sampler's ring remembers).
|
||||
- **Embeds poll nothing while hidden but say nothing when the token is wrong** beyond
|
||||
"check the token"; a 401 and an unreachable host look the same.
|
||||
- **Default widget titles for patterns are the raw pattern** ("CPU.CORE.*.USAGE").
|
||||
- **Terminal tabs can't be reordered**, and there's no keyboard shortcut to switch.
|
||||
- **The hub's own session cookie is 30 days sliding with no "log out everywhere".**
|
||||
|
||||
Reference in New Issue
Block a user