<?php
# WebLogin 3.1
# for EVO CMS 3.x
# german translated version
#
# Created By Raymond Irving 2004
# Modfied for EVO CMS 3.x by info@b-4-u.de 2021-2023
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

defined('IN_PARSER_MODE') or die();

# process account activation
	if ($isACTActivate==1) {
		$id = $_REQUEST['wli'];
		$actkey = $_REQUEST['wla'];

		$ds = $modx->db->select('*', $modx->getFullTableName('users'), "id='".$modx->db->escape($id)."'");
		if($row = $modx->db->getRow($ds)) {
			$username = $row["username"];
			if($actkey!=$row['verified_key']) {
				$output = webLoginAlert(utf8_encode("Der Aktivierungsschlüssel ist ungültig! Das Benutzerkonto konnte nicht aktiviert werden!"));
				return;
			}

		// activate user account
		$modx->db->update(
			array(
				'verified' => '1',
				),
			$modx->getFullTableName('user_attributes'),
			"internalKey='{$row['id']}'"
			);

		if(!$pwdActId) $output = webLoginAlert("Das Konto wurde aktiviert!");
			else {
				// redirect to password activation notification page
				$url = $modx->makeURL($pwdActId);
				$modx->sendRedirect($url,0,'REDIRECT_REFRESH');
			}
		}
		else {
			// error
			$output = webLoginAlert(utf8_encode("Während der Aktivierung des Kontos ist ein Fehler aufgetreten!"));
		}
		return;
	}


# process password activation
	if ($isPWDActivate==1) {
		$id = $_REQUEST['wli'];
		$pwdkey = $_REQUEST['wlk'];

		$ds = $modx->db->select('*', $modx->getFullTableName('users'), "id='".$modx->db->escape($id)."'");
		if($row = $modx->db->getRow($ds)) {
			$username = $row["username"];
			list($newpwd,$newpwdkey) = explode("|",$row['cachepwd']);
			if($newpwdkey!=$pwdkey) {
				$output = webLoginAlert(utf8_encode("Der Aktivierungsschlüssel ist ungültig! Das Benutzerkonto konnte nicht aktiviert werden! Versuchen Sie es erneut oder registrieren Sie sich mit einer anderen E-Mail-Adresse."));
				return;
			}
			// activate new password
			$modx->db->update(
				array(
					'password' => md5($newpwd),
					'cachepwd' => ''
					),
				$modx->getFullTableName('users'),
				"id='{$row['id']}'"
				);

			// unlock user by verify
			$modx->db->update(
				array(
					'verified' => '1'
					),
				$modx->getFullTableName('user_attributes'),
				"internalKey='{$row['id']}'"
				);

			// unblock user by resetting "blockeduntil"
			$modx->db->update(
				array(
					'blockeduntil' => 0,
					),
				$modx->getFullTableName('user_attributes'),
				"internalKey='{$row['id']}'"
				);

			// invoke OnWebChangePassword event
			$modx->invokeEvent("OnWebChangePassword",
				array(
					"userid"		=> $id,
					"username"		=> $username,
					"userpassword"	=> $newpwd
			));

			if(!$pwdActId) $output = webLoginAlert("Das neue Kennwort wurde aktiviert!");
			else {
				// redirect to password activation notification page
				$url = $modx->makeURL($pwdActId);
				$modx->sendRedirect($url,0,'REDIRECT_REFRESH');
			}
		}
		else {
			// error
			$output = webLoginAlert(utf8_encode("Während der Aktivierung des neuen Kennworts ist ein Fehler aufgetreten!"));
		}
		return;
	}


