mirror of
https://github.com/Troplo/Colubrina.git
synced 2024-11-23 11:46:44 +11:00
515 lines
12 KiB
JavaScript
515 lines
12 KiB
JavaScript
|
const express = require("express")
|
||
|
const router = express.Router()
|
||
|
const Errors = require("../lib/errors.js")
|
||
|
const auth = require("../lib/authorize.js")
|
||
|
const { User, Message, ChatAssociation, Chat, Attachment, Friend} = require("../models")
|
||
|
|
||
|
router.delete(
|
||
|
"/association/:id/:associationId",
|
||
|
auth,
|
||
|
async (req, res, next) => {
|
||
|
try {
|
||
|
const io = req.app.get("io")
|
||
|
const chat = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
id: req.params.id,
|
||
|
userId: req.user.id,
|
||
|
rank: "admin"
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: ["id", "username", "createdAt", "updatedAt"]
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
const association = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
id: req.params.associationId,
|
||
|
chatId: chat.chat.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: ["id", "username", "createdAt", "updatedAt"]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
if (!chat) {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
if (!association) {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
if(association.chat)
|
||
|
await association.destroy()
|
||
|
res.sendStatus(204)
|
||
|
const message = await Message.create({
|
||
|
userId: 0,
|
||
|
chatId: chat.chat.id,
|
||
|
content: `${association.user.username} has been removed by ${req.user.username}.`,
|
||
|
type: "leave"
|
||
|
})
|
||
|
const associations = await ChatAssociation.findAll({
|
||
|
where: {
|
||
|
chatId: chat.chat.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
const messageLookup = await Message.findOne({
|
||
|
where: {
|
||
|
id: message.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Attachment,
|
||
|
as: "attachments"
|
||
|
},
|
||
|
{
|
||
|
model: Message,
|
||
|
as: "reply",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
associations.forEach((association) => {
|
||
|
io.to(association.userId).emit("message", {
|
||
|
...messageLookup.dataValues,
|
||
|
associationId: association.id,
|
||
|
keyId: `${message.id}-${message.updatedAt.toISOString()}`
|
||
|
})
|
||
|
})
|
||
|
} catch (err) {
|
||
|
next(err)
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
router.put("/association/:id/:associationId", auth, async (req, res, next) => {
|
||
|
try {
|
||
|
const chat = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
id: req.params.id,
|
||
|
userId: req.user.id,
|
||
|
rank: "admin"
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: ["id", "username", "createdAt", "updatedAt"]
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
const association = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
id: req.params.associationId,
|
||
|
chatId: chat.chat.id
|
||
|
}
|
||
|
})
|
||
|
if (!chat) {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
if (!association) {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
if (association.rank === "admin") {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
await association.update({
|
||
|
rank: req.body.rank
|
||
|
})
|
||
|
res.sendStatus(204)
|
||
|
} catch (err) {
|
||
|
next(err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.post("/association/:id", auth, async (req, res, next) => {
|
||
|
try {
|
||
|
const io = req.app.get("io")
|
||
|
const chat = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
userId: req.user.id,
|
||
|
chatId: req.params.id,
|
||
|
rank: "admin"
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: ["id", "username", "createdAt", "updatedAt"]
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
if (chat) {
|
||
|
if (req.body.users.length > 10) {
|
||
|
throw Errors.invalidParameter(
|
||
|
"User",
|
||
|
"The maximum number of users is 10"
|
||
|
)
|
||
|
}
|
||
|
if (!req.body.users.length) {
|
||
|
throw Errors.invalidParameter(
|
||
|
"User",
|
||
|
"You need at least 1 user to create a chat"
|
||
|
)
|
||
|
}
|
||
|
if (req.body.users.includes(req.user.id)) {
|
||
|
throw Errors.invalidParameter(
|
||
|
"User",
|
||
|
"You cannot create a DM with yourself"
|
||
|
)
|
||
|
}
|
||
|
const friends = await Friend.findAll({
|
||
|
where: {
|
||
|
userId: req.user.id,
|
||
|
friendId: req.body.users,
|
||
|
status: "accepted"
|
||
|
}
|
||
|
})
|
||
|
if (friends.length !== req.body.users.length) {
|
||
|
throw Errors.invalidParameter(
|
||
|
"User",
|
||
|
"You are not friends with this user"
|
||
|
)
|
||
|
}
|
||
|
const users = await ChatAssociation.findAll({
|
||
|
where: {
|
||
|
userId: req.body.users,
|
||
|
chatId: req.params.id
|
||
|
}
|
||
|
})
|
||
|
if (users.length > 0) {
|
||
|
throw Errors.invalidParameter(
|
||
|
"User",
|
||
|
"One or more users are already in this chat"
|
||
|
)
|
||
|
}
|
||
|
const associations = await ChatAssociation.findAll({
|
||
|
where: {
|
||
|
chatId: chat.chatId
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
for (let i = 0; i < req.body.users.length; i++) {
|
||
|
const c1 = await ChatAssociation.create({
|
||
|
chatId: chat.chat.id,
|
||
|
userId: req.body.users[i],
|
||
|
rank: "member"
|
||
|
})
|
||
|
const association = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
id: c1.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt",
|
||
|
"status"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: ["id", "username", "createdAt", "updatedAt"]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
io.to(req.body.users[i]).emit("chatAdded", association)
|
||
|
const message = await Message.create({
|
||
|
userId: 0,
|
||
|
chatId: chat.chatId,
|
||
|
content: `${association.user.username} has been added by ${req.user.username}.`,
|
||
|
type: "join"
|
||
|
})
|
||
|
const messageLookup = await Message.findOne({
|
||
|
where: {
|
||
|
id: message.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Attachment,
|
||
|
as: "attachments"
|
||
|
},
|
||
|
{
|
||
|
model: Message,
|
||
|
as: "reply",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
associations.forEach((association) => {
|
||
|
io.to(association.userId).emit("message", {
|
||
|
...messageLookup.dataValues,
|
||
|
associationId: association.id,
|
||
|
keyId: `${message.id}-${message.updatedAt.toISOString()}`
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
res.sendStatus(204)
|
||
|
} else {
|
||
|
throw Errors.chatNotFoundOrNotAdmin
|
||
|
}
|
||
|
} catch (err) {
|
||
|
next(err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
router.delete("/association/:id", auth, async (req, res, next) => {
|
||
|
try {
|
||
|
const io = req.app.get("io")
|
||
|
const chat = await ChatAssociation.findOne({
|
||
|
where: {
|
||
|
userId: req.user.id,
|
||
|
id: req.params.id
|
||
|
}
|
||
|
})
|
||
|
if (chat) {
|
||
|
await chat.destroy()
|
||
|
res.sendStatus(204)
|
||
|
const message = await Message.create({
|
||
|
userId: 0,
|
||
|
chatId: chat.chatId,
|
||
|
content: `${req.user.username} has left the group.`,
|
||
|
type: "leave"
|
||
|
})
|
||
|
const associations = await ChatAssociation.findAll({
|
||
|
where: {
|
||
|
chatId: chat.chatId
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
const messageLookup = await Message.findOne({
|
||
|
where: {
|
||
|
id: message.id
|
||
|
},
|
||
|
include: [
|
||
|
{
|
||
|
model: Attachment,
|
||
|
as: "attachments"
|
||
|
},
|
||
|
{
|
||
|
model: Message,
|
||
|
as: "reply",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: Chat,
|
||
|
as: "chat",
|
||
|
include: [
|
||
|
{
|
||
|
model: User,
|
||
|
as: "users",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
model: User,
|
||
|
as: "user",
|
||
|
attributes: [
|
||
|
"username",
|
||
|
"name",
|
||
|
"avatar",
|
||
|
"id",
|
||
|
"createdAt",
|
||
|
"updatedAt"
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
associations.forEach((association) => {
|
||
|
io.to(association.userId).emit("message", {
|
||
|
...messageLookup.dataValues,
|
||
|
associationId: association.id,
|
||
|
keyId: `${message.id}-${message.updatedAt.toISOString()}`
|
||
|
})
|
||
|
})
|
||
|
} else {
|
||
|
throw Errors.invalidParameter("chat association id")
|
||
|
}
|
||
|
} catch (err) {
|
||
|
next(err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
module.exports = router
|