qr vcard
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/png"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/chai2010/webp"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/app"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/helpers"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
||||
"gorm.io/gorm"
|
||||
// Importa el repositorio
|
||||
)
|
||||
|
||||
func CreateQr(c *fiber.Ctx) error {
|
||||
var data services.ContactData
|
||||
if err := json.Unmarshal(c.Body(), &data); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Datos inválidos",
|
||||
})
|
||||
}
|
||||
|
||||
// 1. Generar el QR en formato PNG
|
||||
qrBytes, err := services.GenerateVCardQR(data)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "No se pudo generar el QR",
|
||||
})
|
||||
}
|
||||
|
||||
// 2. Decodificar PNG
|
||||
img, err := png.Decode(bytes.NewReader(qrBytes))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error al decodificar QR PNG",
|
||||
})
|
||||
}
|
||||
|
||||
// 3. Convertir a WebP
|
||||
var webpBuf bytes.Buffer
|
||||
if err := webp.Encode(&webpBuf, img, nil); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error al convertir QR a WebP",
|
||||
})
|
||||
}
|
||||
|
||||
random := helpers.RandomString(4)
|
||||
fileName := fmt.Sprintf("qrs/qr-%s-%s.webp", data.FirstName, random)
|
||||
tmpPath := fmt.Sprintf("/tmp/%s.webp", data.FirstName)
|
||||
|
||||
// 4. Guardar archivo temporal
|
||||
if err := os.WriteFile(tmpPath, webpBuf.Bytes(), 0644); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "No se pudo guardar el QR temporalmente",
|
||||
})
|
||||
}
|
||||
defer os.Remove(tmpPath)
|
||||
|
||||
// 5. Subir a OSS
|
||||
ossService, err := services.NewOSSServiceFromDB()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error de conexión con OSS",
|
||||
})
|
||||
}
|
||||
|
||||
if err := ossService.UploadFile(fileName, tmpPath); err != nil {
|
||||
log.Printf("Error subiendo archivo a OSS: %v", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error subiendo archivo a OSS",
|
||||
})
|
||||
}
|
||||
|
||||
// 6. URL del archivo
|
||||
url := fmt.Sprintf("https://%s.%s/%s", ossService.BucketName, ossService.Endpoint, fileName)
|
||||
|
||||
// 7. Buscar si ya existe un registro con ese vcard_id
|
||||
var existing models.QrVcard
|
||||
db := app.Http.Database.DB
|
||||
|
||||
err = db.Where("vcard_id = ?", data.VcardID).First(&existing).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// No existe, crear nuevo
|
||||
newQr := models.QrVcard{
|
||||
Qr: url,
|
||||
UsuarioID: data.FirstName,
|
||||
Email: data.Email,
|
||||
VcardID: data.VcardID,
|
||||
}
|
||||
if err := models.CreateQrVcard(&newQr); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error al guardar nuevo QR en la base de datos",
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Otro error
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error al consultar la base de datos",
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Ya existe, actualizar
|
||||
existing.Qr = url
|
||||
existing.UsuarioID = data.FirstName
|
||||
existing.Email = data.Email
|
||||
|
||||
if err := models.UpdateQrVcard(&existing); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error al actualizar el QR en la base de datos",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Retornar la URL
|
||||
return c.JSON(fiber.Map{
|
||||
"url": url,
|
||||
})
|
||||
}
|
||||
|
||||
func CreateQrTmp(c *fiber.Ctx) error {
|
||||
var data services.ContactData
|
||||
if err := json.Unmarshal(c.Body(), &data); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Datos inválidos",
|
||||
})
|
||||
}
|
||||
|
||||
qrBytes, err := services.GenerateVCardQR(data)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "No se pudo generar el QR",
|
||||
})
|
||||
}
|
||||
|
||||
// Decodificar PNG
|
||||
img, err := png.Decode(bytes.NewReader(qrBytes))
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "No se pudo procesar la imagen",
|
||||
})
|
||||
}
|
||||
|
||||
// Codificar a WebP
|
||||
var webpBuffer bytes.Buffer
|
||||
if err := webp.Encode(&webpBuffer, img, &webp.Options{Lossless: true}); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "No se pudo convertir a WebP",
|
||||
})
|
||||
}
|
||||
|
||||
c.Type("webp")
|
||||
return c.Send(webpBuffer.Bytes())
|
||||
}
|
||||
@@ -80,52 +80,29 @@ func ReenvioEmail(c *fiber.Ctx) error {
|
||||
|
||||
// Función para manejar la solicitud de restablecimiento de contraseña
|
||||
func RequestPasswordResetPost(c *fiber.Ctx) error {
|
||||
// Crear una estructura para mapear los datos entrantes
|
||||
type Request struct {
|
||||
NombreUsuario string `json:"nombre_usuario"` // Mapeo con la clave del JSON
|
||||
}
|
||||
|
||||
var req Request
|
||||
|
||||
// Parsear el cuerpo JSON de la solicitud
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"success": false,
|
||||
"message": "Invalid JSON format",
|
||||
})
|
||||
}
|
||||
|
||||
// Obtener el usuario del JSON parseado
|
||||
usuario := req.NombreUsuario
|
||||
usuario := c.FormValue("nombre_usuario")
|
||||
fmt.Println("Usuario recibido:", usuario)
|
||||
|
||||
// Intentar obtener el usuario por nombre de usuario
|
||||
user, err := models.GetUserByUsuario(usuario)
|
||||
|
||||
if err != nil || user == nil {
|
||||
// Devolver respuesta de error en formato JSON
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"success": false,
|
||||
"message": "Usuario inactivo o no existente",
|
||||
})
|
||||
}
|
||||
|
||||
// Obtener el email del usuario
|
||||
usuario_email := user.Email
|
||||
|
||||
// Imprimir el email en la consola
|
||||
log.Println("Sending password reset email to:", usuario_email)
|
||||
|
||||
// Enviar el correo de restablecimiento de contraseña de forma asíncrona
|
||||
go services.SendPasswordResetEmail(usuario_email, app.Http.Server.Url)
|
||||
|
||||
// Devolver respuesta de éxito en formato JSON
|
||||
return c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "We've sent an email to reset your password to your registered email address",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// todo: Generar contrasenas aleatorias /do/generate-password
|
||||
func generatePassword(length int) (string, error) {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
||||
)
|
||||
|
||||
type TelegramController struct {
|
||||
Service *services.TelegramService
|
||||
}
|
||||
|
||||
func NewTelegramController(service *services.TelegramService) *TelegramController {
|
||||
return &TelegramController{Service: service}
|
||||
}
|
||||
|
||||
func (tc *TelegramController) SendMessage(chatID interface{}, message string) error {
|
||||
if chatID == "" || message == "" {
|
||||
return fmt.Errorf("chat_id and message are required")
|
||||
}
|
||||
|
||||
err := tc.Service.SendMessage(chatID, message)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error sending message: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -261,12 +261,27 @@ func AuthAdmin(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func AuthApi() func(*fiber.Ctx) error {
|
||||
return Authenticate(AuthConfig{
|
||||
SigningKey: []byte(app.Http.Token.ApiJwtSecret),
|
||||
TokenLookup: "header:Verify-Rest-Token",
|
||||
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
|
||||
auth.Logout(ctx)
|
||||
return ctx.Status(401).JSON("Invalid Attempt")
|
||||
},
|
||||
})
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Excluir rutas públicas
|
||||
if c.Path() == "/api/v1/oauth/token" {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Obtener el token de la cookie "Verify-Rest-Token"
|
||||
token := c.Cookies("Verify-Rest-Token")
|
||||
if token == "" {
|
||||
// Si no hay token, regresar un error
|
||||
return c.Status(401).JSON("Token not found")
|
||||
}
|
||||
|
||||
// Continuar con la verificación JWT para otras rutas
|
||||
return Authenticate(AuthConfig{
|
||||
SigningKey: []byte(app.Http.Token.ApiJwtSecret),
|
||||
TokenLookup: "cookie:Verify-Rest-Token", // Ahora se busca en la cookie
|
||||
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
|
||||
auth.Logout(ctx)
|
||||
return ctx.Status(401).JSON("Invalid Attempt")
|
||||
},
|
||||
})(c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ func ApiRoutes(api fiber.Router) {
|
||||
|
||||
func v1AuthRoutes(api fiber.Router) {
|
||||
api.Post("/oauth/token", apiControllers.OAuthToken)
|
||||
api.Post("/generate-qr-tmp", apiControllers.CreateQrTmp)
|
||||
api.Post("/generate-qr", apiControllers.CreateQr)
|
||||
|
||||
}
|
||||
|
||||
func v1Routes(api fiber.Router) {
|
||||
|
||||
+6
-6
@@ -8,10 +8,10 @@ import (
|
||||
)
|
||||
|
||||
func WebAuthRoutes(App fiber.Router) {
|
||||
//App.Get("/login",
|
||||
// middlewares.RedirectToHomePageOnLogin,
|
||||
// controllers.LoginGet,
|
||||
//)
|
||||
App.Get("/login",
|
||||
middlewares.RedirectToHomePageOnLogin,
|
||||
controllers.LoginGet,
|
||||
)
|
||||
App.Post("/do/login",
|
||||
middlewares.ValidateLoginPost,
|
||||
controllers.LoginPost,
|
||||
@@ -39,10 +39,10 @@ func WebAuthRoutes(App fiber.Router) {
|
||||
)
|
||||
// Generar contraseñas aleatorias /do/generate-password
|
||||
App.Post("/do/generate-password",
|
||||
controllers.GeneratePasswordPost,
|
||||
controllers.GeneratePasswordPost,
|
||||
)
|
||||
|
||||
//App.Get("/request-password-reset", middlewares.RedirectToHomePageOnLogin, controllers.RequestPasswordReset)
|
||||
App.Get("/request-password-reset", middlewares.RedirectToHomePageOnLogin, controllers.RequestPasswordReset)
|
||||
App.Post("/do/password-reset/:token",
|
||||
middlewares.RedirectToHomePageOnLogin,
|
||||
middlewares.ValidatePasswordResetPost,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func RutasPublicas(web fiber.Router) {
|
||||
//web.Get("/", controllers.Landing)
|
||||
web.Get("/index", controllers.Index)
|
||||
web.Get("/login", controllers.Login)
|
||||
//web.Get("/login", controllers.Login)
|
||||
web.Get("/ping", Pong)
|
||||
web.Get("/all-routes", AllRoutes)
|
||||
web.Get("/do/verify-email", middlewares.ValidateConfirmToken, controllers.VerifyRegisteredEmail)
|
||||
|
||||
@@ -2,12 +2,13 @@ package routes
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/rest/middlewares"
|
||||
)
|
||||
|
||||
func LoadRoutes(app *fiber.App) {
|
||||
// Grupo de rutas de la API con autenticación
|
||||
//api := app.Group("/api").Use(middlewares.AuthApi())
|
||||
//ApiRoutes(api)
|
||||
api := app.Group("/api").Use(middlewares.AuthApi())
|
||||
ApiRoutes(api)
|
||||
|
||||
// Grupo de rutas web (sin autenticación)
|
||||
web := app.Group("")
|
||||
|
||||
+19
-14
@@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/rest/controllers"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/rest/middlewares"
|
||||
)
|
||||
@@ -55,28 +56,28 @@ func UserRoutes(app fiber.Router) {
|
||||
|
||||
// Rutas de conexiones ssh
|
||||
protected.Get("/conexion_ssh", middlewares.MenuMiddleware, controllers.ConxSsh) // Renderizar la vista
|
||||
protected.Get("/loadconexionssh", controllers.GetConxSsh) // Obtener
|
||||
protected.Post("/conexionssh", controllers.CreateConxSsh) // Crear
|
||||
protected.Put("/conexionssh/:id", controllers.UpdateConxSsh) // Actualizar
|
||||
protected.Delete("/conexionssh/:id", controllers.DeleteConxSsh) // Eliminar
|
||||
protected.Get("/loadconexionssh", controllers.GetConxSsh) // Obtener
|
||||
protected.Post("/conexionssh", controllers.CreateConxSsh) // Crear
|
||||
protected.Put("/conexionssh/:id", controllers.UpdateConxSsh) // Actualizar
|
||||
protected.Delete("/conexionssh/:id", controllers.DeleteConxSsh) // Eliminar
|
||||
|
||||
// Rutas de conexiones db
|
||||
protected.Get("/conexion_db", middlewares.MenuMiddleware, controllers.ConxDb) // Renderizar la vista
|
||||
protected.Get("/loadconexiondb", controllers.GetConxDb) // Obtener
|
||||
protected.Post("/conexiondb", controllers.CreateConxDb) // Crear
|
||||
protected.Put("/conexiondb/:id", controllers.UpdateConxDb) // Actualizar
|
||||
protected.Delete("/conexiondb/:id", controllers.DeleteConxDb) // Eliminar
|
||||
protected.Get("/loadconexiondb", controllers.GetConxDb) // Obtener
|
||||
protected.Post("/conexiondb", controllers.CreateConxDb) // Crear
|
||||
protected.Put("/conexiondb/:id", controllers.UpdateConxDb) // Actualizar
|
||||
protected.Delete("/conexiondb/:id", controllers.DeleteConxDb) // Eliminar
|
||||
|
||||
// Rutas de servidor
|
||||
protected.Get("/servidor", middlewares.MenuMiddleware, controllers.Servidor)
|
||||
protected.Get("/loadservidorselect", controllers.GetServidor)
|
||||
protected.Get("/loadservidor", controllers.GetServidor)
|
||||
protected.Post("/servidor", controllers.CreateServidor)
|
||||
protected.Put("/servidor/:id", controllers.UpdateServidor)
|
||||
protected.Delete("/servidor/:id", controllers.DeleteServidor)
|
||||
protected.Get("/loadservidorselect", controllers.GetServidor)
|
||||
protected.Get("/loadservidor", controllers.GetServidor)
|
||||
protected.Post("/servidor", controllers.CreateServidor)
|
||||
protected.Put("/servidor/:id", controllers.UpdateServidor)
|
||||
protected.Delete("/servidor/:id", controllers.DeleteServidor)
|
||||
|
||||
// Rutas de proveedores de servidor
|
||||
protected.Get("/prov_servidor", middlewares.MenuMiddleware, controllers.ProvServidor)
|
||||
protected.Get("/prov_servidor", middlewares.MenuMiddleware, controllers.ProvServidor)
|
||||
protected.Get("/loadprovservidor", controllers.GetProvServidor)
|
||||
protected.Post("/provservidor", controllers.CreateProvServidor)
|
||||
protected.Put("/provservidor/:id", controllers.UpdateProvServidor)
|
||||
@@ -96,4 +97,8 @@ func UserRoutes(app fiber.Router) {
|
||||
protected.Put("/tipodb/:id", controllers.UpdateTipoDb)
|
||||
protected.Delete("/tipodb/:id", controllers.DeleteTipoDb)
|
||||
|
||||
protected.Get("/ws/ssh/:id", websocket.New(controllers.WSConnectSSH))
|
||||
protected.Get("/ssh/:id", controllers.ConnectSSHview)
|
||||
protected.Get("/terminal", controllers.Terminal)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user