2025-03-19 02:09:30 -06:00
|
|
|
const crypto = require("crypto");
|
|
|
|
|
const db = require("../utils/database");
|
|
|
|
|
const { sendVerificationEmail } = require("../utils/helper");
|
|
|
|
|
|
|
|
|
|
exports.sendVerificationCode = async (req, res) => {
|
|
|
|
|
const { email } = req.body;
|
|
|
|
|
|
|
|
|
|
if (!email) {
|
|
|
|
|
return res.status(400).json({ error: "Email is required" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Generate a random 6-digit code
|
|
|
|
|
const verificationCode = crypto.randomInt(100000, 999999).toString();
|
|
|
|
|
console.log(
|
2025-03-23 14:49:10 -06:00
|
|
|
`Generated verification code for ${email}: ${verificationCode}`,
|
2025-03-19 02:09:30 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Check if email already exists in verification table
|
2025-03-19 04:10:41 -06:00
|
|
|
const [results, fields] = await db.execute(
|
2025-03-19 02:09:30 -06:00
|
|
|
"SELECT * FROM AuthVerification WHERE Email = ?",
|
2025-03-23 14:49:10 -06:00
|
|
|
[email],
|
2025-03-19 02:09:30 -06:00
|
|
|
);
|
2025-03-19 04:10:41 -06:00
|
|
|
|
|
|
|
|
if (results.length > 0) {
|
|
|
|
|
// Update existing record
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
`UPDATE AuthVerification SET VerificationCode = ?, Authenticated = FALSE, Date = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE Email = ?`,
|
2025-03-23 14:49:10 -06:00
|
|
|
[verificationCode, email],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Send email and respond
|
|
|
|
|
await sendVerificationEmail(email, verificationCode);
|
|
|
|
|
res.json({ success: true, message: "Verification code sent" });
|
|
|
|
|
} else {
|
|
|
|
|
// Insert new record
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
"INSERT INTO AuthVerification (Email, VerificationCode, Authenticated) VALUES (?, ?, FALSE)",
|
2025-03-23 14:49:10 -06:00
|
|
|
[email, verificationCode],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
// Send email and respond
|
|
|
|
|
await sendVerificationEmail(email, verificationCode);
|
|
|
|
|
res.json({ success: true, message: "Verification code sent" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error:", error);
|
|
|
|
|
res.status(500).json({ error: "Server error" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.verifyCode = async (req, res) => {
|
2025-03-19 02:09:30 -06:00
|
|
|
const { email, code } = req.body;
|
|
|
|
|
|
|
|
|
|
if (!email || !code) {
|
|
|
|
|
return res.status(400).json({ error: "Email and code are required" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(`Attempting to verify code for ${email}: ${code}`);
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
try {
|
|
|
|
|
// Check verification code
|
|
|
|
|
const [results, fields] = await db.execute(
|
|
|
|
|
"SELECT * FROM AuthVerification WHERE Email = ? AND VerificationCode = ? AND Authenticated = 0 AND Date > DATE_SUB(NOW(), INTERVAL 15 MINUTE)",
|
2025-03-23 14:49:10 -06:00
|
|
|
[email, code],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
console.log(`Invalid or expired verification code for email ${email}`);
|
|
|
|
|
return res
|
|
|
|
|
.status(400)
|
|
|
|
|
.json({ error: "Invalid or expired verification code" });
|
2025-03-19 02:09:30 -06:00
|
|
|
}
|
2025-03-19 04:10:41 -06:00
|
|
|
|
|
|
|
|
const userId = results[0].UserID;
|
|
|
|
|
|
|
|
|
|
// Mark as authenticated
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
"UPDATE AuthVerification SET Authenticated = TRUE WHERE Email = ?",
|
2025-03-23 14:49:10 -06:00
|
|
|
[email],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Verification successful",
|
|
|
|
|
userId,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log("Error: ", error);
|
|
|
|
|
res.status(500).json({ error: "Database error!" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.completeSignUp = async (req, res) => {
|
2025-03-19 02:09:30 -06:00
|
|
|
const data = req.body;
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
try {
|
|
|
|
|
const [results, fields] = await db.execute(
|
|
|
|
|
`SELECT * FROM AuthVerification WHERE Email = ? AND Authenticated = 1;`,
|
2025-03-23 14:49:10 -06:00
|
|
|
[data.email],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (results.length === 0) {
|
|
|
|
|
return res.status(400).json({ error: "Email not verified" });
|
2025-03-19 02:09:30 -06:00
|
|
|
}
|
2025-03-19 04:10:41 -06:00
|
|
|
|
|
|
|
|
// Create the user
|
|
|
|
|
const [createResult] = await db.execute(
|
|
|
|
|
`INSERT INTO User (Name, Email, UCID, Password, Phone, Address)
|
2025-03-23 14:49:10 -06:00
|
|
|
VALUES ('${data.name}', '${data.email}', '${data.UCID}', '${data.password}', '${data.phone}', '${data.address}')`,
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Insert role using the user's ID
|
|
|
|
|
const [insertResult] = await db.execute(
|
|
|
|
|
`INSERT INTO UserRole (UserID, Client, Admin)
|
|
|
|
|
VALUES (LAST_INSERT_ID(), ${data.client || true}, ${
|
2025-03-23 14:49:10 -06:00
|
|
|
data.admin || false
|
|
|
|
|
})`,
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Delete verification record
|
|
|
|
|
const [deleteResult] = await db.execute(
|
2025-03-23 14:49:10 -06:00
|
|
|
`DELETE FROM AuthVerification WHERE Email = '${data.email}'`,
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "User registration completed successfully",
|
|
|
|
|
name: data.name,
|
|
|
|
|
email: data.email,
|
|
|
|
|
UCID: data.UCID,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log("Error: ", error);
|
|
|
|
|
res.status(500).json({ error: "Database error!" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-04-18 19:05:20 -06:00
|
|
|
exports.doLogin = async (req, res) => {
|
|
|
|
|
const { email, password } = req.body;
|
|
|
|
|
|
|
|
|
|
// Input validation
|
|
|
|
|
if (!email || !password) {
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Email and password are required",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Query to find user with matching email
|
|
|
|
|
const query = "SELECT * FROM User WHERE email = ?";
|
|
|
|
|
const [data, fields] = await db.execute(query, [email]);
|
|
|
|
|
|
|
|
|
|
// Check if user was found
|
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
|
const user = data[0];
|
|
|
|
|
|
|
|
|
|
// Verify password match
|
|
|
|
|
if (user.Password === password) {
|
|
|
|
|
// Consider using bcrypt for secure password comparison
|
|
|
|
|
// Return user data without password
|
|
|
|
|
return res.json({
|
|
|
|
|
found: true,
|
|
|
|
|
userID: user.UserID,
|
|
|
|
|
name: user.Name,
|
|
|
|
|
email: user.Email,
|
|
|
|
|
UCID: user.UCID,
|
|
|
|
|
phone: user.Phone,
|
|
|
|
|
address: user.Address,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// Password doesn't match
|
|
|
|
|
return res.json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Invalid email or password",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// User not found
|
|
|
|
|
return res.json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Invalid email or password",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error logging in:", error);
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Database error occurred",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.getAllUser = async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const [users, fields] = await db.execute("SELECT * FROM User;");
|
|
|
|
|
res.json({ Users: users });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Errors: ", error);
|
|
|
|
|
return res.status(500).json({ error: "\nCould not fetch users!" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.findUserByEmail = async (req, res) => {
|
2025-03-19 02:09:30 -06:00
|
|
|
const { email } = req.body;
|
|
|
|
|
|
|
|
|
|
// Input validation
|
|
|
|
|
if (!email) {
|
|
|
|
|
return res.status(400).json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Email is required",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
try {
|
|
|
|
|
// Query to find user with matching email and password
|
|
|
|
|
const query = "SELECT * FROM User WHERE email = ?";
|
|
|
|
|
const [data, fields] = await db.execute(query, [email]);
|
2025-03-19 02:09:30 -06:00
|
|
|
|
|
|
|
|
// Check if user was found
|
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
|
console.log(data);
|
|
|
|
|
const user = data[0];
|
|
|
|
|
|
|
|
|
|
// Return all user data except password
|
|
|
|
|
return res.json({
|
|
|
|
|
found: true,
|
|
|
|
|
userID: user.UserID,
|
|
|
|
|
name: user.Name,
|
|
|
|
|
email: user.Email,
|
|
|
|
|
UCID: user.UCID,
|
|
|
|
|
phone: user.Phone,
|
|
|
|
|
address: user.Address,
|
2025-04-18 19:05:20 -06:00
|
|
|
password: user.Password,
|
2025-03-19 02:09:30 -06:00
|
|
|
// Include any other fields your user might have
|
|
|
|
|
// Make sure the field names match exactly with your database column names
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// User not found or invalid credentials
|
|
|
|
|
return res.json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Invalid email or password",
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-03-19 04:10:41 -06:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error finding user:", error);
|
|
|
|
|
return res.status(500).json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Database error occurred",
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.updateUser = async (req, res) => {
|
2025-03-23 14:49:10 -06:00
|
|
|
try {
|
|
|
|
|
const userId = req.body?.userId;
|
|
|
|
|
const name = req.body?.name;
|
|
|
|
|
const email = req.body?.email;
|
|
|
|
|
const phone = req.body?.phone;
|
|
|
|
|
const UCID = req.body?.UCID;
|
|
|
|
|
const address = req.body?.address;
|
2025-04-18 19:05:20 -06:00
|
|
|
const password = req.body?.password;
|
2025-03-23 14:49:10 -06:00
|
|
|
if (!userId) {
|
|
|
|
|
return res.status(400).json({ error: "User ID is required" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-23 14:49:10 -06:00
|
|
|
// Build updateData manually
|
|
|
|
|
const updateData = {};
|
|
|
|
|
if (name) updateData.name = name;
|
|
|
|
|
if (email) updateData.email = email;
|
|
|
|
|
if (phone) updateData.phone = phone;
|
|
|
|
|
if (UCID) updateData.UCID = UCID;
|
|
|
|
|
if (address) updateData.address = address;
|
2025-04-18 19:05:20 -06:00
|
|
|
if (password) updateData.password = password;
|
2025-03-23 14:49:10 -06:00
|
|
|
if (Object.keys(updateData).length === 0) {
|
|
|
|
|
return res.status(400).json({ error: "No valid fields to update" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-23 14:49:10 -06:00
|
|
|
const updateFields = [];
|
|
|
|
|
const values = [];
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-23 14:49:10 -06:00
|
|
|
Object.entries(updateData).forEach(([key, value]) => {
|
2025-03-19 02:09:30 -06:00
|
|
|
updateFields.push(`${key} = ?`);
|
|
|
|
|
values.push(value);
|
2025-03-23 14:49:10 -06:00
|
|
|
});
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-23 14:49:10 -06:00
|
|
|
values.push(userId);
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-23 14:49:10 -06:00
|
|
|
const query = `UPDATE User SET ${updateFields.join(", ")} WHERE userId = ?`;
|
2025-03-19 04:10:41 -06:00
|
|
|
const [updateResult] = await db.execute(query, values);
|
2025-03-23 14:49:10 -06:00
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
if (updateResult.affectedRows === 0) {
|
2025-03-19 02:09:30 -06:00
|
|
|
return res.status(404).json({ error: "User not found" });
|
|
|
|
|
}
|
2025-03-23 14:49:10 -06:00
|
|
|
|
2025-03-19 02:09:30 -06:00
|
|
|
res.json({ success: true, message: "User updated successfully" });
|
2025-03-19 04:10:41 -06:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error updating user:", error);
|
|
|
|
|
return res.status(500).json({ error: "Could not update user" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.deleteUser = async (req, res) => {
|
2025-03-19 02:09:30 -06:00
|
|
|
const { userId } = req.body;
|
|
|
|
|
|
|
|
|
|
if (!userId) {
|
|
|
|
|
return res.status(400).json({ error: "User ID is required" });
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
try {
|
|
|
|
|
// Delete from UserRole first (assuming foreign key constraint)
|
|
|
|
|
const [result1] = await db.execute(
|
|
|
|
|
"DELETE FROM UserRole WHERE UserID = ?",
|
2025-03-23 14:49:10 -06:00
|
|
|
[userId],
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
2025-03-19 02:09:30 -06:00
|
|
|
|
|
|
|
|
// Then delete from User table
|
2025-03-19 04:10:41 -06:00
|
|
|
const [result2] = await db.execute("DELETE FROM User WHERE UserID = ?", [
|
|
|
|
|
userId,
|
|
|
|
|
]);
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
if (result2.affectedRows === 0) {
|
|
|
|
|
return res.status(404).json({ error: "User not found" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
|
2025-03-19 04:10:41 -06:00
|
|
|
res.json({ success: true, message: "User deleted successfully" });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error: ", error);
|
|
|
|
|
return res.status(500).json({ error: "Could not delete user!" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|