Summary
When bearer auth is enabled (RUVIEW_API_TOKEN set, #443), the Live Demo tab can never connect: its pose stream lives at /api/v1/stream/pose, which falls under the protected /api/v1/* prefix — but the browser WebSocket constructor cannot attach an Authorization header to the upgrade request. The UI shows:
Failed to start: WebSocket connection failed: Unknown error
/ws/sensing was already deliberately exempted for exactly this reason (see the module docs in bearer_auth.rs: "/ws/sensing and /ui/* are served to local browsers that can't easily inject headers"). The same reasoning applies to /api/v1/stream/pose, which was presumably missed because it sits inside the protected prefix.
Repro
docker run -e RUVIEW_API_TOKEN=<token> ... ruvnet/wifi-densepose:latest
- Open the UI, go to Live Demo → connection fails with the error above; server returns
401 on the WS upgrade.
Fix (verified locally, happy to send a PR)
v2/crates/wifi-densepose-sensing-server/src/bearer_auth.rs: add a narrow exempt-path list checked alongside the prefix:
const EXEMPT_PATHS: &[&str] = &["/api/v1/stream/pose"];
...
if !path.starts_with(PROTECTED_PREFIX) || EXEMPT_PATHS.contains(&path) {
return next.run(request).await;
}
plus a regression test asserting the pose stream stays reachable without a token while other /api/v1/* paths remain 401. (Deliberately not a query-string token — the existing CWE-598 regression test correctly forbids that channel.)
Related UI gap (mention or split as preferred)
Even for plain REST, the bundled UI has no way to supply the token: ui/services/api.service.js has setAuthToken(), but nothing ever calls it and there is no settings field for it — so enabling RUVIEW_API_TOKEN currently breaks the entire dashboard (constant HTTP 401 on /api/v1/*). We added a "API Access" token field to the QuickSettings panel (stores in localStorage, applies before first request) and can include that in the PR too.
Summary
When bearer auth is enabled (
RUVIEW_API_TOKENset, #443), the Live Demo tab can never connect: its pose stream lives at/api/v1/stream/pose, which falls under the protected/api/v1/*prefix — but the browserWebSocketconstructor cannot attach anAuthorizationheader to the upgrade request. The UI shows:/ws/sensingwas already deliberately exempted for exactly this reason (see the module docs inbearer_auth.rs: "/ws/sensingand/ui/*are served to local browsers that can't easily inject headers"). The same reasoning applies to/api/v1/stream/pose, which was presumably missed because it sits inside the protected prefix.Repro
docker run -e RUVIEW_API_TOKEN=<token> ... ruvnet/wifi-densepose:latest401on the WS upgrade.Fix (verified locally, happy to send a PR)
v2/crates/wifi-densepose-sensing-server/src/bearer_auth.rs: add a narrow exempt-path list checked alongside the prefix:plus a regression test asserting the pose stream stays reachable without a token while other
/api/v1/*paths remain 401. (Deliberately not a query-string token — the existing CWE-598 regression test correctly forbids that channel.)Related UI gap (mention or split as preferred)
Even for plain REST, the bundled UI has no way to supply the token:
ui/services/api.service.jshassetAuthToken(), but nothing ever calls it and there is no settings field for it — so enablingRUVIEW_API_TOKENcurrently breaks the entire dashboard (constantHTTP 401on/api/v1/*). We added a "API Access" token field to the QuickSettings panel (stores inlocalStorage, applies before first request) and can include that in the PR too.