HEX
Server: Apache
System: Linux 185.122.168.184.host.secureserver.net 5.14.0-570.52.1.el9_6.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Oct 15 06:39:08 EDT 2025 x86_64
User: barbeatleanalyti (1024)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: /home/barbeatleanalyti/www/public_html/webmail/modules/OAuthIntegratorWebclient/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\OAuthIntegratorWebclient;

/**
 * @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) 2019, Afterlogic Corp.
 *
 * @internal
 * @package Modules
 */
class Module extends \Aurora\System\Module\AbstractWebclientModule
{
	public $oManager = null;
	
	/***** private functions *****/
	/**
	 * Initializes module.
	 * 
	 * @ignore
	 */
	public function init()
	{
		include_once __DIR__.'/Classes/OAuthClient/http.php';
		include_once __DIR__.'/Classes/OAuthClient/oauth_client.php';
		
		$this->aErrors = [
			Enums\ErrorCodes::ServiceNotAllowed			=> $this->i18N('ERROR_SERVICE_NOT_ALLOWED'),
			Enums\ErrorCodes::AccountNotAllowedToLogIn	=> $this->i18N('ERROR_ACCOUNT_NOT_ALLOWED'),
			Enums\ErrorCodes::AccountAlreadyConnected	=> $this->i18N('ERROR_ACCOUNT_ALREADY_CONNECTED'),
		];
		
		$this->oManager = new Manager($this);
		
		$this->AddEntry('oauth', 'OAuthIntegratorEntry');
		$this->includeTemplate('StandardLoginFormWebclient_LoginView', 'Login-After', 'templates/SignInButtonsView.html', self::GetName());
		$this->includeTemplate('StandardRegisterFormWebclient_RegisterView', 'Register-After', 'templates/SignInButtonsView.html', self::GetName());
		$this->subscribeEvent('Core::DeleteUser::before', array($this, 'onBeforeDeleteUser'));
		$this->subscribeEvent('Core::GetAccounts', array($this, 'onGetAccounts'));
	}
	
	/**
	 * Deletes all oauth accounts which are owened by the specified user.
	 * 
	 * @ignore
	 * @param int $iUserId User identifier.
	 */
	public function onBeforeDeleteUser($aArgs, &$mResult)
	{
		$this->oManager->deleteAccountByUserId($aArgs['UserId']);
	}
	
	/**
	 * 
	 * @param array $aArgs
	 * @param array $aResult
	 */
	public function onGetAccounts($aArgs, &$aResult)
	{
		$aUserInfo = \Aurora\System\Api::getAuthenticatedUserInfo($aArgs['AuthToken']);
		if (isset($aUserInfo['userId']))
		{
			$iUserId = $aUserInfo['userId'];
			$mAccounts = $this->oManager->getAccounts($iUserId);
			if (\is_array($mAccounts))
			{
				foreach ($mAccounts as $oAccount) {
					$aResult[] = array(
						'Id' => $oAccount->EntityId,
						'UUID' => $oAccount->UUID,
						'Type' => $oAccount->getName(),
						'Email' => $oAccount->Email
					);
				}
			}
		}
	}		
	/***** private functions *****/
	
