Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions backend/src/lib/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ io.use((socket, next) => {

const userSocketMap = {};

// Cache to throttle user lastSeen database updates (max once per minute per user)
const lastDbUpdateCache = new Map();

const throttledUpdateLastSeen = async (userId) => {
const now = Date.now();
const lastUpdate = lastDbUpdateCache.get(userId);
if (lastUpdate && now - lastUpdate < 60000) return;
lastDbUpdateCache.set(userId, now);
try {
await User.findByIdAndUpdate(userId, { lastSeen: new Date() });
} catch (err) {
console.error("Failed to update user lastSeen:", err);
}
};

export const getReceiverSocketIds = (userId) =>
userSocketMap[userId] ? [...userSocketMap[userId]] : [];

Expand All @@ -48,8 +63,6 @@ export const broadcastStatusMoodUpdate = ({ userId, statusMood }) => {

/**
* 🛠️ Security Helper: Validates if two users can communicate.
* Adjust the database query inside based on whether you track relationships via
* a Friends/Block schema or directly within the User model.
*/
const canCommunicate = async (senderId, receiverId) => {
if (!senderId || !receiverId || senderId === receiverId) return false;
Expand All @@ -58,7 +71,6 @@ const canCommunicate = async (senderId, receiverId) => {
const receiver = await User.findById(receiverId);
if (!receiver) return false;

// Example: If your User schema has a 'blockedUsers' array
if (receiver.blockedUsers && receiver.blockedUsers.includes(senderId)) {
return false;
}
Expand All @@ -70,21 +82,6 @@ const canCommunicate = async (senderId, receiverId) => {
}
};

io.on("connection", (socket) => {
const getActiveContacts = async (userId) => {
try {
const [senders, receivers] = await Promise.all([
Message.distinct("senderId", { receiverId: userId }),
Message.distinct("receiverId", { senderId: userId })
]);
const merged = [...senders, ...receivers].map(id => id.toString());
return [...new Set(merged)];
} catch (err) {
console.error("Error fetching active contacts:", err);
return [];
}
}

io.on("connection", (socket) => {
const userId = socket.userId;

Expand Down Expand Up @@ -187,6 +184,6 @@ io.on("connection", (socket) => {

io.emit("getOnlineUsers", Object.keys(userSocketMap));
});
});
});

export { io, app, server };
7 changes: 7 additions & 0 deletions frontend/components/CallHandler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ export default function CallHandler() {
}
};

pc.onconnectionstatechange = () => {
if (pc.connectionState === "failed" || pc.connectionState === "disconnected") {
toast.error("Call connection lost");
endCall();
}
};

setPeer(pc);
return pc;
};
Expand Down