SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,026
Folders
377
Scanned Size
3.79 GB
PHP Files
791
Editable Text Files
12,310
File viewer
guarded to /htdocs
/simon/api/integration_test.php
<?php declare(strict_types=1); date_default_timezone_set('America/Chicago'); header('Content-Type: application/json; charset=utf-8'); function read_json(string $file, array $fallback = []): array { if (!is_file($file)) return $fallback; $raw = @file_get_contents($file); $data = json_decode((string)$raw, true); return is_array($data) ? $data : $fallback; } function write_json(string $file, array $data): bool { $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); return @file_put_contents($file, $json . PHP_EOL, LOCK_EX) !== false; } function respond(array $payload, int $status = 200): void { http_response_code($status); echo json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); exit; } function log_line(string $file, string $line): void { @file_put_contents($file, '[' . date('Y-m-d H:i:s') . '] ' . $line . PHP_EOL, FILE_APPEND | LOCK_EX); } function get_secret_value(string $ref): string { if ($ref === '') return ''; $env = getenv($ref); return is_string($env) ? trim($env) : ''; } function dns_probe(string $host): array { if ($host === '') return ['ok' => false, 'detail' => 'No host provided']; $ip = gethostbyname($host); return [ 'ok' => ($ip !== $host), 'detail' => ($ip !== $host) ? "Resolved to {$ip}" : 'DNS resolution failed' ]; } function port_probe(string $host, int $port, int $timeout = 5): array { if ($host === '' || $port <= 0) return ['ok' => false, 'detail' => 'Missing host or port']; $start = microtime(true); $fp = @fsockopen($host, $port, $errno, $errstr, $timeout); $ms = (int)round((microtime(true) - $start) * 1000); if (!$fp) { return ['ok' => false, 'ms' => $ms, 'detail' => "{$errstr} ({$errno})"]; } fclose($fp); return ['ok' => true, 'ms' => $ms, 'detail' => 'Port reachable']; } function url_probe(string $url): array { if ($url === '') return ['ok' => false, 'ms' => 0, 'detail' => 'No URL provided']; if (!function_exists('curl_init')) return ['ok' => false, 'ms' => 0, 'detail' => 'cURL unavailable']; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_NOBODY => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_USERAGENT => 'SIMON-Links-Test/2.0', ]); $start = microtime(true); curl_exec($ch); $ms = (int)round((microtime(true) - $start) * 1000); $errno = curl_errno($ch); $error = curl_error($ch); $code = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE); curl_close($ch); $reachableCodes = [200, 201, 204, 301, 302, 401, 403, 404, 405]; return [ 'ok' => ($errno === 0 && in_array($code, $reachableCodes, true)), 'ms' => $ms, 'http_code' => $code, 'detail' => $errno === 0 ? 'Host responded' : $error, ]; } function ai_assist(array $result): array { $tips = []; if (($result['checks']['registry']['config_required_present'] ?? true) === false) { $tips[] = 'Fill all required fields before running deeper tests.'; } if (($result['checks']['network']['dns']['ok'] ?? true) === false) { $tips[] = 'Check the hostname spelling and DNS propagation.'; } if (($result['checks']['auth']['secret_ref_present']['ok'] ?? true) === false) { $tips[] = 'Add the credential reference for this provider.'; } if (($result['checks']['auth']['secret_loaded']['ok'] ?? true) === false) { $tips[] = 'Verify the referenced secret exists in protected config or environment variables.'; } if (($result['checks']['service']['login']['ok'] ?? true) === false) { $tips[] = 'The service appears reachable but authentication failed. Recheck credentials.'; } return $tips ?: ['No major issues detected.']; } $slug = trim((string)($_GET['slug'] ?? '')); if ($slug === '') respond(['ok' => false, 'error' => 'Missing slug'], 400); $root = dirname(__DIR__); $dataDir = $root . '/data'; $logDir = $root . '/logs'; $registry = read_json($dataDir . '/links_registry.json', ['connections' => []]); $providers = array_values(array_filter($registry['connections'] ?? [], fn(array $r) => (($r['slug'] ?? '') === $slug))); if (!$providers) respond(['ok' => false, 'error' => 'Provider not found'], 404); $row = $providers[0]; $type = strtolower((string)($row['provider_type'] ?? '')); $result = [ 'ok' => true, 'slug' => $slug, 'provider_type' => $type, 'status' => 'warning', 'score' => 0, 'checks' => [ 'registry' => [], 'network' => [], 'auth' => [], 'service' => [], ], ]; $missing = []; foreach (($row['required_fields'] ?? []) as $field) { $val = $row[$field] ?? null; if ($val === null || $val === '' || (is_array($val) && count($val) === 0)) { $missing[] = $field; } } $result['checks']['registry'] = [ 'config_required_present' => count($missing) === 0, 'missing_required' => $missing, ]; $host = ''; if ($type === 'ftp') { $host = (string)($row['ftp_host'] ?? ''); } elseif ($type === 'database') { $host = (string)($row['db_host'] ?? ''); } elseif ($type === 'email') { $host = (string)($row['smtp_host'] ?? ''); } else { $platformUrl = (string)($row['platform_url'] ?? ''); $host = (string)(parse_url($platformUrl, PHP_URL_HOST) ?: ''); } $result['checks']['network']['dns'] = dns_probe($host); $result['checks']['network']['platform_url'] = url_probe((string)($row['platform_url'] ?? '')); $result['checks']['network']['api_base_url'] = url_probe((string)($row['api_base_url'] ?? '')); $result['checks']['network']['healthcheck_url'] = url_probe((string)($row['healthcheck_url'] ?? '')); $secretRef = (string)($row['secret_ref'] ?? $row['access_token_ref'] ?? $row['ftp_password_ref'] ?? $row['db_password_ref'] ?? $row['smtp_password_ref'] ?? ''); $secretVal = get_secret_value($secretRef); $result['checks']['auth']['secret_ref_present'] = [ 'ok' => $secretRef !== '', 'detail' => $secretRef !== '' ? $secretRef : 'No secret ref configured', ]; $result['checks']['auth']['secret_loaded'] = [ 'ok' => $secretVal !== '', 'detail' => $secretVal !== '' ? 'Secret loaded from protected source' : 'Secret not found in environment/config', ]; if ($type === 'ftp') { $result['checks']['network']['port'] = port_probe((string)($row['ftp_host'] ?? ''), (int)($row['ftp_port'] ?? 22)); $result['checks']['service']['login'] = ['ok' => false, 'detail' => 'Transport/auth test not implemented yet']; } elseif ($type === 'database') { $result['checks']['network']['port'] = port_probe((string)($row['db_host'] ?? ''), (int)($row['db_port'] ?? 3306)); $result['checks']['service']['login'] = ['ok' => false, 'detail' => 'Database auth test not implemented yet']; } elseif ($type === 'email') { $result['checks']['network']['port'] = port_probe((string)($row['smtp_host'] ?? ''), (int)($row['smtp_port'] ?? 587)); $result['checks']['service']['login'] = ['ok' => false, 'detail' => 'SMTP auth test not implemented yet']; } else { $result['checks']['service']['auth_probe'] = ['ok' => false, 'detail' => 'Authenticated API test not implemented yet']; } $result['ai_assist'] = ai_assist($result); $result['next_step'] = 'Review failures and implement provider-specific auth handshake tests.'; log_line($logDir . '/links_activity.log', "TEST {$slug} | " . json_encode(['status' => $result['status']])); respond($result);
Save file
Quick jump
open a path
Open