diff options
Diffstat (limited to 'packages/api')
| -rw-r--r-- | packages/api/routes/assets.ts | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/packages/api/routes/assets.ts b/packages/api/routes/assets.ts index 9d9a60b3..50d11c47 100644 --- a/packages/api/routes/assets.ts +++ b/packages/api/routes/assets.ts @@ -1,9 +1,11 @@ import { zValidator } from "@hono/zod-validator"; -import { and, eq } from "drizzle-orm"; +import { TRPCError } from "@trpc/server"; +import { eq } from "drizzle-orm"; import { Hono } from "hono"; import { z } from "zod"; import { assets } from "@karakeep/db/schema"; +import { BareBookmark } from "@karakeep/trpc/models/bookmarks"; import { authMiddleware } from "../middlewares/auth"; import { serveAsset } from "../utils/assets"; @@ -36,13 +38,38 @@ const app = new Hono() .get("/:assetId", async (c) => { const assetId = c.req.param("assetId"); const assetDb = await c.var.ctx.db.query.assets.findFirst({ - where: and(eq(assets.id, assetId), eq(assets.userId, c.var.ctx.user.id)), + where: eq(assets.id, assetId), + columns: { + id: true, + userId: true, + bookmarkId: true, + }, }); if (!assetDb) { return c.json({ error: "Asset not found" }, { status: 404 }); } - return await serveAsset(c, assetId, c.var.ctx.user.id); + + // If asset is not attached to a bookmark yet, only owner can access it + if (!assetDb.bookmarkId) { + if (assetDb.userId !== c.var.ctx.user.id) { + return c.json({ error: "Asset not found" }, { status: 404 }); + } + return await serveAsset(c, assetId, assetDb.userId); + } + + // If asset is attached to a bookmark, check bookmark access permissions + try { + // This throws if the user doesn't have access to the bookmark + await BareBookmark.bareFromId(c.var.ctx, assetDb.bookmarkId); + } catch (e) { + if (e instanceof TRPCError && e.code === "FORBIDDEN") { + return c.json({ error: "Asset not found" }, { status: 404 }); + } + throw e; + } + + return await serveAsset(c, assetId, assetDb.userId); }); export default app; |
