226 lines
8.3 KiB
JavaScript
226 lines
8.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.handleConnection = void 0;
|
|
const database_js_1 = require("../config/database.js");
|
|
const rateLimiter_js_1 = require("../middleware/rateLimiter.js");
|
|
const chatService_js_1 = require("../services/chatService.js");
|
|
const messageService_js_1 = require("../services/messageService.js");
|
|
const handleConnection = async (io, socket) => {
|
|
console.log(`User connected: ${socket.user.username} (${socket.user.id})`);
|
|
await updateUserOnlineStatus(socket.userId, true);
|
|
const onlineUsers = await database_js_1.prisma.user.findMany({
|
|
where: { isOnline: true },
|
|
select: { id: true, username: true },
|
|
});
|
|
socket.emit("online_users", onlineUsers);
|
|
await joinUserRooms(socket);
|
|
socket.on("send_message", (data) => handleSendMessage(io, socket, data));
|
|
socket.on("delete_message", (data) => handleDeleteMessage(io, socket, data));
|
|
socket.on("react_to_message", (data) => handleReactToMessage(io, socket, data));
|
|
socket.on("typing_start", (data) => handleTypingStart(io, socket, data));
|
|
socket.on("typing_stop", (data) => handleTypingStop(io, socket, data));
|
|
socket.on("join_room", (roomId) => handleJoinRoom(socket, roomId));
|
|
socket.on("leave_room", (roomId) => handleLeaveRoom(socket, roomId));
|
|
socket.on("messages_seen", (data) => handleMessagesSeen(io, socket, data));
|
|
socket.on("disconnect", () => handleDisconnect(socket));
|
|
};
|
|
exports.handleConnection = handleConnection;
|
|
const handleTypingStart = async (io, socket, data) => {
|
|
try {
|
|
const isMember = await chatService_js_1.ChatService.checkRoomMembership(socket.userId, data.roomId);
|
|
if (!isMember)
|
|
return;
|
|
io.to(data.roomId).emit("user_typing", {
|
|
roomId: data.roomId,
|
|
username: data.username,
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling typing start: ${error}`);
|
|
}
|
|
};
|
|
const handleTypingStop = async (io, socket, data) => {
|
|
try {
|
|
const isMember = await chatService_js_1.ChatService.checkRoomMembership(socket.userId, data.roomId);
|
|
if (!isMember)
|
|
return;
|
|
io.to(data.roomId).emit("user_stopped_typing", {
|
|
roomId: data.roomId,
|
|
username: data.username,
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling typing stop: ${error}`);
|
|
}
|
|
};
|
|
const updateUserOnlineStatus = async (userId, isOnline) => {
|
|
try {
|
|
await database_js_1.prisma.user.update({
|
|
where: { id: userId },
|
|
data: {
|
|
isOnline,
|
|
lastSeen: new Date(),
|
|
},
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error(`Error updating user online status: ${error}`);
|
|
}
|
|
};
|
|
const joinUserRooms = async (socket) => {
|
|
try {
|
|
const userRooms = await database_js_1.prisma.chatRoomMember.findMany({
|
|
where: { userId: socket.userId },
|
|
include: { room: true },
|
|
});
|
|
userRooms.forEach(async (member) => {
|
|
await socket.join(member.roomId);
|
|
socket.to(member.roomId).emit("user_online", {
|
|
userId: socket.userId,
|
|
username: socket.user.username,
|
|
});
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error(`Error joining user rooms: ${error}`);
|
|
}
|
|
};
|
|
const handleSendMessage = async (io, socket, data) => {
|
|
try {
|
|
if (!data.roomId) {
|
|
socket.emit("error", { message: "Room ID is required to send a message" });
|
|
return;
|
|
}
|
|
if (data.image && data.image.length > 2 * 1024 * 1024) {
|
|
socket.emit("error", { message: "Image size exceeds 2MB limit" });
|
|
return;
|
|
}
|
|
if (!data.content && !data.image) {
|
|
socket.emit("error", { message: "Message cannot be empty" });
|
|
return;
|
|
}
|
|
if (!(0, rateLimiter_js_1.checkMessageRateLimit)(socket))
|
|
return;
|
|
const isMember = await chatService_js_1.ChatService.checkRoomMembership(socket.userId, data.roomId);
|
|
if (!isMember) {
|
|
socket.emit("error", { message: "Not authorized to send messages to this room" });
|
|
return;
|
|
}
|
|
const result = await messageService_js_1.MessageService.sendMessage(socket.userId, data);
|
|
if (result.success) {
|
|
io.to(data.roomId).emit("new_message", result.data);
|
|
io.to(data.roomId).emit("user_stopped_typing", {
|
|
roomId: data.roomId,
|
|
username: socket.user.username,
|
|
});
|
|
}
|
|
else {
|
|
socket.emit("error", { message: "Failed to send message" });
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling send message: ${error}`);
|
|
socket.emit("error", { message: "Failed to send message" });
|
|
}
|
|
};
|
|
const handleDeleteMessage = async (io, socket, data) => {
|
|
try {
|
|
const result = await messageService_js_1.MessageService.deleteMessage(socket.userId, data.messageId, data.roomId);
|
|
if (result.success) {
|
|
io.to(data.roomId).emit("message_deleted", {
|
|
messageId: data.messageId,
|
|
roomId: data.roomId,
|
|
});
|
|
}
|
|
else {
|
|
socket.emit("error", { message: result.error });
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling delete message: ${error}`);
|
|
socket.emit("error", { message: "Failed to delete message" });
|
|
}
|
|
};
|
|
const handleReactToMessage = async (io, socket, data) => {
|
|
try {
|
|
const result = await messageService_js_1.MessageService.reactToMessage(socket.userId, data);
|
|
if (result.success) {
|
|
const message = await database_js_1.prisma.message.findUnique({
|
|
where: { id: data.messageId },
|
|
select: { roomId: true },
|
|
});
|
|
if (message) {
|
|
io.to(message.roomId).emit("message_reaction_updated", result.data);
|
|
}
|
|
}
|
|
else {
|
|
socket.emit("error", { message: result.error });
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling react to message: ${error}`);
|
|
socket.emit("error", { message: "Failed to react to message" });
|
|
}
|
|
};
|
|
const handleMessagesSeen = async (io, socket, data) => {
|
|
try {
|
|
const isMember = await chatService_js_1.ChatService.checkRoomMembership(socket.userId, data.roomId);
|
|
if (!isMember) {
|
|
socket.emit("error", { message: "Not authorized to access this room" });
|
|
return;
|
|
}
|
|
const messagesInRoom = await database_js_1.prisma.message.findMany({
|
|
where: {
|
|
id: { in: data.messageIds },
|
|
roomId: data.roomId,
|
|
},
|
|
});
|
|
const validMessageIds = messagesInRoom.map((msg) => msg.id);
|
|
if (validMessageIds.length === 0)
|
|
return;
|
|
const result = await messageService_js_1.MessageService.markMessagesAsSeen(socket.userId, validMessageIds);
|
|
if (result.success && result.data) {
|
|
for (const item of result.data) {
|
|
io.to(data.roomId).emit("message_seen_update", {
|
|
messageId: item.messageId,
|
|
seenBy: item.seenBy,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling messages seen: ${error}`);
|
|
socket.emit("error", { message: "Failed to mark messages as seen" });
|
|
}
|
|
};
|
|
const handleJoinRoom = async (socket, roomId) => {
|
|
await socket.join(roomId);
|
|
};
|
|
const handleLeaveRoom = async (socket, roomId) => {
|
|
await socket.leave(roomId);
|
|
};
|
|
const handleDisconnect = async (socket) => {
|
|
console.log(`User disconnected: ${socket.user.username}`);
|
|
await updateUserOnlineStatus(socket.userId, false);
|
|
try {
|
|
const userRooms = await database_js_1.prisma.chatRoomMember.findMany({
|
|
where: {
|
|
userId: socket.userId,
|
|
},
|
|
});
|
|
userRooms.forEach((member) => {
|
|
socket.to(member.roomId).emit("user_offline", {
|
|
userId: socket.userId,
|
|
username: socket.user.username,
|
|
});
|
|
socket.to(member.roomId).emit("user_stopped_typing", {
|
|
roomId: member.roomId,
|
|
username: socket.user.username,
|
|
});
|
|
});
|
|
}
|
|
catch (error) {
|
|
console.error(`Error handling user disconnect: ${error}`);
|
|
}
|
|
};
|