fix: node WebSocket connection and UI connection string#382
fix: node WebSocket connection and UI connection string#382penso merged 5 commits intomoltis-org:mainfrom
Conversation
…ctions (moltis-org#381) Add /ws as a public WebSocket endpoint so remote nodes can connect using device-token authentication at the WebSocket protocol layer. - Register /ws route in both build_gateway_base variants - Add /ws to is_public_path() in auth_middleware - Add test verifying /ws bypasses auth middleware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…oltis-org#380) - Use location.host instead of gon.get('port') + location.hostname for the WebSocket URL, matching the pattern used by all other pages (ws-connect.js, page-settings.js, page-terminal.js) - Change generated command from 'moltis node run' to 'moltis node add' to match the actual CLI subcommand - Remove unused gon import
Greptile SummaryThis PR fixes two independent bugs: a node WebSocket connectivity regression where Key changes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant NodeClient as Node Client
participant Middleware as auth_gate Middleware
participant Handler as ws_upgrade_handler
participant Connection as handle_connection
Note over NodeClient,Connection: Before fix
NodeClient->>Middleware: GET /ws (WebSocket Upgrade)
Middleware->>Middleware: is_public_path /ws = false
Middleware-->>NodeClient: 303 Redirect to /login
Note over NodeClient,Connection: After fix
NodeClient->>Middleware: GET /ws (WebSocket Upgrade)
Middleware->>Middleware: is_public_path /ws = true
Middleware->>Handler: pass through
Handler->>Handler: websocket_header_authenticated
Handler->>Connection: header_authenticated = false
Connection->>Connection: verify device_token in WS handshake
Connection-->>NodeClient: HelloOk
Note over NodeClient,Connection: /ws/chat (browser) unchanged
participant Browser as Browser UI
Browser->>Middleware: GET /ws/chat (session cookie)
Middleware->>Middleware: check_auth = Allowed
Middleware->>Handler: pass through
Handler->>Connection: header_authenticated = true
Connection-->>Browser: HelloOk
|
Update authentication.md and security.md to document the new /ws endpoint as a public path (device token auth at WebSocket protocol level) and include it in the rate-limiting tables alongside /ws/chat.
Add NodeAction::Run that reads connection config from node.json (written by 'moltis node add') and launches the node host. This is the command invoked by the generated launchd plist / systemd unit. Also simplify generated service files to just 'moltis node run' instead of passing all connection args inline — config comes from node.json.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Signed-off-by: Fabien Penso <github@pen.so>
* fix(gateway): add /ws route and bypass auth middleware for node connections (#381) Add /ws as a public WebSocket endpoint so remote nodes can connect using device-token authentication at the WebSocket protocol layer. - Register /ws route in both build_gateway_base variants - Add /ws to is_public_path() in auth_middleware - Add test verifying /ws bypasses auth middleware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(web): correct node connection string and command in nodes page (#380) - Use location.host instead of gon.get('port') + location.hostname for the WebSocket URL, matching the pattern used by all other pages (ws-connect.js, page-settings.js, page-terminal.js) - Change generated command from 'moltis node run' to 'moltis node add' to match the actual CLI subcommand - Remove unused gon import * docs: add /ws to public paths and rate-limiting tables Update authentication.md and security.md to document the new /ws endpoint as a public path (device token auth at WebSocket protocol level) and include it in the rate-limiting tables alongside /ws/chat. * feat(node): add 'moltis node run' subcommand (#381) Add NodeAction::Run that reads connection config from node.json (written by 'moltis node add') and launches the node host. This is the command invoked by the generated launchd plist / systemd unit. Also simplify generated service files to just 'moltis node run' instead of passing all connection args inline — config comes from node.json. * Update crates/gateway/tests/auth_middleware.rs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Signed-off-by: Fabien Penso <github@pen.so> --------- Signed-off-by: Fabien Penso <github@pen.so> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Junle Li <nickleli@gmail.com> Co-authored-by: Fabien Penso <github@pen.so> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix(gateway): add /ws route and bypass auth middleware for node connections (moltis-org#381) Add /ws as a public WebSocket endpoint so remote nodes can connect using device-token authentication at the WebSocket protocol layer. - Register /ws route in both build_gateway_base variants - Add /ws to is_public_path() in auth_middleware - Add test verifying /ws bypasses auth middleware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(web): correct node connection string and command in nodes page (moltis-org#380) - Use location.host instead of gon.get('port') + location.hostname for the WebSocket URL, matching the pattern used by all other pages (ws-connect.js, page-settings.js, page-terminal.js) - Change generated command from 'moltis node run' to 'moltis node add' to match the actual CLI subcommand - Remove unused gon import * docs: add /ws to public paths and rate-limiting tables Update authentication.md and security.md to document the new /ws endpoint as a public path (device token auth at WebSocket protocol level) and include it in the rate-limiting tables alongside /ws/chat. * feat(node): add 'moltis node run' subcommand (moltis-org#381) Add NodeAction::Run that reads connection config from node.json (written by 'moltis node add') and launches the node host. This is the command invoked by the generated launchd plist / systemd unit. Also simplify generated service files to just 'moltis node run' instead of passing all connection args inline — config comes from node.json. * Update crates/gateway/tests/auth_middleware.rs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Signed-off-by: Fabien Penso <github@pen.so> --------- Signed-off-by: Fabien Penso <github@pen.so> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Junle Li <nickleli@gmail.com> Co-authored-by: Fabien Penso <github@pen.so> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Fixes #380 and #381
Changes
1. Add
/wsroute for node connections (#381)Node client (
runner.rs) connects to/ws, but gateway only registers/ws/chat. Auth middleware intercepts the request and returns 303 redirect to/login— the WebSocket upgrade never happens.The WebSocket handler (
ws.rslines 148–165) already supports device-token auth at the protocol level, but gets blocked at the HTTP middleware layer.Fix: Register
/wsroute pointing to the samews_upgrade_handlerand add it tois_public_path(). Includes test verifying/wsbypasses auth.2. Fix UI connection string (#380)
Nodes settings page (
page-nodes.js) usesgon.get("port")(server bind port) +location.hostnameto construct the WebSocket URL. Behind a reverse proxy, this produces unreachable URLs likewss://hostname:38309/ws.Every other WebSocket page (
ws-connect.js,page-settings.js,page-terminal.js) correctly useslocation.host.Also: the generated shell command said
moltis node runbut the CLI subcommand ismoltis node add.Fix: Use
location.host(consistent with all other pages), fix command tonode add, remove unusedgonimport.3. Update docs
Add
/wsto the public paths table inauthentication.md(with note about device-token auth at protocol level) and to the rate-limiting table insecurity.md.4. Add
moltis node runsubcommand (#381)moltis node addsaves config tonode.jsonand generates a service file (launchd plist / systemd unit) that invokesmoltis node run. But therunsubcommand did not exist — the generated service file would fail.Fix: Add
NodeAction::Runthat reads gateway URL and credentials fromnode.jsonand starts the node connection. Also simplify the generated plist/systemd files to usenode runinstead of embedding all connection args inline.