const express = require('express'); const { getConnection, getChannel, getMessage, deleteMessage, addMention, getMentions, getUserByUsername, setHasReplies, addReply, getMessageReplies } = require('../libs/mysql'); const rateLimit = require("express-rate-limit"); const slowDown = require("express-slow-down"); const { checkAuth } = require('../libs/middlewares'); const limiter = rateLimit({ windowMs: 1 * 1000, max: 2, }); const speedLimiter = slowDown({ windowMs: 1 * 1000, delayAfter: 2, delayMs: () => 5000, }); const router = express.Router(); async function getReplies(message, connection) { const replies = await getMessageReplies(connection, message.id); for (const reply of replies) { if (reply.has_replies) { const subReplies = await getReplies(reply, connection); reply.replies = subReplies; } if (reply.content.includes('@')) { const mentions = await getMentions(connection, reply.id); reply.mentions = mentions; } else { reply.mentions = []; } } return replies; } router.get('/:message_id', async (req, res) => { const message_id = req.params.message_id; const connection = await getConnection(); const message = await getMessage(connection, message_id); if (!message[0]) { connection.end(); return res.send({ error: 'No message found' }); } if (message[0].content.includes('@')) { const mentions = await getMentions(connection, message.id); message[0].mentions = mentions; } else { message[0].mentions = []; } if (message[0].has_replies) { const replies = await getReplies(message[0], connection); message[0].replies = replies; } else { message[0].replies = []; } connection.end(); res.send(message[0]); }); router.post('/:message_id/reply', speedLimiter, limiter, checkAuth, async (req, res) => { const { message } = req.body; const { message_id } = req.params; const user = req.user; if (!message) { return res.status(400).send({ error: 'Missing parameters' }); } const connection = await getConnection(); const originalMessage = await getMessage(connection, message_id); if (!originalMessage[0]) { connection.end(); return res.status(400).send({ error: 'No message found' }); } const channel = await getChannel(connection, originalMessage[0].channel_name); const sent_message = await addReply(connection, channel[0].id, user.id, message.replace("\"", "'"), message_id); await setHasReplies(connection, message_id, true); const new_message_id = sent_message.insertId; for (const word of message.split(' ')) { if (word.startsWith('@')) { const username = word.substring(1); const mentionedUser = await getUserByUsername(connection, username); if (mentionedUser[0]) { await addMention(connection, new_message_id, mentionedUser[0].id); } } } connection.end(); req.sockets.emit({ type: 'new_message', channel_id: channel[0].id, user_id: user.id, }); res.send({ message: 'Reply sent' }); }); router.post('/:message_id/delete', checkAuth, async (req, res) => { const { message_id } = req.params; const user = req.user; const connection = await getConnection(); const message = await getMessage(connection, message_id); if (!message[0]) { connection.end(); return res.status(400).send({ error: 'No message found' }); } const channel = await getChannel(connection, message[0].channel_name); if (user.id !== channel[0].owner_id && user.id !== message[0].user_id && user.admin !== 1) { connection.end(); return res.status(401).send({ error: 'Unauthorized' }); } if (message[0].reply_to_id) { const replies = await getMessageReplies(connection, message[0].reply_to_id); if (replies.length === 1) { await setHasReplies(connection, replyToId, false); } } await deleteMessage(connection, message_id); connection.end(); req.sockets.emit({ type: 'delete_message', channel_id: channel[0].id, user_id: user.id, }); res.send({ message: 'Message deleted' }); }); module.exports = router;