package controllers import ( "fmt" "log" "strconv" "github.com/gofiber/fiber/v2" "github.com/sujit-baniya/fiber-boilerplate/pkg/models" "github.com/sujit-baniya/fiber-boilerplate/pkg/services" ) // GetUmindConexionesHandler lista las cuentas de correo conectadas de un // agente, sin exponer los tokens (ni cifrados ni en claro). func GetUmindConexionesHandler(c *fiber.Ctx) error { agenteID, err := strconv.ParseUint(c.Query("agente_id"), 10, 64) if err != nil || agenteID == 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "agente_id requerido"}) } if _, err := accesoAgente(c, uint(agenteID)); err != nil { return err } items, err := models.GetUmindConexionesByAgente(uint(agenteID)) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } out := make([]fiber.Map, len(items)) for i, cx := range items { out[i] = fiber.Map{ "ID": cx.ID, "agente_id": cx.AgenteID, "proveedor": cx.Proveedor, "email": cx.Email, "activo": cx.Activo, "expira_en": cx.ExpiraEn, } } return c.JSON(fiber.Map{"items": out}) } // UmindConectarHandler redirige al staff a la pantalla de consentimiento de // Google/Microsoft. Ruta: GET /app/umind/conexiones/conectar?agente_id=&proveedor= func UmindConectarHandler(c *fiber.Ctx) error { agenteID, err := strconv.ParseUint(c.Query("agente_id"), 10, 64) if err != nil || agenteID == 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "agente_id requerido"}) } proveedor := c.Query("proveedor") if _, err := accesoAgente(c, uint(agenteID)); err != nil { return err } url, err := services.IniciarConexionOAuth(proveedor, uint(agenteID)) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()}) } return c.Redirect(url, fiber.StatusFound) } // UmindOAuthCallbackHandler recibe la vuelta de Google/Microsoft, intercambia // el code y redirige al staff de vuelta a la SPA. // Ruta: GET /app/umind/conexiones/callback/:proveedor func UmindOAuthCallbackHandler(c *fiber.Ctx) error { proveedor := c.Params("proveedor") if errParam := c.Query("error"); errParam != "" { return c.Redirect(fmt.Sprintf("/studio/?oauth_error=%s", errParam), fiber.StatusFound) } code := c.Query("code") state := c.Query("state") if code == "" || state == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "callback inválido"}) } conexion, err := services.CompletarConexionOAuth(proveedor, code, state) if err != nil { log.Printf("[UMIND_OAUTH] error completando conexión (%s): %v", proveedor, err) return c.Redirect("/studio/?oauth_error=1", fiber.StatusFound) } agente, err := models.GetUmindAgenteByID(conexion.AgenteID) if err != nil { return c.Redirect("/studio/?oauth_error=1", fiber.StatusFound) } return c.Redirect(fmt.Sprintf("/studio/tenants/%d/agentes/%d?tab=conexiones", agente.TenantID, agente.ID), fiber.StatusFound) } func DeleteUmindConexionHandler(c *fiber.Ctx) error { id, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "id inválido"}) } if err := accesoConexion(c, uint(id)); err != nil { return err } if err := models.DeleteUmindConexion(uint(id)); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"ok": true}) }