change password added

This commit is contained in:
Ryan
2025-03-21 15:46:55 -04:00
committed by GitHub
parent cef96f0047
commit 53bb72f4ab
4 changed files with 161 additions and 4 deletions

61
auth.js
View File

@@ -41,8 +41,8 @@ function initAuth() {
const headerButtons = document.querySelector(".header-buttons"); const headerButtons = document.querySelector(".header-buttons");
if (headerButtons) { if (headerButtons) {
// Insert after the third child if available. // Insert after the third child if available.
if (headerButtons.children.length >= 4) { if (headerButtons.children.length >= 5) {
headerButtons.insertBefore(restoreBtn, headerButtons.children[4]); headerButtons.insertBefore(restoreBtn, headerButtons.children[5]);
} else { } else {
headerButtons.appendChild(restoreBtn); headerButtons.appendChild(restoreBtn);
} }
@@ -193,6 +193,63 @@ function initAuth() {
document.getElementById("cancelRemoveUserBtn").addEventListener("click", function () { document.getElementById("cancelRemoveUserBtn").addEventListener("click", function () {
closeRemoveUserModal(); closeRemoveUserModal();
}); });
document.getElementById("changePasswordBtn").addEventListener("click", function() {
// Show the modal.
document.getElementById("changePasswordModal").style.display = "block";
});
document.getElementById("closeChangePasswordModal").addEventListener("click", function() {
// Hide the modal.
document.getElementById("changePasswordModal").style.display = "none";
});
document.getElementById("saveNewPasswordBtn").addEventListener("click", function() {
const oldPassword = document.getElementById("oldPassword").value.trim();
const newPassword = document.getElementById("newPassword").value.trim();
const confirmPassword = document.getElementById("confirmPassword").value.trim();
if (!oldPassword || !newPassword || !confirmPassword) {
showToast("Please fill in all fields.");
return;
}
if (newPassword !== confirmPassword) {
showToast("New passwords do not match.");
return;
}
// Prepare the data to send.
const data = { oldPassword, newPassword, confirmPassword };
// Send request to changePassword.php.
fetch("changePassword.php", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": window.csrfToken
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
showToast(result.success);
// Optionally clear form fields and close modal.
document.getElementById("oldPassword").value = "";
document.getElementById("newPassword").value = "";
document.getElementById("confirmPassword").value = "";
document.getElementById("changePasswordModal").style.display = "none";
} else {
showToast("Error: " + (result.error || "Could not change password."));
}
})
.catch(error => {
console.error("Error changing password:", error);
showToast("Error changing password.");
});
});
} }
function checkAuthentication(showLoginToast = true) { function checkAuthentication(showLoginToast = true) {

85
changePassword.php Normal file
View File

@@ -0,0 +1,85 @@
<?php
// changePassword.php
require 'config.php';
header('Content-Type: application/json');
// Make sure the user is logged in.
session_start();
if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
echo json_encode(["error" => "Unauthorized"]);
exit;
}
$username = $_SESSION['username'] ?? '';
if (!$username) {
echo json_encode(["error" => "No username in session"]);
exit;
}
// CSRF token check.
$headers = array_change_key_case(getallheaders(), CASE_LOWER);
$receivedToken = isset($headers['x-csrf-token']) ? trim($headers['x-csrf-token']) : '';
if ($receivedToken !== $_SESSION['csrf_token']) {
echo json_encode(["error" => "Invalid CSRF token"]);
http_response_code(403);
exit;
}
// Get POST data.
$data = json_decode(file_get_contents("php://input"), true);
$oldPassword = trim($data["oldPassword"] ?? "");
$newPassword = trim($data["newPassword"] ?? "");
$confirmPassword = trim($data["confirmPassword"] ?? "");
// Validate input.
if (!$oldPassword || !$newPassword || !$confirmPassword) {
echo json_encode(["error" => "All fields are required."]);
exit;
}
if ($newPassword !== $confirmPassword) {
echo json_encode(["error" => "New passwords do not match."]);
exit;
}
// Path to users file.
$usersFile = USERS_DIR . USERS_FILE;
if (!file_exists($usersFile)) {
echo json_encode(["error" => "Users file not found"]);
exit;
}
// Read current users.
$lines = file($usersFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$userFound = false;
$newLines = [];
foreach ($lines as $line) {
list($storedUser, $storedHash, $storedRole) = explode(':', trim($line));
if ($storedUser === $username) {
$userFound = true;
// Verify the old password.
if (!password_verify($oldPassword, $storedHash)) {
echo json_encode(["error" => "Old password is incorrect."]);
exit;
}
// Hash the new password.
$newHashedPassword = password_hash($newPassword, PASSWORD_BCRYPT);
// Rebuild the line with the new hash.
$newLines[] = $username . ":" . $newHashedPassword . ":" . $storedRole;
} else {
$newLines[] = $line;
}
}
if (!$userFound) {
echo json_encode(["error" => "User not found."]);
exit;
}
// Save updated users file.
if (file_put_contents($usersFile, implode(PHP_EOL, $newLines) . PHP_EOL)) {
echo json_encode(["success" => "Password updated successfully."]);
} else {
echo json_encode(["error" => "Could not update password."]);
}
?>

View File

@@ -91,6 +91,9 @@
<button id="logoutBtn" title="Logout"> <button id="logoutBtn" title="Logout">
<i class="material-icons">exit_to_app</i> <i class="material-icons">exit_to_app</i>
</button> </button>
<button id="changePasswordBtn" title="Change Password">
<i class="material-icons">vpn_key</i>
</button>
<!-- Restore Files Modal (Admin Only) --> <!-- Restore Files Modal (Admin Only) -->
<div id="restoreFilesModal" class="modal centered-modal" style="display: none;"> <div id="restoreFilesModal" class="modal centered-modal" style="display: none;">
<div class="modal-content"> <div class="modal-content">
@@ -311,6 +314,18 @@
</div> </div>
</div> </div>
<!-- Change Password-->
<div id="changePasswordModal" class="modal" style="display:none;">
<div class="modal-content" style="max-width:400px; margin:auto;">
<span id="closeChangePasswordModal" style="cursor:pointer;">&times;</span>
<h3>Change Password</h3>
<input type="password" id="oldPassword" placeholder="Old Password" style="width:100%; margin: 5px 0;" />
<input type="password" id="newPassword" placeholder="New Password" style="width:100%; margin: 5px 0;" />
<input type="password" id="confirmPassword" placeholder="Confirm New Password" style="width:100%; margin: 5px 0;" />
<button id="saveNewPasswordBtn" class="btn btn-primary" style="width:100%;">Save</button>
</div>
</div>
<!-- Add User Modal --> <!-- Add User Modal -->
<div id="addUserModal" class="modal"> <div id="addUserModal" class="modal">
<div class="modal-content"> <div class="modal-content">

View File

@@ -142,14 +142,14 @@ body.dark-mode header {
justify-content: flex-end; justify-content: flex-end;
flex: 1; flex: 1;
min-width: 150px; min-width: 150px;
gap: 10px; gap: 0px;
} }
.header-buttons button { .header-buttons button {
background: none; background: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
padding: 10px; padding: 7px;
border-radius: 50%; border-radius: 50%;
color: #fff; color: #fff;
transition: background-color 0.2s ease, box-shadow 0.2s ease; transition: background-color 0.2s ease, box-shadow 0.2s ease;