forgot password added

--HG--
branch : quitta-gsoc-2013
This commit is contained in:
Quitta 2013-09-20 23:36:19 +02:00
parent 78adc25c8d
commit cf8251f25f
16 changed files with 439 additions and 27 deletions

View file

@ -345,7 +345,7 @@ class Mail_Handler{
} }
//if ticket id is found, that means it is a reply on an existing ticket //if ticket id is found, that means it is a reply on an existing ticket
if($ticket_id){ if($ticket_id && is_numeric($ticket_id) && $ticket_id > 0){
$ticket = new Ticket(); $ticket = new Ticket();
$ticket->load_With_TId($ticket_id); $ticket->load_With_TId($ticket_id);

View file

@ -8,6 +8,31 @@ home_info = "Welcome to the Ryzom Core - Account Management System"
[settings] [settings]
[forgot_password]
title = "Forgot your password?"
forgot_password_message = "Fill in your account's emailaddress to reset the password!"
email_tag = "Email Address"
email_tooltip = "The emailaddress related to the account of which you forgot the password."
email_default = "Email"
email_doesnt_exist = "That emailaddress doesn't match any user!"
email_sent = "An email with further instructions has been sent to the emailaddress!"
[reset_password]
title = "Reset your password"
reset_password_message = "Fill in your new password!"
password_tag = "Desired Password"
password_tooltip = "Pick a hard to guess password (it must be 5-20 characters)."
password_message = "Password must be 5-20 characters."
password_default = "Password"
cpassword_tag = "Confirm Password"
cpassword_tooltip = "Retype your Password"
cpassword_message = "Retype your Password"
cpassword_default = "Re-enter Password"
[syncing] [syncing]
syncing_title = "LibDB-Query List" syncing_title = "LibDB-Query List"
syncing_info = "Here you can see the entire list of elements in the LibDB-Query table. You can easily remove elements and by pressing 'Synchronize' you can start the syncing process manually!" syncing_info = "Here you can see the entire list of elements in the LibDB-Query table. You can easily remove elements and by pressing 'Synchronize' you can start the syncing process manually!"
@ -97,7 +122,8 @@ userlist_info = "welcome to the userlist"
login_info = "Please login with your Username and Password." login_info = "Please login with your Username and Password."
login_error_message = "The username/password were not correct!" login_error_message = "The username/password were not correct!"
login_register_message ="<strong>Register</strong> If you don't have an account yet, create one" login_register_message ="<strong>Register</strong> If you don't have an account yet, create one"
login_register_message_here = "here" login_here = "here"
login_forgot_password_message = "In case you forgot your password, click"
[logout] [logout]
logout_message = "You've been logged out successfully!" logout_message = "You've been logged out successfully!"
@ -105,6 +131,14 @@ login_title = "Login"
login_timer = "You will be redirected to the login page in " login_timer = "You will be redirected to the login page in "
login_text = "Or click here if you don't want to wait!" login_text = "Or click here if you don't want to wait!"
[reset_success]
reset_success_message = "You've changed the password succesfully!"
reset_success_title = "Login"
reset_success_timer = "You will be redirected to the login page in "
login_text = "Or click here if you don't want to wait!"
[register_feedback] [register_feedback]
status_ok = "You registered like a baws!" status_ok = "You registered like a baws!"
status_shardoffline = "It seems the shard is offline, you can use the web-account, but you will need to wait for the shard." status_shardoffline = "It seems the shard is offline, you can use the web-account, but you will need to wait for the shard."
@ -191,4 +225,14 @@ email_subject_warn_unknown_sender = "You tried to reply to someone's ticket!"
email_body_warn_unknown_sender = "It seems you tried to reply to someone's ticket, However this email address isn't linked to any account, please use the matching email address to that account! email_body_warn_unknown_sender = "It seems you tried to reply to someone's ticket, However this email address isn't linked to any account, please use the matching email address to that account!
This action is notified to the real ticket owner!" This action is notified to the real ticket owner!"
;===========================================================================
;FORGOTPASSWORD
;===========================================================================
email_subject_forgot_password = "Request to reset your password"
email_body_forgot_password_header = "A request to reset your account's password has been made, you can do this by going to the following link:
"
email_body_forgot_password_footer = "
----------
If you didn't make this request, please ignore this message."
;=========================================================================== ;===========================================================================

View file

@ -7,6 +7,29 @@ home_info = "Bienvenue sur le Ryzom Core - Account Management System"
[settings] [settings]
[forgot_password]
title = "Oubliez votre passport?"
forgot_password_message = "Entrer votre email address pour reseter le passport!"
email_tag = "Email Address"
email_tooltip = "le emailaddress liee au compte dont vous avez oublie le mot de passe."
email_default = "Email"
email_doesnt_exist = "C'est emailaddress ne correspond pas a n'importe quel utilisateur!"
email_sent = "Un e-mail avec des instructions a ete envoye a l'adresse email!"
[reset_password]
title = "reset votre email"
reset_password_message = "Entrer votre nouveaux mot de passe!"
password_tag = "desire Mot de passe:"
password_tooltip = "Prendre un mot de passe dificille, il faut etre 5-20 caracteres"
password_message = "mot de passe doit être 5-20 caractères."
password_default = "Mot de passe"
cpassword_tag = "Confirmer le mot de passe:"
cpassword_message = "Retapez votre mot de passe"
cpassword_tooltip = "Retapez votre mot de passe"
cpassword_default = "Re-entrer mot de passe"
[syncing] [syncing]
syncing_title = "LibDB-Query Liste" syncing_title = "LibDB-Query Liste"
syncing_info = "Ici vous pouvez voir la liste complete des elements dans le tableau libdb-Query. Vous pouvez facilement supprimer des elements et appuyant sur 'Synchroniser', vous pouvez commencer le processus de synchronisation manuellement!" syncing_info = "Ici vous pouvez voir la liste complete des elements dans le tableau libdb-Query. Vous pouvez facilement supprimer des elements et appuyant sur 'Synchroniser', vous pouvez commencer le processus de synchronisation manuellement!"
@ -93,7 +116,8 @@ userlist_info = "bienvenue sur le userlist page!"
login_info = "S'il vous plait vous connecter avec votre nom d'utilisateur et mot de passe." login_info = "S'il vous plait vous connecter avec votre nom d'utilisateur et mot de passe."
login_error_message = "Le remplie nom d'utilisateur / mot de passe ne sont pas correctes!" login_error_message = "Le remplie nom d'utilisateur / mot de passe ne sont pas correctes!"
login_register_message ="<strong> Inscrivez-vous </strong> Si vous n'avez pas encore de compte, creez-en un" login_register_message ="<strong> Inscrivez-vous </strong> Si vous n'avez pas encore de compte, creez-en un"
login_register_message_here = "ici" login_here = "ici"
login_forgot_password_message = "Dans le cas ou vous avez oublie votre mot de passe, cliquez"
[logout] [logout]
logout_message = "Vous avez été déconnecté avec succès!" logout_message = "Vous avez été déconnecté avec succès!"
@ -101,6 +125,12 @@ login_title = "Identifier"
login_timer = "Vous serez redirigé vers la page de connexion à " login_timer = "Vous serez redirigé vers la page de connexion à "
login_text = "Ou cliquez ici si vous ne voulez pas attendre!" login_text = "Ou cliquez ici si vous ne voulez pas attendre!"
[reset_success]
logout_message = "Vous avez changez votre passport bien!"
login_title = "Identifier"
login_timer = "Vous serez redirigé vers la page de connexion à "
login_text = "Ou cliquez ici si vous ne voulez pas attendre!"
[register_feedback] [register_feedback]
status_ok = "Vous vous êtes inscrit comme un patron!" status_ok = "Vous vous êtes inscrit comme un patron!"
status_shardoffline = "Il semble que le shard est déconnecté, vous pouvez utiliser le web-compte, mais vous devrez attendre pour le tesson." status_shardoffline = "Il semble que le shard est déconnecté, vous pouvez utiliser le web-compte, mais vous devrez attendre pour le tesson."
@ -187,4 +217,14 @@ email_subject_warn_unknown_sender = "Vous avez tent
email_body_warn_unknown_sender = "Il semble que vous avez essayé de répondre à la billetterie de quelqu'un, mais cette adresse e-mail n'est pas liée à un compte, veuillez utiliser l'adresse e-mail correspondant à ce compte! email_body_warn_unknown_sender = "Il semble que vous avez essayé de répondre à la billetterie de quelqu'un, mais cette adresse e-mail n'est pas liée à un compte, veuillez utiliser l'adresse e-mail correspondant à ce compte!
Cet acte est notifié au propriétaire du billet de vrai!" Cet acte est notifié au propriétaire du billet de vrai!"
;===========================================================================
;FORGOTPASSWORD
;===========================================================================
email_subject_forgot_password = "Demande pour reinitialiser votre mot de passe"
email_body_forgot_password_header = "Une demande de reinitialiser le mot de passe de votre compte a ete faite, vous pouvez le faire en allant sur le lien suivant:
"
email_body_forgot_password_footer = "
----------
Si vous n'avez pas fait cette demande, s'il vous plait ignorer ce message."
;=========================================================================== ;===========================================================================

View file

@ -154,6 +154,16 @@ class WebUsers extends Users{
} }
return $this->email; return $this->email;
} }
/**
* get the hashed password
*/
public function getHashedPass(){
$dbw = new DBLayer("web");
$statement = $dbw->execute("SELECT * FROM ams_user WHERE UId=:id", array('id' => $this->uId));
$row = $statement->fetch();
return $row['Password'];
}
/** /**
@ -221,17 +231,19 @@ class WebUsers extends Users{
* @return ok if it worked, if the lib or shard is offline it will return liboffline or shardoffline. * @return ok if it worked, if the lib or shard is offline it will return liboffline or shardoffline.
*/ */
public function setPassword($user, $pass){ public function setPassword($user, $pass){
$reply = WebUsers::setAmsPassword($user, $pass);
$values = Array('user' => $user, 'pass' => $pass); $hashpass = crypt($pass, WebUsers::generateSALT());
try { $reply = WebUsers::setAmsPassword($user, $hashpass);
//make connection with and put into shard db $values = Array('user' => $user, 'pass' => $hashpass);
$dbw = new DBLayer("web"); try {
$dbw->execute("UPDATE ams_user SET Password = :pass WHERE Login = :user ",$values); //make connection with and put into shard db
} $dbw = new DBLayer("web");
catch (PDOException $e) { $dbw->execute("UPDATE ams_user SET Password = :pass WHERE Login = :user ",$values);
//ERROR: the web DB is offline }
} catch (PDOException $e) {
return $reply; //ERROR: the web DB is offline
}
return $reply;
} }

View file

@ -0,0 +1,50 @@
<?php
function forgot_password(){
$email = filter_var($_POST["Email"], FILTER_SANITIZE_EMAIL);
$target_id = WebUsers::getIdFromEmail($email);
if ($target_id == "FALSE"){
//the email address doesn't exist.
$result['prevEmail'] = $email;
$result['EMAIL_ERROR'] = 'TRUE';
$result['no_visible_elements'] = 'TRUE';
helpers :: loadtemplate( 'forgot_password', $result);
exit;
}
$webUser = new WebUsers($target_id);
$target_username = $webUser->getUsername();
$target_hashedPass = $webUser->getHashedPass();
$hashed_key = hash('sha512',$target_hashedPass);
if ( isset( $_COOKIE['Language'] ) ) {
$lang = $_COOKIE['Language'];
}else{
global $DEFAULT_LANGUAGE;
$lang = $DEFAULT_LANGUAGE;
}
global $AMS_TRANS;
$variables = parse_ini_file( $AMS_TRANS . '/' . $lang . '.ini', true );
$mailText = array();
foreach ( $variables['email'] as $key => $value ){
$mailText[$key] = $value;
}
//create the reset url
global $WEBPATH;
$resetURL = $WEBPATH . "?page=reset_password&user=". $target_username . "&email=" . $email . "&key=" . $hashed_key;
//set email stuff
$recipient = $email;
$subject = $mailText['email_subject_forgot_password'];
$body = $mailText['email_body_forgot_password_header'] . $resetURL . $mailText['email_body_forgot_password_footer'];
Mail_Handler::send_mail($recipient, $subject, $body, NULL);
$result['EMAIL_SUCCESS'] = 'TRUE';
$result['prevEmail'] = $email;
$result['no_visible_elements'] = 'TRUE';
helpers :: loadtemplate( 'forgot_password', $result);
exit;
}

View file

@ -0,0 +1,44 @@
<?php
function reset_password(){
//filter all data
$email = filter_var($_GET["email"], FILTER_SANITIZE_EMAIL);
$user = filter_var($_GET["user"], FILTER_SANITIZE_STRING);
$key = filter_var($_GET["key"], FILTER_SANITIZE_STRING);
$password = filter_var($_POST['NewPass'], FILTER_SANITIZE_STRING);
$confirmpass = filter_var($_POST['ConfirmNewPass'], FILTER_SANITIZE_STRING);
$target_id = WebUsers::getId($user);
$webUser = new WebUsers($target_id);
if( (WebUsers::getIdFromEmail($email) == $target_id) && (hash('sha512',$webUser->getHashedPass()) == $key) ){
$params = Array( 'user' => $user, 'CurrentPass' => "dummy", 'NewPass' => $password, 'ConfirmNewPass' => $confirmpass, 'adminChangesOther' => true);
$result = $webUser->check_change_password($params);
if ($result == "success"){
$result = array();
$status = WebUsers::setPassword($user, $password);
if($status == 'ok'){
$result['SUCCESS_PASS'] = "OK";
}else if($status == 'shardoffline'){
$result['SUCCESS_PASS'] = "SHARDOFF";
}
$result['no_visible_elements'] = 'TRUE';
helpers :: loadtemplate( 'reset_success', $result);
exit;
}
$GETString = "";
foreach($_GET as $key => $value){
$GETString = $GETString . $key . '=' . $value . "&";
}
if($GETString != ""){
$GETString = '?'.$GETString;
}
$result['getstring'] = $GETString;
$result['prevNewPass'] = $password;
$result['prevConfirmNewPass'] = $confirmpass;
$result['no_visible_elements'] = 'TRUE';
helpers :: loadtemplate( 'reset_password', $result);
exit;
}
}

View file

@ -0,0 +1,8 @@
<?php
/**
* This function is beign used to send to reset the password.
* @author Daan Janssens, mentored by Matthew Lagoe
*/
function forgot_password(){
}

View file

@ -0,0 +1,31 @@
<?php
function reset_password(){
$email = filter_var($_GET["email"], FILTER_SANITIZE_EMAIL);
$user = filter_var($_GET["user"], FILTER_SANITIZE_STRING);
$key = filter_var($_GET["key"], FILTER_SANITIZE_STRING);
$target_id = WebUsers::getId($user);
$webUser = new WebUsers($target_id);
if( (WebUsers::getIdFromEmail($email) == $target_id) && (hash('sha512',$webUser->getHashedPass()) == $key) ){
//you are allowed on the page!
$GETString = "";
foreach($_GET as $key => $value){
$GETString = $GETString . $key . '=' . $value . "&";
}
if($GETString != ""){
$GETString = '?'.$GETString;
}
$pageElements['getstring'] = $GETString;
return $pageElements;
}else{
global $WEBPATH;
$_SESSION['error_code'] = "403";
header("Location: ".$WEBPATH."?page=error");
exit;
}
}

View file

@ -33,12 +33,23 @@ if ( ! isset( $_GET["page"]) ){
if(isset($_SESSION['user'])){ if(isset($_SESSION['user'])){
$page = $_GET["page"]; $page = $_GET["page"];
}else{ }else{
if($_GET["page"] == 'register'){ switch($_GET["page"]){
$page = 'register'; case 'register':
}else{ $page = 'register';
$page = 'login'; break;
} case 'forgot_password':
$page = 'forgot_password';
break;
case 'reset_password':
$page = 'reset_password';
break;
case 'error':
$page = 'error';
break;
default:
$page = 'login';
break;
}
} }
} }
@ -80,7 +91,7 @@ if(isset($_SESSION['ticket_user'])){
//hide sidebar + topbar in case of login/register //hide sidebar + topbar in case of login/register
if($page == 'login' || $page == 'register' || $page == 'logout'){ if($page == 'login' || $page == 'register' || $page == 'logout' || $page == 'forgot_password' || $page == 'reset_password'){
$return['no_visible_elements'] = 'TRUE'; $return['no_visible_elements'] = 'TRUE';
}else{ }else{
$return['no_visible_elements'] = 'FALSE'; $return['no_visible_elements'] = 'FALSE';

View file

@ -383,9 +383,9 @@
`Body` VARCHAR(400) NULL , `Body` VARCHAR(400) NULL ,
`Status` VARCHAR(45) NULL , `Status` VARCHAR(45) NULL ,
`Attempts` VARCHAR(45) NULL DEFAULT 0 , `Attempts` VARCHAR(45) NULL DEFAULT 0 ,
`UserId` INT(10) UNSIGNED NOT NULL , `UserId` INT(10) UNSIGNED NULL ,
`MessageId` VARCHAR(45) NULL , `MessageId` VARCHAR(45) NULL ,
`TicketId` INT UNSIGNED NOT NULL , `TicketId` INT UNSIGNED NULL ,
`Sender` INT(10) UNSIGNED NULL , `Sender` INT(10) UNSIGNED NULL ,
PRIMARY KEY (`MailId`) , PRIMARY KEY (`MailId`) ,
INDEX `fk_email_ticket_user2` (`UserId` ASC) , INDEX `fk_email_ticket_user2` (`UserId` ASC) ,

View file

@ -309,9 +309,9 @@ CREATE TABLE IF NOT EXISTS `mydb`.`email` (
`Body` VARCHAR(400) NULL , `Body` VARCHAR(400) NULL ,
`Status` VARCHAR(45) NULL , `Status` VARCHAR(45) NULL ,
`Attempts` VARCHAR(45) NULL DEFAULT 0 , `Attempts` VARCHAR(45) NULL DEFAULT 0 ,
`UserId` INT(10) UNSIGNED NOT NULL , `UserId` INT(10) UNSIGNED NULL ,
`MessageId` VARCHAR(45) NULL , `MessageId` VARCHAR(45) NULL ,
`TicketId` INT UNSIGNED NOT NULL , `TicketId` INT UNSIGNED NULL ,
`Sender` INT(10) UNSIGNED NULL , `Sender` INT(10) UNSIGNED NULL ,
PRIMARY KEY (`MailId`) , PRIMARY KEY (`MailId`) ,
INDEX `fk_email_ticket_user2` (`UserId` ASC) , INDEX `fk_email_ticket_user2` (`UserId` ASC) ,

View file

@ -0,0 +1,55 @@
{extends file="layout.tpl"}
{block name=content}
<div class="row-fluid">
<div class="span12 center login-header">
<img src="img/mainlogo.png"/>
</div><!--/span-->
</div><!--/row-->
<div class="row-fluid">
<div class="well span5 center login-box">
<div class="alert alert-info">
{$forgot_password_message}
</div>
<form id="signup" class="form-vertical" method="post" action="index.php">
<legend>{$title}</legend>
<div class="control-group {if isset($EMAIL_ERROR) and $EMAIL_ERROR eq "TRUE"}error{/if}">
<label class="control-label">{$email_tag}</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-envelope"></i></span>
<input type="text" class="input-xlarge" id="Email" name="Email" placeholder="{$email_default}" {if isset($prevEmail)}value="{$prevEmail}"{/if} rel="popover" data-content="{$email_tooltip}" data-original-title="{$email_default}">
</div>
</div>
</div>
{if isset($EMAIL_ERROR) and $EMAIL_ERROR eq "TRUE"}
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
{$email_doesnt_exist}
</div>
{/if}
{if isset($EMAIL_SUCCESS) and $EMAIL_SUCCESS eq "TRUE"}
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert">×</button>
{$email_sent}
</div>
{/if}
<input type="hidden" name="function" value="forgot_password">
<div class="control-group">
<label class="control-label"></label>
<div class="controls">
<button type="submit" class="btn btn-large btn-primary" >Send me the reset link</button>
</div>
</div>
</form>
</div><!--/span-->
</div><!--/row-->
{/block}

View file

@ -12,7 +12,7 @@
<div class="alert alert-info"> <div class="alert alert-info">
{$login_info} {$login_info}
</div> </div>
<form method="post" action="index.php{$getstring}" class="form-horizontal"> <form method="post" action="index.php{if isset($getstring)}{$getstring}{/if}" class="form-horizontal">
<fieldset> <fieldset>
<div data-rel="tooltip" class="input-prepend" data-original-title="Username"> <div data-rel="tooltip" class="input-prepend" data-original-title="Username">
<span class="add-on"><i class="icon-user"></i></span><input type="text" value="" id="Username" name="Username" class="input-large span10" placeholder="Username"> <span class="add-on"><i class="icon-user"></i></span><input type="text" value="" id="Username" name="Username" class="input-large span10" placeholder="Username">
@ -43,7 +43,7 @@
</div> </div>
{/if} {/if}
<div class="alert alert-info"> <div class="alert alert-info">
{$login_register_message} <a href="?page=register">{$login_register_message_here}</a>! {$login_register_message} <a href="?page=register">{$login_here}</a>.<br/> {$login_forgot_password_message} <a href="?page=forgot_password">{$login_here}</a>
</div> </div>
</div><!--/span--> </div><!--/span-->
</div> </div>

View file

@ -0,0 +1,70 @@
{extends file="layout.tpl"}
{block name=content}
<div class="row-fluid">
<div class="span12 center login-header">
<img src="img/mainlogo.png"/>
</div><!--/span-->
</div><!--/row-->
<div class="row-fluid">
<div class="well span5 center login-box">
<form id="signup" class="form-vertical" method="post" action="index.php{$getstring}">
<legend>{$title}</legend>
<div class="control-group {if isset($NEWPASSWORD_ERROR) and $NEWPASSWORD_ERROR eq "TRUE"}error{else if
isset($newpass_error_message) and $newpass_error_message eq "success"}success{else}{/if}">
<label class="control-label">New Password</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on" style="margin-left:5px;"><i class="icon-tag"></i></span>
<input type="password" class="input-xlarge" id="NewPass" name="NewPass" placeholder="Your new password" {if isset($prevNewPass)}value="{$prevNewPass}"{/if}>
{if isset($NEWPASSWORD_ERROR) and $NEWPASSWORD_ERROR eq "TRUE"}<br/><span class="help-inline">{$newpass_error_message}</span>{/if}
</div>
</div>
</div>
<div class="control-group {if isset($CNEWPASSWORD_ERROR) and $CNEWPASSWORD_ERROR eq "TRUE"}error{else if
isset($confirmnewpass_error_message) and $confirmnewpass_error_message eq "success"}success{else}{/if}">
<label class="control-label">Confirm New Password</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on" style="margin-left:5px;"><i class="icon-tags"></i></span>
<input type="password" class="input-xlarge" id="ConfirmNewPass" name="ConfirmNewPass" placeholder="Re-enter the new password" {if isset($prevConfirmNewPass)}value="{$prevConfirmNewPass}"{/if}>
{if isset($CNEWPASSWORD_ERROR) and $CNEWPASSWORD_ERROR eq "TRUE"}<br/><span class="help-inline">{$confirmnewpass_error_message}</span>{/if}
</div>
</div>
</div>
{if isset($SUCCESS_PASS) and $SUCCESS_PASS eq "OK"}
<div class="alert alert-success">
The password has been changed!
</div>
{/if}
{if isset($SUCCESS_PASS) and $SUCCESS_PASS eq "SHARDOFF"}
<div class="alert alert-warning">
The password has been changed, though the shard seems offline, it may take some time to see the change on the shard.
</div>
{/if}
<input type="hidden" name="function" value="reset_password">
<div class="control-group">
<label class="control-label"></label>
<div class="controls">
<button type="submit" class="btn btn-large btn-primary" >Reset the password!</button>
</div>
</div>
</form>
</div><!--/span-->
</div><!--/row-->
{/block}

View file

@ -0,0 +1,47 @@
{extends file="layout.tpl"}
{block name=content}
<div class="row-fluid">
<div class="span12 center login-header">
<img src="img/mainlogo.png"/>
</div><!--/span-->
</div><!--/row-->
<div class="row-fluid">
<div class="well span5 center login-box">
{if isset($SUCCESS_PASS) and $SUCCESS_PASS eq "OK"}
<div class="alert alert-success">
The password has been changed!
</div>
{/if}
{if isset($SUCCESS_PASS) and $SUCCESS_PASS eq "SHARDOFF"}
<div class="alert alert-warning">
The password has been changed, though the shard seems offline, it may take some time to see the change on the shard.
</div>
{/if}
<div class="alert alert-info">
<strong>{$reset_success_title}</strong>
<p>{$reset_success_timer}<span id="seconds">5</span></p>
<p><a href="index.php">{$login_text}</a></p>
</div>
<script>
var seconds = 5;
setInterval(
function(){
if (seconds <= 1) {
window.location = 'index.php';
}
else {
document.getElementById('seconds').innerHTML = --seconds;
}
},
1000
);
</script>
</div><!--/span-->
</div>
{/block}