diff --git a/src/middleware.ts b/src/middleware.ts index 807e65c..bf28af1 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,7 +1,29 @@ -import { authMiddleware } from "@clerk/nextjs"; +import { authMiddleware, redirectToSignIn } from "@clerk/nextjs"; +import { validateRequest } from "./server/unkey"; +import { NextResponse } from "next/server"; export default authMiddleware({ - publicRoutes: ["/", "/api/(.*)"], + publicRoutes: ["/", "/api/public/(.*)"], + afterAuth: async (auth, req) => { + if (!auth.userId && auth.isPublicRoute) { + return NextResponse.next(); + } + + if ( + req.nextUrl.pathname.includes("/api/webhooks") || + req.nextUrl.pathname.includes("/api/private") + ) { + const isValid = await validateRequest(req); + if (isValid) { + return NextResponse.next(); + } else { + return new NextResponse("UNAUTHORIZED", { status: 403 }); + } + } + if (!auth.userId && !auth.isPublicRoute) { + redirectToSignIn({ returnBackUrl: req.url }); + } + }, }); export const config = { diff --git a/src/pages/api/external/ping.ts b/src/pages/api/external/ping.ts deleted file mode 100644 index 9125d74..0000000 --- a/src/pages/api/external/ping.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from "next"; -import { validateRequest } from "~/server/unkey"; - -export default async function handler( - req: NextApiRequest, - res: NextApiResponse -) { - const isValid = await validateRequest(req, res); - - if (isValid) { - res.status(200).json({ result: "Pong!" }); - } -} diff --git a/src/pages/api/private/ping.ts b/src/pages/api/private/ping.ts new file mode 100644 index 0000000..ca89e26 --- /dev/null +++ b/src/pages/api/private/ping.ts @@ -0,0 +1,13 @@ +import { NextResponse } from "next/server"; + +export const config = { + runtime: "edge", + regions: ["pdx1"], +}; + +export default function handler() { + return NextResponse.json( + { message: "Private Pong!" }, + { status: 200, statusText: "SUCCESS" } + ); +} diff --git a/src/pages/api/public/ping.ts b/src/pages/api/public/ping.ts new file mode 100644 index 0000000..e5b6a76 --- /dev/null +++ b/src/pages/api/public/ping.ts @@ -0,0 +1,13 @@ +import { NextResponse } from "next/server"; + +export const config = { + runtime: "edge", + regions: ["pdx1"], +}; + +export default function handler() { + return NextResponse.json( + { message: "Public Pong!" }, + { status: 200, statusText: "SUCCESS" } + ); +} diff --git a/src/pages/api/webhooks/index.ts b/src/pages/api/webhooks/index.ts index b699ab2..1599c00 100644 --- a/src/pages/api/webhooks/index.ts +++ b/src/pages/api/webhooks/index.ts @@ -1,5 +1,4 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { validateRequest } from "~/server/unkey"; import { onUserCreatedHandler, onUserDeletedHandler, @@ -10,12 +9,6 @@ export default async function handler( req: NextApiRequest, res: NextApiResponse ) { - const isValid = await validateRequest(req, res); - - if (!isValid) { - return; - } - try { const requestBody = WebhookEventBodySchema.parse(req.body); diff --git a/src/server/unkey.ts b/src/server/unkey.ts index ad2163d..7c04922 100644 --- a/src/server/unkey.ts +++ b/src/server/unkey.ts @@ -1,5 +1,5 @@ import { Unkey } from "@unkey/api"; -import type { NextApiRequest, NextApiResponse } from "next"; +import { NextRequest } from "next/server"; import { env } from "~/env.mjs"; export const unkey = new Unkey({ token: env.UNKEY_ROOT_KEY }); @@ -15,22 +15,17 @@ export const validateApiKey = async (key: string) => { } }; -export const validateRequest = async ( - req: NextApiRequest, - res: NextApiResponse -) => { +export const validateRequest = async (req: NextRequest) => { let isValidKey: boolean = false; + + const authorization = req.headers.get("authorization"); // Get the auth bearer token if it exists - if (req.headers.authorization) { - const key = req.headers.authorization.split("Bearer ").at(1); + if (authorization) { + const key = authorization.split("Bearer ").at(1); if (key) { isValidKey = await validateApiKey(key); } } - if (!isValidKey) { - res.status(403).json({ error: "UNAUTHORIZED" }); - } - return isValidKey; };