<?php
/*
	DevSaver Web Framework
	Copyright (c) 2002-2018 DevSaver. 
	All rights reserved.
		web:  www.devsaver.com
		mail: support@devsaver.com
*/

if (!defined("STPBase")) {
	die("This file can't be accessed directly!");
}
// dependencies

/**
* description
*
* @library	
* @author	
* @since	
*/
class CAuth extends CAuthBackend{

	/**
	* description
	*
	* @var type
	*
	* @access type
	*/


	var $messages = array(
		"reset_success"		=> array(
			"title"	=> "Success",
			"text"	=> "Email successfully sent!",
		),

		"reset_error"		=> array(
			"title"	=> "Error",
			"text"	=> "Invalid username or email address!",
		),

		"reset_suspended"	=> array(
			"title"	=> "Error",
			"text"	=> "This user account is suspended!",
		),

		"login_success"		=> array(
			"title"	=> "Success",
			"text"	=> "Logging in...",
		),

		"login_invalid"		=> array(
			"title"	=> "Error",
			"text"	=> "Invalid login credentials!",
		),

		"login_suspended"	=> array(
			"title"	=> "Error",
			"text"	=> "This user account is suspended!",
		),

		"login_block"	=> array(
			"title"	=> "Error",
			"text"	=> "This account is blocked: {TIME}!",
		),

		"login_password"	=> array(
			"title"	=> "Error",
			"text"	=> "Invalid login credentials!",//"Invalid password! Also, note that the field is case-sensitive.",
		),

		"captcha"			=> array(
			"title"	=> "Error",
			"text"	=> "captcha:Invalid security code!"
		),

		"error_mail"		=> array(
			"title"	=> "Error",
			"text"	=> "Error sending mail with reset instructions. There was a problem on your server, please contact us at <a hrer='mailto:support@devsaver.com'>support@devsaver.com</a> for assitance."
		),

		"error_mailer"		=> array(
			"title"	=> "Error",
			"text"	=> "There is no mailing library installed. Please contact us at <a hrer='mailto:support@devsaver.com'>support@devsaver.com</a> for assitance."
		),


	);
	
	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function __construct() {
		//parent::CModule("auth");
	}

	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function DoEvents() {
		global $_CONF, $base , $_TSM , $_USER , $_SESS , $_PAGE;

		parent::DoEvents();

		if ($_GET["mod"] == "auth") {	

			$this->__init();
		
			switch ($_GET["sub"]) {

				case "landing":
					if ($_COOKIE["autologin"] == "true") {
						$this->AutoLogin();
					}

				break;

				case "login":
					return $this->LoginUser();
				break;

				case "recover":
					return $this->ResetPassword();
				break;

				case "verify":
					return $this->ResetVerify();
				break;
	#LOGOUT
				case "logout":
					unset($_SESS["minibase"]);
					if (isset($_USER)) {
						unset($_USER);
					}

					//remove the cookie
					setcookie("autologin", "", time() - 3600);  
					setcookie("username", "", time() - 3600);  
					setcookie("keycode" , "" , time() - 3600);

					header("Location: index.php");
					exit;
				break;

	#USERS MANAGEMENT


			}
		}		
	}	



	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function LoginUser() {

		$username = $_POST["username"];
		$pass = $_POST["password"];
		$code = $_POST["image_code"] ;


		global $_SESS , $_USER;

		if ($_SESS["minibase"]["user"]) {
			return $this->Success(
				"login_success",
				$_POST["redirect"] ? $_POST["redirect"] : "index.php"
			);
		}
		

		//read the user
		$user = $this->db->QFetchArray("
			SELECT 
				* 
			FROM 
				{$this->private->tables[users]} 
			WHERE 
				(`user_login`='%s' AND user_login !='') OR 
				(user_email='%s' AND user_email!= '') 
			", 
			array(
				$username , 
				$username
			)
		);

		if ((max($user["user_log_tries"],$_SESS["minibase"]["tries"]) >= 3) && (!$code)) {
			return $this->Error("captcha");
		}

		if ($code && ($_SESS["XML_verify_keylogin"] != $code)) {		
			return $this->Error("captcha");
		}

		//reset the captcha
		$_SESS["XML_verify_keylogin"] = "invalidate";

		if ($user["user_block"] > time()) {

			return $this->error(
				"login_block",
				$this->messages["login_block"]["title"],
				CTemplateStatic::Replace(
					$this->messages["login_block"]["text"],
					array(
						"time"	=> CDate::Friendly($user["user_block"])
					)
				)
			);
		}
		


		$_SESS["minibase"]["tries"] ++;

		if (!is_array($user)) 
			return $this->Error("login_invalid");

		//update the tries
		$this->db->QueryUpdate(
			$this->private->tables["users"],
			array(
				"user_log_tries" => $user["user_log_tries"] + 1,
				"user_block"	 => $user["user_log_tries"] > 5 ? time() + 3600 : $user["user_block"],
			),
			"user_id={$user[user_id]}"
		);

		//check for user status
		if (!$user["user_status"]) {
			return $this->Error("login_suspended");
		}

		//check for the password
		if ($user["user_password"] != md5($pass))
			return $this->Error("login_password");


		if ($_POST["remember"]) {
			$this->GenerateAutoLogin($user);
		}

		//reset the tries and save the last login info
		$this->db->QueryUpdate(
			$this->private->tables["users"],
			array(
				"user_log_tries" => 0,
				"user_log_last_login" => time(),
				"user_log_last_ip" => $_SERVER["REMOTE_ADDR"]
			),
			"user_id={$user[user_id]}"
		);

		$user["acl"] = $this->readUserAcl($user);

		$_SESS["minibase"]["tries"] = 0;
		$_SESS["minibase"]["user"] = 1;
		$_SESS["minibase"]["raw"] = $user;

		$_USER = $user;


		//record login
		if ($_SESS["minibase"]["raw"]["acl"] != "viewonly") {
			$this->db->QueryInsert(
				$this->tables['users_logins'],
				array(
					"login_uid"			=> $user["user_id"],
					"login_date"		=> time(),

					"log_ip"			=> $_SERVER["REMOTE_ADDR"],
					"log_domain"		=> $_SERVER["REMOTE_HOST"],
					"log_agent"			=> $_SERVER["HTTP_USER_AGENT"],
				)
			);

		}

		return $this->Success("login_success",$_POST["redirect"] ? $_POST["redirect"] : "index.php");

	}
	


	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function Error($error , $title = null , $message = null) {

		if (!$title) {
			$title = $this->messages[$error]["title"];
		}
		
		if (!$message) {
			$message = $this->messages[$error]["text"];
		}
		

		return $this->private->templates["error"]->blockReplace(
			"Error",
			array(
				"title"		=> $title , 
				"message"	=> $message
			)
		);
	}
	

