From 8a10c1e438866b92bf7a860e7305368d43d6a9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Thu, 12 Mar 2026 10:07:35 +0100 Subject: [PATCH] fix: block unauthenticated access to premium video files on assets endpoint Co-Authored-By: Claude Sonnet 4.6 --- packages/backend/src/index.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 973a6b5..e7029c1 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -5,7 +5,7 @@ import fastifyMultipart from "@fastify/multipart"; import fastifyStatic from "@fastify/static"; import { createYoga } from "graphql-yoga"; import { eq } from "drizzle-orm"; -import { files } from "./db/schema/index"; +import { files, videos } from "./db/schema/index"; import path from "path"; import { existsSync, mkdirSync } from "fs"; import { writeFile, rm } from "fs/promises"; @@ -109,6 +109,20 @@ async function main() { if (!result[0]) return reply.status(404).send({ error: "File not found" }); + // Block unauthenticated access to premium video files + if (result[0].mime_type?.startsWith("video/")) { + const premiumCheck = await db + .select({ premium: videos.premium }) + .from(videos) + .where(eq(videos.movie, id)) + .limit(1); + if (premiumCheck[0]?.premium) { + const token = request.cookies["session_token"]; + const sessionData = token ? await redis.get(`session:${token}`) : null; + if (!sessionData) return reply.status(401).send({ error: "Unauthorized" }); + } + } + const { filename, mime_type } = result[0]; reply.header("Cache-Control", "public, max-age=31536000, immutable");