Integrates webmail and emailDelivery apps, mail-server and install/upgrade
paths, cyberpanel_ols 2.7.0-style binaries, and v2.4.5 UI patterns while
preserving v2.5.5-dev behavior (SnappyMail/PUBLIC_ROOT, childPath in
launchChild, hardened downloads and SSH activity modal).
- Resolve FTP home paths without duplicating /home/domain; support absolute paths under site home
- Add changeFTPDirectory API and list UI; improve create form path help
- Add setFTPAccountStatus (Status 0/1) with Enable/Disable on list page
- Pure-FTPd MySQL: require Status='1' for authentication in install templates
- Plugin signals for change directory and account status
Replace 'systemctl restart dovecot' with 'doveadm reload' in
virtualHostUtilities, mailUtilities, and renew modules. The nightly
backup scheduler, SSL operations, and weekly cert renewal were
forcefully terminating all client sessions. doveadm reload applies
config changes (including updated SSL certs) without dropping
existing connections. upgrade.py is intentionally left unchanged
as full restarts are appropriate during upgrades.
- secMiddleware: allow dbPassword to bypass strict char check (stronger passwords)
- mysqlUtilities.createDatabase: return (0, error_message) on failure so UI shows real error instead of '0'
- mysqlUtilities.createDatabase: backtick-quote db name (fix 'near -admin' with hyphens), escape password and user for SQL
- submitDBCreation: pass through error message from createDatabase
- backupUtilities, Backupsv2, restoreMeta: treat createDatabase != 1 as failure (tuple return)
- patches/allow-dbpassword-special-chars.patch for secMiddleware deploy
os.path.exists() returns False for broken symlinks (e.g. /usr/bin/php
pointing to removed php7.4), so the old link was never removed and
the new ln -s to lsphp83 failed silently. Use os.path.lexists() instead.
- dockerManager: add 0001_initial migration (CREATE TABLE IF NOT EXISTS), migrate-and-retry on DB errors, safe error response, fix logging.CyberCPLogFileWriter.writeToFile
- dockerManager/views: listContainersPage fallback HTML with error message if template fails
- dockerManager/viewContainer: improve container log readability (font-size 1rem, color #f1f5f9, line-height 1.6)
- baseTemplate: blockIPAddress also adds ban to firewall BannedIP model so Firewall > Banned IPs shows all
- firewall: getBannedIPs migrate-and-retry on OperationalError/ProgrammingError; install runs migrate firewall
- plogical/upgrade: syncBannedIPsJsonToDb() to sync JSON bans to firewall_bannedips; firewallMigrations() calls it; CyberPanelUpgrade runs firewallMigrations(); someDirectories creates /usr/local/CyberCP/data
- install: explicit migrate firewall after global migrate
Postfix SASL PLAIN auth fails with "No worthy mechs found" on
RHEL/AlmaLinux because cyrus-sasl-plain is not installed by default.
- Add cyrus-sasl-plain to postfix install in install.py
- Auto-install in configureRelayHost() for existing servers
- Add to upgrade.py setupSieve() for existing installations
lscpd worker runs as user lscpd, not cyberpanel. The webmail.conf file
(containing master user credentials) was unreadable by lscpd, causing
master auth to silently fail and fall back to empty password auth.
Also fix ownership on existing installs during upgrade.
- Replace free text input with folder dropdown for move-to-folder rules
- Auto-prefix INBOX. namespace to folder names in sieve scripts
- Strip INBOX. prefix when parsing sieve scripts back to rules
- Make upgrade setupSieve() regexes more flexible to handle config variations
- Add os.makedirs for conf.d directory in both install and upgrade
- Validate ManageSieve config with both inet_listener and service checks
- Add home directory (CONCAT) to dovecot-sql.conf.ext user_query so sieve
can locate script storage per user
- Add sieve/sieve_dir plugin settings to dovecot.conf templates
- Add lda_mailbox_autocreate/autosubscribe so fileinto creates missing folders
- Update setupSieve() upgrade function to patch all three on existing installs
On Ubuntu, the install creates /etc/pki/dovecot/ directories but never
populates them with certs. Postfix main.cf references these paths for
STARTTLS. Without them, inbound STARTTLS fails and external mail servers
(Gmail etc.) drop the connection, preventing mail delivery.
Security fixes:
- Escape plain text body to prevent XSS via trustAsHtml
- Add SSRF protection to image proxy (block private IPs, require auth)
- Sanitize Content-Disposition filename to prevent header injection
- Escape Sieve script values to prevent script injection
- Escape IMAP search query to prevent search injection
Install/upgrade fixes:
- Move setupWebmail() call to after Dovecot is installed (was running
before doveadm existed, silently failing on every fresh install)
- Make setupWebmail() a static method callable from install.py
- Fix upgrade idempotency: always run dovecot.conf patching and
migrations even if webmail.conf already exists (partial failure recovery)
Frontend fixes:
- Fix search being a no-op (was ignoring results and just reloading)
- Fix loading spinner stuck forever on API errors (add errback)
- Fix unread count decrementing on already-read messages
- Fix draft auto-save timer leak when navigating away from compose
- Fix composeToContact missing signature and auto-save
- Fix null subject crash in reply/forward
- Clear stale data when switching accounts
- Fix attachment part_id mismatch between parser and downloader
Backend fixes:
- Fix Sieve _read_response infinite loop on connection drop
- Add login check to apiSaveDraft
- Fix apiSSO() resetting selected account to first one on every call,
now preserves previously selected account if still valid
- Fix webmail.conf ownership to use cyberpanel:cyberpanel (Django runs
as cyberpanel user, not nobody)
- Add error notifications when SSO or folder loading fails
Adds master passdb config to dovecot.conf templates, setupWebmail() to
the installer and upgrade paths to generate credentials and create
/etc/dovecot/master-users and /etc/cyberpanel/webmail.conf automatically.
The upgrade path is idempotent and patches existing dovecot.conf if needed.
Rebuilt module fixes NULL pointer dereference in apply_headers() when
OLS generates error responses (4xx/5xx). The get_req_var_by_id() call
for DOC_ROOT crashed because request variables aren't initialized
during error response generation. Fix adds status code guard to skip
header processing for error responses.
Expand mail-domain detection so proxy stays off for:
mail., smtp., imap., pop3., pop., autodiscover., webmail.
(and subdomains containing these). Other A/AAAA/CNAME get proxied by default.
- Return (success, error_msg) from createNONSSLMapEntry instead of 0/1
- Fix logging: use CyberCPLogFileWriter.writeToFile instead of writeToFile
- Match listener block case-insensitively (listener Default / listener default)
- Raise clear ValueError if Default listener block not found in httpd_config.conf
- Propagate actual error messages in createConfigInMainVirtualHostFile and createConfigInMainDomainHostFile
- dnsManager.fixDNSRecordsCloudFlare: track existing_types_by_name;
skip adding A/AAAA when hostname has CNAME (A/AAAA cannot coexist
with CNAME). Clearer docstring.
- dnsUtilities: comment tweak for proxy-capable record types.
- settings.py: read DB password from /etc/cyberpanel/mysqlPassword
when present so panel stays in sync with CLI/install scripts.
- dnsManager.py: include AAAA in record types that get proxied flag on
update (was only A, CNAME); fix HTTP 500 by hardening loadCFKeys and
addDeleteDNSRecordsCloudFlare (safe file read, always pass
domainsList/cfEmail/cfToken to template).
- dnsUtilities.py: A, AAAA and CNAME can be proxied in Cloudflare;
set proxied only for those types; MX, TXT, etc. cannot be proxied.
- Bug: filtering on '::1' in line incorrectly excluded addresses like
2a02:c206:2238:7806::1, so fixDNS() never created AAAA records.
- Fix: use ipaddress.ip_address() and is_loopback/is_link_local so
only actual loopback (::1) and link-local (fe80::) are excluded.
- GetServerIPv6() now returns correct global IPv6 for DNS AAAA records.
- Fix 1: Parse -b/--branch and --mariadb-version with while-loop so only next token is used
(avoids Branch_Name becoming 'v2.5.5-dev --mariadb-version 12.3')
- Fix 2: Default Git_User to master3395 in Pre_Upgrade_Setup_Git_URL (04_git_url, monolithic)
- Fix 3: upgrade.py uses CYBERPANEL_GIT_USER for git clone (default master3395);
export CYBERPANEL_GIT_USER before upgrade.py in 08_main_upgrade and monolithic
- Fix 4: --mariadb-version already supported in 05_repository.sh (MARIADB_VER_REPO)
- firewallUtilities: add closeConnectionsFromIP() using conntrack -D -s IP
- addBannedIP: when IP already banned, close connections and return success message
- Frontend: always call API on Ban IP so backend can close connections; show server message
- Install: add conntrack-tools (RHEL) / conntrack (Debian/Ubuntu) to all install paths
(rhel_deps, debian_deps, install_modules/01_verify_deps, install.py, venvsetup)
- plogical/acl.py: use config.get() for DNS permissions so old ACLs without
deleteZone key do not cause KeyError
- baseTemplate: add deleteZone/addDeleteRecords CSS classes to DNS menu links
for correct permission-based hiding
- system-status.js: fix swapped selectors (deleteZone hides .deleteZone,
addDeleteRecords hides .addDeleteRecords instead of .deleteDatabase)
- versionFetcher: normalize RELEASE_5_2_3 -> 5.2.3 for phpMyAdmin tags
- upgrade: verify tarball size after download; chown lscpd at end of phpMyAdmin install
- install: same glob-based extract + verify; check tarball size
- fix-phpmyadmin.sh: one-off script to install/fix phpMyAdmin on server (404 fix)
- index.html: notification dropdown scroll (list max-height, flex min-height:0), button min-width and contrast, dark text on white for dark mode visibility
- cyberpanel.sh, cyberpanel_upgrade.sh, preUpgrade.sh: default install/upgrade URLs to usmannasir/cyberpanel (keep -r/--repo for fork)
- databases/plogical: AutoLogin, views, phpmyadminsignin updates
New hashes for all 3 platforms after fixing the bug where VHosts with
SSL context but missing listener map entries served the wrong cert.
rhel9: 04921afbad94e7ee69bc93a73985e318df93f28b2b0d578447b0ef43dc6e3818
ubuntu: ae2564742f362d3e34ea814dff37edeb8f8b73ae9ca1484ba78e2453a3987429
rhel8: 855b6bccb4a7893914506a07185cffd834bd31a7f7c080b5b4190283def7fa3e
The previous string replace only matched 'adminEmails root@localhost'
exactly. On fresh OLS installs where adminEmails may have a different value
or different spacing, the replace would silently fail and Auto-SSL config
would never be injected. Use re.sub to match the adminEmails line regardless
of its value.
The string replace matched only 'adminEmails' keyword instead of the
full existing line 'adminEmails root@localhost', causing
the remaining ' root@localhost' to trail onto the acmeEmail
line and break ACME account registration.