deploy-runner.sh was rsyncing panel/public/ but VERSION lives at repo
root — web root /srv/novacpx/public/VERSION was perpetually stale.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Settings page now loads current values from DB and saves via save-option API
- check-novacpx-update reads update_channel setting, checks origin/main or origin/beta
- apply-novacpx-update pulls from channel branch, fixes backup dir (/tmp), fixes SQLite migration syntax, records new version in novacpx_version table + settings.panel_version
- deploy-runner.sh reads update_channel from DB, pulls correct branch, records version after deploy
- webhook.php accepts pushes to both main and beta branches
- Updates page shows channel badge and latest remote version
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switches migration tracking from MySQL to SQLite (panel.db), reads DB path
from config.ini with fallback to /var/lib/novacpx/panel.db. Re-creates the
webhook symlink after each rsync deploy so it survives --delete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- novacpx-webserver-switch: new helper script that manages ports 80/443
only; panel ports 8880-8883 are never touched
- system.php: save-option web_server now calls the helper script instead
of stopping all web servers (which killed the panel)
- admin.js: server options shows live Apache/Nginx status badges and notes
that the panel always runs on Apache
- Notifier.php + test-notify: use plain email address in 'from' field
(CyberMail rejects "Name <email>" format)
- deploy-runner.sh: rsync panel/api/ and panel/lib/ to web root after
panel/public/ sync; also syncs panel/bin/ to /opt/novacpx/bin/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- firewall.php: auto-detect server IPs (loopback, all interface IPs,
private /24 subnets) for Fail2Ban ignoreip; f2b-ignoreip-list/add/
remove/reset actions; write to jail.local directly (www-data owns it);
f2b_set_ignoreip() reloads fail2ban after every change
- auth.php: log failed logins to /var/log/novacpx/access.log in format
fail2ban filters expect — "FAILED LOGIN from <IP> [portal]"
- deploy/fail2ban/: filter.d conf files for all 4 NovaCPX jails
- install.sh: auto-detect local IPs → ignoreip in jail.local; install
filter files; create access.log (www-data:www-data 664)
- admin.js: Fail2Ban Whitelist section in firewall page — chip list with
add/remove/reset; loopback shown with lock icon and non-removable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>