/home/ivoiecob/email.hirewise-va.com/modules/RocketChatWebclient/Module.php
<?php
/**
* This code is licensed under AGPLv3 license or Afterlogic Software License
* if commercial version of the product was purchased.
* For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
*/
namespace Aurora\Modules\RocketChatWebclient;
use Aurora\Api;
use Aurora\Modules\Contacts\Enums\StorageType;
use Aurora\Modules\Contacts\Module as ContactsModule;
use Aurora\Modules\Core\Module as CoreModule;
use Aurora\System\Enums\UserRole;
use Aurora\System\Exceptions\ApiException;
use Aurora\System\Utils;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\MessageFormatter;
use GuzzleHttp\Middleware;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
/**
* @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
* @license https://afterlogic.com/products/common-licensing Afterlogic Software License
* @copyright Copyright (c) 2023, Afterlogic Corp.
*
* @property Settings $oModuleSettings
*
* @package Modules
*/
class Module extends \Aurora\System\Module\AbstractModule
{
public $oRocketChatSettingsManager = null;
protected $sChatUrl = "";
protected $sDemoPass = "demo";
/**
* @var \GuzzleHttp\Client
*/
protected $client = null;
protected $adminAccount = null;
protected $stack = null;
protected $curUserData = false;
protected $curUserInfo = false;
/**
* @return Module
*/
public static function getInstance()
{
return parent::getInstance();
}
/**
* @return Module
*/
public static function Decorator()
{
return parent::Decorator();
}
/**
* @return Settings
*/
public function getModuleSettings()
{
return $this->oModuleSettings;
}
public function init()
{
$this->initLogging();
$this->oRocketChatSettingsManager = new Managers\RocketChatSettings\Manager($this);
$this->initConfig();
$this->AddEntry('chat', 'EntryChat');
$this->AddEntry('chat-direct', 'EntryChatDirect');
$this->subscribeEvent('Core::DeleteUser::before', array($this, 'onBeforeDeleteUser'));
$this->subscribeEvent('Core::Logout::after', array($this, 'onAfterLogout'));
}
/**
* Obtains list of module settings for authenticated user.
*
* @param int|null $TenantId Tenant ID
*
* @return array
*/
public function GetSettings($TenantId = null)
{
$aResult = [];
Api::checkUserRoleIsAtLeast(UserRole::NormalUser);
$oUser = \Aurora\System\Api::getAuthenticatedUser();
if ($oUser) {
$sChatUrl = '';
$sAdminUsername = '';
$oSettings = $this->oModuleSettings;
if (!empty($TenantId)) {
Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin);
$oTenant = Api::getTenantById($TenantId);
if ($oTenant && ($oUser->isAdmin() || $oUser->IdTenant === $oTenant->Id)) {
$sChatUrl = $oSettings->GetTenantValue($oTenant->Name, 'ChatUrl', $sChatUrl);
$sAdminUsername = $oSettings->GetTenantValue($oTenant->Name, 'AdminUsername', $sAdminUsername);
}
} else {
$sChatUrl = $oSettings->ChatUrl;
$sAdminUsername = $oSettings->AdminUsername;
}
if ($oUser->isNormalOrTenant()) {
$aResult = [
'ChatUrl' => $sChatUrl,
'AllowAddMeetingLinkToEvent' => $this->oModuleSettings->AllowAddMeetingLinkToEvent,
'MeetingLinkUrl' => $this->oModuleSettings->MeetingLinkUrl
];
} elseif ($oUser->isAdmin()) {
$aResult = [
'ChatUrl' => $sChatUrl,
'AdminUsername' => $sAdminUsername
];
}
}
return $aResult;
}
/**
* Updates settings of the Chat Module.
*
* @param int $TenantId
* @param string $ChatUrl
* @param string $AdminUsername
* @param string $AdminPassword
* @return boolean
*/
public function UpdateSettings($TenantId, $ChatUrl, $AdminUsername, $AdminPassword = null)
{
$oSettings = $this->oModuleSettings;
if (!empty($TenantId)) {
Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin);
$oTenant = Api::getTenantById($TenantId);
$oUser = Api::getAuthenticatedUser();
if ($oTenant && ($oUser->isAdmin() || $oUser->IdTenant === $oTenant->Id)) {
$aValues = [
'ChatUrl' => $ChatUrl,
'AdminUsername' => $AdminUsername
];
if ($AdminPassword) {
$sDecryptedPassword = Utils::DecryptValue($AdminPassword);
// checks that password is not encrypted already
if ($sDecryptedPassword === false) {
$aValues['AdminPassword'] = Utils::EncryptValue($AdminPassword);
} else {
$aValues['AdminPassword'] = $AdminPassword;
}
}
return $oSettings->SaveTenantSettings($oTenant->Name, $aValues);
}
} else {
Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
$oSettings->ChatUrl = $ChatUrl;
$oSettings->AdminUsername = $AdminUsername;
if ($AdminPassword) {
$sDecryptedPassword = Utils::DecryptValue($AdminPassword);
// checks that password is not encrypted already
if ($sDecryptedPassword === false) {
$oSettings->AdminPassword = Utils::EncryptValue($AdminPassword);
} else {
$oSettings->AdminPassword = $AdminPassword;
}
}
return $oSettings->Save();
}
return false;
}
/**
* This method returns the set of RocketChat settings that should havep artucular values.
*
* @param int|null $TenantId
* @return array
*/
public function GetRocketChatSettings($TenantId = null)
{
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
return $this->oRocketChatSettingsManager->get(
$this->getClient($TenantId),
$this->getAdminHeaders($TenantId)
);
}
/**
* Checks connection to RocketChat with provided credentials. Uses saved password if password argument is ommitted.
*
* @param int|null $TenantId
* @param string $ChatUrl
* @param string $AdminUsername
* @param string $AdminPassword
* @return boolean
*/
public function TestConnection($TenantId, $ChatUrl, $AdminUsername, $AdminPassword = null)
{
$bResult = false;
$oAuthenticatedUser = Api::getAuthenticatedUser();
if ($oAuthenticatedUser && $oAuthenticatedUser->isAdmin()
|| ($oAuthenticatedUser->Role === UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $TenantId)) {
// getting saved password if it was not provided
if ($AdminPassword === null) {
if (isset($TenantId)) {
$oTenant = Api::getTenantById($TenantId);
if ($oTenant) {
$AdminPassword = $this->oModuleSettings->GetTenantValue($oTenant->Name, 'AdminPassword', '');
} else {
throw new ApiException(\Aurora\System\Notifications::InvalidInputParameter);
}
} else {
$AdminPassword = $this->oModuleSettings->AdminPassword;
}
$sDecryptedPassword = Utils::DecryptValue($AdminPassword);
// use decripted password if it was not decrypted successfully
if ($sDecryptedPassword !== false) {
$AdminPassword = $sDecryptedPassword;
}
}
if ($ChatUrl && $AdminUsername && $AdminPassword) {
try {
$client = new Client([
'base_uri' => \rtrim($ChatUrl, '/') . '/api/v1/',
'verify' => false,
'handler' => $this->stack
]);
if ($client) {
$loginResponse = $client->post('login', [
'form_params' => [
'user' => $AdminUsername,
'password' => $AdminPassword,
],
'http_errors' => false
]);
$loginData = json_decode($loginResponse->getBody(), true);
// Check if the login was successful
if ($loginData['status'] === 'success') {
// Step 2: Use the auth token to validate the connection
$authToken = $loginData['data']['authToken'];
$userId = $loginData['data']['userId'];
// Make a test API call (e.g., get user info)
$userInfoResponse = $client->get('users.info', [
'query' => [
'username' => $AdminUsername
],
'headers' => [
'X-Auth-Token' => $authToken,
'X-User-Id' => $userId,
],
'http_errors' => false
]);
$bResult = $userInfoResponse->getStatusCode() === 200;
} elseif ($loginData['status'] === 'success' && $loginData['message']) {
throw new ApiException(\Aurora\System\Notifications::InvalidInputParameter, null, $loginData['message']);
// \Aurora\System\Api::Log('RocketChat connection failed: ' . $loginData['message']);
}
}
} catch (ConnectException $e) {
}
} else {
throw new ApiException(\Aurora\System\Notifications::InvalidInputParameter);
}
} else {
throw new ApiException(\Aurora\System\Notifications::AccessDenied);
}
return $bResult;
}
/**
* Applies some settings to RocketChat to achive better integration with Aurora
*
* @param int|null $TenantId
* @return bool
*/
public function ApplyRocketChatRequiredChanges($TenantId = null)
{
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
return $this->oRocketChatSettingsManager->setConfigs(
$this->getClient($TenantId),
$this->getAdminHeaders($TenantId)
);
}
/**
* Applies some text changes to RocketChat like user's home page.
*
* @param int|null $TenantId
* @return bool
*/
public function ApplyRocketChatTextChanges($TenantId = null)
{
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
return $this->oRocketChatSettingsManager->setTexts(
$this->getClient($TenantId),
$this->getAdminHeaders($TenantId)
);
}
/**
* Applies css theme tweeks to match RocketChat custome theme to Aurora's one
*
* @param int|null $TenantId
* @return bool
*/
public function ApplyRocketChatCssChanges($TenantId = null)
{
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
return $this->oRocketChatSettingsManager->setCss(
$this->getClient($TenantId),
$this->getAdminHeaders($TenantId)
);
}
/**
* This method handles direct chat entry point which can be used to start personal chat with a contact.
*/
public function EntryChatDirect()
{
try {
Api::checkUserRoleIsAtLeast(UserRole::NormalUser);
$sContactUuid = $this->oHttp->GetQuery('chat-direct');
$oCurrentUser = Api::getAuthenticatedUser();
$oContact = ContactsModule::Decorator()->GetContact($sContactUuid, $oCurrentUser->Id);
$sUserPublicId = null;
if ($oContact) {
if ($oContact->Storage === StorageType::Team) {
$sUserPublicId = $oContact->ViewEmail;
} else {
$oUser = $oContact ? Api::getUserById($oContact->IdUser) : null;
if ($oUser && $oCurrentUser && $oCurrentUser->IdTenant === $oUser->IdTenant) {
$sUserPublicId = $oUser->PublicId;
}
}
}
if ($sUserPublicId) {
$sChatLogin = $this->GetLoginForEmail($sUserPublicId);
if ($sChatLogin) {
$this->showChat('direct/' . $sChatLogin . '?layout=embedded');
} else {
$this->showError('User not found');
}
} else {
$this->showError('User not found');
}
} catch (ApiException $oEx) {
$this->showError('User not found');
}
}
/**
* This method handles direct chat entry point which is used to open RocketChat UI in a separate window.
*/
public function EntryChat()
{
$oIntegrator = \Aurora\System\Managers\Integrator::getInstance();
$this->showChat('', $oIntegrator->buildHeadersLink());
}
/**
*
*/
public function InitChat()
{
if (!$this->curUserData) {
$mResult = false;
$oUser = Api::getAuthenticatedUser();
if ($oUser && $this->client && $this->initUser()) {
$sAuthToken = isset($_COOKIE['RocketChatAuthToken']) ? $_COOKIE['RocketChatAuthToken'] : null;
$sUserId = isset($_COOKIE['RocketChatUserId']) ? $_COOKIE['RocketChatUserId'] : null;
if ($sAuthToken !== null && $sUserId !== null) {
$sAuthToken = Utils::DecryptValue($sAuthToken);
Api::AddSecret($sAuthToken);
try {
$res = $this->client->get('me', [
'headers' => [
"X-Auth-Token" => $sAuthToken,
"X-User-Id" => $sUserId,
],
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$body = \json_decode($res->getBody(), true);
$sLang = '';
if (isset($body->settings->preferences->language)) {
$sLang = $body->settings->preferences->language;
}
$sUserLang = Utils::ConvertLanguageNameToShort($oUser->Language);
if ($sUserLang !== $sLang) {
$this->updateLanguage($sUserId, $sAuthToken, $sUserLang);
}
$mResult = true;
}
} catch (ConnectException $oException) {
}
}
if (!$mResult) {
$currentUserInfo = $this->getCurrentUserInfo();
$mLoginResult = false;
if ($currentUserInfo) {
$mLoginResult = $this->loginCurrentUser();
if (!$mLoginResult && !$this->isDemoUser($oUser->PublicId)) {
if ($this->updateUserPassword($currentUserInfo)) {
$mLoginResult = $this->loginCurrentUser();
}
}
} elseif ($this->createCurrentUser() !== false) {
$mLoginResult = $this->loginCurrentUser();
}
if ($mLoginResult && isset($mLoginResult->data)) {
$iAuthTokenCookieExpireTime = (int) CoreModule::getInstance()->oModuleSettings->AuthTokenCookieExpireTime;
$sSameSite = CoreModule::getInstance()->oModuleSettings->CookieSameSite;
$sAuthToken = $mLoginResult->data->authToken;
$sUserId = $mLoginResult->data->userId;
Api::setCookie(
'RocketChatAuthToken',
Utils::EncryptValue($sAuthToken),
\strtotime('+' . $iAuthTokenCookieExpireTime . ' days'),
true,
$sSameSite
);
Api::setCookie(
'RocketChatUserId',
$sUserId,
\strtotime('+' . $iAuthTokenCookieExpireTime . ' days'),
true,
$sSameSite
);
$oUser->save();
}
}
if ($sAuthToken && $sUserId) {
$mResult = [
'authToken' => $sAuthToken,
'userId' => $sUserId,
'unreadCounter' => $this->getUnreadCounter($sUserId, $sAuthToken)
];
}
}
$this->curUserData = $mResult;
}
return $this->curUserData;
}
/**
* Returns RocketChat user's login for currently logged in user.
*/
public function GetLoginForCurrentUser()
{
$mResult = false;
$oUser = Api::getAuthenticatedUser();
if ($oUser) {
$mResult = $this->getUserNameFromEmail($oUser->PublicId);
}
return $mResult;
}
/**
* This method allows to get RocketChat login for a provided email address.
* If RocketChat account is missing it will be created
*
* @param string $Email
* @return string|false
*/
public function GetLoginForEmail($Email)
{
$mResult = false;
$oUserInfo = $this->getUserInfo($Email);
if (!$oUserInfo) {
$oUserInfo = $this->createUser($Email);
}
if ($oUserInfo && $oUserInfo->success) {
$mResult = $oUserInfo->user->username;
}
return $mResult;
}
/**
* Returns number of unread messages for currently logged in user.
*
* @return int
*/
protected function getUnreadCounter($sUserId, $sToken)
{
$iResult = 0;
if ($this->client) {
try {
$res = $this->client->get('subscriptions.get', [
'headers' => [
"X-Auth-Token" => $sToken,
"X-User-Id" => $sUserId,
],
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$aResponse = \json_decode($res->getBody(), true);
if (is_array($aResponse['update'])) {
foreach ($aResponse['update'] as $update) {
$iResult += $update['unread'];
}
}
}
} catch (ConnectException $oException) {
}
}
return $iResult;
}
/**
* Returns number of unread messages for a provided user.
*
* @param int|null $iTenantId
* @return \GuzzleHttp\Client|null
*/
protected function getClient($iTenantId = null)
{
$mResult = null;
$oSettings = $this->oModuleSettings;
$sChatUrl = '';
if (isset($iTenantId)) {
$oTenant = Api::getTenantById($iTenantId);
if ($oTenant) {
$sChatUrl = $oSettings->GetTenantValue($oTenant->Name, 'ChatUrl', '');
}
} else {
$sChatUrl = $oSettings->ChatUrl;
if (isset($this->client)) {
return $this->client;
}
}
if (!empty($sChatUrl)) {
$mResult = new Client([
'base_uri' => \rtrim($sChatUrl, '/') . '/api/v1/',
'verify' => false,
'handler' => $this->stack
]);
}
return $mResult;
}
/**
* Initializes chat client
*/
protected function initConfig()
{
$this->sChatUrl = $this->oModuleSettings->ChatUrl;
$sAdminUser = $this->oModuleSettings->AdminUsername;
if (!empty($this->sChatUrl) && !empty($sAdminUser)) {
$this->client = new Client([
'base_uri' => \rtrim($this->sChatUrl, '/') . '/api/v1/',
'verify' => false,
'handler' => $this->stack
]);
}
}
/**
* Checks if current user is a demo user
*
* @param string $sEmail
* @return bool
*/
protected function isDemoUser($sEmail)
{
$bDemo = false;
if (class_exists('\Aurora\Modules\DemoModePlugin\Module')) {
/** @var \Aurora\Modules\DemoModePlugin\Module $oDemoModePlugin */
$oDemoModePlugin = Api::GetModuleDecorator('DemoModePlugin');
$bDemo = $oDemoModePlugin && $oDemoModePlugin->CheckDemoUser($sEmail);
}
return $bDemo;
}
/**
* Initializes RocketChat logging
*/
protected function initLogging()
{
if ($this->oModuleSettings->EnableLogging && !$this->stack) {
$stack = HandlerStack::create();
$oLogger = new Logger('rocketchat');
$handler = new RotatingFileHandler(Api::GetLogFileDir() . 'rocketchat-log.txt');
$oLogger->pushHandler($handler);
//set your own exception handler so that the exception caused by logging does not interrupt the logic of the main code
$oLogger->setExceptionHandler(function ($e) {
Api::LogException($e);
});
collect([
"REQUEST: {method} - {uri} - HTTP/{version} - {req_headers} - {req_body}",
"RESPONSE: {code} - {res_body}",
])->each(function ($messageFormat) use ($stack, $oLogger) {
// We'll use unshift instead of push, to add the middleware to the bottom of the stack, not the top
$oLogger->pushProcessor(function ($record) {
$record['message'] = str_replace(Api::$aSecretWords, '*****', $record['message']);
$record['message'] = preg_replace(
[
'/(X-Auth-Token|X-2fa-code):(.+?\s)/i',
'/("bcrypt"):(.*?\})/i',
'/("authToken"):(.*?,)/i'
],
'$1: ***** ',
$record['message']
);
return $record;
});
$stack->unshift(Middleware::log(
$oLogger,
new MessageFormatter($messageFormat)
));
});
$this->stack = $stack;
}
}
/**
* Initializes RocketChat client
*
* @return bool
*/
protected function initUser()
{
$bResult = true;
if (!$this->getCurrentUserInfo()) {
if (!$this->createCurrentUser()) {
$bResult = false;
}
}
return $bResult;
}
/**
* Outputs HTML for chat page
*
* @param string $sUrl
* @param string $sIntegratorLinks
*
* @return void
*/
protected function showChat($sUrl = '', $sIntegratorLinks = '')
{
$aUser = $this->InitChat();
$sResult = \file_get_contents($this->GetPath() . '/templates/Chat.html');
if (\is_string($sResult)) {
echo strtr($sResult, [
'{{TOKEN}}' => $aUser ? $aUser['authToken'] : '',
'{{URL}}' => rtrim($this->sChatUrl, '/') . '/' . $sUrl,
'{{IntegratorLinks}}' => $sIntegratorLinks,
]);
}
}
/**
* Outputs text error
*
* @param string $sMessage
*/
protected function showError($sMessage = '')
{
echo $sMessage;
}
/**
* Calculates RocketChat username from user's email depending on module settings
*
* @param string $sEmail
* @return string|false
*/
protected function getUserNameFromEmail($sEmail)
{
$mResult = false;
$iChatUsernameFormat = $this->oModuleSettings->ChatUsernameFormat;
$aEmailParts = explode("@", $sEmail);
if (isset($aEmailParts[1])) {
$aDomainParts = explode(".", $aEmailParts[1]);
}
if (isset($aEmailParts[0])) {
$mResult = $aEmailParts[0];
if (isset($aDomainParts[0]) && ($iChatUsernameFormat == \Aurora\Modules\RocketChatWebclient\Enums\UsernameFormat::UsernameAndDomain)) {
$mResult .= "." . $aDomainParts[0];
}
if (isset($aEmailParts[1]) && ($iChatUsernameFormat == \Aurora\Modules\RocketChatWebclient\Enums\UsernameFormat::UsernameAndFullDomainName)) {
$mResult .= "." . $aEmailParts[1];
}
}
return $mResult;
}
/**
* Returs an Rocket Chat admin credentionals
*
* @param int|null $TenantId
* @param bool $EncrypdedPassword
* @return array|false
*/
protected function getAdminCredentials($TenantId = null, $EncrypdedPassword = true)
{
static $mResult = false;
if (!$mResult) {
$adminCreds = [];
$oSettings = $this->oModuleSettings;
if (isset($TenantId)) {
$oTenant = Api::getTenantById($TenantId);
if ($oTenant) {
$adminCreds = [
'AdminUser' => $oSettings->GetTenantValue($oTenant->Name, 'AdminUsername', ''),
'AdminPass' => $oSettings->GetTenantValue($oTenant->Name, 'AdminPassword', '')
];
}
} else {
$adminCreds = [
'AdminUser' => $oSettings->AdminUsername,
'AdminPass' => $oSettings->AdminPassword
];
}
if (is_array($adminCreds) && isset($adminCreds['AdminPass'])) {
if ($EncrypdedPassword) {
$adminCreds['AdminPass'] = Utils::DecryptValue($adminCreds['AdminPass']);
}
if ($adminCreds['AdminPass']) {
Api::AddSecret($adminCreds['AdminPass']);
$mResult = $adminCreds;
}
}
}
return $mResult;
}
/**
* Obtains RocketChat token for admin user
*
* @param int $TenantId
* @param array $aAdminCreds
* @return object|false
*/
protected function loginAdminAccount($TenantId, $aAdminCreds)
{
$mResult = false;
$client = $this->getClient($TenantId);
try {
if ($client && $aAdminCreds) {
$res = $client->post('login', [
'form_params' => [
'user' => $aAdminCreds['AdminUser'],
'password' => $aAdminCreds['AdminPass']
],
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$mResult = \json_decode($res->getBody());
}
}
} catch (ConnectException $oException) {
}
return $mResult;
}
/**
* @param int|null $TenantId
* @return object|false
*/
protected function getAdminAccount($TenantId = null)
{
$mResult = false;
if (!isset($TenantId) && isset($this->adminAccount)) {
return $this->adminAccount;
}
$aAdminCreds = $this->getAdminCredentials($TenantId);
if ($aAdminCreds) {
$mResult = $this->loginAdminAccount($TenantId, $aAdminCreds);
}
if (!$mResult) {
$aAdminCreds = $this->getAdminCredentials($TenantId, false);
$mResult = $this->loginAdminAccount($TenantId, $aAdminCreds);
}
if (!isset($TenantId) && $mResult) {
$this->adminAccount = $mResult;
}
return $mResult;
}
/**
* @param int|null $TenantId
* @return array
*/
protected function getAdminHeaders($TenantId = null)
{
$oAdmin = $this->getAdminAccount($TenantId);
$aAdminCreds = $this->getAdminCredentials($TenantId);
if ($oAdmin && $aAdminCreds) {
return [
'X-Auth-Token' => $oAdmin->data->authToken,
'X-User-Id' => $oAdmin->data->userId,
'X-2fa-code' => hash('sha256', $aAdminCreds['AdminPass']),
'X-2fa-method' => 'password'
];
}
return [];
}
/**
* Returns RocketChat user info
*
* @param int $sEmail
* @return object|false
*/
protected function getUserInfo($sEmail)
{
$mResult = false;
$sUserName = $this->getUserNameFromEmail($sEmail);
try {
if ($this->client) {
$res = $this->client->get('users.info', [
'query' => [
'username' => $sUserName
],
'headers' => $this->getAdminHeaders(),
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$mResult = \json_decode($res->getBody());
}
}
} catch (ConnectException $oException) {
\Aurora\System\Api::Log('Cannot get ' . $sUserName . ' user info. Exception is below.');
\Aurora\System\Api::LogException($oException);
}
return $mResult;
}
/**
*
*/
protected function getCurrentUserInfo()
{
if (!$this->curUserInfo) {
$oUser = Api::getAuthenticatedUser();
if ($oUser) {
$this->curUserInfo = $this->getUserInfo($oUser->PublicId);
}
}
return $this->curUserInfo;
}
/**
* Creates an user account in RocketChat
*
* @param string $sEmail
* @return object|false
*/
protected function createUser($sEmail)
{
$mResult = false;
$oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($sEmail);
if ($oAccount && $this->client) {
if (!$this->isDemoUser($sEmail)) {
$sPassword = $oAccount->getPassword();
} else {
$sPassword = $this->sDemoPass;
}
Api::AddSecret($sPassword);
$sLogin = $this->getUserNameFromEmail($sEmail);
$sName = isset($oAccount->FriendlyName) && $oAccount->FriendlyName !== '' ? $oAccount->FriendlyName : $sLogin;
try {
$res = $this->client->post('users.create', [
'json' => [
'email' => $sEmail,
'name' => $sName,
'password' => $sPassword,
'username' => $sLogin
],
'headers' => $this->getAdminHeaders(),
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$mResult = \json_decode($res->getBody());
}
} catch (ConnectException $oException) {
\Aurora\System\Api::Log('Cannot create ' . $sEmail . ' user. Exception is below.');
\Aurora\System\Api::LogException($oException);
}
}
return $mResult;
}
protected function createCurrentUser()
{
$mResult = false;
$oUser = Api::getAuthenticatedUser();
if ($oUser) {
$mResult = $this->createUser($oUser->PublicId);
}
return $mResult;
}
protected function loginCurrentUser()
{
$mResult = false;
$oUser = Api::getAuthenticatedUser();
if ($oUser) {
$oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($oUser->PublicId);
if ($oAccount && $this->client) {
if (!$this->isDemoUser($oUser->PublicId)) {
$sPassword = $oAccount->getPassword();
} else {
$sPassword = $this->sDemoPass;
}
Api::AddSecret($sPassword);
try {
$res = $this->client->post('login', [
'form_params' => [
'user' => $this->getUserNameFromEmail($oUser->PublicId),
'password' => $sPassword
],
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$mResult = \json_decode($res->getBody());
$sLang = '';
if (isset($mResult->data->me->settings->preferences->language)) {
$sLang = $mResult->data->me->settings->preferences->language;
}
$sUserLang = Utils::ConvertLanguageNameToShort($oUser->Language);
if ($sUserLang !== $sLang) {
$this->updateLanguage($mResult->data->userId, $mResult->data->authToken, $sUserLang);
}
}
} catch (ConnectException $oException) {
}
}
}
return $mResult;
}
protected function logout()
{
$mResult = false;
if ($this->client) {
try {
$sAuthToken = isset($_COOKIE['RocketChatAuthToken']) ? $_COOKIE['RocketChatAuthToken'] : null;
$sUserId = isset($_COOKIE['RocketChatUserId']) ? $_COOKIE['RocketChatUserId'] : null;
if ($sAuthToken !== null && $sUserId !== null) {
$res = $this->client->post('logout', [
'headers' => [
"X-Auth-Token" => $sAuthToken,
"X-User-Id" => $sUserId,
],
'http_errors' => false
]);
if ($res->getStatusCode() === 200) {
$mResult = \json_decode($res->getBody());
}
}
} catch (ConnectException $oException) {
Api::LogException($oException);
}
}
return $mResult;
}
protected function updateLanguage($sUserId, $sToken, $sLang)
{
if ($this->client) {
$this->client->post('users.setPreferences', [
'json' => [
'userId' => $sUserId,
'data' => [
"language" => $sLang
]
],
'headers' => [
"X-Auth-Token" => $sToken,
"X-User-Id" => $sUserId
],
'http_errors' => false
]);
}
}
protected function updateUserPassword($userInfo)
{
$mResult = false;
$oUser = Api::getAuthenticatedUser();
if ($oUser) {
$oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($oUser->PublicId);
if ($oAccount && $this->client) {
Api::AddSecret($oAccount->getPassword());
$res = $this->client->post('users.update', [
'json' => [
'userId' => $userInfo->user->_id,
'data' => [
'password' => $oAccount->getPassword()
]
],
'headers' => $this->getAdminHeaders(),
'http_errors' => false
]);
$mResult = ($res->getStatusCode() === 200);
}
}
return $mResult;
}
public function onBeforeDeleteUser(&$aArgs, &$mResult)
{
$client = null;
$adminHeaders = null;
$oAuthenticatedUser = Api::getAuthenticatedUser();
if ($oAuthenticatedUser && $oAuthenticatedUser->isNormalOrTenant() &&
$oAuthenticatedUser->Id === (int) $aArgs['UserId']
) {
// Access is granted
$client = $this->client;
$adminHeaders = $this->getAdminHeaders();
} else {
$oUser = Api::getUserById((int) $aArgs['UserId']);
if ($oUser) {
if ($oAuthenticatedUser->Role === UserRole::TenantAdmin && $oUser->IdTenant === $oAuthenticatedUser->IdTenant) {
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin);
} elseif ($oAuthenticatedUser->Role === UserRole::SuperAdmin) {
\Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin);
}
$client = $this->getClient($oUser->IdTenant);
$adminHeaders = $this->getAdminHeaders($oUser->IdTenant);
}
}
$sUserName = $this->getUserNameFromEmail(Api::getUserPublicIdById($aArgs['UserId']));
try {
if ($client) {
$oRes = $client->post('users.delete', [
'json' => [
'username' => $sUserName
],
'headers' => $adminHeaders,
'http_errors' => false,
'timeout' => 1
]);
if ($oRes->getStatusCode() === 200) {
$mResult = true;
}
}
} catch (ConnectException $oException) {
\Aurora\System\Api::Log('Cannot delete ' . $sUserName . ' user from RocketChat. Exception is below.');
\Aurora\System\Api::LogException($oException);
}
}
public function onAfterLogout($aArgs, &$mResult)
{
$sSameSite = CoreModule::getInstance()->oModuleSettings->CookieSameSite;
\Aurora\System\Api::setCookie(
'RocketChatAuthToken',
'',
-1,
true,
$sSameSite
);
\Aurora\System\Api::setCookie(
'RocketChatUserId',
'',
-1,
true,
$sSameSite
);
}
}