<?php 
/**
* @version		$Id: exit.class.php 2700 2025-08-03 18:53:59Z IOS $
* @package		Elxis
* @subpackage	Exit pages handler
* @copyright	Copyright (c) 2006-2025 Elxis CMS (https://www.elxis.org). All rights reserved.
* @license		Elxis Public License ( https://www.elxis.org/elxis-public-license.html )
* @author		Elxis Team ( https://www.elxis.org )
* @description 	Elxis CMS is free software. Read the license for copyright notices and details
*/

defined('_ELXIS_') or die ('Direct access to this location is not allowed');


class exitPage {

	/**********************/
	/* GENERATE EXIT PAGE */
	/**********************/
	static public function make($screen='fatal', $code='', $message='', $pageparams=array()) {
		$screen = trim($screen);
		if (($screen == '') || !in_array($screen, array('403', '404', 'error', 'fatal', 'fatallang', 'offline', 'security', 'alogin', 'pwchange'))) {
			$screen = 'fatal';
		}

		$tpl = 'system';
		if ($screen == 'alogin') {
			if (!defined('ELXIS_ADMIN')) {
				$screen = 'fatal';
				$code = 'EXIT-0001';
				$message = 'You can not login in the administration area from front-end!';
			}
		}
		if ($screen == 'pwchange') {
			$uid = (int)eFactory::getElxis()->user()->uid;
			if ($uid < 1) {
				$screen = 'fatal';
				$code = 'EXIT-0002';
				$message = 'To change your password you must first login!';
			}
		}

		$found = false;
		$doctype = 'html5';
		if (class_exists('eRegistry', false)) {
			if (eRegistry::isLoaded('elxis')) {
				$found = true;
				$tpl = eRegistry::get('elxis')->getConfig('TEMPLATE');
				$tpl_file = ($screen == 'fatallang') ? 'fatal' : $screen;
				if (!file_exists(ELXIS_PATH.'/templates/'.$tpl.'/'.$tpl_file.'.php')) {
					$tpl = 'system';
				}
			}
		}

		$cfg = self::getElxisConfig();
		if (!$found) {
			$tpl = $cfg->get('TEMPLATE');
			$tpl_file = ($screen == 'fatallang') ? 'fatal' : $screen;
			if (!file_exists(ELXIS_PATH.'/templates/'.$tpl.'/'.$tpl_file.'.php')) {
				$tpl = 'system';
			}
		}

		if (class_exists('elxisLanguage', false)) {
			eFactory::getLang()->load('exit');
		}

		$docoptions = self::documentOptions();

		if (@ob_get_length() > 0) { ob_end_clean(); }
		if (($screen == '403') || ($screen == 'security') || (strpos($code, 'DEFB') !== false)) {
			header('HTTP/1.1 403 Forbidden');
			header('Status: 403 Forbidden');
		} else if (($screen == '404') || ($screen == 'fatallang')) {
			header('HTTP/1.1 404 Not Found');
		}
		header('Content-type:'.$docoptions['contenttype'].'; charset=utf-8');
		header('Expires: Sat, 5 Jan 1974 03:00:00 GMT');
		header('Cache-Control: no-store, no-cache, must-revalidate');
		header("Pragma: no-cache");
		header("X-Frame-Options: DENY");
		header("X-XSS-Protection: 1; mode=block");
		header("X-Content-Type-Options: nosniff");
		if ($cfg->get('CSP') != '') {
			if (class_exists('eRegistry', false)) {
				if (eRegistry::isLoaded('eDoc')) { $docoptions['nonce'] = eRegistry::get('eDoc')->getNonce(); }
			}
			if ($docoptions['nonce'] == '') {
				if (function_exists('openssl_random_pseudo_bytes')) {
					$docoptions['nonce'] = bin2hex(openssl_random_pseudo_bytes(32));
				} else {
					$docoptions['nonce'] = 'n'.mt_rand();
				}
			}
			$csp = str_replace('{nonce}', $docoptions['nonce'], $cfg->get('CSP'));
			header('Content-Security-Policy: '.$csp);
		}
		if (stripos($cfg->get('URL'), 'https') === 0) {
			header('Strict-Transport-Security: max-age=31536000; includeSubDomains;');
		}
		unset($cfg);

		switch ($screen) {
			case '403':
				//header("HTTP/1.0 403 Forbidden");header("Status: 403 Forbidden");
				self::error403($tpl, $code, $message, $docoptions);
			break;
			case '404':
				//header("HTTP/1.0 404 Not Found");
				self::error404($tpl, $code, $message, $docoptions);
			break;
			case 'error':
				self::error($tpl, $code, $message, $docoptions);
			break;
			case 'offline':
				self::offline($tpl, $code, $message, $docoptions);
			break;
			case 'security':
				self::security($tpl, $code, $message, $docoptions);
			break;
			case 'fatal':
				self::fatalError($tpl, $code, $message, $docoptions);
			break;
			case 'fatallang': //same template as "fatal" but with special message and logging as Error 404.
				self::fatalLanguageError($tpl, $code, $message, $docoptions);
			break;
			case 'alogin':
				self::adminLogin($tpl, $code, $message, $docoptions);
			break;
			case 'pwchange':
				self::passwordChange($tpl, $code, $message, $docoptions, $pageparams);
			break;
			default: break;
		}
		exit;
	}


