Merge pull request 'feat: trusted IPs bypass admin session timeout' (#55) from dev into main
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 2s

Merge pull request #55: feat: trusted IPs bypass admin session timeout
This commit was merged in pull request #55.
This commit is contained in:
2026-05-26 19:44:22 +00:00
7 changed files with 152 additions and 1 deletions
+5
View File
@@ -31,6 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- License/subscription check
- System email template branding (DB approach)
### Added
- Trusted IPs: configurable repeatable rows of IP addresses, CIDR ranges, and wildcards that bypass admin session timeout
- Supports exact IPs (192.168.1.100), CIDR (10.0.0.0/24), and wildcards (192.168.1.*)
- Each entry has a label and enabled toggle for easy management
## [02.06.00] - 2026-05-25
### Added
+1 -1
View File
@@ -9,7 +9,7 @@
DEFGROUP: Joomla.Plugin
INGROUP: MokoWaaS
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS
VERSION: 02.10.04
VERSION: 02.10.05
PATH: /README.md
BRIEF: MokoWaaS platform plugin for Joomla
-->
@@ -3343,6 +3343,14 @@ class MokoWaaS extends CMSPlugin
return;
}
// Don't timeout trusted IPs — extend their session instead
if ($this->ipIsTrusted())
{
ini_set('session.gc_maxlifetime', 315360000);
return;
}
$session = Factory::getSession();
$lastHit = $session->get('mokowaas.last_activity', 0);
$now = time();
@@ -3360,6 +3368,91 @@ class MokoWaaS extends CMSPlugin
$session->set('mokowaas.last_activity', $now);
}
/**
* Check whether the current request IP matches any trusted IP entry.
*
* Supports exact IPs, CIDR notation (e.g. 10.0.0.0/8), and
* wildcard patterns (e.g. 192.168.1.*).
*
* @return bool True if the current IP is in the trusted list.
*
* @since 02.11.00
*/
protected function ipIsTrusted(): bool
{
$entries = $this->params->get('trusted_ips', '');
if (empty($entries))
{
return false;
}
// Subform stores as JSON string or array
if (\is_string($entries))
{
$entries = json_decode($entries, true);
}
if (!\is_array($entries))
{
return false;
}
$ip = $this->app->input->server->getString('REMOTE_ADDR', '');
$ipLong = ip2long($ip);
if ($ipLong === false)
{
return false;
}
foreach ($entries as $entry)
{
if (empty($entry['enabled']) || empty($entry['ip']))
{
continue;
}
$range = trim($entry['ip']);
// Wildcard: 192.168.1.*
if (str_contains($range, '*'))
{
$pattern = '/^' . str_replace(['.', '*'], ['\\.', '\\d+'], $range) . '$/';
if (preg_match($pattern, $ip))
{
return true;
}
continue;
}
// CIDR: 10.0.0.0/8
if (str_contains($range, '/'))
{
[$subnet, $bits] = explode('/', $range, 2);
$subnetLong = ip2long($subnet);
$mask = -1 << (32 - (int) $bits);
if ($subnetLong !== false && ($ipLong & $mask) === ($subnetLong & $mask))
{
return true;
}
continue;
}
// Exact match
if ($ip === $range)
{
return true;
}
}
return false;
}
/**
* Override Joomla upload restrictions at runtime.
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<field
name="ip"
type="text"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC"
required="true"
hint="e.g. 192.168.1.100 or 10.0.0.0/24"
/>
<field
name="label"
type="text"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC"
hint="e.g. Office network"
/>
<field
name="enabled"
type="radio"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL"
default="1"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</form>
@@ -120,6 +120,13 @@ PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL="Force HTTPS"
PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups."
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout"
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL="Trusted IPs (No Session Timeout)"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC="Sessions from these IP addresses or ranges will never time out. Supports exact IPs, CIDR notation (e.g. 10.0.0.0/24), and wildcards (e.g. 192.168.1.*)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL="IP / CIDR"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC="An IP address, CIDR range, or wildcard pattern."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL="Label"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC="A descriptive label for this entry (e.g. Office, VPN)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL="Enabled"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords."
PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase"
@@ -120,6 +120,13 @@ PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL="Force HTTPS"
PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups."
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout"
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL="Trusted IPs (No Session Timeout)"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC="Sessions from these IP addresses or ranges will never time out. Supports exact IPs, CIDR notation (e.g. 10.0.0.0/24), and wildcards (e.g. 192.168.1.*)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL="IP / CIDR"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC="An IP address, CIDR range, or wildcard pattern."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL="Label"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC="A descriptive label for this entry (e.g. Office, VPN)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL="Enabled"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords."
PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase"
@@ -322,6 +322,17 @@
label="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL"
description="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC"
default="60" hint="Minutes (0 = Joomla default)" />
<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" />