	function Success($error , $link = null) {

		$title = $this->messages[$error]["title"];
		$message = $this->messages[$error]["text"];

		return $this->private->templates["error"]->blockReplace(
			"Success",
			array(
				"title"		=> $title , 
				"message"	=> $message ,
				"redirect"		=> $link != null ? $this->private->templates["error"]->BlockReplace("Link" , array("link" => $link)) : "",
			)
		);
	}


	function __init() {
		global $_CONF;

		if ($this->__inited) {
			return "";
		}

		$this->__inited = true;
		
		$path = $this->tpl_path;

		$templates = array(
			"error"		=> "error.htm",
			"mail"		=> "mail.htm",
		);

		foreach ($templates as $key => $val) {
			$this->private->templates[$key] = new CTemplateDynamic(
				$path . $val
			);
		}

		$this->tpl_module = array(
			"mod_name"	=> "Admin Panel Users",
		);
	} 



	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function ResetPassword() {
		global $_MODULES;

	

		if (is_array($user = $this->db->QFetchArray("SELECT * FROM {$this->private->tables[users]} WHERE user_email LIKE '{$_POST[username]}' OR user_login like '{$_POST[username]}'"))) {

			if ($user["user_log_status"]) {
				return $this->Error("reset_suspended");
			}
			


			//geenrate the key 
			$key = strtoupper(md5($user["user_login"] . time())) ;
			$user["user_key"] = $key;

			$url = 	dirname((strtoupper($_SERVER["HTTPS"]) == "on" ? "https://" :  "http://") . 
				$_SERVER["HTTP_HOST"] . 
//				($_SERVER["SERVER_PORT"] != 80 ? ':' . $_SERVER["SERVER_PORT"] : '') .
				$_SERVER["SCRIPT_NAME"] ) . "/";	

			$user["user_link"] = $url;

			$this->db->QueryUpdate(
				$this->private->tables["users"],
				array(
					"user_key"		=> $key,
					"user_key_date"	=> time(),
				),
				"user_id={$user[user_id]}"
			);

			//use basic mail 
			$this->SendMail(
				array(
					"email_to" => $user["user_email"],
					"email_to_name" => $user["user_first_name"] . " " . $user["user_last_name"],

					"email_from_name" => "DevSaver Support", 
					"email_from" => "support@devsaver.com", 

					"email_subject" => "Password Recovery Instructions",

					"email_body" => $this->private->templates["mail"]->blockReplace("Recover" , $user),
				),
				$user						
			);

			return $this->Success("reset_success");
		} else {
			return $this->Error("reset_error");
		}
	}

	
	/**
	* description
	*
	* @param
	*
	* @return
	*
	* @access
	*/
	function ResetVerify() {
		global $_SESS;


		if (!$_GET["key"]) {
			urlredirect("index.php?mod=auth");
		}


		if (is_array($user = $this->db->QFetchArray("SELECT * FROM {$this->private->tables[users]} WHERE user_key LIKE '{$_GET[key]}' AND !user_log_status "))) {

			$url = 	dirname((strtoupper($_SERVER["HTTPS"]) == "on" ? "https://" :  "http://") . 
				$_SERVER["HTTP_HOST"] . 
//				($_SERVER["SERVER_PORT"] != 80 ? ':' . $_SERVER["SERVER_PORT"] : '') .
				$_SERVER["SCRIPT_NAME"] ) . "/";	

			$user["user_link"] = $url;
			//$user["pass"] = RandomWord(6);

			//reset the key
			$this->db->QueryUpdate(
				$this->private->tables["users"],
				array(
					"user_key"			=> "",
					"user_log_tries"	=> 0,
					"user_block"		=> 0,
				),
				"user_id={$user[user_id]}"
			);

			$user["acl"] = $this->readUserAcl($user);

			$_SESS["minibase"]["user"] = 1;
			$_SESS["minibase"]["raw"] = $user;
			$_SESS["minibase"]["newpass"] = 1;


			urlredirect("index.php?mod=administrators&sub=users&action=edit&user_id={$user[user_id]}&returnurl=" . 
				urlencode("index.php?mod=administrators&sub=myprofile")
			);
		} else {
			urlredirect("index.php?mod=auth");
		}
	}

