In my current application, I have a table called users
which shows a list of users that has access to my app. However, there seems to be a lingering issue whenever I update a user’s password.
My table structure looks like this:
And here is my code. First is the edit user form:
<?php
include('nav/head.php');
if($role_id != '1') {
header('Location: error.php');
exit();
}
// Define user data by User ID
if(isset($_GET['edit_id'])) {
$id = $_GET['edit_id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id=:id");
$stmt->execute(array(":id" => $id));
$rowUser = $stmt->fetch(PDO::FETCH_ASSOC);
} else {
$id = null;
$rowUser = null;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" type="text/css" href="css/toggle.css">
<title>CascoTax | <?php print($rowUser['first_name'] . " " . $rowUser['last_name']); ?></title>
<?php include('nav/header.php'); ?>
<h1 class="h3 mb-2 text-gray-800"> Edit <?php print($rowUser['first_name'] . " " . $rowUser['last_name']); ?></h1>
<br>
<form action="api/users/edit.php" method="post">
<input type="hidden" class="form-control" id="id" name="id" placeholder="" value="<?php print($rowUser['id']); ?>" maxlength="255" autocomplete="off" readonly/>
<div class="form-group">
<label for="role_id">User Status</label>
<!-- <input type="text" class="form-control" id="role_id" name="role_id" placeholder="" value="<?php print($rowUser['role_id']); ?>" maxlength="255" autocomplete="off" /> -->
<?php
if($_SESSION['id'] == $rowUser['id']) {
echo '<select disabled class="form-control" id="status" name="status">
<option selected value="1">Active</option>
<option value="0">Inactive</option>
</select>';
echo '<p style="color: #a40000;">The user status cannot be changed</p>';
} else {
if($rowUser['status'] === '1') {
echo '<select class="form-control" id="status" name="status">
<option selected value="1">Active</option>
<option value="0">Inactive</option>
</select>';
} elseif ($rowUser['status'] === '0') {
echo '<select class="form-control" id="status" name="status">
<option value="1">Active</option>
<option selected value="0">Inactive</option>
</select>';
}
}
?>
</div>
<div class="form-group">
<label for="role_id">User Role</label>
<!-- <input type="text" class="form-control" id="role_id" name="role_id" placeholder="" value="<?php print($rowUser['role_id']); ?>" maxlength="255" autocomplete="off" /> -->
<?php
if($_SESSION['id'] == $rowUser['id']) {
echo '<select disabled class="form-control" id="role_id" name="role_id">
<option selected value="1">Administrator</option>
<option value="2">Operator</option>
</select>';
echo '<p style="color: #a40000;">The user role cannot be changed</p>';
} else {
if($rowUser['role_id'] === '1') {
echo '<select class="form-control" id="role_id" name="role_id">
<option selected value="1">Administrator</option>
<option value="2">Operator</option>
</select>';
} elseif ($rowUser['role_id'] === '2') {
echo '<select class="form-control" id="role_id" name="role_id">
<option value="1">Administrator</option>
<option selected value="2">Operator</option>
</select>';
}
}
?>
</div>
<div class="form-group">
<label for="first_name">First Name</label>
<input type="text" class="form-control" id="first_name" name="first_name" placeholder="" value="<?php print($rowUser['first_name']); ?>" maxlength="255" autocomplete="off" />
</div>
<div class="form-group">
<label for="last_name">Last Name</label>
<input type="text" class="form-control" id="last_name" name="last_name" placeholder="" value="<?php print($rowUser['last_name']); ?>" maxlength="14" autocomplete="off" />
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" class="form-control" id="email" name="email" placeholder="" value="<?php print($rowUser['email']); ?>" autocomplete="off" />
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" name="username" placeholder="" value="<?php print($rowUser['username']); ?>" autocomplete="off" />
</div>
<hr style="background-color: #a40000;">
<div class="form-group">
<label for="password">New Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="" autocomplete="off" />
</div>
<div class="form-group">
<label for="confirm_pwd">Confirm Password</label>
<input type="password" class="form-control" id="confirm_pwd" name="confirm_pwd" placeholder="" autocomplete="off" />
</div>
<input type="submit" name="btn_save" class="btn btn-success" value="Save">
<input type="submit" name="btn_cancel" class="btn btn-danger" value="Cancel">
</form>
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<?php include('nav/footer.php'); ?>
</html>
and here is the API that processes the request:
<?php
include ('../dbconnect.php');
// Update
if(!empty($_POST['password'])) {
$stmt = $pdo->prepare("UPDATE users SET role_id = :role_id, first_name = :first_name, last_name = :last_name, email = :email, username = :username, password = :password, status = :status WHERE id = :id");
$stmt->bindParam(':role_id', $role_id);
$stmt->bindParam(':first_name', $first_name);
$stmt->bindParam(':last_name', $last_name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':status', $status);
$stmt->bindParam(':id', $id);
// Update User Info
if(isset($_POST['btn_save'])) {
if ($_POST['password'] != $_POST['confirm_pwd']) {
die ('The two password provided do not match.');
}
$role_id = $_POST["role_id"];
$first_name = $_POST["first_name"];
$last_name = $_POST["last_name"];
$email = $_POST["email"];
$username = $_POST["username"];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$status = $_POST["status"];
$id = $_POST["id"];
$stmt->execute();
header('Location: ../../users.php');
}
// Return to Users Page
if(isset($_POST['btn_cancel'])) {
header('Location: ../../users.php');
}
} else {
$stmt = $pdo->prepare("UPDATE users SET role_id = :role_id, first_name = :first_name, last_name = :last_name, email = :email, username = :username, status = :status WHERE id = :id");
$stmt->bindParam(':role_id', $role_id);
$stmt->bindParam(':first_name', $first_name);
$stmt->bindParam(':last_name', $last_name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':status', $status);
$stmt->bindParam(':id', $id);
// Update User Info
if(isset($_POST['btn_save'])) {
$role_id = $_POST["role_id"];
$first_name = $_POST["first_name"];
$last_name = $_POST["last_name"];
$email = $_POST["email"];
$username = $_POST["username"];
$status = $_POST["status"];
$id = $_POST["id"];
$stmt->execute();
header('Location: ../../users.php');
}
// Return to Users Page
if(isset($_POST['btn_cancel'])) {
header('Location: ../../users.php');
}
}
?>
Originally, I had an error screen which would appear if a specific user without the proper user role could not access the page. I can update another user’s password and the password changes without any problems. However, when I go to change the password of the logged in user, the role_id in the table goes from 1
to NULL
, the status value goes from 1
to 0
and the error page in my script appears out of format.
This prevents the user from being able to log in again unless the values are manually changed in the database. Why does this happen?