fix: address PR review — error logging, ACL check, fetch error handling
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Universal: Auto Version Bump / Version Bump (push) Has been cancelled
Universal: PR Check / Branch Policy (pull_request) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Joomla: Extension CI / Release Readiness Check (pull_request) Has been cancelled
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Joomla: Extension CI / Lint & Validate (pull_request) Has been cancelled
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been cancelled
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been cancelled
Universal: Build & Release / Promote to RC (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Universal: Auto Version Bump / Version Bump (push) Has been cancelled
Universal: PR Check / Branch Policy (pull_request) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Joomla: Extension CI / Release Readiness Check (pull_request) Has been cancelled
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Joomla: Extension CI / Lint & Validate (pull_request) Has been cancelled
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been cancelled
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been cancelled
Universal: Build & Release / Promote to RC (pull_request) Has been cancelled
- Log failures in protectBackupDir() and protectWebAccessibleDir() instead of silently suppressing with @ (security-critical .htaccess writes) - Add error_log() to empty catch blocks in boot() and syncMenuIcons() - Add core.manage ACL check to checkDir() AJAX endpoint - Surface opendir() failures in browseDir() with warning message - Add HTTP status check (r.ok) to JS fetch calls before parsing JSON - Log temp SQL file deletion failures in SteppedBackupEngine
This commit is contained in:
@@ -109,6 +109,7 @@ class AjaxController extends BaseController
|
||||
// that could contain a backup folder (e.g., /home/user/backups)
|
||||
$dirs = [];
|
||||
$handle = @opendir($path);
|
||||
$warning = null;
|
||||
|
||||
if ($handle) {
|
||||
while (($entry = readdir($handle)) !== false) {
|
||||
@@ -127,18 +128,26 @@ class AjaxController extends BaseController
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
} else {
|
||||
$warning = 'Cannot read directory contents (check permissions)';
|
||||
}
|
||||
|
||||
usort($dirs, fn($a, $b) => strcasecmp($a['name'], $b['name']));
|
||||
|
||||
$parent = dirname($path);
|
||||
|
||||
$this->sendJson([
|
||||
$response = [
|
||||
'error' => false,
|
||||
'current' => $path,
|
||||
'parent' => ($parent !== $path) ? $parent : null,
|
||||
'dirs' => $dirs,
|
||||
]);
|
||||
];
|
||||
|
||||
if ($warning !== null) {
|
||||
$response['warning'] = $warning;
|
||||
}
|
||||
|
||||
$this->sendJson($response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,6 +214,12 @@ class AjaxController extends BaseController
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->app->getIdentity()->authorise('core.manage', 'com_mokojoombackup')) {
|
||||
$this->sendJson(['error' => true, 'message' => 'Access denied']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$rawPath = trim($this->input->getString('path', ''));
|
||||
|
||||
if ($rawPath === '') {
|
||||
|
||||
@@ -530,13 +530,17 @@ class BackupEngine
|
||||
$htaccess = $dir . '/.htaccess';
|
||||
|
||||
if (!is_file($htaccess)) {
|
||||
@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n");
|
||||
if (@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n") === false) {
|
||||
error_log('MokoJoomBackup: Could not create .htaccess in backup directory: ' . $dir);
|
||||
}
|
||||
}
|
||||
|
||||
$index = $dir . '/index.html';
|
||||
|
||||
if (!is_file($index)) {
|
||||
@file_put_contents($index, '<!DOCTYPE html><title></title>');
|
||||
if (@file_put_contents($index, '<!DOCTYPE html><title></title>') === false) {
|
||||
error_log('MokoJoomBackup: Could not create index.html in backup directory: ' . $dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -317,8 +317,8 @@ class SteppedBackupEngine
|
||||
$zip->close();
|
||||
|
||||
// Clean up temp SQL file
|
||||
if (is_file($sqlFile)) {
|
||||
@unlink($sqlFile);
|
||||
if (is_file($sqlFile) && !@unlink($sqlFile)) {
|
||||
error_log('MokoJoomBackup: Could not delete temp SQL file: ' . $sqlFile);
|
||||
}
|
||||
|
||||
$totalSize = file_exists($session->archivePath) ? filesize($session->archivePath) : 0;
|
||||
@@ -572,13 +572,17 @@ class SteppedBackupEngine
|
||||
$htaccess = $dir . '/.htaccess';
|
||||
|
||||
if (!is_file($htaccess)) {
|
||||
@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n");
|
||||
if (@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n") === false) {
|
||||
error_log('MokoJoomBackup: Could not create .htaccess in backup directory: ' . $dir);
|
||||
}
|
||||
}
|
||||
|
||||
$index = $dir . '/index.html';
|
||||
|
||||
if (!is_file($index)) {
|
||||
@file_put_contents($index, '<!DOCTYPE html><title></title>');
|
||||
if (@file_put_contents($index, '<!DOCTYPE html><title></title>') === false) {
|
||||
error_log('MokoJoomBackup: Could not create index.html in backup directory: ' . $dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class MokoJoomBackupComponent extends MVCComponent
|
||||
. ' #menu a[href*="com_mokojoombackup"][href*="view=profiles"] .sidebar-item-title::before { content: "\f013"; }'
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
// Non-critical
|
||||
error_log('MokoJoomBackup: boot() CSS injection failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class FolderPickerField extends FormField
|
||||
body: form,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(r) { if (!r.ok) throw new Error('Server error (HTTP ' + r.status + ')'); return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.error) {
|
||||
setStatus('text-danger', 'icon-unpublish', data.message || 'Error', null);
|
||||
@@ -241,7 +241,7 @@ class FolderPickerField extends FormField
|
||||
body: form,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(r) { if (!r.ok) throw new Error('Server error (HTTP ' + r.status + ')'); return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.error) {
|
||||
tree.textContent = data.message || 'Error loading directory';
|
||||
|
||||
@@ -65,13 +65,17 @@ class ProfileTable extends Table
|
||||
$htaccess = $resolved . '/.htaccess';
|
||||
|
||||
if (!is_file($htaccess)) {
|
||||
@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n");
|
||||
if (@file_put_contents($htaccess, "Order deny,allow\nDeny from all\n") === false) {
|
||||
error_log('MokoJoomBackup: Could not create .htaccess in: ' . $resolved);
|
||||
}
|
||||
}
|
||||
|
||||
$index = $resolved . '/index.html';
|
||||
|
||||
if (!is_file($index)) {
|
||||
@file_put_contents($index, '<!DOCTYPE html><title></title>');
|
||||
if (@file_put_contents($index, '<!DOCTYPE html><title></title>') === false) {
|
||||
error_log('MokoJoomBackup: Could not create index.html in: ' . $resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -243,7 +243,7 @@ class Pkg_MokoJoomBackupInstallerScript
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
} catch (\Throwable $e) {
|
||||
// Non-critical
|
||||
error_log('MokoJoomBackup: syncMenuIcons() failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user