Commit Graph

170 Commits

Author SHA1 Message Date
shuki
05db1f2340 Fix restore: use whmapi1 removeacct instead of /scripts/removeacct
The /scripts/removeacct script was failing with "You do not have
permission to remove that account" even when running as root. Switch
to whmapi1 removeacct which uses the WHM API with proper root
authentication context. Also check the whmapi1 result field since
whmapi1 returns exit code 0 even on logical failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 03:36:28 +02:00
shuki
3b5488f0d7 Fix restore: correct removeacct argument order, add debug output
cPanel's removeacct expects username before flags. Also capture and
log the command output to aid debugging if termination still fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 03:33:31 +02:00
shuki
6779db023a Fix restore: remove invalid --skipbw flag from removeacct
The /scripts/removeacct command only accepts --force and --keepdns.
The --skipbw flag is not a valid option and was causing account
termination to fail during full account restore with terminate enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 03:28:39 +02:00
shuki
4408917aec Redesign cPanel restore plugin to match WHM workflow
Replace the 8-card category grid with a unified restore workflow:
- index.live.cgi: now serves as Step 1 (remote + snapshot selection)
- restore.live.cgi: Step 2 (Full Account/Selective mode toggle with
  type checkboxes, exclude paths, file browser), Step 3 (multi-type
  confirmation), Step 4 (multi-type execution via AdminBin)

Also update cPanel plugin icon from gniza.svg source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 03:13:53 +02:00
shuki
9dc427a1e6 Fix AdminBin: use get_caller_username() instead of REMOTE_USER
AdminBin modules run as root, so $ENV{'REMOTE_USER'} is not set.
The correct way to get the authenticated cPanel user is via the
parent class method get_caller_username().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:31:50 +02:00
shuki
8822f93438 Fix JS syntax errors: convert qq{} to heredocs in restore.live.cgi
Perl's qq{} delimiter matches balanced braces, which conflicted with
JavaScript curly braces, producing empty function bodies. Converted
_print_step1_js and _print_step2_js to heredoc blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:16:58 +02:00
shuki
d26a327595 Add cPanel chrome (sidebar/topbar) to plugin pages
Use $cpanel->header() and $cpanel->footer() from LiveAPI to wrap
plugin content in cPanel's standard layout with sidebar navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:08:56 +02:00
shuki
97eb3ff2ed Remove Content-Type header from index.live.cgi
cPanel's live engine provides the HTTP headers and page chrome
(sidebar, topbar). CGI should not output its own Content-Type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:04:00 +02:00
shuki
c672c9d8ee Fix AdminBin: move run() after variable declarations
__PACKAGE__->run() was called before my variables were declared,
so $MAIN_CONFIG and $REMOTES_DIR were undef when action methods ran.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:01:28 +02:00
shuki
af46c76e62 Fix LIVEAPI error: initialize Cpanel::LiveAPI in .live.cgi files
cPanel's live engine requires .live.cgi files to create a
Cpanel::LiveAPI connection. Without it, the engine cannot
establish communication with the CGI subprocess.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:59:53 +02:00
shuki
065f83d691 Fix AdminBin: add shebang and __PACKAGE__->run()
cPanel's adminbin framework requires the module to be directly
executable with a shebang line, and Script::Call modules need
__PACKAGE__->run() to bootstrap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:57:56 +02:00
shuki
3b6d9ea88f Fix AdminBin compilation: declare $in/$out before open3
Variables declared with 'my' inside open3() were scoped to that call,
causing 'Global symbol requires explicit package name' errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:52:19 +02:00
shuki
a769281e88 Rename cPanel plugin to GNIZA Backups
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:49:53 +02:00
shuki
0aa5e26a02 Fix cPanel icon: use 48x48 PNG for sprite compatibility
The SVG had negative coordinates that rendered off-screen in cPanel's
sprite sheet. Export to clean 48x48 PNG (2.8KB) instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:48:14 +02:00
shuki
7e5fd16a3c Add rebuild_sprites after cPanel plugin install
cPanel requires sprite rebuild for new icons to appear in the interface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:43:22 +02:00
shuki
70ef4d3bcd Use gniza SVG icon for cPanel plugin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:40:22 +02:00
shuki
c1555da3c7 Use gniza backup PNG icon for cPanel plugin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:52:59 +02:00
shuki
66e9cb9def Revert cPanel icon to original gniza-logo.svg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:50:55 +02:00
shuki
5bb85c35ef Fix cPanel icon: replace headphones with backup/restore icon
Server box with data rows (navy) and circular restore arrow (copper)
matching gniza brand colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:42:42 +02:00
shuki
f297d40a85 Add lightweight cPanel icon and update plugin registration
Replace 378KB VTracer-traced logo with a clean 1KB 48x48 SVG icon
for cPanel's icon system. Update install.json, install.sh, and
uninstall.sh to reference the new icon. Also update README with
skip-suspended flag and schedule config fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:40:57 +02:00
shuki
894c918d32 Document correct cPanel install.json format with required fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:34:58 +02:00
shuki
a87ca4a823 Fix cPanel plugin registration: correct install.json format and include icon
- install.json: use cPanel's required fields (type, id, group_id, uri)
  instead of incorrect keys (target_type, category, url)