	/***** public functions *****/
	/**
	 * @ignore
	 */
	public function OAuthIntegratorEntry()
	{
		$mResult = false;
		$aArgs = array(
			'Service' => $this->oHttp->GetQuery('oauth', '')
		);
		$this->broadcastEvent(
			'OAuthIntegratorAction',
			$aArgs,
			$mResult
		);
		
		$sError = $this->oHttp->GetQuery('error', null);
		if (isset($sError))
		{
			if (isset($_COOKIE["oauth-redirect"]))
			{
				$sOAuthIntegratorRedirect = $_COOKIE["oauth-redirect"];
				$sInvitationLinkHash =  isset($_COOKIE["InvitationLinkHash"]) ? $_COOKIE["InvitationLinkHash"] : null;
				if ($sOAuthIntegratorRedirect === 'register' && isset($sInvitationLinkHash))
				{
					
					\Aurora\System\Api::Location2(
						'./#register/' . $sInvitationLinkHash
					);
				}
				
			}
		}
		if (false !== $mResult && \is_array($mResult))
		{
			$oCoreModuleDecorator = \Aurora\Modules\Core\Module::Decorator();
			$iAuthUserId = isset($_COOKIE[\Aurora\System\Application::AUTH_TOKEN_KEY]) ? \Aurora\System\Api::getAuthenticatedUserId($_COOKIE[\Aurora\System\Application::AUTH_TOKEN_KEY]) : null;
			
			$oUser = null;
			$sOAuthIntegratorRedirect = 'login';
			if (isset($_COOKIE["oauth-redirect"]))
			{
				$sOAuthIntegratorRedirect = $_COOKIE["oauth-redirect"];
				@\setcookie('oauth-redirect', null, \strtotime('-1 hour'), \Aurora\System\Api::getCookiePath());
			}
			
			$oOAuthAccount = new Classes\Account(self::GetName());
			$oOAuthAccount->Type = $mResult['type'];
			$oOAuthAccount->AccessToken = isset($mResult['access_token']) ? $mResult['access_token'] : '';
			$oOAuthAccount->RefreshToken = isset($mResult['refresh_token']) ? $mResult['refresh_token'] : '';
			$oOAuthAccount->IdSocial = $mResult['id'];
			$oOAuthAccount->Name = $mResult['name'];
			$oOAuthAccount->Email = $mResult['email'];
			
			$oAccountOld = $this->oManager->getAccountById($oOAuthAccount->IdSocial, $oOAuthAccount->Type);
			if ($oAccountOld)
			{
				if ($sOAuthIntegratorRedirect === 'register')
				{
					\Aurora\System\Api::Location2(
						'./?error=' . Enums\ErrorCodes::AccountAlreadyConnected . '&module=' . self::GetName()
					);
				}
				
				if (!$oAccountOld->issetScope('auth') && $sOAuthIntegratorRedirect !== 'connect')
				{
					\Aurora\System\Api::Location2(
						'./?error=' . Enums\ErrorCodes::AccountNotAllowedToLogIn . '&module=' . self::GetName()
					);
				}
				
				$oOAuthAccount->setScopes(
//					array_merge($oAccountOld->getScopesAsArray(), $mResult['scopes'])						
					$mResult['scopes']
				);
				$oOAuthAccount->EntityId = $oAccountOld->EntityId;
				$oOAuthAccount->IdUser = $oAccountOld->IdUser;
				$this->oManager->updateAccount($oOAuthAccount);
				
				$oUser = $oCoreModuleDecorator->GetUser($oOAuthAccount->IdUser);
			}
			else
			{
				if ($iAuthUserId)
				{
					$aArgs = array(
						'UserName' => $mResult['name'],
						'UserId' => $iAuthUserId
					);
					$this->broadcastEvent(
						'CreateAccount', 
						$aArgs,
						$oUser
					);
				}
				
				$aArgs = array();
				$this->broadcastEvent(
					'CreateOAuthAccount', 
					$aArgs,
					$oUser
				);
				
				if (!($oUser instanceOf \Aurora\Modules\Core\Classes\User)  && 
						($sOAuthIntegratorRedirect === 'register' || $this->getConfig('AllowNewUsersRegister', false)))
				{
					$bPrevState = \Aurora\System\Api::skipCheckUserRole(true);
					
					try
					{
						$iUserId = $oCoreModuleDecorator->CreateUser(0, $oOAuthAccount->Email);
						if ($iUserId)
						{
							$oUser = $oCoreModuleDecorator->GetUser($iUserId);
						}
					}
					catch (\Aurora\System\Exceptions\ApiException $oException)
					{
						if ($oException->getCode() === \Aurora\System\Notifications::UserAlreadyExists)
						{
							\Aurora\System\Api::Location2(
								'./?error=' . Enums\ErrorCodes::AccountAlreadyConnected . '&module=' . self::GetName()
							);
						}
					}
					
					\Aurora\System\Api::skipCheckUserRole($bPrevState);
				}
				
				if ($oUser instanceOf \Aurora\Modules\Core\Classes\User)
				{
					$oOAuthAccount->IdUser = $oUser->EntityId;
					$oOAuthAccount->setScopes($mResult['scopes']);
					$this->oManager->createAccount($oOAuthAccount);
				}
			}
			
			if ($sOAuthIntegratorRedirect === 'login' || $sOAuthIntegratorRedirect === 'register')
			{
				if ($oUser)
				{
					$sAuthToken = \Aurora\System\Api::UserSession()->Set(
						array(
							'token' => 'auth',
							'sign-me' => true,
							'id' => $oUser->EntityId,
							'time' => \time() + 60 * 60 * 24 * 30,
							'account' => $oOAuthAccount->EntityId,
							'account_type' => $oOAuthAccount->getName()
						)
					);
					@\setcookie(\Aurora\System\Application::AUTH_TOKEN_KEY, $sAuthToken, \strtotime('+30 days'), \Aurora\System\Api::getCookiePath());
					
					//this will store user data in static variable of Api class for later usage
					\Aurora\System\Api::getAuthenticatedUser($sAuthToken);
					
					if ($this->oHttp->GetQuery('mobile', '0') === '1')
					{
						return json_encode(
							array(
								'AuthToken' => $sAuthToken
							)
						);
					}
					else
					{
						\Aurora\System\Api::Location2('./');
					}
				}
				else
				{
					\Aurora\System\Api::Location2(
						'./?error=' . Enums\ErrorCodes::AccountNotAllowedToLogIn . '&module=' . self::GetName()
					);
				}
			}
			else
			{
				$sResult = $mResult !== false ? 'true' : 'false';
				$sErrorCode = '';
				
				if ($oUser && $iAuthUserId && $oUser->EntityId !== $iAuthUserId)
				{
					$sResult = 'false';
					$sErrorCode = Enums\ErrorCodes::AccountAlreadyConnected;
				}
				
				echo
				"<script>"
					.	" try {"
					.		"if (typeof(window.opener.".$mResult['type']."ConnectCallback) !== 'undefined') {"
					.			"window.opener.".$mResult['type']."ConnectCallback(".$sResult . ", '".$sErrorCode."','".self::GetName()."');"
					.		"}"
					.	" }"
					.	" finally  {"
					.		"window.close();"
					.	" }"
				. "</script>";
				exit;
			}
		}
	}
	
