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 | |
| parent | 5178732c4c1205698d1846dd82896d9342558ac6 (diff) | |
| download | opencut-eb49500592e5c50c5637c09ea585b065545f2135.tar.gz | |
adds Vercel BotId
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/web/next.config.ts | 3 | ||||
| -rw-r--r-- | apps/web/package.json | 1 | ||||
| -rw-r--r-- | apps/web/src/app/api/waitlist/route.ts | 7 | ||||
| -rw-r--r-- | apps/web/src/app/layout.tsx | 11 |
4 files changed, 21 insertions, 1 deletions
diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index a0a0d31b..02261068 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -1,4 +1,5 @@ import type { NextConfig } from "next"; +import { withBotId } from "botid/next/config"; const nextConfig: NextConfig = { compiler: { @@ -21,4 +22,4 @@ const nextConfig: NextConfig = { }, }; -export default nextConfig; +export default withBotId(nextConfig); diff --git a/apps/web/package.json b/apps/web/package.json index 07b36dcb..193eb244 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -27,6 +27,7 @@ "@upstash/redis": "^1.35.0", "@vercel/analytics": "^1.4.1", "better-auth": "^1.2.7", + "botid": "^1.4.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", 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> |
