import jwt from "jsonwebtoken"; import bcrypt from "bcrypt"; import { VAModel } from "../../../models/vaModel.js"; // Register a new VA async function va_profile_update_callback(req, res) { try { const sf_token = req.headers.sf_token; const accessToken = req.headers.token; let vaUser; let authSource = 'regular'; if(sf_token) { try { const sfDecoded = jwt.verify(sf_token, process.env.JWT_SECRET_SF_TOKEN); if (!sfDecoded?.email && !sfDecoded?.portalId) { return res.status(400).json({ success: false, message: "Invalid Salesforce token payload" }); } // Find user by email or VA ID from Salesforce token if (sfDecoded.portalId) { vaUser = await VAModel.findById(sfDecoded.portalId); } else if (sfDecoded.email) { vaUser = await VAModel.findOne({ "userDetails.email": sfDecoded.email }); } if (!vaUser) { return res.status(404).json({ success: false, message: "VA not found with Salesforce token" }); } authSource = 'salesforce'; } catch (sfError) { return res.status(401).json({ success: false, message: "Invalid or expired Salesforce token" }); } } else { try { if (!accessToken) { return res.status(401).json({ success: false, message: "Missing access token" }); } const decoded = jwt.verify(accessToken, process.env.JWT_SECRET_ACCESS_TOKEN); if (!decoded?.email) { return res.status(400).json({ success: false, message: "Invalid token payload" }); } vaUser = await VAModel.findOne({ "userDetails.email": decoded.email }); if (!vaUser) { return res.status(404).json({ success: false, message: "VA not found" }); } authSource = 'regular'; } catch (tokenError) { return res.status(401).json({ success: false, message: "Invalid or expired access token" }); } } const payload = req.body || {}; const { userDetails, status } = payload; if (!userDetails) { return res.status(400).json({ success: false, message: "Missing userDetails" }); } const allowedFields = [ "firstName", "lastName", "dob", "age", "address", "city", "state", "country", "phone", "skype", "paymentMethod", "payoneerAccount", "veemAccount" ]; let hasUpdates = false; const updatedFields = []; // Update allowed fields if provided allowedFields.forEach(field => { if (userDetails[field] !== undefined && userDetails[field] !== null && userDetails[field] !== '') { vaUser.userDetails[field] = userDetails[field]; hasUpdates = true; updatedFields.push(field); } }); /* ---------------------- PASSWORD UPDATE ---------------------- */ let passwordUpdated = false; if (userDetails.password || userDetails.cPassword || userDetails.oldPassword) { const { oldPassword, password, cPassword } = userDetails; if (authSource === 'salesforce') { return res.status(403).json({ success: false, message: "Password changes require regular authentication", }); } if (!oldPassword || !password || !cPassword) { return res.status(400).json({ success: false, message: "Please provide oldPassword, password, and cPassword to update password", }); } if (password !== cPassword) { return res.status(400).json({ success: false, message: "New passwords do not match", }); } // Verify old password const isMatch = await bcrypt.compare(oldPassword, vaUser.userDetails.password); if (!isMatch) { return res.status(400).json({ success: false, message: "Old password is incorrect", }); } // Hash and update new password const saltRounds = 10; const hashedPassword = await bcrypt.hash(password, saltRounds); vaUser.userDetails.password = hashedPassword; hasUpdates = true; passwordUpdated = true; updatedFields.push('password'); } if (!hasUpdates) { return res.status(400).json({ success: false, message: "No valid fields to update", }); } if (status) { vaUser.status = status; updatedFields.push('status'); } await vaUser.save(); const updatedUser = await VAModel.findById(vaUser._id) .select("-userDetails.password") .lean(); return res.status(200).json({ success: true, message: "Profile updated successfully", data: updatedUser, updatedFields: updatedFields, }); } catch (error) { return res.status(500).json({ success: false, message: "Internal Server Error" }); } } export { va_profile_update_callback };