Use session userID -> Administrator email for subscription checks, activation persistence, and paid-plugin access when Django auth user is not populated.
Render next cache update in Norwegian format and mark overdue cache clearly while triggering background refresh from Installed view when cache metadata is expired.
Inject a lightweight fetch hook into settings pages to call store-activation after successful plugin activation responses, reducing premium relock risk after upgrades.
- Make /plugins/<plugin>/settings/ work for incomplete plugin installs by importing plugin views from source and relaxing overly strict proxy checks.
- Sync INSTALLED_APPS from plugin source when installed markers exist but installed copies are incomplete.
- Keep prior plugin store performance improvements (lazy upgrades fetching, fewer GitHub calls).
- Remove second 'Final confirmation' dialog; keep only the WARNING backup dialog
- After successful upgrade, refetch plugin store and refresh upgrades list so
upgraded plugins no longer appear under Upgrades Available
- New tab between Table View and CyberPanel Plugin Store with badge count
- Dedicated view listing only installed plugins with a newer store version
- Table columns: Plugin Name, New Version, Your Version, Date, Action (Upgrade)
- Notice to read release info and backup before upgrading
- Badge and list populated from existing store API (update_available)
- Add plugin_settings_proxy for /plugins/<name>/settings/ so settings pages
work for all installed plugins (handles plugins installed after worker start)
- Add path('<str:plugin_name>/settings/', plugin_settings_proxy) in pluginHolder.urls
- removeFromSettings/removeFromURLs: use try/except for read/write, raise clear
PermissionError message; ensure panel user can write (chgrp lscpd; chmod g+w)
- Deploy: make CyberCP/settings.py, urls.py, baseTemplate index.html group-
writable by lscpd so uninstall can update them
Fixes false 'Files extracted to wrong location' when /usr/local/CyberCP/README.md
exists. Ensure panel user can create plugin dirs (e.g. chgrp lscpd /usr/local/CyberCP,
chmod g+w, and add panel user to group lscpd).
- Find plugin in GitHub archive by any path segment (Category/pluginName)
- extractPlugin: prefer top-level dir matching plugin name; handle repo-root
single dir by using plugin subdir when present (avoids wrong location)
- Add pluginHolder and pluginInstaller to upgrade recovery essential dirs
Fixes: Files extracted to wrong location (e.g. pm2Manager, README.md in root)
- pluginHolder/urls: insert /usr/local/CyberCP and source paths at top of module
so __import__(plugin_name + '.urls') finds plugin packages (fixes No module
named 'X.urls'). Register plugin routes before catch-all help route.
- pluginHolder/views: add debug_loaded_plugins API and log full traceback on
plugin import failure. panelAccess/emailMarketing settings/ routes added
earlier; cspManager resilient to missing DB table.
Author: master3395
- pluginHolder/views: use dir+meta.xml for installed count; exclude core apps;
repair pass to restore meta.xml from source or GitHub; ensure_plugin_meta_xml
falls back to GitHub when source missing; cap active <= installed
- pluginHolder/urls: include plugin routes for all on-disk plugins (not only
INSTALLED_APPS) so /plugins/<name>/settings/ works after install
- pluginHolder/plugins.html: Install button tries local then store (GitHub)
- CyberCP/settings: sync INSTALLED_APPS with plugin dirs on disk (meta.xml+urls.py)
Author: master3395
- Add CyberCPLogFileWriter.get_current_timestamp() for errorSanitizer (fixes 500 logging)
- After upgrade/install: fetch meta.xml from raw GitHub and overwrite installed file so
store version (e.g. 1.1.0) is correct even when archive ZIP is cached/stale
- Upgrade/install: discover ZIP top-level folder and match plugin folder case-insensitively
- Improves redisManager/memcacheManager upgrade and all store installs
Skip dynamic plugin URL inclusion for plugins that are on disk but not
in Django INSTALLED_APPS to avoid RuntimeError when loading models.
Plugin installer adds apps to INSTALLED_APPS on install; this prevents
breakage when that step was missed or reverted.
- pluginHolder/urls.py: Discover plugins from /usr/local/CyberCP and source
paths (/home/cyberpanel/plugins, /home/cyberpanel-plugins); dynamically
include each plugin's urls so /plugins/<name>/settings/ works without
hardcoding. Add source path to sys.path when loading from source.
- CyberCP/urls.py: Remove hardcoded _plugin_routes; all plugin routes now
served via pluginHolder dynamic inclusion.
Fixes 404 on /plugins/contaboAutoSnapshot/settings/ and any installed plugin
settings page. No per-plugin core changes required.
- Installed plugins: search box in header (same row as Activate/Deactivate All)
- Grid/Table: default sort A-Å by name; sort bar with Name (toggle A-Å/Å-A), Type, Date (toggle newest/oldest)
- Apply sort on load so list shows A-Å when Name A-Å is selected
- Store view: letter filter label 'A-Å Filter' (not A-Z); add Æ, Ø, Å to letter buttons
- views.py: sort pluginList by name (case-insensitive) before template
- Add deploy-installed-plugins-search.sh for template deployment
- Add upgrade button in plugin store when updates are available
- Implement automatic plugin backup before upgrades
- Add revert version functionality with backup selection
- Randomize cache duration (±10 minutes) to prevent simultaneous GitHub API requests
- Display cache expiry time in user's local timezone and locale format
- Fix revert plugin function to work without event object
- Improve error handling in plugin store operations
- 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