This commit is contained in:
Lizandro Guarnizo
2026-05-16 21:05:05 -05:00
parent 605ff74cc8
commit fcc3ff7ca7
4 changed files with 347 additions and 0 deletions
+115
View File
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/app"
"github.com/sujit-baniya/fiber-boilerplate/pkg/auth"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
@@ -391,3 +392,117 @@ func PortalMarcarTicketLeido(c *fiber.Ctx) error {
_ = models.MarkTicketMessagesReadByPortal(uint(ticketID))
return c.JSON(fiber.Map{"ok": true})
}
// ─── Mi Perfil ────────────────────────────────────────────────────────────────
// GET /portal/mi-perfil — devuelve datos del usuario autenticado
func PortalGetMiPerfil(c *fiber.Ctx) error {
u := middlewares.PortalUserFromLocals(c)
if u == nil {
return c.Status(401).JSON(fiber.Map{"error": "no autenticado"})
}
full, err := models.GetPortalUserByID(u.ID)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "error al obtener perfil"})
}
return c.JSON(fiber.Map{
"id": full.ID,
"nombre": full.Nombre,
"email": full.Email,
"telefono": full.Telefono,
"indicativo": full.Indicativo,
"pais": full.Pais,
"documento": full.Documento,
"empresa": full.Empresa,
})
}
// PUT /portal/mi-perfil — actualiza datos del usuario autenticado
func PortalUpdateMiPerfil(c *fiber.Ctx) error {
u := middlewares.PortalUserFromLocals(c)
if u == nil {
return c.Status(401).JSON(fiber.Map{"error": "no autenticado"})
}
type Req struct {
Nombre string `json:"nombre"`
Email string `json:"email"`
Telefono string `json:"telefono"`
Indicativo string `json:"indicativo"`
Pais string `json:"pais"`
Documento string `json:"documento"`
Empresa string `json:"empresa"`
}
var req Req
if err := c.BodyParser(&req); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Datos inválidos"})
}
req.Nombre = strings.TrimSpace(req.Nombre)
req.Email = strings.TrimSpace(req.Email)
if req.Nombre == "" {
return c.Status(400).JSON(fiber.Map{"error": "El nombre es requerido"})
}
if req.Email == "" {
return c.Status(400).JSON(fiber.Map{"error": "El email es requerido"})
}
// Verificar que el email no lo use otro usuario
existing, err := models.GetPortalUserByEmail(req.Email)
if err == nil && existing.ID != u.ID {
return c.Status(400).JSON(fiber.Map{"error": "El email ya está en uso"})
}
full, err := models.GetPortalUserByID(u.ID)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "Usuario no encontrado"})
}
full.Nombre = req.Nombre
full.Email = req.Email
full.Telefono = req.Telefono
full.Indicativo = req.Indicativo
full.Pais = req.Pais
full.Documento = req.Documento
full.Empresa = req.Empresa
if err := models.UpdatePortalUser(full); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true})
}
// PUT /portal/mi-perfil/password — cambia la contraseña del usuario autenticado
func PortalCambiarPassword(c *fiber.Ctx) error {
u := middlewares.PortalUserFromLocals(c)
if u == nil {
return c.Status(401).JSON(fiber.Map{"error": "no autenticado"})
}
type Req struct {
Actual string `json:"actual"`
Nueva string `json:"nueva"`
Confirma string `json:"confirma"`
}
var req Req
if err := c.BodyParser(&req); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Datos inválidos"})
}
if strings.TrimSpace(req.Nueva) == "" {
return c.Status(400).JSON(fiber.Map{"error": "La nueva contraseña no puede estar vacía"})
}
if req.Nueva != req.Confirma {
return c.Status(400).JSON(fiber.Map{"error": "Las contraseñas no coinciden"})
}
if len(req.Nueva) < 8 {
return c.Status(400).JSON(fiber.Map{"error": "La contraseña debe tener al menos 8 caracteres"})
}
full, err := models.GetPortalUserByID(u.ID)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "Usuario no encontrado"})
}
if match, matchErr := app.Http.Hash.Match(req.Actual, full.Password); matchErr != nil || !match {
return c.Status(400).JSON(fiber.Map{"error": "La contraseña actual es incorrecta"})
}
hashed, err := app.Http.Hash.Create(req.Nueva)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "Error al procesar contraseña"})
}
if err := models.UpdatePortalUserPassword(u.ID, hashed); err != nil {
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true})
}
+5
View File
@@ -40,4 +40,9 @@ func PortalRoutes(app fiber.Router) {
portal.Get("/partner-recursos", middlewares.PortalPartnerOnly(), controllers.PortalPartnerRecursos)
portal.Get("/partner-recursos/:id/download", middlewares.PortalPartnerOnly(), controllers.PortalDownloadPartnerRecurso)
portal.Get("/partner-comunicados/:id/download", middlewares.PortalPartnerOnly(), controllers.DownloadPartnerComunicadoArchivo)
// Mi perfil
portal.Get("/mi-perfil", controllers.PortalGetMiPerfil)
portal.Put("/mi-perfil", controllers.PortalUpdateMiPerfil)
portal.Put("/mi-perfil/password", controllers.PortalCambiarPassword)
}