✨ Nouvelles fonctionnalités: - Ajout du mode terrain pour utilisation mobile hors connexion - Génération automatique de reçus PDF avec template personnalisé - Révision complète du système de cartes avec amélioration des performances 🔧 Améliorations techniques: - Refactoring du module chat avec architecture simplifiée - Optimisation du système de sécurité NIST SP 800-63B - Amélioration de la gestion des secteurs géographiques - Support UTF-8 étendu pour les noms d'utilisateurs 📱 Application mobile: - Nouveau mode terrain dans user_field_mode_page - Interface utilisateur adaptative pour conditions difficiles - Synchronisation offline améliorée 🗺️ Cartographie: - Optimisation des performances MapBox - Meilleure gestion des tuiles hors ligne - Amélioration de l'affichage des secteurs 📄 Documentation: - Ajout guide Android (ANDROID-GUIDE.md) - Documentation sécurité API (API-SECURITY.md) - Guide module chat (CHAT_MODULE.md) 🐛 Corrections: - Résolution des erreurs 400 lors de la création d'utilisateurs - Correction de la validation des noms d'utilisateurs - Fix des problèmes de synchronisation chat 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
150 lines
5.5 KiB
PHP
150 lines
5.5 KiB
PHP
#!/usr/bin/env php
|
|
<?php
|
|
|
|
/**
|
|
* Script de nettoyage des données de sécurité
|
|
* À exécuter via cron quotidiennement
|
|
* Exemple crontab: 0 2 * * * /usr/bin/php /var/www/geosector/api/scripts/cron/cleanup_security_data.php
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
// Configuration
|
|
require_once __DIR__ . '/../../bootstrap.php';
|
|
require_once __DIR__ . '/../../src/Config/AppConfig.php';
|
|
require_once __DIR__ . '/../../src/Core/Database.php';
|
|
|
|
// Initialiser la configuration
|
|
$appConfig = AppConfig::getInstance();
|
|
$config = $appConfig->getFullConfig();
|
|
|
|
// Initialiser la base de données
|
|
Database::init($config['database']);
|
|
$db = Database::getInstance();
|
|
|
|
// Configuration de rétention (en jours)
|
|
$RETENTION_DAYS = [
|
|
'performance_metrics' => 30, // Garder 30 jours de métriques
|
|
'failed_login_attempts' => 7, // Garder 7 jours de tentatives
|
|
'resolved_alerts' => 90, // Garder 90 jours d'alertes résolues
|
|
'expired_blocks' => 0 // Débloquer immédiatement les IPs expirées
|
|
];
|
|
|
|
echo "[" . date('Y-m-d H:i:s') . "] Début du nettoyage des données de sécurité\n";
|
|
|
|
try {
|
|
$totalDeleted = 0;
|
|
|
|
// 1. Nettoyer les métriques de performance
|
|
echo "- Nettoyage des métriques de performance (>" . $RETENTION_DAYS['performance_metrics'] . " jours)...\n";
|
|
$stmt = $db->prepare('
|
|
DELETE FROM sec_performance_metrics
|
|
WHERE created_at < DATE_SUB(NOW(), INTERVAL :days DAY)
|
|
');
|
|
$stmt->execute(['days' => $RETENTION_DAYS['performance_metrics']]);
|
|
$deleted = $stmt->rowCount();
|
|
echo " → $deleted lignes supprimées\n";
|
|
$totalDeleted += $deleted;
|
|
|
|
// 2. Nettoyer les tentatives de login échouées
|
|
echo "- Nettoyage des tentatives de login (>" . $RETENTION_DAYS['failed_login_attempts'] . " jours)...\n";
|
|
$stmt = $db->prepare('
|
|
DELETE FROM sec_failed_login_attempts
|
|
WHERE attempt_time < DATE_SUB(NOW(), INTERVAL :days DAY)
|
|
');
|
|
$stmt->execute(['days' => $RETENTION_DAYS['failed_login_attempts']]);
|
|
$deleted = $stmt->rowCount();
|
|
echo " → $deleted lignes supprimées\n";
|
|
$totalDeleted += $deleted;
|
|
|
|
// 3. Nettoyer les alertes résolues
|
|
echo "- Nettoyage des alertes résolues (>" . $RETENTION_DAYS['resolved_alerts'] . " jours)...\n";
|
|
$stmt = $db->prepare('
|
|
DELETE FROM sec_alerts
|
|
WHERE resolved = 1
|
|
AND resolved_at < DATE_SUB(NOW(), INTERVAL :days DAY)
|
|
');
|
|
$stmt->execute(['days' => $RETENTION_DAYS['resolved_alerts']]);
|
|
$deleted = $stmt->rowCount();
|
|
echo " → $deleted lignes supprimées\n";
|
|
$totalDeleted += $deleted;
|
|
|
|
// 4. Débloquer les IPs expirées
|
|
echo "- Déblocage des IPs expirées...\n";
|
|
$stmt = $db->prepare('
|
|
UPDATE sec_blocked_ips
|
|
SET unblocked_at = NOW()
|
|
WHERE blocked_until <= NOW()
|
|
AND unblocked_at IS NULL
|
|
AND permanent = 0
|
|
');
|
|
$stmt->execute();
|
|
$unblocked = $stmt->rowCount();
|
|
echo " → $unblocked IPs débloquées\n";
|
|
|
|
// 5. Supprimer les anciennes IPs débloquées (optionnel, garder 180 jours d'historique)
|
|
echo "- Suppression des anciennes IPs débloquées (>180 jours)...\n";
|
|
$stmt = $db->prepare('
|
|
DELETE FROM sec_blocked_ips
|
|
WHERE unblocked_at IS NOT NULL
|
|
AND unblocked_at < DATE_SUB(NOW(), INTERVAL 180 DAY)
|
|
');
|
|
$stmt->execute();
|
|
$deleted = $stmt->rowCount();
|
|
echo " → $deleted lignes supprimées\n";
|
|
$totalDeleted += $deleted;
|
|
|
|
// 6. Optimiser les tables (optionnel, peut être long sur de grosses tables)
|
|
if ($totalDeleted > 1000) {
|
|
echo "- Optimisation des tables...\n";
|
|
$tables = [
|
|
'sec_performance_metrics',
|
|
'sec_failed_login_attempts',
|
|
'sec_alerts',
|
|
'sec_blocked_ips'
|
|
];
|
|
|
|
foreach ($tables as $table) {
|
|
try {
|
|
$db->exec("OPTIMIZE TABLE $table");
|
|
echo " → Table $table optimisée\n";
|
|
} catch (Exception $e) {
|
|
echo " ⚠ Impossible d'optimiser $table: " . $e->getMessage() . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// 7. Statistiques finales
|
|
echo "\n=== RÉSUMÉ ===\n";
|
|
echo "Total supprimé: $totalDeleted lignes\n";
|
|
echo "IPs débloquées: $unblocked\n";
|
|
|
|
// Obtenir les statistiques actuelles
|
|
$stats = [];
|
|
$tables = [
|
|
'sec_alerts' => "SELECT COUNT(*) as total, SUM(resolved = 0) as active FROM sec_alerts",
|
|
'sec_performance_metrics' => "SELECT COUNT(*) as total FROM sec_performance_metrics",
|
|
'sec_failed_login_attempts' => "SELECT COUNT(*) as total FROM sec_failed_login_attempts",
|
|
'sec_blocked_ips' => "SELECT COUNT(*) as total, SUM(permanent = 1) as permanent FROM sec_blocked_ips WHERE unblocked_at IS NULL"
|
|
];
|
|
|
|
echo "\nÉtat actuel des tables:\n";
|
|
foreach ($tables as $table => $query) {
|
|
$result = $db->query($query)->fetch(PDO::FETCH_ASSOC);
|
|
if ($table === 'sec_alerts') {
|
|
echo "- $table: {$result['total']} total, {$result['active']} actives\n";
|
|
} elseif ($table === 'sec_blocked_ips') {
|
|
$permanent = $result['permanent'] ?? 0;
|
|
echo "- $table: {$result['total']} bloquées, $permanent permanentes\n";
|
|
} else {
|
|
echo "- $table: {$result['total']} enregistrements\n";
|
|
}
|
|
}
|
|
|
|
echo "\n[" . date('Y-m-d H:i:s') . "] Nettoyage terminé avec succès\n";
|
|
|
|
} catch (Exception $e) {
|
|
echo "\n❌ ERREUR: " . $e->getMessage() . "\n";
|
|
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
|
|
exit(1);
|
|
} |