chore: build
Frontend Admin - EAS Build / build (push) Canceled after 0s
Frontend Client - EAS Build / build (push) Canceled after 0s
Backend - Build & Lint / build (push) Failing after 25m18s
Frontend Web - Build & Lint / build (push) Failing after 9m58s

This commit is contained in:
Xor290
2026-08-06 12:06:05 +02:00
parent c034088bee
commit 22a8d5026c
174 changed files with 30315 additions and 16120 deletions
+14 -164
View File
@@ -55,13 +55,13 @@ func generateAdminToken(user *models.User) (string, error) {
claims := models.AdminClaims{
UserID: user.ID,
Username: user.Username,
Role: user.Role, // ← "admin" ou "cabine" ou "livreur"
Role: user.Role,
SessionID: sessionID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(adminTokenDuration)),
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
Issuer: "api-admin", // Même issuer pour tous les admins
Issuer: "api-admin",
Subject: strconv.Itoa(user.ID),
},
}
@@ -73,112 +73,6 @@ func generateAdminToken(user *models.User) (string, error) {
return tokenString, nil
}
// RegisterClient crée un nouveau compte client
func RegisterClient(c *gin.Context) {
var req models.RegisterClientRequest
if err := c.ShouldBindJSON(&req); err != nil {
log.Printf("❌ [REGISTER_CLIENT] Erreur binding: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Données invalides",
})
return
}
// Sanitize text inputs
req.Username = utils.StripHTML(req.Username)
req.Nom = utils.StripHTML(req.Nom)
req.Prenom = utils.StripHTML(req.Prenom)
// Validation téléphone
if !utils.ValidatePhoneNumber(req.Telephone) {
log.Printf("❌ [REGISTER_CLIENT] Téléphone invalide: %s", req.Telephone)
c.JSON(http.StatusBadRequest, gin.H{
"error": "Numéro de téléphone invalide",
})
return
}
normalizedPhone := utils.NormalizePhoneNumber(req.Telephone)
database := c.MustGet("database").(*db.Database)
// Vérifier username unique
if existingClient, _ := database.GetClientByUsername(req.Username); existingClient != nil {
log.Printf("❌ [REGISTER_CLIENT] Username déjà utilisé: %s", req.Username)
c.JSON(http.StatusConflict, gin.H{"error": "Nom d'utilisateur déjà utilisé"})
return
}
// Vérifier téléphone unique
if existingClient, _ := database.GetClientByTelephone(normalizedPhone); existingClient != nil {
log.Printf("❌ [REGISTER_CLIENT] Téléphone déjà utilisé: %s", normalizedPhone)
c.JSON(http.StatusConflict, gin.H{"error": "Ce numéro de téléphone est déjà utilisé"})
return
}
// Hasher le mot de passe
hashed, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
log.Printf("❌ [REGISTER_CLIENT] Erreur bcrypt: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur traitement mot de passe"})
return
}
// Créer le client
client := &models.Client{
Username: req.Username,
Password: string(hashed),
Nom: strings.TrimSpace(req.Nom),
Prenom: strings.TrimSpace(req.Prenom),
Telephone: normalizedPhone,
CreatedAt: time.Now(),
}
if err := database.CreateClient(client); err != nil {
log.Printf("❌ [REGISTER_CLIENT] Erreur création: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création client"})
return
}
// Générer le token
token, err := generateClientToken(client)
if err != nil {
log.Printf("❌ [REGISTER_CLIENT] Erreur génération token: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur génération token"})
return
}
// Sauvegarder le token
expiresAt := time.Now().Add(clientTokenDuration)
if err := database.SaveToken(client.ID, "client", token, expiresAt); err != nil {
log.Printf("❌ [REGISTER_CLIENT] Erreur SaveToken: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur enregistrement token"})
return
}
// Créer la session Redis
sessionID := uuid.New().String()
if err := database.CreateClientSession(client.ID, client.Username, sessionID); err != nil {
log.Printf("⚠️ [REGISTER_CLIENT] Erreur session Redis: %v", err)
}
client.Password = ""
c.JSON(http.StatusCreated, models.LoginResponse{
AccessToken: token,
TokenType: "Bearer",
ExpiresIn: int(clientTokenDuration.Seconds()),
User: gin.H{
"id": client.ID,
"username": client.Username,
"nom": client.Nom,
"prenom": client.Prenom,
"telephone": client.Telephone,
"role": "client",
"session_id": sessionID,
},
})
}
// AdminCreateClient crée un client depuis l'interface admin (sans session ni token)
func AdminCreateClient(c *gin.Context) {
if userRole := c.GetString("role"); userRole != "admin" {
@@ -561,6 +455,12 @@ func LoginAdmin(c *gin.Context) {
return
}
if user.Role == "livreur" {
if err := database.RecordLivreurLogin(user.Username); err != nil {
log.Printf("⚠️ [LOGIN_ADMIN] Erreur enregistrement historique connexion livreur: %v", err)
}
}
token, _ := generateAdminToken(user)
expiresAt := time.Now().Add(adminTokenDuration)
@@ -602,62 +502,6 @@ func LogoutAdmin(c *gin.Context) {
// HELPERS
// ============================================
// GetCurrentClient récupère le client actuel
// GET /api/v1/profile/client
func GetCurrentClient(c *gin.Context) {
clientID := c.GetInt("client_id")
database := c.MustGet("database").(*db.Database)
client, err := database.GetClientByID(clientID)
if err != nil {
log.Printf("❌ [GET_CURRENT_CLIENT] Client non trouvé: ID=%d", clientID)
c.JSON(http.StatusNotFound, gin.H{"error": "Client non trouvé"})
return
}
client.Password = ""
log.Printf("✅ [GET_CURRENT_CLIENT] Client récupéré: %s", client.Username)
c.JSON(http.StatusOK, gin.H{
"client": gin.H{
"id": client.ID,
"username": client.Username,
"nom": client.Nom,
"prenom": client.Prenom,
"telephone": client.Telephone,
"command": client.Command,
"amende": client.Amende,
"points_extra": client.PointsExtra,
},
})
}
// GetCurrentAdmin récupère l'admin/user actuel
// GET /api/v1/profile/admin
func GetCurrentAdmin(c *gin.Context) {
userID := c.GetInt("user_id")
database := c.MustGet("database").(*db.Database)
user, err := database.GetUserByID(userID)
if err != nil {
log.Printf("❌ [GET_CURRENT_ADMIN] User non trouvé: ID=%d", userID)
c.JSON(http.StatusNotFound, gin.H{"error": "Utilisateur non trouvé"})
return
}
user.Password = ""
log.Printf("✅ [GET_CURRENT_ADMIN] User récupéré: %s", user.Username)
c.JSON(http.StatusOK, gin.H{
"user": models.ProfileResponse{
Username: user.Username,
Role: user.Role,
},
})
}
// GetAllUsers récupère tous les utilisateurs (Admin only)
func GetAllUsers(c *gin.Context) {
database := c.MustGet("database").(*db.Database)
@@ -855,3 +699,9 @@ func CreateUser(c *gin.Context) {
log.Printf("✅ [CREATE_USER] Utilisateur %s (%s) créé", user.Username, user.Role)
c.JSON(http.StatusCreated, gin.H{"message": "Utilisateur créé"})
}
func Health(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
}