19 Commits

Author SHA1 Message Date
shuki
a162536585 Rename product from gniza to gniza4cp across entire codebase
- CLI binary: bin/gniza -> bin/gniza4cp
- Install path: /usr/local/gniza4cp/
- Config path: /etc/gniza4cp/
- Log path: /var/log/gniza4cp/
- WHM plugin: gniza4cp-whm/
- cPanel plugin: cpanel/gniza4cp/
- AdminBin: Gniza4cp::Restore
- Perl modules: Gniza4cpWHM::*, Gniza4cpCPanel::*
- DaisyUI theme: gniza4cp
- All internal references, branding, paths updated
- Git remote updated to gniza4cp repo
2026-03-05 21:03:30 +02:00
shuki
a5ab2c788a Remove legacy gniza init CLI command
The WHM setup wizard handles all configuration (SSH, S3, GDrive),
making the interactive CLI init wizard redundant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:00:26 +02:00
shuki
efcd4844e9 Only write debug messages to log file when LOG_LEVEL=debug
Info, warn, and error always go to the log file. Debug messages
are only written to the file when LOG_LEVEL is set to debug,
preventing verbose output in logs at higher levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:57:35 +02:00
shuki
2cf0a8866c Always write all log levels to file, only filter console output
LOG_LEVEL was gating both file and console output, causing empty
log files when set to error/warn. Now the log file always captures
everything while LOG_LEVEL only controls stderr verbosity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:55:55 +02:00
shuki
0fb640d585 Use d/m/Y H:i:s date format for all user-facing timestamps
Update log lines, email notifications, generated config comments,
and WHM logs page. Structural dates (filenames, snapshot dirs,
.complete markers) are unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 07:35:49 +02:00
shuki
bf6624b607 Add daily stats collection cron job at 05:00 UTC
The gniza stats command is now automatically scheduled when
install_schedules() runs, tagged as # gniza:_stats so it is
managed alongside backup schedules (installed/removed together).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 05:33:55 +02:00
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
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
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
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
3547b00ead Add sysbackup/sysrestore CLI commands and schedule integration
- Add lib/sysbackup.sh and lib/sysrestore.sh for system-level
  backup and restore of WHM/cPanel config, packages, and cron jobs
- Wire cmd_sysbackup and cmd_sysrestore into bin/gniza
- Add --sysbackup flag to cmd_backup: runs system backup after all
  account backups complete
- Add SYSBACKUP schedule config key so cron jobs can include
  --sysbackup automatically via build_cron_line()
- Add "Include system backup" toggle to WHM schedule form
- Revert sysbackup toggle from remotes.cgi (belongs in schedules)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:30:10 +02:00
shuki
f881a80557 Fix unbound variable error in _save_remote_globals
REMOTE_HOST, REMOTE_PORT, REMOTE_USER, REMOTE_BASE, BWLIMIT,
RETENTION_COUNT, and RSYNC_EXTRA_OPTS were referenced without
defaults in _save_remote_globals(), causing "unbound variable"
errors under set -u when called before any remote was loaded
(e.g., gniza remote list).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 04:48:00 +02:00
shuki
fac7dc6c80 Add SMTP notification support with WHM settings UI
Send email via curl SMTP when SMTP_HOST is configured, falling back
to system mail/sendmail when empty. NOTIFY_EMAIL now accepts
comma-separated addresses. WHM Settings page gets an SMTP card
with Send Test Email button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 03:46:47 +02:00
shuki
1459bd1b8b Initial commit: gniza backup & disaster recovery CLI + WHM plugin
Full-featured cPanel backup tool with SSH, S3, and Google Drive support.
Includes WHM plugin with Tailwind/DaisyUI UI, multi-remote management,
decoupled schedules, and account restore workflows.

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