const bcrypt = require("bcrypt"); const db = require("../config/database"); // Database connection const fs = require("fs"); const jwt = require("jsonwebtoken"); const nlp = require("compromise"); const nodemailer = require("nodemailer"); const sender_port = process.env.SENDER_PORT; const sender_security = process.env.SENDER_SECURITY; const path = require('path') const { emitEvent } = require("../services/secondaryWebsocket"); console.log('sender port : ', sender_port); console.log('sender security : ', sender_security); // zoho transporter const transporter = nodemailer.createTransport({ host: "smtp.zoho.com", port: 465, secure: true, auth: { user: "kavya.j@tech4biz.io", // Your Zoho email address pass: "8pQfkBw8gbrz", // Your Zoho App Password (not your account password) } }); exports.initWebSocket = (io) => { io.on("connection", (socket) => { console.log("Hospital connected:", socket.id); socket.on("register_hospital", (hospitalCode) => { hospitalSockets[hospitalCode] = socket; console.log(`Hospital ${hospitalCode} registered.`); }); socket.on("disconnect", () => { const hospitalCode = Object.keys(hospitalSockets).find( (key) => hospitalSockets[key] === socket ); if (hospitalCode) delete hospitalSockets[hospitalCode]; console.log(`Hospital ${hospitalCode} disconnected.`); }); }); }; exports.uploadIdPhoto = async (req, res) => { try { // Extracting user ID and hospital code const userId = parseInt(req.params.id, 10); // User ID from route const { hospital_code } = req.user; // Authenticated user's hospital code // Check if user ID is valid if (isNaN(userId)) { console.error("Invalid User ID:", userId); return res.status(400).json({ error: "Invalid user ID" }); } // Check if a file was uploaded if (!req.file) { console.error("No file uploaded"); return res.status(400).json({ error: "No file uploaded" }); } const photoPath = `/uploads/id_photos/${req.file.filename}`; // Verify app user is part of the same hospital const query = ` SELECT hospital_code FROM app_users WHERE id = ? AND hospital_code = ? `; const result = await db.query(query, [userId, hospital_code]); if (result.length === 0) { console.error( "Authorization failed for user ID:", userId, "with hospital_code:", hospital_code ); return res .status(403) .json({ error: "You are not authorized to upload ID for this user" }); } // Update the ID photo path in the database await db.query("UPDATE app_users SET id_photo_url = ? WHERE id = ?", [ photoPath, userId, ]); res.status(200).json({ message: "ID photo uploaded successfully!", id_photo_url: photoPath, }); } catch (error) { console.error("Error uploading ID photo:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.updateSettings = async (req, res) => { try { const userId = req.user.id; // Assuming user is authenticated and userId is available const { pin, pin_enabled, remember_me } = req.body; // Validate pin (if provided) if (pin && (typeof pin !== 'string' || pin.length !== 4)) { return res.status(400).json({ error: 'Invalid PIN format. Must be a 4-digit string.' }); } // Determine expiry based on remember_me let expiresIn = '5h'; let expiryTimestamp = new Date(); if (remember_me) { expiresIn = '30d'; expiryTimestamp.setDate(expiryTimestamp.getDate() + 30); } else { expiryTimestamp.setHours(expiryTimestamp.getHours() + 5); } // Generate new access token const payload = { id: userId, role: 'AppUser' }; const accessToken = jwt.sign(payload, process.env.JWT_ACCESS_TOKEN_SECRET, { expiresIn: expiresIn, }); // Update user settings and access token const query = `UPDATE app_users SET pin_number = ?, pin_enabled = ?, remember_me = ?, access_token = ?, access_token_expiry = ? WHERE id = ?`; const result=await db.query(query, [pin, pin_enabled, remember_me, accessToken, expiryTimestamp, userId]); if (result.affectedRows > 0) { console.log("Table updated successfully."); } else { console.log("Table not updated. No matching user found."); } res.status(200).json({ message: 'Settings updated successfully.', accessToken }); } catch (error) { console.error('Error updating settings:', error); res.status(500).json({ error: 'Internal Server Error' }); } }; exports.hitlike = async (req, res) => { try { // Extract user ID and session ID from the request const { session_id, id } = req.body; const log_id = id; const app_user_id = req.user.id; // Check if both app_user_id and session_id are provided if (!app_user_id || !session_id || !log_id) { return res.status(400).json({ status: 'error', message: 'app user id and session id and log id are required', }); } // Query to toggle the is_liked value const toggleQuery = ` UPDATE interaction_logs SET is_liked = NOT is_liked WHERE app_user_id = ? AND session_id = ? AND id = ? `; // Execute the query const result = await db.query(toggleQuery, [app_user_id, session_id,log_id]); // Check if any rows were affected if (result.affectedRows > 0) { return res.status(200).json({ status: 'success', message: 'Like updated successfully', data: { app_user_id, session_id, is_liked: result.changedRows > 0 ? 1 : 0, // 1 if changed, 0 if not }, }); } else { return res.status(404).json({ status: 'error', message: 'No matching record found to toggle', }); } } catch (error) { console.error('Error during like toggle:', error); return res.status(500).json({ status: 'error', message: 'Internal server error', }); } }; exports.hitFlag = async (req, res) => { try { // Extract user ID and session ID from the request const { session_id, logid } = req.body; const log_id = logid; const app_user_id = req.user.id; // Check if both app_user_id and session_id are provided if (!app_user_id || !session_id || !log_id) { return res.status(400).json({ status: 'error', message: 'app user id and session id and log id are required', }); } // Query to toggle the is_liked value const toggleQuery = ` UPDATE interaction_logs SET is_flagged = NOT is_flagged WHERE app_user_id = ? AND session_id = ? AND id = ? `; // Execute the query const result = await db.query(toggleQuery, [app_user_id, session_id,log_id]); // Check if any rows were affected if (result.affectedRows > 0) { return res.status(200).json({ status: 'success', message: 'Updated successfully', data: { app_user_id, session_id }, }); } else { return res.status(404).json({ status: 'error', message: 'No matching record found to toggle', }); } } catch (error) { console.error('Error during like toggle:', error); return res.status(500).json({ status: 'error', message: 'Internal server error', }); } }; exports.addReportText = async (req, res) => { try { const { session_id, report_text } = req.body; const app_user_id = req.user.id; // Validate input if (!app_user_id || !session_id || typeof report_text !== 'string') { return res.status(400).json({ status: 'error', message: 'app_user_id, session_id, logid, and report_text are required', }); } // Update query const updateQuery = ` UPDATE interaction_logs SET report_text = ? WHERE app_user_id = ? AND session_id = ? `; // Execute update const result = await db.query(updateQuery, [report_text, app_user_id, session_id]); // Handle response if (result.affectedRows > 0) { return res.status(200).json({ status: 'success', message: 'Session reported successfully. Admin will review your report', data: { app_user_id, session_id, report_text }, }); } else { return res.status(404).json({ status: 'error', message: 'No matching record found to update report text', }); } } catch (error) { console.error('Error updating report text:', error); return res.status(500).json({ status: 'error', message: 'Internal server error', }); } }; exports.updateChecked = async (req,res) =>{ try { const app_user_id = req.params.id; if (!["Admin", 8].includes(req.user.role)) { return res.status(403).json({ error: "Unauthorized to approve IDs" }); } const updateQuery = ` UPDATE app_users SET checked = ? WHERE id = ? `; const result = await db.query(updateQuery, [1, app_user_id]); if (result.affectedRows > 0) { return res.status(200).json({ status: 'success', message: 'Acknowledged successfully', }); } else { return res.status(404).json({ status: 'error', message: 'No matching record found to update checked', }); } } catch (error) { console.error("Error updating checked:", error); return res.status(500).json({ error: "Internal server error" }); } } exports.signup = async (req, res) => { try { const { pin, pin_status,remember_me, email, password, hospital_code, username } = req.body; if (!email || !password || !hospital_code || !username) { return res.status(400).json({ error: "Email, password, username, and hospital code are required", }); } const pin_enabled = (pin_status === undefined || pin_status === '') ? 0 : pin_status; const remember_me_ = (remember_me === undefined || remember_me === '') ? 0 : remember_me; // Check if the hospital_code exists in the `hospitals` table const hospitalQuery = "SELECT hospital_code FROM hospitals WHERE hospital_code = ?"; const hospitalResult = await db.query(hospitalQuery, [hospital_code]); if (hospitalResult.length === 0) { return res.status(404).json({ error: "Invalid hospital code" }); } // Check if the email is already in use const userQuery = "SELECT id FROM app_users WHERE email = ?"; const userResult = await db.query(userQuery, [email]); if (userResult.length > 0) { return res.status(400).json({ error: "Email already in use" }); } // Check if a file was uploaded if (!req.file) { return res.status(400).json({ error: "ID photo url is required" }); } // Hash the password const hashPassword = await bcrypt.hash(password, 10); // Insert the new app user into the `app_users` table const insertQuery = ` INSERT INTO app_users (email, hash_password, hospital_code, status, username, pin_number, pin_enabled, remember_me ) VALUES (?, ?, ?, 'Pending', ?, ?, ?,?) `; const result = await db.query(insertQuery, [ email, hashPassword, hospital_code, username, pin, // Set pin to null if not provided pin_enabled, remember_me_ ]); const userId = result.insertId; // Get the new user's ID const filePath = `/uploads/id_photos/${req.file.filename}`; // Correct file path // Update the ID photo path in the database await db.query( "UPDATE app_users SET id_photo_url = ?, upload_status = ? WHERE id = ?", [filePath, "1", userId] ); // ✅ Notify hospitals in the SECONDARY WebSocket instance emitEvent("new_user", { message: `A new user has been created for hospital ${hospital_code}.`, user: { id: userId, username, email, hospital_code: hospital_code }, }); res.status(201).json({ message: "User signed up and ID photo uploaded successfully!", data: { id: userId, email, hospital_code, username, id_photo_url: filePath, pin: pin || null, pin_status : pin_status, remember_me: remember_me }, }); } catch (error) { console.error("Error during signup and ID photo upload:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.login = async (req, res) => { try { const { email, password } = req.body; let remember_me; if (!email || !password) { return res.status(400).json({ error: "Email and password are required" }); } console.log("email----",email) // Check if the user exists const query = "SELECT * FROM app_users WHERE email = ?"; const result = await db.query(query, [email]); console.log("result---",result) if (result.length === 0) { return res.status(404).json({ error: "User not found" }); } const user = result[0]; remember_me = user.remember_me console.log("user-data----------------------",user); const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [user.hospital_code]); // if (hospitalData.publicSignupEnabled) { // throw new Error("Hospital not found"); // } console.log("hospitalData---",hospitalData) let actual_status; actual_status = user.status if(hospitalData[0].publicSignupEnabled){ user.status = "Active" } if (user.status === "Pending" && !hospitalData[0].publicSignupEnabled) { return res.status(404).json({ error: "Your Account is Under Review" }); } if (user.status === "Inactive" && !hospitalData[0].publicSignupEnabled) { return res.status(404).json({ error: "Contact admin your account is not approved" }); } // Validate the password const validPassword = await bcrypt.compare(password, user.hash_password); if (!validPassword) { return res.status(401).json({ error: "Invalid email or password" }); } // Determine expiry based on remember_me let expiresIn = "5h"; let expiryTimestamp = new Date(); let rememberMeValue = remember_me; if (rememberMeValue === undefined) rememberMeValue = user.remember_me; if (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") { const updateQuery = ` UPDATE app_users SET remember_me = ? WHERE id = ? `; await db.query(updateQuery, [remember_me,user.id]); expiresIn = "30d"; expiryTimestamp.setDate(expiryTimestamp.getDate() + 30); } else { expiryTimestamp.setHours(expiryTimestamp.getHours() + 5); } // Generate a new access token const payload = { id: user.id, email: user.email, role: "AppUser" }; const accessToken = jwt.sign(payload, process.env.JWT_ACCESS_TOKEN_SECRET, { expiresIn: expiresIn, }); // SQL query to fetch hospital data based on the provided hospital_code const query_hospital = ` SELECT * FROM hospitals WHERE hospital_code = ?; `; // Run the query const result_hospital = await db.query(query_hospital, [user.hospital_code]); // hospital users const queryHospitalUsr = ` SELECT * FROM hospital_users WHERE hospital_code = ?; `; // Run the query const resultHospitalUsr = await db.query(queryHospitalUsr, [user.hospital_code]); const hospitalUser = resultHospitalUsr[0]; if (!hospitalUser) { return res.status(404).json({ error: "Hospital user not found" }); } // Update the access token and expiry in the database const updateQuery = ` UPDATE app_users SET access_token = ?, access_token_expiry = ?, remember_me = ? WHERE id = ? `; await db.query(updateQuery, [accessToken, expiryTimestamp, (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") ? 1 : 0, user.id]); // Send response res.status(200).json({ message: "Login successful", user: { id: user.id, email: user.email, pin: user.pin_number, pin_enabled: user.pin_enabled, hospital_code: user.hospital_code, hospital_id : hospitalData[0].id, status: user.status, actualStatus: actual_status, hospital_name: result_hospital[0].name_hospital, primary_color: result_hospital[0].primary_color, secondary_color: result_hospital[0].secondary_color, upload_status: user.upload_status, id_photo_url: user.id_photo_url, primary_admin_email: result_hospital[0].primary_admin_email, mobile_number: result_hospital[0].mobile_number, username: user.username, logo_url: resultHospitalUsr[0].profile_photo_url, query_title: user.query_title, remember_me: (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") ? 1 : 0 }, accessToken, }); } catch (error) { console.error("Error during login:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.checkPin = async (req, res) => { try { const { email, pin } = req.body; if (!email || !pin) { return res.status(400).json({ error: "Email and Pin are required" }); } // Check if the user exists const query = "SELECT * FROM app_users WHERE email = ?"; const result = await db.query(query, [email]); if (result.length === 0) { return res.status(404).json({ error: "User not found" }); } const user = result[0]; const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [user.hospital_code]); if (user.status === "Pending" && !hospitalData[0].publicSignupEnabled) { throw new Error("Your Account is Under Review"); } if (user.status === "Inactive" && !hospitalData[0].publicSignupEnabled) { throw new Error("Contact admin your account is not approved"); } // Check PIN if PIN status is enabled if (pin !== user.pin_number) { return res.status(401).json({ error: "Invalid PIN", requires_pin: true, message: "Incorrect PIN. Please try again" }); } // Send response res.status(200).json({ message: "Pin verified successfully", }); } catch (error) { console.error("Error during login:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.logout = async (req, res) => { try { const userId = req.user.id; // Assuming the user is authenticated via middleware // Check if the user exists const query = "SELECT * FROM app_users WHERE id = ?"; const result = await db.query(query, [userId]); if (result.length === 0) { return res.status(404).json({ error: "User not found" }); } // Invalidate the access token in the database const updateQuery = ` UPDATE app_users SET access_token = NULL, access_token_expiry = NULL WHERE id = ? `; await db.query(updateQuery, [userId]); res.status(200).json({ message: "Logout successful" }); } catch (error) { console.error("Error during logout:", error.message); res.status(500).json({ error: "Internal server error" }); } }; // controller.js exports.getAppUsersByHospitalCode = async (req, res) => { try { // Extract the hospital_code from the token (req.user object) const userId = req.user.id; if (!userId) { return res.status(400).json({ error: "User not found for the token" }); } // Query to fetch hospital users based on the hospital_code const query = ` SELECT id, email, status,hospital_code FROM app_users WHERE id = ?; `; const result = await db.query(query, [userId]); if (result.length === 0) { return res .status(404) .json({ error: "No users found for the specified Token" }); } const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [result[0].hospital_code]); if(hospitalData[0].publicSignupEnabled){ result[0].status = 'Active' } // Send the response with the users data res.status(200).json({ message: "Hospital users fetched successfully", user: result[0], }); } catch (error) { console.error("Error fetching hospital users:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.approveUserId = async (req, res) => { try { const appUserId = req.params.id; // App user ID to approve const { role } = req.user; // Authenticated user's details const { Action } = req.body; const { hospital_code } = req.user; if (!req.body.Action) { return res.status(400).json({ error: "Action is required" }); } if (!["Superadmin", "Admin", 8].includes(role)) { return res.status(403).json({ error: "Unauthorized to approve IDs" }); } const query = ` SELECT hospital_code FROM app_users WHERE id = ? AND hospital_code = ? `; const result = await db.query(query, [appUserId, hospital_code]); if (result.length === 0) { return res .status(403) .json({ error: "User does not belong to your hospital" }); } // Approve the ID if (Action == "Reject") { await db.query('UPDATE app_users SET status = "Inactive" WHERE id = ?', [ appUserId, ]); res.status(200).json({ message: "ID Rejected successfully" }); } else if (Action == "Approve") { await db.query('UPDATE app_users SET status = "Active" WHERE id = ?', [ appUserId, ]); res.status(200).json({ message: "ID approved successfully" }); } } catch (error) { console.error("Error approving ID:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.getAppUsers = async (req, res) => { try { const { role } = req.user; // Ensure the user has the proper role if (!["Superadmin", "Admin", 9, 8].includes(role)) { return res.status(403).json({ error: "Unauthorized to view app users" }); } // Query to fetch app users const query = ` SELECT * FROM app_users; `; const users = await db.query(query); if (users.length === 0) { return res .status(404) .json({ message: "No app users found for this hospital" }); } res.status(200).json({ message: "App users fetched successfully", data: users, }); } catch (error) { console.error("Error fetching app users:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.getAppUserByHospitalId = async (req, res) => { try { const { role } = req.user; const { id } = req.params; // Extract user ID from request parameters // Log authenticated user details // Ensure the user has the proper role if (!["Superadmin", "Admin", 8, 9].includes(role)) { return res.status(403).json({ error: "Unauthorized to view app users" }); } // fetching hospital code from hospital id const query1 = `SELECT * FROM hospitals WHERE id = ?`; const result1 = await db.query(query1, [id]); const hospital_code = result1[0].hospital_code; console.log("result1----", result1); // Query to fetch the app user by hospital_code const query = `SELECT * FROM app_users WHERE hospital_code = ?`; const users = await db.query(query, [hospital_code]); if (users.length === 0) { return res.status(404).json({ message: "App users not found" }); } res.status(200).json({ message: "App user fetched successfully", data: users, // Return single user object }); } catch (error) { console.error("Error fetching app user:", error.message); res.status(500).json({ error: "Internal server error" }); } }; exports.deleteAppUser = async (req, res) => { try { const { id } = req.params; const { hospital_code } = req.user; // Check if the user exists const appUserquery = "SELECT * FROM app_users WHERE id = ?"; const users = await db.query(appUserquery, [id]); if (users.length === 0) { return res .status(404) .json({ message: "No app users found for this hospital" }); } // Ensure only Admin or Superadmin can delete users if (!["Admin", "Superadmin", 8, 7,"AppUser"].includes(req.user.role)) { return res.status(403).json({ error: "Unauthorized to delete users" }); } // Ensure user belongs to the same hospital const query = "SELECT hospital_code,id_photo_url FROM app_users WHERE id = ? AND hospital_code = ?"; const result = await db.query(query, [id, hospital_code]); if (!result || result.length === 0) { return res .status(403) .json({ error: "User does not belong to your hospital" }); } // Unlink (delete) the associated file if it exists and is not null if (result[0].id_photo_url) { const filePath = path.join(__dirname, '..','..', 'uploads', result[0].id_photo_url.replace(/^\/uploads\//, '')); fs.access(filePath, fs.constants.F_OK, (err) => { if (err) { console.error(`File not found: ${filePath}`); return; } fs.unlink(filePath, (err) => { if (err) { console.error('Error deleting file:', err.message); } else { console.log('File deleted successfully:', filePath); } }); }); } else { console.log('No file to delete - id_photo_url is null'); } // delete feedback await db.query( 'DELETE FROM feedback WHERE sender_type = ? AND sender_id = ?', ['appuser', id] // Fixed: should be 'id' not 'req.user.id' ); // Delete the user const deleteResult = await db.query("DELETE FROM app_users WHERE id = ?", [ id, ]); if (deleteResult.affectedRows === 0) { return res.status(404).json({ error: "User not found" }); } res.status(200).json({ message: "User deleted successfully" }); } catch (error) { console.error("Error deleting user:", error.message); res.status(500).json({ error: "Internal server error" }); } }; // query title CRUD exports.updateQueryTitle = async (req, res) => { const id = req.user.id; const { query_title } = req.body; if (!query_title) { return res.status(400).json({ error: "query_title is required" }); } try { const result = await db.query( "UPDATE app_users SET query_title = ? WHERE id = ?", [query_title, id] ); if (result.affectedRows === 0) { return res.status(404).json({ error: "User not found" }); } res.json({ message: "Query title updated successfully" }); } catch (error) { console.error("Error updating query title:", error); res.status(500).json({ error: "Internal server error" }); } }; // Delete query_title for a user by user ID exports.getShortTitle = (req, res) => { const { question } = req.body; console.log("Question: ", question); if (!question) return res.status(400).json({ error: "No question provided" }); let shortTitle = nlp(question).sentences().toTitleCase().out("text"); // Remove unnecessary question words shortTitle = shortTitle .replace( /^(What|How|Why|When|Where|Which|Who|Is|Are|Do|Does|Can|Could)\s+/i, "" ) .trim(); if (!shortTitle) return res.status(400).json({ error: "Invalid question format" }); console.log("short question:", shortTitle); res.json({ query_title: shortTitle }); }; exports.deleteQueryTitle = async (req, res) => { const id = req.user.id; try { const result = await db.query( "UPDATE app_users SET query_title = NULL WHERE id = ?", [id] ); if (result.affectedRows === 0) { return res.status(404).json({ error: "User not found" }); } res.json({ message: "Query title deleted successfully" }); } catch (error) { console.error("Error deleting query title:", error); res.status(500).json({ error: "Internal server error" }); } }; exports.sendOtp = async (req, res) => { try { const { email } = req.body; // Validate email input if (!email) { return res.status(400).json({ error: "Email is required" }); } // Check if user exists const user = await db.query( "SELECT id, username, hospital_code FROM app_users WHERE email = ?", [email] ); if (!user.length) { return res.status(404).json({ error: "User not found" }); } console.log("user", user); const userId = user[0].id; const hospital_code = user[0].hospital_code; // fetch hospital name of app_user const hospital = await db.query( "SELECT name_hospital FROM hospitals WHERE hospital_code = ?", [hospital_code] ); console.log("hospital result : ", hospital[0].name_hospital); // Generate a 6-digit OTP const otp = Math.floor(100000 + Math.random() * 900000).toString(); const expiresAt = new Date(Date.now() + 2 * 60 * 60 * 1000); // OTP expires in 1 hour console.log("otp : ", otp, "expiresAt: ", expiresAt); // Store OTP in database await db.query( "UPDATE app_users SET otp_code = ?, otp_expires_at = ? WHERE id = ?", [otp, expiresAt, userId] ); // // Send OTP via email const info = await sendMail( email, hospital[0].name_hospital, user[0].username, otp ); res.json({ message: "OTP sent successfully", email_status: info.response }); } catch (error) { console.error("Error sending OTP:", error); res.status(500).json({ error: "Internal server error" }); } }; exports.changePassword = async (req, res) => { try { const { email, otp, new_password } = req.body; console.log("email : ", email); // Validate inputs if (!email || !otp || !new_password) { return res .status(400) .json({ error: "Email, OTP, and new password are required" }); } // Fetch OTP from the database const user = await db.query( "SELECT id, otp_code, otp_expires_at FROM app_users WHERE email = ?", [email] ); if (!user.length) { return res.status(404).json({ error: "User not found" }); } const userData = user[0]; // ✅ Check if OTP matches if (userData.otp_code !== otp) { return res.status(400).json({ error: "Invalid OTP" }); } // ✅ Check if OTP is expired if (new Date() > new Date(userData.otp_expires_at)) { return res.status(400).json({ error: "OTP expired. Request a new one." }); } // ✅ Hash the new password const hashedPassword = await bcrypt.hash(new_password, 10); // ✅ Update password in DB & clear OTP await db.query( "UPDATE app_users SET hash_password = ?, otp_code = NULL, otp_expires_at = NULL WHERE id = ?", [hashedPassword, userData.id] ); res.json({ message: "Password changed successfully!" }); } catch (error) { console.error("Error resetting password:", error); res.status(500).json({ error: "Internal server error" }); } }; exports.sendPinOtp = async (req, res) => { try { const { email } = req.body; // Validate email input if (!email) { return res.status(400).json({ error: "Email is required" }); } // Check if user exists const user = await db.query( "SELECT id, username, hospital_code FROM app_users WHERE email = ?", [email] ); if (!user.length) { return res.status(404).json({ error: "User not found" }); } console.log("user", user); const userId = user[0].id; const hospital_code = user[0].hospital_code; // fetch hospital name of app_user const hospital = await db.query( "SELECT name_hospital FROM hospitals WHERE hospital_code = ?", [hospital_code] ); console.log("hospital result : ", hospital[0].name_hospital); // Generate a 6-digit OTP const otp = Math.floor(100000 + Math.random() * 900000).toString(); const expiresAt = new Date(Date.now() + 2 * 60 * 60 * 1000); // OTP expires in 1 hour console.log("otp : ", otp, "expiresAt: ", expiresAt); // Store OTP in database await db.query( "UPDATE app_users SET pin_otp = ?, pin_otp_expiry = ? WHERE id = ?", [otp, expiresAt, userId] ); // // Send OTP via email const info = await sendMail( email, hospital[0].name_hospital, user[0].username, otp ); res.json({ message: "OTP sent successfully", email_status: info.response }); } catch (error) { console.error("Error sending OTP:", error); res.status(500).json({ error: "Internal server error" }); } }; exports.changePinByOtp = async (req, res) => { try { const { email, otp, new_pin } = req.body; console.log("email : ", email); // Validate inputs if (!email || !otp || !new_pin) { return res .status(400) .json({ error: "Email, OTP, and new pin are required" }); } // Fetch OTP from the database const user = await db.query( "SELECT id, pin_otp, pin_otp_expiry FROM app_users WHERE email = ?", [email] ); if (!user.length) { return res.status(404).json({ error: "User not found" }); } const userData = user[0]; // ✅ Check if OTP matches if (userData.pin_otp !== otp) { return res.status(400).json({ error: "Invalid OTP" }); } // ✅ Check if OTP is expired if (new Date() > new Date(userData.otp_expires_at)) { return res.status(400).json({ error: "OTP expired. Request a new one." }); } // ✅ Hash the new password // ✅ Update password in DB & clear OTP await db.query( "UPDATE app_users SET pin_number = ?, pin_otp = NULL, pin_otp_expiry = NULL WHERE id = ?", [new_pin, userData.id] ); res.json({ message: "Pin changed successfully!" }); } catch (error) { console.error("Error resetting pin:", error); res.status(500).json({ error: "Internal server error" }); } }; async function sendMail(email, hospital_name, username, otp) { const mailOptions = { from: "kavya.j@tech4biz.io", // Sender's email to: email, // Recipient's email subject: "Spurrinai Login Credentials", // Email subject html: ` Reset Your Password or Pin - Spurrinai Medical Platform
${hospital_name}

