From c36b9f388ca60e8e4c2c457612d990688d8cebd8 Mon Sep 17 00:00:00 2001 From: nicolas-arnaud Date: Sun, 19 Mar 2023 19:17:51 +0100 Subject: [PATCH] may have fix ban, mute, block and kick --- back/volume/src/chat/chat.controller.ts | 4 +- back/volume/src/chat/chat.gateway.ts | 157 ++++++++++++------------ back/volume/src/chat/chat.service.ts | 13 +- front/volume/src/components/Chat.svelte | 11 +- 4 files changed, 93 insertions(+), 92 deletions(-) diff --git a/back/volume/src/chat/chat.controller.ts b/back/volume/src/chat/chat.controller.ts index b58c18d..6437ace 100644 --- a/back/volume/src/chat/chat.controller.ts +++ b/back/volume/src/chat/chat.controller.ts @@ -184,9 +184,7 @@ export class ChatController { if (await this.channelService.isOwner(channel.id, mute.data[0])) { throw new BadRequestException('You cannot mute the owner of the channel') } - if ( - (await this.channelService.getMuteDuration(channel.id, mute.data[0])) > 0 - ) { + if (await this.channelService.isMuted(channel.id, mute.data[0])) { throw new BadRequestException('User is already muted from this channel') } const newMute: number[] = [mute.data[0], Date.now() + mute.data[1] * 1000] diff --git a/back/volume/src/chat/chat.gateway.ts b/back/volume/src/chat/chat.gateway.ts index 7a34f47..a25f536 100644 --- a/back/volume/src/chat/chat.gateway.ts +++ b/back/volume/src/chat/chat.gateway.ts @@ -4,35 +4,35 @@ import { SubscribeMessage, WebSocketGateway, WebSocketServer, - WsException -} from '@nestjs/websockets' -import { Socket, Server } from 'socket.io' + WsException, +} from "@nestjs/websockets"; +import { Socket, Server } from "socket.io"; // import { User } from 'users/user.entity'; -import { UsersService } from 'src/users/users.service' -import { ChatService } from './chat.service' -import type Message from './entity/message.entity' -import * as bcrypt from 'bcrypt' -import { MessageService } from './message.service' -import { CreateMessageDto } from './dto/create-message.dto' -import { ConnectionDto } from './dto/connection.dto' -import { kickUserDto } from './dto/kickUser.dto' -import ConnectedUser from './entity/connection.entity' -import { InjectRepository } from '@nestjs/typeorm' -import { Repository } from 'typeorm' -import type User from 'src/users/entity/user.entity' +import { UsersService } from "src/users/users.service"; +import { ChatService } from "./chat.service"; +import type Message from "./entity/message.entity"; +import * as bcrypt from "bcrypt"; +import { MessageService } from "./message.service"; +import { CreateMessageDto } from "./dto/create-message.dto"; +import { ConnectionDto } from "./dto/connection.dto"; +import { kickUserDto } from "./dto/kickUser.dto"; +import ConnectedUser from "./entity/connection.entity"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; +import type User from "src/users/entity/user.entity"; @WebSocketGateway({ cors: { origin: new RegExp( - `^(http|ws)://${process.env.HOST ?? 'localhost'}(:\\d+)?$` - ) - } + `^(http|ws)://${process.env.HOST ?? "localhost"}(:\\d+)?$` + ), + }, }) export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() - server: Server + server: Server; - constructor ( + constructor( private readonly userService: UsersService, private readonly messageService: MessageService, private readonly chatService: ChatService, @@ -40,102 +40,103 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { private readonly connectedUserRepository: Repository ) {} - async handleConnection (socket: Socket): Promise {} + async handleConnection(socket: Socket): Promise {} - async handleDisconnect (socket: Socket): Promise { + async handleDisconnect(socket: Socket): Promise { const connect = await this.connectedUserRepository.findOneBy({ - socket: socket.id - }) + socket: socket.id, + }); if (connect) - await this.connectedUserRepository.delete({ socket: socket.id }) - socket.disconnect() - console.log('socket %s has disconnected', socket.id) + await this.connectedUserRepository.delete({ socket: socket.id }); + socket.disconnect(); + console.log("socket %s has disconnected", socket.id); } - @SubscribeMessage('joinChannel') - async onJoinChannel (socket: Socket, connect: ConnectionDto): Promise { - console.log('here') - const channel = await this.chatService.getFullChannel(connect.ChannelId) - if (channel.banned.findIndex((ban) => ban[0] === connect.UserId) !== -1) { - this.server.to(socket.id).emit('failedJoin', 'You are banned from this channel') + @SubscribeMessage("joinChannel") + async onJoinChannel(socket: Socket, connect: ConnectionDto): Promise { + console.log("here"); + const channel = await this.chatService.getFullChannel(connect.ChannelId); + if (channel.banned.findIndex((ban) => ban[0] === +connect.UserId) !== -1) { + this.server + .to(socket.id) + .emit("failedJoin", "You are banned from this channel"); } - const user = await this.userService.getFullUser(connect.UserId) - if (channel.password && channel.password !== '') { + const user = await this.userService.getFullUser(connect.UserId); + if (channel.password && channel.password !== "") { if ( !connect.pwd || !(await bcrypt.compare(connect.pwd, channel.password)) ) { - this.server.to(socket.id).emit('failedJoin', 'Wrong password') + this.server.to(socket.id).emit("failedJoin", "Wrong password"); } } - await this.chatService.addUserToChannel(channel, user) + await this.chatService.addUserToChannel(channel, user); const messages = await this.messageService.findMessagesInChannelForUser( channel, user - ) - const conUser = new ConnectedUser() - conUser.user = user.id - conUser.channel = channel.id - conUser.socket = socket.id - const test = await this.connectedUserRepository.save(conUser) - console.log(test) - await socket.join(channel.id.toString()) - this.server.to(socket.id).emit('messages', messages) - console.log(this.server.sockets.adapter.rooms.get(channel.id.toString())) + ); + const conUser = new ConnectedUser(); + conUser.user = user.id; + conUser.channel = channel.id; + conUser.socket = socket.id; + const test = await this.connectedUserRepository.save(conUser); + console.log(test); + await socket.join(channel.id.toString()); + this.server.to(socket.id).emit("messages", messages); + console.log(this.server.sockets.adapter.rooms.get(channel.id.toString())); } - @SubscribeMessage('leaveChannel') - async onLeaveChannel (socket: Socket): Promise { + @SubscribeMessage("leaveChannel") + async onLeaveChannel(socket: Socket): Promise { const connect = await this.connectedUserRepository.findOneBy({ - socket: socket.id - }) - console.log('connection removed', connect?.user) - if (connect == null) return - const channel = await this.chatService.getFullChannel(connect.channel) - socket.disconnect() + socket: socket.id, + }); + console.log("connection removed", connect?.user); + if (connect == null) return; + const channel = await this.chatService.getFullChannel(connect.channel); + socket.disconnect(); if (connect.user === channel.owner.id) { - this.server.in(channel.id.toString()).disconnectSockets() - await this.chatService.removeChannel(channel.id) + this.server.in(channel.id.toString()).disconnectSockets(); + await this.chatService.removeChannel(channel.id); } else { - channel.users = channel.users.filter((e) => e.id !== connect.user) + channel.users = channel.users.filter((e) => e.id !== connect.user); } - await this.connectedUserRepository.delete({ socket: socket.id }) + await this.connectedUserRepository.delete({ socket: socket.id }); } - @SubscribeMessage('addMessage') - async onAddMessage (socket: Socket, message: CreateMessageDto): Promise { - const channel = await this.chatService.getChannel(message.ChannelId) - if ( - (await this.chatService.getMuteDuration(channel.id, message.UserId)) > 0 - ) { - throw new WsException('You are muted') + @SubscribeMessage("addMessage") + async onAddMessage(socket: Socket, message: CreateMessageDto): Promise { + const channel = await this.chatService.getChannel(message.ChannelId); + if (await this.chatService.isMuted(message.UserId, channel.id)) { + throw new WsException("You are muted"); } const createdMessage: Message = await this.messageService.createMessage( message - ) - this.server.to(channel.id.toString()).emit('newMessage', createdMessage) + ); + this.server.to(channel.id.toString()).emit("newMessage", createdMessage); } - @SubscribeMessage('kickUser') - async onKickUser (socket: Socket, kick: kickUserDto): Promise { - const channel = await this.chatService.getFullChannel(kick.chan) + @SubscribeMessage("kickUser") + async onKickUser(socket: Socket, kick: kickUserDto): Promise { + const channel = await this.chatService.getFullChannel(kick.chan); if (channel.owner.id === kick.to) { - throw new WsException('You cannot kick the owner of a channel') + throw new WsException("You cannot kick the owner of a channel"); } if ( channel.owner.id !== kick.from && channel.admins.findIndex((usr) => usr.id === kick.from) === -1 ) { - throw new WsException('You do not have the required privileges') + throw new WsException("You do not have the required privileges"); } - const user = (await this.userService.findUser(kick.to)) as User + const user = (await this.userService.findUser(kick.to)) as User; const connect = (await this.connectedUserRepository.findOneBy({ - user: user.id - })) as ConnectedUser + user: user.id, + })) as ConnectedUser; // await this.onLeaveChannel(socket) await this.server.sockets.sockets .get(connect.socket) - ?.leave(channel.id.toString()) - this.server.sockets.sockets.get(connect.socket)?.disconnect() + ?.leave(channel.id.toString()); + this.server.sockets.sockets.get(connect.socket)?.emit("kicked"); + this.server.sockets.sockets.get(connect.socket)?.disconnect(); } } diff --git a/back/volume/src/chat/chat.service.ts b/back/volume/src/chat/chat.service.ts index 19242bd..6e47b11 100644 --- a/back/volume/src/chat/chat.service.ts +++ b/back/volume/src/chat/chat.service.ts @@ -110,7 +110,7 @@ export class ChatService { const channels = await this.ChannelRepository.find({}) channels.forEach((channel) => { channel.muted = channel.muted.filter((data) => { - return Date.now() - data[1] > 0 + return Date.now() - data[1] < 0 }) void this.update(channel) }) @@ -121,7 +121,7 @@ export class ChatService { const channels = await this.ChannelRepository.find({}) for (const channel of channels) { channel.banned = channel.banned.filter((data) => { - return Date.now() - data[1] > 0 + return Date.now() - data[1] < 0 }) void this.update(channel) } @@ -210,18 +210,13 @@ export class ChatService { return channel.banned.findIndex((ban) => ban[0] === userId) !== -1 } - async getMuteDuration (id: number, userId: number): Promise { + async isMuted (id: number, userId: number): Promise { const channel = await this.ChannelRepository.findOne({ where: { id } }) if (channel === null) { throw new BadRequestException(`Channel #${id} not found`) } - - const mutation: number[] | undefined = channel.muted.find( - (mutation) => mutation[0] === userId - ) - if (mutation == null) return 0 - return mutation[1] + return channel.muted.findIndex((mute) => mute[0] === userId) !== -1 } } diff --git a/front/volume/src/components/Chat.svelte b/front/volume/src/components/Chat.svelte index 55a795d..2125708 100644 --- a/front/volume/src/components/Chat.svelte +++ b/front/volume/src/components/Chat.svelte @@ -73,11 +73,17 @@ }, 1000); console.log("You are joining channel: ", channel.name); }); + socket.on("failedJoin", (error: string) => { show_popup(`Failed to join channel: ${error}`, false); setAppState(APPSTATE.CHANNELS); }); + socket.on("kicked", (msg: string) => { + show_popup(`You have been kicked from channel: ${msg}`, false); + setAppState(APPSTATE.CHANNELS); + }) + console.log("Try to join channel: ", $store.ftId, channel.id, $content); }); @@ -208,8 +214,9 @@ }, body: JSON.stringify({ data: [target.ftId, duration] }), }); - socket.emit("kickUser", channel.id, $store.ftId, target.ftId); - dispatch("return-home"); + if (response.ok) { + socket.emit("kickUser", {chan: channel.id, from: $store.ftId, to: target.ftId}); + } else await show_popup(`Ban of ${username}: ${response.text}`, false); } };