feat: integrate Better Auth and enhance authentication flow

- Added Better Auth integration to the web application, allowing for dual login support with both custom and Better Auth systems.
- Updated authentication client configuration to dynamically set the base URL based on the environment.
- Enhanced chat components to utilize user authentication status, improving user experience and security.
- Refactored various components to support Better Auth, including error handling and user identity management.
- Improved notification handling and user feedback mechanisms during authentication processes.
This commit is contained in:
2025-11-06 09:35:36 -03:00
parent 33f305220b
commit 06f03b53e5
28 changed files with 4109 additions and 436 deletions

View File

@@ -18,31 +18,46 @@ function normalizarTextoParaBusca(texto: string): string {
}
/**
* Helper function para obter usuário autenticado (Better Auth ou Sessão)
* Helper function para obter usuário autenticado
*
* FASE 1 IMPLEMENTADA: Usa Custom Auth Provider configurado no convex.config.ts
*
* O provider tenta:
* 1. Buscar sessão customizada por token (sistema atual) ✅ FUNCIONANDO
* 2. Validar via Better Auth (quando configurado) ⏳ PRÓXIMA FASE
*
* ⚠️ CORREÇÃO DE SEGURANÇA: Busca sessão por token específico (não mais recente)
*/
async function getUsuarioAutenticado(ctx: QueryCtx | MutationCtx) {
// Tentar autenticação via Better Auth primeiro
// Tentar autenticação via Custom Auth Provider (convex.config.ts)
// Isso funciona tanto com tokens customizados quanto com Better Auth
const identity = await ctx.auth.getUserIdentity();
let usuarioAtual = null;
if (identity && identity.email) {
// Buscar usuário por email (vindo do provider)
usuarioAtual = await ctx.db
.query("usuarios")
.withIndex("by_email", (q) => q.eq("email", identity.email!))
.first();
if (usuarioAtual) {
// Log para debug (apenas em desenvolvimento)
if (process.env.NODE_ENV === "development") {
console.log("✅ [getUsuarioAutenticado] Usuário identificado via Custom Auth Provider:", {
id: usuarioAtual._id,
nome: usuarioAtual.nome,
email: usuarioAtual.email,
subject: identity.subject
});
}
return usuarioAtual;
}
}
// Se não encontrou via Better Auth, tentar via sessão mais recente
// Se não encontrou, logar aviso
if (!usuarioAtual) {
const sessaoAtiva = await ctx.db
.query("sessoes")
.filter((q) => q.eq(q.field("ativo"), true))
.order("desc")
.first();
if (sessaoAtiva) {
usuarioAtual = await ctx.db.get(sessaoAtiva.usuarioId);
}
console.warn("⚠️ [getUsuarioAutenticado] Usuário não autenticado - token inválido ou expirado");
}
return usuarioAtual;
@@ -305,7 +320,19 @@ export const enviarMensagem = mutation({
},
handler: async (ctx, args) => {
const usuarioAtual = await getUsuarioAutenticado(ctx);
if (!usuarioAtual) throw new Error("Não autenticado");
if (!usuarioAtual) {
console.error("❌ [enviarMensagem] Usuário não autenticado - Better Auth não conseguiu identificar");
throw new Error("Não autenticado");
}
// Log para debug (apenas em desenvolvimento)
if (process.env.NODE_ENV === "development") {
console.log("✅ [enviarMensagem] Usuário identificado:", {
id: usuarioAtual._id,
nome: usuarioAtual.nome,
email: usuarioAtual.email
});
}
// Verificar se usuário pertence à conversa
const conversa = await ctx.db.get(args.conversaId);