	function SendMail() {
		global $_CONF;


		$params = AStripSlashes(func_get_args());	
		//check to see the numbers of the arguments

		//debug($params);

		switch (func_num_args()) {
			case 1:
				$email = $params[0];
				$vars = array();
			break;

			case 2:
				$email = $params[0];
				$vars = $params[1];
			break;

			case 3:
				$to = $params[0];
				$email = $params[1];
				$vars = $params[2];
			break;

			case 4:
				$to = $params[0];
				$to_name = $params[1];
				$email = $params[2];
				$vars = $params[3];
			break;
		}

		if (isset($email["email_status"]) && !$email["email_status"]) {
			return false;
		}

		//this check its for templates, in case was sent an empty or disabled email template
		if (!($email["email_to"] && $email["email_from"])) {
			return false;
		}

		global $_CONF;

		$vars["site:url"] = $_CONF["url"];
			
				
		$msg = new CTemplate(stripslashes($email["email_body"]) , "string");
		$msg = $msg->Replace($vars);

	
		if (!stristr($msg , "<html")) {
			//add full html page, will help with spam filters
			$msg = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>' . $msg . '</body></html>';
		}
		

		if ($email["email_body_text"]) {
			$msg_text = new CTemplate(stripslashes($email["email_body_text"]) , "string");
			$msg_text = $msg_text->Replace($vars);
		}
		

		$sub = new CTemplate(stripslashes($email["email_subject"]) , "string");
		$sub = $sub->Replace($vars);

		$email["email_from"] = new CTemplate(stripslashes($email["email_from"]) , "string");
		$email["email_from"] = $email["email_from"]->Replace($vars);

		$email["email_from_name"] = new CTemplate(stripslashes($email["email_from_name"]) , "string");
		$email["email_from_name"] = $email["email_from_name"]->Replace($vars);

		if (!$email["email_reply"]) 
			$email["email_reply"] = $email["email_from"];
		if (!$email["email_reply_name"]) 
			$email["email_reply_name"] = $email["email_from_name"];



		if (stristr($email["email_to"] , ",")) {
			$rec = explode("," , $email["email_to"]);

			foreach ($rec as $key => $val) {
				if (trim($val)) {
					$recipients[$val] = $email["email_to_name"] ? $email["email_to_name"] : $val;
				}					
			}				
		} else {
			$recipients = array($email["email_to"] => $email["email_to_name"] ? $email["email_to_name"] : $email["email_to"]);	
		}

		$from = array($email["email_from"] => $email["email_from_name"] ? $email["email_from_name"] : $email["email_from"]);	
		$body = $msg;
		$subject = $sub;
	
		//initialize the mail sending

		if (External::Load("swiftmailer")) {
				$transport = Swift_MailTransport::newInstance();
				$message = Swift_Message::newInstance($subject)
					->setFrom($from)
					->setTo($recipients)
					->setBody(
						$body , 
						"text/html",
						'utf-8'
					);

				//try sending the mail
				try {
					
					$mailer = Swift_Mailer::newInstance($transport);
					$result = $mailer->send($message);

				} catch( Exception $e ){
					echo  $this->Error("error_mail");
					die();
				}

		} elseif (External::Load("phpmailer")) {
				$mail = new PHPMailer;

				$mail->From = $email["email_from"];

				if ($email["email_from_name"]) {
					$mail->FromName = $email["email_from_name"];
				}

				foreach ($recipients as $key => $val) {
					$mail->addAddress($key, $val);     // Add a recipient
				}

				$mail->isHTML(true);                                  // Set email format to HTML

				$mail->Subject = $subject;
				$mail->Body    = $body;
				$mail->AltBody = $msg_text;

				if (!$mail->send()) {
					echo $this->Error("error_mail");
					die();
				}
		} else {
			echo $this->Error("error_mailer");
			die();
		}
	}
}
