I have the below script running as part of a password forgot system. Everything seems to be working fine except that the database is not being updated with the 'token'. As everything else is working fine (i.e. $str is being set and used in the URL sent via email)... i think this must be a problem with the update script but I cant see why. My code is below, all help greatly appreciated.
if(isset($_POST["sign"])){
include('connections/conn.php');
$email = mysqli_real_escape_string($conn, $_POST["email"]);
$data = $conn->query("SELECT id FROM travisor_tradesperson WHERE email='$email'");
if ($data-> num_rows > 0) {
$str = "0123456789qwertyuiopasdfghjklzxcvbnm";
$str = str_shuffle($str);
$str = substr($str, 0, 10);
$url = "http://rhamilton461.web.eeecs.qub.ac.uk/travisor/passReset.php?token=$str&email=$email";
mail($email, "Reset Password", "To reset your password please visit: $url" , "From: rhamilton461#qub.ac.uk\r\n");
$conn->query("UPDATE travisor_tradesperson SET token = '$str' WHERE email='$email'");
echo "Please check your email.";
} else {
echo "Please check your inputs.";
}
}
try out to run script by commenting the calling statement of mail function.
it is possible that your table is not updating because there is error in mail function.
are you getting output as "Please check your email" ???
Related
I am trying to allow users to edit their email address in my PHP system but also prevent them from setting one that already exist, I am also trying run them through FILTER_VALIDATE_EMAIL. However it stops somewhere for me. The checks works fine in same function, but updating the the new one if the checks that I tried to setup are passed doesn't work. I am using a HTML form for updating them. I thought I did it right, I read here check if email exists in MySQL database that it should be possible to do it this way.
Here's my code, does anyone see what I am doing wrong? Where am I missing out?
function EmailCheck($sql) {
if (isset($_POST['email'])) {
$newemail = $_POST["email"];
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
echo "Invalid e-mail, please try a different.";
exit;
}
$check_email = $sql->query("SELECT email FROM auth WHERE email='$newemail'");
if ($check_email-> num_rows) {
echo "E-mail is already in use.";
exit;
}
}
else {
mysqli_query($sql, "UPDATE auth SET email='$newemail' WHERE username = '$this->username'");
header("Location: userinfo.php");
exit;
}
}
Your Update query looks like it is in the wrong place. According to your code, if the posted email value is not set, you are updating the DB. I am guessing that is not what you want to do. The other problem I see is you are only passing the $sql variable to the function. The posted value will never be set.
//initalize flags
$flag1 = "no";
$flag2 = "no";
if( isset($_POST['email'])){
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
echo "Invalid e-mail, please try a different.";
exit;
}else{
//use flag here for for last if
$flag1 = "yes";
}
$check_email = $sql->query("SELECT email FROM auth WHERE email='$newemail'");
if ($check_email-> num_rows) {
echo "E-mail is already in use.";
exit;
}else{
//set 2nd flag here
$flag2 = "yes";
}
if( $flag1 == "yes" && $flag2 == "yes"){
//update query for new email here
}
}else{
//do something when no email is posted
}
I'm so close to completing the login/registration section of my site but I've got some bugs that don't show up in error_log or anything.
About an hour ago, the script worked for the most part. It would validate, insert into/check database, and redirect to index.php (located in user directory along with login and register forms).
Contents of index.php:
/*
If validation script is successful, continue to $destinationUrl, otherwise, go back to try
again. Ultimately, the TRUE statement's output will be the referring page's URL stored as
$_SESSION['Return_Url'] to send users back to where they were, simply as a convenience.
*/
session_start();
if(isset($_SESSION['UserData'])) {
exit(header("location:" . $destinationUrl));
} else {
exit(header("location:" . $loginUrl));
}
That's exactly what I want except one detail: it won't show any user input errors. While trying to fix that, I've managed to screw everything up again and now it still submits data and inserts into the database but doesn't insert $email, and doesn't redirect or anything. On top of that, I don't get any PHP errors so I'm at a loss.
I know the login and registration will work because it did before, but I don't know what I did to cause this issue due to know errors being thrown. I just want the input errors to show up. I'm going to post the original code I copied and edited because what I'm messing with right now is a mess but the validation section is the same.
I did not write these, they were found online after hours of trying script after script. Only this one worked. Therefore, I don't understand exactly what's going on with every part of the script, but I do understand the basic mechanics of what happens, or is supposed to happen as far as validation of input data and adding to/checking data against the database when the form is submitted. The only thing that I have absolutely no idea what and how it works is the output($var) function
Included Scripts
$db= mysqli_connect($dbhost,$dbuser,$dbpwd,$dbase); }
function safe_input($db, $data) {
return htmlspecialchars(mysqli_real_escape_string($db, trim($data)));
}
/*
Currently, I have no idea about JSON or any other languages. Only a decent
portion of PHP, and HTML, of course. Can I just forget this function and use
{return $var;} instead? Because that would make everything so much easier
and I probably wouldn't even be posting these questions... but it's a new
language to me that I couldn't tell you the first thing about.
*/
function output($Return=array()){
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
exit(json_encode($Return));
}
Validation Scripts
(Both scripts are in one file)
<?
require 'config.php';
require 'functions.php';
if(!empty($_POST) && $_POST['Action']=='login_form'){
$Return = array('result'=>array(), 'error'=>'');
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if(filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid email address.";
}elseif($password===''){
$Return['error'] = "Please enter password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' AND password='".md5($password)."' LIMIT 1");
if(mysqli_num_rows($result)==1){
$row = mysqli_fetch_assoc($result);
$Return['result'] = $_SESSION['UserData'] = array('id'=>$row['id']);
} else {
$Return['error'] = 'Invalid Login Credential.';
}
output($Return);
}
if(!empty($_POST) && $_POST['Action']=='registration_form'){
$Return = array('result'=>array(), 'error'=>'');
$name = safe_input($db, $_POST['Name']);
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if($name===''){
$Return['error'] = "Please enter Full name.";
}elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid Email address.";
}elseif($password===''){
$Return['error'] = "Please enter Password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' LIMIT 1");
if(mysqli_num_rows($result)==1){
$Return['error'] = 'The email you entered already belongs to an account, please login.';
}else{
mysqli_query($db, "INSERT INTO tbl (GUID, email, password, entry_date) values(MD5(UUID()), '$email', '".md5($password)."' ,NOW() )");
$id = mysqli_insert_id($db);
mysqli_query($db, "INSERT INTO `tbl' (id,name) VALUES('$id','$name')");
$Return['result'] = $_SESSION['UserData'] = array('id'=>$id);
}
output($Return);
}
?>
I'm not sure how I would echo the $Return array values. I tried making a function out of it like so:
function inputErr($Return) {
if($Return['error']!=''){
output($Return);
}
}
but that didn't work either. Is there a special way to echo an array value? Without the index name attached
Also, if you have any ideas why the email $var is not being added to db while everything else is, please, do share! With the script not throwing any PHP errors, I have no idea where to start.
So I've sent a link after registration to Verify an account, the link contains the users email address and a 32 character code for example:
$to = $email;
$subject = 'Signup | Verification';
$message = '
Thanks for signing up!
Your account has been created, you can login with the following credentials after you have activated your account by pressing the url below.
------------------------
Username: '.$username.'
Password: '.$password.'
------------------------
Please click this link to activate your account:
localhost:8888/website/verify.php?email='.$email.'&hash='.$hash.'
';
$headers = 'From:myemail#email.com' . "\r\n";
mail($to, $subject, $message, $headers);
That all seems to work fine I'm receiving the email with a link like this:
http://localhost:8888/website/verify.php?email=myemail#email.com&hash=fe646d38bc2145ca6c3cf77d52820cd0
The problem comes when I follow the link and try to activate the account. It takes me to Verify.php fine but I keep getting Invalid Approach and I'm unable to set Validation to 1.
<?php include "includes/base.php"; ?>
<?php
if(isset($_GET['Email']) && !empty($_GET['Email']) AND isset($_GET['Hash']) && !empty($_GET['Hash'])){
$email = mysql_escape_string($_GET['Email']);
$hash = mysql_escape_string($_GET['Hash']);
$search = mysql_query("SELECT Email, Hash, Validation FROM users WHERE Email = '".$email."' AND Hash = '".$hash."' AND Validation = 0") or die(mysql_error());
$match = mysql_num_rows($search);
if($match > 0){
mysql_query("UPDATE users SET Validation = 1 WHERE Email = '".$email."' AND Hash = '".$hash."' AND Validation = 0") or die(mysql_error());
echo "Your account has been activated, you can now login";
}else{
echo "The url is either invalid or you already have activated your account.";
}
}else{
echo "Invalid approach, please use the link that has been sent to your email.";
}
?>
1) this code is unsecure as it has SQL injection problem. Use prepared statements
Please keep in mind that mysql_* functions are no longer supported and they are depriated
2) Regarding your code I found that your GET request has 'email' and 'hash' all lowercase, but in PHP code you use $_GET['Email'] and $_GET['Hash'].
You need to change this:
if(isset($_GET['Email']) && !empty($_GET['Email']) AND isset($_GET['Hash']) && !empty($_GET['Hash'])){
$email = mysql_escape_string($_GET['Email']);
$hash = mysql_escape_string($_GET['Hash']);
To this
if(isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['eash']) && !empty($_GET['eash'])){
$email = mysql_escape_string($_GET['email']);
$hash = mysql_escape_string($_GET['eash']);
or change your GET request to the next one:
http://localhost:8888/website/verify.php?Email=myemail#email.com&Hash=fe646d38bc2145ca6c3cf77d52820cd0
Change Hash to hash & Email to email. (Capitalized, but not in link that you send)
Also, your code is prone to sql injection attack as you are directly using the values in the url to query your database. Please use mysql_real_escape_string and perform some sanity checks before making the query.
there's capitals in the PHP whereas there are none in the link
$_GET['Email']
verify.php?email=myemail#email.com
Okay.. I am completely new to this PDO stuff.. I have tried to recreate my mysql script (working) to a PDO script (not working).. I have tested that my DB login informations is correctly programmed for PDO..
This is my PDO script...
<?
session_start();
//connect to DB
require_once("connect.php");
//get the posted values
$email=htmlspecialchars($_POST['email'],ENT_QUOTES);
$pass=md5($_POST['psw']);
//now validating the email and password
$sql - $conn_business->prepare( "SELECT email, password FROM members WHERE email='".$email."'");
$sql -> execute();
$count = $sql->rowCount();
$result = $sql -> fetch();
// Now use $result['rowname'];
$stmt = $conn_business->prepare("SELECT * FROM members WHERE email='".$email."'");
$stmt ->execute();
$act = $stmt -> fetch();
//if email exists
if($count > 0)
{
//compare the password
if(strcmp($result["password"],$pass)==0)
{
// check if activated
if($act["activated"] == "0")
{
echo "act"; //account is not activated yet
}
else
{
echo "yes"; //Logging in
//now set the session from here if needed
$_SESSION['email'] = $email;
}
}
else
echo "no"; //Passwords don't match
}
else
echo "no"; //Invalid Login
?>
And this is my old mysql script...
session_start();
require_once("connect.php");
//get the posted values
$email=htmlspecialchars($_POST['email'],ENT_QUOTES);
$pass=md5($_POST['psw']);
//now validating the username and password
$sql="SELECT email, password members WHERE email='".$email."'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$sql2="SELECT * FROM members WHERE email='".$email."'";
$result2=mysql_query($sql2);
$row2=mysql_fetch_array($result2);
$act = $row2['activated'];
//if username exists
if(mysql_num_rows($result)>0)
{
//compare the password
if(strcmp($row['password'],$pass)==0)
{
// check if activated
if($act == "0")
{
echo "act";
}
else
{
echo "yes";
//now set the session from here if needed
$_SESSION['email'] = $email;
}
}
else
echo "no";
}
else
echo "no"; //Invalid Login
Does anybody know, what I have done wrong? It is an automatically script.. It is called through AJAX and return data based on 'no', 'yes' and 'act' that tells the AJAX/jQuery script what to do.. As I said - the mysql script is working, so please if anyone could tell me what I have done wrong with the PDO script..
EDIT:
when it returns the data to the jQuery script, this should happen:
if yes: start session, redirect to page2.php with session started.
else if act: write in a field that the account is not activated.
else: write that email and password didn't match.
The thing is, that when I try to write the correct e-mail and password - it continues to write : "email and password didn't match" instead of redirecting.. When I say that it is not working it is because the mysql script does as described but the PDO script doesn't..
And I have tried to change the 'echo "no";' to 'echo "yes";' to see if the login would start anyway, but somehow it continues to write that the email and password didn't match..
SOLUTION:
I ahven't told this because I thought it was unnecessary, but the reason for it not to work was because of that i have had my old mysql code in comment marks on top of the page, so that the session_start command didn't work.. After deleting the old code it worked, but then I found something else to change, and that is in the PDO script when it is validating it says:
$sql - $conn_business->prepare( "SELECT email, password FROM members WHERE email='".$email."'");
and then I just changed the '-' after $sql to '=' and now, everything works perfectly... Anyhow thank you everybody.. hope this code can help others..
Did you even read the manual before you "started using" PDO?
That is not how prepared statements are supposed to be used! Your code is filled with SQL injections.
Why are you selecting same row twice ?
The strcmp() is not for checing if one string is identical to another.
And hashing passwords as simple MD5 is just a sick joke.
session_start();
//very stupid way to acquire connection
require_once("connect.php");
//get the posted values
$email = htmlspecialchars($_POST['email'],ENT_QUOTES);
if (filter_var( $email, FILTER_VALIDATE_EMAIL))
{
// posted value is not an email
}
// MD5 is not even remotely secure
$pass = md5($_POST['psw']);
$sql = 'SELECT email, password, activated FROM members WHERE email = :email';
$statement = $conn_business->prepare($sql);
$statement->bindParam(':email', $email, PDO::PARAM_STR);
$output = 'login error';
if ($statement->execute() && $row = $statement->fetch())
{
if ( $row['password'] === $pass )
{
// use account confirmed
if ( $row['activated'] !== 0 ) {
$output = 'not activated';
$_SESSION['email'] = $email;
}
$output = 'logged in';
}
}
echo $output;
i believe the second query in your scripts is not necessary you could simple do
SELECT * FROM members WHERE email=:EMAIL AND password=:PWS;
use bindParam method
$qCredentials->bindParam(":EMAIL",$EMAIL);
$qCredentials->bindParam(":PWS",$PWS);
then do more understable outputs rather than yes or no..
try "Unable to login: Invalid credentials supplied" for invalid types of values or "Unable to login: Invalid credentials, couldn't find user" for invalid user credentials.
You could try to start the session after the user has been successfully logged in your IF condition returning yes, and the methods
$PDOstatement->debugDumpParams()
$PDOstatement->errorInfo()
$PDOstatement->errorCode()
will help you understand what went wrong with a query!
Edit: I solved the problem! It was an issue unrelated to the code that I posted - I had an exit command in the script - but all of your advice still helped in other ways.
I'm trying to automatically send an e-mail to a user when they fill out their picks on a sports website. The early part of the script works: Their picks are correctly inserted or updated in the database. The script breaks when I try to pull the user's e-mail address from a table in the MySQL database and use it to send them a message. But what is very strange about this bug is that it doesn't result in any error messages, and for some reason prevents certain echo statements from running while allowing others.
Here's the relevant code:
...
//set variable for the userID, grabbed from the session array
$userID = $_SESSION['identifier'];
...
//write query to get user's e-mail from the database
$getEmail = "SELECT `email` FROM `useraccounts` WHERE `userID` = '".$userID."'";
//execute query
$result = $db->query($getEmail);
//check if query failed
try
{
if (!$result)
{
throw new customexception("Some kind of database problem occurred when trying to find your e-mail address.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//get the info from the row
$row = $result->fetch_assoc();
//check if function ran, catch exception if it failed
try
{
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get your e-mail address from your user record in the database.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//set e-mail variable
$email = $row['email'];
//set up e-mail information to send a record of their picks to the user
$toAddress = "$email";
$subject = "Your Picks";
$fromAddress = "From: picks#mysite.com";
//take the info the user submitted, format it for the e-mail, and assign to variable $mailContent
//the $winner1, $spread1, etc. variables are defined earlier in the function, and were successfully submitted into the database
$mailContent = "You picked $winner1 to win by $spread1 points, $winner2 to win by $spread2 points, $winner3 to win by $spread3 points, $winner4 to win by $spread4 points, and $winner5 to win by $spread5 points. \n".
"You can change your picks at any time before 1:00pm EST, February 27, 2011. Just go back to the form on the game page and enter your new picks. Good luck!";
//use wordwrap to limit lines of $mailContent to 70 characters
$mailContent = wordwrap($mailContent, 70);
//send the e-mail
$isMailed = mail($toAddress, $subject, $mailContent, $fromAddress);
//debug: check if mail failed
if (!$isMailed)
{
echo "Mail failed.";
}
//debug: echo $email to see if there's anything in there
echo "<p>E-mail: $email</p>";
//debug: echo $toAddress to see if there's anything in there
echo "<p>To address: $toAddress</p>";
//if everything succeeded, write reply and close database
echo $reply;
$db->close();
?>
Just to be clear, $userID is set correctly, because their picks enter the database like they're supposed to. None of the exceptions listed in the code come up, meaning the query seems to have run successfully. I checked the query again by copying it from the PHP code and running it directly on the MySQL database. When it ran directly, it found the correct e-mail address for every userID value I entered.
But the mail never gets delivered, and when I try to echo the $email and $toAddress variables to see if they're empty:
//debug: echo $email to see if there's anything in there
echo "<p>E-mail: $email</p>";
//debug: echo $toAddress to see if there's anything in there
echo "<p>To address: $toAddress</p>";
...nothing shows up. Not even an error message. And that doesn't necessarily mean that the variables are empty: Not even the labels are echoed.
I also tried the code with my personal e-mail hardcoded instead of $toAddress, and no mail was sent. So the mail function isn't working.
I should also note that the script still successfully echoes $reply (which is a string defined much earlier) at the end.
What's really strange is that the login script for my website uses an almost identical piece of code and works perfectly:
$getuserID = "SELECT `userID` FROM `useraccounts` WHERE `u_name` = '".$login."' AND `p_word` = SHA1('".$password."')";
$result = $db->query($getuserID);
//check if query ran, catch exception if it failed
try
{
if ($result === false)
{
throw new customexception("Some kind of database problem occurred when trying to find your user ID.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//get the info from the row
$row = $result->fetch_assoc();
//check if function ran, catch exception if it failed
try
{
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get info from your user record in the database.");
}
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
//set userID variable
$userID = $row['userID'];
//assign the session identifier and include successfullogin.html if all is well
$_SESSION['identifier'] = $userID;
And I used to have the signup script send me an e-mail every time I got a new user, so I know that mail() works in general with my hosting provider:
//set up static e-mail information
$toAddress = "myemail#mysite.com";
$subject = "Advance Sign-Up";
$mailContent = "Name: $firstName $lastName \n".
"Username: $username \n".
"Password: $password \n".
"E-mail: $email \n".
"Country: $country \n".
"State: $state \n".
"City: $city \n".
"ZIP: $zip \n";
$fromAddress = "From: $email";
...
mail($toAddress, $subject, $mailContent, $fromAddress);
This bug is completely mystifying to me. I wish I had some sort of error message to work with, at least. Can anyone see what's wrong?
It should be a comment but for the sake of formatting.
Your way of error handling is quite unusual.
If you really want to use exceptions, it should be done different way: one try block and multiple throws:
try
{
$getEmail = "SELECT `email` FROM `useraccounts` WHERE `userID` = '".$userID."'";
$result = $db->query($getEmail);
if (!$result)
{
throw new customexception("Some kind of database problem occurred when trying to find your e-mail address.");
}
$row = $result->fetch_assoc();
if ($row === false)
{
throw new customexception("Some kind of database problem occurred when trying to get your e-mail address from your user record in the database.");
}
$email = $row['email'];
$toAddress = "$email";
$subject = "Your Picks";
$fromAddress = "From: picks#mysite.com";
$mailContent = "yadda yadda yadda";
$mailContent = wordwrap($mailContent, 70);
mail($toAddress, $subject, $mailContent, $fromAddress);
}
catch (customexception $e)
{
include 'error.html';
echo $e;
$db->close();
include 'footer.php';
exit;
}
?>
Are you positive the database variables have contents? I use echo (or print) to quickly make sure the variables aren't empty. Are you positive your email code works? Try it with set values (such as your own personal e-mail) to make sure it works.
The best way out to ignore such notices is to ensure that the variables exist or in plain PHP, use isset(),if !isset() throw an exception/error and handle it properly.