change password added
This commit is contained in:
61
auth.js
61
auth.js
@@ -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
85
changePassword.php
Normal 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."]);
|
||||||
|
}
|
||||||
|
?>
|
||||||
15
index.html
15
index.html
@@ -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;">×</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">
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user