Hi
My forgotpass.php function used to work. Suddenly it only works up until you get the message: 'An email has been sent to you with instructions on how to reset your password. <strong>(Mail will not send unless you have an smtp server running locally.)'

However no email is sent. It seems that the function: $passwordMessage = sendPasswordEmail from functions.php is not being called, but I can't work out why.

forgotpass.php:

<?php
include("database.php");
include("functions.php");
$show = 'emailForm'; //which form step to show by default
if ($_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900))
{
    $_SESSION['lockout'] = false;
    $_SESSION['badCount'] = 0;
}
if (isset($_POST['subStep']) && !isset($_GET['a']) && $_SESSION['lockout'] != true)
{
    switch($_POST['subStep'])
    {
        case 1:
            //we just submitted an email or username for verification
            $result = checkUNEmail($_POST['uname'],$_POST['email']);
            if ($result['status'] == false )
            {
                $error = true;
                $show = 'userNotFound';
            } else {
                $error = false;
                $show = 'securityForm';
                $securityUser = $result['userID'];
            }
        break;
        case 2:
            //we just submitted the security question for verification
            if ($_POST['userID'] != "" && $_POST['answer'] != "")
            {
                $result = checkSecAnswer($_POST['userID'],$_POST['answer']);
                if ($result == true)
                {
                    //answer was right
                    $error = false;
                    $show = 'successPage';
                    $passwordMessage = sendPasswordEmail($_POST['userID']);
                    $_SESSION['badCount'] = 0;
                } else {
                    //answer was wrong
                    $error = true;
                    $show = 'securityForm';
                    $securityUser = $_POST['userID'];
                    $_SESSION['badCount']++;
                }
            } else {
                $error = true;
                $show = 'securityForm';
            }
        break;
        case 3:
            //we are submitting a new password (only for encrypted)
            if ($_POST['userID'] == '' || $_POST['key'] == '') header("location: login.php");
            if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '')
            {
                $error = true;
                $show = 'recoverForm';
            } else {
                $error = false;
                $show = 'recoverSuccess';
                updateUserPassword($_POST['userID'],$_POST['pw0'],$_POST['key']);
            }
        break;
    }
}
elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") {   
    $show = 'invalidKey';   
    $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u'])));   
    if ($result == false)   
    {   
        $error = true;   
        $show = 'invalidKey';   
    } elseif ($result['status'] == true) {   
        $error = false;   
        $show = 'recoverForm';   
        $securityUser = $result['userID'];   
    }   
}   
if ($_SESSION['badCount'] >= 3)   
{   
    $show = 'speedLimit';   
    $_SESSION['lockout'] = true;   
    $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime'];   
}   
?>  

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Bright-Tutors - Education for Life!</title>
<link href="css/inav-ie-8.css" rel="stylesheet" media="screen">
<link href="css/inav-ie-7.css" rel="stylesheet" media="screen">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
<style type="text/css">
@import url("css/main.css");
#page {
    width: 800px;
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    font-size: 12px;
}
#header {
    width: 800px;
}
.field {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 11px;
    color: #666;
    padding-left: 0px;
    text-align: left;
    width: 500px;
}
.fieldtext {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #666;
    padding-left: 0px;
    text-align: left;
    width: 800px;
}
.submit {
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #666;
    width: 100px;
    text-align: left;
}
</style>
<script type="text/javascript">
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
</script>
</head>
<body onLoad="MM_preloadImages('library/topbar/topbar_r2_c2_s2.jpg','library/topbar/topbar_r2_c4_s2.jpg','library/topbar/topbar_r2_c6_s2.jpg','library/topbar/topbar_r2_c8_s2.jpg','library/topbar/topbar_r2_c10_s2.jpg','library/topbar/topbar_r2_c12_s2.jpg','library/topbar/topbar_r2_c14_s2.jpg')">
<table width="800" border="0" align="center" cellpadding="1" cellspacing="1">
  <tr>
    <td width="172">&nbsp;</td>
    <td width="625">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="2"><div id="header"><hr /></div></td>
  </tr>
  <tr>
    <td colspan="2" align="left"><div id="page">
      <?php switch($show) {   
    case 'emailForm': ?>
      <h2>Password Recovery</h2>
      <p class="fieldtext">You can use this form to recover your password if you have forgotten it.<br>
Because your password is securely encrypted in our database, it is impossible actually recover your password, 
        but we will email you a link that 
        will enable you to reset it securely. <br>
        <br>
        Enter either your username or your email address below to get started.<br>
        <br>
        If you answer the security question wrong 3 times you will be locked out. </p>
      <span class="field">
      <?php if ($error == true) { ?>
      You must enter either a username or email address to continue.
      <?php } ?>
      </span>
      <form action="<?= $_SERVER['Login/PHP_SELF']; ?>" method="post" class="field">
        <div class="field">
          <label for="uname">Username</label>
          <br>
          <input name="uname" type="text" id="uname" value="" size="30" maxlength="30">
          </div>

        <div class="field">
          <label><br>
            - OR -</label>
          <br>
          <br>
        </div>
        <div class="field">
          <label for="email">Email</label>
          <br>
          <input name="email" type="text" id="email" value="" size="30" maxlength="255">
          </div>

        <input type="hidden" name="subStep" value="1" />
        <br>
        <br>
        <div>
          <input type="submit" style="margin-left: 0px;" value="Submit " />
    </div>
        <div class="clear"></div>
    </form>
      <?php break; case 'securityForm': ?>
      <h2>Password Recovery</h2>
      <p class="field">Please answer the security question below:</p>
      <span class="field">
      <?php if ($error == true) { ?>
      You must answer the security question correctly to receive your lost password.
      <?php } ?>
      </span>
      <form action="<?= $_SERVER['Login/PHP_SELF']; ?>" method="post" class="field">
        <div class="field">
          <label>Question<br>
          </label>
          <?= getSecurityQuestion($securityUser); ?>
          </div>

        <div class="field">
          <label for="answer"><br>
            Answer</label>
          <br>
          <input type="text" name="answer" id="answer" value="" maxlength="255">
          </div>

        <input type="hidden" name="subStep" value="2" />
        <input type="hidden" name="userID" value="<?= $securityUser; ?>" />
        <br>
        <br>
        <div class="field">
          <input type="submit" style="margin-left: 0px;" value="Submit" />
    </div>
        <div class="clear"></div>
    </form>
      <?php break; case 'userNotFound': ?>
      <h2>Password Recovery</h2>
      <p class="field">The username or email you entered was not found in our database.<br />
        <br />
        <a href="forgotpass.php">Click here</a> to try again.</p>
      <?php break; case 'successPage': ?>
      <h2>Password Recovery</h2>
      <p class="field">An email has been sent to you with instructions on how to reset your password. <strong>(Mail will not send unless you have an smtp server running locally.)</strong><br />
        <br />
        <a href="login.php">Return</a> to the login page. </p>


      <?php break;
    case 'recoverForm': ?>
      <h2>Password Recovery</h2>
      <p class="field">Welcome back,
        <?= getUserName($securityUser=='' ? $_POST['userID'] : $securityUser); ?>
        .</p>
      <p class="field">In the fields below, enter your new password.</p>
      <span class="field">
      <?php if ($error == true) { ?>
      The new passwords must match and must not be empty.
      <?php } ?>
      </span>
      <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post" class="field">
        <div class="field">
          <label for="pw0">New Password</label>
          <br>
          <input type="password" class="input" name="pw0" id="pw0" value="" maxlength="20">
          </div>

        <div class="field">
          <label for="pw1">Confirm Password</label>
          <br>
          <input type="password" class="input" name="pw1" id="pw1" value="" maxlength="20">
          </div>

        <input type="hidden" name="subStep" value="3" />
        <input type="hidden" name="userID" value="<?= $securityUser=='' ? $_POST['userID'] : $securityUser; ?>" />
        <input type="hidden" name="key" value="<?= $_GET['email']=='' ? $_POST['key'] : $_GET['email']; ?>" />
        <div ><br>
          <input type="submit" style="margin-left: 0px;" value="Submit" />
        </div>
        <div class="clear"></div>
    </form>
      <?php break; case 'invalidKey': ?>
      <h2>Invalid Key</h2>
      <p class="field">The key that you entered was invalid. Either you did not copy the entire key from the email, you are trying to use the key after it has expired (3 days after request), or you have already used the key in which case it is deactivated.<br />
        <br />
        <a href="login.php">Return</a> to the login page. </p>
      <?php break; case 'recoverSuccess': ?>
      <h2>Password Reset</h2>
      <p class="field">Congratulations! your password has been reset successfully.</p>
      <span class="field"><br />
      <br />
      <a href="login.php">Return</a> to the login page.
      </p>
      <?php break; case 'speedLimit': ?>
      </span>
<h2>Warning</h2>
      <p class="field">You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p>
      <span class="field"><br />
      <br />
      <a href="forgotpass.php">Return</a> to the login page.
      </p>
      <?php break; }   
    ob_flush();   
    $mySQL->close();   
