PHP sending email from an include file - php

I'd like to create an includes file which sends an email to user when he logs in. This is how my users get authenticated:
1- my authenticate include file chooses users password in the database based on the user email the login.php passes.
2- if the user is authenticated i just create 2 session variables user_id and user_name
So what I'd like to do is, once the user is authenticated I would like to call my send_login_email function within my email_function include file.
I'm also planning to create more email functions whereby I send an email to user for other notifications, so it's important for the user_email to be saved in a session variable.
This is what my send email includes file lookslike at the moment:
<?php
require_once('../includes/authenticate.inc.php');
function login_mail($_SESSION['uemail'])
{
$to = $_SESSION['uemail'];
$subject = "login";
$message = <?php $user_name ?>, You have logged in.";
$from = "example#email.com";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
}
?>
In my authenticate file I select user details as shown below:
$sql = 'SELECT salt, user_password, user_role, user_name, person_id FROM users WHERE user_email = ?';
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
// bind the input parameter
$stmt->bind_param('s', $user_email);
// bind the result, using a new variable for the password
$stmt->bind_result($salt, $storedPwd, $user_role, $user_name, $person_id);
$stmt->execute();
$stmt->fetch();
and within the if statement that checks if the password is correct i have the following code-I'm also calling the email function here:
$_SESSION['start'] = time();
session_regenerate_id();
header("Location: $redirect");
// get the user's name and id
$_SESSION['name'] = $user_name;
$_SESSION['id'] = $person_id;
$_SESSION['uemail'] = $user_email;
require_once('../includes/email_func.inc.php'); //new stuff
login_mail($_SESSION['uemail']);
When I login sucessfully I do not receive an email.
I'm new to using functions and emails within php and Id really appreciate some help please.
Thank you

Change the function as follows:
function login_mail($to, $user_name)
{
$subject = "login";
$message = "$user_name, You have logged in.";
$from = "example#email.com";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
}
Then call it as:
login_mail($_SESSION['uemail'], $user_name);
The arguments of a function must be ordinary variables, not array elements. You were trying to reference $user_name, which didn't exist in the function. And <?php ...?> is not used in ordinary assignments, it's used when switching from HTML output to PHP code.
Make sure you have error reporting enabled, you should have gotten errors from those mistakes.

Related

Why is the else statement not working inside a foreach loop in php?

