diff options
author | AlTech98 <altech123159@gmail.com> | 2021-09-18 18:36:29 +0200 |
---|---|---|
committer | AlTech98 <altech123159@gmail.com> | 2021-09-18 18:36:29 +0200 |
commit | ceb770fb5b6648c18d66d6997c8916ed60b8c192 (patch) | |
tree | 1995cbe4ec0dfe53860d8520b1de39ed4e02e0d6 | |
parent | Fix gateway not listening for new channels events (diff) | |
download | server-ceb770fb5b6648c18d66d6997c8916ed60b8c192.tar.xz |
Removed ChannelService, more fixes
-rw-r--r-- | api/src/routes/channels/#channel_id/index.ts | 4 | ||||
-rw-r--r-- | api/src/routes/channels/#channel_id/messages/index.ts | 6 | ||||
-rw-r--r-- | api/src/routes/channels/#channel_id/recipients.ts | 6 | ||||
-rw-r--r-- | api/src/routes/users/@me/channels.ts | 4 | ||||
-rw-r--r-- | gateway/src/listener/listener.ts | 2 | ||||
-rw-r--r-- | util/src/entities/Channel.ts | 124 | ||||
-rw-r--r-- | util/src/index.ts | 1 | ||||
-rw-r--r-- | util/src/services/ChannelService.ts | 118 | ||||
-rw-r--r-- | util/src/services/index.ts | 1 | ||||
-rw-r--r-- | util/src/util/Array.ts | 3 | ||||
-rw-r--r-- | util/src/util/index.ts | 1 |
11 files changed, 131 insertions, 139 deletions
diff --git a/api/src/routes/channels/#channel_id/index.ts b/api/src/routes/channels/#channel_id/index.ts index 70dd3994..3f434f5e 100644 --- a/api/src/routes/channels/#channel_id/index.ts +++ b/api/src/routes/channels/#channel_id/index.ts @@ -1,4 +1,4 @@ -import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelService, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util"; +import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util"; import { Request, Response, Router } from "express"; import { handleFile, route } from "@fosscord/api"; @@ -28,7 +28,7 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request ]); } else if (channel.type === ChannelType.GROUP_DM) { - await ChannelService.removeRecipientFromChannel(channel, req.user_id) + await Channel.removeRecipientFromChannel(channel, req.user_id) } else { //TODO messages in this channel should be deleted before deleting the channel await Promise.all([ diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts index bb610a6a..cde14164 100644 --- a/api/src/routes/channels/#channel_id/messages/index.ts +++ b/api/src/routes/channels/#channel_id/messages/index.ts @@ -1,5 +1,5 @@ import { Router, Response, Request } from "express"; -import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent } from "@fosscord/util"; +import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent, Recipient } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { handleMessage, postHandleMessage, route } from "@fosscord/api"; import multer from "multer"; @@ -150,7 +150,6 @@ router.post( return res.status(400).json(error); } } - //TODO querying the DB at every message post should be avoided, caching maybe? const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] }) const embeds = []; @@ -184,7 +183,8 @@ router.post( } } - await Promise.all(channel.recipients!.map(async r => { + //Only one recipients should be closed here, since in group DMs the recipient is deleted not closed + await Promise.all(channel.recipients!.filter(r => r.closed).map(async r => { r.closed = false; return await r.save() })); diff --git a/api/src/routes/channels/#channel_id/recipients.ts b/api/src/routes/channels/#channel_id/recipients.ts index d88b38f3..c7beeee8 100644 --- a/api/src/routes/channels/#channel_id/recipients.ts +++ b/api/src/routes/channels/#channel_id/recipients.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { Channel, ChannelRecipientAddEvent, ChannelService, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util"; +import { Channel, ChannelRecipientAddEvent, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util"; const router: Router = Router(); @@ -13,7 +13,7 @@ router.put("/:user_id", async (req: Request, res: Response) => { user_id ].unique() - const new_channel = await ChannelService.createDMChannel(recipients, req.user_id) + const new_channel = await Channel.createDMChannel(recipients, req.user_id) return res.status(201).json(new_channel); } else { if (channel.recipients!.map(r => r.user_id).includes(user_id)) { @@ -49,7 +49,7 @@ router.delete("/:user_id", async (req: Request, res: Response) => { throw DiscordApiErrors.INVALID_RECIPIENT //TODO is this the right error? } - await ChannelService.removeRecipientFromChannel(channel, user_id) + await Channel.removeRecipientFromChannel(channel, user_id) return res.sendStatus(204); }); diff --git a/api/src/routes/users/@me/channels.ts b/api/src/routes/users/@me/channels.ts index 873ff245..b5782eca 100644 --- a/api/src/routes/users/@me/channels.ts +++ b/api/src/routes/users/@me/channels.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { Recipient, ChannelService, DmChannelDTO } from "@fosscord/util"; +import { Recipient, DmChannelDTO, Channel } from "@fosscord/util"; import { route } from "@fosscord/api"; const router: Router = Router(); @@ -16,7 +16,7 @@ export interface DmChannelCreateSchema { router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => { const body = req.body as DmChannelCreateSchema; - res.json(await ChannelService.createDMChannel(body.recipients, req.user_id, body.name)); + res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name)); }); export default router; diff --git a/gateway/src/listener/listener.ts b/gateway/src/listener/listener.ts index 35841312..ae13cca7 100644 --- a/gateway/src/listener/listener.ts +++ b/gateway/src/listener/listener.ts @@ -32,7 +32,7 @@ export async function setupListener(this: WebSocket) { }); const guilds = members.map((x) => x.guild); const recipients = await Recipient.find({ - where: { user_id: this.user_id }, + where: { user_id: this.user_id, closed: false }, relations: ["channel"], }); const dm_channels = recipients.map((x) => x.channel); diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts index aa2bfab3..ea632778 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts @@ -1,11 +1,13 @@ import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; -import { User } from "./User"; +import { PublicUserProjection, User } from "./User"; import { HTTPError } from "lambert-server"; -import { emitEvent, getPermission, Snowflake } from "../util"; -import { ChannelCreateEvent } from "../interfaces"; +import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial } from "../util"; +import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces"; import { Recipient } from "./Recipient"; +import { DmChannelDTO } from "../dtos"; +import { Message } from "./Message"; export enum ChannelType { GUILD_TEXT = 0, // a text channel within a server @@ -97,7 +99,6 @@ export class Channel extends BaseClass { @Column({ nullable: true }) topic?: string; - // TODO: DM channel static async createChannel( channel: Partial<Channel>, user_id: string = "0", @@ -150,16 +151,123 @@ export class Channel extends BaseClass { new Channel(channel).save(), !opts?.skipEventEmit ? emitEvent({ - event: "CHANNEL_CREATE", - data: channel, - guild_id: channel.guild_id, - } as ChannelCreateEvent) + event: "CHANNEL_CREATE", + data: channel, + guild_id: channel.guild_id, + } as ChannelCreateEvent) : Promise.resolve(), ]); return channel; } + static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) { + recipients = recipients.unique().filter((x) => x !== creator_user_id); + const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) }); + + // TODO: check config for max number of recipients + if (otherRecipientsUsers.length !== recipients.length) { + throw new HTTPError("Recipient/s not found"); + } + + const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM; + + let channel = null; + + const channelRecipients = [...recipients, creator_user_id] + + const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] }) + + for (let ur of userRecipients) { + let re = ur.channel.recipients!.map(r => r.user_id) + if (re.length === channelRecipients.length) { + if (containsAll(re, channelRecipients)) { + if (channel == null) { + channel = ur.channel + await ur.assign({ closed: false }).save() + } + } + } + } + + if (channel == null) { + name = trimSpecial(name); + + channel = await new Channel({ + name, + type, + owner_id: (type === ChannelType.DM ? undefined : creator_user_id), + created_at: new Date(), + last_message_id: null, + recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })), + }).save(); + } + + + const channel_dto = await DmChannelDTO.from(channel) + + if (type === ChannelType.GROUP_DM) { + + for (let recipient of channel.recipients!) { + await emitEvent({ + event: "CHANNEL_CREATE", + data: channel_dto.excludedRecipients([recipient.user_id]), + user_id: recipient.user_id + }) + } + } else { + await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id }); + } + + return channel_dto.excludedRecipients([creator_user_id]) + } + + static async removeRecipientFromChannel(channel: Channel, user_id: string) { + await Recipient.delete({ channel_id: channel.id, user_id: user_id }) + channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id) + + if (channel.recipients?.length === 0) { + await Channel.deleteChannel(channel); + await emitEvent({ + event: "CHANNEL_DELETE", + data: await DmChannelDTO.from(channel, [user_id]), + user_id: user_id + }); + return + } + + await emitEvent({ + event: "CHANNEL_DELETE", + data: await DmChannelDTO.from(channel, [user_id]), + user_id: user_id + }); + + //If the owner leave we make the first recipient in the list the new owner + if (channel.owner_id === user_id) { + channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner? + await emitEvent({ + event: "CHANNEL_UPDATE", + data: await DmChannelDTO.from(channel, [user_id]), + channel_id: channel.id + }); + } + + await channel.save() + + await emitEvent({ + event: "CHANNEL_RECIPIENT_REMOVE", data: { + channel_id: channel.id, + user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection }) + }, channel_id: channel.id + } as ChannelRecipientRemoveEvent); + } + + static async deleteChannel(channel: Channel) { + await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util + //TODO before deleting the channel we should check and delete other relations + await Channel.delete({ id: channel.id }) + } + isDm() { return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM } diff --git a/util/src/index.ts b/util/src/index.ts index 538bfdd1..fc00d46b 100644 --- a/util/src/index.ts +++ b/util/src/index.ts @@ -4,7 +4,6 @@ import "reflect-metadata"; export * from "./util/index"; export * from "./interfaces/index"; export * from "./entities/index"; -export * from "./services/index"; export * from "./dtos/index"; // import Config from "../util/Config"; diff --git a/util/src/services/ChannelService.ts b/util/src/services/ChannelService.ts deleted file mode 100644 index aa021a4a..00000000 --- a/util/src/services/ChannelService.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Channel, ChannelType, Message, PublicUserProjection, Recipient, User } from "../entities"; -import { HTTPError } from "lambert-server"; -import { emitEvent, trimSpecial } from "../util"; -import { DmChannelDTO } from "../dtos"; -import { ChannelRecipientRemoveEvent } from "../interfaces"; - -export function checker(arr: any[], target: any[]) { - return target.every(v => arr.includes(v)); -} - -export class ChannelService { - public static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) { - recipients = recipients.unique().filter((x) => x !== creator_user_id); - const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) }); - - // TODO: check config for max number of recipients - if (otherRecipientsUsers.length !== recipients.length) { - throw new HTTPError("Recipient/s not found"); - } - - const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM; - - let channel = null; - - const channelRecipients = [...recipients, creator_user_id] - - const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] }) - - for (let ur of userRecipients) { - let re = ur.channel.recipients!.map(r => r.user_id) - if (re.length === channelRecipients.length) { - if (checker(re, channelRecipients)) { - if (channel == null) { - channel = ur.channel - await ur.assign({ closed: false }).save() - } - } - } - } - - if (channel == null) { - name = trimSpecial(name); - - channel = await new Channel({ - name, - type, - owner_id: (type === ChannelType.DM ? undefined : creator_user_id), - created_at: new Date(), - last_message_id: null, - recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })), - }).save(); - } - - - const channel_dto = await DmChannelDTO.from(channel) - - if (type === ChannelType.GROUP_DM) { - - for (let recipient of channel.recipients!) { - await emitEvent({ - event: "CHANNEL_CREATE", - data: channel_dto.excludedRecipients([recipient.user_id]), - user_id: recipient.user_id - }) - } - } else { - await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id }); - } - - return channel_dto.excludedRecipients([creator_user_id]) - } - - public static async removeRecipientFromChannel(channel: Channel, user_id: string) { - await Recipient.delete({ channel_id: channel.id, user_id: user_id }) - channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id) - - if (channel.recipients?.length === 0) { - await ChannelService.deleteChannel(channel); - await emitEvent({ - event: "CHANNEL_DELETE", - data: await DmChannelDTO.from(channel, [user_id]), - user_id: user_id - }); - return - } - - await emitEvent({ - event: "CHANNEL_DELETE", - data: await DmChannelDTO.from(channel, [user_id]), - user_id: user_id - }); - - //If the owner leave we make the first recipient in the list the new owner - if (channel.owner_id === user_id) { - channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner? - await emitEvent({ - event: "CHANNEL_UPDATE", - data: await DmChannelDTO.from(channel, [user_id]), - channel_id: channel.id - }); - } - - await channel.save() - - await emitEvent({ - event: "CHANNEL_RECIPIENT_REMOVE", data: { - channel_id: channel.id, - user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection }) - }, channel_id: channel.id - } as ChannelRecipientRemoveEvent); - } - - public static async deleteChannel(channel: Channel) { - await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util - //TODO before deleting the channel we should check and delete other relations - await Channel.delete({ id: channel.id }) - } -} diff --git a/util/src/services/index.ts b/util/src/services/index.ts deleted file mode 100644 index c012a208..00000000 --- a/util/src/services/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./ChannelService"; diff --git a/util/src/util/Array.ts b/util/src/util/Array.ts new file mode 100644 index 00000000..27f7c961 --- /dev/null +++ b/util/src/util/Array.ts @@ -0,0 +1,3 @@ +export function containsAll(arr: any[], target: any[]) { + return target.every(v => arr.includes(v)); +} \ No newline at end of file diff --git a/util/src/util/index.ts b/util/src/util/index.ts index 4e92f017..2de26fc7 100644 --- a/util/src/util/index.ts +++ b/util/src/util/index.ts @@ -12,3 +12,4 @@ export * from "./RabbitMQ"; export * from "./Regex"; export * from "./Snowflake"; export * from "./String"; +export * from "./Array"; |