Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/css/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/css/com_users.tar

controller.php000064400000006212151165234420007444 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users master display controller.
 *
 * @since  1.6
 */
class UsersController extends JControllerLegacy
{
	/**
	 * Checks whether a user can see this view.
	 *
	 * @param   string  $view  The view name.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	protected function canView($view)
	{
		$canDo = JHelperContent::getActions('com_users');

		switch ($view)
		{
			// Special permissions.
			case 'groups':
			case 'group':
			case 'levels':
			case 'level':
				return $canDo->get('core.admin');
				break;

			// Default permissions.
			default:
				return true;
		}
	}

	/**
	 * Method to display a view.
	 *
	 * @param   boolean  $cachable   If true, the view output will be cached
	 * @param   array    $urlparams  An array of safe URL parameters and their
variable types, for valid values see {@link JFilterInput::clean()}.
	 *
	 * @return  JController	 This object to support chaining.
	 *
	 * @since   1.5
	 */
	public function display($cachable = false, $urlparams = false)
	{
		$view   = $this->input->get('view', 'users');
		$layout = $this->input->get('layout',
'default');
		$id     = $this->input->getInt('id');

		if (!$this->canView($view))
		{
			throw new
JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'),
403);
		}

		// Check for edit form.
		if ($view == 'user' && $layout == 'edit'
&& !$this->checkEditId('com_users.edit.user', $id))
		{
			// Somehow the person just went to the form - we don't allow that.
			$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID',
$id));
			$this->setMessage($this->getError(), 'error');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=users',
false));

			return false;
		}
		elseif ($view == 'group' && $layout == 'edit'
&& !$this->checkEditId('com_users.edit.group', $id))
		{
			// Somehow the person just went to the form - we don't allow that.
			$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID',
$id));
			$this->setMessage($this->getError(), 'error');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=groups',
false));

			return false;
		}
		elseif ($view == 'level' && $layout == 'edit'
&& !$this->checkEditId('com_users.edit.level', $id))
		{
			// Somehow the person just went to the form - we don't allow that.
			$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID',
$id));
			$this->setMessage($this->getError(), 'error');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=levels',
false));

			return false;
		}
		elseif ($view == 'note' && $layout == 'edit'
&& !$this->checkEditId('com_users.edit.note', $id))
		{
			// Somehow the person just went to the form - we don't allow that.
			$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID',
$id));
			$this->setMessage($this->getError(), 'error');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=notes',
false));

			return false;
		}

		return parent::display();
	}
}
controllers/profile.php000064400000013641151165234420011273
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersController', JPATH_COMPONENT .
'/controller.php');

/**
 * Profile controller class for Users.
 *
 * @since  1.6
 */
class UsersControllerProfile extends UsersController
{
	/**
	 * Method to check out a user for editing and redirect to the edit form.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public function edit()
	{
		$app         = JFactory::getApplication();
		$user        = JFactory::getUser();
		$loginUserId = (int) $user->get('id');

		// Get the previous user id (if any) and the current user id.
		$previousId = (int)
$app->getUserState('com_users.edit.profile.id');
		$userId     = $this->input->getInt('user_id');

		// Check if the user is trying to edit another users profile.
		if ($userId != $loginUserId)
		{
			$app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'),
'error');
			$app->setHeader('status', 403, true);

			return false;
		}

		$cookieLogin = $user->get('cookieLogin');

		// Check if the user logged in with a cookie
		if (!empty($cookieLogin))
		{
			// If so, the user must login to edit the password and other data.
			$app->enqueueMessage(JText::_('JGLOBAL_REMEMBER_MUST_LOGIN'),
'message');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));

			return false;
		}

		// Set the user id for the user to edit in the session.
		$app->setUserState('com_users.edit.profile.id', $userId);

		// Get the model.
		$model = $this->getModel('Profile', 'UsersModel');

		// Check out the user.
		if ($userId)
		{
			$model->checkout($userId);
		}

		// Check in the previous user.
		if ($previousId)
		{
			$model->checkin($previousId);
		}

		// Redirect to the edit screen.
		$this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit',
false));

		return true;
	}

	/**
	 * Method to save a user's profile data.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function save()
	{
		// Check for request forgeries.
		$this->checkToken();

		$app    = JFactory::getApplication();
		$model  = $this->getModel('Profile',
'UsersModel');
		$user   = JFactory::getUser();
		$userId = (int) $user->get('id');

		// Get the user data.
		$requestData = $app->input->post->get('jform',
array(), 'array');

		// Force the ID to this user.
		$requestData['id'] = $userId;

		// Validate the posted data.
		$form = $model->getForm();

		if (!$form)
		{
			JError::raiseError(500, $model->getError());

			return false;
		}

		// Send an object which can be modified through the plugin event
		$objData = (object) $requestData;
		$app->triggerEvent(
			'onContentNormaliseRequestData',
			array('com_users.user', $objData, $form)
		);
		$requestData = (array) $objData;

		// Validate the posted data.
		$data = $model->validate($form, $requestData);

		// Check for errors.
		if ($data === false)
		{
			// Get the validation messages.
			$errors = $model->getErrors();

			// Push up to three validation messages out to the user.
			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(),
'warning');
				}
				else
				{
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			// Unset the passwords.
			unset($requestData['password1'],
$requestData['password2']);

			// Save the data in the session.
			$app->setUserState('com_users.edit.profile.data',
$requestData);

			// Redirect back to the edit screen.
			$userId = (int)
$app->getUserState('com_users.edit.profile.id');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit&user_id='
. $userId, false));

			return false;
		}

		// Attempt to save the data.
		$return = $model->save($data);

		// Check for errors.
		if ($return === false)
		{
			// Save the data in the session.
			$app->setUserState('com_users.edit.profile.data', $data);

			// Redirect back to the edit screen.
			$userId = (int)
$app->getUserState('com_users.edit.profile.id');
			$this->setMessage(JText::sprintf('COM_USERS_PROFILE_SAVE_FAILED',
$model->getError()), 'warning');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit&user_id='
. $userId, false));

			return false;
		}

		// Redirect the user and adjust session state based on the chosen task.
		switch ($this->getTask())
		{
			case 'apply':
				// Check out the profile.
				$app->setUserState('com_users.edit.profile.id', $return);
				$model->checkout($return);

				// Redirect back to the edit screen.
				$this->setMessage(JText::_('COM_USERS_PROFILE_SAVE_SUCCESS'));

				$redirect =
$app->getUserState('com_users.edit.profile.redirect');

				// Don't redirect to an external URL.
				if (!JUri::isInternal($redirect))
				{
					$redirect = null;
				}

				if (!$redirect)
				{
					$redirect =
'index.php?option=com_users&view=profile&layout=edit&hidemainmenu=1';
				}

				$this->setRedirect(JRoute::_($redirect, false));
				break;

			default:
				// Check in the profile.
				$userId = (int)
$app->getUserState('com_users.edit.profile.id');

				if ($userId)
				{
					$model->checkin($userId);
				}

				// Clear the profile id from the session.
				$app->setUserState('com_users.edit.profile.id', null);

				$redirect =
$app->getUserState('com_users.edit.profile.redirect');

				// Don't redirect to an external URL.
				if (!JUri::isInternal($redirect))
				{
					$redirect = null;
				}

				if (!$redirect)
				{
					$redirect =
'index.php?option=com_users&view=profile&user_id=' .
$return;
				}

				// Redirect to the list screen.
				$this->setMessage(JText::_('COM_USERS_PROFILE_SAVE_SUCCESS'));
				$this->setRedirect(JRoute::_($redirect, false));
				break;
		}

		// Flush the data from the session.
		$app->setUserState('com_users.edit.profile.data', null);
	}
}
controllers/registration.php000064400000015420151165234420012342
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersController', JPATH_COMPONENT .
'/controller.php');

/**
 * Registration controller class for Users.
 *
 * @since  1.6
 */
class UsersControllerRegistration extends UsersController
{
	/**
	 * Method to activate a user.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function activate()
	{
		$user  	 = JFactory::getUser();
		$input 	 = JFactory::getApplication()->input;
		$uParams = JComponentHelper::getParams('com_users');

		// Check for admin activation. Don't allow non-super-admin to delete
a super admin
		if ($uParams->get('useractivation') != 2 &&
$user->get('id'))
		{
			$this->setRedirect('index.php');

			return true;
		}

		// If user registration or account activation is disabled, throw a 403.
		if ($uParams->get('useractivation') == 0 ||
$uParams->get('allowUserRegistration') == 0)
		{
			JError::raiseError(403,
JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));

			return false;
		}

		$model = $this->getModel('Registration',
'UsersModel');
		$token = $input->getAlnum('token');

		// Check that the token is in a valid format.
		if ($token === null || strlen($token) !== 32)
		{
			JError::raiseError(403, JText::_('JINVALID_TOKEN'));

			return false;
		}

		// Get the User ID
		$userIdToActivate = $model->getUserIdFromToken($token);

		if (!$userIdToActivate)
		{
			$this->setMessage(JText::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));

			return false;
		}

		// Get the user we want to activate
		$userToActivate = JFactory::getUser($userIdToActivate);

		// Admin activation is on and admin is activating the account
		if (($uParams->get('useractivation') == 2) &&
$userToActivate->getParam('activate', 0))
		{
			// If a user admin is not logged in, redirect them to the login page
with an error message
			if (!$user->authorise('core.create', 'com_users')
|| !$user->authorise('core.manage', 'com_users'))
			{
				$activationUrl =
'index.php?option=com_users&task=registration.activate&token='
. $token;
				$loginUrl      =
'index.php?option=com_users&view=login&return=' .
base64_encode($activationUrl);

				// In case we still run into this in the second step the user does not
have the right permissions
				$message =
JText::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION_PERMISSIONS');

				// When we are not logged in we should login
				if ($user->guest)
				{
					$message =
JText::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION');
				}

				$this->setMessage($message);
				$this->setRedirect(JRoute::_($loginUrl, false));

				return false;
			}
		}

		// Attempt to activate the user.
		$return = $model->activate($token);

		// Check for errors.
		if ($return === false)
		{
			// Redirect back to the home page.
			$this->setMessage(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED',
$model->getError()), 'error');
			$this->setRedirect('index.php');

			return false;
		}

		$useractivation = $uParams->get('useractivation');

		// Redirect to the login screen.
		if ($useractivation == 0)
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));
		}
		elseif ($useractivation == 1)
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_ACTIVATE_SUCCESS'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));
		}
		elseif ($return->getParam('activate'))
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_VERIFY_SUCCESS'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete',
false));
		}
		else
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_ADMINACTIVATE_SUCCESS'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete',
false));
		}

		return true;
	}

	/**
	 * Method to register a user.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function register()
	{
		// Check for request forgeries.
		$this->checkToken();

		// If registration is disabled - Redirect to login page.
		if
(JComponentHelper::getParams('com_users')->get('allowUserRegistration')
== 0)
		{
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));

			return false;
		}

		$app   = JFactory::getApplication();
		$model = $this->getModel('Registration',
'UsersModel');

		// Get the user data.
		$requestData = $this->input->post->get('jform',
array(), 'array');

		// Validate the posted data.
		$form = $model->getForm();

		if (!$form)
		{
			JError::raiseError(500, $model->getError());

			return false;
		}

		$data = $model->validate($form, $requestData);

		// Check for validation errors.
		if ($data === false)
		{
			// Get the validation messages.
			$errors = $model->getErrors();

			// Push up to three validation messages out to the user.
			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(),
'error');
				}
				else
				{
					$app->enqueueMessage($errors[$i], 'error');
				}
			}

			// Save the data in the session.
			$app->setUserState('com_users.registration.data',
$requestData);

			// Redirect back to the registration screen.
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration',
false));

			return false;
		}

		// Attempt to save the data.
		$return = $model->register($data);

		// Check for errors.
		if ($return === false)
		{
			// Save the data in the session.
			$app->setUserState('com_users.registration.data', $data);

			// Redirect back to the edit screen.
			$this->setMessage($model->getError(), 'error');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration',
false));

			return false;
		}

		// Flush the data from the session.
		$app->setUserState('com_users.registration.data', null);

		// Redirect to the profile screen.
		if ($return === 'adminactivate')
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_COMPLETE_VERIFY'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete',
false));
		}
		elseif ($return === 'useractivate')
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_COMPLETE_ACTIVATE'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete',
false));
		}
		else
		{
			$this->setMessage(JText::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false));
		}

		return true;
	}
}
controllers/remind.php000064400000002621151165234420011105 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersController', JPATH_COMPONENT .
'/controller.php');

/**
 * Reset controller class for Users.
 *
 * @since  1.6
 */
class UsersControllerRemind extends UsersController
{
	/**
	 * Method to request a username reminder.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public function remind()
	{
		// Check the request token.
		$this->checkToken('post');

		$model = $this->getModel('Remind', 'UsersModel');
		$data  = $this->input->post->get('jform', array(),
'array');

		// Submit the password reset request.
		$return	= $model->processRemindRequest($data);

		// Check for a hard error.
		if ($return == false && JDEBUG)
		{
			// The request failed.
			// Go back to the request form.
			$message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED',
$model->getError());
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=remind',
false), $message, 'notice');

			return false;
		}

		// To not expose if the user exists or not we send a generic message.
		$message = JText::_('COM_USERS_REMIND_REQUEST');
		$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false), $message, 'notice');

		return true;
	}
}
controllers/reset.php000064400000011203151165234420010745 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersController', JPATH_COMPONENT .
'/controller.php');

/**
 * Reset controller class for Users.
 *
 * @since  1.6
 */
class UsersControllerReset extends UsersController
{
	/**
	 * Method to request a password reset.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public function request()
	{
		// Check the request token.
		$this->checkToken('post');

		$app   = JFactory::getApplication();
		$model = $this->getModel('Reset', 'UsersModel');
		$data  = $this->input->post->get('jform', array(),
'array');

		// Submit the password reset request.
		$return	= $model->processResetRequest($data);

		// Check for a hard error.
		if ($return instanceof Exception && JDEBUG)
		{
			// Get the error message to display.
			if ($app->get('error_reporting'))
			{
				$message = $return->getMessage();
			}
			else
			{
				$message = JText::_('COM_USERS_RESET_REQUEST_ERROR');
			}

			// Go back to the request form.
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset',
false), $message, 'error');

			return false;
		}
		elseif ($return === false && JDEBUG)
		{
			// The request failed.
			// Go back to the request form.
			$message = JText::sprintf('COM_USERS_RESET_REQUEST_FAILED',
$model->getError());
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset',
false), $message, 'notice');

			return false;
		}

		// To not expose if the user exists or not we send a generic message.
		$message = JText::_('COM_USERS_RESET_REQUEST');
		$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'notice');

		return true;
	}

	/**
	 * Method to confirm the password request.
	 *
	 * @return  boolean
	 *
	 * @access	public
	 * @since   1.6
	 */
	public function confirm()
	{
		// Check the request token.
		$this->checkToken('request');

		$app   = JFactory::getApplication();
		$model = $this->getModel('Reset', 'UsersModel');
		$data  = $this->input->get('jform', array(),
'array');

		// Confirm the password reset request.
		$return	= $model->processResetConfirm($data);

		// Check for a hard error.
		if ($return instanceof Exception)
		{
			// Get the error message to display.
			if ($app->get('error_reporting'))
			{
				$message = $return->getMessage();
			}
			else
			{
				$message = JText::_('COM_USERS_RESET_CONFIRM_ERROR');
			}

			// Go back to the confirm form.
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'error');

			return false;
		}
		elseif ($return === false)
		{
			// Confirm failed.
			// Go back to the confirm form.
			$message = JText::sprintf('COM_USERS_RESET_CONFIRM_FAILED',
$model->getError());
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'notice');

			return false;
		}
		else
		{
			// Confirm succeeded.
			// Proceed to step three.
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete',
false));

			return true;
		}
	}

	/**
	 * Method to complete the password reset process.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public function complete()
	{
		// Check for request forgeries
		$this->checkToken('post');

		$app   = JFactory::getApplication();
		$model = $this->getModel('Reset', 'UsersModel');
		$data  = $this->input->post->get('jform', array(),
'array');

		// Complete the password reset request.
		$return	= $model->processResetComplete($data);

		// Check for a hard error.
		if ($return instanceof Exception)
		{
			// Get the error message to display.
			if ($app->get('error_reporting'))
			{
				$message = $return->getMessage();
			}
			else
			{
				$message = JText::_('COM_USERS_RESET_COMPLETE_ERROR');
			}

			// Go back to the complete form.
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete',
false), $message, 'error');

			return false;
		}
		elseif ($return === false)
		{
			// Complete failed.
			// Go back to the complete form.
			$message = JText::sprintf('COM_USERS_RESET_COMPLETE_FAILED',
$model->getError());
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete',
false), $message, 'notice');

			return false;
		}
		else
		{
			// Complete succeeded.
			// Proceed to the login form.
			$message = JText::_('COM_USERS_RESET_COMPLETE_SUCCESS');
			$this->setRedirect(JRoute::_('index.php?option=com_users&view=login',
false), $message);

			return true;
		}
	}
}
controllers/user.php000064400000003763151165234420010615 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User controller class.
 *
 * @since  1.6
 */
class UsersControllerUser extends JControllerForm
{
	/**
	 * @var    string  The prefix to use with controller messages.
	 * @since  1.6
	 */
	protected $text_prefix = 'COM_USERS_USER';

	/**
	 * Overrides JControllerForm::allowEdit
	 *
	 * Checks that non-Super Admins are not editing Super Admins.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean  True if allowed, false otherwise.
	 *
	 * @since   1.6
	 */
	protected function allowEdit($data = array(), $key = 'id')
	{
		// Check if this person is a Super Admin
		if (JAccess::check($data[$key], 'core.admin'))
		{
			// If I'm not a Super Admin, then disallow the edit.
			if (!JFactory::getUser()->authorise('core.admin'))
			{
				return false;
			}
		}

		return parent::allowEdit($data, $key);
	}

	/**
	 * Method to run batch operations.
	 *
	 * @param   object  $model  The model.
	 *
	 * @return  boolean  True on success, false on failure
	 *
	 * @since   2.5
	 */
	public function batch($model = null)
	{
		$this->checkToken();

		// Set the model
		$model = $this->getModel('User', '', array());

		// Preset the redirect
		$this->setRedirect(JRoute::_('index.php?option=com_users&view=users'
. $this->getRedirectToListAppend(), false));

		return parent::batch($model);
	}

	/**
	 * Function that allows child controller access to model data after the
data has been saved.
	 *
	 * @param   JModelLegacy  $model      The data model object.
	 * @param   array         $validData  The validated data.
	 *
	 * @return  void
	 *
	 * @since   3.1
	 */
	protected function postSaveHook(JModelLegacy $model, $validData = array())
	{
		return;
	}
}
helpers/html/users.php000064400000013716151165234420011037 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Extended Utility class for the Users component.
 *
 * @since  2.5
 */
class JHtmlUsers
{
	/**
	 * Display an image.
	 *
	 * @param   string  $src  The source of the image
	 *
	 * @return  string  A <img> element if the specified file exists,
otherwise, a null string
	 *
	 * @since   2.5
	 */
	public static function image($src)
	{
		$src = preg_replace('#[^A-Z0-9\-_\./]#i', '', $src);
		$file = JPATH_SITE . '/' . $src;

		jimport('joomla.filesystem.path');
		JPath::check($file);

		if (!file_exists($file))
		{
			return '';
		}

		return '<img src="' . JUri::root() . $src .
'" alt="" />';
	}

	/**
	 * Displays an icon to add a note for this user.
	 *
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to add a note
	 *
	 * @since   2.5
	 */
	public static function addNote($userId)
	{
		$title = JText::_('COM_USERS_ADD_NOTE');

		return '<a href="' .
JRoute::_('index.php?option=com_users&task=note.add&u_id='
. (int) $userId) . '" class="hasTooltip btn btn-mini"
title="'
			. $title . '"><span class="icon-vcard"
aria-hidden="true"></span><span
class="hidden-phone">' . $title .
'</span></a>';
	}

	/**
	 * Displays an icon to filter the notes list on this user.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to apply a filter
	 *
	 * @since   2.5
	 */
	public static function filterNotes($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::_('COM_USERS_FILTER_NOTES');

		return '<a href="' .
JRoute::_('index.php?option=com_users&view=notes&filter[search]=uid:'
. (int) $userId)
			. '" class="hasTooltip btn btn-mini"
title="' . $title . '"><span
class="icon-filter"></span></a>';
	}

	/**
	 * Displays a note icon.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to a modal window with the user notes
	 *
	 * @since   2.5
	 */
	public static function notes($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::plural('COM_USERS_N_USER_NOTES', $count);

		return '<button type="button"
data-target="#userModal_' . (int) $userId . '"
id="modal-' . (int) $userId . '"
data-toggle="modal"'
			. ' class="hasTooltip btn btn-mini" title="' .
$title . '">'
			. '<span class="icon-drawer-2"
aria-hidden="true"></span><span
class="hidden-phone">' . $title .
'</span></button>';
	}

	/**
	 * Renders the modal html.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string   The html for the rendered modal
	 *
	 * @since   3.4.1
	 */
	public static function notesModal($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::plural('COM_USERS_N_USER_NOTES', $count);
		$footer = '<button type="button" class="btn"
data-dismiss="modal">'
			. JText::_('JTOOLBAR_CLOSE') . '</button>';

		return JHtml::_(
			'bootstrap.renderModal',
			'userModal_' . (int) $userId,
			array(
				'title'       => $title,
				'backdrop'    => 'static',
				'keyboard'    => true,
				'closeButton' => true,
				'footer'      => $footer,
				'url'         =>
JRoute::_('index.php?option=com_users&view=notes&tmpl=component&layout=modal&filter[user_id]='
. (int) $userId),
				'height'      => '300px',
				'width'       => '800px',
			)
		);

	}

	/**
	 * Build an array of block/unblock user states to be used by jgrid.state,
	 * State options will be different for any user
	 * and for currently logged in user
	 *
	 * @param   boolean  $self  True if state array is for currently logged in
user
	 *
	 * @return  array  a list of possible states to display
	 *
	 * @since  3.0
	 */
	public static function blockStates( $self = false)
	{
		if ($self)
		{
			$states = array(
				1 => array(
					'task'           => 'unblock',
					'text'           => '',
					'active_title'   =>
'COM_USERS_USER_FIELD_BLOCK_DESC',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'unpublish',
					'inactive_class' => 'unpublish',
				),
				0 => array(
					'task'           => 'block',
					'text'           => '',
					'active_title'   => '',
					'inactive_title' =>
'COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF',
					'tip'            => true,
					'active_class'   => 'publish',
					'inactive_class' => 'publish',
				)
			);
		}
		else
		{
			$states = array(
				1 => array(
					'task'           => 'unblock',
					'text'           => '',
					'active_title'   =>
'COM_USERS_TOOLBAR_UNBLOCK',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'unpublish',
					'inactive_class' => 'unpublish',
				),
				0 => array(
					'task'           => 'block',
					'text'           => '',
					'active_title'   =>
'COM_USERS_USER_FIELD_BLOCK_DESC',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'publish',
					'inactive_class' => 'publish',
				)
			);
		}

		return $states;
	}

	/**
	 * Build an array of activate states to be used by jgrid.state,
	 *
	 * @return  array  a list of possible states to display
	 *
	 * @since  3.0
	 */
	public static function activateStates()
	{
		$states = array(
			1 => array(
				'task'           => 'activate',
				'text'           => '',
				'active_title'   =>
'COM_USERS_TOOLBAR_ACTIVATE',
				'inactive_title' => '',
				'tip'            => true,
				'active_class'   => 'unpublish',
				'inactive_class' => 'unpublish',
			),
			0 => array(
				'task'           => '',
				'text'           => '',
				'active_title'   => '',
				'inactive_title' => 'COM_USERS_ACTIVATED',
				'tip'            => true,
				'active_class'   => 'publish',
				'inactive_class' => 'publish',
			)
		);

		return $states;
	}
}
helpers/legacyrouter.php000064400000013673151165234420011441
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2016 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Legacy routing rules class from com_users
 *
 * @since       3.6
 * @deprecated  4.0
 */
class UsersRouterRulesLegacy implements JComponentRouterRulesInterface
{
	/**
	 * Constructor for this legacy router
	 *
	 * @param   JComponentRouterAdvanced  $router  The router this rule
belongs to
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function __construct($router)
	{
		$this->router = $router;
	}

	/**
	 * Preprocess the route for the com_users component
	 *
	 * @param   array  &$query  An array of URL arguments
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function preprocess(&$query)
	{
	}

	/**
	 * Build the route for the com_users component
	 *
	 * @param   array  &$query     An array of URL arguments
	 * @param   array  &$segments  The URL arguments to use to assemble
the subsequent URL.
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function build(&$query, &$segments)
	{
		// Declare static variables.
		static $items;
		static $default;
		static $registration;
		static $profile;
		static $login;
		static $remind;
		static $resend;
		static $reset;

		// Get the relevant menu items if not loaded.
		if (empty($items))
		{
			// Get all relevant menu items.
			$items = $this->router->menu->getItems('component',
'com_users');

			// Build an array of serialized query strings to menu item id mappings.
			foreach ($items as $item)
			{
				if (empty($item->query['view']))
				{
					continue;
				}

				// Check to see if we have found the resend menu item.
				if (empty($resend) && $item->query['view'] ===
'resend')
				{
					$resend = $item->id;

					continue;
				}

				// Check to see if we have found the reset menu item.
				if (empty($reset) && $item->query['view'] ===
'reset')
				{
					$reset = $item->id;

					continue;
				}

				// Check to see if we have found the remind menu item.
				if (empty($remind) && $item->query['view'] ===
'remind')
				{
					$remind = $item->id;

					continue;
				}

				// Check to see if we have found the login menu item.
				if (empty($login) && $item->query['view'] ===
'login' && (empty($item->query['layout']) ||
$item->query['layout'] === 'default'))
				{
					$login = $item->id;

					continue;
				}

				// Check to see if we have found the registration menu item.
				if (empty($registration) && $item->query['view']
=== 'registration')
				{
					$registration = $item->id;

					continue;
				}

				// Check to see if we have found the profile menu item.
				if (empty($profile) && $item->query['view'] ===
'profile')
				{
					$profile = $item->id;
				}
			}

			// Set the default menu item to use for com_users if possible.
			if ($profile)
			{
				$default = $profile;
			}
			elseif ($registration)
			{
				$default = $registration;
			}
			elseif ($login)
			{
				$default = $login;
			}
		}

		if (!empty($query['view']))
		{
			switch ($query['view'])
			{
				case 'reset':
					if ($query['Itemid'] = $reset)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}
					break;

				case 'resend':
					if ($query['Itemid'] = $resend)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}
					break;

				case 'remind':
					if ($query['Itemid'] = $remind)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}
					break;

				case 'login':
					if ($query['Itemid'] = $login)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}
					break;

				case 'registration':
					if ($query['Itemid'] = $registration)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}
					break;

				default:
				case 'profile':
					if (!empty($query['view']))
					{
						$segments[] = $query['view'];
					}

					unset($query['view']);

					if ($query['Itemid'] = $profile)
					{
						unset($query['view']);
					}
					else
					{
						$query['Itemid'] = $default;
					}

					// Only append the user id if not "me".
					$user = JFactory::getUser();

					if (!empty($query['user_id']) &&
($query['user_id'] != $user->id))
					{
						$segments[] = $query['user_id'];
					}

					unset($query['user_id']);

					break;
			}
		}

		$total = count($segments);

		for ($i = 0; $i < $total; $i++)
		{
			$segments[$i] = str_replace(':', '-',
$segments[$i]);
		}
	}

	/**
	 * Parse the segments of a URL.
	 *
	 * @param   array  &$segments  The segments of the URL to parse.
	 * @param   array  &$vars      The URL attributes to be used by the
application.
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function parse(&$segments, &$vars)
	{
		$total = count($segments);

		for ($i = 0; $i < $total; $i++)
		{
			$segments[$i] = preg_replace('/-/', ':',
$segments[$i], 1);
		}

		// Only run routine if there are segments to parse.
		if (count($segments) < 1)
		{
			return;
		}

		// Get the package from the route segments.
		$userId = array_pop($segments);

		if (!is_numeric($userId))
		{
			$vars['view'] = 'profile';

			return;
		}

		if (is_numeric($userId))
		{
			$db = JFactory::getDbo();
			$query = $db->getQuery(true)
				->select($db->quoteName('id'))
				->from($db->quoteName('#__users'))
				->where($db->quoteName('id') . ' = ' . (int)
$userId);
			$db->setQuery($query);
			$userId = $db->loadResult();
		}

		// Set the package id if present.
		if ($userId)
		{
			// Set the package id.
			$vars['user_id'] = (int) $userId;

			// Set the view to package if not already set.
			if (empty($vars['view']))
			{
				$vars['view'] = 'profile';
			}
		}
		else
		{
			JError::raiseError(404,
JText::_('JGLOBAL_RESOURCE_NOT_FOUND'));
		}
	}
}
helpers/route.php000064400000007531151165234420010066 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users Route Helper
 *
 * @since       1.6
 * @deprecated  4.0
 */
class UsersHelperRoute
{
	/**
	 * Method to get the menu items for the component.
	 *
	 * @return  array  	An array of menu items.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function &getItems()
	{
		static $items;

		// Get the menu items for this component.
		if (!isset($items))
		{
			$component = JComponentHelper::getComponent('com_users');
			$items     =
JFactory::getApplication()->getMenu()->getItems('component_id',
$component->id);

			// If no items found, set to empty array.
			if (!$items)
			{
				$items = array();
			}
		}

		return $items;
	}

	/**
	 * Method to get a route configuration for the login view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getLoginRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'login' &&
(empty($item->query['layout']) ||
$item->query['layout'] === 'default'))
			{
				return $item->id;
			}
		}

		return null;
	}

	/**
	 * Method to get a route configuration for the profile view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getProfileRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		// Menu link can only go to users own profile.

		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'profile')
			{
				return $item->id;
			}
		}

		return null;
	}

	/**
	 * Method to get a route configuration for the registration view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getRegistrationRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'registration')
			{
				return $item->id;
			}
		}

		return null;
	}

	/**
	 * Method to get a route configuration for the remind view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getRemindRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'remind')
			{
				return $item->id;
			}
		}

		return null;
	}

	/**
	 * Method to get a route configuration for the resend view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getResendRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'resend')
			{
				return $item->id;
			}
		}

		return null;
	}

	/**
	 * Method to get a route configuration for the reset view.
	 *
	 * @return  mixed  	Integer menu id on success, null on failure.
	 *
	 * @since       1.6
	 * @deprecated  4.0
	 */
	public static function getResetRoute()
	{
		// Get the items.
		$items  = self::getItems();

		// Search for a suitable menu id.
		foreach ($items as $item)
		{
			if (isset($item->query['view']) &&
$item->query['view'] === 'reset')
			{
				return $item->id;
			}
		}

		return null;
	}
}
layouts/joomla/form/renderfield.php000064400000003530151165234420013470
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  Layout
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

extract($displayData);

/**
 * Layout variables
 * ---------------------
 *    $options         : (array)  Optional parameters
 *    $label           : (string) The html code for the label (not required
if $options['hiddenLabel'] is true)
 *    $input           : (string) The input field html code
 */

if (!empty($options['showonEnabled']))
{
	JHtml::_('jquery.framework');
	JHtml::_('script', 'jui/cms.js',
array('version' => 'auto', 'relative'
=> true));
}

$class = empty($options['class']) ? '' : ' '
. $options['class'];
$rel   = empty($options['rel']) ? '' : ' ' .
$options['rel'];

/**
 * @TODO:
 *
 * As mentioned in #8473 (https://github.com/joomla/joomla-cms/pull/8473),
...
 * as long as we cannot access the field properties properly, this seems to
 * be the way to go for now.
 *
 * On a side note: Parsing html is seldom a good idea.
 *
https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454
 */
preg_match('/class=\"([^\"]+)\"/i', $input,
$match);

$required     = (strpos($input, 'aria-required="true"')
!== false || (!empty($match[1]) && strpos($match[1],
'required') !== false));
$typeOfSpacer = (strpos($label, 'spacer-lbl') !== false);

?>

<div class="control-group<?php echo $class; ?>"<?php
echo $rel; ?>>
	<?php if (empty($options['hiddenLabel'])): ?>
		<div class="control-label">
			<?php echo $label; ?>
			<?php if (!$required && !$typeOfSpacer) : ?>
				<span class="optional"><?php echo
JText::_('COM_USERS_OPTIONAL'); ?></span>
			<?php endif; ?>
		</div>
	<?php endif; ?>
	<div class="controls">
		<?php echo $input; ?>
	</div>
</div>
models/forms/frontend.xml000064400000001700151165234420011517
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="params">
		<!--  Basic user account settings. -->
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="editor"
				type="plugins"
				label="COM_USERS_USER_FIELD_EDITOR_LABEL"
				description="COM_USERS_USER_FIELD_EDITOR_DESC"
				folder="editors"
				useaccess="true"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="timezone"
				type="timezone"
				label="COM_USERS_USER_FIELD_TIMEZONE_LABEL"
				description="COM_USERS_USER_FIELD_TIMEZONE_DESC"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="language"
				type="language"
				label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
				description="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC"
				client="site"
				filter="cmd"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>
		</fieldset>
	</fields>
</form>
models/forms/frontend_admin.xml000064400000001426151165234420012674
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="params">
		<!--  Backend user account settings. -->
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="admin_style"
				type="templatestyle"
				label="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL"
				description="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_DESC"
				client="administrator"
				filter="uint"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="admin_language"
				type="language"
				label="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL"
				description="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_DESC"
				client="administrator"
				filter="cmd"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

		</fieldset>
	</fields>
</form>
models/forms/login.xml000064400000001337151165234420011016 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="credentials"
label="COM_USERS_LOGIN_DEFAULT_LABEL">
		<field
			name="username"
			type="text"
			label="COM_USERS_LOGIN_USERNAME_LABEL"
			class="validate-username"
			filter="username"
			size="25"
			required="true"
			validate="username"
			autofocus="true"
		/>

		<field
			name="password"
			type="password"
			label="JGLOBAL_PASSWORD"
			class="validate-password"
			required="true"
			filter="raw"
			size="25"
		/>
	</fieldset>

		<field
			name="secretkey"
			type="text"
			label="JGLOBAL_SECRETKEY"
			autocomplete="one-time-code"
			class=""
			filter="int"
			size="25"
		/>

	<fieldset>
		<field
			name="return"
			type="hidden"
		/>
	</fieldset>
</form>
models/forms/profile.xml000064400000003561151165234420011347
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="core"
label="COM_USERS_PROFILE_DEFAULT_LABEL">
		<field
			name="id"
			type="hidden"
			filter="integer"
		/>

		<field
			name="name"
			type="text"
			label="COM_USERS_PROFILE_NAME_LABEL"
			description="COM_USERS_PROFILE_NAME_DESC"
			filter="string"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="COM_USERS_PROFILE_USERNAME_LABEL"
			description="COM_USERS_DESIRED_USERNAME"
			class="validate-username"
			filter="username"
			message="COM_USERS_PROFILE_USERNAME_MESSAGE"
			required="true"
			size="30"
			validate="username"
		/>

		<field
			name="password1"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD1_LABEL"
			description="COM_USERS_DESIRED_PASSWORD"
			autocomplete="off"
			class="validate-password"
			filter="raw"
			size="30"
			validate="password"
		/>

		<field
			name="password2"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD2_LABEL"
			description="COM_USERS_PROFILE_PASSWORD2_DESC"
			autocomplete="off"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
		/>

		<field
			name="email1"
			type="email"
			label="COM_USERS_PROFILE_EMAIL1_LABEL"
			description="COM_USERS_PROFILE_EMAIL1_DESC"
			filter="string"
			required="true"
			size="30"
			unique="true"
			validate="email"
			validDomains="com_users.domains"
			autocomplete="email"
		/>

		<field
			name="email2"
			type="email"
			label="COM_USERS_PROFILE_EMAIL2_LABEL"
			description="COM_USERS_PROFILE_EMAIL2_DESC"
			field="email1"
			filter="string"
			message="COM_USERS_PROFILE_EMAIL2_MESSAGE"
			required="true"
			size="30"
			validate="equals"
		/>
	</fieldset>
	
	<!-- Used to get the two factor authentication configuration -->
	<field
		name="twofactor"
		type="hidden"
	/>
</form>
models/forms/registration.xml000064400000004024151165234420012414
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_REGISTRATION_DEFAULT_LABEL">
		<field
			name="spacer"
			type="spacer"
			label="COM_USERS_REGISTER_REQUIRED"
			class="text"
		/>

		<field
			name="name"
			type="text"
			label="COM_USERS_REGISTER_NAME_LABEL"
			description="COM_USERS_REGISTER_NAME_DESC"
			filter="string"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="COM_USERS_REGISTER_USERNAME_LABEL"
			description="COM_USERS_DESIRED_USERNAME"
			class="validate-username"
			filter="username"
			message="COM_USERS_REGISTER_USERNAME_MESSAGE"
			required="true"
			size="30"
			validate="username"
		/>

		<field
			name="password1" 
			type="password"
			label="COM_USERS_PROFILE_PASSWORD1_LABEL"
			description="COM_USERS_DESIRED_PASSWORD"
			autocomplete="off"
			class="validate-password"
			field="password1"
			filter="raw"
			size="30"
			validate="password"
			required="true"
		/>

		<field
			name="password2"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD2_LABEL"
			description="COM_USERS_PROFILE_PASSWORD2_DESC"
			autocomplete="off"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
			required="true"
		/>

		<field
			name="email1"
			type="email"
			label="COM_USERS_REGISTER_EMAIL1_LABEL"
			description="COM_USERS_REGISTER_EMAIL1_DESC"
			field="id"
			filter="string"
			required="true"
			size="30"
			unique="true"
			validate="email"
			validDomains="com_users.domains"
			autocomplete="email"
		/>

		<field
			name="email2"
			type="email"
			label="COM_USERS_REGISTER_EMAIL2_LABEL"
			description="COM_USERS_REGISTER_EMAIL2_DESC"
			field="email1"
			filter="string"
			message="COM_USERS_REGISTER_EMAIL2_MESSAGE"
			required="true"
			size="30"
			validate="equals"
		/>

		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			description="COM_USERS_CAPTCHA_DESC"
			validate="captcha"
		/>
	</fieldset>
</form>
models/forms/remind.xml000064400000000765151165234420011170
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_REMIND_DEFAULT_LABEL">
		<field
			name="email"
			type="email"
			label="COM_USERS_FIELD_REMIND_EMAIL_LABEL"
			description="COM_USERS_FIELD_REMIND_EMAIL_DESC"
			required="true"
			size="30"
			validate="email"
			autocomplete="email"
		/>
		
		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			description="COM_USERS_CAPTCHA_DESC"
			validate="captcha"
		/>
	</fieldset>
</form>models/forms/reset_complete.xml000064400000001370151165234420012715
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_COMPLETE_LABEL">
		<field
			name="password1"
			type="password"
			label="COM_USERS_FIELD_RESET_PASSWORD1_LABEL"
			description="COM_USERS_FIELD_RESET_PASSWORD1_DESC"
			autocomplete="off"
			class="validate-password"
			field="password2"
			filter="raw"
			message="COM_USERS_FIELD_RESET_PASSWORD1_MESSAGE"
			required="true"
			size="30"
			validate="equals"
		/>
		<field
			name="password2"
			type="password"
			label="COM_USERS_FIELD_RESET_PASSWORD2_LABEL"
			description="COM_USERS_FIELD_RESET_PASSWORD2_DESC"
			autocomplete="off"
			class="validate-password"
			filter="raw"
			required="true"
			size="30"
			validate="password"
		/>
	</fieldset>
</form>models/forms/reset_confirm.xml000064400000001055151165234420012542
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_CONFIRM_LABEL">
		<field
			name="username"
			type="text"
			label="COM_USERS_FIELD_RESET_CONFIRM_USERNAME_LABEL"
			description="COM_USERS_FIELD_RESET_CONFIRM_USERNAME_DESC"
			filter="username"
			required="true"
			size="30"
		/>

		<field
			name="token"
			type="text"
			label="COM_USERS_FIELD_RESET_CONFIRM_TOKEN_LABEL"
			description="COM_USERS_FIELD_RESET_CONFIRM_TOKEN_DESC"
			filter="alnum"
			required="true"
			size="32"
		/>
	</fieldset>
</form>
models/forms/reset_request.xml000064400000000771151165234420012601
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_REQUEST_LABEL">
		<field 
			name="email"
			type="text"
			label="COM_USERS_FIELD_PASSWORD_RESET_LABEL"
			description="COM_USERS_FIELD_PASSWORD_RESET_DESC"
			class="validate-username"
			filter="email"
			required="true"
			size="30"
		/>

		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			description="COM_USERS_CAPTCHA_DESC"
			validate="captcha"
		/>
	</fieldset>
</form>models/forms/sitelang.xml000064400000000622151165234420011510
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="params">
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="language"
				type="language"
				label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
				description="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC"
				client="site"
				filter="cmd"
				default="active"
			/>
		</fieldset>
	</fields>
</form>models/login.php000064400000005245151165234420007661
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Rest model class for Users.
 *
 * @since  1.6
 */
class UsersModelLogin extends JModelForm
{
	/**
	 * Method to get the login form.
	 *
	 * The base form is loaded from XML and then an event is fired
	 * for users plugins to extend the form with extra fields.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm	A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.login',
'login', array('load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  array  The default data is an empty array.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered login form data.
		$app  = JFactory::getApplication();
		$data = $app->getUserState('users.login.form.data',
array());

		$input = $app->input->getInputForRequestMethod();

		// Check for return URL from the request first
		if ($return = $input->get('return', '',
'BASE64'))
		{
			$data['return'] = base64_decode($return);

			if (!JUri::isInternal($data['return']))
			{
				$data['return'] = '';
			}
		}

		$app->setUserState('users.login.form.data', $data);

		$this->preprocessData('com_users.login', $data);

		return $data;
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_users');

		// Load the parameters.
		$this->setState('params', $params);
	}

	/**
	 * Override JModelAdmin::preprocessForm to ensure the correct plugin group
is loaded.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error in the form event.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		parent::preprocessForm($form, $data, $group);
	}
}
models/profile.php000064400000026153151165234420010212 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\User\UserHelper;
use Joomla\Registry\Registry;

/**
 * Profile model class for Users.
 *
 * @since  1.6
 */
class UsersModelProfile extends JModelForm
{
	/**
	 * @var		object	The user profile data.
	 * @since   1.6
	 */
	protected $data;

	/**
	 * Constructor
	 *
	 * @param   array  $config  An array of configuration options (name,
state, dbo, table_path, ignore_request).
	 *
	 * @since   3.2
	 *
	 * @throws  Exception
	 */
	public function __construct($config = array())
	{
		$config = array_merge(
			array(
				'events_map' => array('validate' =>
'user')
			), $config
		);

		parent::__construct($config);

		// Load the helper and model used for two factor authentication
		JLoader::register('UsersModelUser', JPATH_ADMINISTRATOR .
'/components/com_users/models/user.php');
		JLoader::register('UsersHelper', JPATH_ADMINISTRATOR .
'/components/com_users/helpers/users.php');
	}

	/**
	 * Method to check in a user.
	 *
	 * @param   integer  $userId  The id of the row to check out.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function checkin($userId = null)
	{
		// Get the user id.
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		if ($userId)
		{
			// Initialise the table with JUser.
			$table = JTable::getInstance('User');

			// Attempt to check the row in.
			if (!$table->checkin($userId))
			{
				$this->setError($table->getError());

				return false;
			}
		}

		return true;
	}

	/**
	 * Method to check out a user for editing.
	 *
	 * @param   integer  $userId  The id of the row to check out.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function checkout($userId = null)
	{
		// Get the user id.
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		if ($userId)
		{
			// Initialise the table with JUser.
			$table = JTable::getInstance('User');

			// Get the current user object.
			$user = JFactory::getUser();

			// Attempt to check the row out.
			if (!$table->checkout($user->get('id'), $userId))
			{
				$this->setError($table->getError());

				return false;
			}
		}

		return true;
	}

	/**
	 * Method to get the profile form data.
	 *
	 * The base form data is loaded and then an event is fired
	 * for users plugins to extend the data.
	 *
	 * @return  mixed  	Data object on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getData()
	{
		if ($this->data === null)
		{
			$userId = $this->getState('user.id');

			// Initialise the table with JUser.
			$this->data = new JUser($userId);

			// Set the base user data.
			$this->data->email1 = $this->data->get('email');
			$this->data->email2 = $this->data->get('email');

			// Override the base user data with any data in the session.
			$temp = (array)
JFactory::getApplication()->getUserState('com_users.edit.profile.data',
array());

			foreach ($temp as $k => $v)
			{
				$this->data->$k = $v;
			}

			// Unset the passwords.
			unset($this->data->password1, $this->data->password2);

			$registry           = new Registry($this->data->params);
			$this->data->params = $registry->toArray();
		}

		return $this->data;
	}

	/**
	 * Method to get the profile form.
	 *
	 * The base form is loaded from XML and then an event is fired
	 * for users plugins to extend the form with extra fields.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm  A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.profile',
'profile', array('control' => 'jform',
'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		// Check for username compliance and parameter set
		$isUsernameCompliant = true;
		$username = $loadData ? $form->getValue('username') :
$this->loadFormData()->username;

		if ($username)
		{
			$isUsernameCompliant  =
!(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#',
$username) || strlen(utf8_decode($username)) < 2
				|| trim($username) !== $username);
		}

		$this->setState('user.username.compliant',
$isUsernameCompliant);

		if ($isUsernameCompliant &&
!JComponentHelper::getParams('com_users')->get('change_login_name'))
		{
			$form->setFieldAttribute('username', 'class',
'');
			$form->setFieldAttribute('username', 'filter',
'');
			$form->setFieldAttribute('username',
'description',
'COM_USERS_PROFILE_NOCHANGE_USERNAME_DESC');
			$form->setFieldAttribute('username', 'validate',
'');
			$form->setFieldAttribute('username', 'message',
'');
			$form->setFieldAttribute('username', 'readonly',
'true');
			$form->setFieldAttribute('username', 'required',
'false');
		}

		// When multilanguage is set, a user's default site language should
also be a Content Language
		if (JLanguageMultilang::isEnabled())
		{
			$form->setFieldAttribute('language', 'type',
'frontend_language', 'params');
		}

		// If the user needs to change their password, mark the password fields
as required
		if (JFactory::getUser()->requireReset)
		{
			$form->setFieldAttribute('password1', 'required',
'true');
			$form->setFieldAttribute('password2', 'required',
'true');
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		$data = $this->getData();

		$this->preprocessData('com_users.profile', $data,
'user');

		return $data;
	}

	/**
	 * Override preprocessForm to load the user plugin group instead of
content.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @throws	Exception if there is an error in the form event.
	 *
	 * @since   1.6
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		if
(JComponentHelper::getParams('com_users')->get('frontend_userparams'))
		{
			$form->loadFile('frontend', false);

			if (JFactory::getUser()->authorise('core.login.admin'))
			{
				$form->loadFile('frontend_admin', false);
			}
		}

		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_users');

		// Get the user id.
		$userId =
JFactory::getApplication()->getUserState('com_users.edit.profile.id');
		$userId = !empty($userId) ? $userId : (int)
JFactory::getUser()->get('id');

		// Set the user id.
		$this->setState('user.id', $userId);

		// Load the parameters.
		$this->setState('params', $params);
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  mixed  The user id on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function save($data)
	{
		$userId = (!empty($data['id'])) ? $data['id'] : (int)
$this->getState('user.id');

		$user = new JUser($userId);

		// Prepare the data for the user object.
		$data['email']    =
JStringPunycode::emailToPunycode($data['email1']);
		$data['password'] = $data['password1'];

		// Unset the username if it should not be overwritten
		$isUsernameCompliant =
$this->getState('user.username.compliant');

		if ($isUsernameCompliant &&
!JComponentHelper::getParams('com_users')->get('change_login_name'))
		{
			unset($data['username']);
		}

		// Unset block and sendEmail so they do not get overwritten
		unset($data['block'], $data['sendEmail']);

		// Handle the two factor authentication setup
		if (array_key_exists('twofactor', $data))
		{
			$model = new UsersModelUser;

			$twoFactorMethod = $data['twofactor']['method'];

			// Get the current One Time Password (two factor auth) configuration
			$otpConfig = $model->getOtpConfig($userId);

			if ($twoFactorMethod !== 'none')
			{
				// Run the plugins
				FOFPlatform::getInstance()->importPlugin('twofactorauth');
				$otpConfigReplies =
FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration',
array($twoFactorMethod));

				// Look for a valid reply
				foreach ($otpConfigReplies as $reply)
				{
					if (!is_object($reply) || empty($reply->method) ||
($reply->method != $twoFactorMethod))
					{
						continue;
					}

					$otpConfig->method = $reply->method;
					$otpConfig->config = $reply->config;

					break;
				}

				// Save OTP configuration.
				$model->setOtpConfig($userId, $otpConfig);

				// Generate one time emergency passwords if required (depleted or not
set)
				if (empty($otpConfig->otep))
				{
					$model->generateOteps($userId);
				}
			}
			else
			{
				$otpConfig->method = 'none';
				$otpConfig->config = array();
				$model->setOtpConfig($userId, $otpConfig);
			}

			// Unset the raw data
			unset($data['twofactor']);

			// Reload the user record with the updated OTP configuration
			$user->load($userId);
		}

		// Bind the data.
		if (!$user->bind($data))
		{
			$this->setError(JText::sprintf('COM_USERS_PROFILE_BIND_FAILED',
$user->getError()));

			return false;
		}

		// Load the users plugin group.
		JPluginHelper::importPlugin('user');

		// Retrieve the user groups so they don't get overwritten
		unset($user->groups);
		$user->groups = JAccess::getGroupsByUser($user->id, false);

		// Store the data.
		if (!$user->save())
		{
			$this->setError($user->getError());

			return false;
		}

		// Destroy all active sessions for the user after changing the password
		if ($data['password'])
		{
			UserHelper::destroyUserSessions($user->id, true);
		}

		return $user->id;
	}

	/**
	 * Gets the configuration forms for all two-factor authentication methods
	 * in an array.
	 *
	 * @param   integer  $userId  The user ID to load the forms for (optional)
	 *
	 * @return  array
	 *
	 * @since   3.2
	 */
	public function getTwofactorform($userId = null)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');
		$model = new UsersModelUser;

		$otpConfig = $model->getOtpConfig($userId);

		FOFPlatform::getInstance()->importPlugin('twofactorauth');

		return
FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration',
array($otpConfig, $userId));
	}

	/**
	 * Returns the one time password (OTP) – a.k.a. two factor
authentication –
	 * configuration for a particular user.
	 *
	 * @param   integer  $userId  The numeric ID of the user
	 *
	 * @return  stdClass  An object holding the OTP configuration for this
user
	 *
	 * @since   3.2
	 */
	public function getOtpConfig($userId = null)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		$model = new UsersModelUser;

		return $model->getOtpConfig($userId);
	}
}
models/registration.php000064400000044037151165234420011265
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Router\Route;

/**
 * Registration model class for Users.
 *
 * @since  1.6
 */
class UsersModelRegistration extends JModelForm
{
	/**
	 * @var    object  The user registration data.
	 * @since  1.6
	 */
	protected $data;

	/**
	 * Constructor
	 *
	 * @param   array  $config  An array of configuration options (name,
state, dbo, table_path, ignore_request).
	 *
	 * @since   3.6
	 *
	 * @throws  Exception
	 */
	public function __construct($config = array())
	{
		$config = array_merge(
			array(
				'events_map' => array('validate' =>
'user')
			), $config
		);

		parent::__construct($config);
	}

	/**
	 * Method to get the user ID from the given token
	 *
	 * @param   string  $token  The activation token.
	 *
	 * @return  mixed   False on failure, id of the user on success
	 *
	 * @since   3.8.13
	 */
	public function getUserIdFromToken($token)
	{
		$db = $this->getDbo();

		// Get the user id based on the token.
		$query = $db->getQuery(true);
		$query->select($db->quoteName('id'))
			->from($db->quoteName('#__users'))
			->where($db->quoteName('activation') . ' = ' .
$db->quote($token))
			->where($db->quoteName('block') . ' = ' . 1)
			->where($db->quoteName('lastvisitDate') . ' =
' . $db->quote($db->getNullDate()));
		$db->setQuery($query);

		try
		{
			return (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

			return false;
		}
	}

	/**
	 * Method to activate a user account.
	 *
	 * @param   string  $token  The activation token.
	 *
	 * @return  mixed    False on failure, user object on success.
	 *
	 * @since   1.6
	 */
	public function activate($token)
	{
		$config     = JFactory::getConfig();
		$userParams = JComponentHelper::getParams('com_users');
		$userId     = $this->getUserIdFromToken($token);

		// Check for a valid user id.
		if (!$userId)
		{
			$this->setError(JText::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));

			return false;
		}

		// Load the users plugin group.
		JPluginHelper::importPlugin('user');

		// Activate the user.
		$user = JFactory::getUser($userId);

		// Admin activation is on and user is verifying their email
		if (($userParams->get('useractivation') == 2) &&
!$user->getParam('activate', 0))
		{
			$linkMode = $config->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

			// Compile the admin notification mail values.
			$data = $user->getProperties();
			$data['activation'] =
JApplicationHelper::getHash(JUserHelper::genRandomPassword());
			$user->set('activation', $data['activation']);
			$data['siteurl'] = JUri::base();
			$data['activate'] = JRoute::link(
				'site',
				'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
				false,
				$linkMode,
				true
			);

			$data['fromname'] = $config->get('fromname');
			$data['mailfrom'] = $config->get('mailfrom');
			$data['sitename'] = $config->get('sitename');
			$user->setParam('activate', 1);
			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACTIVATE_WITH_ADMIN_ACTIVATION_SUBJECT',
				$data['name'],
				$data['sitename']
			);

			$emailBody = JText::sprintf(
				'COM_USERS_EMAIL_ACTIVATE_WITH_ADMIN_ACTIVATION_BODY',
				$data['sitename'],
				$data['name'],
				$data['email'],
				$data['username'],
				$data['activate']
			);

			// Get all admin users
			$db = $this->getDbo();
			$query = $db->getQuery(true)
				->select($db->quoteName(array('name',
'email', 'sendEmail', 'id')))
				->from($db->quoteName('#__users'))
				->where($db->quoteName('sendEmail') . ' = 1')
				->where($db->quoteName('block') . ' = 0');

			$db->setQuery($query);

			try
			{
				$rows = $db->loadObjectList();
			}
			catch (RuntimeException $e)
			{
				$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

				return false;
			}

			// Send mail to all users with users creating permissions and receiving
system emails
			foreach ($rows as $row)
			{
				$usercreator = JFactory::getUser($row->id);

				if ($usercreator->authorise('core.create',
'com_users') &&
$usercreator->authorise('core.manage', 'com_users'))
				{
					$return =
JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $row->email, $emailSubject, $emailBody);

					// Check for an error.
					if ($return !== true)
					{
						$this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

						return false;
					}
				}
			}
		}
		// Admin activation is on and admin is activating the account
		elseif (($userParams->get('useractivation') == 2) &&
$user->getParam('activate', 0))
		{
			$user->set('activation', '');
			$user->set('block', '0');

			// Compile the user activated notification mail values.
			$data = $user->getProperties();
			$user->setParam('activate', 0);
			$data['fromname'] = $config->get('fromname');
			$data['mailfrom'] = $config->get('mailfrom');
			$data['sitename'] = $config->get('sitename');
			$data['siteurl'] = JUri::base();
			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACTIVATED_BY_ADMIN_ACTIVATION_SUBJECT',
				$data['name'],
				$data['sitename']
			);

			$emailBody = JText::sprintf(
				'COM_USERS_EMAIL_ACTIVATED_BY_ADMIN_ACTIVATION_BODY',
				$data['name'],
				$data['siteurl'],
				$data['username']
			);

			$return =
JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $data['email'], $emailSubject,
$emailBody);

			// Check for an error.
			if ($return !== true)
			{
				$this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

				return false;
			}
		}
		else
		{
			$user->set('activation', '');
			$user->set('block', '0');
		}

		// Store the user object.
		if (!$user->save())
		{
			$this->setError(JText::sprintf('COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED',
$user->getError()));

			return false;
		}

		return $user;
	}

	/**
	 * Method to get the registration form data.
	 *
	 * The base form data is loaded and then an event is fired
	 * for users plugins to extend the data.
	 *
	 * @return  mixed  Data object on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getData()
	{
		if ($this->data === null)
		{
			$this->data = new stdClass;
			$app = JFactory::getApplication();
			$params = JComponentHelper::getParams('com_users');

			// Override the base user data with any data in the session.
			$temp = (array)
$app->getUserState('com_users.registration.data', array());

			// Don't load the data in this getForm call, or we'll call
ourself
			$form = $this->getForm(array(), false);

			foreach ($temp as $k => $v)
			{
				// Here we could have a grouped field, let's check it
				if (is_array($v))
				{
					$this->data->$k = new stdClass;

					foreach ($v as $key => $val)
					{
						if ($form->getField($key, $k) !== false)
						{
							$this->data->$k->$key = $val;
						}
					}
				}
				// Only merge the field if it exists in the form.
				elseif ($form->getField($k) !== false)
				{
					$this->data->$k = $v;
				}
			}

			// Get the groups the user should be added to after registration.
			$this->data->groups = array();

			// Get the default new user group, guest or public group if not
specified.
			$system = $params->get('new_usertype',
$params->get('guest_usergroup', 1));

			$this->data->groups[] = $system;

			// Unset the passwords.
			unset($this->data->password1, $this->data->password2);

			// Get the dispatcher and load the users plugins.
			$dispatcher = JEventDispatcher::getInstance();
			JPluginHelper::importPlugin('user');

			// Trigger the data preparation event.
			$results = $dispatcher->trigger('onContentPrepareData',
array('com_users.registration', $this->data));

			// Check for errors encountered while preparing the data.
			if (count($results) && in_array(false, $results, true))
			{
				$this->setError($dispatcher->getError());
				$this->data = false;
			}
		}

		return $this->data;
	}

	/**
	 * Method to get the registration form.
	 *
	 * The base form is loaded from XML and then an event is fired
	 * for users plugins to extend the form with extra fields.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm  A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.registration',
'registration', array('control' =>
'jform', 'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		// When multilanguage is set, a user's default site language should
also be a Content Language
		if (JLanguageMultilang::isEnabled())
		{
			$form->setFieldAttribute('language', 'type',
'frontend_language', 'params');
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		$data = $this->getData();

		if (JLanguageMultilang::isEnabled() && empty($data->language))
		{
			$data->language = JFactory::getLanguage()->getTag();
		}

		$this->preprocessData('com_users.registration', $data);

		return $data;
	}

	/**
	 * Override preprocessForm to load the user plugin group instead of
content.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error in the form event.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		$userParams = JComponentHelper::getParams('com_users');

		// Add the choice for site language at registration time
		if ($userParams->get('site_language') == 1 &&
$userParams->get('frontend_userparams') == 1)
		{
			$form->loadFile('sitelang', false);
		}

		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState()
	{
		// Get the application object.
		$app = JFactory::getApplication();
		$params = $app->getParams('com_users');

		// Load the parameters.
		$this->setState('params', $params);
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $temp  The form data.
	 *
	 * @return  mixed  The user id on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function register($temp)
	{
		$params = JComponentHelper::getParams('com_users');

		// Initialise the table with JUser.
		$user = new JUser;
		$data = (array) $this->getData();

		// Merge in the registration data.
		foreach ($temp as $k => $v)
		{
			$data[$k] = $v;
		}

		// Prepare the data for the user object.
		$data['email'] =
JStringPunycode::emailToPunycode($data['email1']);
		$data['password'] = $data['password1'];
		$useractivation = $params->get('useractivation');
		$sendpassword = $params->get('sendpassword', 1);

		// Check if the user needs to activate their account.
		if (($useractivation == 1) || ($useractivation == 2))
		{
			$data['activation'] =
JApplicationHelper::getHash(JUserHelper::genRandomPassword());
			$data['block'] = 1;
		}

		// Bind the data.
		if (!$user->bind($data))
		{
			$this->setError(JText::sprintf('COM_USERS_REGISTRATION_BIND_FAILED',
$user->getError()));

			return false;
		}

		// Load the users plugin group.
		JPluginHelper::importPlugin('user');

		// Store the data.
		if (!$user->save())
		{
			$this->setError(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED',
$user->getError()));

			return false;
		}

		$config = JFactory::getConfig();
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Compile the notification mail values.
		$data = $user->getProperties();
		$data['fromname'] = $config->get('fromname');
		$data['mailfrom'] = $config->get('mailfrom');
		$data['sitename'] = $config->get('sitename');
		$data['siteurl'] = JUri::root();

		// Handle account activation/confirmation emails.
		if ($useractivation == 2)
		{
			// Set the link to confirm the user email.
			$linkMode = $config->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

			$data['activate'] = JRoute::link(
				'site',
				'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
				false,
				$linkMode,
				true
			);

			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACCOUNT_DETAILS',
				$data['name'],
				$data['sitename']
			);

			if ($sendpassword)
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY',
					$data['name'],
					$data['sitename'],
					$data['activate'],
					$data['siteurl'],
					$data['username'],
					$data['password_clear']
				);
			}
			else
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY_NOPW',
					$data['name'],
					$data['sitename'],
					$data['activate'],
					$data['siteurl'],
					$data['username']
				);
			}
		}
		elseif ($useractivation == 1)
		{
			// Set the link to activate the user account.
			$linkMode = $config->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

			$data['activate'] = JRoute::link(
				'site',
				'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
				false,
				$linkMode,
				true
			);

			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACCOUNT_DETAILS',
				$data['name'],
				$data['sitename']
			);

			if ($sendpassword)
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY',
					$data['name'],
					$data['sitename'],
					$data['activate'],
					$data['siteurl'],
					$data['username'],
					$data['password_clear']
				);
			}
			else
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY_NOPW',
					$data['name'],
					$data['sitename'],
					$data['activate'],
					$data['siteurl'],
					$data['username']
				);
			}
		}
		else
		{
			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACCOUNT_DETAILS',
				$data['name'],
				$data['sitename']
			);

			if ($sendpassword)
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_BODY',
					$data['name'],
					$data['sitename'],
					$data['siteurl'],
					$data['username'],
					$data['password_clear']
				);
			}
			else
			{
				$emailBody = JText::sprintf(
					'COM_USERS_EMAIL_REGISTERED_BODY_NOPW',
					$data['name'],
					$data['sitename'],
					$data['siteurl']
				);
			}
		}

		// Send the registration email.
		$return = JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $data['email'], $emailSubject,
$emailBody);

		// Send Notification mail to administrators
		if (($params->get('useractivation') < 2) &&
($params->get('mail_to_admin') == 1))
		{
			$emailSubject = JText::sprintf(
				'COM_USERS_EMAIL_ACCOUNT_DETAILS',
				$data['name'],
				$data['sitename']
			);

			$emailBodyAdmin = JText::sprintf(
				'COM_USERS_EMAIL_REGISTERED_NOTIFICATION_TO_ADMIN_BODY',
				$data['name'],
				$data['username'],
				$data['siteurl']
			);

			// Get all admin users
			$query->clear()
				->select($db->quoteName(array('name',
'email', 'sendEmail', 'id')))
				->from($db->quoteName('#__users'))
				->where($db->quoteName('sendEmail') . ' = 1')
				->where($db->quoteName('block') . ' = 0');

			$db->setQuery($query);

			try
			{
				$rows = $db->loadObjectList();
			}
			catch (RuntimeException $e)
			{
				$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

				return false;
			}

			// Send mail to all users with user creating permissions and receiving
system emails
			foreach ($rows as $row)
			{
				$usercreator = JFactory::getUser($row->id);

				if ($usercreator->authorise('core.create',
'com_users') &&
$usercreator->authorise('core.manage', 'com_users'))
				{
					$return =
JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $row->email, $emailSubject,
$emailBodyAdmin);

					// Check for an error.
					if ($return !== true)
					{
						$this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

						return false;
					}
				}
			}
		}

		// Check for an error.
		if ($return !== true)
		{
			$this->setError(JText::_('COM_USERS_REGISTRATION_SEND_MAIL_FAILED'));

			// Send a system message to administrators receiving system mails
			$db = $this->getDbo();
			$query->clear()
				->select($db->quoteName('id'))
				->from($db->quoteName('#__users'))
				->where($db->quoteName('block') . ' = ' .
(int) 0)
				->where($db->quoteName('sendEmail') . ' = ' .
(int) 1);
			$db->setQuery($query);

			try
			{
				$userids = $db->loadColumn();
			}
			catch (RuntimeException $e)
			{
				$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

				return false;
			}

			if (count($userids) > 0)
			{
				$jdate = new JDate;

				// Build the query to add the messages
				foreach ($userids as $userid)
				{
					$values = array(
						$db->quote($userid),
						$db->quote($userid),
						$db->quote($jdate->toSql()),
						$db->quote(JText::_('COM_USERS_MAIL_SEND_FAILURE_SUBJECT')),
						$db->quote(JText::sprintf('COM_USERS_MAIL_SEND_FAILURE_BODY',
$return, $data['username']))
					);
					$query->clear()
						->insert($db->quoteName('#__messages'))
						->columns($db->quoteName(array('user_id_from',
'user_id_to', 'date_time', 'subject',
'message')))
						->values(implode(',', $values));
					$db->setQuery($query);

					try
					{
						$db->execute();
					}
					catch (RuntimeException $e)
					{
						$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

						return false;
					}
				}
			}

			return false;
		}

		if ($useractivation == 1)
		{
			return 'useractivate';
		}
		elseif ($useractivation == 2)
		{
			return 'adminactivate';
		}
		else
		{
			return $user->id;
		}
	}
}
models/remind.php000064400000011063151165234420010022 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Remind model class for Users.
 *
 * @since  1.5
 */
class UsersModelRemind extends JModelForm
{
	/**
	 * Method to get the username remind request form.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JFor     A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.remind',
'remind', array('control' => 'jform',
'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Override preprocessForm to load the user plugin group instead of
content.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @throws	Exception if there is an error in the form event.
	 *
	 * @since   1.6
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		parent::preprocessForm($form, $data, 'user');
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState()
	{
		// Get the application object.
		$app = JFactory::getApplication();
		$params = $app->getParams('com_users');

		// Load the parameters.
		$this->setState('params', $params);
	}

	/**
	 * Send the remind username email
	 *
	 * @param   array  $data  Array with the data received from the form
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public function processRemindRequest($data)
	{
		// Get the form.
		$form = $this->getForm();
		$data['email'] =
JStringPunycode::emailToPunycode($data['email']);

		// Check for an error.
		if (empty($form))
		{
			return false;
		}

		// Validate the data.
		$data = $this->validate($form, $data);

		// Check for an error.
		if ($data instanceof Exception)
		{
			return false;
		}

		// Check the validation results.
		if ($data === false)
		{
			// Get the validation messages from the form.
			foreach ($form->getErrors() as $formError)
			{
				$this->setError($formError->getMessage());
			}

			return false;
		}

		// Find the user id for the given email address.
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->quoteName('#__users'))
			->where('LOWER(' . $db->quoteName('email') .
') = LOWER(' . $db->quote($data['email']) .
')');

		// Get the user id.
		$db->setQuery($query);

		try
		{
			$user = $db->loadObject();
		}
		catch (RuntimeException $e)
		{
			$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

			return false;
		}

		// Check for a user.
		if (empty($user))
		{
			$this->setError(JText::_('COM_USERS_USER_NOT_FOUND'));

			return false;
		}

		// Make sure the user isn't blocked.
		if ($user->block)
		{
			$this->setError(JText::_('COM_USERS_USER_BLOCKED'));

			return false;
		}

		$config = JFactory::getConfig();

		// Assemble the login link.
		$link = 'index.php?option=com_users&view=login';
		$mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1);

		// Put together the email template data.
		$data = ArrayHelper::fromObject($user);
		$data['fromname'] = $config->get('fromname');
		$data['mailfrom'] = $config->get('mailfrom');
		$data['sitename'] = $config->get('sitename');
		$data['link_text'] = JRoute::_($link, false, $mode);
		$data['link_html'] = JRoute::_($link, true, $mode);

		$subject = JText::sprintf(
			'COM_USERS_EMAIL_USERNAME_REMINDER_SUBJECT',
			$data['sitename']
		);
		$body = JText::sprintf(
			'COM_USERS_EMAIL_USERNAME_REMINDER_BODY',
			$data['sitename'],
			$data['username'],
			$data['link_text']
		);

		// Send the password reset request email.
		$return = JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $user->email, $subject, $body);

		// Check for an error.
		if ($return !== true)
		{
			$this->setError(JText::_('COM_USERS_MAIL_FAILED'), 500);

			return false;
		}

		$dispatcher = \JEventDispatcher::getInstance();
		$dispatcher->trigger('onUserAfterRemind', array($user));

		return true;
	}
}
models/reset.php000064400000030677151165234420007702 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

use Joomla\CMS\User\UserHelper;

defined('_JEXEC') or die;

/**
 * Rest model class for Users.
 *
 * @since  1.5
 */
class UsersModelReset extends JModelForm
{
	/**
	 * Method to get the password reset request form.
	 *
	 * The base form is loaded from XML and then an event is fired
	 * for users plugins to extend the form with extra fields.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm  A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.reset_request',
'reset_request', array('control' =>
'jform', 'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the password reset complete form.
	 *
	 * @param   array    $data      Data for the form.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm    A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getResetCompleteForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.reset_complete',
'reset_complete', $options = array('control' =>
'jform'));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the password reset confirm form.
	 *
	 * @param   array    $data      Data for the form.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm  A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getResetConfirmForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.reset_confirm',
'reset_confirm', $options = array('control' =>
'jform'));

		if (empty($form))
		{
			return false;
		}
		else
		{
			$form->setValue('token', '',
JFactory::getApplication()->input->get('token'));
		}

		return $form;
	}

	/**
	 * Override preprocessForm to load the user plugin group instead of
content.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @throws	Exception if there is an error in the form event.
	 *
	 * @since   1.6
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState()
	{
		// Get the application object.
		$params =
JFactory::getApplication()->getParams('com_users');

		// Load the parameters.
		$this->setState('params', $params);
	}

	/**
	 * Save the new password after reset is done
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   1.6
	 */
	public function processResetComplete($data)
	{
		// Get the form.
		$form = $this->getResetCompleteForm();

		// Check for an error.
		if ($form instanceof Exception)
		{
			return $form;
		}

		// Filter and validate the form data.
		$data = $form->filter($data);
		$return = $form->validate($data);

		// Check for an error.
		if ($return instanceof Exception)
		{
			return $return;
		}

		// Check the validation results.
		if ($return === false)
		{
			// Get the validation messages from the form.
			foreach ($form->getErrors() as $formError)
			{
				$this->setError($formError->getMessage());
			}

			return false;
		}

		// Get the token and user id from the confirmation process.
		$app = JFactory::getApplication();
		$token = $app->getUserState('com_users.reset.token', null);
		$userId = $app->getUserState('com_users.reset.user', null);

		// Check the token and user id.
		if (empty($token) || empty($userId))
		{
			return new
JException(JText::_('COM_USERS_RESET_COMPLETE_TOKENS_MISSING'),
403);
		}

		// Get the user object.
		$user = JUser::getInstance($userId);

		// Check for a user and that the tokens match.
		if (empty($user) || $user->activation !== $token)
		{
			$this->setError(JText::_('COM_USERS_USER_NOT_FOUND'));

			return false;
		}

		// Make sure the user isn't blocked.
		if ($user->block)
		{
			$this->setError(JText::_('COM_USERS_USER_BLOCKED'));

			return false;
		}

		// Check if the user is reusing the current password if required to reset
their password
		if ($user->requireReset == 1 &&
JUserHelper::verifyPassword($data['password1'],
$user->password))
		{
			$this->setError(JText::_('JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD'));

			return false;
		}

		// Prepare user data.
		$data['password']   = $data['password1'];
		$data['activation'] = '';

		// Update the user object.
		if (!$user->bind($data))
		{
			return new \Exception($user->getError(), 500);
		}

		// Save the user to the database.
		if (!$user->save(true))
		{
			return new
JException(JText::sprintf('COM_USERS_USER_SAVE_FAILED',
$user->getError()), 500);
		}

		// Destroy all active sessions for the user
		UserHelper::destroyUserSessions($user->id);

		// Flush the user data from the session.
		$app->setUserState('com_users.reset.token', null);
		$app->setUserState('com_users.reset.user', null);

		return true;
	}

	/**
	 * Receive the reset password request
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   1.6
	 */
	public function processResetConfirm($data)
	{
		// Get the form.
		$form = $this->getResetConfirmForm();

		// Check for an error.
		if ($form instanceof Exception)
		{
			return $form;
		}

		// Filter and validate the form data.
		$data = $form->filter($data);
		$return = $form->validate($data);

		// Check for an error.
		if ($return instanceof Exception)
		{
			return $return;
		}

		// Check the validation results.
		if ($return === false)
		{
			// Get the validation messages from the form.
			foreach ($form->getErrors() as $formError)
			{
				$this->setError($formError->getMessage());
			}

			return false;
		}

		// Find the user id for the given token.
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('activation')
			->select('id')
			->select('block')
			->from($db->quoteName('#__users'))
			->where($db->quoteName('username') . ' = ' .
$db->quote($data['username']));

		// Get the user id.
		$db->setQuery($query);

		try
		{
			$user = $db->loadObject();
		}
		catch (RuntimeException $e)
		{
			return new
JException(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);
		}

		// Check for a user.
		if (empty($user))
		{
			$this->setError(JText::_('COM_USERS_USER_NOT_FOUND'));

			return false;
		}

		if (!$user->activation)
		{
			$this->setError(JText::_('COM_USERS_USER_NOT_FOUND'));

			return false;
		}

		// Verify the token
		if (!JUserHelper::verifyPassword($data['token'],
$user->activation))
		{
			$this->setError(JText::_('COM_USERS_USER_NOT_FOUND'));

			return false;
		}

		// Make sure the user isn't blocked.
		if ($user->block)
		{
			$this->setError(JText::_('COM_USERS_USER_BLOCKED'));

			return false;
		}

		// Push the user data into the session.
		$app = JFactory::getApplication();
		$app->setUserState('com_users.reset.token',
$user->activation);
		$app->setUserState('com_users.reset.user', $user->id);

		return true;
	}

	/**
	 * Method to start the password reset process.
	 *
	 * @param   array  $data  The data expected for the form.
	 *
	 * @return  mixed  Exception | JException | boolean
	 *
	 * @since   1.6
	 */
	public function processResetRequest($data)
	{
		$config = JFactory::getConfig();

		// Get the form.
		$form = $this->getForm();

		$data['email'] =
JStringPunycode::emailToPunycode($data['email']);

		// Check for an error.
		if ($form instanceof Exception)
		{
			return $form;
		}

		// Filter and validate the form data.
		$data = $form->filter($data);
		$return = $form->validate($data);

		// Check for an error.
		if ($return instanceof Exception)
		{
			return $return;
		}

		// Check the validation results.
		if ($return === false)
		{
			// Get the validation messages from the form.
			foreach ($form->getErrors() as $formError)
			{
				$this->setError($formError->getMessage());
			}

			return false;
		}

		// Find the user id for the given email address.
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('id')
			->from($db->quoteName('#__users'))
			->where('LOWER(' . $db->quoteName('email') .
') = LOWER(' . $db->quote($data['email']) .
')');

		// Get the user object.
		$db->setQuery($query);

		try
		{
			$userId = $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			$this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);

			return false;
		}

		// Check for a user.
		if (empty($userId))
		{
			$this->setError(JText::_('COM_USERS_INVALID_EMAIL'));

			return false;
		}

		// Get the user object.
		$user = JUser::getInstance($userId);

		// Make sure the user isn't blocked.
		if ($user->block)
		{
			$this->setError(JText::_('COM_USERS_USER_BLOCKED'));

			return false;
		}

		// Make sure the user isn't a Super Admin.
		if ($user->authorise('core.admin'))
		{
			$this->setError(JText::_('COM_USERS_REMIND_SUPERADMIN_ERROR'));

			return false;
		}

		// Make sure the user has not exceeded the reset limit
		if (!$this->checkResetLimit($user))
		{
			$resetLimit = (int)
JFactory::getApplication()->getParams()->get('reset_time');
			$this->setError(JText::plural('COM_USERS_REMIND_LIMIT_ERROR_N_HOURS',
$resetLimit));

			return false;
		}

		// Set the confirmation token.
		$token = JApplicationHelper::getHash(JUserHelper::genRandomPassword());
		$hashedToken = JUserHelper::hashPassword($token);

		$user->activation = $hashedToken;

		// Save the user to the database.
		if (!$user->save(true))
		{
			return new
JException(JText::sprintf('COM_USERS_USER_SAVE_FAILED',
$user->getError()), 500);
		}

		// Assemble the password reset confirmation link.
		$mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1);
		$link =
'index.php?option=com_users&view=reset&layout=confirm&token='
. $token;

		// Put together the email template data.
		$data = $user->getProperties();
		$data['fromname'] = $config->get('fromname');
		$data['mailfrom'] = $config->get('mailfrom');
		$data['sitename'] = $config->get('sitename');
		$data['link_text'] = JRoute::_($link, false, $mode);
		$data['link_html'] = JRoute::_($link, true, $mode);
		$data['token'] = $token;

		$subject = JText::sprintf(
			'COM_USERS_EMAIL_PASSWORD_RESET_SUBJECT',
			$data['sitename']
		);

		$body = JText::sprintf(
			'COM_USERS_EMAIL_PASSWORD_RESET_BODY',
			$data['sitename'],
			$data['token'],
			$data['link_text']
		);

		// Send the password reset request email.
		$return = JFactory::getMailer()->sendMail($data['mailfrom'],
$data['fromname'], $user->email, $subject, $body);

		// Check for an error.
		if ($return !== true)
		{
			return new JException(JText::_('COM_USERS_MAIL_FAILED'), 500);
		}

		return true;
	}

	/**
	 * Method to check if user reset limit has been exceeded within the
allowed time period.
	 *
	 * @param   JUser  $user  User doing the password reset
	 *
	 * @return  boolean true if user can do the reset, false if limit exceeded
	 *
	 * @since    2.5
	 */
	public function checkResetLimit($user)
	{
		$params = JFactory::getApplication()->getParams();
		$maxCount = (int) $params->get('reset_count');
		$resetHours = (int) $params->get('reset_time');
		$result = true;

		$lastResetTime = strtotime($user->lastResetTime) ?: 0;
		$hoursSinceLastReset = (strtotime(JFactory::getDate()->toSql()) -
$lastResetTime) / 3600;

		if ($hoursSinceLastReset > $resetHours)
		{
			// If it's been long enough, start a new reset count
			$user->lastResetTime = JFactory::getDate()->toSql();
			$user->resetCount = 1;
		}
		elseif ($user->resetCount < $maxCount)
		{
			// If we are under the max count, just increment the counter
			++$user->resetCount;
		}
		else
		{
			// At this point, we know we have exceeded the maximum resets for the
time period
			$result = false;
		}

		return $result;
	}
}
models/rules/loginuniquefield.php000064400000004111151165234420013235
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2016 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('JPATH_PLATFORM') or die;

use Joomla\Registry\Registry;

/**
 * JFormRule for com_users to be sure only one redirect login field has a
value
 *
 * @since  3.6
 */
class JFormRuleLoginUniqueField extends JFormRule
{
	/**
	 * Method to test if two fields have a value in order to use only one
field.
	 * To use this rule, the form
	 * XML needs a validate attribute of loginuniquefield and a field
attribute
	 * that is equal to the field to test against.
	 *
	 * @param   SimpleXMLElement  $element  The SimpleXMLElement object
representing the `<field>` tag for the form field object.
	 * @param   mixed             $value    The form field value to validate.
	 * @param   string            $group    The field name group control
value. This acts as an array container for the field.
	 *                                      For example if the field has
name="foo" and the group value is set to "bar" then the
	 *                                      full field name would end up being
"bar[foo]".
	 * @param   Registry          $input    An optional Registry object with
the entire data set to validate against the entire form.
	 * @param   JForm             $form     The form object for which the
field is being tested.
	 *
	 * @return  boolean  True if the value is valid, false otherwise.
	 *
	 * @since   3.6
	 */
	public function test(SimpleXMLElement $element, $value, $group = null,
Registry $input = null, JForm $form = null)
	{
		$loginRedirectUrl       =
$input['params']->login_redirect_url;
		$loginRedirectMenuitem  =
$input['params']->login_redirect_menuitem;

		if ($form === null)
		{
			throw new InvalidArgumentException(sprintf('The value for $form
must not be null in %s', get_class($this)));
		}

		if ($input === null)
		{
			throw new InvalidArgumentException(sprintf('The value for $input
must not be null in %s', get_class($this)));
		}

		return true;
	}
}
models/rules/logoutuniquefield.php000064400000004116151165234420013443
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2016 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('JPATH_PLATFORM') or die;

use Joomla\Registry\Registry;

/**
 * JFormRule for com_users to be sure only one redirect logout field has a
value
 *
 * @since  3.6
 */
class JFormRuleLogoutUniqueField extends JFormRule
{
	/**
	 * Method to test if two fields have a value in order to use only one
field.
	 * To use this rule, the form
	 * XML needs a validate attribute of logoutuniquefield and a field
attribute
	 * that is equal to the field to test against.
	 *
	 * @param   SimpleXMLElement  $element  The SimpleXMLElement object
representing the `<field>` tag for the form field object.
	 * @param   mixed             $value    The form field value to validate.
	 * @param   string            $group    The field name group control
value. This acts as an array container for the field.
	 *                                      For example if the field has
name="foo" and the group value is set to "bar" then the
	 *                                      full field name would end up being
"bar[foo]".
	 * @param   Registry          $input    An optional Registry object with
the entire data set to validate against the entire form.
	 * @param   JForm             $form     The form object for which the
field is being tested.
	 *
	 * @return  boolean  True if the value is valid, false otherwise.
	 *
	 * @since   3.6
	 */
	public function test(SimpleXMLElement $element, $value, $group = null,
Registry $input = null, JForm $form = null)
	{
		$logoutRedirectUrl      =
$input['params']->logout_redirect_url;
		$logoutRedirectMenuitem =
$input['params']->logout_redirect_menuitem;

		if ($form === null)
		{
			throw new InvalidArgumentException(sprintf('The value for $form
must not be null in %s', get_class($this)));
		}

		if ($input === null)
		{
			throw new InvalidArgumentException(sprintf('The value for $input
must not be null in %s', get_class($this)));
		}

		return true;
	}
}
router.php000064400000004411151165234420006600 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Routing class from com_users
 *
 * @since  3.2
 */
class UsersRouter extends JComponentRouterView
{
	/**
	 * Users Component router constructor
	 *
	 * @param   JApplicationCms  $app   The application object
	 * @param   JMenu            $menu  The menu object to work with
	 */
	public function __construct($app = null, $menu = null)
	{
		$this->registerView(new
JComponentRouterViewconfiguration('login'));
		$profile = new JComponentRouterViewconfiguration('profile');
		$profile->addLayout('edit');
		$this->registerView($profile);
		$this->registerView(new
JComponentRouterViewconfiguration('registration'));
		$this->registerView(new
JComponentRouterViewconfiguration('remind'));
		$this->registerView(new
JComponentRouterViewconfiguration('reset'));

		parent::__construct($app, $menu);

		$this->attachRule(new JComponentRouterRulesMenu($this));

		$params = JComponentHelper::getParams('com_users');

		if ($params->get('sef_advanced', 0))
		{
			$this->attachRule(new JComponentRouterRulesStandard($this));
			$this->attachRule(new JComponentRouterRulesNomenu($this));
		}
		else
		{
			JLoader::register('UsersRouterRulesLegacy', __DIR__ .
'/helpers/legacyrouter.php');
			$this->attachRule(new UsersRouterRulesLegacy($this));
		}
	}
}

/**
 * Users router functions
 *
 * These functions are proxys for the new router interface
 * for old SEF extensions.
 *
 * @param   array  &$query  REQUEST query
 *
 * @return  array  Segments of the SEF url
 *
 * @deprecated  4.0  Use Class based routers instead
 */
function usersBuildRoute(&$query)
{
	$app = JFactory::getApplication();
	$router = new UsersRouter($app, $app->getMenu());

	return $router->build($query);
}

/**
 * Convert SEF URL segments into query variables
 *
 * @param   array  $segments  Segments in the current URL
 *
 * @return  array  Query variables
 *
 * @deprecated  4.0  Use Class based routers instead
 */
function usersParseRoute($segments)
{
	$app = JFactory::getApplication();
	$router = new UsersRouter($app, $app->getMenu());

	return $router->parse($segments);
}
users.php000064400000001240151165234420006416 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;
JHtml::_('behavior.tabstate');

if (!JFactory::getUser()->authorise('core.manage',
'com_users'))
{
	throw new
JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'),
403);
}

JLoader::register('UsersHelper', __DIR__ .
'/helpers/users.php');

$controller = JControllerLegacy::getInstance('Users');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
views/login/tmpl/default.php000064400000001035151165234420012124
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

$cookieLogin = $this->user->get('cookieLogin');

if (!empty($cookieLogin) || $this->user->get('guest'))
{
	// The user is not logged in or needs to provide a password.
	echo $this->loadTemplate('login');
}
else
{
	// The user is already logged in.
	echo $this->loadTemplate('logout');
}
views/login/tmpl/default.xml000064400000010107151165234420012135
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_LOGIN_VIEW_DEFAULT_TITLE"
option="COM_USER_LOGIN_VIEW_DEFAULT_OPTION">
		<help
			key = "JHELP_MENUS_MENU_ITEM_USER_LOGIN"
		/>
		<message>
			<![CDATA[COM_USER_LOGIN_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>

	<!-- Add fields to the parameters object for the layout. -->
	<fields name="params">

		<!-- Basic options. -->
		<fieldset name="basic"
addrulepath="components/com_users/models/rules"
label="COM_MENUS_BASIC_FIELDSET_LABEL">

		<field
			name="loginredirectchoice"
			type="radio"
			label="COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL"
			description="COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option
value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
			<option
value="0">COM_USERS_FIELD_LOGIN_URL</option>
		</field>

		<field
			name="login_redirect_url"
			type="text"
			label="JFIELD_LOGIN_REDIRECT_URL_LABEL"
			description="JFIELD_LOGIN_REDIRECT_URL_DESC"
			class="inputbox"
			validate="loginuniquefield"
			field="login_redirect_menuitem"
			hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
			message="COM_USERS_FIELD_LOGIN_REDIRECT_ERROR"
			showon="loginredirectchoice:0"
		/>

		<field
			name="login_redirect_menuitem"
			type="modal_menu"
			label="COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL"
			description="COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC"
			disable="separator,alias,heading,url"
			showon="loginredirectchoice:1"
			select="true"
			new="true"
			edit="true"
			clear="true"
			>
			<option value="">JDEFAULT</option>
		</field>

		<field
			name="logindescription_show"
			type="list"
			label="JFIELD_BASIS_LOGIN_DESCRIPTION_SHOW_LABEL"
			description="JFIELD_BASIS_LOGIN_DESCRIPTION_SHOW_DESC"
			default="1"
			class="chzn-color"
			>
			<option value="0">JHIDE</option>
			<option value="1">JSHOW</option>
		</field>

		<field
			name="login_description"
			type="textarea"
			label="JFIELD_BASIS_LOGIN_DESCRIPTION_LABEL"
			description="JFIELD_BASIS_LOGIN_DESCRIPTION_DESC"
			rows="3"
			cols="40"
			filter="safehtml"
			showon="logindescription_show:1"
		/>

		<field
			name="login_image"
			type="media"
			label="JFIELD_LOGIN_IMAGE_LABEL"
			description="JFIELD_LOGIN_IMAGE_DESC"
		/>

		<field 
			name="spacer1" 
			type="spacer"
			hr="true"
		/>

		<field
			name="logoutredirectchoice"
			type="radio"
			label="COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL"
			description="COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option
value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
			<option
value="0">COM_USERS_FIELD_LOGIN_URL</option>
		</field>

		<field
			name="logout_redirect_url"
			type="text"
			label="JFIELD_LOGOUT_REDIRECT_URL_LABEL"
			description="JFIELD_LOGOUT_REDIRECT_URL_DESC"
			class="inputbox"
			field="logout_redirect_menuitem"
			validate="logoutuniquefield"
			hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
			message="COM_USERS_FIELD_LOGOUT_REDIRECT_ERROR"
			showon="logoutredirectchoice:0"
		/>
		
		<field
			name="logout_redirect_menuitem"
			type="modal_menu"
			label="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL"
			description="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC"
			disable="separator,alias,heading,url"
			showon="logoutredirectchoice:1"
			select="true"
			new="true"
			edit="true"
			clear="true"
			>
			<option value="">JDEFAULT</option>
		</field>

		<field
			name="logoutdescription_show"
			type="list"
			label="JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL"
			description="JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC"
			default="1"
			class="chzn-color"
			>
			<option value="0">JHIDE</option>
			<option value="1">JSHOW</option>
		</field>

		<field
			name="logout_description"
			type="textarea"
			label="JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL"
			description="JFIELD_BASIS_LOGOUT_DESCRIPTION_DESC"
			rows="3"
			cols="40"
			filter="safehtml"
			showon="logoutdescription_show:1"
		/>

		<field
			name="logout_image"
			type="media"
			label="JFIELD_LOGOUT_IMAGE_LABEL"
			description="JFIELD_LOGOUT_IMAGE_DESC"
		/>

		</fieldset>
	</fields>
</metadata>
views/login/tmpl/default_login.php000064400000006356151165234420013327
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="login<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<?php if (($this->params->get('logindescription_show')
== 1 && str_replace(' ', '',
$this->params->get('login_description')) != '')
|| $this->params->get('login_image') != '') :
?>
		<div class="login-description">
	<?php endif; ?>
	<?php if ($this->params->get('logindescription_show')
== 1) : ?>
		<?php echo $this->params->get('login_description');
?>
	<?php endif; ?>
	<?php if ($this->params->get('login_image') !=
'') : ?>
		<img src="<?php echo
$this->escape($this->params->get('login_image'));
?>" class="login-image" alt="<?php echo
JText::_('COM_USERS_LOGIN_IMAGE_ALT'); ?>" />
	<?php endif; ?>
	<?php if (($this->params->get('logindescription_show')
== 1 && str_replace(' ', '',
$this->params->get('login_description')) != '')
|| $this->params->get('login_image') != '') :
?>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_users&task=user.login');
?>" method="post" class="form-validate
form-horizontal well">
		<fieldset>
			<?php echo
$this->form->renderFieldset('credentials'); ?>
			<?php if ($this->tfa) : ?>
				<?php echo $this->form->renderField('secretkey');
?>
			<?php endif; ?>
			<?php if (JPluginHelper::isEnabled('system',
'remember')) : ?>
				<div class="control-group">
					<div class="control-label">
						<label for="remember">
							<?php echo JText::_('COM_USERS_LOGIN_REMEMBER_ME');
?>
						</label>
					</div>
					<div class="controls">
						<input id="remember" type="checkbox"
name="remember" class="inputbox" value="yes"
/>
					</div>
				</div>
			<?php endif; ?>
			<div class="control-group">
				<div class="controls">
					<button type="submit" class="btn
btn-primary">
						<?php echo JText::_('JLOGIN'); ?>
					</button>
				</div>
			</div>
			<?php $return = $this->form->getValue('return',
'', $this->params->get('login_redirect_url',
$this->params->get('login_redirect_menuitem'))); ?>
			<input type="hidden" name="return"
value="<?php echo base64_encode($return); ?>" />
			<?php echo JHtml::_('form.token'); ?>
		</fieldset>
	</form>
</div>
<div>
	<ul class="nav nav-tabs nav-stacked">
		<li>
			<a href="<?php echo
JRoute::_('index.php?option=com_users&view=reset');
?>">
				<?php echo JText::_('COM_USERS_LOGIN_RESET'); ?>
			</a>
		</li>
		<li>
			<a href="<?php echo
JRoute::_('index.php?option=com_users&view=remind');
?>">
				<?php echo JText::_('COM_USERS_LOGIN_REMIND'); ?>
			</a>
		</li>
		<?php $usersConfig =
JComponentHelper::getParams('com_users'); ?>
		<?php if ($usersConfig->get('allowUserRegistration')) :
?>
			<li>
				<a href="<?php echo
JRoute::_('index.php?option=com_users&view=registration');
?>">
					<?php echo JText::_('COM_USERS_LOGIN_REGISTER'); ?>
				</a>
			</li>
		<?php endif; ?>
	</ul>
</div>
views/login/tmpl/default_logout.php000064400000004212151165234420013515
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

?>
<div class="logout<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<?php if (($this->params->get('logoutdescription_show')
== 1 && str_replace(' ', '',
$this->params->get('logout_description')) !=
'')|| $this->params->get('logout_image') !=
'') : ?>
		<div class="logout-description">
	<?php endif; ?>
	<?php if ($this->params->get('logoutdescription_show')
== 1) : ?>
		<?php echo $this->params->get('logout_description');
?>
	<?php endif; ?>
	<?php if ($this->params->get('logout_image') !=
'') : ?>
		<img src="<?php echo
$this->escape($this->params->get('logout_image'));
?>" class="thumbnail pull-right logout-image"
alt="<?php echo JText::_('COM_USER_LOGOUT_IMAGE_ALT');
?>" />
	<?php endif; ?>
	<?php if (($this->params->get('logoutdescription_show')
== 1 && str_replace(' ', '',
$this->params->get('logout_description')) !=
'')|| $this->params->get('logout_image') !=
'') : ?>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_users&task=user.logout');
?>" method="post" class="form-horizontal
well">
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn
btn-primary">
					<span class="icon-arrow-left icon-white"></span>
					<?php echo JText::_('JLOGOUT'); ?>
				</button>
			</div>
		</div>
		<?php if ($this->params->get('logout_redirect_url')) :
?>
			<input type="hidden" name="return"
value="<?php echo
base64_encode($this->params->get('logout_redirect_url',
$this->form->getValue('return'))); ?>" />
		<?php else : ?>
			<input type="hidden" name="return"
value="<?php echo
base64_encode($this->params->get('logout_redirect_menuitem',
$this->form->getValue('return'))); ?>" />
		<?php endif; ?>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/login/tmpl/logout.xml000064400000001757151165234420012035
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_LOGOUT_VIEW_DEFAULT_TITLE"
option="COM_USER_LOGOUT_VIEW_DEFAULT_OPTION">
		<help key = "JHELP_MENUS_MENU_ITEM_USER_LOGOUT"/>
		<message>
			<![CDATA[COM_USER_LOGOUT_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>

	<!-- Add fields to the request variables for the layout. -->
	<fields name="request">
		<fieldset name="request">
			<field
				name="task"
				type="hidden"
				default="user.menulogout"
			/>
		</fieldset>
	</fields>

	<!-- Add fields to the parameters object for the layout. -->
	<fields name="params">
		<fieldset name="basic"
label="COM_MENUS_BASIC_FIELDSET_LABEL">
			<field
				name="logout"
				type="modal_menu"
				label="JFIELD_LOGOUT_REDIRECT_PAGE_LABEL"
				description="JFIELD_LOGOUT_REDIRECT_PAGE_DESC"
				disable="separator,alias,heading,url"
				select="true"
				new="true"
				edit="true"
				clear="true"
				>
				<option value="">JDEFAULT</option>
			</field>
		</fieldset>
	</fields>
</metadata>
views/login/view.html.php000064400000005727151165234420011455
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Login view class for Users.
 *
 * @since  1.5
 */
class UsersViewLogin extends JViewLegacy
{
	protected $form;

	protected $params;

	protected $state;

	protected $user;

	/**
	 * Method to display the view.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @since   1.5
	 */
	public function display($tpl = null)
	{
		// Get the view data.
		$this->user   = JFactory::getUser();
		$this->form   = $this->get('Form');
		$this->state  = $this->get('State');
		$this->params = $this->state->get('params');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			JError::raiseError(500, implode('<br />', $errors));

			return false;
		}

		// Check for layout override
		$active = JFactory::getApplication()->getMenu()->getActive();

		if (isset($active->query['layout']))
		{
			$this->setLayout($active->query['layout']);
		}

		$tfa = JAuthenticationHelper::getTwoFactorMethods();
		$this->tfa = is_array($tfa) && count($tfa) > 1;

		// Escape strings for HTML output
		$this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

		$this->prepareDocument();

		parent::display($tpl);
	}

	/**
	 * Prepares the document
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$user  = JFactory::getUser();
		$login = $user->get('guest') ? true : false;
		$title = null;

		// Because the application sets a default page title,
		// we need to get it from the menu item itself
		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
		}
		else
		{
			$this->params->def('page_heading', $login ?
JText::_('JLOGIN') : JText::_('JLOGOUT'));
		}

		$title = $this->params->get('page_title', '');

		if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE',
$app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title,
$app->get('sitename'));
		}

		$this->document->setTitle($title);

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords',
$this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots',
$this->params->get('robots'));
		}
	}
}
views/profile/tmpl/default.php000064400000002026151165234420012455
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

?>
<div class="profile<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<?php if (JFactory::getUser()->id == $this->data->id) : ?>
		<ul class="btn-toolbar pull-right">
			<li class="btn-group">
				<a class="btn" href="<?php echo
JRoute::_('index.php?option=com_users&task=profile.edit&user_id='
. (int) $this->data->id); ?>">
					<span class="icon-user"></span>
					<?php echo JText::_('COM_USERS_EDIT_PROFILE'); ?>
				</a>
			</li>
		</ul>
	<?php endif; ?>
	<?php echo $this->loadTemplate('core'); ?>
	<?php echo $this->loadTemplate('params'); ?>
	<?php echo $this->loadTemplate('custom'); ?>
</div>
views/profile/tmpl/default.xml000064400000000463151165234420012471
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_PROFILE_VIEW_DEFAULT_TITLE"
option="COM_USER_PROFILE_VIEW_DEFAULT_OPTION">
		<help
			key = "JHELP_MENUS_MENU_ITEM_USER_PROFILE"
		/>
		<message>
			<![CDATA[COM_USER_PROFILE_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/profile/tmpl/default_core.php000064400000002404151165234420013465
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

?>
<fieldset id="users-profile-core">
	<legend>
		<?php echo JText::_('COM_USERS_PROFILE_CORE_LEGEND'); ?>
	</legend>
	<dl class="dl-horizontal">
		<dt>
			<?php echo JText::_('COM_USERS_PROFILE_NAME_LABEL'); ?>
		</dt>
		<dd>
			<?php echo $this->escape($this->data->name); ?>
		</dd>
		<dt>
			<?php echo JText::_('COM_USERS_PROFILE_USERNAME_LABEL');
?>
		</dt>
		<dd>
			<?php echo $this->escape($this->data->username); ?>
		</dd>
		<dt>
			<?php echo
JText::_('COM_USERS_PROFILE_REGISTERED_DATE_LABEL'); ?>
		</dt>
		<dd>
			<?php echo JHtml::_('date',
$this->data->registerDate, JText::_('DATE_FORMAT_LC1'));
?>
		</dd>
		<dt>
			<?php echo
JText::_('COM_USERS_PROFILE_LAST_VISITED_DATE_LABEL'); ?>
		</dt>
		<?php if ($this->data->lastvisitDate !=
$this->db->getNullDate()) : ?>
			<dd>
				<?php echo JHtml::_('date',
$this->data->lastvisitDate, JText::_('DATE_FORMAT_LC1'));
?>
			</dd>
		<?php else : ?>
			<dd>
				<?php echo JText::_('COM_USERS_PROFILE_NEVER_VISITED');
?>
			</dd>
		<?php endif; ?>
	</dl>
</fieldset>
views/profile/tmpl/default_custom.php000064400000004607151165234420014056
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
JHtml::register('users.spacer', array('JHtmlUsers',
'spacer'));

$fieldsets = $this->form->getFieldsets();

if (isset($fieldsets['core']))
{
	unset($fieldsets['core']);
}

if (isset($fieldsets['params']))
{
	unset($fieldsets['params']);
}

$tmp          = isset($this->data->jcfields) ?
$this->data->jcfields : array();
$customFields = array();

foreach ($tmp as $customField)
{
	$customFields[$customField->name] = $customField;
}

?>
<?php foreach ($fieldsets as $group => $fieldset) : ?>
	<?php $fields = $this->form->getFieldset($group); ?>
	<?php if (count($fields)) : ?>
		<fieldset id="users-profile-custom-<?php echo $group;
?>" class="users-profile-custom-<?php echo $group;
?>">
			<?php if (isset($fieldset->label) && ($legend =
trim(JText::_($fieldset->label))) !== '') : ?>
				<legend><?php echo $legend; ?></legend>
			<?php endif; ?>
			<?php if (isset($fieldset->description) &&
trim($fieldset->description)) : ?>
				<p><?php echo
$this->escape(JText::_($fieldset->description)); ?></p>
			<?php endif; ?>
			<dl class="dl-horizontal">
				<?php foreach ($fields as $field) : ?>
					<?php if (!$field->hidden && $field->type !==
'Spacer') : ?>
						<dt>
							<?php echo $field->title; ?>
						</dt>
						<dd>
							<?php if (key_exists($field->fieldname, $customFields)) :
?>
								<?php echo strlen($customFields[$field->fieldname]->value)
? $customFields[$field->fieldname]->value :
JText::_('COM_USERS_PROFILE_VALUE_NOT_FOUND'); ?>
							<?php elseif (JHtml::isRegistered('users.' .
$field->id)) : ?>
								<?php echo JHtml::_('users.' . $field->id,
$field->value); ?>
							<?php elseif (JHtml::isRegistered('users.' .
$field->fieldname)) : ?>
								<?php echo JHtml::_('users.' . $field->fieldname,
$field->value); ?>
							<?php elseif (JHtml::isRegistered('users.' .
$field->type)) : ?>
								<?php echo JHtml::_('users.' . $field->type,
$field->value); ?>
							<?php else : ?>
								<?php echo JHtml::_('users.value', $field->value);
?>
							<?php endif; ?>
						</dd>
					<?php endif; ?>
				<?php endforeach; ?>
			</dl>
		</fieldset>
	<?php endif; ?>
<?php endforeach; ?>
views/profile/tmpl/default_params.php000064400000002446151165234420014026
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

?>
<?php $fields = $this->form->getFieldset('params');
?>
<?php if (count($fields)) : ?>
	<fieldset id="users-profile-custom">
		<legend><?php echo
JText::_('COM_USERS_SETTINGS_FIELDSET_LABEL');
?></legend>
		<dl class="dl-horizontal">
			<?php foreach ($fields as $field) : ?>
				<?php if (!$field->hidden) : ?>
					<dt>
						<?php echo $field->title; ?>
					</dt>
					<dd>
						<?php if (JHtml::isRegistered('users.' . $field->id))
: ?>
							<?php echo JHtml::_('users.' . $field->id,
$field->value); ?>
						<?php elseif (JHtml::isRegistered('users.' .
$field->fieldname)) : ?>
							<?php echo JHtml::_('users.' . $field->fieldname,
$field->value); ?>
						<?php elseif (JHtml::isRegistered('users.' .
$field->type)) : ?>
							<?php echo JHtml::_('users.' . $field->type,
$field->value); ?>
						<?php else : ?>
							<?php echo JHtml::_('users.value', $field->value);
?>
						<?php endif; ?>
					</dd>
				<?php endif; ?>
			<?php endforeach; ?>
		</dl>
	</fieldset>
<?php endif; ?>
views/profile/tmpl/edit.php000064400000013024151165234420011756
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select');
JHtml::_('bootstrap.tooltip');


// Load user_profile plugin language
$lang = JFactory::getLanguage();
$lang->load('plg_user_profile', JPATH_ADMINISTRATOR);

?>
<div class="profile-edit<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<script type="text/javascript">
		Joomla.twoFactorMethodChange = function(e)
		{
			var selectedPane = 'com_users_twofactor_' +
jQuery('#jform_twofactor_method').val();

			jQuery.each(jQuery('#com_users_twofactor_forms_container>div'),
function(i, el)
			{
				if (el.id != selectedPane)
				{
					jQuery('#' + el.id).hide(0);
				}
				else
				{
					jQuery('#' + el.id).show(0);
				}
			});
		}
	</script>
	<form id="member-profile" action="<?php echo
JRoute::_('index.php?option=com_users&task=profile.save');
?>" method="post" class="form-validate
form-horizontal well" enctype="multipart/form-data">
		<?php // Iterate through the form fieldsets and display each one.
?>
		<?php foreach ($this->form->getFieldsets() as $group =>
$fieldset) : ?>
			<?php $fields = $this->form->getFieldset($group); ?>
			<?php if (count($fields)) : ?>
				<fieldset>
					<?php // If the fieldset has a label set, display it as the legend.
?>
					<?php if (isset($fieldset->label)) : ?>
						<legend>
							<?php echo JText::_($fieldset->label); ?>
						</legend>
					<?php endif; ?>
					<?php if (isset($fieldset->description) &&
trim($fieldset->description)) : ?>
						<p>
							<?php echo $this->escape(JText::_($fieldset->description));
?>
						</p>
					<?php endif; ?>
					<?php // Iterate through the fields in the set and display them.
?>
					<?php foreach ($fields as $field) : ?>
						<?php // If the field is hidden, just display the input. ?>
						<?php if ($field->hidden) : ?>
							<?php echo $field->input; ?>
						<?php else : ?>
							<div class="control-group">
								<div class="control-label">
									<?php echo $field->label; ?>
									<?php if (!$field->required && $field->type !==
'Spacer') : ?>
										<span class="optional">
											<?php echo JText::_('COM_USERS_OPTIONAL'); ?>
										</span>
									<?php endif; ?>
								</div>
								<div class="controls">
									<?php if ($field->fieldname === 'password1') :
?>
										<?php // Disables autocomplete ?>
										<input type="password"
style="display:none">
									<?php endif; ?>
									<?php echo $field->input; ?>
								</div>
							</div>
						<?php endif; ?>
					<?php endforeach; ?>
				</fieldset>
			<?php endif; ?>
		<?php endforeach; ?>
		<?php if (count($this->twofactormethods) > 1 &&
!empty($this->twofactorform)) : ?>
			<fieldset>
				<legend><?php echo
JText::_('COM_USERS_PROFILE_TWO_FACTOR_AUTH');
?></legend>
				<div class="control-group">
					<div class="control-label">
						<label id="jform_twofactor_method-lbl"
for="jform_twofactor_method" class="hasTooltip"
							title="<?php echo '<strong>' .
JText::_('COM_USERS_PROFILE_TWOFACTOR_LABEL') .
'</strong><br />' .
JText::_('COM_USERS_PROFILE_TWOFACTOR_DESC'); ?>">
							<?php echo
JText::_('COM_USERS_PROFILE_TWOFACTOR_LABEL'); ?>
						</label>
					</div>
					<div class="controls">
						<?php echo JHtml::_('select.genericlist',
$this->twofactormethods, 'jform[twofactor][method]',
array('onchange' =>
'Joomla.twoFactorMethodChange()'), 'value',
'text', $this->otpConfig->method,
'jform_twofactor_method', false); ?>
					</div>
				</div>
				<div id="com_users_twofactor_forms_container">
					<?php foreach ($this->twofactorform as $form) : ?>
						<?php $style = $form['method'] ==
$this->otpConfig->method ? 'display: block' :
'display: none'; ?>
						<div id="com_users_twofactor_<?php echo
$form['method']; ?>" style="<?php echo $style;
?>">
							<?php echo $form['form']; ?>
						</div>
					<?php endforeach; ?>
				</div>
			</fieldset>
			<fieldset>
				<legend>
					<?php echo JText::_('COM_USERS_PROFILE_OTEPS'); ?>
				</legend>
				<div class="alert alert-info">
					<?php echo JText::_('COM_USERS_PROFILE_OTEPS_DESC');
?>
				</div>
				<?php if (empty($this->otpConfig->otep)) : ?>
					<div class="alert alert-warning">
						<?php echo
JText::_('COM_USERS_PROFILE_OTEPS_WAIT_DESC'); ?>
					</div>
				<?php else : ?>
					<?php foreach ($this->otpConfig->otep as $otep) : ?>
						<span class="span3">
							<?php echo substr($otep, 0, 4); ?>-<?php echo substr($otep,
4, 4); ?>-<?php echo substr($otep, 8, 4); ?>-<?php echo
substr($otep, 12, 4); ?>
						</span>
					<?php endforeach; ?>
					<div class="clearfix"></div>
				<?php endif; ?>
			</fieldset>
		<?php endif; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
				<a class="btn" href="<?php echo
JRoute::_('index.php?option=com_users&view=profile');
?>" title="<?php echo JText::_('JCANCEL');
?>">
					<?php echo JText::_('JCANCEL'); ?>
				</a>
				<input type="hidden" name="option"
value="com_users" />
				<input type="hidden" name="task"
value="profile.save" />
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/profile/tmpl/edit.xml000064400000000470151165234420011770
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_PROFILE_EDIT_DEFAULT_TITLE"
option="COM_USER_PROFILE_EDIT_DEFAULT_OPTION">
		<help
			key = "JHELP_MENUS_MENU_ITEM_USER_PROFILE_EDIT"
		/>
		<message>
			<![CDATA[COM_USER_PROFILE_EDIT_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/profile/view.html.php000064400000010175151165234420011776
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Profile view class for Users.
 *
 * @since  1.6
 */
class UsersViewProfile extends JViewLegacy
{
	protected $data;

	protected $form;

	protected $params;

	protected $state;

	/**
	 * An instance of JDatabaseDriver.
	 *
	 * @var    JDatabaseDriver
	 * @since  3.6.3
	 */
	protected $db;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed   A string if successful, otherwise an Error object.
	 *
	 * @since   1.6
	 */
	public function display($tpl = null)
	{
		$user = JFactory::getUser();

		// Get the view data.
		$this->data	        = $this->get('Data');
		$this->form	        = $this->getModel()->getForm(new
JObject(array('id' => $user->id)));
		$this->state            = $this->get('State');
		$this->params           = $this->state->get('params');
		$this->twofactorform    = $this->get('Twofactorform');
		$this->twofactormethods = UsersHelper::getTwoFactorMethods();
		$this->otpConfig        = $this->get('OtpConfig');
		$this->db               = JFactory::getDbo();

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			JError::raiseError(500, implode('<br />', $errors));

			return false;
		}

		// View also takes responsibility for checking if the user logged in with
remember me.
		$cookieLogin = $user->get('cookieLogin');

		if (!empty($cookieLogin))
		{
			// If so, the user must login to edit the password and other data.
			// What should happen here? Should we force a logout which destroys the
cookies?
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('JGLOBAL_REMEMBER_MUST_LOGIN'),
'message');
			$app->redirect(JRoute::_('index.php?option=com_users&view=login',
false));

			return false;
		}

		// Check if a user was found.
		if (!$this->data->id)
		{
			JError::raiseError(404,
JText::_('JERROR_USERS_PROFILE_NOT_FOUND'));

			return false;
		}

		JPluginHelper::importPlugin('content');
		$this->data->text = '';
		JEventDispatcher::getInstance()->trigger('onContentPrepare',
array ('com_users.user', &$this->data,
&$this->data->params, 0));
		unset($this->data->text);

		// Check for layout override
		$active = JFactory::getApplication()->getMenu()->getActive();

		if (isset($active->query['layout']))
		{
			$this->setLayout($active->query['layout']);
		}

		// Escape strings for HTML output
		$this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''));

		$this->prepareDocument();

		return parent::display($tpl);
	}

	/**
	 * Prepares the document
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$user  = JFactory::getUser();
		$title = null;

		// Because the application sets a default page title,
		// we need to get it from the menu item itself
		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading',
$this->params->get('page_title', $user->name));
		}
		else
		{
			$this->params->def('page_heading',
JText::_('COM_USERS_PROFILE'));
		}

		$title = $this->params->get('page_title', '');

		if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE',
$app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title,
$app->get('sitename'));
		}

		$this->document->setTitle($title);

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords',
$this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots',
$this->params->get('robots'));
		}
	}
}
views/registration/tmpl/complete.php000064400000000754151165234420013721
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

?>
<div class="registration-complete<?php echo
$this->pageclass_sfx; ?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<h1>
			<?php echo
$this->escape($this->params->get('page_heading')); ?>
		</h1>
	<?php endif; ?>
</div>
views/registration/tmpl/default.php000064400000003543151165234420013534
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="registration<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1><?php echo
$this->escape($this->params->get('page_heading'));
?></h1>
		</div>
	<?php endif; ?>
	<form id="member-registration" action="<?php echo
JRoute::_('index.php?option=com_users&task=registration.register');
?>" method="post" class="form-validate
form-horizontal well" enctype="multipart/form-data">
		<?php // Iterate through the form fieldsets and display each one.
?>
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<?php $fields = $this->form->getFieldset($fieldset->name);
?>
			<?php if (count($fields)) : ?>
				<fieldset>
					<?php // If the fieldset has a label set, display it as the legend.
?>
					<?php if (isset($fieldset->label)) : ?>
						<legend><?php echo JText::_($fieldset->label);
?></legend>
					<?php endif; ?>
					<?php echo $this->form->renderFieldset($fieldset->name);
?>
				</fieldset>
			<?php endif; ?>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JREGISTER'); ?>
				</button>
				<a class="btn" href="<?php echo
JRoute::_(''); ?>" title="<?php echo
JText::_('JCANCEL'); ?>">
					<?php echo JText::_('JCANCEL'); ?>
				</a>
				<input type="hidden" name="option"
value="com_users" />
				<input type="hidden" name="task"
value="registration.register" />
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/registration/tmpl/default.xml000064400000000505151165234420013540
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_REGISTRATION_VIEW_DEFAULT_TITLE"
option="COM_USER_REGISTRATION_VIEW_DEFAULT_OPTION">
		<help
			key="JHELP_MENUS_MENU_ITEM_USER_REGISTRATION"
		/>
		<message>
			<![CDATA[COM_USER_REGISTRATION_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/registration/view.html.php000064400000005306151165234420013050
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Registration view class for Users.
 *
 * @since  1.6
 */
class UsersViewRegistration extends JViewLegacy
{
	protected $data;

	protected $form;

	protected $params;

	protected $state;

	public $document;

	/**
	 * Method to display the view.
	 *
	 * @param   string  $tpl  The template file to include
	 *
	 * @return  mixed
	 *
	 * @since   1.6
	 */
	public function display($tpl = null)
	{
		// Get the view data.
		$this->form   = $this->get('Form');
		$this->data   = $this->get('Data');
		$this->state  = $this->get('State');
		$this->params = $this->state->get('params');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			JError::raiseError(500, implode('<br />', $errors));

			return false;
		}

		// Check for layout override
		$active = JFactory::getApplication()->getMenu()->getActive();

		if (isset($active->query['layout']))
		{
			$this->setLayout($active->query['layout']);
		}

		// Escape strings for HTML output
		$this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

		$this->prepareDocument();

		return parent::display($tpl);
	}

	/**
	 * Prepares the document.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$title = null;

		// Because the application sets a default page title,
		// we need to get it from the menu item itself
		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
		}
		else
		{
			$this->params->def('page_heading',
JText::_('COM_USERS_REGISTRATION'));
		}

		$title = $this->params->get('page_title', '');

		if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE',
$app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title,
$app->get('sitename'));
		}

		$this->document->setTitle($title);

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords',
$this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots',
$this->params->get('robots'));
		}
	}
}
views/remind/tmpl/default.php000064400000002415151165234420012275
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="remind<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form id="user-registration" action="<?php echo
JRoute::_('index.php?option=com_users&task=remind.remind');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (isset($fieldset->label)) : ?>
					<p><?php echo JText::_($fieldset->label); ?></p>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/remind/tmpl/default.xml000064400000000461151165234420012305
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_REMIND_VIEW_DEFAULT_TITLE"
option="COM_USER_REMIND_VIEW_DEFAULT_OPTION">
		<help
			key = "JHELP_MENUS_MENU_ITEM_USER_REMINDER"
		/>
		<message>
			<![CDATA[COM_USER_REMIND_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/remind/view.html.php000064400000005137151165234420011616
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Registration view class for Users.
 *
 * @since  1.5
 */
class UsersViewRemind extends JViewLegacy
{
	protected $form;

	protected $params;

	protected $state;

	/**
	 * Method to display the view.
	 *
	 * @param   string  $tpl  The template file to include
	 *
	 * @return  mixed
	 *
	 * @since   1.5
	 */
	public function display($tpl = null)
	{
		// Get the view data.
		$this->form   = $this->get('Form');
		$this->state  = $this->get('State');
		$this->params = $this->state->params;

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			JError::raiseError(500, implode('<br />', $errors));

			return false;
		}

		// Check for layout override
		$active = JFactory::getApplication()->getMenu()->getActive();

		if (isset($active->query['layout']))
		{
			$this->setLayout($active->query['layout']);
		}

		// Escape strings for HTML output
		$this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

		$this->prepareDocument();

		parent::display($tpl);
	}

	/**
	 * Prepares the document.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$title = null;

		// Because the application sets a default page title,
		// we need to get it from the menu item itself
		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
		}
		else
		{
			$this->params->def('page_heading',
JText::_('COM_USERS_REMIND'));
		}

		$title = $this->params->get('page_title', '');

		if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE',
$app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title,
$app->get('sitename'));
		}

		$this->document->setTitle($title);

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords',
$this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots',
$this->params->get('robots'));
		}
	}
}
views/reset/tmpl/complete.php000064400000002377151165234420012334
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="reset-complete<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_users&task=reset.complete');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (isset($fieldset->label)) : ?>
					<p><?php echo JText::_($fieldset->label); ?></p>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/reset/tmpl/confirm.php000064400000002375151165234420012157
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="reset-confirm<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form action="<?php echo
JRoute::_('index.php?option=com_users&task=reset.confirm');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (isset($fieldset->label)) : ?>
					<p><?php echo JText::_($fieldset->label); ?></p>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/reset/tmpl/default.php000064400000002414151165234420012140
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');

?>
<div class="reset<?php echo $this->pageclass_sfx;
?>">
	<?php if ($this->params->get('show_page_heading')) :
?>
		<div class="page-header">
			<h1>
				<?php echo
$this->escape($this->params->get('page_heading')); ?>
			</h1>
		</div>
	<?php endif; ?>
	<form id="user-registration" action="<?php echo
JRoute::_('index.php?option=com_users&task=reset.request');
?>" method="post" class="form-validate
form-horizontal well">
		<?php foreach ($this->form->getFieldsets() as $fieldset) : ?>
			<fieldset>
				<?php if (isset($fieldset->label)) : ?>
					<p><?php echo JText::_($fieldset->label); ?></p>
				<?php endif; ?>
				<?php echo $this->form->renderFieldset($fieldset->name);
?>
			</fieldset>
		<?php endforeach; ?>
		<div class="control-group">
			<div class="controls">
				<button type="submit" class="btn btn-primary
validate">
					<?php echo JText::_('JSUBMIT'); ?>
				</button>
			</div>
		</div>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/reset/tmpl/default.xml000064400000000462151165234420012152
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USER_RESET_VIEW_DEFAULT_TITLE"
option="COM_USER_RESET_VIEW_DEFAULT_OPTION">
		<help
			key="JHELP_MENUS_MENU_ITEM_USER_PASSWORD_RESET"
		/>
		<message>
			<![CDATA[COM_USER_RESET_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/reset/view.html.php000064400000005402151165234420011455
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Reset view class for Users.
 *
 * @since  1.5
 */
class UsersViewReset extends JViewLegacy
{
	protected $form;

	protected $params;

	protected $state;

	/**
	 * Method to display the view.
	 *
	 * @param   string  $tpl  The template file to include
	 *
	 * @return  mixed
	 *
	 * @since   1.5
	 */
	public function display($tpl = null)
	{
		// This name will be used to get the model
		$name = $this->getLayout();

		// Check that the name is valid - has an associated model.
		if (!in_array($name, array('confirm', 'complete')))
		{
			$name = 'default';
		}

		if ('default' === $name)
		{
			$formname = 'Form';
		}
		else
		{
			$formname = ucfirst($this->_name) . ucfirst($name) .
'Form';
		}

		// Get the view data.
		$this->form   = $this->get($formname);
		$this->state  = $this->get('State');
		$this->params = $this->state->params;

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			JError::raiseError(500, implode('<br />', $errors));

			return false;
		}

		// Escape strings for HTML output
		$this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

		$this->prepareDocument();

		parent::display($tpl);
	}

	/**
	 * Prepares the document.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$title = null;

		// Because the application sets a default page title,
		// we need to get it from the menu item itself
		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
		}
		else
		{
			$this->params->def('page_heading',
JText::_('COM_USERS_RESET'));
		}

		$title = $this->params->get('page_title', '');

		if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE',
$app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title,
$app->get('sitename'));
		}

		$this->document->setTitle($title);

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords',
$this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots',
$this->params->get('robots'));
		}
	}
}
forms/reset_confirm.xml000064400000000666151165506160011271
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_CONFIRM_LABEL">
		<field
			name="username"
			type="text"
			label="COM_USERS_FIELD_RESET_CONFIRM_USERNAME_LABEL"
			filter="username"
			required="true"
			size="30"
		/>

		<field
			name="token"
			type="text"
			label="COM_USERS_FIELD_RESET_CONFIRM_TOKEN_LABEL"
			filter="alnum"
			required="true"
			size="32"
		/>
	</fieldset>
</form>
forms/frontend_admin.xml000064400000001233151165506160011410
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
	<fields name="params">
		<!--  Backend user account settings. -->
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="admin_style"
				type="templatestyle"
				label="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL"
				client="administrator"
				filter="uint"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="admin_language"
				type="language"
				label="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL"
				client="administrator"
				filter="cmd"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>
		</fieldset>
	</fields>
</form>
forms/login.xml000064400000001150151165506160007527 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="credentials"
label="COM_USERS_LOGIN_DEFAULT_LABEL">
		<field
			name="username"
			type="text"
			label="COM_USERS_LOGIN_USERNAME_LABEL"
			class="validate-username"
			filter="username"
			size="25"
			required="true"
			validate="username"
			autofocus="true"
			autocomplete="username"
		/>

		<field
			name="password"
			type="password"
			label="JGLOBAL_PASSWORD"
			required="true"
			filter="raw"
			size="25"
			autocomplete="current-password"
		/>
	</fieldset>

	<fieldset>
		<field
			name="return"
			type="hidden"
		/>
	</fieldset>
</form>
forms/reset_complete.xml000064400000001352151165506160011435
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_COMPLETE_LABEL">
		<field
			name="password1"
			type="password"
			label="COM_USERS_FIELD_RESET_PASSWORD1_LABEL"
			required="true"
			autocomplete="new-password"
			class="validate-password"
			field="password2"
			size="30"
			validate="password"
			strengthmeter="true"
			rules="true"
			force="on"
			filter="raw"
		/>
		<field
			name="password2"
			type="password"
			label="COM_USERS_FIELD_RESET_PASSWORD2_LABEL"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_FIELD_RESET_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
			required="true"
		/>
	</fieldset>
</form>
forms/reset_request.xml000064400000000632151165506160011315
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_RESET_REQUEST_LABEL">
		<field
			name="email"
			type="email"
			label="COM_USERS_FIELD_PASSWORD_RESET_LABEL"
			required="true"
			size="30"
			validate="email"
			autocomplete="email"
		/>

		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			validate="captcha"
		/>
	</fieldset>
</form>
forms/remind.xml000064400000000631151165506160007700 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_REMIND_DEFAULT_LABEL">
		<field
			name="email"
			type="email"
			label="COM_USERS_FIELD_REMIND_EMAIL_LABEL"
			required="true"
			size="30"
			validate="email"
			autocomplete="email"
		/>

		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			validate="captcha"
		/>
	</fieldset>
</form>
forms/registration.xml000064400000003172151165506200011132 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="default"
label="COM_USERS_REGISTRATION_DEFAULT_LABEL">
		<field
			name="spacer"
			type="spacer"
			label="COM_USERS_REGISTER_REQUIRED"
			class="text"
		/>

		<field
			name="name"
			type="text"
			label="COM_USERS_REGISTER_NAME_LABEL"
			filter="string"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="COM_USERS_REGISTER_USERNAME_LABEL"
			class="validate-username"
			filter="username"
			message="COM_USERS_REGISTER_USERNAME_MESSAGE"
			required="true"
			size="30"
			validate="username"
			autocomplete="username"
		/>

		<field
			name="password1"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD1_LABEL"
			required="true"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			size="30"
			validate="password"
			strengthmeter="true"
			rules="true"
			force="on"
			filter="raw"
		/>

		<field
			name="password2"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD2_LABEL"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
			required="true"
		/>

		<field
			name="email1"
			type="email"
			label="COM_USERS_REGISTER_EMAIL1_LABEL"
			field="id"
			filter="string"
			required="true"
			size="30"
			unique="true"
			validate="email"
			validDomains="com_users.domains"
			autocomplete="email"
		/>
	</fieldset>

	<fieldset name="captcha">
		<field
			name="captcha"
			type="captcha"
			label="COM_USERS_CAPTCHA_LABEL"
			validate="captcha"
		/>
	</fieldset>
</form>
forms/profile.xml000064400000002521151165506200010055 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fieldset name="core"
label="COM_USERS_PROFILE_DEFAULT_LABEL">
		<field
			name="id"
			type="hidden"
			filter="integer"
		/>

		<field
			name="name"
			type="text"
			label="COM_USERS_PROFILE_NAME_LABEL"
			filter="string"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="COM_USERS_PROFILE_USERNAME_LABEL"
			class="validate-username"
			filter="username"
			message="COM_USERS_PROFILE_USERNAME_MESSAGE"
			required="true"
			size="30"
			validate="username"
		/>

		<field
			name="password1"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD1_LABEL"
			autocomplete="new-password"
			class="validate-password"
			filter="raw"
			size="30"
			validate="password"
			strengthmeter="true"
			rules="true"
			force="on"
		/>

		<field
			name="password2"
			type="password"
			label="COM_USERS_PROFILE_PASSWORD2_LABEL"
			autocomplete="new-password"
			class="validate-password"
			field="password1"
			filter="raw"
			message="COM_USERS_PROFILE_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
		/>

		<field
			name="email1"
			type="email"
			label="COM_USERS_PROFILE_EMAIL1_LABEL"
			filter="string"
			required="true"
			size="30"
			unique="true"
			validate="email"
			validDomains="com_users.domains"
			autocomplete="email"
		/>

	</fieldset>

</form>
forms/frontend.xml000064400000002373151165506200010241 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fields name="params">
		<!--  Basic user account settings. -->
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="editor"
				type="plugins"
				label="COM_USERS_USER_FIELD_EDITOR_LABEL"
				folder="editors"
				useaccess="true"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="timezone"
				type="timezone"
				label="COM_USERS_USER_FIELD_TIMEZONE_LABEL"
				layout="joomla.form.field.groupedlist-fancy-select"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="language"
				type="language"
				label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
				client="site"
				filter="cmd"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="colorScheme"
				type="list"
				label="COM_USERS_USER_COLORSCHEME_LABEL"
				default=""
				validate="options"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
				<option
value="os">COM_USERS_USER_COLORSCHEME_OPTION_FOLLOW_OS</option>
				<option
value="light">COM_USERS_USER_COLORSCHEME_OPTION_LIGHT</option>
				<option
value="dark">COM_USERS_USER_COLORSCHEME_OPTION_DARK</option>
			</field>
		</fieldset>
	</fields>
</form>
forms/sitelang.xml000064400000000525151165506200010225 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<form>
	<fields name="params">
		<fieldset name="params"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">
			<field
				name="language"
				type="language"
				label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
				client="site"
				filter="cmd"
				default="active"
			/>
		</fieldset>
	</fields>
</form>
tmpl/remind/default.xml000064400000000465151165506200011152
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_REMIND_VIEW_DEFAULT_TITLE"
option="COM_USERS_REMIND_VIEW_DEFAULT_OPTION">
		<help
			key = "Menu_Item:_Username_Reminder_Request"
		/>
		<message>
			<![CDATA[COM_USERS_REMIND_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
tmpl/remind/default.php000064400000003301151165506200011131
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-remind remind">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>
    <form id="user-registration" action="<?php echo
Route::_('index.php?option=com_users&task=remind.remind');
?>" method="post" class="com-users-remind__form
form-validate form-horizontal well">
        <?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
            <fieldset>
                <?php if (isset($fieldset->label)) : ?>
                    <legend><?php echo
Text::_($fieldset->label); ?></legend>
                <?php endif; ?>
                <?php echo
$this->form->renderFieldset($fieldset->name); ?>
            </fieldset>
        <?php endforeach; ?>
        <div class="com-users-remind__submit
control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary validate">
                    <?php echo Text::_('JSUBMIT'); ?>
                </button>
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/reset/complete.php000064400000003313151165506200011164
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-reset-complete reset-complete">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>
    <form action="<?php echo
Route::_('index.php?option=com_users&task=reset.complete');
?>" method="post"
class="com-users-reset-complete__form form-validate form-horizontal
well">
        <?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
            <fieldset>
                <?php if (isset($fieldset->label)) : ?>
                    <legend><?php echo
Text::_($fieldset->label); ?></legend>
                <?php endif; ?>
                <?php echo
$this->form->renderFieldset($fieldset->name); ?>
            </fieldset>
        <?php endforeach; ?>
        <div class="com-users-reset-complete__submit
control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary validate">
                    <?php echo Text::_('JSUBMIT'); ?>
                </button>
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/reset/default.xml000064400000000445151165506200011014 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_RESET_VIEW_DEFAULT_TITLE"
option="COM_USERS_RESET_VIEW_DEFAULT_OPTION">
		<help
			key="Menu_Item:_Password_Reset"
		/>
		<message>
			<![CDATA[COM_USERS_RESET_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
tmpl/reset/confirm.php000064400000003306151165506200011013 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-reset-confirm reset-confirm">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>
    <form action="<?php echo
Route::_('index.php?option=com_users&task=reset.confirm');
?>" method="post"
class="com-users-reset-confirm__form form-validate form-horizontal
well">
        <?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
            <fieldset>
                <?php if (isset($fieldset->label)) : ?>
                    <legend><?php echo
Text::_($fieldset->label); ?></legend>
                <?php endif; ?>
                <?php echo
$this->form->renderFieldset($fieldset->name); ?>
            </fieldset>
        <?php endforeach; ?>
        <div class="com-users-reset-confirm__submit
control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary validate">
                    <?php echo Text::_('JSUBMIT'); ?>
                </button>
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/reset/default.php000064400000003275151165506200011007 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-reset reset">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>
    <form id="user-registration" action="<?php echo
Route::_('index.php?option=com_users&task=reset.request');
?>" method="post" class="com-users-reset__form
form-validate form-horizontal well">
        <?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
            <fieldset>
                <?php if (isset($fieldset->label)) : ?>
                    <legend><?php echo
Text::_($fieldset->label); ?></legend>
                <?php endif; ?>
                <?php echo
$this->form->renderFieldset($fieldset->name); ?>
            </fieldset>
        <?php endforeach; ?>
        <div class="com-users-reset__submit control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary validate">
                    <?php echo Text::_('JSUBMIT'); ?>
                </button>
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/registration/complete.php000064400000001005151165506200012550
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

?>
<div class="com-users-registration-complete
registration-complete">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <h1>
            <?php echo
$this->escape($this->params->get('page_heading')); ?>
        </h1>
    <?php endif; ?>
</div>
tmpl/registration/default.xml000064400000000475151165506210012410
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_REGISTRATION_VIEW_DEFAULT_TITLE"
option="COM_USERS_REGISTRATION_VIEW_DEFAULT_OPTION">
		<help
			key="Menu_Item:_Registration_Form"
		/>
		<message>
			<![CDATA[COM_USERS_REGISTRATION_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
tmpl/registration/default.php000064400000004763151165506210012403
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-registration registration">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1><?php echo
$this->escape($this->params->get('page_heading'));
?></h1>
        </div>
    <?php endif; ?>

    <form id="member-registration" action="<?php echo
Route::_('index.php?option=com_users&task=registration.register');
?>" method="post"
class="com-users-registration__form form-validate"
enctype="multipart/form-data">
        <?php // Iterate through the form fieldsets and display each
one. ?>
        <?php foreach ($this->form->getFieldsets() as $fieldset) :
?>
            <?php if ($fieldset->name === 'captcha'
&& $this->captchaEnabled) : ?>
                <?php continue; ?>
            <?php endif; ?>
            <?php $fields =
$this->form->getFieldset($fieldset->name); ?>
            <?php if (count($fields)) : ?>
                <fieldset>
                    <?php // If the fieldset has a label set, display it
as the legend. ?>
                    <?php if (isset($fieldset->label)) : ?>
                        <legend><?php echo
Text::_($fieldset->label); ?></legend>
                    <?php endif; ?>
                    <?php echo
$this->form->renderFieldset($fieldset->name); ?>
                </fieldset>
            <?php endif; ?>
        <?php endforeach; ?>
        <?php if ($this->captchaEnabled) : ?>
            <?php echo
$this->form->renderFieldset('captcha'); ?>
        <?php endif; ?>
        <div class="com-users-registration__submit
control-group">
            <div class="controls">
                <button type="submit"
class="com-users-registration__register btn btn-primary
validate">
                    <?php echo Text::_('JREGISTER'); ?>
                </button>
                <input type="hidden" name="option"
value="com_users">
                <input type="hidden" name="task"
value="registration.register">
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/login/default.xml000064400000011344151165506210011003 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_LOGIN_VIEW_DEFAULT_TITLE"
option="COM_USERS_LOGIN_VIEW_DEFAULT_OPTION">
		<help
			key = "Menu_Item:_Login_Form"
		/>
		<message>
			<![CDATA[COM_USERS_LOGIN_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>

	<!-- Add fields to the parameters object for the layout. -->
	<fields name="params">

		<!-- Basic options. -->
		<fieldset name="basic"
addruleprefix="Joomla\Component\Users\Site\Rule"
label="COM_MENUS_BASIC_FIELDSET_LABEL">
			<fieldset name="login"
label="COM_USERS_FIELD_OPTIONS_LOGIN">
				<field
					name="loginredirectchoice"
					type="radio"
					label="COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL"
					layout="joomla.form.field.radio.switcher"
					default="1"
					>
					<option
value="0">COM_USERS_FIELD_LOGIN_URL</option>
					<option
value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
				</field>

				<field
					name="login_redirect_url"
					type="text"
					label="JFIELD_LOGIN_REDIRECT_URL_LABEL"
					description="JFIELD_LOGIN_REDIRECT_URL_DESC"
					validate="LoginUniqueField"
					field="login_redirect_menuitem"
					hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
					message="COM_USERS_FIELD_LOGIN_REDIRECT_ERROR"
					showon="loginredirectchoice:0"
				/>

				<field
					name="login_redirect_menuitem"
					type="modal_menu"
					label="COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL"
					description="COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC"
					disable="separator,alias,heading,url"
					showon="loginredirectchoice:1"
					select="true"
					new="true"
					edit="true"
					clear="true"
					>
					<option value="">JOPTION_SELECT_MENU</option>
				</field>

				<field
					name="logindescription_show"
					type="list"
					label="JFIELD_BASIC_LOGIN_DESCRIPTION_SHOW_LABEL"
					default="1"
					class="form-select-color-state"
					validate="options"
					>
					<option value="0">JHIDE</option>
					<option value="1">JSHOW</option>
				</field>

				<field
					name="login_description"
					type="textarea"
					label="JFIELD_BASIC_LOGIN_DESCRIPTION_LABEL"
					rows="3"
					cols="40"
					filter="safehtml"
					showon="logindescription_show:1"
				/>

				<field
					name="login_image"
					type="media"
					schemes="http,https,ftp,ftps,data,file"
					validate="url"
					relative="true"
					label="JFIELD_LOGIN_IMAGE_LABEL"
				/>

				<field
					name="login_image_alt"
					type="text"
					label="COM_USERS_FIELD_IMAGE_ALT_LABEL"
				/>

				<field
					name="login_image_alt_empty"
					type="checkbox"
					label="COM_USERS_FIELD_IMAGE_ALT_EMPTY_LABEL"
					description="COM_USERS_FIELD_IMAGE_ALT_EMPTY_DESC"
				/>
			</fieldset>

			<fieldset name="logout"
label="COM_USERS_FIELD_OPTIONS_LOGOUT">
				<field
					name="logoutredirectchoice"
					type="radio"
					label="COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL"
					layout="joomla.form.field.radio.switcher"
					default="1"
					>
					<option
value="0">COM_USERS_FIELD_LOGIN_URL</option>
					<option
value="1">COM_USERS_FIELD_LOGIN_MENUITEM</option>
				</field>

				<field
					name="logout_redirect_url"
					type="text"
					label="JFIELD_LOGOUT_REDIRECT_URL_LABEL"
					field="logout_redirect_menuitem"
					validate="LogoutUniqueField"
					hint="COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER"
					message="COM_USERS_FIELD_LOGOUT_REDIRECT_ERROR"
					showon="logoutredirectchoice:0"
				/>

				<field
					name="logout_redirect_menuitem"
					type="modal_menu"
					label="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL"
					description="COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC"
					disable="separator,alias,heading,url"
					showon="logoutredirectchoice:1"
					select="true"
					new="true"
					edit="true"
					clear="true"
					>
					<option value="">JOPTION_SELECT_MENU</option>
				</field>

				<field
					name="logoutdescription_show"
					type="list"
					label="JFIELD_BASIC_LOGOUT_DESCRIPTION_SHOW_LABEL"
					default="1"
					class="form-select-color-state"
					validate="options"
					>
					<option value="0">JHIDE</option>
					<option value="1">JSHOW</option>
				</field>

				<field
					name="logout_description"
					type="textarea"
					label="JFIELD_BASIC_LOGOUT_DESCRIPTION_LABEL"
					rows="3"
					cols="40"
					filter="safehtml"
					showon="logoutdescription_show:1"
				/>

				<field
					name="logout_image"
					type="media"
					schemes="http,https,ftp,ftps,data,file"
					validate="url"
					relative="true"
					label="JFIELD_LOGOUT_IMAGE_LABEL"
				/>

				<field
					name="logout_image_alt"
					type="text"
					label="COM_USERS_FIELD_IMAGE_ALT_LABEL"
				/>

				<field
					name="logout_image_alt_empty"
					type="checkbox"
					label="COM_USERS_FIELD_IMAGE_ALT_EMPTY_LABEL"
					description="COM_USERS_FIELD_IMAGE_ALT_EMPTY_DESC"
				/>
			</fieldset>
		</fieldset>
	</fields>
</metadata>
tmpl/login/logout.xml000064400000001755151165506210010675 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_LOGOUT_VIEW_DEFAULT_TITLE"
option="COM_USERS_LOGOUT_VIEW_DEFAULT_OPTION">
		<help key = "Menu_Item:_Logout"/>
		<message>
			<![CDATA[COM_USERS_LOGOUT_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>

	<!-- Add fields to the request variables for the layout. -->
	<fields name="request">
		<fieldset name="request">
			<field
				name="task"
				type="hidden"
				default="user.menulogout"
			/>
		</fieldset>
	</fields>

	<!-- Add fields to the parameters object for the layout. -->
	<fields name="params">
		<fieldset name="basic"
label="COM_MENUS_BASIC_FIELDSET_LABEL">
			<field
				name="logout"
				type="modal_menu"
				label="JFIELD_LOGOUT_REDIRECT_PAGE_LABEL"
				description="JFIELD_LOGOUT_REDIRECT_PAGE_DESC"
				disable="separator,alias,heading,url"
				select="true"
				new="true"
				edit="true"
				clear="true"
				>
				<option value="">JOPTION_SELECT_MENU</option>
			</field>
		</fieldset>
	</fields>
</metadata>
tmpl/login/default_logout.php000064400000005341151165506210012363
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $this */
?>
<div class="com-users-logout logout">
    <?php if ($this->params->get('show_page_heading')) :
?>
    <div class="page-header">
        <h1>
            <?php echo
$this->escape($this->params->get('page_heading')); ?>
        </h1>
    </div>
    <?php endif; ?>

    <?php if
(($this->params->get('logoutdescription_show') == 1
&& str_replace(' ', '',
$this->params->get('logout_description', '')) !=
'') || $this->params->get('logout_image') !=
'') : ?>
        <div class="com-users-logout__description
logout-description">
    <?php endif; ?>

    <?php if
($this->params->get('logoutdescription_show') == 1) : ?>
        <?php echo
$this->params->get('logout_description'); ?>
    <?php endif; ?>

    <?php if ($this->params->get('logout_image') !=
'') : ?>
        <?php echo HTMLHelper::_('image',
$this->params->get('logout_image'),
empty($this->params->get('logout_image_alt')) &&
empty($this->params->get('logout_image_alt_empty')) ? false
: $this->params->get('logout_image_alt'),
['class' => 'com-users-logout__image thumbnail float-end
logout-image']); ?>
    <?php endif; ?>

    <?php if
(($this->params->get('logoutdescription_show') == 1
&& str_replace(' ', '',
$this->params->get('logout_description', '')) !=
'') || $this->params->get('logout_image') !=
'') : ?>
        </div>
    <?php endif; ?>

    <form action="<?php echo
Route::_('index.php?option=com_users&task=user.logout');
?>" method="post" class="com-users-logout__form
form-horizontal well">
        <div class="com-users-logout__submit
control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary">
                    <span class="icon-backward-2 icon-white"
aria-hidden="true"></span>
                    <?php echo Text::_('JLOGOUT'); ?>
                </button>
            </div>
        </div>
        <?php if
($this->params->get('logout_redirect_url')) : ?>
            <input type="hidden" name="return"
value="<?php echo
base64_encode($this->params->get('logout_redirect_url',
$this->form->getValue('return', null, '')));
?>">
        <?php else : ?>
            <input type="hidden" name="return"
value="<?php echo
base64_encode($this->params->get('logout_redirect_menuitem',
$this->form->getValue('return', null, '')));
?>">
        <?php endif; ?>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/login/default_login.php000064400000014133151165506210012161
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;

/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $cookieLogin */

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

$usersConfig = ComponentHelper::getParams('com_users');

?>
<div class="com-users-login login">
    <?php if ($this->params->get('show_page_heading')) :
?>
    <div class="page-header">
        <h1>
            <?php echo
$this->escape($this->params->get('page_heading')); ?>
        </h1>
    </div>
    <?php endif; ?>

    <?php if
(($this->params->get('logindescription_show') == 1
&& str_replace(' ', '',
$this->params->get('login_description', '')) !=
'') || $this->params->get('login_image') !=
'') : ?>
    <div class="com-users-login__description
login-description">
    <?php endif; ?>

        <?php if
($this->params->get('logindescription_show') == 1) : ?>
            <?php echo
$this->params->get('login_description'); ?>
        <?php endif; ?>

        <?php if ($this->params->get('login_image') !=
'') : ?>
            <?php echo HTMLHelper::_('image',
$this->params->get('login_image'),
empty($this->params->get('login_image_alt')) &&
empty($this->params->get('login_image_alt_empty')) ? false
: $this->params->get('login_image_alt'), ['class'
=> 'com-users-login__image login-image']); ?>
        <?php endif; ?>

    <?php if
(($this->params->get('logindescription_show') == 1
&& str_replace(' ', '',
$this->params->get('login_description', '')) !=
'') || $this->params->get('login_image') !=
'') : ?>
    </div>
    <?php endif; ?>

    <form action="<?php echo
Route::_('index.php?option=com_users&task=user.login');
?>" method="post" class="com-users-login__form
form-validate form-horizontal well"
id="com-users-login__form">

        <fieldset>
            <?php echo
$this->form->renderFieldset('credentials',
['class' => 'com-users-login__input']); ?>

            <?php if (PluginHelper::isEnabled('system',
'remember')) : ?>
                <div class="com-users-login__remember">
                    <div class="form-check">
                        <input class="form-check-input"
id="remember" type="checkbox" name="remember"
value="yes">
                        <label class="form-check-label"
for="remember">
                            <?php echo
Text::_('COM_USERS_LOGIN_REMEMBER_ME'); ?>
                        </label>
                    </div>
                </div>
            <?php endif; ?>

            <?php foreach ($this->extraButtons as $button) :
                $dataAttributeKeys = array_filter(array_keys($button),
function ($key) {
                    return substr($key, 0, 5) == 'data-';
                });
                ?>
                <div class="com-users-login__submit
control-group">
                    <div class="controls">
                        <button type="button"
                                class="btn btn-secondary w-100
<?php echo $button['class'] ?? '' ?>"
                                <?php foreach ($dataAttributeKeys as
$key) : ?>
                                    <?php echo $key ?>="<?php
echo $button[$key] ?>"
                                <?php endforeach; ?>
                                <?php if ($button['onclick'])
: ?>
                                onclick="<?php echo
$button['onclick'] ?>"
                                <?php endif; ?>
                                title="<?php echo
Text::_($button['label']) ?>"
                                id="<?php echo
$button['id'] ?>"
                        >
                            <?php if (!empty($button['icon']))
: ?>
                                <span class="<?php echo
$button['icon'] ?>"></span>
                            <?php elseif
(!empty($button['image'])) : ?>
                                <?php echo
HTMLHelper::_('image', $button['image'],
Text::_($button['tooltip'] ?? ''), [
                                    'class' =>
'icon',
                                ], true) ?>
                            <?php elseif
(!empty($button['svg'])) : ?>
                                <?php echo $button['svg'];
?>
                            <?php endif; ?>
                            <?php echo
Text::_($button['label']) ?>
                        </button>
                    </div>
                </div>
            <?php endforeach; ?>

            <div class="com-users-login__submit
control-group">
                <div class="controls">
                    <button type="submit" class="btn
btn-primary">
                        <?php echo Text::_('JLOGIN'); ?>
                    </button>
                </div>
            </div>

            <?php $return =
$this->form->getValue('return', '',
$this->params->get('login_redirect_url',
$this->params->get('login_redirect_menuitem',
''))); ?>
            <input type="hidden" name="return"
value="<?php echo base64_encode($return); ?>">
            <?php echo HTMLHelper::_('form.token'); ?>
        </fieldset>
    </form>
    <div class="com-users-login__options list-group">
        <a class="com-users-login__reset list-group-item"
href="<?php echo
Route::_('index.php?option=com_users&view=reset');
?>">
            <?php echo Text::_('COM_USERS_LOGIN_RESET'); ?>
        </a>
        <a class="com-users-login__remind list-group-item"
href="<?php echo
Route::_('index.php?option=com_users&view=remind');
?>">
            <?php echo Text::_('COM_USERS_LOGIN_REMIND');
?>
        </a>
        <?php if
($usersConfig->get('allowUserRegistration')) : ?>
            <a class="com-users-login__register
list-group-item" href="<?php echo
Route::_('index.php?option=com_users&view=registration');
?>">
                <?php echo
Text::_('COM_USERS_LOGIN_REGISTER'); ?>
            </a>
        <?php endif; ?>
    </div>
</div>
tmpl/login/default.php000064400000001156151165506210010772 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/** @var \Joomla\Component\Users\Site\View\Login\HtmlView $this */

$cookieLogin = $this->user->get('cookieLogin');

if (!empty($cookieLogin) || $this->user->get('guest')) {
    // The user is not logged in or needs to provide a password.
    echo $this->loadTemplate('login');
} else {
    // The user is already logged in.
    echo $this->loadTemplate('logout');
}
tmpl/captive/select.php000064400000005707151165506210011156
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Users\Site\View\Captive\HtmlView;

/** @var HtmlView $this */

$shownMethods = [];

?>
<div id="com-users-select">
    <h2 id="com-users-select-heading">
        <?php echo Text::_('COM_USERS_MFA_SELECT_PAGE_HEAD');
?>
    </h2>
    <div id="com-users-select-information">
        <p>
            <?php echo
Text::_('COM_USERS_LBL_SELECT_INSTRUCTIONS'); ?>
        </p>
    </div>

    <div class="com-users-select-methods p-2">
        <?php foreach ($this->records as $record) :
            if (!array_key_exists($record->method, $this->mfaMethods)
&& ($record->method != 'backupcodes')) {
                continue;
            }

            $allowEntryBatching =
isset($this->mfaMethods[$record->method]) ?
$this->mfaMethods[$record->method]['allowEntryBatching'] :
false;

            if ($this->allowEntryBatching) {
                if ($allowEntryBatching &&
in_array($record->method, $shownMethods)) {
                    continue;
                }
                $shownMethods[] = $record->method;
            }

            $methodName =
$this->getModel()->translateMethodName($record->method);
            ?>
        <a class="com-users-method p-2 border-top border-dark
bg-light d-flex flex-row flex-wrap justify-content-start align-items-center
text-decoration-none gap-2 text-body"
           href="<?php echo
Route::_('index.php?option=com_users&view=captive&record_id='
. $record->id)?>">
            <img src="<?php echo Uri::root() .
$this->getModel()->getMethodImage($record->method) ?>"
                 alt="<?php echo
$this->escape(strip_tags($record->title)) ?>"
                 class="com-users-method-image img-fluid" />
            <?php if (!$this->allowEntryBatching ||
!$allowEntryBatching) : ?>
                <span class="com-users-method-title flex-grow-1
fs-5 fw-bold">
                    <?php if ($record->method ===
'backupcodes') : ?>
                        <?php echo $record->title ?>
                    <?php else : ?>
                        <?php echo $this->escape($record->title)
?>
                    <?php endif; ?>
                </span>
                <small class="com-users-method-name
text-muted">
                    <?php echo $methodName ?>
                </small>
            <?php else : ?>
                <span class="com-users-method-title flex-grow-1
fs-5 fw-bold">
                    <?php echo $methodName ?>
                </span>
                <small class="com-users-method-name
text-muted">
                    <?php echo $methodName ?>
                </small>
            <?php endif; ?>
        </a>
        <?php endforeach; ?>
    </div>
</div>
tmpl/captive/default.php000064400000013010151165506210011305
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Site\Model\CaptiveModel;
use Joomla\Component\Users\Site\View\Captive\HtmlView;
use Joomla\Utilities\ArrayHelper;

/**
 * @var HtmlView     $this  View object
 * @var CaptiveModel $model The model
 */
$model = $this->getModel();

$this->document->getWebAssetManager()
    ->useScript('com_users.two-factor-focus');

?>
<div class="users-mfa-captive card card-body">
    <h2 id="users-mfa-title">
        <?php if (!empty($this->renderOptions['help_url']))
: ?>
            <span class="float-end">
        <a href="<?php echo
$this->renderOptions['help_url'] ?>"
                class="btn btn-sm btn-secondary"
                target="_blank"
        >
            <span class="icon icon-question-sign"
aria-hidden="true"></span>
            <span class="visually-hidden"><?php echo
Text::_('JHELP') ?></span>
        </a>
        </span>
        <?php endif;?>
        <?php if (!empty($this->title)) : ?>
            <?php echo $this->title ?> <small> &ndash;
        <?php endif; ?>
        <?php if (!$this->allowEntryBatching) : ?>
            <?php echo $this->escape($this->record->title)
?>
        <?php else : ?>
            <?php echo
$this->escape($this->getModel()->translateMethodName($this->record->method))
?>
        <?php endif; ?>
        <?php if (!empty($this->title)) : ?>
        </small>
        <?php endif; ?>
    </h2>

    <?php if ($this->renderOptions['pre_message']) : ?>
        <div class="users-mfa-captive-pre-message text-muted
mb-3">
            <?php echo $this->renderOptions['pre_message']
?>
        </div>
    <?php endif; ?>

    <form action="<?php echo
Route::_('index.php?option=com_users&task=captive.validate&record_id='
. ((int) $this->record->id)) ?>"
            id="users-mfa-captive-form"
            method="post"
            class="form-horizontal"
    >
        <?php echo HTMLHelper::_('form.token') ?>

        <div id="users-mfa-captive-form-method-fields">
            <?php if ($this->renderOptions['field_type'] ==
'custom') : ?>
                <?php echo $this->renderOptions['html'];
?>
            <?php endif; ?>
            <div class="row mb-3">
                <?php if ($this->renderOptions['label']) :
?>
                <label for="users-mfa-code"
class="col-sm-3 col-form-label">
                    <?php echo
$this->renderOptions['label'] ?>
                </label>
                <?php endif; ?>
                <div class="col-sm-9 <?php echo
$this->renderOptions['label'] ? '' :
'offset-sm-3' ?>">
                    <?php
                    $attributes = array_merge(
                        [
                            'type'         =>
$this->renderOptions['input_type'],
                            'name'         =>
'code',
                            'value'        => '',
                            'placeholder'  =>
$this->renderOptions['placeholder'] ?? null,
                            'id'           =>
'users-mfa-code',
                            'class'        =>
'form-control',
                            'autocomplete' =>
$this->renderOptions['autocomplete'] ??
'one-time-code'
                        ],
                       
$this->renderOptions['input_attributes']
                    );

                    if (strpos($attributes['class'],
'form-control') === false) {
                        $attributes['class'] .= '
form-control';
                    }
                    ?>
                    <input <?php echo
ArrayHelper::toString($attributes) ?>>
                </div>
            </div>
        </div>

        <div id="users-mfa-captive-form-standard-buttons"
class="row my-3">
            <div class="col-sm-9 offset-sm-3">
                <button class="btn btn-primary me-3 <?php echo
$this->renderOptions['submit_class'] ?>"
                        id="users-mfa-captive-button-submit"
                        style="<?php echo
$this->renderOptions['hide_submit'] ? 'display:
none' : '' ?>"
                        type="submit">
                    <span class="<?php echo
$this->renderOptions['submit_icon'] ?>"
aria-hidden="true"></span>
                    <?php echo
Text::_($this->renderOptions['submit_text']); ?>
                </button>

                <a href="<?php echo
Route::_('index.php?option=com_users&task=user.logout&' .
Factory::getApplication()->getFormToken() . '=1') ?>"
                   class="btn btn-danger btn-sm"
id="users-mfa-captive-button-logout">
                    <span class="icon icon-lock"
aria-hidden="true"></span>
                    <?php echo
Text::_('COM_USERS_MFA_LOGOUT'); ?>
                </a>

                <?php if (count($this->records) > 1) : ?>
                    <div
id="users-mfa-captive-form-choose-another"
class="my-3">
                        <a href="<?php echo
Route::_('index.php?option=com_users&view=captive&task=select')
?>">
                            <?php echo
Text::_('COM_USERS_MFA_USE_DIFFERENT_METHOD'); ?>
                        </a>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    </form>

    <?php if ($this->renderOptions['post_message']) : ?>
        <div class="users-mfa-captive-post-message">
            <?php echo $this->renderOptions['post_message']
?>
        </div>
    <?php endif; ?>

</div>
tmpl/method/edit.php000064400000017263151165506210010451 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Site\View\Method\HtmlView;
use Joomla\Utilities\ArrayHelper;

/** @var  HtmlView  $this */

$cancelURL =
Route::_('index.php?option=com_users&task=methods.display&user_id='
. $this->user->id);

if (!empty($this->returnURL)) {
    $cancelURL = $this->escape(base64_decode($this->returnURL));
}

$recordId     = (int) $this->record->id ?? 0;
$method       = $this->record->method ??
$this->getModel()->getState('method');
$userId       = (int) $this->user->id ?? 0;
$headingLevel = 2;
$hideSubmit   = !$this->renderOptions['show_submit']
&& !$this->isEditExisting
?>
<div class="card card-body">
    <form action="<?php echo
Route::_(sprintf("index.php?option=com_users&task=method.save&id=%d&method=%s&user_id=%d",
$recordId, $method, $userId)) ?>"
          class="form form-horizontal"
id="com-users-method-edit" method="post">
        <?php echo HTMLHelper::_('form.token') ?>
        <?php if (!empty($this->returnURL)) : ?>
        <input type="hidden" name="returnurl"
value="<?php echo $this->escape($this->returnURL)
?>">
        <?php endif; ?>

        <?php if
(!empty($this->renderOptions['hidden_data'])) : ?>
            <?php foreach
($this->renderOptions['hidden_data'] as $key => $value) :
?>
        <input type="hidden" name="<?php echo
$this->escape($key) ?>" value="<?php echo
$this->escape($value) ?>">
            <?php endforeach; ?>
        <?php endif; ?>

        <?php if (!empty($this->title)) : ?>
            <?php if
(!empty($this->renderOptions['help_url'])) : ?>
            <span class="float-end">
                <a href="<?php echo
$this->renderOptions['help_url'] ?>"
                   class="btn btn-sm btn-dark"
                   target="_blank"
                >
                    <span class="icon icon-question-sign"
aria-hidden="true"></span>
                    <span class="visually-hidden"><?php
echo Text::_('JHELP') ?></span>
                </a>
            </span>
            <?php endif;?>
            <h<?php echo $headingLevel ?>
id="com-users-method-edit-head">
                <?php echo Text::_($this->title) ?>
            </h<?php echo $headingLevel ?>>
            <?php $headingLevel++ ?>
        <?php endif; ?>

        <div class="row">
            <label class="col-sm-3 col-form-label"
                for="com-users-method-edit-title">
                <?php echo
Text::_('COM_USERS_MFA_EDIT_FIELD_TITLE'); ?>
            </label>
            <div class="col-sm-9">
                <input type="text"
                        class="form-control"
                        id="com-users-method-edit-title"
                        name="title"
                        value="<?php echo
$this->escape($this->record->title) ?>"
                       
aria-describedby="com-users-method-edit-help">
                <p class="form-text"
id="com-users-method-edit-help">
                    <?php echo
$this->escape(Text::_('COM_USERS_MFA_EDIT_FIELD_TITLE_DESC'))
?>
                </p>
            </div>
        </div>

        <div class="row">
            <div class="col-sm-9 offset-sm-3">
                <div class="form-check">
                    <input class="form-check-input"
type="checkbox" id="com-users-is-default-method"
<?php echo $this->record->default ?
'checked="checked"' : ''; ?>
name="default">
                    <label class="form-check-label"
for="com-users-is-default-method">
                        <?php echo
Text::_('COM_USERS_MFA_EDIT_FIELD_DEFAULT'); ?>
                    </label>
                </div>
            </div>
        </div>

        <?php if
(!empty($this->renderOptions['pre_message'])) : ?>
        <div class="com-users-method-edit-pre-message text-muted
mt-4 mb-3">
            <?php echo $this->renderOptions['pre_message']
?>
        </div>
        <?php endif; ?>

        <?php if
(!empty($this->renderOptions['tabular_data'])) : ?>
        <div
class="com-users-method-edit-tabular-container">
            <?php if
(!empty($this->renderOptions['table_heading'])) : ?>
                <h<?php echo $headingLevel ?> class="h3
border-bottom mb-3">
                    <?php echo
$this->renderOptions['table_heading'] ?>
                </h<?php echo $headingLevel ?>>
            <?php endif; ?>
            <table class="table table-striped">
                <tbody>
                <?php foreach
($this->renderOptions['tabular_data'] as $cell1 => $cell2)
: ?>
                <tr>
                    <td>
                        <?php echo $cell1 ?>
                    </td>
                    <td>
                        <?php echo $cell2 ?>
                    </td>
                </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <?php endif; ?>

        <?php if ($this->renderOptions['field_type'] ==
'custom') : ?>
            <?php echo $this->renderOptions['html']; ?>
        <?php endif; ?>
        <div class="row mb-3 <?php echo
$this->renderOptions['input_type'] === 'hidden' ?
'd-none' : '' ?>">
            <?php if ($this->renderOptions['label']) :
?>
            <label class="col-sm-3 col-form-label"
for="com-users-method-code">
                <?php echo $this->renderOptions['label'];
?>
            </label>
            <?php endif; ?>
            <div class="col-sm-9" <?php echo
$this->renderOptions['label'] ? '' :
'offset-sm-3' ?>>
                <?php
                $attributes = array_merge(
                    [
                        'type'             =>
$this->renderOptions['input_type'],
                        'name'             =>
'code',
                        'value'            =>
$this->escape($this->renderOptions['input_value']),
                        'id'               =>
'com-users-method-code',
                        'class'            =>
'form-control',
                        'aria-describedby' =>
'com-users-method-code-help',
                    ],
                    $this->renderOptions['input_attributes']
                );

                if (strpos($attributes['class'],
'form-control') === false) {
                    $attributes['class'] .= '
form-control';
                }
                ?>
                <input <?php echo ArrayHelper::toString($attributes)
?>>

                <p class="form-text"
id="com-users-method-code-help">
                    <?php echo
$this->escape($this->renderOptions['placeholder']) ?>
                </p>
            </div>
        </div>

        <div class="row mb-3">
            <div class="col-sm-9 offset-sm-3">
                <button type="submit" class="btn
btn-primary me-3 <?php echo $hideSubmit ? 'd-none' :
'' ?> <?php echo
$this->renderOptions['submit_class'] ?>">
                    <span class="<?php echo
$this->renderOptions['submit_icon'] ?>"
aria-hidden="true"></span>
                    <?php echo
Text::_($this->renderOptions['submit_text']); ?>
                </button>

                <a href="<?php echo $cancelURL ?>"
                   class="btn btn-sm btn-danger">
                    <span class="icon icon-cancel-2"
aria-hidden="true"></span>
                    <?php echo Text::_('JCANCEL'); ?>
                </a>
            </div>
        </div>

        <?php if
(!empty($this->renderOptions['post_message'])) : ?>
            <div class="com-users-method-edit-post-message
text-muted">
                <?php echo
$this->renderOptions['post_message'] ?>
            </div>
        <?php endif; ?>
    </form>
</div>
tmpl/method/backupcodes.php000064400000004751151165506210012005
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Site\View\Method\HtmlView;

/** @var  HtmlView $this */

HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');

$cancelURL =
Route::_('index.php?option=com_users&task=methods.display&user_id='
. $this->user->id);

if (!empty($this->returnURL)) {
    $cancelURL = $this->escape(base64_decode($this->returnURL));
}

if ($this->record->method != 'backupcodes') {
    throw new RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'),
403);
}

?>
<h2>
    <?php echo Text::_('COM_USERS_USER_BACKUPCODES') ?>
</h2>

<div class="alert alert-info">
    <?php echo Text::_('COM_USERS_USER_BACKUPCODES_DESC')
?>
</div>

<table class="table table-striped">
    <?php for ($i = 0; $i < (count($this->backupCodes) / 2); $i++)
: ?>
        <tr>
            <td>
                <?php if (!empty($this->backupCodes[2 * $i])) : ?>
                    <?php // This is a Key emoji; we can hide it from
screen readers ?>
                    <span
aria-hidden="true">&#128273;</span>
                    <?php echo $this->backupCodes[2 * $i] ?>
                <?php endif; ?>
            </td>
            <td>
                <?php if (!empty($this->backupCodes[1 + 2 * $i])) :
?>
                    <?php // This is a Key emoji; we can hide it from
screen readers ?>
                    <span
aria-hidden="true">&#128273;</span>
                    <?php echo $this->backupCodes[1 + 2 * $i] ?>
                <?php endif ;?>
            </td>
        </tr>
    <?php endfor; ?>
</table>

<p>
    <?php echo
Text::_('COM_USERS_MFA_BACKUPCODES_RESET_INFO'); ?>
</p>

<a class="btn btn-danger" href="<?php echo
Route::_(sprintf("index.php?option=com_users&task=method.regenerateBackupCodes&user_id=%s&%s=1%s",
$this->user->id, Factory::getApplication()->getFormToken(),
empty($this->returnURL) ? '' : '&returnurl=' .
$this->returnURL)) ?>">
    <span class="icon icon-refresh"
aria-hidden="true"></span>
    <?php echo Text::_('COM_USERS_MFA_BACKUPCODES_RESET');
?>
</a>

<a href="<?php echo $cancelURL ?>"
   class="btn btn-secondary">
    <span class="icon icon-cancel-2
icon-ban-circle"></span>
    <?php echo Text::_('JCANCEL'); ?>
</a>
tmpl/profile/edit.xml000064400000000460151165506210010631 0ustar00<?xml
version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_PROFILE_EDIT_DEFAULT_TITLE"
option="COM_USERS_PROFILE_EDIT_DEFAULT_OPTION">
		<help
			key = "Menu_Item:_Edit_User_Profile"
		/>
		<message>
			<![CDATA[COM_USERS_PROFILE_EDIT_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
tmpl/profile/default_params.php000064400000003255151165506210012667
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

?>
<?php $fields = $this->form->getFieldset('params');
?>
<?php if (count($fields)) : ?>
    <fieldset id="users-profile-custom"
class="com-users-profile__params">
        <legend><?php echo
Text::_('COM_USERS_SETTINGS_FIELDSET_LABEL');
?></legend>
        <dl class="dl-horizontal">
            <?php foreach ($fields as $field) : ?>
                <?php if (!$field->hidden) : ?>
                    <dt>
                        <?php echo $field->title; ?>
                    </dt>
                    <dd>
                        <?php if
(HTMLHelper::isRegistered('users.' . $field->id)) : ?>
                            <?php echo HTMLHelper::_('users.'
. $field->id, $field->value); ?>
                        <?php elseif
(HTMLHelper::isRegistered('users.' . $field->fieldname)) :
?>
                            <?php echo HTMLHelper::_('users.'
. $field->fieldname, $field->value); ?>
                        <?php elseif
(HTMLHelper::isRegistered('users.' . $field->type)) : ?>
                            <?php echo HTMLHelper::_('users.'
. $field->type, $field->value); ?>
                        <?php else : ?>
                            <?php echo
HTMLHelper::_('users.value', $field->value); ?>
                        <?php endif; ?>
                    </dd>
                <?php endif; ?>
            <?php endforeach; ?>
        </dl>
    </fieldset>
<?php endif; ?>
tmpl/profile/edit.php000064400000007015151165506210010623 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

/** @var Joomla\Component\Users\Site\View\Profile\HtmlView $this */

HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');

// Load user_profile plugin language
$lang = $this->getLanguage();
$lang->load('plg_user_profile', JPATH_ADMINISTRATOR);

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
    ->useScript('form.validate');

?>
<div class="com-users-profile__edit profile-edit">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>

    <form id="member-profile" action="<?php echo
Route::_('index.php?option=com_users'); ?>"
method="post" class="com-users-profile__edit-form
form-validate form-horizontal well"
enctype="multipart/form-data">
        <?php // Iterate through the form fieldsets and display each
one. ?>
        <?php foreach ($this->form->getFieldsets() as $group =>
$fieldset) : ?>
            <?php $fields = $this->form->getFieldset($group);
?>
            <?php if (count($fields)) : ?>
                <fieldset>
                    <?php // If the fieldset has a label set, display it
as the legend. ?>
                    <?php if (isset($fieldset->label)) : ?>
                        <legend>
                            <?php echo Text::_($fieldset->label);
?>
                        </legend>
                    <?php endif; ?>
                    <?php if (isset($fieldset->description)
&& trim($fieldset->description)) : ?>
                        <p>
                            <?php echo
$this->escape(Text::_($fieldset->description)); ?>
                        </p>
                    <?php endif; ?>
                    <?php // Iterate through the fields in the set and
display them. ?>
                    <?php foreach ($fields as $field) : ?>
                        <?php echo $field->renderField(); ?>
                    <?php endforeach; ?>
                </fieldset>
            <?php endif; ?>
        <?php endforeach; ?>

        <?php if ($this->mfaConfigurationUI) : ?>
            <fieldset
class="com-users-profile__multifactor">
                <legend><?php echo
Text::_('COM_USERS_PROFILE_MULTIFACTOR_AUTH');
?></legend>
                <?php echo $this->mfaConfigurationUI ?>
            </fieldset>
        <?php endif; ?>

        <div class="com-users-profile__edit-submit
control-group">
            <div class="controls">
                <button type="submit" class="btn
btn-primary validate" name="task"
value="profile.save">
                    <span class="icon-check"
aria-hidden="true"></span>
                    <?php echo Text::_('JSAVE'); ?>
                </button>
                <button type="submit" class="btn
btn-danger" name="task" value="profile.cancel"
formnovalidate>
                    <span class="icon-times"
aria-hidden="true"></span>
                    <?php echo Text::_('JCANCEL'); ?>
                </button>
                <input type="hidden" name="option"
value="com_users">
            </div>
        </div>
        <?php echo HTMLHelper::_('form.token'); ?>
    </form>
</div>
tmpl/profile/default.xml000064400000000453151165506210011332
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_USERS_PROFILE_VIEW_DEFAULT_TITLE"
option="COM_USERS_PROFILE_VIEW_DEFAULT_OPTION">
		<help
			key = "Menu_Item:_User_Profile"
		/>
		<message>
			<![CDATA[COM_USERS_PROFILE_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
tmpl/profile/default_core.php000064400000003106151165506210012327
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

?>
<fieldset id="users-profile-core"
class="com-users-profile__core">
    <legend>
        <?php echo Text::_('COM_USERS_PROFILE_CORE_LEGEND');
?>
    </legend>
    <dl class="dl-horizontal">
        <dt>
            <?php echo
Text::_('COM_USERS_PROFILE_NAME_LABEL'); ?>
        </dt>
        <dd>
            <?php echo $this->escape($this->data->name); ?>
        </dd>
        <dt>
            <?php echo
Text::_('COM_USERS_PROFILE_USERNAME_LABEL'); ?>
        </dt>
        <dd>
            <?php echo $this->escape($this->data->username);
?>
        </dd>
        <dt>
            <?php echo
Text::_('COM_USERS_PROFILE_REGISTERED_DATE_LABEL'); ?>
        </dt>
        <dd>
            <?php echo HTMLHelper::_('date',
$this->data->registerDate, Text::_('DATE_FORMAT_LC1'));
?>
        </dd>
        <dt>
            <?php echo
Text::_('COM_USERS_PROFILE_LAST_VISITED_DATE_LABEL'); ?>
        </dt>
        <?php if ($this->data->lastvisitDate !== null) : ?>
            <dd>
                <?php echo HTMLHelper::_('date',
$this->data->lastvisitDate, Text::_('DATE_FORMAT_LC1'));
?>
            </dd>
        <?php else : ?>
            <dd>
                <?php echo
Text::_('COM_USERS_PROFILE_NEVER_VISITED'); ?>
            </dd>
        <?php endif; ?>
    </dl>
</fieldset>
tmpl/profile/default_custom.php000064400000006355151165506210012722
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

$fieldsets = $this->form->getFieldsets();

if (isset($fieldsets['core'])) {
    unset($fieldsets['core']);
}

if (isset($fieldsets['params'])) {
    unset($fieldsets['params']);
}

$tmp          = $this->data->jcfields ?? [];
$customFields = [];

foreach ($tmp as $customField) {
    $customFields[$customField->name] = $customField;
}

unset($tmp);

?>
<?php foreach ($fieldsets as $group => $fieldset) : ?>
    <?php $fields = $this->form->getFieldset($group); ?>
    <?php if (count($fields)) : ?>
        <fieldset id="users-profile-custom-<?php echo $group;
?>" class="com-users-profile__custom
users-profile-custom-<?php echo $group; ?>">
            <?php if (isset($fieldset->label) && ($legend =
trim(Text::_($fieldset->label))) !== '') : ?>
                <legend><?php echo $legend; ?></legend>
            <?php endif; ?>
            <?php if (isset($fieldset->description) &&
trim($fieldset->description)) : ?>
                <p><?php echo
$this->escape(Text::_($fieldset->description)); ?></p>
            <?php endif; ?>
            <dl class="dl-horizontal">
                <?php foreach ($fields as $field) : ?>
                    <?php // Correct the field name so that subform
custom fields show up. ?>
                    <?php if ($field->type === 'Subform'
&& $field->fieldname === 'row') : ?>
                        <?php
preg_match("/jform\[com_fields]\[(.*)]/", $field->name,
$matches); ?>
                        <?php $field->fieldname = $matches[1]; ?>
                    <?php endif; ?>
                    <?php if (!$field->hidden &&
$field->type !== 'Spacer') : ?>
                        <dt>
                            <?php echo $field->title; ?>
                        </dt>
                        <dd>
                            <?php if
(array_key_exists($field->fieldname, $customFields)) : ?>
                                <?php echo
strlen($customFields[$field->fieldname]->value) ?
$customFields[$field->fieldname]->value :
Text::_('COM_USERS_PROFILE_VALUE_NOT_FOUND'); ?>
                            <?php elseif
(HTMLHelper::isRegistered('users.' . $field->id)) : ?>
                                <?php echo
HTMLHelper::_('users.' . $field->id, $field->value); ?>
                            <?php elseif
(HTMLHelper::isRegistered('users.' . $field->fieldname)) :
?>
                                <?php echo
HTMLHelper::_('users.' . $field->fieldname, $field->value);
?>
                            <?php elseif
(HTMLHelper::isRegistered('users.' . $field->type)) : ?>
                                <?php echo
HTMLHelper::_('users.' . $field->type, $field->value);
?>
                            <?php else : ?>
                                <?php echo
HTMLHelper::_('users.value', $field->value); ?>
                            <?php endif; ?>
                        </dd>
                    <?php endif; ?>
                <?php endforeach; ?>
            </dl>
        </fieldset>
    <?php endif; ?>
<?php endforeach; ?>
tmpl/profile/default.php000064400000002400151165506210011313
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;

?>
<div class="com-users-profile profile">
    <?php if ($this->params->get('show_page_heading')) :
?>
        <div class="page-header">
            <h1>
                <?php echo
$this->escape($this->params->get('page_heading')); ?>
            </h1>
        </div>
    <?php endif; ?>

    <?php if ($this->getCurrentUser()->id ==
$this->data->id) : ?>
        <ul class="com-users-profile__edit btn-toolbar
float-end">
            <li class="btn-group">
                <a class="btn btn-primary" href="<?php
echo
Route::_('index.php?option=com_users&task=profile.edit&user_id='
. (int) $this->data->id); ?>">
                    <span class="icon-user-edit"
aria-hidden="true"></span> <?php echo
Text::_('COM_USERS_EDIT_PROFILE'); ?>
                </a>
            </li>
        </ul>
    <?php endif; ?>

    <?php echo $this->loadTemplate('core'); ?>
    <?php echo $this->loadTemplate('params'); ?>
    <?php echo $this->loadTemplate('custom'); ?>
</div>
tmpl/methods/list.php000064400000022626151165506210010661 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Users\Administrator\Helper\Mfa as MfaHelper;
use Joomla\Component\Users\Site\Model\MethodsModel;
use Joomla\Component\Users\Site\View\Methods\HtmlView;

/** @var HtmlView $this */

/** @var MethodsModel $model */
$model = $this->getModel();

$this->document->getWebAssetManager()->useScript('com_users.two-factor-list');

HTMLHelper::_('bootstrap.tooltip', '.hasTooltip');

$canAddEdit = MfaHelper::canAddEditMethod($this->user);
$canDelete  = MfaHelper::canDeleteMethod($this->user);
?>
<div id="com-users-methods-list-container">
    <?php foreach ($this->methods as $methodName => $method) :
        $methodClass = 'com-users-methods-list-method-name-' .
htmlentities($method['name'])
            . ($this->defaultMethod == $methodName ? '
com-users-methods-list-method-default' : '');
        ?>
        <div class="com-users-methods-list-method <?php echo
$methodClass?> mx-1 my-3 card <?php echo
count($method['active']) ? 'border-secondary' :
'' ?>">
            <div class="com-users-methods-list-method-header
card-header <?php echo count($method['active']) ?
'border-secondary bg-secondary text-white' : '' ?>
d-flex flex-wrap align-items-center gap-2">
                <div class="com-users-methods-list-method-image
pt-1 px-3 pb-2 bg-light rounded-2">
                    <img src="<?php echo Uri::root() .
$method['image'] ?>"
                         alt="<?php echo
$this->escape($method['display']) ?>"
                         class="img-fluid"
                    >
                </div>
                <div class="com-users-methods-list-method-title
flex-grow-1 d-flex flex-column">
                    <h2 class="h4 p-0 m-0 d-flex gap-3
align-items-center">
                        <span class="me-1 flex-grow-1">
                            <?php echo $method['display']
?>
                        </span>
                        <?php if ($this->defaultMethod ==
$methodName) : ?>
                            <span
id="com-users-methods-list-method-default-tag" class="badge
bg-info me-1 fs-6">
                                <?php echo
Text::_('COM_USERS_MFA_LIST_DEFAULTTAG') ?>
                            </span>
                        <?php endif; ?>
                    </h2>
                </div>
            </div>

            <div
class="com-users-methods-list-method-records-container
card-body">
                <div class="com-users-methods-list-method-info my-1
pb-1 small text-muted">
                    <?php echo $method['shortinfo'] ?>
                </div>

                <?php if (count($method['active'])) : ?>
                    <div
class="com-users-methods-list-method-records pt-2 my-2">
                        <?php foreach ($method['active'] as
$record) : ?>
                            <div
class="com-users-methods-list-method-record d-flex flex-row flex-wrap
justify-content-start border-top py-2">
                                <div
class="com-users-methods-list-method-record-info flex-grow-1 d-flex
flex-column align-items-start gap-1">
                                    <?php if ($methodName ===
'backupcodes' && $canAddEdit) : ?>
                                        <div class="alert
alert-info mt-1 w-100">
                                            <?php echo
Text::sprintf('COM_USERS_MFA_BACKUPCODES_PRINT_PROMPT_HEAD',
Route::_('index.php?option=com_users&task=method.edit&id='
. (int) $record->id . ($this->returnURL ? '&returnurl='
. $this->escape(urlencode($this->returnURL)) : '') .
'&user_id=' . $this->user->id),
'text-decoration-underline') ?>
                                        </div>
                                    <?php else : ?>
                                        <h3
class="com-users-methods-list-method-record-title-container mb-1
fs-5">
                                            <?php if
($record->default) : ?>
                                                <span
id="com-users-methods-list-method-default-badge-small"
                                                     
class="text-warning me-1 hasTooltip"
                                                      title="<?php
echo $this->escape(Text::_('COM_USERS_MFA_LIST_DEFAULTTAG'))
?>">
                                                    <span
class="icon icon-star"
aria-hidden="true"></span>
                                                    <span
class="visually-hidden"><?php echo
$this->escape(Text::_('COM_USERS_MFA_LIST_DEFAULTTAG'))
?></span>
                                                </span>
                                            <?php endif; ?>
                                            <span
class="com-users-methods-list-method-record-title fw-bold">
                                                <?php echo
$this->escape($record->title); ?>
                                            </span>
                                        </h3>
                                    <?php endif; ?>

                                    <div
class="com-users-methods-list-method-record-lastused my-1 d-flex
flex-row flex-wrap justify-content-start gap-5 text-muted small
w-100">
                                        <span
class="com-users-methods-list-method-record-createdon">
                                            <?php echo
Text::sprintf('COM_USERS_MFA_LBL_CREATEDON',
$model->formatRelative($record->created_on)) ?>
                                        </span>
                                        <span
class="com-users-methods-list-method-record-lastused-date">
                                            <?php echo
Text::sprintf('COM_USERS_MFA_LBL_LASTUSED',
$model->formatRelative($record->last_used)) ?>
                                        </span>
                                    </div>

                                </div>

                                <?php if ($methodName !==
'backupcodes' && ($canAddEdit || $canDelete)) : ?>
                                <div
class="com-users-methods-list-method-record-actions my-2 d-flex
flex-row flex-wrap justify-content-center align-content-center
align-items-start">
                                    <?php if ($canAddEdit) : ?>
                                    <a
class="com-users-methods-list-method-record-edit btn btn-secondary
btn-sm mx-1 hasTooltip"
                                       href="<?php echo
Route::_('index.php?option=com_users&task=method.edit&id='
. (int) $record->id . ($this->returnURL ? '&returnurl='
. $this->escape(urlencode($this->returnURL)) : '') .
'&user_id=' . $this->user->id)?>"
                                       title="<?php echo
Text::_('JACTION_EDIT') ?> <?php echo
$this->escape($record->title); ?>">
                                        <span class="icon
icon-pencil" aria-hidden="true"></span>
                                        <span
class="visually-hidden"><?php echo
Text::_('JACTION_EDIT') ?> <?php echo
$this->escape($record->title); ?></span>
                                    </a>
                                    <?php endif ?>

                                    <?php if
($method['canDisable'] && $canDelete) : ?>
                                    <a
class="com-users-methods-list-method-record-delete btn btn-danger
btn-sm mx-1 hasTooltip"
                                       href="<?php echo
Route::_('index.php?option=com_users&task=method.delete&id='
. (int) $record->id . ($this->returnURL ? '&returnurl='
. $this->escape(urlencode($this->returnURL)) : '') .
'&user_id=' . $this->user->id . '&' .
Factory::getApplication()->getFormToken() . '=1')?>"
                                       title="<?php echo
Text::_('JACTION_DELETE') ?> <?php echo
$this->escape($record->title); ?>">
                                        <span class="icon
icon-trash" aria-hidden="true"></span>
                                        <span
class="visually-hidden"><?php echo
Text::_('JACTION_DELETE') ?> <?php echo
$this->escape($record->title); ?></span>
                                    </a>
                                    <?php endif; ?>
                                </div>
                                <?php endif; ?>
                            </div>
                        <?php endforeach; ?>
                    </div>
                <?php endif; ?>

                <?php if ($canAddEdit &&
(empty($method['active']) || $method['allowMultiple']))
: ?>
                    <div
class="com-users-methods-list-method-addnew-container border-top
pt-2">
                        <a href="<?php echo
Route::_('index.php?option=com_users&task=method.add&method='
. $this->escape(urlencode($method['name'])) .
($this->returnURL ? '&returnurl=' .
$this->escape(urlencode($this->returnURL)) : '') .
'&user_id=' . $this->user->id)?>"
                           class="com-users-methods-list-method-addnew
btn btn-outline-primary btn-sm"
                        >
                            <span class="icon-plus-2"
aria-hidden="true"></span>
                            <?php echo
Text::sprintf('COM_USERS_MFA_ADD_AUTHENTICATOR_OF_TYPE',
$method['display']) ?>
                        </a>
                    </div>
                <?php endif; ?>
            </div>
        </div>
    <?php endforeach; ?>
</div>
tmpl/methods/firsttime.php000064400000003327151165506210011711
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Site\View\Methods\HtmlView;

/** @var HtmlView $this */

$headingLevel = 2;
?>
<div id="com-users-methods-list">
    <?php if (!$this->isAdmin) : ?>
        <h<?php echo $headingLevel ?>
id="com-users-methods-list-head">
            <?php echo
Text::_('COM_USERS_MFA_FIRSTTIME_PAGE_HEAD'); ?>
        </h<?php echo $headingLevel++ ?>>
    <?php endif; ?>
    <div id="com-users-methods-list-instructions"
class="alert alert-info">
        <h<?php echo $headingLevel ?>
class="alert-heading">
            <span class="fa fa-shield-alt"
aria-hidden="true"></span>
            <?php echo
Text::_('COM_USERS_MFA_FIRSTTIME_INSTRUCTIONS_HEAD'); ?>
        </h<?php echo $headingLevel ?>>
        <p>
            <?php echo
Text::_('COM_USERS_MFA_FIRSTTIME_INSTRUCTIONS_WHATITDOES'); ?>
        </p>
        <a href="<?php echo Route::_(
           
'index.php?option=com_users&task=methods.doNotShowThisAgain'
.
                ($this->returnURL ? '&returnurl=' .
$this->escape(urlencode($this->returnURL)) : '') .
                '&user_id=' . $this->user->id .
                '&' .
Factory::getApplication()->getFormToken() . '=1'
        )?>"
           class="btn btn-danger w-100">
            <?php echo
Text::_('COM_USERS_MFA_FIRSTTIME_NOTINTERESTED'); ?>
        </a>
    </div>

    <?php $this->setLayout('list');
    echo $this->loadTemplate(); ?>
</div>
tmpl/methods/default.php000064400000004323151165506210011324
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

// Prevent direct access
defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Site\View\Methods\HtmlView;

/** @var HtmlView $this */
?>
<div id="com-users-methods-list">
    <?php if (!$this->get('forHMVC', false)) : ?>
        <h2 id="com-users-methods-list-head">
            <?php echo
Text::_('COM_USERS_MFA_LIST_PAGE_HEAD'); ?>
        </h2>
    <?php endif ?>

    <div id="com-users-methods-reset-container"
class="d-flex align-items-center border border-1 rounded-3 p-2
bg-light">
        <div id="com-users-methods-reset-message"
class="flex-grow-1">
            <?php echo Text::_('COM_USERS_MFA_LIST_STATUS_' .
($this->mfaActive ? 'ON' : 'OFF')) ?>
        </div>
        <?php if ($this->mfaActive) : ?>
            <div>
                <a href="<?php echo
Route::_('index.php?option=com_users&task=methods.disable&'
. Factory::getApplication()->getFormToken() . '=1' .
($this->returnURL ? '&returnurl=' .
$this->escape(urlencode($this->returnURL)) : '') .
'&user_id=' . $this->user->id) ?>"
                   class="btn btn-danger btn-sm">
                    <?php echo
Text::_('COM_USERS_MFA_LIST_REMOVEALL'); ?>
                </a>
            </div>
        <?php endif; ?>
    </div>

    <?php if (!count($this->methods)) : ?>
        <div id="com-users-methods-list-instructions"
class="alert alert-info mt-2">
            <span class="icon icon-info-circle"
aria-hidden="true"></span>
            <?php echo
Text::_('COM_USERS_MFA_LIST_INSTRUCTIONS'); ?>
        </div>
    <?php elseif ($this->isMandatoryMFASetup) : ?>
        <div class="alert alert-info my-3">
            <h3 class="alert-heading">
                <?php echo
Text::_('COM_USERS_MFA_MANDATORY_NOTICE_HEAD') ?>
            </h3>
            <p>
                <?php echo
Text::_('COM_USERS_MFA_MANDATORY_NOTICE_BODY') ?>
            </p>
        </div>
    <?php endif ?>

    <?php $this->setLayout('list');
    echo $this->loadTemplate(); ?>
</div>
src/Service/Router.php000064400000005154151165506210010733 0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Service;

use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Component\Router\RouterView;
use Joomla\CMS\Component\Router\RouterViewConfiguration;
use Joomla\CMS\Component\Router\Rules\MenuRules;
use Joomla\CMS\Component\Router\Rules\NomenuRules;
use Joomla\CMS\Component\Router\Rules\StandardRules;
use Joomla\CMS\Menu\AbstractMenu;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Routing class from com_users
 *
 * @since  3.2
 */
class Router extends RouterView
{
    /**
     * Users Component router constructor
     *
     * @param   SiteApplication  $app   The application object
     * @param   AbstractMenu     $menu  The menu object to work with
     */
    public function __construct(SiteApplication $app, AbstractMenu $menu)
    {
        $this->registerView(new
RouterViewConfiguration('login'));
        $profile = new RouterViewConfiguration('profile');
        $profile->addLayout('edit');
        $this->registerView($profile);
        $this->registerView(new
RouterViewConfiguration('registration'));
        $this->registerView(new
RouterViewConfiguration('remind'));
        $this->registerView(new
RouterViewConfiguration('reset'));
        $this->registerView(new
RouterViewConfiguration('callback'));
        $this->registerView(new
RouterViewConfiguration('captive'));
        $this->registerView(new
RouterViewConfiguration('methods'));

        $method = new RouterViewConfiguration('method');
        $method->setKey('id');
        $this->registerView($method);

        parent::__construct($app, $menu);

        $this->attachRule(new MenuRules($this));
        $this->attachRule(new StandardRules($this));
        $this->attachRule(new NomenuRules($this));
    }

    /**
     * Get the method ID from a URL segment
     *
     * @param   string  $segment  The URL segment
     * @param   array   $query    The URL query parameters
     *
     * @return integer
     * @since 4.2.0
     */
    public function getMethodId($segment, $query)
    {
        return (int) $segment;
    }

    /**
     * Get a segment from a method ID
     *
     * @param   integer  $id     The method ID
     * @param   array    $query  The URL query parameters
     *
     * @return int[]
     * @since 4.2.0
     */
    public function getMethodSegment($id, $query)
    {
        return [$id => (int) $id];
    }
}
src/Model/BackupcodesModel.php000064400000001040151165506210012305
0ustar00<?php

/**
 * @package    Joomla.Administrator
 * @subpackage com_users
 *
 * @copyright  (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Model for managing backup codes
 *
 * @since 4.2.0
 */
class BackupcodesModel extends
\Joomla\Component\Users\Administrator\Model\BackupcodesModel
{
}
src/Model/MethodsModel.php000064400000001056151165506210011474
0ustar00<?php

/**
 * @package    Joomla.Administrator
 * @subpackage com_users
 *
 * @copyright  (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Multi-factor Authentication Methods list page's model
 *
 * @since 4.2.0
 */
class MethodsModel extends
\Joomla\Component\Users\Administrator\Model\MethodsModel
{
}
src/Model/RegistrationModel.php000064400000054720151165506210012551
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Date\Date;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormFactoryInterface;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\String\PunycodeHelper;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserFactoryAwareInterface;
use Joomla\CMS\User\UserFactoryAwareTrait;
use Joomla\CMS\User\UserHelper;
use Joomla\Database\ParameterType;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Registration model class for Users.
 *
 * @since  1.6
 */
class RegistrationModel extends FormModel implements
UserFactoryAwareInterface
{
    use UserFactoryAwareTrait;

    /**
     * @var    object  The user registration data.
     * @since  1.6
     */
    protected $data;

    /**
     * Constructor.
     *
     * @param   array                 $config       An array of
configuration options (name, state, dbo, table_path, ignore_request).
     * @param   MVCFactoryInterface   $factory      The factory.
     * @param   FormFactoryInterface  $formFactory  The form factory.
     *
     * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel
     * @since   3.2
     */
    public function __construct($config = [], MVCFactoryInterface $factory
= null, FormFactoryInterface $formFactory = null)
    {
        $config = array_merge(
            [
                'events_map' => ['validate' =>
'user'],
            ],
            $config
        );

        parent::__construct($config, $factory, $formFactory);
    }

    /**
     * Method to get the user ID from the given token
     *
     * @param   string  $token  The activation token.
     *
     * @return  mixed   False on failure, id of the user on success
     *
     * @since   3.8.13
     */
    public function getUserIdFromToken($token)
    {
        $db       = $this->getDatabase();

        // Get the user id based on the token.
        $query = $db->getQuery(true);
        $query->select($db->quoteName('id'))
            ->from($db->quoteName('#__users'))
            ->where($db->quoteName('activation') . ' =
:activation')
            ->where($db->quoteName('block') . ' =
1')
            ->where($db->quoteName('lastvisitDate') .
' IS NULL')
            ->bind(':activation', $token);
        $db->setQuery($query);

        try {
            return (int) $db->loadResult();
        } catch (\RuntimeException $e) {
           
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

            return false;
        }
    }

    /**
     * Method to activate a user account.
     *
     * @param   string  $token  The activation token.
     *
     * @return  mixed    False on failure, user object on success.
     *
     * @since   1.6
     */
    public function activate($token)
    {
        $app        = Factory::getApplication();
        $userParams = ComponentHelper::getParams('com_users');
        $userId     = $this->getUserIdFromToken($token);

        // Check for a valid user id.
        if (!$userId) {
           
$this->setError(Text::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));

            return false;
        }

        // Load the users plugin group.
        PluginHelper::importPlugin('user');

        // Activate the user.
        $user = $this->getUserFactory()->loadUserById($userId);

        // Admin activation is on and user is verifying their email
        if (($userParams->get('useractivation') == 2)
&& !$user->getParam('activate', 0)) {
            $linkMode = $app->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

            // Compile the admin notification mail values.
            $data               = $user->getProperties();
            $data['activation'] =
ApplicationHelper::getHash(UserHelper::genRandomPassword());
            $user->set('activation',
$data['activation']);
            $data['siteurl']  = Uri::base();
            $data['activate'] = Route::link(
                'site',
               
'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
                false,
                $linkMode,
                true
            );

            $data['fromname'] =
$app->get('fromname');
            $data['mailfrom'] =
$app->get('mailfrom');
            $data['sitename'] =
$app->get('sitename');
            $user->setParam('activate', 1);

            // Get all admin users
            $db    = $this->getDatabase();
            $query = $db->getQuery(true)
                ->select($db->quoteName(['name',
'email', 'sendEmail', 'id']))
                ->from($db->quoteName('#__users'))
                ->where($db->quoteName('sendEmail') .
' = 1')
                ->where($db->quoteName('block') . ' =
0');

            $db->setQuery($query);

            try {
                $rows = $db->loadObjectList();
            } catch (\RuntimeException $e) {
               
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

                return false;
            }

            // Send mail to all users with users creating permissions and
receiving system emails
            foreach ($rows as $row) {
                $usercreator =
$this->getUserFactory()->loadUserById($row->id);

                if ($usercreator->authorise('core.create',
'com_users') &&
$usercreator->authorise('core.manage', 'com_users'))
{
                    try {
                        $mailer = new
MailTemplate('com_users.registration.admin.verification_request',
$app->getLanguage()->getTag());
                        $mailer->addTemplateData($data);
                        $mailer->addRecipient($row->email);
                        $return = $mailer->send();
                    } catch (\Exception $exception) {
                        try {
                            Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                            $return = false;
                        } catch (\RuntimeException $exception) {
                           
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

                            $return = false;
                        }
                    }

                    // Check for an error.
                    if ($return !== true) {
                       
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

                        return false;
                    }
                }
            }
        } elseif (($userParams->get('useractivation') == 2)
&& $user->getParam('activate', 0)) {
            // Admin activation is on and admin is activating the account
            $user->set('activation', '');
            $user->set('block', '0');

            // Compile the user activated notification mail values.
            $data = $user->getProperties();
            $user->setParam('activate', 0);
            $data['fromname'] =
$app->get('fromname');
            $data['mailfrom'] =
$app->get('mailfrom');
            $data['sitename'] =
$app->get('sitename');
            $data['siteurl']  = Uri::base();
            $mailer           = new
MailTemplate('com_users.registration.user.admin_activated',
$app->getLanguage()->getTag());
            $mailer->addTemplateData($data);
            $mailer->addRecipient($data['email']);

            try {
                $return = $mailer->send();
            } catch (\Exception $exception) {
                try {
                    Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                    $return = false;
                } catch (\RuntimeException $exception) {
                   
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

                    $return = false;
                }
            }

            // Check for an error.
            if ($return !== true) {
               
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

                return false;
            }
        } else {
            $user->set('activation', '');
            $user->set('block', '0');
        }

        // Store the user object.
        if (!$user->save()) {
           
$this->setError(Text::sprintf('COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED',
$user->getError()));

            return false;
        }

        return $user;
    }

    /**
     * Method to get the registration form data.
     *
     * The base form data is loaded and then an event is fired
     * for users plugins to extend the data.
     *
     * @return  mixed  Data object on success, false on failure.
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function getData()
    {
        if ($this->data === null) {
            $this->data = new \stdClass();
            $app        = Factory::getApplication();
            $params     =
ComponentHelper::getParams('com_users');

            // Override the base user data with any data in the session.
            $temp = (array)
$app->getUserState('com_users.registration.data', []);

            // Don't load the data in this getForm call, or we'll
call ourself
            $form = $this->getForm([], false);

            foreach ($temp as $k => $v) {
                // Here we could have a grouped field, let's check it
                if (\is_array($v)) {
                    $this->data->$k = new \stdClass();

                    foreach ($v as $key => $val) {
                        if ($form->getField($key, $k) !== false) {
                            $this->data->$k->$key = $val;
                        }
                    }
                } elseif ($form->getField($k) !== false) {
                    // Only merge the field if it exists in the form.
                    $this->data->$k = $v;
                }
            }

            // Get the groups the user should be added to after
registration.
            $this->data->groups = [];

            // Get the default new user group, guest or public group if not
specified.
            $system = $params->get('new_usertype',
$params->get('guest_usergroup', 1));

            $this->data->groups[] = $system;

            // Unset the passwords.
            unset($this->data->password1,
$this->data->password2);

            // Get the dispatcher and load the users plugins.
            PluginHelper::importPlugin('user');

            // Trigger the data preparation event.
           
Factory::getApplication()->triggerEvent('onContentPrepareData',
['com_users.registration', $this->data]);
        }

        return $this->data;
    }

    /**
     * Method to get the registration form.
     *
     * The base form is loaded from XML and then an event is fired
     * for users plugins to extend the form with extra fields.
     *
     * @param   array    $data      An optional array of data for the form
to interrogate.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form  A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.registration',
'registration', ['control' => 'jform',
'load_data' => $loadData]);

        if (empty($form)) {
            return false;
        }

        // When multilanguage is set, a user's default site language
should also be a Content Language
        if (Multilanguage::isEnabled()) {
            $form->setFieldAttribute('language',
'type', 'frontend_language', 'params');
        }

        return $form;
    }

    /**
     * Method to get the data that should be injected in the form.
     *
     * @return  mixed  The data for the form.
     *
     * @since   1.6
     */
    protected function loadFormData()
    {
        $data = $this->getData();

        if (Multilanguage::isEnabled() &&
empty($data->language)) {
            $data->language = Factory::getLanguage()->getTag();
        }

        $this->preprocessData('com_users.registration',
$data);

        return $data;
    }

    /**
     * Override preprocessForm to load the user plugin group instead of
content.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import
(defaults to "content").
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception if there is an error in the form event.
     */
    protected function preprocessForm(Form $form, $data, $group =
'user')
    {
        $userParams = ComponentHelper::getParams('com_users');

        // Add the choice for site language at registration time
        if ($userParams->get('site_language') == 1 &&
$userParams->get('frontend_userparams') == 1) {
            $form->loadFile('sitelang', false);
        }

        parent::preprocessForm($form, $data, $group);
    }

    /**
     * Method to auto-populate the model state.
     *
     * Note. Calling getState in this method will result in recursion.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function populateState()
    {
        // Get the application object.
        $app    = Factory::getApplication();
        $params = $app->getParams('com_users');

        // Load the parameters.
        $this->setState('params', $params);
    }

    /**
     * Method to save the form data.
     *
     * @param   array  $temp  The form data.
     *
     * @return  mixed  The user id on success, false on failure.
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function register($temp)
    {
        $params = ComponentHelper::getParams('com_users');

        // Initialise the table with Joomla\CMS\User\User.
        $user = new User();
        $data = (array) $this->getData();

        // Merge in the registration data.
        foreach ($temp as $k => $v) {
            $data[$k] = $v;
        }

        // Prepare the data for the user object.
        $data['email']    =
PunycodeHelper::emailToPunycode($data['email1']);
        $data['password'] = $data['password1'];
        $useractivation   = $params->get('useractivation');
        $sendpassword     = $params->get('sendpassword', 1);

        // Check if the user needs to activate their account.
        if (($useractivation == 1) || ($useractivation == 2)) {
            $data['activation'] =
ApplicationHelper::getHash(UserHelper::genRandomPassword());
            $data['block']      = 1;
        }

        // Bind the data.
        if (!$user->bind($data)) {
            $this->setError($user->getError());

            return false;
        }

        // Load the users plugin group.
        PluginHelper::importPlugin('user');

        // Store the data.
        if (!$user->save()) {
           
$this->setError(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED',
$user->getError()));

            return false;
        }

        $app   = Factory::getApplication();
        $db    = $this->getDatabase();
        $query = $db->getQuery(true);

        // Compile the notification mail values.
        $data             = $user->getProperties();
        $data['fromname'] = $app->get('fromname');
        $data['mailfrom'] = $app->get('mailfrom');
        $data['sitename'] = $app->get('sitename');
        $data['siteurl']  = Uri::root();

        // Handle account activation/confirmation emails.
        if ($useractivation == 2) {
            // Set the link to confirm the user email.
            $linkMode = $app->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

            $data['activate'] = Route::link(
                'site',
               
'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
                false,
                $linkMode,
                true
            );

            $mailtemplate =
'com_users.registration.user.admin_activation';
        } elseif ($useractivation == 1) {
            // Set the link to activate the user account.
            $linkMode = $app->get('force_ssl', 0) == 2 ?
Route::TLS_FORCE : Route::TLS_IGNORE;

            $data['activate'] = Route::link(
                'site',
               
'index.php?option=com_users&task=registration.activate&token='
. $data['activation'],
                false,
                $linkMode,
                true
            );

            $mailtemplate =
'com_users.registration.user.self_activation';
        } else {
            $mailtemplate =
'com_users.registration.user.registration_mail';
        }

        if ($sendpassword) {
            $mailtemplate .= '_w_pw';
        }

        // Try to send the registration email.
        try {
            $mailer = new MailTemplate($mailtemplate,
$app->getLanguage()->getTag());
            $mailer->addTemplateData($data);
            $mailer->addRecipient($data['email']);
            $return = $mailer->send();
        } catch (\Exception $exception) {
            try {
                Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                $return = false;
            } catch (\RuntimeException $exception) {
               
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

               
$this->setError(Text::_('COM_MESSAGES_ERROR_MAIL_FAILED'));

                $return = false;
            }
        }

        // Send mail to all users with user creating permissions and
receiving system emails
        if (($params->get('useractivation') < 2) &&
($params->get('mail_to_admin') == 1)) {
            // Get all admin users
            $query->clear()
                ->select($db->quoteName(['name',
'email', 'sendEmail', 'id']))
                ->from($db->quoteName('#__users'))
                ->where($db->quoteName('sendEmail') .
' = 1')
                ->where($db->quoteName('block') . ' =
0');

            $db->setQuery($query);

            try {
                $rows = $db->loadObjectList();
            } catch (\RuntimeException $e) {
               
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

                return false;
            }

            // Send mail to all superadministrators id
            foreach ($rows as $row) {
                $usercreator =
$this->getUserFactory()->loadUserById($row->id);

                if (!$usercreator->authorise('core.create',
'com_users') ||
!$usercreator->authorise('core.manage',
'com_users')) {
                    continue;
                }

                try {
                    $mailer = new
MailTemplate('com_users.registration.admin.new_notification',
$app->getLanguage()->getTag());
                    $mailer->addTemplateData($data);
                    $mailer->addRecipient($row->email);
                    $return = $mailer->send();
                } catch (\Exception $exception) {
                    try {
                        Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                        $return = false;
                    } catch (\RuntimeException $exception) {
                       
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

                        $return = false;
                    }
                }

                // Check for an error.
                if ($return !== true) {
                   
$this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'));

                    return false;
                }
            }
        }

        // Check for an error.
        if ($return !== true) {
           
$this->setError(Text::_('COM_USERS_REGISTRATION_SEND_MAIL_FAILED'));

            // Send a system message to administrators receiving system
mails
            $db = $this->getDatabase();
            $query->clear()
                ->select($db->quoteName('id'))
                ->from($db->quoteName('#__users'))
                ->where($db->quoteName('block') . ' =
0')
                ->where($db->quoteName('sendEmail') .
' = 1');
            $db->setQuery($query);

            try {
                $userids = $db->loadColumn();
            } catch (\RuntimeException $e) {
               
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

                return false;
            }

            if (\count($userids) > 0) {
                $jdate     = new Date();
                $dateToSql = $jdate->toSql();
                $subject   =
Text::_('COM_USERS_MAIL_SEND_FAILURE_SUBJECT');
                $message   =
Text::sprintf('COM_USERS_MAIL_SEND_FAILURE_BODY',
$data['username']);

                // Build the query to add the messages
                foreach ($userids as $userid) {
                    $values = [
                        ':user_id_from',
                        ':user_id_to',
                        ':date_time',
                        ':subject',
                        ':message',
                    ];
                    $query->clear()
                       
->insert($db->quoteName('#__messages'))
                       
->columns($db->quoteName(['user_id_from',
'user_id_to', 'date_time', 'subject',
'message']))
                        ->values(implode(',', $values));
                    $query->bind(':user_id_from', $userid,
ParameterType::INTEGER)
                        ->bind(':user_id_to', $userid,
ParameterType::INTEGER)
                        ->bind(':date_time', $dateToSql)
                        ->bind(':subject', $subject)
                        ->bind(':message', $message);

                    $db->setQuery($query);

                    try {
                        $db->execute();
                    } catch (\RuntimeException $e) {
                       
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

                        return false;
                    }
                }
            }

            return false;
        }

        if ($useractivation == 1) {
            return 'useractivate';
        }

        if ($useractivation == 2) {
            return 'adminactivate';
        }

        return $user->id;
    }
}
src/Model/LoginModel.php000064400000010175151165506210011143
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Uri\Uri;
use Joomla\Database\ParameterType;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Login model class for Users.
 *
 * @since  1.6
 */
class LoginModel extends FormModel
{
    /**
     * Method to get the login form.
     *
     * The base form is loaded from XML and then an event is fired
     * for users plugins to extend the form with extra fields.
     *
     * @param   array    $data      An optional array of data for the form
to interrogate.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form    A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.login',
'login', ['load_data' => $loadData]);

        if (empty($form)) {
            return false;
        }

        return $form;
    }

    /**
     * Method to get the data that should be injected in the form.
     *
     * @return  array  The default data is an empty array.
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function loadFormData()
    {
        // Check the session for previously entered login form data.
        $app  = Factory::getApplication();
        $data = $app->getUserState('users.login.form.data',
[]);

        $input = $app->getInput()->getInputForRequestMethod();

        // Check for return URL from the request first
        if ($return = $input->get('return', '',
'BASE64')) {
            $data['return'] = base64_decode($return);

            if (!Uri::isInternal($data['return'])) {
                $data['return'] = '';
            }
        }

        $app->setUserState('users.login.form.data', $data);

        $this->preprocessData('com_users.login', $data);

        return $data;
    }

    /**
     * Method to auto-populate the model state.
     *
     * Calling getState in this method will result in recursion.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function populateState()
    {
        // Get the application object.
        $params =
Factory::getApplication()->getParams('com_users');

        // Load the parameters.
        $this->setState('params', $params);
    }

    /**
     * Override Joomla\CMS\MVC\Model\AdminModel::preprocessForm to ensure
the correct plugin group is loaded.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import
(defaults to "content").
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception if there is an error in the form event.
     */
    protected function preprocessForm(Form $form, $data, $group =
'user')
    {
        parent::preprocessForm($form, $data, $group);
    }

    /**
     * Returns the language for the given menu id.
     *
     * @param  int  $id  The menu id
     *
     * @return string
     *
     * @since  4.2.0
     */
    public function getMenuLanguage(int $id): string
    {
        if (!Multilanguage::isEnabled()) {
            return '';
        }

        $db    = $this->getDatabase();
        $query = $db->getQuery(true)
            ->select($db->quoteName('language'))
            ->from($db->quoteName('#__menu'))
            ->where($db->quoteName('client_id') . ' =
0')
            ->where($db->quoteName('id') . ' =
:id')
            ->bind(':id', $id, ParameterType::INTEGER);

        $db->setQuery($query);

        try {
            return $db->loadResult();
        } catch (\RuntimeException $e) {
            return '';
        }
    }
}
src/Model/RemindModel.php000064400000013544151165506210011314
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

use Joomla\CMS\Event\User\AfterRemindEvent;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Router\Route;
use Joomla\CMS\String\PunycodeHelper;
use Joomla\Utilities\ArrayHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Remind model class for Users.
 *
 * @since  1.5
 */
class RemindModel extends FormModel
{
    /**
     * Method to get the username remind request form.
     *
     * @param   array    $data      An optional array of data for the form
to interrogate.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form|bool A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.remind',
'remind', ['control' => 'jform',
'load_data' => $loadData]);

        if (empty($form)) {
            return false;
        }

        return $form;
    }

    /**
     * Override preprocessForm to load the user plugin group instead of
content.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import
(defaults to "content").
     *
     * @return  void
     *
     * @throws  \Exception if there is an error in the form event.
     *
     * @since   1.6
     */
    protected function preprocessForm(Form $form, $data, $group =
'user')
    {
        parent::preprocessForm($form, $data, 'user');
    }

    /**
     * Method to auto-populate the model state.
     *
     * Note. Calling getState in this method will result in recursion.
     *
     * @return  void
     *
     * @since   1.6
     *
     * @throws  \Exception
     */
    protected function populateState()
    {
        // Get the application object.
        $app    = Factory::getApplication();
        $params = $app->getParams('com_users');

        // Load the parameters.
        $this->setState('params', $params);
    }

    /**
     * Send the remind username email
     *
     * @param   array  $data  Array with the data received from the form
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function processRemindRequest($data)
    {
        // Get the form.
        $form          = $this->getForm();
        $data['email'] =
PunycodeHelper::emailToPunycode($data['email']);

        // Check for an error.
        if (empty($form)) {
            return false;
        }

        // Validate the data.
        $data = $this->validate($form, $data);

        // Check for an error.
        if ($data instanceof \Exception) {
            return false;
        }

        // Check the validation results.
        if ($data === false) {
            // Get the validation messages from the form.
            foreach ($form->getErrors() as $formError) {
                $this->setError($formError->getMessage());
            }

            return false;
        }

        // Find the user id for the given email address.
        $db    = $this->getDatabase();
        $query = $db->getQuery(true)
            ->select('*')
            ->from($db->quoteName('#__users'))
            ->where('LOWER(' .
$db->quoteName('email') . ') = LOWER(:email)')
            ->bind(':email', $data['email']);

        // Get the user id.
        $db->setQuery($query);

        try {
            $user = $db->loadObject();
        } catch (\RuntimeException $e) {
           
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

            return false;
        }

        // Check for a user.
        if (empty($user)) {
           
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));

            return false;
        }

        // Make sure the user isn't blocked.
        if ($user->block) {
           
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));

            return false;
        }

        $app = Factory::getApplication();

        // Assemble the login link.
        $link = 'index.php?option=com_users&view=login';
        $mode = $app->get('force_ssl', 0) == 2 ? 1 : (-1);

        // Put together the email template data.
        $data              = ArrayHelper::fromObject($user);
        $data['sitename']  = $app->get('sitename');
        $data['link_text'] = Route::_($link, false, $mode);
        $data['link_html'] = Route::_($link, true, $mode);

        $mailer = new MailTemplate('com_users.reminder',
$app->getLanguage()->getTag());
        $mailer->addTemplateData($data);
        $mailer->addRecipient($user->email, $user->name);

        // Try to send the password reset request email.
        try {
            $return = $mailer->send();
        } catch (\Exception $exception) {
            try {
                Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                $return = false;
            } catch (\RuntimeException $exception) {
               
Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

                $return = false;
            }
        }

        // Check for an error.
        if ($return !== true) {
            $this->setError(Text::_('COM_USERS_MAIL_FAILED'));

            return false;
        }

       
$this->getDispatcher()->dispatch('onUserAfterRemind', new
AfterRemindEvent('onUserAfterRemind', [
            'subject' => $user,
        ]));

        return true;
    }
}
src/Model/MethodModel.php000064400000001052151165506250011311
0ustar00<?php

/**
 * @package    Joomla.Administrator
 * @subpackage com_users
 *
 * @copyright  (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Multi-factor Authentication Method management model
 *
 * @since 4.2.0
 */
class MethodModel extends
\Joomla\Component\Users\Administrator\Model\MethodModel
{
}
src/Model/ResetModel.php000064400000040344151165506250011162
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Event\AbstractEvent;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Router\Route;
use Joomla\CMS\String\PunycodeHelper;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserFactoryAwareInterface;
use Joomla\CMS\User\UserFactoryAwareTrait;
use Joomla\CMS\User\UserHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Reset model class for Users.
 *
 * @since  1.5
 */
class ResetModel extends FormModel implements UserFactoryAwareInterface
{
    use UserFactoryAwareTrait;

    /**
     * Method to get the password reset request form.
     *
     * The base form is loaded from XML and then an event is fired
     * for users plugins to extend the form with extra fields.
     *
     * @param   array    $data      An optional array of data for the form
to interrogate.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form  A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.reset_request',
'reset_request', ['control' => 'jform',
'load_data' => $loadData]);

        if (empty($form)) {
            return false;
        }

        return $form;
    }

    /**
     * Method to get the password reset complete form.
     *
     * @param   array    $data      Data for the form.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form    A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getResetCompleteForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.reset_complete',
'reset_complete', $options = ['control' =>
'jform']);

        if (empty($form)) {
            return false;
        }

        return $form;
    }

    /**
     * Method to get the password reset confirm form.
     *
     * @param   array    $data      Data for the form.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form  A Form object on success, false on failure
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function getResetConfirmForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.reset_confirm',
'reset_confirm', $options = ['control' =>
'jform']);

        if (empty($form)) {
            return false;
        }

        $form->setValue('token', '',
Factory::getApplication()->getInput()->get('token'));

        return $form;
    }

    /**
     * Override preprocessForm to load the user plugin group instead of
content.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import
(defaults to "content").
     *
     * @return  void
     *
     * @throws  \Exception if there is an error in the form event.
     *
     * @since   1.6
     */
    protected function preprocessForm(Form $form, $data, $group =
'user')
    {
        parent::preprocessForm($form, $data, $group);
    }

    /**
     * Method to auto-populate the model state.
     *
     * Note. Calling getState in this method will result in recursion.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function populateState()
    {
        // Get the application object.
        $params =
Factory::getApplication()->getParams('com_users');

        // Load the parameters.
        $this->setState('params', $params);
    }

    /**
     * Save the new password after reset is done
     *
     * @param   array  $data  The data expected for the form.
     *
     * @return  mixed  \Exception | boolean
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function processResetComplete($data)
    {
        // Get the form.
        $form = $this->getResetCompleteForm();

        // Check for an error.
        if ($form instanceof \Exception) {
            return $form;
        }

        // Filter and validate the form data.
        $data   = $form->filter($data);
        $return = $form->validate($data);

        // Check for an error.
        if ($return instanceof \Exception) {
            return $return;
        }

        // Check the validation results.
        if ($return === false) {
            // Get the validation messages from the form.
            foreach ($form->getErrors() as $formError) {
                $this->setError($formError->getMessage());
            }

            return false;
        }

        // Get the token and user id from the confirmation process.
        $app    = Factory::getApplication();
        $token  = $app->getUserState('com_users.reset.token',
null);
        $userId = $app->getUserState('com_users.reset.user',
null);

        // Check the token and user id.
        if (empty($token) || empty($userId)) {
            return new
\Exception(Text::_('COM_USERS_RESET_COMPLETE_TOKENS_MISSING'),
403);
        }

        // Get the user object.
        $user = $this->getUserFactory()->loadUserById($userId);

        $event = AbstractEvent::create(
            'onUserBeforeResetComplete',
            [
                'subject' => $user,
            ]
        );
        $app->getDispatcher()->dispatch($event->getName(),
$event);

        // Check for a user and that the tokens match.
        if (empty($user) || $user->activation !== $token) {
           
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));

            return false;
        }

        // Make sure the user isn't blocked.
        if ($user->block) {
           
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));

            return false;
        }

        // Check if the user is reusing the current password if required to
reset their password
        if ($user->requireReset == 1 &&
UserHelper::verifyPassword($data['password1'],
$user->password)) {
           
$this->setError(Text::_('JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD'));

            return false;
        }

        // Prepare user data.
        $data['password']   = $data['password1'];
        $data['activation'] = '';

        // Update the user object.
        if (!$user->bind($data)) {
            return new \Exception($user->getError(), 500);
        }

        // Save the user to the database.
        if (!$user->save(true)) {
            return new
\Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED',
$user->getError()), 500);
        }

        // Destroy all active sessions for the user
        UserHelper::destroyUserSessions($user->id);

        // Flush the user data from the session.
        $app->setUserState('com_users.reset.token', null);
        $app->setUserState('com_users.reset.user', null);

        $event = AbstractEvent::create(
            'onUserAfterResetComplete',
            [
                'subject' => $user,
            ]
        );
        $app->getDispatcher()->dispatch($event->getName(),
$event);

        return true;
    }

    /**
     * Receive the reset password request
     *
     * @param   array  $data  The data expected for the form.
     *
     * @return  mixed  \Exception | boolean
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function processResetConfirm($data)
    {
        // Get the form.
        $form = $this->getResetConfirmForm();

        // Check for an error.
        if ($form instanceof \Exception) {
            return $form;
        }

        // Filter and validate the form data.
        $data   = $form->filter($data);
        $return = $form->validate($data);

        // Check for an error.
        if ($return instanceof \Exception) {
            return $return;
        }

        // Check the validation results.
        if ($return === false) {
            // Get the validation messages from the form.
            foreach ($form->getErrors() as $formError) {
                $this->setError($formError->getMessage());
            }

            return false;
        }

        // Find the user id for the given token.
        $db    = $this->getDatabase();
        $query = $db->getQuery(true)
            ->select($db->quoteName(['activation',
'id', 'block']))
            ->from($db->quoteName('#__users'))
            ->where($db->quoteName('username') . ' =
:username')
            ->bind(':username', $data['username']);

        // Get the user id.
        $db->setQuery($query);

        try {
            $user = $db->loadObject();
        } catch (\RuntimeException $e) {
            return new
\Exception(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()), 500);
        }

        // Check for a user.
        if (empty($user)) {
           
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));

            return false;
        }

        if (!$user->activation) {
           
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));

            return false;
        }

        // Verify the token
        if (!UserHelper::verifyPassword($data['token'],
$user->activation)) {
           
$this->setError(Text::_('COM_USERS_USER_NOT_FOUND'));

            return false;
        }

        // Make sure the user isn't blocked.
        if ($user->block) {
           
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));

            return false;
        }

        // Push the user data into the session.
        $app = Factory::getApplication();
        $app->setUserState('com_users.reset.token',
$user->activation);
        $app->setUserState('com_users.reset.user',
$user->id);

        return true;
    }

    /**
     * Method to start the password reset process.
     *
     * @param   array  $data  The data expected for the form.
     *
     * @return  mixed  \Exception | boolean
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function processResetRequest($data)
    {
        $app = Factory::getApplication();

        // Get the form.
        $form = $this->getForm();

        $data['email'] =
PunycodeHelper::emailToPunycode($data['email']);

        // Check for an error.
        if ($form instanceof \Exception) {
            return $form;
        }

        // Filter and validate the form data.
        $data   = $form->filter($data);
        $return = $form->validate($data);

        // Check for an error.
        if ($return instanceof \Exception) {
            return $return;
        }

        // Check the validation results.
        if ($return === false) {
            // Get the validation messages from the form.
            foreach ($form->getErrors() as $formError) {
                $this->setError($formError->getMessage());
            }

            return false;
        }

        // Find the user id for the given email address.
        $db    = $this->getDatabase();
        $query = $db->getQuery(true)
            ->select($db->quoteName('id'))
            ->from($db->quoteName('#__users'))
            ->where('LOWER(' .
$db->quoteName('email') . ') = LOWER(:email)')
            ->bind(':email', $data['email']);

        // Get the user object.
        $db->setQuery($query);

        try {
            $userId = $db->loadResult();
        } catch (\RuntimeException $e) {
           
$this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR',
$e->getMessage()));

            return false;
        }

        // Check for a user.
        if (empty($userId)) {
           
$this->setError(Text::_('COM_USERS_INVALID_EMAIL'));

            return false;
        }

        // Get the user object.
        $user = $this->getUserFactory()->loadUserById($userId);

        // Make sure the user isn't blocked.
        if ($user->block) {
           
$this->setError(Text::_('COM_USERS_USER_BLOCKED'));

            return false;
        }

        // Make sure the user isn't a Super Admin.
        if ($user->authorise('core.admin')) {
           
$this->setError(Text::_('COM_USERS_REMIND_SUPERADMIN_ERROR'));

            return false;
        }

        // Make sure the user has not exceeded the reset limit
        if (!$this->checkResetLimit($user)) {
            $resetLimit = (int)
Factory::getApplication()->getParams()->get('reset_time');
           
$this->setError(Text::plural('COM_USERS_REMIND_LIMIT_ERROR_N_HOURS',
$resetLimit));

            return false;
        }

        // Set the confirmation token.
        $token       =
ApplicationHelper::getHash(UserHelper::genRandomPassword());
        $hashedToken = UserHelper::hashPassword($token);

        $user->activation = $hashedToken;

        $event = AbstractEvent::create(
            'onUserBeforeResetRequest',
            [
                'subject' => $user,
            ]
        );
        $app->getDispatcher()->dispatch($event->getName(),
$event);

        // Save the user to the database.
        if (!$user->save(true)) {
            return new
\Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED',
$user->getError()), 500);
        }

        // Assemble the password reset confirmation link.
        $mode = $app->get('force_ssl', 0) == 2 ? 1 : (-1);
        $link =
'index.php?option=com_users&view=reset&layout=confirm&token='
. $token;

        // Put together the email template data.
        $data              = $user->getProperties();
        $data['sitename']  = $app->get('sitename');
        $data['link_text'] = Route::_($link, false, $mode);
        $data['link_html'] = Route::_($link, true, $mode);
        $data['token']     = $token;

        $mailer = new MailTemplate('com_users.password_reset',
$app->getLanguage()->getTag());
        $mailer->addTemplateData($data);
        $mailer->addRecipient($user->email, $user->name);

        // Try to send the password reset request email.
        try {
            $return = $mailer->send();
        } catch (\Exception $exception) {
            try {
                Log::add(Text::_($exception->getMessage()),
Log::WARNING, 'jerror');

                $return = false;
            } catch (\RuntimeException $exception) {
               
$app->enqueueMessage(Text::_($exception->errorMessage()),
'warning');

                $return = false;
            }
        }

        // Check for an error.
        if ($return !== true) {
            return new
\Exception(Text::_('COM_USERS_MAIL_FAILED'), 500);
        }

        $event = AbstractEvent::create(
            'onUserAfterResetRequest',
            [
                'subject' => $user,
            ]
        );
        $app->getDispatcher()->dispatch($event->getName(),
$event);

        return true;
    }

    /**
     * Method to check if user reset limit has been exceeded within the
allowed time period.
     *
     * @param   User  $user  User doing the password reset
     *
     * @return  boolean true if user can do the reset, false if limit
exceeded
     *
     * @since    2.5
     * @throws  \Exception
     */
    public function checkResetLimit($user)
    {
        $params     = Factory::getApplication()->getParams();
        $maxCount   = (int) $params->get('reset_count');
        $resetHours = (int) $params->get('reset_time');
        $result     = true;

        $lastResetTime       = strtotime($user->lastResetTime) ?: 0;
        $hoursSinceLastReset = (strtotime(Factory::getDate()->toSql()) -
$lastResetTime) / 3600;

        if ($hoursSinceLastReset > $resetHours) {
            // If it's been long enough, start a new reset count
            $user->lastResetTime = Factory::getDate()->toSql();
            $user->resetCount    = 1;
        } elseif ($user->resetCount < $maxCount) {
            // If we are under the max count, just increment the counter
            ++$user->resetCount;
        } else {
            // At this point, we know we have exceeded the maximum resets
for the time period
            $result = false;
        }

        return $result;
    }
}
src/Model/CaptiveModel.php000064400000001051151165506250011463
0ustar00<?php

/**
 * @package    Joomla.Administrator
 * @subpackage com_users
 *
 * @copyright  (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license    GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Captive Multi-factor Authentication page's model
 *
 * @since 4.2.0
 */
class CaptiveModel extends
\Joomla\Component\Users\Administrator\Model\CaptiveModel
{
}
src/Model/ProfileModel.php000064400000024241151165506250011476
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Model;

use Joomla\CMS\Access\Access;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormFactoryInterface;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\String\PunycodeHelper;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserHelper;
use Joomla\Component\Users\Administrator\Model\UserModel;
use Joomla\Registry\Registry;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Profile model class for Users.
 *
 * @since  1.6
 */
class ProfileModel extends FormModel
{
    /**
     * @var     object  The user profile data.
     * @since   1.6
     */
    protected $data;

    /**
     * Constructor.
     *
     * @param   array                 $config       An array of
configuration options (name, state, dbo, table_path, ignore_request).
     * @param   MVCFactoryInterface   $factory      The factory.
     * @param   FormFactoryInterface  $formFactory  The form factory.
     *
     * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel
     * @since   3.2
     */
    public function __construct($config = [], MVCFactoryInterface $factory
= null, FormFactoryInterface $formFactory = null)
    {
        $config = array_merge(
            [
                'events_map' => ['validate' =>
'user'],
            ],
            $config
        );

        parent::__construct($config, $factory, $formFactory);
    }

    /**
     * Method to get the profile form data.
     *
     * The base form data is loaded and then an event is fired
     * for users plugins to extend the data.
     *
     * @return  User
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function getData()
    {
        if ($this->data === null) {
            $userId = $this->getState('user.id');

            // Initialise the table with Joomla\CMS\User\User.
            $this->data = new User($userId);

            // Set the base user data.
            $this->data->email1 =
$this->data->get('email');

            // Override the base user data with any data in the session.
            $temp = (array)
Factory::getApplication()->getUserState('com_users.edit.profile.data',
[]);

            foreach ($temp as $k => $v) {
                $this->data->$k = $v;
            }

            // Unset the passwords.
            unset($this->data->password1,
$this->data->password2);

            $registry           = new Registry($this->data->params);
            $this->data->params = $registry->toArray();
        }

        return $this->data;
    }

    /**
     * Method to get the profile form.
     *
     * The base form is loaded from XML and then an event is fired
     * for users plugins to extend the form with extra fields.
     *
     * @param   array    $data      An optional array of data for the form
to interrogate.
     * @param   boolean  $loadData  True if the form is to load its own
data (default case), false if not.
     *
     * @return  Form|bool  A Form object on success, false on failure
     *
     * @since   1.6
     */
    public function getForm($data = [], $loadData = true)
    {
        // Get the form.
        $form = $this->loadForm('com_users.profile',
'profile', ['control' => 'jform',
'load_data' => $loadData]);

        if (empty($form)) {
            return false;
        }

        // Check for username compliance and parameter set
        $isUsernameCompliant = true;
        $username            = $loadData ?
$form->getValue('username') :
$this->loadFormData()->username;

        if ($username) {
            $isUsernameCompliant  =
!(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#',
$username)
                || \strlen(mb_convert_encoding($username,
'ISO-8859-1', 'UTF-8')) < 2
                || trim($username) !== $username);
        }

        $this->setState('user.username.compliant',
$isUsernameCompliant);

        if ($isUsernameCompliant &&
!ComponentHelper::getParams('com_users')->get('change_login_name'))
{
            $form->setFieldAttribute('username',
'class', '');
            $form->setFieldAttribute('username',
'filter', '');
            $form->setFieldAttribute('username',
'description',
'COM_USERS_PROFILE_NOCHANGE_USERNAME_DESC');
            $form->setFieldAttribute('username',
'validate', '');
            $form->setFieldAttribute('username',
'message', '');
            $form->setFieldAttribute('username',
'readonly', 'true');
            $form->setFieldAttribute('username',
'required', 'false');
        }

        // When multilanguage is set, a user's default site language
should also be a Content Language
        if (Multilanguage::isEnabled()) {
            $form->setFieldAttribute('language',
'type', 'frontend_language', 'params');
        }

        // If the user needs to change their password, mark the password
fields as required
        if ($this->getCurrentUser()->requireReset) {
            $form->setFieldAttribute('password1',
'required', 'true');
            $form->setFieldAttribute('password2',
'required', 'true');
        }

        return $form;
    }

    /**
     * Method to get the data that should be injected in the form.
     *
     * @return  mixed  The data for the form.
     *
     * @since   1.6
     */
    protected function loadFormData()
    {
        $data = $this->getData();

        $this->preprocessData('com_users.profile', $data,
'user');

        return $data;
    }

    /**
     * Override preprocessForm to load the user plugin group instead of
content.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import
(defaults to "content").
     *
     * @return  void
     *
     * @throws  \Exception if there is an error in the form event.
     *
     * @since   1.6
     */
    protected function preprocessForm(Form $form, $data, $group =
'user')
    {
        if
(ComponentHelper::getParams('com_users')->get('frontend_userparams'))
{
            $form->loadFile('frontend', false);

            if
($this->getCurrentUser()->authorise('core.login.admin')) {
                $form->loadFile('frontend_admin', false);
            }
        }

        parent::preprocessForm($form, $data, $group);
    }

    /**
     * Method to auto-populate the model state.
     *
     * Note. Calling getState in this method will result in recursion.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function populateState()
    {
        // Get the application object.
        $params =
Factory::getApplication()->getParams('com_users');

        // Get the user id.
        $userId =
Factory::getApplication()->getUserState('com_users.edit.profile.id');
        $userId = !empty($userId) ? $userId : (int)
$this->getCurrentUser()->get('id');

        // Set the user id.
        $this->setState('user.id', $userId);

        // Load the parameters.
        $this->setState('params', $params);
    }

    /**
     * Method to save the form data.
     *
     * @param   array  $data  The form data.
     *
     * @return  mixed  The user id on success, false on failure.
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function save($data)
    {
        $userId = (!empty($data['id'])) ? $data['id'] :
(int) $this->getState('user.id');

        $user = new User($userId);

        // Prepare the data for the user object.
        $data['email']    =
PunycodeHelper::emailToPunycode($data['email1']);
        $data['password'] = $data['password1'];

        // Unset the username if it should not be overwritten
        $isUsernameCompliant =
$this->getState('user.username.compliant');

        if ($isUsernameCompliant &&
!ComponentHelper::getParams('com_users')->get('change_login_name'))
{
            unset($data['username']);
        }

        // Unset block and sendEmail so they do not get overwritten
        unset($data['block'], $data['sendEmail']);

        // Bind the data.
        if (!$user->bind($data)) {
            $this->setError($user->getError());

            return false;
        }

        // Load the users plugin group.
        PluginHelper::importPlugin('user');

        // Retrieve the user groups so they don't get overwritten
        unset($user->groups);
        $user->groups = Access::getGroupsByUser($user->id, false);

        // Store the data.
        if (!$user->save()) {
            $this->setError($user->getError());

            return false;
        }

        // Destroy all active sessions for the user after changing the
password
        if ($data['password1']) {
            UserHelper::destroyUserSessions($user->id, true);
        }

        return $user->id;
    }

    /**
     * Gets the configuration forms for all two-factor authentication
methods
     * in an array.
     *
     * @param   integer  $userId  The user ID to load the forms for
(optional)
     *
     * @return  array
     *
     * @since   3.2
     *
     * @deprecated   4.2 will be removed in 6.0.
     *               Will be removed without replacement
     */
    public function getTwofactorform($userId = null)
    {
        return [];
    }

    /**
     * No longer used
     *
     * @param   integer  $userId  Ignored
     *
     * @return  \stdClass
     *
     * @since   3.2
     *
     * @deprecated   4.2 will be removed in 6.0.
     *               Will be removed without replacement
     */
    public function getOtpConfig($userId = null)
    {
        @trigger_error(
            sprintf(
                '%s() is deprecated. Use
\Joomla\Component\Users\Administrator\Helper\Mfa::getUserMfaRecords()
instead.',
                __METHOD__
            ),
            E_USER_DEPRECATED
        );

        /** @var UserModel $model */
        $model = $this->bootComponent('com_users')
            ->getMVCFactory()->createModel('User',
'Administrator');

        return $model->getOtpConfig();
    }
}
src/Controller/ProfileController.php000064400000016577151165506250013661
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Application\CMSWebApplicationInterface;
use Joomla\CMS\Event\Model;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Profile controller class for Users.
 *
 * @since  1.6
 */
class ProfileController extends BaseController
{
    /**
     * Method to check out a user for editing and redirect to the edit
form.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function edit()
    {
        $app         = $this->app;
        $user        = $this->app->getIdentity();
        $loginUserId = (int) $user->get('id');

        // Get the current user id.
        $userId     = $this->input->getInt('user_id');

        // Check if the user is trying to edit another users profile.
        if ($userId != $loginUserId) {
           
$app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'),
'error');
            $app->setHeader('status', 403, true);

            return false;
        }

        $cookieLogin = $user->get('cookieLogin');

        // Check if the user logged in with a cookie
        if (!empty($cookieLogin)) {
            // If so, the user must login to edit the password and other
data.
           
$app->enqueueMessage(Text::_('JGLOBAL_REMEMBER_MUST_LOGIN'),
'message');
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

            return false;
        }

        // Set the user id for the user to edit in the session.
        $app->setUserState('com_users.edit.profile.id',
$userId);

        // Redirect to the edit screen.
       
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit',
false));

        return true;
    }

    /**
     * Method to save a user's profile data.
     *
     * @return  void|boolean
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function save()
    {
        // Check for request forgeries.
        $this->checkToken();

        $app    = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\ProfileModel $model */
        $model  = $this->getModel('Profile',
'Site');
        $user   = $this->app->getIdentity();
        $userId = (int) $user->get('id');

        // Get the user data.
        $requestData =
$app->getInput()->post->get('jform', [],
'array');

        // Force the ID to this user.
        $requestData['id'] = $userId;

        // Validate the posted data.
        $form = $model->getForm();

        if (!$form) {
            throw new \Exception($model->getError(), 500);
        }

        // Send an object which can be modified through the plugin event
        $objData = (object) $requestData;
        $this->getDispatcher()->dispatch(
            'onContentNormaliseRequestData',
            new
Model\NormaliseRequestDataEvent('onContentNormaliseRequestData',
[
                'context' => 'com_users.user',
                'data'    => $objData,
                'subject' => $form,
            ])
        );
        $requestData = (array) $objData;

        // Validate the posted data.
        $data = $model->validate($form, $requestData);

        // Check for errors.
        if ($data === false) {
            // Get the validation messages.
            $errors = $model->getErrors();

            // Push up to three validation messages out to the user.
            for ($i = 0, $n = \count($errors); $i < $n && $i
< 3; $i++) {
                if ($errors[$i] instanceof \Exception) {
                    $app->enqueueMessage($errors[$i]->getMessage(),
CMSWebApplicationInterface::MSG_ERROR);
                } else {
                    $app->enqueueMessage($errors[$i],
CMSWebApplicationInterface::MSG_ERROR);
                }
            }

            // Unset the passwords.
            unset($requestData['password1'],
$requestData['password2']);

            // Save the data in the session.
            $app->setUserState('com_users.edit.profile.data',
$requestData);

            // Redirect back to the edit screen.
            $userId = (int)
$app->getUserState('com_users.edit.profile.id');
           
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit&user_id='
. $userId, false));

            return false;
        }

        // Attempt to save the data.
        $return = $model->save($data);

        // Check for errors.
        if ($return === false) {
            // Save the data in the session.
            $app->setUserState('com_users.edit.profile.data',
$data);

            // Redirect back to the edit screen.
            $userId = (int)
$app->getUserState('com_users.edit.profile.id');
           
$this->setMessage(Text::sprintf('COM_USERS_PROFILE_SAVE_FAILED',
$model->getError()), 'warning');
           
$this->setRedirect(Route::_('index.php?option=com_users&view=profile&layout=edit&user_id='
. $userId, false));

            return false;
        }

        // Redirect the user and adjust session state based on the chosen
task.
        switch ($this->getTask()) {
            case 'apply':
                // Check out the profile.
               
$app->setUserState('com_users.edit.profile.id', $return);

                // Redirect back to the edit screen.
               
$this->setMessage(Text::_('COM_USERS_PROFILE_SAVE_SUCCESS'));

                $redirect =
$app->getUserState('com_users.edit.profile.redirect',
'');

                // Don't redirect to an external URL.
                if (!Uri::isInternal($redirect)) {
                    $redirect = null;
                }

                if (!$redirect) {
                    $redirect =
'index.php?option=com_users&view=profile&layout=edit&hidemainmenu=1';
                }

                $this->setRedirect(Route::_($redirect, false));
                break;

            default:
                // Clear the profile id from the session.
               
$app->setUserState('com_users.edit.profile.id', null);

                $redirect =
$app->getUserState('com_users.edit.profile.redirect',
'');

                // Don't redirect to an external URL.
                if (!Uri::isInternal($redirect)) {
                    $redirect = null;
                }

                if (!$redirect) {
                    $redirect =
'index.php?option=com_users&view=profile&user_id=' .
$return;
                }

                // Redirect to the list screen.
               
$this->setMessage(Text::_('COM_USERS_PROFILE_SAVE_SUCCESS'));
                $this->setRedirect(Route::_($redirect, false));
                break;
        }

        // Flush the data from the session.
        $app->setUserState('com_users.edit.profile.data',
null);
    }

    /**
     * Method to cancel an edit.
     *
     * @return  void
     *
     * @since   4.0.0
     */
    public function cancel()
    {
        // Check for request forgeries.
        $this->checkToken();

        // Flush the data from the session.
        $this->app->setUserState('com_users.edit.profile',
null);

        // Redirect to user profile.
       
$this->setRedirect(Route::_('index.php?option=com_users&view=profile',
false));
    }
}
src/Controller/CallbackController.php000064400000001210151165506250013727
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\Component\Users\Administrator\Controller\CallbackController as
AdminCallbackController;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Multi-factor Authentication plugins' AJAX callback controller
 *
 * @since 4.2.0
 */
class CallbackController extends AdminCallbackController
{
}
src/Controller/DisplayController.php000064400000011304151165506250013645
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Base controller class for Users.
 *
 * @since  1.5
 */
class DisplayController extends BaseController
{
    /**
     * Method to display a view.
     *
     * @param   boolean        $cachable   If true, the view output will be
cached
     * @param   array|boolean  $urlparams  An array of safe URL parameters
and their variable types.
     *                         @see       
\Joomla\CMS\Filter\InputFilter::clean() for valid values.
     *
     * @return  void
     *
     * @since   1.5
     * @throws  \Exception
     */
    public function display($cachable = false, $urlparams = false)
    {
        // Get the document object.
        $document = $this->app->getDocument();

        // Set the default view name and format from the Request.
        $vName   = $this->input->getCmd('view',
'login');
        $vFormat = $document->getType();
        $lName   = $this->input->getCmd('layout',
'default');

        if ($view = $this->getView($vName, $vFormat)) {
            // Do any specific processing by view.
            switch ($vName) {
                case 'registration':
                    // If the user is already logged in, redirect to the
profile page.
                    $user = $this->app->getIdentity();

                    if ($user->get('guest') != 1) {
                        // Redirect to profile page.
                       
$this->setRedirect(Route::_('index.php?option=com_users&view=profile',
false));

                        return;
                    }

                    // Check if user registration is enabled
                    if
(ComponentHelper::getParams('com_users')->get('allowUserRegistration')
== 0) {
                        // Registration is disabled - Redirect to login
page.
                       
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

                        return;
                    }

                    // The user is a guest, load the registration model and
show the registration page.
                    $model = $this->getModel('Registration');
                    break;

                case 'profile':
                    // Handle view specific models.
                    // If the user is a guest, redirect to the login page.
                    $user = $this->app->getIdentity();

                    if ($user->get('guest') == 1) {
                        // Redirect to login page.
                       
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

                        return;
                    }

                    $model = $this->getModel($vName);
                    break;

                case 'login':
                    // Handle the default views.
                    $model = $this->getModel($vName);
                    break;

                case 'remind':
                case 'reset':
                    // If the user is already logged in, redirect to the
profile page.
                    $user = $this->app->getIdentity();

                    if ($user->get('guest') != 1) {
                        // Redirect to profile page.
                       
$this->setRedirect(Route::_('index.php?option=com_users&view=profile',
false));

                        return;
                    }

                    $model = $this->getModel($vName);
                    break;

                case 'captive':
                case 'methods':
                case 'method':
                    $controller =
$this->factory->createController($vName, 'Site', [],
$this->app, $this->input);
                    $task       = $this->input->get('task',
'');

                    return $controller->execute($task);

                default:
                    $model = $this->getModel('Login');
                    break;
            }

            // Make sure we don't send a referer
            if (\in_array($vName, ['remind', 'reset']))
{
                $this->app->setHeader('Referrer-Policy',
'no-referrer', true);
            }

            // Push the model into the view (as default).
            $view->setModel($model, true);
            $view->setLayout($lName);

            // Push document object into the view.
            $view->document = $document;

            $view->display();
        }
    }
}
src/Controller/MethodsController.php000064400000002565151165506250013654
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Administrator\Controller\MethodsController as
AdminMethodsController;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Multi-factor Authentication methods selection and management controller
 *
 * @since 4.2.0
 */
class MethodsController extends AdminMethodsController
{
    /**
     * Execute a task by triggering a Method in the derived class.
     *
     * @param   string  $task    The task to perform.
     *
     * @return  mixed   The value returned by the called Method.
     *
     * @throws  \Exception
     * @since   4.2.0
     */
    public function execute($task)
    {
        try {
            return parent::execute($task);
        } catch (\Exception $e) {
            if ($e->getCode() !== 403) {
                throw $e;
            }

            if ($this->app->getIdentity()->guest) {
               
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

                return null;
            }
        }

        return null;
    }
}
src/Controller/RegistrationController.php000064400000022524151165506250014720
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Application\CMSWebApplicationInterface;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
use Joomla\CMS\User\UserFactoryAwareInterface;
use Joomla\CMS\User\UserFactoryAwareTrait;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Registration controller class for Users.
 *
 * @since  1.6
 */
class RegistrationController extends BaseController implements
UserFactoryAwareInterface
{
    use UserFactoryAwareTrait;

    /**
     * Method to activate a user.
     *
     * @return  boolean  True on success, false on failure.
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function activate()
    {
        $user    = $this->app->getIdentity();
        $input   = $this->input;
        $uParams = ComponentHelper::getParams('com_users');

        // Check for admin activation. Don't allow non-super-admin to
delete a super admin
        if ($uParams->get('useractivation') != 2 &&
$user->get('id')) {
            $this->setRedirect('index.php');

            return true;
        }

        // If user registration or account activation is disabled, throw a
403.
        if ($uParams->get('useractivation') == 0 ||
$uParams->get('allowUserRegistration') == 0) {
            throw new
\Exception(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'),
403);
        }

        /** @var \Joomla\Component\Users\Site\Model\RegistrationModel
$model */
        $model = $this->getModel('Registration',
'Site');
        $token = $input->getAlnum('token');

        // Check that the token is in a valid format.
        if ($token === null || \strlen($token) !== 32) {
            throw new \Exception(Text::_('JINVALID_TOKEN'), 403);
        }

        // Get the User ID
        $userIdToActivate = $model->getUserIdFromToken($token);

        if (!$userIdToActivate) {
           
$this->setMessage(Text::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

            return false;
        }

        // Get the user we want to activate
        $userToActivate =
$this->getUserFactory()->loadUserById($userIdToActivate);

        // Admin activation is on and admin is activating the account
        if (($uParams->get('useractivation') == 2) &&
$userToActivate->getParam('activate', 0)) {
            // If a user admin is not logged in, redirect them to the login
page with an error message
            if (!$user->authorise('core.create',
'com_users') || !$user->authorise('core.manage',
'com_users')) {
                $activationUrl =
'index.php?option=com_users&task=registration.activate&token='
. $token;
                $loginUrl      =
'index.php?option=com_users&view=login&return=' .
base64_encode($activationUrl);

                // In case we still run into this in the second step the
user does not have the right permissions
                $message =
Text::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION_PERMISSIONS');

                // When we are not logged in we should login
                if ($user->guest) {
                    $message =
Text::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION');
                }

                $this->setMessage($message);
                $this->setRedirect(Route::_($loginUrl, false));

                return false;
            }
        }

        // Attempt to activate the user.
        $return = $model->activate($token);

        // Check for errors.
        if ($return === false) {
            // Redirect back to the home page.
           
$this->setMessage(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED',
$model->getError()), 'error');
            $this->setRedirect('index.php');

            return false;
        }

        $useractivation = $uParams->get('useractivation');

        // Redirect to the login screen.
        if ($useractivation == 0) {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));
        } elseif ($useractivation == 1) {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_ACTIVATE_SUCCESS'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));
        } elseif ($return->getParam('activate')) {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_VERIFY_SUCCESS'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete',
false));
        } else {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_ADMINACTIVATE_SUCCESS'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete',
false));
        }

        return true;
    }

    /**
     * Method to register a user.
     *
     * @return  boolean  True on success, false on failure.
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function register()
    {
        // Check for request forgeries.
        $this->checkToken();

        // If registration is disabled - Redirect to login page.
        if
(ComponentHelper::getParams('com_users')->get('allowUserRegistration')
== 0) {
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

            return false;
        }

        $app   = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\RegistrationModel
$model */
        $model = $this->getModel('Registration',
'Site');

        // Get the user data.
        $requestData = $this->input->post->get('jform',
[], 'array');

        // Validate the posted data.
        $form = $model->getForm();

        if (!$form) {
            throw new \Exception($model->getError(), 500);
        }

        $data = $model->validate($form, $requestData);

        // Check for validation errors.
        if ($data === false) {
            // Get the validation messages.
            $errors = $model->getErrors();

            // Push up to three validation messages out to the user.
            for ($i = 0, $n = \count($errors); $i < $n && $i
< 3; $i++) {
                if ($errors[$i] instanceof \Exception) {
                    $app->enqueueMessage($errors[$i]->getMessage(),
CMSWebApplicationInterface::MSG_ERROR);
                } else {
                    $app->enqueueMessage($errors[$i],
CMSWebApplicationInterface::MSG_ERROR);
                }
            }

            /**
             * We need the filtered value of calendar fields because the
UTC normalisation is
             * done in the filter and on output. This would apply the
Timezone offset on
             * reload. We set the calendar values we save to the processed
date.
             */
            $filteredData = $form->filter($requestData);

            foreach ($form->getFieldset() as $field) {
                if ($field->type === 'Calendar') {
                    $fieldName = $field->fieldname;

                    if ($field->group) {
                        if
(isset($filteredData[$field->group][$fieldName])) {
                            $requestData[$field->group][$fieldName] =
$filteredData[$field->group][$fieldName];
                        }
                    } else {
                        if (isset($filteredData[$fieldName])) {
                            $requestData[$fieldName] =
$filteredData[$fieldName];
                        }
                    }
                }
            }

            // Save the data in the session.
            $app->setUserState('com_users.registration.data',
$requestData);

            // Redirect back to the registration screen.
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration',
false));

            return false;
        }

        // Attempt to save the data.
        $return = $model->register($data);

        // Check for errors.
        if ($return === false) {
            // Save the data in the session.
            $app->setUserState('com_users.registration.data',
$data);

            // Redirect back to the edit screen.
            $this->setMessage($model->getError(), 'error');
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration',
false));

            return false;
        }

        // Flush the data from the session.
        $app->setUserState('com_users.registration.data',
null);

        // Redirect to the profile screen.
        if ($return === 'adminactivate') {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_COMPLETE_VERIFY'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete',
false));
        } elseif ($return === 'useractivate') {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_COMPLETE_ACTIVATE'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=registration&layout=complete',
false));
        } else {
           
$this->setMessage(Text::_('COM_USERS_REGISTRATION_SAVE_SUCCESS'));
           
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));
        }

        return true;
    }
}
src/Controller/RemindController.php000064400000003377151165506250013471
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Reset controller class for Users.
 *
 * @since  1.6
 */
class RemindController extends BaseController
{
    /**
     * Method to request a username reminder.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function remind()
    {
        // Check the request token.
        $this->checkToken('post');

        /** @var \Joomla\Component\Users\Site\Model\RemindModel $model */
        $model = $this->getModel('Remind', 'Site');
        $data  = $this->input->post->get('jform', [],
'array');

        // Submit the password reset request.
        $return = $model->processRemindRequest($data);

        // Check for a hard error.
        if ($return == false && JDEBUG) {
            // The request failed.
            // Go back to the request form.
            $message =
Text::sprintf('COM_USERS_REMIND_REQUEST_FAILED',
$model->getError());
           
$this->setRedirect(Route::_('index.php?option=com_users&view=remind',
false), $message, 'notice');

            return false;
        }

        // To not expose if the user exists or not we send a generic
message.
        $message = Text::_('COM_USERS_REMIND_REQUEST');
       
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false), $message, 'notice');

        return true;
    }
}
src/Controller/CaptiveController.php000064400000002541151165506250013636
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Administrator\Controller\CaptiveController as
AdminCaptiveController;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Captive Multi-factor Authentication page controller
 *
 * @since 4.2.0
 */
class CaptiveController extends AdminCaptiveController
{
    /**
     * Execute a task by triggering a Method in the derived class.
     *
     * @param   string  $task    The task to perform.
     *
     * @return  mixed   The value returned by the called Method.
     *
     * @throws  \Exception
     * @since   4.2.0
     */
    public function execute($task)
    {
        try {
            return parent::execute($task);
        } catch (\Exception $e) {
            if ($e->getCode() !== 403) {
                throw $e;
            }

            if ($this->app->getIdentity()->guest) {
               
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

                return null;
            }
        }

        return null;
    }
}
src/Controller/ResetController.php000064400000013131151165506250013322
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Reset controller class for Users.
 *
 * @since  1.6
 */
class ResetController extends BaseController
{
    /**
     * Method to request a password reset.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function request()
    {
        // Check the request token.
        $this->checkToken('post');

        $app   = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
        $model = $this->getModel('Reset', 'Site');
        $data  = $this->input->post->get('jform', [],
'array');

        // Submit the password reset request.
        $return = $model->processResetRequest($data);

        // Check for a hard error.
        if ($return instanceof \Exception && JDEBUG) {
            // Get the error message to display.
            if ($app->get('error_reporting')) {
                $message = $return->getMessage();
            } else {
                $message =
Text::_('COM_USERS_RESET_REQUEST_ERROR');
            }

            // Go back to the request form.
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset',
false), $message, 'error');

            return false;
        }

        if ($return === false && JDEBUG) {
            // The request failed.
            // Go back to the request form.
            $message =
Text::sprintf('COM_USERS_RESET_REQUEST_FAILED',
$model->getError());
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset',
false), $message, 'notice');

            return false;
        }

        // To not expose if the user exists or not we send a generic
message.
        $message = Text::_('COM_USERS_RESET_REQUEST');
       
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'notice');

        return true;
    }

    /**
     * Method to confirm the password request.
     *
     * @return  boolean
     *
     * @access  public
     * @since   1.6
     */
    public function confirm()
    {
        // Check the request token.
        $this->checkToken('request');

        $app   = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
        $model = $this->getModel('Reset', 'Site');
        $data  = $this->input->get('jform', [],
'array');

        // Confirm the password reset request.
        $return = $model->processResetConfirm($data);

        // Check for a hard error.
        if ($return instanceof \Exception) {
            // Get the error message to display.
            if ($app->get('error_reporting')) {
                $message = $return->getMessage();
            } else {
                $message =
Text::_('COM_USERS_RESET_CONFIRM_ERROR');
            }

            // Go back to the confirm form.
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'error');

            return false;
        }

        if ($return === false) {
            // Confirm failed.
            // Go back to the confirm form.
            $message =
Text::sprintf('COM_USERS_RESET_CONFIRM_FAILED',
$model->getError());
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=confirm',
false), $message, 'notice');

            return false;
        }

        // Confirm succeeded.
        // Proceed to step three.
       
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete',
false));

        return true;
    }

    /**
     * Method to complete the password reset process.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function complete()
    {
        // Check for request forgeries
        $this->checkToken('post');

        $app   = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\ResetModel $model */
        $model = $this->getModel('Reset', 'Site');
        $data  = $this->input->post->get('jform', [],
'array');

        // Complete the password reset request.
        $return = $model->processResetComplete($data);

        // Check for a hard error.
        if ($return instanceof \Exception) {
            // Get the error message to display.
            if ($app->get('error_reporting')) {
                $message = $return->getMessage();
            } else {
                $message =
Text::_('COM_USERS_RESET_COMPLETE_ERROR');
            }

            // Go back to the complete form.
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete',
false), $message, 'error');

            return false;
        }

        if ($return === false) {
            // Complete failed.
            // Go back to the complete form.
            $message =
Text::sprintf('COM_USERS_RESET_COMPLETE_FAILED',
$model->getError());
           
$this->setRedirect(Route::_('index.php?option=com_users&view=reset&layout=complete',
false), $message, 'notice');

            return false;
        }

        // Complete succeeded.
        // Proceed to the login form.
        $message = Text::_('COM_USERS_RESET_COMPLETE_SUCCESS');
       
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false), $message);

        return true;
    }
}
src/Controller/MethodController.php000064400000002527151165506250013467
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Router\Route;
use Joomla\Component\Users\Administrator\Controller\MethodController as
AdminMethodController;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Multi-factor Authentication method controller
 *
 * @since 4.2.0
 */
class MethodController extends AdminMethodController
{
    /**
     * Execute a task by triggering a Method in the derived class.
     *
     * @param   string  $task    The task to perform.
     *
     * @return  mixed   The value returned by the called Method.
     *
     * @throws  \Exception
     * @since   4.2.0
     */
    public function execute($task)
    {
        try {
            return parent::execute($task);
        } catch (\Exception $e) {
            if ($e->getCode() !== 403) {
                throw $e;
            }

            if ($this->app->getIdentity()->guest) {
               
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false));

                return null;
            }
        }

        return null;
    }
}
src/Controller/UserController.php000064400000020743151165506250013165
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Controller;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Uri\Uri;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Registration controller class for Users.
 *
 * @since  1.6
 */
class UserController extends BaseController
{
    /**
     * Method to log in a user.
     *
     * @return  void
     *
     * @since   1.6
     */
    public function login()
    {
        $this->checkToken('post');

        $input = $this->input->getInputForRequestMethod();

        // Populate the data array:
        $data = [];

        $data['return']    =
base64_decode($input->get('return', '',
'BASE64'));
        $data['username']  = $input->get('username',
'', 'USERNAME');
        $data['password']  = $input->get('password',
'', 'RAW');
        $data['secretkey'] =
$input->get('secretkey', '', 'RAW');

        // Check for a simple menu item id
        if (is_numeric($data['return'])) {
            $itemId         = (int) $data['return'];
            $data['return'] = 'index.php?Itemid=' .
$itemId;

            if (Multilanguage::isEnabled()) {
                $language = $this->getModel('Login',
'Site')->getMenuLanguage($itemId);

                if ($language !== '*') {
                    $data['return'] .= '&lang=' .
$language;
                }
            }
        } elseif (!Uri::isInternal($data['return'])) {
            // Don't redirect to an external URL.
            $data['return'] = '';
        }

        // Set the return URL if empty.
        if (empty($data['return'])) {
            $data['return'] =
'index.php?option=com_users&view=profile';
        }

        // Set the return URL in the user state to allow modification by
plugins
        $this->app->setUserState('users.login.form.return',
$data['return']);

        // Get the log in options.
        $options             = [];
        $options['remember'] =
$this->input->getBool('remember', false);
        $options['return']   = $data['return'];

        // Get the log in credentials.
        $credentials              = [];
        $credentials['username']  = $data['username'];
        $credentials['password']  = $data['password'];
        $credentials['secretkey'] = $data['secretkey'];

        // Perform the log in.
        if (true !== $this->app->login($credentials, $options)) {
            // Login failed !
            // Clear user name, password and secret key before sending the
login form back to the user.
            $data['remember']  = (int)
$options['remember'];
            $data['username']  = '';
            $data['password']  = '';
            $data['secretkey'] = '';
           
$this->app->setUserState('users.login.form.data', $data);
           
$this->app->redirect(Route::_('index.php?option=com_users&view=login',
false));
        }

        // Success
        if ($options['remember'] == true) {
            $this->app->setUserState('rememberLogin',
true);
        }

        $this->app->setUserState('users.login.form.data',
[]);

       
$this->app->redirect(Route::_($this->app->getUserState('users.login.form.return'),
false));
    }

    /**
     * Method to log out a user.
     *
     * @return  void
     *
     * @since   1.6
     */
    public function logout()
    {
        $this->checkToken('request');

        $app = $this->app;

        // Prepare the logout options.
        $options = [
            'clientid' =>
$app->get('shared_session', '0') ? null : 0,
        ];

        // Perform the log out.
        $error = $app->logout(null, $options);
        $input = $app->getInput()->getInputForRequestMethod();

        // Check if the log out succeeded.
        if ($error instanceof \Exception) {
           
$app->redirect(Route::_('index.php?option=com_users&view=login',
false));
        }

        // Get the return URL from the request and validate that it is
internal.
        $return = $input->get('return', '',
'BASE64');
        $return = base64_decode($return);

        // Check for a simple menu item id
        if (is_numeric($return)) {
            $itemId = (int) $return;
            $return = 'index.php?Itemid=' . $itemId;

            if (Multilanguage::isEnabled()) {
                $language = $this->getModel('Login',
'Site')->getMenuLanguage($itemId);

                if ($language !== '*') {
                    $return .= '&lang=' . $language;
                }
            }
        } elseif (!Uri::isInternal($return)) {
            $return = '';
        }

        // In case redirect url is not set, redirect user to homepage
        if (empty($return)) {
            $return = Uri::root();
        }

        // Show a message when a user is logged out.
       
$app->enqueueMessage(Text::_('COM_USERS_FRONTEND_LOGOUT_SUCCESS'),
'message');

        // Redirect the user.
        $app->redirect(Route::_($return, false));
    }

    /**
     * Method to logout directly and redirect to page.
     *
     * @return  void
     *
     * @since   3.5
     */
    public function menulogout()
    {
        // Get the ItemID of the page to redirect after logout
        $app    = $this->app;
        $active = $app->getMenu()->getActive();
        $itemid = $active ?
$active->getParams()->get('logout') : 0;

        // Get the language of the page when multilang is on
        if (Multilanguage::isEnabled()) {
            if ($itemid) {
                $language = $this->getModel('Login',
'Site')->getMenuLanguage($itemid);

                // URL to redirect after logout
                $url = 'index.php?Itemid=' . $itemid . ($language
!== '*' ? '&lang=' . $language : '');
            } else {
                // Logout is set to default. Get the home page ItemID
                $lang_code =
$app->getInput()->cookie->getString(ApplicationHelper::getHash('language'));
                $item      = $app->getMenu()->getDefault($lang_code);
                $itemid    = $item->id;

                // Redirect to Home page after logout
                $url = 'index.php?Itemid=' . $itemid;
            }
        } else {
            // URL to redirect after logout, default page if no ItemID is
set
            $url = $itemid ? 'index.php?Itemid=' . $itemid :
Uri::root();
        }

        // Logout and redirect
       
$this->setRedirect(Route::_('index.php?option=com_users&task=user.logout&'
. Session::getFormToken() . '=1&return=' .
base64_encode($url), false));
    }

    /**
     * Method to request a username reminder.
     *
     * @return  boolean
     *
     * @since   1.6
     */
    public function remind()
    {
        // Check the request token.
        $this->checkToken('post');

        $app   = $this->app;

        /** @var \Joomla\Component\Users\Site\Model\RemindModel $model */
        $model = $this->getModel('Remind', 'Site');
        $data  = $this->input->post->get('jform', [],
'array');

        // Submit the username remind request.
        $return = $model->processRemindRequest($data);

        // Check for a hard error.
        if ($return instanceof \Exception) {
            // Get the error message to display.
            $message = $app->get('error_reporting')
                ? $return->getMessage()
                : Text::_('COM_USERS_REMIND_REQUEST_ERROR');

            // Go back to the complete form.
           
$this->setRedirect(Route::_('index.php?option=com_users&view=remind',
false), $message, 'error');

            return false;
        }

        if ($return === false) {
            // Go back to the complete form.
            $message =
Text::sprintf('COM_USERS_REMIND_REQUEST_FAILED',
$model->getError());
           
$this->setRedirect(Route::_('index.php?option=com_users&view=remind',
false), $message, 'notice');

            return false;
        }

        // Proceed to the login form.
        $message = Text::_('COM_USERS_REMIND_REQUEST_SUCCESS');
       
$this->setRedirect(Route::_('index.php?option=com_users&view=login',
false), $message);

        return true;
    }

    /**
     * Method to resend a user.
     *
     * @return  void
     *
     * @since   1.6
     */
    public function resend()
    {
        // Check for request forgeries
        // $this->checkToken('post');
    }
}
src/View/Login/HtmlView.php000064400000007522151165506250011601
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Login;

use Joomla\CMS\Factory;
use Joomla\CMS\Helper\AuthenticationHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\User\User;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Login view class for Users.
 *
 * @since  1.5
 */
class HtmlView extends BaseHtmlView
{
    /**
     * The Form object
     *
     * @var  \Joomla\CMS\Form\Form
     */
    protected $form;

    /**
     * The page parameters
     *
     * @var  \Joomla\Registry\Registry|null
     */
    protected $params;

    /**
     * The model state
     *
     * @var  \Joomla\Registry\Registry
     */
    protected $state;

    /**
     * The logged in user
     *
     * @var  User
     */
    protected $user;

    /**
     * The page class suffix
     *
     * @var    string
     * @since  4.0.0
     */
    protected $pageclass_sfx = '';

    /**
     * No longer used
     *
     * @var    boolean
     * @since  4.0.0
     *
     * @deprecated  4.3 will be removed in 6.0
     *              Will be removed without replacement
     */
    protected $tfa = false;

    /**
     * Additional buttons to show on the login page
     *
     * @var    array
     * @since  4.0.0
     */
    protected $extraButtons = [];

    /**
     * Method to display the view.
     *
     * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
     *
     * @return  void
     *
     * @since   1.5
     * @throws  \Exception
     */
    public function display($tpl = null)
    {
        // Get the view data.
        $this->user   = $this->getCurrentUser();
        $this->form   = $this->get('Form');
        $this->state  = $this->get('State');
        $this->params = $this->state->get('params');

        // Check for errors.
        if (\count($errors = $this->get('Errors'))) {
            throw new GenericDataException(implode("\n",
$errors), 500);
        }

        // Check for layout override
        $active = Factory::getApplication()->getMenu()->getActive();

        if (isset($active->query['layout'])) {
            $this->setLayout($active->query['layout']);
        }

        $this->extraButtons =
AuthenticationHelper::getLoginButtons('com-users-login__form');

        // Escape strings for HTML output
        $this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

        $this->prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function prepareDocument()
    {
        $login = (bool)
$this->getCurrentUser()->get('guest');

        // Because the application sets a default page title,
        // we need to get it from the menu item itself
        $menu = Factory::getApplication()->getMenu()->getActive();

        if ($menu) {
            $this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
        } else {
            $this->params->def('page_heading', $login ?
Text::_('JLOGIN') : Text::_('JLOGOUT'));
        }

       
$this->setDocumentTitle($this->params->get('page_title',
''));

        if ($this->params->get('menu-meta_description')) {
           
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->params->get('robots')) {
            $this->getDocument()->setMetaData('robots',
$this->params->get('robots'));
        }
    }
}
src/View/Registration/HtmlView.php000064400000007542151165506250013205
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Registration;

use Joomla\CMS\Document\HtmlDocument;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Plugin\PluginHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Registration view class for Users.
 *
 * @since  1.6
 */
class HtmlView extends BaseHtmlView
{
    /**
     * Registration form data
     *
     * @var  \stdClass|false
     */
    protected $data;

    /**
     * The Form object
     *
     * @var  \Joomla\CMS\Form\Form
     */
    protected $form;

    /**
     * The page parameters
     *
     * @var  \Joomla\Registry\Registry|null
     */
    protected $params;

    /**
     * The model state
     *
     * @var  \Joomla\Registry\Registry
     */
    protected $state;

    /**
     * The HtmlDocument instance
     *
     * @var  HtmlDocument
     */
    public $document;

    /**
     * Should we show a captcha form for the submission of the article?
     *
     * @var    boolean
     *
     * @since  3.7.0
     */
    protected $captchaEnabled = false;

    /**
     * The page class suffix
     *
     * @var    string
     * @since  4.0.0
     */
    protected $pageclass_sfx = '';

    /**
     * Method to display the view.
     *
     * @param   string  $tpl  The template file to include
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function display($tpl = null)
    {
        // Get the view data.
        $this->form   = $this->get('Form');
        $this->data   = $this->get('Data');
        $this->state  = $this->get('State');
        $this->params = $this->state->get('params');

        // Check for errors.
        if (\count($errors = $this->get('Errors'))) {
            throw new GenericDataException(implode("\n",
$errors), 500);
        }

        // Check for layout override
        $active = Factory::getApplication()->getMenu()->getActive();

        if (isset($active->query['layout'])) {
            $this->setLayout($active->query['layout']);
        }

        $captchaSet = $this->params->get('captcha',
Factory::getApplication()->get('captcha', '0'));

        foreach (PluginHelper::getPlugin('captcha') as $plugin) {
            if ($captchaSet === $plugin->name) {
                $this->captchaEnabled = true;
                break;
            }
        }

        // Escape strings for HTML output
        $this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

        $this->prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function prepareDocument()
    {
        // Because the application sets a default page title,
        // we need to get it from the menu item itself
        $menu = Factory::getApplication()->getMenu()->getActive();

        if ($menu) {
            $this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
        } else {
            $this->params->def('page_heading',
Text::_('COM_USERS_REGISTRATION'));
        }

       
$this->setDocumentTitle($this->params->get('page_title',
''));

        if ($this->params->get('menu-meta_description')) {
           
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->params->get('robots')) {
            $this->getDocument()->setMetaData('robots',
$this->params->get('robots'));
        }
    }
}
src/View/Profile/HtmlView.php000064400000012710151165506250012124
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Profile;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Object\CMSObject;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\User\User;
use Joomla\Component\Users\Administrator\Helper\Mfa;
use Joomla\Database\DatabaseDriver;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Profile view class for Users.
 *
 * @since  1.6
 */
class HtmlView extends BaseHtmlView
{
    /**
     * Profile form data for the user
     *
     * @var  User
     */
    protected $data;

    /**
     * The Form object
     *
     * @var  \Joomla\CMS\Form\Form
     */
    protected $form;

    /**
     * The page parameters
     *
     * @var  \Joomla\Registry\Registry|null
     */
    protected $params;

    /**
     * The model state
     *
     * @var  \Joomla\Registry\Registry
     */
    protected $state;

    /**
     * An instance of DatabaseDriver.
     *
     * @var    DatabaseDriver
     * @since  3.6.3
     *
     * @deprecated  4.3 will be removed in 6.0
     *              Will be removed without replacement use database from
the container instead
     *              Example:
Factory::getContainer()->get(DatabaseInterface::class);
     */
    protected $db;

    /**
     * The page class suffix
     *
     * @var    string
     * @since  4.0.0
     */
    protected $pageclass_sfx = '';

    /**
     * The Multi-factor Authentication configuration interface for the
user.
     *
     * @var   string|null
     * @since 4.2.0
     */
    protected $mfaConfigurationUI;

    /**
     * Execute and display a template script.
     *
     * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
     *
     * @return  void|boolean
     *
     * @since   1.6
     * @throws  \Exception
     */
    public function display($tpl = null)
    {
        $user = $this->getCurrentUser();

        // Get the view data.
        $this->data               = $this->get('Data');
        $this->form               = $this->getModel()->getForm(new
CMSObject(['id' => $user->id]));
        $this->state              = $this->get('State');
        $this->params             =
$this->state->get('params');
        $this->mfaConfigurationUI =
Mfa::getConfigurationInterface($user);
        $this->db                 = Factory::getDbo();

        // Check for errors.
        if (\count($errors = $this->get('Errors'))) {
            throw new GenericDataException(implode("\n",
$errors), 500);
        }

        // View also takes responsibility for checking if the user logged
in with remember me.
        $cookieLogin = $user->get('cookieLogin');

        if (!empty($cookieLogin)) {
            // If so, the user must login to edit the password and other
data.
            // What should happen here? Should we force a logout which
destroys the cookies?
            $app = Factory::getApplication();
           
$app->enqueueMessage(Text::_('JGLOBAL_REMEMBER_MUST_LOGIN'),
'message');
           
$app->redirect(Route::_('index.php?option=com_users&view=login',
false));

            return false;
        }

        // Check if a user was found.
        if (!$this->data->id) {
            throw new
\Exception(Text::_('JERROR_USERS_PROFILE_NOT_FOUND'), 404);
        }

        PluginHelper::importPlugin('content');
        $this->data->text = '';
       
Factory::getApplication()->triggerEvent('onContentPrepare',
['com_users.user', &$this->data,
&$this->data->params, 0]);
        unset($this->data->text);

        // Check for layout from menu item.
        $active = Factory::getApplication()->getMenu()->getActive();

        if (
            $active && isset($active->query['layout'])
            && isset($active->query['option'])
&& $active->query['option'] === 'com_users'
            && isset($active->query['view'])
&& $active->query['view'] === 'profile'
        ) {
            $this->setLayout($active->query['layout']);
        }

        // Escape strings for HTML output
        $this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''));

        $this->prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function prepareDocument()
    {
        // Because the application sets a default page title,
        // we need to get it from the menu item itself
        $menu = Factory::getApplication()->getMenu()->getActive();

        if ($menu) {
            $this->params->def('page_heading',
$this->params->get('page_title',
$this->getCurrentUser()->name));
        } else {
            $this->params->def('page_heading',
Text::_('COM_USERS_PROFILE'));
        }

       
$this->setDocumentTitle($this->params->get('page_title',
''));

        if ($this->params->get('menu-meta_description')) {
           
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->params->get('robots')) {
            $this->getDocument()->setMetaData('robots',
$this->params->get('robots'));
        }
    }
}
src/View/Remind/HtmlView.php000064400000006021151165506250011740
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Remind;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Remind view class for Users.
 *
 * @since  1.5
 */
class HtmlView extends BaseHtmlView
{
    /**
     * The Form object
     *
     * @var  \Joomla\CMS\Form\Form
     */
    protected $form;

    /**
     * The page parameters
     *
     * @var  \Joomla\Registry\Registry|null
     */
    protected $params;

    /**
     * The model state
     *
     * @var  \Joomla\Registry\Registry
     */
    protected $state;

    /**
     * The page class suffix
     *
     * @var    string
     * @since  4.0.0
     */
    protected $pageclass_sfx = '';

    /**
     * Method to display the view.
     *
     * @param   string  $tpl  The template file to include
     *
     * @return  void
     *
     * @since   1.5
     * @throws  \Exception
     */
    public function display($tpl = null)
    {
        // Get the view data.
        $this->form   = $this->get('Form');
        $this->state  = $this->get('State');
        $this->params = $this->state->params;

        // Check for errors.
        if (\count($errors = $this->get('Errors'))) {
            throw new GenericDataException(implode("\n",
$errors), 500);
        }

        // Check for layout override
        $active = Factory::getApplication()->getMenu()->getActive();

        if (isset($active->query['layout'])) {
            $this->setLayout($active->query['layout']);
        }

        // Escape strings for HTML output
        $this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

        $this->prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function prepareDocument()
    {
        // Because the application sets a default page title,
        // we need to get it from the menu item itself
        $menu = Factory::getApplication()->getMenu()->getActive();

        if ($menu) {
            $this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
        } else {
            $this->params->def('page_heading',
Text::_('COM_USERS_REMIND'));
        }

       
$this->setDocumentTitle($this->params->get('page_title',
''));

        if ($this->params->get('menu-meta_description')) {
           
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->params->get('robots')) {
            $this->getDocument()->setMetaData('robots',
$this->params->get('robots'));
        }
    }
}
src/View/Method/HtmlView.php000064400000001072151165506250011743
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Method;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * View for Multi-factor Authentication method add/edit page
 *
 * @since 4.2.0
 */
class HtmlView extends
\Joomla\Component\Users\Administrator\View\Method\HtmlView
{
}
src/View/Methods/HtmlView.php000064400000001071151165506250012125
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Methods;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * View for Multi-factor Authentication methods list page
 *
 * @since 4.2.0
 */
class HtmlView extends
\Joomla\Component\Users\Administrator\View\Methods\HtmlView
{
}
src/View/Captive/HtmlView.php000064400000001064151165506250012117
0ustar00<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2022 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Captive;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * View for Multi-factor Authentication captive page
 *
 * @since 4.2.0
 */
class HtmlView extends
\Joomla\Component\Users\Administrator\View\Captive\HtmlView
{
}
src/View/Reset/HtmlView.php000064400000006300151165506250011604
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\View\Reset;

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Reset view class for Users.
 *
 * @since  1.5
 */
class HtmlView extends BaseHtmlView
{
    /**
     * The Form object
     *
     * @var  \Joomla\CMS\Form\Form
     */
    protected $form;

    /**
     * The page parameters
     *
     * @var  \Joomla\Registry\Registry|null
     */
    protected $params;

    /**
     * The model state
     *
     * @var  \Joomla\Registry\Registry
     */
    protected $state;

    /**
     * The page class suffix
     *
     * @var    string
     * @since  4.0.0
     */
    protected $pageclass_sfx = '';

    /**
     * Method to display the view.
     *
     * @param   string  $tpl  The template file to include
     *
     * @return  void
     *
     * @since   1.5
     */
    public function display($tpl = null)
    {
        // This name will be used to get the model
        $name = $this->getLayout();

        // Check that the name is valid - has an associated model.
        if (!\in_array($name, ['confirm', 'complete']))
{
            $name = 'default';
        }

        if ('default' === $name) {
            $formname = 'Form';
        } else {
            $formname = ucfirst($this->_name) . ucfirst($name) .
'Form';
        }

        // Get the view data.
        $this->form   = $this->get($formname);
        $this->state  = $this->get('State');
        $this->params = $this->state->params;

        // Check for errors.
        if (\count($errors = $this->get('Errors'))) {
            throw new GenericDataException(implode("\n",
$errors), 500);
        }

        // Escape strings for HTML output
        $this->pageclass_sfx =
htmlspecialchars($this->params->get('pageclass_sfx',
''), ENT_COMPAT, 'UTF-8');

        $this->prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document.
     *
     * @return  void
     *
     * @since   1.6
     * @throws  \Exception
     */
    protected function prepareDocument()
    {
        // Because the application sets a default page title,
        // we need to get it from the menu item itself
        $menu = Factory::getApplication()->getMenu()->getActive();

        if ($menu) {
            $this->params->def('page_heading',
$this->params->get('page_title', $menu->title));
        } else {
            $this->params->def('page_heading',
Text::_('COM_USERS_RESET'));
        }

       
$this->setDocumentTitle($this->params->get('page_title',
''));

        if ($this->params->get('menu-meta_description')) {
           
$this->getDocument()->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->params->get('robots')) {
            $this->getDocument()->setMetaData('robots',
$this->params->get('robots'));
        }
    }
}
src/Rule/LogoutUniqueFieldRule.php000064400000005022151165506250013214
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2017 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Rule;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * FormRule for com_users to be sure only one redirect logout field has a
value
 *
 * @since  3.6
 */
class LogoutUniqueFieldRule extends FormRule
{
    /**
     * Method to test if two fields have a value in order to use only one
field.
     * To use this rule, the form
     * XML needs a validate attribute of logoutuniquefield and a field
attribute
     * that is equal to the field to test against.
     *
     * @param   \SimpleXMLElement  $element  The SimpleXMLElement object
representing the `<field>` tag for the form field object.
     * @param   mixed              $value    The form field value to
validate.
     * @param   string             $group    The field name group control
value. This acts as an array container for the field.
     *                                       For example if the field has
name="foo" and the group value is set to "bar" then the
     *                                       full field name would end up
being "bar[foo]".
     * @param   Registry           $input    An optional Registry object
with the entire data set to validate against the entire form.
     * @param   Form               $form     The form object for which the
field is being tested.
     *
     * @return  boolean  True if the value is valid, false otherwise.
     *
     * @since   3.6
     */
    public function test(\SimpleXMLElement $element, $value, $group = null,
Registry $input = null, Form $form = null)
    {
        $logoutRedirectUrl      =
$input['params']->logout_redirect_url;
        $logoutRedirectMenuitem =
$input['params']->logout_redirect_menuitem;

        if ($form === null) {
            throw new \InvalidArgumentException(sprintf('The value for
$form must not be null in %s', \get_class($this)));
        }

        if ($input === null) {
            throw new \InvalidArgumentException(sprintf('The value for
$input must not be null in %s', \get_class($this)));
        }

        // Test the input values for logout.
        if ($logoutRedirectUrl != '' &&
$logoutRedirectMenuitem != '') {
            return false;
        }

        return true;
    }
}
src/Rule/LoginUniqueFieldRule.php000064400000005012151165506250013012
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_users
 *
 * @copyright   (C) 2017 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Users\Site\Rule;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * FormRule for com_users to be sure only one redirect login field has a
value
 *
 * @since  3.6
 */
class LoginUniqueFieldRule extends FormRule
{
    /**
     * Method to test if two fields have a value in order to use only one
field.
     * To use this rule, the form
     * XML needs a validate attribute of loginuniquefield and a field
attribute
     * that is equal to the field to test against.
     *
     * @param   \SimpleXMLElement  $element  The SimpleXMLElement object
representing the `<field>` tag for the form field object.
     * @param   mixed              $value    The form field value to
validate.
     * @param   string             $group    The field name group control
value. This acts as an array container for the field.
     *                                       For example if the field has
name="foo" and the group value is set to "bar" then the
     *                                       full field name would end up
being "bar[foo]".
     * @param   Registry           $input    An optional Registry object
with the entire data set to validate against the entire form.
     * @param   Form               $form     The form object for which the
field is being tested.
     *
     * @return  boolean  True if the value is valid, false otherwise.
     *
     * @since   3.6
     */
    public function test(\SimpleXMLElement $element, $value, $group = null,
Registry $input = null, Form $form = null)
    {
        $loginRedirectUrl       =
$input['params']->login_redirect_url;
        $loginRedirectMenuitem  =
$input['params']->login_redirect_menuitem;

        if ($form === null) {
            throw new \InvalidArgumentException(sprintf('The value for
$form must not be null in %s', \get_class($this)));
        }

        if ($input === null) {
            throw new \InvalidArgumentException(sprintf('The value for
$input must not be null in %s', \get_class($this)));
        }

        // Test the input values for login.
        if ($loginRedirectUrl != '' &&
$loginRedirectMenuitem != '') {
            return false;
        }

        return true;
    }
}
access.xml000064400000005200151165673530006540 0ustar00<?xml
version="1.0" encoding="utf-8" ?>
<access component="com_users">
	<section name="component">
		<action name="core.admin" title="JACTION_ADMIN"
description="JACTION_ADMIN_COMPONENT_DESC" />
		<action name="core.options"
title="JACTION_OPTIONS"
description="JACTION_OPTIONS_COMPONENT_DESC" />
		<action name="core.manage" title="JACTION_MANAGE"
description="JACTION_MANAGE_COMPONENT_DESC" />
		<action name="core.create" title="JACTION_CREATE"
description="JACTION_CREATE_COMPONENT_DESC" />
		<action name="core.delete" title="JACTION_DELETE"
description="JACTION_DELETE_COMPONENT_DESC" />
		<action name="core.edit" title="JACTION_EDIT"
description="JACTION_EDIT_COMPONENT_DESC" />
		<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="JACTION_EDITSTATE_COMPONENT_DESC" />
		<action name="core.edit.value"
title="JACTION_EDITVALUE"
description="JACTION_EDITVALUE_COMPONENT_DESC" />
	</section>
	<section name="category">
		<action name="core.create" title="JACTION_CREATE"
description="COM_CATEGORIES_ACCESS_CREATE_DESC" />
		<action name="core.delete" title="JACTION_DELETE"
description="COM_CATEGORIES_ACCESS_DELETE_DESC" />
		<action name="core.edit" title="JACTION_EDIT"
description="COM_CATEGORIES_ACCESS_EDIT_DESC" />
		<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="COM_CATEGORIES_ACCESS_EDITSTATE_DESC" />
		<action name="core.edit.own"
title="JACTION_EDITOWN"
description="COM_CATEGORIES_ACCESS_EDITOWN_DESC" />
	</section>
	<section name="fieldgroup">
		<action name="core.create" title="JACTION_CREATE"
description="COM_FIELDS_GROUP_PERMISSION_CREATE_DESC" />
		<action name="core.delete" title="JACTION_DELETE"
description="COM_FIELDS_GROUP_PERMISSION_DELETE_DESC" />
		<action name="core.edit" title="JACTION_EDIT"
description="COM_FIELDS_GROUP_PERMISSION_EDIT_DESC" />
		<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="COM_FIELDS_GROUP_PERMISSION_EDITSTATE_DESC" />
		<action name="core.edit.own"
title="JACTION_EDITOWN"
description="COM_FIELDS_GROUP_PERMISSION_EDITOWN_DESC" />
		<action name="core.edit.value"
title="JACTION_EDITVALUE"
description="COM_FIELDS_GROUP_PERMISSION_EDITVALUE_DESC" />
	</section>
	<section name="field">
		<action name="core.delete" title="JACTION_DELETE"
description="COM_FIELDS_FIELD_PERMISSION_DELETE_DESC" />
		<action name="core.edit" title="JACTION_EDIT"
description="COM_FIELDS_FIELD_PERMISSION_EDIT_DESC" />
		<action name="core.edit.state"
title="JACTION_EDITSTATE"
description="COM_FIELDS_FIELD_PERMISSION_EDITSTATE_DESC" />
		<action name="core.edit.value"
title="JACTION_EDITVALUE"
description="COM_FIELDS_FIELD_PERMISSION_EDITVALUE_DESC" />
	</section>
</access>
config.xml000064400000020120151165673530006542 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<config>
	<fieldset 
		name="user_options"
		label="COM_USERS_CONFIG_USER_OPTIONS" >
		<field
			name="allowUserRegistration"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_LABEL"
			description="COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_DESC"
			class="btn-group btn-group-yesno"
			default="0"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="new_usertype"
			type="usergrouplist"
			label="COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_LABEL"
			description="COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_DESC"
			default="2"
			checksuperusergroup="1"
		/>

		<field
			name="guest_usergroup"
			type="usergrouplist"
			label="COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_LABEL"
			description="COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_DESC"
			default="1"
			checksuperusergroup="1"
		/>

		<field
			name="sendpassword"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_SENDPASSWORD_LABEL"
			description="COM_USERS_CONFIG_FIELD_SENDPASSWORD_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="useractivation"
			type="list"
			label="COM_USERS_CONFIG_FIELD_USERACTIVATION_LABEL"
			description="COM_USERS_CONFIG_FIELD_USERACTIVATION_DESC"
			default="2"
			>
			<option value="0">JNONE</option>
			<option
value="1">COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_SELFACTIVATION</option>
			<option
value="2">COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_ADMINACTIVATION</option>
		</field>

		<field
			name="mail_to_admin"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_MAILTOADMIN_LABEL"
			description="COM_USERS_CONFIG_FIELD_MAILTOADMIN_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="captcha"
			type="plugins"
			label="COM_USERS_CONFIG_FIELD_CAPTCHA_LABEL"
			description="COM_USERS_CONFIG_FIELD_CAPTCHA_DESC"
			folder="captcha"
			filter="cmd"
			useglobal="true"
			>
			<option value="0">JOPTION_DO_NOT_USE</option>
		</field>

		<field
			name="frontend_userparams"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_LABEL"
			description="COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JSHOW</option>
			<option value="0">JHIDE</option>
		</field>

		<field
			name="site_language"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_FRONTEND_LANG_LABEL"
			description="COM_USERS_CONFIG_FIELD_FRONTEND_LANG_DESC"
			class="btn-group btn-group-yesno"
			default="0"
			showon="frontend_userparams:1"
			>
			<option value="1">JSHOW</option>
			<option value="0">JHIDE</option>
		</field>

		<field
			name="change_login_name"
			type="radio"
			label="COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_LABEL"
			description="COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_DESC"
			class="btn-group btn-group-yesno"
			default="0"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

	</fieldset>

	<fieldset
		name="domain_options"
		label="COM_USERS_CONFIG_DOMAIN_OPTIONS"
		>

		<field
			name="domains"
			type="subform"
			label="COM_USERS_CONFIG_FIELD_DOMAINS_LABEL"
			description="COM_USERS_CONFIG_FIELD_DOMAINS_DESC"
			multiple="true"
			layout="joomla.form.field.subform.repeatable-table"
			formsource="administrator/components/com_users/models/forms/config_domain.xml"
		/>
	</fieldset>

	<fieldset
		name="password_options"
		label="COM_USERS_CONFIG_PASSWORD_OPTIONS" >
		<field
			name="reset_count"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_LABEL"
			description="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_DESC"
			first="0"
			last="20"
			step="1"
			default="10"
		/>

		<field
			name="reset_time"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_LABEL"
			description="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_DESC"
			first="1"
			last="24"
			step="1"
			default="1"
		/>

		<field
			name="minimum_length"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH"
			description="COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH_DESC"
			first="4"
			last="99"
			step="1"
			default="4"
		/>

		<field
			name="minimum_integers"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS"
			description="COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS_DESC"
			first="0"
			last="98"
			step="1"
			default="0"
		/>

		<field
			name="minimum_symbols"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS"
			description="COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS_DESC"
			first="0"
			last="98"
			step="1"
			default="0"
		/>

		<field
			name="minimum_uppercase"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE"
			description="COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE_DESC"
			first="0"
			last="98"
			step="1"
			default="0"
		/>

		<field
			name="minimum_lowercase"
			type="integer"
			label="COM_USERS_CONFIG_FIELD_MINIMUM_LOWERCASE"
			description="COM_USERS_CONFIG_FIELD_MINIMUM_LOWERCASE_DESC"
			first="0"
			last="98"
			step="1"
			default="0"
		/>

	</fieldset>

	<fieldset
		name="user_notes_history"
		label="COM_USERS_CONFIG_FIELD_NOTES_HISTORY" >

		<field
			name="save_history"
			type="radio"
			label="JGLOBAL_SAVE_HISTORY_OPTIONS_LABEL"
			description="JGLOBAL_SAVE_HISTORY_OPTIONS_DESC"
			class="btn-group btn-group-yesno"
			default="0"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="history_limit"
			type="number"
			label="JGLOBAL_HISTORY_LIMIT_OPTIONS_LABEL"
			description="JGLOBAL_HISTORY_LIMIT_OPTIONS_DESC"
			filter="integer"
			default="5"
			showon="save_history:1"
		/>

	</fieldset>

 	<fieldset
		name="massmail"
		label="COM_USERS_MASS_MAIL"
		description="COM_USERS_MASS_MAIL_DESC">

		<field
 			name="mailSubjectPrefix"
 			type="text"
			label="COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_LABEL"
			description="COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_DESC"
		/>

 		<field
 			name="mailBodySuffix"
			type="textarea"
			label="COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_LABEL"
			description="COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_DESC"
 			rows="5"
 			cols="30"
		/>

	</fieldset>

	<fieldset
		name="debug"
		label="COM_USERS_DEBUG_LABEL"
		description="COM_USERS_DEBUG_DESC">

		<field
			name="debugUsers"
			type="radio"
			label="COM_USERS_DEBUG_USERS_LABEL"
			description="COM_USERS_DEBUG_USERS_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="debugGroups"
			type="radio"
			label="COM_USERS_DEBUG_GROUPS_LABEL"
			description="COM_USERS_DEBUG_GROUPS_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

	</fieldset>

	<fieldset name="integration"
		label="JGLOBAL_INTEGRATION_LABEL"
		description="COM_USERS_CONFIG_INTEGRATION_SETTINGS_DESC"
	>

		<field
			name="integration_sef"
			type="note"
			label="JGLOBAL_SEF_TITLE"
		/>

		<field
			name="sef_advanced"
			type="radio"
			class="btn-group btn-group-yesno btn-group-reversed"
			default="0"
			label="JGLOBAL_SEF_ADVANCED_LABEL"
			description="JGLOBAL_SEF_ADVANCED_DESC"
			filter="integer"
			>
			<option
value="0">JGLOBAL_SEF_ADVANCED_LEGACY</option>
			<option
value="1">JGLOBAL_SEF_ADVANCED_MODERN</option>
		</field>

		<field
			name="integration_customfields"
			type="note"
			label="JGLOBAL_FIELDS_TITLE"
		/>

		<field
			name="custom_fields_enable"
			type="radio"
			label="JGLOBAL_CUSTOM_FIELDS_ENABLE_LABEL"
			description="JGLOBAL_CUSTOM_FIELDS_ENABLE_DESC"
			class="btn-group btn-group-yesno"
			default="1"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

	</fieldset>

	<fieldset
		name="permissions"
		label="JCONFIG_PERMISSIONS_LABEL"
		description="JCONFIG_PERMISSIONS_DESC"
		>

		<field
			name="rules"
			type="rules"
			label="JCONFIG_PERMISSIONS_LABEL"
			filter="rules"
			validate="rules"
			component="com_users"
			section="component"
		/>

	</fieldset>
</config>
controllers/group.php000064400000003172151165673530010776 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User view level controller class.
 *
 * @since  1.6
 */
class UsersControllerGroup extends JControllerForm
{
	/**
	 * @var	    string  The prefix to use with controller messages.
	 * @since   1.6
	 */
	protected $text_prefix = 'COM_USERS_GROUP';

	/**
	 * Method to check if you can save a new or existing record.
	 *
	 * Overrides JControllerForm::allowSave to check the core.admin
permission.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	protected function allowSave($data, $key = 'id')
	{
		return (JFactory::getUser()->authorise('core.admin',
$this->option) && parent::allowSave($data, $key));
	}

	/**
	 * Overrides JControllerForm::allowEdit
	 *
	 * Checks that non-Super Admins are not editing Super Admins.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	protected function allowEdit($data = array(), $key = 'id')
	{
		// Check if this group is a Super Admin
		if (JAccess::checkGroup($data[$key], 'core.admin'))
		{
			// If I'm not a Super Admin, then disallow the edit.
			if (!JFactory::getUser()->authorise('core.admin'))
			{
				return false;
			}
		}

		return parent::allowEdit($data, $key);
	}
}
controllers/groups.php000064400000005727151165673530011171 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User groups list controller class.
 *
 * @since  1.6
 */
class UsersControllerGroups extends JControllerAdmin
{
	/**
	 * @var     string  The prefix to use with controller messages.
	 * @since   1.6
	 */
	protected $text_prefix = 'COM_USERS_GROUPS';

	/**
	 * Proxy for getModel.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  object  The model.
	 *
	 * @since   1.6
	 */
	public function getModel($name = 'Group', $prefix =
'UsersModel', $config = array())
	{
		return parent::getModel($name, $prefix, array('ignore_request'
=> true));
	}

	/**
	 * Removes an item.
	 *
	 * Overrides JControllerAdmin::delete to check the core.admin permission.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function delete()
	{
		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}

		return parent::delete();
	}

	/**
	 * Method to publish a list of records.
	 *
	 * Overrides JControllerAdmin::publish to check the core.admin permission.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function publish()
	{
		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}

		return parent::publish();
	}

	/**
	 * Changes the order of one or more records.
	 *
	 * Overrides JControllerAdmin::reorder to check the core.admin permission.
	 *
	 * @return  boolean  True on success
	 *
	 * @since   1.6
	 */
	public function reorder()
	{
		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}

		return parent::reorder();
	}

	/**
	 * Method to save the submitted ordering values for records.
	 *
	 * Overrides JControllerAdmin::saveorder to check the core.admin
permission.
	 *
	 * @return  boolean  True on success
	 *
	 * @since   1.6
	 */
	public function saveorder()
	{
		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}

		return parent::saveorder();
	}

	/**
	 * Check in of one or more records.
	 *
	 * Overrides JControllerAdmin::checkin to check the core.admin permission.
	 *
	 * @return  boolean  True on success
	 *
	 * @since   1.6
	 */
	public function checkin()
	{
		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}

		return parent::checkin();
	}
}
controllers/level.php000064400000006066151165673530010756 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * User view level controller class.
 *
 * @since  1.6
 */
class UsersControllerLevel extends JControllerForm
{
	/**
	 * @var     string  The prefix to use with controller messages.
	 * @since   1.6
	 */
	protected $text_prefix = 'COM_USERS_LEVEL';

	/**
	 * Method to check if you can save a new or existing record.
	 *
	 * Overrides JControllerForm::allowSave to check the core.admin
permission.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	protected function allowSave($data, $key = 'id')
	{
		return (JFactory::getUser()->authorise('core.admin',
$this->option) && parent::allowSave($data, $key));
	}

	/**
	 * Overrides JControllerForm::allowEdit
	 *
	 * Checks that non-Super Admins are not editing Super Admins.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   3.8.8
	 */
	protected function allowEdit($data = array(), $key = 'id')
	{
		// Get user instance
		$user = JFactory::getUser();

		// Check for if Super Admin can edit
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->quoteName('#__viewlevels'))
			->where($db->quoteName('id') . ' = ' . (int)
$data['id']);
		$db->setQuery($query);

		$viewlevel = $db->loadAssoc();

		// Decode level groups
		$groups = json_decode($viewlevel['rules']);

		// If this group is super admin and this user is not super admin, canEdit
is false
		if (!$user->authorise('core.admin') &&
JAccess::checkGroup($groups[0], 'core.admin'))
		{
			$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'));

			return false;
		}

		return parent::allowEdit($data, $key);
	}

	/**
	 * Removes an item.
	 *
	 * Overrides JControllerAdmin::delete to check the core.admin permission.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function delete()
	{
		// Check for request forgeries.
		$this->checkToken();

		$ids = $this->input->get('cid', array(),
'array');

		if (!JFactory::getUser()->authorise('core.admin',
$this->option))
		{
			JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR'));
			jexit();
		}
		elseif (empty($ids))
		{
			JError::raiseWarning(500,
JText::_('COM_USERS_NO_LEVELS_SELECTED'));
		}
		else
		{
			// Get the model.
			$model = $this->getModel();

			$ids = ArrayHelper::toInteger($ids);

			// Remove the items.
			if (!$model->delete($ids))
			{
				JError::raiseWarning(500, $model->getError());
			}
			else
			{
				$this->setMessage(JText::plural('COM_USERS_N_LEVELS_DELETED',
count($ids)));
			}
		}

		$this->setRedirect('index.php?option=com_users&view=levels');
	}
}
controllers/levels.php000064400000001735151165673530011137 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User view levels list controller class.
 *
 * @since  1.6
 */
class UsersControllerLevels extends JControllerAdmin
{
	/**
	 * @var     string  The prefix to use with controller messages.
	 * @since   1.6
	 */
	protected $text_prefix = 'COM_USERS_LEVELS';

	/**
	 * Proxy for getModel.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  object  The model.
	 *
	 * @since   1.6
	 */
	public function getModel($name = 'Level', $prefix =
'UsersModel', $config = array())
	{
		return parent::getModel($name, $prefix, array('ignore_request'
=> true));
	}
}
controllers/mail.php000064400000002424151165673530010563 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users mail controller.
 *
 * @since  1.6
 */
class UsersControllerMail extends JControllerLegacy
{
	/**
	 * Send the mail
	 *
	 * @return void
	 *
	 * @since 1.6
	 */
	public function send()
	{
		// Redirect to admin index if mass mailer disabled in conf
		if (JFactory::getApplication()->get('massmailoff', 0) == 1)
		{
			JFactory::getApplication()->redirect(JRoute::_('index.php',
false));
		}

		// Check for request forgeries.
		$this->checkToken('request');

		$model = $this->getModel('Mail');

		if ($model->send())
		{
			$type = 'message';
		}
		else
		{
			$type = 'error';
		}

		$msg = $model->getError();
		$this->setRedirect('index.php?option=com_users&view=mail',
$msg, $type);
	}

	/**
	 * Cancel the mail
	 *
	 * @return void
	 *
	 * @since 1.6
	 */
	public function cancel()
	{
		// Check for request forgeries.
		$this->checkToken('request');

		// Clear data from session.
		\JFactory::getApplication()->setUserState('com_users.display.mail.data',
null);

		$this->setRedirect('index.php');
	}
}
controllers/note.php000064400000002140151165673530010601 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User note controller class.
 *
 * @since  2.5
 */
class UsersControllerNote extends JControllerForm
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $text_prefix = 'COM_USERS_NOTE';

	/**
	 * Gets the URL arguments to append to an item redirect.
	 *
	 * @param   integer  $recordId  The primary key id for the item.
	 * @param   string   $key       The name of the primary key variable.
	 *
	 * @return  string  The arguments to append to the redirect URL.
	 *
	 * @since   2.5
	 */
	protected function getRedirectToItemAppend($recordId = null, $key =
'id')
	{
		$append = parent::getRedirectToItemAppend($recordId, $key);

		$userId = JFactory::getApplication()->input->get('u_id',
0, 'int');

		if ($userId)
		{
			$append .= '&u_id=' . $userId;
		}

		return $append;
	}
}
controllers/notes.php000064400000001766151165673530011001 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User notes controller class.
 *
 * @since  2.5
 */
class UsersControllerNotes extends JControllerAdmin
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $text_prefix = 'COM_USERS_NOTES';

	/**
	 * Method to get a model object, loading it if required.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  object  The model.
	 *
	 * @since   2.5
	 */
	public function getModel($name = 'Note', $prefix =
'UsersModel', $config = array('ignore_request' =>
true))
	{
		return parent::getModel($name, $prefix, $config);
	}
}
controllers/users.php000064400000006004151165673530011000 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Users list controller class.
 *
 * @since  1.6
 */
class UsersControllerUsers extends JControllerAdmin
{
	/**
	 * @var    string  The prefix to use with controller messages.
	 * @since  1.6
	 */
	protected $text_prefix = 'COM_USERS_USERS';

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @since   1.6
	 * @see     JController
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);

		$this->registerTask('block', 'changeBlock');
		$this->registerTask('unblock', 'changeBlock');
	}

	/**
	 * Proxy for getModel.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  object  The model.
	 *
	 * @since   1.6
	 */
	public function getModel($name = 'User', $prefix =
'UsersModel', $config = array('ignore_request' =>
true))
	{
		return parent::getModel($name, $prefix, $config);
	}

	/**
	 * Method to change the block status on a record.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function changeBlock()
	{
		// Check for request forgeries.
		$this->checkToken();

		$ids    = $this->input->get('cid', array(),
'array');
		$values = array('block' => 1, 'unblock' => 0);
		$task   = $this->getTask();
		$value  = ArrayHelper::getValue($values, $task, 0, 'int');

		if (empty($ids))
		{
			JError::raiseWarning(500,
JText::_('COM_USERS_USERS_NO_ITEM_SELECTED'));
		}
		else
		{
			// Get the model.
			$model = $this->getModel();

			// Change the state of the records.
			if (!$model->block($ids, $value))
			{
				JError::raiseWarning(500, $model->getError());
			}
			else
			{
				if ($value == 1)
				{
					$this->setMessage(JText::plural('COM_USERS_N_USERS_BLOCKED',
count($ids)));
				}
				elseif ($value == 0)
				{
					$this->setMessage(JText::plural('COM_USERS_N_USERS_UNBLOCKED',
count($ids)));
				}
			}
		}

		$this->setRedirect('index.php?option=com_users&view=users');
	}

	/**
	 * Method to activate a record.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public function activate()
	{
		// Check for request forgeries.
		$this->checkToken();

		$ids = $this->input->get('cid', array(),
'array');

		if (empty($ids))
		{
			JError::raiseWarning(500,
JText::_('COM_USERS_USERS_NO_ITEM_SELECTED'));
		}
		else
		{
			// Get the model.
			$model = $this->getModel();

			// Change the state of the records.
			if (!$model->activate($ids))
			{
				JError::raiseWarning(500, $model->getError());
			}
			else
			{
				$this->setMessage(JText::plural('COM_USERS_N_USERS_ACTIVATED',
count($ids)));
			}
		}

		$this->setRedirect('index.php?option=com_users&view=users');
	}
}
helpers/debug.php000064400000007530151165673540010027 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Users component debugging helper.
 *
 * @since  1.6
 */
class UsersHelperDebug
{
	/**
	 * Get a list of the components.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public static function getComponents()
	{
		// Initialise variable.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('name AS text, element AS value')
			->from('#__extensions')
			->where('enabled >= 1')
			->where('type =' . $db->quote('component'));

		$items = $db->setQuery($query)->loadObjectList();

		if (count($items))
		{
			$lang = JFactory::getLanguage();

			foreach ($items as &$item)
			{
				// Load language
				$extension = $item->value;
				$source = JPATH_ADMINISTRATOR . '/components/' . $extension;
				$lang->load("$extension.sys", JPATH_ADMINISTRATOR, null,
false, true)
					|| $lang->load("$extension.sys", $source, null, false,
true);

				// Translate component name
				$item->text = JText::_($item->text);
			}

			// Sort by component name
			$items = ArrayHelper::sortObjects($items, 'text', 1, true,
true);
		}

		return $items;
	}

	/**
	 * Get a list of the actions for the component or code actions.
	 *
	 * @param   string  $component  The name of the component.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public static function getDebugActions($component = null)
	{
		$actions = array();

		// Try to get actions for the component
		if (!empty($component))
		{
			$component_actions = JAccess::getActions($component);

			if (!empty($component_actions))
			{
				foreach ($component_actions as &$action)
				{
					$actions[$action->title] = array($action->name,
$action->description);
				}
			}
		}

		// Use default actions from configuration if no component selected or
component doesn't have actions
		if (empty($actions))
		{
			$filename = JPATH_ADMINISTRATOR .
'/components/com_config/model/form/application.xml';

			if (is_file($filename))
			{
				$xml = simplexml_load_file($filename);

				foreach ($xml->children()->fieldset as $fieldset)
				{
					if ('permissions' == (string) $fieldset['name'])
					{
						foreach ($fieldset->children() as $field)
						{
							if ('rules' == (string) $field['name'])
							{
								foreach ($field->children() as $action)
								{
									$actions[(string) $action['title']] = array(
										(string) $action['name'],
										(string) $action['description']
									);
								}

								break;
							}
						}
					}
				}

				// Load language
				$lang = JFactory::getLanguage();
				$extension = 'com_config';
				$source = JPATH_ADMINISTRATOR . '/components/' . $extension;

				$lang->load($extension, JPATH_ADMINISTRATOR, null, false, false)
					|| $lang->load($extension, $source, null, false, false)
					|| $lang->load($extension, JPATH_ADMINISTRATOR,
$lang->getDefault(), false, false)
					|| $lang->load($extension, $source, $lang->getDefault(), false,
false);
			}
		}

		return $actions;
	}

	/**
	 * Get a list of filter options for the levels.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getLevelsOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '1',
JText::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1));
		$options[] = JHtml::_('select.option', '2',
JText::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2));
		$options[] = JHtml::_('select.option', '3',
JText::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3));
		$options[] = JHtml::_('select.option', '4',
'4');
		$options[] = JHtml::_('select.option', '5',
'5');
		$options[] = JHtml::_('select.option', '6',
'6');

		return $options;
	}
}
helpers/users.php000064400000015426151165673540010105 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users component helper.
 *
 * @since  1.6
 */
class UsersHelper
{
	/**
	 * @var    JObject  A cache for the available actions.
	 * @since  1.6
	 */
	protected static $actions;

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_USERS'),
			'index.php?option=com_users&view=users',
			$vName == 'users'
		);

		// Groups and Levels are restricted to core.admin
		$canDo = JHelperContent::getActions('com_users');

		if ($canDo->get('core.admin'))
		{
			JHtmlSidebar::addEntry(
				JText::_('COM_USERS_SUBMENU_GROUPS'),
				'index.php?option=com_users&view=groups',
				$vName == 'groups'
			);
			JHtmlSidebar::addEntry(
				JText::_('COM_USERS_SUBMENU_LEVELS'),
				'index.php?option=com_users&view=levels',
				$vName == 'levels'
			);
		}

		if (JComponentHelper::isEnabled('com_fields') &&
JComponentHelper::getParams('com_users')->get('custom_fields_enable',
'1'))
		{
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELDS'),
				'index.php?option=com_fields&context=com_users.user',
				$vName == 'fields.fields'
			);
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELD_GROUPS'),
				'index.php?option=com_fields&view=groups&context=com_users.user',
				$vName == 'fields.groups'
			);
		}

		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_NOTES'),
			'index.php?option=com_users&view=notes',
			$vName == 'notes'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'),
			'index.php?option=com_categories&extension=com_users',
			$vName == 'categories'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with
new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_users');
	}

	/**
	 * Get a list of filter options for the blocked state of a user.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getStateOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '0',
JText::_('JENABLED'));
		$options[] = JHtml::_('select.option', '1',
JText::_('JDISABLED'));

		return $options;
	}

	/**
	 * Get a list of filter options for the activated state of a user.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getActiveOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '0',
JText::_('COM_USERS_ACTIVATED'));
		$options[] = JHtml::_('select.option', '1',
JText::_('COM_USERS_UNACTIVATED'));

		return $options;
	}

	/**
	 * Get a list of the user groups for filtering.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getGroups()
	{
		$options = JHelperUsergroups::getInstance()->getAll();

		foreach ($options as &$option)
		{
			$option->value = $option->id;
			$option->text = str_repeat('- ', $option->level) .
$option->title;
		}

		return $options;
	}

	/**
	 * Creates a list of range options used in filter select list
	 * used in com_users on users view
	 *
	 * @return  array
	 *
	 * @since   2.5
	 */
	public static function getRangeOptions()
	{
		$options = array(
			JHtml::_('select.option', 'today',
JText::_('COM_USERS_OPTION_RANGE_TODAY')),
			JHtml::_('select.option', 'past_week',
JText::_('COM_USERS_OPTION_RANGE_PAST_WEEK')),
			JHtml::_('select.option', 'past_1month',
JText::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')),
			JHtml::_('select.option', 'past_3month',
JText::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')),
			JHtml::_('select.option', 'past_6month',
JText::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')),
			JHtml::_('select.option', 'past_year',
JText::_('COM_USERS_OPTION_RANGE_PAST_YEAR')),
			JHtml::_('select.option', 'post_year',
JText::_('COM_USERS_OPTION_RANGE_POST_YEAR')),
		);

		return $options;
	}

	/**
	 * Creates a list of two factor authentication methods used in com_users
	 * on user view
	 *
	 * @return  array
	 *
	 * @since   3.2.0
	 */
	public static function getTwoFactorMethods()
	{
		FOFPlatform::getInstance()->importPlugin('twofactorauth');
		$identities =
FOFPlatform::getInstance()->runPlugins('onUserTwofactorIdentify',
array());

		$options = array(
			JHtml::_('select.option', 'none',
JText::_('JGLOBAL_OTPMETHOD_NONE'), 'value',
'text'),
		);

		if (!empty($identities))
		{
			foreach ($identities as $identity)
			{
				if (!is_object($identity))
				{
					continue;
				}

				$options[] = JHtml::_('select.option', $identity->method,
$identity->title, 'value', 'text');
			}
		}

		return $options;
	}

	/**
	 * Get a list of the User Groups for Viewing Access Levels
	 *
	 * @param   string  $rules  User Groups in JSON format
	 *
	 * @return  string  $groups  Comma separated list of User Groups
	 *
	 * @since   3.6
	 */
	public static function getVisibleByGroups($rules)
	{
		$rules = json_decode($rules);

		if (!$rules)
		{
			return false;
		}

		$rules = implode(',', $rules);

		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.title AS text')
			->from('#__usergroups as a')
			->where('a.id IN (' . $rules . ')');
		$db->setQuery($query);

		$groups = $db->loadColumn();
		$groups = implode(', ', $groups);

		return $groups;
	}

	/**
	 * Returns a valid section for users. If it is not valid then null
	 * is returned.
	 *
	 * @param   string  $section  The section to get the mapping for
	 *
	 * @return  string|null  The new section
	 *
	 * @since   3.7.0
	 */
	public static function validateSection($section)
	{
		if (JFactory::getApplication()->isClient('site'))
		{
			switch ($section)
			{
				case 'registration':
				case 'profile':
					$section = 'user';
			}
		}

		if ($section != 'user')
		{
			// We don't know other sections
			return null;
		}

		return $section;
	}

	/**
	 * Returns valid contexts
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getContexts()
	{
		JFactory::getLanguage()->load('com_users',
JPATH_ADMINISTRATOR);

		$contexts = array(
			'com_users.user' => JText::_('COM_USERS'),
		);

		return $contexts;
	}
}
models/debuggroup.php000064400000014331151165673540010722 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersHelperDebug', JPATH_ADMINISTRATOR .
'/components/com_users/helpers/debug.php');

/**
 * Methods supporting a list of User ACL permissions
 *
 * @since  1.6
 */
class UsersModelDebuggroup extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JController
	 * @since   3.6.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'a.title',
				'component', 'a.name',
				'a.lft',
				'a.id',
				'level_start', 'level_end', 'a.level',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Get a list of the actions.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public function getDebugActions()
	{
		$component = $this->getState('filter.component');

		return UsersHelperDebug::getDebugActions($component);
	}

	/**
	 * Override getItems method.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public function getItems()
	{
		$groupId = $this->getState('group_id');

		if (($assets = parent::getItems()) && $groupId)
		{
			$actions = $this->getDebugActions();

			foreach ($assets as &$asset)
			{
				$asset->checks = array();

				foreach ($actions as $action)
				{
					$name = $action[0];

					$asset->checks[$name] = JAccess::checkGroup($groupId, $name,
$asset->name);
				}
			}
		}

		return $assets;
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.lft', $direction
= 'asc')
	{
		$app = JFactory::getApplication('administrator');

		// Adjust the context to support modal layouts.
		$layout = $app->input->get('layout',
'default');

		if ($layout)
		{
			$this->context .= '.' . $layout;
		}

		// Load the filter state.
		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search', '',
'string'));
		$this->setState('group_id',
$this->getUserStateFromRequest($this->context .
'.group_id', 'group_id', 0, 'int', false));

		$levelStart = $this->getUserStateFromRequest($this->context .
'.filter.level_start', 'filter_level_start',
'', 'cmd');
		$this->setState('filter.level_start', $levelStart);

		$value = $this->getUserStateFromRequest($this->context .
'.filter.level_end', 'filter_level_end', '',
'cmd');

		if ($value > 0 && $value < $levelStart)
		{
			$value = $levelStart;
		}

		$this->setState('filter.level_end', $value);

		$this->setState('filter.component',
$this->getUserStateFromRequest($this->context .
'.filter.component', 'filter_component', '',
'string'));

		// Load the parameters.
		$params = JComponentHelper::getParams('com_users');
		$this->setState('params', $params);

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('group_id');
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' .
$this->getState('filter.level_start');
		$id .= ':' . $this->getState('filter.level_end');
		$id .= ':' . $this->getState('filter.component');

		return parent::getStoreId($id);
	}

	/**
	 * Get the group being debugged.
	 *
	 * @return  JObject
	 *
	 * @since   1.6
	 */
	public function getGroup()
	{
		$groupId = (int) $this->getState('group_id');

		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('id, title')
			->from('#__usergroups')
			->where('id = ' . $groupId);

		$db->setQuery($query);

		try
		{
			$group = $db->loadObject();
		}
		catch (RuntimeException $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		return $group;
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   1.6
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'a.id, a.name, a.title, a.level, a.lft, a.rgt'
			)
		);
		$query->from($db->quoteName('#__assets', 'a'));

		// Filter the items over the search string if set.
		if ($this->getState('filter.search'))
		{
			// Escape the search token.
			$search = $db->quote('%' . str_replace(' ',
'%',
$db->escape(trim($this->getState('filter.search')), true) .
'%'));

			// Compile the different search clauses.
			$searches = array();
			$searches[] = 'a.name LIKE ' . $search;
			$searches[] = 'a.title LIKE ' . $search;

			// Add the clauses to the query.
			$query->where('(' . implode(' OR ', $searches) .
')');
		}

		// Filter on the start and end levels.
		$levelStart = (int) $this->getState('filter.level_start');
		$levelEnd = (int) $this->getState('filter.level_end');

		if ($levelEnd > 0 && $levelEnd < $levelStart)
		{
			$levelEnd = $levelStart;
		}

		if ($levelStart > 0)
		{
			$query->where('a.level >= ' . $levelStart);
		}

		if ($levelEnd > 0)
		{
			$query->where('a.level <= ' . $levelEnd);
		}

		// Filter the items over the component if set.
		if ($this->getState('filter.component'))
		{
			$component = $this->getState('filter.component');
			$query->where('(a.name = ' . $db->quote($component) .
' OR a.name LIKE ' . $db->quote($component . '.%') .
')');
		}

		// Add the list ordering clause.
		$query->order($db->escape($this->getState('list.ordering',
'a.lft')) . ' ' .
$db->escape($this->getState('list.direction',
'ASC')));

		return $query;
	}
}
models/debuguser.php000064400000013701151165673540010544 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('UsersHelperDebug', JPATH_ADMINISTRATOR .
'/components/com_users/helpers/debug.php');

/**
 * Methods supporting a list of User ACL permissions
 *
 * @since  1.6
 */
class UsersModelDebugUser extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JController
	 * @since   3.6.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'a.title',
				'component', 'a.name',
				'a.lft',
				'a.id',
				'level_start', 'level_end', 'a.level',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Get a list of the actions.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public function getDebugActions()
	{
		$component = $this->getState('filter.component');

		return UsersHelperDebug::getDebugActions($component);
	}

	/**
	 * Override getItems method.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public function getItems()
	{
		$userId = $this->getState('user_id');
		$user   = JFactory::getUser($userId);

		if (($assets = parent::getItems()) && $userId)
		{
			$actions = $this->getDebugActions();

			foreach ($assets as &$asset)
			{
				$asset->checks = array();

				foreach ($actions as $action)
				{
					$name = $action[0];

					$asset->checks[$name] = $user->authorise($name,
$asset->name);
				}
			}
		}

		return $assets;
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.lft', $direction
= 'asc')
	{
		$app = JFactory::getApplication('administrator');

		// Adjust the context to support modal layouts.
		$layout = $app->input->get('layout',
'default');

		if ($layout)
		{
			$this->context .= '.' . $layout;
		}

		// Load the filter state.
		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search', '',
'string'));
		$this->setState('user_id',
$this->getUserStateFromRequest($this->context . '.user_id',
'user_id', 0, 'int', false));

		$levelStart = $this->getUserStateFromRequest($this->context .
'.filter.level_start', 'filter_level_start',
'', 'cmd');
		$this->setState('filter.level_start', $levelStart);

		$value = $this->getUserStateFromRequest($this->context .
'.filter.level_end', 'filter_level_end', '',
'cmd');

		if ($value > 0 && $value < $levelStart)
		{
			$value = $levelStart;
		}

		$this->setState('filter.level_end', $value);

		$this->setState('filter.component',
$this->getUserStateFromRequest($this->context .
'.filter.component', 'filter_component', '',
'string'));

		// Load the parameters.
		$params = JComponentHelper::getParams('com_users');
		$this->setState('params', $params);

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('user_id');
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' .
$this->getState('filter.level_start');
		$id .= ':' . $this->getState('filter.level_end');
		$id .= ':' . $this->getState('filter.component');

		return parent::getStoreId($id);
	}

	/**
	 * Get the user being debugged.
	 *
	 * @return  JUser
	 *
	 * @since   1.6
	 */
	public function getUser()
	{
		$userId = $this->getState('user_id');

		return JFactory::getUser($userId);
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   1.6
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'a.id, a.name, a.title, a.level, a.lft, a.rgt'
			)
		);
		$query->from($db->quoteName('#__assets', 'a'));

		// Filter the items over the search string if set.
		if ($this->getState('filter.search'))
		{
			// Escape the search token.
			$search = $db->quote('%' . str_replace(' ',
'%',
$db->escape(trim($this->getState('filter.search')), true) .
'%'));

			// Compile the different search clauses.
			$searches = array();
			$searches[] = 'a.name LIKE ' . $search;
			$searches[] = 'a.title LIKE ' . $search;

			// Add the clauses to the query.
			$query->where('(' . implode(' OR ', $searches) .
')');
		}

		// Filter on the start and end levels.
		$levelStart = (int) $this->getState('filter.level_start');
		$levelEnd = (int) $this->getState('filter.level_end');

		if ($levelEnd > 0 && $levelEnd < $levelStart)
		{
			$levelEnd = $levelStart;
		}

		if ($levelStart > 0)
		{
			$query->where('a.level >= ' . $levelStart);
		}

		if ($levelEnd > 0)
		{
			$query->where('a.level <= ' . $levelEnd);
		}

		// Filter the items over the component if set.
		if ($this->getState('filter.component'))
		{
			$component = $this->getState('filter.component');
			$query->where('(a.name = ' . $db->quote($component) .
' OR a.name LIKE ' . $db->quote($component . '.%') .
')');
		}

		// Add the list ordering clause.
		$query->order($db->escape($this->getState('list.ordering',
'a.lft')) . ' ' .
$db->escape($this->getState('list.direction',
'ASC')));

		return $query;
	}
}
models/fields/groupparent.php000064400000005277151165673540012404
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\Helper\UserGroupsHelper;

FormHelper::loadFieldClass('list');

/**
 * User Group Parent field..
 *
 * @since  1.6
 */
class JFormFieldGroupParent extends JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var        string
	 * @since   1.6
	 */
	protected $type = 'GroupParent';

	/**
	 * Method to clean the Usergroup Options from all children starting by a
given father
	 *
	 * @param   array    $userGroupsOptions  The usergroup options to clean
	 * @param   integer  $fatherId           The father ID to start with
	 *
	 * @return  array  The cleaned field options
	 *
	 * @since   3.9.4
	 */
	private function cleanOptionsChildrenByFather($userGroupsOptions,
$fatherId)
	{
		foreach ($userGroupsOptions as $userGroupsOptionsId =>
$userGroupsOptionsData)
		{
			if ((int) $userGroupsOptionsData->parent_id === (int) $fatherId)
			{
				unset($userGroupsOptions[$userGroupsOptionsId]);

				$userGroupsOptions =
$this->cleanOptionsChildrenByFather($userGroupsOptions,
$userGroupsOptionsId);
			}
		}

		return $userGroupsOptions;
	}

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects
	 *
	 * @since   1.6
	 */
	protected function getOptions()
	{
		$options        = UserGroupsHelper::getInstance()->getAll();
		$currentGroupId = $this->form->getValue('id');

		// Prevent to set yourself as parent
		if ($currentGroupId)
		{
			unset($options[$currentGroupId]);
		}

		// We should not remove any groups when we are creating a new group
		if (!is_null($currentGroupId))
		{
			// Prevent parenting direct children and children of children of this
item.
			$options = $this->cleanOptionsChildrenByFather($options,
$currentGroupId);
		}

		$options      = array_values($options);
		$isSuperAdmin = Factory::getUser()->authorise('core.admin');

		// Pad the option text with spaces using depth level as a multiplier.
		for ($i = 0, $n = count($options); $i < $n; $i++)
		{
			// Show groups only if user is super admin or group is not super admin
			if ($isSuperAdmin || !Access::checkGroup($options[$i]->id,
'core.admin'))
			{
				$options[$i]->value = $options[$i]->id;
				$options[$i]->text = str_repeat('- ',
$options[$i]->level) . $options[$i]->title;
			}
			else
			{
				unset($options[$i]);
			}
		}

		// Merge any additional options in the XML definition.
		return array_merge(parent::getOptions(), $options);
	}
}
models/fields/levels.php000064400000001465151165673540011323
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JFormHelper::loadFieldClass('list');

/**
 * Access Levels field.
 *
 * @since  3.6.0
 */
class JFormFieldLevels extends JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var     string
	 * @since   3.6.0
	 */
	protected $type = 'Levels';

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects
	 *
	 * @since   3.6.0
	 */
	protected function getOptions()
	{
		// Merge any additional options in the XML definition.
		return array_merge(parent::getOptions(),
UsersHelperDebug::getLevelsOptions());
	}
}
models/forms/config_domain.xml000064400000001165151165673540012513
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset>
		<field
			name="name"
			type="text"
			label="COM_USERS_CONFIG_FIELD_DOMAIN_NAME_LABEL"
			description="COM_USERS_CONFIG_FIELD_DOMAIN_NAME_DESC"
			required="true"
		/>

		<field
			name="rule"
			type="list"
			label="COM_USERS_CONFIG_FIELD_DOMAIN_RULE_LABEL"
			description="COM_USERS_CONFIG_FIELD_DOMAIN_RULE_DESC"
			required="true"
			default="0"
			filter="integer"
			>
			<option
value="1">COM_USERS_CONFIG_FIELD_DOMAIN_RULE_OPTION_ALLOW</option>
			<option
value="0">COM_USERS_CONFIG_FIELD_DOMAIN_RULE_OPTION_DISALLOW</option>
		</field>
	</fieldset>
</form>
models/forms/fields/user.xml000064400000000357151165673540012145
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="params"
label="COM_FIELDS_FIELD_BASIC_LABEL">
		<fieldset name="basic">
			<field
				name="display"
				type="hidden"
			    	default="2"
			/>
		</fieldset>
	</fields>
</form>
models/forms/filter_debuggroup.xml000064400000003577151165673540013440
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_ASSETS"
			description="COM_USERS_SEARCH_IN_ASSETS"
			hint="JSEARCH_FILTER"
		/>

		<field
			name="component"
			type="Components"
			label="COM_USERS_FILTER_COMPONENT_LABEL"
			description="COM_USERS_FILTER_COMPONENT_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_COMPONENT</option>
		</field>

		<field
			name="level_start"
			type="Levels"
			label="COM_USERS_FILTER_LEVEL_START_LABEL"
			description="COM_USERS_FILTER_LEVEL_START_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_LEVEL_START</option>
		</field>

		<field
			name="level_end"
			type="Levels"
			label="COM_USERS_FILTER_LEVEL_END_LABEL"
			description="COM_USERS_FILTER_LEVEL_END_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_LEVEL_END</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			onchange="this.form.submit();"
			default="a.lft ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.title
ASC">COM_USERS_HEADING_ASSET_TITLE_ASC</option>
			<option value="a.title
DESC">COM_USERS_HEADING_ASSET_TITLE_DESC</option>
			<option value="a.name
ASC">COM_USERS_HEADING_ASSET_NAME_ASC</option>
			<option value="a.name
DESC">COM_USERS_HEADING_ASSET_NAME_DESC</option>
			<option value="a.lft
ASC">COM_USERS_HEADING_LFT_ASC</option>
			<option value="a.lft
DESC">COM_USERS_HEADING_LFT_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_debuguser.xml000064400000003572151165673540013255
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_ASSETS"
			description="COM_USERS_SEARCH_IN_ASSETS"
			hint="JSEARCH_FILTER"
		/>
		<field
			name="component"
			type="Components"
			label="COM_USERS_FILTER_COMPONENT_LABEL"
			description="COM_USERS_FILTER_COMPONENT_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_COMPONENT</option>
		</field>
		<field
			name="level_start"
			type="Levels"
			label="COM_USERS_FILTER_LEVEL_START_LABEL"
			description="COM_USERS_FILTER_LEVEL_START_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_LEVEL_START</option>
		</field>
		<field
			name="level_end"
			type="Levels"
			label="COM_USERS_FILTER_LEVEL_END_LABEL"
			description="COM_USERS_FILTER_LEVEL_END_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_SELECT_LEVEL_END</option>
		</field>
	</fields>
	<fields name="list">
		<field
			name="fullordering"
			type="list"
			onchange="this.form.submit();"
			default="a.lft ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.title
ASC">COM_USERS_HEADING_ASSET_TITLE_ASC</option>
			<option value="a.title
DESC">COM_USERS_HEADING_ASSET_TITLE_DESC</option>
			<option value="a.name
ASC">COM_USERS_HEADING_ASSET_NAME_ASC</option>
			<option value="a.name
DESC">COM_USERS_HEADING_ASSET_NAME_DESC</option>
			<option value="a.lft
ASC">COM_USERS_HEADING_LFT_ASC</option>
			<option value="a.lft
DESC">COM_USERS_HEADING_LFT_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>
		<field
			name="limit"
			type="limitbox"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_groups.xml000064400000002144151165673540012601
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_GROUPS_LABEL"
			description="COM_USERS_SEARCH_IN_GROUPS"
			hint="JSEARCH_FILTER"
		/>
	</fields>
	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.lft ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.lft
ASC">JGRID_HEADING_ORDERING_ASC</option>
			<option value="a.lft
DESC">JGRID_HEADING_ORDERING_DESC</option>
			<option value="a.title
ASC">COM_USERS_HEADING_GROUP_TITLE_ASC</option>
			<option value="a.title
DESC">COM_USERS_HEADING_GROUP_TITLE_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>
		<field
			name="limit"
			type="limitbox"
			label="JGLOBAL_LIMIT"
			description="JGLOBAL_LIMIT"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_levels.xml000064400000002166151165673540012560
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_ACCESS_LEVELS"
			description="COM_USERS_SEARCH_IN_LEVEL_NAME"
			hint="JSEARCH_FILTER"
		/>
	</fields>
	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.ordering ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.ordering
ASC">JGRID_HEADING_ORDERING_ASC</option>
			<option value="a.ordering
DESC">JGRID_HEADING_ORDERING_DESC</option>
			<option value="a.title
ASC">COM_USERS_HEADING_LEVEL_NAME_ASC</option>
			<option value="a.title
DESC">COM_USERS_HEADING_LEVEL_NAME_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>
		<field
			name="limit"
			type="limitbox"
			label="JGLOBAL_LIMIT"
			description="JGLOBAL_LIMIT"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_notes.xml000064400000004256151165673540012420
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_USER_NOTES"
			description="COM_USERS_SEARCH_IN_NOTE_TITLE"
			hint="JSEARCH_FILTER"
		/>
		<field
			name="published"
			type="status"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
		</field>
		<field
			name="category_id"
			type="category"
			label="JOPTION_FILTER_CATEGORY"
			description="JOPTION_FILTER_CATEGORY_DESC"
			extension="com_users"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_CATEGORY</option>
		</field>
		<field
			name="level"
			type="integer"
			label="JOPTION_FILTER_LEVEL"
			description="JOPTION_FILTER_LEVEL_DESC"
			first="1"
			last="10"
			step="1"
			languages="*"
			onchange="this.form.submit();"
			>
			<option
value="">JOPTION_SELECT_MAX_LEVELS</option>
		</field>
	</fields>
	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.review_time DESC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.state ASC">JSTATUS_ASC</option>
			<option value="a.state DESC">JSTATUS_DESC</option>
			<option value="a.subject
ASC">COM_USERS_HEADING_SUBJECT_ASC</option>
			<option value="a.subject
DESC">COM_USERS_HEADING_SUBJECT_DESC</option>
			<option value="c.title
ASC">COM_USERS_HEADING_CATEGORY_ASC</option>
			<option value="c.title
DESC">COM_USERS_HEADING_CATEGORY_DESC</option>
			<option value="u.name
ASC">COM_USERS_HEADING_USER_ASC</option>
			<option value="u.name
DESC">COM_USERS_HEADING_USER_DESC</option>
			<option value="a.review_time
ASC">COM_USERS_HEADING_REVIEW_ASC</option>
			<option value="a.review_time
DESC">COM_USERS_HEADING_REVIEW_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>
		<field
			name="limit"
			type="limitbox"
			label="JGLOBAL_LIMIT"
			description="JGLOBAL_LIMIT"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/filter_users.xml000064400000006175151165673540012433
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_USERS_SEARCH_USERS"
			description="COM_USERS_SEARCH_IN_NAME"
			hint="JSEARCH_FILTER"
		/>
		<field
			name="state"
			type="userstate"
			label="COM_USERS_FILTER_STATE"
			description="COM_USERS_FILTER_STATE_DESC"
			onchange="this.form.submit();"
			>
			<option value="">COM_USERS_FILTER_STATE</option>
		</field>
		<field
			name="active"
			type="useractive"
			label="COM_USERS_FILTER_ACTIVE"
			description="COM_USERS_FILTER_ACTIVE_DESC"
			onchange="this.form.submit();"
			>
			<option value="">COM_USERS_FILTER_ACTIVE</option>
		</field>
		<field
			name="group_id"
			type="usergrouplist"
			label="COM_USERS_FILTER_GROUP"
			description="COM_USERS_FILTER_GROUP_DESC"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_FILTER_USERGROUP</option>
		</field>
		<field
			name="lastvisitrange"
			type="lastvisitdaterange"
			label="COM_USERS_OPTION_FILTER_LAST_VISIT_DATE"
			description="COM_USERS_OPTION_FILTER_LAST_VISIT_DATE"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_FILTER_LAST_VISIT_DATE</option>
		</field>
		<field
			name="range"
			type="registrationdaterange"
			label="COM_USERS_OPTION_FILTER_DATE"
			description="COM_USERS_OPTION_FILTER_DATE"
			onchange="this.form.submit();"
			>
			<option
value="">COM_USERS_OPTION_FILTER_DATE</option>
		</field>
	</fields>
	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="COM_CONTENT_LIST_FULL_ORDERING"
			description="COM_CONTENT_LIST_FULL_ORDERING_DESC"
			onchange="this.form.submit();"
			default="a.name ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.name
ASC">COM_USERS_HEADING_NAME_ASC</option>
			<option value="a.name
DESC">COM_USERS_HEADING_NAME_DESC</option>
			<option value="a.username
ASC">COM_USERS_HEADING_USERNAME_ASC</option>
			<option value="a.username
DESC">COM_USERS_HEADING_USERNAME_DESC</option>
			<option value="a.block
ASC">COM_USERS_HEADING_ENABLED_ASC</option>
			<option value="a.block
DESC">COM_USERS_HEADING_ENABLED_DESC</option>
			<option value="a.activation
ASC">COM_USERS_HEADING_ACTIVATED_ASC</option>
			<option value="a.activation
DESC">COM_USERS_HEADING_ACTIVATED_DESC</option>
			<option value="a.email
ASC">COM_USERS_HEADING_EMAIL_ASC</option>
			<option value="a.email
DESC">COM_USERS_HEADING_EMAIL_DESC</option>
			<option value="a.lastvisitDate
ASC">COM_USERS_HEADING_LAST_VISIT_DATE_ASC</option>
			<option value="a.lastvisitDate
DESC">COM_USERS_HEADING_LAST_VISIT_DATE_DESC</option>
			<option value="a.registerDate
ASC">COM_USERS_HEADING_REGISTRATION_DATE_ASC</option>
			<option value="a.registerDate
DESC">COM_USERS_HEADING_REGISTRATION_DATE_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>
		<field
			name="limit"
			type="limitbox"
			label="COM_CONTENT_LIST_LIMIT"
			description="COM_CONTENT_LIST_LIMIT_DESC"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/group.xml000064400000001335151165673540011052 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="group_details">
		<field 
			name="id" 
			type="hidden"
			default="0"
			required="true"
			readonly="true"
		/>

		<field 
			name="title" 
			type="text"
			label="COM_USERS_GROUP_FIELD_TITLE_LABEL"
			description="COM_USERS_GROUP_FIELD_TITLE_DESC"
			required="true"
			size="40"
		/>

		<field 
			name="parent_id" 
			type="groupparent"
			label="COM_USERS_GROUP_FIELD_PARENT_LABEL"
			description="COM_USERS_GROUP_FIELD_PARENT_DESC"
		/>

		<field 
			name="actions" 
			type="hidden"
			multiple="true"
		/>

		<field 
			name="lft" 
			type="hidden"
			filter="unset"
		/>

		<field 
			name="rgt" 
			type="hidden"
			filter="unset"
		/>
	</fieldset>
</form>
models/forms/level.xml000064400000001062151165673540011022 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset>
		<field 
			name="id" 
			type="hidden"
			default="0"
			readonly="true"
			required="true"
		/>

		<field 
			name="title" 
			type="text"
			label="COM_USERS_LEVEL_FIELD_TITLE_LABEL"
			description="COM_USERS_LEVEL_FIELD_TITLE_DESC"
			required="true"
			size="50"
		/>

		<field 
			name="ordering" 
			type="text"
			label="JFIELD_ORDERING_LABEL"
			description="JFIELD_ORDERING_DESC"
			default="0"
		/>

		<field 
			name="rules" 
			type="hidden"
			filter="int_array"
		/>
	</fieldset>
</form>
models/forms/mail.xml000064400000002734151165673540010644 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset>

		<field 
			name="recurse" 
			type="checkbox"
			label="COM_USERS_MAIL_FIELD_RECURSE_LABEL"
			description="COM_USERS_MAIL_FIELD_RECURSE_DESC"
			value="1"
		/>

		<field 
			name="mode" 
			type="checkbox"
			label="COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_LABEL"
			description="COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_DESC"
			value="1"
		/>

		<field 
			name="disabled" 
			type="checkbox"
			label="COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_LABEL"
			description="COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_DESC"
			value="1"
		/>

		<field 
			name="group" 
			type="usergrouplist"
			label="COM_USERS_MAIL_FIELD_GROUP_LABEL"
			description="COM_USERS_MAIL_FIELD_GROUP_DESC"
			default="0"
			size="10"
			>
			<option
value="0">COM_USERS_MAIL_FIELD_VALUE_ALL_USERS_GROUPS</option>
		</field>

		<field 
			name="bcc" 
			type="checkbox"
			label="COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_LABEL"
			description="COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_DESC"
			default="1"
			value="1"
			checked="1"
		/>

		<field 
			name="subject" 
			type="text"
			label="COM_USERS_MAIL_FIELD_SUBJECT_LABEL"
			description="COM_USERS_MAIL_FIELD_SUBJECT_DESC"
			class="span8"
			maxlength="150"
			size="30"
		/>

		<field 
			name="message" 
			type="textarea"
			label="COM_USERS_MAIL_FIELD_MESSAGE_LABEL"
			description="COM_USERS_MAIL_FIELD_MESSAGE_DESC"
			class="span11 vert"
			cols="70"
			rows="20"
		/>
	</fieldset>
</form>
models/forms/note.xml000064400000005452151165673540010667 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset
		addfieldpath="/administrator/components/com_categories/models/fields"
	>
		<field
			name="id"
			type="hidden"
			label="COM_USERS_FIELD_ID_LABEL"
			class="readonly"
			size="6"
			default="0"
			readonly="true"
		/>

		<field
			name="user_id"
			type="user"
			label="COM_USERS_FIELD_USER_ID_LABEL"
			description="JLIB_FORM_SELECT_USER"
			size="50"
			class="input-medium"
			required="true"
		/>

		<field
			name="catid"
			type="modal_category"
			label="COM_USERS_FIELD_CATEGORY_ID_LABEL"
			description="JFIELD_CATEGORY_DESC"
			extension="com_users"
			required="true"
			select="true"
			new="true"
			edit="true"
			clear="true"
		/>

		<field
			name="subject"
			type="text"
			label="COM_USERS_FIELD_SUBJECT_LABEL"
			description="COM_USERS_FIELD_SUBJECT_DESC"
			size="80"
		/>

		<field
			name="body"
			type="editor"
			label="COM_USERS_FIELD_NOTEBODY_LABEL"
			description="COM_USERS_FIELD_NOTEBODY_DESC"
			rows="10"
			cols="80"
			filter="safehtml"
		/>

		<field
			name="state"
			type="list"
			label="JSTATUS"
			description="COM_USERS_FIELD_STATE_DESC"
			size="1"
			default="1"
			>
			<option value="1">JPUBLISHED</option>
			<option value="0">JUNPUBLISHED</option>
			<option value="2">JARCHIVED</option>
			<option value="-2">JTRASHED</option>
		</field>

		<field
			name="review_time"
			type="calendar"
			label="COM_USERS_FIELD_REVIEW_TIME_LABEL"
			description="COM_USERS_FIELD_REVIEW_TIME_DESC"
			default="NOW"
			translateformat="true"
			filter="user_utc"
		/>

		<field
			name="checked_out"
			type="hidden"
			filter="unset"
		/>

		<field
			name="checked_out_time"
			type="hidden"
			filter="unset"
		/>

		<field
			name="created_user_id"
			type="hidden"
			label="JGLOBAL_FIELD_CREATED_BY_LABEL"
			filter="unset"
		/>

		<field
			name="created_time"
			type="hidden"
			label="JGLOBAL_FIELD_CREATED_LABEL"
			filter="unset"
		/>

		<field
			name="modified_user_id"
			type="hidden"
			label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
			filter="unset"
		/>

		<field
			name="modified_time"
			type="hidden"
			label="JGLOBAL_FIELD_MODIFIED_LABEL"
			filter="unset"
		/>

		<field
			name="publish_up"
			type="calendar"
			label="JGLOBAL_FIELD_PUBLISH_UP_LABEL"
			description="JGLOBAL_FIELD_PUBLISH_UP_DESC"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="publish_down"
			type="calendar"
			label="JGLOBAL_FIELD_PUBLISH_DOWN_LABEL"
			description="JGLOBAL_FIELD_PUBLISH_DOWN_DESC"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="version_note"
			type="text"
			label="JGLOBAL_FIELD_VERSION_NOTE_LABEL"
			description="JGLOBAL_FIELD_VERSION_NOTE_DESC"
			maxlength="255"
			size="45"
			labelclass="control-label"
		/>
	</fieldset>
</form>
models/forms/user.xml000064400000011402151165673570010673 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="user_details">
		<field
			name="name"
			type="text"
			label="COM_USERS_USER_FIELD_NAME_LABEL"
			description="COM_USERS_USER_FIELD_NAME_DESC"
			required="true"
			size="30"
		/>

		<field
			name="username"
			type="text"
			label="COM_USERS_USER_FIELD_USERNAME_LABEL"
			description="COM_USERS_USER_FIELD_USERNAME_DESC"
			required="true"
			size="30"
		/>

		<field
			name="password"
			type="password"
			label="JGLOBAL_PASSWORD"
			description="COM_USERS_USER_FIELD_PASSWORD_DESC"
			autocomplete="off"
			class="validate-password"
			filter="raw"
			validate="password"
			size="30"
		/>

		<field
			name="password2"
			type="password"
			label="COM_USERS_USER_FIELD_PASSWORD2_LABEL"
			description="COM_USERS_USER_FIELD_PASSWORD2_DESC"
			autocomplete="off"
			class="validate-password"
			filter="raw"
			message="COM_USERS_USER_FIELD_PASSWORD1_MESSAGE"
			size="30"
			validate="equals"
			field="password"
		/>

		<field
			name="email"
			type="email"
			label="JGLOBAL_EMAIL"
			description="COM_USERS_USER_FIELD_EMAIL_DESC"
			required="true"
			size="30"
			validate="email"
			validDomains="com_users.domains"
		/>

		<field
			name="registerDate"
			type="calendar"
			label="COM_USERS_USER_FIELD_REGISTERDATE_LABEL"
			description="COM_USERS_USER_FIELD_REGISTERDATE_DESC"
			class="readonly"
			readonly="true"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="lastvisitDate"
			type="calendar"
			label="COM_USERS_USER_FIELD_LASTVISIT_LABEL"
			description="COM_USERS_USER_FIELD_LASTVISIT_DESC"
			class="readonly"
			readonly="true"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="lastResetTime"
			type="calendar"
			label="COM_USERS_USER_FIELD_LASTRESET_LABEL"
			description="COM_USERS_USER_FIELD_LASTRESET_DESC"
			class="readonly"
			readonly="true"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="resetCount"
			type="number"
			label="COM_USERS_USER_FIELD_RESETCOUNT_LABEL"
			description="COM_USERS_USER_FIELD_RESETCOUNT_DESC"
			class="readonly"
			default="0"
			readonly="true"
		/>

		<field
			name="sendEmail"
			type="radio"
			label="COM_USERS_USER_FIELD_SENDEMAIL_LABEL"
			description="COM_USERS_USER_FIELD_SENDEMAIL_DESC"
			default="0"
			class="btn-group btn-group-yesno"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="block"
			type="radio"
			label="COM_USERS_USER_FIELD_BLOCK_LABEL"
			description="COM_USERS_USER_FIELD_BLOCK_DESC"
			class="btn-group btn-group-yesno btn-group-reversed"
			default="0"
			>
			<option
value="1">COM_USERS_USER_FIELD_BLOCK</option>
			<option
value="0">COM_USERS_USER_FIELD_ENABLE</option>
		</field>

		<field
			name="requireReset"
			type="radio"
			label="COM_USERS_USER_FIELD_REQUIRERESET_LABEL"
			description="COM_USERS_USER_FIELD_REQUIRERESET_DESC"
			default="0"
			class="btn-group btn-group-yesno"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="id"
			type="number"
			label="JGLOBAL_FIELD_ID_LABEL"
			description="JGLOBAL_FIELD_ID_DESC"
			class="readonly"
			default="0"
			readonly="true"
		/>

	</fieldset>
	<field name="groups" type="hidden" />
	<field name="twofactor" type="hidden" />

	<fields name="params">

		<!--  Basic user account settings. -->
		<fieldset name="settings"
label="COM_USERS_SETTINGS_FIELDSET_LABEL">

			<field
				name="admin_style"
				type="templatestyle"
				label="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL"
				description="COM_USERS_USER_FIELD_BACKEND_TEMPLATE_DESC"
				client="administrator"
				filter="uint"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="admin_language"
				type="language"
				label="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL"
				description="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_DESC"
				client="administrator"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="language"
				type="language"
				label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL"
				description="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC"
				client="site"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="editor"
				type="plugins"
				label="COM_USERS_USER_FIELD_EDITOR_LABEL"
				description="COM_USERS_USER_FIELD_EDITOR_DESC"
				folder="editors"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

			<field
				name="timezone"
				type="timezone"
				label="COM_USERS_USER_FIELD_TIMEZONE_LABEL"
				description="COM_USERS_USER_FIELD_TIMEZONE_DESC"
				>
				<option value="">JOPTION_USE_DEFAULT</option>
			</field>

		</fieldset>

	</fields>
</form>
models/group.php000064400000020741151165673570007720 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;

/**
 * User group model.
 *
 * @since  1.6
 */
class UsersModelGroup extends JModelAdmin
{
	/**
	 * Constructor
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 */
	public function __construct($config = array())
	{
		$config = array_merge(
			array(
				'event_after_delete'  =>
'onUserAfterDeleteGroup',
				'event_after_save'    => 'onUserAfterSaveGroup',
				'event_before_delete' =>
'onUserBeforeDeleteGroup',
				'event_before_save'   =>
'onUserBeforeSaveGroup',
				'events_map'          => array('delete' =>
'user', 'save' => 'user')
			), $config
		);

		parent::__construct($config);
	}

	/**
	 * Returns a reference to the a Table object, always creating it.
	 *
	 * @param   string  $type    The table type to instantiate
	 * @param   string  $prefix  A prefix for the table class name. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  JTable	A database object
	 *
	 * @since   1.6
	 */
	public function getTable($type = 'Usergroup', $prefix =
'JTable', $config = array())
	{
		$return = JTable::getInstance($type, $prefix, $config);

		return $return;
	}

	/**
	 * Method to get the record form.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm	A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.group',
'group', array('control' => 'jform',
'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data =
JFactory::getApplication()->getUserState('com_users.edit.group.data',
array());

		if (empty($data))
		{
			$data = $this->getItem();
		}

		$this->preprocessData('com_users.group', $data);

		return $data;
	}

	/**
	 * Override preprocessForm to load the user plugin group instead of
content.
	 *
	 * @param   JForm   $form   A form object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error loading the form.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'')
	{
		$obj = is_array($data) ? ArrayHelper::toObject($data,
'JObject') : $data;

		if (isset($obj->parent_id) && $obj->parent_id == 0
&& $obj->id > 0)
		{
			$form->setFieldAttribute('parent_id', 'type',
'hidden');
			$form->setFieldAttribute('parent_id', 'hidden',
'true');
		}

		parent::preprocessForm($form, $data, 'user');
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.6
	 */
	public function save($data)
	{
		// Include the user plugins for events.
		JPluginHelper::importPlugin($this->events_map['save']);

		/**
		 * Check the super admin permissions for group
		 * We get the parent group permissions and then check the group
permissions manually
		 * We have to calculate the group permissions manually because we
haven't saved the group yet
		 */
		$parentSuperAdmin = JAccess::checkGroup($data['parent_id'],
'core.admin');

		// Get core.admin rules from the root asset
		$rules =
JAccess::getAssetRules('root.1')->getData('core.admin');

		// Get the value for the current group (will be true (allowed), false
(denied), or null (inherit)
		$groupSuperAdmin =
$rules['core.admin']->allow($data['id']);

		// We only need to change the $groupSuperAdmin if the parent is true or
false. Otherwise, the value set in the rule takes effect.
		if ($parentSuperAdmin === false)
		{
			// If parent is false (Denied), effective value will always be false
			$groupSuperAdmin = false;
		}
		elseif ($parentSuperAdmin === true)
		{
			// If parent is true (allowed), group is true unless explicitly set to
false
			$groupSuperAdmin = ($groupSuperAdmin === false) ? false : true;
		}

		// Check for non-super admin trying to save with super admin group
		$iAmSuperAdmin =
JFactory::getUser()->authorise('core.admin');

		if (!$iAmSuperAdmin && $groupSuperAdmin)
		{
			$this->setError(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN'));

			return false;
		}

		/**
		 * Check for super-admin changing self to be non-super-admin
		 * First, are we a super admin
		 */
		if ($iAmSuperAdmin)
		{
			// Next, are we a member of the current group?
			$myGroups =
JAccess::getGroupsByUser(JFactory::getUser()->get('id'),
false);

			if (in_array($data['id'], $myGroups))
			{
				// Now, would we have super admin permissions without the current
group?
				$otherGroups = array_diff($myGroups, array($data['id']));
				$otherSuperAdmin = false;

				foreach ($otherGroups as $otherGroup)
				{
					$otherSuperAdmin = $otherSuperAdmin ?:
JAccess::checkGroup($otherGroup, 'core.admin');
				}

				/**
				 * If we would not otherwise have super admin permissions
				 * and the current group does not have super admin permissions, throw
an exception
				 */
				if ((!$otherSuperAdmin) && (!$groupSuperAdmin))
				{
					$this->setError(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'));

					return false;
				}
			}
		}

		if (JFactory::getApplication()->input->get('task') ==
'save2copy')
		{
			$data['title'] =
$this->generateGroupTitle($data['parent_id'],
$data['title']);
		}

		// Proceed with the save
		return parent::save($data);
	}

	/**
	 * Method to delete rows.
	 *
	 * @param   array  &$pks  An array of item ids.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   1.6
	 * @throws  Exception
	 */
	public function delete(&$pks)
	{
		// Typecast variable.
		$pks    = (array) $pks;
		$user   = JFactory::getUser();
		$groups = JAccess::getGroupsByUser($user->get('id'));

		// Get a row instance.
		$table = $this->getTable();

		// Load plugins.
		JPluginHelper::importPlugin($this->events_map['delete']);
		$dispatcher = JEventDispatcher::getInstance();

		// Check if I am a Super Admin
		$iAmSuperAdmin = $user->authorise('core.admin');

		// Do not allow to delete groups to which the current user belongs
		foreach ($pks as $pk)
		{
			if (in_array($pk, $groups))
			{
				JError::raiseWarning(403,
JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP'));

				return false;
			}
		}

		// Iterate the items to delete each one.
		foreach ($pks as $i => $pk)
		{
			if ($table->load($pk))
			{
				// Access checks.
				$allow = $user->authorise('core.edit.state',
'com_users');

				// Don't allow non-super-admin to delete a super admin
				$allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk,
'core.admin')) ? false : $allow;

				if ($allow)
				{
					// Fire the before delete event.
					$dispatcher->trigger($this->event_before_delete,
array($table->getProperties()));

					if (!$table->delete($pk))
					{
						$this->setError($table->getError());

						return false;
					}
					else
					{
						// Trigger the after delete event.
						$dispatcher->trigger($this->event_after_delete,
array($table->getProperties(), true, $this->getError()));
					}
				}
				else
				{
					// Prune items that you can't change.
					unset($pks[$i]);
					JError::raiseWarning(403,
JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
				}
			}
			else
			{
				$this->setError($table->getError());

				return false;
			}
		}

		return true;
	}

	/**
	 * Method to generate the title of group on Save as Copy action
	 *
	 * @param   integer  $parentId  The id of the parent.
	 * @param   string   $title     The title of group
	 *
	 * @return  string  Contains the modified title.
	 *
	 * @since   3.3.7
	 */
	protected function generateGroupTitle($parentId, $title)
	{
		// Alter the title & alias
		$table = $this->getTable();

		while ($table->load(array('title' => $title,
'parent_id' => $parentId)))
		{
			if ($title == $table->title)
			{
				$title = StringHelper::increment($title);
			}
		}

		return $title;
	}
}
models/groups.php000064400000013453151165673570010105 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Methods supporting a list of user group records.
 *
 * @since  1.6
 */
class UsersModelGroups extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JController
	 * @since   1.6
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'parent_id', 'a.parent_id',
				'title', 'a.title',
				'lft', 'a.lft',
				'rgt', 'a.rgt',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.lft', $direction
= 'asc')
	{
		// Load the filter state.
		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search', '',
'string'));

		// Load the parameters.
		$params = JComponentHelper::getParams('com_users');
		$this->setState('params', $params);

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');

		return parent::getStoreId($id);
	}

	/**
	 * Gets the list of groups and adds expensive joins to the result set.
	 *
	 * @return  mixed  An array of data items on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getItems()
	{
		// Get a storage key.
		$store = $this->getStoreId();

		// Try to load the data from internal storage.
		if (empty($this->cache[$store]))
		{
			$items = parent::getItems();

			// Bail out on an error or empty list.
			if (empty($items))
			{
				$this->cache[$store] = $items;

				return $items;
			}

			try
			{
				$items = $this->populateExtraData($items);
			}
			catch (RuntimeException $e)
			{
				$this->setError($e->getMessage());

				return false;
			}

			// Add the items to the internal cache.
			$this->cache[$store] = $items;
		}

		return $this->cache[$store];
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'a.*'
			)
		);
		$query->from($db->quoteName('#__usergroups') . ' AS
a');

		// Filter the comments over the search string if set.
		$search = $this->getState('filter.search');

		if (!empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			else
			{
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));
				$query->where('a.title LIKE ' . $search);
			}
		}

		// Add the list ordering clause.
		$query->order($db->escape($this->getState('list.ordering',
'a.lft')) . ' ' .
$db->escape($this->getState('list.direction',
'ASC')));

		return $query;
	}

	/**
	 * Populate level & path for items.
	 *
	 * @param   array  $items  Array of stdClass objects
	 *
	 * @return  array
	 *
	 * @since   3.6.3
	 */
	private function populateExtraData(array $items)
	{
		// First pass: get list of the group id's and reset the counts.
		$groupsByKey = array();

		foreach ($items as $item)
		{
			$groupsByKey[(int) $item->id] = $item;
		}

		$groupIds = array_keys($groupsByKey);

		$db = $this->getDbo();

		// Get total enabled users in group.
		$query = $db->getQuery(true);

		// Count the objects in the user group.
		$query->select('map.group_id, COUNT(DISTINCT map.user_id) AS
user_count')
			->from($db->quoteName('#__user_usergroup_map',
'map'))
			->join('LEFT', $db->quoteName('#__users',
'u') . ' ON ' . $db->quoteName('u.id') .
' = ' . $db->quoteName('map.user_id'))
			->where($db->quoteName('map.group_id') . ' IN
(' . implode(',', $groupIds) . ')')
			->where($db->quoteName('u.block') . ' = 0')
			->group($db->quoteName('map.group_id'));
		$db->setQuery($query);

		try
		{
			$countEnabled = $db->loadAssocList('group_id',
'count_enabled');
		}
		catch (RuntimeException $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		// Get total disabled users in group.
		$query->clear('where')
			->where('map.group_id IN (' . implode(',',
$groupIds) . ')')
			->where('u.block = 1');
		$db->setQuery($query);

		try
		{
			$countDisabled = $db->loadAssocList('group_id',
'count_disabled');
		}
		catch (RuntimeException $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		// Inject the values back into the array.
		foreach ($groupsByKey as &$item)
		{
			$item->count_enabled   = isset($countEnabled[$item->id]) ? (int)
$countEnabled[$item->id]['user_count'] : 0;
			$item->count_disabled  = isset($countDisabled[$item->id]) ? (int)
$countDisabled[$item->id]['user_count'] : 0;
			$item->user_count      = $item->count_enabled +
$item->count_disabled;
		}

		$groups = new JHelperUsergroups($groupsByKey);

		return array_values($groups->getAll());
	}
}
models/level.php000064400000016443151165673570007677 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;


use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\UserGroupsHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\Utilities\ArrayHelper;

/**
 * User view level model.
 *
 * @since  1.6
 */
class UsersModelLevel extends AdminModel
{
	/**
	 * @var	array	A list of the access levels in use.
	 * @since   1.6
	 */
	protected $levelsInUse = null;

	/**
	 * Method to test whether a record can be deleted.
	 *
	 * @param   object  $record  A record object.
	 *
	 * @return  boolean  True if allowed to delete the record. Defaults to the
permission set in the component.
	 *
	 * @since   1.6
	 */
	protected function canDelete($record)
	{
		$groups = json_decode($record->rules);

		if ($groups === null)
		{
			throw new RuntimeException('Invalid rules schema');
		}

		$isAdmin = JFactory::getUser()->authorise('core.admin');

		// Check permissions
		foreach ($groups as $group)
		{
			if (!$isAdmin && JAccess::checkGroup($group,
'core.admin'))
			{
				$this->setError(JText::_('JERROR_ALERTNOAUTHOR'));

				return false;
			}
		}

		// Check if the access level is being used by any content.
		if ($this->levelsInUse === null)
		{
			// Populate the list once.
			$this->levelsInUse = array();

			$db    = $this->getDbo();
			$query = $db->getQuery(true)
				->select('DISTINCT access');

			// Get all the tables and the prefix
			$tables = $db->getTableList();
			$prefix = $db->getPrefix();

			foreach ($tables as $table)
			{
				// Get all of the columns in the table
				$fields = $db->getTableColumns($table);

				/**
				 * We are looking for the access field.  If custom tables are using
something other
				 * than the 'access' field they are on their own
unfortunately.
				 * Also make sure the table prefix matches the live db prefix (eg, it
is not a "bak_" table)
				 */
				if (strpos($table, $prefix) === 0 &&
isset($fields['access']))
				{
					// Lookup the distinct values of the field.
					$query->clear('from')
						->from($db->quoteName($table));
					$db->setQuery($query);

					try
					{
						$values = $db->loadColumn();
					}
					catch (RuntimeException $e)
					{
						$this->setError($e->getMessage());

						return false;
					}

					$this->levelsInUse = array_merge($this->levelsInUse, $values);

					// TODO Could assemble an array of the tables used by each view level
list those,
					// giving the user a clue in the error where to look.
				}
			}

			// Get uniques.
			$this->levelsInUse = array_unique($this->levelsInUse);

			// Ok, after all that we are ready to check the record :)
		}

		if (in_array($record->id, $this->levelsInUse))
		{
			$this->setError(JText::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE',
$record->id, $record->title));

			return false;
		}

		return parent::canDelete($record);
	}

	/**
	 * Returns a reference to the a Table object, always creating it.
	 *
	 * @param   string  $type    The table type to instantiate
	 * @param   string  $prefix  A prefix for the table class name. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  JTable  A database object
	 *
	 * @since   1.6
	 */
	public function getTable($type = 'Viewlevel', $prefix =
'JTable', $config = array())
	{
		$return = JTable::getInstance($type, $prefix, $config);

		return $return;
	}

	/**
	 * Method to get a single record.
	 *
	 * @param   integer  $pk  The id of the primary key.
	 *
	 * @return  mixed  Object on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getItem($pk = null)
	{
		$result = parent::getItem($pk);

		// Convert the params field to an array.
		$result->rules = json_decode($result->rules);

		return $result;
	}

	/**
	 * Method to get the record form.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm	A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.level',
'level', array('control' => 'jform',
'load_data' => $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data =
JFactory::getApplication()->getUserState('com_users.edit.level.data',
array());

		if (empty($data))
		{
			$data = $this->getItem();
		}

		$this->preprocessData('com_users.level', $data);

		return $data;
	}

	/**
	 * Method to preprocess the form
	 *
	 * @param   JForm   $form   A form object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error loading the form.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'')
	{
		parent::preprocessForm($form, $data, 'user');
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.6
	 */
	public function save($data)
	{
		if (!isset($data['rules']))
		{
			$data['rules'] = array();
		}

		$data['title'] =
JFilterInput::getInstance()->clean($data['title'],
'TRIM');

		return parent::save($data);
	}

	/**
	 * Method to validate the form data.
	 *
	 * @param   \JForm  $form   The form to validate against.
	 * @param   array   $data   The data to validate.
	 * @param   string  $group  The name of the field group to validate.
	 *
	 * @return  array|boolean  Array of filtered data if valid, false
otherwise.
	 *
	 * @see     \JFormRule
	 * @see     \JFilterInput
	 * @since   3.8.8
	 */
	public function validate($form, $data, $group = null)
	{
		$isSuperAdmin = Factory::getUser()->authorise('core.admin');

		// Non Super user should not be able to change the access levels of super
user groups
		if (!$isSuperAdmin)
		{
			if (!isset($data['rules']) ||
!is_array($data['rules']))
			{
				$data['rules'] = array();
			}

			$groups = array_values(UserGroupsHelper::getInstance()->getAll());

			$rules = array();

			if (!empty($data['id']))
			{
				$table = $this->getTable();

				$table->load($data['id']);

				$rules = json_decode($table->rules);
			}

			$rules = ArrayHelper::toInteger($rules);

			for ($i = 0, $n = count($groups); $i < $n; ++$i)
			{
				if (Access::checkGroup((int) $groups[$i]->id,
'core.admin'))
				{
					if (in_array((int) $groups[$i]->id, $rules) &&
!in_array((int) $groups[$i]->id, $data['rules']))
					{
						$data['rules'][] = (int) $groups[$i]->id;
					}
					elseif (!in_array((int) $groups[$i]->id, $rules) &&
in_array((int) $groups[$i]->id, $data['rules']))
					{
						$this->setError(Text::_('JLIB_USER_ERROR_NOT_SUPERADMIN'));

						return false;
					}
				}
			}
		}

		return parent::validate($form, $data, $group);
	}
}
models/levels.php000064400000012357151165673570010062 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Methods supporting a list of user access level records.
 *
 * @since  1.6
 */
class UsersModelLevels extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JController
	 * @since   1.6
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'title', 'a.title',
				'ordering', 'a.ordering',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.ordering',
$direction = 'asc')
	{
		// Load the filter state.
		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search'));

		// Load the parameters.
		$params = JComponentHelper::getParams('com_users');
		$this->setState('params', $params);

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');

		return parent::getStoreId($id);
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'a.*'
			)
		);
		$query->from($db->quoteName('#__viewlevels') . ' AS
a');

		// Add the level in the tree.
		$query->group('a.id, a.title, a.ordering, a.rules');

		// Filter the items over the search string if set.
		$search = $this->getState('filter.search');

		if (!empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			else
			{
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));
				$query->where('a.title LIKE ' . $search);
			}
		}

		$query->group('a.id');

		// Add the list ordering clause.
		$query->order($db->escape($this->getState('list.ordering',
'a.ordering')) . ' ' .
$db->escape($this->getState('list.direction',
'ASC')));

		return $query;
	}

	/**
	 * Method to adjust the ordering of a row.
	 *
	 * @param   integer  $pk         The ID of the primary key to move.
	 * @param   integer  $direction  Increment, usually +1 or -1
	 *
	 * @return  boolean  False on failure or error, true otherwise.
	 */
	public function reorder($pk, $direction = 0)
	{
		// Sanitize the id and adjustment.
		$pk = (!empty($pk)) ? $pk : (int)
$this->getState('level.id');
		$user = JFactory::getUser();

		// Get an instance of the record's table.
		$table = JTable::getInstance('viewlevel');

		// Load the row.
		if (!$table->load($pk))
		{
			$this->setError($table->getError());

			return false;
		}

		// Access checks.
		$allow = $user->authorise('core.edit.state',
'com_users');

		if (!$allow)
		{
			$this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));

			return false;
		}

		// Move the row.
		// TODO: Where clause to restrict category.
		$table->move($pk);

		return true;
	}

	/**
	 * Saves the manually set order of records.
	 *
	 * @param   array    $pks    An array of primary key ids.
	 * @param   integer  $order  Order position
	 *
	 * @return  boolean|JException  Boolean true on success, boolean false or
JException instance on error
	 */
	public function saveorder($pks, $order)
	{
		$table = JTable::getInstance('viewlevel');
		$user = JFactory::getUser();
		$conditions = array();

		if (empty($pks))
		{
			return JError::raiseWarning(500,
JText::_('COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED'));
		}

		// Update ordering values
		foreach ($pks as $i => $pk)
		{
			$table->load((int) $pk);

			// Access checks.
			$allow = $user->authorise('core.edit.state',
'com_users');

			if (!$allow)
			{
				// Prune items that you can't change.
				unset($pks[$i]);
				JError::raiseWarning(403,
JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
			}
			elseif ($table->ordering != $order[$i])
			{
				$table->ordering = $order[$i];

				if (!$table->store())
				{
					$this->setError($table->getError());

					return false;
				}
			}
		}

		// Execute reorder for each category.
		foreach ($conditions as $cond)
		{
			$table->load($cond[0]);
			$table->reorder($cond[1]);
		}

		return true;
	}
}
models/mail.php000064400000013253151165673570007506 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users mail model.
 *
 * @since  1.6
 */
class UsersModelMail extends JModelAdmin
{
	/**
	 * Method to get the row form.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  JForm	A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.mail', 'mail',
array('control' => 'jform', 'load_data'
=> $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data =
JFactory::getApplication()->getUserState('com_users.display.mail.data',
array());

		$this->preprocessData('com_users.mail', $data);

		return $data;
	}

	/**
	 * Method to preprocess the form
	 *
	 * @param   JForm   $form   A form object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error loading the form.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Send the email
	 *
	 * @return  boolean
	 */
	public function send()
	{
		$app    = JFactory::getApplication();
		$data   = $app->input->post->get('jform', array(),
'array');
		$user   = JFactory::getUser();
		$access = new JAccess;
		$db     = $this->getDbo();

		$mode         = array_key_exists('mode', $data) ? (int)
$data['mode'] : 0;
		$subject      = array_key_exists('subject', $data) ?
$data['subject'] : '';
		$grp          = array_key_exists('group', $data) ? (int)
$data['group'] : 0;
		$recurse      = array_key_exists('recurse', $data) ? (int)
$data['recurse'] : 0;
		$bcc          = array_key_exists('bcc', $data) ? (int)
$data['bcc'] : 0;
		$disabled     = array_key_exists('disabled', $data) ? (int)
$data['disabled'] : 0;
		$message_body = array_key_exists('message', $data) ?
$data['message'] : '';

		// Automatically removes html formatting
		if (!$mode)
		{
			$message_body = JFilterInput::getInstance()->clean($message_body,
'string');
		}

		// Check for a message body and subject
		if (!$message_body || !$subject)
		{
			$app->setUserState('com_users.display.mail.data', $data);
			$this->setError(JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY'));

			return false;
		}

		// Get users in the group out of the ACL, if group is provided.
		$to = $grp !== 0 ? $access->getUsersByGroup($grp, $recurse) : array();

		// When group is provided but no users are found in the group.
		if ($grp !== 0 && !$to)
		{
			$rows = array();
		}
		else
		{
			// Get all users email and group except for senders
			$query = $db->getQuery(true)
				->select($db->quoteName('email'))
				->from($db->quoteName('#__users'))
				->where($db->quoteName('id') . ' != ' . (int)
$user->id);

			if ($grp !== 0)
			{
				$query->where($db->quoteName('id') . ' IN ('
. implode(',', $to) . ')');
			}

			if ($disabled === 0)
			{
				$query->where($db->quoteName('block') . ' =
0');
			}

			$db->setQuery($query);
			$rows = $db->loadColumn();
		}

		// Check to see if there are any users in this group before we continue
		if (!$rows)
		{
			$app->setUserState('com_users.display.mail.data', $data);

			if (in_array($user->id, $to))
			{
				$this->setError(JText::_('COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP'));
			}
			else
			{
				$this->setError(JText::_('COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP'));
			}

			return false;
		}

		// Get the Mailer
		$mailer = JFactory::getMailer();
		$params = JComponentHelper::getParams('com_users');

		// Build email message format.
		$mailer->setSender(array($app->get('mailfrom'),
$app->get('fromname')));
		$mailer->setSubject($params->get('mailSubjectPrefix') .
stripslashes($subject));
		$mailer->setBody($message_body .
$params->get('mailBodySuffix'));
		$mailer->IsHtml($mode);

		// Add recipients
		if ($bcc)
		{
			$mailer->addBcc($rows);
			$mailer->addRecipient($app->get('mailfrom'));
		}
		else
		{
			$mailer->addRecipient($rows);
		}

		// Send the Mail
		$rs = $mailer->Send();

		// Check for an error
		if ($rs instanceof Exception)
		{
			$app->setUserState('com_users.display.mail.data', $data);
			$this->setError($rs->getError());

			return false;
		}
		elseif (empty($rs))
		{
			$app->setUserState('com_users.display.mail.data', $data);
			$this->setError(JText::_('COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT'));

			return false;
		}
		else
		{
			/**
			 * Fill the data (specially for the 'mode', 'group'
and 'bcc': they could not exist in the array
			 * when the box is not checked and in this case, the default value would
be used instead of the '0'
			 * one)
			 */
			$data['mode']    = $mode;
			$data['subject'] = $subject;
			$data['group']   = $grp;
			$data['recurse'] = $recurse;
			$data['bcc']     = $bcc;
			$data['message'] = $message_body;
			$app->setUserState('com_users.display.mail.data', array());
			$app->enqueueMessage(JText::plural('COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS',
count($rows)), 'message');

			return true;
		}
	}
}
models/note.php000064400000006433151165673570007533 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User note model.
 *
 * @since  2.5
 */
class UsersModelNote extends JModelAdmin
{
	/**
	 * The type alias for this content type.
	 *
	 * @var      string
	 * @since    3.2
	 */
	public $typeAlias = 'com_users.note';

	/**
	 * Method to get the record form.
	 *
	 * @param   array    $data      Data for the form.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  mixed  A JForm object on success, false on failure
	 *
	 * @since   2.5
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.note', 'note',
array('control' => 'jform', 'load_data'
=> $loadData));

		if (empty($form))
		{
			return false;
		}

		return $form;
	}

	/**
	 * Method to get a single record.
	 *
	 * @param   integer  $pk  The id of the primary key.
	 *
	 * @return  mixed  Object on success, false on failure.
	 *
	 * @since   2.5
	 */
	public function getItem($pk = null)
	{
		$result = parent::getItem($pk);

		// Get the dispatcher and load the content plugins.
		$dispatcher = JEventDispatcher::getInstance();
		JPluginHelper::importPlugin('content');

		// Load the user plugins for backward compatibility (v3.3.3 and earlier).
		JPluginHelper::importPlugin('user');

		// Trigger the data preparation event.
		$dispatcher->trigger('onContentPrepareData',
array('com_users.note', $result));

		return $result;
	}

	/**
	 * Method to get a table object, load it if necessary.
	 *
	 * @param   string  $name     The table name. Optional.
	 * @param   string  $prefix   The class prefix. Optional.
	 * @param   array   $options  Configuration array for model. Optional.
	 *
	 * @return  JTable  The table object
	 *
	 * @since   2.5
	 */
	public function getTable($name = 'Note', $prefix =
'UsersTable', $options = array())
	{
		return JTable::getInstance($name, $prefix, $options);
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Get the application
		$app = JFactory::getApplication();

		// Check the session for previously entered form data.
		$data = $app->getUserState('com_users.edit.note.data',
array());

		if (empty($data))
		{
			$data = $this->getItem();

			// Prime some default values.
			if ($this->getState('note.id') == 0)
			{
				$data->set('catid',
$app->input->get('catid',
$app->getUserState('com_users.notes.filter.category_id'),
'int'));
			}

			$userId = $app->input->get('u_id', 0, 'int');

			if ($userId != 0)
			{
				$data->user_id = $userId;
			}
		}

		$this->preprocessData('com_users.note', $data);

		return $data;
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function populateState()
	{
		parent::populateState();

		$userId = JFactory::getApplication()->input->get('u_id',
0, 'int');
		$this->setState('note.user_id', $userId);
	}
}
models/notes.php000064400000013450151165673570007713 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User notes model class.
 *
 * @since  2.5
 */
class UsersModelNotes extends JModelList
{
	/**
	 * Class constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @since  2.5
	 */
	public function __construct($config = array())
	{
		// Set the list ordering fields.
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'user_id', 'a.user_id',
				'u.name',
				'subject', 'a.subject',
				'catid', 'a.catid', 'category_id',
				'state', 'a.state', 'published',
				'c.title',
				'review_time', 'a.review_time',
				'publish_up', 'a.publish_up',
				'publish_down', 'a.publish_down',
				'level', 'c.level',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery  A JDatabaseQuery object to retrieve the data
set.
	 *
	 * @since   2.5
	 */
	protected function getListQuery()
	{
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState('list.select',
				'a.id, a.subject, a.checked_out, a.checked_out_time,' .
				'a.catid, a.created_time, a.review_time,' .
				'a.state, a.publish_up, a.publish_down'
			)
		);
		$query->from('#__user_notes AS a');

		// Join over the category
		$query->select('c.title AS category_title, c.params AS
category_params')
			->join('LEFT', '#__categories AS c ON c.id =
a.catid');

		// Join over the users for the note user.
		$query->select('u.name AS user_name')
			->join('LEFT', '#__users AS u ON u.id =
a.user_id');

		// Join over the users for the checked out user.
		$query->select('uc.name AS editor')
			->join('LEFT', '#__users AS uc ON uc.id =
a.checked_out');

		// Filter by search in title
		$search = $this->getState('filter.search');

		if (!empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			elseif (stripos($search, 'uid:') === 0)
			{
				$query->where('a.user_id = ' . (int) substr($search, 4));
			}
			else
			{
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));
				$query->where('((a.subject LIKE ' . $search . ') OR
(u.name LIKE ' . $search . ') OR (u.username LIKE ' .
$search . '))');
			}
		}

		// Filter by published state
		$published = $this->getState('filter.published');

		if (is_numeric($published))
		{
			$query->where('a.state = ' . (int) $published);
		}
		elseif ($published === '')
		{
			$query->where('(a.state IN (0, 1))');
		}

		// Filter by a single category.
		$categoryId = (int) $this->getState('filter.category_id');

		if ($categoryId)
		{
			$query->where('a.catid = ' . $categoryId);
		}

		// Filter by a single user.
		$userId = (int) $this->getState('filter.user_id');

		if ($userId)
		{
			// Add the body and where filter.
			$query->select('a.body')
				->where('a.user_id = ' . $userId);
		}

		// Filter on the level.
		if ($level = $this->getState('filter.level'))
		{
			$query->where($db->quoteName('c.level') . ' <=
' . (int) $level);
		}

		// Add the list ordering clause.
		$query->order($db->escape($this->getState('list.ordering',
'a.review_time')) . ' ' .
$db->escape($this->getState('list.direction',
'DESC')));

		return $query;
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 *
	 * @since   2.5
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' . $this->getState('filter.published');
		$id .= ':' .
$this->getState('filter.category_id');
		$id .= ':' . $this->getState('filter.user_id');
		$id .= ':' . $this->getState('filter.level');

		return parent::getStoreId($id);
	}

	/**
	 * Gets a user object if the user filter is set.
	 *
	 * @return  JUser  The JUser object
	 *
	 * @since   2.5
	 */
	public function getUser()
	{
		$user = new JUser;

		// Filter by search in title
		$search = (int) $this->getState('filter.user_id');

		if ($search != 0)
		{
			$user->load((int) $search);
		}

		return $user;
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.review_time',
$direction = 'desc')
	{
		// Adjust the context to support modal layouts.
		if ($layout =
JFactory::getApplication()->input->get('layout'))
		{
			$this->context .= '.' . $layout;
		}

		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search'));
		$this->setState('filter.published',
$this->getUserStateFromRequest($this->context .
'.filter.published', 'filter_published', '',
'string'));
		$this->setState('filter.category_id',
$this->getUserStateFromRequest($this->context .
'.filter.category_id', 'filter_category_id'));
		$this->setState('filter.user_id',
$this->getUserStateFromRequest($this->context .
'.filter.user_id', 'filter_user_id'));
		$this->setState('filter.level',
$this->getUserStateFromRequest($this->context .
'.filter.level', 'filter_level', '',
'cmd'));

		parent::populateState($ordering, $direction);
	}
}
models/user.php000064400000101446151165673570007544 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;

/**
 * User model.
 *
 * @since  1.6
 */
class UsersModelUser extends JModelAdmin
{
	/**
	 * An item.
	 *
	 * @var    array
	 */
	protected $_item = null;

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @since   3.2
	 */
	public function __construct($config = array())
	{
		$config = array_merge(
			array(
				'event_after_delete'  => 'onUserAfterDelete',
				'event_after_save'    => 'onUserAfterSave',
				'event_before_delete' => 'onUserBeforeDelete',
				'event_before_save'   => 'onUserBeforeSave',
				'events_map'          => array('save' =>
'user', 'delete' => 'user',
'validate' => 'user')
			), $config
		);

		parent::__construct($config);
	}

	/**
	 * Returns a reference to the a Table object, always creating it.
	 *
	 * @param   string  $type    The table type to instantiate
	 * @param   string  $prefix  A prefix for the table class name. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  JTable  A database object
	 *
	 * @since   1.6
	 */
	public function getTable($type = 'User', $prefix =
'JTable', $config = array())
	{
		$table = JTable::getInstance($type, $prefix, $config);

		return $table;
	}

	/**
	 * Method to get a single record.
	 *
	 * @param   integer  $pk  The id of the primary key.
	 *
	 * @return  mixed  Object on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getItem($pk = null)
	{
		$pk = (!empty($pk)) ? $pk : (int)
$this->getState('user.id');

		if ($this->_item === null)
		{
			$this->_item = array();
		}

		if (!isset($this->_item[$pk]))
		{
			$this->_item[$pk] = parent::getItem($pk);
		}

		return $this->_item[$pk];
	}

	/**
	 * Method to get the record form.
	 *
	 * @param   array    $data      An optional array of data for the form to
interrogate.
	 * @param   boolean  $loadData  True if the form is to load its own data
(default case), false if not.
	 *
	 * @return  mixed  A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	public function getForm($data = array(), $loadData = true)
	{
		// Get the form.
		$form = $this->loadForm('com_users.user', 'user',
array('control' => 'jform', 'load_data'
=> $loadData));

		if (empty($form))
		{
			return false;
		}

		// If the user needs to change their password, mark the password fields
as required
		if (JFactory::getUser()->requireReset)
		{
			$form->setFieldAttribute('password', 'required',
'true');
			$form->setFieldAttribute('password2', 'required',
'true');
		}

		// When multilanguage is set, a user's default site language should
also be a Content Language
		if (JLanguageMultilang::isEnabled())
		{
			$form->setFieldAttribute('language', 'type',
'frontend_language', 'params');
		}

		$userId = $form->getValue('id');

		// The user should not be able to set the requireReset value on their own
account
		if ((int) $userId === (int) JFactory::getUser()->id)
		{
			$form->removeField('requireReset');
		}

		return $form;
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data =
JFactory::getApplication()->getUserState('com_users.edit.user.data',
array());

		if (empty($data))
		{
			$data = $this->getItem();
		}

		$this->preprocessData('com_users.profile', $data,
'user');

		return $data;
	}

	/**
	 * Override JModelAdmin::preprocessForm to ensure the correct plugin group
is loaded.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import
(defaults to "content").
	 *
	 * @return  void
	 *
	 * @since   1.6
	 * @throws  Exception if there is an error in the form event.
	 */
	protected function preprocessForm(JForm $form, $data, $group =
'user')
	{
		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.6
	 */
	public function save($data)
	{
		$pk   = (!empty($data['id'])) ? $data['id'] : (int)
$this->getState('user.id');
		$user = JUser::getInstance($pk);

		$my = JFactory::getUser();
		$iAmSuperAdmin = $my->authorise('core.admin');

		// User cannot modify own user groups
		if ((int) $user->id == (int) $my->id && !$iAmSuperAdmin
&& isset($data['groups']))
		{
			// Form was probably tampered with
			JFactory::getApplication()->enqueueMessage(JText::_('COM_USERS_USERS_ERROR_CANNOT_EDIT_OWN_GROUP'),
'warning');

			$data['groups'] = null;
		}

		if ($data['block'] && $pk == $my->id &&
!$my->block)
		{
			$this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF'));

			return false;
		}

		// Make sure user groups is selected when add/edit an account
		if (empty($data['groups']) && ((int) $user->id !=
(int) $my->id || $iAmSuperAdmin))
		{
			$this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_SAVE_ACCOUNT_WITHOUT_GROUPS'));

			return false;
		}

		// Make sure that we are not removing ourself from Super Admin group
		if ($iAmSuperAdmin && $my->get('id') == $pk)
		{
			// Check that at least one of our new groups is Super Admin
			$stillSuperAdmin = false;
			$myNewGroups = $data['groups'];

			foreach ($myNewGroups as $group)
			{
				$stillSuperAdmin = $stillSuperAdmin ?: JAccess::checkGroup($group,
'core.admin');
			}

			if (!$stillSuperAdmin)
			{
				$this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF'));

				return false;
			}
		}

		// Handle the two factor authentication setup
		if (array_key_exists('twofactor', $data))
		{
			$twoFactorMethod = $data['twofactor']['method'];

			// Get the current One Time Password (two factor auth) configuration
			$otpConfig = $this->getOtpConfig($pk);

			if ($twoFactorMethod != 'none')
			{
				// Run the plugins
				FOFPlatform::getInstance()->importPlugin('twofactorauth');
				$otpConfigReplies =
FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration',
array($twoFactorMethod));

				// Look for a valid reply
				foreach ($otpConfigReplies as $reply)
				{
					if (!is_object($reply) || empty($reply->method) ||
($reply->method != $twoFactorMethod))
					{
						continue;
					}

					$otpConfig->method = $reply->method;
					$otpConfig->config = $reply->config;

					break;
				}

				// Save OTP configuration.
				$this->setOtpConfig($pk, $otpConfig);

				// Generate one time emergency passwords if required (depleted or not
set)
				if (empty($otpConfig->otep))
				{
					$oteps = $this->generateOteps($pk);
				}
			}
			else
			{
				$otpConfig->method = 'none';
				$otpConfig->config = array();
				$this->setOtpConfig($pk, $otpConfig);
			}

			// Unset the raw data
			unset($data['twofactor']);

			// Reload the user record with the updated OTP configuration
			$user->load($pk);
		}

		// Bind the data.
		if (!$user->bind($data))
		{
			$this->setError($user->getError());

			return false;
		}

		// Store the data.
		if (!$user->save())
		{
			$this->setError($user->getError());

			return false;
		}

		$this->setState('user.id', $user->id);

		return true;
	}

	/**
	 * Method to delete rows.
	 *
	 * @param   array  &$pks  An array of item ids.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function delete(&$pks)
	{
		$user  = JFactory::getUser();
		$table = $this->getTable();
		$pks   = (array) $pks;

		// Check if I am a Super Admin
		$iAmSuperAdmin = $user->authorise('core.admin');

		JPluginHelper::importPlugin($this->events_map['delete']);
		$dispatcher = JEventDispatcher::getInstance();

		if (in_array($user->id, $pks))
		{
			$this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF'));

			return false;
		}

		// Iterate the items to delete each one.
		foreach ($pks as $i => $pk)
		{
			if ($table->load($pk))
			{
				// Access checks.
				$allow = $user->authorise('core.delete',
'com_users');

				// Don't allow non-super-admin to delete a super admin
				$allow = (!$iAmSuperAdmin && JAccess::check($pk,
'core.admin')) ? false : $allow;

				if ($allow)
				{
					// Get users data for the users to delete.
					$user_to_delete = JFactory::getUser($pk);

					// Fire the before delete event.
					$dispatcher->trigger($this->event_before_delete,
array($table->getProperties()));

					if (!$table->delete($pk))
					{
						$this->setError($table->getError());

						return false;
					}
					else
					{
						// Trigger the after delete event.
						$dispatcher->trigger($this->event_after_delete,
array($user_to_delete->getProperties(), true, $this->getError()));
					}
				}
				else
				{
					// Prune items that you can't change.
					unset($pks[$i]);
					JError::raiseWarning(403,
JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
				}
			}
			else
			{
				$this->setError($table->getError());

				return false;
			}
		}

		return true;
	}

	/**
	 * Method to block user records.
	 *
	 * @param   array    &$pks   The ids of the items to publish.
	 * @param   integer  $value  The value of the published state
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.6
	 */
	public function block(&$pks, $value = 1)
	{
		$app        = JFactory::getApplication();
		$dispatcher = JEventDispatcher::getInstance();
		$user       = JFactory::getUser();

		// Check if I am a Super Admin
		$iAmSuperAdmin = $user->authorise('core.admin');
		$table         = $this->getTable();
		$pks           = (array) $pks;

		JPluginHelper::importPlugin($this->events_map['save']);

		// Prepare the logout options.
		$options = array(
			'clientid' => $app->get('shared_session',
'0') ? null : 0,
		);

		// Access checks.
		foreach ($pks as $i => $pk)
		{
			if ($value == 1 && $pk == $user->get('id'))
			{
				// Cannot block yourself.
				unset($pks[$i]);
				JError::raiseWarning(403,
JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF'));
			}
			elseif ($table->load($pk))
			{
				$old   = $table->getProperties();
				$allow = $user->authorise('core.edit.state',
'com_users');

				// Don't allow non-super-admin to delete a super admin
				$allow = (!$iAmSuperAdmin && JAccess::check($pk,
'core.admin')) ? false : $allow;

				if ($allow)
				{
					// Skip changing of same state
					if ($table->block == $value)
					{
						unset($pks[$i]);
						continue;
					}

					$table->block = (int) $value;

					// If unblocking, also change password reset count to zero to unblock
reset
					if ($table->block === 0)
					{
						$table->resetCount = 0;
					}

					// Allow an exception to be thrown.
					try
					{
						if (!$table->check())
						{
							$this->setError($table->getError());

							return false;
						}

						// Trigger the before save event.
						$result = $dispatcher->trigger($this->event_before_save,
array($old, false, $table->getProperties()));

						if (in_array(false, $result, true))
						{
							// Plugin will have to raise its own error or throw an exception.
							return false;
						}

						// Store the table.
						if (!$table->store())
						{
							$this->setError($table->getError());

							return false;
						}

						// Trigger the after save event
						$dispatcher->trigger($this->event_after_save,
array($table->getProperties(), false, true, null));
					}
					catch (Exception $e)
					{
						$this->setError($e->getMessage());

						return false;
					}

					// Log the user out.
					if ($value)
					{
						$app->logout($table->id, $options);
					}
				}
				else
				{
					// Prune items that you can't change.
					unset($pks[$i]);
					JError::raiseWarning(403,
JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
				}
			}
		}

		return true;
	}

	/**
	 * Method to activate user records.
	 *
	 * @param   array  &$pks  The ids of the items to activate.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.6
	 */
	public function activate(&$pks)
	{
		$dispatcher = JEventDispatcher::getInstance();
		$user       = JFactory::getUser();

		// Check if I am a Super Admin
		$iAmSuperAdmin = $user->authorise('core.admin');
		$table         = $this->getTable();
		$pks           = (array) $pks;

		JPluginHelper::importPlugin($this->events_map['save']);

		// Access checks.
		foreach ($pks as $i => $pk)
		{
			if ($table->load($pk))
			{
				$old   = $table->getProperties();
				$allow = $user->authorise('core.edit.state',
'com_users');

				// Don't allow non-super-admin to delete a super admin
				$allow = (!$iAmSuperAdmin && JAccess::check($pk,
'core.admin')) ? false : $allow;

				if (empty($table->activation))
				{
					// Ignore activated accounts.
					unset($pks[$i]);
				}
				elseif ($allow)
				{
					$table->block      = 0;
					$table->activation = '';

					// Allow an exception to be thrown.
					try
					{
						if (!$table->check())
						{
							$this->setError($table->getError());

							return false;
						}

						// Trigger the before save event.
						$result = $dispatcher->trigger($this->event_before_save,
array($old, false, $table->getProperties()));

						if (in_array(false, $result, true))
						{
							// Plugin will have to raise it's own error or throw an
exception.
							return false;
						}

						// Store the table.
						if (!$table->store())
						{
							$this->setError($table->getError());

							return false;
						}

						// Fire the after save event
						$dispatcher->trigger($this->event_after_save,
array($table->getProperties(), false, true, null));
					}
					catch (Exception $e)
					{
						$this->setError($e->getMessage());

						return false;
					}
				}
				else
				{
					// Prune items that you can't change.
					unset($pks[$i]);
					JError::raiseWarning(403,
JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
				}
			}
		}

		return true;
	}

	/**
	 * Method to perform batch operations on an item or a set of items.
	 *
	 * @param   array  $commands  An array of commands to perform.
	 * @param   array  $pks       An array of item ids.
	 * @param   array  $contexts  An array of item contexts.
	 *
	 * @return  boolean  Returns true on success, false on failure.
	 *
	 * @since   2.5
	 */
	public function batch($commands, $pks, $contexts)
	{
		// Sanitize user ids.
		$pks = array_unique($pks);
		$pks = ArrayHelper::toInteger($pks);

		// Remove any values of zero.
		if (array_search(0, $pks, true))
		{
			unset($pks[array_search(0, $pks, true)]);
		}

		if (empty($pks))
		{
			$this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED'));

			return false;
		}

		$done = false;

		if (!empty($commands['group_id']))
		{
			$cmd = ArrayHelper::getValue($commands, 'group_action',
'add');

			if (!$this->batchUser((int) $commands['group_id'], $pks,
$cmd))
			{
				return false;
			}

			$done = true;
		}

		if (!empty($commands['reset_id']))
		{
			if (!$this->batchReset($pks, $commands['reset_id']))
			{
				return false;
			}

			$done = true;
		}

		if (!$done)
		{
			$this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION'));

			return false;
		}

		// Clear the cache
		$this->cleanCache();

		return true;
	}

	/**
	 * Batch flag users as being required to reset their passwords
	 *
	 * @param   array   $userIds  An array of user IDs on which to operate
	 * @param   string  $action   The action to perform
	 *
	 * @return  boolean  True on success, false on failure
	 *
	 * @since   3.2
	 */
	public function batchReset($userIds, $action)
	{
		$userIds = ArrayHelper::toInteger($userIds);

		// Check if I am a Super Admin
		$iAmSuperAdmin =
JFactory::getUser()->authorise('core.admin');

		// Non-super super user cannot work with super-admin user.
		if (!$iAmSuperAdmin &&
JUserHelper::checkSuperUserInUsers($userIds))
		{
			$this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER'));

			return false;
		}

		// Set the action to perform
		if ($action === 'yes')
		{
			$value = 1;
		}
		else
		{
			$value = 0;
		}

		// Prune out the current user if they are in the supplied user ID array
		$userIds = array_diff($userIds, array(JFactory::getUser()->id));

		if (empty($userIds))
		{
			$this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_REQUIRERESET_SELF'));

			return false;
		}

		// Get the DB object
		$db = $this->getDbo();

		$userIds = ArrayHelper::toInteger($userIds);

		$query = $db->getQuery(true);

		// Update the reset flag
		$query->update($db->quoteName('#__users'))
			->set($db->quoteName('requireReset') . ' = ' .
$value)
			->where($db->quoteName('id') . ' IN (' .
implode(',', $userIds) . ')');

		$db->setQuery($query);

		try
		{
			$db->execute();
		}
		catch (RuntimeException $e)
		{
			$this->setError($e->getMessage());

			return false;
		}

		return true;
	}

	/**
	 * Perform batch operations
	 *
	 * @param   integer  $groupId  The group ID which assignments are being
edited
	 * @param   array    $userIds  An array of user IDs on which to operate
	 * @param   string   $action   The action to perform
	 *
	 * @return  boolean  True on success, false on failure
	 *
	 * @since   1.6
	 */
	public function batchUser($groupId, $userIds, $action)
	{
		$userIds = ArrayHelper::toInteger($userIds);

		// Check if I am a Super Admin
		$iAmSuperAdmin =
JFactory::getUser()->authorise('core.admin');

		// Non-super super user cannot work with super-admin user.
		if (!$iAmSuperAdmin &&
JUserHelper::checkSuperUserInUsers($userIds))
		{
			$this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER'));

			return false;
		}

		// Non-super admin cannot work with super-admin group.
		if ((!$iAmSuperAdmin && JAccess::checkGroup($groupId,
'core.admin')) || $groupId < 1)
		{
			$this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP'));

			return false;
		}

		// Get the DB object
		$db = $this->getDbo();

		switch ($action)
		{
			// Sets users to a selected group
			case 'set':
				$doDelete = 'all';
				$doAssign = true;
				break;

			// Remove users from a selected group
			case 'del':
				$doDelete = 'group';
				break;

			// Add users to a selected group
			case 'add':
			default:
				$doAssign = true;
				break;
		}

		// Remove the users from the group if requested.
		if (isset($doDelete))
		{
			$query = $db->getQuery(true);

			// Remove users from the group
			$query->delete($db->quoteName('#__user_usergroup_map'))
				->where($db->quoteName('user_id') . ' IN (' .
implode(',', $userIds) . ')');

			// Only remove users from selected group
			if ($doDelete == 'group')
			{
				$query->where($db->quoteName('group_id') . ' =
' . (int) $groupId);
			}

			$db->setQuery($query);

			try
			{
				$db->execute();
			}
			catch (RuntimeException $e)
			{
				$this->setError($e->getMessage());

				return false;
			}
		}

		// Assign the users to the group if requested.
		if (isset($doAssign))
		{
			$query = $db->getQuery(true);

			// First, we need to check if the user is already assigned to a group
			$query->select($db->quoteName('user_id'))
				->from($db->quoteName('#__user_usergroup_map'))
				->where($db->quoteName('group_id') . ' = ' .
(int) $groupId);
			$db->setQuery($query);
			$users = $db->loadColumn();

			// Build the values clause for the assignment query.
			$query->clear();
			$groups = false;

			foreach ($userIds as $id)
			{
				if (!in_array($id, $users))
				{
					$query->values($id . ',' . $groupId);
					$groups = true;
				}
			}

			// If we have no users to process, throw an error to notify the user
			if (!$groups)
			{
				$this->setError(JText::_('COM_USERS_ERROR_NO_ADDITIONS'));

				return false;
			}

			$query->insert($db->quoteName('#__user_usergroup_map'))
				->columns(array($db->quoteName('user_id'),
$db->quoteName('group_id')));
			$db->setQuery($query);

			try
			{
				$db->execute();
			}
			catch (RuntimeException $e)
			{
				$this->setError($e->getMessage());

				return false;
			}
		}

		return true;
	}

	/**
	 * Gets the available groups.
	 *
	 * @return  array  An array of groups
	 *
	 * @since   1.6
	 */
	public function getGroups()
	{
		$user = JFactory::getUser();

		if ($user->authorise('core.edit', 'com_users')
&& $user->authorise('core.manage',
'com_users'))
		{
			$model = JModelLegacy::getInstance('Groups',
'UsersModel', array('ignore_request' => true));

			return $model->getItems();
		}
		else
		{
			return null;
		}
	}

	/**
	 * Gets the groups this object is assigned to
	 *
	 * @param   integer  $userId  The user ID to retrieve the groups for
	 *
	 * @return  array  An array of assigned groups
	 *
	 * @since   1.6
	 */
	public function getAssignedGroups($userId = null)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		if (empty($userId))
		{
			$result   = array();
			$form     = $this->getForm();

			if ($form)
			{
				$groupsIDs = $form->getValue('groups');
			}

			if (!empty($groupsIDs))
			{
				$result = $groupsIDs;
			}
			else
			{
				$params = JComponentHelper::getParams('com_users');

				if ($groupId = $params->get('new_usertype',
$params->get('guest_usergroup', 1)))
				{
					$result[] = $groupId;
				}
			}
		}
		else
		{
			$result = JUserHelper::getUserGroups($userId);
		}

		return $result;
	}

	/**
	 * Returns the one time password (OTP) – a.k.a. two factor
authentication –
	 * configuration for a particular user.
	 *
	 * @param   integer  $userId  The numeric ID of the user
	 *
	 * @return  stdClass  An object holding the OTP configuration for this
user
	 *
	 * @since   3.2
	 */
	public function getOtpConfig($userId = null)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		// Initialise
		$otpConfig = (object) array(
			'method' => 'none',
			'config' => array(),
			'otep'   => array()
		);

		/**
		 * Get the raw data, without going through JUser (required in order to
		 * be able to modify the user record before logging in the user).
		 */
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->qn('#__users'))
			->where($db->qn('id') . ' = ' . (int)
$userId);
		$db->setQuery($query);
		$item = $db->loadObject();

		// Make sure this user does have OTP enabled
		if (empty($item->otpKey))
		{
			return $otpConfig;
		}

		// Get the encrypted data
		list($method, $config) = explode(':', $item->otpKey, 2);
		$encryptedOtep = $item->otep;

		// Get the secret key, yes the thing that is saved in the configuration
file
		$key = $this->getOtpConfigEncryptionKey();

		if (strpos($config, '{') === false)
		{
			$openssl         = new FOFEncryptAes($key, 256);
			$mcrypt          = new FOFEncryptAes($key, 256, 'cbc', null,
'mcrypt');

			$decryptedConfig = $mcrypt->decryptString($config);

			if (strpos($decryptedConfig, '{') !== false)
			{
				// Data encrypted with mcrypt
				$decryptedOtep = $mcrypt->decryptString($encryptedOtep);
				$encryptedOtep = $openssl->encryptString($decryptedOtep);
			}
			else
			{
				// Config data seems to be save encrypted, this can happen with 3.6.3
and openssl, lets get the data
				$decryptedConfig = $openssl->decryptString($config);
			}

			$otpKey = $method . ':' . $decryptedConfig;

			$query = $db->getQuery(true)
				->update($db->qn('#__users'))
				->set($db->qn('otep') . '=' .
$db->q($encryptedOtep))
				->set($db->qn('otpKey') . '=' .
$db->q($otpKey))
				->where($db->qn('id') . ' = ' .
$db->q($userId));
			$db->setQuery($query);
			$db->execute();
		}
		else
		{
			$decryptedConfig = $config;
		}

		// Create an encryptor class
		$aes = new FOFEncryptAes($key, 256);

		// Decrypt the data
		$decryptedOtep = $aes->decryptString($encryptedOtep);

		// Remove the null padding added during encryption
		$decryptedConfig = rtrim($decryptedConfig, "\0");
		$decryptedOtep = rtrim($decryptedOtep, "\0");

		// Update the configuration object
		$otpConfig->method = $method;
		$otpConfig->config = @json_decode($decryptedConfig);
		$otpConfig->otep = @json_decode($decryptedOtep);

		/*
		 * If the decryption failed for any reason we essentially disable the
		 * two-factor authentication. This prevents impossible to log in sites
		 * if the site admin changes the site secret for any reason.
		 */
		if (is_null($otpConfig->config))
		{
			$otpConfig->config = array();
		}

		if (is_object($otpConfig->config))
		{
			$otpConfig->config = (array) $otpConfig->config;
		}

		if (is_null($otpConfig->otep))
		{
			$otpConfig->otep = array();
		}

		if (is_object($otpConfig->otep))
		{
			$otpConfig->otep = (array) $otpConfig->otep;
		}

		// Return the configuration object
		return $otpConfig;
	}

	/**
	 * Sets the one time password (OTP) – a.k.a. two factor authentication
–
	 * configuration for a particular user. The $otpConfig object is the same
as
	 * the one returned by the getOtpConfig method.
	 *
	 * @param   integer   $userId     The numeric ID of the user
	 * @param   stdClass  $otpConfig  The OTP configuration object
	 *
	 * @return  boolean  True on success
	 *
	 * @since   3.2
	 */
	public function setOtpConfig($userId, $otpConfig)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		$updates = (object) array(
			'id'     => $userId,
			'otpKey' => '',
			'otep'   => ''
		);

		// Create an encryptor class
		$key = $this->getOtpConfigEncryptionKey();
		$aes = new FOFEncryptAes($key, 256);

		// Create the encrypted option strings
		if (!empty($otpConfig->method) && ($otpConfig->method !=
'none'))
		{
			$decryptedConfig = json_encode($otpConfig->config);
			$decryptedOtep = json_encode($otpConfig->otep);
			$updates->otpKey = $otpConfig->method . ':' .
$decryptedConfig;
			$updates->otep = $aes->encryptString($decryptedOtep);
		}

		$db = $this->getDbo();
		$result = $db->updateObject('#__users', $updates,
'id');

		return $result;
	}

	/**
	 * Gets the symmetric encryption key for the OTP configuration data. It
	 * currently returns the site's secret.
	 *
	 * @return  string  The encryption key
	 *
	 * @since   3.2
	 */
	public function getOtpConfigEncryptionKey()
	{
		return JFactory::getConfig()->get('secret');
	}

	/**
	 * Gets the configuration forms for all two-factor authentication methods
	 * in an array.
	 *
	 * @param   integer  $userId  The user ID to load the forms for (optional)
	 *
	 * @return  array
	 *
	 * @since   3.2
	 */
	public function getTwofactorform($userId = null)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		$otpConfig = $this->getOtpConfig($userId);

		FOFPlatform::getInstance()->importPlugin('twofactorauth');

		return
FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration',
array($otpConfig, $userId));
	}

	/**
	 * Generates a new set of One Time Emergency Passwords (OTEPs) for a given
user.
	 *
	 * @param   integer  $userId  The user ID
	 * @param   integer  $count   How many OTEPs to generate? Default: 10
	 *
	 * @return  array  The generated OTEPs
	 *
	 * @since   3.2
	 */
	public function generateOteps($userId, $count = 10)
	{
		$userId = (!empty($userId)) ? $userId : (int)
$this->getState('user.id');

		// Initialise
		$oteps = array();

		// Get the OTP configuration for the user
		$otpConfig = $this->getOtpConfig($userId);

		// If two factor authentication is not enabled, abort
		if (empty($otpConfig->method) || ($otpConfig->method ==
'none'))
		{
			return $oteps;
		}

		$salt = '0123456789';
		$base = strlen($salt);
		$length = 16;

		for ($i = 0; $i < $count; $i++)
		{
			$makepass = '';
			$random = JCrypt::genRandomBytes($length + 1);
			$shift = ord($random[0]);

			for ($j = 1; $j <= $length; ++$j)
			{
				$makepass .= $salt[($shift + ord($random[$j])) % $base];
				$shift += ord($random[$j]);
			}

			$oteps[] = $makepass;
		}

		$otpConfig->otep = $oteps;

		// Save the now modified OTP configuration
		$this->setOtpConfig($userId, $otpConfig);

		return $oteps;
	}

	/**
	 * Checks if the provided secret key is a valid two factor authentication
	 * secret key. If not, it will check it against the list of one time
	 * emergency passwords (OTEPs). If it's a valid OTEP it will also
remove it
	 * from the user's list of OTEPs.
	 *
	 * This method will return true in the following conditions:
	 * - The two factor authentication is not enabled
	 * - You have provided a valid secret key for
	 * - You have provided a valid OTEP
	 *
	 * You can define the following options in the $options array:
	 * otp_config		The OTP (one time password, a.k.a. two factor auth)
	 *				    configuration object. If not set we'll load it
automatically.
	 * warn_if_not_req	Issue a warning if you are checking a secret key
against
	 *					a user account which doesn't have any two factor
	 *					authentication method enabled.
	 * warn_irq_msg		The string to use for the warn_if_not_req warning
	 *
	 * @param   integer  $userId     The user's numeric ID
	 * @param   string   $secretKey  The secret key you want to check
	 * @param   array    $options    Options; see above
	 *
	 * @return  boolean  True if it's a valid secret key for this user.
	 *
	 * @since   3.2
	 */
	public function isValidSecretKey($userId, $secretKey, $options = array())
	{
		// Load the user's OTP (one time password, a.k.a. two factor auth)
configuration
		if (!array_key_exists('otp_config', $options))
		{
			$otpConfig = $this->getOtpConfig($userId);
			$options['otp_config'] = $otpConfig;
		}
		else
		{
			$otpConfig = $options['otp_config'];
		}

		// Check if the user has enabled two factor authentication
		if (empty($otpConfig->method) || ($otpConfig->method ==
'none'))
		{
			// Load language
			$lang = JFactory::getLanguage();
			$extension = 'com_users';
			$source = JPATH_ADMINISTRATOR . '/components/' . $extension;

			$lang->load($extension, JPATH_ADMINISTRATOR, null, false, true)
				|| $lang->load($extension, $source, null, false, true);

			$warn = true;
			$warnMessage =
JText::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA');

			if (array_key_exists('warn_if_not_req', $options))
			{
				$warn = $options['warn_if_not_req'];
			}

			if (array_key_exists('warn_irq_msg', $options))
			{
				$warnMessage = $options['warn_irq_msg'];
			}

			// Warn the user if they are using a secret code but they have not
			// enabled two factor auth in their account.
			if (!empty($secretKey) && $warn)
			{
				try
				{
					$app = JFactory::getApplication();
					$app->enqueueMessage($warnMessage, 'warning');
				}
				catch (Exception $exc)
				{
					// This happens when we are in CLI mode. In this case
					// no warning is issued
					return true;
				}
			}

			return true;
		}

		$credentials = array(
			'secretkey' => $secretKey,
		);

		// Try to validate the OTP
		FOFPlatform::getInstance()->importPlugin('twofactorauth');

		$otpAuthReplies =
FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate',
array($credentials, $options));

		$check = false;

		/*
		 * This looks like noob code but DO NOT TOUCH IT and do not convert
		 * to in_array(). During testing in_array() inexplicably returned
		 * null when the OTEP begins with a zero! o_O
		 */
		if (!empty($otpAuthReplies))
		{
			foreach ($otpAuthReplies as $authReply)
			{
				$check = $check || $authReply;
			}
		}

		// Fall back to one time emergency passwords
		if (!$check)
		{
			$check = $this->isValidOtep($userId, $secretKey, $otpConfig);
		}

		return $check;
	}

	/**
	 * Checks if the supplied string is a valid one time emergency password
	 * (OTEP) for this user. If it is it will be automatically removed from
the
	 * user's list of OTEPs.
	 *
	 * @param   integer  $userId     The user ID against which you are
checking
	 * @param   string   $otep       The string you want to test for validity
	 * @param   object   $otpConfig  Optional; the two factor authentication
configuration (automatically fetched if not set)
	 *
	 * @return  boolean  True if it's a valid OTEP or if two factor auth
is not
	 *                   enabled in this user's account.
	 *
	 * @since   3.2
	 */
	public function isValidOtep($userId, $otep, $otpConfig = null)
	{
		if (is_null($otpConfig))
		{
			$otpConfig = $this->getOtpConfig($userId);
		}

		// Did the user use an OTEP instead?
		if (empty($otpConfig->otep))
		{
			if (empty($otpConfig->method) || ($otpConfig->method ==
'none'))
			{
				// Two factor authentication is not enabled on this account.
				// Any string is assumed to be a valid OTEP.
				return true;
			}
			else
			{
				/**
				 * Two factor authentication enabled and no OTEPs defined. The
				 * user has used them all up. Therefore anything they enter is
				 * an invalid OTEP.
				 */
				return false;
			}
		}

		// Clean up the OTEP (remove dashes, spaces and other funny stuff
		// our beloved users may have unwittingly stuffed in it)
		$otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT);
		$otep = str_replace('-', '', $otep);

		$check = false;

		// Did we find a valid OTEP?
		if (in_array($otep, $otpConfig->otep))
		{
			// Remove the OTEP from the array
			$otpConfig->otep = array_diff($otpConfig->otep, array($otep));

			$this->setOtpConfig($userId, $otpConfig);

			// Return true; the OTEP was a valid one
			$check = true;
		}

		return $check;
	}
}
models/users.php000064400000032004151165673570007720 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Methods supporting a list of user records.
 *
 * @since  1.6
 */
class UsersModelUsers extends JModelList
{
	/**
	 * A blacklist of filter variables to not merge into the model's
state
	 *
	 * @var    array
	 */
	protected $filterBlacklist = array('groups',
'excluded');

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JController
	 * @since   1.6
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'name', 'a.name',
				'username', 'a.username',
				'email', 'a.email',
				'block', 'a.block',
				'sendEmail', 'a.sendEmail',
				'registerDate', 'a.registerDate',
				'lastvisitDate', 'a.lastvisitDate',
				'activation', 'a.activation',
				'active',
				'group_id',
				'range',
				'lastvisitrange',
				'state',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function populateState($ordering = 'a.name',
$direction = 'asc')
	{
		$app = JFactory::getApplication('administrator');

		// Adjust the context to support modal layouts.
		if ($layout = $app->input->get('layout',
'default', 'cmd'))
		{
			$this->context .= '.' . $layout;
		}

		// Load the filter state.
		$this->setState('filter.search',
$this->getUserStateFromRequest($this->context .
'.filter.search', 'filter_search', '',
'string'));
		$this->setState('filter.active',
$this->getUserStateFromRequest($this->context .
'.filter.active', 'filter_active', '',
'cmd'));
		$this->setState('filter.state',
$this->getUserStateFromRequest($this->context .
'.filter.state', 'filter_state', '',
'cmd'));
		$this->setState('filter.group_id',
$this->getUserStateFromRequest($this->context .
'.filter.group_id', 'filter_group_id', null,
'int'));
		$this->setState('filter.range',
$this->getUserStateFromRequest($this->context .
'.filter.range', 'filter_range', '',
'cmd'));
		$this->setState(
			'filter.lastvisitrange',
$this->getUserStateFromRequest($this->context .
'.filter.lastvisitrange', 'filter_lastvisitrange',
'', 'cmd')
		);

		$groups =
json_decode(base64_decode($app->input->get('groups',
'', 'BASE64')));

		if (isset($groups))
		{
			$groups = ArrayHelper::toInteger($groups);
		}

		$this->setState('filter.groups', $groups);

		$excluded =
json_decode(base64_decode($app->input->get('excluded',
'', 'BASE64')));

		if (isset($excluded))
		{
			$excluded = ArrayHelper::toInteger($excluded);
		}

		$this->setState('filter.excluded', $excluded);

		// Load the parameters.
		$params = JComponentHelper::getParams('com_users');
		$this->setState('params', $params);

		// List state information.
		parent::populateState($ordering, $direction);
	}

	/**
	 * Method to get a store id based on model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  A prefix for the store id.
	 *
	 * @return  string  A store id.
	 *
	 * @since   1.6
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' . $this->getState('filter.active');
		$id .= ':' . $this->getState('filter.state');
		$id .= ':' . $this->getState('filter.group_id');
		$id .= ':' . $this->getState('filter.range');

		return parent::getStoreId($id);
	}

	/**
	 * Gets the list of users and adds expensive joins to the result set.
	 *
	 * @return  mixed  An array of data items on success, false on failure.
	 *
	 * @since   1.6
	 */
	public function getItems()
	{
		// Get a storage key.
		$store = $this->getStoreId();

		// Try to load the data from internal storage.
		if (empty($this->cache[$store]))
		{
			$groups  = $this->getState('filter.groups');
			$groupId = $this->getState('filter.group_id');

			if (isset($groups) && (empty($groups) || $groupId &&
!in_array($groupId, $groups)))
			{
				$items = array();
			}
			else
			{
				$items = parent::getItems();
			}

			// Bail out on an error or empty list.
			if (empty($items))
			{
				$this->cache[$store] = $items;

				return $items;
			}

			// Joining the groups with the main query is a performance hog.
			// Find the information only on the result set.

			// First pass: get list of the user id's and reset the counts.
			$userIds = array();

			foreach ($items as $item)
			{
				$userIds[] = (int) $item->id;
				$item->group_count = 0;
				$item->group_names = '';
				$item->note_count = 0;
			}

			// Get the counts from the database only for the users in the list.
			$db    = $this->getDbo();
			$query = $db->getQuery(true);

			// Join over the group mapping table.
			$query->select('map.user_id, COUNT(map.group_id) AS
group_count')
				->from('#__user_usergroup_map AS map')
				->where('map.user_id IN (' . implode(',',
$userIds) . ')')
				->group('map.user_id')
				// Join over the user groups table.
				->join('LEFT', '#__usergroups AS g2 ON g2.id =
map.group_id');

			$db->setQuery($query);

			// Load the counts into an array indexed on the user id field.
			try
			{
				$userGroups = $db->loadObjectList('user_id');
			}
			catch (RuntimeException $e)
			{
				$this->setError($e->getMessage());

				return false;
			}

			$query->clear()
				->select('n.user_id, COUNT(n.id) As note_count')
				->from('#__user_notes AS n')
				->where('n.user_id IN (' . implode(',',
$userIds) . ')')
				->where('n.state >= 0')
				->group('n.user_id');

			$db->setQuery($query);

			// Load the counts into an array indexed on the aro.value field (the
user id).
			try
			{
				$userNotes = $db->loadObjectList('user_id');
			}
			catch (RuntimeException $e)
			{
				$this->setError($e->getMessage());

				return false;
			}

			// Second pass: collect the group counts into the master items array.
			foreach ($items as &$item)
			{
				if (isset($userGroups[$item->id]))
				{
					$item->group_count = $userGroups[$item->id]->group_count;

					// Group_concat in other databases is not supported
					$item->group_names =
$this->_getUserDisplayedGroups($item->id);
				}

				if (isset($userNotes[$item->id]))
				{
					$item->note_count = $userNotes[$item->id]->note_count;
				}
			}

			// Add the items to the internal cache.
			$this->cache[$store] = $items;
		}

		return $this->cache[$store];
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   1.6
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db    = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'a.*'
			)
		);

		$query->from($db->quoteName('#__users') . ' AS
a');

		// If the model is set to check item state, add to the query.
		$state = $this->getState('filter.state');

		if (is_numeric($state))
		{
			$query->where('a.block = ' . (int) $state);
		}

		// If the model is set to check the activated state, add to the query.
		$active = $this->getState('filter.active');

		if (is_numeric($active))
		{
			if ($active == '0')
			{
				$query->where('a.activation IN (' .
$db->quote('') . ', ' . $db->quote('0')
. ')');
			}
			elseif ($active == '1')
			{
				$query->where($query->length('a.activation') . '
> 1');
			}
		}

		// Filter the items over the group id if set.
		$groupId = $this->getState('filter.group_id');
		$groups  = $this->getState('filter.groups');

		if ($groupId || isset($groups))
		{
			$query->join('LEFT', '#__user_usergroup_map AS map2 ON
map2.user_id = a.id')
				->group(
					$db->quoteName(
						array(
							'a.id',
							'a.name',
							'a.username',
							'a.password',
							'a.block',
							'a.sendEmail',
							'a.registerDate',
							'a.lastvisitDate',
							'a.activation',
							'a.params',
							'a.email'
						)
					)
				);

			if ($groupId)
			{
				$query->where('map2.group_id = ' . (int) $groupId);
			}

			if (isset($groups))
			{
				$query->where('map2.group_id IN (' .
implode(',', $groups) . ')');
			}
		}

		// Filter the items over the search string if set.
		$search = $this->getState('filter.search');

		if (!empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			elseif (stripos($search, 'username:') === 0)
			{
				$search = $db->quote('%' . $db->escape(substr($search,
9), true) . '%');
				$query->where('a.username LIKE ' . $search);
			}
			else
			{
				// Escape the search token.
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));

				// Compile the different search clauses.
				$searches   = array();
				$searches[] = 'a.name LIKE ' . $search;
				$searches[] = 'a.username LIKE ' . $search;
				$searches[] = 'a.email LIKE ' . $search;

				// Add the clauses to the query.
				$query->where('(' . implode(' OR ', $searches) .
')');
			}
		}

		// Add filter for registration ranges select list
		$range = $this->getState('filter.range');

		// Apply the range filter.
		if ($range)
		{
			$dates = $this->buildDateRange($range);

			if ($dates['dNow'] === false)
			{
				$query->where(
					$db->qn('a.registerDate') . ' < ' .
$db->quote($dates['dStart']->format('Y-m-d
H:i:s'))
				);
			}
			else
			{
				$query->where(
					$db->qn('a.registerDate') . ' >= ' .
$db->quote($dates['dStart']->format('Y-m-d
H:i:s')) .
					' AND ' . $db->qn('a.registerDate') . '
<= ' .
$db->quote($dates['dNow']->format('Y-m-d H:i:s'))
				);
			}
		}

		// Add filter for registration ranges select list
		$lastvisitrange = $this->getState('filter.lastvisitrange');

		// Apply the range filter.
		if ($lastvisitrange)
		{
			$dates = $this->buildDateRange($lastvisitrange);

			if (is_string($dates['dStart']))
			{
				$query->where(
					$db->qn('a.lastvisitDate') . ' = ' .
$db->quote($dates['dStart'])
				);
			}
			elseif ($dates['dNow'] === false)
			{
				$query->where(
					$db->qn('a.lastvisitDate') . ' < ' .
$db->quote($dates['dStart']->format('Y-m-d
H:i:s'))
				);
			}
			else
			{
				$query->where(
					$db->qn('a.lastvisitDate') . ' >= ' .
$db->quote($dates['dStart']->format('Y-m-d
H:i:s')) .
					' AND ' . $db->qn('a.lastvisitDate') . '
<= ' .
$db->quote($dates['dNow']->format('Y-m-d H:i:s'))
				);
			}
		}

		// Filter by excluded users
		$excluded = $this->getState('filter.excluded');

		if (!empty($excluded))
		{
			$query->where('id NOT IN (' . implode(',',
$excluded) . ')');
		}

		// Add the list ordering clause.
		$query->order($db->qn($db->escape($this->getState('list.ordering',
'a.name'))) . ' ' .
$db->escape($this->getState('list.direction',
'ASC')));

		return $query;
	}

	/**
	 * Construct the date range to filter on.
	 *
	 * @param   string  $range  The textual range to construct the filter for.
	 *
	 * @return  string  The date range to filter on.
	 *
	 * @since   3.6.0
	 */
	private function buildDateRange($range)
	{
		// Get UTC for now.
		$dNow   = new JDate;
		$dStart = clone $dNow;

		switch ($range)
		{
			case 'past_week':
				$dStart->modify('-7 day');
				break;

			case 'past_1month':
				$dStart->modify('-1 month');
				break;

			case 'past_3month':
				$dStart->modify('-3 month');
				break;

			case 'past_6month':
				$dStart->modify('-6 month');
				break;

			case 'post_year':
				$dNow = false;
			case 'past_year':
				$dStart->modify('-1 year');
				break;

			case 'today':
				// Ranges that need to align with local 'days' need special
treatment.
				$app    = JFactory::getApplication();
				$offset = $app->get('offset');

				// Reset the start time to be the beginning of today, local time.
				$dStart = new JDate('now', $offset);
				$dStart->setTime(0, 0, 0);

				// Now change the timezone back to UTC.
				$tz = new DateTimeZone('GMT');
				$dStart->setTimezone($tz);
				break;
			case 'never':
				$dNow = false;
				$dStart = $this->_db->getNullDate();
				break;
		}

		return array('dNow' => $dNow, 'dStart' =>
$dStart);
	}

	/**
	 * SQL server change
	 *
	 * @param   integer  $userId  User identifier
	 *
	 * @return  string   Groups titles imploded :$
	 */
	protected function _getUserDisplayedGroups($userId)
	{
		$db    = $this->getDbo();
		$query = $db->getQuery(true)
			->select($db->qn('title'))
			->from($db->qn('#__usergroups', 'ug'))
			->join('LEFT',
$db->qn('#__user_usergroup_map', 'map') . ' ON
(ug.id = map.group_id)')
			->where($db->qn('map.user_id') . ' = ' . (int)
$userId);

		try
		{
			$result = $db->setQuery($query)->loadColumn();
		}
		catch (RunTimeException $e)
		{
			$result = array();
		}

		return implode("\n", $result);
	}
}
tables/note.php000064400000007423151165673570007522 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * User notes table class
 *
 * @since  2.5
 */
class UsersTableNote extends JTable
{
	/**
	 * Constructor
	 *
	 * @param   JDatabaseDriver  &$db  Database object
	 *
	 * @since  2.5
	 */
	public function __construct(&$db)
	{
		parent::__construct('#__user_notes', 'id', $db);

		$this->setColumnAlias('published', 'state');

		JTableObserverContenthistory::createObserver($this,
array('typeAlias' => 'com_users.note'));
	}

	/**
	 * Overloaded store method for the notes table.
	 *
	 * @param   boolean  $updateNulls  Toggle whether null values should be
updated.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   2.5
	 */
	public function store($updateNulls = false)
	{
		$date = JFactory::getDate()->toSql();
		$userId = JFactory::getUser()->get('id');

		$this->modified_time = $date;
		$this->modified_user_id = $userId;

		if (!((int) $this->review_time))
		{
			// Null date.
			$this->review_time = $this->_db->getNullDate();
		}

		if (empty($this->id))
		{
			// New record.
			$this->created_time = $date;
			$this->created_user_id = $userId;
		}

		// Attempt to store the data.
		return parent::store($updateNulls);
	}

	/**
	 * Method to set the publishing state for a row or list of rows in the
database
	 * table.  The method respects checked out rows by other users and will
attempt
	 * to check-in rows that it can after adjustments are made.
	 *
	 * @param   mixed    $pks     An optional array of primary key values to
update.  If not set the instance property value is used.
	 * @param   integer  $state   The publishing state. eg. [0 = unpublished,
1 = published]
	 * @param   integer  $userId  The user id of the user performing the
operation.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 */
	public function publish($pks = null, $state = 1, $userId = 0)
	{
		$k = $this->_tbl_key;

		// Sanitize input.
		$pks = ArrayHelper::toInteger($pks);
		$userId = (int) $userId;
		$state  = (int) $state;

		// If there are no primary keys set check to see if the instance key is
set.
		if (empty($pks))
		{
			if ($this->$k)
			{
				$pks = array($this->$k);
			}
			// Nothing to set publishing state on, return false.
			else
			{
				$this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED'));

				return false;
			}
		}

		$query = $this->_db->getQuery(true)
			->update($this->_db->quoteName($this->_tbl))
			->set($this->_db->quoteName('state') . ' =
' . (int) $state);

		// Build the WHERE clause for the primary keys.
		$query->where($k . '=' . implode(' OR ' . $k .
'=', $pks));

		// Determine if there is checkin support for the table.
		if (!property_exists($this, 'checked_out') ||
!property_exists($this, 'checked_out_time'))
		{
			$checkin = false;
		}
		else
		{
			$query->where('(checked_out = 0 OR checked_out = ' . (int)
$userId . ')');
			$checkin = true;
		}

		// Update the publishing state for rows with the given primary keys.
		$this->_db->setQuery($query);

		try
		{
			$this->_db->execute();
		}
		catch (RuntimeException $e)
		{
			$this->setError($this->_db->getMessage());

			return false;
		}

		// If checkin is supported and all rows were adjusted, check them in.
		if ($checkin && (count($pks) ==
$this->_db->getAffectedRows()))
		{
			// Checkin the rows.
			foreach ($pks as $pk)
			{
				$this->checkin($pk);
			}
		}

		// If the JTable instance value is in the list of primary keys that were
set, set the instance.
		if (in_array($this->$k, $pks))
		{
			$this->state = $state;
		}

		$this->setError('');

		return true;
	}
}
users.xml000064400000002525151165673570006453 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<extension type="component" version="3.1"
method="upgrade">
	<name>com_users</name>
	<author>Joomla! Project</author>
	<creationDate>April 2006</creationDate>
	<copyright>(C) 2005 - 2020 Open Source Matters. All rights
reserved.</copyright>
	<license>GNU General Public License version 2 or later; see
LICENSE.txt</license>
	<authorEmail>admin@joomla.org</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>3.0.0</version>
	<description>COM_USERS_XML_DESCRIPTION</description>

	<files folder="site">
		<filename>controller.php</filename>
		<filename>router.php</filename>
		<filename>users.php</filename>
		<folder>controllers</folder>
		<folder>helpers</folder>
		<folder>models</folder>
		<folder>views</folder>
	</files>
	<languages folder="site">
		<language
tag="en-GB">language/en-GB.com_users.ini</language>
	</languages>
	<administration>
		<files folder="admin">
			<filename>config.xml</filename>
			<filename>controller.php</filename>
			<filename>users.php</filename>
			<folder>controllers</folder>
			<folder>helpers</folder>
			<folder>models</folder>
			<folder>views</folder>
		</files>
		<languages folder="admin">
			<language
tag="en-GB">language/en-GB.com_users.ini</language>
			<language
tag="en-GB">language/en-GB.com_users.sys.ini</language>
		</languages>
	</administration>
</extension>
views/debuggroup/tmpl/default.php000064400000007744151165673570013211
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('formbehavior.chosen', 'select');

$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirn  =
$this->escape($this->state->get('list.direction'));
$colSpan   = 4 + count($this->actions);
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=debuggroup&group_id='
. (int) $this->state->get('group_id')); ?>"
method="post" name="adminForm"
id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<div class="clearfix"> </div>
		<table class="table table-striped">
			<thead>
				<tr>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ASSET_TITLE', 'a.title', $listDirn,
$listOrder); ?>
					</th>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ASSET_NAME', 'a.name', $listDirn,
$listOrder); ?>
					</th>
					<?php foreach ($this->actions as $key => $action) : ?>
					<th width="5%" class="center">
						<span class="hasTooltip" title="<?php echo
JHtml::_('tooltipText', $key, $action[1]);
?>"><?php echo JText::_($key); ?></span>
					</th>
					<?php endforeach; ?>
					<th width="5%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_LFT', 'a.lft', $listDirn,
$listOrder); ?>
					</th>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
					</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<td colspan="<?php echo $colSpan; ?>">
						<?php echo $this->pagination->getListFooter(); ?>
					</td>
				</tr>
			</tfoot>
			<tbody>
				<?php foreach ($this->items as $i => $item) : ?>
					<tr class="row0">
						<td>
							<?php echo $this->escape($item->title); ?>
						</td>
						<td class="nowrap">
							<?php echo
JLayoutHelper::render('joomla.html.treeprefix',
array('level' => $item->level + 1)) .
$this->escape($item->name); ?>
						</td>
						<?php foreach ($this->actions as $action) : ?>
							<?php
							$name  = $action[0];
							$check = $item->checks[$name];
							if ($check === true) :
								$class  = 'icon-ok';
								$button = 'btn-success';
							elseif ($check === false) :
								$class  = 'icon-remove';
								$button = 'btn-danger';
							elseif ($check === null) :
								$class  = 'icon-ban-circle';
								$button = 'btn-warning';
							else :
								$class  = '';
								$button = '';
							endif;
							?>
						<td class="center">
							<span class="icon-white <?php echo $class;
?>"></span>
						</td>
						<?php endforeach; ?>
						<td class="center">
							<?php echo (int) $item->lft; ?>
							- <?php echo (int) $item->rgt; ?>
						</td>
						<td class="center">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
		<div>
			<?php echo JText::_('COM_USERS_DEBUG_LEGEND'); ?>
			<span class="icon-white
icon-ban-circle"></span><?php echo
JText::_('COM_USERS_DEBUG_IMPLICIT_DENY'); ?>&nbsp;
			<span class="icon-white icon-ok"></span><?php
echo JText::_('COM_USERS_DEBUG_EXPLICIT_ALLOW'); ?>&nbsp;
			<span class="icon-white
icon-remove"></span><?php echo
JText::_('COM_USERS_DEBUG_EXPLICIT_DENY'); ?>
			<br /><br />
		</div>
	</div>
</form>
views/debuggroup/view.html.php000064400000004567151165673570012526
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View class for a list of User Group ACL permissions.
 *
 * @since  1.6
 */
class UsersViewDebuggroup extends JViewLegacy
{
	protected $actions;

	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var   JPagination
	 * @since 1.6
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		// Access check.
		if (!JFactory::getUser()->authorise('core.manage',
'com_users'))
		{
			throw new
JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'),
403);
		}

		$this->actions       = $this->get('DebugActions');
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->group         = $this->get('Group');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		// Vars only used in hathor.
		// @deprecated  4.0 To be removed with Hathor
		$this->levels        = UsersHelperDebug::getLevelsOptions();
		$this->components    = UsersHelperDebug::getComponents();

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();

		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_GROUP_TITLE',
$this->group->id, $this->escape($this->group->title)),
'users groups');
		JToolbarHelper::cancel('group.cancel',
'JTOOLBAR_CLOSE');

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_DEBUG_GROUPS');
	}
}
views/debuguser/tmpl/default.php000064400000007741151165673570013030
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('formbehavior.chosen', 'select');

$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirn  =
$this->escape($this->state->get('list.direction'));
$colSpan   = 4 + count($this->actions);
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=debuguser&user_id='
. (int) $this->state->get('user_id')); ?>"
method="post" name="adminForm"
id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<div class="clearfix"> </div>
		<table class="table table-striped">
			<thead>
				<tr>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ASSET_TITLE', 'a.title', $listDirn,
$listOrder); ?>
					</th>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ASSET_NAME', 'a.name', $listDirn,
$listOrder); ?>
					</th>
					<?php foreach ($this->actions as $key => $action) : ?>
					<th width="5%" class="center">
						<span class="hasTooltip" title="<?php echo
JHtml::_('tooltipText', $key, $action[1]);
?>"><?php echo JText::_($key); ?></span>
					</th>
					<?php endforeach; ?>
					<th width="5%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_LFT', 'a.lft', $listDirn,
$listOrder); ?>
					</th>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
					</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<td colspan="<?php echo $colSpan; ?>">
						<?php echo $this->pagination->getListFooter(); ?>
					</td>
				</tr>
			</tfoot>
			<tbody>
				<?php foreach ($this->items as $i => $item) : ?>
					<tr class="row0">
						<td>
							<?php echo $this->escape($item->title); ?>
						</td>
						<td class="nowrap">
							<?php echo
JLayoutHelper::render('joomla.html.treeprefix',
array('level' => $item->level + 1)) .
$this->escape($item->name); ?>
						</td>
						<?php foreach ($this->actions as $action) : ?>
							<?php
							$name  = $action[0];
							$check = $item->checks[$name];
							if ($check === true) :
								$class  = 'icon-ok';
								$button = 'btn-success';
							elseif ($check === false) :
								$class  = 'icon-remove';
								$button = 'btn-danger';
							elseif ($check === null) :
								$class  = 'icon-ban-circle';
								$button = 'btn-warning';
							else :
								$class  = '';
								$button = '';
							endif;
							?>
						<td class="center">
							<span class="icon-white <?php echo $class;
?>"></span>
						</td>
						<?php endforeach; ?>
						<td class="center">
							<?php echo (int) $item->lft; ?>
							- <?php echo (int) $item->rgt; ?>
						</td>
						<td class="center">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
		<div>
			<?php echo JText::_('COM_USERS_DEBUG_LEGEND'); ?>
			<span class="icon-white
icon-ban-circle"></span><?php echo
JText::_('COM_USERS_DEBUG_IMPLICIT_DENY'); ?>&nbsp;
			<span class="icon-white icon-ok"></span><?php
echo JText::_('COM_USERS_DEBUG_EXPLICIT_ALLOW'); ?>&nbsp;
			<span class="icon-white
icon-remove"></span><?php echo
JText::_('COM_USERS_DEBUG_EXPLICIT_DENY'); ?>
			<br /><br />
		</div>
	</div>
</form>
views/debuguser/view.html.php000064400000004547151165673570012346
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View class for a list of User ACL permissions.
 *
 * @since  1.6
 */
class UsersViewDebuguser extends JViewLegacy
{
	protected $actions;

	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var   JPagination
	 * @since 1.6
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		// Access check.
		if (!JFactory::getUser()->authorise('core.manage',
'com_users'))
		{
			throw new
JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'),
403);
		}

		$this->actions       = $this->get('DebugActions');
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->user          = $this->get('User');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		// Vars only used in hathor.
		// @deprecated  4.0 To be removed with Hathor
		$this->levels        = UsersHelperDebug::getLevelsOptions();
		$this->components    = UsersHelperDebug::getComponents();

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();

		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_USER_TITLE',
$this->user->id, $this->escape($this->user->name)),
'users user');
		JToolbarHelper::cancel('user.cancel',
'JTOOLBAR_CLOSE');

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_DEBUG_USERS');
	}
}
views/group/tmpl/edit.php000064400000003051151165673570011466
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select');

JFactory::getDocument()->addScriptDeclaration("
	Joomla.submitbutton = function(task)
	{
		if (task == 'group.cancel' ||
document.formvalidator.isValid(document.getElementById('group-form')))
		{
			Joomla.submitform(task,
document.getElementById('group-form'));
		}
	};
");
?>

<form action="<?php echo
JRoute::_('index.php?option=com_users&layout=edit&id=' .
(int) $this->item->id); ?>" method="post"
name="adminForm" id="group-form"
class="form-validate form-horizontal">
	<fieldset>
		<?php echo JHtml::_('bootstrap.startTabSet',
'myTab', array('active' => 'details'));
?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'details', JText::_('COM_USERS_USERGROUP_DETAILS'));
?>
			<?php echo $this->form->renderField('title'); ?>
			<?php echo $this->form->renderField('parent_id');
?>
		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php $this->ignore_fieldsets = array('group_details');
?>
		<?php echo JLayoutHelper::render('joomla.edit.params',
$this); ?>
		<?php echo JHtml::_('bootstrap.endTabSet'); ?>
	</fieldset>

	<input type="hidden" name="task" value=""
/>
	<?php echo JHtml::_('form.token'); ?>
</form>
views/group/tmpl/edit.xml000064400000000302151165673570011473
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_GROUP_VIEW_EDIT_TITLE">
		<message>
			<![CDATA[COM_USERS_GROUP_VIEW_EDIT_DESC]]>
		</message>
	</layout>
</metadata>
views/group/view.html.php000064400000004115151165673570011504
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View to edit a user group.
 *
 * @since  1.6
 */
class UsersViewGroup extends JViewLegacy
{
	protected $form;

	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $item;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		$this->state = $this->get('State');
		$this->item  = $this->get('Item');
		$this->form  = $this->get('Form');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();
		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		JFactory::getApplication()->input->set('hidemainmenu',
true);

		$isNew = ($this->item->id == 0);
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::_($isNew ?
'COM_USERS_VIEW_NEW_GROUP_TITLE' :
'COM_USERS_VIEW_EDIT_GROUP_TITLE'), 'users
groups-add');

		if ($canDo->get('core.edit') ||
$canDo->get('core.create'))
		{
			JToolbarHelper::apply('group.apply');
			JToolbarHelper::save('group.save');
		}

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::save2new('group.save2new');
		}

		// If an existing item, can save to a copy.
		if (!$isNew && $canDo->get('core.create'))
		{
			JToolbarHelper::save2copy('group.save2copy');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('group.cancel');
		}
		else
		{
			JToolbarHelper::cancel('group.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::divider();
		JToolbarHelper::help('JHELP_USERS_GROUPS_EDIT');
	}
}
views/groups/tmpl/default.php000064400000012725151165673570012360
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$user        = JFactory::getUser();
$listOrder   =
$this->escape($this->state->get('list.ordering'));
$listDirn    =
$this->escape($this->state->get('list.direction'));
$debugGroups =
$this->state->get('params')->get('debugGroups',
1);

JText::script('COM_USERS_GROUPS_CONFIRM_DELETE');

JFactory::getDocument()->addScriptDeclaration('
		Joomla.submitbutton = function(task) {
			if (task == "groups.delete") {
				var i, cids = document.getElementsByName("cid[]");
				for (i = 0; i < cids.length; i++) {
					if (cids[i].checked &&
cids[i].parentNode.getAttribute("data-usercount") != 0) {
						if
(confirm(Joomla.JText._("COM_USERS_GROUPS_CONFIRM_DELETE"))) {
							Joomla.submitform(task);
						}
						return false;
					}
				}
			}

			Joomla.submitform(task);
			return false;
		};
');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=groups');
?>" method="post" name="adminForm"
id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this, 'options' =>
array('filterButton' => false))); ?>
		<div class="clearfix"> </div>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="groupList">
				<thead>
					<tr>
						<th width="1%" class="nowrap">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_GROUP_TITLE', 'a.title', $listDirn,
$listOrder); ?>
						</th>
						<th width="1%" class="nowrap center">
							<span class="icon-publish hasTooltip"
aria-hidden="true" title="<?php echo
JText::_('COM_USERS_COUNT_ENABLED_USERS'); ?>">
								<span class="element-invisible"><?php echo
JText::_('COM_USERS_COUNT_ENABLED_USERS'); ?></span>
							</span>
						</th>
						<th width="1%" class="nowrap center">
							<span class="icon-unpublish hasTooltip"
aria-hidden="true" title="<?php echo
JText::_('COM_USERS_COUNT_DISABLED_USERS'); ?>">
								<span class="element-invisible"><?php echo
JText::_('COM_USERS_COUNT_DISABLED_USERS'); ?></span>
							</span>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="5">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
				<?php foreach ($this->items as $i => $item) :
					$canCreate = $user->authorise('core.create',
'com_users');
					$canEdit   = $user->authorise('core.edit',
'com_users');

					// If this group is super admin and this user is not super admin,
$canEdit is false
					if (!$user->authorise('core.admin') &&
JAccess::checkGroup($item->id, 'core.admin'))
					{
						$canEdit = false;
					}
					$canChange = $user->authorise('core.edit.state',
'com_users');
				?>
					<tr class="row<?php echo $i % 2; ?>">
						<td class="center" data-usercount="<?php echo
$item->user_count; ?>">
							<?php if ($canEdit) : ?>
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							<?php endif; ?>
						</td>
						<td>
							<?php echo
JLayoutHelper::render('joomla.html.treeprefix',
array('level' => $item->level + 1)); ?>
							<?php if ($canEdit) : ?>
							<a href="<?php echo
JRoute::_('index.php?option=com_users&task=group.edit&id='
. $item->id); ?>">
								<?php echo $this->escape($item->title); ?></a>
							<?php else : ?>
								<?php echo $this->escape($item->title); ?>
							<?php endif; ?>
							<?php if ($debugGroups) : ?>
								<div class="small"><a href="<?php echo
JRoute::_('index.php?option=com_users&view=debuggroup&group_id='
. (int) $item->id); ?>">
								<?php echo JText::_('COM_USERS_DEBUG_GROUP');
?></a></div>
							<?php endif; ?>
						</td>
						<td class="center btns">
							<a class="badge <?php if ($item->count_enabled > 0)
echo 'badge-success'; ?>" href="<?php echo
JRoute::_('index.php?option=com_users&view=users&filter[group_id]='
. (int) $item->id . '&filter[state]=0'); ?>">
								<?php echo $item->count_enabled; ?></a>
						</td>
						<td class="center btns">
							<a class="badge <?php if ($item->count_disabled >
0) echo 'badge-important'; ?>" href="<?php echo
JRoute::_('index.php?option=com_users&view=users&filter[group_id]='
. (int) $item->id . '&filter[state]=1'); ?>">
								<?php echo $item->count_disabled; ?></a>
						</td>
						<td class="hidden-phone">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
		<?php endif; ?>

		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/groups/tmpl/default.xml000064400000000312151165673570012356
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_GROUPS_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_USERS_GROUPS_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/groups/view.html.php000064400000005023151165673570011666
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View class for a list of user groups.
 *
 * @since  1.6
 */
class UsersViewGroups extends JViewLegacy
{
	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var   JPagination
	 * @since 1.6
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		UsersHelper::addSubmenu('groups');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();
		$this->sidebar = JHtmlSidebar::render();
		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::_('COM_USERS_VIEW_GROUPS_TITLE'),
'users groups');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('group.add');
		}

		if ($canDo->get('core.edit'))
		{
			JToolbarHelper::editList('group.edit');
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.delete'))
		{
			JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE',
'groups.delete', 'JTOOLBAR_DELETE');
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_GROUPS');
	}

	/**
	 * Returns an array of fields the table can be sorted by
	 *
	 * @return  array  Array containing the field name to sort by as the key
and display text as value
	 *
	 * @since   3.0
	 */
	protected function getSortFields()
	{
		return array(
			'a.title' =>
JText::_('COM_USERS_HEADING_GROUP_TITLE'),
			'a.id'    => JText::_('JGRID_HEADING_ID'),
		);
	}
}
views/level/tmpl/edit.php000064400000002703151165673570011444
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('behavior.formvalidator');

JFactory::getDocument()->addScriptDeclaration("
	Joomla.submitbutton = function(task)
	{
		if (task == 'level.cancel' ||
document.formvalidator.isValid(document.getElementById('level-form')))
		{
			Joomla.submitform(task,
document.getElementById('level-form'));
		}
	};
");
?>

<form action="<?php echo
JRoute::_('index.php?option=com_users&id=' . (int)
$this->item->id); ?>" method="post"
name="adminForm" id="level-form"
class="form-validate form-horizontal">
	<fieldset>
		<legend><?php echo
JText::_('COM_USERS_LEVEL_DETAILS'); ?></legend>
		<div class="control-group">
			<div class="control-label">
				<?php echo $this->form->getLabel('title'); ?>
			</div>
			<div class="controls">
				<?php echo $this->form->getInput('title'); ?>
			</div>
		</div>
	</fieldset>

	<fieldset>
		<legend><?php echo
JText::_('COM_USERS_USER_GROUPS_HAVING_ACCESS');
?></legend>
		<?php echo JHtml::_('access.usergroups',
'jform[rules]', $this->item->rules, true); ?>
	</fieldset>
	<input type="hidden" name="task" value=""
/>
	<?php echo JHtml::_('form.token'); ?>
</form>
views/level/tmpl/edit.xml000064400000000302151165673570011446
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_LEVEL_VIEW_EDIT_TITLE">
		<message>
			<![CDATA[COM_USERS_LEVEL_VIEW_EDIT_DESC]]>
		</message>
	</layout>
</metadata>
views/level/view.html.php000064400000004131151165673570011455
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View to edit a user view level.
 *
 * @since  1.6
 */
class UsersViewLevel extends JViewLegacy
{
	protected $form;

	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $item;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		$this->form  = $this->get('Form');
		$this->item  = $this->get('Item');
		$this->state = $this->get('State');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();
		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		JFactory::getApplication()->input->set('hidemainmenu',
true);

		$isNew = ($this->item->id == 0);
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::_($isNew ?
'COM_USERS_VIEW_NEW_LEVEL_TITLE' :
'COM_USERS_VIEW_EDIT_LEVEL_TITLE'), 'users
levels-add');

		if ($canDo->get('core.edit') ||
$canDo->get('core.create'))
		{
			JToolbarHelper::apply('level.apply');
			JToolbarHelper::save('level.save');
		}

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::save2new('level.save2new');
		}

		// If an existing item, can save to a copy.
		if (!$isNew && $canDo->get('core.create'))
		{
			JToolbarHelper::save2copy('level.save2copy');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('level.cancel');
		}
		else
		{
			JToolbarHelper::cancel('level.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::divider();
		JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS_EDIT');
	}
}
views/levels/tmpl/default.php000064400000011435151165673570012330
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$user       = JFactory::getUser();
$listOrder  =
$this->escape($this->state->get('list.ordering'));
$listDirn   =
$this->escape($this->state->get('list.direction'));
$saveOrder  = $listOrder == 'a.ordering';

if ($saveOrder)
{
	$saveOrderingUrl =
'index.php?option=com_users&task=levels.saveOrderAjax&tmpl=component';
	JHtml::_('sortablelist.sortable', 'levelList',
'adminForm', strtolower($listDirn), $saveOrderingUrl);
}

?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=levels');
?>" method="post" id="adminForm"
name="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this, 'options' =>
array('filterButton' => false))); ?>
		<div class="clearfix"> </div>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="levelList">
				<thead>
					<tr>
						<th width="1%" class="nowrap center
hidden-phone">
							<?php echo JHtml::_('searchtools.sort', '',
'a.ordering', $listDirn, $listOrder, null, 'asc',
'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
						</th>
						<th width="1%">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th>
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_LEVEL_NAME', 'a.title', $listDirn,
$listOrder); ?>
						</th>
						<th class="nowrap hidden-phone">
							<?php echo
JText::_('COM_USERS_USER_GROUPS_HAVING_ACCESS'); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="5">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
				<?php $count = count($this->items); ?>
				<?php foreach ($this->items as $i => $item) :
					$ordering  = ($listOrder == 'a.ordering');
					$canCreate = $user->authorise('core.create',    
'com_users');
					$canEdit   = $user->authorise('core.edit',      
'com_users');
					$canChange = $user->authorise('core.edit.state',
'com_users');

					// Decode level groups
					$groups = json_decode($item->rules);

					// If this group is super admin and this user is not super admin,
$canEdit is false
					if (!JFactory::getUser()->authorise('core.admin')
&& JAccess::checkGroup($groups[0], 'core.admin'))
					{
						$canEdit   = false;
						$canChange = false;
					}
					?>
					<tr class="row<?php echo $i % 2; ?>">
						<td class="order nowrap center hidden-phone">
							<?php
							$iconClass = '';
							if (!$canChange)
							{
								$iconClass = ' inactive';
							}
							elseif (!$saveOrder)
							{
								$iconClass = ' inactive tip-top hasTooltip"
title="' . JHtml::_('tooltipText',
'JORDERINGDISABLED');
							}
							?>
							<span class="sortable-handler<?php echo $iconClass
?>">
								<span class="icon-menu"
aria-hidden="true"></span>
							</span>
							<?php if ($canChange && $saveOrder) : ?>
								<input type="text" style="display:none"
name="order[]" size="5" value="<?php echo
$item->ordering; ?>" class="width-20 text-area-order"
/>
							<?php endif; ?>
						</td>
						<td class="center">
							<?php if ($canEdit) : ?>
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							<?php endif; ?>
						</td>
						<td>
							<?php if ($canEdit) : ?>
							<a href="<?php echo
JRoute::_('index.php?option=com_users&task=level.edit&id='
. $item->id); ?>">
								<?php echo $this->escape($item->title); ?></a>
							<?php else : ?>
								<?php echo $this->escape($item->title); ?>
							<?php endif; ?>
						</td>
						<td class="hidden-phone">
							<?php echo UsersHelper::getVisibleByGroups($item->rules);
?>
						</td>
						<td class="hidden-phone">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
				<?php endforeach; ?>
				</tbody>
			</table>
		<?php endif; ?>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/levels/tmpl/default.xml000064400000000312151165673640012327
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_LEVELS_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_USERS_LEVELS_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/levels/view.html.php000064400000005124151165673640011641
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View class for a list of view levels.
 *
 * @since  1.6
 */
class UsersViewLevels extends JViewLegacy
{
	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var   JPagination
	 * @since 1.6
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		UsersHelper::addSubmenu('levels');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		$this->addToolbar();
		$this->sidebar = JHtmlSidebar::render();
		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		$canDo = JHelperContent::getActions('com_users');

		JToolbarHelper::title(JText::_('COM_USERS_VIEW_LEVELS_TITLE'),
'users levels');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('level.add');
		}

		if ($canDo->get('core.edit'))
		{
			JToolbarHelper::editList('level.edit');
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.delete'))
		{
			JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE',
'level.delete', 'JTOOLBAR_DELETE');
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS');
	}

	/**
	 * Returns an array of fields the table can be sorted by
	 *
	 * @return  array  Array containing the field name to sort by as the key
and display text as value
	 *
	 * @since   3.0
	 */
	protected function getSortFields()
	{
		return array(
			'a.ordering' =>
JText::_('JGRID_HEADING_ORDERING'),
			'a.title'    =>
JText::_('COM_USERS_HEADING_LEVEL_NAME'),
			'a.id'       => JText::_('JGRID_HEADING_ID'),
		);
	}
}
views/mail/tmpl/default.php000064400000006621151165673640011757
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

$script = "\t" . 'Joomla.submitbutton =
function(pressbutton) {' . "\n";
$script .= "\t\t" . 'var form = document.adminForm;' .
"\n";
$script .= "\t\t" . 'if (pressbutton ==
\'mail.cancel\') {' . "\n";
$script .= "\t\t\t" . 'Joomla.submitform(pressbutton);'
. "\n";
$script .= "\t\t\t" . 'return;' . "\n";
$script .= "\t\t" . '}' . "\n";
$script .= "\t\t" . '// do field validation' .
"\n";
$script .= "\t\t" . 'if (form.jform_subject.value ==
""){' . "\n";
$script .= "\t\t\t" . 'alert("' .
JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_SUBJECT', true) .
'");' . "\n";
$script .= "\t\t" . '} else if
(getSelectedValue(\'adminForm\',\'jform[group]\') <
0){' . "\n";
$script .= "\t\t\t" . 'alert("' .
JText::_('COM_USERS_MAIL_PLEASE_SELECT_A_GROUP', true) .
'");' . "\n";
$script .= "\t\t" . '} else if (form.jform_message.value ==
""){' . "\n";
$script .= "\t\t\t" . 'alert("' .
JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_MESSAGE', true) .
'");' . "\n";
$script .= "\t\t" . '} else {' . "\n";
$script .= "\t\t\t" . 'Joomla.submitform(pressbutton);'
. "\n";
$script .= "\t\t" . '}' . "\n";
$script .= "\t\t" . '}' . "\n";

JHtml::_('behavior.core');
JHtml::_('formbehavior.chosen', 'select');

JFactory::getDocument()->addScriptDeclaration($script);
?>

<form action="<?php echo
JRoute::_('index.php?option=com_users&view=mail');
?>" name="adminForm" method="post"
id="adminForm">
	<div class="row-fluid">
		<div class="span9">
			<fieldset class="adminform">
				<div class="control-group">
					<div class="control-label"><?php echo
$this->form->getLabel('subject'); ?></div>
					<div class="controls"><?php echo
JComponentHelper::getParams('com_users')->get('mailSubjectPrefix');
?>
						<?php echo $this->form->getInput('subject');
?></div>
				</div>
				<div class="control-group">
					<div class="control-label"><?php echo
$this->form->getLabel('message'); ?></div>
					<div class="controls"><?php echo
$this->form->getInput('message'); ?><br>
						<?php echo
JComponentHelper::getParams('com_users')->get('mailBodySuffix');
?></div>
				</div>
			</fieldset>
			<input type="hidden" name="task"
value="" />
			<?php echo JHtml::_('form.token'); ?>
		</div>
		<div class="span3">
			<fieldset class="form-inline">
				<div class="control-group checkbox">
					<div class="controls"><?php echo
$this->form->getInput('recurse'); ?> <?php echo
$this->form->getLabel('recurse'); ?></div>
				</div>
				<div class="control-group checkbox">
					<div class="control-label"><?php echo
$this->form->getInput('mode'); ?> <?php echo
$this->form->getLabel('mode'); ?></div>
				</div>
				<div class="control-group checkbox">
					<div class="control-label"><?php echo
$this->form->getInput('disabled'); ?> <?php echo
$this->form->getLabel('disabled'); ?></div>
				</div>
				<div class="control-group checkbox">
					<div class="control-label"><?php echo
$this->form->getInput('bcc'); ?> <?php echo
$this->form->getLabel('bcc'); ?></div>
				</div>
				<div class="control-group">
					<div class="control-label"><?php echo
$this->form->getLabel('group'); ?></div>
					<div class="controls"><?php echo
$this->form->getInput('group'); ?></div>
				</div>
			</fieldset>
		</div>
	</div>
</form>
views/mail/tmpl/default.xml000064400000000306151165673640011762
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_MAIL_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_USERS_MAIL_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/mail/view.html.php000064400000003005151165673640011265
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users mail view.
 *
 * @since  1.6
 */
class UsersViewMail extends JViewLegacy
{
	/**
	 * @var object form object
	 */
	protected $form;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		// Redirect to admin index if mass mailer disabled in conf
		if (JFactory::getApplication()->get('massmailoff', 0) == 1)
		{
			JFactory::getApplication()->redirect(JRoute::_('index.php',
false));
		}

		// Get data from the model
		$this->form = $this->get('Form');

		$this->addToolbar();
		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		JFactory::getApplication()->input->set('hidemainmenu',
true);

		JToolbarHelper::title(JText::_('COM_USERS_MASS_MAIL'),
'users massmail');
		JToolbarHelper::custom('mail.send', 'envelope.png',
'send_f2.png', 'COM_USERS_TOOLBAR_MAIL_SEND_MAIL',
false);
		JToolbarHelper::cancel('mail.cancel');
		JToolbarHelper::divider();
		JToolbarHelper::preferences('com_users');
		JToolbarHelper::divider();
		JToolbarHelper::help('JHELP_USERS_MASS_MAIL_USERS');
	}
}
views/note/tmpl/edit.php000064400000005137151165673640011304
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select');

JFactory::getDocument()->addScriptDeclaration('
jQuery(document).ready(function() {
	Joomla.submitbutton = function(task)
	{
		if (task == "note.cancel" ||
document.formvalidator.isValid(document.getElementById("note-form")))
		{
			' . $this->form->getField('body')->save() .
'
			Joomla.submitform(task, document.getElementById("note-form"));
		}
	}
});');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=note&id=' .
(int) $this->item->id); ?>" method="post"
name="adminForm" id="note-form"
class="form-validate form-horizontal">
		<fieldset class="adminform">
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('subject'); ?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('subject'); ?>
				</div>
			</div>
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('user_id'); ?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('user_id'); ?>
				</div>
			</div>
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('catid'); ?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('catid'); ?>
				</div>
			</div>
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('state'); ?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('state'); ?>
				</div>
			</div>
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('review_time');
?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('review_time');
?>
				</div>
			</div>
			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('version_note');
?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('version_note');
?>
				</div>
			</div>

			<div class="control-group">
				<div class="control-label">
					<?php echo $this->form->getLabel('body'); ?>
				</div>
				<div class="controls">
					<?php echo $this->form->getInput('body'); ?>
				</div>
			</div>

			<input type="hidden" name="task"
value="" />
			<?php echo JHtml::_('form.token'); ?>
		</fieldset>
</form>
views/note/tmpl/edit.xml000064400000000300151165673640011300
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_NOTE_VIEW_EDIT_TITLE">
		<message>
			<![CDATA[COM_USERS_NOTE_VIEW_EDIT_DESC]]>
		</message>
	</layout>
</metadata>
views/note/view.html.php000064400000005710151165673640011315
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User note edit view
 *
 * @since  2.5
 */
class UsersViewNote extends JViewLegacy
{
	/**
	 * The edit form.
	 *
	 * @var    JForm
	 * @since  2.5
	 */
	protected $form;

	/**
	 * The item data.
	 *
	 * @var    object
	 * @since  2.5
	 */
	protected $item;

	/**
	 * The model state.
	 *
	 * @var    JObject
	 * @since  2.5
	 */
	protected $state;

	/**
	 * Override the display method for the view.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise a JError object.
	 *
	 * @since   2.5
	 */
	public function display($tpl = null)
	{
		// Initialise view variables.
		$this->state = $this->get('State');
		$this->item  = $this->get('Item');
		$this->form  = $this->get('Form');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Get the component HTML helpers
		JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

		parent::display($tpl);
		$this->addToolbar();
	}

	/**
	 * Display the toolbar.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function addToolbar()
	{
		$input = JFactory::getApplication()->input;
		$input->set('hidemainmenu', 1);

		$user       = JFactory::getUser();
		$isNew      = ($this->item->id == 0);
		$checkedOut = !($this->item->checked_out == 0 ||
$this->item->checked_out == $user->get('id'));

		// Since we don't track these assets at the item level, use the
category id.
		$canDo = JHelperContent::getActions('com_users',
'category', $this->item->catid);

		JToolbarHelper::title(JText::_('COM_USERS_NOTES'), 'users
user');

		// If not checked out, can save the item.
		if (!$checkedOut && ($canDo->get('core.edit') ||
count($user->getAuthorisedCategories('com_users',
'core.create'))))
		{
			JToolbarHelper::apply('note.apply');
			JToolbarHelper::save('note.save');
		}

		if (!$checkedOut &&
count($user->getAuthorisedCategories('com_users',
'core.create')))
		{
			JToolbarHelper::save2new('note.save2new');
		}

		// If an existing item, can save to a copy.
		if (!$isNew &&
(count($user->getAuthorisedCategories('com_users',
'core.create')) > 0))
		{
			JToolbarHelper::save2copy('note.save2copy');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('note.cancel');
		}
		else
		{
			if (JComponentHelper::isEnabled('com_contenthistory')
&& $this->state->params->get('save_history', 0)
&& $canDo->get('core.edit'))
			{
				JToolbarHelper::versions('com_users.note',
$this->item->id);
			}

			JToolbarHelper::cancel('note.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::divider();
		JToolbarHelper::help('JHELP_USERS_USER_NOTES_EDIT');
	}
}
views/notes/tmpl/default.php000064400000011575151165673640012171
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$user       = JFactory::getUser();
$listOrder  =
$this->escape($this->state->get('list.ordering'));
$listDirn   =
$this->escape($this->state->get('list.direction'));
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=notes');
?>" method="post" name="adminForm"
id="adminForm">
<?php if (!empty( $this->sidebar)) : ?>
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
<?php else : ?>
	<div id="j-main-container">
<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>

		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
		<table class="table table-striped">
			<thead>
				<tr>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('grid.checkall'); ?>
					</th>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
					</th>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_SUBJECT', 'a.subject', $listDirn,
$listOrder); ?>
					</th>
					<th width="20%" class="nowrap hidden-phone">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_USER', 'u.name', $listDirn,
$listOrder); ?>
					</th>
					<th width="10%" class="nowrap hidden-phone
hidden-tablet">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_REVIEW', 'a.review_time', $listDirn,
$listOrder); ?>
					</th>
					<th width="1%" class="nowrap hidden-phone">
						<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
					</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<td colspan="6">
						<?php echo $this->pagination->getListFooter(); ?>
					</td>
				</tr>
			</tfoot>
			<tbody>
			<?php foreach ($this->items as $i => $item) :
				$canEdit    = $user->authorise('core.edit',      
'com_users.category.' . $item->catid);
				$canCheckin = $user->authorise('core.admin',     
'com_checkin') || $item->checked_out ==
$user->get('id') || $item->checked_out == 0;
				$canChange  = $user->authorise('core.edit.state',
'com_users.category.' . $item->catid) && $canCheckin;
				$subject    = $item->subject ?:
JText::_('COM_USERS_EMPTY_SUBJECT');
				?>
				<tr class="row<?php echo $i % 2; ?>">
					<td class="center checklist">
						<?php echo JHtml::_('grid.id', $i, $item->id); ?>
					</td>
					<td class="center">
						<div class="btn-group">
							<?php echo JHtml::_('jgrid.published', $item->state,
$i, 'notes.', $canChange, 'cb', $item->publish_up,
$item->publish_down); ?>
							<?php // Create dropdown items and render the dropdown list.
							if ($canChange)
							{
								JHtml::_('actionsdropdown.' . ((int) $item->state ===
2 ? 'un' : '') . 'archive', 'cb' .
$i, 'notes');
								JHtml::_('actionsdropdown.' . ((int) $item->state ===
-2 ? 'un' : '') . 'trash', 'cb' .
$i, 'notes');
								echo JHtml::_('actionsdropdown.render',
$this->escape($subject));
							}
							?>
						</div>
					</td>
					<td>
						<?php if ($item->checked_out) : ?>
							<?php echo JHtml::_('jgrid.checkedout', $i,
$item->editor, $item->checked_out_time, 'notes.',
$canCheckin); ?>
						<?php endif; ?>
						<?php $subject = $item->subject ?:
JText::_('COM_USERS_EMPTY_SUBJECT'); ?>
						<?php if ($canEdit) : ?>
							<a href="<?php echo
JRoute::_('index.php?option=com_users&task=note.edit&id='
. $item->id); ?>"><?php echo $this->escape($subject);
?></a>
						<?php else : ?>
							<?php echo $this->escape($subject); ?>
						<?php endif; ?>
						<div class="small">
							<?php echo JText::_('JCATEGORY') . ': ' .
$this->escape($item->category_title); ?>
						</div>
					</td>
					<td class="hidden-phone">
						<?php echo $this->escape($item->user_name); ?>
					</td>
					<td class="hidden-phone hidden-tablet">
						<?php if ($item->review_time !==
JFactory::getDbo()->getNullDate()) : ?>
							<?php echo JHtml::_('date', $item->review_time,
JText::_('DATE_FORMAT_LC4')); ?>
						<?php else : ?>
							<?php echo JText::_('COM_USERS_EMPTY_REVIEW'); ?>
						<?php endif; ?>
					</td>
					<td class="hidden-phone">
						<?php echo (int) $item->id; ?>
					</td>
				</tr>
			<?php endforeach; ?>
			</tbody>
		</table>
		<?php endif; ?>

		<div>
			<input type="hidden" name="task"
value="" />
			<input type="hidden" name="boxchecked"
value="0" />
			<?php echo JHtml::_('form.token'); ?>
		</div>
	</div>
</form>
views/notes/tmpl/default.xml000064400000000310151165673640012163
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_NOTES_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_USERS_NOTES_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/notes/tmpl/modal.php000064400000003224151165673640011631
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
?>
<div class="unotes">
	<h1><?php echo
JText::sprintf('COM_USERS_NOTES_FOR_USER',
$this->user->name, $this->user->id); ?></h1>
<?php if (empty($this->items)) : ?>
	<?php echo JText::_('COM_USERS_NO_NOTES'); ?>
<?php else : ?>
	<ul class="alternating">
	<?php foreach ($this->items as $item) : ?>
		<li>
			<div class="fltlft utitle">
				<?php if ($item->subject) : ?>
					<h4><?php echo
JText::sprintf('COM_USERS_NOTE_N_SUBJECT', (int) $item->id,
$this->escape($item->subject)); ?></h4>
				<?php else : ?>
					<h4><?php echo
JText::sprintf('COM_USERS_NOTE_N_SUBJECT', (int) $item->id,
JText::_('COM_USERS_EMPTY_SUBJECT')); ?></h4>
				<?php endif; ?>
			</div>

			<div class="fltlft utitle">
				<?php echo JHtml::_('date', $item->created_time,
JText::_('DATE_FORMAT_LC2')); ?>
			</div>

			<?php $category_image = $item->cparams->get('image');
?>

			<?php if ($item->catid && isset($category_image)) : ?>
			<div class="fltlft utitle">
				<?php echo JHtml::_('users.image', $category_image); ?>
			</div>

			<div class="fltlft utitle">
				<em><?php echo $this->escape($item->category_title);
?></em>
			</div>
			<?php endif; ?>

			<div class="clr"></div>
			<div class="ubody">
				<?php echo (isset($item->body) ?
JHtml::_('content.prepare', $item->body) : '');
?>
			</div>
		</li>
	<?php endforeach; ?>
	</ul>
<?php endif; ?>
</div>
views/notes/view.html.php000064400000007553151165673640011507
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * User notes list view
 *
 * @since  2.5
 */
class UsersViewNotes extends JViewLegacy
{
	/**
	 * A list of user note objects.
	 *
	 * @var    array
	 * @since  2.5
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var    JPagination
	 * @since  2.5
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var    JObject
	 * @since  2.5
	 */
	protected $state;

	/**
	 * The model state.
	 *
	 * @var    JUser
	 * @since  2.5
	 */
	protected $user;

	/**
	 * Override the display method for the view.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise a JError object.
	 *
	 * @since   2.5
	 */
	public function display($tpl = null)
	{
		// Initialise view variables.
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->user          = $this->get('User');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		UsersHelper::addSubmenu('notes');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Get the component HTML helpers
		JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

		// Turn parameters into registry objects
		foreach ($this->items as $item)
		{
			$item->cparams = new Registry($item->category_params);
		}

		$this->addToolbar();
		$this->sidebar = JHtmlSidebar::render();
		parent::display($tpl);
	}

	/**
	 * Display the toolbar.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function addToolbar()
	{
		$canDo = JHelperContent::getActions('com_users',
'category',
$this->state->get('filter.category_id'));

		JToolbarHelper::title(JText::_('COM_USERS_VIEW_NOTES_TITLE'),
'users user');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('note.add');
		}

		if ($canDo->get('core.edit'))
		{
			JToolbarHelper::editList('note.edit');
		}

		if ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::divider();
			JToolbarHelper::publish('notes.publish',
'JTOOLBAR_PUBLISH', true);
			JToolbarHelper::unpublish('notes.unpublish',
'JTOOLBAR_UNPUBLISH', true);

			JToolbarHelper::divider();
			JToolbarHelper::archiveList('notes.archive');
			JToolbarHelper::checkin('notes.checkin');
		}

		if ($this->state->get('filter.published') == -2
&& $canDo->get('core.delete'))
		{
			JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE',
'notes.delete', 'JTOOLBAR_EMPTY_TRASH');
			JToolbarHelper::divider();
		}
		elseif ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::trash('notes.trash');
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_USER_NOTES');

		JHtmlSidebar::setAction('index.php?option=com_users&view=notes');
	}

	/**
	 * Returns an array of fields the table can be sorted by
	 *
	 * @return  array  Array containing the field name to sort by as the key
and display text as value
	 *
	 * @since   3.0
	 */
	protected function getSortFields()
	{
		return array(
			'u.name'        =>
JText::_('COM_USERS_USER_HEADING'),
			'a.subject'     =>
JText::_('COM_USERS_SUBJECT_HEADING'),
			'c.title'       =>
JText::_('COM_USERS_CATEGORY_HEADING'),
			'a.state'       => JText::_('JSTATUS'),
			'a.review_time' =>
JText::_('COM_USERS_REVIEW_HEADING'),
			'a.id'          => JText::_('JGRID_HEADING_ID')
		);
	}
}
views/user/tmpl/edit.php000064400000011173151165673640011312
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', 'select');

JFactory::getDocument()->addScriptDeclaration("
	Joomla.submitbutton = function(task)
	{
		if (task == 'user.cancel' ||
document.formvalidator.isValid(document.getElementById('user-form')))
		{
			Joomla.submitform(task, document.getElementById('user-form'));
		}
	};

	Joomla.twoFactorMethodChange = function(e)
	{
		var selectedPane = 'com_users_twofactor_' +
jQuery('#jform_twofactor_method').val();

		jQuery.each(jQuery('#com_users_twofactor_forms_container>div'),
function(i, el) {
			if (el.id != selectedPane)
			{
				jQuery('#' + el.id).hide(0);
			}
			else
			{
				jQuery('#' + el.id).show(0);
			}
		});
	};
");

// Get the form fieldsets.
$fieldsets = $this->form->getFieldsets();
?>

<form action="<?php echo
JRoute::_('index.php?option=com_users&layout=edit&id=' .
(int) $this->item->id); ?>" method="post"
name="adminForm" id="user-form"
class="form-validate form-horizontal"
enctype="multipart/form-data">

	<?php echo JLayoutHelper::render('joomla.edit.item_title',
$this); ?>

	<fieldset>
		<?php echo JHtml::_('bootstrap.startTabSet',
'myTab', array('active' => 'details'));
?>

			<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'details', JText::_('COM_USERS_USER_ACCOUNT_DETAILS'));
?>
				<?php foreach
($this->form->getFieldset('user_details') as $field) :
?>
					<div class="control-group">
						<div class="control-label">
							<?php echo $field->label; ?>
						</div>
						<div class="controls">
							<?php if ($field->fieldname == 'password') : ?>
								<?php // Disables autocomplete ?> <input
type="password" style="display:none">
							<?php endif; ?>
							<?php echo $field->input; ?>
						</div>
					</div>
				<?php endforeach; ?>
			<?php echo JHtml::_('bootstrap.endTab'); ?>

			<?php if ($this->grouplist) : ?>
				<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'groups', JText::_('COM_USERS_ASSIGNED_GROUPS')); ?>
					<?php echo $this->loadTemplate('groups'); ?>
				<?php echo JHtml::_('bootstrap.endTab'); ?>
			<?php endif; ?>

			<?php
			$this->ignore_fieldsets = array('user_details');
			echo JLayoutHelper::render('joomla.edit.params', $this);
			?>

		<?php if (!empty($this->tfaform) && $this->item->id)
: ?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'twofactorauth',
JText::_('COM_USERS_USER_TWO_FACTOR_AUTH')); ?>
		<div class="control-group">
			<div class="control-label">
				<label id="jform_twofactor_method-lbl"
for="jform_twofactor_method" class="hasTooltip"
						title="<?php echo '<strong>' .
JText::_('COM_USERS_USER_FIELD_TWOFACTOR_LABEL') .
'</strong><br />' .
JText::_('COM_USERS_USER_FIELD_TWOFACTOR_DESC'); ?>">
					<?php echo
JText::_('COM_USERS_USER_FIELD_TWOFACTOR_LABEL'); ?>
				</label>
			</div>
			<div class="controls">
				<?php echo JHtml::_('select.genericlist',
Usershelper::getTwoFactorMethods(), 'jform[twofactor][method]',
array('onchange' =>
'Joomla.twoFactorMethodChange()'), 'value',
'text', $this->otpConfig->method,
'jform_twofactor_method', false); ?>
			</div>
		</div>
		<div id="com_users_twofactor_forms_container">
			<?php foreach ($this->tfaform as $form) : ?>
			<?php $style = $form['method'] ==
$this->otpConfig->method ? 'display: block' :
'display: none'; ?>
			<div id="com_users_twofactor_<?php echo
$form['method'] ?>" style="<?php echo $style;
?>">
				<?php echo $form['form'] ?>
			</div>
			<?php endforeach; ?>
		</div>

		<fieldset>
			<legend>
				<?php echo JText::_('COM_USERS_USER_OTEPS'); ?>
			</legend>
			<div class="alert alert-info">
				<?php echo JText::_('COM_USERS_USER_OTEPS_DESC'); ?>
			</div>
			<?php if (empty($this->otpConfig->otep)) : ?>
			<div class="alert alert-warning">
				<?php echo JText::_('COM_USERS_USER_OTEPS_WAIT_DESC');
?>
			</div>
			<?php else : ?>
			<?php foreach ($this->otpConfig->otep as $otep) : ?>
			<span class="span3">
				<?php echo substr($otep, 0, 4); ?>-<?php echo substr($otep, 4,
4); ?>-<?php echo substr($otep, 8, 4); ?>-<?php echo
substr($otep, 12, 4); ?>
			</span>
			<?php endforeach; ?>
			<div class="clearfix"></div>
			<?php endif; ?>
		</fieldset>

		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php endif; ?>

		<?php echo JHtml::_('bootstrap.endTabSet'); ?>
	</fieldset>

	<input type="hidden" name="task" value=""
/>
	<?php echo JHtml::_('form.token'); ?>
</form>
views/user/tmpl/edit.xml000064400000000300151165673640011311
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_USER_VIEW_EDIT_TITLE">
		<message>
			<![CDATA[COM_USERS_USER_VIEW_EDIT_DESC]]>
		</message>
	</layout>
</metadata>
views/user/tmpl/edit_groups.php000064400000000713151165673640012707
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');
?>
<?php echo JHtml::_('access.usergroups',
'jform[groups]', $this->groups, true); ?>
views/user/view.html.php000064400000005055151165673640011330
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * User view class.
 *
 * @since  1.5
 */
class UsersViewUser extends JViewLegacy
{
	protected $form;

	protected $item;

	protected $grouplist;

	protected $groups;

	protected $state;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 *
	 * @since   1.5
	 */
	public function display($tpl = null)
	{
		$this->form      = $this->get('Form');
		$this->item      = $this->get('Item');
		$this->state     = $this->get('State');
		$this->tfaform   = $this->get('Twofactorform');
		$this->otpConfig = $this->get('otpConfig');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Prevent user from modifying own group(s)
		$user = JFactory::getUser();

		if ((int) $user->id != (int) $this->item->id ||
$user->authorise('core.admin'))
		{
			$this->grouplist = $this->get('Groups');
			$this->groups    = $this->get('AssignedGroups');
		}

		$this->form->setValue('password', null);
		$this->form->setValue('password2', null);

		parent::display($tpl);
		$this->addToolbar();
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		JFactory::getApplication()->input->set('hidemainmenu',
true);

		$user      = JFactory::getUser();
		$canDo     = JHelperContent::getActions('com_users');
		$isNew     = ($this->item->id == 0);
		$isProfile = $this->item->id == $user->id;

		JToolbarHelper::title(
			JText::_(
				$isNew ? 'COM_USERS_VIEW_NEW_USER_TITLE' : ($isProfile ?
'COM_USERS_VIEW_EDIT_PROFILE_TITLE' :
'COM_USERS_VIEW_EDIT_USER_TITLE')
			),
			'user ' . ($isNew ? 'user-add' : ($isProfile ?
'user-profile' : 'user-edit'))
		);

		if ($canDo->get('core.edit') ||
$canDo->get('core.create'))
		{
			JToolbarHelper::apply('user.apply');
			JToolbarHelper::save('user.save');
		}

		if ($canDo->get('core.create') &&
$canDo->get('core.manage'))
		{
			JToolbarHelper::save2new('user.save2new');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('user.cancel');
		}
		else
		{
			JToolbarHelper::cancel('user.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::divider();
		JToolbarHelper::help('JHELP_USERS_USER_MANAGER_EDIT');
	}
}
views/users/tmpl/default.php000064400000016667151165673640012211
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$listOrder  =
$this->escape($this->state->get('list.ordering'));
$listDirn   =
$this->escape($this->state->get('list.direction'));
$loggeduser = JFactory::getUser();
$debugUsers =
$this->state->get('params')->get('debugUsers',
1);
?>
<form action="<?php echo
JRoute::_('index.php?option=com_users&view=users');
?>" method="post" name="adminForm"
id="adminForm">
	<?php if (!empty( $this->sidebar)) : ?>
		<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
		</div>
		<div id="j-main-container" class="span10">
	<?php else : ?>
		<div id="j-main-container">
	<?php endif; ?>
		<?php
		// Search tools bar
		echo JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this));
		?>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="userList">
				<thead>
					<tr>
						<th width="1%" class="nowrap center">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_NAME', 'a.name', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap">
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_USERNAME', 'a.username', $listDirn,
$listOrder); ?>
						</th>
						<th width="5%" class="nowrap center">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ENABLED', 'a.block', $listDirn,
$listOrder); ?>
						</th>
						<th width="5%" class="nowrap center
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ACTIVATED', 'a.activation',
$listDirn, $listOrder); ?>
						</th>
						<th width="10%" class="nowrap">
							<?php echo JText::_('COM_USERS_HEADING_GROUPS'); ?>
						</th>
						<th width="15%" class="nowrap hidden-phone
hidden-tablet">
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_EMAIL', 'a.email', $listDirn, $listOrder);
?>
						</th>
						<th width="10%" class="nowrap hidden-phone
hidden-tablet">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_LAST_VISIT_DATE', 'a.lastvisitDate',
$listDirn, $listOrder); ?>
						</th>
						<th width="10%" class="nowrap hidden-phone
hidden-tablet">
							<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_REGISTRATION_DATE',
'a.registerDate', $listDirn, $listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="10">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
				<?php foreach ($this->items as $i => $item) :
					$canEdit   = $this->canDo->get('core.edit');
					$canChange =
$loggeduser->authorise('core.edit.state',	'com_users');

					// If this group is super admin and this user is not super admin,
$canEdit is false
					if ((!$loggeduser->authorise('core.admin')) &&
JAccess::check($item->id, 'core.admin'))
					{
						$canEdit   = false;
						$canChange = false;
					}
				?>
					<tr class="row<?php echo $i % 2; ?>">
						<td class="center">
							<?php if ($canEdit || $canChange) : ?>
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							<?php endif; ?>
						</td>
						<td>
							<div class="name break-word">
							<?php if ($canEdit) : ?>
								<a href="<?php echo
JRoute::_('index.php?option=com_users&task=user.edit&id='
. (int) $item->id); ?>" title="<?php echo
JText::sprintf('COM_USERS_EDIT_USER',
$this->escape($item->name)); ?>">
									<?php echo $this->escape($item->name); ?></a>
							<?php else : ?>
								<?php echo $this->escape($item->name); ?>
							<?php endif; ?>
							</div>
							<div class="btn-group">
								<?php echo JHtml::_('users.filterNotes',
$item->note_count, $item->id); ?>
								<?php echo JHtml::_('users.notes',
$item->note_count, $item->id); ?>
								<?php echo JHtml::_('users.addNote', $item->id);
?>
							</div>
							<?php echo JHtml::_('users.notesModal',
$item->note_count, $item->id); ?>
							<?php if ($item->requireReset == '1') : ?>
								<span class="label label-warning"><?php echo
JText::_('COM_USERS_PASSWORD_RESET_REQUIRED'); ?></span>
							<?php endif; ?>
							<?php if ($debugUsers) : ?>
								<div class="small"><a href="<?php echo
JRoute::_('index.php?option=com_users&view=debuguser&user_id='
. (int) $item->id); ?>">
								<?php echo JText::_('COM_USERS_DEBUG_USER');
?></a></div>
							<?php endif; ?>
						</td>
						<td class="break-word">
							<?php echo $this->escape($item->username); ?>
						</td>
						<td class="center">
							<?php
							$self = $loggeduser->id == $item->id;

							if ($canChange) :
								echo JHtml::_('jgrid.state',
JHtml::_('users.blockStates', $self), $item->block, $i,
'users.', !$self);
							else :
								echo JHtml::_('jgrid.state',
JHtml::_('users.blockStates', $self), $item->block, $i,
'users.', false);
							endif; ?>
						</td>
						<td class="center hidden-phone">
							<?php
							$activated = empty( $item->activation) ? 0 : 1;
							echo JHtml::_('jgrid.state',
JHtml::_('users.activateStates'), $activated, $i,
'users.', (boolean) $activated);
							?>
						</td>
						<td>
							<?php if (substr_count($item->group_names, "\n")
> 1) : ?>
								<span class="hasTooltip" title="<?php echo
JHtml::_('tooltipText',
JText::_('COM_USERS_HEADING_GROUPS'),
nl2br($item->group_names), 0); ?>"><?php echo
JText::_('COM_USERS_USERS_MULTIPLE_GROUPS'); ?></span>
							<?php else : ?>
								<?php echo nl2br($item->group_names); ?>
							<?php endif; ?>
						</td>
						<td class="hidden-phone break-word hidden-tablet">
							<?php echo
JStringPunycode::emailToUTF8($this->escape($item->email)); ?>
						</td>
						<td class="hidden-phone hidden-tablet">
							<?php if ($item->lastvisitDate !=
$this->db->getNullDate()) : ?>
								<?php echo JHtml::_('date', $item->lastvisitDate,
JText::_('DATE_FORMAT_LC6')); ?>
							<?php else : ?>
								<?php echo JText::_('JNEVER'); ?>
							<?php endif; ?>
						</td>
						<td class="hidden-phone hidden-tablet">
							<?php echo JHtml::_('date', $item->registerDate,
JText::_('DATE_FORMAT_LC6')); ?>
						</td>
						<td class="hidden-phone">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
			<?php // Load the batch processing form if user is allowed ?>
			<?php if ($loggeduser->authorise('core.create',
'com_users')
				&& $loggeduser->authorise('core.edit',
'com_users')
				&& $loggeduser->authorise('core.edit.state',
'com_users')) : ?>
				<?php echo JHtml::_(
					'bootstrap.renderModal',
					'collapseModal',
					array(
						'title'  =>
JText::_('COM_USERS_BATCH_OPTIONS'),
						'footer' =>
$this->loadTemplate('batch_footer'),
					),
					$this->loadTemplate('batch_body')
				); ?>
			<?php endif; ?>
		<?php endif; ?>

		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/users/tmpl/default.xml000064400000000310151165673640012174
0ustar00<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_USERS_USERS_VIEW_DEFAULT_TITLE">
		<message>
			<![CDATA[COM_USERS_USERS_VIEW_DEFAULT_DESC]]>
		</message>
	</layout>
</metadata>
views/users/tmpl/default_batch_body.php000064400000003351151165673650014352
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Create the copy/move options.
$options = array(
	JHtml::_('select.option', 'add',
JText::_('COM_USERS_BATCH_ADD')),
	JHtml::_('select.option', 'del',
JText::_('COM_USERS_BATCH_DELETE')),
	JHtml::_('select.option', 'set',
JText::_('COM_USERS_BATCH_SET'))
);

// Create the reset password options.
$resetOptions = array(
	JHtml::_('select.option', '',
JText::_('COM_USERS_NO_ACTION')),
	JHtml::_('select.option', 'yes',
JText::_('JYES')),
	JHtml::_('select.option', 'no',
JText::_('JNO'))
);
JHtml::_('formbehavior.chosen', 'select');
?>

<div class="container-fluid">
	<div class="row-fluid">
		<div class="controls">
			<label id="batch-choose-action-lbl"
class="control-label" for="batch-group-id">
				<?php echo JText::_('COM_USERS_BATCH_GROUP'); ?>
			</label>
			<div id="batch-choose-action" class="combo
controls">
				<div class="control-group">
					<select name="batch[group_id]"
id="batch-group-id">
						<option value=""><?php echo
JText::_('JSELECT'); ?></option>
						<?php echo JHtml::_('select.options',
JHtml::_('user.groups')); ?>
					</select>
				</div>
			</div>
			<div class="control-group radio">
				<?php echo JHtml::_('select.radiolist', $options,
'batch[group_action]', '', 'value',
'text', 'add'); ?>
			</div>
		</div>
	</div>
	<label><?php echo
JText::_('COM_USERS_REQUIRE_PASSWORD_RESET'); ?></label>
	<div class="control-group radio">
		<?php echo JHtml::_('select.radiolist', $resetOptions,
'batch[reset_id]', '', 'value',
'text', ''); ?>
	</div>
</div>
views/users/tmpl/default_batch_footer.php000064400000001136151165673650014712
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

?>
<button type="button" class="btn"
onclick="document.getElementById('batch-group-id').value=''"
data-dismiss="modal">
	<?php echo JText::_('JCANCEL'); ?>
</button>
<button type="submit" class="btn btn-success"
onclick="Joomla.submitbutton('user.batch');return
false;">
	<?php echo JText::_('JGLOBAL_BATCH_PROCESS'); ?>
</button>
views/users/tmpl/modal.php000064400000012230151165673650011640
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip', '.hasTooltip',
array('placement' => 'bottom'));
JHtml::_('bootstrap.popover', '.hasPopover',
array('placement' => 'bottom'));
JHtml::_('formbehavior.chosen', 'select');
JHtml::_('behavior.multiselect');

// Special case for the search field tooltip.
$searchFilterDesc =
$this->filterForm->getFieldAttribute('search',
'description', null, 'filter');
JHtml::_('bootstrap.tooltip', '#filter_search',
array('title' => JText::_($searchFilterDesc),
'placement' => 'bottom'));

$input           = JFactory::getApplication()->input;
$field           = $input->getCmd('field');
$listOrder       =
$this->escape($this->state->get('list.ordering'));
$listDirn        =
$this->escape($this->state->get('list.direction'));
$enabledStates   = array(0 => 'icon-publish', 1 =>
'icon-unpublish');
$activatedStates = array(0 => 'icon-publish', 1 =>
'icon-unpublish');
$userRequired    = (int) $input->get('required', 0,
'int');

/**
 * Mootools compatibility
 *
 * There is an extra option passed in the URL for the iframe &ismoo=0
for the bootstraped field.
 * By default the value will be 1 or defaults to mootools behaviour using
function jSelectUser()
 *
 * This should be removed when mootools won't be shipped by Joomla.
 */
$isMoo = $input->getInt('ismoo', 1);

if ($isMoo)
{
	$onClick =
"window.parent.jSelectUser(this);window.parent.jQuery('.modal.in').modal('hide');";
}

?>
<div class="container-popup">
	<form action="<?php echo
JRoute::_('index.php?option=com_users&view=users&layout=modal&tmpl=component&groups='
. $input->get('groups', '', 'BASE64') .
'&excluded=' . $input->get('excluded',
'', 'BASE64')); ?>" method="post"
name="adminForm" id="adminForm">
		<?php if (!$userRequired) : ?>
		<div class="pull-left">
			<button type="button" class="btn button-select"
data-user-value="0" data-user-name="<?php echo
$this->escape(JText::_('JLIB_FORM_SELECT_USER')); ?>"
				data-user-field="<?php echo $this->escape($field);
?>" <?php if ($isMoo) : ?>value=""
onclick="window.parent.jSelectUser(this)"<?php endif;
?>><?php echo JText::_('JOPTION_NO_USER');
?></button>&nbsp;
		</div>
		<?php endif; ?>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<?php if (empty($this->items)) : ?>
		<div class="alert alert-no-items">
			<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
		</div>
		<?php else : ?>
		<table class="table table-striped table-condensed">
			<thead>
				<tr>
					<th class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_NAME', 'a.name', $listDirn,
$listOrder); ?>
					</th>
					<th width="25%" class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_USERNAME', 'a.username', $listDirn,
$listOrder); ?>
					</th>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ENABLED', 'a.block', $listDirn,
$listOrder); ?>
					</th>
					<th width="1%" class="nowrap center">
						<?php echo JHtml::_('searchtools.sort',
'COM_USERS_HEADING_ACTIVATED', 'a.activation',
$listDirn, $listOrder); ?>
					</th>
					<th width="25%" class="nowrap">
						<?php echo JText::_('COM_USERS_HEADING_GROUPS'); ?>
					</th>
					<th width="1%" class="nowrap">
						<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
					</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<td colspan="6">
						<?php echo $this->pagination->getListFooter(); ?>
					</td>
				</tr>
			</tfoot>
			<tbody>
				<?php $i = 0; ?>
				<?php foreach ($this->items as $item) : ?>
					<tr class="row<?php echo $i % 2; ?>">
						<td>
							<a class="pointer button-select" href="#"
data-user-value="<?php echo $item->id; ?>"
data-user-name="<?php echo $this->escape($item->name);
?>"
								data-user-field="<?php echo $this->escape($field);
?>" <?php if ($isMoo) : ?>onclick="<?php echo
$onClick; ?>"<?php endif; ?>>
								<?php echo $this->escape($item->name); ?>
							</a>
						</td>
						<td>
							<?php echo $this->escape($item->username); ?>
						</td>
						<td class="center">
							<span class="<?php echo $enabledStates[(int)
$this->escape($item->block)]; ?>"></span>
						</td>
						<td class="center">
							<span class="<?php echo
$activatedStates[(empty($item->activation) ? 0 : 1)];
?>"></span>
						</td>
						<td>
							<?php echo nl2br($item->group_names); ?>
						</td>
						<td>
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
		<?php endif; ?>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="field"
value="<?php echo $this->escape($field); ?>" />
		<input type="hidden" name="boxchecked"
value="0" />
		<input type="hidden" name="required"
value="<?php echo $userRequired; ?>" />
		<input type="hidden" name="ismoo"
value="<?php echo $isMoo; ?>" />
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>
views/users/view.html.php000064400000010645151165673650011515
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * View class for a list of users.
 *
 * @since  1.6
 */
class UsersViewUsers extends JViewLegacy
{
	/**
	 * The item data.
	 *
	 * @var   object
	 * @since 1.6
	 */
	protected $items;

	/**
	 * The pagination object.
	 *
	 * @var   JPagination
	 * @since 1.6
	 */
	protected $pagination;

	/**
	 * The model state.
	 *
	 * @var   JObject
	 * @since 1.6
	 */
	protected $state;

	/**
	 * A JForm instance with filter fields.
	 *
	 * @var    JForm
	 * @since  3.6.3
	 */
	public $filterForm;

	/**
	 * An array with active filters.
	 *
	 * @var    array
	 * @since  3.6.3
	 */
	public $activeFilters;

	/**
	 * An ACL object to verify user rights.
	 *
	 * @var    JObject
	 * @since  3.6.3
	 */
	protected $canDo;

	/**
	 * An instance of JDatabaseDriver.
	 *
	 * @var    JDatabaseDriver
	 * @since  3.6.3
	 */
	protected $db;

	/**
	 * Display the view
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->state         = $this->get('State');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');
		$this->canDo         =
JHelperContent::getActions('com_users');
		$this->db            = JFactory::getDbo();

		UsersHelper::addSubmenu('users');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Include the component HTML helpers.
		JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

		$this->addToolbar();
		$this->sidebar = JHtmlSidebar::render();

		parent::display($tpl);
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolbar()
	{
		$canDo = $this->canDo;
		$user  = JFactory::getUser();

		// Get the toolbar object instance
		$bar = JToolbar::getInstance('toolbar');

		JToolbarHelper::title(JText::_('COM_USERS_VIEW_USERS_TITLE'),
'users user');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('user.add');
		}

		if ($canDo->get('core.edit'))
		{
			JToolbarHelper::editList('user.edit');
		}

		if ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::divider();
			JToolbarHelper::publish('users.activate',
'COM_USERS_TOOLBAR_ACTIVATE', true);
			JToolbarHelper::unpublish('users.block',
'COM_USERS_TOOLBAR_BLOCK', true);
			JToolbarHelper::custom('users.unblock',
'unblock.png', 'unblock_f2.png',
'COM_USERS_TOOLBAR_UNBLOCK', true);
			JToolbarHelper::divider();
		}

		if ($canDo->get('core.delete'))
		{
			JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE',
'users.delete', 'JTOOLBAR_DELETE');
			JToolbarHelper::divider();
		}

		// Add a batch button
		if ($user->authorise('core.create', 'com_users')
			&& $user->authorise('core.edit',
'com_users')
			&& $user->authorise('core.edit.state',
'com_users'))
		{
			$title = JText::_('JTOOLBAR_BATCH');

			// Instantiate a new JLayoutFile instance and render the batch button
			$layout = new JLayoutFile('joomla.toolbar.batch');

			$dhtml = $layout->render(array('title' => $title));
			$bar->appendButton('Custom', $dhtml, 'batch');
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences('com_users');
			JToolbarHelper::divider();
		}

		JToolbarHelper::help('JHELP_USERS_USER_MANAGER');
	}

	/**
	 * Returns an array of fields the table can be sorted by
	 *
	 * @return  array  Array containing the field name to sort by as the key
and display text as value
	 *
	 * @since   3.0
	 */
	protected function getSortFields()
	{
		return array(
			'a.name'          =>
JText::_('COM_USERS_HEADING_NAME'),
			'a.username'      =>
JText::_('JGLOBAL_USERNAME'),
			'a.block'         =>
JText::_('COM_USERS_HEADING_ENABLED'),
			'a.activation'    =>
JText::_('COM_USERS_HEADING_ACTIVATED'),
			'a.email'         => JText::_('JGLOBAL_EMAIL'),
			'a.lastvisitDate' =>
JText::_('COM_USERS_HEADING_LAST_VISIT_DATE'),
			'a.registerDate'  =>
JText::_('COM_USERS_HEADING_REGISTRATION_DATE'),
			'a.id'            =>
JText::_('JGRID_HEADING_ID'),
		);
	}
}