Recovery System

Similar to this original from Tibia.
This commit is contained in:
ElGovanni 2016-04-19 20:41:57 +02:00
parent dfa6ceaa32
commit 91d0ffa95c
5 changed files with 318 additions and 46 deletions

View File

@ -533,6 +533,13 @@
'debug' => false, // Enable debugging if you have problems and are looking for errors.
'fromName' => $config['site_title'],
);
//Recovery System by ElGovanni (https://github.com/ElGovanni) //know as Burczyk
$config['recovery_key'] = array(
'enabled' => true,
'length' => 10, //less or equal value from database (default is: 20)
'send_to_mail' => true,
'change_email_by_recovery' => true,
);
// Use Znote's External Open Tibia Services Server
// Currently in Alpha and is pretty useless, but will contain paypal blacklist etc in future.
// You can use the official server: http://zeotss.znote.eu/

View File

@ -19,7 +19,7 @@
Token::create();
?>
<center> <h3><a href="register.php">New account</a></h3>
<font size="1">- Lost <a href="recovery.php?mode=username">username</a> or <a href="recovery.php?mode=password">password</a>?</font></center>
<font size="1">- <a href="lostaccount.php" title="recovery access to login">Problems with logging?</a></font></center>
</ul>
</form>
</div>

222
lostaccount.php Normal file
View File

