Quote admin password arguments during install and harden upgrade rewrites of /usr/bin/adminPass so shell-sensitive characters are preserved instead of expanded.
Add plogical/cyberpanel_python.py with resolve_cyberpanel_python() and
ensure_cyberpanel_bin_python_shim() (symlink to system Python when venv
binary is absent). Call shim before writing root crontab on install/upgrade,
and from IncBackups/IncScheduler.py so existing jobs self-heal. IncBackups
views use resolved interpreter for backupUtilities. Upgrade._python_for_manage
delegates to resolve_cyberpanel_python().
LiteSpeed CyberPanel vhost serves /static/ from public/static while
collectstatic writes to STATIC_ROOT. Merge after collectstatic and ensure
webmail assets so /webmail/ Angular loads. Hook install/upgrade staticContent,
deploy scripts, and upgrade.sh; fix Django --noinput flag; restore lscpd
ownership on public/static after chown root. SnappyMail: require index.php on
install and validate tree after unzip on upgrade.
- recover_database_credentials: read root password from JSON mysqlPassword
when present; try cyberpanel password from settings.py then FTP/DNS/Postfix
configs; refuse DROP/CREATE or random passwords unless
CYBERPANEL_ALLOW_DB_CREDENTIAL_RESET=1 (legacy recovery).
- Pre-upgrade MariaDB: GRANT root privileges without IDENTIFIED BY so the
existing root password hash is not rewritten.
Add install_utils.get_lsphp_install_suffixes() (Alma 9/10+, EL9+,
Ubuntu 24.04+, Debian 13+ use 74–85; older OS keep 71–85).
installCyberPanel.installAllPHPVersions uses the matrix and installs
every listed lsphp on Ubuntu (fixes 74 skipped by slice).
upgrade.get_available_php_versions loads the same helper from install/.
Extend PHP-FPM restart loops to 8.4/8.5 and CloudLinux list to 85.
Clarify /usr/bin/php symlink priority comments in install.py.
Add docs/THIRD_PARTY_NOTICES.md for the bundled list-unsubscribe-header
plugin (AGPL-3.0, upstream GitHub). Link from README. Add CPScripts helper
to sync the plugin from a local snappymail-plugins checkout into install/.
Re-run install_and_enable_list_unsubscribe_header_plugin from plogical.snappymail_plugin_utilities after snappymail_cyberpanel.php; keep bundled plugin under install/snappymail/plugins/.
- Add install/snappymail/plugins/list-unsubscribe-header (upstream GitHub plugin)
- Add plogical/snappymail_plugin_utilities.py to copy into snappymail + legacy rainloop data roots and merge enabled_list
- Run after SnappyMail CyberPanel installer in install.py and upgrade.py
- InstallMailBoxFoldersPlugin now merges plugins instead of replacing enabled_list; also installs list-unsubscribe
Roundcube is not shipped by CyberPanel core; SnappyMail is the bundled webmail.
ng-if on pagination bars created a child scope so ng-model for Per page and Go to page updated a shadowed copy; handlers read the controller scope — controls appeared to do nothing. Use ng-show instead.
Bump firewall.js query cb after merge with upstream (cb=11) so browsers reload the script.
Tracked copies (public/static, static) must match firewall/static so the panel serves the fixed JS. Add rulesFetchGen, try/finally, fetchStatus==1, expose populateCurrentRecords on scope.
Remove duplicate Trusted IPs management from dashboard Recent SSH Logs;
use actionable alert count on the tab (exclude info-only SSH tips).
Add sshSecurityWhitelistUtilities with normalized IP matching for logs
and analyzeSSHSecurity. Wire whitelist API routes, firewall ban guard,
and login hooks. Firewall tab remains the canonical trusted-IP editor.
Add a user-management automation flow that enables OLS+Apache backend wiring for website and child-domain creation, including idempotent config updates, health/syntax validation gates, rollback-safe retries, and operator test/documentation assets.
- mailUtilities: insert CyberCP first on sys.path (dnspython dns shadowing); Rspamd log under /var/log/cyberpanel; log before ServiceManager; dnf on EL8/9; append package stderr
- emailPremium: Rspamd admin UI without cloud addon gate; JsonResponse; fetchRspamdSettings unlocked
- emailDelivery: AutoField PKs; 0001_initial SeparateDatabaseAndState for int FK to loginSystem
- mailUtilities: insert CyberCP first on sys.path (dnspython dns shadowing); Rspamd log under /var/log/cyberpanel; log before ServiceManager; dnf on EL8/9; append package stderr
- emailPremium: Rspamd admin UI without cloud addon gate; JsonResponse; fetchRspamdSettings unlocked
- emailDelivery: AutoField PKs; 0001_initial SeparateDatabaseAndState for int FK to loginSystem
Add runtime table self-healing for catch-all/plus/pattern email features and make upgrade SQL idempotent on existing latin1 installations by avoiding failing FK creation while preserving forwarding compatibility.
Add runtime table self-healing for catch-all/plus/pattern email features and make upgrade SQL idempotent on existing latin1 installations by avoiding failing FK creation while preserving forwarding compatibility.
Restore catch-all, plus-addressing, pattern-forwarding, and email-limits controllers in the public static JS so CyberPanel email management pages no longer fail with Angular controller registration errors.
Restore catch-all, plus-addressing, pattern-forwarding, and email-limits controllers in the public static JS so CyberPanel email management pages no longer fail with Angular controller registration errors.
CyberPanel previously added _dmarc at the apex (p=none) in two code paths and _dmarc on every child subdomain, which conflicts with a single externally managed policy (e.g. Cloudflare) and violates RFC 7489 (one TXT RRset per name). Comment out automatic DMARC creation so operators set one record at _dmarc.<apex> only.
CyberPanel previously added _dmarc at the apex (p=none) in two code paths and _dmarc on every child subdomain, which conflicts with a single externally managed policy (e.g. Cloudflare) and violates RFC 7489 (one TXT RRset per name). Comment out automatic DMARC creation so operators set one record at _dmarc.<apex> only.
- dnsUtilities: correct createDNSRecordCloudFlare argument order (priority, ttl)
- vhostConfs/ApacheVhosts: OLSLBConf uses real docRoot and acme-challenge path for child vhosts (vhRoot is parent domain)
- virtualHostUtilities: defer ChildDomains save until after SSL/Apache; cleanup ORM row on failure; createDomain CLI exits 0/1 with 1,/0, stdout
- websiteFunctions: submitDomainCreation waits on subprocess and returns failure JSON on error
- dnsUtilities: correct createDNSRecordCloudFlare argument order (priority, ttl)
- vhostConfs/ApacheVhosts: OLSLBConf uses real docRoot and acme-challenge path for child vhosts (vhRoot is parent domain)
- virtualHostUtilities: defer ChildDomains save until after SSL/Apache; cleanup ORM row on failure; createDomain CLI exits 0/1 with 1,/0, stdout
- websiteFunctions: submitDomainCreation waits on subprocess and returns failure JSON on error
When removing a child domain, matching only the apex label (e.g. vscode)
left mail.* and www.* (and MX/TXT/DMARC) records in the parent zone.
Normalize record names to FQDN under the zone and delete the subdomain
FQDN plus any names under it.