Display the admin's current IP address with a hint to add it,
making it easy to configure trusted IP entries without looking
up the IP separately.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add configurable repeatable rows of trusted IP addresses that bypass
the admin session timeout. Supports exact IPs, CIDR ranges, and
wildcard patterns with per-entry labels and enabled toggles.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Joomla 6 changed SubscriberInterface event handlers to receive a typed
event object instead of pass-by-reference parameters. Update
onBeforeApiRoute() to accept BeforeApiRouteEvent and extract the
router via $event->getRouter().
Fixes#48
Authored-by: Moko Consulting
Updated manifest default, PHP fallbacks in MokoWaaS.php and script.php.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces hardcoded help.joomla.org and docs.joomla.org links in
the Atum template header with the WaaS support URL from plugin
config. Uses JS injection in onBeforeCompileHead.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dev is now ahead of main (02.07.00). All manifests, README, and
updates.xml aligned. Updates.xml has all 6 channels with correct
pkg_mokowaas element.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Joomla automatically disables update sites for extensions with
protected=1. ensureProtectedFlag() now also checks and re-enables
the MokoWaaS update site each admin session.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Moved isMasterUser() check to top of enforceAdminRestrictions() so
master user is never blocked by any restriction including install
from URL, global config, sysinfo, installer, and template editing.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Non-master users navigating to the plugin edit page are redirected
back to the plugins list with a warning message.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Installer::install() expects a directory path, not a ZIP file. Now
downloads → extracts to tmp dir → installs from extracted dir → cleans up.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When an alias domain has offline=No, the plugin overrides Joomla's
configuration.php offline=1 setting. This allows the dev/staging alias
to remain accessible while the main site shows the offline page.
Use case: put clarksvillefurs.com offline for maintenance while
clarksvillefurs.dev.mokoconsulting.tech stays accessible for testing.
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>
Instead of rendering a custom HTML page, set config('offline', 1) at
onAfterRoute so Joomla renders the site template's offline.php layout.
Custom offline_message is passed via config if set.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Removed primaryHost check from getCurrentAlias() — just look up
current host in aliases list directly
- Handle Joomla subform stdClass→array conversion
- Strip trailing slashes from alias domains
- Moved handleSiteAlias() to onAfterRoute (client type resolved)
- Use http_response_code(503) + die() for offline page
- Cast offline value to string for comparison
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uri::root() returns the current request domain, so redirecting from an
alias to Uri::root()/administrator redirects back to the alias. Added
primary_domain field to Site Aliases tab and getPrimaryHost() method
that checks: plugin setting → $live_site → alias exclusion fallback.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Read plugin_version from manifest XML instead of hardcoding
- Hide MokoWaaS from plugin/installer list for non-master users
- Block non-master uninstall and disable attempts
- No self-healing lock — master users can still disable if needed
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>
Alias domains were creating separate Grafana datasources with unique
UIDs, causing provisioning failures (duplicate UID) when Grafana
restarts. Only the primary domain should be registered.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move site aliases from a comma-separated text field in Diagnostics to its
own tab using Joomla's subform repeatable-table layout. Each alias entry
now supports: domain, offline toggle with custom message, robots meta
directive, and backend redirect to primary domain. Frontend stays on the
alias domain while admin requests can be redirected to the primary.
Authored-by: Moko Consulting
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>