From 1da2fdb856012e1ad17950983756e49fba657d74 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 17:01:11 -0500 Subject: [PATCH 1/7] docs: comprehensive CHANGELOG consolidation for v01.41.00 Consolidated all fragmented changelog entries from the session into a single clean v01.41.00 release entry organized by feature area. Covers: multi-remote, snapshots, SFTP, MokoRestore, sanitization, engine improvements, admin UI, CLI/API, notifications, security. --- CHANGELOG.md | 135 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 110 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d641130..9a92f44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,38 +1,123 @@ # Changelog + ## [Unreleased] -## [01.41.00] --- 2026-06-23 +## [01.41.00] — 2026-06-23 -## [01.41.00] --- 2026-06-23 +### Added — Multi-Remote Storage +- New `#__mokosuitebackup_remotes` table for multiple destinations per profile +- Remote destinations UI: AJAX-driven add/edit/delete/toggle modal on profile edit +- Engine uploads to ALL enabled destinations (BackupEngine + SteppedBackupEngine) +- Migration auto-converts existing SFTP/S3/GDrive/FTP profile columns to new table +- Backward compatibility: falls back to legacy single-remote columns if table empty +- Secrets masked in API responses, merged from DB on save -### Added -- Multi-remote storage: new `#__mokosuitebackup_remotes` table for multiple destinations per profile (#97) -- Remote destinations UI: AJAX-driven add/edit/delete/toggle modal on profile edit view -- Engine integration: BackupEngine and SteppedBackupEngine upload to all enabled destinations -- Migration SQL: auto-migrates existing SFTP/S3/GDrive/FTP configs to new table -- Backward compatibility: falls back to legacy single-remote columns if remotes table is empty -- Secrets masked in API responses, merged from DB on save to prevent leakage +### Added — Content Snapshots +- Lightweight JSON snapshots of articles, categories, and modules +- Includes tags, custom fields, workflow associations, field values +- Restore modes: Replace (clean slate), Merge (upsert), Selective (per-article) +- Snapshot retention: max count + max age with automatic cleanup +- Scheduled snapshot task via com_scheduler +- CLI: `mokosuitebackup:snapshot create|restore|list|delete` +- REST API: create, list, restore, delete, download snapshots +- Tabbed browse modal: Articles / Categories / Modules with item counts -## [01.40.00] --- 2026-06-23 +### Added — SFTP Remote Storage +- SFTP support with SSH key file authentication (key stored base64 in database) +- Auth type dropdown: Password / Key File / Key File + Passphrase +- SshKeyField: file upload via FileReader, key never exposed in HTML +- SFTP remote directory browser for path selection +- `__KEEP_EXISTING__` sentinel preserves key on profile re-save +### Added — MokoRestore Wizard (9 steps) +- Per-table conflict resolution: Replace / Skip / Merge / Data Only +- Preset buttons: "All Replace", "All Skip", "Everything except users" +- Post-restore actions: reset passwords, hits, versions, sessions, cache +- Auto-detect sanitized passwords and prompt for reset (random temp password) +- Standalone mode: restore.php scans directory for ZIP files +- Wrapped mode: restore.php bundled inside backup ZIP +- Security gate with filesystem verification + path traversal protection -## [01.40.00] --- 2026-06-23 +### Added — Data Sanitization +- Sanitize user passwords: replace hashes with invalid sentinel +- Sanitize user emails: replace with dummy values +- Clear session data: exclude `#__session` table +- Preserve super admin credentials (optional) +- GDPR-friendly backup sharing for demos and staging sites -## [01.39.01] --- 2026-06-23 +### Added — Backup Engine +- Pre-flight validation: directory, disk space, extensions, credentials, running backups +- Auto-verify archive integrity after creation (ZIP, tar.gz, 7z) +- 7z archive format via system 7za/7z CLI binary with native encryption +- Streaming database dump to temp file (prevents OOM on large sites) +- S3 streaming upload via CURLOPT_PUT (prevents OOM) +- Graceful remote degradation: local backup preserved if upload fails +- DatabaseDumper::dumpToFile() for memory-efficient operation -## [01.39.01] --- 2026-06-23 +### Added — Admin UI +- Dashboard: snapshot widget, 30-day backup trend chart, per-profile storage breakdown +- CPanel admin dashboard module (mod_mokosuitebackup_cpanel) with quick actions +- Backup type filter dropdown in backups list +- Backup comparison: select two backups for side-by-side diff +- Archive browser: view files inside backup without extracting +- Manual purge: delete backups older than a date with count preview +- Run Backup button on profile list and edit views with backup count badges +- "Do not navigate away" warning in backup/restore progress modals +- Clickable placeholder pills for backup directory and archive name fields +- Comprehensive help modal with absolute/relative/placeholder path documentation +- Placeholder resolution display with EXAMPLE prefix +- All placeholders UPPERCASE: [HOST], [SITE_NAME], [DATE], [DATETIME], etc. -### Added -- MokoRestore: post-restore reset options — passwords, hits, versions, sessions, cache (#131) -- MokoRestore: per-table conflict resolution — replace, skip, merge, data-only per table (#132) -- MokoRestore: preset buttons — "All Replace", "All Skip", "Everything except users" -- MokoRestore: auto-detect sanitized passwords and prompt for reset -- Data sanitization: passwords, emails, sessions in backup profile settings (#129) -- Manual purge: delete all backups older than a selected date with count preview (#119) -- CPanel admin dashboard module with backup status, quick actions, and profile buttons (#105) -- 7z archive format via system 7za/7z binary with optional password encryption (#122) -- SFTP remote file browser: browse remote server directories to select backup path (#98) +### Added — CLI & API +- `mokosuitebackup:restore` with --files-only, --db-only, --password options +- `mokosuitebackup:snapshot` with create, restore, list, delete actions +- REST API for snapshots: create, list, restore, delete, download +- Profile credentials masked in API responses + +### Added — Notifications & Logging +- Email/ntfy notifications for site restore, snapshot create/restore +- Joomla Action Logs for restore, snapshot, and snapshot restore events +- Global ntfy server/topic/token settings (fallback for profiles) + +### Added — Security & Configuration +- Webcron secret field with CSPRNG generator + strength meter +- IP whitelist field with current IP detection + one-click "Add my IP" +- 10 ACL permissions with full enforcement audit across all controllers +- Config defaults: archive format, MokoRestore mode, sanitization settings +- Path traversal protection on all archive extraction (ZIP, tar.gz, JPA) ### Fixed -- MokoRestore: data-only mode now uses REPLACE INTO to handle existing rows -- MokoRestore: temporary password is now randomly generated (not hardcoded "changeme") +- CLI RestoreCommand passed wrong arguments (filepath instead of record ID) +- JPA path traversal: reject `../` in archive entry paths +- S3Uploader OOM: streaming upload instead of file_get_contents +- DatabaseDumper OOM: streaming to file instead of in-memory string +- AkeebaImporter: removed unserialize() (PHP object injection risk) +- BackupTable: delete DB row before file (prevents data loss) +- RestoreEngine: staging path sanitized with preg_replace +- API profiles: sensitive fields masked with `***` +- Webcron: missing return after sendJsonResponse on auth failure +- loadFormData(): cast array to object (PHP 8.x TypeError fix) +- MokoRestore data-only mode: uses REPLACE INTO for existing rows +- Plaintext archive deleted on encryption failure +- TarGzArchiver: intermediate .tar cleaned in finally block +- Install script: single-line comments converted to block comments +- Orphaned root-level webservices plugin files removed +- include_mokorestore column: TINYINT changed to VARCHAR(20) +- Script.php merge conflict markers resolved + +## [01.24.00] — 2026-06-02 + +### Added +- Initial release: full-site backup and restore for Joomla 6 +- Database, files, and configuration backup +- ZIP and tar.gz archive formats with AES-256 encryption +- Differential backups based on file manifests +- FTP/FTPS, S3, Google Drive remote storage +- MokoRestore standalone restore wizard +- CLI backup and restore commands +- REST API for remote management +- Scheduled tasks via com_scheduler +- Email and ntfy push notifications +- Per-profile retention, exclusions, and notifications +- Akeeba Backup migration tool +- Admin dashboard with system health checks -- 2.52.0 From 0f95cb6e9f2ac6ed1f1c68df002077b3af7b5f62 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Tue, 23 Jun 2026 22:01:24 +0000 Subject: [PATCH 2/7] chore(version): pre-release bump to 01.41.01-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 8231281..6ebfee6 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.41.00 +# VERSION: 01.41.01 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index 488ece1..6fbac5e 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 01.41.00 + 01.41.01 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index c1d1470..7b379d5 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 01.41.00 + 01.41.01 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index 55624e1..f2a44ea 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.41.00 + 01.41.01 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 003d5fc..22b377a 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 01.41.00 + 01.41.01 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 c9c353a..19620aa 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 01.41.00 + 01.41.01 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 e2d61d6..8eae75d 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.41.00 + 01.41.01 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 a378e6f..ca261d2 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 01.41.00 + 01.41.01 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 092a62c..b6a8da8 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 01.41.00 + 01.41.01 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 206e591..8adeb9e 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.41.00 + 01.41.01 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 82f94df..0d33a21 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 01.41.00 + 01.41.01 2026-06-02 Moko Consulting hello@mokoconsulting.tech -- 2.52.0 From 6c47838b3001606c46a122130fb7ee4973c96ecf Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 17:09:37 -0500 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20clean=20up=20wordy=20field=20descrip?= =?UTF-8?q?tions=20=E2=80=94=20shorter,=20punchier=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backup dir, archive name, MokoRestore, SFTP key, sanitization, encryption descriptions all shortened. Removed redundant placeholder lists (now handled by clickable pills and help modal). --- .../language/en-GB/com_mokosuitebackup.ini | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 a84ba6e..62fddd3 100644 --- a/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini +++ b/source/packages/com_mokosuitebackup/language/en-GB/com_mokosuitebackup.ini @@ -127,15 +127,15 @@ COM_MOKOJOOMBACKUP_COMPRESSION_FASTEST="Low (fast)" COM_MOKOJOOMBACKUP_COMPRESSION_NORMAL="Normal (balanced)" COM_MOKOJOOMBACKUP_COMPRESSION_BEST="Maximum (smallest)" COM_MOKOJOOMBACKUP_FIELD_ENCRYPTION_PASSWORD="Encryption Password" -COM_MOKOJOOMBACKUP_FIELD_ENCRYPTION_PASSWORD_DESC="Set a password to encrypt the backup archive with AES-256. Leave blank for no encryption. Required to restore encrypted backups." +COM_MOKOJOOMBACKUP_FIELD_ENCRYPTION_PASSWORD_DESC="AES-256 encryption password. Leave blank for no encryption. Required to restore." COM_MOKOJOOMBACKUP_FIELD_SPLIT_SIZE="Split Size (MB)" COM_MOKOJOOMBACKUP_FIELD_SPLIT_SIZE_DESC="Split archive into parts of this size in MB. 0 = no splitting." COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR="Backup Directory" -COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR_DESC="Directory where backup archives are stored. Supports placeholders: [HOME] (user home directory), [HOST], [DATE], [YEAR], [MONTH], [DAY], [PROFILE_NAME], [SITE_NAME], [TYPE]. Use [HOME]/backups to store outside the web root. Absolute paths (starting with /) are used as-is; relative paths resolve from the Joomla root." +COM_MOKOJOOMBACKUP_FIELD_BACKUP_DIR_DESC="Where backups are stored. Use placeholders like [HOME]/backups for portability. Click the ? icon for full documentation." COM_MOKOJOOMBACKUP_FIELD_ARCHIVE_NAME_FORMAT="Archive Name Format" -COM_MOKOJOOMBACKUP_FIELD_ARCHIVE_NAME_FORMAT_DESC="Filename template for backup archives (without extension). Placeholders: [HOST] hostname, [DATE] Ymd, [TIME] His, [DATETIME] Ymd_His, [YEAR] [MONTH] [DAY] [HOUR] [MINUTE] [SECOND], [PROFILE_ID], [PROFILE_NAME], [SITE_NAME], [TYPE], [RANDOM]." +COM_MOKOJOOMBACKUP_FIELD_ARCHIVE_NAME_FORMAT_DESC="Filename template (without extension). Click the placeholder buttons below to insert tokens." COM_MOKOJOOMBACKUP_FIELD_INCLUDE_MOKORESTORE="MokoRestore Script" -COM_MOKOJOOMBACKUP_FIELD_INCLUDE_MOKORESTORE_DESC="Include the MokoRestore standalone restore wizard. 'Wrapped' bundles it inside the backup ZIP. 'Standalone' generates a separate restore.php that scans for backup ZIPs in its directory — ideal for remote servers." +COM_MOKOJOOMBACKUP_FIELD_INCLUDE_MOKORESTORE_DESC="None: no restore script. Wrapped: bundled inside the ZIP. Standalone: separate restore.php file (ideal for remote servers)." COM_MOKOJOOMBACKUP_MOKORESTORE_NONE="None" COM_MOKOJOOMBACKUP_MOKORESTORE_WRAPPED="Wrapped (inside backup ZIP)" COM_MOKOJOOMBACKUP_MOKORESTORE_STANDALONE="Standalone (separate restore.php)" @@ -143,13 +143,13 @@ COM_MOKOJOOMBACKUP_MOKORESTORE_STANDALONE="Standalone (separate restore.php)" ; Data Sanitization COM_MOKOJOOMBACKUP_FIELDSET_SANITIZATION="Data Sanitization" COM_MOKOJOOMBACKUP_FIELD_SANITIZE_PASSWORDS="Sanitize User Passwords" -COM_MOKOJOOMBACKUP_FIELD_SANITIZE_PASSWORDS_DESC="Replace all user password hashes with an invalid value. Users will not be able to log in with the restored backup without resetting their password. Ideal for sharing backups, creating demo/staging sites, or GDPR compliance." +COM_MOKOJOOMBACKUP_FIELD_SANITIZE_PASSWORDS_DESC="Replace password hashes with invalid values. Users must reset passwords after restore. For demos, staging, or GDPR." COM_MOKOJOOMBACKUP_FIELD_PRESERVE_SUPER_ADMIN="Preserve Super Admin Password" COM_MOKOJOOMBACKUP_FIELD_PRESERVE_SUPER_ADMIN_DESC="Keep the password for Super Users (group ID 8) intact. You will still be able to log in as a Super Admin after restoring." COM_MOKOJOOMBACKUP_FIELD_SANITIZE_EMAILS="Sanitize User Emails" -COM_MOKOJOOMBACKUP_FIELD_SANITIZE_EMAILS_DESC="Replace all user email addresses with dummy values (user123@sanitized.example.com). Prevents accidental emails being sent to real users from a cloned/staging site. Super admin emails are preserved if 'Preserve Super Admin' is enabled." +COM_MOKOJOOMBACKUP_FIELD_SANITIZE_EMAILS_DESC="Replace emails with dummy values. Prevents accidental emails from cloned sites. Super admin preserved if enabled above." COM_MOKOJOOMBACKUP_FIELD_SANITIZE_SESSIONS="Clear Session Data" -COM_MOKOJOOMBACKUP_FIELD_SANITIZE_SESSIONS_DESC="Exclude active session data from the backup. This logs out all users and prevents session hijacking when the backup is restored on another server. Enabled by default." +COM_MOKOJOOMBACKUP_FIELD_SANITIZE_SESSIONS_DESC="Exclude session data. Logs out all users on restore, prevents session hijacking. Enabled by default." ; Exclusion filter fields COM_MOKOJOOMBACKUP_FIELD_EXCLUDE_DIRS="Exclude Directories" @@ -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 or paste your SSH private key (e.g. id_rsa or id_ed25519). The key is stored securely in the database and written to a temp file with 0600 permissions only during upload, then deleted. Leave blank to use password authentication." +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_UPLOAD="Upload Key File" COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_REPLACE="Replace Key" COM_MOKOJOOMBACKUP_FIELD_SFTP_KEY_LOADED="Key loaded" -- 2.52.0 From 0b2b8851632ddc24ed1e3dc84fa705963e6e75d4 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Tue, 23 Jun 2026 22:10:35 +0000 Subject: [PATCH 4/7] chore(version): pre-release bump to 01.41.02-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 6ebfee6..d9ad262 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.41.01 +# VERSION: 01.41.02 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index 6fbac5e..d426f19 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 01.41.01 + 01.41.02 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index 7b379d5..bfcd08a 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 01.41.01 + 01.41.02 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index f2a44ea..acd9096 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.41.01 + 01.41.02 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 22b377a..c529bda 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 01.41.01 + 01.41.02 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 19620aa..b8cead6 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 01.41.01 + 01.41.02 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 8eae75d..26eb5cd 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.41.01 + 01.41.02 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 ca261d2..00c0a2e 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 01.41.01 + 01.41.02 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 b6a8da8..d0f2bc7 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 01.41.01 + 01.41.02 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 8adeb9e..43dd423 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.41.01 + 01.41.02 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index 0d33a21..c3e3dc3 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 01.41.01 + 01.41.02 2026-06-02 Moko Consulting hello@mokoconsulting.tech -- 2.52.0 From ff7418721dc50937fd8a0fce2a37e18d6ab46f41 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 17:19:46 -0500 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20review=20findings=20=E2=80=94=20key?= =?UTF-8?q?=20desc,=20missing=20changelog,=20[HOST]=20domain=20resolution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Language: "encrypted" → "base64-encoded" for SSH key description - CHANGELOG: added 3 missing bug fix entries (fields_values scope, CSRF token on Run Backup, SFTP showon/required) - [HOST] placeholder: resolve domain from Joomla live_site config when HTTP_HOST is unavailable (CLI), instead of falling back to system hostname (joomla.invalid). Applied to both PlaceholderResolver and FolderPickerField. --- CHANGELOG.md | 3 +++ .../language/en-GB/com_mokosuitebackup.ini | 2 +- .../src/Engine/PlaceholderResolver.php | 27 ++++++++++++++++++- .../src/Field/FolderPickerField.php | 25 ++++++++++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) 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 { -- 2.52.0 From e633d0cc0a1e159cffb27889c05c2ddece42eb17 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Tue, 23 Jun 2026 22:20:21 +0000 Subject: [PATCH 6/7] chore(version): pre-release bump to 01.41.03-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- source/packages/com_mokosuitebackup/mokosuitebackup.xml | 2 +- .../mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml | 2 +- .../packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml | 2 +- .../packages/plg_quickicon_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml | 2 +- source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml | 2 +- .../plg_webservices_mokosuitebackup/mokosuitebackup.xml | 2 +- source/pkg_mokosuitebackup.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index d9ad262..4371c59 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.41.02 +# VERSION: 01.41.03 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/source/packages/com_mokosuitebackup/mokosuitebackup.xml b/source/packages/com_mokosuitebackup/mokosuitebackup.xml index d426f19..6573375 100644 --- a/source/packages/com_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/com_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> MokoSuiteBackup - 01.41.02 + 01.41.03 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml index bfcd08a..6e57699 100644 --- a/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml +++ b/source/packages/mod_mokosuitebackup_cpanel/mod_mokosuitebackup_cpanel.xml @@ -8,7 +8,7 @@ --> mod_mokosuitebackup_cpanel - 01.41.02 + 01.41.03 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml b/source/packages/plg_actionlog_mokosuitebackup/mokosuitebackup.xml index acd9096..4fb15e4 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.41.02 + 01.41.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 c529bda..dab69af 100644 --- a/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_console_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Console - MokoSuiteBackup - 01.41.02 + 01.41.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 b8cead6..d4a7f35 100644 --- a/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_content_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Content - MokoSuiteBackup - 01.41.02 + 01.41.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 26eb5cd..2a65691 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.41.02 + 01.41.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 00c0a2e..f2e13c9 100644 --- a/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_system_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> System - MokoSuiteBackup - 01.41.02 + 01.41.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 d0f2bc7..d419a22 100644 --- a/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml +++ b/source/packages/plg_task_mokosuitebackup/mokosuitebackup.xml @@ -7,7 +7,7 @@ --> Task - MokoSuiteBackup - 01.41.02 + 01.41.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 43dd423..d45eae7 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.41.02 + 01.41.03 2026-06-02 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitebackup.xml b/source/pkg_mokosuitebackup.xml index c3e3dc3..c690d33 100644 --- a/source/pkg_mokosuitebackup.xml +++ b/source/pkg_mokosuitebackup.xml @@ -8,7 +8,7 @@ Package - MokoSuiteBackup mokosuitebackup - 01.41.02 + 01.41.03 2026-06-02 Moko Consulting hello@mokoconsulting.tech -- 2.52.0 From 898520d1db5e2628b0c83dffd2cd70cfeb359628 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 17:58:25 -0500 Subject: [PATCH 7/7] chore: sync auto-release.yml from Template-Generic [skip ci] --- .mokogitea/workflows/auto-release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index 18b67de..ce90d46 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -27,7 +27,7 @@ name: "Universal: Build & Release" on: pull_request: - types: [opened, closed] + types: [opened, synchronize, closed] branches: - main paths-ignore: @@ -66,6 +66,7 @@ jobs: runs-on: release if: >- (github.event.action == 'opened' && github.event.pull_request.merged != true) || + (github.event.action == 'synchronize' && github.event.pull_request.merged != true) || (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc') steps: -- 2.52.0