diff --git a/src/server.js b/src/server.js index b3376c9..587e7f0 100644 --- a/src/server.js +++ b/src/server.js @@ -196,236 +196,14 @@ import { ObjectId } from 'mongodb/lib/bson.js'; const vaSocketRespectToClient = new Map(); -io.use(async (socket, next) => { - try { - const token = socket.handshake.auth?.token; - const projectId = socket.handshake.auth?.projectId; - const userType = socket.handshake.auth?.userType; - - console.log("🔐 Received token:", token); - - if (!token) { - return next(new Error("Not Authorized: Missing Token")); - } - - const decoded = jwt.verify(token, process.env.JWT_SECRET_ACCESS_TOKEN); - - if (!decoded?.email) { - return next(new Error("Invalid token payload")); - } - - /* ---------------------- 1⃣ Check if VA ---------------------- */ - let vaUser = null; - let clientData = null; - - if (userType === "va") { - vaUser = await VAModel.findOne({ "userDetails.email": decoded.email }); - clientData = await ProjectModel.findById(projectId).populate("clientId"); - } else if (userType === "client") { - clientData = await ProjectModel.findById(projectId).populate("clientId"); - } - - if (clientData == null) return next(new Error("Invalid Project ID")); - const vaProjClientId = clientData.clientId._id; - - if (vaUser && vaUser.accessToken === token) { - socket.data.role = "va"; - socket.data.vaId = vaUser._id.toString(); - socket.data.vaEmail = decoded.email; - - const a = vaProjClientId.toString(); - const b = clientData.clientId._id.toString(); - const c = JSON.stringify(clientData); - - console.log(a, b, c, "vaProjClientId vs clientData.clientId"); - - vaSocketRespectToClient.set(vaProjClientId.toString(), socket.id) - - console.log("✅ Authenticated VA:", vaUser.userDetails.email); - return next(); - } - - /* ---------------------- 2⃣ Check if Client ---------------------- */ - // const clientUser = await ClientModel.findOne({ "userDetails.email": decoded.email }); - - // if (clientUser) { - // socket.data.role = "client"; - // socket.data.clientId = clientUser._id.toString(); - - // // Get all VA IDs assigned to this client - // socket.data.allowedVAs = clientUser.vaIds.map((va) => va.toString()); - - // console.log("✅ Authenticated Client:", clientUser.userDetails.email); - // return next(); - // } - const clientUser = clientData.clientId; - - if (clientUser) { - socket.data.role = "client"; - socket.data.clientId = clientUser._id.toString(); - - // Get all VA IDs assigned to this client - socket.data.allowedVAs = clientData.vaAssigned.map((va) => va.toString()); - - // console.log("✅ Authenticated Client:", clientUser.userDetails.email); - return next(); - } - - return next(new Error("Not Authorized: Invalid User")); - } catch (error) { - console.error("❌ Socket Auth Error:", error.message); - next(new Error("Authentication failed: " + error.message)); - } -}); - - - -io.on("connection", (socket) => { - console.log("User connected:", socket.id); - - // Register role and ID (client or VA) - socket.on("register", async ({ role, id, projectId = null, clientId = null }) => { - if (role === "va") { - socket.data.role = "va"; - socket.data.vaId = id; - console.log(`VA registered: ${id}`); - } - - if (role === "client") { - socket.data.role = "client"; - socket.data.vaId = id; - socket.data.projectId = projectId; - socket.data.clientId = null - - if (!projectId || !clientId) { - console.log("projectId is missing in register payload"); - return; - } - - socket.data.clientId = clientId; - - // 🧩 Get allowed VAs for this client - const client = await ClientModel.findById(clientId) - .populate("projectIds") // to access their projects - .populate("vaIds"); // optional if you track directly - - // Collect all VA IDs from their projects - const projectVAIds = new Set(); - for (const project of client.projectIds) { - const populated = await ProjectModel.findById(project._id).populate("vaAssigned"); - populated.vaAssigned.forEach((va) => projectVAIds.add(va._id.toString())); - } - - // Store allowed VA IDs in socket memory - socket.data.allowedVAs = Array.from(projectVAIds); - console.log(`Client ${id} can view VAs:`, socket.data.allowedVAs); - } - }); - - // When VA sends live image - socket.on("sendImage", async ({ token, image, title }) => { - try { - // Verify token - const decoded = jwt.verify(token, process.env.JWT_SECRET_ACCESS_TOKEN); - const vaEmail = decoded.email; - - // Find VA in DB - const vaUser = await VAModel.findOne({ "userDetails.email": vaEmail }); - if (!vaUser) { - console.log("❌ Unauthorized VA"); - return; - } - - const vaId = vaUser._id.toString(); - console.log("🟢 Received image from VA:", vaId); - - // Broadcast image only to allowed clients - for (let [_, clientSocket] of io.sockets.sockets) { - if ( - clientSocket.data.role === "client" && - clientSocket.data.allowedVAs?.includes(vaId) - ) { - clientSocket.emit("receiveImage", image, title); - } - } - } catch (err) { - console.error("❌ Token verification failed:", err.message); - } - }); - - socket.on("selectApp", ({ appTitle, clientId }) => { - console.log(`VA selected app: ${appTitle}`); - - const sssrrrr = vaSocketRespectToClient.get(clientId); - console.log(vaSocketRespectToClient.get(clientId), sssrrrr, "vaSocketRespectToClient[clientId]") - // You can forward this info to the respective Electron client - socket.to(vaSocketRespectToClient.get(clientId)).emit("appToCapture", { appTitle }); - }); - - socket.on("getVisibleApps", async ({ token, apps }) => { - try { - // Verify token - const decoded = jwt.verify(token, process.env.JWT_SECRET_ACCESS_TOKEN); - const vaEmail = decoded.email; - - // Find VA in DB - const vaUser = await VAModel.findOne({ "userDetails.email": vaEmail }); - if (!vaUser) { - console.log("❌ Unauthorized VA"); - return; - } - - const vaId = vaUser._id.toString(); - console.log("🟢 Received Apps from VA:", vaId); - - // Broadcast image only to allowed clients - for (let [_, clientSocket] of io.sockets.sockets) { - if ( - clientSocket.data.role === "client" && - clientSocket.data.allowedVAs?.includes(vaId) - ) { - clientSocket.emit("receiveVisibleApps", apps); - } - } - } catch (err) { - console.error("❌ Token verification failed:", err.message); - } - }); - - - socket.on('disconnect', () => { - console.log('a user Disconnected'); - }); -}); - - - - -// io.on('connection', (socket) => { - -// socket.on("sendImage", (base64String) => { -// io.emit("receiveImage", base64String); -// }); - - -// socket.on('disconnect', () => { -// console.log('a user Disconnected'); -// }); -// }); - -app.get("/client/login", (req, res) => { - res.render("client_login") -}) -app.get("/client/forgot-password", (req, res) => { - res.render("forgot_password") -}) - // Handling Socket io.use(async (socket, next) => { try { const token = socket.handshake.auth?.token; const projectId = socket.handshake.auth?.projectId; const userType = socket.handshake.auth?.userType; + const vaId = socket.handshake.auth?.vaId; + console.log("🔐 Received token:", token); @@ -464,7 +242,7 @@ io.use(async (socket, next) => { console.log(a, b, c, "vaProjClientId vs clientData.clientId"); - vaSocketRespectToClient.set(`${vaProjClientId.toString()}-${vaUser._id.toString()}`, socket.id) + vaSocketRespectToClient.set(`${vaProjClientId.toString()}-${vaUser._id.toString()}-${projectId.toString()}-va`, socket.id) console.log("✅ Authenticated VA:", vaUser.userDetails.email); return next(); @@ -491,6 +269,7 @@ io.use(async (socket, next) => { // Get all VA IDs assigned to this client socket.data.allowedVAs = clientData.vaAssigned.map((va) => va.toString()); + vaSocketRespectToClient.set(`${vaProjClientId.toString()}-${vaId.toString()}-${projectId.toString()}-client`, socket.id) // console.log("✅ Authenticated Client:", clientUser.userDetails.email); return next(); @@ -503,8 +282,6 @@ io.use(async (socket, next) => { } }); - - io.on("connection", (socket) => { console.log("User connected:", socket.id); @@ -539,7 +316,7 @@ io.on("connection", (socket) => { }); // When VA sends live image - socket.on("sendImage", async ({ token, image, title }) => { + socket.on("sendImage", async ({ token, image, title, projectId }) => { try { // Verify token const decoded = jwt.verify(token, process.env.JWT_SECRET_ACCESS_TOKEN); @@ -552,30 +329,42 @@ io.on("connection", (socket) => { return; } + const project = await ProjectModel.findById(projectId); + if (!project) { + console.log("❌ Invalid Project ID"); + return; + } + + const clientId = project.clientId.toString(); const vaId = vaUser._id.toString(); + const clientVaUniqueId = `${clientId}-${vaId}-${projectId}-client`; + const socketId = vaSocketRespectToClient.get(clientVaUniqueId); + console.log("🟢 Received image from VA:", vaId); // Broadcast image only to allowed clients - for (let [_, clientSocket] of io.sockets.sockets) { - if ( - clientSocket.data.role === "client" && - clientSocket.data.allowedVAs?.includes(vaId) - ) { - clientSocket.emit("receiveImage", image, title); - } - } + // for (let [_, clientSocket] of io.sockets.sockets) { + // if ( + // clientSocket.data.role === "client" && + // clientSocket.data.allowedVAs?.includes(vaId) + // ) { + // clientSocket.emit("receiveImage", image, title); + // } + // } + + // Can be like clientId-projectId-vaId to uniquely identify + socket.to(socketId).emit("receiveImage", image, title); } catch (err) { console.error("❌ Token verification failed:", err.message); } }); - socket.on("selectApp", ({ appTitle, clientId }) => { + socket.on("selectApp", ({ appTitle, clientId, vaId, projectId }) => { console.log(`VA selected app: ${appTitle}`); - const sssrrrr = vaSocketRespectToClient.get(`${clientId}-${socket.data.vaId}`); - console.log(vaSocketRespectToClient.get(`${clientId}-${socket.data.vaId}`), sssrrrr, "vaSocketRespectToClient[clientId]") + console.log(vaSocketRespectToClient.get(`${clientId}-${vaId}-${projectId}-va`), "vaSocketRespectToClient[clientId]") // You can forward this info to the respective Electron client - socket.to(vaSocketRespectToClient.get(`${clientId}-${socket.data.vaId}`)).emit("appToCapture", { appTitle }); + socket.to(vaSocketRespectToClient.get(`${clientId}-${vaId}-${projectId}-va`)).emit("appToCapture", { appTitle }); }); socket.on("getVisibleApps", async ({ token, apps }) => { @@ -600,7 +389,7 @@ io.on("connection", (socket) => { clientSocket.data.role === "client" && clientSocket.data.allowedVAs?.includes(vaId) ) { - clientSocket.emit("receiveVisibleApps", apps); + clientSocket.emit("receiveVisibleApps", {apps, vaId}); } } } catch (err) { @@ -614,37 +403,12 @@ io.on("connection", (socket) => { }); }); - - - -// io.on('connection', (socket) => { - -// socket.on("sendImage", (base64String) => { -// io.emit("receiveImage", base64String); -// }); - - -// socket.on('disconnect', () => { -// console.log('a user Disconnected'); -// }); -// }); - - - -// Express App Listening -// app.listen(PORT, () => { -// mongoose -// .connect( -// process.env.MONGO_URI, -// ) -// .then(() => console.log("mongodb connected")) -// .catch((err) => { -// console.log(err.message); -// process.exit(1); -// }); -// console.log(`Express started on http://localhost:${PORT}`); -// }); - +app.get("/client/login", (req, res) => { + res.render("client_login") +}) +app.get("/client/forgot-password", (req, res) => { + res.render("forgot_password") +}) app.use((req, res) => { res.status(404).render("not_found", { diff --git a/views/client/dashboard-dashboard.ejs b/views/client/dashboard-dashboard.ejs index 4fc3e5e..091dc6b 100644 --- a/views/client/dashboard-dashboard.ejs +++ b/views/client/dashboard-dashboard.ejs @@ -148,8 +148,7 @@