nexus...
This commit is contained in:
@@ -21,6 +21,13 @@
|
|||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error(data.error || `HTTP ${res.status}`);
|
throw new Error(data.error || `HTTP ${res.status}`);
|
||||||
}
|
}
|
||||||
|
if (data && data.results && typeof data.results === 'object') {
|
||||||
|
const failures = Object.values(data.results).filter((row) => row && row.ok === false);
|
||||||
|
if (failures.length) {
|
||||||
|
const first = failures[0];
|
||||||
|
throw new Error(first.error || 'action_failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,64 @@ $normalizeApiPath = function (string $baseUrl, string $apiPath): string {
|
|||||||
return $base . $path;
|
return $base . $path;
|
||||||
};
|
};
|
||||||
|
|
||||||
$apiRequest = function (array $instance, array $params) use ($normalizeApiPath): array {
|
$httpRequest = function (string $method, string $url, array $headers, ?string $body, bool $verify, int $timeout): array {
|
||||||
|
$raw = '';
|
||||||
|
$httpCode = 0;
|
||||||
|
$error = '';
|
||||||
|
|
||||||
|
if (function_exists('curl_init')) {
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_TIMEOUT => $timeout,
|
||||||
|
CURLOPT_CONNECTTIMEOUT => $timeout,
|
||||||
|
CURLOPT_SSL_VERIFYPEER => $verify,
|
||||||
|
CURLOPT_SSL_VERIFYHOST => $verify ? 2 : 0,
|
||||||
|
CURLOPT_CUSTOMREQUEST => $method,
|
||||||
|
CURLOPT_HTTPHEADER => $headers,
|
||||||
|
]);
|
||||||
|
if ($body !== null) {
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||||
|
}
|
||||||
|
$raw = (string)curl_exec($ch);
|
||||||
|
if ($raw === '' && curl_errno($ch)) {
|
||||||
|
$error = curl_error($ch);
|
||||||
|
}
|
||||||
|
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch);
|
||||||
|
} else {
|
||||||
|
$ctx = stream_context_create([
|
||||||
|
'http' => [
|
||||||
|
'method' => $method,
|
||||||
|
'timeout' => $timeout,
|
||||||
|
'header' => implode("\r\n", $headers),
|
||||||
|
'content' => $body ?? '',
|
||||||
|
],
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => $verify,
|
||||||
|
'verify_peer_name' => $verify,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$raw = (string)@file_get_contents($url, false, $ctx);
|
||||||
|
$httpCode = 200;
|
||||||
|
if ($raw === '') {
|
||||||
|
$error = 'HTTP request failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error !== '') {
|
||||||
|
return ['ok' => false, 'error' => $error, 'http_code' => $httpCode, 'url' => $url];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($raw, true);
|
||||||
|
if (!is_array($data)) {
|
||||||
|
return ['ok' => false, 'error' => 'invalid_json', 'http_code' => $httpCode, 'raw' => $raw, 'url' => $url];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['ok' => true, 'data' => $data, 'http_code' => $httpCode, 'url' => $url];
|
||||||
|
};
|
||||||
|
|
||||||
|
$v5Request = function (array $instance, array $params) use ($normalizeApiPath, $httpRequest): array {
|
||||||
if (!empty($instance['token']) && !isset($params['auth'])) {
|
if (!empty($instance['token']) && !isset($params['auth'])) {
|
||||||
$params['auth'] = $instance['token'];
|
$params['auth'] = $instance['token'];
|
||||||
}
|
}
|
||||||
@@ -48,53 +105,78 @@ $apiRequest = function (array $instance, array $params) use ($normalizeApiPath):
|
|||||||
}
|
}
|
||||||
$verify = !empty($instance['verify_tls']);
|
$verify = !empty($instance['verify_tls']);
|
||||||
|
|
||||||
$raw = '';
|
return $httpRequest('GET', $full, ['Accept: application/json'], null, $verify, $timeout);
|
||||||
$httpCode = 0;
|
};
|
||||||
$error = '';
|
|
||||||
|
|
||||||
if (function_exists('curl_init')) {
|
$v6Auth = function (array $instance) use ($httpRequest): array {
|
||||||
$ch = curl_init($full);
|
$base = rtrim((string)$instance['url'], '/');
|
||||||
curl_setopt_array($ch, [
|
$url = $base . '/api/auth';
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
$timeout = (int)($instance['timeout'] ?? 8);
|
||||||
CURLOPT_TIMEOUT => $timeout,
|
if ($timeout <= 0) {
|
||||||
CURLOPT_CONNECTTIMEOUT => $timeout,
|
$timeout = 8;
|
||||||
CURLOPT_SSL_VERIFYPEER => $verify,
|
}
|
||||||
CURLOPT_SSL_VERIFYHOST => $verify ? 2 : 0,
|
$verify = !empty($instance['verify_tls']);
|
||||||
]);
|
$payload = ['password' => (string)($instance['token'] ?? '')];
|
||||||
$raw = (string)curl_exec($ch);
|
$body = json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
if ($raw === '' && curl_errno($ch)) {
|
$res = $httpRequest('POST', $url, ['Accept: application/json', 'Content-Type: application/json'], $body, $verify, $timeout);
|
||||||
$error = curl_error($ch);
|
if (!$res['ok']) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
$data = (array)($res['data'] ?? []);
|
||||||
|
$session = (array)($data['session'] ?? []);
|
||||||
|
$sid = (string)($session['sid'] ?? '');
|
||||||
|
$res['sid'] = $sid;
|
||||||
|
return $res;
|
||||||
|
};
|
||||||
|
|
||||||
|
$v6Request = function (array $instance, string $path, string $method, array $payload, string $sid) use ($httpRequest): array {
|
||||||
|
$base = rtrim((string)$instance['url'], '/');
|
||||||
|
$path = ltrim($path, '/');
|
||||||
|
$url = $base . '/api/' . $path;
|
||||||
|
$timeout = (int)($instance['timeout'] ?? 8);
|
||||||
|
if ($timeout <= 0) {
|
||||||
|
$timeout = 8;
|
||||||
|
}
|
||||||
|
$verify = !empty($instance['verify_tls']);
|
||||||
|
$headers = ['Accept: application/json'];
|
||||||
|
if ($sid !== '') {
|
||||||
|
$headers[] = 'sid: ' . $sid;
|
||||||
|
$headers[] = 'X-FTL-SID: ' . $sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = null;
|
||||||
|
if ($method !== 'GET') {
|
||||||
|
if ($sid !== '' && !isset($payload['sid'])) {
|
||||||
|
$payload['sid'] = $sid;
|
||||||
}
|
}
|
||||||
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$body = json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
curl_close($ch);
|
$headers[] = 'Content-Type: application/json';
|
||||||
} else {
|
}
|
||||||
$ctx = stream_context_create([
|
|
||||||
'http' => [
|
return $httpRequest($method, $url, $headers, $body, $verify, $timeout);
|
||||||
'method' => 'GET',
|
};
|
||||||
'timeout' => $timeout,
|
|
||||||
],
|
$detectApi = function (array $instance) use ($v6Auth, $v6Request, $v5Request): array {
|
||||||
'ssl' => [
|
$sid = '';
|
||||||
'verify_peer' => $verify,
|
$authRes = null;
|
||||||
'verify_peer_name' => $verify,
|
if (!empty($instance['token'])) {
|
||||||
],
|
$authRes = $v6Auth($instance);
|
||||||
]);
|
if (($authRes['ok'] ?? false) && !empty($authRes['sid'])) {
|
||||||
$raw = (string)@file_get_contents($full, false, $ctx);
|
$sid = (string)$authRes['sid'];
|
||||||
$httpCode = 200;
|
|
||||||
if ($raw === '') {
|
|
||||||
$error = 'HTTP request failed';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($error !== '') {
|
$probe = $v6Request($instance, 'stats/summary', 'GET', [], $sid);
|
||||||
return ['ok' => false, 'error' => $error, 'http_code' => $httpCode, 'url' => $full];
|
if ($probe['ok'] || in_array((int)($probe['http_code'] ?? 0), [401, 403], true)) {
|
||||||
|
return ['version' => 6, 'sid' => $sid, 'probe' => $probe, 'auth' => $authRes];
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = json_decode($raw, true);
|
$legacy = $v5Request($instance, ['summaryRaw' => 1]);
|
||||||
if (!is_array($data)) {
|
if ($legacy['ok']) {
|
||||||
return ['ok' => false, 'error' => 'invalid_json', 'http_code' => $httpCode, 'raw' => $raw, 'url' => $full];
|
return ['version' => 5, 'sid' => '', 'probe' => $legacy];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['ok' => true, 'data' => $data, 'http_code' => $httpCode, 'url' => $full];
|
return ['version' => 0, 'sid' => '', 'probe' => $probe, 'legacy' => $legacy];
|
||||||
};
|
};
|
||||||
|
|
||||||
$resolvePrimaryId = function () use ($instances): ?string {
|
$resolvePrimaryId = function () use ($instances): ?string {
|
||||||
@@ -229,53 +311,187 @@ if ($action === 'dashboard') {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$now = time();
|
||||||
|
$from = $now - 3600;
|
||||||
|
|
||||||
foreach ($instances as $id => $instance) {
|
foreach ($instances as $id => $instance) {
|
||||||
$errors = [];
|
$errors = [];
|
||||||
|
$summaryData = null;
|
||||||
|
$topData = null;
|
||||||
|
$queryTypesData = null;
|
||||||
|
$querySourcesData = null;
|
||||||
|
$forwardDestData = null;
|
||||||
|
$recentData = null;
|
||||||
|
$updates = ['available' => false, 'details' => []];
|
||||||
|
$versionsData = null;
|
||||||
|
|
||||||
$summary = $apiRequest($instance, ['summaryRaw' => 1]);
|
$apiInfo = $detectApi($instance);
|
||||||
if (!$summary['ok']) {
|
if ($apiInfo['version'] === 6) {
|
||||||
$errors[] = $makeError('summary', $summary);
|
$sid = (string)($apiInfo['sid'] ?? '');
|
||||||
|
$summary = $apiInfo['probe'];
|
||||||
|
if (!$summary['ok']) {
|
||||||
|
$errors[] = $makeError('summary', $summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
$blocking = $v6Request($instance, 'dns/blocking', 'GET', [], $sid);
|
||||||
|
if (!$blocking['ok']) {
|
||||||
|
$errors[] = $makeError('blocking', $blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
$queries = $v6Request($instance, 'queries?from=' . $from . '&until=' . $now . '&length=2000', 'GET', [], $sid);
|
||||||
|
if (!$queries['ok']) {
|
||||||
|
$errors[] = $makeError('queries', $queries);
|
||||||
|
}
|
||||||
|
|
||||||
|
$upstreams = $v6Request($instance, 'stats/upstreams', 'GET', [], $sid);
|
||||||
|
if (!$upstreams['ok']) {
|
||||||
|
$errors[] = $makeError('upstreams', $upstreams);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($summary['ok'] && is_array($summary['data'])) {
|
||||||
|
$sum = $summary['data'];
|
||||||
|
$queriesBlock = (array)($sum['queries'] ?? []);
|
||||||
|
$clientsBlock = (array)($sum['clients'] ?? []);
|
||||||
|
$status = 'unknown';
|
||||||
|
if ($blocking['ok'] && is_array($blocking['data'])) {
|
||||||
|
$blockingState = $blocking['data']['blocking'] ?? null;
|
||||||
|
if ($blockingState === true || $blockingState === 'enabled') {
|
||||||
|
$status = 'enabled';
|
||||||
|
} elseif ($blockingState === false || $blockingState === 'disabled') {
|
||||||
|
$status = 'disabled';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$summaryData = [
|
||||||
|
'dns_queries_today' => (int)($queriesBlock['total'] ?? 0),
|
||||||
|
'ads_blocked_today' => (int)($queriesBlock['blocked'] ?? 0),
|
||||||
|
'unique_clients' => (int)($clientsBlock['active'] ?? $clientsBlock['total'] ?? 0),
|
||||||
|
'unique_domains' => (int)($queriesBlock['unique_domains'] ?? 0),
|
||||||
|
'queries_forwarded' => (int)($queriesBlock['forwarded'] ?? 0),
|
||||||
|
'queries_cached' => (int)($queriesBlock['cached'] ?? 0),
|
||||||
|
'status' => $status,
|
||||||
|
];
|
||||||
|
if ($summaryData['dns_queries_today'] > 0) {
|
||||||
|
$summaryData['ads_percentage_today'] = round(
|
||||||
|
$summaryData['ads_blocked_today'] / $summaryData['dns_queries_today'] * 100,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$summaryData['ads_percentage_today'] = 0;
|
||||||
|
}
|
||||||
|
$queryTypesData = (array)($queriesBlock['types'] ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($queries['ok'] && is_array($queries['data'])) {
|
||||||
|
$queryList = (array)($queries['data']['queries'] ?? []);
|
||||||
|
$topAds = [];
|
||||||
|
$topQueries = [];
|
||||||
|
$sources = [];
|
||||||
|
$recent = [];
|
||||||
|
|
||||||
|
foreach ($queryList as $entry) {
|
||||||
|
if (!is_array($entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$domainRaw = $entry['domain'] ?? '';
|
||||||
|
$domain = '';
|
||||||
|
if (is_array($domainRaw)) {
|
||||||
|
$domain = (string)($domainRaw['name'] ?? $domainRaw['domain'] ?? '');
|
||||||
|
} else {
|
||||||
|
$domain = (string)$domainRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clientRaw = $entry['client'] ?? '';
|
||||||
|
$client = '';
|
||||||
|
if (is_array($clientRaw)) {
|
||||||
|
$name = (string)($clientRaw['name'] ?? '');
|
||||||
|
$ip = (string)($clientRaw['ip'] ?? '');
|
||||||
|
$client = $name !== '' ? ($name . ' (' . $ip . ')') : ($ip !== '' ? $ip : 'unknown');
|
||||||
|
} else {
|
||||||
|
$client = (string)$clientRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($client !== '') {
|
||||||
|
$sources[$client] = ($sources[$client] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
if ($domain !== '') {
|
||||||
|
$topQueries[$domain] = ($topQueries[$domain] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$statusVal = (string)($entry['status'] ?? '');
|
||||||
|
$isBlocked = str_contains($statusVal, 'GRAVITY') || str_contains($statusVal, 'BLOCK');
|
||||||
|
if ($isBlocked && $domain !== '') {
|
||||||
|
$topAds[$domain] = ($topAds[$domain] ?? 0) + 1;
|
||||||
|
$recent[] = ['domain' => $domain, 'instance' => $instance['name']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$topData = ['top_ads' => $topAds, 'top_queries' => $topQueries];
|
||||||
|
$querySourcesData = $sources;
|
||||||
|
$recentData = $recent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($upstreams['ok'] && is_array($upstreams['data'])) {
|
||||||
|
$upList = (array)($upstreams['data']['upstreams'] ?? []);
|
||||||
|
$forwardDestData = [];
|
||||||
|
foreach ($upList as $item) {
|
||||||
|
if (!is_array($item)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$label = (string)($item['name'] ?? $item['ip'] ?? '');
|
||||||
|
if ($label === '' && isset($item['port'])) {
|
||||||
|
$label = 'upstream:' . (string)$item['port'];
|
||||||
|
}
|
||||||
|
if ($label === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$forwardDestData[$label] = (int)($item['count'] ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$summary = $apiInfo['probe'];
|
||||||
|
$topItems = $v5Request($instance, ['topItems' => 50]);
|
||||||
|
$queryTypes = $v5Request($instance, ['getQueryTypes' => 1]);
|
||||||
|
$querySources = $v5Request($instance, ['getQuerySources' => 1]);
|
||||||
|
$forwardDest = $v5Request($instance, ['getForwardDestinations' => 1]);
|
||||||
|
$recentBlocked = $v5Request($instance, ['recentBlocked' => 30]);
|
||||||
|
$versions = $v5Request($instance, ['versions' => 1]);
|
||||||
|
|
||||||
|
if (!$summary['ok']) {
|
||||||
|
$errors[] = $makeError('summary', $summary);
|
||||||
|
}
|
||||||
|
if (!$topItems['ok']) {
|
||||||
|
$errors[] = $makeError('topItems', $topItems);
|
||||||
|
}
|
||||||
|
if (!$queryTypes['ok']) {
|
||||||
|
$errors[] = $makeError('queryTypes', $queryTypes);
|
||||||
|
}
|
||||||
|
if (!$querySources['ok']) {
|
||||||
|
$errors[] = $makeError('querySources', $querySources);
|
||||||
|
}
|
||||||
|
if (!$forwardDest['ok']) {
|
||||||
|
$errors[] = $makeError('forwardDestinations', $forwardDest);
|
||||||
|
}
|
||||||
|
if (!$recentBlocked['ok']) {
|
||||||
|
$errors[] = $makeError('recentBlocked', $recentBlocked);
|
||||||
|
}
|
||||||
|
if (!$versions['ok']) {
|
||||||
|
$errors[] = $makeError('versions', $versions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$summaryData = $summary['ok'] ? $summary['data'] : null;
|
||||||
|
$topData = $topItems['ok'] ? $topItems['data'] : null;
|
||||||
|
$queryTypesData = $queryTypes['ok'] ? $extractQueryTypes($queryTypes['data']) : null;
|
||||||
|
$querySourcesData = $querySources['ok'] ? $extractSources($querySources['data']) : null;
|
||||||
|
$forwardDestData = $forwardDest['ok'] ? $extractForwardDestinations($forwardDest['data']) : null;
|
||||||
|
$recentData = $recentBlocked['ok'] ? $recentBlocked['data'] : null;
|
||||||
|
$versionsData = $versions['ok'] ? $versions['data'] : null;
|
||||||
|
$updates = $parseUpdates(is_array($versionsData) ? $versionsData : null);
|
||||||
|
} else {
|
||||||
|
$probe = $apiInfo['probe'] ?? ['error' => 'unknown'];
|
||||||
|
$errors[] = $makeError('probe', is_array($probe) ? $probe : ['error' => 'unknown']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$topItems = $apiRequest($instance, ['topItems' => 50]);
|
|
||||||
if (!$topItems['ok']) {
|
|
||||||
$errors[] = $makeError('topItems', $topItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
$queryTypes = $apiRequest($instance, ['getQueryTypes' => 1]);
|
|
||||||
if (!$queryTypes['ok']) {
|
|
||||||
$errors[] = $makeError('queryTypes', $queryTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
$querySources = $apiRequest($instance, ['getQuerySources' => 1]);
|
|
||||||
if (!$querySources['ok']) {
|
|
||||||
$errors[] = $makeError('querySources', $querySources);
|
|
||||||
}
|
|
||||||
|
|
||||||
$forwardDest = $apiRequest($instance, ['getForwardDestinations' => 1]);
|
|
||||||
if (!$forwardDest['ok']) {
|
|
||||||
$errors[] = $makeError('forwardDestinations', $forwardDest);
|
|
||||||
}
|
|
||||||
|
|
||||||
$recentBlocked = $apiRequest($instance, ['recentBlocked' => 30]);
|
|
||||||
if (!$recentBlocked['ok']) {
|
|
||||||
$errors[] = $makeError('recentBlocked', $recentBlocked);
|
|
||||||
}
|
|
||||||
|
|
||||||
$versions = $apiRequest($instance, ['versions' => 1]);
|
|
||||||
if (!$versions['ok']) {
|
|
||||||
$errors[] = $makeError('versions', $versions);
|
|
||||||
}
|
|
||||||
|
|
||||||
$summaryData = $summary['ok'] ? $summary['data'] : null;
|
|
||||||
$topData = $topItems['ok'] ? $topItems['data'] : null;
|
|
||||||
$queryTypesData = $queryTypes['ok'] ? $extractQueryTypes($queryTypes['data']) : null;
|
|
||||||
$querySourcesData = $querySources['ok'] ? $extractSources($querySources['data']) : null;
|
|
||||||
$forwardDestData = $forwardDest['ok'] ? $extractForwardDestinations($forwardDest['data']) : null;
|
|
||||||
$recentData = $recentBlocked['ok'] ? $recentBlocked['data'] : null;
|
|
||||||
$versionsData = $versions['ok'] ? $versions['data'] : null;
|
|
||||||
$updates = $parseUpdates(is_array($versionsData) ? $versionsData : null);
|
|
||||||
|
|
||||||
if (is_array($summaryData)) {
|
if (is_array($summaryData)) {
|
||||||
$aggregate['summary']['dns_queries_today'] += (int)($summaryData['dns_queries_today'] ?? 0);
|
$aggregate['summary']['dns_queries_today'] += (int)($summaryData['dns_queries_today'] ?? 0);
|
||||||
$aggregate['summary']['ads_blocked_today'] += (int)($summaryData['ads_blocked_today'] ?? 0);
|
$aggregate['summary']['ads_blocked_today'] += (int)($summaryData['ads_blocked_today'] ?? 0);
|
||||||
@@ -384,12 +600,52 @@ if ($action === 'test') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$instance = $instances[$target];
|
$instance = $instances[$target];
|
||||||
$result = $apiRequest($instance, ['summaryRaw' => 1]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$sid = (string)($apiInfo['sid'] ?? '');
|
||||||
|
$result = $apiInfo['probe'];
|
||||||
|
if ($result['ok']) {
|
||||||
|
$respond([
|
||||||
|
'ok' => true,
|
||||||
|
'status' => 'ok',
|
||||||
|
'message' => 'Verbindung OK. API v6 antwortet.',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$httpCode = (int)($result['http_code'] ?? 0);
|
||||||
|
$error = (string)($result['error'] ?? 'error');
|
||||||
|
$status = 'error';
|
||||||
|
$message = 'Unbekannter Fehler.';
|
||||||
|
|
||||||
|
if ($httpCode === 0) {
|
||||||
|
$status = 'unreachable';
|
||||||
|
$message = 'Host nicht erreichbar oder kein HTTP-Response.';
|
||||||
|
} elseif ($httpCode === 401 || $httpCode === 403) {
|
||||||
|
$status = 'auth';
|
||||||
|
$message = 'API Passwort falsch oder nicht berechtigt.';
|
||||||
|
} elseif ($error === 'invalid_json') {
|
||||||
|
$status = 'invalid';
|
||||||
|
$message = 'API antwortet nicht mit JSON. URL pruefen.';
|
||||||
|
} else {
|
||||||
|
$status = 'error';
|
||||||
|
$message = 'API Fehler: ' . $error . ' (HTTP ' . $httpCode . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
$respond([
|
||||||
|
'ok' => false,
|
||||||
|
'status' => $status,
|
||||||
|
'message' => $message,
|
||||||
|
'http_code' => $httpCode,
|
||||||
|
'error' => $error,
|
||||||
|
'url' => (string)($result['url'] ?? ''),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $v5Request($instance, ['summaryRaw' => 1]);
|
||||||
if ($result['ok']) {
|
if ($result['ok']) {
|
||||||
$respond([
|
$respond([
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
'status' => 'ok',
|
'status' => 'ok',
|
||||||
'message' => 'Verbindung OK. API antwortet.',
|
'message' => 'Verbindung OK. API v5 antwortet.',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +692,18 @@ if ($action === 'disable') {
|
|||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, ['disable' => $minutes * 60]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$sid = (string)($apiInfo['sid'] ?? '');
|
||||||
|
$result = $v6Request($instance, 'dns/blocking', 'POST', [
|
||||||
|
'blocking' => false,
|
||||||
|
'timer' => $minutes * 60,
|
||||||
|
], $sid);
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, ['disable' => $minutes * 60]);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
@@ -452,7 +719,17 @@ if ($action === 'enable') {
|
|||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, ['enable' => 1]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$sid = (string)($apiInfo['sid'] ?? '');
|
||||||
|
$result = $v6Request($instance, 'dns/blocking', 'POST', [
|
||||||
|
'blocking' => true,
|
||||||
|
], $sid);
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, ['enable' => 1]);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
@@ -467,7 +744,15 @@ if ($action === 'gravity') {
|
|||||||
}
|
}
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, ['updateGravity' => 1]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$sid = (string)($apiInfo['sid'] ?? '');
|
||||||
|
$result = $v6Request($instance, 'action/gravity', 'POST', [], $sid);
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, ['updateGravity' => 1]);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
@@ -492,7 +777,14 @@ if ($action === 'domain_add') {
|
|||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, $params);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$result = ['ok' => false, 'error' => 'not_supported_v6', 'http_code' => 400, 'url' => ''];
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, $params);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
@@ -512,7 +804,14 @@ if ($action === 'adlist_add') {
|
|||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, ['list' => 'adlist', 'add' => $url]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$result = ['ok' => false, 'error' => 'not_supported_v6', 'http_code' => 400, 'url' => ''];
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, ['list' => 'adlist', 'add' => $url]);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
@@ -528,7 +827,14 @@ if ($action === 'update') {
|
|||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
foreach ($targets as $id => $instance) {
|
foreach ($targets as $id => $instance) {
|
||||||
$result = $apiRequest($instance, ['update' => 1]);
|
$apiInfo = $detectApi($instance);
|
||||||
|
if ($apiInfo['version'] === 6) {
|
||||||
|
$result = ['ok' => false, 'error' => 'not_supported_v6', 'http_code' => 400, 'url' => ''];
|
||||||
|
} elseif ($apiInfo['version'] === 5) {
|
||||||
|
$result = $v5Request($instance, ['update' => 1]);
|
||||||
|
} else {
|
||||||
|
$result = ['ok' => false, 'error' => 'unknown_api', 'http_code' => 0, 'url' => ''];
|
||||||
|
}
|
||||||
$results[$id] = $result;
|
$results[$id] = $result;
|
||||||
}
|
}
|
||||||
$respond(['ok' => true, 'results' => $results]);
|
$respond(['ok' => true, 'results' => $results]);
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ if ($primaryId === '') {
|
|||||||
<input type="text" name="url" placeholder="http://pi-hole.local" required>
|
<input type="text" name="url" placeholder="http://pi-hole.local" required>
|
||||||
</label>
|
</label>
|
||||||
<label class="form-field">
|
<label class="form-field">
|
||||||
<span class="muted">API Token (leer lassen = unveraendert)</span>
|
<span class="muted">API Token / Web-Passwort (v6) (leer lassen = unveraendert)</span>
|
||||||
<input type="password" name="token" placeholder="Token" autocomplete="new-password">
|
<input type="password" name="token" placeholder="Token" autocomplete="new-password">
|
||||||
</label>
|
</label>
|
||||||
<label class="form-field" style="align-items:center;">
|
<label class="form-field" style="align-items:center;">
|
||||||
|
|||||||
Reference in New Issue
Block a user