Peering admin menu item is inert — clicking it opens nothing #131
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#131
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Reported by Nikola, v0.4.3 dogfood. Signed in as admin, the avatar menu shows "Peering" between Settings and License. Clicking it does nothing — no dialog, no view, no error.
This is the admin surface from #101/#120 (
PeeringAPI— issue keys, register peers, allow-lists). The end-user send UI (#105) works and is separate; this is the operator side, where a peering actually gets configured. Without it, peering cannot be set up through the UI at all, which also blocks #106.Investigating now: the menu item
um-peeringexists in the markup and is un-hidden onfeat.lic(it shares the license gate), but it may have no click handler, or a handler that references a dialog/view that was never built. #120 is titled "completes #101 — Settings panel", so the question is whether the panel was ever wired to this button.Fix lands in this issue once the cause is confirmed.
Root cause — confirmed by static analysis
A
ReferenceErrorfrom a guard that doesn't guard. The click handler:closeUserMenuis never declared — it appears at this one call site and nowhere else. Every sibling handler usescloseMenus()(defined line 1262).The trap:
closeUserMenu && …looks defensive, but&&only short-circuits a declared falsy value. Referencing an undeclared identifier throwsReferenceError: closeUserMenu is not definedthe instant the arrow function runs.openPeeringDialog()is never reached. No dialog, console-only error — precisely the reported symptom.Everything else is fine: the
peerdlgmarkup, allpeerdlg-*ids,peerRefresh(line 1704),openPeeringDialog(1797) — all present, and both<script>blocks parse clean. The handler was simply written by hand in a way that diverged from the codebase'scloseMenus()convention, and the divergence is the bug.A second bug in the same two lines: wrong visibility gate
Peering visibility is gated on the license feature. That is wrong both ways:
feat.lic === false, so the button is hidden and they cannot configure peering through the UI at all./api/v1/admin/peering/*, whichPeeringAPI.gaterefuses with 403.The admin API is admin-gated server-side, so the button should mirror
um-settings:!(me && me.admin).The fix
Primary (closes the reported symptom):
closeUserMenu && closeUserMenu()→closeMenus(). Obvious, no alternatives — it just adopts the existing convention.Gate:
!feat.lic→!(me && me.admin). Also fairly obvious (mirror Settings).One design choice for you — the gate has a subtlety worth a decision
On the dogfood,
peering.statePathis not set in config.json, soapiH.Peeringis nil and the/api/v1/admin/peering/*routes don't exist. So even after both fixes, an admin clicking Peering here would open the dialog and then seepeerRefreshfail (404), because the peering subsystem isn't enabled server-side.statePathis a deploy-time prerequisite — the admin UI configures within it, it can't create it.Two ways to handle that:
me.admin). Simplest. The button shows for any admin; if peering isn't configured, the dialog opens but reports it can't load. Honest but slightly ugly on an unconfigured instance./api/v1/admin/peering/peers(200 = mounted, 404 = not), the same pattern the send UI already uses forfeat.peerSend. The button then only appears oncestatePathis set, so it never opens a dialog that can't work.I'll ship A now, because it fixes the reported bug and is correct for the configured case, and B is a refinement rather than a correction. If you'd rather have B (button hidden until peering is actually enabled), say so and I'll add the probe — it's ~5 lines and mirrors code that already exists.
Fixed in PR #132, merged. Shipping in v0.4.4 so it reaches the dogfood.
Both lines corrected: the
closeUserMenuReferenceError →closeMenus(), and the!feat.licgate →!(me && me.admin).Reminder for verification: the button will now respond, but on the dogfood the dialog opens onto an empty/erroring panel because
peering.statePathis unset — the peering subsystem isn't enabled server-side yet. That is the next step (settingstatePath, which is #106's setup), not a regression. The button working and the dialog opening is what this issue was about.Option B from my diagnosis (hide the button until peering is actually configured) remains open for your call.