security: protected status prevents disable/uninstall
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 25s
Joomla: Repo Health / Release configuration (push) Failing after 4s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 3s

- 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>
This commit is contained in:
Jonathan Miller
2026-05-24 03:53:33 -05:00
parent 6e0d5387cf
commit b048b47e7c
2 changed files with 86 additions and 1 deletions
+33
View File
@@ -37,6 +37,9 @@ class Pkg_MokowaasInstallerScript
$this->enablePlugin('system', 'mokowaas');
$this->enablePlugin('webservices', 'mokowaas');
// Mark MokoWaaS extensions as protected (prevents disable/uninstall at framework level)
$this->protectExtensions();
// Trigger heartbeat registration
$this->sendHeartbeat();
}
@@ -71,6 +74,36 @@ class Pkg_MokowaasInstallerScript
}
}
/**
* Set the protected flag on all MokoWaaS extensions.
*
* Joomla's protected flag prevents disabling and uninstalling at the
* framework level — no plugin-side interception needed.
*
* @return void
*
* @since 02.03.10
*/
private function protectExtensions(): void
{
try
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('protected') . ' = 1')
->set($db->quoteName('locked') . ' = 0')
->where('(' . $db->quoteName('element') . ' = ' . $db->quote('mokowaas')
. ' OR ' . $db->quoteName('element') . ' = ' . $db->quote('pkg_mokowaas') . ')');
$db->setQuery($query);
$db->execute();
}
catch (\Throwable $e)
{
Log::add('Error protecting MokoWaaS extensions: ' . $e->getMessage(), Log::WARNING, 'jerror');
}
}
/**
* Send heartbeat to the MokoWaaS monitoring receiver.
*