I'm building a script that helps a user reset their password if they forgot it. This specific script firstly checks if the email the user wants the token sent to exists. If it does, the token is inserted into a tokens table.
I am still developing and testing, so I haven't created the mail function yet.
I have an if statement that checks if the email exists, then creates the token. If it doesn't exists, it shows the page to enter an email address again. The if statement is working perfect, but the else is not. I'm pasting the entire file here, though it is only the part with the foreach statement that concerns our problem.
The else statement shows absolutely nothing.
<?php
//generate tokens to verify users who forgot their passwords. Send these tokens to the user's email
require $_SERVER['DOCUMENT_ROOT'] . "/phonebook/config.php";
//get user's email
$mail = htmlspecialchars($_POST['email']);
//generate token
$token = $token = openssl_random_pseudo_bytes(20);
//Convert the binary data into something more readable
$token = bin2hex($token);
//check if the email entered exists
$check = $conn->prepare("SELECT email FROM users WHERE email = :email");
$check->bindParam(":email", $mail);
$check->execute();
foreach ($check as $confirm) {
if ($confirm['email'] == $mail) {
//send tokens to the database
$sql = $conn->prepare("INSERT INTO tokens (email, token)
VALUES(:email, :token)");
$sql->bindParam(":email", $mail);
$sql->bindParam(":token", $token);
$sql->execute();
echo "<h2>Enter security code</h2>
A security code has been sent to the email addres $mail. Enter that code in the box below:
<form action = 'http://localhost/phonebook/controls/forgotpassword.php' method = 'post'>
<input type = 'hidden' name = 'email' value = '$mail'>
<input type = 'text' name = 'token'> <br>
<input type = 'submit' value = 'Reset password'>
</form>
Did not receive code? Go <a href = 'http://localhost/pages/forgotpassword.php'here</a>";
} else {
echo "That email does not exist. Please try again.";
include_once "$paste/phonebook/pages/forgotpassword.php";
}
}
Spotting three problems here.
You compare $mail which is encoded using htmlspecialchars() against an email address which is probably not encoded.
You fetch several rows instead of one:
//check if the email entered exists
$check = $conn->prepare("SELECT email FROM users WHERE email = :email LIMIT 1");
$check->bindParam(":email", $mail);
$check->execute();
$confirm = $check->fetch()
if (isset($confirm['email']) && $confirm['email'] === $mail) {
//send tokens to the database
You tell the "user" that the email address does exist in your system; this is a privacy and data security concern. Just send something like "If the entered email address is in our system, we just sent a password reset link to it."

Random numbers are generated twice when verifying email

I'm new to PHP. I'm currently doing an email validation. My code is supposed to generate a random number, send to user via email and verify it when user enters.
Here is my code:
<?php
require 'PHPMailer/PHPMailerAutoload.php';
session_start();
// initializing variables
$email = $_SESSION ['email'];
$user_code = "";
$errors = array();
// generate a four digit random number
$gen_code = strval (rand (10000, 99999));
// send code to user email
// connect to the database
$db = mysqli_connect('localhost', 'root', '', 'register');
// REGISTER USER
if (isset($_POST['email_confirm'])) {
// receive all input values from the form
$user_code = mysqli_real_escape_string($db, $_POST['code']);
// check whether both codes match
if ($user_code != $gen_code) { array_push($errors, "The codes do not match"); }
else {
// set isConfirmed == true
if (count($errors) == 0) {
$query = "UPDATE user_database SET isConfirmed = true WHERE email = '$email'";
mysqli_query($db, $query);
$_SESSION['email'] = $email;
header('location: user_details.php');
}
}
}
?>
Here email_confirm is the name of my submit button and code is the name of text box.
It all works fine when page is first loaded. I get an email with a random integer.
Problem starts when I click my submit button. I receive another email with different number and the number I already entered is not equal to the one I received from email.
Please help
If this is a simpler and an experimental application, you should store gen_code in this session soon after its sent to the user confirmation email. Otherwise, store the code in db and retrieve it when your application receives email confirm POST request and compare the code that was sent by the user against the session or db wherever you'd stored it.
if (isset($_POST['email_confirm'])) {
// receive all input values from the form
$code = $_SESSION['gen_code']; // in case you would wish to store and retrieve code from db, replace this code with one which retrieved from db by email id... SELECT code from user where email=$email
$user_code = mysqli_real_escape_string($db, $_POST['code']);
// check whether both codes match
if ($user_code != $code) {
array_push($errors, "The codes do not match");
} else {
if (count($errors) == 0) {
$query = "UPDATE user_database SET isConfirmed = true WHERE email = '$email'";
mysqli_query($db, $query);
$_SESSION['email'] = $email;
header('location: user_details.php');
}
}
}

undefined index on $_SESSION and all $_POST part

I want to make register form for my website. But I faced error and this is my code:
<?php
/* Registration process, inserts user info into the database
and sends account confirmation email message
*/
// Set session variables to be used on profile.php page
$_SESSION['email'] = $_POST['email'];
$_SESSION['first_name'] = $_POST['firstname'];
$_SESSION['last_name'] = $_POST['lastname'];
$mysqli = mysqli_connect("localhost","root","","data");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// Escape all $_POST variables to protect against SQL injections
$first_name = $mysqli->escape_string($_POST['firstname']);
$last_name = $mysqli->escape_string($_POST['lastname']);
$email = $mysqli->escape_string($_POST['email']);
$password = $mysqli->escape_string(password_hash($_POST['password'],
PASSWORD_BCRYPT));
$hash = $mysqli->escape_string( md5( rand(0,1000) ) );
// Check if user with that email already exists
$result = $mysqli->query("SELECT * FROM login WHERE email='$email'") or
die($mysqli->error());
// We know user email exists if the rows returned are more than 0
if ( $result->num_rows > 0 ) {
$_SESSION['message'] = 'User with this email already exists!';
header("location: error.php");
}
else { // Email doesn't already exist in a database, proceed...
// active is 0 by DEFAULT (no need to include it here)
$sql = "INSERT INTO login (first_name, last_name, email, password, hash)"
."VALUES ('$first_name','$last_name','$email','$password', '
$hash')";
// Add user to the database
if ( $mysqli->query($sql) ){
$_SESSION['active'] = 0; //0 until user activates their account with
verify.php
$_SESSION['logged_in'] = true; // So we know the user has logged in
$_SESSION['message'] =
"Confirmation link has been sent to $email, please verify
your account by clicking on the link in the message!";
// Send registration confirmation link (verify.php)
$to = $email;
$subject = 'Account Verification ( clevertechie.com )';
$message_body = '
Hello '.$first_name.',
Thank you for signing up!
Please click this link to activate your account:
http://localhost/login-system/verify.php?email='.$email.'&
hash='.$hash;
mail( $to, $subject, $message_body );
header("location: profile.php");
}
else {
$_SESSION['message'] = 'Registration failed!';
header("location: error.php");
exit();
}
}
The error state that:
Undefined index: firstname, lastname, email, password
at line set session variables and line for escape all $_POST variables to protect SQL injection. Anyone know how to fix this error. Thank you.
You are missing session_start() at the start of your code, this needs to be called before you echo/output anything to the browser.
You'll also need to add session_start to your error.php to read from the session there.
When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers...
The read callback will retrieve any existing session data (stored in a special serialized format) and will be unserialized and used to automatically populate the $_SESSION superglobal when the read callback returns the saved session data back to PHP session handling.
See: http://php.net/manual/en/function.session-start.php
If(isset($_POST['first_name']) && isset($_POST['last_name']) && isset($_POST['email'])){
// Escape all $_POST variables to protect against SQL injections
$first_name = $mysqli->escape_string($_POST['firstname']);
$last_name = $mysqli- >escape_string($_POST['lastname']);
}
In PHP, a variable or array element which has never been set is different from one whose value is null; attempting to access such an unset value is a runtime error.
That's what you're running into: the array $_POST does not have any element at the index "username", so the interpreter aborts your program before it ever gets to the nullity test.

PDO email verification

I am trying to make a user registration script.
In my registration.php script, I validate user inputs then insert them into database. I then want to send the user a verification link in an email using SMTP with:
$user_activation_hash = sha1(uniqid(mt_rand(), true)); //creating ramdom string
$mail = new PHPMailer;
$mail->IsSMTP();
$mail->CharSet = 'UTF-8';
$mail->Host = "info"; // SMTP server
$mail->Username = "info"; // SMTP account username
$mail->Password = "info"; // SMTP account password
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Port = info; // set the SMTP port for the server
$mail->From = "info"; //the email the mail comes from
$mail->FromName = "someName"; //what name should be shown at the email
$mail->AddAddress($email); //where the mail should be sent to
$mail->Subject = "email validation"; //subject of the mail
//how the link should look in the mail the "url" should point to the verification.php file
$link = "url path to my verification.php script".'?verification_code='.urlencode($user_activation_hash);
//the message in the mail with the above link
$mail->Body = "Please click on this link to activate your account:".' '.$link;
if(!$mail->Send()) {
echo "there was an error sending the mail" . ' ' . $mail->ErrorInfo;
//if there is an error sending the mail then I delete it here
return false;
} else {
//here I update the user with the new random created string
$sql = 'UPDATE `user` SET verification = :verification WHERE Id = :Id';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
$stmt->bindParam(':verification', $user_activation_hash, PDO::PARAM_STR);
$stmt->execute();
$dbh = null;
return true;
}
All of this works fine so far the registered user gets an email with the random link created.
here is an example of the link the user gets: http://url/to/verification.php?verification_code=80371b8ff9b0d5fb444f4be68c8b5a0d9757603b
When they click the link they are directed to my verification.php script:
if(!empty($_GET['verification_code']) && isset($_GET['verification_code'])){
$verificationCode = $_GET['verification_code'];
//check the database for the verification code from the link
$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':verification', $verificationCode, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();
$Id = $row['Id'];
if (empty($row)){
echo "the account was not found";
}else{
//if they match. make the user active in db
$sql = 'UPDATE user SET isActive = 1, verification = NULL WHERE Id=:Id';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();
echo "The account has been activated!";
}
}
}
Okay so here is my headache and I hope I can explain it properly:
All of this works. When I create the first user it works after registration I can see a verification code in the database and when I click the link it gets activated. But the following users getting registered is being activated at once when I hit the registration.php script! It is like both scripts are being run at once and then making the activation link completely unnecessary.
I have no idea what causes this behavior. Is it because my pdo connection isn't closed properly from my first script? Is it because PHP normally just runs all scripts in a directory when only one I called? Is it because I don't understand how the $_GET function works?
I can't possible find a way why this shouldn't work so here is some of the things I have already tried:
I have tried registering a user with the verification.php script commented out then first uncomment it and click the link being send when the user is registered. this works.
I have tried moving my verification.php script to another folder. Didn't help anything
I have tried closing the connection in the verification.php then made a new PDO after. this didn't work either.
I have tried alot of ways to change the $_GET method but no success.
UPDATE!: now i have tried to see exactly where the code breaks and i noticed something unusual. when the registration.php is run the user is set in the database as not active. As soon as i recieve the email with the link. the user is set to active, without ever clicking the link
Please tell me someone out there knows what's up.
the problem is the first user when registered the table was completely empty
but when the second user registered and enter the verification.php with no get value it searches for the user that has verification = null (the first user)
and complete the code esily so all you need is to modify your code
just edit the first query in the verification.php file instead of this
$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification';
do it like this
$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';
for the checking that if the value is sent or not
if(isset($_GET["verification_code"]){
$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':verification', $verificationCode, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();
$Id = $row['Id'];
if ($Id == null){
echo "the account was not found";
}else{
// check if the verificationcode found in the database, matches the verificationcode from the link
if ($row['verification'] !== $verificationCode) {
//checking if it already exists and if there is an error then deleting the user
} else {
//if they match. make the user active in db
$sql = 'UPDATE user SET isActive = 1, verification = NULL WHERE Id=:Id';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();
echo "The account has been activated!";
}
}
}

Php/sqli executed by referencing the link in a send email function?

So i have this page called unsubscribe_process which when given a url query, e.g. www.example.com/unsubscribe_process.php?passkey=123, it will then find and delete the member using mysqli.
The problem I am having is with my unsubscribe.php page. It includes a form and allows the user to put in their email. The form will be submitted, and then an email is sent to the user linking the unsubscribe_process.php page with the specific query and passkey for that user. The hope would be then the user checks their email and clicks the link and then the unsubscribe_process page would remove them from the database.
Back to subscribe.php page, it has no DELETE slqi function anywhere in it, however somehow the user gets deleted after submitted the form. It seems to execute the www.example.com/unsubscribe_process.php?passkey=123 within subscribe.php, without the user having to click on it in the email.
Here is the function that is executed once a user submits their email:
function sendEmail() {
//enter details into db automatically
$con = #require './../dbcon.php';
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
$email = mysqli_real_escape_string($dbConnection, $_POST['email']);
$atIndex = strrpos($email, "#");
$emailindex = substr($email, 0, $atIndex);
if ($email=='')
{
echo "<p>No Username has been specified. Please <a href=http://www.example.com/unsubscribe.php> try again.</a></p>";
}
//check if username exists in database
$result = mysqli_query($DB,"SELECT * FROM members WHERE user='". $emailindex ."'") or die(mysql_error());
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_array($result);
$passkey = $row['confirmcode'];
//if password is set then erase password and send an email to user to update details/create new password.
if ($row['paid'] ==1){
$to=$email;
$subject="Unsubscribe";
$header="from: webmaster#example.com";
$message.="You can now unsubscribe yourself in one click with the following link: \r\n";
$message.="http://www.example.com/unsubscribe_process.php?passkey=$passkey\r\n\r\n";
$sentmail = mail($to,$subject,$message,$header);
if($sentmail){
echo "</br><p class='maintextSubmit' align='center'> Please check your email to complete the process.</p>";
}
else echo "</br><p class='maintextError' align='center'> An error occurred. Please try again.</p>";
}
mysqli_close($DB);
}
}
}
SO: Does php execute the link for me when sending the email? This is literally the only reference to the unsubscribe_process.php page anywhere on the subscribe.php page. Why does the unsubscribe_process.php?passkey=$passkey get executed when the email is sent? How can I prevent this from happening (aka only when the link is clicked via the email)? Am I missing something?

Categories