diff options
| author | Ahmet Kilinc <akx9@icloud.com> | 2025-07-16 01:00:40 +0100 |
|---|---|---|
| committer | Ahmet Kilinc <akx9@icloud.com> | 2025-07-16 01:00:40 +0100 |
| commit | eb49500592e5c50c5637c09ea585b065545f2135 (patch) | |
| tree | 8cf0df336f2af737ef775c516c1f3380b418bc7e /apps/web/src | |
| parent | 5178732c4c1205698d1846dd82896d9342558ac6 (diff) | |
| download | opencut-eb49500592e5c50c5637c09ea585b065545f2135.tar.gz | |
adds Vercel BotId
Diffstat (limited to 'apps/web/src')
| -rw-r--r-- | apps/web/src/app/api/waitlist/route.ts | 7 | ||||
| -rw-r--r-- | apps/web/src/app/layout.tsx | 11 |
2 files changed, 18 insertions, 0 deletions
diff --git a/apps/web/src/app/api/waitlist/route.ts b/apps/web/src/app/api/waitlist/route.ts index 4d64be77..031ebd5a 100644 --- a/apps/web/src/app/api/waitlist/route.ts +++ b/apps/web/src/app/api/waitlist/route.ts @@ -1,6 +1,7 @@ import { NextRequest, NextResponse } from "next/server";
import { db, eq } from "@opencut/db";
import { waitlist } from "@opencut/db/schema";
+import { checkBotId } from "botid/server";
import { nanoid } from "nanoid";
import { waitlistRateLimit } from "@/lib/rate-limit";
import { z } from "zod";
@@ -143,6 +144,12 @@ async function validateCSRFToken(request: NextRequest): Promise<boolean> { }
export async function POST(request: NextRequest) {
+ const verification = await checkBotId();
+
+ if (verification.isBot) {
+ return NextResponse.json({ error: "Access denied" }, { status: 403 });
+ }
+
const identifier = request.headers.get("x-forwarded-for") ?? "127.0.0.1";
const { success } = await waitlistRateLimit.limit(identifier);
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 9ac54262..1cbc3f2e 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -7,9 +7,17 @@ import { TooltipProvider } from "../components/ui/tooltip"; import { StorageProvider } from "../components/storage-provider"; import { baseMetaData } from "./metadata"; import { defaultFont } from "../lib/font-config"; +import { BotIdClient } from "botid/client"; export const metadata = baseMetaData; +const protectedRoutes = [ + { + path: "/api/waitlist", + method: "POST", + }, +]; + export default function RootLayout({ children, }: Readonly<{ @@ -17,6 +25,9 @@ export default function RootLayout({ }>) { return ( <html lang="en" suppressHydrationWarning> + <head> + <BotIdClient protect={protectedRoutes} /> + </head> <body className={`${defaultFont.className} font-sans antialiased`}> <ThemeProvider attribute="class" forcedTheme="dark"> <TooltipProvider> |
