import { defineApp, defineAuth } from "convex/server"; import betterAuth from "@convex-dev/better-auth/convex.config"; /** * Custom Auth Provider para aceitar tokens customizados * * Este provider funciona junto com Better Auth para suportar: * 1. Tokens customizados do sistema atual (via sessoes) * 2. Tokens do Better Auth (quando configurado) */ const customAuth = defineAuth({ getToken: async (request: Request): Promise => { // Tentar obter token de várias fontes // 1. Authorization header (Bearer token) const authHeader = request.headers.get("authorization"); if (authHeader?.startsWith("Bearer ")) { return authHeader.substring(7); } // 2. x-auth-token header const xAuthToken = request.headers.get("x-auth-token"); if (xAuthToken) { return xAuthToken; } // 3. Query parameter (para WebSocket) const url = new URL(request.url); const queryToken = url.searchParams.get("authToken"); if (queryToken) { return queryToken; } return null; }, getIdentity: async (ctx, token: string) => { if (!token) return null; // Buscar sessão ativa por token const sessao = await ctx.db .query("sessoes") .withIndex("by_token", (q) => q.eq("token", token)) .filter((q) => q.eq(q.field("ativo"), true)) .first(); if (!sessao) return null; // Buscar usuário da sessão const usuario = await ctx.db.get(sessao.usuarioId); if (!usuario || !usuario.ativo) return null; // Retornar identity compatível com Better Auth return { subject: usuario._id, email: usuario.email, emailVerified: true, name: usuario.nome, }; }, }); /** * Configuração Better Auth para Convex * * Usando Better Auth oficialmente integrado com Convex. * O Custom Auth Provider acima funciona junto com Better Auth para suportar tokens customizados. */ const app = defineApp(); app.use(customAuth); app.use(betterAuth); export default app;