@ -0,0 +1,222 @@
<?php require_once 'engine/init.php'; include 'layout/overall/header.php';
$acceptedChars = '123456789ZXCVBNMASDFGHJKLQWERTYUIOPzxcvbnmasdfghjklqwertyuiop';
if (empty($_POST) === false) {
if(isset($_POST['step']) && !empty($_POST['step']) && getValue($_POST['step'])>2){
if (!Token::isValid($_POST['token'])) {
$errors[] = 'Token is invalid.';
}
}
}
if(empty($_GET)){
$step = (isset($_POST['step']) && !empty($_POST['step'])) ? getValue($_POST['step']) : false;
$character = (isset($_POST['character']) && !empty($_POST['character'])) ? getValue($_POST['character']) : false;
$option = (isset($_POST['option']) && !empty($_POST['option'])) ? getValue($_POST['option']) : false;
$new_email = (isset($_POST['new_email']) && !empty($_POST['new_email'])) ? getValue($_POST['new_email']) : false;
$rec_key = (isset($_POST['rec_key']) && !empty($_POST['rec_key'])) ? getValue($_POST['rec_key']) : false;
switch ($step) {
case '1':
{
{
?>
<form action="" method="post">
<h2>Specify your problem</h2>
<label><input type="radio" name="option" value=0> I have forgotten my password</label><br>
<label><input type="radio" name="option" value=1> I have forgotten my account name</label><br>
<?php
if($config['recovery_key']['change_email_by_recovery'] && empty($errors))
echo '<label><input type="radio" name="option" value=2> I don\'t have access to my e-mail</label><br>';
else
echo '<label><input type="radio" name="option" value=2> Recovery password by key</label><br>';
echo '<input type="hidden" name="character" value="'.$character.'">';
?>
<button type="submit" name="step" value=2>Submit</button>
</form>
<?php
}
}
break;
break;
case '2':
{
switch ($option) {
case '0':
header('Location: recovery.php?mode=password');
break;
case '1':
header('Location: recovery.php?mode=username');
break;
case '2':
{
if($config['recovery_key']['change_email_by_recovery']){
if(user_character_exist($character)){
?>
<h2>We'll send authentication code to your new e-mail and then new password</h2>
<form action="" method="post">
<label>New e-mail address<br><input type="text" placeholder="new e-mail address" name="new_email" autocomplete="off"></label><br><br>
<label>Recovery key<br><input type="text" placeholder="recovery key" name="rec_key" autocomplete="off"></label><br>
<?php echo '<input type="hidden" name="character" value="'.$character.'">'; Token::create();?>
<button type="submit" name="step" value=3>Submit</button>
</form>
<?php
}else {
echo 'We can\'t find that character';
}
}else{
?>
<form action="" method="post">
<label>Recovery key<br><input type="text" placeholder="recovery key" name="rec_key" autocomplete="off"></label><br>
<?php echo '<input type="hidden" name="character" value="'.$character.'">'; Token::create();?>
<button type="submit" name="step" value=3>Submit</button>
</form>
<?php
}
}
break;
default:
echo "Something went wrong, please conact with administrator.";
break;
}
}
break;
case '3':
{
if(user_character_exist($character) && empty($errors)){
$query = mysql_select_single("SELECT `p`.`id` AS `player_id`, `a`.`name`, `a`.`key`, `a`.`email_new_time`, `a`.`email`, `a`.`id` AS `account_id` FROM `players` `p` INNER JOIN `accounts` `a` ON `p`.`account_id`=`a`.`id` WHERE `p`.`name` = '$character' LIMIT 1;");
if($config['recovery_key']['change_email_by_recovery']){
if($query['key']==$rec_key && filter_var($new_email, FILTER_VALIDATE_EMAIL) != false && $query['email']!=$new_email){
if((intval($query['email_new_time']) - time())>=7140) //interval
echo "Something went wrong";
else {
$tempKey = NULL;
for($i=0; $i < 25; $i++) {
$cnum[$i] = $acceptedChars{mt_rand(0, 60)};
$tempKey .= $cnum[$i];
}
mysql_update("UPDATE `accounts` SET `email_code` = '".$tempKey."', `email_new` = '".$new_email."', `email_new_time` = '".intval(time()+7200)."' WHERE `id` = '".$query['account_id']."';");
$thisurl = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$thisurl .= "?confirm&u=".$query['account_id']."&tempkey=".$tempKey;
//Authenticate email
$mailer = new Mail($config['mailserver']);
$title = "Please authenticate your account at $_SERVER[HTTP_HOST].";
$body = "<h1>Please click on the following link to authenticate your account:</h1>";
$body .= "<p><a href='$thisurl'>$thisurl</a></p>";
$body .= "<hr><p>I am an automatic no-reply e-mail. Any emails sent back to me will be ignored.</p>";
$mailer->sendMail($_POST['new_email'], $title, $body, $query['name']);
echo 'We have sent an e-mail to your new address with link to authenticate this e-mail, please check it.';
}
} else {
echo 'Incorrect e-mail or recovery key.<br>';
}
}else{
if((intval($query['email_new_time']) - time())>=7140) //interval
echo "Something went wrong";
else{
$newPassword = NULL;
for($i=0; $i < 10; $i++) {
$cnum[$i] = $acceptedChars{mt_rand(0, 60)};
$newPassword .= $cnum[$i];
}
$salt = '';
if ($config['TFSVersion'] != 'TFS_03') {
// TFS 0.2 and 1.0
$password = sha1($newPassword);
} else {
// TFS 0.3/4
if (config('salt') === true) {
$saltdata = mysql_select_single("SELECT `salt` FROM `accounts` WHERE `id` = $auid LIMIT 1;");
if ($saltdata !== false) $salt .= $saltdata['salt'];
}
$password = sha1($salt.$newPassword);
}
mysql_update("UPDATE `accounts` SET `password`='".$password."', `email_new_time` = '".intval(time()+7200)."' WHERE `id` = '".$query['account_id']."';");
echo "Your new password is: ".$newPassword."<br>Stay safe.";
}
}
} else {
echo output_errors($errors);
echo 'This character not exist.';
}
}
break;
default:
?>
<h2>Welcome to the Lost Account Interface!</h2><br>
<p>If you have lost access to your account, this interface can help you. Of course, you need to prove that your claim to the account is justified. Enter the requested data and follow the instructions carefully. Please understand there is no way to get access to your lost account if the interface cannot help you.</p>
<form action="" method="post">
Character name: <br>
<input type="text" name="character"><br>
<button type="submit" name="step" value=1>Submit</button>
</form>
<?php
break;
}
}elseif (isset($_GET['confirm']) && empty($_GET['confirm'])) {
$auid = (isset($_GET['u']) && (int)$_GET['u'] > 0) ? (int)$_GET['u'] : false;
$tempKey = (isset($_GET['tempkey'])) ? $_GET['tempkey'] : false;
$tempKeyStatus = true;
for($i = 0;$i<strlen($tempKey); $i++)
{
$homeStatus = false;
for($j = 0; $j<strlen($acceptedChars); $j++)
{
$homeStatus = false;
if($tempKey[$i] == $acceptedChars[$j]){
$homeStatus = true;
break;
}
}
if($homeStatus===false)
{
$tempKeyStatus=false;
break;
}
}
if($tempKeyStatus===false)
return false;
$query = mysql_select_single("SELECT `email_code`, `email_new`, `name`, `password` FROM `accounts` WHERE `id` = $auid LIMIT 1;");
if($query!==false && $query['email_code']==$tempKey && $query['email_new']){
$newPassword = NULL;
for($i=0; $i < 10; $i++) {
$cnum[$i] = $acceptedChars{mt_rand(0, 60)};
$newPassword .= $cnum[$i];
}
$salt = '';
if ($config['TFSVersion'] != 'TFS_03') {
// TFS 0.2 and 1.0
$password = sha1($newPassword);
} else {
// TFS 0.3/4
if (config('salt') === true) {
$saltdata = mysql_select_single("SELECT `salt` FROM `accounts` WHERE `id` = $auid LIMIT 1;");
if ($saltdata !== false) $salt .= $saltdata['salt'];
}
$password = sha1($salt.$newPassword);
}
//Send new password
$mailer = new Mail($config['mailserver']);
$title = "This is your new password at $_SERVER[HTTP_HOST].";
$body = "<p>Password: ".$newPassword."</p>";
$body .= "<p>Stay safe at ".$config['mailserver']['fromName'].".</p>";
$body .= "<hr><p>I am an automatic no-reply e-mail. Any emails sent back to me will be ignored.</p>";
$mailer->sendMail($query['email_new'], $title, $body, $query['name']);
mysql_update("UPDATE `accounts` SET `email` = '".$query['email_new']."', `email_new` = '0', `email_code` = '0', `password` = '$password' WHERE `id` = $auid LIMIT 1;");
echo "We have sent new password to your new e-mail, have fun! :)";
}else{
echo 'Something went wrong';
}
}
include 'layout/overall/footer.php'; ?>

