diff --git a/src/config/navigation.ts b/src/config/navigation.ts index 26626bf..19c44ce 100644 --- a/src/config/navigation.ts +++ b/src/config/navigation.ts @@ -1,15 +1,14 @@ -export type NavChildItem = { - label: string; - href: string; -}; - export type NavItem = { label: string; href: string; - children?: NavChildItem[]; + protected?: boolean; + public?: boolean; + onlyPublic?: boolean; + visible?: boolean; + children?: NavItem[]; }; export const NAV_ITEMS: NavItem[] = [ - { label: "home", href: "/home" }, - { label: "about", href: "/about" }, + { label: "home", href: "/home", public: true }, + { label: "predictions", href: "/predictions", public: true }, ]; diff --git a/src/proxy.ts b/src/proxy.ts index 5a8a588..4e17c5a 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,50 +1,55 @@ -import { NextResponse } from 'next/server'; -import { withAuth } from 'next-auth/middleware'; -import createIntlMiddleware from 'next-intl/middleware'; -import { routing } from './i18n/routing'; +import { NAV_ITEMS } from "@/config/navigation"; +import { withAuth } from "next-auth/middleware"; +import createMiddleware from "next-intl/middleware"; +import { NextRequest } from "next/server"; +import { routing } from "./i18n/routing"; -const intlMiddleware = createIntlMiddleware(routing); +const publicPages = NAV_ITEMS.flatMap((item) => [ + ...(!item.protected ? [item.href] : []), + ...(item.children + ?.filter((child) => !child.protected) + .map((child) => child.href) ?? []), +]); -const publicPaths = ['/signin', '/signup', '/forgot-password', '/reset-password']; -const localizedPublicPaths = routing.locales.flatMap((locale) => publicPaths.map((path) => `/${locale}${path}`)); -const allPublicPaths = [...publicPaths, ...localizedPublicPaths]; +const handleI18nRouting = createMiddleware(routing); -export default withAuth( - async function middleware(req) { - const intlResponse = intlMiddleware(req); - if (intlResponse) return intlResponse; - - const token = req.nextauth?.token; - const { pathname } = req.nextUrl; - - // Kullanıcı giriş yaptıysa ve public bir sayfadaysa → home'a yönlendir - if (token && allPublicPaths.some((p) => pathname.startsWith(p))) { - const redirectUrl = new URL(`/${routing.defaultLocale}/home`, req.url); - return NextResponse.redirect(redirectUrl); - } - - return NextResponse.next(); +const authMiddleware = withAuth( + // Note that this callback is only invoked if + // the `authorized` callback has returned `true` + // and not for pages listed in `pages`. + function onSuccess(req) { + return handleI18nRouting(req); }, { - pages: { - signIn: `/${routing.defaultLocale}/signin`, - }, callbacks: { - /** - * Eğer public route'taysa -> yetkilendirme kontrolü atla - * Aksi halde -> token gerekli - */ - authorized: ({ token, req }) => { - const { pathname } = req.nextUrl; - if (allPublicPaths.some((p) => pathname.startsWith(p))) { - return true; // public sayfa, izin ver - } - return !!token; // diğerleri için token gerekli - }, + authorized: ({ token }) => token != null, + }, + pages: { + signIn: "/home", }, }, ); +export default function proxy(req: NextRequest) { + // CRITICAL: Skip API routes entirely - they should not go through i18n or auth middleware + if (req.nextUrl.pathname.startsWith("/api/")) { + return; // Return undefined to pass through without modification + } + + const publicPathnameRegex = RegExp( + `^(/(${routing.locales.join("|")}))?(${publicPages.flatMap((p) => (p === "/" ? ["", "/"] : p)).join("|")})/?$`, + "i", + ); + const isPublicPage = publicPathnameRegex.test(req.nextUrl.pathname); + + if (isPublicPage) { + return handleI18nRouting(req); + } else { + return (authMiddleware as any)(req); + } +} + export const config = { - matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)'], + matcher: "/((?!api|trpc|_next|_vercel|.*\\..*).*)", + // matcher: ['/', '/(de|en|tr)/:path*'], };