Custom DaisyUI theme using the provided color palette:
- Primary: dark blue rgb(5,61,142)
- Secondary/Error: orange rgb(238,118,45)
- Accent/Warning: yellow rgb(254,204,0)
- Info: teal rgb(90,168,189)
- Neutral: darker blue rgb(2,44,105)
- Base: white/gray
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace raw cron entries with descriptions like "Every hour, to rasp"
or "Daily at 02:00, all remotes". Add cron_to_human() to Cron.pm.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WHM CSS adds margin to checked radio inputs, causing the active
button in join groups to shift down. Added m-0 class to all
join-item radio buttons to override.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline style with Tailwind inline-flex items-stretch classes
on join button groups. Rebuild CSS with new safelist entries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WHM CSS causes the active/checked button in DaisyUI join groups
to shift down. Added inline display:inline-flex;align-items:stretch
to all join containers in remotes.cgi and restore.cgi.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The forked child stayed in the CGI's process group and got killed
when Apache cleaned up the CGI process. Now uses double-fork with
POSIX::setsid() to fully daemonize the backup process.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
gniza backup requires /etc/gniza/gniza.conf to exist. The WHM plugin
only created remote configs in remotes.d/ but not the main config,
causing "Config file not found" errors. Now creates it with defaults
when adding a remote if it doesn't exist.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a "Run Now" button in each schedule's Actions column that
triggers the backup in the background, logging to the same cron
log file. Forks the process and redirects immediately.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
When adding a remote via WHM, create the base directory structure
on the remote server (matching gniza init remote CLI behavior).
Creates $REMOTE_BASE/<hostname>/accounts/ via SSH mkdir or rclone mkdir.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read-only log viewer with file list (sorted by mtime), per-file viewer
with level-based coloring (ERROR/WARN/INFO/DEBUG), level filter buttons,
cron log truncation (last 500 lines default), and path traversal protection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Setup wizard step 1 (SSH key) stays as-is, then redirects to
remotes.cgi?action=add&wizard=1 and schedules.cgi?action=add&wizard=1
instead of reimplementing its own forms.
- Remove ~200 lines of duplicated form/handler code from setup.cgi
- Wizard gets full feature parity (S3/GDrive, password auth, etc.)
- key_path pre-fills REMOTE_KEY, remote_name pre-fills REMOTES
- wizard=1 flag chains the flow: remote add → schedule add → index
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The setup wizard is SSH-only but was missing the REMOTE_TYPE field,
causing validation to fail with "must be ssh, s3, or gdrive".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a dedicated alert area div below the action buttons. Alerts
render in normal document flow with proper padding and styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Append alert to the data-theme container instead of document.body
so it stays within the gniza content frame. Use position:absolute
relative to the container.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WHM's CSS overrides inline styles on positioned elements. Inject a
style tag with !important rules targeting #gniza-alert to ensure
fixed positioning, padding, and sizing are applied correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove previous alert before showing new one to prevent stacking.
Add inline padding, border-radius, and font-size since WHM CSS
overrides DaisyUI alert defaults.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove previous toast before showing new one to prevent stacking.
Position bottom-right with padding, rounded corners, and proper
font size for a clean toast appearance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SSH stderr can contain \r and other control characters that break
JSON parsing. Strip all control chars after escaping known ones.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>