import { WebSocketGateway , SubscribeMessage , WsResponse , WebSocketServer , NestGateway , OnGatewayInit , OnGatewayConnection , OnGatewayDisconnect , } from '@nestjs/websockets' ; import * as socketIO from 'socket.io' ; import * as cookie from 'cookie' ; import { Observable , of } from 'rxjs' ; import { map } from 'rxjs/operators' ; import { SecurityService } from '../../common/security/security.service' ; import { ChatCache } from '../chat.cache' ; import { ChatService } from '../chat.service' ; import { UserJWT } from '../../auth/interfaces/user-JWT.interface' ; @ WebSocketGateway ( 8002 , { namespace : '/api/chat/gateway' } ) export class ChatGateway implements NestGateway , OnGatewayConnection { requiredRolesForGateway = [ 'anon' , 'user' ] ; recentlyCreatedAnonEvent = 'recently-created-anon' ; requiredRolesForAdminRoute = [ 'admin' ] ; constructor ( private readonly chatCache , private readonly securityService , private readonly chatService ) { } @ WebSocketServer ( ) server : SocketIO . Namespace ; async handleConnection ( client ) { const parsedCookies = cookie . parse ( client . request . headers . cookie ) ; const userCookie = parsedCookies [ 'SESSIONID' ] ; if ( ! userCookie ) { return client . disconnect ( ) ; } const user = await this . securityService . decodeJwt ( userCookie ) ; const canAccess = this . roleGuard ( user . roles , this . requiredRolesForGateway ) ; if ( ! canAccess ) { return client . disconnect ( ) ; } client [ 'user' ] = user ; client . emit ( 'message' , 'successfully connected to api/chat/gateway websocket' ) ; } @ SubscribeMessage ( 'join-chatroom' ) async onJoinChatroom ( client , data ) { const user = client [ 'user' ] ; const chatroom = await this . chatService . findChatroomByName ( data . roomName ) ; if ( chatroom === undefined ) { client . leaveAll ( ) ; const newlyCreatedChatroom = await this . chatService . createChatroom ( data . roomName , user ) ; client . join ( newlyCreatedChatroom . name ) ; return client . emit ( 'message' , newlyCreatedChatroom ) ; } client . leaveAll ( ) ; client . join ( chatroom . name ) ; return client . emit ( 'message' , chatroom ) ; } @ SubscribeMessage ( 'message' ) async onRecentlyCreatedAnon ( client , data ) { const savedMessage = await this . chatService . addMessage ( data , client [ 'user' ] ) ; return this . server . to ( data . roomName ) . emit ( 'message' , savedMessage ) ; } private roleGuard ( roles , requiredRoles ) { return roles . some ( role => ! ! requiredRoles . find ( item => item === role ) ) ; } }