This commit is contained in:
Anton Afanasyeu
2026-06-23 12:29:33 +02:00
commit 59fb5013c3
26 changed files with 2375 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../src/bootstrap.php';
require_once __DIR__ . '/../../src/RemoteAccessRepository.php';
header('Content-Type: application/json; charset=utf-8');
Auth::check();
if (!Rbac::can('remote_access_view')) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$action = trim((string)($_GET['action'] ?? ''));
if ($method === 'GET') {
if ($action === 'devices') {
json_out(['ok' => true, 'devices' => RemoteAccessRepository::listDevices()]);
}
if ($action === 'sessions') {
$filter = trim((string)($_GET['status'] ?? ''));
json_out(['ok' => true, 'sessions' => RemoteAccessRepository::listSessions($filter)]);
}
if ($action === 'events') {
json_out(['ok' => true, 'events' => RemoteAccessRepository::listEvents((int)($_GET['limit'] ?? 100))]);
}
if ($action === 'dashboard') {
$payload = RemoteAccessRepository::buildDashboardPayload(
rtrim(Auth::basePath(), '/'),
'/app/androidcast_project'
);
json_out([
'ok' => true,
'devices' => $payload['devices'],
'active_sessions' => $payload['active_sessions'],
'inactive_sessions' => $payload['inactive_sessions'],
'recent_events' => $payload['recent_events'],
'permissions' => [
'can_operate' => Rbac::can('remote_access_operate'),
'can_admin' => Rbac::can('remote_access_admin'),
],
'config' => [
'wg_endpoint' => (string) cfg('remote_access.wg_endpoint', ''),
],
]);
}
json_out(['ok' => false, 'error' => 'unknown_action'], 400);
}
if ($method !== 'POST') {
json_out(['ok' => false, 'error' => 'method_not_allowed'], 405);
}
$raw = file_get_contents('php://input') ?: '';
$body = json_decode($raw, true);
if (!is_array($body)) {
json_out(['ok' => false, 'error' => 'invalid_json'], 400);
}
$user = Auth::user();
$userId = (int)($user['id'] ?? 0);
if ($action === 'whitelist') {
if (!Rbac::can('remote_access_admin')) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$deviceId = trim((string)($body['device_id'] ?? ''));
if ($deviceId === '') {
json_out(['ok' => false, 'error' => 'missing_device_id'], 400);
}
if (!RemoteAccessRepository::canAccessDevice($deviceId)) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
if (!RemoteAccessRepository::setDeviceWhitelist($deviceId, !empty($body['whitelisted']), $body['notes'] ?? null)) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
RemoteAccessRepository::logEvent($deviceId, null, $userId, 'whitelist_update', null, [
'whitelisted' => !empty($body['whitelisted']),
], '');
json_out(['ok' => true]);
}
if ($action === 'open_session') {
if (!Rbac::can('remote_access_operate')) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$deviceId = trim((string)($body['device_id'] ?? ''));
if ($deviceId === '') {
json_out(['ok' => false, 'error' => 'missing_device_id'], 400);
}
if (!RemoteAccessRepository::canAccessDevice($deviceId)) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$result = RemoteAccessRepository::openSession($deviceId, $userId);
if (empty($result['ok'])) {
$err = $result['error'] ?? 'failed';
json_out(['ok' => false, 'error' => $err], $err === 'forbidden' ? 403 : 400);
}
json_out(['ok' => true, 'session_id' => $result['session_id'] ?? '']);
}
if ($action === 'close_session') {
if (!Rbac::can('remote_access_operate')) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$sessionId = trim((string)($body['session_id'] ?? ''));
if ($sessionId === '') {
json_out(['ok' => false, 'error' => 'missing_session_id'], 400);
}
if (!RemoteAccessRepository::canOperatorCloseSession($sessionId, $userId)) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
RemoteAccessRepository::closeSession($sessionId, RemoteAccessRepository::STATUS_CLOSED, 'operator_closed');
RemoteAccessRepository::logEvent((string)($body['device_id'] ?? ''), $sessionId, $userId, 'session_close', 'operator', null, '');
json_out(['ok' => true]);
}
json_out(['ok' => false, 'error' => 'unknown_action'], 400);