Adiciona o frontend Next.js em frontend/ (setup, design system, autenticação/tema, layout/navegação, área master, área tenant completa: clientes, produtos, vendas, recebimentos, whatsapp, e-mail, alertas, equipe e perfil). Estende o backend de forma aditiva e autorizada: cookie httpOnly para refresh token (Etapa 13) e CRUD de equipe + edição de perfil do tenant (Etapa 18, módulo src/modules/equipe/ novo e PUT /tenant/perfil). Detalhes completos em Etapas/V2/*. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { SESSION_COOKIE, type SessionArea } from '@/lib/auth/session-cookie';
|
|
|
|
/**
|
|
* Proteção de rotas (Etapa 13). Verifica só a *presença* do cookie de
|
|
* sinalização `sc_session` (não sensível, setado pelo frontend após
|
|
* login) — o access token real fica em memória no client, invisível
|
|
* aqui, e o refresh token httpOnly pertence ao backend (`Path=/auth`,
|
|
* outra origem), também invisível ao middleware. Por isso esta é uma
|
|
* checagem otimista: evita o "flash" de conteúdo protegido, mas quem
|
|
* decide de verdade é o backend em cada chamada de API.
|
|
*/
|
|
export function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl;
|
|
const area = request.cookies.get(SESSION_COOKIE)?.value as SessionArea | undefined;
|
|
|
|
const isMasterRoute = pathname.startsWith('/master');
|
|
const isTenantRoute = pathname.startsWith('/app');
|
|
|
|
if (!area && (isMasterRoute || isTenantRoute)) {
|
|
const loginUrl = new URL('/login', request.url);
|
|
loginUrl.searchParams.set('redirect', pathname);
|
|
return NextResponse.redirect(loginUrl);
|
|
}
|
|
|
|
if (area === 'tenant' && isMasterRoute) {
|
|
return NextResponse.redirect(new URL('/app/dashboard', request.url));
|
|
}
|
|
|
|
if (area === 'master' && isTenantRoute) {
|
|
return NextResponse.redirect(new URL('/master/dashboard', request.url));
|
|
}
|
|
|
|
return NextResponse.next();
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ['/master/:path*', '/app/:path*'],
|
|
};
|