Files
geo/api/index.php
Pierre 5ab03751e1 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>
2025-08-19 19:38:03 +02:00

197 lines
6.6 KiB
PHP
Executable File

<?php
declare(strict_types=1);
require_once __DIR__ . '/bootstrap.php';
// Chargement des fichiers principaux
require_once __DIR__ . '/src/Config/AppConfig.php';
require_once __DIR__ . '/src/Core/Database.php';
require_once __DIR__ . '/src/Core/AddressesDatabase.php';
require_once __DIR__ . '/src/Core/Router.php';
require_once __DIR__ . '/src/Core/Session.php';
require_once __DIR__ . '/src/Core/Request.php';
require_once __DIR__ . '/src/Core/Response.php';
require_once __DIR__ . '/src/Utils/ClientDetector.php';
require_once __DIR__ . '/src/Services/LogService.php';
// Chargement des services de sécurité
require_once __DIR__ . '/src/Services/Security/PerformanceMonitor.php';
require_once __DIR__ . '/src/Services/Security/IPBlocker.php';
require_once __DIR__ . '/src/Services/Security/SecurityMonitor.php';
require_once __DIR__ . '/src/Services/Security/AlertService.php';
// Chargement des contrôleurs
require_once __DIR__ . '/src/Controllers/LogController.php';
require_once __DIR__ . '/src/Controllers/LoginController.php';
require_once __DIR__ . '/src/Controllers/EntiteController.php';
require_once __DIR__ . '/src/Controllers/UserController.php';
require_once __DIR__ . '/src/Controllers/OperationController.php';
require_once __DIR__ . '/src/Controllers/PassageController.php';
require_once __DIR__ . '/src/Controllers/VilleController.php';
require_once __DIR__ . '/src/Controllers/FileController.php';
require_once __DIR__ . '/src/Controllers/SectorController.php';
require_once __DIR__ . '/src/Controllers/PasswordController.php';
require_once __DIR__ . '/src/Controllers/ChatController.php';
require_once __DIR__ . '/src/Controllers/SecurityController.php';
// Initialiser la configuration
$appConfig = AppConfig::getInstance();
$config = $appConfig->getFullConfig();
// Initialiser la base de données principale
Database::init($config['database']);
// Initialiser la base de données des adresses
AddressesDatabase::init($appConfig->getAddressesDatabaseConfig());
// Configuration CORS
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
$allowedOrigins = $config['api']['allowed_origins'];
// Vérifier si l'origine est autorisée
if (in_array($origin, $allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-App-Identifier');
header('Access-Control-Allow-Credentials: true');
}
// Gestion des requêtes preflight (OPTIONS)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
exit(0);
}
// Initialiser la session
Session::start();
// ===== DÉBUT DU MONITORING DE SÉCURITÉ =====
use App\Services\Security\PerformanceMonitor;
use App\Services\Security\IPBlocker;
use App\Services\Security\SecurityMonitor;
use App\Services\Security\AlertService;
// Obtenir l'IP du client
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
// Vérifier si l'IP est bloquée
if (IPBlocker::isBlocked($clientIp)) {
http_response_code(403);
Response::json([
'success' => false,
'message' => 'Access denied. Your IP has been blocked.',
'error_code' => 'IP_BLOCKED'
], 403);
exit;
}
// Vérifier le rate limiting
if (!SecurityMonitor::checkRateLimit($clientIp)) {
http_response_code(429);
Response::json([
'success' => false,
'message' => 'Too many requests. Please try again later.',
'error_code' => 'RATE_LIMIT_EXCEEDED'
], 429);
exit;
}
// Démarrer le monitoring de performance
PerformanceMonitor::startRequest();
// Capturer le endpoint pour le monitoring
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
$requestMethod = $_SERVER['REQUEST_METHOD'] ?? 'GET';
// Vérifier les patterns de scan
if (!SecurityMonitor::checkScanPattern($requestUri)) {
// Pattern suspect détecté, bloquer l'IP temporairement
IPBlocker::block($clientIp, 3600, 'Suspicious scan pattern detected');
http_response_code(404);
Response::json([
'success' => false,
'message' => 'Not found'
], 404);
exit;
}
// Vérifier les paramètres pour injection SQL
$allParams = array_merge($_GET, $_POST, json_decode(file_get_contents('php://input'), true) ?? []);
if (!empty($allParams) && !SecurityMonitor::checkRequestParameters($allParams)) {
// Injection SQL détectée, bloquer l'IP définitivement
IPBlocker::blockPermanent($clientIp, 'SQL injection attempt');
http_response_code(400);
Response::json([
'success' => false,
'message' => 'Bad request'
], 400);
exit;
}
// Créer l'instance de routeur
$router = new Router();
// Enregistrer une fonction de shutdown pour capturer les métriques
register_shutdown_function(function() use ($requestUri, $requestMethod) {
$statusCode = http_response_code();
// Terminer le monitoring de performance
PerformanceMonitor::endRequest($requestUri, $requestMethod, $statusCode);
// Vérifier les patterns 404
if ($statusCode === 404) {
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
SecurityMonitor::check404Pattern($clientIp);
}
// Alerter sur les erreurs 500
if ($statusCode >= 500) {
$error = error_get_last();
AlertService::trigger('HTTP_500', [
'endpoint' => $requestUri,
'method' => $requestMethod,
'error_message' => $error['message'] ?? 'Unknown error',
'error_file' => $error['file'] ?? 'Unknown',
'error_line' => $error['line'] ?? 0,
'message' => "Erreur serveur 500 sur $requestUri"
], 'ERROR');
}
// Nettoyer périodiquement les IPs expirées (1% de chance)
if (rand(1, 100) === 1) {
IPBlocker::cleanupExpired();
}
});
// Gérer les erreurs non capturées
set_exception_handler(function($exception) use ($requestUri, $requestMethod) {
// Logger l'erreur
error_log("Uncaught exception: " . $exception->getMessage());
// Créer une alerte
AlertService::trigger('UNCAUGHT_EXCEPTION', [
'endpoint' => $requestUri,
'method' => $requestMethod,
'exception' => get_class($exception),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => substr($exception->getTraceAsString(), 0, 1000)
], 'ERROR');
// Retourner une erreur 500
http_response_code(500);
Response::json([
'success' => false,
'message' => 'Internal server error'
], 500);
});
// Gérer la requête
try {
$router->handle();
} catch (Exception $e) {
// Les exceptions sont gérées par le handler ci-dessus
throw $e;
}