diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a92f44..4eb9d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,9 @@ - Install script: single-line comments converted to block comments - Orphaned root-level webservices plugin files removed - include_mokorestore column: TINYINT changed to VARCHAR(20) +- Snapshot fields_values: scoped dump and restore to com_content.article (previously destroyed values for contacts, users, etc.) +- Run Backup button: accept CSRF token from GET (fixes "token did not match" on profile edit) +- SFTP fields: moved into remote fieldset for showon visibility; removed required attr that blocked non-SFTP saves - Script.php merge conflict markers resolved ## [01.24.00] — 2026-06-02 diff --git a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini index 62fddd3..8942f04 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini @@ -277,7 +277,7 @@ COM_MOKOJOOMBACKUP_FIELD_SFTP_USERNAME_DESC="Username for SSH authentication" COM_MOKOJOOMBACKUP_FIELD_SFTP_PASSWORD="SSH Password" COM_MOKOJOOMBACKUP_FIELD_SFTP_PASSWORD_DESC="Password for SSH authentication. Leave blank if using a key file." COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY="SSH Private Key" -COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_DESC="Upload your SSH private key (id_rsa, id_ed25519). Stored encrypted in DB, written to temp file during upload only. Leave blank for password auth." +COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_DESC="Upload your SSH private key (id_rsa, id_ed25519). Stored base64-encoded in DB, written to temp file during upload only. Leave blank for password auth." COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_UPLOAD="Upload Key File" COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_REPLACE="Replace Key" COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_LOADED="Key loaded" diff --git a/source/packages/com_mokosuitebackup/src/Engine/PlaceholderResolver.php b/source/packages/com_mokosuitebackup/src/Engine/PlaceholderResolver.php index 36fa19d..2d6b548 100644 --- a/source/packages/com_mokosuitebackup/src/Engine/PlaceholderResolver.php +++ b/source/packages/com_mokosuitebackup/src/Engine/PlaceholderResolver.php @@ -51,7 +51,32 @@ class PlaceholderResolver public function __construct(object $profile) { $now = new \DateTimeImmutable('now'); - $hostname = preg_replace('/[^a-zA-Z0-9._-]/', '', $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? php_uname('n')); + + /* Resolve hostname: prefer HTTP_HOST (web), then try Joomla config (CLI), then system hostname */ + $rawHost = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? ''; + + if (empty($rawHost) || $rawHost === 'localhost') { + try { + $app = Factory::getApplication(); + $liveSite = $app->get('live_site', ''); + + if (!empty($liveSite)) { + $parsed = parse_url($liveSite, PHP_URL_HOST); + + if (!empty($parsed)) { + $rawHost = $parsed; + } + } + } catch (\Throwable $e) { + /* fallback */ + } + } + + if (empty($rawHost)) { + $rawHost = php_uname('n'); + } + + $hostname = preg_replace('/[^a-zA-Z0-9._-]/', '', $rawHost); $siteName = ''; diff --git a/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php b/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php index 5a0797f..1d78f48 100644 --- a/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php +++ b/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php @@ -38,7 +38,30 @@ class FolderPickerField extends FormField } // Build placeholder map for JS resolution - $hostname = preg_replace('/[^a-zA-Z0-9._-]/', '', $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? php_uname('n')); + /* Resolve hostname: prefer HTTP_HOST, then Joomla live_site config, then system hostname */ + $rawHost = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? ''; + + if (empty($rawHost) || $rawHost === 'localhost') { + try { + $liveSite = Factory::getApplication()->get('live_site', ''); + + if (!empty($liveSite)) { + $parsed = parse_url($liveSite, PHP_URL_HOST); + + if (!empty($parsed)) { + $rawHost = $parsed; + } + } + } catch (\Throwable $e) { + /* fallback */ + } + } + + if (empty($rawHost)) { + $rawHost = php_uname('n'); + } + + $hostname = preg_replace('/[^a-zA-Z0-9._-]/', '', $rawHost); $siteName = ''; try {