fix(api): authorize the standalone upload and preview routes (#707)

POST /api/v1/upload, POST /api/v1/preview and POST /api/v1/preview/generate
authenticated but never authorized, sitting between requireFileAccess (which
guards /api/v1/files) and toolAccessMiddleware (scoped to /api/v1/tools/). A key
scoped to settings:read alone could still stage bytes behind the unauthenticated
download URL and drive Sharp, libheif, LibRaw and FFmpeg.

Upload now takes requireFileAccess; both preview routes take tools:use.
requireFileAccess moves to permissions.ts so the modules share one definition.
This commit is contained in:
SnapOtter
2026-08-01 14:40:09 +08:00
committed by GitHub
parent 059af34ace
commit 1544966b52
6 changed files with 188 additions and 38 deletions
+4
View File
@@ -58,6 +58,7 @@ import { docsRoutes } from "../../apps/api/src/routes/docs.js";
import { registerEnterpriseRoutes } from "../../apps/api/src/routes/enterprise/index.js";
import { feedbackRoutes } from "../../apps/api/src/routes/feedback.js";
import { registerFetchUrlsRoute } from "../../apps/api/src/routes/fetch-urls.js";
import { filePreviewRoutes } from "../../apps/api/src/routes/file-preview.js";
import { fileRoutes } from "../../apps/api/src/routes/files.js";
import { registerJobRoutes } from "../../apps/api/src/routes/jobs.js";
import { registerMemeTemplates } from "../../apps/api/src/routes/meme-templates.js";
@@ -192,6 +193,9 @@ export async function buildTestApp(): Promise<TestApp> {
// User file library routes (persistent file management with versioning)
await userFileRoutes(app);
// Library thumbnails plus the on-demand preview for uploaded media
await filePreviewRoutes(app);
// Meme template routes
await registerMemeTemplates(app);