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 // tenant, sin exponer los tokens (ni cifrados ni en claro). func GetUmindConexionesHandler(c *fiber.Ctx) error { tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 64) if err != nil || tenantID == 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "tenant_id requerido"}) } items, err := models.GetUmindConexionesByTenant(uint(tenantID)) 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, "tenant_id": cx.TenantID, "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?tenant_id=&proveedor= func UmindConectarHandler(c *fiber.Ctx) error { tenantID, err := strconv.ParseUint(c.Query("tenant_id"), 10, 64) if err != nil || tenantID == 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "tenant_id requerido"}) } proveedor := c.Query("proveedor") if _, err := models.GetUmindTenantByID(uint(tenantID)); err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "tenant no encontrado"}) } url, err := services.IniciarConexionOAuth(proveedor, uint(tenantID)) 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("/orchestrator/?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("/orchestrator/?oauth_error=1", fiber.StatusFound) } return c.Redirect(fmt.Sprintf("/orchestrator/tenants/%d?tab=conexiones", conexion.TenantID), 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 := models.DeleteUmindConexion(uint(id)); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) } return c.JSON(fiber.Map{"ok": true}) }