Reset Your Password or Pin

Hello ${username},

We received a request to reset the password for your account on the Spurrinai healthcare platform. For your security reasons, please verify this action.

Please enter this verification code:

${otp}

on the password reset screen

Reset Password
Note: This verification code will expire in 2 hours for security reasons.

If you did not request this password reset, please contact our IT security team immediately at info@spurrinai.com or call our support line at +1 (800) 555-1234.

`, }; try { const info = await transporter.sendMail(mailOptions); console.log("info: ", info); return info; } catch (error) { console.error(`Error sending email to ${email}:`, error); return error; } } // chat-sessions exports.getChatSessionsByAppUserID = async (req, res) => { try { console.log("user data", req.user) const { role } = req.user; // Ensure the user has the proper role // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // return res.status(403).json({ error: 'Unauthorized to view chats' }); // } if (!req.user.id) { return res.status(400).json({ error: "user id not found" }); } // Query to fetch app users const query = ` SELECT session_id, MIN(session_title) AS session_title, MIN(created_at) AS created_at FROM interaction_logs WHERE app_user_id = ${req.user.id} AND session_id IS NOT NULL GROUP BY session_id ORDER BY session_id DESC; `; const session_ids = await db.query(query); if (session_ids.length === 0) { return res.status(404).json({ message: 'No interaction logs found for this app user', data: session_ids }); } res.status(200).json({ message: 'Interaction logs fetched successfully', data: session_ids, }); } catch (error) { console.error('Error fetching interaction logs:', error.message); res.status(500).json({ error: 'Internal server error' }); } } exports.getChatForEachSession = async (req, res) => { try { console.log("user data", req.user) const session_id = req.params.session_id; console.log("session_id ", session_id) // Ensure the user has the proper role // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // return res.status(403).json({ error: 'Unauthorized to view chats' }); // } if (!req.user.id) { return res.status(400).json({ error: "user id not found" }); } // Query to fetch app users const query = ` SELECT * FROM interaction_logs WHERE app_user_id = ? AND session_id = ? AND status = 'Active'; `; const values = [req.user.id, session_id]; const interaction_logs = await db.query(query, values); if (interaction_logs.length === 0) { return res.status(404).json({ message: 'No interaction logs found for this app user or session', data: interaction_logs }); } res.status(200).json({ message: 'Interaction logs fetched successfully', data: interaction_logs, }); } catch (error) { console.error('Error fetching interaction logs:', error.message); res.status(500).json({ error: 'Internal server error' }); } } exports.deleteChatSessions = async (req, res) => { const id = req.user.id; const { session_id } = req.body console.log("session_id ", session_id) console.log("app_user_id ", id) try { const result = await db.query( "UPDATE interaction_logs SET session_id = NULL WHERE app_user_id = ? AND session_id = ?", [id, session_id] ); if (result.affectedRows === 0) { return res.status(404).json({ error: "No session found" }); } res.json({ message: "Chat session deleted successfully" }); } catch (error) { console.error("Error deleting query title:", error); res.status(500).json({ error: "Internal server error" }); } } exports.clearChatbasedOnSessions = async (req, res) => { const id = req.user.id; const { session_id } = req.body try { const result = await db.query( "UPDATE interaction_logs SET status = ? WHERE app_user_id = ? AND session_id = ?", ['Inactive', id, session_id] ); if (result.affectedRows === 0) { return res.status(404).json({ error: "No chat found" }); } res.json({ message: "Chat deleted successfully" }); } catch (error) { console.error("Error deleting chat:", error); res.status(500).json({ error: "Internal server error" }); } } exports.getChatByTime = async (req, res) => { try { console.log("user data", req.user) const { lastcreated_at } = req.body; // Ensure the user has the proper role // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // return res.status(403).json({ error: 'Unauthorized to view chats' }); // } if (!req.user.id) { return res.status(400).json({ error: "user id not found" }); } // Query to fetch app users let results console.log("last created at", lastcreated_at) if (!lastcreated_at) { // Handles null, undefined, empty string, etc. const query = ` SELECT * FROM interaction_logs WHERE app_user_id = ?; `; results = await db.query(query, [req.user.id]); } else { console.log("Executing with last_created_at:", lastcreated_at); const query = ` SELECT * FROM interaction_logs WHERE app_user_id = ? AND created_at > ?; `; results = await db.query(query, [req.user.id, lastcreated_at]); } if (results.length === 0) { return res.status(404).json({ message: 'No interaction logs found for this app user' }); } res.status(200).json({ message: 'Interaction logs fetched successfully', data: results, }); } catch (error) { console.error('Error fetching interaction logs:', error.message); res.status(500).json({ error: 'Internal server error' }); } } exports.checkEmailCode = async (req, res) => { try { const { email, hospital_code } = req.body; // Check if the email and code are provided if (!email || !hospital_code) { return res.status(400).json({ error: "Email and code are required" }); } console.log("received data", email, hospital_code) // Check if the email exists in the database const useremail = await db.query("SELECT * FROM app_users WHERE email = ?", [email]); console.log("user email", useremail) if (useremail.length) { return res.status(404).json({ error: "Email already in use" }); } // Check if the code is correct const usercode = await db.query("SELECT hospital_code FROM hospital_users WHERE hospital_code = ?", [hospital_code]); console.log("user code", usercode) if (!usercode.length) { return res.status(404).json({ error: "Please enter valid hospital code" }); } // Code is correct, return success response res.status(200).json({ message: "Email code is correct" }); } catch (error) { console.error("Error checking email code:", error); res.status(500).json({ error: "Internal server error" }); } } // get popular topics exports.getPopularTopics = async (req, res) => { let popularTopics = []; try { // Fetch top 4 most viewed questions console.log("req.user data : ", req.user) const rows = await getMappedPopularQuestionsAnswers(req.user.hospital_code); if (!rows) { popularTopics = [] } else { popularTopics = rows; } console.log('hospital data : ', rows) res.status(200).json({ success: true, data: popularTopics }); } catch (error) { console.error('Error fetching popular topics:', error); res.status(500).json({ success: false, message: 'Internal server error' }); } } const getMappedPopularQuestionsAnswers = async (hospitalCode) => { console.log("Hospital code is---", hospitalCode); try { const query = ` SELECT il.query, il.response FROM interaction_logs il WHERE il.hospital_code = ? ORDER BY il.created_at DESC -- Sorting by most recent interactions LIMIT 10; -- Fetch more than 4 to filter unwanted entries `; const rows = await db.query(query, [hospitalCode]); console.log("Fetched questions before filtering:", rows); // Skip the row if either condition is true const filteredRows = rows.filter(row => !(row.query.toLowerCase().includes("yes") || row.response.includes("Please reply with 'yes'")) ); // Return only the top 4 filtered results return filteredRows.slice(0, 4); } catch (error) { console.error("Error fetching popular topics:", error.message); throw new Error("Internal server error"); } }; exports.changePin = async (req, res) => { try { const { current_pin, new_pin } = req.body; const userId = req.user.id; if (!current_pin || !new_pin) { return res.status(400).json({ error: "Current pin and new pin are required" }); } // Add PIN length validation if (new_pin.length !== 4 || !/^\d+$/.test(new_pin)) { return res.status(400).json({ error: "New PIN must be exactly 4 digits" }); } // Get user's current pin const userQuery = "SELECT pin_number FROM app_users WHERE id = ?"; const user = await db.query(userQuery, [userId]); if (!user.length) { return res.status(404).json({ error: "User not found" }); } // Verify current pin if (user[0].pin_number !== current_pin) { return res.status(400).json({ error: "Current pin is incorrect" }); } // Check if new pin is same as current pin if (current_pin === new_pin) { return res.status(400).json({ error: "New PIN cannot be the same as current PIN" }); } // Update to new pin await db.query( "UPDATE app_users SET pin_number = ? WHERE id = ?", [new_pin, userId] ); res.json({ message: "Pin changed successfully" }); } catch (error) { console.error("Error changing pin:", error); res.status(500).json({ error: "Internal server error" }); } }; exports.forgotPin = async (req, res) => { try { const { email } = req.body; if (!email) { return res.status(400).json({ error: "Email is required" }); } // Get user details const userQuery = ` SELECT au.id, au.username, au.pin_number, au.hospital_code, h.name_hospital FROM app_users au JOIN hospitals h ON au.hospital_code = h.hospital_code WHERE au.email = ? `; const user = await db.query(userQuery, [email]); if (!user.length) { return res.status(404).json({ error: "User not found" }); } const userData = user[0]; // Send pin via email const mailOptions = { from: "kavya.j@tech4biz.io", to: email, subject: "Your Spurrinai PIN", html: ` Your PIN - Spurrinai Medical Platform
${userData.name_hospital}

