const auth = require("../lib/authorize") const { Friend, User } = require("../models") const Errors = require("../lib/errors") const express = require("express") const router = express.Router() router.get("/", auth, async (req, res, next) => { try { let friends = await Friend.findAll({ where: { userId: req.user.id }, include: [ { model: User, as: "user", attributes: ["id", "username", "avatar", "createdAt", "updatedAt"] }, { model: User, as: "user2", attributes: ["id", "username", "avatar", "createdAt", "updatedAt"] } ] }) res.json(friends) } catch (err) { next(err) } }) router.post("/", auth, async (req, res, next) => { try { const io = req.app.get("io") let friendRes try { friendRes = req.body.friend.split(":") } catch { friendRes = req.body.friend } const user = await User.findOne({ where: { username: friendRes[0] || friendRes } }) if (user) { const friend = await Friend.findOne({ where: { userId: req.user.id, friendId: user.id } }) if (friend) { throw Errors.friendAlreadyFriends } else { if (!user.privacy.communications.enabled) { throw Errors.communicationsUserNotOptedIn } else { const newFriend = await Friend.create({ userId: req.user.id, friendId: user.id }) const remoteFriend = await Friend.create({ userId: user.id, friendId: req.user.id, status: "pendingCanAccept" }) io.to(user.id).emit("friendUpdate", {}) io.to(req.user.id).emit("friendUpdate", {}) io.to(user.id).emit("friendRequest", { ...remoteFriend.dataValues, user: { username: req.user.username, discussionsImage: req.user.discussionsImage, avatar: req.user.avatar, id: req.user.id } }) res.json(newFriend) } } } else { throw Errors.communicationsUserNotFound } } catch (err) { next(err) } }) router.delete("/:id", auth, async (req, res, next) => { try { const io = req.app.get("io") const friend = await Friend.findOne({ where: { userId: req.user.id, id: req.params.id } }) if (friend) { await friend.destroy() await Friend.destroy({ where: { userId: friend.friendId, friendId: req.user.id } }) io.to(friend.friendId).emit("friendUpdate", {}) io.to(req.user.id).emit("friendUpdate", {}) res.sendStatus(204) } else { throw Errors.friendNotFound } } catch (err) { next(err) } }) router.put("/:id", auth, async (req, res, next) => { try { const io = req.app.get("io") const friend = await Friend.findOne({ where: { id: req.params.id, userId: req.user.id, status: "pendingCanAccept" } }) if (friend) { await friend.update({ status: "accepted" }) const remoteFriend = await Friend.findOne({ where: { userId: friend.friendId, friendId: friend.userId }, include: [ { model: User, as: "user", attributes: ["id", "username", "createdAt", "updatedAt"] }, { model: User, as: "user2", attributes: ["id", "username", "createdAt", "updatedAt"] } ] }) await remoteFriend.update({ status: "accepted" }) io.to(friend.userId).emit("friendUpdate", {}) io.to(remoteFriend.userId).emit("friendUpdate", {}) io.to(remoteFriend.userId).emit("friendAccepted", { ...remoteFriend.dataValues }) res.json(friend) } else { throw Errors.friendNotFound } } catch (err) { next(err) } }) module.exports = router