diff --git a/admin_backup.php b/admin_backup.php
index 841ab95d..3fa4dfa4 100644
--- a/admin_backup.php
+++ b/admin_backup.php
@@ -9,6 +9,7 @@ require_once "includes/inc_all_admin.php";
If you are unable to back up the entire VM, you'll need to back up the files & database individually. There is no built-in restore. See the
docs here.
Download database
+
Download Uploads
diff --git a/post/admin/admin_backup.php b/post/admin/admin_backup.php
index 7ad9fde8..1ea20c4a 100644
--- a/post/admin/admin_backup.php
+++ b/post/admin/admin_backup.php
@@ -71,6 +71,54 @@ if (isset($_GET['download_database'])) {
exit;
}
+if (isset($_GET['download_uploads'])) {
+ validateCSRFToken($_GET['csrf_token']);
+
+ function zipFolder($folderPath, $zipFilePath) {
+ $zip = new ZipArchive();
+ if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
+ die("Cannot open <$zipFilePath>\n");
+ }
+
+ $folderPath = realpath($folderPath);
+
+ $files = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($folderPath),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ );
+
+ foreach ($files as $name => $file) {
+ if (!$file->isDir()) {
+ $filePath = $file->getRealPath();
+ $relativePath = substr($filePath, strlen($folderPath) + 1);
+ $zip->addFile($filePath, $relativePath);
+ }
+ }
+
+ $zip->close();
+ }
+
+ $uploadDir = 'uploads';
+ $zipFile = 'uploads.zip';
+
+ zipFolder($uploadDir, $zipFile);
+
+ // Trigger file download
+ if (file_exists($zipFile)) {
+ header('Content-Type: application/zip');
+ header('Content-Disposition: attachment; filename="' . basename($zipFile) . '"');
+ header('Content-Length: ' . filesize($zipFile));
+ flush();
+ readfile($zipFile);
+ unlink($zipFile); // Optional: delete after download
+ exit;
+ }
+
+ logAction("Uploads", "Download", "$session_name downloaded the uploads folder.");
+
+}
+
+
if (isset($_POST['backup_master_key'])) {
validateCSRFToken($_POST['csrf_token']);
@@ -104,3 +152,4 @@ if (isset($_POST['backup_master_key'])) {
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
}
+
diff --git a/setup.php b/setup.php
index 0ea74101..1674cedd 100644
--- a/setup.php
+++ b/setup.php
@@ -108,6 +108,59 @@ if (isset($_POST['add_database'])) {
}
+if (isset($_POST['restore_database'])) {
+
+ if (isset($_FILES["sql_file"])) {
+
+ // Drop all existing tables
+ mysqli_query($mysqli, "SET foreign_key_checks = 0");
+ $tables = mysqli_query($mysqli, "SHOW TABLES");
+ while ($row = mysqli_fetch_array($tables)) {
+ mysqli_query($mysqli, "DROP TABLE IF EXISTS `" . $row[0] . "`");
+ }
+ mysqli_query($mysqli, "SET foreign_key_checks = 1");
+
+
+ $file = $_FILES["sql_file"];
+ $filename = $file["name"];
+ $tempPath = $file["tmp_name"];
+
+ $fileExt = pathinfo($filename, PATHINFO_EXTENSION);
+ if (strtolower($fileExt) !== "sql") {
+ die("Only .sql files are allowed.");
+ }
+
+ // Save uploaded file temporarily
+ $destination = "temp_" . time() . ".sql";
+ if (!move_uploaded_file($tempPath, $destination)) {
+ die("Failed to upload the file.");
+ }
+
+ $command = sprintf(
+ 'mysql -h%s -u%s -p%s %s < %s',
+ escapeshellarg($dbhost),
+ escapeshellarg($dbusername),
+ escapeshellarg($dbpassword),
+ escapeshellarg($database),
+ escapeshellarg($destination)
+ );
+
+ exec($command, $output, $returnCode);
+ unlink($destination); // cleanup
+
+ if ($returnCode === 0) {
+ echo "SQL file imported successfully!";
+ } else {
+ echo "Import failed. Error code: $returnCode";
+ }
+ }
+
+ $_SESSION['alert_message'] = "Database imported successfully";
+
+ //header("Location: login.php");
+ exit;
+}
+
if (isset($_POST['add_user'])) {
$user_count = mysqli_num_rows(mysqli_query($mysqli,"SELECT COUNT(*) FROM users"));
if ($user_count < 0) {
@@ -922,6 +975,26 @@ if (isset($_POST['add_telemetry'])) {
+
+
+