soulseek: peer menu with browse and favorites
slskd has no favorites or buddy-list concept — 0.26.0's UsersController exposes only endpoint/browse/directory/info/status — so Officer owns that data itself: a soulseek_favorites table served by the slskd sidecar under a /_officer/* namespace, which can never collide with slskd's /api/v0/*. The main server gains exactly one line, injecting X-Officer-User on the proxy hop, so it stays a thin auth proxy and grows no Soulseek logic. The route is handled before the upstream check, so favorites keep working with slskd down. Usernames in search results and downloads become a dropdown (browse shares, toggle favorite). Browsing publishes to a nonce-stamped, consumed-once channel so the Users section looks the peer up without re-running the expensive browse on every remount, and favorites get their own section at the top of that panel, which doubles as its landing content. CardHeader had to split its toggle row to host the dropdown, since a trigger can't live inside the collapse button. The schema file is deliberately self-contained so it can move wholesale into the sidecar directory when sidecars start owning their own schema. Its DDL was applied by hand, matching drizzle's constraint naming, rather than running a whole-schema push. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,10 @@ import { getSlskdServerUrl } from './sidecar-server';
|
||||
// the subpath + query + body to the officer-slskd sidecar, which OWNS the slskd contract and injects the
|
||||
// slskd API key. The platform holds no slskd credentials.
|
||||
//
|
||||
// This is a catch-all with no routes of its own: the full /api/slskd/* contract (slskd's own API, e.g.
|
||||
// /api/v0/searches, /api/v0/transfers) is documented at the top of the sidecar's fetch handler —
|
||||
// src/servers/sidecar/slskd/index.ts.
|
||||
// This is a catch-all with no routes of its own: the full /api/slskd/* contract is documented at the top
|
||||
// of the sidecar's fetch handler (src/servers/sidecar/slskd/index.ts). That contract covers both slskd's
|
||||
// own API (/api/v0/searches, /api/v0/transfers, …) and the sidecar's Officer-owned routes (/_officer/*,
|
||||
// features slskd has no concept of). Both are opaque from here — this file never grows Soulseek logic.
|
||||
|
||||
export const slskdRouter = createRouter();
|
||||
|
||||
@@ -28,6 +29,9 @@ slskdRouter.all('/*', async (ctx) => {
|
||||
if (contentType) headers['Content-Type'] = contentType;
|
||||
const range = ctx.req.header('range');
|
||||
if (range) headers['Range'] = range;
|
||||
// Forward the authenticated user id so the sidecar can serve its own Officer-owned routes (/_officer/*,
|
||||
// e.g. favourite peers) against Postgres. The sidecar binds loopback only, so this header is trusted.
|
||||
headers['X-Officer-User'] = String(ctx.get('user').id);
|
||||
|
||||
const hasBody = method !== 'GET' && method !== 'HEAD';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user