# process password reminder
	if ($isPWDReminder==1) {
		$email = $_POST['txtwebemail'];
		$webpwdreminder_message = $modx->config['webpwdreminder_message'];
		$emailsubject = $modx->config['emailsubject'];
		$emailsender = $modx->config['emailsender'];
		$site_name = $modx->config['site_name'];

		// lookup account
		$ds = $modx->db->select(
			'wu.*, wua.fullname',
			$modx->getFullTableName('users')." AS wu INNER JOIN ".$modx->getFullTableName('user_attributes')." AS wua ON wua.internalkey=wu.id",
			"wua.email='".$modx->db->escape($email)."'");
			if($row = $modx->db->getRow($ds)) {
			$newpwd = webLoginGeneratePassword(8);
			$newpwdkey = webLoginGeneratePassword(8); // activation key

			//save new password
			$modx->db->update(
				array(
					'cachepwd' => "{$newpwd}|{$newpwdkey}",
					),
				$modx->getFullTableName('users'),
				"id='{$row['id']}'"
				);

			// built activation url
			$xhtmlUrlSetting = $modx->config['xhtml_urls'];
			$modx->config['xhtml_urls'] = false;
			if($_SERVER['SERVER_PORT']!='80') {
				$url = $modx->config['server_protocol'].'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$modx->makeURL($modx->documentIdentifier,'',"webloginmode=actp&wli=".$row['id']."&wlk=".$newpwdkey);
			} else {
				$url = $modx->config['server_protocol'].'://'.$_SERVER['SERVER_NAME'].$modx->makeURL($modx->documentIdentifier,'',"webloginmode=actp&wli=".$row['id']."&wlk=".$newpwdkey);
			}
			$modx->config['xhtml_urls'] = $xhtmlUrlSetting;

			// replace placeholders and send email
			$message = str_replace("[+uid+]",$row['username'],$webpwdreminder_message);
			$message = str_replace("[+pwd+]",$newpwd,$message);
			$message = str_replace("[+ufn+]",$row['fullname'],$message);
			$message = str_replace("[+sname+]",$site_name,$message);
			$message = str_replace("[+semail+]",$emailsender,$message);
			$message = str_replace("[+surl+]",$url,$message);

			// fix charset problems
			$message = utf8_decode($message);

			// send mail
			if (!ini_get('safe_mode'))
				$sent = mail($email, "$site_name - Aktivierungs-Kennwort", $message, "From: ".$emailsender."\r\n"."X-Mailer: MODx Content Manager - PHP/".phpversion(), "-f {$emailsender}");
			else
				$sent = mail($email, "$site_name - Aktivierungs-Kennwort", $message, "From: ".$emailsender."\r\n"."X-Mailer: MODx Content Manager - PHP/".phpversion());

			if(!$sent) {
				// error
				$output = webLoginAlert(utf8_encode("E-Mail konnte nicht an $email gesendet werden!"));
				return;
			}

			if(!$pwdReqId) $output = webLoginAlert(utf8_encode("Eine Aktivierungs-E-Mail wurde an $email gesandt."));
			else {
				// redirect to password request notification page
				$url = $modx->makeURL($pwdReqId);
				$modx->sendRedirect($url,0,'REDIRECT_REFRESH');
			}
		}
		else {
			$output = webLoginAlert(utf8_encode("Der Server hat die E-Mail-Adresse zurückgewiesen!"));
		}
		return;
	}


# process logout
	if ($isLogOut==1){
		$internalKey = $_SESSION['webInternalKey'];
		$username = $_SESSION['webShortname'];

		// invoke OnBeforeWebLogout event
		$modx->invokeEvent("OnBeforeWebLogout",
								array(
									"userid"   => $internalKey,
									"username" => $username
								));

		clearWebuserSession();

		// invoke OnWebLogout event
		$modx->invokeEvent("OnWebLogout",
								array(
									"userid"	=> $internalKey,
									"username"	=> $username
								));

		// redirect to first authorized logout page
		$url = preserveUrl($loHomeId);
		$modx->sendRedirect($url,0,'REDIRECT_REFRESH');
		return;
	}


