Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b820317916 | ||
|
|
09148130a8 |
+46
-1
@@ -1,6 +1,7 @@
|
|||||||
import { createRouter } from '@@/create-router';
|
import { createRouter } from '@@/create-router';
|
||||||
import { createSidecarProxy } from '@@/sidecar/create-proxy';
|
import { createSidecarProxy } from '@@/sidecar/create-proxy';
|
||||||
import { getLinkwardenConfig, setLinkwardenConfig, getAccount } from '../db/queries';
|
import { getLinkwardenConfig, setLinkwardenConfig, getAccount } from '../db/queries';
|
||||||
|
import { stripHopByHop } from '../sidecar/upstream';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mounted at `/api/linkwarden`.
|
* Mounted at `/api/linkwarden`.
|
||||||
@@ -32,7 +33,51 @@ const proxy = createSidecarProxy({
|
|||||||
timeoutSeconds: 120,
|
timeoutSeconds: 120,
|
||||||
});
|
});
|
||||||
|
|
||||||
router.route('/lw', proxy.router);
|
/*
|
||||||
|
── The factory's ROUTER is not used, and that is the whole reason this is written out ──
|
||||||
|
|
||||||
|
`createSidecarProxy` is for AUTHENTICATED proxying: its forwarder does `ctx.get('user').id`, because
|
||||||
|
every other sidecar behind it is reached by somebody with an Officer session. This door is declared in
|
||||||
|
`unauthenticatedPaths`, so there is no user, and mounting the factory's router here answered every
|
||||||
|
request with `TypeError: undefined is not an object` as a 500. Measured on alpha, not reasoned about.
|
||||||
|
|
||||||
|
Vault hand-writes its public router for exactly this reason and I should have followed it rather than
|
||||||
|
reaching for the shared thing because it was shared.
|
||||||
|
|
||||||
|
What the factory IS still used for, and why it is still constructed: `getHttpUrl()`, so the port the
|
||||||
|
sidecar announced is discovered in one place; and `registerProxiedPrefix`, which runs at construction
|
||||||
|
and tells the body parser to leave `/api/linkwarden/lw` alone. Both matter, and neither is the router.
|
||||||
|
*/
|
||||||
|
router.all('/lw/*', async (ctx) => {
|
||||||
|
const base = proxy.getHttpUrl();
|
||||||
|
if (!base) return ctx.text('the Linkwarden sidecar is not running', 503);
|
||||||
|
|
||||||
|
const url = new URL(ctx.req.url);
|
||||||
|
const subpath = url.pathname.slice('/api/linkwarden/lw'.length) || '/';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Authorization is FORWARDED, not replaced — the opposite of the door below.
|
||||||
|
|
||||||
|
The client's own credential is the only one in play here, and Linkwarden is the only thing entitled
|
||||||
|
to judge it. Officer adds no security to a stock extension because it has nothing to check: this is
|
||||||
|
the same exposure through one address instead of two, which is what lets Linkwarden stop listening
|
||||||
|
on its own.
|
||||||
|
*/
|
||||||
|
const hasBody = ctx.req.method !== 'GET' && ctx.req.method !== 'HEAD';
|
||||||
|
const init: RequestInit & { duplex?: 'half' } = {
|
||||||
|
method: ctx.req.method,
|
||||||
|
headers: stripHopByHop(ctx.req.raw.headers),
|
||||||
|
redirect: 'manual',
|
||||||
|
...(hasBody ? { body: ctx.req.raw.body, duplex: 'half' as const } : {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const upstream = await fetch(`${base}${subpath}${url.search}`, init);
|
||||||
|
return new Response(upstream.body, { status: upstream.status, headers: stripHopByHop(upstream.headers) });
|
||||||
|
} catch {
|
||||||
|
return ctx.text('Linkwarden unreachable', 502);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ── where the instance is ────────────────────────────────────────────────────────────────────────
|
// ── where the instance is ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ import type { PluginManifest } from '@@/plugins/manifest';
|
|||||||
*/
|
*/
|
||||||
export const manifest: PluginManifest = {
|
export const manifest: PluginManifest = {
|
||||||
publisher: 'officerdev',
|
publisher: 'officerdev',
|
||||||
version: '2026.09.05.01',
|
version: '2026.09.05.02',
|
||||||
platform: '>=1.0.0',
|
platform: '>=1.0.0',
|
||||||
|
|
||||||
label: 'Linkwarden',
|
label: 'Linkwarden',
|
||||||
|
|||||||
Reference in New Issue
Block a user