# Changelog ## [Unreleased] ### Added - Customizable restore script filename per backup profile (reduces discoverability on remote servers) - MokoRestore standalone mode: multi-ZIP selector when multiple backup archives are present - MokoRestore preflight: Joomla installation detection warning before overwriting an existing site - MokoRestore error handling: try/catch on fetch calls, HTTP status checks, JSON parse recovery - Download button on individual backup record detail toolbar - Profile column in backup records list links to the profile edit view ### Changed - Moved download, browse archive, and view log actions from backup list rows into the individual backup record view - Removed "Run Backup" / "Backup Now" buttons from profiles list, profile edit toolbar, and backup records view (backups are triggered from the dashboard only) - Removed ordering field from profiles; default sort is now by ID ascending - MokoRestore cleanup and security messages now reference the actual script filename instead of hardcoded "restore.php" ### Fixed - Bootstrap 5 modal conversion for snapshots view (data-bs-dismiss, modal-footer, getOrCreateInstance) - ntfy default URL changed from ntfy.sh to ntfy.mokoconsulting.tech - Untranslated JFIELD_ORDERING_ASC / JFIELD_ORDERING_LABEL language keys replaced with component-specific keys - Options page title now shows "MokoSuiteBackup Options" instead of raw language key - Profile dropdown IDs in backup records and dashboard show "#ID — Title (type)" format - MokoRestore stalling: unhandled promise rejections from network errors or non-JSON responses left UI in loading state ## [01.43.00] --- 2026-06-24 ## [01.43.00] --- 2026-06-24 ## [01.42.00] --- 2026-06-23 ## [01.42.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 — 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 ### 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 ### 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 ### 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 ### 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 - Backup count badges on profile list - "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 — 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 - 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) - 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 ### 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