- Include icon SVG in tar.gz archive (install_plugin validates icon exists)
- Without correct fields, install_plugin silently skipped registration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:34:43 +02:00
shuki
c05a0293b0 Comprehensive documentation update for cPanel plugin, install scripts, and security
- Expand cPanel User Restore Plugin section with restore categories table,
  CGI naming convention, AdminBin validation patterns, and registration details
- Add detailed GnizaCPanel::UI function reference including safe I/O functions
- Expand AdminBin Module section with validation regex table and remote filtering
- Reorganize Security section into CLI, WHM, and cPanel subsections
- Add Install/Uninstall Scripts section documenting all steps and tar.gz quirk
- Add Upgrade Considerations section (CSRF file→dir migration, token write
  robustness, SMTP test token sync)
- Add "Adding a new cPanel plugin page" guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:17:45 +02:00
shuki
a779d861a6 Fix CSRF upgrade path: remove stale file before creating directory
Old versions stored CSRF/flash as plain files at the directory path.
New code expects directories. _ensure_dir now removes conflicting
plain files left by older versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:14:33 +02:00
shuki
cc7e46a88f Fix CSRF token write failure and SMTP test token sync
- Add fallback write when O_EXCL _safe_write fails for CSRF tokens
  (ensures token is always persisted to disk)
- Update SMTP test JS to sync new CSRF token into main form hidden field
  (prevents stale token after SMTP test consumes the original)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:09:24 +02:00
shuki
7802d7ebe0 Fix uninstall_plugin to use tar.gz archive like install_plugin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:05:04 +02:00
shuki
1dccbce6d0 Fix cPanel plugin install: copy install.json to target dir and use tar.gz archive
install_plugin requires a tar.gz archive, not a raw JSON file. Also copies
install.json to the plugin directory so uninstall_plugin can reference it.
Includes CLAUDE.md documentation updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 00:02:27 +02:00
shuki
1f68ea1058 Security hardening, static analysis fixes, and expanded test coverage
- Fix CRITICAL: safe config parser replacing shell source, sshpass -e,
  CSRF with /dev/urandom, symlink-safe file I/O
- Fix HIGH: input validation for timestamps/accounts, path traversal
  prevention in Runner.pm, AJAX CSRF on all endpoints
- Fix MEDIUM: umask 077, chmod 700 on config dirs, Config.pm TOCTOU lock,
  rsync exit code capture bug, RSYNC_EXTRA_OPTS character validation
- ShellCheck: fix word-splitting in notify.sh, safe rm in pkgacct.sh,
  suppress cross-file SC2034 false positives
- Perl::Critic: return undef→bare return, return (sort), unpack @_,
  explicit return on void subs, rename Config::write→save
- Remove dead code: enforce_retention_all(), rsync_dry_run()
- Add require_cmd checks for rsync/ssh/hostname/gzip at startup
- Escape $hint/$tip in CGI helper functions for defense-in-depth
- Expand tests from 17→40: validate_timestamp, validate_account_name,
  _safe_source_config (including malicious input), numeric validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:57:26 +02:00
shuki
b16893086d Add terminate-before-restore toggle, logo, and installer improvements
- Add "Terminate First" toggle to restore page (UI, Runner, CLI, lib)
- When enabled, removes existing cPanel account before restoring
- Add GNIZA Backup SVG logo to WHM plugin header (inline base64)
- Copy uninstall.sh to /usr/local/gniza/ during installation
- Update CLAUDE.md with new restore params and Runner options

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:43:48 +02:00
shuki
b8858bcbc8 Remove restore strategy (merge/terminate) from all layers
Restores now always merge into existing accounts (--force). The
terminate-and-recreate option is removed from CLI, restore library,
Runner allowlist, and WHM UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:47:28 +02:00
shuki
ee2a0100f6 Remove Restore Strategy toggle from restore page
Always defaults to merge (overwrite) strategy. The terminate & re-create
option is removed from the UI to simplify the restore workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:45:43 +02:00
shuki
8dcd3aaca7 Add info tooltips to form fields across remotes, settings, and restore pages
Adds ⓘ tooltip icons with contextual help text to technical fields:
- remotes.cgi: SSH key, S3 endpoint, GDrive service account/folder ID,
  base dir, bandwidth limit, rsync options, retention count
