Version 4.7.13

This commit is contained in:
Neo committed 2025-12-19 16:14:56 -08:00
1 parent fd22d99e69
commit 7124a02564
954 files changed
+29277 -59308

No files matched your search

@@ -138,7 +138,6 @@ class _settings extends \IPS\Dispatcher\Controller
/* Show our own oauth clients? */
$showApps = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'core_oauth_clients', array( array( 'oauth_enabled=1 AND oauth_ucp=1' ) ) )->first();
/* Return */
return \IPS\Theme::i()->getTemplate( 'system' )->settings( $area, $output, ( \IPS\Settings::i()->allow_email_changes != 'disabled' ), $canChangePassword, \IPS\Member::loggedIn()->group['g_dname_changes'], $canChangeSignature, $loginMethods, $canConfigureMfa, $showApps );
}
@@ -240,8 +239,14 @@ class _settings extends \IPS\Dispatcher\Controller
/* Build the form */
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_collapseTablet';
$form->addDummy( 'current_email', htmlspecialchars( \IPS\Member::loggedIn()->email, ENT_DISALLOWED, 'UTF-8', FALSE ) );
$form->add( new \IPS\Helpers\Form\Email( 'new_email', '', TRUE, array( 'accountEmail' => \IPS\Member::loggedIn() ) ) );
$currentEmail = htmlspecialchars( \IPS\Member::loggedIn()->email, ENT_DISALLOWED, 'UTF-8', FALSE );
$form->addDummy( 'current_email', \IPS\Member::loggedIn()->members_bitoptions["email_messages_bounce"] ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->memberEmailBlockedMessage( $currentEmail ) : $currentEmail );
$form->add( new \IPS\Helpers\Form\Email(
'new_email',
'',
TRUE,
array( 'accountEmail' => \IPS\Member::loggedIn() )
) );
/* Handle submissions */
$values = NULL;
@@ -634,7 +639,7 @@ class _settings extends \IPS\Dispatcher\Controller
return \IPS\Theme::i()->getTemplate( 'system' )->settingsMfaPassword( $login, $error );
}
}
/* Get our handlers and the output, even if it's just for a backdrop */
$handlers = array();
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
@@ -683,6 +688,9 @@ class _settings extends \IPS\Dispatcher\Controller
\IPS\Member::loggedIn()->members_bitoptions['security_questions_opt_out'] = FALSE;
\IPS\Member::loggedIn()->save();
/* Invalidate other sessions */
\IPS\Member::loggedIn()->invalidateSessionsAndLogins( \IPS\Session::i()->id );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ) );
}
@@ -720,10 +728,128 @@ class _settings extends \IPS\Dispatcher\Controller
return;
}
}
$output.= \IPS\Theme::i()->getTemplate( 'system' )->settingsPrivacy();
/* If we're still here, just show the screen */
return $output;
}
/**
* Request personal identifiable information
*
* @return void
*/
protected function requestPiiData()
{
if( !isset( $_SESSION['passwordValidatedForMfa'] ) OR !\IPS\Member\PrivacyAction::canRequestPiiData() OR \IPS\Settings::i()->pii_type !== 'on' )
{
\IPS\Output::i()->error( 'node_error', '1C122/10', 403, '' );
}
\IPS\Member\PrivacyAction::requestPiiData();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front')->setFragment('piiDataRequest'), 'pii_requested' );
}
/**
* Download personal identifiable information
*
* @return void
* @throws \Exception
*/
protected function downloadPiiData()
{
\IPS\Session::i()->csrfCheck();
if( !isset( $_SESSION['passwordValidatedForMfa'] ) OR !\IPS\Member\PrivacyAction::canDownloadPiiData() OR \IPS\Settings::i()->pii_type !== 'on' )
{
\IPS\Output::i()->error( 'node_error', '1C122/11', 403, '' );
}
$xml = \IPS\Member::loggedIn()->getPiiData();
\IPS\Db::i()->delete( 'core_member_privacy_actions', array( 'member_id=? AND action=?', \IPS\Member::loggedIn()->member_id, \IPS\Member\PrivacyAction::TYPE_REQUEST_PII ) );
\IPS\Db::i()->delete( 'core_notifications', array( 'member=? AND notification_key=?', \IPS\Member::loggedIn()->member_id, 'pii_data' ) );
\IPS\Member::loggedIn()->logHistory( 'core', 'privacy', array( 'type' => 'pii_download' ) );
\IPS\Output::i()->sendOutput( $xml->asXML(), 200, 'application/xml', [ 'Content-Disposition' => \IPS\Output::getContentDisposition( 'attachment', \IPS\Member::loggedIn()->name.'_personal_information.xml' ) ], FALSE, FALSE, FALSE );
}
/**
* Request account deletion
*
* @return void
*/
protected function requestAccountDeletion()
{
\IPS\Session::i()->csrfCheck();
if( !isset( $_SESSION['passwordValidatedForMfa'] ) OR !\IPS\Member::loggedIn()->canUseAccountDeletion() OR \IPS\Settings::i()->right_to_be_forgotten_type !== 'on' )
{
\IPS\Output::i()->error( 'node_error', '2C122/13', 403, '' );
}
if( !\IPS\Member\PrivacyAction::canDeleteAccount() )
{
\IPS\Output::i()->error( 'node_error', '1C122/12', 403, '' );
}
if( \IPS\Request::i()->vkey )
{
\IPS\Member\PrivacyAction::requestAccountDeletion( NULL, FALSE );
}
else
{
\IPS\Member\PrivacyAction::requestAccountDeletion(NULL, TRUE );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front')->setFragment('requestAccountDeletion'), 'account_deletion_requested' );
}
/**
* Cancel account deletion
*
* @return void
*/
protected function cancelAccountDeletion()
{
\IPS\Session::i()->csrfCheck();
try
{
$where = [];
$where[] = ['member_id=?', \IPS\Member::loggedIn()->member_id];
$where[] = [ \IPS\Db::i()->in( 'action',[\IPS\Member\PrivacyAction::TYPE_REQUEST_DELETE, \IPS\Member\PrivacyAction::TYPE_REQUEST_DELETE_VALIDATION ] ) ];
$row = \IPS\Db::i()->select( '*', \IPS\Member\PrivacyAction::$databaseTable, $where )->first();
\IPS\Member\PrivacyAction::constructFromData( $row )->delete();
\IPS\Member::loggedIn()->logHistory( 'core', 'privacy', [ 'type' => 'account_deletion_cancelled' ] );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front'), 'account_deletion_cancelled' );
}
catch( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2C122/Y', 404, '' );
}
}
/**
* Confirm account deletion
*
* @return void
*/
protected function confirmAccountDeletion()
{
$key = \IPS\Request::i()->vid;
try
{
$request = \IPS\Member\PrivacyAction::getDeletionRequestByMemberAndKey( \IPS\Member::loggedIn(), $key );
$request->confirmAccountDeletion();
\IPS\Output::i()->redirect( $this->url->setQueryString( 'area','mfa'), 'account_deletion_confirmed' );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C122/Z', 404, '' );
}
}
/**
* Initial MFA Setup
@@ -1225,8 +1351,9 @@ class _settings extends \IPS\Dispatcher\Controller
$content = nl2br( trim( $pre->nodeValue ) );
$preBreaks += \count( explode( "<br />", $content ) );
}
if ( \is_numeric( $sigLimits[5] ) and ( $signature->getElementsByTagName('p')->length + $signature->getElementsByTagName('br')->length + $preBreaks ) > $sigLimits[5] )
/* Line limit with a sensible length restriction to prevent broken html */
if ( ( \is_numeric( $sigLimits[5] ) and ( $signature->getElementsByTagName('p')->length + $signature->getElementsByTagName('br')->length + $preBreaks ) > $sigLimits[5] ) or \strlen( $values['signature'] ) > 20000 )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack('sig_num_lines_exceeded');
}
@@ -1729,6 +1856,12 @@ class _settings extends \IPS\Dispatcher\Controller
{
\IPS\Session::i()->csrfCheck();
/* Check validation */
if( !isset( $_SESSION['passwordValidatedForMfa'] ) )
{
\IPS\Output::i()->error( 'node_error', '1C122/14', 403, '' );
}
/* Check this value can be toggled */
if( \IPS\Member::loggedIn()->group['g_hide_online_list'] >= 1 )
{