import http from 'http' ; import express from 'express' ; import Koa from 'koa' ; import crypto from 'crypto' ; import Io from 'socket.io' ; import cors from 'kcors' ; import Router from 'koa-router' ; import koaStatic from 'koa-static' ; import koaSend from 'koa-send' ; import config from '../api/config' ; import pollForInactiveRooms from './pollForInactiveRooms' ; import Logger from '../utils/LoggerWithFilePrefix' ; import isProduction from '../utils/isProduction' ; import SocketsIPService from './socketsIPService' ; import socketIOServerStore from './store/socketIOServerStore' ; import getDeskreenGlobal from '../utils/mainProcessHelpers/getDeskreenGlobal' ; import DarkwireSocket from './darkwireSocket' ; import getStore from './store' ; const { port } = config ; const getRoomIdHash = ( id ) => { return crypto . createHash ( 'sha256' ) . update ( id ) . digest ( 'hex' ) ; } ; const ioHandleOnConnection = ( socket ) => { const { roomId } = socket . handshake . query ; const store = getStore ( ) ; setTimeout ( async ( ) => { if ( ! getDeskreenGlobal ( ) . roomIDService . isRoomIDTaken ( roomId ) ) { socket . emit ( 'NOT_ALLOWED' ) ; setTimeout ( ( ) => { socket . disconnect ( ) ; } , 1000 ) ; } else { const roomIdHash = getRoomIdHash ( roomId ) ; let room = await store . get ( 'rooms' , roomIdHash ) ; room = JSON . parse ( room || '{}' ) ; new DarkwireSocket ( { roomIdOriginal : roomId , roomId : roomIdHash , socket , room , } ) ; } } , 500 ) ; } ; function setStaticFileHeaders ( ctx ) { ctx . set ( { 'strict-transport-security' : 'max-age=31536000' , 'X-Frame-Options' : 'deny' , 'X-XSS-Protection' : '1; mode=block' , 'X-Content-Type-Options' : 'nosniff' , 'Referrer-Policy' : 'no-referrer' , 'Feature-Policy' : "geolocation 'none'; vr 'none'; payment 'none'; microphone 'none'" , } ) ; } class DeskreenSignalingServer { log = new Logger ( __filename ) ; expressApp : express . Application ; server = ( { } as unknown ) as http . Server ; port : number ; app : Koa | undefined ; constructor ( ) { this . expressApp = express ( ) ; this . port = parseInt ( ( port as unknown ) as string , 10 ) ; this . init ( ) ; } init ( ) { this . app = new Koa ( ) ; const router = new Router ( ) ; this . app . use ( cors ( ) ) ; this . app . use ( router . routes ( ) ) ; const clientDistDirectory = isProduction ( ) ? `${ __dirname }/client/build` : `${ __dirname }/../client/build` ; if ( clientDistDirectory ) { this . app . use ( async ( ctx , next ) => { setStaticFileHeaders ( ctx ) ; await koaStatic ( clientDistDirectory ) ( ctx , next ) ; } ) ; this . app . use ( async ( ctx ) => { setStaticFileHeaders ( ctx ) ; await koaSend ( ctx , 'index.html' , { root : clientDistDirectory } ) ; } ) ; } else { this . app . use ( async ( ctx ) => { ctx . body = { ready : true } ; } ) ; } const protocol = http ; this . server = protocol . createServer ( this . app . callback ( ) ) ; const io = Io ( this . server , { pingInterval : 20000 , pingTimeout : 5000 , serveClient : false , } ) ; io . sockets . on ( 'connection' , ( socket ) => { const socketId = socket . id ; const clientIp = socket . request . connection . remoteAddress ; SocketsIPService . setIPOfSocketID ( socketId , clientIp ) ; } ) ; io . on ( 'connection' , ( socket ) => { ioHandleOnConnection ( socket ) ; } ) ; socketIOServerStore . setServer ( io ) ; } async start ( ) { pollForInactiveRooms ( ) ; this . port = parseInt ( ( port as unknown ) as string , 10 ) ; this . server = this . callListenOnHttpServer ( ) ; return this . server ; } callListenOnHttpServer ( ) { return this . server . listen ( this . port , ( ) => { this . log . info ( `Deskreen signaling server is online at port ${ this . port }` ) ; } ) ; } stop ( ) { this . server . close ( ) ; } } const deskreenServer = new DeskreenSignalingServer ( ) ; export default deskreenServer ;