diff --git a/apps/web/env.d.ts b/apps/web/env.d.ts index ece89e76..8868e855 100644 --- a/apps/web/env.d.ts +++ b/apps/web/env.d.ts @@ -5,6 +5,7 @@ declare global { DATABASE: D1Database; VECTORIZE_INDEX: VectorizeIndex; AI: any; + RATELIMITER: any; } } } diff --git a/apps/web/src/app/api/ask/route.ts b/apps/web/src/app/api/ask/route.ts index 89123ac9..631b6633 100644 --- a/apps/web/src/app/api/ask/route.ts +++ b/apps/web/src/app/api/ask/route.ts @@ -13,6 +13,14 @@ export async function POST(req: NextRequest) { req.cookies.get("authjs.session-token")?.value ?? req.headers.get("Authorization")?.replace("Bearer ", ""); + const { success } = await process.env.RATELIMITER.limit({ key: token }); + + if (!success) { + return new Response(JSON.stringify({ message: "Rate limit exceeded" }), { + status: 429, + }); + } + const sessionData = await db .select() .from(sessions) diff --git a/apps/web/src/app/api/chat/route.ts b/apps/web/src/app/api/chat/route.ts index 985458f4..841e921f 100644 --- a/apps/web/src/app/api/chat/route.ts +++ b/apps/web/src/app/api/chat/route.ts @@ -14,6 +14,14 @@ export async function POST(req: NextRequest) { req.cookies.get("authjs.session-token")?.value ?? req.headers.get("Authorization")?.replace("Bearer ", ""); + const { success } = await process.env.RATELIMITER.limit({ key: token }); + + if (!success) { + return new Response(JSON.stringify({ message: "Rate limit exceeded" }), { + status: 429, + }); + } + const sessionData = await db .select() .from(sessions) diff --git a/apps/web/src/app/api/query/route.ts b/apps/web/src/app/api/query/route.ts index 02bb79da..fa834f15 100644 --- a/apps/web/src/app/api/query/route.ts +++ b/apps/web/src/app/api/query/route.ts @@ -13,6 +13,14 @@ export async function GET(req: NextRequest) { req.cookies.get("authjs.session-token")?.value ?? req.headers.get("Authorization")?.replace("Bearer ", ""); + const { success } = await process.env.RATELIMITER.limit({ key: token }); + + if (!success) { + return new Response(JSON.stringify({ message: "Rate limit exceeded" }), { + status: 429, + }); + } + const sessionData = await db .select() .from(sessions) diff --git a/apps/web/src/app/api/store/route.ts b/apps/web/src/app/api/store/route.ts index ca6921c4..1e590f9f 100644 --- a/apps/web/src/app/api/store/route.ts +++ b/apps/web/src/app/api/store/route.ts @@ -27,6 +27,14 @@ export async function POST(req: NextRequest) { ); } + const { success } = await process.env.RATELIMITER.limit({ key: token }); + + if (!success) { + return new Response(JSON.stringify({ message: "Rate limit exceeded" }), { + status: 429, + }); + } + const sessionData = await db .select() .from(sessions) diff --git a/apps/web/wrangler.toml b/apps/web/wrangler.toml index 12619fdb..049e482b 100644 --- a/apps/web/wrangler.toml +++ b/apps/web/wrangler.toml @@ -10,3 +10,11 @@ index_name = "anycontext-idx" binding = "DATABASE" database_name = "dev-d1-anycontext" database_id = "fc562605-157a-4f60-b439-2a24ffed5b4c" + +[[unsafe.bindings]] +name = "RATELIMITER" +type = "ratelimit" +namespace_id = "1001" + +# 25 requests per 10 seconds +simple = { limit = 25, period = 10 } \ No newline at end of file