switch off Vaultwarden's routers, pending extraction into a plugin

Same treatment as the browser relay: mounts commented, code left on disk. Its
tables were already commented out of the schema earlier tonight, which is what
made this necessary — /api/vault was mounted against tables db:push no longer
creates, so a fresh core install shipped an endpoint that could only fail with a
Postgres "relation does not exist".

Vaultwarden is not one mount. Eight places had to go, and grepping for `vault`
found them only because several are not named after a router:

  hono.ts   /api/vault                      the authenticated reverse-proxy
            /vaultwarden                    the unauthenticated one for the browser extension
            VAULT_ONLY_PREFIXES loop        /identity, /notifications, /icons, /events
            the isBitwardenClient diverter  an /api/* middleware that hands Bitwarden
                                            clients to the vault router before anything else sees them
            ./api/vault/sidecar-server      a SIDE-EFFECT import capturing the sidecar's port
            UNPROTECTED_API_PREFIXES        the '/vault' entry
  server.tsx  the 'vault' ws provider, its handler, and the notifications upgrade route

The side-effect import is the one worth naming: it registers a sidecar listener
and appears in no route table, so nothing about unmounting the routers would have
stopped it running.

No capability registry change, unlike browser and task-logs. Vaultwarden is
exempt from totality on both halves — EXEMPT_API_PREFIXES has '/vault'
("Bitwarden protocol clients authenticate to Vaultwarden, not to Officer") and
EXEMPT_WS_PROVIDERS has 'vault'. So nothing claims it and nothing breaks by
unmounting it. I said the opposite before checking; the check is what settled it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-13 02:05:54 +00:00
co-authored by Claude Opus 5
parent 595dd082a7
commit 1eecc400a7
2 changed files with 24 additions and 24 deletions
+12 -12
View File
@@ -16,7 +16,7 @@ import { taskRunnerWebsocket } from './servers/api/tasks/task-executor';
import { pipelineWebsocket } from './servers/api/tasks/pipeline-executor';
import { cliampWebsocket, cliampAudioWebsocket } from './servers/api/cliamp/relay';
import { desktopWebsocket } from './servers/api/desktop/websocket';
import { vaultWebsocket, upgradeVaultWs } from './servers/api/vault/websocket';
// import { vaultWebsocket, upgradeVaultWs } from './servers/api/vault/websocket';
import officerWeb from './apps/officer-web/index.gen.html';
// import { startBrowserRelay } from './servers/api/browser/relay'; // switched off — see below
import { registerSidecar, unregisterSidecar, handleSidecarMessage } from './servers/sidecar-registry';
@@ -44,7 +44,7 @@ type WSData = {
| 'cliamp'
| 'cliamp-audio'
| 'desktop'
| 'vault'
// | 'vault'
| 'sidecar';
sessionId?: string;
cwd?: string;
@@ -138,7 +138,7 @@ const handlers: Record<string, any> = {
cliamp: cliampWebsocket,
'cliamp-audio': cliampAudioWebsocket,
desktop: desktopWebsocket,
vault: vaultWebsocket,
// vault: vaultWebsocket,
sidecar: sidecarWebsocket,
};
@@ -279,10 +279,10 @@ const server = serve({
},
// Vaultwarden notifications hub: upgrade the WebSocket here (proxied to upstream by vaultWebsocket);
// everything else on this path (SignalR long-poll negotiate/poll) falls through to the HTTP proxy.
'/api/vault/notifications/*': (req, server) => {
if (req.headers.get('upgrade') === 'websocket') return upgradeVaultWs(req, server);
return honoServer.fetch(req, server);
},
// '/api/vault/notifications/*': (req, server) => {
// if (req.headers.get('upgrade') === 'websocket') return upgradeVaultWs(req, server);
// return honoServer.fetch(req, server);
// },
'/api/sidecar/register': (req: Request, server: any) => {
const ok = server.upgrade(req, {
data: { provider: 'sidecar', userId: 0, email: '', username: '' },
@@ -308,14 +308,14 @@ const server = serve({
// entry for the same reason /dav does: only the paths listed here reach hono, and anything else
// falls through to the SPA — which answers 200 with the React shell, so a missing line here looks
// like a working endpoint returning nonsense rather than a 404.
'/vaultwarden/*': honoServer.fetch,
// '/vaultwarden/*': honoServer.fetch,
// The same proxy at the root, so the extension needs only the bare Officer URL. These four prefixes
// are Vaultwarden's alone — nothing in Officer answers on them — so routing them here costs nothing.
// `/api/*` already reaches hono below, where a Bitwarden client header diverts it.
'/identity/*': honoServer.fetch,
'/notifications/*': honoServer.fetch,
'/icons/*': honoServer.fetch,
'/events/*': honoServer.fetch,
// '/identity/*': honoServer.fetch,
// '/notifications/*': honoServer.fetch,
// '/icons/*': honoServer.fetch,
// '/events/*': honoServer.fetch,
'/': officerWeb,
'/*': officerWeb,
'/api': honoServer.fetch,