From 6a85b418a8c3a0e9fe23b1f6d3cbd56f6007e432 Mon Sep 17 00:00:00 2001 From: Gabriel Mehdevi Date: Sat, 18 Mar 2023 16:05:11 +0100 Subject: [PATCH] brought back connect Users to improve kick OwnerLeave and Join --- back/volume/src/chat/chat.controller.ts | 15 ------ back/volume/src/chat/chat.gateway.ts | 54 ++++++++++++++----- back/volume/src/chat/chat.module.ts | 3 +- .../src/chat/entity/connection.entity.ts | 16 ++++++ front/volume/src/components/Chat.svelte | 5 +- 5 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 back/volume/src/chat/entity/connection.entity.ts diff --git a/back/volume/src/chat/chat.controller.ts b/back/volume/src/chat/chat.controller.ts index ba39ccf..3bd142b 100644 --- a/back/volume/src/chat/chat.controller.ts +++ b/back/volume/src/chat/chat.controller.ts @@ -217,21 +217,6 @@ export class ChatController { await this.channelService.updatePassword(id, data.password) } - @Get(':id/leave') - async leaveChannel ( - @Profile42() profile: Profile, - @Param('id', ParseIntPipe) id: number - ): Promise { - if (await this.channelService.isOwner(id, +profile.id)) { - await this.channelService.removeChannel(id) // -> verify that the deletion the break others users behaviors. - } - const channel = await this.channelService.getFullChannel(id) - channel.users = channel.users.filter((usr: User) => { - return usr.ftId !== profile.id - }) - await this.channelService.save(channel) - } - @Get() async getChannelsForUser (@Profile42() profile: Profile): Promise { const chan = await this.channelService.getChannelsForUser(+profile.id) diff --git a/back/volume/src/chat/chat.gateway.ts b/back/volume/src/chat/chat.gateway.ts index 94534be..dda71b5 100644 --- a/back/volume/src/chat/chat.gateway.ts +++ b/back/volume/src/chat/chat.gateway.ts @@ -16,6 +16,11 @@ 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 { connect } from 'http2' +import User from 'src/users/entity/user.entity' @WebSocketGateway({ cors: { @@ -31,8 +36,10 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { constructor ( private readonly userService: UsersService, private readonly messageService: MessageService, - private readonly chatService: ChatService - ) {} + private readonly chatService: ChatService, + @InjectRepository(ConnectedUser) + private readonly connectedUserRepository: Repository + ) {} async handleConnection (socket: Socket): Promise {} @@ -66,6 +73,12 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { channel, user ) + const conUser = { + user : user.id, + channel : channel.id, + socket: socket.id + } + this.connectedUserRepository.create(conUser) this.server.to(socket.id).emit('messages', messages) await socket.join(channel.id.toString()) } @@ -83,8 +96,19 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { @SubscribeMessage('leaveChannel') async onLeaveChannel (socket: Socket): Promise { - socket.disconnect() - } + const connect = await this.connectedUserRepository.findOneBy({socket : socket.id}) + 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() + this.chatService.removeChannel(channel.id) + } else { + channel.users = channel.users.filter((e) => e.id !== connect.user) + } + await this.connectedUserRepository.delete({ socket : socket.id }) + } @SubscribeMessage('addMessage') async onAddMessage (socket: Socket, message: CreateMessageDto): Promise { @@ -101,15 +125,19 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { } @SubscribeMessage('kickUser') - async onKickUser (socket: Socket, msg: kickUserDto): Promise { - console.log('kick called') - const channel = await this.chatService.getFullChannel(msg.chan) - if ( - channel.owner.id !== msg.from && - channel.admins.findIndex((usr) => usr.id === msg.from) === -1 - ) { - throw new WsException('You do not have the required privileges') - } + 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') + 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') + } + const user = await this.userService.findUser(kick.to) as User + const connect = await this.connectedUserRepository.findOneBy({user : user.id}) as ConnectedUser await this.onLeaveChannel(socket) + this.server.sockets.sockets.get(connect.socket)?.disconnect() } } diff --git a/back/volume/src/chat/chat.module.ts b/back/volume/src/chat/chat.module.ts index 08ad1d1..8909b26 100644 --- a/back/volume/src/chat/chat.module.ts +++ b/back/volume/src/chat/chat.module.ts @@ -10,12 +10,13 @@ import { MessageService } from './message.service' import Channel from './entity/channel.entity' import Message from './entity/message.entity' +import ConnectedUser from './entity/connection.entity' @Module({ imports: [ UsersModule, AuthModule, - TypeOrmModule.forFeature([Channel, Message]) + TypeOrmModule.forFeature([Channel, Message, ConnectedUser]) ], controllers: [ChatController], providers: [ChatService, ChatGateway, MessageService], diff --git a/back/volume/src/chat/entity/connection.entity.ts b/back/volume/src/chat/entity/connection.entity.ts new file mode 100644 index 0000000..de27caa --- /dev/null +++ b/back/volume/src/chat/entity/connection.entity.ts @@ -0,0 +1,16 @@ +import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from 'typeorm' + +import Channel from './channel.entity' +import User from 'src/users/entity/user.entity' + +@Entity() +export default class ConnectedUser { + @Column() + user: number + + @Column() + channel: number + + @PrimaryColumn() + socket: string +} diff --git a/front/volume/src/components/Chat.svelte b/front/volume/src/components/Chat.svelte index c34ed82..f5de1fa 100644 --- a/front/volume/src/components/Chat.svelte +++ b/front/volume/src/components/Chat.svelte @@ -295,7 +295,10 @@ mode: "cors", }); if (response.ok) { - window.location.href = "/channels"; + return { + status: 200, + redirect: "/channels/" + }; } else { await show_popup("Failed to leave channel",false); }