From d72ad03c422179352b9d769b4c824afc3f7a7c83 Mon Sep 17 00:00:00 2001 From: Minit Date: Wed, 22 Apr 2026 14:19:24 +0530 Subject: [PATCH 1/3] fix(api): require authentication on loom-download endpoint Co-Authored-By: Claude Sonnet 4.6 --- apps/web/app/api/tools/loom-download/route.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/web/app/api/tools/loom-download/route.ts b/apps/web/app/api/tools/loom-download/route.ts index 44293cf52f3..504bd65751b 100644 --- a/apps/web/app/api/tools/loom-download/route.ts +++ b/apps/web/app/api/tools/loom-download/route.ts @@ -1,4 +1,5 @@ import { randomUUID } from "node:crypto"; +import { getCurrentUser } from "@cap/database/auth/session"; import { type NextRequest, NextResponse } from "next/server"; import { fetchConvertedVideoViaMediaServer, @@ -160,6 +161,11 @@ async function tryMp4CandidateDownload( } export async function GET(request: NextRequest) { + const user = await getCurrentUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + const videoId = request.nextUrl.searchParams.get("id"); const videoName = request.nextUrl.searchParams.get("name"); From 3f2db032c414aa4ad0d98c0a4723a8da37cf1915 Mon Sep 17 00:00:00 2001 From: Minit Date: Wed, 22 Apr 2026 14:49:03 +0530 Subject: [PATCH 2/3] fix(api): add per-user rate limiting to loom-download endpoint --- apps/web/app/api/tools/loom-download/route.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/web/app/api/tools/loom-download/route.ts b/apps/web/app/api/tools/loom-download/route.ts index 504bd65751b..4e55be17126 100644 --- a/apps/web/app/api/tools/loom-download/route.ts +++ b/apps/web/app/api/tools/loom-download/route.ts @@ -7,6 +7,10 @@ import { } from "@/lib/media-client"; import { convertRemoteVideoToMp4Buffer } from "@/lib/video-convert"; +const rateLimitMap = new Map(); +const WINDOW_MS = 60_000; +const MAX_REQUESTS = 10; + function isHlsUrl(url: string): boolean { return (url.split("?")[0] ?? "").toLowerCase().endsWith(".m3u8"); } @@ -166,6 +170,16 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } + const now = Date.now(); + const entry = rateLimitMap.get(user.id); + if (!entry || now > entry.resetAt) { + rateLimitMap.set(user.id, { count: 1, resetAt: now + WINDOW_MS }); + } else if (entry.count >= MAX_REQUESTS) { + return NextResponse.json({ error: "Rate limit exceeded" }, { status: 429 }); + } else { + entry.count++; + } + const videoId = request.nextUrl.searchParams.get("id"); const videoName = request.nextUrl.searchParams.get("name"); From 6cbd76f5bcd445edfd5ae808875aaaeacfdc076e Mon Sep 17 00:00:00 2001 From: Minit Date: Wed, 13 May 2026 09:41:10 +0530 Subject: [PATCH 3/3] fix(api): remove in-memory rate limiter from loom-download endpoint --- apps/web/app/api/tools/loom-download/route.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/apps/web/app/api/tools/loom-download/route.ts b/apps/web/app/api/tools/loom-download/route.ts index 4e55be17126..504bd65751b 100644 --- a/apps/web/app/api/tools/loom-download/route.ts +++ b/apps/web/app/api/tools/loom-download/route.ts @@ -7,10 +7,6 @@ import { } from "@/lib/media-client"; import { convertRemoteVideoToMp4Buffer } from "@/lib/video-convert"; -const rateLimitMap = new Map(); -const WINDOW_MS = 60_000; -const MAX_REQUESTS = 10; - function isHlsUrl(url: string): boolean { return (url.split("?")[0] ?? "").toLowerCase().endsWith(".m3u8"); } @@ -170,16 +166,6 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } - const now = Date.now(); - const entry = rateLimitMap.get(user.id); - if (!entry || now > entry.resetAt) { - rateLimitMap.set(user.id, { count: 1, resetAt: now + WINDOW_MS }); - } else if (entry.count >= MAX_REQUESTS) { - return NextResponse.json({ error: "Rate limit exceeded" }, { status: 429 }); - } else { - entry.count++; - } - const videoId = request.nextUrl.searchParams.get("id"); const videoName = request.nextUrl.searchParams.get("name");