Version 4.6.0

This commit is contained in:
Neo committed 2025-12-19 05:55:31 -08:00
1 parent f79dcf067a
commit 517a5e1f70
2036 files changed
+110041 -26162

No files matched your search

+43 -31
View File
@@ -235,6 +235,7 @@ class _Login
$leastOffensiveException = NULL;
$success = NULL;
$fails = array();
$failsNoAccount = array();
foreach ( $this->usernamePasswordMethods() as $method )
{
@@ -265,7 +266,7 @@ class _Login
if ( $member )
{
static::checkIfAccountIsLocked( $member, TRUE );
$success = new Login\Success( $member, $method, isset( \IPS\Request::i()->remember_me ), $member->members_bitoptions['is_anon'] );
$success = new Login\Success( $member, $method, isset( \IPS\Request::i()->remember_me ) );
break;
}
}
@@ -275,6 +276,10 @@ class _Login
{
$fails[ $e->member->member_id ] = $e->member;
}
elseif( $e->getCode() === \IPS\Login\Exception::NO_ACCOUNT and $e->member AND $e->member->email )
{
$failsNoAccount[ $e->member->email ] = $e->member;
}
if ( $leastOffensiveException === NULL or $leastOffensiveException->getCode() < $e->getCode() )
{
@@ -294,6 +299,24 @@ class _Login
$failedMember->save();
}
}
foreach( $failsNoAccount as $failedMember )
{
if ( !$success or $success->member->email != $failedMember->email )
{
try
{
$failedLogins = \is_array( \IPS\Data\Store::i()->failedLogins ) ? \IPS\Data\Store::i()->failedLogins : array();
}
catch( \OutOfRangeException $e )
{
$failedLogins = array();
}
$failedLogins[ $failedMember->email ][ \IPS\Request::i()->ipAddress() ][] = time();
\IPS\Data\Store::i()->failedLogins = $failedLogins;
}
}
if ( $success )
{
@@ -335,7 +358,7 @@ class _Login
if ( $member = $method->authenticateButton( $this ) )
{
static::checkIfAccountIsLocked( $member, TRUE );
return new Login\Success( $member, $method, isset( \IPS\Request::i()->remember_me ), $member->members_bitoptions['is_anon'] );
return new Login\Success( $member, $method, isset( \IPS\Request::i()->remember_me ) );
}
}
}
@@ -348,7 +371,12 @@ class _Login
{
static::checkIfAccountIsLocked( $e->member );
}
/* Or if the account doesn't exist but we've tried the brute-force number of times, show the account is locked even though it doesn't exist */
elseif( $e->getCode() === \IPS\Login\Exception::NO_ACCOUNT and $e->member AND $e->member->email )
{
static::checkIfAccountIsLocked( $e->member );
}
/* If we're still here, throw the error we got */
throw $e;
}
@@ -362,6 +390,7 @@ class _Login
*
* @param \IPS\Member $member The account
* @param bool $success Boolean value indicating if the login was successful. If TRUE, and the account is not locked, failed logins will be removed.
* @note The $member object may be a guest object with an email address set
* @return void
* @throws \Exception
*/
@@ -371,7 +400,7 @@ class _Login
if ( $unlockTime !== FALSE )
{
/* Notify the member if they've been locked */
if( \count( $member->failed_logins[ \IPS\Request::i()->ipAddress() ] ) == \IPS\Settings::i()->ipb_bruteforce_attempts )
if( $member->failedLoginCount( \IPS\Request::i()->ipAddress() ) == \IPS\Settings::i()->ipb_bruteforce_attempts )
{
/* Can we get a physical location */
try
@@ -382,8 +411,12 @@ class _Login
{
$location = \IPS\Request::i()->ipAddress();
}
\IPS\Email::buildFromTemplate( 'core', 'account_locked', array( $member, $location, isset( $unlockTime ) ? $unlockTime : NULL ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $member );
$member->logHistory( 'core', 'login', array( 'type' => 'lock', 'count' => \count( $member->failed_logins[ \IPS\Request::i()->ipAddress() ] ), 'unlockTime' => isset( $unlockTime ) ? $unlockTime->getTimestamp() : NULL ) );
if( $member->member_id )
{
\IPS\Email::buildFromTemplate( 'core', 'account_locked', array( $member, $location, isset( $unlockTime ) ? $unlockTime : NULL ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $member );
$member->logHistory( 'core', 'login', array( 'type' => 'lock', 'count' => \count( $member->failed_logins[ \IPS\Request::i()->ipAddress() ] ), 'unlockTime' => isset( $unlockTime ) ? $unlockTime->getTimestamp() : NULL ) );
}
}
if ( \IPS\Settings::i()->ipb_bruteforce_period and \IPS\Settings::i()->ipb_bruteforce_unlock )
@@ -474,7 +507,8 @@ class _Login
$existingMember = \IPS\Member::load( $email, 'email' );
if ( $existingMember->member_id and ( !$exclude or $exclude->member_id != $existingMember->member_id ) )
{
return \IPS\Member::loggedIn()->language()->addToStack('member_email_exists');
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=lostpass", "front", "lostpassword" );
return \IPS\Member::loggedIn()->language()->addToStack( 'member_email_exists', FALSE, array( 'sprintf' => array( (string) $url ) ) );
}
/* Check each handler */
@@ -488,7 +522,8 @@ class _Login
}
else
{
return \IPS\Member::loggedIn()->language()->addToStack('member_email_exists');
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=lostpass", "front", "lostpassword" );
return \IPS\Member::loggedIn()->language()->addToStack( 'member_email_exists', FALSE, array( 'sprintf' => array( (string) $url ) ) );
}
}
}
@@ -619,27 +654,4 @@ class _Login
/* Member sync callback */
\IPS\Member::loggedIn()->memberSync( 'onLogout', array( $redirectUrl ?: \IPS\Http\Url::internal('') ) );
}
/* !Backwards Compatibility for login handlers created before 4.3 */
/**
* Get Legacy Handlers
*
* @deprecated
* @return array
*/
public static function handlers()
{
$return = array();
foreach ( \IPS\Db::i()->select( '*', 'core_login_methods', array( 'login_enabled=1' ) ) as $method )
{
$method = \IPS\Login\Handler::constructFromData( $method );
if ( $method instanceof \IPS\Login\LoginAbstract )
{
$return[ mb_substr( \get_class( $method ), 10 ) ] = $method;
}
}
return $return;
}
}