mirror of
https://github.com/pavlobu/deskreen.git
synced 2025-05-17 16:00:16 -07:00
162 lines
4.2 KiB
TypeScript
162 lines
4.2 KiB
TypeScript
/*
|
|
* original JS code from darkwire.io
|
|
* translated to typescript for Deskreen app
|
|
* by Pavlo (Paul) Buidenkov
|
|
* */
|
|
|
|
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 getPort from 'get-port';
|
|
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: string) => {
|
|
return crypto.createHash('sha256').update(id).digest('hex');
|
|
};
|
|
|
|
const ioHandleOnConnection = (socket: Io.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 || '{}');
|
|
|
|
// eslint-disable-next-line no-new
|
|
new DarkwireSocket({
|
|
roomIdOriginal: roomId,
|
|
roomId: roomIdHash,
|
|
socket,
|
|
room,
|
|
});
|
|
}
|
|
}, 500); // timeout 500 millisecond for throttling malitios connections
|
|
};
|
|
|
|
function setStaticFileHeaders(
|
|
ctx: Koa.ParameterizedContext<Koa.DefaultState, Koa.DefaultContext>
|
|
) {
|
|
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'",
|
|
// 'Cache-Control': 'max-age=0', // make browser get fresh files and make new connection when client connected
|
|
});
|
|
}
|
|
|
|
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(): void {
|
|
this.server.close();
|
|
}
|
|
}
|
|
|
|
const deskreenServer = new DeskreenSignalingServer();
|
|
|
|
export default deskreenServer;
|