Version 4.3.0

This commit is contained in:
Neo committed 2025-12-19 05:47:12 -08:00
1 parent 96997ddd8e
commit fe1acf984a
1349 files changed
+116159 -67711

No files matched your search

@@ -34,11 +34,19 @@ class _register extends \IPS\Dispatcher\Controller
\IPS\Output::i()->redirect( \IPS\Settings::i()->base_url );
}
if( !\IPS\Settings::i()->allow_reg and \IPS\Request::i()->do !== 'complete'
if( \IPS\Request::i()->do !== 'complete'
and \IPS\Request::i()->do !== 'changeEmail' and \IPS\Request::i()->do !== 'validate'
and \IPS\Request::i()->do !== 'validating' and \IPS\Request::i()->do !== 'reconfirm' )
and \IPS\Request::i()->do !== 'validating' and \IPS\Request::i()->do !== 'reconfirm'
and \IPS\Request::i()->do !== 'finish' )
{
\IPS\Output::i()->error( 'reg_disabled', '2S129/5', 403, '' );
if ( \IPS\Login::registrationType() == 'redirect' )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Settings::i()->allow_reg_target ) );
}
elseif ( \IPS\Login::registrationType() == 'disabled' )
{
\IPS\Output::i()->error( 'reg_disabled', '2S129/5', 403, '' );
}
}
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
@@ -62,20 +70,20 @@ class _register extends \IPS\Dispatcher\Controller
\IPS\Output::i()->allowDefaultWidgets = FALSE;
/* Quick registration does not work with COPPA */
if ( \IPS\Settings::i()->quick_register )
if ( \IPS\Login::registrationType() == 'normal' )
{
$form = $this->_registrationForm();
$form->class = 'ipsForm_fullWidth';
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('registration');
if( (string) \IPS\Request::i()->url() == (string) \IPS\Http\Url::internal( 'app=core&module=system&controller=register', NULL, 'register' ) )
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->register( $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupRegisterTemplate' ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) ) ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) ) );
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupRegisterTemplate' ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ), \IPS\Login::LOGIN_REGISTRATION_FORM ) );
}
else
{
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupRegisterTemplate' ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->register( $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupRegisterTemplate' ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ), \IPS\Login::LOGIN_REGISTRATION_FORM ) ), new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) ) );
}
return;
@@ -137,7 +145,7 @@ class _register extends \IPS\Dispatcher\Controller
{
$form = $this->_registrationForm();
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->register( $form, new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) ) );
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->register( $form, new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ), \IPS\Login::LOGIN_REGISTRATION_FORM ) );
};
/* Output */
@@ -209,18 +217,36 @@ class _register extends \IPS\Dispatcher\Controller
/* Log them in */
\IPS\Session::i()->setMember( $member );
\IPS\Member\Device::loadOrCreate( $member, FALSE )->updateAfterAuthentication( TRUE, '' );
\IPS\Member\Device::loadOrCreate( $member, FALSE )->updateAfterAuthentication( TRUE, NULL );
$redirectUrl = \IPS\Login::getRegistrationDestination( $member );
if ( isset( \IPS\Request::i()->ref ) and $ref = @base64_decode( \IPS\Request::i()->ref ) )
{
try
{
$ref = \IPS\Http\Url::createFromString( $ref );
if ( !( $ref instanceof \IPS\Http\Url\Internal ) or $ref->base !== 'front' )
{
throw new \Exception;
}
}
catch ( \Exception $e )
{
$ref = \IPS\Http\Url::internal('');
}
}
else
{
$ref = \IPS\Http\Url::internal('');
}
/* Redirect */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'redirect' => (string) $redirectUrl ) );
\IPS\Output::i()->json( array( 'redirect' => (string) $ref ) );
}
else
{
\IPS\Output::i()->redirect( $redirectUrl );
\IPS\Output::i()->redirect( $ref );
}
}
}
@@ -241,7 +267,7 @@ class _register extends \IPS\Dispatcher\Controller
$haveRequired = FALSE;
foreach( $steps AS $id => $step )
{
if ( $step->required )
if ( $step->required AND !$step->completed( \IPS\Member::loggedIn() ) )
{
$haveRequired = TRUE;
break;
@@ -253,8 +279,7 @@ class _register extends \IPS\Dispatcher\Controller
/* Nope, forward */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
$wizardSteps = array();
$url = \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=finish', 'front', 'register' );
foreach( \IPS\Application::allExtensions( 'core', 'ProfileSteps' ) AS $extension )
@@ -265,6 +290,8 @@ class _register extends \IPS\Dispatcher\Controller
}
}
$wizardSteps = \IPS\Member\ProfileStep::setOrder( $wizardSteps );
$wizardSteps = array_merge( $wizardSteps, array( 'profile_done' => function( $data ) {
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'saved' );
} ) );
@@ -288,11 +315,11 @@ class _register extends \IPS\Dispatcher\Controller
$form = new \IPS\Helpers\Form( 'form', 'register_button', NULL, array( 'data-controller' => 'core.front.system.register') );
$form->add( new \IPS\Helpers\Form\Text( 'username', NULL, TRUE, array( 'accountUsername' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array( 'accountEmail' => TRUE, 'maxLength' => 150, 'bypassProfanity' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array( 'showMeter' => \IPS\Settings::i()->password_strength_meter, 'checkStrength' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'password_confirm', NULL, TRUE, array( 'confirm' => 'password' ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array( 'showMeter' => \IPS\Settings::i()->password_strength_meter, 'checkStrength' => TRUE, 'bypassProfanity' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'password_confirm', NULL, TRUE, array( 'confirm' => 'password', 'bypassProfanity' => TRUE ) ) );
/* Profile fields */
if ( ! \IPS\Settings::i()->quick_register )
if ( \IPS\Login::registrationType() == 'full' )
{
foreach ( \IPS\core\ProfileFields\Field::fields( array(), \IPS\core\ProfileFields\Field::REG ) as $group => $fields )
{
@@ -330,7 +357,15 @@ class _register extends \IPS\Dispatcher\Controller
if( $qanda )
{
$question = \IPS\Db::i()->select( '*', 'core_question_and_answer', array( 'qa_id=?', $qanda ) )->first();
try
{
$question = \IPS\Db::i()->select( '*', 'core_question_and_answer', array( 'qa_id=?', $qanda ) )->first();
}
catch( \UnderflowException $e )
{
throw new \DomainException( 'q_and_a_incorrect' );
}
$answers = json_decode( $question['qa_answers'] );
if( $answers )
@@ -380,14 +415,14 @@ class _register extends \IPS\Dispatcher\Controller
$form->addSeparator();
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_admin_mails', TRUE, FALSE ) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_admin_mails', \IPS\Settings::i()->updates_consent_default == 'enabled' ? TRUE : FALSE, FALSE ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms' ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms', array(), \IPS\Http\Url::PROTOCOL_RELATIVE ) );
/* Build the appropriate links for registration terms & privacy policy */
if ( \IPS\Settings::i()->privacy_type == "internal" )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy' ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy', array(), \IPS\Http\Url::PROTOCOL_RELATIVE ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' );
}
else if ( \IPS\Settings::i()->privacy_type == "external" )
{
@@ -478,33 +513,40 @@ class _register extends \IPS\Dispatcher\Controller
$member = new \IPS\Member;
$member->name = $values['username'];
$member->email = $values['email_address'];
$member->members_pass_salt = $member->generateSalt();
$member->members_pass_hash = $member->encryptedPassword( $values['password'] );
$member->setLocalPassword( $values['password'] );
$member->allow_admin_mails = $values['reg_admin_mails'];
$member->member_group_id = \IPS\Settings::i()->member_group;
$member->members_bitoptions['view_sigs'] = TRUE;
$member->last_visit = time();
/* Query spam service */
$spamCode = NULL;
$spamAction = NULL;
if( \IPS\Settings::i()->spam_service_enabled )
{
if( $member->spamService() == 4 )
$spamAction = $member->spamService( 'register', NULL, $spamCode );
if( $spamAction == 4 )
{
\IPS\Output::i()->error( 'spam_denied_account', '2S129/1', 403, '' );
}
}
/* Initial Save */
$member->save();
/* This looks a bit weird, but the extensions expect an account to exist at this point, so we'll let the system save it now, then do what we need to do, then save again */
foreach( \IPS\Member\ProfileStep::loadAll() AS $step )
if ( \IPS\Settings::i()->quick_register )
{
$extension = $step->extension;
$extension::formatFormValues( $values, $member, $form );
/* Initial Save */
$member->save();
/* This looks a bit weird, but the extensions expect an account to exist at this point, so we'll let the system save it now, then do what we need to do, then save again */
foreach( \IPS\Member\ProfileStep::loadAll() AS $step )
{
$extension = $step->extension;
$extension::formatFormValues( $values, $member, $form );
}
}
/* Save anything the profile extensions did */
$member->save();
$member->logHistory( 'core', 'account', array( 'type' => 'register', 'spamCode' => $spamCode, 'spamAction' => $spamAction ), FALSE );
/* Security Questions */
if ( \IPS\Settings::i()->security_questions_enabled and in_array( \IPS\Settings::i()->security_questions_prompt, array( 'register', 'optional' ) ) )
@@ -550,7 +592,18 @@ class _register extends \IPS\Dispatcher\Controller
{
\IPS\Db::i()->replace( 'core_pfields_content', array_merge( array( 'member_id' => $member->member_id ), $profileFields ) );
}
/* Log that we gave consent for admin emails */
$member->logHistory( 'core', 'admin_mails', array( 'enabled' => (boolean) $member->allow_admin_mails ) );
/* Log that we gave consent for terms and privacy */
if ( \IPS\Settings::i()->privacy_type != 'none' )
{
$member->logHistory( 'core', 'terms_acceptance', array( 'type' => 'privacy' ) );
}
$member->logHistory( 'core', 'terms_acceptance', array( 'type' => 'terms' ) );
/* Handle validation */
$member->postRegistration();
@@ -593,7 +646,13 @@ class _register extends \IPS\Dispatcher\Controller
}
/* They're not validated but in what way? */
if( $validating['user_verified'] )
if ( $validating['reg_cancelled'] )
{
/* They are cancelled and will be deleted, haha, etc */
\IPS\Output::i()->error( 'reg_is_cancelled', '2C223/9', 403, '' );
}
else if ( $validating['user_verified'] )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->notAdminValidated();
}
@@ -690,7 +749,7 @@ class _register extends \IPS\Dispatcher\Controller
/* Check we are an incomplete member */
if ( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
elseif ( \IPS\Member::loggedIn()->real_name and \IPS\Member::loggedIn()->email )
{
@@ -711,6 +770,17 @@ class _register extends \IPS\Dispatcher\Controller
{
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array( 'accountEmail' => TRUE ) ) );
}
if ( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms' ) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_agreed_terms', NULL, TRUE, array(), function( $val )
{
if ( !$val )
{
throw new \InvalidArgumentException('reg_not_agreed_terms');
}
} ) );
}
$form->addButton( 'cancel', 'link', \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=cancel', 'front', 'register' )->csrf() );
/* Handle the submission */
@@ -720,13 +790,16 @@ class _register extends \IPS\Dispatcher\Controller
{
\IPS\Member::loggedIn()->name = $values['username'];
}
$spamCode = NULL;
$spamAction = NULL;
if( isset( $values['email_address'] ) )
{
\IPS\Member::loggedIn()->email = $values['email_address'];
if( \IPS\Settings::i()->spam_service_enabled )
{
if( \IPS\Member::loggedIn()->spamService() == 4 )
$spamAction = \IPS\Member::loggedIn()->spamService( 'register', NULL, $spamCode );
if( $spamAction == 4 )
{
$action = \IPS\Settings::i()->spam_service_action_4;
@@ -740,9 +813,11 @@ class _register extends \IPS\Dispatcher\Controller
}
}
}
\IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] = FALSE;
/* Save */
\IPS\Member::loggedIn()->save();
\IPS\Member::loggedIn()->logHistory( 'core', 'account', array( 'type' => 'complete' ), FALSE );
/* Handle validation */
\IPS\Member::loggedIn()->postRegistration( ( isset( $values['email_address'] ) ) ? FALSE : TRUE );
@@ -751,7 +826,26 @@ class _register extends \IPS\Dispatcher\Controller
\IPS\Session::i()->setType( \IPS\Session\Front::LOGIN_TYPE_MEMBER );
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Login::getRegistrationDestination( \IPS\Member::loggedIn() ) );
if ( isset( \IPS\Request::i()->ref ) and $ref = @base64_decode( \IPS\Request::i()->ref ) )
{
try
{
$ref = \IPS\Http\Url::createFromString( $ref );
if ( !( $ref instanceof \IPS\Http\Url\Internal ) or $ref->base !== 'front' )
{
throw new \Exception;
}
}
catch ( \Exception $e )
{
$ref = \IPS\Http\Url::internal('');
}
}
else
{
$ref = \IPS\Http\Url::internal('');
}
\IPS\Output::i()->redirect( $ref );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_complete_details');
@@ -784,7 +878,7 @@ class _register extends \IPS\Dispatcher\Controller
/* Build the form */
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Email( 'new_email', '', TRUE, array( 'accountEmail' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Email( 'new_email', '', TRUE, array( 'accountEmail' => \IPS\Member::loggedIn() ) ) );
$captcha = new \IPS\Helpers\Form\Captcha;
if ( (string) $captcha !== '' )
{
@@ -794,17 +888,33 @@ class _register extends \IPS\Dispatcher\Controller
/* Handle submissions */
if ( $values = $form->values() )
{
/* Check spam defense whitelist */
if( \IPS\Settings::i()->spam_service_enabled AND ( isset( $pending['new_reg'] ) AND $pending['new_reg'] ) AND \IPS\Member::loggedIn()->spamDefenseWhitelist() )
{
/* We specifically say it's 'register' so that actions are still performed on the account */
$newEmailScore = \IPS\Member::loggedIn()->spamService( 'register', $values['new_email'] );
/* Is it a ban response? */
if( $newEmailScore == 4 )
{
\IPS\Output::i()->error( 'spam_denied_account', '2C223/A', 403, '' );
}
}
/* Change the email */
$oldEmail = \IPS\Member::loggedIn()->email;
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
\IPS\Member::loggedIn()->email = $values['new_email'];
\IPS\Member::loggedIn()->save();
foreach ( \IPS\Login::methods() as $method )
{
try
{
$handler->changeEmail( \IPS\Member::loggedIn(), $oldEmail, $values['new_email'] );
$method->changeEmail( \IPS\Member::loggedIn(), $oldEmail, $values['new_email'] );
}
catch( \BadMethodCallException $e ) {}
}
\IPS\Member::loggedIn()->save();
\IPS\Member::loggedIn()->memberSync( 'onEmailChange', array( $values['new_email'], $oldEmail ) );
\IPS\Member::loggedIn()->logHistory( 'core', 'email_change', array( 'old' => $oldEmail, 'new' => $values['new_email'], 'by' => 'manual' ) );
/* Invalidate sessions except this one */
\IPS\Member::loggedIn()->invalidateSessionsAndLogins( \IPS\Session::i()->id );
@@ -879,16 +989,9 @@ class _register extends \IPS\Dispatcher\Controller
/* Member sync callback */
\IPS\Member::loggedIn()->memberSync( 'onLogout', array( \IPS\Http\Url::internal( '' ) ) );
/* Login handler callback */
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
try
{
$handler->logoutAccount( \IPS\Member::loggedIn(), \IPS\Http\Url::internal( '' ) );
}
catch( \BadMethodCallException $e ) {}
}
/* Flag user as having cancelled their registration */
\IPS\Db::i()->update( 'core_validating', array( 'reg_cancelled' => time() ), array( 'member_id=? AND new_reg=1', \IPS\Member::loggedIn()->member_id ) );
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'reg_canceled' );
@@ -902,23 +1005,27 @@ class _register extends \IPS\Dispatcher\Controller
protected function reconfirm()
{
/* Generate form */
$form = new \IPS\Helpers\Form;
$form = new \IPS\Helpers\Form( 'reconfirm_checkbox', 'reconfirm_checkbox' );
if ( isset( \IPS\Request::i()->ref ) )
{
$form->hiddenValues['ref'] = \IPS\Request::i()->ref;
}
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Checkbox( 'reconfirm_checkbox', NULL, FALSE, array(), function( $val )
{
if ( !$val )
{
throw new \InvalidArgumentException('reg_not_agreed_terms');
}
} ) );
/* Handle submissions */
if ( $values = $form->values() )
{
/* Log that we gave consent */
if ( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'] )
{
\IPS\Member::loggedIn()->logHistory( 'core', 'terms_acceptance', array( 'type' => 'privacy' ) );
}
if ( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] )
{
\IPS\Member::loggedIn()->logHistory( 'core', 'terms_acceptance', array( 'type' => 'terms' ) );
}
\IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'] = FALSE;
\IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] = FALSE;
\IPS\Member::loggedIn()->save();