	/********************/
	/* DOCUMENT OPTIONS */
	/********************/
	static private function documentOptions() {
		$docoptions = array();
		$docoptions['dc'] = 'html5';
		$docoptions['doctype'] = '<!DOCTYPE html>';
		$docoptions['contenttype'] = 'text/html';
		$docoptions['nonce'] = '';//if CSP is enable will get a value later from eDoc

		return $docoptions;
	}


	/***********************/
	/* MAKE ERROR 403 PAGE */
	/***********************/
	static private function error403($tpl, $code, $message, $docoptions) {
		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('ERROR').' 403';
		$page->msgtitle = $eLang->get('FORBIDDEN');
		$page->message = (trim($message) == '') ? $eLang->get('ACCESS_NOT_ALLOWED') : $message;
		$page->url = eFactory::getURI()->getUriString();
		$page->loginlink = $elxis->makeURL('user:login/');
		$page->sitelink = $elxis->makeURL();
		$page->code = 'E403';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon();
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		include(ELXIS_PATH.'/templates/'.$tpl.'/403.php');
	}


	/***********************/
	/* MAKE ERROR 404 PAGE */
	/***********************/
	static private function error404($tpl, $code, $message, $docoptions) {
		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('ERROR').' 404';
		$page->msgtitle = $eLang->get('PAGE_NOT_FOUND');
		$page->message = (trim($message) == '') ? $eLang->get('PAGE_REQ_NOT_FOUND') : $message;
		$page->url = eFactory::getURI()->getUriString();
		$page->searchaction = $elxis->makeURL('search:/');
		$page->sitelink = $elxis->makeURL();
		$page->code = 'E404';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		if (!defined('ELXIS_ADMIN')) {
			$page->menu = eFactory::getMenu()->getItems('mainmenu', 'frontend');
		} else {
			$page->menu = array();
		}
		$page->favicon = self::getFavicon();
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		if (class_exists('elxisError', false)) {
			$msg = 'ERROR 404 (Page not found). Reference code: '.$page->refcode."\nURL: ".$page->url;
			elxisError::logNotfound($msg);
		}

		include(ELXIS_PATH.'/templates/'.$tpl.'/404.php');
	}


	/*********************/
	/* MAKE OFFLINE PAGE */
	/*********************/
	static private function offline($tpl, $code, $message, $docoptions) {
		$lstatus = self::userLogin(false, false);

		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('OFFLINE');
		$page->msgtitle = $eLang->get('WEBSITE_OFFLINE');
		if (trim($message) != '') {
			$page->message = $message;
		} elseif ($elxis->getConfig('OFFLINE_MESSAGE') != '') {
			$page->message = $elxis->getConfig('OFFLINE_MESSAGE');
		} elseif ($elxis->getConfig('ONLINE') === 3) {
			$page->message = $eLang->get('OWN_USER_ACCESS');
		} else {
			$page->message = $eLang->get('WEBSITE_MAINTENANCE');
		}
		$page->url = eFactory::getURI()->getUriString();
		$page->loginaction = $elxis->makeURL('user:login/elxis.html', '', true);
		$page->sitelink = $elxis->makeURL();
		$page->code = 'OFF';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon();
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		if ($elxis->getConfig('ONLINE') === 3) {
			$page->title = $eLang->get('PRIVATE_SITE');
			$page->msgtitle = $eLang->get('WEBSITE_PRIVATE');
		}

		$page->loginerror = '';
		switch ($lstatus) {
			case 1:
				$page->loginerror = $eLang->get('FILL_VALID_USERPASS');
			break;
			case 2:
				$page->loginerror = $eLang->get('ONLY_ADMINS_LOGIN');
			break;
			case 0:
			default:
				if (isset($_GET['elxerror'])) {
					$page->loginerror = strip_tags(urldecode($_GET['elxerror']));
				}
			break;
		}

		include(ELXIS_PATH.'/templates/'.$tpl.'/offline.php');
	}