?>
    </span></div></td>
  </tr>
</table>
</body>
</html>

And this is the relevant part of the functions.php:

function sendPasswordEmail($userID)   
{   
    global $mySQL;   
    if ($SQL = $mySQL->prepare("SELECT `Username`,`reg_email`,`Password` FROM `tutor_reg` WHERE `ID` = ? LIMIT 1"))   
    {   
        $SQL->bind_param('i',$userID);   
        $SQL->execute();   
        $SQL->store_result();   
        $SQL->bind_result($uname,$email,$pword);   
        $SQL->fetch();   
        $SQL->close();   
        $expFormat = mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+3, date("Y"));   
        $expDate = date("Y-m-d H:i:s",$expFormat);   
        $key = sha1($uname . '_' . $email . rand(0,10000) .$expDate );   
        if ($SQL = $mySQL->prepare("INSERT INTO `recoveryemails_enc` (`UserID`,`Key`,`expDate`) VALUES (?,?,?)"))   
        {   
            $SQL->bind_param('iss',$userID,$key,$expDate);   
            $SQL->execute();   
            $SQL->close();   
            $passwordLink = "<a href=\"?a=recover&email=" . $key . "&u=" . urlencode(base64_encode($userID)) . "\">http://www.bright-tutors.com/forgotpass.php?a=recover&email=" . $key . "&u=" . urlencode(base64_encode($userID)) . "</a>";   
            $message = "Dear $uname,<br/ >" . 
            $message ="Please visit the following link to reset your password:<br/ >" .
            $message ="Please COPY and PASTE the entire link into your browser. <br/ >" .
            $message ="$passwordLink<br/ >" . 
            $message ="The link will expire after 3 days for security reasons.<br/ >" .   
            $message ="If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited.<br/ >" .
            $message ="Thank You" .  
            $message ="--Bright-Tutors team<br/ >" . 
            $headers .= "From: Bright-Tutors <bright-tutors.com> \n";   
            $headers .= "To-Sender: \n";   
            $headers .= "X-Mailer: PHP\n"; // mailer   
            $headers .= "Reply-To: enquiries@bright-tutors\n"; // Reply address   
            $headers .= "Return-Path: liz.banbury@gmail.com\n"; //Return Path for errors   
            $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type   
            $subject = "Your Lost Password";   
            @mail($email,$subject,$message,$headers);   
            return str_replace("\r\n","<br/ >",$message);   
        }   
    }   
}  

