feat(mqtt-bridge): mirror dashboard for MQTT Bridge sources#3143
Conversation
Adds an "Open" button to mqtt_bridge cards on the source list and routes to a read-only mirror of the Meshtastic dashboard. Bridges ingest packets from upstream but have no transmit path, so every surface that would call out to the mesh is suppressed: - Sidebar: hide Device Configuration, Automation, Remote Administration - Channels: hide send composer + the `Show MQTT messages` toggle (every packet a bridge ingests has viaMqtt=true, so the filter would always blank the list — also relax the per-channel permission filter so slots outside 0-7 surface, since bridges see arbitrary slot indices) - Messages: hide DM message log + send composer (telemetry block remains), hide the four top action buttons (Traceroute / Exchange Node Info / Exchange Position / Request Neighbor Info) and the matching items in the DM Actions dropdown (Traceroute, Exchange Position, Exchange Node Info, Request Telemetry, Scan for Admin). Traceroute History remains since it's a read-only view. - AppHeader: hide the node-info slot so the env-default Meshtastic IP doesn't leak in as a fallback when the bridge has no local device. Server side, MqttBridgeManager now exposes the Meshtastic-shaped methods the consolidated /api/poll + /api/connection routes call through resolveSourceManager (getConnectionStatus, getAllNodesAsync, getDeviceConfig, getDeviceNodeNums, getSecurityKeys). Without these the endpoints 500'd with `TypeError: ... is not a function` and the whole dashboard stayed blank. mapDbNodeToDeviceInfo + loadAllNodesAsDeviceInfo are extracted to src/server/utils/dbNodeMapper.ts so both managers share the projection. SourceContext now carries sourceType so App.tsx can derive isMqttBridge and thread mqttReadOnly through Sidebar / ChannelsTab / MessagesTab / AppHeader. Tab-permission gates also check !isMqttBridge so URL-hash navigation to #configuration / #admin / #automation redirects out. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Code Review Complete ✅I've analyzed this MQTT Bridge dashboard PR and found it to be well-implemented with good adherence to the project's architecture. Here's my comprehensive review: StrengthsArchitecture & Design
API Design
UI Implementation
Issues & RecommendationsSecurity & Edge Cases
Performance Concerns
Code Quality
Minor Suggestions
Test Plan ValidationThe test plan looks comprehensive and covers the key scenarios. I'd add:
Overall AssessmentThis is a solid implementation that successfully extends MeshMonitor's multi-source architecture to support read-only MQTT bridge dashboards. The code follows project conventions well and the UI gating is comprehensive. With the security validation fix and test coverage additions, this will be ready for production. Recommendation: Approve with minor fixes ✅ |
…ish (#3145) Version bump and CHANGELOG entry for 4.6.5. Highlights: - #3143 MQTT Bridge mirror dashboard (read-only Open button on bridge cards; suppresses every TX surface; MqttBridgeManager now exposes the Meshtastic-shaped methods the consolidated /api/poll + /api/connection endpoints expect). - #3142 MeshCore Telemetry dashboard tab via source-agnostic Dashboard. - #3141 MeshCore: preserve LPP channel byte in remote telemetry rows. - #3140 DM: skip PKI flag when keyMismatchDetected. - #3138 docs reorganization. - #3137 unified: merge nodes across sources so labels show in the unified Nodes view. - #3136 mqtt: allow standalone mqtt_bridge as client-proxy target. CLAUDE.md version line updated to 4.6.5. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
mqtt_bridgecards on the source list and routes to a read-only mirror of the Meshtastic dashboard. The mirror suppresses every surface that would call out to the mesh — bridges only ingest, they don't transmit./api/polland/api/connectionwhen the active manager is anMqttBridgeManager— previously those endpoints called Meshtastic-specific methods on the manager unconditionally, leaving bridge dashboards blank.UI changes (gated by
mqttReadOnly/isMqttBridge)viaMqtt:true, so the filter would always blank the list). Per-channel permission filter is relaxed so slots outside0-7surface in the picker — bridges routinely see arbitrary slot indices from upstream nodes with custom configs.Server changes
MqttBridgeManagernow exposes the Meshtastic-shaped methods the consolidated/api/poll+/api/connectionroutes call throughresolveSourceManager:getConnectionStatus,getAllNodesAsync,getDeviceConfig(null),getDeviceNodeNums(empty),getSecurityKeys(nulls).mapDbNodeToDeviceInfo+ a newloadAllNodesAsDeviceInfo(sourceId)are extracted intosrc/server/utils/dbNodeMapper.tsso both managers share the projection.Plumbing
SourceContextnow carriessourceTypesoApp.tsxcan deriveisMqttBridgeand threadmqttReadOnlythrough Sidebar / ChannelsTab / MessagesTab / AppHeader.!isMqttBridgeso URL-hash navigation to#configuration/#admin/#automationredirects out.Test plan
curl /api/connection?sourceId=<bridge>and/api/poll?sourceId=<bridge>both return200.🤖 Generated with Claude Code