chore: fix vulenrability

This commit is contained in:
2026-03-12 21:59:18 +01:00
parent f5902665ec
commit 9cb50bb625
12 changed files with 146 additions and 153 deletions
+25 -50
View File
@@ -49,7 +49,7 @@ func AddProductsBasket(c *gin.Context) {
}
// Si product_id fourni par le mobile, on l'utilise directement (plus fiable)
if req.ProductID > 0 {
if req.ProductID > 0 || req.NameProduct == "" || req.Category == "" {
stock, err := database.GetProductStockByID(req.ProductID)
if err != nil {
log.Printf("❌ [ADD_PANIER] Produit %d non trouvé: %v", req.ProductID, err)
@@ -60,48 +60,22 @@ func AddProductsBasket(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Stock insuffisant", "available": stock})
return
}
if err := database.DecrementProductStockByID(req.ProductID, req.Quantity); err != nil {
log.Printf("❌ [ADD_PANIER] Erreur décrement stock product_id=%d: %v", req.ProductID, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
return
}
panier, err := database.AddProductInBasketByID(req.Username, req.ProductID, req.Quantity)
if err != nil {
log.Printf("❌ [ADD_PANIER] Erreur ajout product_id=%d qty=%.3f: %v", req.ProductID, req.Quantity, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
return
}
if err := database.DecrementProductStockByID(req.ProductID, req.Quantity); err != nil {
log.Printf("❌ [ADD_PANIER] Erreur décrement stock product_id=%d: %v", req.ProductID, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de réserver le stock"})
return
}
c.JSON(http.StatusCreated, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
return
}
// Fallback : recherche par nom+catégorie (compatibilité)
if req.NameProduct == "" || req.Category == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "product_id ou name_product+category requis"})
return
}
stock, err := database.GetProductStock(req.NameProduct, req.Category)
if err != nil {
log.Printf("❌ [ADD_PANIER] Produit '%s'/'%s' non trouvé: %v", req.NameProduct, req.Category, err)
c.JSON(http.StatusNotFound, gin.H{"error": "Produit non trouvé"})
return
}
if stock < req.Quantity {
c.JSON(http.StatusBadRequest, gin.H{"error": "Stock insuffisant", "available": stock})
return
}
panier, err := database.AddProductInBasket(req.Username, req.NameProduct, req.Quantity, req.Category)
if err != nil {
log.Printf("❌ [ADD_PANIER] Erreur ajout '%s': %v", req.NameProduct, err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible d'ajouter le produit au panier", "details": err.Error()})
return
}
if err := database.DecrementProductStock(req.NameProduct, req.Category, req.Quantity); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de réserver le stock"})
return
}
c.JSON(http.StatusCreated, gin.H{"success": true, "message": "Produit ajouté au panier avec succès", "panier": panier})
}
// ============================================
@@ -426,35 +400,36 @@ func ValidateBasket(c *gin.Context) {
log.Printf("✅ [CHECKOUT] Zone OK: %s, total=%.2f€ >= %.2f€, crédit parrainage utilisé: %.2f€", zoneResult.ZoneName, cartTotal, zoneResult.MinAmount, referralUsed)
// ============================================
// 2️⃣ Créer la commande (qui décrémente automatiquement le stock)
// 2️⃣ Débiter le parrainage AVANT la commande (évite double-spend)
// ============================================
if referralUsed > 0 {
if err := database.DebitReferralBalance(usernameStr, referralUsed); err != nil {
log.Printf("❌ [CHECKOUT] Solde parrainage insuffisant pour %s: %v", usernameStr, err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Solde parrainage insuffisant ou déjà utilisé"})
return
}
log.Printf("✅ [CHECKOUT] Crédit parrainage -%.2f€ débité pour %s", referralUsed, usernameStr)
}
command, err := database.CreateCommandWithAddress(usernameStr, req.DeliveryAddress)
if err != nil {
if referralUsed > 0 {
_ = database.RestoreReferralBalance(usernameStr, referralUsed)
}
log.Printf("❌ [CHECKOUT] Erreur création commande: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création commande", "details": err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création commande"})
return
}
commandID := command.ID
log.Printf("✅ [CHECKOUT] Commande %d créée", commandID)
// Débiter le solde parrainage si utilisé
if referralUsed > 0 {
tx, txErr := database.Begin()
if txErr == nil {
if txErr = database.UseClientReferralBalance(tx, usernameStr, referralUsed); txErr != nil {
tx.Rollback()
log.Printf("⚠️ [CHECKOUT] Impossible de débiter le crédit parrainage: %v", txErr)
} else {
tx.Commit()
log.Printf("✅ [CHECKOUT] Crédit parrainage -%.2f€ débité pour %s", referralUsed, usernameStr)
// Stocker le montant de parrainage sur la commande
if err := database.SetCommandReferralUsed(commandID, referralUsed); err != nil {
log.Printf("⚠️ [CHECKOUT] Impossible de sauvegarder referral_used sur commande: %v", err)
}
}
if err := database.SetCommandReferralUsed(commandID, referralUsed); err != nil {
log.Printf("⚠️ [CHECKOUT] Impossible de sauvegarder referral_used sur commande: %v", err)
}
}
log.Printf("✅ [CHECKOUT] Commande %d créée", commandID)
// Notifier immédiatement tous les admins et agents cabine
go database.NotifyAllAdminCabine(commandID, usernameStr, req.DeliveryAddress)