sourcebot/packages/web/src/middleware.ts

71 lines
No EOL
2.5 KiB
TypeScript

import { auth } from "@/auth";
import { Session } from "next-auth";
import { NextRequest, NextResponse } from "next/server";
import { notAuthenticated, serviceErrorResponse } from "./lib/serviceError";
interface NextAuthRequest extends NextRequest {
auth: Session | null;
}
const apiMiddleware = (req: NextAuthRequest) => {
if (req.nextUrl.pathname.startsWith("/api/auth")) {
return NextResponse.next();
}
if (!req.auth) {
return serviceErrorResponse(
notAuthenticated(),
);
}
return NextResponse.next();
}
const defaultMiddleware = (req: NextAuthRequest) => {
// We're not able to check if the user doesn't belong to any orgs in the middleware, since we cannot call prisma. As a result, we do this check
// in the root layout. However, there are certain endpoints (ex. login, redeem, onboard) that we want the user to be able to hit even if they don't
// belong to an org. It seems like the easiest way to do this is to check for these paths here and pass in a flag to the root layout using the headers
// https://github.com/vercel/next.js/discussions/43657#discussioncomment-5981981
const bypassOrgCheck = req.nextUrl.pathname === "/login" || req.nextUrl.pathname === "/redeem" || req.nextUrl.pathname.includes("onboard");
const requestheaders = new Headers(req.headers);
requestheaders.set("x-bypass-org-check", bypassOrgCheck.toString());
// if we're trying to redeem an invite while not authed we continue to the redeem page so
// that we can pipe the invite_id to the login page
if (!req.auth && req.nextUrl.pathname === "/redeem") {
return NextResponse.next({
request: {
headers: requestheaders,
}
});
}
if (!req.auth && req.nextUrl.pathname !== "/login") {
const newUrl = new URL("/login", req.nextUrl.origin);
return NextResponse.redirect(newUrl);
} else if (req.auth && req.nextUrl.pathname === "/login") {
const newUrl = new URL("/", req.nextUrl.origin);
return NextResponse.redirect(newUrl);
}
return NextResponse.next({
request: {
headers: requestheaders,
}
});
}
export default auth(async (req) => {
if (req.nextUrl.pathname.startsWith("/api")) {
return apiMiddleware(req);
}
return defaultMiddleware(req);
})
export const config = {
// https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
matcher: ['/((?!_next/static|ingest|_next/image|favicon.ico|sitemap.xml|robots.txt).*)'],
}