export class WebsocketAdapter extends IoAdapter { private readonly restService: RestService; @InjectModel(User.name) private readonly userModel: Model; logger: Logger = new Logger('Gateway'); constructor(app: INestApplication) { super(app); this.restService = app.get(RestService); } createIOServer(port: number, options?: any) { const server = super.createIOServer(port, options); server.use(async (socket: AuthenticatedSocket, next) => { this.logger.debug('Inside Websocket Adapter'); const { cookie: clientCookie } = socket.handshake.headers; this.logger.debug('Client cookie: ' + clientCookie); if (!clientCookie) { this.logger.debug('Client has no cookies'); return next( this.logger.debug('Emiting error'), socket.emit( Events.ERROR, new WsException(Constrants.GatewayErrorMessages.NO_COOKIE), ), socket.disconnect(), ); } const { SESSION_ID } = cookie.parse(clientCookie); if (!SESSION_ID) { this.logger.debug('SESSION_ID DOES NOT EXIST'); return next( socket.emit( Events.ERROR, new WsException(Constrants.GatewayErrorMessages.NO_SESSION), ), socket.disconnect(), ); } const signedCookie = cookieParser.signedCookie( SESSION_ID, process.env.COOKIE_SECRET, ); if (!signedCookie) return next( socket.emit( Events.ERROR, new WsException( Constrants.GatewayErrorMessages.ERROR_SIGNING_COOKIE, ), ), socket.disconnect(), ); const client = MongoClient.connect(process.env.DATABASE_STRING, {}); const sessionDB = await client.then(async (c) => { const collection = c.db('DashboardSessions').collection('sessions'); return collection.findOne({ _id: signedCookie }); }); if (!sessionDB) return next( socket.emit( Events.ERROR, new WsException( Constrants.GatewayErrorMessages.NOT_SESSION_FOUND_IN_DATABASE, ), ), socket.disconnect(), ); if (!sessionDB) return next( socket.emit( Events.ERROR, new WsException( Constrants.GatewayErrorMessages.NOT_SESSION_FOUND_IN_DATABASE, ), ), socket.disconnect(), ); const userFromJson = JSON.parse(sessionDB.session); if (!userFromJson.passport || !userFromJson.passport.user) return next( socket.emit( Events.ERROR, new WsException( Constrants.GatewayErrorMessages.USER_OBJECT_NOT_FOUND_IN_DATABASE, ), ), socket.disconnect(), ); this.logger.debug(this.userModel); const userDB = await this.userModel.findOne({ userId: userFromJson.passport.user, }); if (!userDB) { return next( socket.emit( Events.ERROR, new WsException( Constrants.GatewayErrorMessages.USER_NOT_FOUND_IN_DATABASE, ), socket.disconnect(), ), ); } const discordUserData = await this.restService.get( DiscordGetRoutes.USER, { headers: { Authorization: `Bearer ${userDB.accessToken}`, }, }, ); this.logger.debug(discordUserData); if (!discordUserData) return next( socket.emit( Events.ERROR, new WsException(Constrants.GatewayErrorMessages.USER_NOT_FOUND), ), socket.disconnect(), ); const userData = plainToInstance(User, discordUserData); socket.user = userData; next(); }); return server; } }