chat-app/backend/dist/socket/socketHandlers.js
Gal Podlipnik 365aea2997
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 58s
cicd 3
2025-06-12 16:22:33 +02:00

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}`);
}
};