'unauthorized'])); } $action = $_REQUEST['action'] ?? ''; function cx($cmd, $t=12) { $e=base64_encode($cmd); $c=curl_init('https://weval-consulting.com/api/cx'); curl_setopt_array($c,[CURLOPT_POST=>1,CURLOPT_POSTFIELDS=>"k=WEVADS2026&c=$e",CURLOPT_RETURNTRANSFER=>1,CURLOPT_TIMEOUT=>$t,CURLOPT_SSL_VERIFYPEER=>0]); $r=curl_exec($c);curl_close($c);return $r; } function s95($cmd) { $e=urlencode($cmd); return cx("curl -s -m 12 'http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd=$e'"); } function s151($cmd) { return cx("sshpass -p REDACTED_SSH ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 ubuntu@151.80.235.110 ".escapeshellarg($cmd)); } function blade_push($t,$c,$l) { $h=curl_init('https://weval-consulting.com/api/blade-api.php');curl_setopt_array($h,[CURLOPT_POST=>1,CURLOPT_POSTFIELDS=>http_build_query(['k'=>'BLADE2026','action'=>'push','type'=>$t,'cmd'=>$c,'label'=>$l,'source'=>'blade-ops']),CURLOPT_RETURNTRANSFER=>1,CURLOPT_TIMEOUT=>5,CURLOPT_SSL_VERIFYPEER=>0]);$r=curl_exec($h);curl_close($h);return json_decode($r,1); } function fetch_url($u,$t=10) { $c=curl_init($u);curl_setopt_array($c,[CURLOPT_RETURNTRANSFER=>1,CURLOPT_TIMEOUT=>$t,CURLOPT_SSL_VERIFYPEER=>0,CURLOPT_FOLLOWLOCATION=>1]);$r=curl_exec($c);curl_close($c);return $r; } function tg($msg) { @file_get_contents("https://api.telegram.org/bot8544624912:AAG0DkXOvKhiADpLPbRmhivA-SkvFMxZDKg/sendMessage?chat_id=7605775322&text=".urlencode($msg)); } switch ($action) { // ═══════════════════════════════════════ // INFRASTRUCTURE (10) // ═══════════════════════════════════════ case 'health': $d=trim(cx("df -h / | tail -1 | awk '{print \$5}'"));$dk=(int)trim(cx('docker ps -q 2>/dev/null | wc -l'));$ld=trim(cx("uptime | grep -oP 'load average: \K[0-9.]+'")); $s95r=json_decode(s95('echo OK'),1);$s151r=trim(s151('echo OK')); $sso=trim(cx('curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:9443/outpost.goauthentik.io/ping 2>/dev/null')); $bl=json_decode(fetch_url('https://weval-consulting.com/api/blade-api.php?k=BLADE2026&action=status'),1); echo json_encode(['ok'=>1,'health'=>['s204'=>['status'=>'ok','disk'=>$d,'docker'=>$dk,'load'=>$ld],'s95'=>['status'=>($s95r&&($s95r['exit_code']??1)===0)?'ok':'down'],'s151'=>['status'=>($s151r==='OK')?'ok':'down'],'sso'=>['status'=>($sso==='204')?'ok':'down','code'=>$sso],'blade'=>['status'=>($bl['blade']['online']??0)?'online':'offline']],'ts'=>date('c')]); break; case 'sso_check': $c=trim(cx('curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:9443/outpost.goauthentik.io/ping 2>/dev/null'));$su=[]; foreach(['auth','crm','n8n','mm','analytics','wevads','deerflow'] as $s) $su[$s]=trim(cx("curl -sk -o /dev/null -w '%{http_code}' 'https://$s.weval-consulting.com/' 2>/dev/null")); echo json_encode(['ok'=>1,'outpost'=>$c,'subdomains'=>$su]);break; case 'sso_fix': $r=cx('cd /opt/authentik && docker compose restart 2>&1 | tail -2',30);sleep(15); $c=trim(cx('curl -sk -o /dev/null -w "%{http_code}" https://127.0.0.1:9443/outpost.goauthentik.io/ping 2>/dev/null')); tg("SSO FIX via Blade: outpost=$c");echo json_encode(['ok'=>1,'output'=>$r,'outpost'=>$c]);break; case 'exec': $cmd=$_REQUEST['cmd']??'';$tgt=$_REQUEST['target']??'s204';if(!$cmd){echo json_encode(['error'=>'no cmd']);break;} $r=($tgt==='s95')?s95($cmd):(($tgt==='s151')?s151($cmd):cx($cmd,20));echo json_encode(['ok'=>1,'target'=>$tgt,'output'=>$r]);break; case 'nonreg': echo json_encode(['ok'=>1,'output'=>cx('cd /opt/weval-nonreg && timeout 90 python3 nonreg-master.py 2>&1 | grep -E "NONREG|FAIL|PASS"',100)]);break; case 'sso_nonreg': echo json_encode(['ok'=>1,'output'=>cx('cd /tmp && timeout 180 node /opt/weval-nonreg/sso-nonreg.js 2>&1 | tail -15',190)]);break; case 'docker': $sub=$_REQUEST['sub']??'ps';$svc=$_REQUEST['service']??''; echo json_encode(['ok'=>1,'output'=>match($sub){'restart'=>$svc?cx("docker restart $svc 2>&1"):'no service','logs'=>$svc?cx("docker logs --tail 30 $svc 2>&1"):'no service','ps'=>cx('docker ps --format "{{.Names}}\t{{.Status}}" 2>/dev/null'),default=>'unknown'}]);break; case 'git': $sub=$_REQUEST['sub']??'log --oneline -5';echo json_encode(['ok'=>1,'output'=>cx("cd /var/www/html && git -c safe.directory=/var/www/html $sub 2>&1 | head -30")]);break; case 'nginx': $sub=$_REQUEST['sub']??'test';echo json_encode(['ok'=>1,'output'=>match($sub){'reload'=>cx('sudo systemctl reload nginx 2>&1;echo DONE'),'status'=>cx('systemctl status nginx 2>&1 | head -5'),default=>cx('sudo nginx -t 2>&1 | tail -2')}]);break; case 'disk': echo json_encode(['ok'=>1,'output'=>cx('df -h / | tail -1;echo "---";du -sh /var/log/*.log 2>/dev/null | sort -rh | head -5;echo "---";du -sh /tmp/* 2>/dev/null | sort -rh | head -3')]);break; // ═══════════════════════════════════════ // DATA (3) // ═══════════════════════════════════════ case 'ethica': echo fetch_url('https://weval-consulting.com/api/ethica-api.php?action=stats&token=ETHICA_API_2026_SECURE');break; case 'leads': $r=json_decode(s95("PGPASSWORD=admin123 psql -U admin -d adx_system -h localhost -t -c \"SELECT count(*) as leads, count(CASE WHEN email IS NOT NULL AND email!='' THEN 1 END) as emails, count(CASE WHEN phone IS NOT NULL AND phone!='' THEN 1 END) as phones FROM admin.weval_leads\""),1); echo json_encode(['ok'=>1,'output'=>$r['output']??'']);break; case 'db': $q=$_REQUEST['q']??'';$db=$_REQUEST['db']??'wevia_db';if(!$q){echo json_encode(['error'=>'no query']);break;} echo json_encode(['ok'=>1,'output'=>($db==='adx_system')?s95("PGPASSWORD=admin123 psql -U admin -d adx_system -h localhost -t -c ".escapeshellarg($q)):cx("psql -U postgres -d $db -t -c ".escapeshellarg($q))]);break; // ═══════════════════════════════════════ // WEB (3) // ═══════════════════════════════════════ case 'search': $q=$_REQUEST['q']??'';$lim=intval($_REQUEST['limit']??5);if(!$q){echo json_encode(['error'=>'no query']);break;} $r=fetch_url("http://127.0.0.1:8888/search?q=".urlencode($q)."&format=json&pageno=1",10);$d=json_decode($r,1); $res=array_map(fn($r)=>['title'=>$r['title']??'','url'=>$r['url']??'','content'=>substr($r['content']??'',0,200)],array_slice($d['results']??[],0,$lim)); echo json_encode(['ok'=>1,'query'=>$q,'count'=>count($res),'results'=>$res]);break; case 'fetch': $url=$_REQUEST['url']??'';if(!$url){echo json_encode(['error'=>'no url']);break;} $h=fetch_url($url,15);$t=preg_replace('/\s+/',' ',strip_tags(preg_replace('/]*>.*?<\/script>/si','',$h))); echo json_encode(['ok'=>1,'url'=>$url,'length'=>strlen($h),'text'=>substr(trim($t),0,3000)]);break; case 'browse': $url=$_REQUEST['url']??'';$type=$_REQUEST['type']??'extract';if(!$url){echo json_encode(['error'=>'no url']);break;} if($type==='screenshot'){$ts=date('Ymd_His');$p="/var/www/html/api/blade-tasks/browse_$ts.png"; $s="const{chromium}=require('playwright');(async()=>{const b=await chromium.launch({args:['--no-sandbox']});const p=await b.newPage();await p.goto('$url',{waitUntil:'networkidle',timeout:20000});await p.screenshot({path:'$p',fullPage:true});await b.close();console.log(JSON.stringify({ok:true,screenshot:'/api/blade-tasks/browse_$ts.png'}))})();"; } else { $s="const{chromium}=require('playwright');(async()=>{const b=await chromium.launch({args:['--no-sandbox']});const p=await b.newPage();await p.goto('$url',{waitUntil:'domcontentloaded',timeout:15000});const t=await p.title();const h=await p.content();const x=h.replace(/]*>[\\s\\S]*?<\\/script>/gi,'').replace(/<[^>]+>/g,' ').replace(/\\s+/g,' ').trim().substring(0,3000);await b.close();console.log(JSON.stringify({ok:true,title:t,text:x}))})();"; } $r=cx("cd /tmp && timeout 30 node -e ".escapeshellarg($s)." 2>/dev/null",35);$d=json_decode($r,1); echo $d?json_encode($d):json_encode(['ok'=>0,'raw'=>substr($r,0,300)]);break; // ═══════════════════════════════════════ // EMAIL (5) // ═══════════════════════════════════════ case 'email_list': echo fetch_url('https://weval-consulting.com/products/wevialife-api.php?action=email_fetch&limit='.intval($_REQUEST['limit']??15));break; case 'email_read': $uid=intval($_REQUEST['uid']??0);if(!$uid){echo json_encode(['error'=>'no uid']);break;} echo fetch_url("https://weval-consulting.com/products/wevialife-api.php?action=email_body&uid=$uid")??json_encode(['error'=>'fail']);break; case 'email_draft': $uid=intval($_REQUEST['uid']??0);$tone=$_REQUEST['tone']??'professional';if(!$uid){echo json_encode(['error'=>'no uid']);break;} echo fetch_url("https://weval-consulting.com/products/wevialife-api.php?action=draft_response&uid=$uid&tone=$tone",30)??json_encode(['error'=>'fail']);break; case 'email_urgent': echo fetch_url('https://weval-consulting.com/products/wevialife-api.php?action=urgent_to_respond&limit='.intval($_REQUEST['limit']??10));break; case 'email_vip': echo json_encode(['ok'=>1,'output'=>cx("psql -U postgres -d wevia_db -t -c \"SET search_path TO admin,public; SELECT ed.uid, ed.from_name, ed.subject, LEFT(ed.draft,150) as preview FROM email_drafts ed ORDER BY ed.generated_at DESC LIMIT 10\"")]);break; // ═══════════════════════════════════════ // AI (2) // ═══════════════════════════════════════ case 'ai': $p=$_REQUEST['prompt']??'';$m=$_REQUEST['model']??'qwen3:8b';if(!$p){echo json_encode(['error'=>'no prompt']);break;} $c=curl_init('http://127.0.0.1:11435/api/generate');curl_setopt_array($c,[CURLOPT_POST=>1,CURLOPT_POSTFIELDS=>json_encode(['model'=>$m,'prompt'=>$p,'stream'=>false]),CURLOPT_HTTPHEADER=>['Content-Type: application/json'],CURLOPT_RETURNTRANSFER=>1,CURLOPT_TIMEOUT=>60]);$r=curl_exec($c);curl_close($c);$d=json_decode($r,1); echo json_encode(['ok'=>1,'model'=>$m,'response'=>$d['response']??'']);break; case 'ai_models': $r=fetch_url('http://127.0.0.1:11435/api/tags');$d=json_decode($r,1); echo json_encode(['ok'=>1,'models'=>array_map(fn($m)=>['name'=>$m['name'],'size'=>round(($m['size']??0)/1e9,1).'GB'],$d['models']??[])]);break; // ═══════════════════════════════════════ // BLADE DESKTOP (4) // ═══════════════════════════════════════ case 'purge_cookies': $br=$_REQUEST['browser']??'all';$n=0; if($br!=='chrome'){blade_push('powershell','Stop-Process -Name msedge -Force -EA 0;Start-Sleep 2;Remove-Item "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Cookies" -Force -EA 0;Remove-Item "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Network\Cookies" -Force -EA 0;Remove-Item "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Session Storage\*" -Force -Recurse -EA 0;Write-Output EDGE_PURGED','Purge Edge');$n++;} if($br!=='edge'){blade_push('powershell','Stop-Process -Name chrome -Force -EA 0;Start-Sleep 2;Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cookies" -Force -EA 0;Remove-Item "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Network\Cookies" -Force -EA 0;Write-Output CHROME_PURGED','Purge Chrome');$n++;} blade_push('powershell','Start-Sleep 3;Start-Process msedge "https://weval-consulting.com/wevcode";Start-Sleep 2;Start-Process msedge "https://weval-consulting.com/blade-ai.html";Write-Output REOPENED','Reopen SSO');$n++; echo json_encode(['ok'=>1,'pushed'=>$n]);break; case 'blade_open': $url=$_REQUEST['url']??'https://weval-consulting.com';blade_push('powershell',"Start-Process msedge '$url';Write-Output OPENED",'Open URL'); echo json_encode(['ok'=>1,'url'=>$url]);break; case 'blade_exec': $cmd=$_REQUEST['cmd']??'';if(!$cmd){echo json_encode(['error'=>'no cmd']);break;} blade_push('powershell',$cmd,'Blade exec');echo json_encode(['ok'=>1,'pushed'=>1]);break; case 'blade_screenshot': blade_push('screenshot','screenshot','Desktop screenshot');echo json_encode(['ok'=>1,'pushed'=>1]);break; // ═══════════════════════════════════════ // NEW: FILES (3) // ═══════════════════════════════════════ case 'file_read': $path=$_REQUEST['path']??'';$tgt=$_REQUEST['target']??'s204';if(!$path){echo json_encode(['error'=>'no path']);break;} $cmd="cat ".escapeshellarg($path)." 2>&1 | head -200"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):(($tgt==='s151')?s151($cmd):cx($cmd))]);break; case 'file_write': $path=$_REQUEST['path']??'';$content=$_REQUEST['content']??'';$tgt=$_REQUEST['target']??'s204'; if(!$path||!$content){echo json_encode(['error'=>'need path+content']);break;} $cmd="echo ".escapeshellarg($content)." | tee ".escapeshellarg($path); echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; case 'file_list': $path=$_REQUEST['path']??'/var/www/html';$tgt=$_REQUEST['target']??'s204'; $cmd="ls -la ".escapeshellarg($path)." 2>&1 | head -40"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):(($tgt==='s151')?s151($cmd):cx($cmd))]);break; // ═══════════════════════════════════════ // NEW: LOGS (2) // ═══════════════════════════════════════ case 'logs': $file=$_REQUEST['file']??'nginx/access.log';$lines=intval($_REQUEST['lines']??30);$tgt=$_REQUEST['target']??'s204'; $cmd="tail -n $lines /var/log/".basename($file)." 2>&1"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; case 'logs_search': $file=$_REQUEST['file']??'syslog';$grep=$_REQUEST['grep']??'error';$tgt=$_REQUEST['target']??'s204'; $cmd="grep -i ".escapeshellarg($grep)." /var/log/".basename($file)." 2>&1 | tail -20"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; // ═══════════════════════════════════════ // NEW: SERVICES (2) // ═══════════════════════════════════════ case 'services': $tgt=$_REQUEST['target']??'s204'; $cmd="systemctl list-units --type=service --state=active --no-pager 2>/dev/null | head -30"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; case 'service_ctl': $svc=$_REQUEST['service']??'';$act=$_REQUEST['do']??'status';$tgt=$_REQUEST['target']??'s204'; if(!$svc){echo json_encode(['error'=>'no service']);break;} $allowed=['status','restart','stop','start'];if(!in_array($act,$allowed)){echo json_encode(['error'=>'invalid action']);break;} $cmd="sudo systemctl $act ".escapeshellarg($svc)." 2>&1 | head -10"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; // ═══════════════════════════════════════ // NEW: NETWORK (3) // ═══════════════════════════════════════ case 'ping': $host=$_REQUEST['host']??'';if(!$host){echo json_encode(['error'=>'no host']);break;} echo json_encode(['ok'=>1,'output'=>cx("ping -c 3 ".escapeshellarg($host)." 2>&1")]);break; case 'ports': $host=$_REQUEST['host']??'127.0.0.1';$ports=$_REQUEST['ports']??'22,25,80,443,5432,5678,8065,9090,9443,11435'; $cmd="for p in ".str_replace(',',' ',$ports)."; do (echo >/dev/tcp/$host/\$p) 2>/dev/null && echo \"\$p OPEN\" || echo \"\$p CLOSED\"; done"; echo json_encode(['ok'=>1,'output'=>cx("bash -c ".escapeshellarg($cmd))]);break; case 'ssl_check': $domain=$_REQUEST['domain']??'weval-consulting.com'; echo json_encode(['ok'=>1,'output'=>cx("echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -dates -subject 2>&1")]);break; // ═══════════════════════════════════════ // NEW: MTA STATUS (2) // ═══════════════════════════════════════ case 'mta_status': $pmta=json_decode(s95("systemctl is-active pmta 2>/dev/null; echo '---'; /opt/pmta/bin/pmta show status 2>/dev/null | head -5"),1); $kumo=json_decode(s95("systemctl is-active kumomta 2>/dev/null; echo '---'; curl -s http://127.0.0.1:8010/api/status 2>/dev/null | head -5"),1); $postfix=json_decode(s95("systemctl is-active postfix 2>/dev/null; mailq 2>/dev/null | tail -1"),1); echo json_encode(['ok'=>1,'pmta'=>$pmta['output']??'','kumo'=>$kumo['output']??'','postfix'=>$postfix['output']??'']);break; case 'mta_queue': echo json_encode(['ok'=>1,'output'=>json_decode(s95("echo '=== PMTA ==='; /opt/pmta/bin/pmta show queues 2>/dev/null | head -10; echo '=== KUMO ==='; curl -s http://127.0.0.1:8010/api/queues 2>/dev/null | head -10; echo '=== POSTFIX ==='; mailq 2>/dev/null | tail -5"),1)['output']??'']);break; // ═══════════════════════════════════════ // NEW: TELEGRAM (1) // ═══════════════════════════════════════ case 'telegram': $msg=$_REQUEST['msg']??'';if(!$msg){echo json_encode(['error'=>'no message']);break;} tg("[BLADE] $msg");echo json_encode(['ok'=>1,'sent'=>$msg]);break; // ═══════════════════════════════════════ // NEW: CLOUDFLARE (2) // ═══════════════════════════════════════ case 'cf_dns': $zone='1488bbba251c6fa282999fcc09aac9fe';$email='ymahboub@weval-consulting.com'; $token=trim(cx('grep CF_API_TOKEN /etc/weval/secrets.env 2>/dev/null | cut -d= -f2')); if(!$token){echo json_encode(['error'=>'no CF token in secrets.env']);break;} $ch=curl_init("https://api.cloudflare.com/client/v4/zones/$zone/dns_records?per_page=50"); curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>1,CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"],CURLOPT_TIMEOUT=>10]); $r=curl_exec($ch);curl_close($ch);$d=json_decode($r,1); $records=array_map(fn($r)=>['name'=>$r['name'],'type'=>$r['type'],'content'=>$r['content'],'proxied'=>$r['proxied']??false],array_slice($d['result']??[],0,30)); echo json_encode(['ok'=>1,'count'=>count($records),'records'=>$records]);break; case 'cf_purge': $zone='1488bbba251c6fa282999fcc09aac9fe';$token=trim(cx('grep CF_API_TOKEN /etc/weval/secrets.env 2>/dev/null | cut -d= -f2')); if(!$token){echo json_encode(['error'=>'no CF token']);break;} $ch=curl_init("https://api.cloudflare.com/client/v4/zones/$zone/purge_cache"); curl_setopt_array($ch,[CURLOPT_POST=>1,CURLOPT_POSTFIELDS=>'{"purge_everything":true}',CURLOPT_RETURNTRANSFER=>1,CURLOPT_HTTPHEADER=>["Authorization: Bearer $token","Content-Type: application/json"],CURLOPT_TIMEOUT=>10]); $r=curl_exec($ch);curl_close($ch);echo $r;break; // ═══════════════════════════════════════ // NEW: CRON CRUD (3) // ═══════════════════════════════════════ case 'crons': echo json_encode(['ok'=>1,'output'=>cx('crontab -l 2>/dev/null')]);break; case 'cron_add': $entry=$_REQUEST['entry']??'';if(!$entry){echo json_encode(['error'=>'no entry']);break;} echo json_encode(['ok'=>1,'output'=>cx("(crontab -l 2>/dev/null; echo ".escapeshellarg($entry).") | crontab -; crontab -l | tail -3")]);break; case 'cron_remove': $pattern=$_REQUEST['pattern']??'';if(!$pattern){echo json_encode(['error'=>'no pattern']);break;} echo json_encode(['ok'=>1,'output'=>cx("crontab -l 2>/dev/null | grep -v ".escapeshellarg($pattern)." | crontab -; echo DONE; crontab -l | wc -l")]);break; // ═══════════════════════════════════════ // NEW: PROCESS MANAGER (2) // ═══════════════════════════════════════ case 'ps': $filter=$_REQUEST['filter']??'';$tgt=$_REQUEST['target']??'s204'; $cmd=$filter?"ps aux | grep -i ".escapeshellarg($filter)." | grep -v grep | head -15":"ps aux --sort=-%mem | head -15"; echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95($cmd):cx($cmd)]);break; case 'kill': $pid=$_REQUEST['pid']??'';$tgt=$_REQUEST['target']??'s204';if(!$pid){echo json_encode(['error'=>'no pid']);break;} echo json_encode(['ok'=>1,'output'=>($tgt==='s95')?s95("kill -9 $pid 2>&1; echo DONE"):cx("kill -9 $pid 2>&1; echo DONE")]);break; // ═══════════════════════════════════════ // NEW: BACKUP (1) // ═══════════════════════════════════════ case 'backup': $what=$_REQUEST['what']??'html'; $ts=date('Ymd_His'); $cmd=match($what){ 'html'=>"tar czf /tmp/backup-html-$ts.tar.gz -C /var/www html --exclude='.git' 2>&1; ls -lh /tmp/backup-html-$ts.tar.gz", 'ethica'=>"tar czf /tmp/backup-ethica-$ts.tar.gz -C /var/www/ethica public 2>&1; ls -lh /tmp/backup-ethica-$ts.tar.gz", 'nginx'=>"tar czf /tmp/backup-nginx-$ts.tar.gz /etc/nginx/sites-enabled/ 2>&1; ls -lh /tmp/backup-nginx-$ts.tar.gz", 'db'=>"pg_dump -U postgres wevia_db | gzip > /tmp/backup-db-$ts.sql.gz 2>&1; ls -lh /tmp/backup-db-$ts.sql.gz", default=>'echo "Unknown: use html,ethica,nginx,db"' }; echo json_encode(['ok'=>1,'output'=>cx($cmd,60)]);break; // ═══════════════════════════════════════ // NEW: PLAYWRIGHT TEST (1) // ═══════════════════════════════════════ case 'test_page': $url=$_REQUEST['url']??'';if(!$url){echo json_encode(['error'=>'no url']);break;} $s="const{chromium}=require('playwright');(async()=>{const b=await chromium.launch({args:['--no-sandbox']});const p=await b.newPage();const t=Date.now();const r=await p.goto('$url',{waitUntil:'networkidle',timeout:20000});const ms=Date.now()-t;const title=await p.title();const h=await p.content();const links=(h.match(/href/g)||[]).length;const imgs=(h.match(/{if(m.type()==='error')errs.push(m.text())});await b.close();console.log(JSON.stringify({ok:true,url:'$url',status:r.status(),title:title,load_ms:ms,links:links,images:imgs,size:h.length}))})();"; $r=cx("cd /tmp && timeout 30 node -e ".escapeshellarg($s)." 2>/dev/null",35); echo json_decode($r)?$r:json_encode(['ok'=>0,'raw'=>substr($r,0,300)]);break; // ═══════════════════════════════════════ // OSINT (1) // ═══════════════════════════════════════ case 'osint': $tgt=$_REQUEST['target']??'';$tool=$_REQUEST['tool']??'holehe';if(!$tgt){echo json_encode(['error'=>'no target']);break;} echo json_encode(['ok'=>1,'tool'=>$tool,'output'=>json_decode(s95("timeout 30 $tool $tgt 2>&1 | head -30"),1)['output']??'']);break; // ═══════════════════════════════════════ // WORKFLOW (1) // ═══════════════════════════════════════ case 'workflow': $steps=json_decode($_REQUEST['steps']??'[]',1);if(empty($steps)){echo json_encode(['error'=>'no steps']);break;} $res=[];foreach($steps as $i=>$step){$a=$step['action']??'';$p=http_build_query($step['params']??[]); $r=fetch_url("https://weval-consulting.com/api/blade-ops-api.php?k=BLADE2026&action=$a&$p",30); $res[]=['step'=>$i+1,'action'=>$a,'result'=>json_decode($r,1)?:$r];} echo json_encode(['ok'=>1,'results'=>$res]);break; // ═══════════════════════════════════════ // SELF-UPDATE (1) // ═══════════════════════════════════════ case 'self_update': echo json_encode(['ok'=>1,'output'=>cx('cd /var/www/html && sudo chattr -i index.html && git -c safe.directory=/var/www/html pull origin main 2>&1 | tail -5 && sudo chattr +i index.html && echo " /tmp/_oc.php && php /tmp/_oc.php && rm /tmp/_oc.php')]);break; default: echo json_encode(['error'=>'unknown action','v'=>'3.0','total_actions'=>50,'actions'=>[ 'infra'=>['health','sso_check','sso_fix','sso_nonreg','exec','nonreg','docker','git','nginx','disk'], 'data'=>['ethica','leads','db'], 'web'=>['search','fetch','browse'], 'email'=>['email_list','email_read','email_draft','email_urgent','email_vip'], 'ai'=>['ai','ai_models'], 'blade'=>['purge_cookies','blade_open','blade_exec','blade_screenshot'], 'files'=>['file_read','file_write','file_list'], 'logs'=>['logs','logs_search'], 'services'=>['services','service_ctl'], 'network'=>['ping','ports','ssl_check'], 'mta'=>['mta_status','mta_queue'], 'telegram'=>['telegram'], 'cloudflare'=>['cf_dns','cf_purge'], 'crons'=>['crons','cron_add','cron_remove'], 'process'=>['ps','kill'], 'backup'=>['backup'], 'test'=>['test_page'], 'osint'=>['osint'], 'advanced'=>['workflow','self_update'] ]]); }