455
pack.php
455
pack.php
@@ -117,7 +117,7 @@ echo "Collecting source files...\n";
|
||||
/**
|
||||
* Extract PHP code from file (without opening tag and namespace)
|
||||
*/
|
||||
function extractPhpCode(string $filePath, bool $minify = false): string {
|
||||
function extractPhpCode(string $filePath, bool $minify = false, bool $isPacked = false): string {
|
||||
$content = file_get_contents($filePath);
|
||||
|
||||
// Remove opening PHP tag
|
||||
@@ -133,6 +133,12 @@ function extractPhpCode(string $filePath, bool $minify = false): string {
|
||||
// Only match 'use' at the start of a line (namespace imports), not closure 'use' clauses
|
||||
$content = preg_replace('/^use\s+[A-Z\\\\][^;]*;\s*/im', '', $content);
|
||||
|
||||
// For packed version, replace ALESHELL_SRC references with packed equivalents
|
||||
if ($isPacked) {
|
||||
// Replace View::render calls to use PackedView for embedded views
|
||||
$content = str_replace('ALESHELL_SRC', '__DIR__', $content);
|
||||
}
|
||||
|
||||
if ($minify) {
|
||||
// Remove multi-line comments but preserve strings
|
||||
$content = preg_replace('/\/\*(?!.*?\*\/).*?\*\//s', '', $content);
|
||||
@@ -184,6 +190,9 @@ declare(strict_types=1);
|
||||
// CONFIGURATION
|
||||
// ============================================================================
|
||||
|
||||
define('ALESHELL_VERSION', '2.0.0');
|
||||
define('ALESHELL_PACKED', true);
|
||||
|
||||
HEADER;
|
||||
|
||||
// Add configuration
|
||||
@@ -223,7 +232,7 @@ $output .= "// =================================================================
|
||||
foreach ($coreFiles as $file) {
|
||||
$path = __DIR__ . '/' . $file;
|
||||
if (file_exists($path)) {
|
||||
$code = extractPhpCode($path, $minify);
|
||||
$code = extractPhpCode($path, $minify, true);
|
||||
// Replace namespace references with inline
|
||||
$code = str_replace('AleShell2\\Core\\', 'AleShell2_', $code);
|
||||
$code = str_replace('AleShell2\\Security\\', 'AleShell2_', $code);
|
||||
@@ -233,6 +242,83 @@ foreach ($coreFiles as $file) {
|
||||
$className = basename($file, '.php');
|
||||
$code = preg_replace('/class\s+' . $className . '/', 'class AleShell2_' . $className, $code);
|
||||
|
||||
// Transform type hints for internal classes (Session, Auth, Request, Response, Router, View)
|
||||
$internalClasses = ['Session', 'Auth', 'Request', 'Response', 'Router', 'View'];
|
||||
foreach ($internalClasses as $internalClass) {
|
||||
$code = preg_replace('/private\s+' . $internalClass . '\s+\$/', 'private AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/public\s+' . $internalClass . '\s+\$/', 'public AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/,\s*' . $internalClass . '\s+\$/', ', AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/\(\s*' . $internalClass . '\s+\$/', '(AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/:\s*' . $internalClass . '(\s|\)|,|$)/', ': AleShell2_' . $internalClass . '$1', $code);
|
||||
$code = preg_replace('/new\s+' . $internalClass . '\s*\(/', 'new AleShell2_' . $internalClass . '(', $code);
|
||||
}
|
||||
|
||||
// Fix redirect paths for packed version - convert path-based to query parameter format
|
||||
$code = str_replace("\$response->redirect('/login')", "\$response->redirect('?action=login')", $code);
|
||||
$code = str_replace("\$response->redirect('/logout')", "\$response->redirect('?action=logout')", $code);
|
||||
|
||||
// Special handling for View class - make it use embedded views
|
||||
if ($className === 'View') {
|
||||
$code = str_replace(
|
||||
"\$viewPath = __DIR__ . '/Views/' . str_replace('.', '/', \$view) . '.php';",
|
||||
"\$viewPath = \$view; // Using embedded views",
|
||||
$code
|
||||
);
|
||||
$code = preg_replace(
|
||||
'/if\s*\(\s*!file_exists\s*\(\s*\$viewPath\s*\)\s*\)[\s\S]*?throw new \\\\RuntimeException\s*\([^)]+\)\s*;[\s\S]*?\}/',
|
||||
'global $ALESHELL_VIEWS;
|
||||
$templateKey = $view;
|
||||
|
||||
if (!isset($ALESHELL_VIEWS[$templateKey])) {
|
||||
throw new \\RuntimeException("View not found: {$view}");
|
||||
}',
|
||||
$code
|
||||
);
|
||||
$code = preg_replace(
|
||||
'/ob_start\s*\(\s*\)\s*;\s*\n\s*include\s+\$viewPath\s*;\s*\n\s*return\s+ob_get_clean\s*\(\s*\)\s*;/',
|
||||
'ob_start();
|
||||
eval(\'?>\' . $ALESHELL_VIEWS[$templateKey]);
|
||||
return ob_get_clean();',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
// Special handling for Application class - skip config file loading
|
||||
if ($className === 'Application') {
|
||||
$code = preg_replace(
|
||||
'/\$configFile = __DIR__ . \'\/Config\/config\.php\';[\s\S]*?if \(file_exists\(\$configFile\)\) \{[\s\S]*?\$this->config = require \$configFile;[\s\S]*?\} else \{/',
|
||||
'// Packed mode: use default config directly
|
||||
{',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
// Special handling for Response class - fix PHP 8.4 deprecation warnings
|
||||
// Convert "string $param = null" to "?string $param = null"
|
||||
if ($className === 'Response') {
|
||||
$code = preg_replace('/string\s+(\$\w+)\s*=\s*null/', '?string $1 = null', $code);
|
||||
}
|
||||
|
||||
// Special handling for Request class - parse JSON body for AJAX requests
|
||||
if ($className === 'Request') {
|
||||
$code = preg_replace(
|
||||
'/\$this->post = \$_POST;/',
|
||||
'$this->post = $_POST;
|
||||
// Parse JSON body for AJAX requests
|
||||
$contentType = $_SERVER[\'CONTENT_TYPE\'] ?? \'\';
|
||||
if (stripos($contentType, \'application/json\') !== false) {
|
||||
$rawBody = file_get_contents(\'php://input\');
|
||||
if ($rawBody) {
|
||||
$jsonData = json_decode($rawBody, true);
|
||||
if (is_array($jsonData)) {
|
||||
$this->post = array_merge($this->post, $jsonData);
|
||||
}
|
||||
}
|
||||
}',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
$output .= "// Source: {$file}\n";
|
||||
$output .= $code . "\n\n";
|
||||
echo " Added core: {$className}\n";
|
||||
@@ -247,7 +333,7 @@ $output .= "// =================================================================
|
||||
foreach ($securityFiles as $file) {
|
||||
$path = __DIR__ . '/' . $file;
|
||||
if (file_exists($path)) {
|
||||
$code = extractPhpCode($path, $minify);
|
||||
$code = extractPhpCode($path, $minify, true);
|
||||
$code = str_replace('AleShell2\\Core\\', 'AleShell2_', $code);
|
||||
$code = str_replace('AleShell2\\Security\\', 'AleShell2_', $code);
|
||||
$code = str_replace('AleShell2\\Modules\\', 'AleShell2_', $code);
|
||||
@@ -255,6 +341,13 @@ foreach ($securityFiles as $file) {
|
||||
$className = basename($file, '.php');
|
||||
$code = preg_replace('/class\s+' . $className . '/', 'class AleShell2_' . $className, $code);
|
||||
|
||||
// Transform type hints for internal classes
|
||||
$code = preg_replace('/private\s+Session\s+\$/', 'private AleShell2_Session $', $code);
|
||||
$code = preg_replace('/public\s+Session\s+\$/', 'public AleShell2_Session $', $code);
|
||||
$code = preg_replace('/,\s*Session\s+\$/', ', AleShell2_Session $', $code);
|
||||
$code = preg_replace('/\(\s*Session\s+\$/', '(AleShell2_Session $', $code);
|
||||
$code = preg_replace('/:\s*Session(\s|$)/', ': AleShell2_Session$1', $code);
|
||||
|
||||
$output .= "// Source: {$file}\n";
|
||||
$output .= $code . "\n\n";
|
||||
echo " Added security: {$className}\n";
|
||||
@@ -269,7 +362,7 @@ $output .= "// =================================================================
|
||||
foreach ($moduleFiles as $file) {
|
||||
$path = __DIR__ . '/' . $file;
|
||||
if (file_exists($path)) {
|
||||
$code = extractPhpCode($path, $minify);
|
||||
$code = extractPhpCode($path, $minify, true);
|
||||
$code = str_replace('AleShell2\\Core\\', 'AleShell2_', $code);
|
||||
$code = str_replace('AleShell2\\Security\\', 'AleShell2_', $code);
|
||||
$code = str_replace('AleShell2\\Modules\\', 'AleShell2_', $code);
|
||||
@@ -290,6 +383,231 @@ foreach ($moduleFiles as $file) {
|
||||
$code = preg_replace('/extends\s+' . $className . '/', 'extends AleShell2_' . $className, $code);
|
||||
$code = preg_replace('/extends\s+BaseController/', 'extends AleShell2_BaseController', $code);
|
||||
|
||||
// Fix redirect paths for packed version - convert path-based to query parameter format
|
||||
$code = str_replace("\$response->redirect('/')", "\$response->redirect('?module=dashboard')", $code);
|
||||
$code = str_replace("\$response->redirect('/login')", "\$response->redirect('?action=login')", $code);
|
||||
$code = str_replace("\$response->redirect('/logout')", "\$response->redirect('?action=logout')", $code);
|
||||
$code = str_replace("\$response->redirect('/dashboard')", "\$response->redirect('?module=dashboard')", $code);
|
||||
$code = str_replace("\$response->redirect('/files')", "\$response->redirect('?module=files')", $code);
|
||||
$code = str_replace("\$response->redirect('/terminal')", "\$response->redirect('?module=terminal')", $code);
|
||||
$code = str_replace("\$response->redirect('/editor')", "\$response->redirect('?module=editor')", $code);
|
||||
$code = str_replace("\$response->redirect('/processes')", "\$response->redirect('?module=processes')", $code);
|
||||
$code = str_replace("\$response->redirect('/network')", "\$response->redirect('?module=network')", $code);
|
||||
$code = str_replace("\$response->redirect('/database')", "\$response->redirect('?module=database')", $code);
|
||||
$code = str_replace("\$response->redirect('/system')", "\$response->redirect('?module=system')", $code);
|
||||
|
||||
// Transform type hints for internal classes (Session, Auth, Request, Response, Router, View)
|
||||
$internalClasses = ['Session', 'Auth', 'Request', 'Response', 'Router', 'View'];
|
||||
foreach ($internalClasses as $internalClass) {
|
||||
$code = preg_replace('/protected\s+' . $internalClass . '\s+\$/', 'protected AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/private\s+' . $internalClass . '\s+\$/', 'private AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/public\s+' . $internalClass . '\s+\$/', 'public AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/,\s*' . $internalClass . '\s+\$/', ', AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/\(\s*' . $internalClass . '\s+\$/', '(AleShell2_' . $internalClass . ' $', $code);
|
||||
$code = preg_replace('/:\s*' . $internalClass . '(\s|\)|,|$)/', ': AleShell2_' . $internalClass . '$1', $code);
|
||||
$code = preg_replace('/new\s+' . $internalClass . '\s*\(/', 'new AleShell2_' . $internalClass . '(', $code);
|
||||
// Also transform static method calls like View::render() to AleShell2_View::render()
|
||||
$code = preg_replace('/\b' . $internalClass . '::/', 'AleShell2_' . $internalClass . '::', $code);
|
||||
}
|
||||
|
||||
// Fix PHP 8.4 deprecation: float modulo in SystemController and BaseController
|
||||
if ($className === 'SystemController' || $className === 'BaseController') {
|
||||
// Cast $seconds to int before modulo operations
|
||||
$code = str_replace('($seconds % 86400)', '((int)$seconds % 86400)', $code);
|
||||
$code = str_replace('($seconds % 3600)', '((int)$seconds % 3600)', $code);
|
||||
}
|
||||
|
||||
// Fix SystemController: formatBytes expects int but disk functions return float
|
||||
if ($className === 'SystemController') {
|
||||
// Cast disk space values to int before passing to formatBytes
|
||||
$code = str_replace(
|
||||
'$totalSpace ? $this->formatBytes($totalSpace)',
|
||||
'$totalSpace ? $this->formatBytes((int)$totalSpace)',
|
||||
$code
|
||||
);
|
||||
$code = str_replace(
|
||||
'$freeSpace ? $this->formatBytes($freeSpace)',
|
||||
'$freeSpace ? $this->formatBytes((int)$freeSpace)',
|
||||
$code
|
||||
);
|
||||
$code = str_replace(
|
||||
'$this->formatBytes($totalSpace - $freeSpace)',
|
||||
'$this->formatBytes((int)($totalSpace - $freeSpace))',
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
// Fix TerminalController: Replace Application::getInstance() with direct session access
|
||||
if ($className === 'TerminalController') {
|
||||
// Replace the pattern used to get session in terminal controller
|
||||
$code = str_replace(
|
||||
'$app = Application::getInstance();
|
||||
$session = $app->getSession();',
|
||||
'// Packed version: use $_SESSION directly',
|
||||
$code
|
||||
);
|
||||
// Fix session get calls
|
||||
$code = str_replace('$session->get(\'terminal_history\', [])', '($_SESSION[\'terminal_history\'] ?? [])', $code);
|
||||
$code = str_replace('$session->set(\'terminal_history\', $history)', '$_SESSION[\'terminal_history\'] = $history', $code);
|
||||
$code = str_replace('$session->remove(\'terminal_history\')', 'unset($_SESSION[\'terminal_history\'])', $code);
|
||||
$code = str_replace('$session->get(\'terminal_cwd\')', '($_SESSION[\'terminal_cwd\'] ?? null)', $code);
|
||||
$code = str_replace('$session->set(\'terminal_cwd\', $newDir)', '$_SESSION[\'terminal_cwd\'] = $newDir', $code);
|
||||
}
|
||||
|
||||
// Fix FilesController: list method uses post() but is called via GET with query params
|
||||
// Change to input() which checks both POST and query params
|
||||
if ($className === 'FilesController') {
|
||||
// In the list method, change $request->post() to $request->input() for path
|
||||
$code = str_replace(
|
||||
'$path = $request->post(\'path\', getcwd());',
|
||||
'$path = $request->input(\'path\', getcwd());',
|
||||
$code
|
||||
);
|
||||
$code = str_replace(
|
||||
'$showHidden = (bool)$request->post(\'hidden\', false);',
|
||||
'$showHidden = (bool)$request->input(\'hidden\', false);',
|
||||
$code
|
||||
);
|
||||
$code = str_replace(
|
||||
'$sortBy = $request->post(\'sort\', \'name\');',
|
||||
'$sortBy = $request->input(\'sort\', \'name\');',
|
||||
$code
|
||||
);
|
||||
$code = str_replace(
|
||||
'$sortOrder = $request->post(\'order\', \'asc\');',
|
||||
'$sortOrder = $request->input(\'order\', \'asc\');',
|
||||
$code
|
||||
);
|
||||
// Add 'type' field to scanDirectory output - JS expects file.type but API returns is_directory
|
||||
$code = str_replace(
|
||||
"'is_directory' => \$isDir,",
|
||||
"'is_directory' => \$isDir,\n 'type' => \$isDir ? 'directory' : (is_link(\$fullPath) ? 'link' : 'file'),",
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
// Fix DashboardController: The view expects 'systemInfo' but controller passes 'data' with system info
|
||||
// We need to make the dashboard controller get detailed system info like SystemController does
|
||||
if ($className === 'DashboardController') {
|
||||
// Replace the render call to pass systemInfo directly
|
||||
$code = str_replace(
|
||||
"'data' => \$this->getDashboardData(),",
|
||||
"'systemInfo' => \$this->getDetailedSystemInfo(),\n 'data' => \$this->getDashboardData(),",
|
||||
$code
|
||||
);
|
||||
// Add the getDetailedSystemInfo method (copy from SystemController logic)
|
||||
$dashboardMethodsToAdd = <<<'DASHBOARD_METHODS'
|
||||
|
||||
/**
|
||||
* Get detailed system info for dashboard (same as SystemController)
|
||||
*/
|
||||
private function getDetailedSystemInfo(): array
|
||||
{
|
||||
return [
|
||||
'server' => $this->getServerInfoDetailed(),
|
||||
'php' => $this->getPhpInfoDetailed(),
|
||||
'hardware' => $this->getHardwareInfoDetailed(),
|
||||
'disk' => $this->getDiskInfoDetailed(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getServerInfoDetailed(): array
|
||||
{
|
||||
$info = [
|
||||
'hostname' => gethostname() ?: 'unknown',
|
||||
'os' => PHP_OS_FAMILY,
|
||||
'os_detail' => php_uname(),
|
||||
'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown',
|
||||
'server_name' => $_SERVER['SERVER_NAME'] ?? 'unknown',
|
||||
'server_addr' => $_SERVER['SERVER_ADDR'] ?? 'unknown',
|
||||
'server_port' => $_SERVER['SERVER_PORT'] ?? 'unknown',
|
||||
'document_root' => $_SERVER['DOCUMENT_ROOT'] ?? '',
|
||||
'current_user' => get_current_user(),
|
||||
'current_uid' => getmyuid(),
|
||||
'current_gid' => getmygid(),
|
||||
'process_id' => getmypid(),
|
||||
'uptime' => $this->getUptime(),
|
||||
'load_average' => function_exists('sys_getloadavg') ? (function() {
|
||||
$load = sys_getloadavg();
|
||||
return $load ? ['1min' => round($load[0], 2), '5min' => round($load[1], 2), '15min' => round($load[2], 2)] : null;
|
||||
})() : null,
|
||||
];
|
||||
return $info;
|
||||
}
|
||||
|
||||
private function getPhpInfoDetailed(): array
|
||||
{
|
||||
return [
|
||||
'version' => PHP_VERSION,
|
||||
'version_id' => PHP_VERSION_ID,
|
||||
'sapi' => php_sapi_name(),
|
||||
'ini_path' => php_ini_loaded_file() ?: 'unknown',
|
||||
'extension_dir' => ini_get('extension_dir'),
|
||||
'include_path' => ini_get('include_path'),
|
||||
'memory_limit' => ini_get('memory_limit'),
|
||||
'max_execution_time' => ini_get('max_execution_time'),
|
||||
'max_input_time' => ini_get('max_input_time'),
|
||||
'post_max_size' => ini_get('post_max_size'),
|
||||
'upload_max_filesize' => ini_get('upload_max_filesize'),
|
||||
'max_file_uploads' => ini_get('max_file_uploads'),
|
||||
'display_errors' => ini_get('display_errors'),
|
||||
'error_reporting' => error_reporting(),
|
||||
'date_timezone' => date_default_timezone_get(),
|
||||
'disabled_functions' => ini_get('disable_functions') ?: 'none',
|
||||
];
|
||||
}
|
||||
|
||||
private function getHardwareInfoDetailed(): array
|
||||
{
|
||||
$info = ['cpu' => 'unknown', 'cpu_cores' => 0, 'memory_total' => 'unknown', 'memory_free' => 'unknown', 'memory_available' => 'unknown'];
|
||||
if (is_readable('/proc/cpuinfo')) {
|
||||
$cpuinfo = file_get_contents('/proc/cpuinfo');
|
||||
if (preg_match('/model name\s*:\s*(.+)/i', $cpuinfo, $matches)) {
|
||||
$info['cpu'] = trim($matches[1]);
|
||||
}
|
||||
$info['cpu_cores'] = substr_count($cpuinfo, 'processor');
|
||||
}
|
||||
if (is_readable('/proc/meminfo')) {
|
||||
$meminfo = file_get_contents('/proc/meminfo');
|
||||
if (preg_match('/MemTotal:\s*(\d+)\s*kB/i', $meminfo, $matches)) {
|
||||
$info['memory_total'] = $this->formatBytes((int)$matches[1] * 1024);
|
||||
}
|
||||
if (preg_match('/MemFree:\s*(\d+)\s*kB/i', $meminfo, $matches)) {
|
||||
$info['memory_free'] = $this->formatBytes((int)$matches[1] * 1024);
|
||||
}
|
||||
if (preg_match('/MemAvailable:\s*(\d+)\s*kB/i', $meminfo, $matches)) {
|
||||
$info['memory_available'] = $this->formatBytes((int)$matches[1] * 1024);
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
private function getDiskInfoDetailed(): array
|
||||
{
|
||||
$disks = [];
|
||||
if (PHP_OS_FAMILY === 'Linux') {
|
||||
$df = @shell_exec('df -h 2>/dev/null');
|
||||
if ($df) {
|
||||
$lines = explode("\n", trim($df));
|
||||
array_shift($lines);
|
||||
foreach ($lines as $line) {
|
||||
$parts = preg_split('/\s+/', $line);
|
||||
if (count($parts) >= 6 && strpos($parts[0], '/dev/') === 0) {
|
||||
$disks[] = [
|
||||
'device' => $parts[0], 'total' => $parts[1], 'used' => $parts[2],
|
||||
'free' => $parts[3], 'percent_used' => $parts[4], 'mount' => $parts[5],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $disks;
|
||||
}
|
||||
DASHBOARD_METHODS;
|
||||
// Insert the methods before the closing brace of the class
|
||||
$code = preg_replace('/}\s*$/', $dashboardMethodsToAdd . "\n}\n", $code);
|
||||
}
|
||||
|
||||
$output .= "// Source: {$file}\n";
|
||||
$output .= $code . "\n\n";
|
||||
echo " Added module: {$className}\n";
|
||||
@@ -364,11 +682,48 @@ class AleShell2_PackedView {
|
||||
}
|
||||
}
|
||||
|
||||
// Simplified Router for packed version
|
||||
class AleShell2_PackedRouter {
|
||||
private array $routes = [];
|
||||
private $app;
|
||||
|
||||
public function __construct($app) {
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
public function get(string $action, callable $handler): void {
|
||||
$this->routes['GET'][$action] = $handler;
|
||||
}
|
||||
|
||||
public function post(string $action, callable $handler): void {
|
||||
$this->routes['POST'][$action] = $handler;
|
||||
}
|
||||
|
||||
public function dispatch(AleShell2_Request $request, AleShell2_Response $response): void {
|
||||
$method = $request->getMethod();
|
||||
$action = $request->get('action', '');
|
||||
$module = $request->get('module', '');
|
||||
|
||||
// Determine route key - module takes priority for navigation routes
|
||||
// action is used for standalone routes like 'login', 'logout'
|
||||
// When module is present, use module as route key (action is handled inside the module)
|
||||
$routeKey = $module ?: $action ?: '';
|
||||
|
||||
if (isset($this->routes[$method][$routeKey])) {
|
||||
$handler = $this->routes[$method][$routeKey];
|
||||
$handler($request, $response, []);
|
||||
} else {
|
||||
// Default route - redirect to login or dashboard
|
||||
$response->redirect('?action=login');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modified Application for packed version
|
||||
class AleShell2_PackedApplication {
|
||||
private AleShell2_Request $request;
|
||||
private AleShell2_Response $response;
|
||||
private AleShell2_Router $router;
|
||||
private AleShell2_PackedRouter $router;
|
||||
private AleShell2_Session $session;
|
||||
private AleShell2_Auth $auth;
|
||||
private AleShell2_PackedView $view;
|
||||
@@ -384,15 +739,25 @@ class AleShell2_PackedApplication {
|
||||
// Initialize components
|
||||
$this->request = new AleShell2_Request();
|
||||
$this->response = new AleShell2_Response();
|
||||
$this->session = new AleShell2_Session($this->config['session_timeout'] ?? 3600);
|
||||
$this->auth = new AleShell2_Auth(
|
||||
$this->config['password_hash'],
|
||||
$this->session,
|
||||
$this->config['max_login_attempts'] ?? 5,
|
||||
$this->config['lockout_duration'] ?? 900
|
||||
);
|
||||
// Create a config array compatible with Session class
|
||||
$sessionConfig = [
|
||||
'security' => [
|
||||
'session_timeout' => $this->config['session_timeout'] ?? 3600,
|
||||
]
|
||||
];
|
||||
$this->session = new AleShell2_Session($sessionConfig);
|
||||
// Create a config array compatible with Auth class
|
||||
$authConfig = [
|
||||
'security' => [
|
||||
'password' => $this->config['password_hash'],
|
||||
'max_attempts' => $this->config['max_login_attempts'] ?? 5,
|
||||
'lockout_time' => $this->config['lockout_duration'] ?? 900,
|
||||
'csrf_protection' => true,
|
||||
]
|
||||
];
|
||||
$this->auth = new AleShell2_Auth($authConfig, $this->session);
|
||||
$this->view = new AleShell2_PackedView();
|
||||
$this->router = new AleShell2_Router($this);
|
||||
$this->router = new AleShell2_PackedRouter($this);
|
||||
|
||||
// Set security headers
|
||||
$this->setSecurityHeaders();
|
||||
@@ -450,17 +815,17 @@ class AleShell2_PackedApplication {
|
||||
private function setupRoutes(): void {
|
||||
// Auth routes (public)
|
||||
$this->router->get('login', function($req, $res, $params) {
|
||||
$controller = new AleShell2_AuthController($this);
|
||||
$controller->showLogin($req, $res, $params);
|
||||
$controller = new AleShell2_AuthController($this->getControllerConfig(), $this->auth);
|
||||
$controller->login($req, $res, $params);
|
||||
});
|
||||
|
||||
$this->router->post('login', function($req, $res, $params) {
|
||||
$controller = new AleShell2_AuthController($this);
|
||||
$controller = new AleShell2_AuthController($this->getControllerConfig(), $this->auth);
|
||||
$controller->login($req, $res, $params);
|
||||
});
|
||||
|
||||
$this->router->get('logout', function($req, $res, $params) {
|
||||
$controller = new AleShell2_AuthController($this);
|
||||
$controller = new AleShell2_AuthController($this->getControllerConfig(), $this->auth);
|
||||
$controller->logout($req, $res, $params);
|
||||
});
|
||||
|
||||
@@ -477,13 +842,13 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// Dashboard
|
||||
$this->router->get('dashboard', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_DashboardController($this);
|
||||
$controller = new AleShell2_DashboardController($this->getControllerConfig(), $this->auth);
|
||||
$controller->index($req, $res, $params);
|
||||
}));
|
||||
|
||||
// Files
|
||||
$this->router->get('files', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_FilesController($this);
|
||||
$controller = new AleShell2_FilesController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
match($action) {
|
||||
'list' => $controller->list($req, $res, $params),
|
||||
@@ -495,7 +860,7 @@ class AleShell2_PackedApplication {
|
||||
}));
|
||||
|
||||
$this->router->post('files', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_FilesController($this);
|
||||
$controller = new AleShell2_FilesController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
match($action) {
|
||||
'write' => $controller->write($req, $res, $params),
|
||||
@@ -511,12 +876,12 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// Terminal
|
||||
$this->router->get('terminal', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_TerminalController($this);
|
||||
$controller = new AleShell2_TerminalController($this->getControllerConfig(), $this->auth);
|
||||
$controller->index($req, $res, $params);
|
||||
}));
|
||||
|
||||
$this->router->post('terminal', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_TerminalController($this);
|
||||
$controller = new AleShell2_TerminalController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'exec');
|
||||
if ($action === 'exec') {
|
||||
$controller->execute($req, $res, $params);
|
||||
@@ -525,18 +890,18 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// Editor
|
||||
$this->router->get('editor', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_EditorController($this);
|
||||
$controller = new AleShell2_EditorController($this->getControllerConfig(), $this->auth);
|
||||
$controller->index($req, $res, $params);
|
||||
}));
|
||||
|
||||
$this->router->post('editor', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_EditorController($this);
|
||||
$controller = new AleShell2_EditorController($this->getControllerConfig(), $this->auth);
|
||||
$controller->save($req, $res, $params);
|
||||
}));
|
||||
|
||||
// Processes
|
||||
$this->router->get('processes', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_ProcessesController($this);
|
||||
$controller = new AleShell2_ProcessesController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
if ($action === 'list') {
|
||||
$controller->list($req, $res, $params);
|
||||
@@ -546,7 +911,7 @@ class AleShell2_PackedApplication {
|
||||
}));
|
||||
|
||||
$this->router->post('processes', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_ProcessesController($this);
|
||||
$controller = new AleShell2_ProcessesController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'kill');
|
||||
if ($action === 'kill') {
|
||||
$controller->kill($req, $res, $params);
|
||||
@@ -555,7 +920,7 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// Network
|
||||
$this->router->get('network', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_NetworkController($this);
|
||||
$controller = new AleShell2_NetworkController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
if ($action === 'connections') {
|
||||
$controller->connections($req, $res, $params);
|
||||
@@ -565,7 +930,7 @@ class AleShell2_PackedApplication {
|
||||
}));
|
||||
|
||||
$this->router->post('network', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_NetworkController($this);
|
||||
$controller = new AleShell2_NetworkController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action');
|
||||
match($action) {
|
||||
'ping' => $controller->ping($req, $res, $params),
|
||||
@@ -577,7 +942,7 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// Database
|
||||
$this->router->get('database', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_DatabaseController($this);
|
||||
$controller = new AleShell2_DatabaseController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
match($action) {
|
||||
'tables' => $controller->tables($req, $res, $params),
|
||||
@@ -588,7 +953,7 @@ class AleShell2_PackedApplication {
|
||||
}));
|
||||
|
||||
$this->router->post('database', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_DatabaseController($this);
|
||||
$controller = new AleShell2_DatabaseController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action');
|
||||
match($action) {
|
||||
'connect' => $controller->connect($req, $res, $params),
|
||||
@@ -601,7 +966,7 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// System
|
||||
$this->router->get('system', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_SystemController($this);
|
||||
$controller = new AleShell2_SystemController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'index');
|
||||
match($action) {
|
||||
'info' => $controller->info($req, $res, $params),
|
||||
@@ -614,7 +979,7 @@ class AleShell2_PackedApplication {
|
||||
|
||||
// API
|
||||
$this->router->get('api', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_ApiController($this);
|
||||
$controller = new AleShell2_ApiController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action', 'status');
|
||||
match($action) {
|
||||
'status' => $controller->status($req, $res, $params),
|
||||
@@ -626,7 +991,7 @@ class AleShell2_PackedApplication {
|
||||
}));
|
||||
|
||||
$this->router->post('api', $authMiddleware(function($req, $res, $params) {
|
||||
$controller = new AleShell2_ApiController($this);
|
||||
$controller = new AleShell2_ApiController($this->getControllerConfig(), $this->auth);
|
||||
$action = $req->get('action');
|
||||
match($action) {
|
||||
'exec' => $controller->exec($req, $res, $params),
|
||||
@@ -659,6 +1024,30 @@ class AleShell2_PackedApplication {
|
||||
public function getAuth(): AleShell2_Auth { return $this->auth; }
|
||||
public function getView(): AleShell2_PackedView { return $this->view; }
|
||||
public function getConfig(): array { return $this->config; }
|
||||
|
||||
// Get config in the format expected by controllers
|
||||
public function getControllerConfig(): array {
|
||||
return [
|
||||
'security' => [
|
||||
'password' => $this->config['password_hash'],
|
||||
'max_attempts' => $this->config['max_login_attempts'] ?? 5,
|
||||
'lockout_time' => $this->config['lockout_duration'] ?? 900,
|
||||
'session_timeout' => $this->config['session_timeout'] ?? 3600,
|
||||
'csrf_protection' => true,
|
||||
'restricted_paths' => [],
|
||||
'blocked_commands' => [],
|
||||
],
|
||||
'features' => [
|
||||
'file_manager' => true,
|
||||
'terminal' => true,
|
||||
'code_editor' => true,
|
||||
'process_manager' => true,
|
||||
'network_tools' => true,
|
||||
'database_tools' => true,
|
||||
'system_info' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Run the application
|
||||
|
||||
Referencia en una nueva incidencia
Block a user