package db import ( "database/sql" "fmt" "log" "time" ) func (d *Database) SaveToken(userID int, userType string, token string, expiresAt time.Time) error { // Valider le user_type validTypes := map[string]bool{ "client": true, "admin": true, "cabine": true, "livreur": true, } if !validTypes[userType] { return fmt.Errorf("type d'utilisateur invalide: %s", userType) } query := `INSERT INTO jwt_tokens (user_id, user_type, token, date_save, date_fin) VALUES ($1, $2, $3, CURRENT_TIMESTAMP, $4)` _, err := d.Exec(query, userID, userType, token, expiresAt) if err != nil { return fmt.Errorf("erreur lors de l'enregistrement du token: %w", err) } log.Printf("✅ Token enregistré pour %s ID: %d", userType, userID) return nil } // IsTokenValid vérifie si un token existe et n'est pas expiré func (d *Database) IsTokenValid(token string) (bool, error) { query := `SELECT COUNT(*) FROM jwt_tokens WHERE token = $1 AND date_fin > $2` var count int err := d.QueryRow(query, token, time.Now()).Scan(&count) if err != nil { return false, fmt.Errorf("erreur lors de la vérification du token: %w", err) } return count > 0, nil } // RevokeToken révoque un token (le supprime de la base) func (d *Database) RevokeToken(token string) error { query := `DELETE FROM jwt_tokens WHERE token = $1` result, err := d.Exec(query, token) if err != nil { return fmt.Errorf("erreur lors de la révocation du token: %w", err) } rowsAffected, _ := result.RowsAffected() if rowsAffected > 0 { log.Printf("✅ Token révoqué avec succès") } return nil } // RevokeAllUserTokens révoque tous les tokens d'un utilisateur func (d *Database) RevokeAllUserTokens(userID int, userType string) error { query := `DELETE FROM jwt_tokens WHERE user_id = $1 AND user_type = $2` result, err := d.Exec(query, userID, userType) if err != nil { return fmt.Errorf("erreur lors de la révocation des tokens: %w", err) } rowsAffected, _ := result.RowsAffected() log.Printf("✅ %d token(s) révoqué(s) pour %s ID: %d", rowsAffected, userType, userID) return nil } // GetUserActiveTokens récupère tous les tokens actifs d'un utilisateur func (d *Database) GetUserActiveTokens(userID int, userType string) ([]map[string]any, error) { query := `SELECT id, token, date_save, date_fin FROM jwt_tokens WHERE user_id = $1 AND user_type = $2 AND date_fin > $3 ORDER BY date_save DESC` rows, err := d.Query(query, userID, userType, time.Now()) if err != nil { return nil, fmt.Errorf("erreur lors de la récupération des tokens: %w", err) } defer rows.Close() var tokens []map[string]any for rows.Next() { var id int var token string var dateSave, dateFin time.Time err := rows.Scan(&id, &token, &dateSave, &dateFin) if err != nil { return nil, fmt.Errorf("erreur lors du scan: %w", err) } tokens = append(tokens, map[string]any{ "id": id, "token": token[:20] + "...", // Tronquer pour la sécurité "date_save": dateSave, "date_fin": dateFin, "user_type": userType, }) } return tokens, nil } func (d *Database) GetTokenInfo(token string) (map[string]any, error) { query := `SELECT user_id, user_type, date_save, date_fin FROM jwt_tokens WHERE token = $1 AND date_fin > $2` var userID int var userType string var dateSave, dateFin time.Time err := d.QueryRow(query, token, time.Now()).Scan(&userID, &userType, &dateSave, &dateFin) if err == sql.ErrNoRows { return nil, fmt.Errorf("token non trouvé ou expiré") } if err != nil { return nil, fmt.Errorf("erreur lors de la récupération des infos du token: %w", err) } tokenInfo := map[string]any{ "user_id": userID, "user_type": userType, "date_save": dateSave, "date_fin": dateFin, } return tokenInfo, nil } func (d *Database) CountActiveTokensByType() (map[string]int, error) { query := `SELECT user_type, COUNT(*) as count FROM jwt_tokens WHERE date_fin > $1 GROUP BY user_type` rows, err := d.Query(query, time.Now()) if err != nil { return nil, fmt.Errorf("erreur lors du comptage des tokens: %w", err) } defer rows.Close() counts := make(map[string]int) for rows.Next() { var userType string var count int if err := rows.Scan(&userType, &count); err != nil { return nil, err } counts[userType] = count } return counts, nil }