Browse Source

may have fix ban, mute, block and kick

master
nicolas-arnaud 2 years ago
parent
commit
c36b9f388c
  1. 4
      back/volume/src/chat/chat.controller.ts
  2. 143
      back/volume/src/chat/chat.gateway.ts
  3. 13
      back/volume/src/chat/chat.service.ts
  4. 11
      front/volume/src/components/Chat.svelte

4
back/volume/src/chat/chat.controller.ts

@ -184,9 +184,7 @@ export class ChatController {
if (await this.channelService.isOwner(channel.id, mute.data[0])) { if (await this.channelService.isOwner(channel.id, mute.data[0])) {
throw new BadRequestException('You cannot mute the owner of the channel') throw new BadRequestException('You cannot mute the owner of the channel')
} }
if ( if (await this.channelService.isMuted(channel.id, mute.data[0])) {
(await this.channelService.getMuteDuration(channel.id, mute.data[0])) > 0
) {
throw new BadRequestException('User is already muted from this channel') throw new BadRequestException('User is already muted from this channel')
} }
const newMute: number[] = [mute.data[0], Date.now() + mute.data[1] * 1000] const newMute: number[] = [mute.data[0], Date.now() + mute.data[1] * 1000]

143
back/volume/src/chat/chat.gateway.ts

@ -4,33 +4,33 @@ import {
SubscribeMessage, SubscribeMessage,
WebSocketGateway, WebSocketGateway,
WebSocketServer, WebSocketServer,
WsException WsException,
} from '@nestjs/websockets' } from "@nestjs/websockets";
import { Socket, Server } from 'socket.io' import { Socket, Server } from "socket.io";
// import { User } from 'users/user.entity'; // import { User } from 'users/user.entity';
import { UsersService } from 'src/users/users.service' import { UsersService } from "src/users/users.service";
import { ChatService } from './chat.service' import { ChatService } from "./chat.service";
import type Message from './entity/message.entity' import type Message from "./entity/message.entity";
import * as bcrypt from 'bcrypt' import * as bcrypt from "bcrypt";
import { MessageService } from './message.service' import { MessageService } from "./message.service";
import { CreateMessageDto } from './dto/create-message.dto' import { CreateMessageDto } from "./dto/create-message.dto";
import { ConnectionDto } from './dto/connection.dto' import { ConnectionDto } from "./dto/connection.dto";
import { kickUserDto } from './dto/kickUser.dto' import { kickUserDto } from "./dto/kickUser.dto";
import ConnectedUser from './entity/connection.entity' import ConnectedUser from "./entity/connection.entity";
import { InjectRepository } from '@nestjs/typeorm' import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from 'typeorm' import { Repository } from "typeorm";
import type User from 'src/users/entity/user.entity' import type User from "src/users/entity/user.entity";
@WebSocketGateway({ @WebSocketGateway({
cors: { cors: {
origin: new RegExp( origin: new RegExp(
`^(http|ws)://${process.env.HOST ?? 'localhost'}(:\\d+)?$` `^(http|ws)://${process.env.HOST ?? "localhost"}(:\\d+)?$`
) ),
} },
}) })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect { export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() @WebSocketServer()
server: Server server: Server;
constructor( constructor(
private readonly userService: UsersService, private readonly userService: UsersService,
@ -44,98 +44,99 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
async handleDisconnect(socket: Socket): Promise<void> { async handleDisconnect(socket: Socket): Promise<void> {
const connect = await this.connectedUserRepository.findOneBy({ const connect = await this.connectedUserRepository.findOneBy({
socket: socket.id socket: socket.id,
}) });
if (connect) if (connect)
await this.connectedUserRepository.delete({ socket: socket.id }) await this.connectedUserRepository.delete({ socket: socket.id });
socket.disconnect() socket.disconnect();
console.log('socket %s has disconnected', socket.id) console.log("socket %s has disconnected", socket.id);
} }
@SubscribeMessage('joinChannel') @SubscribeMessage("joinChannel")
async onJoinChannel(socket: Socket, connect: ConnectionDto): Promise<void> { async onJoinChannel(socket: Socket, connect: ConnectionDto): Promise<void> {
console.log('here') console.log("here");
const channel = await this.chatService.getFullChannel(connect.ChannelId) const channel = await this.chatService.getFullChannel(connect.ChannelId);
if (channel.banned.findIndex((ban) => ban[0] === connect.UserId) !== -1) { if (channel.banned.findIndex((ban) => ban[0] === +connect.UserId) !== -1) {
this.server.to(socket.id).emit('failedJoin', 'You are banned from this channel') this.server
.to(socket.id)
.emit("failedJoin", "You are banned from this channel");
} }
const user = await this.userService.getFullUser(connect.UserId) const user = await this.userService.getFullUser(connect.UserId);
if (channel.password && channel.password !== '') { if (channel.password && channel.password !== "") {
if ( if (
!connect.pwd || !connect.pwd ||
!(await bcrypt.compare(connect.pwd, channel.password)) !(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( const messages = await this.messageService.findMessagesInChannelForUser(
channel, channel,
user user
) );
const conUser = new ConnectedUser() const conUser = new ConnectedUser();
conUser.user = user.id conUser.user = user.id;
conUser.channel = channel.id conUser.channel = channel.id;
conUser.socket = socket.id conUser.socket = socket.id;
const test = await this.connectedUserRepository.save(conUser) const test = await this.connectedUserRepository.save(conUser);
console.log(test) console.log(test);
await socket.join(channel.id.toString()) await socket.join(channel.id.toString());
this.server.to(socket.id).emit('messages', messages) this.server.to(socket.id).emit("messages", messages);
console.log(this.server.sockets.adapter.rooms.get(channel.id.toString())) console.log(this.server.sockets.adapter.rooms.get(channel.id.toString()));
} }
@SubscribeMessage('leaveChannel') @SubscribeMessage("leaveChannel")
async onLeaveChannel(socket: Socket): Promise<void> { async onLeaveChannel(socket: Socket): Promise<void> {
const connect = await this.connectedUserRepository.findOneBy({ const connect = await this.connectedUserRepository.findOneBy({
socket: socket.id socket: socket.id,
}) });
console.log('connection removed', connect?.user) console.log("connection removed", connect?.user);
if (connect == null) return if (connect == null) return;
const channel = await this.chatService.getFullChannel(connect.channel) const channel = await this.chatService.getFullChannel(connect.channel);
socket.disconnect() socket.disconnect();
if (connect.user === channel.owner.id) { if (connect.user === channel.owner.id) {
this.server.in(channel.id.toString()).disconnectSockets() this.server.in(channel.id.toString()).disconnectSockets();
await this.chatService.removeChannel(channel.id) await this.chatService.removeChannel(channel.id);
} else { } 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') @SubscribeMessage("addMessage")
async onAddMessage(socket: Socket, message: CreateMessageDto): Promise<void> { async onAddMessage(socket: Socket, message: CreateMessageDto): Promise<void> {
const channel = await this.chatService.getChannel(message.ChannelId) const channel = await this.chatService.getChannel(message.ChannelId);
if ( if (await this.chatService.isMuted(message.UserId, channel.id)) {
(await this.chatService.getMuteDuration(channel.id, message.UserId)) > 0 throw new WsException("You are muted");
) {
throw new WsException('You are muted')
} }
const createdMessage: Message = await this.messageService.createMessage( const createdMessage: Message = await this.messageService.createMessage(
message message
) );
this.server.to(channel.id.toString()).emit('newMessage', createdMessage) this.server.to(channel.id.toString()).emit("newMessage", createdMessage);
} }
@SubscribeMessage('kickUser') @SubscribeMessage("kickUser")
async onKickUser(socket: Socket, kick: kickUserDto): Promise<void> { async onKickUser(socket: Socket, kick: kickUserDto): Promise<void> {
const channel = await this.chatService.getFullChannel(kick.chan) const channel = await this.chatService.getFullChannel(kick.chan);
if (channel.owner.id === kick.to) { 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 ( if (
channel.owner.id !== kick.from && channel.owner.id !== kick.from &&
channel.admins.findIndex((usr) => usr.id === kick.from) === -1 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({ const connect = (await this.connectedUserRepository.findOneBy({
user: user.id user: user.id,
})) as ConnectedUser })) as ConnectedUser;
// await this.onLeaveChannel(socket) // await this.onLeaveChannel(socket)
await this.server.sockets.sockets await this.server.sockets.sockets
.get(connect.socket) .get(connect.socket)
?.leave(channel.id.toString()) ?.leave(channel.id.toString());
this.server.sockets.sockets.get(connect.socket)?.disconnect() this.server.sockets.sockets.get(connect.socket)?.emit("kicked");
this.server.sockets.sockets.get(connect.socket)?.disconnect();
} }
} }

13
back/volume/src/chat/chat.service.ts

@ -110,7 +110,7 @@ export class ChatService {
const channels = await this.ChannelRepository.find({}) const channels = await this.ChannelRepository.find({})
channels.forEach((channel) => { channels.forEach((channel) => {
channel.muted = channel.muted.filter((data) => { channel.muted = channel.muted.filter((data) => {
return Date.now() - data[1] > 0 return Date.now() - data[1] < 0
}) })
void this.update(channel) void this.update(channel)
}) })
@ -121,7 +121,7 @@ export class ChatService {
const channels = await this.ChannelRepository.find({}) const channels = await this.ChannelRepository.find({})
for (const channel of channels) { for (const channel of channels) {
channel.banned = channel.banned.filter((data) => { channel.banned = channel.banned.filter((data) => {
return Date.now() - data[1] > 0 return Date.now() - data[1] < 0
}) })
void this.update(channel) void this.update(channel)
} }
@ -210,18 +210,13 @@ export class ChatService {
return channel.banned.findIndex((ban) => ban[0] === userId) !== -1 return channel.banned.findIndex((ban) => ban[0] === userId) !== -1
} }
async getMuteDuration (id: number, userId: number): Promise<number> { async isMuted (id: number, userId: number): Promise<boolean> {
const channel = await this.ChannelRepository.findOne({ const channel = await this.ChannelRepository.findOne({
where: { id } where: { id }
}) })
if (channel === null) { if (channel === null) {
throw new BadRequestException(`Channel #${id} not found`) throw new BadRequestException(`Channel #${id} not found`)
} }
return channel.muted.findIndex((mute) => mute[0] === userId) !== -1
const mutation: number[] | undefined = channel.muted.find(
(mutation) => mutation[0] === userId
)
if (mutation == null) return 0
return mutation[1]
} }
} }

11
front/volume/src/components/Chat.svelte

@ -73,11 +73,17 @@
}, 1000); }, 1000);
console.log("You are joining channel: ", channel.name); console.log("You are joining channel: ", channel.name);
}); });
socket.on("failedJoin", (error: string) => { socket.on("failedJoin", (error: string) => {
show_popup(`Failed to join channel: ${error}`, false); show_popup(`Failed to join channel: ${error}`, false);
setAppState(APPSTATE.CHANNELS); 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); console.log("Try to join channel: ", $store.ftId, channel.id, $content);
}); });
@ -208,8 +214,9 @@
}, },
body: JSON.stringify({ data: [target.ftId, duration] }), body: JSON.stringify({ data: [target.ftId, duration] }),
}); });
socket.emit("kickUser", channel.id, $store.ftId, target.ftId); if (response.ok) {
dispatch("return-home"); socket.emit("kickUser", {chan: channel.id, from: $store.ftId, to: target.ftId});
} else await show_popup(`Ban of ${username}: ${response.text}`, false);
} }
}; };

Loading…
Cancel
Save