\PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, ]); } return $pdo; } /* ── Janus client ────────────────────────────────────────────────── */ function janusClient(): \AndroidCast\Sfu\JanusClient { static $client = null; if ($client === null) { $url = sfuConfig('janus_url', 'http://10.7.16.237:8088/janus'); $client = new \AndroidCast\Sfu\JanusClient($url); } return $client; } /* ── Auth helper ─────────────────────────────────────────────────── */ function sfuRequireAuth(): array { /* Try composed BE session */ $composedBe = '/var/www/ac/composed/backend/src/bootstrap.php'; if (is_file($composedBe)) { require_once $composedBe; if (function_exists('requireAuth')) { return requireAuth(); } } /* Minimal cookie/bearer check */ session_start(); if (empty($_SESSION['user_id'])) { http_response_code(401); echo json_encode(['ok' => false, 'error' => 'unauthorized']); exit; } return ['id' => (int) $_SESSION['user_id'], 'email' => $_SESSION['email'] ?? '']; } /* ── JSON helpers ────────────────────────────────────────────────── */ function sfuJsonOk(array $data = []): void { header('Content-Type: application/json; charset=utf-8'); echo json_encode(['ok' => true] + $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } function sfuJsonErr(string $message, int $code = 400): void { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode(['ok' => false, 'error' => $message], JSON_UNESCAPED_SLASHES); exit; }