Help would be much appreciated as the site needs to be launched and this did used to work. I just have no idea why the email is not being sent.......

Hi,

I'm not sure if is this but: neither the From: header, nor the Reply-To: are correct email addresses. In the From header is missing the local part, i.e. the part that goes before @:

"From: Bright-Tutors <bright-tutors.com> \n";

In the Reply-To the missing part is the top level domain, it should be:

"Reply-To: enquiries@bright-tutors.com\n";

You can also try to change all the \n with \r\n. And consider the use of the SwiftMailer library: http://swiftmailer.org/

Hi,
You need to narrow down the likely problem area as there's a lot of code posted and it would take someone else a lot of work to set up a test db, etc.
Can you debug a little and then repost with some results?
Verify whether sendPasswordEmail is being called by inserting an exit or die command as the first line of the function:
exit("spe function entered, ID: ".$userID);
This should lead you to a next step, either in the function or in the page.

Hi

Many thanks for replying. So I've done a bit more testing. With the tests so far the user email is currently my gmail email address. When I change the email address to my work email address, which goes to a big corporate server, then I received the email.

The issue is where the recipient email is running and/or where you are sending it from. So in addition when I use my PC, I can get the email to the gmail account, but not from my laptop, which is just on wifi. i.e in the initial warning '(Mail will not send unless you have an smtp server running locally.)'
But how can I change that?

Obviously this is not good for going live, as users will obviously use laptops, phones etc to need to reset the password.

So the change in behavior is not related to the code you posted but is related to the mail system being used by the website hosting provider. Can you tell me a little more about that. For example, is it a commercial shared host system.
I'm quite familiar with the symptoms you describe being caused by the mail send server being blocked by the receiving mail system. This situation can be caused by other websites on the same server abusing the email system. This can be temporary and I have found more common when a website is new. AOL is one of the worst culprits for blocking emails from specific servers and being unresponsive even when the ISP calls them to resolve.
Here's my suggested plan of attack:
1. Resolve the 'From' and 'Reply to' address problem mentioned by cereal if you haven't already. This could be causing the emails to be undelivered. I'd recommend using 'donotreply@bright-tutors.com' for the 'from' and correct the 'Reply to' to be 'enquiries@bright-tutors.com'.
2. If this does not solve the problem, write a very simple php script to send mail messages using the 'From' address above and test if they are being consistently delivered, try different recipient mail systems if you can. I can help with this if you need. Sometimes when a site is new, mail messages can take a long time to transit the recipients email system. If you can't find the emails at the recipient email system, do all the usual checks, Spam/Trash folder, add donotreply@bright-tutors.com to the recipient's address book, add bright-tutors.com to the recipients 'white list' (different mail providers have different ways of handling this).
3. If you are experiencing consistent non-delivery contact the ISP and tell them your test emails are not being delivered (don't do this before doing 2, they will blame your script). I have had success with GoDaddy's support system responding to this kind of problem. Sometimes they will already know a particular server is blacklisted by some mail services. By the way, I've never had a problem with gmail.

By the way, I don't understand the '(Mail will not send unless you have an smtp server running locally.)' message. The php code is using PHP's 'mail' command which uses the web servers 'sendmail' software. Maybe someone else can chip in on this.

Many thanks everyone. Adding this: 'donotreply@bright-tutors.com' in the From: got it to work.
Thanks for all the help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.