This commit is contained in:
newtbot 2023-12-30 01:02:13 +08:00
commit 0aefebae75
2 changed files with 262 additions and 71 deletions

View File

@ -140,7 +140,6 @@ app.get("/home", isAuthenticated, (req, res) => {
// Retrieve the overall last 10 logins for all users // Retrieve the overall last 10 logins for all users
const loginsQuery = const loginsQuery =
"SELECT username, lastLogin FROM users ORDER BY lastLogin DESC LIMIT 10"; "SELECT username, lastLogin FROM users ORDER BY lastLogin DESC LIMIT 10";
connection.query(loginsQuery, (error, loginResults) => { connection.query(loginsQuery, (error, loginResults) => {
if (error) { if (error) {
console.error("Error executing login logs query:", error); console.error("Error executing login logs query:", error);
@ -531,7 +530,7 @@ app.post("/reset-password/:token", async (req, res) => {
// Update user's password and clear reset token // Update user's password and clear reset token
const updateQuery = const updateQuery =
"UPDATE users SET password = ?, reset_token = NULL, reset_token_expiry = NULL WHERE reset_token = ?"; "UPDATE users SET password = ?, reset_token = NULL, reset_token_expiry = NULL WHERE reset_token = ?";
connection.query(updateQuery, [hashedPassword, token], (updateErr) => { connection.query(updateQuery, [hashedPassword, token], async (updateErr, updateResults) => {
if (updateErr) { if (updateErr) {
console.error("Error updating password:", updateErr); console.error("Error updating password:", updateErr);
// Pass the error to the template when rendering the reset-password page // Pass the error to the template when rendering the reset-password page
@ -540,6 +539,15 @@ app.post("/reset-password/:token", async (req, res) => {
resetError: "Error updating password", resetError: "Error updating password",
}); });
} else { } else {
// Log password reset activity
const username = selectResults[0].username; // Assuming 'username' is the column name
const logQuery = "INSERT INTO user_logs (username, activity, timestamp) VALUES (?, 'Password Reseted successfully', NOW())";
connection.query(logQuery, [username], (logErr) => {
if (logErr) {
console.error("Error logging password reset:", logErr);
// You might want to handle the logging error here
}
});
// Redirect to the success page upon successful password reset // Redirect to the success page upon successful password reset
res.redirect("/success"); res.redirect("/success");
} }
@ -564,6 +572,7 @@ app.get("/reset-password/:token", (req, res) => {
}); });
app.post("/reset-password", async (req, res) => { app.post("/reset-password", async (req, res) => {
const { username, password, confirmPassword } = req.body; const { username, password, confirmPassword } = req.body;
const creatorUsername = req.session.username;
// Check if passwords match // Check if passwords match
if (password !== confirmPassword) { if (password !== confirmPassword) {
@ -590,10 +599,7 @@ app.post("/reset-password", async (req, res) => {
// Update user's password based on the username // Update user's password based on the username
const updateQuery = "UPDATE users SET password = ? WHERE username = ?"; const updateQuery = "UPDATE users SET password = ? WHERE username = ?";
connection.query( connection.query(updateQuery, [hashedPassword, username], async (updateErr, updateResults) => {
updateQuery,
[hashedPassword, username],
(updateErr, updateResults) => {
if (updateErr) { if (updateErr) {
console.error("Error updating password:", updateErr); console.error("Error updating password:", updateErr);
return res.status(500).json({ error: "Error updating password" }); return res.status(500).json({ error: "Error updating password" });
@ -601,20 +607,26 @@ app.post("/reset-password", async (req, res) => {
// Check if the update affected any rows // Check if the update affected any rows
if (updateResults.affectedRows > 0) { if (updateResults.affectedRows > 0) {
// Log password reset activity
const logQuery = "INSERT INTO user_logs (username, activity, timestamp) VALUES (?, ?, NOW())";
const logActivity = `Password has been reset for ${username}`;
connection.query(logQuery, [creatorUsername, logActivity], (logErr) => {
if (logErr) {
console.error("Error logging password reset:", logErr);
// You might want to handle the logging error here
}
// Password update successful // Password update successful
return res return res.status(200).json({ success: "Password updated successfully" });
.status(200) });
.json({ success: "Password updated successfully" });
} else { } else {
return res return res.status(404).json({
.status(404)
.json({
error: "User not found or password not updated.", error: "User not found or password not updated.",
}); });
} }
} });
);
}); });
async function checkIfUserExists(username) { async function checkIfUserExists(username) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const query = "SELECT * FROM users WHERE username = ?"; const query = "SELECT * FROM users WHERE username = ?";
@ -627,6 +639,91 @@ async function checkIfUserExists(username) {
}); });
}); });
} }
app.get('/searchUser', (req, res) => {
const { username } = req.query;
const query = 'SELECT * FROM users WHERE username = ?';
connection.query(query, [username], (err, results) => {
if (err) {
console.error('MySQL query error:', err);
res.status(500).json({ success: false, error: 'Internal Server Error' });
} else if (results.length === 0) {
// No user found with the given username
res.status(404).json({ success: false, error: 'User not found' });
} else {
res.json(results);
}
});
});
app.get('/api/users', (req, res) => {
const query = 'SELECT * FROM users';
connection.query(query, (err, results) => {
if (err) {
console.error('MySQL query error:', err);
res.status(500).json({ success: false, error: 'Internal Server Error' });
} else {
res.json(results);
}
});
});
// Route to search for a user by username
app.get('/api/searchUser', (req, res) => {
const { username } = req.query;
const query = 'SELECT * FROM users WHERE username = ?';
connection.query(query, [username], (err, results) => {
if (err) {
console.error('MySQL query error:', err);
res.status(500).json({ success: false, error: 'Internal Server Error' });
} else {
res.json(results);
}
});
});
// Route to delete a user by username
app.delete('/api/deleteUser/:username', async (req, res) => {
const { username } = req.params;
const query = 'DELETE FROM users WHERE username = ?';
const creatorUsername = req.session.username;
try {
// Log deletion activity to USER_LOGS
const deletionActivity = `User ${username} has been successfully deleted`;
const logQuery = 'INSERT INTO USER_LOGS (USERNAME, ACTIVITY, TIMESTAMP) VALUES (?, ?, CURRENT_TIMESTAMP)';
await executeQuery(logQuery, [creatorUsername, deletionActivity]);
// Perform user deletion
const results = await executeQuery(query, [username]);
if (results.affectedRows === 0) {
res.status(404).json({ success: false, error: 'User not found' });
} else {
res.json({ success: true, message: 'User deleted successfully' });
}
} catch (error) {
console.error('MySQL query error:', error);
res.status(500).json({ success: false, error: 'Internal Server Error', details: error.message });
}
});
async function executeQuery(sql, values) {
return new Promise((resolve, reject) => {
connection.query(sql, values, (err, results) => {
if (err) {
reject(err);
} else {
resolve(results);
}
});
});
}
app.use(express.static("views")); app.use(express.static("views"));

View File

@ -44,7 +44,6 @@
<th>Name</th> <th>Name</th>
<th>Username</th> <th>Username</th>
<th>Email</th> <th>Email</th>
<th>Password</th>
<th>Last Login</th> <th>Last Login</th>
<th>Job Title</th> <th>Job Title</th>
</tr> </tr>
@ -56,7 +55,6 @@
<td><%= user.name %></td> <td><%= user.name %></td>
<td><%= user.username %></td> <td><%= user.username %></td>
<td><%= user.email %></td> <td><%= user.email %></td>
<td><%= user.password %></td>
<td><%= new Date(user.lastLogin).toLocaleString('en-US', { timeZone: 'Asia/Singapore' }) %></td> <td><%= new Date(user.lastLogin).toLocaleString('en-US', { timeZone: 'Asia/Singapore' }) %></td>
<td><%= user.jobTitle %></td> <td><%= user.jobTitle %></td>
</tr> </tr>
@ -134,7 +132,17 @@
</div> </div>
</div> </div>
</div> </div>
<div id="deleteUserContainer" style="display: none;">
<h3>Delete User</h3>
<div class="search-container">
<input type="text" id="searchUserInput" placeholder="Search by username">
<button id="searchUserButton">Search</button>
</div>
<div id="searchResultsContainer" style="display: none;">
<h4>Search Results</h4>
<ul id="searchResultsList"></ul>
</div>
</div>
<!-- Your existing script tags --> <!-- Your existing script tags -->
@ -153,6 +161,7 @@ $(document).ready(function () {
$('#createUserForm').hide(); $('#createUserForm').hide();
$('#userDataContainer').hide(); $('#userDataContainer').hide();
$('#downloadButtonContainer').hide(); $('#downloadButtonContainer').hide();
$('#deleteUserContainer').hide();
}); });
$('#addUserLink').on('click', function () { $('#addUserLink').on('click', function () {
@ -160,6 +169,7 @@ $(document).ready(function () {
$('#createUserForm').show(); $('#createUserForm').show();
$('#userDataContainer').hide(); $('#userDataContainer').hide();
$('#downloadButtonContainer').hide(); $('#downloadButtonContainer').hide();
$('#deleteUserContainer').hide();
}); });
$('#userDataLink').on('click', function () { $('#userDataLink').on('click', function () {
@ -167,26 +177,110 @@ $(document).ready(function () {
$('#createUserForm').hide(); $('#createUserForm').hide();
$('#userDataContainer').show(); $('#userDataContainer').show();
$('#downloadButtonContainer').show(); $('#downloadButtonContainer').show();
$('#deleteUserContainer').hide();
}); });
$('#searchUserButton').on('click', function () {
console.log('Search button clicked');
const searchUsername = $('#searchUserInput').val();
// Call the function to search for the user
searchUser(searchUsername);
});
$('#deleteUserLink').on('click', function () {
$('#deleteUserContainer').show();
$('#resetPasswordFormContainer').hide();
$('#createUserForm').hide();
$('#userDataContainer').hide();
$('#downloadButtonContainer').hide();
}); });
$('#downloadButton').on('click', function () { $('#downloadButton').on('click', function () {
// Call the downloadExcel function with the allUsers data // Call the downloadExcel function with the allUsers data
downloadExcel(allUsers); downloadExcel(allUsers);
}); });
});
function searchUser(username) {
fetch(`/api/searchUser?username=${username}`) // Add the /api prefix here
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(`HTTP error! Status: ${response.status}`);
}
})
.then(users => {
// Display search results
displaySearchResults(users);
})
.catch(error => {
console.error('Search error:', error);
// Handle errors, e.g., display an alert
});
}
// Function to display search results
function displaySearchResults(users) {
const searchResultsList = $('#searchResultsList');
// Clear previous results
searchResultsList.empty();
if (users && users.length > 0) {
users.forEach(user => {
const listItem = `<li>${user.username} - <button class="deleteUserButton" data-username="${user.username}">Delete</button></li>`;
searchResultsList.append(listItem);
});
// Show the search results container
$('#searchResultsContainer').show();
} else {
// Hide the search results container if no results
$('#searchResultsContainer').hide();
}
}
// Event listener for delete user button in search results
$('#searchResultsList').on('click', '.deleteUserButton', function () {
const usernameToDelete = $(this).data('username');
console.log('Before fetch for user deletion');
// Make a fetch request to delete the user
fetch(`/api/deleteUser/${usernameToDelete}`, {
method: 'DELETE',
})
.then(response => {
console.log('Inside fetch response handler');
if (response.ok) {
// Assuming your server sends a JSON response
return response.json();
} else {
throw new Error(`HTTP error! Status: ${response.status}`);
}
})
.then(data => {
console.log('User deletion success:', data);
alert('User deleted successfully');
$('#searchResultsContainer').hide();
})
.catch(error => {
console.error('User deletion error:', error);
alert('Failed to delete user. Please try again.');
// Handle errors, e.g., display an alert
});
});
function downloadExcel(allUsers) { function downloadExcel(allUsers) {
if (allUsers && allUsers.length > 0) { if (allUsers && allUsers.length > 0) {
const workbook = new ExcelJS.Workbook(); const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('All Users'); const worksheet = workbook.addWorksheet('All Users');
const headers = ['Name', 'Username', 'Email', 'Password', 'Last Login', 'Job Title']; const headers = ['Name', 'Username', 'Email', 'Last Login', 'Job Title'];
worksheet.addRow(headers); worksheet.addRow(headers);
allUsers.forEach(user => { allUsers.forEach(user => {
const rowData = [ const rowData = [
user.name || '', user.name || '',
user.username || '', user.username || '',
user.email || '', user.email || '',
user.password || '',
user.lastLogin ? new Date(user.lastLogin).toLocaleString('en-US', { timeZone: 'Asia/Singapore' }) : '', user.lastLogin ? new Date(user.lastLogin).toLocaleString('en-US', { timeZone: 'Asia/Singapore' }) : '',
user.jobTitle || '' user.jobTitle || ''
]; ];