<?php
/**************************************************************************************************
| Ionicware
| http://www.ionicware.com
| support@ionicware.com
|
|**************************************************************************************************
|
| Copyright (c) 2011 ionicware.com. All rights reserved.
|**************************************************************************************************/

include("include/config.php");
include("include/functions/import.php");
include("include/functions/cloudflare_wrapper.php");
$thebaseurl = $config['baseurl'];

$r = cleanit((is_array($_REQUEST['r']) ? null : stripslashes($_REQUEST['r']))); // ?x[]=: as on 7.4, not a TypeError (#1925)

/*
 * We need to test the base 64 to make
 * sure it is not redirecting offsite.
 * 12/22/2014
 */
$redirectUrl = base64_decode($r);
if (stristr($redirectUrl, '<') || stristr($redirectUrl, '>') || stristr($redirectUrl, "'") || stristr($redirectUrl, '"'))
{
	$r 				= '';
	$_REQUEST['r'] 	= '';
}


if ($config['baseurl'] == 'https://www.seoclerk.com')
{
	$baseurl2 = 'https://www.seoclerks.com';
}
else
{
	$baseurl2 = $config['baseurl'];
}

/*
 * Get the total amount of times this
 * IP has attempted to login
 * 12/23/2015
 */
$totalFailed 			= !empty($_POST['passkey_login_action']) ? 0 : CountBotLoginAttempts(43200); // 43200 = 12 hours

if (!empty($_POST['passkey_login_action']))
{
	$passkeyLoginAction = (string) $_POST['passkey_login_action'];
	try
	{
		if (!empty($_SESSION['USERID']) || !empty($_SESSION['ADMINID']) || !empty($_SESSION['ADMINUSERLOGIN']))
			passkeyJsonResponse(array('ok' => false, 'error' => 'Sign out before using another passkey.'), 409);
		if (!passkeysEnabled()) passkeyJsonResponse(array('ok' => false, 'error' => 'Passkey login is unavailable.'), 503);
		if (!CSFRRequestCheckNoUser()) passkeyJsonResponse(array('ok' => false, 'error' => $lang[2768]), 403);
		if (passkeyLoginFailedIpAttempts(43200) >= $config['botBruteLoginBan'] || passkeyLoginAssertionRateLimited(false))
			passkeyJsonResponse(array('ok' => false, 'error' => 'Too many login attempts. Please wait and try again.'), 429);
		if ($passkeyLoginAction === 'options')
			passkeyJsonResponse(array('ok' => true, 'options' => passkeyLoginOptions()));
		if ($passkeyLoginAction === 'finish')
		{
			$payload = json_decode(isset($_POST['payload']) ? $_POST['payload'] : '', true);
			$USERID = passkeyFinishPrimaryLogin($payload);
			$member = passkeyLoadLoginMember($USERID);
			passkeyEstablishLoginSession($member, !empty($_POST['remember']));
			// The JSON body makes shutdown too late to emit the edge auth cookie.
			syncAuthStateCookie();
			$redirect = passkeyLoginRedirect($r);
			passkeyJsonResponse(array('ok' => true, 'redirect' => $redirect));
		}
		passkeyJsonResponse(array('ok' => false, 'error' => 'Unknown passkey login action.'), 400);
	}
	catch (Throwable $passkeyLoginError)
	{
		$passkeyLoginStatus = passkeyLoginErrorStatus($passkeyLoginError);
		if ($passkeyLoginAction === 'finish')
		{
			try { passkeyRecordPrimaryLoginFailure($passkeyLoginError); }
			catch (Throwable $passkeyFailureRecordError)
			{
				$passkeyLoginError = $passkeyFailureRecordError;
				$passkeyLoginStatus = 503;
			}
		}
		passkeyJsonResponse(array('ok' => false, 'error' => passkeyPublicError($passkeyLoginError)), $passkeyLoginStatus);
	}
}

