Commit Graph

15 Commits

Author SHA1 Message Date
Jonathan Miller b785b0e748 feat: add .htaccess reset option to MokoRestore
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 19s
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 / 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
Add checkbox in Step 4 to reset .htaccess to Joomla defaults.
Backs up existing as .htaccess.bak before overwriting. Optional
and unchecked by default to preserve custom rules.
2026-06-14 21:22:45 -05:00
Jonathan Miller 3a6354e648 refactor: store config as .bak, rebuild on restore
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 3s
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
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 18s
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 / 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
Instead of storing a sanitized configuration.php in the archive,
save it as configuration.php.bak with credentials stripped. No
configuration.php exists in the archive — it's rebuilt from the
.bak template + user-provided credentials during restore.

Backup side:
- configuration.php stored as configuration.php.bak (sanitized)
- No configuration.php in the archive (prevents accidental use)

MokoRestore side:
- Reads .bak as base template (preserves non-sensitive settings:
  debug, cache, SEF, editor, timezone, etc.)
- Replaces all sanitized fields with user input
- Clears proxy/Redis/TLS placeholders to empty strings
- Deletes .bak after successful rebuild
- Falls back to configuration.php for legacy backups

FileRestorer:
- Added configuration.php.bak to skip list
2026-06-14 15:30:17 -05:00
Jonathan Miller c96444fe80 feat: add SMTP fields to MokoRestore config step
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 4s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
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
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
Since configuration.php is now sanitized in backups, MokoRestore
needs UI fields for the stripped SMTP credentials. Adds:

