Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA\Authy;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -22,9 +22,24 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _Exception extends \DomainException
|
||||
{
|
||||
/**
|
||||
* @brief Token reused
|
||||
*/
|
||||
const TOKEN_REUSED = 60019;
|
||||
|
||||
/**
|
||||
* @brief Token invalid
|
||||
*/
|
||||
const TOKEN_INVALID = 60020;
|
||||
|
||||
/**
|
||||
* @brief User invalid
|
||||
*/
|
||||
const USER_INVALID = 60027;
|
||||
|
||||
/**
|
||||
* @brief Phone number invalid
|
||||
*/
|
||||
const PHONE_NUMBER_INVALID = 60033;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA\Authy;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -86,7 +86,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
{
|
||||
/* Asking for a text or call instead? */
|
||||
$availableMethods = explode( ',', \IPS\Settings::i()->authy_setup );
|
||||
if ( isset( \IPS\Request::i()->authy_method ) and $mfaDetails['authy']['setupMethod'] == 'authy' and in_array( \IPS\Request::i()->authy_method, $availableMethods ) )
|
||||
if ( isset( \IPS\Request::i()->authy_method ) and $mfaDetails['authy']['setupMethod'] == 'authy' and \in_array( \IPS\Request::i()->authy_method, $availableMethods ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -166,7 +166,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
catch ( Exception $e )
|
||||
{
|
||||
if ( in_array( $e->getCode(), array( Exception::TOKEN_REUSED, Exception::TOKEN_INVALID ) ) )
|
||||
if ( \in_array( $e->getCode(), array( Exception::TOKEN_REUSED, Exception::TOKEN_INVALID ) ) )
|
||||
{
|
||||
$_SESSION['authyAuthError'] = $e->getUserMessage();
|
||||
}
|
||||
@@ -196,7 +196,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
|
||||
/* Call Authy */
|
||||
$availableMethods = explode( ',', \IPS\Settings::i()->authy_setup );
|
||||
$method = ( isset( \IPS\Request::i()->method ) and in_array( \IPS\Request::i()->method, $availableMethods ) ) ? \IPS\Request::i()->method : array_shift( $availableMethods );
|
||||
$method = ( isset( \IPS\Request::i()->method ) and \in_array( \IPS\Request::i()->method, $availableMethods ) ) ? \IPS\Request::i()->method : array_shift( $availableMethods );
|
||||
$_SESSION['authyConfigureError'] = NULL;
|
||||
try
|
||||
{
|
||||
@@ -230,7 +230,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
catch ( Exception $e )
|
||||
{
|
||||
if ( in_array( $e->getCode(), array( Exception::USER_INVALID, Exception::PHONE_NUMBER_INVALID ) ) )
|
||||
if ( \in_array( $e->getCode(), array( Exception::USER_INVALID, Exception::PHONE_NUMBER_INVALID ) ) )
|
||||
{
|
||||
$_SESSION['authyConfigureError'] = $e->getUserMessage();
|
||||
}
|
||||
@@ -297,19 +297,19 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
|
||||
/* If Authy app is one of the available options... */
|
||||
if ( in_array( 'authy', $availableMethods ) )
|
||||
if ( \in_array( 'authy', $availableMethods ) )
|
||||
{
|
||||
/* Are we getting a onetouch status? */
|
||||
if ( \IPS\Request::i()->onetouchCheck and \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'status' => intval( $this->_onetouchCheck( $member, \IPS\Request::i()->onetouchCheck ) ) ) );
|
||||
\IPS\Output::i()->json( array( 'status' => \intval( $this->_onetouchCheck( $member, \IPS\Request::i()->onetouchCheck ) ) ) );
|
||||
}
|
||||
|
||||
/* If it is not the only option... */
|
||||
if ( count( $availableMethods ) > 1 )
|
||||
if ( \count( $availableMethods ) > 1 )
|
||||
{
|
||||
/* If they have asked for a text/call instead, do that */
|
||||
if ( !isset( $mfaDetails['authy']['sent'] ) and isset( \IPS\Request::i()->authy_method ) and in_array( \IPS\Request::i()->authy_method, $availableMethods ) )
|
||||
if ( !isset( $mfaDetails['authy']['sent'] ) and isset( \IPS\Request::i()->authy_method ) and \in_array( \IPS\Request::i()->authy_method, $availableMethods ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -368,7 +368,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
|
||||
/* If text message is the only available option, or we have chosen that option, do that... */
|
||||
if ( in_array( 'sms', $availableMethods ) and ( count( $availableMethods ) == 1 ) or ( isset( $mfaDetails['authy']['sent'] ) and $mfaDetails['authy']['sent']['method'] == 'sms' ) or ( isset( \IPS\Request::i()->authy_method ) and \IPS\Request::i()->authy_method == 'sms' ) )
|
||||
if ( \in_array( 'sms', $availableMethods ) and ( \count( $availableMethods ) == 1 ) or ( isset( $mfaDetails['authy']['sent'] ) and $mfaDetails['authy']['sent']['method'] == 'sms' ) or ( isset( \IPS\Request::i()->authy_method ) and \IPS\Request::i()->authy_method == 'sms' ) )
|
||||
{
|
||||
/* Send the text if we haven't already */
|
||||
if ( !isset( $mfaDetails['authy']['sent'] ) )
|
||||
@@ -418,7 +418,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
|
||||
/* Otherwise we're going to show a screen */
|
||||
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->authyAuthenticate( count( $availableMethods ) == 1 ? 'phone' : 'choose', FALSE, isset( $_SESSION['authyAuthError'] ) ? $_SESSION['authyAuthError'] : 'authy_error', FALSE, $availableMethods, NULL, $url );
|
||||
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->authyAuthenticate( \count( $availableMethods ) == 1 ? 'phone' : 'choose', FALSE, isset( $_SESSION['authyAuthError'] ) ? $_SESSION['authyAuthError'] : 'authy_error', FALSE, $availableMethods, NULL, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,7 +522,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
catch ( Exception $e )
|
||||
{
|
||||
if ( in_array( $e->getCode(), array( Exception::TOKEN_REUSED, Exception::TOKEN_INVALID ) ) )
|
||||
if ( \in_array( $e->getCode(), array( Exception::TOKEN_REUSED, Exception::TOKEN_INVALID ) ) )
|
||||
{
|
||||
$_SESSION['authyAuthError'] = $e->getUserMessage();
|
||||
}
|
||||
@@ -680,11 +680,11 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
{
|
||||
$availableMethods = explode( ',', \IPS\Settings::i()->authy_method );
|
||||
|
||||
if ( in_array( 'authy', $availableMethods ) )
|
||||
if ( \in_array( 'authy', $availableMethods ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_authy_title');
|
||||
}
|
||||
elseif ( in_array( 'sms', $availableMethods ) and count( $availableMethods ) == 1 )
|
||||
elseif ( \in_array( 'sms', $availableMethods ) and \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_sms_title');
|
||||
}
|
||||
@@ -703,9 +703,9 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
{
|
||||
$availableMethods = explode( ',', \IPS\Settings::i()->authy_method );
|
||||
|
||||
if ( in_array( 'authy', $availableMethods ) )
|
||||
if ( \in_array( 'authy', $availableMethods ) )
|
||||
{
|
||||
if ( count( $availableMethods ) == 1 )
|
||||
if ( \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_authy_only_desc_user');
|
||||
}
|
||||
@@ -714,11 +714,11 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_authy_mixed_desc_user');
|
||||
}
|
||||
}
|
||||
elseif ( in_array( 'sms', $availableMethods ) and count( $availableMethods ) == 1 )
|
||||
elseif ( \in_array( 'sms', $availableMethods ) and \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_sms_desc_user');
|
||||
}
|
||||
elseif ( in_array( 'phone', $availableMethods ) and count( $availableMethods ) == 1 )
|
||||
elseif ( \in_array( 'phone', $availableMethods ) and \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_phone_desc_user');
|
||||
}
|
||||
@@ -737,11 +737,11 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
{
|
||||
$availableMethods = explode( ',', \IPS\Settings::i()->authy_method );
|
||||
|
||||
if ( in_array( 'authy', $availableMethods ) and count( $availableMethods ) == 1 )
|
||||
if ( \in_array( 'authy', $availableMethods ) and \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_authy_recovery');
|
||||
}
|
||||
elseif ( in_array( 'sms', $availableMethods ) and count( $availableMethods ) == 1 )
|
||||
elseif ( \in_array( 'sms', $availableMethods ) and \count( $availableMethods ) == 1 )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('mfa_sms_recovery');
|
||||
}
|
||||
@@ -813,6 +813,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
/**
|
||||
* Verify an Authy API Key
|
||||
*
|
||||
* @param string $val The API key submitted
|
||||
* @return array
|
||||
* @throws \DomainException
|
||||
*/
|
||||
|
||||
Whitespace-only changes.
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA\GoogleAuthenticator;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -77,15 +77,15 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( function_exists( 'random_bytes' ) )
|
||||
if ( \function_exists( 'random_bytes' ) )
|
||||
{
|
||||
$randomString = random_bytes( 16 );
|
||||
}
|
||||
elseif ( function_exists( 'mcrypt_create_iv' ) )
|
||||
elseif ( \function_exists( 'mcrypt_create_iv' ) )
|
||||
{
|
||||
$randomString = mcrypt_create_iv( 16, MCRYPT_DEV_URANDOM );
|
||||
}
|
||||
elseif ( function_exists( 'openssl_random_pseudo_bytes' ) )
|
||||
elseif ( \function_exists( 'openssl_random_pseudo_bytes' ) )
|
||||
{
|
||||
$randomString = openssl_random_pseudo_bytes( 16 );
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
$secret = '';
|
||||
for ( $i = 0; $i < 16; ++$i )
|
||||
{
|
||||
$secret .= $validChars[ ord( $randomString[ $i ] ) & 31 ];
|
||||
$secret .= $validChars[ \ord( $randomString[ $i ] ) & 31 ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
$waitUntil = ( \IPS\Db::i()->select( 'time', 'core_googleauth_used_codes', array( 'member=?', $member->member_id ), 'time DESC', 1 )->first() * 30 ) + 30;
|
||||
$waitUntil = ( \IPS\Db::i()->select( 'time', 'core_googleauth_used_codes', array( '`member`=?', $member->member_id ), 'time DESC', 1 )->first() * 30 ) + 30;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
@@ -257,13 +257,13 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
$submittedCode = str_replace( ' ', '', $submittedCode );
|
||||
|
||||
$validTimes = array( new \IPS\DateTime(), ( new \IPS\DateTime() )->add( new \DateInterval('PT30S') ), ( new \IPS\DateTime() )->sub( new \DateInterval('PT30S') ) );
|
||||
$blockedTimes = iterator_to_array( \IPS\Db::i()->select( 'time', 'core_googleauth_used_codes', array( 'member=?', $member->member_id ) ) );
|
||||
$blockedTimes = iterator_to_array( \IPS\Db::i()->select( 'time', 'core_googleauth_used_codes', array( '`member`=?', $member->member_id ) ) );
|
||||
|
||||
$allowedCodes = array();
|
||||
foreach ( $validTimes as $time )
|
||||
{
|
||||
$codeTime = floor( $time->getTimestamp() / 30 );
|
||||
if ( !in_array( $codeTime, $blockedTimes ) )
|
||||
if ( !\in_array( $codeTime, $blockedTimes ) )
|
||||
{
|
||||
$allowedCodes[ static::getCodeForSecretAtTime( $secret, $time ) ] = $codeTime;
|
||||
}
|
||||
@@ -301,17 +301,17 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
$block .= str_pad( base_convert( $chars[ $secret[ $i + $j ] ], 10, 2 ), 5, '0', STR_PAD_LEFT );
|
||||
}
|
||||
$eightBits = str_split( $block, 8 );
|
||||
for ( $z = 0; $z < count( $eightBits ); ++$z )
|
||||
for ( $z = 0; $z < \count( $eightBits ); ++$z )
|
||||
{
|
||||
$decodedSecretKey .= ( ( $y = chr( base_convert( $eightBits[ $z ], 2, 10) ) ) || ord( $y ) == 48) ? $y : '';
|
||||
$decodedSecretKey .= ( ( $y = \chr( base_convert( $eightBits[ $z ], 2, 10) ) ) || \ord( $y ) == 48) ? $y : '';
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash the timestamp with the secret key */
|
||||
$hash = hash_hmac('SHA1', chr(0).chr(0).chr(0).chr(0).pack('N*', floor( $time->getTimestamp() / 30 ) ), $decodedSecretKey, true);
|
||||
$hash = hash_hmac('SHA1', \chr(0).\chr(0).\chr(0).\chr(0).pack('N*', floor( $time->getTimestamp() / 30 ) ), $decodedSecretKey, true);
|
||||
|
||||
/* Unpack it */
|
||||
$value = unpack( 'N', \substr( $hash, ord( \substr( $hash, -1 ) ) & 0x0F, 4 ) );
|
||||
$value = unpack( 'N', \substr( $hash, \ord( \substr( $hash, -1 ) ) & 0x0F, 4 ) );
|
||||
$value = $value[1];
|
||||
|
||||
/* Get 32 bits */
|
||||
|
||||
Whitespace-only changes.
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -52,7 +52,20 @@ abstract class _MFAHandler
|
||||
'questions' => new \IPS\MFA\SecurityQuestions\Handler()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes any previous authentication settings for this user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function resetAuthentication()
|
||||
{
|
||||
if ( isset( $_SESSION['MFAAuthenticated'] ) )
|
||||
{
|
||||
unset( $_SESSION['MFAAuthenticated'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display output when trying to access an area
|
||||
*
|
||||
@@ -73,7 +86,7 @@ abstract class _MFAHandler
|
||||
}
|
||||
|
||||
/* If MFA is not enabled for this area, do nothing */
|
||||
if ( !\IPS\Settings::i()->security_questions_areas or !in_array( "{$app}_{$area}", explode( ',', \IPS\Settings::i()->security_questions_areas ) ) )
|
||||
if ( !\IPS\Settings::i()->security_questions_areas or !\in_array( "{$app}_{$area}", explode( ',', \IPS\Settings::i()->security_questions_areas ) ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -150,7 +163,7 @@ abstract class _MFAHandler
|
||||
|
||||
/* Display */
|
||||
$knownDevicesAvailable = FALSE;
|
||||
if ( $app === 'core' and $area === 'AuthenticateFront' and !in_array( "app_AuthenticateFrontKnown", explode( ',', \IPS\Settings::i()->security_questions_areas ) ) )
|
||||
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() )
|
||||
{
|
||||
@@ -188,7 +201,7 @@ abstract class _MFAHandler
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
foreach ( $acceptableHandlers as $key => $handler )
|
||||
{
|
||||
if ( ( count( $acceptableHandlers ) == 1 ) or $key == \IPS\Request::i()->mfa_method )
|
||||
if ( ( \count( $acceptableHandlers ) == 1 ) or $key == \IPS\Request::i()->mfa_method )
|
||||
{
|
||||
if ( $handler->configurationScreenSubmit( $member ) )
|
||||
{
|
||||
@@ -371,7 +384,6 @@ abstract class _MFAHandler
|
||||
* Configuration options when editing member account in ACP
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form $form Set to TRUE if multiple options are being displayed
|
||||
* @return array
|
||||
*/
|
||||
public function acpConfiguration( \IPS\Member $member )
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA\SecurityQuestions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -42,6 +42,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
/**
|
||||
* Member *can* use this handler (even if they have not yet configured it)
|
||||
*
|
||||
* @param \IPS\Member $member Member to check
|
||||
* @return bool
|
||||
*/
|
||||
public function memberCanUseHandler( \IPS\Member $member )
|
||||
@@ -52,7 +53,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
/**
|
||||
* Member has configured this handler
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Member $member Member to check
|
||||
* @return bool
|
||||
*/
|
||||
public function memberHasConfiguredHandler( \IPS\Member $member )
|
||||
@@ -100,7 +101,7 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
);
|
||||
}
|
||||
|
||||
if ( count( $answers ) >= \IPS\Settings::i()->security_questions_number )
|
||||
if ( \count( $answers ) >= \IPS\Settings::i()->security_questions_number )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_security_answers', array( 'answer_member_id=?', $member->member_id ) );
|
||||
\IPS\Db::i()->insert( 'core_security_answers', $answers );
|
||||
@@ -329,12 +330,12 @@ class _Handler extends \IPS\MFA\MFAHandler
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $toInsert ) )
|
||||
if ( \count( $toInsert ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_security_answers', $toInsert );
|
||||
}
|
||||
|
||||
if ( count( $toInsert ) >= \IPS\Settings::i()->security_questions_number )
|
||||
if ( \count( $toInsert ) >= \IPS\Settings::i()->security_questions_number )
|
||||
{
|
||||
$member->members_bitoptions['has_security_answers'] = TRUE;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace IPS\MFA\SecurityQuestions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
|
||||
Whitespace-only changes.
Whitespace-only changes.
Reference in new issue
Block a user