	/**
	 * Returns oauth account with specified type.
	 * 
	 * @param string $Type Type of oauth account.
	 * @return \Aurora\Modules\OAuthIntegratorWebclient\Classes\Account
	 */
	public function GetAccount($Type)
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
		
		return $this->oManager->getAccount(
			\Aurora\System\Api::getAuthenticatedUserId(),
			$Type
		);
	}
	
	/**
	 * Updates oauth acount.
	 * 
	 * @param \Aurora\Modules\OAuthIntegratorWebclient\Classes\Account $oAccount Oauth account.
	 * @return boolean
	 */
	public function UpdateAccount(\Aurora\Modules\OAuthIntegratorWebclient\Classes\Account $oAccount)
	{
		return $this->oManager->updateAccount($oAccount);
	}
	/***** public functions *****/
	
	/***** public functions might be called with web API *****/
	/**
	 * Returns all oauth services names.
	 * 
	 * @return array
	 */
	public function GetServices()
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
	}
	
	/**
	 * Returns all oauth services settings for authenticated user.
	 * 
	 * @return array
	 */
	public function GetSettings()
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
		
		$aSettings = array();
		
		$oUser = \Aurora\System\Api::getAuthenticatedUser();
		if (!empty($oUser) && $oUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin)
		{
			$aArgs = array();
			$aServices = array();
			$this->broadcastEvent(
				'GetServicesSettings', 
				$aArgs,
				$aServices
			);
			$aSettings['Services'] = $aServices;
		}
		
		if (!empty($oUser) && $oUser->Role === \Aurora\System\Enums\UserRole::NormalUser)
		{
			$aSettings['AuthModuleName'] = $this->getConfig('AuthModuleName');
			$aSettings['OnlyPasswordForAccountCreate'] = $this->getConfig('OnlyPasswordForAccountCreate');
		}
		
		return $aSettings;
	}
	
	/**
	 * Updates all oauth services settings.
	 * 
	 * @param array $Services Array with services settings passed by reference.
	 * 
	 * @return boolean
	 */
	public function UpdateSettings($Services)
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin);
		
		$aArgs = array(
			'Services' => $Services
		);
		$this->broadcastEvent(
			'UpdateServicesSettings', 
			$aArgs
		);
		
		return true;
	}
	
	/**
	 * Get all oauth accounts.
	 * 
	 * @return array
	 */
	public function GetAccounts()
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
		
		$UserId = \Aurora\System\Api::getAuthenticatedUserId();
		$aResult = array();
		$mAccounts = $this->oManager->getAccounts($UserId);
		if (\is_array($mAccounts))
		{
			foreach ($mAccounts as $oAccount) {
				$aResult[] = array(
					'Id' => $oAccount->EntityId,
					'UUID' => $oAccount->UUID,
					'Type' => $oAccount->Type,
					'Email' => $oAccount->Email,
					'Name' => $oAccount->Name,
					'Scopes' => $oAccount->Scopes,
				);
			}
		}
		return $aResult;
	}
	
	/**
	 * Deletes oauth account with specified type.
	 * 
	 * @param string $Type Type of oauth account.
	 * @return boolean
	 */
	public function DeleteAccount($Type)
	{
		\Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
		
		return $this->oManager->deleteAccount(
			\Aurora\System\Api::getAuthenticatedUserId(),
			$Type
		);
	}
	/***** public functions might be called with web API *****/
}