Compare commits

..

7 Commits

Author SHA1 Message Date
jmiller 6b1352d82c Merge pull request 'feat: backup bridge plugin to detect MokoSuiteBackup (#208)' (#209) from feature/208-backup-bridge into dev
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 13s
Generic: Project CI / Lint & Validate (pull_request) Successful in 38s
Generic: Project CI / Lint & Validate (push) Successful in 38s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 39s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 49s
Universal: PR Check / Validate PR (pull_request) Failing after 38s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (push) Has been skipped
2026-06-18 19:54:34 +00:00
Jonathan Miller 446539844d ci: retrigger after runner restart
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Generic: Project CI / Lint & Validate (pull_request) Successful in 25s
Universal: PR Check / Validate PR (pull_request) Failing after 24s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 29s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 1s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 22s
2026-06-18 12:55:05 -05:00
Jonathan Miller 9b347dd136 fix(backup): send error on failure, use staleDays for cutoff, consistent shape (#208)
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Generic: Project CI / Lint & Validate (pull_request) Successful in 11s
Universal: PR Check / Validate PR (pull_request) Failing after 24s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 29s
- Send explicit error status when backup data collection fails instead
  of omitting the key (so HQ can distinguish failure from not-installed)
- Add status='ok' to not-installed return for consistent array shape
- Use staleDays param instead of hardcoded 7-day cutoff in fallback query
2026-06-18 11:13:29 -05:00
Jonathan Miller bca879f0d3 feat(backup): use real MokoSuiteBackup schema and prefer BackupStatusHelper (#208)
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 9s
Universal: PR Check / Validate PR (pull_request) Failing after 24s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 28s
Update bridge to use correct column names (backupstart/backupend,
status values: complete/fail/running/pending). Prefer the
BackupStatusHelper API when available, with direct table query
fallback for older MokoSuiteBackup versions.
2026-06-18 10:41:54 -05:00
Jonathan Miller 0d731eafd0 fix: swap demo/sync plugin manifests — contents were in wrong files
The merge rename accidentally swapped the XML manifest contents between
plg_task_mokosuiteclientdemo and plg_task_mokosuiteclientsync. The demo
manifest contained the sync element/name/namespace and vice versa,
causing JInstaller to look for mokosuiteclientsync.xml inside the demo
plugin zip.
2026-06-18 10:37:22 -05:00
Jonathan Miller 559db324cb feat(backup): scaffold backup bridge plugin (#208)
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Add plg_system_mokosuiteclient_backup — detects MokoSuiteBackup and
collects backup status for heartbeat payloads to MokoSuiteHQ.

Scaffolding includes manifest, service provider, extension class,
and language files. Table column names are placeholders pending
MokoSuiteBackup schema confirmation (MokoSuiteBackup#47).
2026-06-18 10:24:54 -05:00
Jonathan Miller bd37187f0e ci: add changelog extraction to promote-rc job in auto-release [skip ci] 2026-06-18 10:04:13 -05:00
63 changed files with 7110 additions and 225 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
<display-name>Package - MokoSuiteClient</display-name>
<org>MokoConsulting</org>
<description>White-label identity, security hardening, and tenant restriction layer for Suite-managed Joomla environments</description>
<version>02.38.00</version>
<version>02.34.84</version>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
<governance>
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
# VERSION: 02.38.00
# VERSION: 02.34.84
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+33 -4
View File
@@ -14,16 +14,14 @@
INGROUP: MokoSuiteClient.Documentation
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
PATH: ./CHANGELOG.md
VERSION: 02.38.00
VERSION: 02.34.84
BRIEF: Version history using `Keep a Changelog`
-->
# Changelog
## [Unreleased]
## [02.35.00] --- 2026-06-18
### Changed
- **Full rename: MokoSuite → MokoSuiteClient** — repo, all Joomla element names (com_mokosuiteclient, plg_system_mokosuiteclient, mod_mokosuiteclient_*, etc.), PHP classes, language files, folder structure, and manifest references. This is the client tracker for the MokoSuite platform.
@@ -178,3 +176,34 @@
- Content Sync config tab (targets now in scheduled tasks)
- Site Aliases config tab (hardcoded to dev.{primary_domain})
- File sync (images/, files/, media/) — sync is API/DB content only
## [02.29] - 2026-05-31
### Added
- `allow_extension_updates` param — separate update rights from installer restrictions; tenants can update extensions by default even when the installer is restricted
- Hardcoded master usernames — multiple privileged users supported with identical access
### Fixed
- Emergency access IP whitelist: empty `allowed_ips` now permits all IPs (was blocking everyone)
- Emergency access reads `allowed_ips` from plugin params instead of global config
- `plg_task_mokosuiteclientsync` — Joomla Scheduled Task plugin for automatic content sync to remote sites
- Community Builder tables added to demo reset safe table list
- API endpoint `POST /api/index.php/v1/mokosuiteclient/install` — install extensions from a remote ZIP URL
- Demo Mode with configurable warning banner on frontend when enabled
- Demo banner countdown now shows weeks/days/months for longer intervals instead of raw hours
- `DemoResetService` — baseline snapshot and restore for DB tables + media files
- API endpoints `POST /?mokosuiteclient=reset` and `POST /?mokosuiteclient=snapshot` (query-string)
- REST endpoints `POST /api/v1/mokosuiteclient/reset` and `GET/POST /api/v1/mokosuiteclient/snapshot`
- `plg_task_mokosuiteclientdemo` — Joomla Scheduled Task plugin for automatic demo site reset
- Admin toggles: Take Snapshot Now and Restore Baseline Now in plugin config
- Content Sync: one-way push of articles, categories, menus, and modules to remote MokoSuiteClient sites
- Content Sync: API endpoints `POST /?mokosuiteclient=sync` (sender) and `POST /?mokosuiteclient=sync-receive` (receiver)
- Content Sync: REST endpoints `POST /api/v1/mokosuiteclient/sync` and `POST /api/v1/mokosuiteclient/sync-receive`
- Content Sync: configurable sync targets with URL + API token in plugin settings
- Package installer: protect all MokoSuiteClient extensions (not just system plugin) and ensure update server stays enabled
- Package installer: clean up legacy `mokosuiteclientbrand` extension entries and files on install/update
- API endpoint `GET /?mokosuiteclient=extensions` and `GET /api/v1/mokosuiteclient/extensions` — list installed extensions with version, status, and update server info
## [02.20] --- 2026-05-28
+1 -1
View File
@@ -14,7 +14,7 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Documentation
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: ./CODE_OF_CONDUCT.md
BRIEF: Reference + packaging repo for Moko Consulting Developer GPT Other Default
-->
+1 -1
View File
@@ -19,7 +19,7 @@
DEFGROUP: mokoconsulting-tech.MokoSuiteClientBrand
INGROUP: MokoStandards.Governance
REPO: https://github.com/mokoconsulting-tech/MokoSuiteClientBrand
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /GOVERNANCE.md
BRIEF: Project governance rules, roles, and decision process for MokoSuiteClientBrand
-->
+1 -1
View File
@@ -15,7 +15,7 @@
INGROUP: MokoSuiteClient.Documentation
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
PATH: ./LICENSE.md
VERSION: 02.38.00
VERSION: 02.34.84
BRIEF: Project license (GPL-3.0-or-later)
-->
GNU GENERAL PUBLIC LICENSE
+3 -3
View File
@@ -12,10 +12,10 @@
# ==============================================================================
# Extension Configuration
EXTENSION_NAME := mokosuiteclient
EXTENSION_TYPE := package
EXTENSION_NAME := mokoexample
EXTENSION_TYPE := module
# Options: module, plugin, component, package, template
EXTENSION_VERSION := 02.35.00
EXTENSION_VERSION := 1.0.0
# Module Configuration (for modules only)
MODULE_TYPE := site
+1 -1
View File
@@ -9,7 +9,7 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /README.md
BRIEF: MokoSuiteClient platform plugin for Joomla
-->
+1 -1
View File
@@ -23,7 +23,7 @@ DEFGROUP: [PROJECT_NAME]
INGROUP: [PROJECT_NAME].Documentation
REPO: [REPOSITORY_URL]
PATH: /SECURITY.md
VERSION: 02.38.00
VERSION: 02.34.84
BRIEF: Security vulnerability reporting and handling policy
-->
+2 -2
View File
@@ -11,13 +11,13 @@
INGROUP: MokoSuiteClient.Build
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
FILE: build-guide.md
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/
BRIEF: Build and packaging guide for the MokoSuiteClient system plugin
NOTE: Defines environment setup, repository layout, packaging rules, and release preparation
-->
# MokoSuiteClient Build Guide (VERSION: 02.38.00)
# MokoSuiteClient Build Guide (VERSION: 02.34.84)
## 1. Purpose
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/configuration-guide.md
BRIEF: Configuration guide for the MokoSuiteClient system plugin
NOTE: Defines plugin parameters, expected behaviors, and recommended defaults
-->
# MokoSuiteClient Configuration Guide (VERSION: 02.38.00)
# MokoSuiteClient Configuration Guide (VERSION: 02.34.84)
## 1. Objective
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/installation-guide.md
BRIEF: Installation guide for the MokoSuiteClient system plugin
NOTE: First document in the guide set
-->
# MokoSuiteClient Installation Guide (VERSION: 02.38.00)
# MokoSuiteClient Installation Guide (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/operations-guide.md
BRIEF: Operational guide for administering and managing the MokoSuiteClient system plugin
NOTE: Defines lifecycle, responsibilities, and operational behaviors
-->
# MokoSuiteClient Operations Guide (VERSION: 02.38.00)
# MokoSuiteClient Operations Guide (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/rollback-and-recovery-guide.md
BRIEF: Rollback and recovery guide for restoring stable operation after plugin related incidents
NOTE: Completes the core guide set for Suite plugin governance
-->
# MokoSuiteClient Rollback and Recovery Guide (VERSION: 02.38.00)
# MokoSuiteClient Rollback and Recovery Guide (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -7,13 +7,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/testing-guide.md
BRIEF: Testing guide for MokoSuiteClient v02.01.08
NOTE: Covers manual test procedures for language overrides, install/uninstall, and configuration
-->
# MokoSuiteClient Testing Guide (VERSION: 02.38.00)
# MokoSuiteClient Testing Guide (VERSION: 02.34.84)
## 1. Prerequisites
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/troubleshooting-guide.md
BRIEF: Troubleshooting guide for diagnosing and resolving issues related to the MokoSuiteClient plugin
NOTE: Designed for administrators and Suite operations teams
-->
# MokoSuiteClient Troubleshooting Guide (VERSION: 02.38.00)
# MokoSuiteClient Troubleshooting Guide (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Guides
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/guides/upgrade-and-versioning-guide.md
BRIEF: Guide for updating, versioning, and maintaining the MokoSuiteClient plugin
NOTE: Defines release flow, version rules, and upgrade validation
-->
# MokoSuiteClient Upgrade and Versioning Guide (VERSION: 02.38.00)
# MokoSuiteClient Upgrade and Versioning Guide (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -10,13 +10,13 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoSuiteClient.Documentation
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
VERSION: 02.38.00
VERSION: 02.34.84
PATH: /docs/index.md
BRIEF: Master index of all documentation for the MokoSuiteClient plugin
NOTE: Automatically maintained index for all guide canvases
-->
# MokoSuiteClient Documentation Index (VERSION: 02.38.00)
# MokoSuiteClient Documentation Index (VERSION: 02.34.84)
## Introduction
+2 -2
View File
@@ -11,12 +11,12 @@
INGROUP: MokoSuiteClient
REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
PATH: /docs/plugin-basic.md
VERSION: 02.38.00
VERSION: 02.34.84
BRIEF: Baseline documentation for the MokoSuiteClient system plugin
NOTE: Foundational reference for internal and external stakeholders
-->
# MokoSuiteClient Plugin Overview (VERSION: 02.38.00)
# MokoSuiteClient Plugin Overview (VERSION: 02.34.84)
## Introduction
+1 -1
View File
@@ -10,7 +10,7 @@ DEFGROUP: MokoSuiteClient.Documentation
INGROUP: MokoStandards.Templates
REPO: https://github.com/mokoconsulting-tech/MokoSuiteClient
PATH: /docs/update-server.md
VERSION: 02.38.00
VERSION: 02.34.84
BRIEF: How this extension's Joomla update server file (update.xml) is managed
-->
@@ -35,7 +35,7 @@ class HtmlView extends BaseHtmlView
protected function addToolbar(): void
{
ToolbarHelper::title(Text::_('COM_MOKOSUITECLIENT_TICKET_SETTINGS'), 'cog');
ToolbarHelper::title(Text::_('COM_MOKOSUITE_TICKET_SETTINGS'), 'cog');
ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mokosuiteclient&view=tickets');
}
}
@@ -20,7 +20,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>MokoSuiteClient admin dashboard and REST API. Provides a control panel for managing MokoSuiteClient feature plugins, site health monitoring, and remote management endpoints.</description>
<namespace path="src">Moko\Component\MokoSuiteClient</namespace>
@@ -7,8 +7,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>MOD_MOKOSUITECLIENT_CACHE_DESC</description>
<version>02.34.84-dev</version>
<description>MOD_MOKOSUITE_CACHE_DESC</description>
<namespace path="src">Moko\Module\MokoSuiteCache</namespace>
<files>
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>MOD_MOKOSUITECLIENT_CATEGORIES_DESC</description>
<namespace path="src">Moko\Module\MokoSuiteClientCategories</namespace>
@@ -7,8 +7,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>MOD_MOKOSUITECLIENT_CPANEL_DESC</description>
<version>02.34.84-dev</version>
<description>MOD_MOKOSUITE_CPANEL_DESC</description>
<namespace path="src">Moko\Module\MokoSuiteCpanel</namespace>
<files>
@@ -25,64 +25,64 @@
<config>
<fields name="params">
<fieldset name="basic"
label="MOD_MOKOSUITECLIENT_CPANEL_FIELDSET_DISPLAY"
description="MOD_MOKOSUITECLIENT_CPANEL_FIELDSET_DISPLAY_DESC">
label="MOD_MOKOSUITE_CPANEL_FIELDSET_DISPLAY"
description="MOD_MOKOSUITE_CPANEL_FIELDSET_DISPLAY_DESC">
<field name="collapsed" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_COLLAPSED_LABEL"
description="MOD_MOKOSUITECLIENT_CPANEL_COLLAPSED_DESC"
label="MOD_MOKOSUITE_CPANEL_COLLAPSED_LABEL"
description="MOD_MOKOSUITE_CPANEL_COLLAPSED_DESC"
layout="joomla.form.field.radio.switcher">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="show_health" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_HEALTH_LABEL"
label="MOD_MOKOSUITE_CPANEL_SHOW_HEALTH_LABEL"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_stats" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_STATS_LABEL"
description="MOD_MOKOSUITECLIENT_CPANEL_SHOW_STATS_DESC"
label="MOD_MOKOSUITE_CPANEL_SHOW_STATS_LABEL"
description="MOD_MOKOSUITE_CPANEL_SHOW_STATS_DESC"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_disk" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_DISK_LABEL"
label="MOD_MOKOSUITE_CPANEL_SHOW_DISK_LABEL"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_ip" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_IP_LABEL"
label="MOD_MOKOSUITE_CPANEL_SHOW_IP_LABEL"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_plugins" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_PLUGINS_LABEL"
label="MOD_MOKOSUITE_CPANEL_SHOW_PLUGINS_LABEL"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_actions" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_ACTIONS_LABEL"
description="MOD_MOKOSUITECLIENT_CPANEL_SHOW_ACTIONS_DESC"
label="MOD_MOKOSUITE_CPANEL_SHOW_ACTIONS_LABEL"
description="MOD_MOKOSUITE_CPANEL_SHOW_ACTIONS_DESC"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field name="show_versions" type="radio" default="1"
label="MOD_MOKOSUITECLIENT_CPANEL_SHOW_VERSIONS_LABEL"
description="MOD_MOKOSUITECLIENT_CPANEL_SHOW_VERSIONS_DESC"
label="MOD_MOKOSUITE_CPANEL_SHOW_VERSIONS_LABEL"
description="MOD_MOKOSUITE_CPANEL_SHOW_VERSIONS_DESC"
layout="joomla.form.field.radio.switcher">
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>MokoSuiteClient admin sidebar menu — renders a dedicated MokoSuiteClient section in the admin menu before Joomla's default menu.</description>
<namespace path="src">Moko\Module\MokoSuiteClientMenu</namespace>
@@ -22,7 +22,7 @@
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoSuiteClient
* REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
* VERSION: 02.38.00
* VERSION: 02.34.84
* PATH: /src/Extension/MokoSuiteClient.php
* NOTE: Core system plugin for MokoSuiteClient admin tools suite
*/
@@ -8,7 +8,7 @@
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoSuiteClient
* VERSION: 02.38.00
* VERSION: 02.34.84
* PATH: /src/Field/CopyableTokenField.php
* BRIEF: Read-only token field with a copy-to-clipboard button
*/
@@ -30,7 +30,7 @@
<license>GNU General Public License version 3 or later; see LICENSE.md</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>MokoSuiteClient core system plugin — coordinates feature plugins, heartbeat, health checks, and admin customizations.</description>
<namespace path=".">Moko\Plugin\System\MokoSuiteClient</namespace>
<scriptfile>script.php</scriptfile>
@@ -68,13 +68,13 @@
addfieldprefix="Moko\Plugin\System\MokoSuiteClient\Field"
>
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIELDSET_CORE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIELDSET_CORE_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIELDSET_CORE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIELDSET_CORE_DESC">
<field
name="health_api_token"
type="CopyableToken"
label="PLG_SYSTEM_MOKOSUITECLIENT_HEALTH_TOKEN_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_HEALTH_TOKEN_DESC"
label="PLG_SYSTEM_MOKOSUITE_HEALTH_TOKEN_LABEL"
description="PLG_SYSTEM_MOKOSUITE_HEALTH_TOKEN_DESC"
default=""
filter="raw"
readonly="true"
@@ -22,7 +22,7 @@
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoSuiteClient
* REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
* VERSION: 02.38.00
* VERSION: 02.34.84
* PATH: /src/script.php
* BRIEF: Installation script for MokoSuiteClient plugin
* NOTE: Handles installation, update, and uninstallation tasks including language override deployment
@@ -767,7 +767,7 @@ class plgSystemMokoSuiteClientInstallerScript implements InstallerScriptInterfac
'id_holder' => '',
'title_holder' => '',
'table_name' => '',
'text_prefix' => 'PLG_SYSTEM_MOKOSUITECLIENT',
'text_prefix' => 'PLG_SYSTEM_MOKOSUITE',
];
$db->insertObject('#__action_log_config', $config);
@@ -22,7 +22,7 @@
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoSuiteClient
* REPO: https://github.com/mokoconsulting-tech/mokosuiteclient
* VERSION: 02.38.00
* VERSION: 02.34.84
* PATH: /src/services/provider.php
* BRIEF: Service provider for dependency injection in Joomla 5.x
* NOTE: Registers the plugin with Joomla's DI container
@@ -0,0 +1,13 @@
; MokoSuiteClient Backup Bridge Plugin
; Copyright (C) 2026 Moko Consulting. All rights reserved.
; License: GPL-3.0-or-later
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP="System - MokoSuiteClient Backup"
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC="Detects MokoSuiteBackup and includes backup status in heartbeat payloads sent to MokoSuiteHQ."
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC="Backup Monitoring"
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC_DESC="Configure backup status collection for heartbeat reporting."
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_LABEL="Include in Heartbeat"
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_DESC="Include MokoSuiteBackup status data in heartbeat payloads sent to MokoSuiteHQ."
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_LABEL="Stale Backup Threshold (days)"
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_DESC="Number of days without a backup before status is marked as degraded. Default: 7."
@@ -0,0 +1,3 @@
; MokoSuiteClient Backup Bridge Plugin - System strings
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP="System - MokoSuiteClient Backup"
PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC="MokoSuiteBackup detection and heartbeat integration."
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoSuiteClient Backup</name>
<element>mokosuiteclient_backup</element>
<author>Moko Consulting</author>
<creationDate>2026-06-18</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientBackup</namespace>
<files>
<folder>src</folder>
<folder>services</folder>
<folder>language</folder>
</files>
<languages folder="language">
<language tag="en-GB">en-GB/plg_system_mokosuiteclient_backup.ini</language>
<language tag="en-GB">en-GB/plg_system_mokosuiteclient_backup.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC_DESC">
<field name="heartbeat_enabled" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="stale_days" type="number" default="7"
label="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_DESC"
min="1" max="90" step="1" />
</fieldset>
</fields>
</config>
</extension>
@@ -0,0 +1,34 @@
<?php
/**
* @package MokoSuiteClient
* @subpackage plg_system_mokosuiteclient_backup
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*/
defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Moko\Plugin\System\MokoSuiteClientBackup\Extension\Backup;
return new class implements ServiceProviderInterface
{
public function register(Container $container): void
{
$container->set(
PluginInterface::class,
function (Container $container) {
$dispatcher = $container->get(DispatcherInterface::class);
$plugin = new Backup($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuiteclient_backup'));
$plugin->setApplication(Factory::getApplication());
return $plugin;
}
);
}
};
@@ -0,0 +1,263 @@
<?php
/**
* @package MokoSuiteClient
* @subpackage plg_system_mokosuiteclient_backup
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*/
namespace Moko\Plugin\System\MokoSuiteClientBackup\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Database\DatabaseInterface;
use Joomla\Event\SubscriberInterface;
/**
* MokoSuiteClient Backup Bridge Plugin
*
* Detects whether MokoSuiteBackup is installed and collects backup
* status data for inclusion in heartbeat payloads to MokoSuiteHQ.
*
* Prefers MokoSuiteBackup's own BackupStatusHelper when available,
* falling back to a direct table query if the helper class is missing
* (e.g. older versions of MokoSuiteBackup).
*
* @since 02.34.84
*/
class Backup extends CMSPlugin implements SubscriberInterface
{
protected $autoloadLanguage = true;
public static function getSubscribedEvents(): array
{
return [
'onMokoSuiteClientCollectHeartbeat' => 'onCollectHeartbeat',
];
}
/**
* Collect backup status data for the heartbeat payload.
*
* Triggered by the monitor plugin before sending a heartbeat.
* Appends a 'backup' key to the heartbeat data array.
*/
public function onCollectHeartbeat($event): void
{
if (!$this->params->get('heartbeat_enabled', 1))
{
return;
}
try
{
$data = $this->getBackupStatus();
$event->addResult('backup', $data);
}
catch (\Throwable $e)
{
Log::add('Backup bridge: ' . $e->getMessage(), Log::WARNING, 'mokosuiteclient');
// Send explicit error so HQ knows collection failed,
// rather than interpreting absence as "not installed"
$event->addResult('backup', [
'installed' => true,
'status' => 'error',
'message' => 'Failed to collect backup status',
]);
}
}
/**
* Check if MokoSuiteBackup is installed.
*
* Queries the extensions table for the component, which is more
* reliable than checking for database tables alone.
*/
public function isBackupInstalled(): bool
{
try
{
$db = Factory::getContainer()->get(DatabaseInterface::class);
$query = $db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__extensions'))
->where($db->quoteName('element') . ' = ' . $db->quote('com_mokosuitebackup'))
->where($db->quoteName('type') . ' = ' . $db->quote('component'));
$db->setQuery($query);
return (int) $db->loadResult() > 0;
}
catch (\Throwable $e)
{
return false;
}
}
/**
* Get backup status summary from MokoSuiteBackup.
*
* Prefers the BackupStatusHelper API when available. Falls back
* to a direct database query for compatibility with older versions.
*
* @return array Backup status data for heartbeat inclusion.
*/
public function getBackupStatus(): array
{
if (!$this->isBackupInstalled())
{
return [
'installed' => false,
'status' => 'ok',
];
}
// Prefer MokoSuiteBackup's own helper (clean public API)
$helperClass = 'Joomla\\Component\\MokoSuiteBackup\\Administrator\\Utility\\BackupStatusHelper';
if (class_exists($helperClass))
{
$staleDays = (int) $this->params->get('stale_days', 7);
return $helperClass::getStatus($staleDays);
}
// Fallback: direct table query for older MokoSuiteBackup versions
$db = Factory::getContainer()->get(DatabaseInterface::class);
$tables = $db->getTableList();
$prefix = $db->getPrefix();
if (!in_array($prefix . 'mokosuitebackup_records', $tables, true))
{
return [
'installed' => true,
'status' => 'degraded',
'message' => 'Backup tables not found',
];
}
return $this->queryBackupRecords($db);
}
/**
* Query MokoSuiteBackup records for the latest backup summary.
*
* Column names match the MokoSuiteBackup schema:
* - backupstart/backupend (not created/modified)
* - status: pending, running, complete, fail
* - total_size in bytes
*
* @param DatabaseInterface $db Database driver.
*
* @return array Backup status array.
*/
private function queryBackupRecords(DatabaseInterface $db): array
{
$staleDays = (int) $this->params->get('stale_days', 7);
// Most recent backup record
$query = $db->getQuery(true)
->select([
$db->quoteName('id'),
$db->quoteName('description'),
$db->quoteName('status'),
$db->quoteName('backup_type'),
$db->quoteName('total_size'),
$db->quoteName('backupstart'),
$db->quoteName('backupend'),
$db->quoteName('origin'),
$db->quoteName('filesexist'),
])
->from($db->quoteName('#__mokosuitebackup_records'))
->order($db->quoteName('id') . ' DESC');
$db->setQuery($query, 0, 1);
$latest = $db->loadObject();
if (!$latest)
{
return [
'installed' => true,
'status' => 'degraded',
'message' => 'No backups found',
];
}
// Count completed backups
$db->setQuery(
$db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__mokosuitebackup_records'))
->where($db->quoteName('status') . ' = ' . $db->quote('complete'))
);
$totalBackups = (int) $db->loadResult();
$cutoff = date('Y-m-d H:i:s', strtotime("-{$staleDays} days"));
$db->setQuery(
$db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__mokosuitebackup_records'))
->where($db->quoteName('status') . ' = ' . $db->quote('complete'))
->where($db->quoteName('backupstart') . ' >= ' . $db->quote($cutoff))
);
$recentBackups = (int) $db->loadResult();
// Failures in last 7 days
$db->setQuery(
$db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__mokosuitebackup_records'))
->where($db->quoteName('status') . ' = ' . $db->quote('fail'))
->where($db->quoteName('backupstart') . ' >= ' . $db->quote($cutoff))
);
$failCount7d = (int) $db->loadResult();
// Determine status
$daysSince = 999;
if (!empty($latest->backupstart) && $latest->backupstart !== '0000-00-00 00:00:00')
{
$daysSince = (int) ((time() - strtotime($latest->backupstart)) / 86400);
}
$status = 'ok';
if ($latest->status === 'fail')
{
$status = 'degraded';
}
elseif ($latest->status !== 'complete')
{
$status = ($latest->status === 'running') ? 'ok' : 'degraded';
}
elseif ($daysSince > $staleDays)
{
$status = 'degraded';
}
$sizeMb = $latest->total_size
? round($latest->total_size / 1048576)
: null;
return [
'installed' => true,
'status' => $status,
'last_backup' => $latest->backupstart,
'last_status' => $latest->status,
'last_size_mb' => $sizeMb,
'days_since' => $daysSince,
'backup_type' => $latest->backup_type,
'origin' => $latest->origin,
'total_backups' => $totalBackups,
'recent_7d' => $recentBackups,
'fail_count_7d' => $failCount7d,
'files_exist' => (bool) $latest->filesexist,
'description' => $latest->description,
];
}
}
@@ -3,27 +3,27 @@
; License: GPL-3.0-or-later
; IP Geolocation by DB-IP — https://db-ip.com
PLG_SYSTEM_MOKOSUITECLIENT_DBIP="System - MokoSuiteClient DB-IP"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DESC="IP geolocation for MokoSuiteClient using DB-IP Lite databases. Ships with country-level data; city-level data is downloaded from CDN or loaded from a local file."
PLG_SYSTEM_MOKOSUITE_DBIP="System - MokoSuiteClient DB-IP"
PLG_SYSTEM_MOKOSUITE_DBIP_DESC="IP geolocation for MokoSuiteClient using DB-IP Lite databases. Ships with country-level data; city-level data is downloaded from CDN or loaded from a local file."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_FIELDSET_BASIC="DB-IP Settings"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_FIELDSET_BASIC_DESC="Configure IP geolocation database source and level."
PLG_SYSTEM_MOKOSUITE_DBIP_FIELDSET_BASIC="DB-IP Settings"
PLG_SYSTEM_MOKOSUITE_DBIP_FIELDSET_BASIC_DESC="Configure IP geolocation database source and level."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_LABEL="Database Source"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_DESC="CDN downloads the city database automatically from the configured URL. Local uses a MMDB file you provide on the server."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_CDN="CDN (auto-download)"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_LOCAL="Local file"
PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_LABEL="Database Source"
PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_DESC="CDN downloads the city database automatically from the configured URL. Local uses a MMDB file you provide on the server."
PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_CDN="CDN (auto-download)"
PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_LOCAL="Local file"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_LEVEL_LABEL="Database Level"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_LEVEL_DESC="Country is bundled (~8 MB). City provides region, city, and coordinates but requires a separate download (~125 MB)."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_COUNTRY="Country (bundled)"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_CITY="City (remote download)"
PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_LEVEL_LABEL="Database Level"
PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_LEVEL_DESC="Country is bundled (~8 MB). City provides region, city, and coordinates but requires a separate download (~125 MB)."
PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_COUNTRY="Country (bundled)"
PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_CITY="City (remote download)"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_AUTO_UPDATE_LABEL="Auto-Update Database"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_AUTO_UPDATE_DESC="Automatically download the latest city database monthly when an admin visits the backend."
PLG_SYSTEM_MOKOSUITE_DBIP_AUTO_UPDATE_LABEL="Auto-Update Database"
PLG_SYSTEM_MOKOSUITE_DBIP_AUTO_UPDATE_DESC="Automatically download the latest city database monthly when an admin visits the backend."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_CDN_URL_LABEL="CDN Download URL"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_CDN_URL_DESC="URL to download the city-level MMDB file. Default points to the MokoConsulting geoip-data repository."
PLG_SYSTEM_MOKOSUITE_DBIP_CDN_URL_LABEL="CDN Download URL"
PLG_SYSTEM_MOKOSUITE_DBIP_CDN_URL_DESC="URL to download the city-level MMDB file. Default points to the MokoConsulting geoip-data repository."
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_LOCAL_PATH_LABEL="Local MMDB Path"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_LOCAL_PATH_DESC="Absolute path to a DB-IP MMDB file on the server (e.g. /home/user/dbip-city-lite.mmdb)."
PLG_SYSTEM_MOKOSUITE_DBIP_LOCAL_PATH_LABEL="Local MMDB Path"
PLG_SYSTEM_MOKOSUITE_DBIP_LOCAL_PATH_DESC="Absolute path to a DB-IP MMDB file on the server (e.g. /home/user/dbip-city-lite.mmdb)."
@@ -2,5 +2,5 @@
; Copyright (C) 2026 Moko Consulting. All rights reserved.
; License: GPL-3.0-or-later
PLG_SYSTEM_MOKOSUITECLIENT_DBIP="System - MokoSuiteClient DB-IP"
PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DESC="IP geolocation for MokoSuiteClient using DB-IP Lite databases."
PLG_SYSTEM_MOKOSUITE_DBIP="System - MokoSuiteClient DB-IP"
PLG_SYSTEM_MOKOSUITE_DBIP_DESC="IP geolocation for MokoSuiteClient using DB-IP Lite databases."
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_DBIP_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientDBIP</namespace>
<files>
@@ -28,26 +28,26 @@
<config>
<fields name="params">
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_FIELDSET_BASIC_DESC">
label="PLG_SYSTEM_MOKOSUITE_DBIP_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITE_DBIP_FIELDSET_BASIC_DESC">
<field name="database_source" type="list" default="cdn"
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_DESC">
<option value="cdn">PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_CDN</option>
<option value="local">PLG_SYSTEM_MOKOSUITECLIENT_DBIP_SOURCE_LOCAL</option>
label="PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_DESC">
<option value="cdn">PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_CDN</option>
<option value="local">PLG_SYSTEM_MOKOSUITE_DBIP_SOURCE_LOCAL</option>
</field>
<field name="database_level" type="list" default="country"
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_LEVEL_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_LEVEL_DESC">
<option value="country">PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_COUNTRY</option>
<option value="city">PLG_SYSTEM_MOKOSUITECLIENT_DBIP_DATABASE_CITY</option>
label="PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_LEVEL_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_LEVEL_DESC">
<option value="country">PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_COUNTRY</option>
<option value="city">PLG_SYSTEM_MOKOSUITE_DBIP_DATABASE_CITY</option>
</field>
<field name="auto_update" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_AUTO_UPDATE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_AUTO_UPDATE_DESC"
label="PLG_SYSTEM_MOKOSUITE_DBIP_AUTO_UPDATE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DBIP_AUTO_UPDATE_DESC"
class="btn-group btn-group-yesno"
showon="database_source:cdn">
<option value="1">JYES</option>
@@ -56,15 +56,15 @@
<field name="cdn_url" type="url"
default="https://git.mokoconsulting.tech/MokoConsulting/geoip-data/releases/download/latest/dbip-city-lite.mmdb"
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_CDN_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_CDN_URL_DESC"
label="PLG_SYSTEM_MOKOSUITE_DBIP_CDN_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DBIP_CDN_URL_DESC"
filter="url"
showon="database_source:cdn" />
<field name="local_path" type="text"
default=""
label="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_LOCAL_PATH_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DBIP_LOCAL_PATH_DESC"
label="PLG_SYSTEM_MOKOSUITE_DBIP_LOCAL_PATH_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DBIP_LOCAL_PATH_DESC"
filter="path"
showon="database_source:local" />
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_DEVTOOLS_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientDevTools</namespace>
<files>
@@ -26,36 +26,36 @@
<config>
<fields name="params">
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_FIELDSET_BASIC_DESC">
label="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_FIELDSET_BASIC_DESC">
<field name="dev_mode" type="radio" default="0"
label="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DEV_MODE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DEV_MODE_DESC"
label="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_DEV_MODE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_DEV_MODE_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="reset_hits" type="radio" default="0"
label="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_RESET_HITS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_RESET_HITS_DESC"
label="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_RESET_HITS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_RESET_HITS_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="delete_versions" type="radio" default="0"
label="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DELETE_VERSIONS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_DELETE_VERSIONS_DESC"
label="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_DELETE_VERSIONS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_DELETE_VERSIONS_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="reset_download_keys" type="radio" default="0"
label="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_RESET_DLKEYS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_DEVTOOLS_RESET_DLKEYS_DESC"
label="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_RESET_DLKEYS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_DEVTOOLS_RESET_DLKEYS_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_FIREWALL_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientFirewall</namespace>
<files>
@@ -36,25 +36,25 @@
<fields name="params">
<!-- Network & Session -->
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_BASIC_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_BASIC_DESC">
<field name="force_https" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FORCE_HTTPS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FORCE_HTTPS_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FORCE_HTTPS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FORCE_HTTPS_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="admin_session_timeout" type="number"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_SESSION_TIMEOUT_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_SESSION_TIMEOUT_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_SESSION_TIMEOUT_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_SESSION_TIMEOUT_DESC"
default="60" hint="Minutes (0 = Joomla default)" />
<field name="trusted_ips" type="subform"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_TRUSTED_IPS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_TRUSTED_IPS_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_TRUSTED_IPS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_TRUSTED_IPS_DESC"
formsource="plugins/system/mokosuiteclient_firewall/forms/trusted_ip_entry.xml"
multiple="true"
layout="joomla.form.field.subform.repeatable-table"
@@ -64,20 +64,20 @@
<!-- WAF Shields -->
<fieldset name="waf"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_WAF"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_WAF_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_WAF"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_WAF_DESC">
<field name="waf_enabled" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_ENABLED_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_ENABLED_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_ENABLED_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_ENABLED_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="waf_sqli" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_SQLI_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_SQLI_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_SQLI_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_SQLI_DESC"
class="btn-group btn-group-yesno"
showon="waf_enabled:1">
<option value="1">JYES</option>
@@ -85,8 +85,8 @@
</field>
<field name="waf_xss" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_XSS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_XSS_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_XSS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_XSS_DESC"
class="btn-group btn-group-yesno"
showon="waf_enabled:1">
<option value="1">JYES</option>
@@ -94,8 +94,8 @@
</field>
<field name="waf_mua" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_MUA_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_MUA_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_MUA_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_MUA_DESC"
class="btn-group btn-group-yesno"
showon="waf_enabled:1">
<option value="1">JYES</option>
@@ -103,15 +103,15 @@
</field>
<field name="waf_mua_blocklist" type="textarea"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_MUA_LIST_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_MUA_LIST_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_MUA_LIST_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_MUA_LIST_DESC"
rows="4" filter="raw"
default="sqlmap,nikto,nmap,havij,w3af,acunetix,nessus,openvas,masscan,gobuster,dirbuster,wpscan,joomscan"
showon="waf_enabled:1[AND]waf_mua:1" />
<field name="waf_rfi" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_RFI_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_RFI_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_RFI_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_RFI_DESC"
class="btn-group btn-group-yesno"
showon="waf_enabled:1">
<option value="1">JYES</option>
@@ -119,8 +119,8 @@
</field>
<field name="waf_dfi" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_DFI_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_WAF_DFI_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_DFI_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_WAF_DFI_DESC"
class="btn-group btn-group-yesno"
showon="waf_enabled:1">
<option value="1">JYES</option>
@@ -130,8 +130,8 @@
<!-- Security Headers -->
<fieldset name="headers"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_HEADERS"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_HEADERS_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_HEADERS"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_HEADERS_DESC">
<field name="header_xframe" type="radio" default="1"
label="X-Frame-Options" description="Clickjacking protection (SAMEORIGIN)"
@@ -177,12 +177,12 @@
<!-- Access Control -->
<fieldset name="access_control"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_ACCESS"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_ACCESS_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_ACCESS"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_ACCESS_DESC">
<field name="ip_blocklist" type="subform"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_IP_BLOCKLIST_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_IP_BLOCKLIST_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_IP_BLOCKLIST_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_IP_BLOCKLIST_DESC"
formsource="plugins/system/mokosuiteclient_firewall/forms/trusted_ip_entry.xml"
multiple="true"
layout="joomla.form.field.subform.repeatable-table"
@@ -190,13 +190,13 @@
buttons="add,remove,move" />
<field name="admin_secret" type="text"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_ADMIN_SECRET_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_ADMIN_SECRET_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_ADMIN_SECRET_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_ADMIN_SECRET_DESC"
default="" filter="raw" hint="Leave empty to disable" />
<field name="admin_secret_redirect" type="text"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_ADMIN_SECRET_REDIRECT_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_ADMIN_SECRET_REDIRECT_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_ADMIN_SECRET_REDIRECT_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_ADMIN_SECRET_REDIRECT_DESC"
default="" filter="url" hint="Empty = 403 Forbidden"
showon="admin_secret!:" />
@@ -211,8 +211,8 @@
showon="autoban_threshold!:0" />
<field name="block_frontend_superuser" type="radio" default="0"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_FE_SU_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_FE_SU_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_FE_SU_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_FE_SU_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -221,28 +221,28 @@
<!-- File & Template Protection -->
<fieldset name="protection"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_PROTECTION"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_PROTECTION_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_PROTECTION"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_PROTECTION_DESC">
<field name="block_sensitive_files" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_FILES_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_FILES_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_FILES_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_FILES_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="block_direct_php" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_PHP_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_PHP_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_PHP_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_PHP_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="block_template_switch" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_TMPL_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_BLOCK_TMPL_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_TMPL_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_BLOCK_TMPL_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -251,29 +251,29 @@
<!-- Password Policy -->
<fieldset name="password_policy"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_PASSWORD"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_PASSWORD_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_PASSWORD"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_PASSWORD_DESC">
<field name="password_min_length" type="number" default="12"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_PASSWORD_LENGTH_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_PASSWORD_LENGTH_DESC" />
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_PASSWORD_LENGTH_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_PASSWORD_LENGTH_DESC" />
<field name="password_require_uppercase" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_PASSWORD_UPPER_LABEL"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_PASSWORD_UPPER_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="password_require_number" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_PASSWORD_NUMBER_LABEL"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_PASSWORD_NUMBER_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="password_require_special" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_PASSWORD_SPECIAL_LABEL"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_PASSWORD_SPECIAL_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -282,17 +282,17 @@
<!-- Upload Restrictions -->
<fieldset name="uploads"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_UPLOADS"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_FIELDSET_UPLOADS_DESC">
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_UPLOADS"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_FIELDSET_UPLOADS_DESC">
<field name="upload_allowed_types" type="text"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_UPLOAD_TYPES_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_UPLOAD_TYPES_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_UPLOAD_TYPES_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_UPLOAD_TYPES_DESC"
default="jpg,jpeg,png,gif,webp,svg,pdf,doc,docx,xls,xlsx" />
<field name="upload_max_size_mb" type="number"
label="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_UPLOAD_SIZE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_FIREWALL_UPLOAD_SIZE_DESC"
label="PLG_SYSTEM_MOKOSUITE_FIREWALL_UPLOAD_SIZE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_FIREWALL_UPLOAD_SIZE_DESC"
default="100" />
</fieldset>
</fields>
@@ -8,7 +8,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_LICENSE_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientLicense</namespace>
<files><folder>src</folder><folder>services</folder><folder>language</folder></files>
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_MONITOR_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientMonitor</namespace>
<files>
@@ -26,12 +26,12 @@
<config>
<fields name="params">
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_FIELDSET_BASIC_DESC">
label="PLG_SYSTEM_MOKOSUITE_MONITOR_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITE_MONITOR_FIELDSET_BASIC_DESC">
<field name="heartbeat_enabled" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_HEARTBEAT_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_HEARTBEAT_DESC"
label="PLG_SYSTEM_MOKOSUITE_MONITOR_HEARTBEAT_LABEL"
description="PLG_SYSTEM_MOKOSUITE_MONITOR_HEARTBEAT_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -39,8 +39,8 @@
<field name="base_url" type="url"
default="https://waas.dev.mokoconsulting.tech"
label="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_BASE_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_MONITOR_BASE_URL_DESC"
label="PLG_SYSTEM_MOKOSUITE_MONITOR_BASE_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITE_MONITOR_BASE_URL_DESC"
filter="url" />
<field name="signing_key" type="hidden"
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_OFFLINE_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientOffline</namespace>
<files>
@@ -25,15 +25,15 @@
<config>
<fields name="params" addfieldprefix="Moko\Plugin\System\MokoSuiteClientOffline\Field">
<fieldset name="basic" label="PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_FIELDSET_BASIC">
<fieldset name="basic" label="PLG_SYSTEM_MOKOSUITE_OFFLINE_FIELDSET_BASIC">
<field name="tos_slug" type="menuslug"
label="PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_SLUG_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_SLUG_DESC"
label="PLG_SYSTEM_MOKOSUITE_OFFLINE_SLUG_LABEL"
description="PLG_SYSTEM_MOKOSUITE_OFFLINE_SLUG_DESC"
multiple="true" />
<field name="include_children" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_CHILDREN_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_OFFLINE_CHILDREN_DESC"
label="PLG_SYSTEM_MOKOSUITE_OFFLINE_CHILDREN_LABEL"
description="PLG_SYSTEM_MOKOSUITE_OFFLINE_CHILDREN_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
@@ -8,8 +8,8 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_SYSTEM_MOKOSUITECLIENT_TENANT_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_SYSTEM_MOKOSUITE_TENANT_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteClientTenant</namespace>
<files>
@@ -26,20 +26,20 @@
<config>
<fields name="params">
<fieldset name="basic"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_FIELDSET_BASIC_DESC">
label="PLG_SYSTEM_MOKOSUITE_TENANT_FIELDSET_BASIC"
description="PLG_SYSTEM_MOKOSUITE_TENANT_FIELDSET_BASIC_DESC">
<field name="restrict_installer" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_INSTALLER_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_INSTALLER_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_INSTALLER_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_INSTALLER_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="allow_extension_updates" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_ALLOW_UPDATES_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_ALLOW_UPDATES_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_ALLOW_UPDATES_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_ALLOW_UPDATES_DESC"
class="btn-group btn-group-yesno"
showon="restrict_installer:1">
<option value="1">JYES</option>
@@ -47,40 +47,40 @@
</field>
<field name="hide_sysinfo" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_HIDE_SYSINFO_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_HIDE_SYSINFO_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_HIDE_SYSINFO_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_HIDE_SYSINFO_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="restrict_global_config" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_CONFIG_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_CONFIG_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_CONFIG_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_CONFIG_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="restrict_template_editing" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_TEMPLATE_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_RESTRICT_TEMPLATE_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_TEMPLATE_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_RESTRICT_TEMPLATE_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="disable_install_url" type="radio" default="1"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_DISABLE_INSTALL_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_DISABLE_INSTALL_URL_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_DISABLE_INSTALL_URL_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_DISABLE_INSTALL_URL_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="hidden_menu_items" type="textarea"
label="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_HIDDEN_MENUS_LABEL"
description="PLG_SYSTEM_MOKOSUITECLIENT_TENANT_HIDDEN_MENUS_DESC"
label="PLG_SYSTEM_MOKOSUITE_TENANT_HIDDEN_MENUS_LABEL"
description="PLG_SYSTEM_MOKOSUITE_TENANT_HIDDEN_MENUS_DESC"
rows="5" filter="raw" />
</fieldset>
</fields>
@@ -8,7 +8,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>Runs scheduled helpdesk automation rules — auto-close resolved tickets, SLA breach escalation, and time-based actions.</description>
<namespace path="src">Moko\Plugin\Task\MokoSuiteClientTickets</namespace>
@@ -27,15 +27,15 @@ class TicketAutomation extends CMSPlugin implements SubscriberInterface
protected const TASKS_MAP = [
'mokosuiteclient.ticket.automation' => [
'langConstPrefix' => 'PLG_TASK_MOKOSUITECLIENT_TICKETS_AUTOMATION',
'langConstPrefix' => 'PLG_TASK_MOKOSUITE_TICKETS_AUTOMATION',
'method' => 'runAutomation',
],
'mokosuiteclient.ticket.imap_poll' => [
'langConstPrefix' => 'PLG_TASK_MOKOSUITECLIENT_TICKETS_IMAP_POLL',
'langConstPrefix' => 'PLG_TASK_MOKOSUITE_TICKETS_IMAP_POLL',
'method' => 'runImapPoll',
],
'mokosuiteclient.ticket.autoclose' => [
'langConstPrefix' => 'PLG_TASK_MOKOSUITECLIENT_TICKETS_AUTOCLOSE',
'langConstPrefix' => 'PLG_TASK_MOKOSUITE_TICKETS_AUTOCLOSE',
'method' => 'runAutoClose',
],
];
@@ -12,8 +12,8 @@
<license>GNU General Public License version 3 or later; see LICENSE</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_TASK_MOKOSUITECLIENTDEMO_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_TASK_MOKOSUITEDEMO_DESC</description>
<namespace path="src">Moko\Plugin\Task\MokoSuiteClientDemo</namespace>
<files>
@@ -10,7 +10,7 @@
* INGROUP: MokoSuiteClient
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient
* PATH: /src/packages/plg_system_mokosuiteclient/Service/DemoResetService.php
* VERSION: 02.38.00
* VERSION: 02.34.84
* BRIEF: Content-only snapshot/restore for demo site reset
*/
@@ -12,8 +12,8 @@
<license>GNU General Public License version 3 or later; see LICENSE</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<description>PLG_TASK_MOKOSUITECLIENTSYNC_DESC</description>
<version>02.34.84-dev</version>
<description>PLG_TASK_MOKOSUITESYNC_DESC</description>
<namespace path="src">Moko\Plugin\Task\MokoSuiteClientSync</namespace>
<files>
@@ -10,7 +10,7 @@
* INGROUP: MokoSuiteClient
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient
* PATH: /src/packages/plg_system_mokosuiteclient/Service/ContentSyncReceiver.php
* VERSION: 02.38.00
* VERSION: 02.34.84
* BRIEF: Receiver-side content sync — applies incoming payload to local DB
*/
@@ -10,7 +10,7 @@
* INGROUP: MokoSuiteClient
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteClient
* PATH: /src/packages/plg_system_mokosuiteclient/Service/ContentSyncService.php
* VERSION: 02.38.00
* VERSION: 02.34.84
* BRIEF: Sender-side content sync — builds payload and pushes to remote sites
*/
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<description>Joomla Web Services API routes for MokoSuiteClient site management — health checks, cache, updates, backups, and site info.</description>
<namespace path="src">Moko\Plugin\WebServices\MokoSuiteClient</namespace>
<files>
+2 -1
View File
@@ -2,7 +2,7 @@
<extension type="package" method="upgrade">
<name>Package - MokoSuiteClient</name>
<packagename>mokosuiteclient</packagename>
<version>02.38.00-rc</version>
<version>02.34.84-dev</version>
<creationDate>2026-06-02</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -25,6 +25,7 @@
<file type="module" id="mod_mokosuiteclient_menu" client="administrator">mod_mokosuiteclient_menu.zip</file>
<file type="module" id="mod_mokosuiteclient_cache" client="administrator">mod_mokosuiteclient_cache.zip</file>
<file type="module" id="mod_mokosuiteclient_categories" client="administrator">mod_mokosuiteclient_categories.zip</file>
<file type="plugin" id="plg_system_mokosuiteclient_backup" group="system">plg_system_mokosuiteclient_backup.zip</file>
<file type="plugin" id="plg_webservices_mokosuiteclient" group="webservices">plg_webservices_mokosuiteclient.zip</file>
<file type="plugin" id="plg_task_mokosuiteclientdemo" group="task">plg_task_mokosuiteclientdemo.zip</file>
<file type="plugin" id="plg_task_mokosuiteclientsync" group="task">plg_task_mokosuiteclientsync.zip</file>
+1 -2
View File
@@ -20,7 +20,7 @@ use Joomla\CMS\Log\Log;
*
* @since 2.2.0
*/
class Pkg_MokosuiteclientInstallerScript
class Pkg_MokosuiteInstallerScript
{
/**
* Runs after package installation/update.
@@ -78,7 +78,6 @@ class Pkg_MokosuiteclientInstallerScript
$this->enablePlugin('system', 'mokosuiteclient_devtools');
$this->enablePlugin('system', 'mokosuiteclient_offline');
$this->enablePlugin('system', 'mokosuiteclient_dbip');
$this->enablePlugin('system', 'mokosuiteclient_monitor');
$this->enablePlugin('webservices', 'mokosuiteclient');
$this->enablePlugin('task', 'mokosuiteclientdemo');
$this->enablePlugin('task', 'mokosuiteclientsync');
+48
View File
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-LICENSE-IDENTIFIER: GPL-3.0-or-later
FILE INFORMATION
DEFGROUP: Joomla.Component
INGROUP: MokoWaaS
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS
VERSION: 02.34.84
PATH: /mokowaas.xml
BRIEF: Component manifest for MokoWaaS admin dashboard and REST API
-->
<extension type="component" method="upgrade">
<name>MokoWaaS</name>
<author>Moko Consulting</author>
<creationDate>2026-06-02</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.34.00</version>
<description>MokoWaaS admin dashboard and REST API. Provides a control panel for managing MokoWaaS feature plugins, site health monitoring, and remote management endpoints.</description>
<namespace path="src">Moko\Component\MokoWaaS</namespace>
<administration>
<menu img="class:cogs">MokoWaaS</menu>
<files folder="admin">
<folder>language</folder>
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
</administration>
<api>
<files folder="api">
<folder>src</folder>
</files>
</api>
<media destination="com_mokowaas" folder="media">
<folder>css</folder>
<folder>js</folder>
</media>
</extension>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
<?php
/**
* Copyright (C) 2025 Moko Consulting <hello@mokoconsulting.tech>
*
* SPDX-LICENSE-IDENTIFIER: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.34.84
* PATH: /src/Field/AllowedIpsField.php
* BRIEF: Custom form field that displays the current IP whitelist
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
class AllowedIpsField extends FormField
{
protected $type = 'AllowedIps';
protected function getInput()
{
$config = Factory::getApplication()->getConfig();
$allowedRaw = $config->get('mokowaas_allowed_ips', '');
$currentIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
if (empty($allowedRaw))
{
$status = '<span class="badge bg-danger">Not configured</span>';
$ipList = '<em>No IPs set — emergency access is blocked.</em>';
}
else
{
$ips = array_map('trim', explode(',', $allowedRaw));
$status = '<span class="badge bg-success">'
. count($ips) . ' IP(s) configured</span>';
$ipItems = [];
foreach ($ips as $ip)
{
$match = ($ip === $currentIp)
? ' <span class="badge bg-info">your IP</span>'
: '';
$ipItems[] = '<code>' . htmlspecialchars($ip)
. '</code>' . $match;
}
$ipList = implode(', ', $ipItems);
}
$yourIp = '<code>' . htmlspecialchars($currentIp) . '</code>';
return '<div class="alert alert-info mb-0">'
. '<strong>IP Whitelist:</strong> ' . $status . '<br>'
. '<strong>Allowed IPs:</strong> ' . $ipList . '<br>'
. '<strong>Your current IP:</strong> ' . $yourIp . '<br>'
. '<small class="text-muted">Set <code>public '
. '$mokowaas_allowed_ips = \'1.2.3.4,5.6.7.8\';</code>'
. ' in configuration.php to change.</small>'
. '</div>';
}
protected function getLabel()
{
return '';
}
}
@@ -0,0 +1,40 @@
<?php
/**
* Copyright (C) 2025 Moko Consulting <hello@mokoconsulting.tech>
*
* SPDX-LICENSE-IDENTIFIER: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.34.84
* PATH: /src/Field/CurrentIpField.php
* BRIEF: Read-only field that displays the current user's IP address
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Form\FormField;
class CurrentIpField extends FormField
{
protected $type = 'CurrentIp';
protected function getInput()
{
$currentIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
return '<div class="alert alert-info mb-0 py-2">'
. '<strong>Your current IP:</strong> '
. '<code>' . htmlspecialchars($currentIp) . '</code> '
. '<small class="text-muted">&mdash; add this to the table below to keep your session alive.</small>'
. '</div>';
}
protected function getLabel()
{
return '';
}
}
@@ -0,0 +1,237 @@
<?php
/**
* @package MokoWaaS
* @subpackage plg_system_mokowaas
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.34.84
* PATH: /src/Field/DemoTaskInfoField.php
* BRIEF: Read-only field showing scheduled task info with link to manage it
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Router\Route;
/**
* Displays the demo reset scheduled task status: schedule, next run,
* last run, and a direct link to edit the task in Joomla's Scheduler.
*
* @since 02.29.00
*/
class DemoTaskInfoField extends FormField
{
protected $type = 'DemoTaskInfo';
protected function getInput()
{
// Query the scheduled task — if it exists and is enabled, demo mode is on
try
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__scheduler_tasks'))
->where($db->quoteName('type') . ' = ' . $db->quote('mokowaas.demo.reset'));
$db->setQuery($query);
$task = $db->loadAssoc();
}
catch (\Throwable $e)
{
$task = null;
}
$newTaskLink = Route::_('index.php?option=com_scheduler&task=task.add');
if (!$task)
{
return '<div class="alert alert-info mb-0 py-2">'
. 'No demo reset task configured. '
. '<a href="' . $newTaskLink . '" class="alert-link">Create a Scheduled Task</a> '
. 'and select <strong>MokoWaaS Demo Reset</strong> to enable demo mode.</div>';
}
$taskId = (int) $task['id'];
$state = (int) $task['state'];
$siteTimezone = Factory::getApplication()->get('offset', 'UTC');
// Parse schedule from execution_rules
$rules = json_decode($task['execution_rules'] ?? '{}', true);
$ruleType = $rules['rule-type'] ?? '';
switch ($ruleType)
{
case 'cron-expression':
$schedule = $rules['cron-expression'] ?? '';
$friendlySchedule = $this->friendlySchedule($schedule);
break;
case 'interval-minutes':
$mins = (int) ($rules['interval-minutes'] ?? 0);
if ($mins >= 1440 && $mins % 1440 === 0)
{
$days = $mins / 1440;
$schedule = 'Every ' . $days . ' day' . ($days > 1 ? 's' : '');
}
elseif ($mins >= 60 && $mins % 60 === 0)
{
$hours = $mins / 60;
$schedule = 'Every ' . $hours . ' hour' . ($hours > 1 ? 's' : '');
}
else
{
$schedule = 'Every ' . $mins . ' minute' . ($mins !== 1 ? 's' : '');
}
$friendlySchedule = $schedule;
break;
case 'interval-hours':
$hours = (int) ($rules['interval-hours'] ?? 0);
$schedule = 'Every ' . $hours . ' hour' . ($hours !== 1 ? 's' : '');
$friendlySchedule = $schedule;
break;
case 'interval-days':
$days = (int) ($rules['interval-days'] ?? 0);
$schedule = 'Every ' . $days . ' day' . ($days !== 1 ? 's' : '');
$friendlySchedule = $schedule;
break;
default:
$schedule = $ruleType ?: 'Not set';
$friendlySchedule = 'Custom';
}
// Next execution
$nextExec = $task['next_execution'] ?? '';
$nextFormatted = 'Not scheduled';
$nextBadge = '';
if (!empty($nextExec) && $nextExec !== '0000-00-00 00:00:00')
{
try
{
$dt = new \DateTime($nextExec, new \DateTimeZone('UTC'));
$dt->setTimezone(new \DateTimeZone($siteTimezone));
$nextFormatted = $dt->format('M j, Y g:i A T');
}
catch (\Throwable $e)
{
$nextFormatted = $nextExec;
}
$diff = strtotime($nextExec . ' UTC') - time();
if ($diff <= 0)
{
$nextBadge = '<span class="badge bg-warning text-dark">DUE</span>';
}
elseif ($diff < 3600)
{
$nextBadge = '<span class="badge bg-info">in ' . (int) ceil($diff / 60) . ' min</span>';
}
elseif ($diff < 86400)
{
$nextBadge = '<span class="badge bg-info">in ' . round($diff / 3600, 1) . 'h</span>';
}
else
{
$nextBadge = '<span class="badge bg-secondary">in ' . round($diff / 86400, 1) . 'd</span>';
}
}
// Last execution
$lastExec = $task['last_execution'] ?? '';
$lastFormatted = 'Never';
if (!empty($lastExec) && $lastExec !== '0000-00-00 00:00:00')
{
try
{
$dt = new \DateTime($lastExec, new \DateTimeZone('UTC'));
$dt->setTimezone(new \DateTimeZone($siteTimezone));
$lastFormatted = $dt->format('M j, Y g:i A T');
}
catch (\Throwable $e)
{
$lastFormatted = $lastExec;
}
}
// State badge
$stateBadge = $state === 1
? '<span class="badge bg-success">Enabled</span>'
: '<span class="badge bg-danger">Disabled</span>';
// Link to edit the task
$editLink = Route::_('index.php?option=com_scheduler&task=task.edit&id=' . $taskId);
// Task params — default to On when keys are missing (matches form defaults)
$taskParams = json_decode($task['params'] ?? '{}', true) ?: [];
$bannerOn = !isset($taskParams['banner_enabled']) || (int) $taskParams['banner_enabled'] === 1;
$mediaOn = !isset($taskParams['include_media']) || (int) $taskParams['include_media'] === 1;
$countdownOn = !isset($taskParams['show_countdown']) || (int) $taskParams['show_countdown'] === 1;
// Check if snapshot exists
$snapshotExists = is_dir(JPATH_ROOT . '/mokowaas-snapshots/default');
// Build info card
return '<div class="card card-body bg-light py-2 px-3 mb-0">'
. '<table class="table table-sm table-borderless mb-1" style="max-width:550px">'
. '<tr><td class="text-muted" style="width:130px">Status</td><td>' . $stateBadge . '</td></tr>'
. '<tr><td class="text-muted">Schedule</td><td>' . htmlspecialchars($friendlySchedule) . '</td></tr>'
. '<tr><td class="text-muted">Next Reset</td><td>' . htmlspecialchars($nextFormatted) . ' ' . $nextBadge . '</td></tr>'
. '<tr><td class="text-muted">Last Reset</td><td>' . htmlspecialchars($lastFormatted) . '</td></tr>'
. '<tr><td class="text-muted">Runs</td><td>' . (int) ($task['times_executed'] ?? 0) . ' executed, ' . (int) ($task['times_failed'] ?? 0) . ' failed</td></tr>'
. '<tr><td class="text-muted">Baseline</td><td>' . ($snapshotExists ? '<span class="badge bg-success">Saved</span>' : '<span class="badge bg-warning text-dark">Not taken yet</span>') . '</td></tr>'
. '<tr><td class="text-muted">Banner</td><td>' . ($bannerOn ? 'On' : 'Off') . ($countdownOn ? ' + countdown' : '') . '</td></tr>'
. '<tr><td class="text-muted">Images</td><td>' . ($mediaOn ? 'Included' : 'Excluded') . '</td></tr>'
. '</table>'
. '<a href="' . $editLink . '" class="btn btn-sm btn-outline-primary">'
. '<span class="icon-cog" aria-hidden="true"></span> Manage Scheduled Task</a>'
. '</div>';
}
protected function getLabel()
{
return '<label class="form-label"><strong>Scheduled Reset</strong></label>';
}
/**
* Convert a cron expression to a human-readable string.
*
* @param string $cron Cron expression
*
* @return string
*/
private function friendlySchedule(string $cron): string
{
$map = [
'* * * * *' => 'Every minute',
'*/5 * * * *' => 'Every 5 minutes',
'*/15 * * * *' => 'Every 15 minutes',
'*/30 * * * *' => 'Every 30 minutes',
'0 */1 * * *' => 'Every hour',
'0 */4 * * *' => 'Every 4 hours',
'0 */6 * * *' => 'Every 6 hours',
'0 */12 * * *' => 'Every 12 hours',
'0 0 * * *' => 'Daily at midnight',
'0 6 * * *' => 'Daily at 6:00 AM',
'0 0 * * 0' => 'Weekly (Sunday)',
'0 0 1 * *' => 'Monthly (1st)',
];
return $map[$cron] ?? 'Custom';
}
}
@@ -0,0 +1,156 @@
<?php
/**
* @package MokoWaaS
* @subpackage plg_system_mokowaas
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.34.84
* PATH: /src/Field/NextResetField.php
* BRIEF: Read-only field showing next reset time from Joomla scheduled task
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
/**
* Pulls the next execution time directly from the Joomla scheduled task
* (#__scheduler_tasks) and displays it formatted in the site timezone.
*
* @since 02.29.00
*/
class NextResetField extends FormField
{
protected $type = 'NextReset';
protected function getInput()
{
// Check if demo mode is enabled
$demoEnabled = false;
if ($this->form)
{
$demoEnabled = (int) $this->form->getValue('demo_mode_enabled', 'params', 0) === 1;
}
if (!$demoEnabled)
{
return '<span class="form-control-plaintext text-muted">Demo mode is off</span>'
. '<input type="hidden" name="' . $this->name . '" value="" />';
}
// Query the actual next_execution from the scheduled task
try
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select([
$db->quoteName('next_execution'),
$db->quoteName('last_execution'),
$db->quoteName('state'),
])
->from($db->quoteName('#__scheduler_tasks'))
->where($db->quoteName('type') . ' = ' . $db->quote('mokowaas.demo.reset'));
$db->setQuery($query);
$task = $db->loadAssoc();
}
catch (\Throwable $e)
{
$task = null;
}
if (!$task)
{
return '<div class="alert alert-secondary mb-0 py-2">No scheduled task found — save to create one automatically.</div>'
. '<input type="hidden" name="' . $this->name . '" value="" />';
}
if ((int) $task['state'] !== 1)
{
return '<div class="alert alert-warning mb-0 py-2">Scheduled task is disabled.</div>'
. '<input type="hidden" name="' . $this->name . '" value="" />';
}
$nextExec = $task['next_execution'];
$lastExec = $task['last_execution'];
if (empty($nextExec) || $nextExec === '0000-00-00 00:00:00')
{
return '<div class="alert alert-secondary mb-0 py-2">Waiting for first run...</div>'
. '<input type="hidden" name="' . $this->name . '" value="" />';
}
// Convert to site timezone
$utcTimestamp = strtotime($nextExec);
$siteTimezone = Factory::getApplication()->get('offset', 'UTC');
try
{
$dt = new \DateTime('@' . $utcTimestamp);
$dt->setTimezone(new \DateTimeZone($siteTimezone));
$formatted = $dt->format('l, F j, Y \a\t g:i A T');
}
catch (\Throwable $e)
{
$formatted = $nextExec . ' UTC';
}
// Relative time
$diff = $utcTimestamp - time();
$relative = '';
if ($diff <= 0)
{
$relative = '<span class="badge bg-warning text-dark">overdue</span>';
}
elseif ($diff < 3600)
{
$mins = (int) ceil($diff / 60);
$relative = '<span class="badge bg-info">in ' . $mins . ' min</span>';
}
elseif ($diff < 86400)
{
$hours = round($diff / 3600, 1);
$relative = '<span class="badge bg-info">in ' . $hours . 'h</span>';
}
else
{
$days = round($diff / 86400, 1);
$relative = '<span class="badge bg-secondary">in ' . $days . 'd</span>';
}
// Last run info
$lastInfo = '';
if (!empty($lastExec) && $lastExec !== '0000-00-00 00:00:00')
{
try
{
$lastDt = new \DateTime($lastExec);
$lastDt->setTimezone(new \DateTimeZone($siteTimezone));
$lastInfo = '<small class="text-muted ms-2">Last run: ' . $lastDt->format('M j, g:i A') . '</small>';
}
catch (\Throwable $e)
{
// skip
}
}
return '<div class="d-flex align-items-center gap-2 flex-wrap">'
. '<span class="form-control-plaintext" style="font-weight:500">'
. '<span class="icon-calendar" aria-hidden="true"></span> '
. htmlspecialchars($formatted) . '</span> '
. $relative
. $lastInfo
. '<input type="hidden" name="' . $this->name . '" value="' . htmlspecialchars($nextExec) . '" />'
. '</div>';
}
}
@@ -0,0 +1,175 @@
<?php
/**
* @package MokoWaaS
* @subpackage plg_system_mokowaas
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GNU General Public License version 3 or later; see LICENSE
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.34.84
* PATH: /src/Field/SnapshotTablesField.php
* BRIEF: Multi-select list field that loads DB tables with sensible defaults
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
/**
* Renders a multi-select list box of all Joomla database tables, with
* content-related tables pre-selected by default.
*
* @since 02.26.00
*/
class SnapshotTablesField extends FormField
{
protected $type = 'SnapshotTables';
/**
* Tables selected by default when no value is stored yet.
*
* @var array
* @since 02.25.00
*/
private const DEFAULT_TABLES = [
'#__content',
'#__categories',
'#__fields',
'#__fields_values',
'#__fields_groups',
'#__menu',
'#__menu_types',
'#__modules',
'#__modules_menu',
'#__users',
'#__user_usergroup_map',
'#__user_profiles',
'#__tags',
'#__contentitem_tag_map',
'#__assets',
];
/**
* Table suffixes grouped by category.
*
* @var array
* @since 02.25.00
*/
private const TABLE_GROUPS = [
'Content' => ['content', 'categories', 'fields', 'fields_values', 'fields_groups', 'tags', 'contentitem_tag_map', 'ucm_content', 'ucm_history'],
'Users' => ['users', 'user_usergroup_map', 'user_profiles', 'usergroups', 'user_keys', 'user_mfa'],
'Menus' => ['menu', 'menu_types'],
'Modules' => ['modules', 'modules_menu'],
'Assets' => ['assets'],
];
protected function getInput()
{
$db = Factory::getDbo();
$prefix = $db->getPrefix();
$tables = $db->getTableList();
// Resolve selected values
$selected = $this->value;
if ($selected === null || $selected === '')
{
$selected = self::DEFAULT_TABLES;
}
elseif (is_string($selected))
{
$selected = array_filter(array_map('trim', explode("\n", $selected)));
}
$selected = (array) $selected;
// Flatten nested arrays from broken save format [["#__content"],["#__categories"]]
$selected = array_map(function ($v) {
return is_array($v) ? reset($v) : $v;
}, $selected);
// Group tables
$grouped = [];
foreach ($tables as $table)
{
if (strpos($table, $prefix) !== 0)
{
continue;
}
$suffix = substr($table, strlen($prefix));
$logical = '#__' . $suffix;
$group = 'Other';
foreach (self::TABLE_GROUPS as $groupName => $patterns)
{
if (in_array($suffix, $patterns, true))
{
$group = $groupName;
break;
}
}
$grouped[$group][] = $logical;
}
// Build HTML select with optgroups
$size = (int) ($this->element['size'] ?? 15);
$html = '<select name="' . $this->name . '" id="' . $this->id . '"'
. ' multiple="multiple" size="' . $size . '"'
. ' class="form-select">';
$priority = ['Content', 'Users', 'Menus', 'Modules', 'Assets'];
foreach ($priority as $g)
{
if (!empty($grouped[$g]))
{
$html .= '<optgroup label="' . $g . '">';
foreach ($grouped[$g] as $t)
{
$sel = in_array($t, $selected, true) ? ' selected="selected"' : '';
$html .= '<option value="' . htmlspecialchars($t) . '"' . $sel . '>' . htmlspecialchars($t) . '</option>';
}
$html .= '</optgroup>';
unset($grouped[$g]);
}
}
if (!empty($grouped['Other']))
{
$html .= '<optgroup label="Other">';
foreach ($grouped['Other'] as $t)
{
$sel = in_array($t, $selected, true) ? ' selected="selected"' : '';
$html .= '<option value="' . htmlspecialchars($t) . '"' . $sel . '>' . htmlspecialchars($t) . '</option>';
}
$html .= '</optgroup>';
}
$html .= '</select>';
// "Reset to defaults" link
$defaultsJson = htmlspecialchars(json_encode(self::DEFAULT_TABLES), ENT_QUOTES, 'UTF-8');
$html .= '<div class="mt-1">'
. '<a href="#" class="small" onclick="'
. 'var sel=document.getElementById(\'' . $this->id . '\');'
. 'var defs=' . $defaultsJson . ';'
. 'Array.from(sel.options).forEach(function(o){o.selected=defs.indexOf(o.value)!==-1;});'
. 'return false;'
. '"><span class="icon-refresh" aria-hidden="true"></span> Reset to defaults</a>'
. '</div>';
return $html;
}
}
@@ -0,0 +1,260 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2025 Moko Consulting <hello@mokoconsulting.tech>
This file is part of a Moko Consulting project.
SPDX-LICENSE-IDENTIFIER: GPL-3.0-or-later
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License (./LICENSE.md).
# FILE INFORMATION
DEFGROUP: Joomla.Plugin
INGROUP: MokoWaaS
REPO: https://github.com/mokoconsulting-tech/mokowaas
VERSION: 02.34.84
PATH: /src/mokowaas.xml
BRIEF: Plugin manifest for MokoWaaS system plugin
NOTE: Defines installation metadata, files, and configuration for Joomla
-->
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoWaaS</name>
<element>mokowaas</element>
<author>Moko Consulting</author>
<creationDate>2026-05-22</creationDate>
<copyright>Copyright (C) 2025 Moko Consulting. All rights reserved.</copyright>
<license>GNU General Public License version 3 or later; see LICENSE.md</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.34.00</version>
<description>This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.</description>
<namespace path=".">Moko\Plugin\System\MokoWaaS</namespace>
<scriptfile>script.php</scriptfile>
<files>
<filename plugin="mokowaas">script.php</filename>
<folder>Extension</folder>
<folder>Field</folder>
<folder>Helper</folder>
<folder>Service</folder>
<folder>forms</folder>
<folder>payload</folder>
<folder>services</folder>
<folder>language</folder>
<folder>administrator</folder>
</files>
<media destination="plg_system_mokowaas" folder="media">
<filename>index.html</filename>
<filename>favicon.ico</filename>
<filename>favicon.svg</filename>
<filename>favicon_256.png</filename>
<filename>logo.png</filename>
</media>
<languages folder="language">
<language tag="en-GB">en-GB/plg_system_mokowaas.ini</language>
<language tag="en-US">en-US/plg_system_mokowaas.ini</language>
</languages>
<languages folder="administrator/language">
<language tag="en-GB">en-GB/plg_system_mokowaas.sys.ini</language>
<language tag="en-US">en-US/plg_system_mokowaas.sys.ini</language>
</languages>
<administration>
<files folder="administrator">
<folder>language</folder>
</files>
</administration>
<config>
<fields name="params"
addfieldprefix="Moko\Plugin\System\MokoWaaS\Field"
>
<fieldset name="basic">
<field
name="health_api_token"
type="CopyableToken"
label="PLG_SYSTEM_MOKOWAAS_HEALTH_TOKEN_LABEL"
description="PLG_SYSTEM_MOKOWAAS_HEALTH_TOKEN_DESC"
default=""
filter="raw"
readonly="true"
/>
<field name="dev_mode" type="radio" default="0"
label="PLG_SYSTEM_MOKOWAAS_DEV_MODE_LABEL"
description="PLG_SYSTEM_MOKOWAAS_DEV_MODE_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="reset_hits"
type="radio"
label="PLG_SYSTEM_MOKOWAAS_RESET_HITS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_RESET_HITS_DESC"
default="0"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="delete_versions"
type="radio"
label="PLG_SYSTEM_MOKOWAAS_DELETE_VERSIONS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_DELETE_VERSIONS_DESC"
default="0"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</fieldset>
<fieldset name="tenant_restrictions"
label="PLG_SYSTEM_MOKOWAAS_FIELDSET_TENANT_LABEL"
description="PLG_SYSTEM_MOKOWAAS_FIELDSET_TENANT_DESC"
>
<field name="restrict_installer" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_RESTRICT_INSTALLER_LABEL"
description="PLG_SYSTEM_MOKOWAAS_RESTRICT_INSTALLER_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="allow_extension_updates" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_ALLOW_UPDATES_LABEL"
description="PLG_SYSTEM_MOKOWAAS_ALLOW_UPDATES_DESC"
class="btn-group btn-group-yesno"
showon="restrict_installer:1">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="hide_sysinfo" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_HIDE_SYSINFO_LABEL"
description="PLG_SYSTEM_MOKOWAAS_HIDE_SYSINFO_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="restrict_global_config" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_RESTRICT_CONFIG_LABEL"
description="PLG_SYSTEM_MOKOWAAS_RESTRICT_CONFIG_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="restrict_template_editing" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_RESTRICT_TEMPLATE_LABEL"
description="PLG_SYSTEM_MOKOWAAS_RESTRICT_TEMPLATE_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="disable_install_url" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_DISABLE_INSTALL_URL_LABEL"
description="PLG_SYSTEM_MOKOWAAS_DISABLE_INSTALL_URL_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="hidden_menu_items" type="textarea"
label="PLG_SYSTEM_MOKOWAAS_HIDDEN_MENUS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_HIDDEN_MENUS_DESC"
rows="5" filter="raw" />
</fieldset>
<fieldset name="demo_mode"
label="PLG_SYSTEM_MOKOWAAS_FIELDSET_DEMO_LABEL"
description="PLG_SYSTEM_MOKOWAAS_FIELDSET_DEMO_DESC"
addfieldprefix="Moko\Plugin\System\MokoWaaS\Field"
>
<field name="demo_scheduled_task" type="DemoTaskInfo"
label="PLG_SYSTEM_MOKOWAAS_DEMO_TASK_INFO_LABEL"
/>
</fieldset>
<fieldset name="security"
label="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_LABEL"
description="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_DESC"
addfieldprefix="Moko\Plugin\System\MokoWaaS\Field"
>
<field
name="emergency_access"
type="radio"
label="PLG_SYSTEM_MOKOWAAS_EMERGENCY_ACCESS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_EMERGENCY_ACCESS_DESC"
default="1"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="allowed_ips_display"
type="AllowedIps"
label=""
/>
<field name="force_https" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="admin_session_timeout" type="number"
label="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL"
description="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC"
default="60" hint="Minutes (0 = Joomla default)" />
<field
name="current_ip_display"
type="CurrentIp"
label=""
/>
<field
name="trusted_ips"
type="subform"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC"
formsource="plugins/system/mokowaas/forms/trusted_ip_entry.xml"
multiple="true"
layout="joomla.form.field.subform.repeatable-table"
groupByFieldset="false"
buttons="add,remove,move"
/>
<field name="password_min_length" type="number" default="12"
label="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL"
description="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC" />
<field name="password_require_uppercase" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="password_require_number" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_PASSWORD_NUMBER_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="password_require_special" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_PASSWORD_SPECIAL_LABEL"
class="btn-group btn-group-yesno">
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field name="upload_allowed_types" type="text"
label="PLG_SYSTEM_MOKOWAAS_UPLOAD_TYPES_LABEL"
description="PLG_SYSTEM_MOKOWAAS_UPLOAD_TYPES_DESC"
default="jpg,jpeg,png,gif,webp,svg,pdf,doc,docx,xls,xlsx" />
<field name="upload_max_size_mb" type="number"
label="PLG_SYSTEM_MOKOWAAS_UPLOAD_SIZE_LABEL"
description="PLG_SYSTEM_MOKOWAAS_UPLOAD_SIZE_DESC"
default="100" />
</fieldset>
</fields>
</config>
</extension>