/**
 * UPDATE - Removed this due to the new theme always displaying a captcha 5/14/2021
 */
// $totalFailedCaptcha 	= CountBotLoginAttempts(86400); // For showing a captcha, we can't to count a bit higher.  86400

/*
 * Fetch the location so we can see where the user
 * is from. Used to block bots (enabled captcha)
 * 9/14/2016
 */
$geoData 			= GetGeoData($_SERVER['REMOTE_ADDR']);
$ipCountry 	 		= utf8_encode($geoData->country->name);

/*
 * Captcha Country array
 * 9/14/2016
 */
$countryCaptchaArray = array('Russian Federation', 'Ukraine', 'Switzerland', 'Germany', 'Poland', 'Brazil', 'Bulgaria', 'Vietnam', 'Cyprus', 'Mexico');

/**
 * Check and see if the user is new and needs to check a captcha first
 * 1/29/2020 - SE
 */
//if (newIpAddress($_SERVER['REMOTE_ADDR'])) $needsCaptchaFirst = 1;

//if ($_REQUEST['submitCap'] == 1 && isCaptchaValid()) $needsCaptchaFirst = 0;

/*
 * If the user is logged in, send them to the homepage
 * 5/13/2013
 */
if ($_SESSION['USERID'] != "" && $_SESSION['USERID'] >= 0 && is_numeric($_SESSION['USERID']))
{
	if (!empty($_REQUEST['r'])) redirectAndDie('/' . decodeRedirectPath($r));
	else redirectAndDie('/marketplace');
}

if ($_REQUEST['jlog'] == 1 && !isCaptchaValid())
{
	$error .= "<li>" . $lang[2096] . "</li>";
	$_REQUEST['jlog'] = 0;
}

