mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-07-12 03:53:17 +02:00
Fix critical webmail bugs: XSS, SSRF, install ordering, and UI issues
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
This commit is contained in:
@@ -2805,48 +2805,48 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
def setupWebmail():
|
||||
"""Set up Dovecot master user and webmail config for SSO (idempotent)"""
|
||||
try:
|
||||
# Skip if already configured
|
||||
if os.path.exists('/etc/cyberpanel/webmail.conf'):
|
||||
Upgrade.stdOut("Webmail master user already configured, skipping.", 0)
|
||||
return
|
||||
|
||||
# Skip if no mail server installed
|
||||
if not os.path.exists('/etc/dovecot/dovecot.conf'):
|
||||
Upgrade.stdOut("Dovecot not installed, skipping webmail setup.", 0)
|
||||
return
|
||||
|
||||
Upgrade.stdOut("Setting up webmail master user for SSO...", 0)
|
||||
# Always run migrations and dovecot.conf patching even if conf exists
|
||||
already_configured = os.path.exists('/etc/cyberpanel/webmail.conf') and \
|
||||
os.path.exists('/etc/dovecot/master-users')
|
||||
|
||||
from plogical.randomPassword import generate_pass
|
||||
if not already_configured:
|
||||
Upgrade.stdOut("Setting up webmail master user for SSO...", 0)
|
||||
|
||||
master_password = generate_pass(32)
|
||||
from plogical.randomPassword import generate_pass
|
||||
|
||||
# Hash the password using doveadm
|
||||
result = subprocess.run(
|
||||
['doveadm', 'pw', '-s', 'SHA512-CRYPT', '-p', master_password],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
Upgrade.stdOut("doveadm pw failed: " + result.stderr, 0)
|
||||
return
|
||||
master_password = generate_pass(32)
|
||||
|
||||
password_hash = result.stdout.strip()
|
||||
# Hash the password using doveadm
|
||||
result = subprocess.run(
|
||||
['doveadm', 'pw', '-s', 'SHA512-CRYPT', '-p', master_password],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
Upgrade.stdOut("doveadm pw failed: " + result.stderr, 0)
|
||||
return
|
||||
|
||||
# Write /etc/dovecot/master-users
|
||||
with open('/etc/dovecot/master-users', 'w') as f:
|
||||
f.write('cyberpanel_master:' + password_hash + '\n')
|
||||
os.chmod('/etc/dovecot/master-users', 0o600)
|
||||
subprocess.call(['chown', 'dovecot:dovecot', '/etc/dovecot/master-users'])
|
||||
password_hash = result.stdout.strip()
|
||||
|
||||
# Write /etc/cyberpanel/webmail.conf
|
||||
webmail_conf = {
|
||||
'master_user': 'cyberpanel_master',
|
||||
'master_password': master_password
|
||||
}
|
||||
with open('/etc/cyberpanel/webmail.conf', 'w') as f:
|
||||
json.dump(webmail_conf, f)
|
||||
os.chmod('/etc/cyberpanel/webmail.conf', 0o600)
|
||||
subprocess.call(['chown', 'cyberpanel:cyberpanel', '/etc/cyberpanel/webmail.conf'])
|
||||
# Write /etc/dovecot/master-users
|
||||
with open('/etc/dovecot/master-users', 'w') as f:
|
||||
f.write('cyberpanel_master:' + password_hash + '\n')
|
||||
os.chmod('/etc/dovecot/master-users', 0o600)
|
||||
subprocess.call(['chown', 'dovecot:dovecot', '/etc/dovecot/master-users'])
|
||||
|
||||
# Write /etc/cyberpanel/webmail.conf
|
||||
webmail_conf = {
|
||||
'master_user': 'cyberpanel_master',
|
||||
'master_password': master_password
|
||||
}
|
||||
with open('/etc/cyberpanel/webmail.conf', 'w') as f:
|
||||
json.dump(webmail_conf, f)
|
||||
os.chmod('/etc/cyberpanel/webmail.conf', 0o600)
|
||||
subprocess.call(['chown', 'cyberpanel:cyberpanel', '/etc/cyberpanel/webmail.conf'])
|
||||
|
||||
# Patch dovecot.conf if master user config not present
|
||||
dovecot_conf_path = '/etc/dovecot/dovecot.conf'
|
||||
|
||||
Reference in New Issue
Block a user