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

@@ -350,6 +350,22 @@ class _settings extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->error( 'no_module_permission', '2C122/T', 403, '' );
}
$canChangePassword = FALSE;
foreach ( \IPS\Login::methods() as $method )
{
if ( $method->canChangePassword( \IPS\Member::loggedIn() ) )
{
$canChangePassword = TRUE;
break;
}
}
if( !$canChangePassword )
{
\IPS\Output::i()->error( 'no_module_permission', '3C122/W', 403, '' );
}
if( \IPS\Member::loggedIn()->isAdmin() )
{
@@ -538,7 +554,7 @@ class _settings extends \IPS\Dispatcher\Controller
}
}
$oauthApps = \IPS\Db::i()->select( 'COUNT(DISTINCT client_id)', 'core_oauth_server_access_tokens', array( 'member_id=? AND oauth_enabled=1 AND oauth_ucp=1', \IPS\Member::loggedIn()->member_id ) )
$oauthApps = \IPS\Db::i()->select( 'COUNT(DISTINCT client_id)', 'core_oauth_server_access_tokens', array( "member_id=? AND oauth_enabled=1 AND oauth_ucp=1 AND status='active'", \IPS\Member::loggedIn()->member_id ) )
->join( 'core_oauth_clients', 'oauth_client_id=client_id' )
->first();
@@ -563,7 +579,7 @@ class _settings extends \IPS\Dispatcher\Controller
$device->login_key = NULL;
$device->save();
\IPS\Db::i()->delete( 'core_oauth_server_access_tokens', array( 'member_id=? AND device_key=?', $device->member_id, $device->device_key ) );
\IPS\Db::i()->update( 'core_oauth_server_access_tokens', array( 'status' => 'revoked' ), array( 'member_id=? AND device_key=?', $device->member_id, $device->device_key ) );
\IPS\Member::loggedIn()->logHistory( 'core', 'login', array( 'type' => 'logout', 'device' => $device->device_key ) );
@@ -585,20 +601,27 @@ class _settings extends \IPS\Dispatcher\Controller
if ( !isset( $_SESSION['passwordValidatedForMfa'] ) )
{
$login = new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ), \IPS\Login::LOGIN_REAUTHENTICATE );
$error = NULL;
try
$usernamePasswordMethods = $login->usernamePasswordMethods();
$buttonMethods = $login->buttonMethods();
/* Only prompt for re-authentication if it is possible */
if( $usernamePasswordMethods OR $buttonMethods )
{
if ( $success = $login->authenticate() )
$error = NULL;
try
{
$_SESSION['passwordValidatedForMfa'] = TRUE;
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ) );
if ( $success = $login->authenticate() )
{
$_SESSION['passwordValidatedForMfa'] = TRUE;
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ) );
}
}
catch ( \IPS\Login\Exception $e )
{
$error = $e->getMessage();
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsMfaPassword( $login, $error );
}
catch ( \IPS\Login\Exception $e )
{
$error = $e->getMessage();
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsMfaPassword( $login, $error );
}
/* Get our handlers and the output, even if it's just for a backdrop */
@@ -742,7 +765,7 @@ class _settings extends \IPS\Dispatcher\Controller
$this->_performRedirect( \IPS\Http\Url::internal('') );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_complete_details');
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_complete_2fa_title');
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( '2fa.css', 'core', 'global' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->mfaSetup( $handlers, \IPS\Member::loggedIn(), \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&do=initialMfa', 'front', 'settings' )->addRef( $this->_performRedirect( \IPS\Http\Url::internal(''), '', TRUE ) ) );
}
@@ -1128,7 +1151,7 @@ class _settings extends \IPS\Dispatcher\Controller
}
/* Number of Images */
if ( \is_numeric( $sigLimits[1] ) and $signature->getElementsByTagName('img')->length > 0 )
if ( \is_numeric( $sigLimits[1] ) )
{
$imageCount = 0;
foreach ( $signature->getElementsByTagName('img') as $img )
@@ -1138,6 +1161,15 @@ class _settings extends \IPS\Dispatcher\Controller
$imageCount++;
}
}
/* Look for background-image URLs too */
$xpath = new \DOMXpath( $signature );
foreach ( $xpath->query("//*[contains(@style, 'url') and contains(@style, 'background')]") as $styleUrl )
{
$imageCount++;
}
if( $imageCount > $sigLimits[1] )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack('sig_num_images_exceeded');
@@ -1479,6 +1511,10 @@ class _settings extends \IPS\Dispatcher\Controller
foreach ( \IPS\Db::i()->select( '*', 'core_oauth_server_access_tokens', array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), 'issued DESC' ) as $accessToken )
{
if ( $accessToken['status'] == 'revoked' )
{
continue;
}
try
{
$client = \IPS\Api\OAuthClient::load( $accessToken['client_id'] );
@@ -1538,7 +1574,7 @@ class _settings extends \IPS\Dispatcher\Controller
try
{
$client = \IPS\Api\OAuthClient::load( \IPS\Request::i()->client_id );
\IPS\Db::i()->delete( 'core_oauth_server_access_tokens', array( 'client_id=? AND member_id=?', $client->client_id, \IPS\Member::loggedIn()->member_id ) );
\IPS\Db::i()->update( 'core_oauth_server_access_tokens', array( 'status' => 'revoked' ), array( 'client_id=? AND member_id=?', $client->client_id, \IPS\Member::loggedIn()->member_id ) );
\IPS\Member::loggedIn()->logHistory( 'core', 'oauth', array( 'type' => 'revoked_access_token', 'client' => $client->client_id ) );
}
catch ( \Exception $e ) { }