Files
goodgo-platform/apps/web/middleware.ts
Ho Ngoc Hai 53580d444b fix(web): add /listings to middleware publicPaths (TEC-3090)
Unauthenticated requests to /listings were being 302-redirected to /login
because '/listings' was missing from the publicPaths allowlist. /listings
is the public marketplace board and must be accessible without auth.

Unblocks 5 Playwright DataTable specs + smoke test (TEC-3040).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 12:50:15 +07:00

48 lines
1.4 KiB
TypeScript

import { NextResponse, type NextRequest } from 'next/server';
import createIntlMiddleware from 'next-intl/middleware';
import { routing } from '@/i18n/routing';
const intlMiddleware = createIntlMiddleware(routing);
const publicPaths = ['/login', '/register', '/search', '/listings', '/auth/callback'];
const publicExactPaths = ['/'];
const authOnlyPaths = ['/login', '/register'];
function isPublicPath(pathname: string): boolean {
return (
publicExactPaths.includes(pathname) ||
publicPaths.some((path) => pathname.startsWith(path))
);
}
function stripLocale(pathname: string): string {
const localePattern = /^\/(vi|en)(\/|$)/;
return pathname.replace(localePattern, '/') || '/';
}
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const strippedPath = stripLocale(pathname);
const hasAuthCookie = request.cookies.has('goodgo_authenticated');
if (!isPublicPath(strippedPath) && !hasAuthCookie) {
const loginUrl = new URL('/login', request.url);
loginUrl.searchParams.set('redirect', strippedPath);
return NextResponse.redirect(loginUrl);
}
const isAuthOnly = authOnlyPaths.some((path) =>
strippedPath.startsWith(path),
);
if (isAuthOnly && hasAuthCookie) {
return NextResponse.redirect(new URL('/dashboard', request.url));
}
return intlMiddleware(request);
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico|public).*)'],
};