- SMTP Host, User, Password fields in Step 4 (Site Configuration)
- Clean card-based layout with General and Mail sections
- Only replaces SMTP values if provided (blank = leave existing)
- Pre-fills SMTP fields from extracted config (if not sanitized)
- Expanded info banner explaining secret key regeneration
2026-06-14 15:25:58 -05:00
Jonathan Miller 2ff76263ff fix: recompute checksum after MokoRestore wrapping
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 7s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 23s
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 / 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
The SHA-256 checksum was computed before the MokoRestore wrap step,
then the archive was replaced with the wrapped version without
recomputing the hash. This left the checksum column empty or stale
for MokoRestore-wrapped backups.
2026-06-14 15:07:18 -05:00
Jonathan Miller 2f490c3208 feat: sanitize configuration.php in backups
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 4s
Joomla: Extension CI / Release Readiness Check (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 7s
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 8s
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 / 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
Strip sensitive credentials from configuration.php before adding it
to the backup archive. Replaced fields use [SANITIZED:field] placeholders:
- Database: host, user, password, db
- Security: secret
- SMTP: smtpuser, smtppass, smtphost
- Proxy: proxy_user, proxy_pass
- Redis: redis_server_auth, session_redis_server_auth
- DB TLS: dbsslkey, dbsslcert, dbsslca

Non-sensitive fields (sitename, debug, cache, SEF, paths, etc.)
are preserved as-is for inspection and partial restores.

MokoRestore detects sanitized placeholders and leaves those form
fields blank so the user must enter fresh credentials (like the
Joomla installer). In-Joomla restore is unaffected because
RestoreEngine preserves the current site's configuration.php.

Applied to both BackupEngine (synchronous) and SteppedBackupEngine
(AJAX-based) code paths.
2026-06-14 14:42:54 -05:00
Jonathan Miller c381829fc5 fix: ACL review — missing checks, HTTP status codes, memory safety
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 3s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 20s
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 / 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
- Add ACL check (core.manage) to verify() — was completely unguarded
- Add checkToken('get') to download() for CSRF protection
- Wrap all setMessage() calls in Text::_() for proper translation
- Add HTTP 403 status to all AJAX token/ACL denial responses
- Add $status param to sendJson() helper
- Wrap viewLog() DB query in try-catch, return JSON error on failure
- Fix viewLog() file_get_contents to detect read errors vs missing
- Replace API download() file_get_contents + base64 with streaming
  readfile() to prevent memory exhaustion on large backups
- Gate backup profile selector in template behind backup.run permission
2026-06-13 07:42:23 -05:00
Jonathan Miller ff5f0108b9 feat: wire up ACL permission checks across all controllers and views
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 3s
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 6s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 20s
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 / 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
Enforce granular permissions defined in access.xml:

Controllers (server-side enforcement):
- BackupsController: start() → backup.run, download() → backup.download,
  restore() → backup.restore
- AjaxController: init()/step() → backup.run, browseDir()/viewLog() →
  core.manage
- API BackupsController: backup() → backup.run, download() →
  backup.download, profiles() → core.manage
- ProfilesController: importAkeeba() → core.create

Views (toolbar button visibility):
- Backups: conditionally show Start, Restore, Delete, Preferences
- Profiles: conditionally show Add, Edit, Import, Delete, Preferences
- Profile edit: conditionally show Save/Apply based on create/edit

Templates:
- Backups list: hide download button when backup.download denied
2026-06-13 07:23:57 -05:00
Jonathan Miller eb0b41101b fix: add user-facing warnings for remaining silent failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 11s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 12s
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 8s
Universal: PR Check / Validate PR (pull_request) Failing after 31s
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 / 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
- preflight_saveKey: warn user if license key could not be preserved
- createDefaultScheduledTask: warn user to create task manually
- migrateDefaultBackupDir: warn user to review profile settings
- createBackupDirectory: warn if .htaccess protection file fails
- boot(): widen catch to \Exception for consistency
2026-06-13 06:31:13 -05:00
Jonathan Miller 5393180eb9 fix: address PR review — error handling, security, code quality
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 7s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 12s
Universal: Auto Version Bump / Version Bump (push) Successful in 15s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 7s
Universal: PR Check / Validate PR (pull_request) Failing after 26s
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 / 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
- Move uninstall guard to top of postflight()
- Refactor plugin enables into loop with per-plugin try-catch
- Replace @mkdir with createBackupDirectory() — check result, warn
  user, add .htaccess + index.html protection
- Merge menu_icon into existing params instead of overwriting
- Add HtmlDocument type check in boot(), narrow catch to RuntimeException
- Add Joomla version check in preflight()
- Add error_log on missing parent/component in ensureSubmenuItems()
- Rename warnDefaultBackupDir → migrateDefaultBackupDir
- Narrow all \Throwable catches to \Exception
- Warn user on restoreDownloadKey failure via enqueueMessage
- Use null-safe operator for getIdentity()?->id
- Remove orphaned docblock, fix ensureSubmenuItems docblock
- Tighten syncMenuIcons LIKE pattern
2026-06-12 19:22:16 -05:00
Jonathan Miller 7ba0468907 fix: submenu icons not rendering in Joomla 6
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 15s
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
The CSS selector #menu doesn't exist in Joomla 6 — mod_menu uses
id="menu{moduleId}" (dynamic). Switch to .main-nav class selector
which is stable across Joomla 4/5/6. Also use margin-inline-end
for RTL support.
2026-06-11 22:14:56 -05:00
Jonathan Miller 2a9443601e fix: [DEFAULT_DIR] resolves to JPATH_ROOT/backups, shown as placeholder
- getDefaultAbsolute() now returns JPATH_ROOT/backups instead of
  the old admin component directory
- SQL default, form default, and install migration all use [DEFAULT_DIR]
- portablize() converts ./backups and old literal paths back to [DEFAULT_DIR]
- Users see [DEFAULT_DIR] in the field, resolved path shown in status
2026-06-11 15:27:17 -05:00
Jonathan Miller 5c697b9eeb fix: pretty names for all sub-extensions, default backup dir to ./backups
- Component: MokoSuiteBackup
- Plugins: System/Task/Console/Content/QuickIcon/ActionLog/WebServices - MokoSuiteBackup
- Default backup_dir changed to ./backups (relative to site root)
- Auto-migrate old defaults on upgrade
2026-06-11 12:48:11 -05:00
Jonathan Miller 49f3d9fdcf feat: change default backup dir to ../backups (outside web root)
- Default backup_dir is now ../backups (relative to JPATH_ROOT),
  which resolves outside public_html on most hosting setups
- Added BackupDirectory::normalizePath() to resolve ../ segments
  without requiring the path to exist on disk
- Added BackupDirectory::portablize() to auto-detect absolute paths
  and replace them with portable placeholders ([HOME], ../backups)
- ProfileTable::check() auto-normalizes backup_dir on save
- Install postflight auto-migrates old in-webroot defaults to ../backups
- Dashboard warning now checks resolved path instead of string matching
- .htaccess protection only applied when directory is inside web root
2026-06-11 12:39:59 -05:00
Jonathan Miller e8b40d9389 fix: resolve relative paths in folder browser, add placeholders help modal
- browseDir() now resolves paths via BackupDirectory::resolve() before
  permission check, fixing "access denied" when browsing from [DEFAULT_DIR]
- SQL default for backup_dir changed to [DEFAULT_DIR] placeholder
- Added help button (?) next to Browse that opens a modal listing all
  available placeholders with examples and recommended paths
2026-06-11 12:30:23 -05:00
Jonathan Miller ace33b60fe feat: rename mokojoombackup → mokosuitebackup, add [HOME] placeholder for backup directory
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
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
Renames all sub-extensions from mokojoombackup to mokosuitebackup
(package, component, 7 plugins, language files, manifests).

Adds [HOME] placeholder to BackupDirectory and PlaceholderResolver
so users can set backup_dir to [HOME]/backups (outside web root).
Fixes folder browser "access denied" on PHP-FPM shared hosting
where getenv('HOME') returns empty by adding POSIX and JPATH_ROOT
fallback detection.
2026-06-11 12:24:27 -05:00