· 6 years ago · Mar 14, 2019, 07:24 AM
1<?php
2
3/********************/
4/* RequestReset.php */
5/********************/
6
7<form id="frmRequestReset" method="post" action="./RequestResetDAO.php">
8 <!-- User email address -->
9 <label for="userEmail">Email</label>
10 <!-- user email must match pattern defined by regex pattern, all "auto" functionality disable to mitigate input error -->
11 <input id="txtEmail" type="email" name="email" placeholder="Email" autocapitalize="none"
12 autocorrect="off" autocomplete="off" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
13 required="required">
14 <button id="pwReset" class="btn btnGreen" type="submit">Request Reset</button>
15</form>
16
17/***********************/
18/* RequestResetDAO.php */
19/***********************/
20
21if($_SERVER['REQUEST_METHOD'] == 'POST') {
22
23 if(isset($_POST['email']) && !empty($_POST['email'])) { // if a value exists in sent data
24 // Set variable values
25 $email = mysqli_real_escape_string($connection, $_POST['email']);
26
27 $result = mysqli_query($connection, "SELECT `user_id`, `email` FROM `tbl_members` WHERE email='$email'") or die(mysqli_error($connection));
28
29 if(@mysqli_num_rows($result) == 1) { // if a match was found
30 // list is a shortcut for assigning variables ie. $user_id = $row[0]
31 list($user_id, $user_email) = mysqli_fetch_array($result, MYSQLI_NUM);
32 mysqli_free_result($result);
33
34 // create a random string as verification token
35 $token = openssl_random_pseudo_bytes(16);
36 $token = bin2hex($token);
37
38 $timestamp = date('Y-m-d H:i:s');
39 $set_date = strtotime($timestamp);
40 $date = date("Y-m-d H:i:s", $set_date);
41
42 $sql = "INSERT INTO `tbl_password_reset_request` (`user_id`, date_time_requested, token) VALUES ($user_id, '$date', '$token')";
43 $query = mysqli_query($connection, $sql) or die(mysqli_error($connection));
44
45 $reset_id = mysqli_insert_id($connection);
46
47 $verifyLocation = "url/dir/Reset/VerifyResetDAO.php";
48 $sendLink = $verifyLocation . '?uid=' . $user_id . '&id=' . $reset_id . "&request=" . $token;
49
50 $subject = "Password Reset - (dot)chat";
51
52 $body = "
53 A password reset has been requested for $user_email on (dot)chat.
54
55 You can reset your password by following the link below and entering a new password:
56 $sendLink
57
58 If you did not request this password reset then you can safely ignore this email.
59 ";
60
61 $body = wordwrap($body, 70); // truncate the line length as per php.net mail() documentation
62
63
64 mail($user_email, $subject, $body);
65
66 closeConnection($connection);
67 header('Location: url/dir/Reset/ResetStatus.php?requestResult=received');
68 exit();
69 } else {
70 // return false;
71 closeConnection($connection);
72 header('Location: url/dir/Reset/ResetStatus.php?requestResult=not-found');
73 exit();
74 }
75 }
76}
77
78/***************************************************/
79/* VerifyResetDAO.php (directed to from email URL) */
80/***************************************************/
81
82session_start(); // start session to create a session for reset to be completed
83
84$connection = openConnection();
85
86$user_id = isset($_GET['uid']) ? trim($_GET['uid']) : '';
87$token = isset($_GET['request']) ? trim($_GET['request']) : '';
88$request_id = isset($_GET['id']) ? trim($_GET['id']) : '';
89
90//Now, we need to query our password_reset_request table and
91//make sure that the GET variables we received belong to
92//a valid forgot password request.
93
94$sql = "SELECT `request_id`, `user_id`, `date_time_requested`
95 FROM `tbl_password_reset_request`
96 WHERE `request_id`=$request_id AND `user_id`=$user_id AND `token`='$token' AND `expired`=0";
97
98$query = mysqli_query($connection, $sql) or die(mysqli_error($connection));
99
100if(@mysqli_num_rows($query) == 1) {
101
102 //The request is valid, so give them a session variable
103 //that gives them access to the reset password form.
104 $_SESSION['user_id_reset_pw'] = $user_id;
105
106 //Redirect them to your reset password form.
107 header('Location: CompleteReset.php');
108 exit;
109} else {
110 header('Location: ./ResetStatus.php?resetResult=fail');
111 exit;
112}
113
114/******************************************************************************/
115/* ResetStatus.php (if verify has failed, give reason dependent on GET value) */
116/******************************************************************************/
117
118<main>
119 <?php if(isset($_GET['resetResult']) && $_GET['resetResult'] == 'fail'): ?>
120 <h2>Password Reset Failed</h2>
121 <p class="warning">We recommend trying a <a href="./RequestReset.php">new password reset</a>.</p>
122 <p class="warning">If this doesn't work, please contact <a href="#">support</a> with details of your full name and email address.</p>
123 <?php endif; ?>
124
125 <?php if(isset($_GET['requestResult']) && $_GET['requestResult'] == 'received'): ?>
126 <h2>We got your reset request!</h2>
127 <p class="success">Your password reset request was successful. Please check your email inbox for the reset link.</p>
128 <?php endif; ?>
129
130 <?php if(isset($_GET['requestResult']) && $_GET['requestResult'] == 'not-found'): ?>
131 <h2>Request Failed</h2>
132 <p class="warning">The email you entered was not found in our records. If this is an error, please contact <a href="#">support</a>.</p>
133 <?php endif; ?>
134</main>
135
136/**********************************************************************************/
137/* CompleteReset.php (if verify success, send user to page to enter new password) */
138/**********************************************************************************/
139
140<form id="userVerifyPwForm" method="post" action="./CompleteResetDAO.php"> <!-- submit form as POST as it contains user information -->
141 <!-- Password Entry -->
142 <label for="enter_password" class="field-label">Password</label>
143 <!-- set input type as password to notify browser that this is password entry and obsfuscate input -->
144 <input class="field-text" type="password" id="enter_assword" name="password" placeholder="Enter a secure password"
145 pattern=".{8,}" required="required" />
146
147 <label for="confirm_password" class="field-label">Confirm Password</label>
148 <input class="field-text" type="password" id="confirm_password" name="confirm_password"
149 placeholder="Confirm the password" required="required" />
150
151 <!-- Password strength and complexity -->
152 <label for="pw-complexity" class="field-label">Strength: </label><span id="pw-strength">None</span>
153 <meter max="4" id="pw-complexity"></meter>
154
155 <!-- Submit form -->
156 <button type="submit" class="btnGreen">Reset Password</button>
157</form>
158
159/**************************************************************/
160/* CompleteResetDAO.php (Update password details in database) */
161/**************************************************************/
162<?php
163session_start();
164
165$connection = openConnection();
166
167$user_id = $_SESSION['user_id_reset_pw'];
168$password = mysqli_real_escape_string($connection, (password_hash($_POST['password'], PASSWORD_DEFAULT)));
169
170$sql = "UPDATE `tbl_members`
171 SET `password`='$password'
172 WHERE `user_id`=$user_id";
173
174$query = mysqli_query($connection, $sql) or die(mysqli_error($connection));
175
176if(mysqli_affected_rows($connection) == 1) {
177
178 $expire = mysqli_query($connection, "UPDATE `tbl_password_reset_request` SET `expired`=1 WHERE `user_id`=$user_id") or die(mysqli_error($connection));
179 header("Location: ../login.php?pwReset=success");
180 exit;
181
182} else {
183
184 header("Location: ./ResetStatus.php?resetResult=fail");
185 exit;
186
187}