diff options
Diffstat (limited to 'packages/api/routes')
| -rw-r--r-- | packages/api/routes/assets.ts | 55 | ||||
| -rw-r--r-- | packages/api/routes/public.ts | 47 | ||||
| -rw-r--r-- | packages/api/routes/rss.ts | 4 |
3 files changed, 53 insertions, 53 deletions
diff --git a/packages/api/routes/assets.ts b/packages/api/routes/assets.ts index de4e384d..9d9a60b3 100644 --- a/packages/api/routes/assets.ts +++ b/packages/api/routes/assets.ts @@ -1,18 +1,13 @@ import { zValidator } from "@hono/zod-validator"; import { and, eq } from "drizzle-orm"; import { Hono } from "hono"; -import { stream } from "hono/streaming"; import { z } from "zod"; import { assets } from "@karakeep/db/schema"; -import { - createAssetReadStream, - getAssetSize, - readAssetMetadata, -} from "@karakeep/shared/assetdb"; import { authMiddleware } from "../middlewares/auth"; -import { toWebReadableStream, uploadAsset } from "../utils/upload"; +import { serveAsset } from "../utils/assets"; +import { uploadAsset } from "../utils/upload"; const app = new Hono() .use(authMiddleware) @@ -47,51 +42,7 @@ const app = new Hono() if (!assetDb) { return c.json({ error: "Asset not found" }, { status: 404 }); } - - const [metadata, size] = await Promise.all([ - readAssetMetadata({ - userId: c.var.ctx.user.id, - assetId, - }), - - getAssetSize({ - userId: c.var.ctx.user.id, - assetId, - }), - ]); - - const range = c.req.header("Range"); - if (range) { - const parts = range.replace(/bytes=/, "").split("-"); - const start = parseInt(parts[0], 10); - const end = parts[1] ? parseInt(parts[1], 10) : size - 1; - - const fStream = createAssetReadStream({ - userId: c.var.ctx.user.id, - assetId, - start, - end, - }); - c.status(206); // Partial Content - c.header("Content-Range", `bytes ${start}-${end}/${size}`); - c.header("Accept-Ranges", "bytes"); - c.header("Content-Length", (end - start + 1).toString()); - c.header("Content-type", metadata.contentType); - return stream(c, async (stream) => { - await stream.pipe(toWebReadableStream(fStream)); - }); - } else { - const fStream = createAssetReadStream({ - userId: c.var.ctx.user.id, - assetId, - }); - c.status(200); - c.header("Content-Length", size.toString()); - c.header("Content-type", metadata.contentType); - return stream(c, async (stream) => { - await stream.pipe(toWebReadableStream(fStream)); - }); - } + return await serveAsset(c, assetId, c.var.ctx.user.id); }); export default app; diff --git a/packages/api/routes/public.ts b/packages/api/routes/public.ts new file mode 100644 index 00000000..d17049c4 --- /dev/null +++ b/packages/api/routes/public.ts @@ -0,0 +1,47 @@ +import { zValidator } from "@hono/zod-validator"; +import { and, eq } from "drizzle-orm"; +import { Hono } from "hono"; +import { z } from "zod"; + +import { assets } from "@karakeep/db/schema"; +import { verifySignedToken } from "@karakeep/shared/signedTokens"; +import { zAssetSignedTokenSchema } from "@karakeep/shared/types/assets"; + +import { unauthedMiddleware } from "../middlewares/auth"; +import { serveAsset } from "../utils/assets"; + +const app = new Hono().get( + "/assets/:assetId", + unauthedMiddleware, + zValidator( + "query", + z.object({ + token: z.string(), + }), + ), + async (c) => { + const assetId = c.req.param("assetId"); + const tokenPayload = verifySignedToken( + c.req.valid("query").token, + zAssetSignedTokenSchema, + ); + if (!tokenPayload) { + return c.json({ error: "Invalid or expired token" }, { status: 403 }); + } + if (tokenPayload.assetId !== assetId) { + return c.json({ error: "Invalid or expired token" }, { status: 403 }); + } + const userId = tokenPayload.userId; + + const assetDb = await c.var.ctx.db.query.assets.findFirst({ + where: and(eq(assets.id, assetId), eq(assets.userId, userId)), + }); + + if (!assetDb) { + return c.json({ error: "Asset not found" }, { status: 404 }); + } + return await serveAsset(c, assetId, userId); + }, +); + +export default app; diff --git a/packages/api/routes/rss.ts b/packages/api/routes/rss.ts index 81c9756c..88b943ad 100644 --- a/packages/api/routes/rss.ts +++ b/packages/api/routes/rss.ts @@ -28,8 +28,10 @@ const app = new Hono().get( const searchParams = c.req.valid("query"); const token = searchParams.token; - const res = await List.getForRss(c.var.ctx, listId, token, { + const res = await List.getPublicListContents(c.var.ctx, listId, token, { limit: searchParams.limit ?? 20, + order: "desc", + cursor: null, }); const list = res.list; |
