task-managment / src / middleware.tsx
middleware.tsx
Raw
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",
    "/",
  ],
};