- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD) * DEV: Clés TEST Pierre (mode test) * REC: Clés TEST Client (mode test) * PROD: Clés LIVE Client (mode live) - Ajout de la gestion des bases de données immeubles/bâtiments * Configuration buildings_database pour DEV/REC/PROD * Service BuildingService pour enrichissement des adresses - Optimisations pages et améliorations ergonomie - Mises à jour des dépendances Composer - Nettoyage des fichiers obsolètes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
207 lines
7.0 KiB
PHP
Executable File
207 lines
7.0 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
|
|
require_once __DIR__ . '/src/Services/StripeService.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 de la classe Controller de base
|
|
require_once __DIR__ . '/src/Core/Controller.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';
|
|
require_once __DIR__ . '/src/Controllers/StripeController.php';
|
|
require_once __DIR__ . '/src/Controllers/StripeWebhookController.php';
|
|
require_once __DIR__ . '/src/Controllers/MigrationController.php';
|
|
require_once __DIR__ . '/src/Controllers/HealthController.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([
|
|
'status' => 'error',
|
|
'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([
|
|
'status' => 'error',
|
|
'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([
|
|
'status' => 'error',
|
|
'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([
|
|
'status' => 'error',
|
|
'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([
|
|
'status' => 'error',
|
|
'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;
|
|
}
|