- middleware: torna /machines/handshake público para permitir criação de sessão de máquina sem login prévio - nav-user: oculta botão 'Encerrar sessão' quando a sessão é de máquina (role === 'machine') Efeito: no app desktop (Tauri), o handshake passa a autenticar corretamente, o cabeçalho exibe nome/e-mail do colaborador/gestor e o portal permite abrir chamados. Nota: em navegação web comum, 'Sair' permanece visível para usuários humanos.
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server"
|
|
import { getCookieCache } from "better-auth/cookies"
|
|
|
|
// Rotas públicas explícitas (não autenticadas)
|
|
// Permite handshake de máquina sem sessão prévia para criar a sessão de máquina.
|
|
const PUBLIC_PATHS = [/^\/login$/, /^\/machines\/handshake$/]
|
|
// Rotas somente admin
|
|
const ADMIN_ONLY_PATHS = [/^\/admin(?:$|\/)/]
|
|
const APP_HOME = "/dashboard"
|
|
|
|
export async function middleware(request: NextRequest) {
|
|
const { pathname, search } = request.nextUrl
|
|
|
|
if (PUBLIC_PATHS.some((pattern) => pattern.test(pathname))) return NextResponse.next()
|
|
|
|
const session = await getCookieCache(request)
|
|
|
|
if (!session?.user) {
|
|
const redirectUrl = new URL("/login", request.url)
|
|
redirectUrl.searchParams.set("callbackUrl", pathname + search)
|
|
return NextResponse.redirect(redirectUrl)
|
|
}
|
|
|
|
const role = (session.user as { role?: string })?.role?.toLowerCase() ?? "agent"
|
|
|
|
const isAdmin = role === "admin"
|
|
// Em desenvolvimento, evitamos bloquear rotas admin por possíveis diferenças
|
|
// de cache de cookie/sessão entre dev server e middleware. Em produção, aplica o gate.
|
|
if (
|
|
process.env.NODE_ENV === "production" &&
|
|
!isAdmin &&
|
|
ADMIN_ONLY_PATHS.some((pattern) => pattern.test(pathname))
|
|
) {
|
|
return NextResponse.redirect(new URL(APP_HOME, request.url))
|
|
}
|
|
|
|
return NextResponse.next()
|
|
}
|
|
|
|
export const config = {
|
|
runtime: "nodejs",
|
|
// Evita executar para assets e imagens estáticas
|
|
matcher: ["/((?!api|_next/static|_next/image|favicon.ico|icon.png).*)"],
|
|
}
|