Files
2026-03-05 10:25:39 +01:00

102 lines
3.6 KiB
PHP

<?php
// /messages/_bootstrap.php
declare(strict_types=1);
/**
* Bootstrap commun de la messagerie.
* - Mode CLI (cron/outils) : bypass login/CSRF, mais DB chargée.
* - Mode Web : session requise (role=praticien|client + reference_id), CSRF.
* - Charge DB (../includes/db.php ou ../public/includes/db.php) + i18n.
* - Expose helpers h(), json_response(), assert_conversation_access().
* - Expose $GLOBALS['MESSAGES_CTX'] = [role, me_id, csrf_token].
*/
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
// Charge le bootstrap global du site (env + session + DB + lang + helpers)
require_once realpath(__DIR__ . '/../public/includes/init_pr_cl.php');
if (!isset($pdo) || !($pdo instanceof PDO)) {
json_response(['ok'=>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
];
}