View File

@ -8,20 +8,21 @@ if (empty($_POST) === false) {
/* Token used for cross site scripting security */
if (!Token::isValid($_POST['token'])) {
$errors[] = 'Token is invalid.';
}
$required_fields = array('new_email', 'new_flag');
foreach($_POST as $key=>$value) {
if (empty($value) && in_array($key, $required_fields) === true) {
$errors[] = 'You need to fill in all fields.';
break 1;
} elseif(isset($_POST['create_rkey'])!=true){
$required_fields = array('new_email', 'new_flag');
foreach($_POST as $key=>$value) {
if (empty($value) && in_array($key, $required_fields) === true) {
$errors[] = 'You need to fill in all fields.';
break 1;
}
}
}
if (empty($errors) === true) {
if (filter_var($_POST['new_email'], FILTER_VALIDATE_EMAIL) === false) {
$errors[] = 'A valid email address is required.';
} else if (user_email_exist($_POST['new_email']) === true && $user_data['email'] !== $_POST['new_email']) {
$errors[] = 'That email address is already in use.';
if (empty($errors) === true) {
if (filter_var($_POST['new_email'], FILTER_VALIDATE_EMAIL) === false) {
$errors[] = 'A valid email address is required.';
} else if (user_email_exist($_POST['new_email']) === true && $user_data['email'] !== $_POST['new_email']) {
$errors[] = 'That email address is already in use.';
}
}
}
}
@ -29,7 +30,33 @@ if (empty($_POST) === false) {
<h1>Settings</h1>
<?php
if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
if(isset($_POST['create_rkey']) && $config['recovery_key']['enabled']) {
$acceptedChars = '123456789ZXCVBNMASDFGHJKLQWERTYUIOPzxcvbnmasdfghjklqwertyuiop';
$randomString = NULL;
for($i=0; $i < $config['recovery_key']['length']; $i++) {
$cnum[$i] = $acceptedChars{mt_rand(0, 60)};
$randomString .= $cnum[$i];
}
$update_data = array(
'key' => $randomString,
'reckey_created' => time()
);
user_update_account($update_data);
if($config['recovery_key']['send_to_mail']) {
$mailer = new Mail($config['mailserver']);
$title = "You have created recovery key for $_SERVER[HTTP_HOST].";
$body = "<h1>Please save it in safe place:</h1>";
$body .= "<p>$randomString</p>";
$body .= "<p>Thank you for stay safe and enjoy at".$config['mailserver']['fromName']."</p>";
$body .= "<hr><p>I am an automatic no-reply e-mail. Any emails sent back to me will be ignored.</p>";
$mailer->sendMail($user_data['email'], $title, $body, $user_data['name']);
}
echo "<p>Your new recovery key is: ".$randomString;
if($config['recovery_key']['send_to_mail'])
echo '<br>Duplicate has been send to your e-mail address: '.$user_data['email'];
echo '</p>';
} elseif (isset($_GET['success']) === true && empty($_GET['success']) === true) {
echo 'Your settings have been updated.';
} else {
if (empty($_POST) === false && empty($errors) === true) {
@ -82,6 +109,22 @@ if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
</li>
</ul>
</form>
<?php
if($config['recovery_key']['enabled']){
$query = mysql_select_single("SELECT `reckey_created` FROM `accounts` WHERE `id` = '$session_user_id'");
echo '<h2>Recovery Key</h2>';
if($query['reckey_created'] !=0){
echo '<input type="text" name="rkey" value="'.gmdate('Y-m-d', $query['reckey_created']).'" disabled>';
echo '<button disabled>Create</button>';
}
else{
?>
<form action="" method="post">
<input type="text" name="rkey" value="" disabled>
<?php Token::create(); ?>
<button name="create_rkey" type="submit">Create</button>
</form>
<?php }} ?>
<script>
function selectCurrentFlag(flag) {
document.getElementById("flag_select").value = flag != null ? flag : "";