Closed devrenzz closed 3 months ago
To migrate use the createCsrfProtect
named export and catch the CsrfError
error instead of looking at the response object.
Try this:
import { CsrfError, createCsrfProtect } from '@edge-csrf/nextjs';
// Access Allowed Only for Signed-In Users:
const PrivatePaths: string[] = [ROUTES.Profiles];
// Access Denied for Signed-In Users:
const RestrictedPaths: string[] = ['/auth'];
const imageExtensions = ['.png', '.jpg', '.jpeg', '.svg', '.gif', '.webp'];
export const config = {
matcher: [
/*
* Match all paths except for:
* 1. /api routes
* 2. /_next (Next.js internals)
* 3. /_static (inside /public)
* 4. all root files inside /public (e.g. /favicon.ico)
*/
'/((?!api/|_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)'
// '/((?!_next/static|_next/image|favicon.ico).*)'
]
};
// initalize protection function
const csrfProtect = createCsrfProtect({
cookie: {
secure: process.env.NODE_ENV === 'production',
name: PRESSCART_CSRF_TOKEN_KEY
}
});
export default async function middleware(req: NextRequest) {
const { supabase, response: res } = createMiddlewareClient(req);
const url = req.nextUrl.clone();
//skip if image
if (imageExtensions.some((ext) => url.pathname.includes(ext))) return res;
const {
data: { user }
} = await supabase.auth.getUser();
const path = url.pathname;
const hasAccountType = user?.user_metadata?.account_type;
if (!path.startsWith('/auth')) {
// csrf protection
try {
await csrfProtect(req, res);
} catch (err) {
if (err instanceof CsrfError) return new NextResponse('invalid csrf token', { status: 403 });
throw err;
}
}
if (req.nextUrl.pathname === '/csrf-token') {
return NextResponse.json({
csrfToken: res.headers.get('X-CSRF-Token') || 'missing'
});
}
const aPrivatePath = Boolean(
PrivatePaths.find((pathname) => path.includes(pathname))
);
const aRestrictedPath = Boolean(
RestrictedPaths.find((pathname) => path.includes(pathname))
);
if (user && aPrivatePath && !hasAccountType) {
return NextResponse.redirect(new URL(`/account-type`, req.url));
}
if (!user && aPrivatePath) {
return NextResponse.redirect(new URL(ROUTES.Login, req.url));
}
if (user && aRestrictedPath) {
const team = await getLatestTeam(user.id);
const latestProfile = team?.profiles[team.profiles.length - 1];
const route = `${ROUTES.Profiles}/${latestProfile?.uuid}`;
return NextResponse.redirect(new URL(`/${team?.slug}${route}`, req.url));
}
if (path === '/') {
return NextResponse.redirect(new URL(ROUTES.Login, req.url));
}
if (
path === ROUTES.EmailConfirmation &&
(!url.searchParams.has('email') ||
!url.searchParams.get('email')?.match(REGEX.Email))
) {
return NextResponse.redirect(new URL(ROUTES.Login, req.url));
}
return res;
}
Did this work? Let me know if you're still having trouble upgrading.
Did this work? Let me know if you're still having trouble upgrading.
Hello, sorry for the late reply. It works perfectly. Thank you so much for the quick response!
Awesome! Happy to hear it's working.
Hello, I have this old edge-csrf version
1.09
and it working fine but with the new version. I don't have any idea how I can update it based onREADME
in NextJS. As of now, I handle protected routes thru middleware and also I don't want to run the csrf validation if user is on login page. Thankyou!