Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.3] Notification email on admin registration approval #39650

Open
wants to merge 36 commits into
base: 5.3-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6d2e8ec
add the js to the build
carlitorweb Jan 15, 2023
4a90395
activate the user and send a notification
carlitorweb Jan 16, 2023
9818951
reviewers changes
carlitorweb Jan 16, 2023
6a9d9a3
Reviewers changes
carlitorweb Jan 16, 2023
25b54d0
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Jan 16, 2023
8bc6db7
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Jan 16, 2023
fbde984
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Jan 16, 2023
3b4e6fc
Merge branch '4.3-dev' into activate_send_email
carlitorweb Jan 16, 2023
39b8807
fix phpcs
carlitorweb Jan 16, 2023
095a504
js lint fixes
carlitorweb Jan 16, 2023
5da1653
reviewers changes
carlitorweb Jan 16, 2023
5c5c018
success message + reviewers changes + lenguages strings
carlitorweb Jan 18, 2023
0b3ea90
dont allow the button creating a user + reviewers changes
carlitorweb Jan 18, 2023
8edcee8
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Jan 18, 2023
7ee0c86
Update administrator/language/en-GB/com_users.ini
obuisard Jan 20, 2023
c50472d
wrong check if user is actived
carlitorweb Jan 20, 2023
c4cab6c
Merge branch '4.3-dev' into activate_send_email
carlitorweb Jan 20, 2023
31b6734
Merge branch '4.3-dev' into activate_send_email
carlitorweb Jan 22, 2023
85fb799
Merge branch '4.3-dev' into activate_send_email
carlitorweb Jan 26, 2023
2adb5e0
Merge branch '4.3-dev' into activate_send_email
QuyTon Feb 4, 2023
d4375a8
Update administrator/components/com_users/src/View/User/HtmlView.php
QuyTon Feb 4, 2023
6b4ee8a
Merge branch '4.3-dev' into activate_send_email
QuyTon Feb 21, 2023
ae6303d
Merge branch '4.3-dev' into activate_send_email
carlitorweb Mar 11, 2023
f6a26c3
Merge branch '4.4-dev' into activate_send_email
carlitorweb Mar 11, 2023
3edd0e6
Merge branch '4.4-dev' into activate_send_email
MacJoom Mar 22, 2023
6f8fe41
Merge branch '5.1-dev' into activate_send_email
Hackwar Mar 29, 2024
f5cf34a
Remove unused import
QuyTon Apr 3, 2024
f316e46
Merge branch '5.2-dev' into activate_send_email
richard67 May 4, 2024
b13a47a
use the administrator default language for Mail template
carlitorweb May 5, 2024
c375030
use the site default language for Mail template
carlitorweb May 5, 2024
8e0f66a
Merge branch '5.2-dev' into activate_send_email
carlitorweb May 5, 2024
72c936f
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Aug 16, 2024
41c9c84
Update administrator/components/com_users/src/Controller/UserControll…
carlitorweb Aug 16, 2024
41bc2fd
Merge branch '5.2-dev' into activate_send_email
carlitorweb Aug 18, 2024
74f21d6
Update joomla.asset.json
carlitorweb Aug 18, 2024
b7adf0a
Merge branch '5.3-dev' into activate_send_email
richard67 Sep 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Joomla\CMS\Access\Access;
use Joomla\CMS\MVC\Controller\FormController;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;

Expand Down Expand Up @@ -160,4 +161,34 @@ public function batch($model = null)
protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
{
}