- settings.cgi: working dir, log retention, include/exclude accounts,
  lock file, SSH timeout/retries, rsync options
- restore.cgi: restore mode, restore strategy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:28:57 +02:00
shuki
5b19d5d29e Fix empty retention count display on remotes list page
Fall back to default '30' when RETENTION_COUNT is set to empty string,
not just when the key is missing from the config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:26:29 +02:00
shuki
afff4ef091 Change remote selection from checkboxes to toggles in schedule form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:25:50 +02:00
shuki
2a646e52f8 Fix tooltip icon wrapping and position on schedule option toggles
Widen label to w-52 with whitespace-nowrap to prevent the info icon
from wrapping to a new line. Change tooltip position from right to top.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:24:17 +02:00
shuki
51ae90e221 Add circled question mark icons for tooltip triggers on schedule options
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:22:03 +02:00
shuki
60b7c6d9cb Replace description paragraphs with tooltips on schedule option toggles
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:18:15 +02:00
shuki
ffb27d5bf7 Merge system backup and skip suspended toggles into single Options card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:17:22 +02:00
shuki
bea3ff05cb Add exclude paths for restore and skip-suspended/schedule enhancements
- Add --exclude flag to restore account/files commands to skip specific
  paths during homedir restoration (rsync --exclude / rclone --exclude)
- Add exclude paths UI in WHM restore form (step 2 tag input + modal,
  step 3 summary, step 4 command building)
- Add rclone_from_remote_filtered() for passing extra args to rclone copy
- Add _build_exclude_args() helper in restore.sh
- Add exclude pattern to Runner.pm allowlist
- Add skip-suspended flag and schedule configuration enhancements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:10:33 +02:00
shuki
0eb480489e Add per-schedule toggle to skip suspended cPanel accounts
Adds SKIP_SUSPENDED config key and --skip-suspended CLI flag that
excludes suspended accounts (detected via /var/cpanel/suspended/)
from backups. Follows the same pattern as the existing SYSBACKUP
toggle across all layers: config, schedule loader, cron builder,
CLI flag parsing, and WHM UI (table toggle, AJAX handler, form card).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:10:18 +02:00
shuki
7393412b20 Fix button vertical alignment on restore page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:09:30 +02:00
shuki
7083efcc05 Add background job execution for restore and live status dashboard
- Runner.pm: extract _validate()/_build_cmd_line(), add run_async() that
  forks a detached child via setsid() to run commands in background
- restore.cgi: handle_step4() builds commands array and uses run_async()
  instead of blocking synchronous execution, redirects to logs.cgi
- logs.cgi: add auto-refresh JS (10s list view, 5s file view with
  auto-scroll) that polls index.cgi?action=status while gniza is running
- index.cgi: add live status card with AJAX polling and JSON endpoint
- Cron/schedule: redirect cron output to /dev/null (gniza has own logs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:07:09 +02:00
shuki
6a2986c505 Show SSH Key Setup accordion on edit remote too
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:06:02 +02:00
shuki
c602df43f6 Convert SSH Key Setup to collapsed accordion
Uses DaisyUI collapse component so the SSH guidance is hidden
by default and expandable on click.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:04:26 +02:00
shuki
ade44dfff4 Align button rows with items-center to fix vertical misalignment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:01:02 +02:00
shuki
35eac96f25 Change all Cancel/Back buttons from btn-ghost to btn-info
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:59:18 +02:00
shuki
6511715b2b Add Sys Backup toggle column to schedules list
Adds a "Sys Backup" column with an AJAX toggle in the schedules
table. Toggling it updates SYSBACKUP in the schedule config and
reinstalls the cron entry to include/remove --sysbackup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:49:48 +02:00
shuki
543b38bd53 Add 'gniza schedule run <name>' command
Runs a schedule's backup immediately with the correct --remote and
--sysbackup flags from the schedule config. Also fixes WHM Run Now
button to include --sysbackup when enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:46:26 +02:00
shuki
e0982fe7a1 Add --sysbackup flag to Cron.pm cron line builder
Cron.pm's install_schedule() had its own cron line builder that
didn't include --sysbackup. Now it checks SYSBACKUP=yes in the
schedule config and appends --sysbackup to the cron command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:38:46 +02:00
shuki
0da580666c Always reinstall cron when saving a schedule
Previously the cron was only updated if it was already active.
Now every save reinstalls the cron entry so changes (like enabling
--sysbackup) take effect immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:36:20 +02:00