From 28750113c6ae8545e19dfba0b1efaf672f62061a Mon Sep 17 00:00:00 2001 From: Quiint Date: Thu, 3 Aug 2023 22:46:00 -0400 Subject: [PATCH] poopie --- middleware/authenticate.js | 3 +- models/DirectMessage.js | 27 +++++ models/Swit.js | 3 +- routes/dm.js | 140 +++++++++++++++++++++++ routes/swit.js | 59 ++++++++++ server.js | 15 ++- uploads/1d23510b8fbf92776ecc858c09f99546 | Bin 0 -> 29935 bytes 7 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 models/DirectMessage.js create mode 100644 routes/dm.js create mode 100644 uploads/1d23510b8fbf92776ecc858c09f99546 diff --git a/middleware/authenticate.js b/middleware/authenticate.js index 354cbe3..5fc4571 100644 --- a/middleware/authenticate.js +++ b/middleware/authenticate.js @@ -6,4 +6,5 @@ function authenticate(req, res, next) { req.userId = decoded.userId; next(); }); -} \ No newline at end of file +} + diff --git a/models/DirectMessage.js b/models/DirectMessage.js new file mode 100644 index 0000000..ffd8347 --- /dev/null +++ b/models/DirectMessage.js @@ -0,0 +1,27 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const DirectMessageSchema = new Schema({ + sender: { + type: Schema.Types.ObjectId, + ref: 'User', + required: true + }, + recipient: { + type: Schema.Types.ObjectId, + ref: 'User', + required: true + }, + content: { + type: String, + required: true + }, + timestamp: { + type: Date, + default: Date.now + }, +}, { + timestamps: true +}); + +module.exports = mongoose.model('DirectMessage', DirectMessageSchema); diff --git a/models/Swit.js b/models/Swit.js index 366ac12..292230b 100644 --- a/models/Swit.js +++ b/models/Swit.js @@ -9,7 +9,8 @@ const SwitSchema = new mongoose.Schema({ text: { type: String }, user: { type: mongoose.Schema.Types.ObjectId, ref: 'User'}, date: { type: Date, default: Date.now}, - username: String + username: String, + likes: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }] // Add this line }], reposts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User'}] }, { timestamps: true }); diff --git a/routes/dm.js b/routes/dm.js new file mode 100644 index 0000000..afe8a75 --- /dev/null +++ b/routes/dm.js @@ -0,0 +1,140 @@ +const express = require('express'); +const router = express.Router(); +const DirectMessage = require('../models/DirectMessage'); +const jwt = require('jsonwebtoken'); +const User = require('../models/User'); + +function authenticate(req, res, next) { + const token = req.header('Authorization'); + if (!token) return res.sendStatus(401); + jwt.verify(token, 'SECRET_KEY', (err, decoded) => { + if (err) return res.sendStatus(401); + req.userId = decoded.userId; + next(); + }); +} + +router.get('/', authenticate, async (req, res) => { + try { + const dms = await DirectMessage.find({ + $or: [ + { sender: req.userId }, + { recipient: req.userId }, + ], + }).populate('sender recipient', 'username'); + + // Group the messages by conversation + let conversations = {}; + dms.forEach(dm => { + const otherUserId = dm.sender._id.toString() === req.userId ? dm.recipient._id.toString() : dm.sender._id.toString(); + if (!conversations[otherUserId]) { + conversations[otherUserId] = { + userId: otherUserId, + username: dm.sender._id.toString() === req.userId ? dm.recipient.username : dm.sender.username, + messages: [], + }; + } + conversations[otherUserId].messages.push(dm); + }); + + // Convert the conversations object to an array + const conversationsArray = Object.values(conversations); + + res.json(conversationsArray); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Could not get Direct Messages." }); + } +}); + + +router.get('/:otherUserId', authenticate, async (req, res) => { + const { otherUserId } = req.params; + + try { + const dms = await DirectMessage.find({ + $or: [ + { sender: req.userId, recipient: otherUserId }, + { sender: otherUserId, recipient: req.userId }, + ], + }).populate('sender recipient', 'username'); + + res.json(dms); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Could not get Direct Messages." }); + } +}); + +router.delete('/:dmId', authenticate, async (req, res) => { + const { dmId } = req.params; + + try { + const dm = await DirectMessage.findById(dmId); + + if (!dm) { + return res.status(404).json({ error: "Direct Message not found." }); + } + + // Check if the authenticated user is the sender of the DM + if (dm.sender.toString() !== req.userId) { + return res.status(403).json({ error: "You can only delete your own Direct Messages." }); + } + + await dm.remove(); + + res.json({ message: "Direct Message deleted." }); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Could not delete Direct Message." }); + } +}); + +router.post('/send', authenticate, async (req, res) => { + const { recipientId, text, senderId } = req.body; + console.log(req.user) + + if (!recipientId || !text) { + return res.status(400).json({ error: "Recipient ID and text are required." }); + } + + try { + // Check if the recipient exists + const recipient = await User.findById(recipientId); + if (!recipient) { + return res.status(404).json({ error: "Recipient not found." }); + } +// Create the Direct Message +const dm = new DirectMessage({ + sender: senderId, + recipient: recipientId, + content: text, + }); + + // Save the Direct Message + const savedDm = await dm.save(); + + // Populate the sender and recipient fields with full user objects + await savedDm.populate('sender recipient', 'username').exec; + + // Now emit the `new_dm` event with the populated Direct Message + const io = req.app.io; + const senderSocketId = req.app.onlineUsers[senderId]; + const recipientSocketId = req.app.onlineUsers[recipientId]; + if (senderSocketId) { + io.to(senderSocketId).emit('new_dm', savedDm); + } + if (recipientSocketId) { + io.to(recipientSocketId).emit('new_dm', savedDm); + } + + + + res.json(savedDm); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Could not send Direct Message." }); + } + }); + +module.exports = router; diff --git a/routes/swit.js b/routes/swit.js index 63b05d2..83e9a19 100644 --- a/routes/swit.js +++ b/routes/swit.js @@ -49,6 +49,13 @@ router.get('/swits/following', authenticate, async (req, res) => { res.json(swits.reverse()); }); +router.get('/swits/user/:id', authenticate, async (req, res) => { + const { id } = req.params; + const swits = await Swit.find({ user: id }); + console.log(swits) + res.json(swits.reverse()); +}); + router.post('/swits/:id/like', authenticate, async (req, res) => { const swit = await Swit.findById(req.params.id); if (!swit) return res.status(404).send('Swit not found'); @@ -112,6 +119,58 @@ router.get('/swits/:id/comments', authenticate, async (req, res) => { res.send(swit.comments); }); + +router.post('/swits/:switId/comments/:commentId/like', authenticate, async (req, res) => { + const swit = await Swit.findById(req.params.switId); + if (!swit) return res.status(404).send('Swit not found'); + console.log(swit) + const comment = swit.comments.id(req.params.commentId); + if (!comment) return res.status(404).send('Comment not found'); + + if (comment.likes.includes(req.userId)) { + return res.status(400).json({ error: 'You have already liked this comment' }); + } + + comment.likes.push(req.userId); + await swit.save(); + + res.sendStatus(200); +}); + +router.post('/swits/:switId/comments/:commentId/unlike', authenticate, async (req, res) => { + const swit = await Swit.findById(req.params.switId); + if (!swit) return res.status(404).send('Swit not found'); + + const comment = swit.comments.id(req.params.commentId); + if (!comment) return res.status(404).send('Comment not found'); + + comment.likes = comment.likes.filter(id => id.toString() !== req.userId); + await swit.save(); + + res.sendStatus(200); +}); + +router.delete('/swits/:switId/comments/:commentId', authenticate, async (req, res) => { + const { switId, commentId } = req.params; + + const swit = await Swit.findById(switId); + if (!swit) return res.status(404).send('Swit not found'); + + const commentIndex = swit.comments.findIndex(comment => comment._id.toString() === commentId); + if (commentIndex === -1) return res.status(404).send('Comment not found'); + + // Only allow the user who posted the comment to delete it + if (swit.comments[commentIndex].user.toString() !== req.userId) { + return res.status(403).send('You do not have permission to delete this comment'); + } + + swit.comments.splice(commentIndex, 1); + await swit.save(); + + res.sendStatus(204); +}); + + router.post('/swits/:id/repost', authenticate, async (req, res) => { const swit = await Swit.findById(req.params.id); if (!swit) return res.status(404).send('Swit not found'); diff --git a/server.js b/server.js index c34b337..6f4fa67 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,7 @@ const session = require('express-session'); require('dotenv').config(); const http = require('http'); const { Server } = require('socket.io'); +const dmRoutes = require('./routes/dm'); const app = express(); @@ -16,17 +17,20 @@ const server = http.createServer(app); const io = new Server(server); app.io = io; -let onlineUsers = {}; +app.onlineUsers = {}; io.on('connection', (socket) => { console.log('a user connected'); + socket.on('user connected', (userId) => { - onlineUsers[userId] = socket.id; + console.log(`User ${userId} connected`); // log when a 'user connected' message is received + app.onlineUsers[userId] = socket.id; + console.log(app.onlineUsers); // log the current state of the `onlineUsers` object }); socket.on('disconnect', () => { console.log('user disconnected'); - const userId = Object.keys(onlineUsers).find(key => onlineUsers[key] === socket.id); - if (userId) delete onlineUsers[userId]; + const userId = Object.keys(app.onlineUsers).find(key => app.onlineUsers[key] === socket.id); + if (userId) delete app.onlineUsers[userId]; }); }); @@ -55,11 +59,12 @@ app.use('/api/v1/app/auth', authRoutes); // Mount the auth routes at /auth app.use('/api/v1/app/swit', switRoutes); // Mount the swit routes at /swits app.use('/api/v1/app/user', userRoutes); // Mount the user routes at /user app.use('/api/v1/app/notify', notifyRoutes); // Mount the notify routes at /notify +app.use('/api/v1/app/dms', dmRoutes); // Mount the dm routes at /dms' app.get('/', (req, res) => { res.send('Hello, World!'); }); -app.listen(port, '0.0.0.0', () => { +server.listen(port, '0.0.0.0', () => { console.log(`Server is running on http://localhost:${port}`); }); diff --git a/uploads/1d23510b8fbf92776ecc858c09f99546 b/uploads/1d23510b8fbf92776ecc858c09f99546 new file mode 100644 index 0000000000000000000000000000000000000000..bb640f8aeabb285a544ec002b26a59588f047f3f GIT binary patch literal 29935 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 literal 0 HcmV?d00001