Skip to content

Commit

Permalink
insert tokens in db and send email to user
Browse files Browse the repository at this point in the history
  • Loading branch information
kuldp18 committed Jan 3, 2024
1 parent 7d3ebcd commit 2e00079
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/vendor/
.env
67 changes: 67 additions & 0 deletions controllers/forgot_pass.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

//Load Composer's autoloader
require '../vendor/autoload.php';


use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

use Dotenv\Dotenv as Dotenv;


function is_email_invalid(string $email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return true;
}
return false;
}

function is_email_wrong(bool|array $result)
{
if (!$result) {
return true;
}
return false;
}


function send_reset_email($email, $reset_token)
{
$mail = new PHPMailer(true);
$dotenv = Dotenv::createImmutable(__DIR__ . "/../");
$dotenv->load();

try {
//Server settings
$mail->isSMTP(); //Send using SMTP
$mail->Host = $_ENV['SMTP_HOST']; //Set the SMTP server to send through
$mail->SMTPAuth = true; //Enable SMTP authentication
$mail->Username = $_ENV['SMTP_USERNAME']; //SMTP username
$mail->Password = $_ENV['SMTP_PASSWORD']; //SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`

//Recipients
$mail->setFrom($_ENV['SMTP_USERNAME'], 'Quirx Support');
$mail->addAddress($email); //Name is optional
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = 'Quirx Password Reset';
// generate reset link with token and email
$reset_link = "http://localhost/quirx/pages/reset_password.php?email=" . $email . "&token=" . $reset_token;

$mail->Body = "Dear user,<br><br>
Click on the link below to reset your password:<br><br>
<a href='$reset_link'>Reset Password</a><br><br>Regards,<br>Quirx Support";

$mail->send();
return true;
} catch (Exception $e) {
return false;
}
}
66 changes: 66 additions & 0 deletions includes/forgot_pass.inc.php
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
<?php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];

try {
require_once "./db_handler.inc.php";
require_once "../models/forgot_pass.inc.php";
require_once "../controllers/forgot_pass.inc.php";


$errors = [];

// check if email is empty
if (empty($email)) {
$errors["empty_input"] = "Please input your registered email";
}

// check if email is invalid
else if (is_email_invalid($email)) {
$errors["invalid_email"] = "Please enter a valid email address";
}

// check if email exists in database if email is not empty and is valid
if (empty($errors)) {
$result = get_user($pdo, $email);

// check if email is wrong
if (is_email_wrong($result)) {
$errors["email_not_found"] = "Email not found";
}
}


require_once "./config_session.inc.php";

if ($errors) {
$_SESSION["errors_forgot_password"] = $errors;
header('Location: ../pages/forgot_password.php');
die();
}

// generate reset token
$reset_token = bin2hex(random_bytes(32));
date_default_timezone_set("Asia/Kolkata");
$date = date("Y-m-d");

// insert reset token into database and send reset email

insert_reset_token($pdo, $email, $reset_token, $date);
send_reset_email($email, $reset_token);

// redirect to forgot password page with success message if everything is successful
header('Location: ../pages/forgot_password.php?reset=success');

//close connection

$pdo = null;
$stmt = null;
die();
} catch (PDOException $e) {
die("Query failed: " . $e->getMessage());
}
} else {
header("Location: ../index.php");
exit();
}
28 changes: 28 additions & 0 deletions models/forgot_pass.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

function get_user(object $pdo, string $email)
{
$query = "SELECT * FROM users WHERE email = :email"; // :email is a named placeholder
$stmt = $pdo->prepare($query); // prepare the query
$stmt->bindParam(":email", $email, PDO::PARAM_STR); // bind the $email variable to the :email placeholder
$stmt->execute(); // execute the query

$result = $stmt->fetch(PDO::FETCH_ASSOC); //fetch the result from the query
return $result;
}

function insert_reset_token($pdo, $email, $reset_token, $date)
{
// insert reset token into users table
$query = "UPDATE users SET reset_token = :reset_token, reset_token_expiration = :reset_token_expiration WHERE email = :email";
$stmt = $pdo->prepare($query);
//bind all parameters
$stmt->bindParam(":reset_token", $reset_token, PDO::PARAM_STR);
$stmt->bindParam(":reset_token_expiration", $date, PDO::PARAM_STR);
$stmt->bindParam(":email", $email, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result;
}
18 changes: 18 additions & 0 deletions pages/forgot_password.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php
require_once "../includes/config_session.inc.php";
require_once "../views/forgot_pass.inc.php";

?>


Expand Down Expand Up @@ -34,6 +36,22 @@
</form>
</main>

<?php

if (isset($_GET["reset"]) && $_GET["reset"] === "success") {
echo <<<HTML
<section class="modal modal--success">
<h1 class="modal__title">Password reset link has been sent to your registered email.</h1>
<span class="modal__close modal__close--success">X</span>
</section>
HTML;
}
?>

<?php
check_and_print_forgot_password_errors();
?>


<script src="../js/close_modal.js"></script>
</body>
Expand Down
14 changes: 14 additions & 0 deletions pages/reset_password.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
21 changes: 21 additions & 0 deletions views/forgot_pass.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

function check_and_print_forgot_password_errors()
{

if (isset($_SESSION["errors_forgot_password"])) {
$errors = $_SESSION["errors_forgot_password"];
if (count($errors) > 0) {
echo "<section class='modal modal--error'>";
echo "<h1 class='modal__title'>Unable to reset your password: </h1>";
echo "<span class='modal__close modal__close--error'>X</span>";
foreach ($errors as $error) {
echo "<p class='modal__item'>$error</p>";
}
echo "</section>";
unset($_SESSION["errors_forgot_password"]);
}
}
}

0 comments on commit 2e00079

Please sign in to comment.