feat: change default backup dir to ../backups (outside web root)
- Default backup_dir is now ../backups (relative to JPATH_ROOT), which resolves outside public_html on most hosting setups - Added BackupDirectory::normalizePath() to resolve ../ segments without requiring the path to exist on disk - Added BackupDirectory::portablize() to auto-detect absolute paths and replace them with portable placeholders ([HOME], ../backups) - ProfileTable::check() auto-normalizes backup_dir on save - Install postflight auto-migrates old in-webroot defaults to ../backups - Dashboard warning now checks resolved path instead of string matching - .htaccess protection only applied when directory is inside web root
This commit is contained in:
+22
-29
@@ -191,25 +191,11 @@ class Pkg_MokoSuiteBackupInstallerScript
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Create and protect default backup directory
|
||||
$backupDir = JPATH_ADMINISTRATOR . '/components/com_mokosuitebackup/backups';
|
||||
// Create default backup directory (outside web root)
|
||||
$backupDir = JPATH_ROOT . '/../backups';
|
||||
|
||||
if (!is_dir($backupDir)) {
|
||||
mkdir($backupDir, 0755, true);
|
||||
}
|
||||
|
||||
if (is_dir($backupDir)) {
|
||||
$htaccess = $backupDir . '/.htaccess';
|
||||
|
||||
if (!is_file($htaccess)) {
|
||||
file_put_contents($htaccess, "# Apache 2.4+\n<IfModule mod_authz_core.c>\n Require all denied\n</IfModule>\n# Apache 2.2\n<IfModule !mod_authz_core.c>\n Order deny,allow\n Deny from all\n</IfModule>\n");
|
||||
}
|
||||
|
||||
$index = $backupDir . '/index.html';
|
||||
|
||||
if (!is_file($index)) {
|
||||
file_put_contents($index, '<!DOCTYPE html><title></title>');
|
||||
}
|
||||
@mkdir($backupDir, 0755, true);
|
||||
}
|
||||
|
||||
// Create default scheduled task — every 30 days, profile 1
|
||||
@@ -247,26 +233,33 @@ class Pkg_MokoSuiteBackupInstallerScript
|
||||
{
|
||||
try {
|
||||
$db = Factory::getDbo();
|
||||
// Check for profiles using the old in-webroot default
|
||||
$oldDefaults = [
|
||||
'administrator/components/com_mokosuitebackup/backups',
|
||||
'administrator/components/com_mokojoombackup/backups',
|
||||
'[DEFAULT_DIR]',
|
||||
];
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->where($db->quoteName('published') . ' = 1')
|
||||
->where('(' . $db->quoteName('backup_dir') . ' = ' . $db->quote('administrator/components/com_mokosuitebackup/backups')
|
||||
. ' OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('[DEFAULT_DIR]')
|
||||
. ' OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('')
|
||||
->where('(' . $db->quoteName('backup_dir') . ' IN ('
|
||||
. implode(',', array_map([$db, 'quote'], $oldDefaults))
|
||||
. ') OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('')
|
||||
. ' OR ' . $db->quoteName('backup_dir') . ' IS NULL)');
|
||||
$db->setQuery($query);
|
||||
|
||||
if ((int) $db->loadResult() > 0) {
|
||||
$profileUrl = Route::_('index.php?option=com_mokosuitebackup&view=profiles');
|
||||
|
||||
Factory::getApplication()->enqueueMessage(
|
||||
'<strong>Backup Directory Warning</strong> — '
|
||||
. 'One or more profiles store backups in the default directory inside the web root. '
|
||||
. 'For better security, configure a backup directory outside the web root. '
|
||||
. '<a href="' . $profileUrl . '" class="btn btn-sm btn-warning ms-2">Edit Profiles</a>',
|
||||
'warning'
|
||||
);
|
||||
// Auto-migrate old defaults to the new ../backups convention
|
||||
$update = $db->getQuery(true)
|
||||
->update($db->quoteName('#__mokosuitebackup_profiles'))
|
||||
->set($db->quoteName('backup_dir') . ' = ' . $db->quote('../backups'))
|
||||
->where('(' . $db->quoteName('backup_dir') . ' IN ('
|
||||
. implode(',', array_map([$db, 'quote'], $oldDefaults))
|
||||
. ') OR ' . $db->quoteName('backup_dir') . ' = ' . $db->quote('')
|
||||
. ' OR ' . $db->quoteName('backup_dir') . ' IS NULL)');
|
||||
$db->setQuery($update);
|
||||
$db->execute();
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
error_log('MokoSuiteBackup: warnDefaultBackupDir() failed: ' . $e->getMessage());
|
||||
|
||||
Reference in New Issue
Block a user