MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/com_mokosuitebackup/sql/install.mysql.sql b/source/packages/com_mokosuitebackup/sql/install.mysql.sql
index 67020ec..a87895c 100644
--- a/source/packages/com_mokosuitebackup/sql/install.mysql.sql
+++ b/source/packages/com_mokosuitebackup/sql/install.mysql.sql
@@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` (
`sftp_host` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_port` INT(5) UNSIGNED NOT NULL DEFAULT 22,
`sftp_username` VARCHAR(255) NOT NULL DEFAULT '',
+ `sftp_auth_type` VARCHAR(20) NOT NULL DEFAULT 'key',
`sftp_password` VARCHAR(255) NOT NULL DEFAULT '',
`sftp_key_data` MEDIUMTEXT,
`sftp_passphrase` VARCHAR(255) NOT NULL DEFAULT '',
diff --git a/source/packages/com_mokosuitebackup/sql/updates/mysql/01.36.00.sql b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.36.00.sql
new file mode 100644
index 0000000..b8b6565
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/sql/updates/mysql/01.36.00.sql
@@ -0,0 +1,4 @@
+-- MokoSuiteBackup 01.36.00 — SFTP auth type column
+
+ALTER TABLE `#__mokosuitebackup_profiles`
+ ADD COLUMN `sftp_auth_type` VARCHAR(20) NOT NULL DEFAULT 'key' AFTER `sftp_username`;
diff --git a/source/packages/com_mokosuitebackup/src/Engine/SftpUploader.php b/source/packages/com_mokosuitebackup/src/Engine/SftpUploader.php
index 5911c06..980ea4a 100644
--- a/source/packages/com_mokosuitebackup/src/Engine/SftpUploader.php
+++ b/source/packages/com_mokosuitebackup/src/Engine/SftpUploader.php
@@ -141,7 +141,15 @@ class SftpUploader implements RemoteUploaderInterface
$tmpDir = sys_get_temp_dir();
$keyFile = $tmpDir . '/mokobackup-sftp-' . bin2hex(random_bytes(8)) . '.key';
- if (file_put_contents($keyFile, $this->keyData) === false) {
+ /* Key is stored base64-encoded in the database — decode before writing */
+ $keyContent = base64_decode($this->keyData, true);
+
+ if ($keyContent === false) {
+ /* Fallback: might be raw PEM (legacy or paste) */
+ $keyContent = $this->keyData;
+ }
+
+ if (file_put_contents($keyFile, $keyContent) === false) {
throw new \RuntimeException('Cannot write temporary SSH key file');
}
diff --git a/source/packages/com_mokosuitebackup/src/Field/SshKeyField.php b/source/packages/com_mokosuitebackup/src/Field/SshKeyField.php
new file mode 100644
index 0000000..176ce22
--- /dev/null
+++ b/source/packages/com_mokosuitebackup/src/Field/SshKeyField.php
@@ -0,0 +1,109 @@
+
+ * @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
+ * @license GNU General Public License version 3 or later; see LICENSE
+ *
+ * Custom field for SSH private key input.
+ * Supports both file upload (via FileReader JS) and paste-in textarea.
+ * The key content is stored in the database, not as a file on disk.
+ */
+
+namespace Joomla\Component\MokoSuiteBackup\Administrator\Field;
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Form\FormField;
+use Joomla\CMS\Language\Text;
+
+class SshKeyField extends FormField
+{
+ protected $type = 'SshKey';
+
+ protected function getInput(): string
+ {
+ $value = $this->value ?? '';
+ $id = $this->id;
+ $name = $this->name;
+
+ $hasKey = !empty($value) && str_contains($value, 'PRIVATE KEY');
+
+ $html = '';
+
+ /* Status badge */
+ if ($hasKey) {
+ $html .= ''
+ . ' '
+ . Text::_('COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_LOADED')
+ . '';
+ }
+
+ /* File upload button */
+ $html .= '';
+ $html .= '';
+
+ $html .= '';
+
+ if ($hasKey) {
+ $html .= ' ';
+ }
+
+ /* Hidden field — key data is NEVER rendered as visible text.
+ On existing keys, we submit a sentinel value to preserve the DB value
+ unless a new file is uploaded or clear is clicked. */
+ if ($hasKey) {
+ $html .= '';
+ } else {
+ $html .= '';
+ }
+
+ $html .= '
';
+ $html .= $this->getScript();
+
+ return $html;
+ }
+
+ private function getScript(): string
+ {
+ return <<<'JS'
+
+JS;
+ }
+}
diff --git a/source/packages/com_mokosuitebackup/src/Table/ProfileTable.php b/source/packages/com_mokosuitebackup/src/Table/ProfileTable.php
index fef06ca..5102e91 100644
--- a/source/packages/com_mokosuitebackup/src/Table/ProfileTable.php
+++ b/source/packages/com_mokosuitebackup/src/Table/ProfileTable.php
@@ -25,6 +25,23 @@ class ProfileTable extends Table
public function store($updateNulls = true): bool
{
+ /* Handle SSH key sentinel — when __KEEP_EXISTING__ is submitted,
+ preserve the current DB value instead of overwriting with the sentinel.
+ This prevents the key from being exposed in the form HTML. */
+ if (isset($this->sftp_key_data) && $this->sftp_key_data === '__KEEP_EXISTING__') {
+ if ($this->id) {
+ $db = $this->getDbo();
+ $query = $db->getQuery(true)
+ ->select($db->quoteName('sftp_key_data'))
+ ->from($db->quoteName($this->_tbl))
+ ->where($db->quoteName('id') . ' = ' . (int) $this->id);
+ $db->setQuery($query);
+ $this->sftp_key_data = $db->loadResult() ?: '';
+ } else {
+ $this->sftp_key_data = '';
+ }
+ }
+
$result = parent::store($updateNulls);
if ($result && !empty($this->backup_dir)) {
diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
index c772cd4..f6fc4f3 100644
--- a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Action Log - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-04
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
index 21baa6b..652e0c9 100644
--- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Console - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-04
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
index 6223170..0fad0bd 100644
--- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Content - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-04
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
index 4a16d7c..1612ee8 100644
--- a/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml
@@ -1,7 +1,7 @@
Quick Icon - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml
index 12314b7..e21776c 100644
--- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
System - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml
index 4623395..9b2faa7 100644
--- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Task - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml
index a831160..f2ac768 100644
--- a/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml
+++ b/source/packages/plg_webservices_mokosuitebackup/mokosuitebackup.xml
@@ -7,7 +7,7 @@
-->
Web Services - MokoSuiteBackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech
diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml
index f1ade58..9b1bb07 100644
--- a/source/pkg_mokosuitebackup.xml
+++ b/source/pkg_mokosuitebackup.xml
@@ -8,7 +8,7 @@
Package - MokoSuiteBackup
mokosuitebackup
- 01.35.01
+ 01.35.03
2026-06-02
Moko Consulting
hello@mokoconsulting.tech