if($_REQUEST['jlog'] == 1 && CSFRRequestCheckNoUser() && !empty($_REQUEST['fld']))
{

	$user_username = cleanit($_REQUEST['l_username']);
	if($user_username == "")
	{
		$error = "<li>".$lang['13']."</li>";
	}

	$user_password = cleanit($_REQUEST['l_password']);
	if($user_password == "")
	{
		$error .= "<li>".$lang['17']."</li>";
	}

	/*
	 * Users are able to CSFR login
	 * remotely using other people's
	 * accounts.
	 * 4/15/2016
	 */
	if (!empty($_REQUEST['_ss']))
	{
		$_ssid 		= session_decrypt($_REQUEST['_ss']);
		$_ssarray 	= explode('::', $_ssid);

		if (is_array($_ssarray) && $_ssarray[1] == 1 && !empty($_ssarray[0]) && intval($_ssarray[2]) > 0)
		{
			$time = time() - 600; // 10 minutes
			if ($_ssarray[2] < $time)
			{
			//	$error .= "<li>".$lang['2227']."</li>";
			}
		}
		else
		{
		//	$error .= "<li>".$lang['2227']."</li>";
		}
	}
	else
	{
	//	$error .= "<li>".$lang['2227']."</li>";
	}


	/*
	 * Check the captcha
	 * 12/23/2015
	 */
	// if (($totalFailedCaptcha > 1 || in_array($ipCountry, $countryCaptchaArray)))
	// {
	if (1 == 1)
	{
		if (1 == 1) //!empty($_POST['g-recaptcha-response'])) // Modified on 1/30/2017 because it could be blank
		{
			// if (userNeedsCaptcha() && !isCaptchaValid())
			// {
			// 	$error .= "<li>" . $lang['2096'] . "</li>";

			// 	$query="SELECT status, USERID, username, afunds, funds from seoclerks.members WHERE (username='".addslashes($user_username)."'
			// 				OR email='".addslashes($user_username)."')";
			// 	$result=$conn->execute($query);

			// 	/*
			// 	 * Server Data
			// 	 */
			// 	$querystring = addslashes($_SERVER['QUERY_STRING']) . 'INVALID CAPTCHA LOGIN';
			// 	$ip			 = addslashes($_SERVER['REMOTE_ADDR']);
			// 	$agent		 = addslashes($_SERVER['HTTP_USER_AGENT']);
			// 	$script		 = addslashes($_SERVER['SCRIPT_FILENAME']);
			// 	$postdata	 = ''; //addslashes(serialize($_REQUEST));

			// 	$query = "INSERT INTO members_ledger (USERID, username, script, querystring, postdata, afunds, funds, added, ip, agent)
			// 			VALUES ( '{$result->fields['USERID']}', '{$result->fields['username']}', '{$script}', '{$querystring}', '{$postdata}', '{$result->fields['afunds']}', '{$result->fields['funds']}', UNIX_TIMESTAMP(NOW()),
			// 					'{$ip}', '{$agent}')";
			// 	//$conn->execute($query);
			// 	UpdateMembersAllSites($query, '', 'members_ledger');

			// }
		}
		else
		{
			$error .= "<li>" . $lang[2096] . "</li>";

			$query="SELECT status, USERID, username, afunds, funds from seoclerks.members WHERE (username='".addslashes($user_username)."'
							OR email='".addslashes($user_username)."')";
			$result=$conn->execute($query);

			/*
			 * Server Data
			 */
			$querystring = addslashes(ledgerQueryString('INVALID CAPTCHA LOGIN'));
			$ip			 = addslashes($_SERVER['REMOTE_ADDR']);
			$agent		 = addslashes($_SERVER['HTTP_USER_AGENT']);
			$script		 = addslashes($_SERVER['SCRIPT_FILENAME']);
			$postdata	 = ''; //addslashes(serialize($_REQUEST));

			$query = "INSERT INTO members_ledger (USERID, username, script, querystring, postdata, afunds, funds, added, ip, agent)
					VALUES ( '{$result->fields['USERID']}', '{$result->fields['username']}', '{$script}', '{$querystring}', '{$postdata}', '{$result->fields['afunds']}', '{$result->fields['funds']}', UNIX_TIMESTAMP(NOW()),
							'{$ip}', '{$agent}')";
			//$conn->execute($query);
			UpdateMembersAllSites($query, '', 'members_ledger');

		}
	}

	$l_remember_me = cleanit($_REQUEST['l_remember_me']);

	/*
	 * Is this an openid signup attempt?
	 * 8/27/2013
	 */
	$identity_id = intval(cleanit($_REQUEST['identity_id']));

	/*
	 * Have they tried to login 3 times and failed
	 * within the last 10 minutes?
	 * 8/19/2014
	 */
	 if (($_SESSION['failed_login'] >= 3 && $_SESSION['failed_time'] >= (time()-1800)) || IsAccountLoginLocked($user_username, 1800) >= 3)
	 {
		$error = $lang['2000'];

		$query="SELECT status, USERID, username, afunds, funds from seoclerks.members WHERE (username='".addslashes($user_username)."' OR email='".addslashes($user_username)."')";
		$result=$conn->execute($query);

		/*
		 * Server Data
		 */
		$querystring = addslashes(ledgerQueryString('BLOCKED LOGIN ATTEMPT - Reached 3 failed login within 1800 seconds.'));
		$ip			 = addslashes($_SERVER['REMOTE_ADDR']);
		$agent		 = addslashes($_SERVER['HTTP_USER_AGENT']);
		$script		 = addslashes($_SERVER['SCRIPT_FILENAME']);
		$postdata	 = ''; //addslashes(serialize($_REQUEST));

		$query = "INSERT INTO members_ledger (USERID, username, script, querystring, postdata, afunds, funds, added, ip, agent)
				VALUES ( '{$result->fields['USERID']}', '{$result->fields['username']}', '{$script}', '{$querystring}', '{$postdata}', '{$result->fields['afunds']}', '{$result->fields['funds']}', UNIX_TIMESTAMP(NOW()),
						'{$ip}', '{$agent}')";
		//$conn->execute($query);
		UpdateMembersAllSites($query, '', 'members_ledger');
	 }

	/*
	 * If this user is brute-force attempting to
	 * login and has more than 15 failed attempts,
	 * reject their login until 30 minutes has
	 * passed.
	 * 1800 = 30 minutes
	 * 12/17/2015
	 */
	//$totalFailed 	= CountBotLoginAttempts(); // Made redundant as it is counted at top.

	if ($totalFailed >= $config['botBruteLoginBan'])
	{
		$error 	= $lang['42'];

		$query="SELECT status, USERID, username, afunds, funds
					FROM seoclerks.members
					WHERE (username='".addslashes($user_username)."'
							OR email='".addslashes($user_username)."')";
		$result=$conn->execute($query);

		/*
		 * Server Data
		 */
		$querystring = addslashes(ledgerQueryString('BLOCKED LOGIN ATTEMPT - Reached ' . $config['botBruteLoginBan'] . ' failed logins'));
		$ip			 = addslashes($_SERVER['REMOTE_ADDR']);
		$agent		 = addslashes($_SERVER['HTTP_USER_AGENT']);
		$script		 = addslashes($_SERVER['SCRIPT_FILENAME']);
		$postdata	 = ''; //addslashes(serialize($_REQUEST));

		$query = "INSERT INTO members_ledger (USERID, username, script, querystring, postdata, afunds, funds, added, ip, agent)
				VALUES ( '{$result->fields['USERID']}', '{$result->fields['username']}', '{$script}', '{$querystring}', '{$postdata}', '{$result->fields['afunds']}', '{$result->fields['funds']}', UNIX_TIMESTAMP(NOW()),
						'{$ip}', '{$agent}')";
		UpdateMembersAllSites($query, '', 'members_ledger');

		/**
		 * Send this to CloudFlare to that they will issue a
		 * challenge to the user.
		 *
		 * 2021-08-06 09:52:52 JD
		 */
		cloudflareBanIp($_SERVER['REMOTE_ADDR'], $config['include']['cloudFlareEmail'], $config['include']['cfGlobalToken']);

		/**
		 * Send a message to the Helpdesk
		 */
		// SwiftMailSendGeneric($config['ZDAutoEmail'], $config['sitetitle'], $config['support_email'], 'Possible brute force bot detected', "The IP address {$_SERVER['REMOTE_ADDR']} has attempted to login {$config['botBruteLoginBan']} times or more and failed. They have automatically been blocked from logging in.");

		// Ban them
		$query = "INSERT INTO seoclerks.banned_bot_ip (ip) VALUES('{$ip}')";
		$conn->execute($query);

	}

	if($error == "")
	{
		$encryptedpassword = md5($user_password);
		$query="SELECT status, USERID, email, username, verified, referer, oldtheme, displaytype from seoclerks.members
			WHERE (username='".addslashes($user_username)."' OR email='".addslashes($user_username)."')
				and password='".addslashes($encryptedpassword)."'";
		$result=$conn->execute($query);

		if($result->recordcount()<1)
		{
			$error 						= $lang['42'];
			$_SESSION['failed_login'] 	= $_SESSION['failed_login'] + 1;
			$_SESSION['failed_time']	= time();

			// The ledger row the IP and account lockouts count (security.php)
			recordFailedMemberLogin($user_username);
		}
		elseif(!memberStatusIsActive($result->fields['status']))
		{
			$error = "<li>".$lang['43']."</li>";
		}

		if($error=="")
		{
			/**
			 * lastlogin and lip are not written here any more. A
			 * matching password is not a finished login while two
			 * factor may still be owed; RecordMemberLogin() writes
			 * them once it has been decided. Clearing the marker makes
			 * it record this login even if the session recorded one
			 * for this account before.
			 *
			 * 2026-09-21
			 */
			unset($_SESSION['LOGIN_RECORDED']);

			/**
			 * Set the session variables for the user
			 */
			$_SESSION['referer'] 		= $result->fields['referer'];
	    	$_SESSION['USERID']	 		= $result->fields['USERID'];
			$_SESSION['EMAIL']	 		= $result->fields['email'];
			$_SESSION['USERNAME']		= $result->fields['username'];
			$_SESSION['VERIFIED']		= $result->fields['verified'];
			$_SESSION['W']				= $encryptedpassword;
			$_SESSION['displaytype'] 	= $result->fields['displaytype'];
			$_SESSION['oldtheme'] 		= $result->fields['oldtheme'];
			$_SESSION['upid']			= 1;
			$_SESSION['justLoggedIn']	= 1;

			/**
			 * Claim any guest cart lines from this session for the
			 * account that just logged in (issue #909).
			 *
			 * 2026-08-18 JD
			 */
			cartMergeGuestCart(intval($result->fields['USERID']));

			/*
			 * If this was an openid login, verify the
			 * openid identity and proceed
			 * 8/27/2013
			 */
			 if ($identity_id > 0)
			 {
				 $query = "UPDATE seoclerks.members_identity SET USERID='".addslashes($result->fields['USERID'])."', status=1
				 				WHERE identity_id='".addslashes($identity_id)."'";
				 $conn->execute($query);
			 }

			if($l_remember_me == "1")
				create_slrememberme();

			if (!empty($_REQUEST['r'])) redirectAndDie('/' . decodeRedirectPath($r));
			else redirectAndDie('/marketplace');
		}
	}
}

