Version 4.2.0

This commit is contained in:
Neo committed 2025-12-19 05:44:59 -08:00
1 parent 0dc2aee5ed
commit 96997ddd8e
2074 files changed
+125454 -55780

No files matched your search

+79 -21
View File
@@ -1,12 +1,11 @@
<?php
/**
* @brief Abstract Multi Factor Authentication Handler and Factory
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 26 Aug 2016
* @version SVN_VERSION_NUMBER
*/
namespace IPS\MFA;
@@ -48,6 +47,7 @@ abstract class _MFAHandler
public static function handlers()
{
return array(
'authy' => new \IPS\MFA\Authy\Handler(),
'google' => new \IPS\MFA\GoogleAuthenticator\Handler(),
'questions' => new \IPS\MFA\SecurityQuestions\Handler()
);
@@ -93,8 +93,14 @@ abstract class _MFAHandler
}
if ( isset( \IPS\Request::i()->_mfa ) and \IPS\Request::i()->_mfa == 'optout' )
{
\IPS\Session::i()->csrfCheck();
$member->members_bitoptions['security_questions_opt_out'] = TRUE;
$member->save();
/* Log MFA Optout */
$member->logHistory( 'core', 'mfa', array( 'handler' => 'questions', 'enable' => FALSE, 'optout' => TRUE ) );
return NULL;
}
}
@@ -122,27 +128,42 @@ abstract class _MFAHandler
}
/* "Try another way to sign in" */
if ( isset( \IPS\Request::i()->_mfa ) and \IPS\Request::i()->_mfa == 'alt' )
if ( isset( \IPS\Request::i()->_mfa ) )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( '2fa.css', 'core', 'global' ) );
/* What handlers have we configured? */
$configuredHandlers = array();
foreach ( $acceptableHandlers as $key => $handler )
{
if ( $handler->memberHasConfiguredHandler( $member ) )
if ( \IPS\Request::i()->_mfa == 'alt' )
{
/* What handlers have we configured? */
$configuredHandlers = array();
foreach ( $acceptableHandlers as $key => $handler )
{
$configuredHandlers[ $key ] = $handler;
if ( $handler->memberHasConfiguredHandler( $member ) )
{
$configuredHandlers[ $key ] = $handler;
}
}
if ( isset( \IPS\Request::i()->_mfaMethod ) and array_key_exists( \IPS\Request::i()->_mfaMethod, $configuredHandlers ) )
{
return static::_showHandlerAuthScreen( $configuredHandlers[ \IPS\Request::i()->_mfaMethod ], $url->setQueryString( array( '_mfa' => 'alt', '_mfaMethod' => \IPS\Request::i()->_mfaMethod ) ), $member );
}
/* Display */
$knownDevicesAvailable = FALSE;
if ( $app === 'core' and $area === 'AuthenticateFront' and !in_array( "app_AuthenticateFrontKnown", explode( ',', \IPS\Settings::i()->security_questions_areas ) ) )
{
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_members_known_devices', array( 'member_id=?', $member->member_id ) )->first() )
{
$knownDevicesAvailable = TRUE;
}
}
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->mfaRecovery( $configuredHandlers, $url, $knownDevicesAvailable );
}
if ( isset( \IPS\Request::i()->_mfaMethod ) and array_key_exists( \IPS\Request::i()->_mfaMethod, $configuredHandlers ) )
elseif ( \IPS\Request::i()->_mfa == 'knownDevice' )
{
return static::_showHandlerAuthScreen( $configuredHandlers[ \IPS\Request::i()->_mfaMethod ], $url->setQueryString( array( '_mfa' => 'alt', '_mfaMethod' => \IPS\Request::i()->_mfaMethod ) ), $member );
return \IPS\Theme::i()->getTemplate( 'system', 'core' )->mfaKnownDeviceInfo( $url );
}
/* Display */
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->mfaRecovery( $configuredHandlers, $url );
}
/* Normal authentication form */
@@ -162,8 +183,9 @@ abstract class _MFAHandler
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( '2fa.css', 'core', 'global' ) );
/* Did we just submit it? */
if ( isset( \IPS\Request::i()->mfa_setup ) )
if ( isset( \IPS\Request::i()->mfa_setup ) and isset( \IPS\Request::i()->csrfKey ) )
{
\IPS\Session::i()->csrfCheck();
foreach ( $acceptableHandlers as $key => $handler )
{
if ( ( count( $acceptableHandlers ) == 1 ) or $key == \IPS\Request::i()->mfa_method )
@@ -199,6 +221,7 @@ abstract class _MFAHandler
/* Did we just submit it? */
if ( isset( \IPS\Request::i()->mfa_auth ) )
{
\IPS\Session::i()->csrfCheck();
if ( $handler->authenticationScreenSubmit( $member ) )
{
$member->failed_mfa_attempts = 0;
@@ -210,6 +233,8 @@ abstract class _MFAHandler
{
$member->failed_mfa_attempts++;
$member->save();
\IPS\Request::i()->mfa_auth = NULL;
}
}
@@ -357,7 +382,10 @@ abstract class _MFAHandler
{
if ( isset( $values["mfa_{$this->key}_title"] ) and !$values["mfa_{$this->key}_title"] )
{
$this->disableHandlerForMember( $member );
if ( isset( $member->mfa_details[ $this->key ] ) )
{
$this->disableHandlerForMember( $member );
}
}
}
@@ -371,4 +399,34 @@ abstract class _MFAHandler
*/
abstract public function disableHandlerForMember( \IPS\Member $member );
/**
* Get title for UCP
*
* @return string
*/
public function ucpTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack("mfa_{$this->key}_title");
}
/**
* Get description for UCP
*
* @return string
*/
public function ucpDesc()
{
return \IPS\Member::loggedIn()->language()->addToStack("mfa_{$this->key}_desc_user");
}
/**
* Get label for recovery button
*
* @return string
*/
public function recoveryButton()
{
return \IPS\Member::loggedIn()->language()->addToStack("mfa_recovery_{$this->key}");
}
}