Pular para o conteúdo

Autenticação

O Juca usa NextAuth v5 (Auth.js) para autenticação com sessões baseadas em JWT. Dois provedores de autenticação estão configurados: Google OAuth e magic links via Resend (e-mail).

O sistema de autenticação é definido em src/lib/auth.ts:

// Exports
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [Google, Resend],
session: { strategy: 'jwt' },
pages: { signIn: '/auth/signin' },
// ...
});

Variáveis de ambiente obrigatórias para produção:

VariávelPropósito
GOOGLE_CLIENT_IDClient ID do Google OAuth
GOOGLE_CLIENT_SECRETClient secret do Google OAuth
AUTH_SECRETSegredo JWT do NextAuth
RESEND_API_KEYChave de API do Resend para e-mails de magic link
AUTH_EMAIL_FROME-mail de remetente para magic links
ADMIN_EMAILSLista de e-mails de administradores separados por vírgula

Para desenvolvimento local, defina ENABLE_DEV_AUTH=true para ignorar a autenticação completamente. Isso retorna um usuário dev fixo:

// Usuário dev retornado quando ENABLE_DEV_AUTH=true
{ id: 'dev-user', email: 'dev@localhost', name: 'Dev User', role: 'admin' }

O Juca usa dois padrões distintos de autenticação dependendo do contexto:

src/actions/utils.ts
import { requireActionAuth } from '@/actions/utils';
// Em qualquer server action:
const user = await requireActionAuth();
// Lança erro se não autenticado (exceto se ENABLE_DEV_AUTH=true)
// Em qualquer handler de rota de API:
import { auth } from '@/lib/auth';
export async function GET(request: Request) {
const session = await auth();
if (!session?.user) return new Response('Unauthorized', { status: 401 });
// ...
}

Os usuários administradores são determinados pela variável de ambiente ADMIN_EMAILS (separados por vírgula, sem distinção de maiúsculas/minúsculas). A função isAdmin() verifica a pertinência, e o callback do JWT adiciona um campo role ao token.

O middleware de autenticação (src/middleware.ts) protege todas as rotas exceto assets estáticos e o endpoint de health check:

src/middleware.ts
export { auth as middleware } from '@/lib/auth';
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|icons|manifest.json|sw.js).*)']
};
ComponenteLocalizaçãoPropósito
AuthProvidersrc/components/auth/AuthProvider.tsxWrapper do SessionProvider do NextAuth
Página de loginsrc/app/auth/signin/page.tsxUI de login personalizada