/**
* Get the XHR request to activate a user
* js: media/com_users/js/activate-user-send-email
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function active(): void
{
// Get the ID of the user
$userId = $this->input->getString('userid', '');

// Prepare the default response
$responseError = false;
$responseMessage = null;

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

// Activate the user and send the email
if (!$model->activate($userId)) {
$responseError = true;
}

$responseMessage = \Joomla\CMS\Factory::getApplication()->getMessageQueue();

echo new JsonResponse(null, $responseMessage, $responseError);
}
}
103 changes: 81 additions & 22 deletions administrator/components/com_users/src/Model/UserModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Plugin\PluginHelper;
Expand Down Expand Up @@ -224,9 +225,8 @@ protected function preprocessForm(Form $form, $data, $group = 'user')
*/
public function save($data)
{
$pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id');
$user = $this->getUserFactory()->loadUserById($pk);

$pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id');
$user = $this->getUserFactory()->loadUserById($pk);
$my = $this->getCurrentUser();
$iAmSuperAdmin = $my->authorise('core.admin');

Expand Down Expand Up @@ -380,8 +380,8 @@ public function delete(&$pks)
*/
public function block(&$pks, $value = 1)
{
$app = Factory::getApplication();
$user = $this->getCurrentUser();
$app = Factory::getApplication();
$user = $this->getCurrentUser();

// Check if I am a Super Admin
$iAmSuperAdmin = $user->authorise('core.admin');
Expand Down Expand Up @@ -484,26 +484,80 @@ public function block(&$pks, $value = 1)
*/
public function activate(&$pks)
{
$user = $this->getCurrentUser();
$app = Factory::getApplication();
$user = $app->getIdentity();

// Check if I am a Super Admin
// Check if I am a super admin
$iAmSuperAdmin = $user->authorise('core.admin');
$table = $this->getTable();
$pks = (array) $pks;

// Load user table
$table = $this->getTable();
$pks = (array) $pks;

// Compile the user activated notification mail default values.
$mailData = [];
$mailData['siteurl'] = \Joomla\CMS\Uri\Uri::root();
$mailData['fromname'] = $app->get('fromname');
$mailData['mailfrom'] = $app->get('mailfrom');
$mailData['sitename'] = $app->get('sitename');

// Load com_users site language strings, the mail template use it
$app->getLanguage()->load('com_users', JPATH_SITE);

$sendMailTo = function ($userData) use ($app, $mailData) {
$mailData['name'] = $userData['name'];
$mailData['username'] = $userData['username'];

// Use the default language
$langTag = ComponentHelper::getParams('com_languages')->get('site', 'en-GB');

$mailer = new MailTemplate('com_users.registration.user.admin_activated', $langTag);
$mailer->addTemplateData($mailData);
$mailer->addRecipient($userData['email']);

try {
$return = $mailer->send();
} catch (\Exception $exception) {
try {
\Joomla\CMS\Log\Log::add(Text::_($exception->getMessage()), \Joomla\CMS\Log\Log::WARNING, 'jerror');

$return = false;
} catch (\RuntimeException $exception) {
$app->enqueueMessage(Text::_($exception->errorMessage()), $app::MSG_WARNING);

$return = false;
}
}

// Check for an error.
if ($return !== true) {
$app->enqueueMessage(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED'), $app::MSG_WARNING);

return false;
}

$app->enqueueMessage(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_SUCCESS'), $app::MSG_INFO);
return true;
};

PluginHelper::importPlugin($this->events_map['save']);

// Access checks.
// Activate and send the notification email
foreach ($pks as $i => $pk) {
if ($table->load($pk)) {
$old = $table->getProperties();
$allow = $user->authorise('core.edit.state', 'com_users');
$prevUserData = $table->getProperties();
$allow = $user->authorise('core.edit.state', 'com_users');

// Don't allow non-super-admin to delete a super admin
// Don't allow non-super-admin to edit the active status of a super admin
$allow = (!$iAmSuperAdmin && Access::check($pk, 'core.admin')) ? false : $allow;

// Ignore activated accounts but check if we can still
// resend the notification email
if (empty($table->activation)) {
// Ignore activated accounts.
if (\is_null($table->lastvisitDate)) {
$sendMailTo($prevUserData);
}

unset($pks[$i]);
} elseif ($allow) {
$table->block = 0;
Expand All @@ -518,7 +572,7 @@ public function activate(&$pks)
}

// Trigger the before save event.
$result = Factory::getApplication()->triggerEvent($this->event_before_save, [$old, false, $table->getProperties()]);
$result = Factory::getApplication()->triggerEvent($this->event_before_save, [$prevUserData, false, $table->getProperties()]);

if (\in_array(false, $result, true)) {
// Plugin will have to raise it's own error or throw an exception.
Expand All @@ -534,6 +588,11 @@ public function activate(&$pks)

// Fire the after save event
Factory::getApplication()->triggerEvent($this->event_after_save, [$table->getProperties(), false, true, null]);

// Send the email
if (!$sendMailTo($prevUserData)) {
return false;
}
} catch (\Exception $e) {
$this->setError($e->getMessage());

Expand All @@ -542,7 +601,7 @@ public function activate(&$pks)
} else {
// Prune items that you can't change.
unset($pks[$i]);
Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error');
$app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error');
}
}
}
Expand Down Expand Up @@ -733,10 +792,10 @@ public function batchUser($groupId, $userIds, $action)
// Remove the users from the group if requested.
if (isset($doDelete)) {
/*
* First we need to check that the user is part of more than one group
* otherwise we will end up with a user that is not part of any group
* unless we are moving the user to a new group.
*/
* First we need to check that the user is part of more than one group
* otherwise we will end up with a user that is not part of any group
* unless we are moving the user to a new group.
*/
if ($doDelete === 'group') {
$query = $db->getQuery(true);
$query->select($db->quoteName('user_id'))
Expand Down Expand Up @@ -877,8 +936,8 @@ public function getAssignedGroups($userId = null)
$userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id');

if (empty($userId)) {
$result = [];
$form = $this->getForm();
$result = [];
$form = $this->getForm();

if ($form) {
$groupsIDs = $form->getValue('groups');
Expand Down
20 changes: 20 additions & 0 deletions administrator/components/com_users/src/View/User/HtmlView.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,26 @@ function (Toolbar $childBar) use ($canDo, $isProfile) {
$toolbar->cancel('user.cancel');
}

// Check lastvisitDate for allow resend the activation email
$userIsNotActive = !empty($this->item->activation) || \is_null($this->item->lastvisitDate);

if ($this->item->id > 0 && $userIsNotActive) {
$buttonText = !empty($this->item->activation)
? Text::_('COM_USERS_USER_ACTIVATE_AND_MAIL')
: Text::_('COM_USERS_USER_ACTIVATION_REMINDER');

$toolbar->standardButton('activate', $buttonText)
->buttonClass('btn activate-send-mail')
->attributes([
'data-option' => 'com_users',
'data-task' => 'user.active',
'data-format' => 'json',
'data-userid' => $this->item->id,
])
->icon('icon-mail')
->onclick('');
}

$toolbar->divider();
$toolbar->help('Users:_Edit_Profile');
}
Expand Down
3 changes: 2 additions & 1 deletion administrator/components/com_users/tmpl/user/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->getDocument()->getWebAssetManager();
$wa->useScript('keepalive')
->useScript('form.validate');
->useScript('form.validate')
->useScript('com_users.activate-user-send-email');

$input = Factory::getApplication()->getInput();

Expand Down
2 changes: 2 additions & 0 deletions administrator/language/en-GB/com_users.ini
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ COM_USERS_USERS_N_ITEMS_DELETED="%d users deleted."
COM_USERS_USERS_N_ITEMS_DELETED_1="User deleted."
COM_USERS_USERS_TABLE_CAPTION="Users"
COM_USERS_USER_ACCOUNT_DETAILS="Account Details"
COM_USERS_USER_ACTIVATE_AND_MAIL="Activate & Send Email"
COM_USERS_USER_ACTIVATION_REMINDER="Send Activation Reminder"
COM_USERS_USER_ALLOWTOURAUTOSTART_LABEL="Allow Auto Starting Tours"
COM_USERS_USER_BACKUPCODE="Backup Code"
COM_USERS_USER_BACKUPCODES="Backup Codes"
Expand Down
11 changes: 11 additions & 0 deletions build/media_source/com_users/joomla.asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@
"attributes": {
"type": "module"
}
},
{
"name": "com_users.activate-user-send-email",
"type": "script",
"uri": "com_users/activate-user-send-email.min.js",
"dependencies": [
"core"
],
"attributes": {
"type": "module"
}
}
]
}
54 changes: 54 additions & 0 deletions build/media_source/com_users/js/activate-user-send-email.es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

if (!Joomla) {
throw new Error('Joomla API was not properly initialized');
}

const button = document.querySelector('.activate-send-mail');

if (button && Object.keys(button.dataset).length !== 0) {
button.addEventListener('click', () => {
button.querySelector('span').className = 'icon-spinner';
button.disabled = true;

const queryString = Object.keys(button.dataset)
.reduce((a, k) => {
a.push(`${k}=${encodeURIComponent(button.dataset[k])}`);
return a;
}, [])
.join('&');

const url = `index.php?${queryString}`;

Joomla.request({
url,
method: 'GET',

onSuccess: (resp) => {
let response;
try {
response = JSON.parse(resp);
} catch (error) {
button.classList.add('error');
}

button.querySelector('span').className = 'icon-mail';
button.disabled = false;

if (response.messages) {
Joomla.renderMessages(response.messages);
}
},
onError: (resp) => {
const response = JSON.parse(resp);
button.classList.add('error');
if (response.messages) {
Joomla.renderMessages(response.messages);
}
},
});
});
}
1 change: 1 addition & 0 deletions language/en-GB/com_users.ini
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION="Please log in to confirm that you a
COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION_PERMISSIONS="You are not authorised to activate new accounts, please log in with a privileged account."
COM_USERS_REGISTRATION_ACTIVATE_SUCCESS="Your Account has been activated. You can now log in using the username and password you chose during the registration."
COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED="An error was encountered while sending activation notification email"
COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_SUCCESS="The user has been notified that their account has been activated."
COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED="Failed to save activation data: %s"
COM_USERS_REGISTRATION_ADMINACTIVATE_SUCCESS="The user's account has been activated and the user has been notified about it."
COM_USERS_REGISTRATION_COMPLETE_ACTIVATE="Your account has been created and an activation link has been sent to the email address you entered. Note that you must activate the account by selecting the activation link when you get the email before you can login."
Expand Down