feat: Release version 3.1.4 - Mode terrain et génération PDF
✨ 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>
This commit is contained in:
150
api/scripts/cron/cleanup_security_data.php
Normal file
150
api/scripts/cron/cleanup_security_data.php
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/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);
|
||||
}
|
||||
Reference in New Issue
Block a user