Adds MokoOnyx as a git submodule at src/packages/tpl_mokoonyx (pinned
to main branch) so it packages alongside all other MokoWaaS extensions.
Every WaaS site uses both, so installing them as a single package
ensures they stay in sync.
- Added submodule for MokoOnyx repo
- Added template entry to pkg_mokowaas.xml
- Added mokoonyx to protected extensions in script.php
- Added submodules: recursive to CI checkout steps
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Atum template has a 'top' position that renders full-width above the
component output inside the content section. Removed the column-span
CSS hack since top position is naturally full-width.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Joomla's cpanel view renders quickicon (icon position) modules above
regular cpanel modules. Changed from position=cpanel to position=icon
so MokoWaaS appears at the very top of the admin dashboard.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Article count, user count, pending updates with badges
- Disk usage progress bar with color coding
- Current IP display
- Clear Cache button with AJAX spinner
- Check Updates + update count button
- Module defaults to ordering=-1 (top) and access=Super Users
- Added padding to module container
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Admin dashboard module (mod_mokowaas_cpanel) showing:
- MokoWaaS version, debug/offline status badges
- Health indicator (database connectivity check)
- Feature plugin status badges (enabled/disabled)
- Link to full MokoWaaS control panel
- Auto-assigns to cpanel position on install
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add admin dashboard to com_mokowaas with site info bar, feature plugin
grid with AJAX toggles, and quick actions (clear cache, check updates)
- Split monolithic system plugin into 4 toggleable feature plugins:
Firewall, Tenant Restrictions, DevTools, and Health Monitor
- Add MokoWaaSHelper utility class for shared master-user detection
- Add static updates.xml (licensing system deferred)
- Restore universal moko-platform workflows
- Add param migration in package script for existing sites
- Fix license key warning to show once per session
- Rename license key messages to "Moko Consulting License Key"
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Version bump across all manifests and docs
- Auto-cleanup of legacy master users no longer in MASTER_KEYS
- Updated CHANGELOG with all 02.31.00 changes
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Persistent admin warning when no download key is set on the MokoWaaS
update site, with link to System → Update Sites
- Daily heartbeat validates the key against MokoGitea's dynamic endpoint;
shows error if key is invalid or expired
- Package postflight removes stale/duplicate update site entries and
orphaned #__updates rows
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update server now points to MokoGitea's dynamic endpoint which
validates license keys (dlid) and generates update XML from git
releases. Users enter the download key via Joomla's native
System → Update Sites interface. Legacy static URLs are auto-migrated
on install/update.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add plg_task_mokowaassync scheduled task plugin for automated content sync
- Fix demo banner countdown to show weeks/days/months for longer intervals
- Add Community Builder tables to DemoResetService safe reset list
- Remove all CI/CD workflow files (manual release process)
- Bump version to 02.28.00 across all manifests and updates.xml
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- protectExtensions() now covers all MokoWaaS elements (package, system
plugin, component, webservices, task, perfectpublisher)
- enableUpdateServer() ensures #__update_sites stays enabled for MokoWaaS
- cleanupLegacyExtensions() removes old mokowaasbrand entries from
#__extensions and deletes plugins/system/mokowaasbrand/ from filesystem
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds Demo Mode feature for configuring sites as demo instances with
automatic periodic reset to a saved baseline. Includes DemoResetService
for DB table + media snapshots, frontend warning banner, REST and
query-string API endpoints, admin toggles, and a Joomla Scheduled Task
plugin (plg_task_mokowaasdemo) for automatic reset.
Closes#88
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set protected=1, locked=0 on MokoWaaS extensions via package script
- Self-healing: plugin checks and restores protected flag each session
- Block non-master disable via plugin list toggle (plugins.publish)
- Block non-master uninstall via installer manage
- Joomla framework natively enforces protected status (greys out toggles)
- Master users can still manage settings and updates
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- manifest.xml: package-type plugin → package
- Canonical URL injection for alias domains (prevents SEO duplication)
- Heartbeat registration for alias domains (each alias gets Grafana datasource)
- Package script.php: enable plugins on every install/update, heartbeat on postflight
- Remove accidentally committed profile.ps1 and TODO.md
- Add profile.ps1 and TODO.md to .gitignore
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure MokoWaaS from a standalone system plugin into a Joomla
package containing:
- plg_system_mokowaas — existing system plugin (moved to packages/)
- com_mokowaas — minimal API-only component with health, cache, and
update controllers for Joomla Web Services API
- plg_webservices_mokowaas — registers /api/v1/mokowaas/* routes
Package script auto-enables both plugins on fresh install.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The receiver returns 'updated' when re-registering an existing site,
but the code only accepted 'registered', causing false 'HTTP 200 — Unknown' warnings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The postflight still had the old Grafana API code with obfuscated tokens,
causing 403 RBAC errors on install/update. Now uses the heartbeat receiver
at bench.mokoconsulting.tech/api/waas-heartbeat/register.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- enforceLocked() runs every page load — re-enables, re-locks, re-protects
if someone tampers with the database flags
- preflight() blocks uninstall attempts with error message
- Logs tampering attempts to mokowaas log category
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove all Grafana API code (630 lines), obfuscated tokens, SA tokens,
ensureGrafanaPlugin, provisionGrafanaDatasource, buildDashboardModel.
Replace with simple HTTP POST to heartbeat receiver on bench server.
Receiver writes Grafana provisioning YAML and restarts Grafana container.
No API tokens or RBAC permissions needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New service account token with correct RBAC permissions
- script.php postflight now shows success/failure messages to admin
- Logs all heartbeat attempts with HTTP code and cURL errors
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CURLOPT_SSL_VERIFYPEER=false for shared hosting environments
- Add CURLOPT_FOLLOWLOCATION to handle redirects
- Log all Grafana heartbeat attempts with HTTP code and cURL errors
- Helps debug provisioning failures on DreamHost and similar hosts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API key and URL stored as XOR-encoded base64 constants. Deobfuscated
at runtime only when needed. Prevents plain-text grep discovery.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Health endpoint always enabled when plugin is installed
- Grafana URL and API key hardcoded as constants
- Removed enable_health_endpoint, grafana_url, grafana_api_key from config UI
- Token still auto-generated and shown as read-only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements heartbeat telemetry for WaaS dashboard monitoring:
- JSON health endpoint at /?mokowaas=health with token auth
- Database, filesystem, cache, and extension health checks
- Auto-generated API token (separate from Joomla user tokens)
- Grafana Infinity datasource auto-provisioning via REST API
- Shared dashboard with endpoint dropdown variable
- Auto-provision on plugin install/update via script.php
- Grafana plugin install via API (replaces deprecated CLI)
- Deprovisioning on disable (datasource cleanup)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
If MokoOnyx is installed, lock it and set as default.
Unlock MokoCassiopeia to allow uninstall.
Falls back to MokoCassiopeia if Onyx not present.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated version in all .ini, .php, .md files to 02.01.08.
Added SHA256 checksum to updates.xml for install integrity validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MokoCassiopeia zip shipped at src/payload/mokocassiopeia.zip
- Install script uses local payload instead of downloading
- Removed getDownloadUrlFromUpdates (no longer needed)
- Added update-payload.yml workflow to refresh payload on merge to main
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The release zip is properly structured for Joomla installation.
Simplified extraction logic — release zips have templateDetails.xml
at root or one level deep. Added better error messages with the
failing URL for debugging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Send email to webmaster@mokoconsulting.tech on every install/update
with site name, version, PHP, Joomla version
- Changed locked=0 (allows uninstall by super users) but kept
protected=1 (prevents disabling)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of hardcoding the zip URL, fetches MokoCassiopeia's updates.xml
from the repo main branch and parses the downloadurl. This way the
download location is controlled by the MokoCassiopeia repo.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Joomla Installer::install() expects a directory path, not a zip file.
Now extracts the zip to a temp folder, finds the templateDetails.xml,
and passes the correct directory to the installer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Minor version bump to 02.01.01:
- Auto-install mokocassiopeia from GitHub if not present
- Lock and protect the template (cannot be disabled/uninstalled)
- Set mokocassiopeia as default site template
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On install/update, checks if mokocassiopeia template exists. If found,
locks and protects it. If missing, downloads latest release from
GitHub and installs it automatically.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
install() only runs on first install. Moved enableAndLockPlugin() to
postflight() which runs on both install and update, ensuring existing
installs get locked when updating.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sets both locked=1 and protected=1 in #__extensions on install.
Prevents tenants from disabling or uninstalling the plugin through
the Extension Manager.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
First release of v02.00 — patch .00 reserved for development.
Version bumped across all files: manifest, PHP, language, docs,
composer, updates.xml, changelog, README.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Atum reads color values from #__template_styles params (hue, link-color,
special-color) and outputs them as inline CSS variables at render time.
Our CSS variable injection was being overridden by Atum's own output.
Now enforceAtumBranding() sets the color params directly in the DB:
- color_primary → hue (hex→HSL converted) + special-color
- color_sidebar → header-color
- color_link → link-color
Added hexToHsl() helper for the conversion. Install script also sets
default Moko theme colors at install time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add #__action_log_config entry so MokoWaaS emergency access events
display with proper type title and text prefix in System > Action Logs.
Both #__action_logs_extensions and #__action_log_config are cleaned up
on uninstall.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Register plg_system_mokowaas in #__action_logs_extensions on install
so emergency access events appear as filterable in Action Logs UI
- Unregister on uninstall
- Set Moko brand colors as defaults: navy #1a2744, dark #0f1b2d,
accent green #2ecc71
- Force HTTPS default: Yes (was No)
- Admin session timeout default: 60 minutes (was 0/disabled)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace CSS-based logo injection with proper Atum template param
enforcement. The plugin now sets logoBrandLarge, logoBrandSmall,
loginLogo, and favicon via #__template_styles params — both at
install time and enforced at runtime.
Media assets shipped with plugin:
- logo.png → sidebar brand (expanded) + login page logo
- favicon_256.png → sidebar brand (collapsed)
- favicon.svg → modern browser favicon (SVG preferred)
- favicon.ico → legacy browser fallback
- favicon_256.png → Apple/Android touch icon
Removed per-config media upload fields (admin_logo, login_logo,
custom_favicon) — images are now fixed in the plugin media folder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The mokoconsulting.tech/support, /kb, and /news pages exist. Restore
runtime enforcement in MokoWaaS.php and install-time write in
script.php.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>