diff --git a/middleware.ts b/middleware.ts index cc76c8a..a7349c9 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,6 +1,6 @@ -import { authMiddleware } from "@clerk/nextjs"; +import { authMiddleware, redirectToSignIn } from "@clerk/nextjs"; import { validateRequest } from "./app/_lib/unkey"; -import { NextRequest, NextResponse } from "next/server"; +import { NextResponse } from "next/server"; import { Ratelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis"; import { env } from "./env.mjs"; @@ -16,28 +16,73 @@ const rateLimit = new Ratelimit({ export default authMiddleware({ ignoredRoutes: ["/"], - publicRoutes: ["/api/external/(.*)", "/api/webhooks/(.*)"], - apiRoutes: ["/api/internal/(.*)"], - beforeAuth: async (req: NextRequest) => { - const { success } = await rateLimit.limit(req.ip || ""); - if (success) { - if (req.nextUrl.pathname.includes("/api/external/private")) { - const isValid = await validateRequest(req); - - if (!isValid) { - return new NextResponse("UNAUTHORIZED", { - status: 403, - statusText: "Unauthorized!", - }); - } + publicRoutes: [ + "/api/external/public/(.*)", + "/api/webhooks", + "/api/webhooks/(.*)", + ], + afterAuth: async (auth, req) => { + if (!auth.userId && auth.isPublicRoute) { + const { success } = await rateLimit.limit(req.ip || ""); + if (success) { + return NextResponse.next(); } - return NextResponse.next(); + return new NextResponse("TOO MANY REQUESTS", { + status: 429, + statusText: "Too many requests!", + }); } - return new NextResponse("TOO MANY REQUESTS", { - status: 429, - statusText: "Too many requests!", - }); + if (req.nextUrl.pathname.includes("/api/internal")) { + const { success } = await rateLimit.limit(req.ip || ""); + + if (!success) { + return new NextResponse("TOO MANY REQUESTS", { + status: 429, + statusText: "Too many requests!", + }); + } + + if (auth.userId) { + return NextResponse.next(); + } else { + return new NextResponse("UNAUTHORIZED", { + status: 403, + statusText: "Unauthorized!", + }); + } + } + + if (req.nextUrl.pathname.includes("/api/external/private")) { + const { success } = await rateLimit.limit(req.ip || ""); + + if (!success) { + return new NextResponse("TOO MANY REQUESTS", { + status: 429, + statusText: "Too many requests!", + }); + } + + const isValid = await validateRequest(req); + + if (isValid) { + return NextResponse.next(); + } else { + return new NextResponse("UNAUTHORIZED", { + status: 403, + statusText: "Unauthorized!", + }); + } + } + + if (!auth.userId && !auth.isPublicRoute) { + if (req.nextUrl.pathname.includes("/api")) { + return NextResponse.next(); + } + // This is annoying... + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any + return redirectToSignIn({ returnBackUrl: req.url }); + } }, });