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

+22 -15
View File
@@ -56,8 +56,8 @@ class _ajax extends \IPS\Dispatcher\Controller
$results[] = array(
'id' => $member->member_id,
'value' => $member->name,
'name' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->group['prefix'] . htmlspecialchars( $member->name, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ) . $member->group['suffix'] : htmlspecialchars( $member->name, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ),
'extra' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? htmlspecialchars( $member->email, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ) : $member->groupName,
'name' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->group['prefix'] . htmlspecialchars( $member->name, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ) . $member->group['suffix'] : htmlspecialchars( $member->name, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ),
'extra' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? htmlspecialchars( $member->email, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ) : $member->groupName,
'photo' => (string) $member->photo,
);
}
@@ -342,9 +342,9 @@ class _ajax extends \IPS\Dispatcher\Controller
$return['notifications']['data'][] = array(
'id' => $notification->id,
'title' => htmlspecialchars( $data['title'], \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ),
'title' => htmlspecialchars( $data['title'], ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ),
'url' => (string) $data['url'],
'content' => isset( $data['content'] ) ? htmlspecialchars( $data['content'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : NULL,
'content' => isset( $data['content'] ) ? htmlspecialchars( $data['content'], ENT_DISALLOWED, 'UTF-8', FALSE ) : NULL,
'date' => $notification->updated_time->getTimestamp(),
'author_photo' => $data['author'] ? $data['author']->photo : NULL
);
@@ -360,17 +360,24 @@ class _ajax extends \IPS\Dispatcher\Controller
foreach ( \IPS\Db::i()->select( 'map_topic_id', 'core_message_topic_user_map', array( 'map_user_id=? AND map_user_active=1 AND map_has_unread=1 AND map_ignore_notification=0', \IPS\Member::loggedIn()->member_id ), 'map_last_topic_reply DESC', $messagesDifference ) as $conversationId )
{
$conversation = \IPS\core\Messenger\Conversation::load( $conversationId );
$message = $conversation->comments( 1, 0, 'date', 'desc' );
$return['messages']['data'][] = array(
'id' => $conversation->id,
'title' => htmlspecialchars( $conversation->title, \IPS\HTMLENTITIES | ENT_QUOTES, 'UTF-8', FALSE ),
'url' => (string) $conversation->url()->setQueryString( 'latest', 1 ),
'message' => $message->truncated(),
'date' => $message->mapped('date'),
'author_photo' => (string) $message->author()->photo
);
$conversation = \IPS\core\Messenger\Conversation::load( $conversationId );
$message = $conversation->comments( 1, 0, 'date', 'desc' );
if( $message )
{
$return['messages']['data'][] = array(
'id' => $conversation->id,
'title' => htmlspecialchars( $conversation->title, ENT_DISALLOWED | ENT_QUOTES, 'UTF-8', FALSE ),
'url' => (string) $conversation->url()->setQueryString( 'latest', 1 ),
'message' => $message->truncated(),
'date' => $message->mapped('date'),
'author_photo' => (string) $message->author()->photo
);
}
else
{
\IPS\Log::log( "Private conversation {$conversation->id} titled {$conversation->title} has no messages", 'orphaned_data' );
}
}
}
}
@@ -0,0 +1,41 @@
<?php
/**
* @brief Cookie Policy
* @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 12 Dec 2017
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Cookie Policy
*/
class _cookies extends \IPS\Dispatcher\Controller
{
/**
* Privacy Policy
*
* @return void
*/
protected function manage()
{
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=cookies', NULL, 'cookies' ), array(), 'loc_viewing_cookie_policy' );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('cookies_about') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cookies_about');
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->cookies();
}
}
@@ -29,6 +29,6 @@ class _designermode extends \IPS\Dispatcher\Controller
*/
protected function missing()
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'theme_designers_mode_error_missing', FALSE, array( 'sprintf' => array( \IPS\Request::i()->id ) ) ), "DESMODE", 500 );
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'theme_designers_mode_error_missing', FALSE, array( 'sprintf' => array( intval( \IPS\Request::i()->id ) ) ) ), "4C370/1", 500 );
}
}
@@ -51,7 +51,7 @@ class _editor extends \IPS\Dispatcher\Controller
protected function code()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->code( \IPS\Request::i()->val, \IPS\Request::i()->editorId, md5( uniqid() ), \IPS\Request::i()->lang ?: '' );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->code( \IPS\Request::i()->val, \IPS\Request::i()->editorId, md5( mt_rand() ), \IPS\Request::i()->lang ?: '' );
}
/**
@@ -155,7 +155,7 @@ class _editor extends \IPS\Dispatcher\Controller
}
else
{
$title = \IPS\Request::i()->title ?: $url;
$title = \IPS\Request::i()->title ?: (string) $url;
$insert = "<a href='{$url}' ipsNoEmbed='true'>{$title}</a>";
}
@@ -178,41 +178,42 @@ class _editor extends \IPS\Dispatcher\Controller
}
/**
* Get Emoticons Configuration
* Get Emoji
*
* @return void
*/
protected function emoticons()
protected function emoji()
{
$emoticons = array();
$emoji = ( \IPS\Settings::i()->emoji_style == 'disabled' or !\IPS\Settings::i()->getFromConfGlobal('sql_utf8mb4') ) ? array() : json_decode( file_get_contents( \IPS\ROOT_PATH . '/applications/core/data/emoji.json' ), TRUE );
foreach ( \IPS\Db::i()->select( '*', 'core_emoticons', NULL, 'emo_set_position,emo_position' ) as $row )
{
if ( !isset( $emoticons[ $row['emo_set'] ] ) )
$shortcode = ( \IPS\Settings::i()->emoji_shortcodes and preg_match( '/^:.*:$/', $row['typed'] ) );
try
{
$setLang = 'core_emoticon_group_' . $row['emo_set'];
$emoticons[ $row['emo_set'] ] = array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( $setLang ),
'total' => 0,
'emoticons' => array(),
);
$categoryName = \IPS\Member::loggedIn()->language()->get( 'core_emoticon_group_' . $row['emo_set'] );
}
catch( \UnderflowException $e )
{
$categoryName = '_default';
}
$emoticons[ $row['emo_set'] ]['emoticons'][] = array(
'src' => \IPS\File::get( 'core_Emoticons', $row['image'] )->url,
'srcset' => $row['image_2x'] ? \IPS\File::get( 'core_Emoticons', $row['image_2x'] )->url . ' 2x' : FALSE,
'height' => $row['height'] ?: FALSE,
'width' => $row['width'] ?: FALSE,
'text' => $row['typed']
$emoji[ $row['emo_set'] ][] = array(
'code' => 'custom-' . $row['emo_set'] . '-' . $row['id'],
'name' => $row['typed'],
'skinTone' => false,
'shortNames' => $shortcode ? array( trim( $row['typed'], ':' ) ) : array(),
'ascii' => $shortcode ? array() : array( $row['typed'] ),
'categoryName' => $categoryName,
'image' => \IPS\File::get( 'core_Emoticons', $row['image'] )->url,
'image2x' => $row['image_2x'] ? \IPS\File::get( 'core_Emoticons', $row['image_2x'] )->url : FALSE,
'width' => $row['width'],
'height' => $row['height'],
);
}
}
foreach ( $emoticons as $set => $data )
{
$emoticons[ $set ]['total'] = count( $data['emoticons'] );
}
\IPS\Output::i()->json( $emoticons );
\IPS\Output::i()->json( $emoji );
}
/**
@@ -37,9 +37,6 @@ class _followed extends \IPS\Dispatcher\Controller
/* Get the different types */
$types = array();
/* Don't forget Members */
$types['core'] = array( 'core_member' => "\IPS\Member" );
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
{
@@ -61,6 +58,9 @@ class _followed extends \IPS\Dispatcher\Controller
}
}
}
/* Don't forget Members - add this on to the end so it never defaults UNLESS we only have apps that do not have followable content */
$types['core'] = array( 'core_member' => "\IPS\Member" );
/* What type are we looking at? */
$currentAppModule = NULL;
@@ -84,11 +84,6 @@ class _followed extends \IPS\Dispatcher\Controller
{
foreach ( $_types as $key => $class )
{
if ( $key == 'core_member' )
{
continue;
}
$currentAppModule = $appModule;
$currentType = $key;
break 2;
@@ -31,11 +31,14 @@ class _guidelines extends \IPS\Dispatcher\Controller
{
if ( \IPS\Settings::i()->gl_type == "none" )
{
\IPS\Output::i()->error( 'node_error', '', 404 ); /* @todo Error code */
\IPS\Output::i()->error( 'node_error', '2C380/1', 404, 'guidelines_set_to_none_admin' );
}
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=guidelines', NULL, 'guidelines' ), array(), 'loc_viewing_guidelines' );
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('guidelines') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('guidelines');
+81 -115
View File
@@ -34,24 +34,47 @@ class _login extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('') );
}
/* Force HTTPs? */
if ( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and \IPS\Settings::i()->logins_over_https and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) );
}
/* Init login class */
$login = new \IPS\Login( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) );
/* Init login class */
$login = new \IPS\Login( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login' ) );
/* What's our referrer? */
$ref = \IPS\Request::i()->ref;
/* Process */
$error = isset( \IPS\Request::i()->_err ) && \IPS\Member::loggedIn()->language()->checkKeyExists( \IPS\Request::i()->_err ) ? \IPS\Request::i()->_err : NULL;
$error = NULL;
try
{
$member = $login->authenticate();
if ( $member !== NULL )
if ( $success = $login->authenticate() )
{
$this->_doLogin( $member, $login->flags['signin_anonymous'], $login->flags['remember_me'], \IPS\Login::getDestination(), FALSE, $login->usedHandler );
if ( $ref and $ref = @base64_decode( $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('');
}
if ( $success->mfa() )
{
$_SESSION['processing2FA'] = array( 'memberId' => $success->member->member_id, 'anonymous' => $success->anonymous, 'remember' => $success->rememberMe, 'destination' => (string) $ref, 'handler' => $success->handler->id );
\IPS\Output::i()->redirect( $ref->setQueryString( '_mfaLogin', 1 ) );
}
$success->process();
\IPS\Output::i()->redirect( $ref->setQueryString( '_fromLogin', 1 ) );
}
}
catch ( \IPS\Login\Exception $e )
@@ -59,91 +82,33 @@ class _login extends \IPS\Dispatcher\Controller
if ( $e->getCode() === \IPS\Login\Exception::MERGE_SOCIAL_ACCOUNT )
{
$e->member = $e->member->member_id;
$e->handler = $e->handler->id;
$_SESSION['linkAccounts'] = json_encode( $e );
$linkUrl = \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=link', 'front', 'login' );
if ( isset( \IPS\Request::i()->ref ) )
{
$linkUrl = $linkUrl->setQueryString( 'ref', \IPS\Request::i()->ref );
}
\IPS\Output::i()->redirect( $linkUrl );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=link', 'front', 'login' )->setQueryString( 'ref', $ref ), '', 303 );
}
$error = $e->getMessage();
}
if ( \IPS\Request::i()->isAjax() && $error )
{
\IPS\Output::i()->json( array( 'status' => 'error', 'error' => $error ), 401 );
}
else
{
/* Display Login Form */
\IPS\Output::i()->allowDefaultWidgets = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->login( $login->forms(), $error );
}
/* Display Login Form */
\IPS\Output::i()->allowDefaultWidgets = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->login( $login, $ref, $error );
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', NULL, 'login' ), array(), 'loc_logging_in' );
}
/**
* Process the login
*
* @param \IPS\Member $member The member
* @param bool $anonymous If the login is anonymous
* @param bool $rememberMe If the "remember me" checkbox was checked
* @param \IPS\Http\Url $destination Where to redirect to
* @param bool $bypass2FA If true, will not perform 2FA check
* @param string $loginHandler Which login handler processed the login
* @return void
*/
protected function _doLogin( $member, $anonymous=FALSE, $rememberMe=TRUE, $destination=NULL, $bypass2FA=FALSE, $loginHandler=NULL )
{
/* Get destination */
if ( !$destination )
{
$destination = \IPS\Http\Url::internal( '' );
}
/* Is this a known device? */
$device = \IPS\Member\Device::loadOrCreate( $member );
/* Do we need to do 2FA? */
if ( !$bypass2FA and $output = \IPS\MFA\MFAHandler::accessToArea( 'core', $device->known ? 'AuthenticateFrontKnown' : 'AuthenticateFront', \IPS\Http\Url::internal( '' ), $member ) )
{
$_SESSION['processing2FA'] = array( 'memberId' => $member->member_id, 'anonymous' => $anonymous, 'remember' => $rememberMe, 'destination' => (string) $destination, 'handler' => $loginHandler );
\IPS\Output::i()->redirect( $destination->setQueryString( '_mfaLogin', 1 ) );
}
/* Log in */
\IPS\Session::i()->setMember( $member );
if ( $anonymous and !\IPS\Settings::i()->disable_anonymous )
{
\IPS\Session::i()->setAnon();
}
/* Log device */
$device->anonymous = $anonymous and !\IPS\Settings::i()->disable_anonymous;
$device->updateAfterAuthentication( $rememberMe, $loginHandler );
/* Member sync */
$member->memberSync( 'onLogin', array( \IPS\Login::getDestination() ) );
/* Redirect */
\IPS\Output::i()->redirect( $destination->setQueryString( '_fromLogin', 1 ), '', 303 );
}
/**
* MFA
*
* @return void
*/
protected function mfa()
{
{
/* Have we logged in? */
$member = NULL;
if ( isset( $_SESSION['processing2FA'] ) )
@@ -156,7 +121,7 @@ class _login extends \IPS\Dispatcher\Controller
}
/* Where do we want to go? */
$destination = NULL;
$destination = \IPS\Http\Url::internal( '' );
try
{
$destination = \IPS\Http\Url::createFromString( $_SESSION['processing2FA']['destination'] );
@@ -167,8 +132,9 @@ class _login extends \IPS\Dispatcher\Controller
$device = \IPS\Member\Device::loadOrCreate( $member );
$output = \IPS\MFA\MFAHandler::accessToArea( 'core', $device->known ? 'AuthenticateFrontKnown' : 'AuthenticateFront', \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=mfa', 'front', 'login' ), $member );
if ( !$output )
{
$this->_doLogin( $member, $_SESSION['processing2FA']['anonymous'], $_SESSION['processing2FA']['remember'], $destination, TRUE, $_SESSION['processing2FA']['handler'] );
{
( new \IPS\Login\Success( $member, \IPS\Login\Handler::load( $_SESSION['processing2FA']['handler'] ), $_SESSION['processing2FA']['remember'], $_SESSION['processing2FA']['anonymous'] ) )->process();
\IPS\Output::i()->redirect( $destination->setQueryString( '_fromLogin', 1 ), '', 303 );
}
/* Nope, just send us where we want to go not logged in */
@@ -199,35 +165,36 @@ class _login extends \IPS\Dispatcher\Controller
*/
protected function link()
{
/* Get the member we're linking with */
if ( !isset( $_SESSION['linkAccounts'] ) )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
$details = json_decode( $_SESSION['linkAccounts'], TRUE );
$member = \IPS\Member::load( $details['member'] );
if ( !$member->member_id )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
$form = new \IPS\Helpers\Form( 'link_accounts', 'login' );
if ( isset( \IPS\Request::i()->ref ) )
/* And then handler to link with */
$handler = \IPS\Login\Handler::load( $details['handler'] );
/* Init reauthentication */
$login = new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=link', 'front', 'login' )->setQueryString( 'ref', isset( \IPS\Request::i()->ref ) ? \IPS\Request::i()->ref : NULL ), \IPS\Login::LOGIN_REAUTHENTICATE );
$login->reauthenticateAs = $member;
$error = NULL;
/* If successful (or if there's no way to reauthenticate which would only happen if a login handler has been deleted)) complete the link... */
try
{
$form->hiddenValues['ref'] = \IPS\Request::i()->ref;
}
$form->addDummy( 'email_address', htmlspecialchars( isset( $details['email'] ) ? $details['email'] : $member->email, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array( 'validateFor' => $member ) ) );
if ( $values = $form->values() )
{
try
{
$class = 'IPS\Login\\' . ucfirst( $details['handler'] );
$class::link( $member, $details['details'] );
if ( $success = $login->authenticate() or ( !count( $login->usernamePasswordMethods() ) and !count( $login->buttonMethods() ) ) )
{
$handler->completeLink( $member, $details['details'] );
unset( $_SESSION['linkAccounts'] );
$destination = NULL;
$destination = \IPS\Http\Url::internal( '' );
if ( isset( \IPS\Request::i()->ref ) )
{
try
@@ -240,18 +207,27 @@ class _login extends \IPS\Dispatcher\Controller
}
catch ( \Exception $e ) { }
}
$this->_doLogin( $member, FALSE, TRUE, $destination, FALSE, $details['handler'] );
$success = new \IPS\Login\Success( $member, $handler );
if ( $success->mfa() )
{
$_SESSION['processing2FA'] = array( 'memberId' => $success->member->member_id, 'anonymous' => $success->anonymous, 'remember' => $success->rememberMe, 'destination' => (string) $destination, 'handler' => $success->handler->id );
\IPS\Output::i()->redirect( $destination->setQueryString( '_mfaLogin', 1 ) );
}
$success->process();
\IPS\Output::i()->redirect( $destination->setQueryString( '_fromLogin', 1 ) );
}
catch ( \IPS\Login\Exception $e )
{
$form->error = $e->getMessage();
}
}
catch ( \IPS\Login\Exception $e )
{
$error = $e->getMessage();
}
/* Otherwise show the reauthenticate form */
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->mergeSocialAccount( $details['handler'], $member, $form );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->mergeSocialAccount( $handler, $member, $login, $error );
}
/**
@@ -309,16 +285,6 @@ class _login extends \IPS\Dispatcher\Controller
setcookie( session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"] );
session_destroy();
/* Login handler callback */
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
try
{
$handler->logoutAccount( $member, $redirectUrl );
}
catch( \BadMethodCallException $e ) {}
}
/* Member sync callback */
$member->memberSync( 'onLogout', array( $redirectUrl ) );
@@ -345,7 +311,7 @@ class _login extends \IPS\Dispatcher\Controller
/* Not logged in as admin? */
if ( $admin->member_id != \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 )->setQueryString( array( 'ref' => base64_encode( \IPS\Request::i()->url() ), '_err' => 'login_as_user_login' ) ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login' )->setQueryString( array( 'ref' => base64_encode( \IPS\Request::i()->url() ), '_err' => 'login_as_user_login' ) ) );
}
/* Do it */
@@ -22,6 +22,26 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _lostpass extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
if ( \IPS\Settings::i()->allow_forgot_password == 'disabled' )
{
\IPS\Output::i()->error( 'page_doesnt_exist', '2S151/2', 404, '' );
}
if ( \IPS\Settings::i()->allow_forgot_password == 'redirect' )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Settings::i()->allow_forgot_password_target ) );
}
return parent::execute();
}
/**
* Manage
*
@@ -32,11 +52,7 @@ class _lostpass extends \IPS\Dispatcher\Controller
/* Build the form */
$form = new \IPS\Helpers\Form( "lostpass", 'request_password' );
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array( 'bypassProfanity' => TRUE ), function( $val ){
/* Check email exists */
$member = \IPS\Member::load( $val, 'email' );
if( !$member->member_id )
if( !\IPS\Login::emailIsInUse( $val ) )
{
throw new \LogicException( 'lost_pass_no_email' );
}
@@ -47,62 +63,107 @@ class _lostpass extends \IPS\Dispatcher\Controller
/* Handle the reset */
if ( $values = $form->values() )
{
/* Load the member */
/* If using "normal" method and we have an account, and at least one login handler we can process a password change for, we're good */
$member = \IPS\Member::load( $values['email_address'], 'email' );
/* If we have an existing validation record, we can just reuse it */
$sendEmail = TRUE;
try
if ( $member->member_id and \IPS\Settings::i()->allow_forgot_password == 'normal' )
{
$existing = \IPS\Db::i()->select( array( 'vid', 'email_sent' ), 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) )->first();
$vid = $existing['vid'];
/* If we sent a lost password email within the last 15 minutes, don't send another one otherwise someone could be a nuisence */
if ( $existing['email_sent'] and $existing['email_sent'] > ( time() - 900 ) )
foreach ( \IPS\Login::methods() as $method )
{
$sendEmail = FALSE;
if ( $method->canChangePassword( $member ) )
{
return $this->_sendForgotPasswordEmail( $member );
}
}
else
{
\IPS\Db::i()->update( 'core_validating', array( 'email_sent' => time() ), array( 'vid=?', $vid ) );
}
}
catch ( \UnderflowException $e )
{
$vid = md5( $member->members_pass_hash . \IPS\Login::generateRandomString() );
\IPS\Db::i()->insert( 'core_validating', array(
'vid' => $vid,
'member_id' => $member->member_id,
'entry_date' => time(),
'lost_pass' => 1,
'ip_address' => $member->ip_address,
'email_sent' => time(),
) );
}
/* Send email */
if ( $sendEmail )
/* If not, send them to the handler if we can */
foreach( \IPS\Login::methods() as $method )
{
\IPS\Email::buildFromTemplate( 'core', 'lost_password_init', array( $member, $vid ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $member );
$message = "lost_pass_confirm";
if( $method->emailIsInUse( $values['email_address'] ) === TRUE )
{
if ( $url = $method->forgotPasswordUrl() )
{
\IPS\Output::i()->redirect( $url );
}
}
}
/* If we have no way to reset the password, can we allow creating a local password as a last attempt? */
if ( $member->member_id )
{
foreach( \IPS\Login::methods() as $method )
{
if ( $method instanceof \IPS\Login\Handler\Standard )
{
return $this->_sendForgotPasswordEmail( $member );
}
}
}
/* Otherwise, sorry, we can't do this */
\IPS\Output::i()->error( 'lost_pass_not_possible', '1S151/3', 403, '' );
}
/* Show form */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPass( $form );
}
/**
* Send forgot password email
*
* @param \IPS\Member $member The member
* @return void
*/
protected function _sendForgotPasswordEmail( \IPS\Member $member )
{
/* If we have an existing validation record, we can just reuse it */
$sendEmail = TRUE;
try
{
$existing = \IPS\Db::i()->select( array( 'vid', 'email_sent' ), 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) )->first();
$vid = $existing['vid'];
/* If we sent a lost password email within the last 15 minutes, don't send another one otherwise someone could be a nuisence */
if ( $existing['email_sent'] and $existing['email_sent'] > ( time() - 900 ) )
{
$sendEmail = FALSE;
}
else
{
$message = "lost_pass_too_soon";
\IPS\Db::i()->update( 'core_validating', array( 'email_sent' => time() ), array( 'vid=?', $vid ) );
}
/* Show confirmation page with further instructions */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPassConfirm( $message );
}
catch ( \UnderflowException $e )
{
$vid = md5( $member->members_pass_hash . \IPS\Login::generateRandomString() );
\IPS\Db::i()->insert( 'core_validating', array(
'vid' => $vid,
'member_id' => $member->member_id,
'entry_date' => time(),
'lost_pass' => 1,
'ip_address' => $member->ip_address,
'email_sent' => time(),
) );
}
/* Send email */
if ( $sendEmail )
{
\IPS\Email::buildFromTemplate( 'core', 'lost_password_init', array( $member, $vid ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $member );
$message = "lost_pass_confirm";
}
else
{
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPass( $form );
$message = "lost_pass_too_soon";
}
/* Show confirmation page with further instructions */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPassConfirm( $message );
}
/**
@@ -135,21 +196,17 @@ class _lostpass extends \IPS\Dispatcher\Controller
/* Reset the failed logins storage - we don't need to save because the login handler will do that for us later */
$member->failed_logins = array();
/* Now reset the member's password */
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
/* Now reset the member's password. If no handlers accept the change, create a local password */
if ( !$member->changePassword( $values['password'], 'lost' ) )
{
/* We cannot update our password in some login handlers, that's ok */
try
{
$handler->changePassword( $member, $values['password'] );
}
catch( \BadMethodCallException $e ){}
$member->setLocalPassword( $values['password'] );
$member->save();
}
/* Log in, and invalidate all other sessions */
\IPS\Session::i()->setMember( $member );
$member->invalidateSessionsAndLogins( \IPS\Session::i()->id );
\IPS\Member\Device::loadOrCreate( $member )->updateAfterAuthentication( isset( \IPS\Request::i()->cookie['login_key'] ), '' );
\IPS\Member\Device::loadOrCreate( $member )->updateAfterAuthentication( isset( \IPS\Request::i()->cookie['login_key'] ) );
/* Delete validating record and log in */
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) );
@@ -93,6 +93,8 @@ class _metatags extends \IPS\Dispatcher\Controller
*/
protected function end()
{
\IPS\Session::i()->csrfCheck();
$_SESSION['live_meta_tags'] = FALSE;
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( \IPS\Request::i()->url ) );
@@ -113,6 +113,12 @@ class _notifications extends \IPS\Dispatcher\Controller
/* Handle submissions */
if ( $values = $form->values() )
{
/* Log if admin mail setting is changed */
if ( \IPS\Member::loggedIn()->allow_admin_mails !== $values['allow_admin_mails'] )
{
\IPS\Member::loggedIn()->logHistory( 'core', 'admin_mails', array( 'enabled' => $values['allow_admin_mails'] ) );
}
\IPS\Member::loggedIn()->allow_admin_mails = $values['allow_admin_mails'];
\IPS\Member::loggedIn()->auto_track = json_encode( array(
'content' => ( is_array( $values['auto_track'] ) AND in_array( 'content', $values['auto_track'] ) ) ? 1 : 0,
@@ -168,12 +174,12 @@ class _notifications extends \IPS\Dispatcher\Controller
{
foreach ( $ext->classes as $classname )
{
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname;
break;
}
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname::$containerNodeClass;
break;
@@ -182,7 +188,7 @@ class _notifications extends \IPS\Dispatcher\Controller
{
foreach( $classname::$containerFollowClasses as $followClass )
{
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $followClass;
break;
@@ -216,6 +222,11 @@ class _notifications extends \IPS\Dispatcher\Controller
$class = 'IPS\\Member';
}
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'club' )
{
$class = 'IPS\Member\Club';
}
if ( !$class )
{
\IPS\Output::i()->error( 'node_error', '2C154/3', 404, '' );
@@ -223,7 +234,6 @@ class _notifications extends \IPS\Dispatcher\Controller
/* Get thing */
$thing = NULL;
$indexId = NULL;
try
{
if ( in_array( 'IPS\Node\Model', class_parents( $class ) ) )
@@ -242,17 +252,19 @@ class _notifications extends \IPS\Dispatcher\Controller
}
catch ( \Exception $e ) { }
}
else if ( $class != "IPS\Member" )
elseif ( $class == 'IPS\Member\Club' )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'follow_thing', FALSE, array( 'sprintf' => array( $thing->_title ) ) );
\IPS\Output::i()->breadcrumb = array(
array( \IPS\Http\Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), \IPS\Member::loggedIn()->language()->addToStack('module__core_clubs') ),
array( $thing->url(), $thing->name )
);
}
elseif ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'follow_thing', FALSE, array( 'sprintf' => array( $thing->mapped('title') ) ) );
/* Work out the index ID */
try
{
$indexId = \IPS\Content\Search\Index::i()->getIndexId( $thing );
}
catch ( \UnderflowException $e ) { }
/* Set navigation */
$container = NULL;
@@ -300,7 +312,7 @@ class _notifications extends \IPS\Dispatcher\Controller
{
$type = 'follower_content';
}
elseif ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
elseif ( $class == 'IPS\Member\Club' or in_array( 'IPS\Content\Item', class_parents( $class ) ) )
{
$type = 'new_comment';
}
@@ -348,8 +360,11 @@ class _notifications extends \IPS\Dispatcher\Controller
if ( $class != "IPS\Member" )
{
$options['daily'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_daily');
$options['weekly'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_weekly');
if ( $class != "IPS\Member\Club" )
{
$options['daily'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_daily');
$options['weekly'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_weekly');
}
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_no_notification');
}
@@ -361,7 +376,7 @@ class _notifications extends \IPS\Dispatcher\Controller
) ) );
}
else
{
{
foreach ( $options as $k => $v )
{
$form->hiddenValues[ $k ] = $v;
@@ -401,7 +416,6 @@ class _notifications extends \IPS\Dispatcher\Controller
'follow_notify_freq' => ( $class == "IPS\Member" ) ? 'immediate' : $values['follow_type'],
'follow_notify_sent' => 0,
'follow_visible' => 1,
'follow_index_id' => $indexId,
);
if ( $current )
{
@@ -412,6 +426,33 @@ class _notifications extends \IPS\Dispatcher\Controller
\IPS\Db::i()->insert( 'core_follow', $save );
}
/* Also follow all nodes if following club */
if( $class == "IPS\Member\Club" )
{
foreach ( $thing->nodes() as $node )
{
$itemClass = $node['node_class']::$contentItemClass;
$followApp = $itemClass::$application;
$followArea = mb_strtolower( mb_substr( $node['node_class'], mb_strrpos( $node['node_class'], '\\' ) + 1 ) );
$save = array(
'follow_id' => md5( $followApp . ';' . $followArea . ';' . $node['node_id'] . ';' . \IPS\Member::loggedIn()->member_id ),
'follow_app' => $followApp,
'follow_area' => $followArea,
'follow_rel_id' => $node['node_id'],
'follow_member_id' => \IPS\Member::loggedIn()->member_id,
'follow_is_anon' => !$values['follow_public'],
'follow_added' => time(),
'follow_notify_do' => ( isset( $values['follow_type'] ) AND $values['follow_type'] == 'none' ) ? 0 : 1,
'follow_notify_meta' => '',
'follow_notify_freq' => $values['follow_type'],
'follow_notify_sent' => 0,
'follow_visible' => 1,
);
\IPS\Db::i()->insert( 'core_follow', $save, TRUE );
}
}
/* Send notification if following member */
if( $class == "IPS\Member" )
{
@@ -463,40 +504,46 @@ class _notifications extends \IPS\Dispatcher\Controller
\IPS\Db::i()->delete( 'core_follow', array( 'follow_id=? AND follow_member_id=?', \IPS\Request::i()->id, \IPS\Member::loggedIn()->member_id ) );
/* Get class */
$class = NULL;
foreach ( \IPS\Application::load( \IPS\Request::i()->follow_app )->extensions( 'core', 'ContentRouter' ) as $ext )
/* Get class */
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
foreach ( $ext->classes as $classname )
$class = 'IPS\\Member';
}
elseif( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'club' )
{
$class = 'IPS\\Member\Club';
}
else
{
$class = NULL;
foreach ( \IPS\Application::load( \IPS\Request::i()->follow_app )->extensions( 'core', 'ContentRouter' ) as $ext )
{
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
foreach ( $ext->classes as $classname )
{
$class = $classname;
break;
}
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname::$containerNodeClass;
break;
}
if( isset( $classname::$containerFollowClasses ) )
{
foreach( $classname::$containerFollowClasses as $followClass )
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
$class = $classname;
break;
}
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname::$containerNodeClass;
break;
}
if( isset( $classname::$containerFollowClasses ) )
{
foreach( $classname::$containerFollowClasses as $followClass )
{
$class = $followClass;
break;
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $followClass;
break;
}
}
}
}
}
}
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
$class = 'IPS\\Member';
}
/* Get thing */
$thing = NULL;
@@ -515,6 +562,19 @@ class _notifications extends \IPS\Dispatcher\Controller
catch ( \OutOfRangeException $e )
{
}
/* Unfollow club areas */
if( $class == "IPS\Member\Club" )
{
foreach ( $thing->nodes() as $node )
{
$itemClass = $node['node_class']::$contentItemClass;
$followApp = $itemClass::$application;
$followArea = mb_strtolower( mb_substr( $node['node_class'], mb_strrpos( $node['node_class'], '\\' ) + 1 ) );
\IPS\Db::i()->delete( 'core_follow', array( 'follow_id=? AND follow_member_id=?', md5( $followApp . ';' . $followArea . ';' . $node['node_id'] . ';' . \IPS\Member::loggedIn()->member_id ), \IPS\Member::loggedIn()->member_id ) );
}
}
if ( \IPS\Request::i()->isAjax() )
{
@@ -542,9 +602,13 @@ class _notifications extends \IPS\Dispatcher\Controller
{
$class = 'IPS\\Member';
}
else if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'club' )
{
$class = 'IPS\\Member\Club';
}
else
{
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area );
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area );
}
if ( !class_exists( $class ) )
@@ -566,6 +630,13 @@ class _notifications extends \IPS\Dispatcher\Controller
$anonymous = $classname::containerFollowers( $thing, $classname::FOLLOW_ANONYMOUS )->count( TRUE );
$title = $thing->_title;
}
else if ( $class == "IPS\Member\Club" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
$followers = $thing->followers( $class::FOLLOW_PUBLIC, array( 'none', 'immediate', 'daily', 'weekly' ), NULL, array( ( $thisPage - 1 ) * $perPage, $perPage ), 'name' );
$anonymous = $thing->followers( $class::FOLLOW_ANONYMOUS )->count( TRUE );
$title = $thing->_title;
}
else if ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
@@ -617,9 +688,13 @@ class _notifications extends \IPS\Dispatcher\Controller
{
$class = 'IPS\\Member';
}
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'club' )
{
$class = 'IPS\\Member\Club';
}
else
{
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area );
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area );
}
if ( !class_exists( $class ) )
{
@@ -693,6 +768,23 @@ class _notifications extends \IPS\Dispatcher\Controller
\IPS\Db::i()->delete( 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=?', \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id ) );
if( \IPS\Request::i()->follow_area == 'club' )
{
try
{
$club = \IPS\Member\Club::load( \IPS\Request::i()->follow_id );
foreach ( $club->nodes() as $node )
{
$itemClass = $node['node_class']::$contentItemClass;
$followApp = $itemClass::$application;
$followArea = mb_strtolower( mb_substr( $node['node_class'], mb_strrpos( $node['node_class'], '\\' ) + 1 ) );
\IPS\Db::i()->delete( 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=?', $followApp, $followArea, $node['node_id'] ) );
}
}
catch ( \OutOfRangeException $e ) { }
}
\IPS\Output::i()->redirect( ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::createFromString( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' ), 'followers_removed' );
}
}
@@ -31,7 +31,7 @@ class _privacy extends \IPS\Dispatcher\Controller
{
if ( \IPS\Settings::i()->privacy_type == "none" )
{
\IPS\Output::i()->error( 'node_error', '', 404 ); /* @todo Error code */
\IPS\Output::i()->error( 'node_error', '2C381/1', 404, 'privacy_set_to_none_acp' );
}
/* Set Session Location */
@@ -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();
File diff suppressed because it is too large. Load diff
@@ -31,10 +31,10 @@ class _twitter extends \IPS\Dispatcher\Controller
{
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 )->setQueryString( 'ref', base64_encode( \IPS\Http\Url::internal( 'app=core&module=system&controller=twitter' ) ) ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login' )->setQueryString( 'ref', base64_encode( \IPS\Http\Url::internal( 'app=core&module=system&controller=twitter' ) ) ) );
}
$twitter = \IPS\Login::getHandler('Twitter');
$twitter = \IPS\Login\Handler::findMethod('IPS\Login\Handler\Oauth1\Twitter');
$promote = \IPS\core\Promote::getPromoter( 'Twitter' );
$url = \IPS\Http\Url::internal( 'app=core&module=system&controller=twitter' );
@@ -43,8 +43,7 @@ class _twitter extends \IPS\Dispatcher\Controller
/* Get a request token */
if ( !isset( \IPS\Request::i()->oauth_token ) )
{
$callback = $url->setQueryString( 'csrf', \IPS\Session::i()->csrfKey );
$response = $twitter->sendRequest( 'get', 'https://api.twitter.com/oauth/request_token', array( 'oauth_callback' => (string) $callback ) )->decodeQueryString('oauth_token');
$response = $twitter->requestToken( $url->setQueryString( 'csrf', \IPS\Session::i()->csrfKey ) );
\IPS\Output::i()->redirect( "https://api.twitter.com/oauth/authorize?force_login=1&oauth_token={$response['oauth_token']}" );
}
@@ -55,9 +54,7 @@ class _twitter extends \IPS\Dispatcher\Controller
}
/* Authenticate */
$response = $twitter->sendRequest( 'post', 'https://api.twitter.com/oauth/access_token', array( 'oauth_verifier' => \IPS\Request::i()->oauth_verifier ), \IPS\Request::i()->oauth_token )->decodeQueryString('user_id');
$user = $twitter->sendRequest( 'get', 'https://api.twitter.com/1.1/account/verify_credentials.json', array(), $response['oauth_token'], $response['oauth_token_secret'] )->decodeJson();
$response = $twitter->exchangeToken( \IPS\Request::i()->oauth_verifier, \IPS\Request::i()->oauth_token );
/* Store the settings */
$promote->saveSettings( array(
@@ -65,17 +62,19 @@ class _twitter extends \IPS\Dispatcher\Controller
'owner' => \IPS\Member::loggedIn()->member_id,
'secret' => $response['oauth_token_secret'],
'token' => $response['oauth_token'],
'name' => $user['screen_name']
'name' => $response['screen_name']
) );
/* Show a done page */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('promote_twitter_sorted');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'promote' )->promoteTwitterComplete( $user );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'promote' )->promoteTwitterComplete( $response );
}
catch ( \Exception $e )
{
throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR );
\IPS\Log::log( $e, 'twitter_promote' );
\IPS\Output::i()->error( 'generic_error', '4C375/1', 403, $e->getMessage() );
}
}
}
@@ -49,6 +49,9 @@ class _unsubscribe extends \IPS\Dispatcher\Controller
$member->allow_admin_mails = 0;
$member->save();
/* Log it */
$member->logHistory( 'core', 'admin_mails', array( 'enabled' => FALSE ) );
/* And then show them a confirmation screen */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('unsubscribed');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->unsubscribed();
+12 -6
View File
@@ -81,7 +81,7 @@ class _vse extends \IPS\Dispatcher\Controller
/* VSE CSS */
if ( isset( $css['core']['front']['custom']['vse.css'] ) )
{
$functionName = "css_" . uniqid();
$functionName = "css_" . mt_rand();
\IPS\Theme::makeProcessFunction( \IPS\Theme::fixResourceTags( $css['core']['front']['custom']['vse.css']['css_content'], 'front' ), $functionName, '', FALSE, TRUE );
$vseCss = call_user_func( 'IPS\\Theme\\'. $functionName );
}
@@ -89,7 +89,7 @@ class _vse extends \IPS\Dispatcher\Controller
if ( isset( $css['core']['front']['custom']['custom.css'] ) )
{
/* Custom CSS */
$functionName = "css_" . uniqid();
$functionName = "css_" . mt_rand();
\IPS\Theme::makeProcessFunction( \IPS\Theme::fixResourceTags( $css['core']['front']['custom']['custom.css']['css_content'], 'front' ), $functionName, '', FALSE, TRUE );
$customCss = call_user_func( 'IPS\\Theme\\'. $functionName );
}
@@ -133,10 +133,16 @@ class _vse extends \IPS\Dispatcher\Controller
$options['options'] = $options;
break;
}
$field = new $class( "core_theme_setting_title_{$data['sc_id']}", $value, false, $options );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $data['sc_title'], FALSE, array( 'escape' => true ) );
$form->add( $field );
if ( class_exists( $class ) )
{
$field = new $class( "core_theme_setting_title_{$data['sc_id']}", $value, false, $options );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $data['sc_title'], FALSE, array( 'escape' => true ) );
$form->add( $field );
}
else
{
\IPS\Log::log( 'VSE tried to load ' . $class . ' for theme setting ' . $key, 'vse_error' );
}
}
}
@@ -135,7 +135,7 @@ class _warnings extends \IPS\Content\Controller
{
\IPS\Output::i()->error( 'no_module_permission', '2C184/6', 403, '' );
}
/* Build the form */
$form = \IPS\core\Warnings\Warning::create();
$form->class = 'ipsForm_vertical';
@@ -165,7 +165,7 @@ class _warnings extends \IPS\Content\Controller
}
/**
* Axknowledge Warning
* Acknowledge Warning
*
* @return void
*/
@@ -262,7 +262,13 @@ class _warnings extends \IPS\Content\Controller
* @return void
*/
protected function reasonAjax()
{
{
/* Check permission */
if ( ! ( \IPS\Settings::i()->warn_on AND \IPS\Member::loggedIn()->modPermission('mod_see_warn') ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
}
$remove = array(
'date' => NULL,
'time' => NULL,
@@ -351,6 +357,13 @@ class _warnings extends \IPS\Content\Controller
);
$member = \IPS\Member::load( \IPS\Request::i()->member );
/* Check permission */
if ( !( \IPS\Settings::i()->warn_on AND ( \IPS\Member::loggedIn()->modPermission('mod_see_warn') or ( \IPS\Settings::i()->warn_show_own and \IPS\Member::loggedIn()->member_id == $member->member_id ) ) ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
}
try
{
$action = \IPS\Db::i()->select( '*', 'core_members_warn_actions', array( 'wa_points<=?', ( $member->warn_level + \IPS\Request::i()->points ) ), 'wa_points DESC', 1 )->first();
@@ -68,7 +68,7 @@ class _widgets extends \IPS\Dispatcher\Controller
}
}
$block = \IPS\Widget::load( $appOrPlugin, $widget['key'], uniqid(), array(), $widget['restrict'], null );
$block = \IPS\Widget::load( $appOrPlugin, $widget['key'], mt_rand(), array(), $widget['restrict'], null );
$block->allowReuse = (boolean) $widget['allow_reuse'];
$block->menuStyle = $widget['menu_style'];
@@ -131,12 +131,20 @@ class _widgets extends \IPS\Dispatcher\Controller
}
}
}
catch ( \OutOfRangeException $e ) { }
catch ( \UnderflowException $e ) { }
}
if ( !isset( $widget ) )
{
$widget = \IPS\Widget::load( ( $key[0] == 'plugin' ) ? \IPS\Plugin::load( $key[1] ) : \IPS\Application::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
try
{
$widget = \IPS\Widget::load( ( $key[0] == 'plugin' ) ? \IPS\Plugin::load( $key[1] ) : \IPS\Application::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
}
catch( \OutOfRangeException $e )
{
$widget = '';
}
}
\IPS\Output::i()->sendOutput( (string) $widget );
@@ -217,6 +225,7 @@ class _widgets extends \IPS\Dispatcher\Controller
$blocks[ $k ]['configuration'] = $values;
\IPS\Db::i()->insert( 'core_widget_areas', array( 'app' => \IPS\Request::i()->pageApp, 'module' => \IPS\Request::i()->pageModule, 'controller' => \IPS\Request::i()->pageController, 'area' => \IPS\Request::i()->pageArea, 'widgets' => json_encode( $blocks ) ), TRUE );
\IPS\Widget::deleteCaches( $block['key'], ( isset( $block['app'] ) ) ? $block['app'] : NULL, ( isset( $block['plugin'] ) ) ? $block['plugin'] : NULL );
\IPS\Output::i()->json( 'OK' );
}
\IPS\Output::i()->output = $widget->configuration()->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'widgets', 'core' ) ), 'formTemplate' ), $widget );