Files
reflector/www/middleware.ts
Mathieu Virbel 833a5d1191 fix: sso refresh token race condition (#405)
With NextAuth, there is a race condition of the current implementation
of refreshToken using multiple tab. Because getSession() is broadcasted
(or triggered by another component, window focus or such), we may ask
for the jwt() to be refreshed at the same time.

The problem is the first time will go correctly, while all others calls
will be rejected as they are using a revoked token.

This redis lock is per-user, and will use redis lock as a source of
truth.
2024-09-05 00:47:02 +02:00

59 lines
1.4 KiB
TypeScript

import { withAuth } from "next-auth/middleware";
import { getConfig } from "./app/lib/edgeConfig";
import { NextResponse } from "next/server";
const LOGIN_REQUIRED_PAGES = [
"/transcripts/[!new]",
"/browse(.*)",
"/rooms(.*)",
];
const PROTECTED_PAGES = new RegExp(
LOGIN_REQUIRED_PAGES.map((page) => `^${page}$`).join("|"),
);
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
// must be a copy of LOGIN_REQUIRED_PAGES
// cannot use anything dynamic (...LOGIN_REQUIRED_PAGES, or .concat(LOGIN_REQUIRED_PAGES))
// as per https://nextjs.org/docs/messages/invalid-page-config
"/",
"/transcripts(.*)",
"/browse(.*)",
"/rooms(.*)",
],
};
export default withAuth(
async function middleware(request) {
const config = await getConfig();
const pathname = request.nextUrl.pathname;
// feature-flags protected paths
if (
(!config.features.browse && pathname.startsWith("/browse")) ||
(!config.features.rooms && pathname.startsWith("/rooms"))
) {
return NextResponse.redirect(request.nextUrl.origin);
}
},
{
callbacks: {
async authorized({ req, token }) {
const config = await getConfig();
if (
config.features.requireLogin &&
PROTECTED_PAGES.test(req.nextUrl.pathname)
) {
return !!token;
}
return true;
},
},
},
);