Your PIN Information

Hello ${userData.username},

Here is your PIN for the Spurrinai healthcare platform:

${userData.pin_number}

For security reasons, please do not share this PIN with anyone. If you did not request this information, please contact our support team immediately.

` }; await transporter.sendMail(mailOptions); res.json({ message: "PIN has been sent to your email" }); } catch (error) { console.error("Error in forgot pin:", error); res.status(500).json({ error: "Internal server error" }); } }; // const bcrypt = require("bcrypt"); // const db = require("../config/database"); // Database connection // const fs = require("fs"); // const JWT_ACCESS_TOKEN_SECRET = process.env.JWT_ACCESS_TOKEN_SECRET; // const JWT_ACCESS_TOKEN_EXPIRY = "5h"; // const jwt = require("jsonwebtoken"); // const nlp = require("compromise"); // const nodemailer = require("nodemailer"); // const sender_mail = process.env.mail; // const sender_app_password = process.env.apppassword; // const sender_port = process.env.SENDER_PORT; // const sender_security = process.env.SENDER_SECURITY; // const path = require('path') // const { emitEvent } = require("../services/secondaryWebsocket"); // console.log('sender port : ', sender_port); // console.log('sender security : ', sender_security); // // zoho transporter // const transporter = nodemailer.createTransport({ // host: "smtp.zoho.com", // port: 465, // secure: true, // auth: { // user: "info@spurrin.com", // pass: "wTcEi6ME4yfc" // }, // tls: { // rejectUnauthorized: false, // Allow self-signed certificates // minVersion: "TLSv1.2" // } // }); // exports.initWebSocket = (io) => { // io.on("connection", (socket) => { // console.log("Hospital connected:", socket.id); // socket.on("register_hospital", (hospitalCode) => { // hospitalSockets[hospitalCode] = socket; // console.log(`Hospital ${hospitalCode} registered.`); // }); // socket.on("disconnect", () => { // const hospitalCode = Object.keys(hospitalSockets).find( // (key) => hospitalSockets[key] === socket // ); // if (hospitalCode) delete hospitalSockets[hospitalCode]; // console.log(`Hospital ${hospitalCode} disconnected.`); // }); // }); // }; // exports.uploadIdPhoto = async (req, res) => { // try { // // Extracting user ID and hospital code // const userId = parseInt(req.params.id, 10); // User ID from route // const { hospital_code } = req.user; // Authenticated user's hospital code // // Check if user ID is valid // if (isNaN(userId)) { // console.error("Invalid User ID:", userId); // return res.status(400).json({ error: "Invalid user ID" }); // } // // Check if a file was uploaded // if (!req.file) { // console.error("No file uploaded"); // return res.status(400).json({ error: "No file uploaded" }); // } // const photoPath = `/uploads/id_photos/${req.file.filename}`; // // Verify app user is part of the same hospital // const query = ` // SELECT hospital_code FROM app_users WHERE id = ? AND hospital_code = ? // `; // const result = await db.query(query, [userId, hospital_code]); // if (result.length === 0) { // console.error( // "Authorization failed for user ID:", // userId, // "with hospital_code:", // hospital_code // ); // return res // .status(403) // .json({ error: "You are not authorized to upload ID for this user" }); // } // // Update the ID photo path in the database // await db.query("UPDATE app_users SET id_photo_url = ? WHERE id = ?", [ // photoPath, // userId, // ]); // res.status(200).json({ // message: "ID photo uploaded successfully!", // id_photo_url: photoPath, // }); // } catch (error) { // console.error("Error uploading ID photo:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.updateSettings = async (req, res) => { // try { // const userId = req.user.id; // Assuming user is authenticated and userId is available // const { pin, pin_enabled, remember_me } = req.body; // console.log("data---",pin,pin_enabled,remember_me) // // if (typeof pin_enabled !== 'boolean' || typeof remember_me !== 'boolean') { // // return res.status(400).json({ error: 'Invalid data format' }); // // } // // Validate pin (if provided) // if (pin && (typeof pin !== 'string' || pin.length !== 4)) { // return res.status(400).json({ error: 'Invalid PIN format. Must be a 4-digit string.' }); // } // // Determine expiry based on remember_me // let expiresIn = '5h'; // let expiryTimestamp = new Date(); // if (remember_me) { // expiresIn = '30d'; // expiryTimestamp.setDate(expiryTimestamp.getDate() + 30); // } else { // expiryTimestamp.setHours(expiryTimestamp.getHours() + 5); // } // // Generate new access token // const payload = { id: userId, role: 'AppUser' }; // const accessToken = jwt.sign(payload, process.env.JWT_ACCESS_TOKEN_SECRET, { // expiresIn: expiresIn, // }); // // Update user settings and access token // const query = `UPDATE app_users SET pin_number = ?, pin_enabled = ?, remember_me = ?, access_token = ?, access_token_expiry = ? WHERE id = ?`; // const result=await db.query(query, [pin, pin_enabled, remember_me, accessToken, expiryTimestamp, userId]); // if (result.affectedRows > 0) { // console.log("Table updated successfully."); // } else { // console.log("Table not updated. No matching user found."); // } // res.status(200).json({ message: 'Settings updated successfully.', accessToken }); // } catch (error) { // console.error('Error updating settings:', error); // res.status(500).json({ error: 'Internal Server Error' }); // } // }; // exports.hitlike = async (req, res) => { // try { // // Extract user ID and session ID from the request // const { session_id, id } = req.body; // const log_id = id; // const app_user_id = req.user.id; // // Check if both app_user_id and session_id are provided // if (!app_user_id || !session_id || !log_id) { // return res.status(400).json({ // status: 'error', // message: 'app user id and session id and log id are required', // }); // } // // Query to toggle the is_liked value // const toggleQuery = ` // UPDATE interaction_logs // SET is_liked = NOT is_liked // WHERE app_user_id = ? AND session_id = ? AND id = ? // `; // // Execute the query // const result = await db.query(toggleQuery, [app_user_id, session_id,log_id]); // // Check if any rows were affected // if (result.affectedRows > 0) { // return res.status(200).json({ // status: 'success', // message: 'Like updated successfully', // data: { // app_user_id, // session_id, // is_liked: result.changedRows > 0 ? 1 : 0, // 1 if changed, 0 if not // }, // }); // } else { // return res.status(404).json({ // status: 'error', // message: 'No matching record found to toggle', // }); // } // } catch (error) { // console.error('Error during like toggle:', error); // return res.status(500).json({ // status: 'error', // message: 'Internal server error', // }); // } // }; // exports.signup = async (req, res) => { // try { // const { pin, pin_status,remember_me, email, password, hospital_code, username } = req.body; // console.log("pin--",pin) // console.log("pin_status",pin_status) // console.log("email--",email) // console.log('password---',password) // console.log("hospital_code---",hospital_code) // console.log("username--",username) // console.log("remember_me--",remember_me) // if (!email || !password || !hospital_code || !username) { // return res.status(400).json({ // error: "Email, password, username, and hospital code are required", // }); // } // const pin_enabled = (pin_status === undefined || pin_status === '') ? 0 : pin_status; // const remember_me_ = (remember_me === undefined || remember_me === '') ? 0 : remember_me; // // Check if the hospital_code exists in the `hospitals` table // const hospitalQuery = // "SELECT hospital_code FROM hospitals WHERE hospital_code = ?"; // const hospitalResult = await db.query(hospitalQuery, [hospital_code]); // if (hospitalResult.length === 0) { // return res.status(404).json({ error: "Invalid hospital code" }); // } // // Check if the email is already in use // const userQuery = "SELECT id FROM app_users WHERE email = ?"; // const userResult = await db.query(userQuery, [email]); // if (userResult.length > 0) { // return res.status(400).json({ error: "Email already in use" }); // } // // Hash the password // const hashPassword = await bcrypt.hash(password, 10); // // Insert the new app user into the `app_users` table // const insertQuery = ` // INSERT INTO app_users (email, hash_password, hospital_code, status, username, pin_number, pin_enabled, remember_me ) // VALUES (?, ?, ?, 'Pending', ?, ?, ?,?) // `; // const result = await db.query(insertQuery, [ // email, // hashPassword, // hospital_code, // username, // pin, // Set pin to null if not provided // pin_enabled, // remember_me_ // ]); // const userId = result.insertId; // Get the new user's ID // // Check if a file was uploaded // if (!req.file) { // return res.status(400).json({ error: "ID photo is required" }); // } // const filePath = `/uploads/id_photos/${req.file.filename}`; // Correct file path // // Update the ID photo path in the database // await db.query( // "UPDATE app_users SET id_photo_url = ?, upload_status = ? WHERE id = ?", // [filePath, "1", userId] // ); // // ✅ Notify hospitals in the SECONDARY WebSocket instance // emitEvent("new_user", { // message: `A new user has been created for hospital ${hospital_code}.`, // user: { id: userId, username, email }, // }); // res.status(201).json({ // message: "User signed up and ID photo uploaded successfully!", // data: { // id: userId, // email, // hospital_code, // username, // id_photo_url: filePath, // pin: pin || null, // pin_status : pin_status, // remember_me: remember_me // }, // }); // } catch (error) { // console.error("Error during signup and ID photo upload:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.login = async (req, res) => { // try { // const { email, password } = req.body; // let remember_me; // if (!email || !password) { // return res.status(400).json({ error: "Email and password are required" }); // } // console.log("email----",email) // // Check if the user exists // const query = "SELECT * FROM app_users WHERE email = ?"; // const result = await db.query(query, [email]); // console.log("result---",result) // if (result.length === 0) { // return res.status(404).json({ error: "User not found" }); // } // const user = result[0]; // remember_me = user.remember_me // const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [user.hospital_code]); // // if (hospitalData.publicSignupEnabled) { // // throw new Error("Hospital not found"); // // } // if (user.status === "Pending" && !hospitalData[0].publicSignupEnabled) { // return res.status(404).json({ message: "Your Account is Under Review" }); // } // if (user.status === "Inactive" && !hospitalData[0].publicSignupEnabled) { // return res.status(404).json({ message: "Contact admin your account is not approved" }); // } // if(hospitalData[0].publicSignupEnabled){ // user.status = "Active" // } // // Validate the password // const validPassword = await bcrypt.compare(password, user.hash_password); // if (!validPassword) { // return res.status(401).json({ error: "Invalid email or password" }); // } // // Determine expiry based on remember_me // let expiresIn = "5h"; // let expiryTimestamp = new Date(); // let rememberMeValue = remember_me; // if (rememberMeValue === undefined) rememberMeValue = user.remember_me; // if (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") { // const updateQuery = ` // UPDATE app_users // SET remember_me = ? // WHERE id = ? // `; // await db.query(updateQuery, [remember_me,user.id]); // expiresIn = "30d"; // expiryTimestamp.setDate(expiryTimestamp.getDate() + 30); // } else { // expiryTimestamp.setHours(expiryTimestamp.getHours() + 5); // } // // Generate a new access token // const payload = { id: user.id, email: user.email, role: "AppUser" }; // const accessToken = jwt.sign(payload, process.env.JWT_ACCESS_TOKEN_SECRET, { // expiresIn: expiresIn, // }); // // SQL query to fetch hospital data based on the provided hospital_code // const query_hospital = ` // SELECT * FROM hospitals WHERE hospital_code = ?; // `; // // Run the query // const result_hospital = await db.query(query_hospital, [user.hospital_code]); // // hospital users // const queryHospitalUsr = ` // SELECT * FROM hospital_users WHERE hospital_code = ?; // `; // // Run the query // const resultHospitalUsr = await db.query(queryHospitalUsr, [user.hospital_code]); // const hospitalUser = resultHospitalUsr[0]; // if (!hospitalUser) { // return res.status(404).json({ error: "Hospital user not found" }); // } // // Update the access token and expiry in the database // const updateQuery = ` // UPDATE app_users // SET access_token = ?, access_token_expiry = ?, remember_me = ? // WHERE id = ? // `; // await db.query(updateQuery, [accessToken, expiryTimestamp, (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") ? 1 : 0, user.id]); // // Send response // res.status(200).json({ // message: "Login successful", // user: { // id: user.id, // email: user.email, // pin: user.pin_number, // pin_enabled: user.pin_enabled, // hospital_code: user.hospital_code, // status: user.status, // hospital_name: result_hospital[0].name_hospital, // primary_color: result_hospital[0].primary_color, // secondary_color: result_hospital[0].secondary_color, // upload_status: user.upload_status, // id_photo_url: user.id_photo_url, // primary_admin_email: result_hospital[0].primary_admin_email, // mobile_number: result_hospital[0].mobile_number, // username: user.username, // logo_url: resultHospitalUsr[0].profile_photo_url, // query_title: user.query_title, // remember_me: (rememberMeValue === true || rememberMeValue === 1 || rememberMeValue === "1" || rememberMeValue === "true") ? 1 : 0 // }, // accessToken, // }); // } catch (error) { // console.error("Error during login:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.checkPin = async (req, res) => { // try { // const { email, pin } = req.body; // if (!email || !pin) { // return res.status(400).json({ error: "Email and Pin are required" }); // } // // Check if the user exists // const query = "SELECT * FROM app_users WHERE email = ?"; // const result = await db.query(query, [email]); // if (result.length === 0) { // return res.status(404).json({ error: "User not found" }); // } // const user = result[0]; // const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [user.hospital_code]); // if (user.status === "Pending" && !hospitalData[0].publicSignupEnabled) { // throw new Error("Your Account is Under Review"); // } // if (user.status === "Inactive" && !hospitalData[0].publicSignupEnabled) { // throw new Error("Contact admin your account is not approved"); // } // // Check PIN if PIN status is enabled // if (pin !== user.pin_number) { // return res.status(401).json({ // error: "Invalid PIN", // requires_pin: true, // message: "Incorrect PIN. Please try again" // }); // } // // Send response // res.status(200).json({ // message: "Pin verified successfully", // }); // } catch (error) { // console.error("Error during login:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.logout = async (req, res) => { // try { // const userId = req.user.id; // Assuming the user is authenticated via middleware // // Check if the user exists // const query = "SELECT * FROM app_users WHERE id = ?"; // const result = await db.query(query, [userId]); // if (result.length === 0) { // return res.status(404).json({ error: "User not found" }); // } // // Invalidate the access token in the database // const updateQuery = ` // UPDATE app_users // SET access_token = NULL, access_token_expiry = NULL // WHERE id = ? // `; // await db.query(updateQuery, [userId]); // res.status(200).json({ message: "Logout successful" }); // } catch (error) { // console.error("Error during logout:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // // controller.js // exports.getAppUsersByHospitalCode = async (req, res) => { // try { // // Extract the hospital_code from the token (req.user object) // const userId = req.user.id; // if (!userId) { // return res.status(400).json({ error: "User not found for the token" }); // } // // Query to fetch hospital users based on the hospital_code // const query = ` // SELECT id, email, status,hospital_code // FROM app_users // WHERE id = ?; // `; // const result = await db.query(query, [userId]); // if (result.length === 0) { // return res // .status(404) // .json({ error: "No users found for the specified Token" }); // } // const hospitalData = await db.query("SELECT * FROM hospitals WHERE hospital_code = ?", [result[0].hospital_code]); // if(hospitalData[0].publicSignupEnabled){ // result[0].status = 'Active' // } // // Send the response with the users data // res.status(200).json({ // message: "Hospital users fetched successfully", // user: result[0], // }); // } catch (error) { // console.error("Error fetching hospital users:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.approveUserId = async (req, res) => { // try { // const appUserId = req.params.id; // App user ID to approve // const { role } = req.user; // Authenticated user's details // const { Action } = req.body; // const { hospital_code } = req.user; // if (!req.body.Action) { // return res.status(400).json({ error: "Action is required" }); // } // if (!["Superadmin", "Admin", 8].includes(role)) { // return res.status(403).json({ error: "Unauthorized to approve IDs" }); // } // const query = ` // SELECT hospital_code FROM app_users WHERE id = ? AND hospital_code = ? // `; // const result = await db.query(query, [appUserId, hospital_code]); // if (result.length === 0) { // return res // .status(403) // .json({ error: "User does not belong to your hospital" }); // } // // Approve the ID // if (Action == "Reject") { // await db.query('UPDATE app_users SET status = "Inactive" WHERE id = ?', [ // appUserId, // ]); // res.status(200).json({ message: "ID Rejected successfully" }); // } else if (Action == "Approve") { // await db.query('UPDATE app_users SET status = "Active" WHERE id = ?', [ // appUserId, // ]); // res.status(200).json({ message: "ID approved successfully" }); // } // } catch (error) { // console.error("Error approving ID:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.getAppUsers = async (req, res) => { // try { // const { role } = req.user; // // Ensure the user has the proper role // if (!["Superadmin", "Admin", 9, 8].includes(role)) { // return res.status(403).json({ error: "Unauthorized to view app users" }); // } // // Query to fetch app users // const query = ` // SELECT * FROM app_users; // `; // const users = await db.query(query); // if (users.length === 0) { // return res // .status(404) // .json({ message: "No app users found for this hospital" }); // } // res.status(200).json({ // message: "App users fetched successfully", // data: users, // }); // } catch (error) { // console.error("Error fetching app users:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.getAppUserByHospitalId = async (req, res) => { // try { // const { role } = req.user; // const { id } = req.params; // Extract user ID from request parameters // // Log authenticated user details // // Ensure the user has the proper role // if (!["Superadmin", "Admin", 8, 9].includes(role)) { // return res.status(403).json({ error: "Unauthorized to view app users" }); // } // // fetching hospital code from hospital id // const query1 = `SELECT * FROM hospitals WHERE id = ?`; // const [result1] = await db.query(query1, [id]); // const hospital_code = result1.hospital_code; // // Query to fetch the app user by hospital_code // const query = `SELECT * FROM app_users WHERE hospital_code = ?`; // const users = await db.query(query, [hospital_code]); // if (users.length === 0) { // return res.status(404).json({ message: "App users not found" }); // } // res.status(200).json({ // message: "App user fetched successfully", // data: users, // Return single user object // }); // } catch (error) { // console.error("Error fetching app user:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.deleteAppUser = async (req, res) => { // try { // const { id } = req.params; // const { hospital_code } = req.user; // // Check if the user exists // // const [users] = await db.query('SELECT * FROM app_users WHERE id = ?', [id]); // ✅ Properly handle array // // if (!users || users.length === 0) { // // return res.status(404).json({ error: 'User not found' }); // // } // const appUserquery = "SELECT * FROM app_users WHERE id = ?"; // const users = await db.query(appUserquery, [id]); // if (users.length === 0) { // return res // .status(404) // .json({ message: "No app users found for this hospital" }); // } // // Ensure only Admin or Superadmin can delete users // if (!["Admin", "Superadmin", 8, 7].includes(req.user.role)) { // return res.status(403).json({ error: "Unauthorized to delete users" }); // } // // Ensure user belongs to the same hospital // const query = // "SELECT hospital_code,id_photo_url FROM app_users WHERE id = ? AND hospital_code = ?"; // const result = await db.query(query, [id, hospital_code]); // if (!result || result.length === 0) { // return res // .status(403) // .json({ error: "User does not belong to your hospital" }); // } // // Unlink (delete) the associated file if it exists // const filePath = path.join(__dirname, '..','..', 'uploads', result[0].id_photo_url.replace(/^\/uploads\//, '')); // fs.access(filePath, fs.constants.F_OK, (err) => { // if (err) { // console.error(`File not found: ${filePath}`); // return; // } // fs.unlink(filePath, (err) => { // if (err) { // console.error('Error deleting file:', err.message); // } else { // console.log('File deleted successfully:', filePath); // } // }); // }); // // Delete the user // const deleteResult = await db.query("DELETE FROM app_users WHERE id = ?", [ // id, // ]); // if (deleteResult.affectedRows === 0) { // return res.status(404).json({ error: "User not found" }); // } // res.status(200).json({ message: "User deleted successfully" }); // } catch (error) { // console.error("Error deleting user:", error.message); // res.status(500).json({ error: "Internal server error" }); // } // }; // // query title CRUD // exports.updateQueryTitle = async (req, res) => { // const id = req.user.id; // const { query_title } = req.body; // if (!query_title) { // return res.status(400).json({ error: "query_title is required" }); // } // try { // const result = await db.query( // "UPDATE app_users SET query_title = ? WHERE id = ?", // [query_title, id] // ); // if (result.affectedRows === 0) { // return res.status(404).json({ error: "User not found" }); // } // res.json({ message: "Query title updated successfully" }); // } catch (error) { // console.error("Error updating query title:", error); // res.status(500).json({ error: "Internal server error" }); // } // }; // // Delete query_title for a user by user ID // exports.getShortTitle = (req, res) => { // const { question } = req.body; // console.log("Question: ", question); // if (!question) return res.status(400).json({ error: "No question provided" }); // let shortTitle = nlp(question).sentences().toTitleCase().out("text"); // // Remove unnecessary question words // shortTitle = shortTitle // .replace( // /^(What|How|Why|When|Where|Which|Who|Is|Are|Do|Does|Can|Could)\s+/i, // "" // ) // .trim(); // if (!shortTitle) // return res.status(400).json({ error: "Invalid question format" }); // console.log("short question:", shortTitle); // res.json({ query_title: shortTitle }); // }; // exports.deleteQueryTitle = async (req, res) => { // const id = req.user.id; // try { // const result = await db.query( // "UPDATE app_users SET query_title = NULL WHERE id = ?", // [id] // ); // if (result.affectedRows === 0) { // return res.status(404).json({ error: "User not found" }); // } // res.json({ message: "Query title deleted successfully" }); // } catch (error) { // console.error("Error deleting query title:", error); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.sendOtp = async (req, res) => { // try { // const { email } = req.body; // // Validate email input // if (!email) { // return res.status(400).json({ error: "Email is required" }); // } // // Check if user exists // const user = await db.query( // "SELECT id, username, hospital_code FROM app_users WHERE email = ?", // [email] // ); // if (!user.length) { // return res.status(404).json({ error: "User not found" }); // } // console.log("user", user); // const userId = user[0].id; // const hospital_code = user[0].hospital_code; // // fetch hospital name of app_user // const hospital = await db.query( // "SELECT name_hospital FROM hospitals WHERE hospital_code = ?", // [hospital_code] // ); // console.log("hospital result : ", hospital[0].name_hospital); // // Generate a 6-digit OTP // const otp = Math.floor(100000 + Math.random() * 900000).toString(); // const expiresAt = new Date(Date.now() + 2 * 60 * 60 * 1000); // OTP expires in 1 hour // console.log("otp : ", otp, "expiresAt: ", expiresAt); // // Store OTP in database // await db.query( // "UPDATE app_users SET otp_code = ?, otp_expires_at = ? WHERE id = ?", // [otp, expiresAt, userId] // ); // // // Send OTP via email // const info = await sendMail( // email, // hospital[0].name_hospital, // user[0].username, // otp // ); // res.json({ message: "OTP sent successfully", email_status: info.response }); // } catch (error) { // console.error("Error sending OTP:", error); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.changePassword = async (req, res) => { // try { // const { email, otp, new_password } = req.body; // console.log("email : ", email); // // Validate inputs // if (!email || !otp || !new_password) { // return res // .status(400) // .json({ error: "Email, OTP, and new password are required" }); // } // // Fetch OTP from the database // const user = await db.query( // "SELECT id, otp_code, otp_expires_at FROM app_users WHERE email = ?", // [email] // ); // if (!user.length) { // return res.status(404).json({ error: "User not found" }); // } // const userData = user[0]; // // ✅ Check if OTP matches // if (userData.otp_code !== otp) { // return res.status(400).json({ error: "Invalid OTP" }); // } // // ✅ Check if OTP is expired // if (new Date() > new Date(userData.otp_expires_at)) { // return res.status(400).json({ error: "OTP expired. Request a new one." }); // } // // ✅ Hash the new password // const hashedPassword = await bcrypt.hash(new_password, 10); // // ✅ Update password in DB & clear OTP // await db.query( // "UPDATE app_users SET hash_password = ?, otp_code = NULL, otp_expires_at = NULL WHERE id = ?", // [hashedPassword, userData.id] // ); // res.json({ message: "Password changed successfully!" }); // } catch (error) { // console.error("Error resetting password:", error); // res.status(500).json({ error: "Internal server error" }); // } // }; // async function sendMail(email, hospital_name, username, otp) { // const mailOptions = { // from: sender_mail, // Sender's email // to: email, // Recipient's email // subject: "Spurrinai Login Credentials", // Email subject // html: ` // // // // // Reset Your Password - Spurrinai Medical Platform // // // //
//
//
${hospital_name}
//

