import { createRouter } from '../create-router'; import { IMAGES_DIR } from '../env'; // `GET /files/:filename` — the generated image bytes. // // Was an unauthenticated top-level `/images/*` route with a durable `PUBLIC_URL`-prefixed link on the // standalone service. Inside Officer it is mounted like every other route — the permission gate on the // platform side already authenticated the request before the proxy forwarded it here, so this route // itself needs no auth of its own; it only needs to refuse path traversal. // // Named `/files`, not `/images`, to avoid any ambiguity with the JSON API mounted at `/images` in // hono.ts — `/images/:filename` here would sit one segment away from `/images/generations/:id`. export const filesRouter = createRouter(); filesRouter.get('/:filename', async (ctx) => { const name = ctx.req.param('filename'); // No traversal: the name is a filename, so anything with a separator is not one. if (!name || name.includes('/') || name.includes('\\') || name.includes('..')) { return ctx.text('Not found', 404); } const file = Bun.file(`${IMAGES_DIR}/${name}`); if (!(await file.exists())) return ctx.text('Not found', 404); return new Response(file, { headers: { 'cache-control': 'private, max-age=31536000, immutable' } }); });