# process login
	$username = $modx->db->escape(htmlspecialchars($_POST['username'], ENT_NOQUOTES, $modx->config['modx_charset']));
	$givenPassword = htmlspecialchars($_POST['password'], ENT_NOQUOTES, $modx->config['modx_charset']);
	$captcha_code = isset($_POST['captcha_code'])? $_POST['captcha_code']: '';
	$rememberme = $_POST['rememberme'];

	// invoke OnBeforeWebLogin event
	$modx->invokeEvent("OnBeforeWebLogin",
							array(
								"username"		=> $username,
								"userpassword"	=> $givenPassword,
								"rememberme"	=> $rememberme
							));

	$ds = $modx->db->select(
		'wu.*, wua.*',
		$modx->getFullTableName('users')." AS wu, ".$modx->getFullTableName('user_attributes')." AS wua",
		"BINARY wu.username='{$username}' AND wua.internalKey=wu.id");
	$row = $modx->db->getRow($ds);

	if(!$row) {
		$output = webLoginAlert(utf8_encode("Der Benutzername ist unbekannt oder das Kennwort stimmt nicht!"));
		return;
	}

	if ((isset($row['verified'])) and ($row['verified'] == '0')) {
		$output = webLoginAlert(utf8_encode("Das Benutzerkonto ist nicht aktiviert! Aktivieren Sie das Konto über die Aktivierungs-E-Mail oder wenden Sie sich an den Website-Administrator!"));
		return;
	}

	$internalKey			= $row['internalKey'];
	$dbasePassword			= $row['password'];
	$failedlogins			= $row['failedlogincount'];
	$blocked				= $row['blocked'];
	$blockeduntildate		= $row['blockeduntil'];
	$blockedafterdate		= $row['blockedafter'];
	$registeredsessionid	= $row['sessionid'];
	$role					= $row['role'];
	$lastlogin				= $row['lastlogin'];
	$nrlogins				= $row['logincount'];
	$fullname				= $row['fullname'];
	$email					= $row['email'];

	// load user settings
	if($internalKey){
		$result = $modx->db->select('setting_name, setting_value', $modx->getFullTableName('user_settings'), "user='{$internalKey}'");
		while ($row = $modx->db->getRow($result)) {
			$modx->config[$row['setting_name']] = $row['setting_value'];
		}
	}

	if($failedlogins>=$modx->config['failed_login_attempts'] && $blockeduntildate>time()) {	// blocked due to number of login errors.
		clearWebuserSession();
		$output = webLoginAlert(utf8_encode("Die maximale Anzahl der Anmeldeversuche wurde erreicht! Aus Sicherheitsgründen wurde das Konto gesperrt!"));
		return;
	}

	if($failedlogins>=$modx->config['failed_login_attempts'] && $blockeduntildate<time()) {	// blocked due to number of login errors, but get to try again
		$modx->db->update(
			array(
				'failedlogincount' => 0,
				'blockeduntil' => (time()-1),
				),
			$modx->getFullTableName('user_attributes'),
			"internalKey='{$internalKey}'"
			);
	}

	if($blocked=="1") { // this user has been blocked by an admin, so no way he's loggin in!
		clearWebuserSession();
		$output = webLoginAlert(utf8_encode("Die Anmeldung ist nicht möglich! Das Konto wurde gesperrt!"));
		return;
	}

	// blockuntil
	if($blockeduntildate>time()) { // this user has a block until date
		clearWebuserSession();
		$output = webLoginAlert(utf8_encode("Die Anmeldung ist nicht möglich! Das Konto wurde gesperrt bis ". date('d.m.y H:i', $blockeduntildate)."!"));
		return;
	}

	// blockafter
	if($blockedafterdate>0 && $blockedafterdate<time()) { // this user has a block after date
		clearWebuserSession();
		$output = webLoginAlert(utf8_encode("Die Anmeldung ist nicht möglich! Das Konto ist dauerhaft gesperrt seit ". date('d.m.y H:i', $blockedafterdate)."!"));
		return;
	}

	// allowed ip
	if (isset($modx->config['allowed_ip'])) {
		if (strpos($modx->config['allowed_ip'],$_SERVER['REMOTE_ADDR'])===false) {
			$output = webLoginAlert(utf8_encode("Aus Sicherheitsgründen ist eine Anmeldung vom aktuellen Computernetzwerk aus nicht möglich!"));
			return;
		}
	}

	// allowed days
	if (isset($modx->config['allowed_days'])) {
		$date = getdate();
		$day = $date['wday']+1;
		if (strpos($modx->config['allowed_days'],"$day")===false) {
			$output = webLoginAlert(utf8_encode("Die Anmeldung ist heute nicht möglich. Für dieses Konto wurde eine Tagessperre gesetzt. Melden Sie sich morgen wieder an oder wenden Sie sich an den Administrator, um die Tagessperre zu ändern!"));
			return;
		}
	}

	// invoke OnWebAuthentication event
	$rt = $modx->invokeEvent("OnWebAuthentication",
							array(
								"userid"		=> $internalKey,
								"username"	 	=> $username,
								"userpassword"	=> $givenPassword,
								"savedpassword"	=> $dbasePassword,
								"rememberme"	=> $rememberme
							));

	// check if plugin authenticated the user
	if (!$rt||(is_array($rt) && !in_array(TRUE,$rt))) {
		// check user password - local authentication
		$userData = array(
			'username'	  => $username,
			'password'	  => $givenPassword,
			'rememberme'	=> $rememberme
		);

		try {
			$modx->UserManager->login($userData);
		} catch (Exception $e) {
			$output = webLoginAlert(utf8_encode('Der eingegebene Benutzername oder das Kennwort stimmt nicht!'));
			$newloginerror = 1;
		}	
	}

	if(isset($modx->config['use_captcha']) && $modx->config['use_captcha']==1 && isset($_POST['cmdwebsignup'])) {
		if($_SESSION['veriword']!=$captcha_code) {
			$output = webLoginAlert("Falscher Sicherheitscode! Geben Sie den angezeigten Sicherheitscode neu ein!");
			$newloginerror = 1;
		}
	}

	if(isset($newloginerror) && $newloginerror==1) {
		$failedlogins += $newloginerror;
		if($failedlogins>=$modx->config['failed_login_attempts']) { //increment the failed login counter, and block until!
			$modx->db->update(
				array(
					'failedlogincount' => $failedlogins,
					'blockeduntil'	 => (time()+($modx->config['blocked_minutes']*60)),
					),
				$modx->getFullTableName('user_attributes'),
				"internalKey='{$internalKey}'"
				);
		} else { //increment the failed login counter
			$modx->db->update(
				array(
					'failedlogincount' => $failedlogins,
					),
				$modx->getFullTableName('user_attributes'),
				"internalKey='{$internalKey}'"
				);
		}
		clearWebuserSession();
		return;
	}

	$currentsessionid = session_id();

	if(!isset($_SESSION['webValidated'])) {
		$modx->db->update(
			"failedlogincount=0, logincount=logincount+1, lastlogin=thislogin, thislogin=".time().", sessionid='{$currentsessionid}'",
			$modx->getFullTableName('user_attributes'),
			"internalKey='{$internalKey}'"
			);
	}

	$_SESSION['webShortname']=$username;
	$_SESSION['webFullname']=$fullname;
	$_SESSION['webEmail']=$email;
	$_SESSION['webValidated']=1;
	$_SESSION['webInternalKey']=$internalKey;
	$_SESSION['webValid']=base64_encode($givenPassword);
	$_SESSION['webUser']=base64_encode($username);
	$_SESSION['webFailedlogins']=$failedlogins;
	$_SESSION['webLastlogin']=$lastlogin;
	$_SESSION['webnrlogins']=$nrlogins;
	$_SESSION['webUserGroupNames'] = ''; // reset user group names

	// get user's document groups
	$ds = $modx->db->select(
		'dg.document_group AS documentgroup',
		"(".$modx->getFullTableName('member_groups')." AS mg INNER JOIN ".$modx->getFullTableName('membergroup_access')." AS mga ON mg.user_group = mga.membergroup) INNER JOIN ".$modx->getFullTableName('document_groups')." AS dg ON mga.documentgroup = dg.document_group",
		"mg.member = '{$internalKey}' GROUP BY documentgroup"
	);

	$_SESSION['webDocgroups'] = $modx->db->getColumn('documentgroup', $ds);	

	$ds = $modx->db->select(
		'dgn.name',
		"(".$modx->getFullTableName('member_groups')." AS mg INNER JOIN ".$modx->getFullTableName('membergroup_access')." AS mga ON mg.user_group = mga.membergroup) INNER JOIN ".$modx->getFullTableName('documentgroup_names')." AS dgn ON mga.documentgroup = dgn.id",
		"mg.member = '{$internalKey}'"
	);

	$_SESSION['webUserGroupNames']= $this->db->getColumn('name', $ds); 

	if($rememberme) {
		$_SESSION['modx.web.session.cookie.lifetime']= intval($modx->config['session.cookie.lifetime']);
	} else {
		$_SESSION['modx.web.session.cookie.lifetime']= 0;
	}

	$log = new logHandler;
	$log->initAndWriteLog("Logged in", $_SESSION['webInternalKey'], $_SESSION['webShortname'], "58", "-", "WebLogin");

	// get login home page
	$ok=false;
	if(isset($modx->config['login_home']) && $id=$modx->config['login_home']) {
		if ($modx->getPageInfo($id)) $ok = true;
	}
	if (!$ok) {
		// check if a login home id page was set
		foreach($liHomeId as $id) {
			$id = trim($id);
			if ($modx->getPageInfo($id)) {
				$ok=true;
				break;
			}
		}
	}

	// update active users list if redirectinq to another page
	if($id!=$modx->documentIdentifier) {
		$itemid = isset($_REQUEST['id']) ? $_REQUEST['id'] : 'NULL' ;
		$lasthittime = $modx->time;
		$a = 998;

		// web users are stored with negative id
		$sql = "REPLACE INTO ".$modx->getFullTableName('active_users')." (internalKey, username, lasthit, action, id) values(-{$_SESSION['webInternalKey']}, '{$_SESSION['webShortname']}', '{$lasthittime}', '{$a}', {$itemid})";
		$modx->db->query($sql);

		$modx->updateValidatedUserSession();
	}

	// invoke OnWebLogin event
	$modx->invokeEvent("OnWebLogin",
							array(
								"userid"		=> $internalKey,
								"username"		=> $username,
								"userpassword"	=> $givenPassword,
								"rememberme"	=> $_POST['rememberme']
							));

	// redirect
	if(isset($_REQUEST['refurl']) && !empty($_REQUEST['refurl'])) {
		// last accessed page
		$targetPageId= urldecode($_REQUEST['refurl']);
		if (strpos($targetPageId, 'q=') !== false) {
			$urlPos = strpos($targetPageId, 'q=')+2;
			$alias = substr($targetPageId, $urlPos);
			$aliasLength = (strpos($alias, '&'))? strpos($alias, '&'): strlen($alias);
			$alias = substr($alias, 0, $aliasLength);
			$url = $modx->config['base_url'] . $alias;
		} elseif (intval($targetPageId)) {
			$url = preserveUrl($targetPageId);
		} else {
			$url = urldecode($_REQUEST['refurl']);
		}
		$modx->sendRedirect($url);
	}
	else {
		// login home page
		$url = preserveUrl($id);
		$modx->sendRedirect($url);
	}

	return;

	function clearWebuserSession() {
		// if we were launched from the manager
		// do NOT destroy session
		if (isset($_SESSION['mgrValidated'])) {
			unset($_SESSION['webShortname']);
			unset($_SESSION['webFullname']);
			unset($_SESSION['webEmail']);
			unset($_SESSION['webValidated']);
			unset($_SESSION['webInternalKey']);
			unset($_SESSION['webValid']);
			unset($_SESSION['webUser']);
			unset($_SESSION['webFailedlogins']);
			unset($_SESSION['webLastlogin']);
			unset($_SESSION['webnrlogins']);
			unset($_SESSION['webUsrConfigSet']);
			unset($_SESSION['webUserGroupNames']);
			unset($_SESSION['webDocgroups']);
			unset($_SESSION['webDocgrpNames']);
		}
		else {
			// Unset all of the session variables.
			// destroy session cookie
			if (isset($_COOKIE[session_name()])) {
				setcookie(session_name(), '', 0, MODX_BASE_URL);
			}
			session_destroy();
		}
	}
?>