Reset Your Password

//
//
//
Hello ${username},
//

We received a request to reset the password for your account on the Spurrinai healthcare platform. For your security reasons, please verify this action.

//
//

Please enter this verification code:

//
${otp}
//

on the password reset screen

//
// Reset Password //
// Note: This verification code will expire in 2 hours for security reasons. //
//
//

If you did not request this password reset, please contact our IT security team immediately at info@spurrinai.com or call our support line at +1 (800) 555-1234.

//
//
// //
// // `, // }; // try { // const info = await transporter.sendMail(mailOptions); // console.log("info: ", info); // return info; // } catch (error) { // console.error(`Error sending email to ${email}:`, error); // return error; // } // } // // chat-sessions // exports.getChatSessionsByAppUserID = async (req, res) => { // try { // console.log("user data", req.user) // const { role } = req.user; // // Ensure the user has the proper role // // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // // return res.status(403).json({ error: 'Unauthorized to view chats' }); // // } // if (!req.user.id) { // return res.status(400).json({ error: "user id not found" }); // } // // Query to fetch app users // const query = ` // SELECT session_id, // MIN(session_title) AS session_title, // MIN(created_at) AS created_at // FROM interaction_logs // WHERE app_user_id = ${req.user.id} // AND session_id IS NOT NULL // GROUP BY session_id // ORDER BY session_id DESC; // `; // const session_ids = await db.query(query); // if (session_ids.length === 0) { // return res.status(404).json({ message: 'No interaction logs found for this app user', data: session_ids }); // } // res.status(200).json({ // message: 'Interaction logs fetched successfully', // data: session_ids, // }); // } catch (error) { // console.error('Error fetching interaction logs:', error.message); // res.status(500).json({ error: 'Internal server error' }); // } // } // exports.getChatForEachSession = async (req, res) => { // try { // console.log("user data", req.user) // const session_id = req.params.session_id; // console.log("session_id ", session_id) // // Ensure the user has the proper role // // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // // return res.status(403).json({ error: 'Unauthorized to view chats' }); // // } // if (!req.user.id) { // return res.status(400).json({ error: "user id not found" }); // } // // Query to fetch app users // const query = ` // SELECT * FROM interaction_logs // WHERE app_user_id = ? // AND session_id = ? // AND status = 'Active'; // `; // const values = [req.user.id, session_id]; // const interaction_logs = await db.query(query, values); // if (interaction_logs.length === 0) { // return res.status(404).json({ message: 'No interaction logs found for this app user or session', data: interaction_logs }); // } // res.status(200).json({ // message: 'Interaction logs fetched successfully', // data: interaction_logs, // }); // } catch (error) { // console.error('Error fetching interaction logs:', error.message); // res.status(500).json({ error: 'Internal server error' }); // } // } // exports.deleteChatSessions = async (req, res) => { // const id = req.user.id; // const { session_id } = req.body // console.log("session_id ", session_id) // console.log("app_user_id ", id) // try { // const result = await db.query( // "UPDATE interaction_logs SET session_id = NULL WHERE app_user_id = ? AND session_id = ?", // [id, session_id] // ); // if (result.affectedRows === 0) { // return res.status(404).json({ error: "No session found" }); // } // res.json({ message: "Chat session deleted successfully" }); // } catch (error) { // console.error("Error deleting query title:", error); // res.status(500).json({ error: "Internal server error" }); // } // } // exports.clearChatbasedOnSessions = async (req, res) => { // const id = req.user.id; // const { session_id } = req.body // try { // const result = await db.query( // "UPDATE interaction_logs SET status = ? WHERE app_user_id = ? AND session_id = ?", // ['Inactive', id, session_id] // ); // if (result.affectedRows === 0) { // return res.status(404).json({ error: "No chat found" }); // } // res.json({ message: "Chat deleted successfully" }); // } catch (error) { // console.error("Error deleting chat:", error); // res.status(500).json({ error: "Internal server error" }); // } // } // exports.getChatByTime = async (req, res) => { // try { // console.log("user data", req.user) // const { lastcreated_at } = req.body; // // Ensure the user has the proper role // // if (!['Superadmin', 'Admin', 9, 8].includes(role)) { // // return res.status(403).json({ error: 'Unauthorized to view chats' }); // // } // if (!req.user.id) { // return res.status(400).json({ error: "user id not found" }); // } // // Query to fetch app users // let results // console.log("last created at", lastcreated_at) // if (!lastcreated_at) { // Handles null, undefined, empty string, etc. // const query = ` // SELECT * FROM interaction_logs // WHERE app_user_id = ?; // `; // results = await db.query(query, [req.user.id]); // } else { // console.log("Executing with last_created_at:", lastcreated_at); // const query = ` // SELECT * FROM interaction_logs // WHERE app_user_id = ? // AND created_at > ?; // `; // results = await db.query(query, [req.user.id, lastcreated_at]); // } // if (results.length === 0) { // return res.status(404).json({ message: 'No interaction logs found for this app user' }); // } // res.status(200).json({ // message: 'Interaction logs fetched successfully', // data: results, // }); // } catch (error) { // console.error('Error fetching interaction logs:', error.message); // res.status(500).json({ error: 'Internal server error' }); // } // } // exports.checkEmailCode = async (req, res) => { // try { // const { email, hospital_code } = req.body; // // Check if the email and code are provided // if (!email || !hospital_code) { // return res.status(400).json({ error: "Email and code are required" }); // } // console.log("received data", email, hospital_code) // // Check if the email exists in the database // const useremail = await db.query("SELECT * FROM app_users WHERE email = ?", [email]); // console.log("user email", useremail) // if (useremail.length) { // return res.status(404).json({ error: "Email already in use" }); // } // // Check if the code is correct // const usercode = await db.query("SELECT hospital_code FROM hospital_users WHERE hospital_code = ?", [hospital_code]); // console.log("user code", usercode) // if (!usercode.length) { // return res.status(404).json({ error: "Please enter valid hospital code" }); // } // // Code is correct, return success response // res.status(200).json({ message: "Email code is correct" }); // } catch (error) { // console.error("Error checking email code:", error); // res.status(500).json({ error: "Internal server error" }); // } // } // // get popular topics // exports.getPopularTopics = async (req, res) => { // let popularTopics = []; // try { // // Fetch top 4 most viewed questions // console.log("req.user data : ", req.user) // const rows = await getMappedPopularQuestionsAnswers(req.user.hospital_code); // if (!rows) { // popularTopics = [] // } // else { // popularTopics = rows; // } // console.log('hospital data : ', rows) // res.status(200).json({ // success: true, // data: popularTopics // }); // } catch (error) { // console.error('Error fetching popular topics:', error); // res.status(500).json({ // success: false, // message: 'Internal server error' // }); // } // } // const getMappedPopularQuestionsAnswers = async (hospitalCode) => { // console.log("Hospital code is---", hospitalCode); // try { // const query = ` // SELECT il.query, il.response // FROM interaction_logs il // WHERE il.hospital_code = ? // ORDER BY il.created_at DESC -- Sorting by most recent interactions // LIMIT 10; -- Fetch more than 4 to filter unwanted entries // `; // const rows = await db.query(query, [hospitalCode]); // console.log("Fetched questions before filtering:", rows); // // Skip the row if either condition is true // const filteredRows = rows.filter(row => // !(row.query.toLowerCase().includes("yes") || row.response.includes("Please reply with 'yes'")) // ); // // Return only the top 4 filtered results // return filteredRows.slice(0, 4); // } catch (error) { // console.error("Error fetching popular topics:", error.message); // throw new Error("Internal server error"); // } // }; // exports.changePin = async (req, res) => { // try { // const { current_pin, new_pin } = req.body; // const userId = req.user.id; // if (!current_pin || !new_pin) { // return res.status(400).json({ error: "Current pin and new pin are required" }); // } // // Add PIN length validation // if (new_pin.length !== 4 || !/^\d+$/.test(new_pin)) { // return res.status(400).json({ error: "New PIN must be exactly 4 digits" }); // } // // Get user's current pin // const userQuery = "SELECT pin_number FROM app_users WHERE id = ?"; // const user = await db.query(userQuery, [userId]); // if (!user.length) { // return res.status(404).json({ error: "User not found" }); // } // // Verify current pin // if (user[0].pin_number !== current_pin) { // return res.status(400).json({ error: "Current pin is incorrect" }); // } // // Check if new pin is same as current pin // if (current_pin === new_pin) { // return res.status(400).json({ error: "New PIN cannot be the same as current PIN" }); // } // // Update to new pin // await db.query( // "UPDATE app_users SET pin_number = ? WHERE id = ?", // [new_pin, userId] // ); // res.json({ message: "Pin changed successfully" }); // } catch (error) { // console.error("Error changing pin:", error); // res.status(500).json({ error: "Internal server error" }); // } // }; // exports.forgotPin = async (req, res) => { // try { // const { email } = req.body; // if (!email) { // return res.status(400).json({ error: "Email is required" }); // } // // Get user details // const userQuery = ` // SELECT au.id, au.username, au.pin_number, au.hospital_code, h.name_hospital // FROM app_users au // JOIN hospitals h ON au.hospital_code = h.hospital_code // WHERE au.email = ? // `; // const user = await db.query(userQuery, [email]); // if (!user.length) { // return res.status(404).json({ error: "User not found" }); // } // const userData = user[0]; // // Send pin via email // const mailOptions = { // from: "srikanth.mallikarjuna@tech4biz.io", // to: email, // subject: "Your Spurrinai PIN", // html: ` // // // // // Your PIN - Spurrinai Medical Platform // // // //
//
//
${userData.name_hospital}
//

Your PIN Information

//
//
//
Hello ${userData.username},
//

Here is your PIN for the Spurrinai healthcare platform:

//
//
${userData.pin_number}
//
//
//

For security reasons, please do not share this PIN with anyone. If you did not request this information, please contact our support team immediately.

//
//
// //
// // ` // }; // await transporter.sendMail(mailOptions); // res.json({ message: "PIN has been sent to your email" }); // } catch (error) { // console.error("Error in forgot pin:", error); // res.status(500).json({ error: "Internal server error" }); // } // };