- cyberpanel.sh uses #!/bin/bash so should be executed with bash
- Change to /tmp directory before execution to ensure writable location
- Fixes permission issues when cyberpanel.sh tries to execute other scripts
- Execute with 'sh' instead of relying on exec permissions
- More reliable in process substitution context
- Handles cases where chmod might not work properly
- Use absolute path (/tmp/cyberpanel-96375.sh) instead of relative path
- Use exec instead of ./ to execute the script
- Ensures proper permissions and execution in process substitution context
- Clean up script file after execution
- Remove complex modular architecture that was causing variable persistence issues
- Use simple OS detection like stable branch
- Download cyberpanel.sh directly for v2.5.5-dev branch
- Add disk space checking (10GB minimum)
- Support both yum and dnf for RHEL-based systems
- Fallback to standard cyberpanel.sh if branch-specific download fails
- Much simpler and more reliable approach
- Always call detect_os() and get_os_info() in install_dependencies()
- This ensures variables are fresh and properly captured
- Add confirmation message showing captured values
- Fixes issue where variables were detected but empty when passed to manage_dependencies
- Remove debug output that wasn't showing
- Use eval with get_os_info() to properly capture OS variables
- Add better error messages showing actual variable values
- Ensure variables are properly exported before calling manage_dependencies
- Fix missing 'fi' closing the TEMP_DIR check block
- Add check_disk_space() function to verify minimum 10GB available
- Display disk space requirements and available space
- Warn if insufficient space but allow continuation
- Use eval with get_os_info() to capture OS variables
- Ensures variables are properly set in current shell scope
- Fixes issue where variables were detected but not available to install_dependencies()
- Temporarily disable set -e when trying to create temp directories
- Prevents script from exiting when /tmp is full
- Allows fallback to alternative directories or fallback installer
- Try multiple temp directory locations (/tmp, /var/tmp, /root, /root)
- Clean up old temporary directories before creating new ones
- Skip git clone if no temp directory can be created
- Try multiple locations for fallback installer download
- Better error messages for disk space issues
- Use flag-based approach to track git clone success
- Verify repository structure (install.sh and modules/) before using
- Fix fallback execution path
- Support both yum and dnf for package installation
- Better error messages
- Add timeout for git clone (180 seconds)
- Better error messages showing actual git errors
- Verify repository structure before using cloned repo
- Improve fallback installer download with better error handling
- Support both yum and dnf for RHEL-based systems
- FTPUsers: use domain__domain__in (FK to Websites) not domain__in
- Session: use session.get('userID'), return JSON when missing
- ACL: use currentACL.get('admin',0) to avoid KeyError
- /proc: resilient parsing for net/dev, diskstats, stat
- Log errors via CyberCPLogFileWriter; generic user-facing messages
- Prevents intermittent 500s that zero out insights (Users, Sites, etc.)
- Calculate total installed plugins count
- Calculate total active/enabled plugins count
- Display statistics in page header with icons
- Shows 'Installed: X' and 'Active: Y' counts
- Statistics only shown when plugins are installed
- Improves visibility of plugin status at a glance
- Fix except block indentation to match try block
- Add error handling for enrichment in stale cache fallback
- Ensures proper exception handling structure
- Wrap mailUtilities.checkHome in try-except
- Add try-except around _enrich_store_plugins calls
- If enrichment fails, return plugins without enrichment instead of 500 error
- Add error handling for _is_plugin_enabled calls
- Prevents HTTP 500 errors when plugin store loading fails
- Fixes issue where installing discordWebhooks caused plugin store to fail
- Remove redundant local import of pluginInstaller inside install_from_store function
- pluginInstaller is already imported at module level (line 20)
- The local import was creating a variable shadowing issue
- When the cleanup code path wasn't executed, pluginInstaller was referenced before assignment
- Fixes installation from store failing with variable reference error
- Only check /usr/local/CyberCP/ for installed status, not /home/cyberpanel/plugins/
- Require both plugin directory AND meta.xml to exist for installed status
- Plugins in source directory are not considered installed
- Fixes issue where Discord Webhooks, Fail2ban, Premium Plugin Example, and Test Plugin showed as installed when they weren't
Previously, the check used: os.path.exists(installed_path) or os.path.exists(source_path)
This incorrectly marked plugins as installed if they existed in the source directory.
Now uses: os.path.exists(installed_path) and os.path.exists(installed_meta)
This correctly only marks plugins as installed if they're actually in /usr/local/CyberCP/ with meta.xml
- Make toggleView more flexible - only require the specific view element needed
- Store view can now work even when gridView/tableView don't exist (no plugins installed)
- Fix initialization to directly show store view without calling toggleView recursively
- Find store button by text content instead of array index for reliability
- Prevents 'View elements not found' errors when loading Plugin Store with no installed plugins
- Hide Grid and Table view buttons when plugins list is empty
- Only show Plugin Store button when no plugins are installed
- Improves UX by preventing clicks on non-functional buttons
- Combined with null checks, ensures no JavaScript errors occur
- Add null checks for gridView, tableView, and storeView elements
- Prevent 'Cannot read properties of null' errors when elements don't exist
- Add null checks for viewBtns array access
- Add function existence checks before calling setupStoreSearch, loadPluginStore, displayStorePlugins
- Improve initialization code with better error handling
- Fixes Plugin Store loading errors when no plugins are installed
- Filter pluginList to only include plugins where installed == True
- Uninstalled plugins will only appear in Plugin Store, not Installed Plugins
- This fixes the issue where uninstalled plugins were still showing locally
- Plugins in /home/cyberpanel/plugins/ but not in /usr/local/CyberCP/ are now hidden from Installed Plugins
- Track INSTALLED_APPS section state while iterating
- Only remove plugin if found within INSTALLED_APPS section
- Prevents removing plugin references from comments or other sections
- Use more precise string matching to avoid partial matches
- removeFromSettings: Match plugin name in quotes within INSTALLED_APPS context
- removeFromURLs: Match plugin name in path() and include() patterns
- Prevents false positives (e.g., 'pluginName2' matching 'pluginName')
This ensures uninstall only removes the exact plugin, not similar names.
- Verify plugin directory is actually removed after removeFiles()
- If directory still exists, retry with ProcessUtilities.normalExecutioner()
- Return error if directory still exists after all attempts
- Prevents silent failures where uninstall appears successful but plugin remains
Fixes: Plugins showing as installed after 'successful' uninstall
- Check if running as root (os.geteuid() == 0)
- If root: fix permissions directly without sudo
- If not root: use ProcessUtilities.normalExecutioner() which handles
privileged commands properly (no password prompt needed)
- Remove sudo dependency that was causing password prompts
Fixes: sudo password prompt errors when uninstalling plugins
- Try direct removal first (fastest)
- If that fails, use sudo chown/chmod to fix permissions, then remove
- Final fallback: use sudo rm -rf
- Better error handling and logging at each step
Fixes: Permission denied errors when uninstalling plugins with root-owned files
(examplePlugin, paypalPremiumPlugin, pm2Manager)
Remove commented-out emailMarketing URL reference from template.
Django may still try to parse commented {% url %} tags, causing
'Reverse for emailMarketing not found' error.
emailMarketing was removed from INSTALLED_APPS but websiteFunctions
was still trying to import it, causing ModuleNotFoundError.
Fixes: ModuleNotFoundError: No module named 'emailMarketing'
- Comment out emailMarketing menu item in baseTemplate/index.html
- Skip emailMarketing in pluginHolder/views.py when listing plugins
- Prevents HTTP 500 error when template tries to reverse 'emailMarketing' URL
Fixes: HTTP 500 on /plugins/installed after emailMarketing removal
- Use pluginInstaller.removeFiles() which handles permissions properly
- Add fallback to rm -rf if pluginInstaller method fails
- Better error handling and logging
- Applied to both install_plugin and install_from_store functions
Fixes: Incomplete plugin directory cleanup failures due to permission issues