import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export async function middleware(request: NextRequest) { const hostname = request.headers.get('host') || ''; const url = request.nextUrl; const apiBase = process.env.API_INTERNAL_URL || 'http://backend:8080'; // Extrair subdomínio (remover porta se houver) const hostnameWithoutPort = hostname.split(':')[0]; const subdomain = hostnameWithoutPort.split('.')[0]; // Rotas públicas que não precisam de validação de tenant const publicPaths = ['/login', '/cadastro', '/']; const isPublicPath = publicPaths.some(path => url.pathname === path || url.pathname.startsWith(path + '/')); // Validar subdomínio de agência ({subdomain}.localhost) apenas se não for rota pública if (hostname.includes('.') && !isPublicPath) { try { const res = await fetch(`${apiBase}/api/tenant/check?subdomain=${subdomain}`, { cache: 'no-store', headers: { 'Content-Type': 'application/json', } }); if (!res.ok) { console.error(`Tenant check failed for ${subdomain}: ${res.status}`); // Se for 404, realmente não existe. Se for 500, pode ser erro temporário. // Por segurança, vamos redirecionar apenas se tivermos certeza que falhou a validação (ex: 404) // ou se o backend estiver inalcançável de forma persistente. // Para evitar loops durante desenvolvimento, vamos permitir passar se for erro de servidor (5xx) // mas redirecionar se for 404. if (res.status === 404) { const baseHost = hostname.split('.').slice(1).join('.') || hostname; const redirectUrl = new URL(url.toString()); redirectUrl.hostname = baseHost; redirectUrl.pathname = '/'; return NextResponse.redirect(redirectUrl); } } } catch (err) { console.error('Middleware error:', err); // Em caso de erro de rede (backend fora do ar), permitir carregar a página // para não travar o frontend completamente (pode mostrar erro na tela depois) // return NextResponse.next(); } } // Para requisições de API, adicionar headers com informações do tenant if (url.pathname.startsWith('/api/')) { // Cria um header customizado com o subdomain const requestHeaders = new Headers(request.headers); requestHeaders.set('X-Tenant-Subdomain', subdomain); requestHeaders.set('X-Original-Host', hostname); return NextResponse.rewrite(url, { request: { headers: requestHeaders, }, }); } // Permitir acesso normal return NextResponse.next(); } export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ '/((?!_next/static|_next/image|favicon.ico).*)', ], };