load();
}
require_once __DIR__ . '/../src/Engine/Language.php';
// Handle Language Switch
if (isset($_GET['lang'])) {
$lang = in_array($_GET['lang'], ['en', 'th']) ? $_GET['lang'] : 'en';
setcookie('lang', $lang, time() + (86400 * 365), "/");
$redirect = strtok($_SERVER["REQUEST_URI"], '?');
header("Location: " . $redirect);
exit;
}
// Initialize Router
$router = new Router();
// Set base path dynamically to support subfolders (e.g. /ksh_soar)
$basePath = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
$basePath = str_replace('/public', '', $basePath);
if ($basePath === '/') {
$basePath = '';
}
$router->setBasePath($basePath);
// API / Webhook Routes
$router->mount('/api', function() use ($router) {
$router->post('/webhook/wazuh', function() {
$controller = new WazuhWebhookController();
$controller->handle();
});
$router->mount('/agent', function() use ($router) {
$router->get('/specs', function() {
$controller = new \App\Controllers\AgentController();
$controller->getSpecs();
});
$router->get('/quick-details', function() {
$controller = new \App\Controllers\AgentController();
$controller->getEndpointQuickDetails();
});
$router->get('/network', function() {
$controller = new \App\Controllers\AgentController();
$controller->getNetworkInspector();
});
$router->get('/processes', function() {
$controller = new \App\Controllers\AgentController();
$controller->getProcesses();
});
$router->get('/all-metadata', function() {
$controller = new \App\Controllers\AgentController();
$controller->getAllAgentsMetadata();
});
});
$router->post('/test-notification', function() {
require_once __DIR__ . '/../src/Integrations/Notifier.php';
header('Content-Type: application/json');
$type = $_POST['type'] ?? '';
$msg = "🛠️ [Test Message] This is a test notification from KSH SOAR.";
$success = false;
if ($type === 'line') {
if (empty($_ENV['LINE_NOTIFY_TOKEN'])) {
echo json_encode(['status' => 'error', 'message' => 'LINE_NOTIFY_TOKEN is not set in .env']);
return;
}
$success = \App\Integrations\Notifier::sendLineNotify($msg);
} else if ($type === 'telegram') {
if (empty($_ENV['TELEGRAM_BOT_TOKEN']) || empty($_ENV['TELEGRAM_CHAT_ID'])) {
echo json_encode(['status' => 'error', 'message' => 'Telegram tokens are not set in .env']);
return;
}
$appName = $_ENV['APP_NAME'] ?? 'KSH SOAR';
$tgMsg = "🧪 [{$appName}] MOCKUP SECURITY ALERT\n";
$tgMsg .= "━━━━━━━━━━━━━━━━━━━━\n";
$tgMsg .= "⚠️ Risk Level: 12 (High)\n";
$tgMsg .= "🆔 Rule ID: 5716\n";
$tgMsg .= "🖥 Agent: WEB-SERVER-01\n";
$tgMsg .= "🌐 IP Address: 192.168.1.100\n";
$tgMsg .= "━━━━━━━━━━━━━━━━━━━━\n";
$tgMsg .= "📝 Description:\nเข้าสู่ระบบล้มเหลวหลายครั้งติดต่อกัน (อาจมีการ Brute-force)\n\n";
$tgMsg .= "📍 Action Taken:\n";
$tgMsg .= "✅ Auto-created Investigation Case #105\n";
$tgMsg .= "🤖 AI Remediation Analysis queued.\n\n";
$tgMsg .= "✅ System Integration Test Successful!";
$success = \App\Integrations\Notifier::sendTelegram($tgMsg);
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid type']);
return;
}
if ($success) {
echo json_encode(['status' => 'success', 'message' => ucfirst($type) . ' notification sent successfully!']);
} else {
echo json_encode(['status' => 'error', 'message' => 'Failed to send notification. Please check your tokens.']);
}
});
$router->post('/clear-all-alerts', function() {
$controller = new DashboardController();
$controller->clearAllAlerts();
});
$router->post('/virustotal-check', function() {
header('Content-Type: application/json');
$type = $_POST['type'] ?? '';
$value = $_POST['value'] ?? '';
$apiKey = $_ENV['VIRUSTOTAL_API_KEY'] ?? '';
if (empty($apiKey)) {
echo json_encode(['status' => 'error', 'message' => 'VIRUSTOTAL_API_KEY is not configured in .env']);
return;
}
if (empty($value)) {
echo json_encode(['status' => 'error', 'message' => 'No value provided for scanning.']);
return;
}
$url = "";
if ($type === 'hash') {
$url = "https://www.virustotal.com/api/v3/files/" . urlencode($value);
} else if ($type === 'ip') {
$url = "https://www.virustotal.com/api/v3/ip_addresses/" . urlencode($value);
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid scan type.']);
return;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-apikey: {$apiKey}"
]);
$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpcode == 200) {
$data = json_decode($response, true);
$stats = $data['data']['attributes']['last_analysis_stats'] ?? null;
if ($stats) {
$malicious = $stats['malicious'] ?? 0;
$suspicious = $stats['suspicious'] ?? 0;
$total = array_sum($stats);
$html = "