Problem
Every other client-to-server call on `QtWebSocketBackend` (`registerModel`,
`registerModelShared`, `attachModel`, `assignPrimary`, `deregisterModel`) stamps
`env.session` on the outgoing envelope before sending — but `listInstances` did not.
Same gap in `morph::net::SocketBackend::listInstances`.
Effect: a `SigningAuthorizer`-gated `instances()` call always fails "unauthorized"
over Socket mode, since `RemoteServer`'s `"instances"` branch calls
`_authorizer->authorize(env.session, env.typeId, {})`, and `SigningAuthorizer::authorize`
verifies `ctx.token` — which was always empty/default on this one call path.
Verified real, not merely suspected: traced the full authorization chain
(`RemoteServer`'s dispatch → `SigningAuthorizer::authorize` → `TokenVerifier::verify`
failing on an empty token) and confirmed every sibling call site on both backends
does stamp the session while `listInstances` alone did not, on both:
- `src/qt/qt_websocket_backend.cpp` (`QtWebSocketBackend::listInstances`)
- `include/morph/net/socket_backend.hpp` (`SocketBackend::listInstances`)
Why this was latent, not already caught
Checked every rung in the tree: only `bank` and `bookmarks` call `.instances()` at
all. `bank` uses `LocalBackend` exclusively (no socket path — unaffected). `bookmarks`
uses `BookmarksAuthorizer` (`SigningAuthorizer`-derived) but never actually calls
`.instances()` anywhere (confirmed via grep — zero real call sites). `polls` calls
Socket-mode `.instances()` but uses `PollsAuthorizer`, which is `AllowAllAuthorizer`-
derived and ignores the session entirely — unaffected either way. Kanban (application
ladder rung 4, in progress) is the first rung to combine a verifying authorizer with
Socket-mode `instances()`, which is why this surfaced only now.
Fix (already applied on the in-progress `ladder-kanban-impl` branch)
One line per file, matching the exact pattern every sibling call site already uses:
`env.session = _session;` (Qt backend) / `env.session = currentSession();` (net backend),
added immediately after `::morph::wire::makeInstances(typeId)` and before encoding.
Verified this fix is a strict no-op for any `AllowAllAuthorizer`-derived rung (its
`authorize()` ignores `ctx` entirely), so it cannot regress `polls` or any other
existing rung's `instances()` usage.
Ask
Backport this one-line-per-file fix to `master` independently of the kanban rung's
own PR, since it's a framework correctness fix unrelated to kanban's app code — filing
now so it isn't lost inside a large rung-4 diff, and so other in-flight rungs can pick
it up without waiting on kanban's own review cycle.
Problem
Every other client-to-server call on `QtWebSocketBackend` (`registerModel`,
`registerModelShared`, `attachModel`, `assignPrimary`, `deregisterModel`) stamps
`env.session` on the outgoing envelope before sending — but `listInstances` did not.
Same gap in `morph::net::SocketBackend::listInstances`.
Effect: a `SigningAuthorizer`-gated `instances()` call always fails "unauthorized"
over Socket mode, since `RemoteServer`'s `"instances"` branch calls
`_authorizer->authorize(env.session, env.typeId, {})`, and `SigningAuthorizer::authorize`
verifies `ctx.token` — which was always empty/default on this one call path.
Verified real, not merely suspected: traced the full authorization chain
(`RemoteServer`'s dispatch → `SigningAuthorizer::authorize` → `TokenVerifier::verify`
failing on an empty token) and confirmed every sibling call site on both backends
does stamp the session while `listInstances` alone did not, on both:
Why this was latent, not already caught
Checked every rung in the tree: only `bank` and `bookmarks` call `.instances()` at
all. `bank` uses `LocalBackend` exclusively (no socket path — unaffected). `bookmarks`
uses `BookmarksAuthorizer` (`SigningAuthorizer`-derived) but never actually calls
`.instances()` anywhere (confirmed via grep — zero real call sites). `polls` calls
Socket-mode `.instances()` but uses `PollsAuthorizer`, which is `AllowAllAuthorizer`-
derived and ignores the session entirely — unaffected either way. Kanban (application
ladder rung 4, in progress) is the first rung to combine a verifying authorizer with
Socket-mode `instances()`, which is why this surfaced only now.
Fix (already applied on the in-progress `ladder-kanban-impl` branch)
One line per file, matching the exact pattern every sibling call site already uses:
`env.session = _session;` (Qt backend) / `env.session = currentSession();` (net backend),
added immediately after `::morph::wire::makeInstances(typeId)` and before encoding.
Verified this fix is a strict no-op for any `AllowAllAuthorizer`-derived rung (its
`authorize()` ignores `ctx` entirely), so it cannot regress `polls` or any other
existing rung's `instances()` usage.
Ask
Backport this one-line-per-file fix to `master` independently of the kanban rung's
own PR, since it's a framework correctness fix unrelated to kanban's app code — filing
now so it isn't lost inside a large rung-4 diff, and so other in-flight rungs can pick
it up without waiting on kanban's own review cycle.