if ($_SESSION['userbrowser'] == 'mobile')
{
	$templateselect = "mobile/login.tpl";
}
else
{
	$templateselect = "login.tpl";
}

/*
 * To make the title unique,
 * decode the redirect if available
 */
if (!empty($r))
{
	$redirect 		= base64_decode($r);
	if (substr($redirect, 0, 1) == '/')
	{
		$redirect = substr($redirect, 1);
	}
	$pagetitle 		= $lang['1486'] . ' ' . $thebaseurl . '/' . $redirect;
}
else
{
	$pagetitle 		= $lang[40];
}


/*
 * We need to fetch the captcha again to ensure
 * the number is accurate here (in case they have
 * just failed a login above).
 * 3/2/2017
 *
 * Removed this due to it being called twice 5/14/2021 SE
 */
// $totalFailedCaptcha 	= CountBotLoginAttempts(86400); // For showing a captcha, we can't to count a bit higher.  86400

/*
 * If the total amount of failed logins is
 * more than 4, add the captcha
 *
 * Turned on captcha for everyone 12-9-2019 following an intense
 * login attack. - JD
 *
 * 12/23/2015
 */
$loginCaptcha = 1;

/**
 * Get our CSFR token
 */
$CSFR 			= GenerateCSFRCode();


if ($config['themeUni']	== 1)
{
	$config['pagetitle']				= $pagetitle;
	$config['include']['validateJs'] 	= 1; // The validation JS for validating form input
	$config['include']['tagsinput'] 	= 1;
	$config['set_recaptcha'] 			= 1;
	$authPagePane						= 'login'; // The tab view_login.php opens on a phone

	/*
	 * /login/{base64 return path} is linked from public pages (follow buttons, bids)
	 * and each one looked like its own page to Google. Never index a login form.
	 * 2026-09-23
	 */
	$config['noindex']					= 1;
	$config['canonicalUrl']				= str_ireplace('seoclerks.com', 'seoclerk.com', $config['baseurl']) . '/login';

	include 'views/header/view_header-loader.php';
	include 'views/login/view_login.php';
	include 'views/footer/view_footer-loader.php';
}
else
{

	//TEMPLATES BEGIN
	//TEMPLATES END

}

?>
