--- name: project-novacpx-todo description: NovaCPX numbered TODO list β€” reference by number when requesting work metadata: node_type: memory type: project originSessionId: c454fc50-f93d-4ddd-b9f3-f3f442e89fb9 --- NovaCPX pre-production TODO. Reference items by number (e.g. "work on #3"). ## πŸ”΄ CRITICAL β€” Blocking for any real use **#1 β€” Auto-deploy pipeline on VM** βœ… DONE Webhook at https://10.48.200.110:8882/deploy/webhook.php. GitHub webhook fires on push to main or beta. Deploy-runner.sh cron every minute processes queue. Accepts both main+beta branches; reads update_channel from DB to pull correct branch. **#2 β€” Sessions table in schema** βœ… DONE Confirmed sessions table exists. Also added settings and api_tokens tables. **#3 β€” End-to-end account creation test** βœ… DONE Fixed: systemd ProtectSystem=full blocked /etc writes. Fixed: sudo mkdir/chown needed for home dir setup. All working: Linux user + home dir + public_html + vhost + DNS zone + Apache serving. **#4 β€” Mail server virtual domain config** βœ… DONE vmail user + /var/mail/vhosts. Postfix + Dovecot fully wired. **#5 β€” DNS zone files working** βœ… DONE named running, dig @localhost verified, AppArmor allows reads. **#6 β€” Let's Encrypt SSL tested live** βœ… DONE (infrastructure verified) Certbot 2.9.0 installed. Will work with real public domains. --- ## 🟑 IMPORTANT β€” Needed before real traffic **#9 β€” Password change** βœ… DONE **#10 β€” Webmail SSO** βœ… DONE **#11 β€” DKIM provisioning** βœ… DONE **#12 β€” File manager security audit** βœ… DONE **#13 β€” PHP syntax guard on admin.js load** βœ… DONE **#7 β€” User/reseller panel pages connected to real data** βœ… DONE **#8 β€” Reseller account isolation audit** βœ… DONE --- ## 🟠 FEATURES β€” Expected in beta **#14 β€” WordPress Manager** βœ… DONE (backend + admin UI) **#15 β€” Backup system** βœ… DONE **#16 β€” Cloudflare API integration** βœ… DONE **#17 β€” Two-factor auth (TOTP)** βœ… DONE **#18 β€” Reseller white-label** βœ… DONE reseller_branding table, branding.php endpoint, _branding.php server-side helper. **#19 β€” Server monitoring charts** βœ… DONE server_stats table + collect-stats.php cron (every 5 min). Chart.js lazy-loaded. **#20 β€” Cron job manager (user panel)** βœ… DONE **#21 β€” Package limits enforcement** βœ… DONE **#22a β€” Multiple FTP server options** βœ… DONE **#22b β€” WHMCS billing bridge** βœ… DONE **#22c β€” Multiple mail server options** βœ… DONE **#22d β€” Multiple web server options** βœ… DONE **#22e β€” DNS options + NS health checker** βœ… DONE --- ## πŸ”΅ POLISH β€” Pre-production **#23 β€” Documentation** βœ… DONE **#24 β€” Audit log UI** βœ… DONE **#25 β€” Email notifications** βœ… DONE **#26 β€” Mobile-responsive CSS pass** βœ… DONE **#27 β€” Custom error pages** βœ… DONE **#28 β€” API rate limiting middleware** βœ… DONE **#29 β€” Session management UI** βœ… DONE **#30 β€” Installer idempotency** βœ… DONE --- ## 🐳 DOCKER β€” Tiered container management **#31-35 β€” Docker Engine + admin/reseller/user panels** βœ… DONE DockerManager.php. **140-app catalog** across 15+ categories. "My Apps" tab backed by docker_compose_stacks (not docker_containers). Async background launch with nohup. Email domain dropdown (local-part + domain select from DB). **Docker catalog history:** - Initial: 9 apps (wordpress, ghost, nextcloud, gitea, matomo, vaultwarden, nodejs, flask, static) - 2026-06-09: Expanded to 60 apps (added monitoring, wiki, messaging, security, business, design categories) - 2026-06-10: Expanded to 140 apps (added AI/LLM, dev tools, databases, networking, CMS/commerce, project mgmt, communication, file/storage, ERP/business, media, smart home, dashboards) **Per-account uninstall** βœ… DONE (uninstall-account API, user panel "Remove All My Apps" button) **Per-stack Reinstall** βœ… DONE (Reinstall button in stacks table, stack-reinstall API, pullβ†’downβ†’up) **Admin App Catalog tab** βœ… DONE (launch apps on behalf of accounts from admin Docker page) --- ## πŸ› οΈ ADMIN ROOT CONTROLS (added 2026-06-20) **#41 β€” phpMyAdmin root section** βœ… DONE Quick-access buttons + tool cards in DB Manager (mysql-manager page). phpMyAdmin at /phpmyadmin, Adminer at /adminer.php. db-tools API detects installed tools and serves URLs. **#42 β€” Docker root GUI** βœ… DONE Full docker page: containers, images, volumes, networks, compose stacks, app catalog, user quotas. All actions (start/stop/remove/logs/inspect) work. Sync-orphans endpoint for post-restore. **#43 β€” PostgreSQL root GUI** βœ… DONE Adminer installed at /adminer.php (handles MySQL + PostgreSQL). Separate PostgreSQL Databases section in DB Manager with direct Adminer PG link. db-tools API detects adminer.php. **#44 β€” Mail server root controls** βœ… DONE mail-server page: service controls (postfix/dovecot/rspamd), mail queue viewer + flush, virtual mail domains list with email counts, mail log tail. **#45 β€” FTP controls section** βœ… DONE ftp-server page: FTP service status + restart/reload/stop, all FTP accounts from DB with username/directory/permissions. **#46 β€” Nginx proxy controls** βœ… DONE nginx-proxy page: comprehensive proxy host management with add/edit/delete, upstream sync, settings, setup guide. **#47 β€” Web server root controls** βœ… DONE web-server page: CPU/RAM/disk/uptime stats, services with restart/reload/stop, PHP defaults, log viewer (nginx-error/access/panel/deploy). --- **#49 β€” Disable/remove conflicting web servers on install** βœ… DONE (install.sh updated) **#51 β€” Server settings sections in admin panel** βœ… DONE All service pages exist in admin: web-server (#47), mail-server (#44), ftp-server (#45), docker, mysql-manager, nginx-proxy, firewall, fail2ban. Each shows install/running status. **#50 β€” Post-restore automation script** βœ… DONE (v2) `/usr/local/bin/novacpx-post-restore` at deploy/novacpx-post-restore.sh: fixes config.ini, cleans orphaned pools, bumps PHP-FPM max_children, pulls latest code+migrations, cleans orphaned DB users before creating webacct, deploys dashboard+notes, Basic Auth, disables Apache2. --no-git flag available. **#48 β€” Collapsible sidebar navigation** βœ… DONE CSS in nova.css, JS in nova.js (_initCollapsibleNav exposed on window). Admin: runs on DOMContentLoaded. Reseller + user: called after renderRNav()/renderNav(). State persisted in localStorage. --- ## πŸ†• NEW FEATURES (added 2026-06-20) **#36 β€” Sub-domains section** βœ… DONE Admin: global view across all accounts. Reseller: filtered to their customers. User: create/remove own subdomains. Backend was already in domains.php (add-subdomain, list, remove). **#37 β€” Parked domains section** βœ… DONE Admin: global view across all accounts. Reseller: filtered to their customers. User: park/remove domains. Backend was already in domains.php (add-alias, list, remove). **#38 β€” Settings section (account-level)** βœ… DONE User panel Account > Settings: shows account info, resource usage gauges, PHP config (version/memory/upload/exec time), quick links to SSL/2FA/password change. **#39 β€” Default index file on new account** βœ… DONE AccountManager now creates a dark-themed modern index.html on account creation. Admin can set a custom HTML template in Server Options (default_index_template setting, {domain}/{username} placeholders). Falls back to built-in if none set. **#40 β€” Linux uninstaller** βœ… DONE `uninstall.sh` at repo root. Full backup β†’ confirmation β†’ removes accounts/users/pools/vhosts/systemd/sudoers/cron/DKIM/DNS/postfix/fail2ban/all dirs. Prints scp + temp HTTP download options. --yes flag to skip confirm. Usage: `bash uninstall.sh [--yes]` --- ## πŸ”’ SECURITY FIXES (2026-06-09, code review) **Shell injection fixes** βœ… DONE - WordPressManager.php: escapeshellarg() on all exec() paths in cloneStaging(); delete() reordered (DB first, filesystem second) - PHPManager.php: sudo rm -f for FPM pool deletion (www-data can't unlink root-owned files); SQLite syntax for updateConfig() - WP-CLI download: 30s timeout + 100KB size validation **install.sh sudoers hardening** βœ… DONE - Replaced `ufw *` wildcard with 9 specific subcommands - Removed `curl *` NOPASSWD entirely (code doesn't need it) - Removed `env *` NOPASSWD entirely (security risk) --- ## πŸ”§ RECENT FIXES (2026-06-09/10) **SSL cert SAN** βœ… DONE Cert regenerated with subjectAltName=IP:10.48.200.110 β€” required for Chrome fetch() to work. **Update caching + nightly cron** βœ… DONE check-novacpx-update + check-os-update cache in settings table (12h TTL, ?force=1 bypass). Nightly cron at 2am: /srv/novacpx/public/bin/cache-update-check.php. **OS upgrade script** βœ… DONE Fixed date format bug (date -u +"%H:%M:%S UTC"). Fixed backup dir (/tmp/novacpx-backup-TIMESTAMP instead of /var/novacpx/). **SEO meta tags** βœ… DONE All 3 panel index.php files have description, keywords, robots=noindex,nofollow. **Version tracking** βœ… DONE deploy-runner.sh and apply-novacpx-update both write to novacpx_version table + settings.panel_version after every deploy. Current: 1.0.27. **VERSION file sync** βœ… DONE (2026-06-10) deploy-runner.sh now copies VERSION from repo root to /srv/novacpx/public/VERSION after each deploy. **Update channels (stable/beta)** βœ… DONE Settings page loads/saves channel from DB. check-novacpx-update reads channel and checks correct remote branch. apply-novacpx-update pulls from correct branch. deploy-runner.sh reads channel from DB. beta branch created on GitHub. GitHub Actions auto-bumps: mainβ†’PATCH, betaβ†’-beta.N. **Settings page DB sync** βœ… DONE settings() function loads panel_name, default_php, nameservers, update_channel from server-options API. Saves via save-option API on submit. **JARVIS agent** βœ… DONE Installed 2026-06-09. Agent ID: novacpx_e3b07264. Online and reporting. **Parker Slingshot JARVIS monitoring** βœ… DONE Updated from parkerslingshot.epictravelexpeditions.com β†’ parkerslingshotrentals.com in facts_collector.php, alerts.php, do_server.php.