import {
clerkMiddleware,
redirectToSignIn,
createRouteMatcher,
} from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import { extractPayload, VARIABLES_CONFIG } from "./lib/db/util";
const isPublicRoute = createRouteMatcher([
"/sign-in(.*)",
"/sign-up(.*)",
"/api/webhooks(.*)",
"/(api|trpc)(.*)",
"/auth/accept-invitation",
]);
export default clerkMiddleware(async (auth, req) => {
const session = auth();
const url = new URL(req.nextUrl);
const currentPath = req.nextUrl.pathname;
const authSection = session as any;
const existInDb = authSection.sessionClaims?.metadata?.existInDb;
const verificationToken = req.cookies.get(
VARIABLES_CONFIG.VERIFICATION_TOKEN!
)?.value;
const payload = verificationToken ? extractPayload(verificationToken):null
const invitationToken = url.searchParams.get("__clerk_ticket");
const adminRedirected = req.cookies.get("admin_redirected")?.value;
const isAdmin = authSection.sessionClaims?.metadata?.role === "admin" || payload?.role
if (isPublicRoute(req)) {
return NextResponse.next();
}
if (invitationToken && url.pathname !== "/auth/accept-invitation") {
const redirectUrl = req.nextUrl.clone();
redirectUrl.pathname = "/auth/accept-invitation";
redirectUrl.searchParams.set("__clerk_ticket", invitationToken);
return NextResponse.redirect(redirectUrl);
}
if (!session.sessionId) {
return redirectToSignIn({ returnBackUrl: req.url });
}
if (
(existInDb || verificationToken) &&
!invitationToken &&
currentPath === "/auth/verification"
) {
const destination = isAdmin ? "/dashboard" : "/";
return NextResponse.redirect(new URL(destination, req.url),307);
}
if (!existInDb && !verificationToken && currentPath !== "/auth/verification") {
const redirectUrl = req.nextUrl.clone();
redirectUrl.pathname = "/auth/verification";
return NextResponse.redirect(redirectUrl);
}
if (isAdmin && !adminRedirected && currentPath !== "/dashboard") {
const response = NextResponse.redirect(new URL("/dashboard", req.url),307);
response.cookies.set("admin_redirected", "true", {
httpOnly: true,
path: "/",
maxAge:60 * 30
});
return response;
}
if (!isAdmin && currentPath.startsWith("/dashboard")) {
return NextResponse.redirect(new URL("/", req.url));
}
return NextResponse.next();
});
export const config = {
matcher: [
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
"/(api|trpc)(.*)",
"/api/webhooks(.*)",
"/auth/accept-invitation",
"/",
],
};