Version 4.7.23

This commit is contained in:
Neo committed 2025-12-19 16:21:27 -08:00
1 parent 7124a02564
commit 25ddeb65d6
1791 files changed
+76990 -44452

No files matched your search

+7 -13
View File
@@ -188,10 +188,7 @@ class _Front extends \IPS\Session
/* Or if the access token wasn't valid, log it as a fail so that it can't be bruteforced */
else
{
$failedLogins = \is_array( $expectedMember->failed_logins ) ? $expectedMember->failed_logins : array();
$failedLogins[ \IPS\Request::i()->ipAddress() ][] = time();
$expectedMember->failed_logins = $failedLogins;
$expectedMember->save();
$expectedMember->failedLogin();
}
}
catch ( \Exception $e )
@@ -231,10 +228,7 @@ class _Front extends \IPS\Session
catch ( \OutOfRangeException $e )
{
/* ... so log it as a failed login */
$failedLogins = \is_array( $member->failed_logins ) ? $member->failed_logins : array();
$failedLogins[ \IPS\Request::i()->ipAddress() ][] = time();
$member->failed_logins = $failedLogins;
$member->save();
$member->failedLogin();
/* Then set us as a guest and clear out those cookies */
$this->member = new \IPS\Member;
@@ -267,7 +261,7 @@ class _Front extends \IPS\Session
}
else
{
$type = $this->userAgent->spider ? static::LOGIN_TYPE_SPIDER : static::LOGIN_TYPE_GUEST;
$type = $this->userAgent->bot ? static::LOGIN_TYPE_SPIDER : static::LOGIN_TYPE_GUEST;
}
/* Set data */
@@ -289,7 +283,7 @@ class _Front extends \IPS\Session
'current_id' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_id'] : NULL ) : \intval( \IPS\Request::i()->id ),
'uagent_key' => $this->userAgent->browser ?: '',
'uagent_version' => $this->userAgent->browserVersion ?: '',
'uagent_type' => $this->userAgent->spider ? 'search' : 'browser',
'uagent_type' => $this->userAgent->bot ? 'search' : 'browser',
'search_thread_id' => $session ? \intval( $session['search_thread_id'] ) : 0,
'search_thread_time' => $session ? $session['search_thread_time'] : 0,
'data' => $session ? $session['data'] : '',
@@ -303,10 +297,10 @@ class _Front extends \IPS\Session
);
/* Is this a spider? */
if( $this->userAgent->spider )
if( $this->userAgent->bot )
{
/* Is this Facebook? Do we need to treat them as a user of a different group? */
if( $this->userAgent->spider == 'facebook' )
if( $this->userAgent->bot == 'facebook' )
{
if( \IPS\core\ShareLinks\Service::load( 'facebook', 'share_key' )->enabled )
{
@@ -376,7 +370,7 @@ class _Front extends \IPS\Session
$this->data['data'] = $data;
$this->setLocationData();
if ( $this->save === TRUE and ( !empty( \IPS\Request::i()->cookie ) or $this->userAgent->spider or $this->member->member_id ) ) // If a guest and cookies are disabled we do not write to database to prevent duplicate sessions unless it's a search engine, which we deal with separately
if ( $this->save === TRUE and ( !empty( \IPS\Request::i()->cookie ) or $this->userAgent->bot or $this->member->member_id ) ) // If a guest and cookies are disabled we do not write to database to prevent duplicate sessions unless it's a search engine, which we deal with separately
{
\IPS\Session\Store::i()->updateSession( $this->data );
}
+6 -5
View File
@@ -51,16 +51,17 @@ abstract class _Store
{
if ( static::$instance === NULL )
{
if ( \IPS\REDIS_ENABLED and \IPS\CACHE_METHOD == 'Redis' and ( \IPS\CACHE_CONFIG or \IPS\REDIS_CONFIG ) )
if ( \IPS\Redis::isEnabled() )
{
try
{
/* Try and use Redis */
$connection = \IPS\Redis::i()->connection('read');
if( !$connection )
$writeConnection = \IPS\Redis::i()->connection('write');
$readConnection = \IPS\Redis::i()->connection('read');
if( !$writeConnection OR !$readConnection )
{
throw new \RuntimeException;
throw new \RedisException;
}
/* No exceptions means it worked */
+1 -1
View File
@@ -50,7 +50,7 @@ class _Database extends \IPS\Session\Store
$userAgent = \IPS\Http\Useragent::parse();
/* Spiders match by IP and useragent */
if ( $userAgent->spider )
if ( $userAgent->bot )
{
$session = \IPS\Db::i()->select( '*', 'core_sessions', array( 'id=? OR ( ip_address=? AND browser=? )', $sessionId, \IPS\Request::i()->ipAddress(), $_SERVER['HTTP_USER_AGENT'] ) )->first();
}
+53 -32
View File
@@ -26,7 +26,22 @@ class _Redis extends \IPS\Session\Store
* @brief Default expiration for keys in seconds
*/
static protected $ttl = 1800; #30 mins
/**
* Return the hash we will use to obfuscate the session ID
*
* @return string
*/
public static function getHash(): string
{
if ( \IPS\TEXT_ENCRYPTION_KEY )
{
return \IPS\TEXT_ENCRYPTION_KEY;
}
return \IPS\Settings::i()->sql_pass;
}
/**
* Load the session from the storage engine
*
@@ -35,7 +50,7 @@ class _Redis extends \IPS\Session\Store
*/
public function loadSession( $sessionId )
{
if ( $result = \IPS\Redis::i()->hGetAll( static::_key( 'session_id_' . md5( $sessionId . \IPS\Settings::i()->sql_pass ) ) ) )
if ( $result = \IPS\Redis::i()->hGetAll( static::_key( 'session_id_' . md5( $sessionId . static::getHash() ) ) ) )
{
try
{
@@ -59,8 +74,8 @@ class _Redis extends \IPS\Session\Store
$group = \IPS\Member\Group::load( $data['member_group'] );
/* Update the specific session */
\IPS\Redis::i()->del( static::_key( 'session_id_' . md5( $data['id'] . \IPS\Settings::i()->sql_pass ) ) );
\IPS\Redis::i()->hMSet( static::_key( 'session_id_' . md5( $data['id'] . \IPS\Settings::i()->sql_pass ) ), array(
\IPS\Redis::i()->del( static::_key( 'session_id_' . md5( $data['id'] . static::getHash() ) ) );
\IPS\Redis::i()->hMSet( static::_key( 'session_id_' . md5( $data['id'] . static::getHash() ) ), array(
'member_id' => $data['member_id'],
'member_name' => $data['member_name'],
'seo_name' => $data['seo_name'],
@@ -71,7 +86,7 @@ class _Redis extends \IPS\Session\Store
), static::$ttl );
/* Update the list of sessions for the online list [ microtime => sessionID ] */
\IPS\Redis::i()->zAdd( static::_key( 'session_map' ), time(), 'session_id_' . md5( $data['id'] . \IPS\Settings::i()->sql_pass ), static::$ttl );
\IPS\Redis::i()->zAdd( static::_key( 'session_map' ), time(), 'session_id_' . md5( $data['id'] . static::getHash() ), static::$ttl );
/* Update users list */
if ( $data['uagent_type'] == 'search' )
@@ -81,7 +96,7 @@ class _Redis extends \IPS\Session\Store
}
else if ( $data['member_id'] )
{
\IPS\Redis::i()->zAdd( static::_key( 'session_online_users' ), time(), $data['member_id'] . '__' . 'session_id_' . md5( $data['id'] . \IPS\Settings::i()->sql_pass ), static::$ttl );
\IPS\Redis::i()->zAdd( static::_key( 'session_online_users' ), time(), $data['member_id'] . '__' . 'session_id_' . md5( $data['id'] . static::getHash() ), static::$ttl );
}
else
{
@@ -112,10 +127,10 @@ class _Redis extends \IPS\Session\Store
public function deleteSession( $sessionId )
{
$data = $this->loadSession( $sessionId );
\IPS\Redis::i()->del( static::_key( 'session_id_' . md5( $sessionId . \IPS\Settings::i()->sql_pass ) ) );
\IPS\Redis::i()->zRem( static::_key( 'session_map' ), 'session_id_' . md5( $sessionId . \IPS\Settings::i()->sql_pass ) );
\IPS\Redis::i()->del( static::_key( 'session_id_' . md5( $sessionId . static::getHash() ) ) );
\IPS\Redis::i()->zRem( static::_key( 'session_map' ), 'session_id_' . md5( $sessionId . static::getHash() ) );
\IPS\Redis::i()->zRem( static::_key( 'session_online_spiders' ), md5( $data['ip_address'] . $data['browser'] ) );
\IPS\Redis::i()->zRem( static::_key( 'session_online_users' ), $data['member_id'] . '__' . 'session_id_' . md5( $data['id'] . \IPS\Settings::i()->sql_pass ) );
\IPS\Redis::i()->zRem( static::_key( 'session_online_users' ), $data['member_id'] . '__' . 'session_id_' . md5( $data['id'] . static::getHash() ) );
\IPS\Redis::i()->zRem( static::_key( 'session_online_guests' ), md5( $data['ip_address'] ) );
}
@@ -134,11 +149,12 @@ class _Redis extends \IPS\Session\Store
$keepSessionIds = array( $keepSessionIds );
}
$sessionMap = \IPS\Redis::i()->zRange( static::_key( 'session_map' ), 0, -1 );
$sessionMap = \IPS\Redis::i()->zRange( static::_key( 'session_online_users' ), 0, -1 );
foreach( $sessionMap as $index => $redisKey )
{
$session = \IPS\Redis::i()->hMGet( $redisKey, array( 'data' ) );
$key = explode( '__', $redisKey );
$session = \IPS\Redis::i()->hMGet( $key[1], array( 'data' ) );
try
{
@@ -208,7 +224,7 @@ class _Redis extends \IPS\Session\Store
{
foreach ( $redis as $data )
{
list( $id, $sessionKey ) = explode( '__', $data );
[ $id, $sessionKey ] = explode( '__', $data );
if ( $id == $memberId )
{
@@ -293,6 +309,11 @@ class _Redis extends \IPS\Session\Store
* Redis key
*/
protected $fetchAttempt = 0;
/**
* @var array|null cache online user data after fetching it
*/
protected ?array $onlineUsers = null;
/**
* Fetch all online users (but not spiders)
@@ -306,19 +327,19 @@ class _Redis extends \IPS\Session\Store
*/
public function getOnlineUsers( $flags=0, $sort='desc', $limit=NULL, $memberGroup=NULL, $showAnonymous=FALSE )
{
try
if( $this->onlineUsers === NULL )
{
$results = \IPS\Redis::i()->lRange( static::_key( 'session_onlinelist' ), 0, -1 );
try
{
$this->onlineUsers = \IPS\Redis::i()->lRange( static::_key( 'session_onlinelist' ), 0, -1 );
}
catch ( \RedisException $e )
{
/* Something went wrong, so reset the key to force a new file */
static::resetKey();
}
}
catch ( \RedisException $e )
{
/* Something went wrong, so reset the key to force a new file */
static::resetKey();
$results = NULL;
}
if ( ! $results )
if ( ! $this->onlineUsers )
{
/* Ensure file is deleted */
try
@@ -351,10 +372,10 @@ class _Redis extends \IPS\Session\Store
try
{
/* Force expiration in 30 seconds to prevent stale caches hanging around */
\IPS\Redis::i()->expire( static::_key( 'session_onlinelist' ), 30 );
$results = \IPS\Redis::i()->lRange( static::_key( 'session_onlinelist' ), 0, -1 );
/* Force expiration in 60 seconds to prevent stale caches hanging around */
\IPS\Redis::i()->expire( static::_key( 'session_onlinelist' ), 60 );
$this->onlineUsers = \IPS\Redis::i()->lRange( static::_key( 'session_onlinelist' ), 0, -1 );
}
catch ( \RedisException $e )
{
@@ -370,7 +391,7 @@ class _Redis extends \IPS\Session\Store
}
else
{
$results = array();
$this->onlineUsers = array();
}
}
}
@@ -382,7 +403,7 @@ class _Redis extends \IPS\Session\Store
$return = array();
$i = 0;
while( $i < \count( $results ) )
while( $i < \count( $this->onlineUsers ) )
{
$fields = array();
$data = NULL;
@@ -392,7 +413,7 @@ class _Redis extends \IPS\Session\Store
{
try
{
$data = \IPS\Redis::i()->decode( $results[ $i++ ] );
$data = \IPS\Redis::i()->decode( $this->onlineUsers[ $i++ ] );
}
catch( \RedisException $e )
{
@@ -402,11 +423,11 @@ class _Redis extends \IPS\Session\Store
/* login_type must be cast as an integer or else anonymous state can be lost when adjustSessions() runs */
elseif( $field === 'login_type' )
{
$fields[ $field ] = (int) $results[ $i++ ];
$fields[ $field ] = (int) $this->onlineUsers[ $i++ ];
}
else
{
$fields[ $field ] = $results[ $i++ ];
$fields[ $field ] = $this->onlineUsers[ $i++ ];
}
}