	/**************/
	/* LOGIN USER */
	/**************/
	static private function userLogin($internal, $makeotp=false) {
		$elxis = eFactory::getElxis();

		$iresponse = array('success' => false, 'errormsg' => '');

		if (($elxis->getConfig('ONLINE') !== 2) && ($elxis->getConfig('ONLINE') !== 3)) {
			if ($internal) {
				$iresponse['errormsg'] = 'The site is not offline!';
				return $iresponse;
			} else {
				return 0;
			}
		}

		if (!isset($_POST['uname'])) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDUNAME');
				return $iresponse;
			} else {
				return 0;
			}
		}
		if (!isset($_POST['pword'])) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
				return $iresponse;
			} else {
				return 0;
			}
		}

		$uname = trim($elxis->sanitizeInput('uname', INPUT_POST, true, false));
		$pword = trim($elxis->sanitizeInput('pword', INPUT_POST, true, false));
		$otp = trim($elxis->sanitizeInput('otp', INPUT_POST, true, false));
		if ($uname == '') {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDUNAME');
				return $iresponse;
			} else {
				return 1;
			}
		}
		if ($pword == '') {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
				return $iresponse;
			} else {
				return 1;
			}
		}
		$is_email_login = false;
		if (strpos($uname, '@') !== false) {
			if (!filter_var($uname, FILTER_VALIDATE_EMAIL)) {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDEMAIL');
					return $iresponse;
				} else {
					return 1;
				}
			}
			$is_email_login = true;
		}

		$db = eFactory::getDB();

		$sql = "SELECT COUNT(".$db->quoteId('uid').") FROM ".$db->quoteId('#__users');
		if ($is_email_login) {
			$sql .= " WHERE ".$db->quoteId('email')." = :unml AND ".$db->quoteId('block')." = 0";
		} else {
			$sql .= " WHERE ".$db->quoteId('uname')." = :unml AND ".$db->quoteId('block')." = 0";
		}
		if ($elxis->getConfig('ONLINE') === 2) {//only administrators
			$sql .= " AND ".$db->quoteId('gid')." = 1";
		}
		$stmt = $db->prepare($sql);
		$stmt->bindParam(':unml', $uname, PDO::PARAM_STR);
		$stmt->execute();
		$c = (int)$stmt->fetchResult();
		if ($c !== 1) {
			if ($internal) {
				if ($elxis->getConfig('ONLINE') === 2) {
					$iresponse['errormsg'] = eFactory::getLang()->get('ONLY_ADMINS_LOGIN');
				} else {
					$iresponse['errormsg'] = eFactory::getLang()->get('FILL_VALID_USERPASS');
				}
				return $iresponse;
			} else {
				return ($elxis->getConfig('ONLINE') === 2) ? 2 : 1;
			}
		}

		elxisLoader::loadInit('libraries:elxis:auth.class', 'eAuth', 'elxisAuth');
		$eAuth = eRegistry::get('eAuth');
		if ($eAuth->getError() != '') {
			if ($internal) {
				$iresponse['errormsg'] = 'Authentication error!';
				return $iresponse;
			} else {
				return 0;
			}
		}
		if (!$eAuth->setAuth('elxis')) {
			if ($internal) {
				$iresponse['errormsg'] = 'Could not set elxis authenticator as current! Is it enabled?';
				return $iresponse;
			} else {
				return 0;
			}
		}

		$options = array();
		$options['auth_method'] = 'elxis';
		$options['uname'] = $uname;
		$options['pword'] = $pword;

		if ($makeotp) {
			if (!$internal) {
				return 0;
			}
			$iresponse = $elxis->makeOTP($options);
			return $iresponse;
		}

		$options['remember'] = 1;
		$options['return'] = '';
		$options['internal'] = false;
		if ($otp != '') { $options['otp'] = $otp; }

		if ($internal) {
			$options['internal'] = true;
			$iresponse = $elxis->login($options);
			return $iresponse;
		} else {
			$elxis->login($options);
			$elxis->redirect('');
		}
	}


	/***************************/
	/* MAKE GENERIC ERROR PAGE */
	/***************************/
	static private function error($tpl, $code, $message, $docoptions) {
		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('ERROR');
		$page->msgtitle = $eLang->get('ERROR_OCCURED');
		$page->message = $message;
		$page->url = eFactory::getURI()->getUriString();
		$page->sitelink = $elxis->makeURL();
		$page->code = 'ERR';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon();
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		$msg = 'ERROR (generic). Reference code: '.$page->refcode."\nURL: ".$page->url;
		elxisError::logError($msg);

		include(ELXIS_PATH.'/templates/'.$tpl.'/error.php');
	}


	/****************************/
	/* MAKE SECURITY BLOCK PAGE */
	/****************************/
	static private function security($tpl, $code, $message, $docoptions) {
		$cfg = self::getElxisConfig();

		$page = new stdClass;
		$page->title = 'Security alert';
		$page->msgtitle = 'Request dropped!';
		$page->message = (trim($message) != '') ? $message : 'Elxis defender blocked your request.';
		$page->sitelink = $cfg->get('URL');
		$page->secure_sitelink = $cfg->get('URL');
		if (isset($_SERVER['HTTPS'])) {
			if (($_SERVER['HTTPS'] == 'on') || ($_SERVER['HTTPS'] == 1)) {
				$page->secure_sitelink = preg_replace('@^(http\:)@i', 'https:', $page->sitelink);
			}
		}
		$page->code = 'SEC';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon($page->secure_sitelink);
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="en" dir="ltr"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		include(ELXIS_PATH.'/templates/'.$tpl.'/security.php');
	}


	/*************************/
	/* MAKE FATAL ERROR PAGE */
	/*************************/
	static private function fatalError($tpl, $code, $message, $docoptions) {
		$cfg = self::getElxisConfig();

		$page = new stdClass;
		$page->title = 'Fatal error';
		$page->msgtitle = 'Unrecoverable error!';
		$page->message = (trim($message) != '') ? $message : 'The system encountered an unrecoverable error and is unable to proceed.';
		$page->sitelink = $cfg->get('URL');
		$page->secure_sitelink = $cfg->get('URL');
		if (isset($_SERVER['HTTPS'])) {
			if (($_SERVER['HTTPS'] == 'on') || ($_SERVER['HTTPS'] == 1)) {
				$page->secure_sitelink = preg_replace('@^(http\:)@i', 'https:', $page->sitelink);
			}
		}
		$page->code = 'SEC';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon($page->secure_sitelink);
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="en" dir="ltr"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		$msg = 'FATAL ERROR. Reference code: '.$page->refcode;
		if (isset($_SERVER['REQUEST_URI'])) { $msg .= "\nURL: ".$_SERVER['REQUEST_URI']; }
		elxisError::logError($msg);

		include(ELXIS_PATH.'/templates/'.$tpl.'/fatal.php');
	}


	/**********************************/
	/* MAKE FATAL LANGUAGE ERROR PAGE */
	/**********************************/
	static private function fatalLanguageError($tpl, $code, $message, $docoptions) {
		$cfg = self::getElxisConfig();

		$page = new stdClass;
		$page->title = 'Error 404';
		$page->msgtitle = 'Wrong language!';
		$page->message = (trim($message) != '') ? $message : 'The URL is invalid as you requested a non-existing language.';
		$page->sitelink = $cfg->get('URL');
		$page->secure_sitelink = $cfg->get('URL');
		if (isset($_SERVER['HTTPS'])) {
			if (($_SERVER['HTTPS'] == 'on') || ($_SERVER['HTTPS'] == 1)) {
				$page->secure_sitelink = preg_replace('@^(http\:)@i', 'https:', $page->sitelink);
			}
		}
		$page->code = 'E404';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon($page->secure_sitelink);
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="en" dir="ltr"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		$msg = 'ERROR 404 (Page not found). Reference code: '.$page->refcode;
		if (isset($_SERVER['REQUEST_URI'])) { $msg .= "\nURL: ".$_SERVER['REQUEST_URI']; }
		if (class_exists('elxisError', false)) { elxisError::logNotfound($msg); }

		include(ELXIS_PATH.'/templates/'.$tpl.'/fatal.php');
	}


	/**********************************/
	/* MAKE ADMINISTRATION LOGIN PAGE */
	/**********************************/
	static private function adminLogin($tpl, $code, $message, $docoptions) {
		$message = (int)$message;
		$lstatus = self::userAdminLogin($message, false, false);
		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('LOGIN');
		$page->msgtitle = $eLang->get('ADMINISTRATION_LOGIN');
		$page->confirmform = 0;
		$page->buttontext = $eLang->get('LOGIN');

		if ($message == 1) {
			$page->confirmform = 1;
			$page->buttontext = $eLang->get('CONFIRM');
			$page->message = $eLang->get('CONFIRM_INFO');
		} else {
			$page->message = $eLang->get('VUP_ACCESS_ADMIN');
		}

		$installed_langs = eFactory::getFiles()->listFolders('language');

		$page->loginaction = $elxis->makeAURL('', '', true);
		$page->sitelink = $elxis->makeURL();
		$page->code = 'ALOG';
		$page->refcode = ($code == '') ? $page->code : $page->code.'-'.$code;
		$page->favicon = self::getFavicon();
		$page->infolangs = $eLang->getallinfo($installed_langs);
		$page->loginerror = '';
		$page->return = (isset($_POST['return'])) ? self::getReturnURL() : eFactory::getURI()->getRealUriString();
		if ($page->return != '') { $page->return = base64_encode($elxis->secureURL($page->return, true)); }
		unset($installed_langs);

		switch ($lstatus) {
			case -2: case -3: case -4:
				$page->loginerror = $eLang->get('INVALIDPASS');
			break;
			case -5: $page->loginerror = 'Something wrong happened. Please try again.'; break;
			case -6: $page->loginerror = $eLang->get('FILL_VALID_USERPASS'); break;
			case -7: $page->loginerror = $eLang->get('USERNOTFOUND'); break;
			case -8: $page->loginerror = $eLang->get('NOT_ENOUGH_PRIV'); break;
			case 0: case -1: default:
				if (isset($_GET['elxerror'])) {
					$page->loginerror = strip_tags(urldecode($_GET['elxerror']));
				}
			break;
		}

		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		include(ELXIS_PATH.'/templates/'.$tpl.'/alogin.php');
	}


	/*************************************/
	/* MAKE EXPIRED PASSWORD CHANGE PAGE */
	/*************************************/
	static private function passwordChange($tpl, $code, $message, $docoptions, $pageparams) {
		$eLang = eFactory::getLang();
		$elxis = eFactory::getElxis();

		$page = new stdClass;
		$page->title = $eLang->get('CHANGE_PWORD');
		$page->msgtitle = $eLang->get('CURPWORD_EXPIRED');
		$page->buttontext = $eLang->get('CHANGE');
		$page->sitelink = $elxis->makeURL();
		$page->favicon = self::getFavicon();
		$page->doctype = $docoptions['doctype'];
		$page->contenttype = $docoptions['contenttype'];
		$page->htmlattributes = ' lang="'.$eLang->getinfo('LANGUAGE').'" dir="'.$eLang->getinfo('DIR').'"';
		$page->extrahead = '';//deprecated, compatibility with 4.x templates
		$page->cdata = false;//deprecated, compatibility with 4.x templates
		$page->nonce = $docoptions['nonce'];

		include(ELXIS_PATH.'/templates/'.$tpl.'/pwchange.php');
	}


	/*******************************/
	/* LOGIN USER IN ADMIN CONSOLE */
	/*******************************/
	static private function userAdminLogin($confirmpass=0, $internal=false, $makeotp=false) {
		$elxis = eFactory::getElxis();
		$db = eFactory::getDB();

		$iresponse = array('success' => false, 'errormsg' => '');

		if ($confirmpass == 1) {
			if (!isset($_POST['pword2'])) {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
					return $iresponse;
				} else {
					return -1;
				}
			}

			$pword2 = trim($elxis->sanitizeInput('pword2', INPUT_POST, true, false));
			if (trim($pword2) == '') {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
					return $iresponse;
				} else {
					return -2;
				}
			}

			$uname = $elxis->user()->uname;
			$uid = $elxis->user()->uid;
			$gid = $elxis->user()->gid;

			$sql = "SELECT ".$db->quoteId('uid').", ".$db->quoteId('pword').", ".$db->quoteId('gid')
			."\n FROM ".$db->quoteId('#__users')." WHERE ".$db->quoteId('uname')." = :username";
			$stmt = $db->prepareLimit($sql, 0, 1);
			$stmt->execute(array(':username' => $uname));
			$row = $stmt->fetch(PDO::FETCH_ASSOC);
			if (!$row) {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('USERNOTFOUND');
					return $iresponse;
				} else {
					return -3;
				}
			}
			$encpass = $elxis->obj('crypt')->getEncryptedPassword($pword2);
			if ($encpass != $row['pword']) {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
					return $iresponse;
				} else {
					return -4;
				}
			}
			if (($row['uid'] <> $elxis->user()->uid) || ($row['gid'] <> $elxis->user()->gid)) {
				if ($internal) {
					$iresponse['errormsg'] = 'Something wrong happened. Please try again.';
					return $iresponse;
				} else {
					return -5;
				}
			}

			$eSession = eFactory::getSession();
			$_session = $elxis->session();

			$eSession->set('backauth', 1);

			//regenerate session
			$old_session_id = $_session->session_id;
			$session_regenerated = false;
			if ($eSession->regenerate()) {
				$_session->session_id = $eSession->getId();
				$_session->forceNew();
				$session_regenerated = true;
			}
			if ($elxis->getConfig('SESSION_HANDLER') == 'database') {
				$ok = $_session->update();
			} else {
				$ok = $_session->insert();
			}
			if ($ok && $session_regenerated) {
				$_session->removeOld($old_session_id);
			}
			if ($internal) {
				$iresponse['success'] = true;
				return $iresponse;
			} else {
				$url = self::getReturnURL();
				$elxis->redirect($url);
			}
		}

		if (!isset($_POST['uname'])) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDUNAME');
				return $iresponse;
			} else {
				return -1;
			}
		}
		if (!isset($_POST['pword'])) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
				return $iresponse;
			} else {
				return -1;
			}
		}

		$uname = trim($elxis->sanitizeInput('uname', INPUT_POST, true, false));
		$pword = trim($elxis->sanitizeInput('pword', INPUT_POST, true, false));
		$otp = trim($elxis->sanitizeInput('otp', INPUT_POST, true, false));
		if ($uname == '') {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDUNAME');
				return $iresponse;
			} else {
				return -6;
			}
		}
		if ($pword == '') {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDPASS');
				return $iresponse;
			} else {
				return -6;
			}
		}

		$minlevel = ($elxis->getConfig('SECURITY_LEVEL') > 1) ? 100 : 70;

		$is_email_login = false;
		if (strpos($uname, '@') !== false) {
			if (!filter_var($uname, FILTER_VALIDATE_EMAIL)) {
				if ($internal) {
					$iresponse['errormsg'] = eFactory::getLang()->get('INVALIDEMAIL');
					return $iresponse;
				} else {
					return -6;
				}
			}
			$is_email_login = true;
		}

		$sql = "SELECT u.uid, g.level FROM ".$db->quoteId('#__users')." u"
		."\n INNER JOIN ".$db->quoteId('#__groups')." g ON g.gid = u.gid";
		if ($is_email_login) {
			$sql .= "\n WHERE u.email = :unml AND u.block = 0";
		} else {
			$sql .= "\n WHERE u.uname = :unml AND u.block = 0";
		}
		$stmt = $db->prepareLimit($sql, 0, 1);
		$stmt->bindParam(':unml', $uname, PDO::PARAM_STR);
		$stmt->execute();
		$row = $stmt->fetch(PDO::FETCH_ASSOC);
		if (!$row) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('USERNOTFOUND');
				return $iresponse;
			} else {
				return -7;
			}
		}
		if ($row['level'] < $minlevel) {
			if ($internal) {
				$iresponse['errormsg'] = eFactory::getLang()->get('NOT_ENOUGH_PRIV');
				return $iresponse;
			} else {
				return -8;
			}
		}

		$url = self::getReturnURL();

		elxisLoader::loadInit('libraries:elxis:auth.class', 'eAuth', 'elxisAuth');
		$eAuth = eRegistry::get('eAuth');
		if ($eAuth->getError() != '') {
			if ($internal) {
				$iresponse['errormsg'] = 'Authentication error! Please try again.';
				return $iresponse;
			} else {
				return -5;
			}
		}
		if (!$eAuth->setAuth('elxis')) {
			if ($internal) {
				$iresponse['errormsg'] = 'Could not set elxis authenticator as current! Is it enabled?';
				return $iresponse;
			} else {
				return -5;
			}
		}

		$options = array();
		$options['auth_method'] = 'elxis';
		$options['uname'] = $uname;
		$options['pword'] = $pword;

		if ($makeotp) {
			if (!$internal) {
				return 0;
			}
			$iresponse = $elxis->makeOTP($options);
			return $iresponse;
		}

		$options['remember'] = 0;
		$options['return'] = $url;
		$options['internal'] = false;
		if ($otp != '') { $options['otp'] = $otp; }

		if ($internal) {
			$options['internal'] = true;
			$iresponse = $elxis->login($options);
			if ($iresponse['success'] === true) {
				eFactory::getSession()->set('backauth', 1);
			}
			return $iresponse;
		} else {
			$ok = $elxis->login($options);
			if ($ok === true) {
				eFactory::getSession()->set('backauth', 1);
			}
			$elxis->redirect($url);
		}
	}


	/**************************************/
	/* PERFORM CUSTOM ACTION (ELXIS 5.5+) */
	/**************************************/
	static public function action($xaction) {
		$response = array('success' => 0, 'message' => '');

		if (class_exists('elxisLanguage', false)) {
			eFactory::getLang()->load('exit');
		}

		if (($xaction == '') || !in_array($xaction, array('login', 'makeotp', 'makeaotp', 'alogin', 'aconfirm', 'changepw'))) {
			$response['message'] = 'Invalid request!';
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}

		if ($xaction == 'login') {
			if (defined('ELXIS_ADMIN')) {
				$response['message'] = 'Invalid request!';
				$encoded = json_encode($response);
				self::makeResponse($encoded);
			}
			self::actionLogin($response, false);
		}
		if ($xaction == 'makeotp') {
			if (defined('ELXIS_ADMIN')) {
				$response['message'] = 'Invalid request!';
				$encoded = json_encode($response);
				self::makeResponse($encoded);
			}
			self::actionLogin($response, true);
		}

		if ($xaction == 'alogin') {
			if (!defined('ELXIS_ADMIN')) {
				$response['message'] = 'Invalid request!';
				$encoded = json_encode($response);
				self::makeResponse($encoded);
			}
			self::actionALogin($response, false);
		}
		if ($xaction == 'aconfirm') {
			if (!defined('ELXIS_ADMIN')) { 
				$response['message'] = 'Invalid request!';
				$encoded = json_encode($response);
				self::makeResponse($encoded);
			}
			self::actionAConfirm($response);
		}
		if ($xaction == 'makeaotp') {
			if (!defined('ELXIS_ADMIN')) {
				$response['message'] = 'Invalid request!';
				$encoded = json_encode($response);
				self::makeResponse($encoded);
			}
			self::actionALogin($response, true);
		}
		if ($xaction == 'changepw') {
			self::actionChangePW();
		}

		$response['message'] = 'Invalid request!';
		$encoded = json_encode($response);
		self::makeResponse($encoded);
	}


	/************************************/
	/* ACTION FRONTEND LOGIN / MAKE OTP */
	/************************************/
	static private function actionLogin($response, $makeotp=false) {
		if (isset($_POST['token'])) {
			$sess_token = trim(eFactory::getSession()->get('token_loginform'));
			$token = trim(eFactory::getElxis()->sanitizeInput('token', INPUT_POST, true, false));
		} else {
			$sess_token = '';
			$token = '';
		}
		if (($token == '') || ($sess_token == '') || ($sess_token != $token)) {
			$response['message'] = eFactory::getLang()->get('REQDROPPEDSEC');
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}

		$iresponse = self::userLogin(true, $makeotp);
		if ($iresponse['success']) {
			$response['success'] = 1;
			if (isset($iresponse['method'])) { $response['method'] = $iresponse['method']; }
		} else {
			$response['message'] = $iresponse['errormsg'];
		}
		$encoded = json_encode($response);
		self::makeResponse($encoded);
	}


	/***********************************/
	/* ACTION BACKEND LOGIN / MAKE OTP */
	/***********************************/
	static private function actionALogin($response, $makeotp=false) {
		if (isset($_POST['token'])) {
			$sess_token = trim(eFactory::getSession()->get('token_loginform'));
			$token = trim(eFactory::getElxis()->sanitizeInput('token', INPUT_POST, true, false));
		} else {
			$sess_token = '';
			$token = '';
		}
		if (($token == '') || ($sess_token == '') || ($sess_token != $token)) {
			$response['message'] = eFactory::getLang()->get('REQDROPPEDSEC');
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}

		$iresponse = self::userAdminLogin(0, true, $makeotp);
		if ($iresponse['success']) {
			$response['success'] = 1;
			if (isset($iresponse['method'])) { $response['method'] = $iresponse['method']; }
		} else {
			$response['message'] = $iresponse['errormsg'];
		}
		$encoded = json_encode($response);
		self::makeResponse($encoded);
	}


	/***********************************/
	/* ACTION BACKEND CONFIRM PASSWORD */
	/***********************************/
	static private function actionAConfirm($response) {
		if (isset($_POST['token'])) {
			$sess_token = trim(eFactory::getSession()->get('token_loginform'));
			$token = trim(eFactory::getElxis()->sanitizeInput('token', INPUT_POST, true, false));
		} else {
			$sess_token = '';
			$token = '';
		}
		if (($token == '') || ($sess_token == '') || ($sess_token != $token)) {
			$response['message'] = eFactory::getLang()->get('REQDROPPEDSEC');
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}

		$iresponse = self::userAdminLogin(1, true, false);
		if ($iresponse['success']) {
			$response['success'] = 1;
		} else {
			$response['message'] = $iresponse['errormsg'];
		}
		$encoded = json_encode($response);
		self::makeResponse($encoded);
	}


	/*********************************************/
	/* ACTION CHANGE PASSWORD (FRONTEND/BACKEND) */
	/************************************/
	static private function actionChangePW() {
		$elxis = eFactory::getElxis();

		$response = array('success' => 0, 'message' => '');

		$uid = (int)$elxis->user()->uid;
		if ($uid < 1) {
			$response['message'] = 'To change your password you must first login!';
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		if (isset($_POST['token'])) {
			$sess_token = trim(eFactory::getSession()->get('token_cpwform'));
			$token = trim($elxis->sanitizeInput('token', INPUT_POST, true, false));
		} else {
			$sess_token = '';
			$token = '';
		}
		if (($token == '') || ($sess_token == '') || ($sess_token != $token)) {
			$response['message'] = eFactory::getLang()->get('REQDROPPEDSEC');
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}

		$curpword = trim($elxis->sanitizeInput('curpword', INPUT_POST, true, false));
		$newpword = trim($elxis->sanitizeInput('newpword', INPUT_POST, true, false));
		$cnewpword = trim($elxis->sanitizeInput('cnewpword', INPUT_POST, true, false));

		if ($curpword == '') {
			$eLang = eFactory::getLang();
			$response['message'] = sprintf($eLang->get('FIELDNOEMPTY'), $eLang->get('CUR_PWORD'));
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		if ($newpword == '') {
			$eLang = eFactory::getLang();
			$response['message'] = sprintf($eLang->get('FIELDNOEMPTY'), $eLang->get('NEW_PWORD'));
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		if ($cnewpword == '') {
			$eLang = eFactory::getLang();
			$response['message'] = sprintf($eLang->get('FIELDNOEMPTY'), $eLang->get('NEW_CONFPWORD'));
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		if ($newpword  != $cnewpword) {
			$response['message'] = 'Passwords do not match!';
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		if ($curpword == $newpword) {
			$response['message'] = 'The new password is the same as the old one!';
			$encoded = json_encode($response);
			self::makeResponse($encoded);
		}
		$changeresponse = $elxis->changeCurrentUserPassword($curpword, $newpword);

		if ($changeresponse['success'] == 1) {
			$eLang = eFactory::getLang();
			$response['success'] = 1;
			$response['message'] = sprintf($eLang->get('PASS_CHANGED_NEWEXDATE'), $changeresponse['months']);
		} else {
			$response['message'] = $changeresponse['message'];
		}

		$encoded = json_encode($response);
		self::makeResponse($encoded);
	}


	/*****************/
	/* MAKE RESPONSE */
	/*****************/
	static private function makeResponse($response, $type='application/json') {
		if (ob_get_length() > 0) { ob_end_clean(); }
		header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
		header('Last-Modified: '.gmdate('D, d M Y H:i:s').'GMT');
		header('Cache-Control: no-cache, must-revalidate');
		header('Pragma: no-cache');
		header('Content-type: '.$type.'; charset=utf-8');
		echo $response;
		exit;
	}


	/*******************************/
	/* GET/CREATE LOGIN RETURN URL */
	/*******************************/
	static private function getReturnURL() {
		$elxis = eFactory::getElxis();
		$return = '';
		if (isset($_POST['return']) && (trim($_POST['return']) != '')) {
			$return1 = base64_decode($_POST['return']);
			$return = filter_var($return1, FILTER_SANITIZE_URL);
			if ($return != $return1) {
				$return = '';
			} else {
				if (!filter_var($return, FILTER_VALIDATE_URL)) {
					$return = '';
				} else { //no external redirection!
					$siteurl = $elxis->getConfig('URL');
					if (strpos($return, $siteurl) === false) {
						$siteurlssl = eFactory::getURI()->secureBase(true);
						if (strpos($return, $siteurlssl) === false) {
							$return = '';
						}
					}
				}
			}
		}

		if ($return == '') { $return = $elxis->makeAURL('', '', true); }
		return $return;
	}

	
	/***************************/
	/* GET ELXIS CONFIGURATION */
	/***************************/
	static private function getElxisConfig() {
		if (!class_exists('elxisConfig', false)) {
			elxisLoader::loadFile('configuration.php');
		}
		$cfg = new elxisConfig();
		return $cfg;
	}


	/*******************/
	/* GET FAVICON URL */
	/*******************/
	static private function getFavicon($seclink='') {
		if (file_exists(ELXIS_PATH.'/favicon.ico')) {
			$favicon = 'favicon.ico';
		} elseif (file_exists(ELXIS_PATH.'/favicon.png')) {
			$favicon = 'favicon.png';
		} elseif (file_exists(ELXIS_PATH.'/media/images/favicon.ico')) {
			$favicon = 'media/images/favicon.ico';
		} elseif (file_exists(ELXIS_PATH.'/media/images/favicon.png')) {
			$favicon = 'media/images/favicon.png';
		} else {
			return '';
		}

		if ($seclink != '') {
			return $seclink.'/'.$favicon;
		} else {
			return eFactory::getElxis()->secureBase().'/'.$favicon;
		}
	}

}

?>