<?xml version="1.0" encoding="UTF-8"?>
<plugin name="Chatwee" version_long="10002" version_human="1.0.2" author="Chatwee" website="http://chatwee.com" update_check=""><hooks><hook type="S" class="\IPS\Theme\class_core_front_global" filename="embed_code"><![CDATA[//<?php

if (!defined( '\IPS\SUITE_UNIQUE_KEY'))
{
	exit;
}

class hook1 extends _HOOK_CLASS_
{
	public static function hookData() {
		try
		{
			return array_merge_recursive(array(
				'globalTemplate' =>	array(
					0 => array (
						'selector' => '#ipsLayout_footer',
						'type' => 'add_after',
						'content' => '{template="embed_code" group="plugins" location="global" app="core"}',
					)
				)
			), parent::hookData());
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}
}
]]></hook><hook type="C" class="\IPS\Login" filename="login"><![CDATA[//<?php

if(!defined('\IPS\SUITE_UNIQUE_KEY'))
{
	exit;
}

require_once \IPS\ROOT_PATH . "/plugins/chatwee/hooks/sdk.php";

class hook2 extends _HOOK_CLASS_
{
	public function authenticate()
	{
		try
		{
			$result = call_user_func_array('parent::authenticate', func_get_args());

			$user = isSet($result->member) ? $result->member : $result;

			if($user->member_id)
			{
				try
				{
				    if (\IPS\Settings::i()->sso_enable == 1)
				    {
					    \PluginController::authenticateCallback($user);
					}
				}
				catch (\Exception $exception)
				{
					\IPS\Log::log($exception, 'chatwee_plugin');
				}
			}

			return call_user_func_array('parent::authenticate', func_get_args());
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}
}]]></hook><hook type="C" class="\IPS\Login\LoginAbstract" filename="logout"><![CDATA[//<?php

if(!defined('\IPS\SUITE_UNIQUE_KEY'))
{
	exit;
}

require_once \IPS\ROOT_PATH . "/plugins/chatwee/hooks/sdk.php";

abstract class hook3 extends _HOOK_CLASS_
{
	public function logoutAccount(\IPS\Member $member, \IPS\Http\Url $redirectUrl)
	{
		try
			{
			try
			{
                if (\IPS\Settings::i()->sso_enable == 1) {
                    \PluginController::logoutAccountCallback();
                }
			}
			catch (\Exception $exception)
			{
				\IPS\Log::log($exception, 'chatwee_plugin');
			}

			return call_user_func_array('parent::logoutAccount', func_get_args());
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}
}]]></hook><hook type="C" class="\IPS\Login" filename="sdk"><![CDATA[<?php

class HttpClient
{
    const USER_AGENT_HEADER = "ChatweeV2 PHP SDK 1.02 RAW";

    private $response;

    private $responseStatus;

    private $responseObject;

    public function get($path, $parameters)
    {
        try
        {
            if(SsoConfiguration::isConfigurationSet() === false)
            {
                throw new \Exception("The client credentials are not set");
            }
            $apiUrl = SsoConfiguration::getApiUrl();
            $parameters["chatId"] = SsoConfiguration::getChatId();
            $parameters["clientKey"] = SsoConfiguration::getClientKey();

            $serializedParameters = self::_serializeParameters($parameters);
            $url = $apiUrl . "/" . $path . "?" . $serializedParameters;

            self::call("GET", $url, null);
        }
        catch ( \RuntimeException $e )
        {
            if ( method_exists( get_parent_class(), __FUNCTION__ ) )
            {
                return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
            }
            else
            {
                throw $e;
            }
        }
    }


    public function delete($path, $parameters)
    {
	try
	{

	        if (SsoConfiguration::isConfigurationSet() === false) {
	            throw new \Exception("The client credentials are not set");
	        }

	        $apiUrl = SsoConfiguration::getApiUrl();
	        $parameters["chatId"] = SsoConfiguration::getChatId();
	        $parameters["clientKey"] = SsoConfiguration::getClientKey();

	        $url = $apiUrl . "/" . $path;
	        self::call("DELETE", $url, $parameters);
	}
	catch ( \RuntimeException $e )
	{
		if ( method_exists( get_parent_class(), __FUNCTION__ ) )
		{
			return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
		}
		else
		{
			throw $e;
		}
	}
    }


    public function post($path, $parameters)
    {
	try
	{

	        if (SsoConfiguration::isConfigurationSet() === false) {
	            throw new \Exception("The client credentials are not set");
	        }
	        $apiUrl = SsoConfiguration::getApiUrl();
	        $parameters["chatId"] = SsoConfiguration::getChatId();
	        $parameters["clientKey"] = SsoConfiguration::getClientKey();

	        $url = $apiUrl . "/" . $path;
	        self::call("POST", $url, $parameters);
	}
	catch ( \RuntimeException $e )
	{
		if ( method_exists( get_parent_class(), __FUNCTION__ ) )
		{
			return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
		}
		else
		{
			throw $e;
		}
	}
    }


    public function put($path, $parameters)
    {
	try
	{
	        if (SsoConfiguration::isConfigurationSet() === false) {
	            throw new \Exception("The client credentials are not set");
	        }
	        $apiUrl = SsoConfiguration::getApiUrl();
	        $parameters["chatId"] = SsoConfiguration::getChatId();
	        $parameters["clientKey"] = SsoConfiguration::getClientKey();

	        $url = $apiUrl . "/" . $path;
	        self::call("PUT", $url, $parameters);
	}
	catch ( \RuntimeException $e )
	{
		if ( method_exists( get_parent_class(), __FUNCTION__ ) )
		{
			return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
		}
		else
		{
			throw $e;
		}
	}
    }


    private function call($method, $url, $parameter)
    {
	try
	{

	        $curl = curl_init();


	        $customUserAgent = SsoConfiguration::getCustomUserAgent();

	        $userAgent = $customUserAgent ? $customUserAgent : self::USER_AGENT_HEADER;


	        curl_setopt($curl, CURLOPT_TIMEOUT, 60);

	        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);

	        curl_setopt($curl, CURLOPT_URL, $url);

	        curl_setopt($curl, CURLOPT_ENCODING, 'gzip');

	        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

	        curl_setopt($curl, CURLOPT_HTTPHEADER, Array(

	            'Accept: application/json',

	            'Content-Type: application/json',

	            'User-Agent: ' . $userAgent

	        ));


	        if ($method != "GET") {

	            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameter));

	        }


	        $this->response = curl_exec($curl);

	        $this->responseStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);

	        curl_close($curl);


	        $this->responseObject = $this->response ? json_decode($this->response) : null;


	        if ($this->responseStatus != 200) {

	            $responseError = $this->responseObject ? $this->responseObject->errorMessage : "ChatweeV2 PHP SDK unknown error: " . $this->responseStatus;

	            $responseError .= ' ' . curl_error($curl);

	            $responseError .= " (" . $url . ")";

	            throw new \Exception($responseError);

	        }

	}
	catch ( \RuntimeException $e )
	{
		if ( method_exists( get_parent_class(), __FUNCTION__ ) )
		{
			return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
		}
		else
		{
			throw $e;
		}
	}
    }

    private function _serializeParameters($parameters)
    {
		try {
			if (!is_array($parameters) || count($parameters) == 0) {
				return "";
			}

			$result = "";
			foreach ($parameters as $key => $value) {
				$result .= ($key . "=" . ($value ? urlencode($value) : $value) . '&');
			}

			$result = substr_replace($result, "", -1);
			return $result;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public function getResponse()
    {
		try {
			return $this->response;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public function getResponseObject()
    {
		try {
			return $this->responseObject;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public function getResponseStatus()
    {
		try {
			return $this->responseStatus;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class SsoConfiguration
{
    private static $_apiUrl = null;

    private static $_chatId = null;

    private static $_clientKey = null;

    private static $_customUserAgent = null;

    public static function setApiUrl($apiUrl)
    {
		try {
			self::$_apiUrl = $apiUrl;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function setChatId($chatId)
    {
		try {
			self::$_chatId = $chatId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function setClientKey($clientKey)
    {
		try {
	            self::$_clientKey = $clientKey;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function setCustomUserAgent($customUserAgent)
    {
		try {
	        self::$_customUserAgent = $customUserAgent;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getApiUrl()
    {
		try {
	            return self::$_apiUrl;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getChatId()
    {
		try {
			return self::$_chatId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getClientKey()
    {
		try {
			return self::$_clientKey;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getCustomUserAgent()
    {
		try {
			return self::$_customUserAgent;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function isConfigurationSet()
    {
		try {
			return self::$_chatId !== null && self::$_clientKey !== null;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class SsoManager
{

    public static function registerUser($parameters)
    {
		try {
			if (isSet($parameters["login"]) === false) {
				throw new \Exception("login parameter is required");
			}

			$userId = SsoUser::register(Array(
				"login" => $parameters["login"],
				"isAdmin" => isSet($parameters["isAdmin"]) === true ? $parameters["isAdmin"] : false,
				"avatar" => isSet($parameters["avatar"]) === true ? $parameters["avatar"] : ""
			));

			return $userId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function loginUser($parameters)
    {
		try {
			if (isSet($parameters["userId"]) === false) {
				throw new \Exception("userId parameter is required");
			}
			if (self::isLogged() === true) {
				self::logoutUser();
			}

			$sessionId = SsoUser::login(Array(
				"userId" => $parameters["userId"],
				"userIp" => SsoUtils::getUserIp()
			));

			SsoSession::setSessionId($sessionId);

			return $sessionId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function logoutUser()
    {
		try {
			if (self::isLogged() === false) {
				return false;
			}
			$sessionId = SsoSession::getSessionId();

			SsoUser::removeSession(Array(
				"sessionId" => $sessionId
			));

			SsoSession::clearSessionId();
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function editUser($parameters)
    {
		try {
			if (isSet($parameters["login"]) === false) {
				throw new \Exception("login parameter is required");
			}
			if (isSet($parameters["userId"]) === false) {
				throw new \Exception("userId parameter is required");
			}

			$editParameters = Array(
				"userId" => $parameters["userId"],
				"login" => $parameters["login"],
				"avatar" => isSet($parameters["avatar"]) === true ? $parameters["avatar"] : ""
			);

			if (isSet($parameters["isAdmin"]) === true) {
				$editParameters["isAdmin"] = $parameters["isAdmin"];
			}

			SsoUser::edit($editParameters);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    private static function isLogged()
    {
		try {
			return SsoSession::isSessionSet();
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class SsoSession
{
    const SESSION_DURATION = 86400;

    private static function getCookieKey()
    {
		try {
			if (SsoConfiguration::isConfigurationSet() === false) {
				throw new \Exception("The client credentials are not set");
			}
			return "chatwee-SID-" . SsoConfiguration::getChatId();
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getSessionId()
    {
		try {
	            $cookieKey = self::getCookieKey();

			return isSet($_COOKIE[$cookieKey]) ? $_COOKIE[$cookieKey] : null;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function setSessionId($sessionId)
    {
		try {
			$hostChunks = explode(".", $_SERVER["HTTP_HOST"]);

			$hostChunks = array_slice($hostChunks, -2);

			$cookieDomain = "." . implode(".", $hostChunks);

			setcookie(self::getCookieKey(), $sessionId, time() + self::SESSION_DURATION, "/", $cookieDomain);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function clearSessionId()
    {
		try {
			$hostChunks = explode(".", $_SERVER["HTTP_HOST"]);

			$hostChunks = array_slice($hostChunks, -2);

			$cookieDomain = "." . implode(".", $hostChunks);

			setcookie(self::getCookieKey(), "", time() - 1, "/", $cookieDomain);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function isSessionSet()
    {
		try {
			return SsoSession::getSessionId() !== null;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class SsoUser
{
    public static function register($parameters)
    {
		try {
			$requestParameters = Array(
				"login" => $parameters["login"],
				"isAdmin" => $parameters["isAdmin"] === true ? "1" : "0",
				"avatar" => $parameters["avatar"]
			);

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/register", $requestParameters);

			$userId = $httpClient->getResponseObject();

			return $userId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function login($parameters)
    {
		try {
			$requestParameters = Array(
				"userId" => $parameters["userId"]
			);

			if (isSet($parameters["userIp"])) {
				if (filter_var($parameters["userIp"], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
					$requestParameters["userIp"] = $parameters["userIp"];
				}
			}

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/login", $requestParameters);

			$sessionId = $httpClient->getResponseObject();

			return $sessionId;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function removeSession($parameters)
    {
		try {
			$requestParameters = Array(
				"sessionId" => $parameters["sessionId"]
			);

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/remove-session", $requestParameters);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function validateSession($parameters)
    {
		try {
			$requestParameters = Array(
				"sessionId" => $parameters["sessionId"]
			);

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/validate-session", $requestParameters);

			$validationResponse = $httpClient->getResponseObject();

			return $validationResponse;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function logout($parameters)
    {
		try {
			$requestParameters = Array(
				"userId" => $parameters["userId"]
			);

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/logout", $requestParameters);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function edit($parameters)
    {
		try {
			$requestParameters = Array(
				"userId" => $parameters["userId"],
				"login" => $parameters["login"],
				"avatar" => $parameters["avatar"]
			);

			if (isSet($parameters["isAdmin"]) === true) {
				$requestParameters["isAdmin"] = $parameters["isAdmin"] === true ? "1" : "0";
			}

			$httpClient = new HttpClient();
			$httpClient->get("sso-user/edit", $requestParameters);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class SsoUtils
{
    public static function getUserIp()
    {
		try {
			if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
				$ip = $_SERVER["HTTP_CLIENT_IP"];
			} elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
				$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
			} else {
				$ip = $_SERVER["REMOTE_ADDR"];
			}
			return $ip;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}

class PluginController
{
    public static function finishCallback()
    {
		try {

			if (!\IPS\Request::i()->isAjax()) {
				self::setSsoCredentials();
				self::synchronizeSessions();
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function authenticateCallback($user)
    {
		try {
			self::setSsoCredentials();
			self::ssoLogin($user);
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function logoutAccountcallback()
    {
		try {
			self::setSsoCredentials();
			self::ssoLogout();
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function setSsoCredentials()
    {
		try {
			$api_url = \IPS\Settings::i()->api_url;
			$chatId = \IPS\Settings::i()->chat_id;
			$clientKey = \IPS\Settings::i()->api_key;

			SsoConfiguration::setApiUrl($api_url);
			SsoConfiguration::setChatId($chatId);
			SsoConfiguration::setClientKey($clientKey);
			SsoConfiguration::setCustomUserAgent("Chatwee IPB Plugin 1.0.4");
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function synchronizeSessions()
    {
		try {
			$user = \IPS\Member::loggedIn();

			$isUserLoggedIn = $user->member_id ? true : false;

			if ($isUserLoggedIn === true && SsoSession::isSessionSet() === false) {
				self::ssoLogin($user);
			}
			if ($isUserLoggedIn === true && SsoSession::isSessionSet() === true) {
				try {
					$isSessionValid = SsoUser::validateSession(array(
						'sessionId' => SsoSession::getSessionId(),
					));
				} catch (\Exception $exception) {
					throw new \Exception("A Chatwee plugin error occured: " . $exception->getMessage());
				}

				if ($isSessionValid === false) {
					self::ssoLogin($user);
				}
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function ssoLogin($user)
    {
		try {
			$userId = $user->member_id;

			$chatweeUserId = self::getChatweeUserId($userId);

			if (!$chatweeUserId) {
				$chatweeUserId = self::ssoRegister($user);
			}
			if (!$chatweeUserId) {
				return false;
			}

			try {
				SsoManager::editUser(array(
					'userId' => $chatweeUserId,
					'login' => $user->name,
					'avatar' => $user->photo,
					'isAdmin' => self::isChatweeAdmin($user)
				));
			} catch (\Exception $exception) {
				if (strpos($exception->getMessage(), "User does not exist") !== false) {
					$chatweeUserId = self::ssoRegister($user);
				} else {
					throw new \Exception("A Chatwee plugin error occured: " . $exception->getMessage());
				}
			}

			try {
				$sessionId = SsoManager::loginUser(array(
					'userId' => $chatweeUserId
				));
			} catch (\Exception $exception) {
				throw new \Exception("A Chatwee plugin error occured: " . $exception->getMessage());
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function ssoLogout()
    {
		try {
			try {
				SsoManager::logoutUser();

			} catch (\Exception $exception) {
				throw new \Exception("A Chatwee plugin error occured: " . $exception->getMessage());
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function ssoRegister($user)
    {
		try {
			$userId = $user->member_id;

			try {
				$chatweeUserId = SsoManager::registerUser(Array(
					"login" => $user->name,
					"avatar" => $user->photo,
					"isAdmin" => self::isChatweeAdmin($user)
				));

				self::assignChatweeUserId($userId, $chatweeUserId);

				return $chatweeUserId;
			} catch (\Exception $exception) {
				throw new \Exception("A Chatwee plugin error occured: " . $exception->getMessage());
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function assignChatweeUserId($userId, $chatweeUserId)
    {
		try {
			try {
				\IPS\Db::i()->delete("chatwee", array('user_id=?', $userId));

				\IPS\Db::i()->insert("chatwee", array("user_id" => $userId, "chatwee_id" => $chatweeUserId, 'username' => ''));
			} catch (\Exception $exception) {
				throw $exception;
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function getChatweeUserId($userId)
    {
		try {
			try {
				$result = \IPS\Db::i()->select('*', 'chatwee', 'user_id = ' . $userId);

				if ($result->count() === 1) {
					$row = $result->first();
					return $row["chatwee_id"];
				}

				return null;
			} catch (\Exception $exception) {
				return null;
			}
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }

    public static function isChatweeAdmin($user)
    {
		try {

			if ($user->isAdmin() === true) {
				return true;
			}

			if (\IPS\Settings::i()->chatwee_moderators == 1 && is_array($user->groups) && in_array(6, $user->groups)) {
				return true;
			}

			return false;
		} catch (\RuntimeException $e) {
			if (method_exists(get_parent_class(), __FUNCTION__)) {
				return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
			} else {
				throw $e;
			}
		}
    }
}]]></hook><hook type="C" class="\IPS\Dispatcher\Front" filename="validate"><![CDATA[//<?php

if(!defined('\IPS\SUITE_UNIQUE_KEY'))
{
	exit;
}

require_once \IPS\ROOT_PATH . "/plugins/chatwee/hooks/sdk.php";

class hook5 extends _HOOK_CLASS_
{
	public function finish()
	{
		try
		{
			try
			{
				\PluginController::finishCallback();
			}
			catch (\Exception $exception)
			{
				\IPS\Log::log($exception, 'chatwee_plugin');
			}

			return call_user_func_array('parent::finish', func_get_args());
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}
}
]]></hook><hook type="C" class="\IPS\Member" filename="member_logout"><![CDATA[//<?php

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
	exit;
}

abstract class hook6 extends _HOOK_CLASS_
{
	public function memberSync( $method, $params=array () )
	{
		try
		{
			if($method === 'onLogout')
			{
				try
				{
                    if (\IPS\Settings::i()->sso_enable == 1) {
                        \PluginController::logoutAccountCallback();
					}
				}
				catch (\Exception $exception)
				{
					\IPS\Log::log($exception, 'chatwee_plugin');
				}
			}

			parent::memberSync( $method, $params );
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}
}
]]></hook></hooks><settings><setting><key>chatwee_code</key><default/></setting><setting><key>sso_enable</key><default>0</default></setting><setting><key>api_url</key><default/></setting><setting><key>chat_id</key><default/></setting><setting><key>api_key</key><default/></setting><setting><key>chatwee_moderators</key><default/></setting></settings><settingsCode><![CDATA[//<?php

$form->add( new \IPS\Helpers\Form\TextArea( 'chatwee_code', \IPS\Settings::i()->chatwee_code, TRUE, array(), function ($val) {
            $val = trim($val);
            $exp = "/^<script src=[\'\"]?https:\/\/([a-z]+\.)?chatwee-api\.com\/(v2)?\/script\/[0-9a-f]{24}\.js[\'\"]><\/script>$/";
            $noOfMatches = preg_match_all($exp, $val);
            if($noOfMatches != 1){
                throw new \DomainException('form_bad_value');
            }
        } ) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'sso_enable', \IPS\Settings::i()->sso_enable, FALSE, array(), NULL ) );
$form->add( new \IPS\Helpers\Form\Text( 'api_url', \IPS\Settings::i()->api_url, FALSE, array(),  NULL, NULL, NULL, 'api_url' ) );
$form->add( new \IPS\Helpers\Form\Text( 'chat_id', \IPS\Settings::i()->chat_id, FALSE, array(), NULL ) );
$form->add( new \IPS\Helpers\Form\Text( 'api_key', \IPS\Settings::i()->api_key, FALSE, array(), NULL ) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'chatwee_moderators', \IPS\Settings::i()->chatwee_moderators, FALSE, array(), NULL, NULL, NULL, 'chatwee_moderators' ) );


if ( $values = $form->values() )
{
    $api_url = trim($values["api_url"]);
    $chat_id = trim($values["chat_id"]);
    $api_key = trim($values["api_key"]);

    if ($values["sso_enable"]
        && strlen ($chat_id) == 24
        && strlen ($api_key ) == 24
        && filter_var($api_url, FILTER_VALIDATE_URL) !== false) {
        $form->saveAsSettings();
        return true;
    } else if (!$values["sso_enable"]) {
        $form->saveAsSettings();
        return TRUE;
    }else{
        \IPS\Output::i()->error( "Error while saving data. Please ensure the right values are set.", '1L169/4', 400, '' );
        return;
    }
}


return $form;]]></settingsCode><tasks/><widgets/><htmlFiles><html filename="embed_code.phtml">PGlwczp0ZW1wbGF0ZSBwYXJhbWV0ZXJzPSIiIC8+DQoNCjxkaXY+DQogICAge3NldHRpbmc9ImNoYXR3ZWVfY29kZSJ8cmF3IGVzY2FwZT0idHJ1ZSJ9DQo8L2Rpdj4NCg==</html></htmlFiles><cssFiles/><jsFiles/><resourcesFiles/><lang><word key="chatwee_code" js="0">Chatwee installation code</word><word key="chatwee_code_desc" js="0"><![CDATA[Copy the Chatwee installation code from your <a href='https://client.chatwee.com' target='_blank'>Dashboard</a> and paste it into the box. If you don't have a Chatwee account yet, please <a href='https://client.chatwee.com/register-form/v2' target='_blank'>sign up</a> absolutely for free.]]></word><word key="sso_enable" js="0">Enable SSO</word><word key="sso_enable_desc" js="0">Check this box if you want your users to log in via Single Sign-on.</word><word key="api_url" js="0">API URL</word><word key="api_url_desc" js="0"><![CDATA[Enter your API URL available in the <a href='https://client.chatwee.com' target='_blank'>Integration</a> tab.]]></word><word key="chat_id" js="0">Chat ID</word><word key="chat_id_desc" js="0"><![CDATA[Enter your Chat ID available in the <a href='https://client.chatwee.com' target='_blank'>Integration</a> tab.]]></word><word key="api_key" js="0">Client API Key</word><word key="api_key_desc" js="0"><![CDATA[Enter your Client API Key available in the <a href='https://client.chatwee.com' target='_blank'>Integration</a> tab.]]></word><word key="chatwee_moderators" js="0">Moderators as Chatwee admins</word><word key="chatwee_moderators_desc" js="0">Check this box if you would like to assign admin powers to Moderators.</word></lang><versions><version long="10000" human="1.0.0"><![CDATA[//<?php


/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
	header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
	exit;
}

/**
 * Install Code
 */
class ips_plugins_setup_install
{
	/**
	 * ...
	 *
	 * @return	array	If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
	 */
	public function step1()
	{
        \IPS\Db::i()->createTable( array(
            'name' => 'chatwee',
            'columns' => array(
                array(
                    'name'			=> 'user_id',
                    'type'			=> 'INT',
                    'allow_null'	=> FALSE,
                    'primary'		=> TRUE
                ),
                array(
                    'name'			=> 'chatwee_id',
                    'type'			=> 'VARCHAR',
                    'length'		=> 255,
                    'allow_null'	=> FALSE
                ),
                array(
                    'name'			=> 'set_as_chat_admin',
                    'type'			=> 'TINYINT',
                    'default'		=> 0,
                    'length'		=> 1
                ),
                array(
                    'name'			=> 'username',
                    'type'			=> 'VARCHAR',
                    'length'		=> 255,
                    'allow_null'	=> FALSE
                ),
                array(
                    'name'			=> 'avatar',
                    'type'			=> 'TEXT',
                    'allow_null'	=> TRUE
                )
            ),
            'if_not_exists'	=> TRUE,
        ));

		return TRUE;
	}

	// You can create as many additional methods (step2, step3, etc.) as is necessary.
	// Each step will be executed in a new HTTP request
}]]></version><version long="10002" human="1.0.2"><![CDATA[//<?php


/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
	header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
	exit;
}

/**
 * 1.0.2 Upgrade Code
 */
class ips_plugins_setup_upg_10002
{
	/**
	 * ...
	 *
	 * @return	array	If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
	 */
	public function step1()
	{


		return TRUE;
	}

	// You can create as many additional methods (step2, step3, etc.) as is necessary.
	// Each step will be executed in a new HTTP request
}]]></version></versions></plugin>
