false,'error'=>'pdo_not_in_scope']); } // ===== Helpers communs ===== if (!function_exists('h')) { function h($v): string { return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } } if (!function_exists('json_response')) { function json_response(array $data, int $code = 200): void { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } } if (!function_exists('assert_conversation_access')) { /** * Vérifie l'accès du user courant à la conversation. * @return array Conversation row (id, praticien_id, client_id, status) */ function assert_conversation_access(PDO $pdo, int $conversation_id, string $role, int $me_id): array { $stmt = $pdo->prepare("SELECT id, praticien_id, client_id, status FROM conversations WHERE id = ? LIMIT 1"); $stmt->execute([$conversation_id]); $c = $stmt->fetch(PDO::FETCH_ASSOC); if (!$c) json_response(['error' => 'conversation_not_found'], 404); $ok = ($role === 'praticien' && (int)$c['praticien_id'] === $me_id) || ($role === 'client' && (int)$c['client_id'] === $me_id); // En CLI (outils), on ne bloque pas; en Web on bloque if (!$ok && PHP_SAPI !== 'cli') { json_response(['error' => 'forbidden'], 403); } return $c; } } // ===== Contexte selon SAPI ===== if (PHP_SAPI === 'cli') { // --- MODE CLI (ex: /messages/tools/gc.php) --- // Pas d'exigence de session/login/CSRF ici. $GLOBALS['MESSAGES_CTX'] = [ 'role' => 'praticien', // valeur neutre; non utilisée par gc.php 'me_id' => 0, 'csrf_token' => '' ]; } else { // --- MODE WEB --- // Sécurité (require_login) depuis /public/includes/securite.php si présent. $sec = APP_HTDOCS . '/public/includes/securite.php'; if (is_file($sec)) { require_once $sec; if (function_exists('require_login_or_redirect')) { require_login_or_redirect(['praticien', 'client','admin']); } } // Variables de session attendues $role = $_SESSION['role'] ?? null; // 'praticien' | 'client' $me_id = $_SESSION['reference_id'] ?? null; // id de la personne (table praticien|client) if (!in_array($role, ['praticien', 'client','admin'], true) || empty($me_id)) { http_response_code(403); echo "Accès refusé (session invalide)."; exit; } // CSRF token if (empty($_SESSION['_csrf'])) { $_SESSION['_csrf'] = bin2hex(random_bytes(16)); } $csrf_token = $_SESSION['_csrf']; $GLOBALS['MESSAGES_CTX'] = [ 'role' => $role, 'me_id' => (int)$me_id, 'csrf_token' => $csrf_token ]; }