v2.0.13 — oumta-dashboard via PHP proxy; quiet support poll
Dashboard now reachable across the internet: browser calls /api/dashboard/* same-origin, PHP forwards to OUMTA_DASHBOARD_URL (configurable via env, with docker-compose defaults pointing at host.docker.internal:8085). Keeps the bearer token server-side and lets the dashboard live on a private network. Plumbing bits: polling indicator now green (no reason to look anxious about a healthy poll loop), and the support plugin returns 200 pulled=0 when its relay isn't configured instead of flooding the network tab with 502s on every background tick. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7bce6a3a36
commit
efd3f9d5ae
6 files changed
+92
-26
No files matched your search
@@ -1005,6 +1005,55 @@ if (str_starts_with($route, '/api/')) {
|
||||
if ($route === '/api/caldav/sync' && $method === 'POST') {
|
||||
echo json_encode($caldav->sync()); exit;
|
||||
}
|
||||
// ── Oumta dashboard proxy ──
|
||||
// Browser talks to /api/dashboard/* same-origin; we forward everything
|
||||
// after that prefix to OUMTA_DASHBOARD_URL. Keeps CORS out of the
|
||||
// browser, lets the dashboard live on a private network, and keeps any
|
||||
// bearer token server-side. No SSE / streaming here: the response is
|
||||
// buffered whole, so the plugin uses its polling fallback.
|
||||
if (str_starts_with($route, '/api/dashboard/')) {
|
||||
$upstreamPath = substr($route, strlen('/api/dashboard'));
|
||||
$upstream = rtrim(OUMTA_DASHBOARD_URL, '/') . $upstreamPath;
|
||||
$query = $_SERVER['QUERY_STRING'] ?? '';
|
||||
if ($query !== '') $upstream .= '?' . $query;
|
||||
|
||||
$headers = ['Accept: application/json'];
|
||||
if (OUMTA_DASHBOARD_TOKEN !== '') {
|
||||
$headers[] = 'Authorization: Bearer ' . OUMTA_DASHBOARD_TOKEN;
|
||||
}
|
||||
|
||||
$ch = curl_init($upstream);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_TIMEOUT => 15,
|
||||
]);
|
||||
if ($method !== 'GET' && $method !== 'HEAD') {
|
||||
$body = file_get_contents('php://input');
|
||||
if ($body !== '' && $body !== false) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
$headers[] = 'Content-Type: ' . ($_SERVER['CONTENT_TYPE'] ?? 'application/json');
|
||||
}
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
hyprcrdApplySafeCurlOpts($ch);
|
||||
$resp = curl_exec($ch);
|
||||
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$ct = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($status === 0) {
|
||||
http_response_code(502);
|
||||
echo json_encode(['error' => 'dashboard upstream unreachable', 'detail' => APP_DEBUG ? $err : '']);
|
||||
exit;
|
||||
}
|
||||
http_response_code($status);
|
||||
if ($ct) header('Content-Type: ' . $ct);
|
||||
echo $resp;
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── Relay ──
|
||||
|
||||
if ($route === '/api/relay/settings' && $method === 'GET') {
|
||||
|
||||
Reference in new issue
Block a user