14 Commits

Author SHA1 Message Date
Jonathan Miller 42c995853f docs: update changelog with all unreleased changes
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-06 13:32:21 -05:00
Jonathan Miller 5460c7b211 chore: consolidate changelog entries to minor versions only
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Release configuration (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Collapsed all patch-level entries (01.00.00, 01.01.01–01.01.04) into
two minor version sections: 01.00 and 01.01. Deduplicated and grouped
entries by Added/Changed/Fixed within each.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 12:56:34 -05:00
Jonathan Miller 610f875ad9 refactor: rename Kickstart to MokoRestore
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Replace all Akeeba Kickstart branding with MokoRestore:
- Rename Kickstart.php to MokoRestore.php
- Rename class Kickstart to MokoRestore
- Update DB column: include_kickstart → include_mokorestore
- Update form field and language string keys
- Update all variable names, log messages, and comments
- Update CHANGELOG references

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-03 04:37:27 -05:00
Jonathan Miller 0136a5a24b chore: release prep v01.00.00
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
- Remove -dev suffix from all version strings
- Convert CHANGELOG [Unreleased] section to 01.00.00

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 20:05:13 -05:00
Jonathan Miller 63997252bf feat: dashboard widget (#18), differential backups (#19), JPA import (#20)
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
#18 — Dashboard Quickicon Widget:
- plg_quickicon_mokobackup: shows backup status on admin dashboard
- Displays: last backup time, total count, storage used
- Warning states: no backups, recent failures, stale (>7 days)
- Links to backup records view

#19 — Differential Backups:
- New backup_type: "differential" — only backs up changed/new files
- DifferentialScanner: builds manifest (path+size+mtime) on full backups
- Compares current filesystem against base manifest on differential runs
- Manifest stored in backup record (LONGTEXT column)
- Falls back to full backup if no base manifest exists
- Database is always fully dumped (no incremental DB)

#20 — JPA Format Import:
- JpaUnarchiver: parses Akeeba JPA binary format
- Handles: archive header, file entities, gzip decompression, permissions
- RestoreEngine auto-detects JPA vs ZIP by reading signature bytes
- Enables restoring from existing Akeeba .jpa backup files

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 18:56:21 -05:00
Jonathan Miller 9d311f30e0 feat: AES-256 archive encryption (#17)
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
- Per-profile encryption_password field in archive settings
- BackupEngine encrypts all files in ZIP using ZipArchive::EM_AES_256
  (WinZip-compatible, requires PHP 7.2+ with libzip 1.2.0+)
- Encryption runs after ZIP creation, before checksum computation
- RestoreEngine accepts password parameter for decryption
- BackupsController passes encryption_password to restore
- Kickstart restore.php: password input field in Step 2, passed to
  ZipArchive::setPassword() before extraction
- Clear error messages for wrong password or missing AES support

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 18:46:23 -05:00
Jonathan Miller 74ee3ea3ab feat: SHA-256 checksums (#15) and S3 storage backend (#16)
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
#15 — Backup Integrity Verification:
- Compute SHA-256 hash after archive creation, store in checksum column
- "Verify Integrity" toolbar button re-computes and compares
- Hash logged in backup step log

#16 — S3-Compatible Storage:
- S3Uploader with AWS Signature V4 (no SDK dependency, pure cURL)
- Single PUT for files <= 100 MB, multipart upload for larger files
- Multipart: 10 MB parts, abort on failure, XML completion
- Works with AWS S3, Wasabi, Backblaze B2, MinIO (custom endpoints)
- Profile form fields: endpoint, region, access key, secret key, bucket, path
- showon conditional visibility (only shown when remote_storage=s3)
- Akeeba importer maps S3 credentials from Akeeba profiles
- Added to BackupEngine createUploader() factory

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 18:38:23 -05:00
Jonathan Miller 7650026aac docs: update CHANGELOG for #14 and #21
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 16:36:05 -05:00
Jonathan Miller c0ee2608f1 feat: Akeeba Backup Pro settings importer with auto-disable
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Import Akeeba profiles, filters, remote storage settings, and backup
history into MokoJoomBackup. After successful import, Akeeba plugins
and scheduled tasks are automatically disabled.

- AkeebaImporter: reads #__ak_profiles and #__ak_stats tables
- Parses both INI-format and JSON-format Akeeba configuration
- Maps backup types (dbonly→database, filesonly→files)
- Maps remote storage (ftp, googledrive) with credential transfer
- Parses Akeeba filter format (per-root, nested) to newline lists
- Imports backup history with profile ID remapping
- "Import from Akeeba" button auto-detected in Profiles view toolbar
- Disables Akeeba plugins + scheduled tasks (does NOT uninstall)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 15:48:31 -05:00
Jonathan Miller 5e5d79327b feat: AJAX step-based backup engine for shared hosting
On shared hosting where max_execution_time cannot be overridden,
backups now run as a series of small AJAX requests. Each request
does one unit of work (dump one table, add one batch of files)
and returns within the time limit.

- SteppedBackupEngine: orchestrates init → database → files →
  finalize → upload → complete phases
- SteppedSession: persists state between requests via temp JSON files
  with automatic cleanup of stale sessions (24h)
- AjaxController: handles init and step requests with CSRF protection
- Admin UI: progress bar modal with real-time phase and percentage
  updates, auto-reloads on completion
- Steps: 1 table per DB step, 200 files per file step (configurable)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 15:37:38 -05:00
Jonathan Miller 5502c19a5d feat: add restore engine and Kickstart self-extracting archives
- Add RestoreEngine: extract ZIP, restore files, import DB, preserve
  configuration.php, clean up staging directory
- Add FileRestorer: recursive file copy with protected file handling
  (skips configuration.php, .htaccess at root level)
- Add DatabaseImporter: streaming line-by-line SQL execution with
  comment/multiline handling and error tolerance
- Add Kickstart: standalone restore.php generator with web UI for
  restoring on blank servers (like Akeeba Kickstart Pro)
  - Pre-flight checks (PHP version, zip ext, writable)
  - Step-by-step: extract, import DB, update config, cleanup
  - Dark theme UI, CSRF protection, no dependencies
- Add "Include Restore Script" toggle per profile — wraps backup as
  outer.zip containing restore.php + site-backup.zip
- Add restore button to admin backups toolbar
- Fix innerHTML XSS risk (use DOM methods instead)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 14:58:21 -05:00
Jonathan Miller 4a159bab39 feat: implement FTP and Google Drive remote uploaders
- Add RemoteUploaderInterface for pluggable storage backends
- Add FtpUploader: FTP/FTPS with passive mode, SSL, recursive dir
  creation, and post-upload size verification
- Add GoogleDriveUploader: OAuth2 refresh token auth, resumable upload
  API with 5 MB chunking for reliable large-file transfers
- Wire uploaders into BackupEngine Step 3: after ZIP creation, upload
  to configured remote, optionally delete local copy
- No SDK dependencies — pure PHP with cURL for Google Drive

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 14:03:46 -05:00
Jonathan Miller 201a281e3a feat: add scheduled tasks, individual fields, remote storage
- Add plg_task_mokobackup: Joomla Scheduled Tasks integration so each
  backup profile can run on its own schedule (like Akeeba Backup Pro)
- Replace JSON config/filters with individual form fields and DB columns
- Add FTP/FTPS and Google Drive remote storage options per profile
- Add archive settings tab (format, compression, split size, backup dir)
- Add exclusion filter fields (dirs, files, tables) as newline-separated
  textareas instead of raw JSON

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 13:58:50 -05:00
Jonathan Miller b82c1f8a24 feat: initial MokoJoomBackup package — Akeeba Backup Pro replacement
Full-site backup and restore for Joomla with three sub-extensions:
- com_mokobackup: Admin component with backup engine, profiles, and records
- plg_system_mokobackup: Auto-cleanup of expired backups
- plg_webservices_mokobackup: REST API wire-compatible with mcp_mokobackup

Backup engine supports full/database/files modes with step-based execution,
file/directory/table exclusion filters, and CLI script for cron use.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 13:47:36 -05:00