You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.7 KiB
111 lines
3.7 KiB
import {
|
|
type OnGatewayConnection,
|
|
type OnGatewayDisconnect,
|
|
SubscribeMessage,
|
|
WebSocketGateway,
|
|
WebSocketServer,
|
|
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'
|
|
|
|
@WebSocketGateway({
|
|
cors: { origin: new RegExp(`^(http|ws)://${process.env.HOST ?? 'localhost'}(:\\d+)?$`) }
|
|
})
|
|
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
|
@WebSocketServer()
|
|
server: Server
|
|
|
|
constructor (
|
|
private readonly userService: UsersService,
|
|
private readonly messageService: MessageService,
|
|
private readonly chatService: ChatService,
|
|
) {}
|
|
|
|
async handleConnection (socket: Socket): Promise<void> {}
|
|
|
|
async handleDisconnect (socket: Socket): Promise<void> {
|
|
await this.onLeaveChannel(socket)
|
|
socket.disconnect()
|
|
}
|
|
|
|
@SubscribeMessage('joinChannel')
|
|
async onJoinChannel (socket: Socket, connect: ConnectionDto): Promise<void> {
|
|
console.log(
|
|
'User %s is trying to join channel %s',
|
|
connect.UserId,
|
|
connect.ChannelId,
|
|
connect.pwd
|
|
)
|
|
const channel = await this.chatService.getFullChannel(connect.ChannelId)
|
|
if (channel.banned.findIndex((ban) => ban.ftId === connect.UserId) !== -1) {
|
|
throw new WsException('You are banned from entering this channel')
|
|
}
|
|
const user = await this.userService.getFullUser(connect.UserId)
|
|
if (channel.password && channel.password !== '') {
|
|
if (
|
|
!connect.pwd ||
|
|
!(await bcrypt.compare(connect.pwd, channel.password))
|
|
) {
|
|
throw new WsException('Wrong password')
|
|
}
|
|
} else await this.chatService.addUserToChannel(channel, user)
|
|
const messages = await this.messageService.findMessagesInChannelForUser(
|
|
channel,
|
|
user
|
|
)
|
|
this.server.to(socket.id).emit('messages', messages)
|
|
await socket.join(channel.id.toString())
|
|
}
|
|
|
|
@SubscribeMessage('getMessages')
|
|
async onGetMessages (socket: Socket, connect: ConnectionDto): Promise<void> {
|
|
const user = await this.userService.getFullUser(connect.UserId)
|
|
const channel = await this.chatService.getFullChannel(connect.ChannelId)
|
|
const messages = await this.messageService.findMessagesInChannelForUser(channel, user)
|
|
this.server.to(socket.id).emit('messages', messages)
|
|
}
|
|
|
|
@SubscribeMessage('leaveChannel')
|
|
async onLeaveChannel (socket: Socket): Promise<void> {
|
|
const id = socket.id as any
|
|
}
|
|
|
|
@SubscribeMessage('addMessage')
|
|
async onAddMessage (socket: Socket, message: CreateMessageDto): Promise<void> {
|
|
const channel = await this.chatService.getChannel(message.ChannelId)
|
|
if (
|
|
(await this.chatService.getMuteDuration(channel.id, message.UserId)) > 0
|
|
) {
|
|
throw new WsException('You are muted')
|
|
}
|
|
const createdMessage: Message = await this.messageService.createMessage(
|
|
message
|
|
)
|
|
this.server.to(channel.id.toString()).emit('newMessage', createdMessage)
|
|
}
|
|
|
|
@SubscribeMessage('kickUser')
|
|
async onKickUser (
|
|
socket: Socket,
|
|
chan: number,
|
|
from: number,
|
|
to: number
|
|
): Promise<void> {
|
|
const channel = await this.chatService.getChannel(chan)
|
|
if (
|
|
channel.owner.id !== from ||
|
|
channel.admins.find((e) => e.id === from) == null
|
|
) {
|
|
throw new WsException('You do not have the required privileges')
|
|
}
|
|
await this.onLeaveChannel(socket)
|
|
}
|
|
}
|
|
|