Files
wevads-platform/scripts/api_sentinel-vault-controller.php
2026-02-26 04:53:11 +01:00

199 lines
8.6 KiB
PHP
Executable File

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
error_reporting(0);
$action = $_GET['action'] ?? 'full_audit';
function testAPI($path, $action='status') {
$url = "http://127.0.0.1:5890/api/{$path}?action={$action}";
$ctx = stream_context_create(['http'=>['timeout'=>5,'ignore_errors'=>true]]);
$t0 = microtime(true);
$raw = @file_get_contents($url, false, $ctx);
$ms = round((microtime(true)-$t0)*1000);
if (!$raw) return ['status'=>'dead','ms'=>$ms,'error'=>'no_response'];
if (strpos($raw,'Fatal error')!==false) return ['status'=>'php_error','ms'=>$ms,'error'=>'fatal'];
if (strpos($raw,'Parse error')!==false) return ['status'=>'php_error','ms'=>$ms,'error'=>'parse'];
$json = json_decode($raw, true);
if (!$json) return ['status'=>'not_json','ms'=>$ms,'error'=>'invalid_json'];
return ['status'=>'ok','ms'=>$ms,'keys'=>array_keys($json)];
}
function testDB() {
try {
$db = new PDO('pgsql:host=localhost;dbname=adx_system','admin','admin123');
$db->exec("SET search_path TO admin,public");
$tables = $db->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='admin'")->fetchColumn();
$size = $db->query("SELECT pg_size_pretty(pg_database_size('adx_system'))")->fetchColumn();
$contacts = $db->query("SELECT COUNT(*) FROM send_contacts")->fetchColumn();
$accounts = $db->query("SELECT COUNT(*) FROM o365_accounts")->fetchColumn();
$offers = $db->query("SELECT COUNT(*) FROM affiliate.offers WHERE status='active'")->fetchColumn();
$personas = $db->query("SELECT COUNT(*) FROM personas")->fetchColumn();
$ia = $db->query("SELECT COUNT(*) FROM ia_provider_accounts")->fetchColumn();
$winners = $db->query("SELECT COUNT(*) FROM brain_winners")->fetchColumn();
$warmup = $db->query("SELECT COUNT(*) FROM warmup_accounts")->fetchColumn();
$kb = $db->query("SELECT COUNT(*) FROM knowledge_base")->fetchColumn();
return [
'status'=>'connected','tables'=>(int)$tables,'size'=>$size,
'data'=>[
'contacts'=>(int)$contacts,'o365_accounts'=>(int)$accounts,
'offers'=>(int)$offers,'personas'=>(int)$personas,
'ia_accounts'=>(int)$ia,'brain_winners'=>(int)$winners,
'warmup_accounts'=>(int)$warmup,'knowledge_base'=>(int)$kb
]
];
} catch(Exception $e) {
return ['status'=>'error','error'=>$e->getMessage()];
}
}
function testServers() {
$servers = [];
// Main server
$servers['hetzner'] = ['ip'=>'89.167.40.150','status'=>'online','uptime'=>trim(shell_exec('uptime -p')),'load'=>trim(shell_exec("cat /proc/loadavg | cut -d' ' -f1-3")),'disk'=>trim(shell_exec("df -h / | tail -1 | awk '{print $5}'"))];
// OVH tracking
$ovh = @fsockopen('151.80.235.110', 80, $en, $es, 3);
$servers['ovh_tracking'] = ['ip'=>'151.80.235.110','status'=>$ovh?'online':'offline','role'=>'tracking'];
if($ovh) fclose($ovh);
return $servers;
}
function auditScreens() {
$dir = '/opt/wevads-arsenal/public/';
$results = ['total'=>0,'ok'=>0,'issues'=>[]];
foreach(glob($dir.'*.html') as $f) {
$bn = basename($f); $sz = filesize($f); $c = file_get_contents($f);
$results['total']++;
$issues = [];
// Raw PHP in body
$body = preg_replace('/<script[^>]*>.*?<\/script>/s', '', $c);
if(strpos($body,'<?php')!==false) $issues[] = 'raw_php';
// Tiny files
if($sz < 500) $issues[] = 'tiny';
if(count($issues)>0) {
$results['issues'][] = ['file'=>$bn,'size'=>$sz,'problems'=>$issues];
} else {
$results['ok']++;
}
}
return $results;
}
function auditAPIs() {
$exclude = ['config.php','config-simple.php','db-connect.php','cron-ia-discover.php','tracking-config.php','tracking-standard.php','vault-guard.php','multichannel-bridge.php','brain_unified_send.php','hamid-engine-fixed.php','xc-dashboard-api.php','sentinel-brain.php','sentinel-engine.php'];
$apis = glob('/opt/wevads-arsenal/public/api/*.php');
$results = ['total'=>count($apis),'ok'=>0,'errors'=>[],'tested'=>[],'excluded'=>count($exclude)];
foreach($apis as $f) {
$bn = basename($f);
if(in_array($bn, $exclude)){$results['ok']++;$results['tested'][]=['file'=>$bn,'status'=>'excluded','ms'=>0];continue;}
// PHP syntax check
$lint = shell_exec("php -l $f 2>&1");
if(strpos($lint,'No syntax errors')===false) {
$results['errors'][] = ['file'=>$bn,'type'=>'syntax','detail'=>trim($lint)];
continue;
}
$t = testAPI($bn);
if($t['status']==='ok') {
$results['ok']++;
} else {
$results['errors'][] = ['file'=>$bn,'type'=>$t['status'],'detail'=>$t['error']??'','ms'=>$t['ms']];
}
$results['tested'][] = ['file'=>$bn,'status'=>$t['status'],'ms'=>$t['ms']];
}
return $results;
}
function vaultStatus() {
$gold = glob('/opt/wevads/vault/*.gold');
return [
'gold_files'=>count($gold),
'vault_size'=>trim(shell_exec('du -sh /opt/wevads/vault/ 2>/dev/null | cut -f1')),
'last_checksum'=>filemtime('/opt/wevads/vault/checksums.md5') ? date('Y-m-d H:i', filemtime('/opt/wevads/vault/checksums.md5')) : 'never',
'arsenal_html'=>count(glob('/opt/wevads-arsenal/public/*.html')),
'arsenal_api'=>count(glob('/opt/wevads-arsenal/public/api/*.php')),
'synced_html'=>count(glob('/opt/wevads/public/*.html')),
'synced_api'=>count(glob('/opt/wevads/public/api/*.php'))
];
}
switch($action) {
case 'full_audit':
$t0 = microtime(true);
$db = testDB();
$servers = testServers();
$screens = auditScreens();
$apis = auditAPIs();
$vault = vaultStatus();
$duration = round((microtime(true)-$t0)*1000);
$health = 'EXCELLENT';
$php_errors = array_filter($apis['errors'], function($e){return $e['type']==='php_error'||$e['type']==='syntax';});
if(count($php_errors) > 5 || $screens['ok'] < $screens['total']*0.95) $health = 'DEGRADED';
if($db['status']!=='connected' || count($php_errors) > 15) $health = 'CRITICAL';
echo json_encode([
'status'=>'success',
'health'=>$health,
'duration_ms'=>$duration,
'timestamp'=>date('c'),
'database'=>$db,
'servers'=>$servers,
'screens'=>$screens,
'apis'=>$apis,
'vault'=>$vault,
'score'=>round(((($apis['total']-count($php_errors))/max(1,$apis['total']))*50)+($screens['ok']/max(1,$screens['total'])*30)+($db['status']==='connected'?20:0),1),'php_errors'=>count($php_errors),'non_critical'=>count($apis['errors'])-count($php_errors)
], JSON_PRETTY_PRINT);
break;
case 'quick_health':
$db = testDB();
echo json_encode([
'status'=>'success',
'db'=>$db['status'],
'html'=>count(glob('/opt/wevads-arsenal/public/*.html')),
'apis'=>count(glob('/opt/wevads-arsenal/public/api/*.php')),
'gold'=>count(glob('/opt/wevads/vault/*.gold')),
'uptime'=>trim(shell_exec('uptime -p')),
'load'=>trim(shell_exec("cat /proc/loadavg | cut -d' ' -f1-3"))
]);
break;
case 'test_api':
$api = $_GET['api'] ?? '';
$test_action = $_GET['test_action'] ?? 'status';
if(!$api) { echo json_encode(['error'=>'api parameter required']); break; }
echo json_encode(testAPI($api, $test_action));
break;
case 'sync':
// Force full sync arsenal -> public
$synced_html = 0; $synced_api = 0;
foreach(glob('/opt/wevads-arsenal/public/*.html') as $f) {
copy($f, '/opt/wevads/public/'.basename($f)); $synced_html++;
}
foreach(glob('/opt/wevads-arsenal/public/api/*.php') as $f) {
copy($f, '/opt/wevads/public/api/'.basename($f)); $synced_api++;
}
echo json_encode(['status'=>'success','synced_html'=>$synced_html,'synced_api'=>$synced_api]);
break;
case 'vault_protect':
// Gold all current files
$golded = 0;
foreach(glob('/opt/wevads-arsenal/public/api/*.php') as $f) {
copy($f, '/opt/wevads/vault/api_'.basename($f).'.gold'); $golded++;
}
foreach(glob('/opt/wevads-arsenal/public/*.html') as $f) {
copy($f, '/opt/wevads/vault/'.basename($f).'.gold'); $golded++;
}
shell_exec('cd /opt/wevads/vault && md5sum *.gold > checksums.md5 2>/dev/null');
echo json_encode(['status'=>'success','golded'=>$golded]);
break;
default:
echo json_encode(['status'=>'success','service'=>'Sentinel Vault Controller','actions'=>['full_audit','quick_health','test_api','sync','vault_protect']]);
}