From 8abdefd403b49cce550163871fa3b4d102f0560f Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Wed, 20 Apr 2022 18:46:39 +0100 Subject: [PATCH] remove athena --- .env.sample | 11 -- environment/development/.env.sample | 11 -- environment/uat/.env.sample | 11 -- environment/uat/docker-compose.yml | 9 -- src/server/router/api/admin.js | 6 - src/server/router/api/index.js | 25 ---- src/server/router/api/realtime.js | 165 ----------------------- src/server/websocket/athena/helpers.js | 72 ---------- src/server/websocket/athena/index.js | 180 ------------------------- src/server/websocket/index.js | 0 src/server/websocket/web/commands.js | 65 --------- src/server/websocket/web/controls.js | 55 -------- src/server/websocket/web/index.js | 102 -------------- 13 files changed, 712 deletions(-) delete mode 100644 src/server/router/api/realtime.js delete mode 100644 src/server/websocket/athena/helpers.js delete mode 100644 src/server/websocket/athena/index.js delete mode 100644 src/server/websocket/index.js delete mode 100644 src/server/websocket/web/commands.js delete mode 100644 src/server/websocket/web/controls.js delete mode 100644 src/server/websocket/web/index.js diff --git a/.env.sample b/.env.sample index 0e75b4b..d3be20f 100644 --- a/.env.sample +++ b/.env.sample @@ -48,14 +48,3 @@ USE_USER_ADMIN_API=0 CLIENT_SOCKET_PORT=81 CLIENT_SOCKET_HOST="0.0.0.0" - -# Enables Athena service -ATHENA_ENABLED=1 -# Disables crypto on Websocket server - use for testing on local network, change ATHENA_HOST in openpilot to ws:// instead of wss:// -ATHENA_SECURE=1 -# Maxmium hits to /realtime/* per 30s -ATHENA_API_RATE_LIMIT=100 -ATHENA_SOCKET_HOST="0.0.0.0" -ATHENA_SOCKET_PORT=4040 -# Higher the number = lower traffic, varies on how many devices are connected -ATHENA_SOCKET_HEARTBEAT_FREQ=5000 diff --git a/environment/development/.env.sample b/environment/development/.env.sample index c895dd5..515b57e 100644 --- a/environment/development/.env.sample +++ b/environment/development/.env.sample @@ -48,14 +48,3 @@ USE_USER_ADMIN_API=0 CLIENT_SOCKET_PORT=81 CLIENT_SOCKET_HOST="0.0.0.0" - -# Enables Athena service -ATHENA_ENABLED=1 -# Disables crypto on Websocket server - use for testing on local network, change ATHENA_HOST in openpilot to ws:// instead of wss:// -ATHENA_SECURE=1 -# Maxmium hits to /realtime/* per 30s -ATHENA_API_RATE_LIMIT=100 -ATHENA_SOCKET_HOST="0.0.0.0" -ATHENA_SOCKET_PORT=4040 -# Higher the number = lower traffic, varies on how many devices are connected -ATHENA_SOCKET_HEARTBEAT_FREQ=5000 diff --git a/environment/uat/.env.sample b/environment/uat/.env.sample index e2e8126..784c944 100644 --- a/environment/uat/.env.sample +++ b/environment/uat/.env.sample @@ -48,14 +48,3 @@ USE_USER_ADMIN_API=0 CLIENT_SOCKET_PORT=81 CLIENT_SOCKET_HOST="0.0.0.0" - -# Enables Athena service -ATHENA_ENABLED=1 -# Disables crypto on Websocket server - use for testing on local network, change ATHENA_HOST in openpilot to ws:// instead of wss:// -ATHENA_SECURE=1 -# Maxmium hits to /realtime/* per 30s -ATHENA_API_RATE_LIMIT=100 -ATHENA_SOCKET_HOST="0.0.0.0" -ATHENA_SOCKET_PORT=4040 -# Higher the number = lower traffic, varies on how many devices are connected -ATHENA_SOCKET_HEARTBEAT_FREQ=5000 diff --git a/environment/uat/docker-compose.yml b/environment/uat/docker-compose.yml index 97140f2..ec6efd7 100644 --- a/environment/uat/docker-compose.yml +++ b/environment/uat/docker-compose.yml @@ -57,15 +57,6 @@ services: - "traefik.http.routers.api.tls=true" - "traefik.http.routers.api.tls.certresolver=retropilot" - # Athena service forwards requests to container port 4040 - - "traefik.http.services.athena.loadbalancer.server.port=4040" - # Expose athena at https://uat.athena.retropilot.org - - "traefik.http.routers.athena.rule=Host(`athena.uat.retropilot.org`)" - - "traefik.http.routers.athena.entrypoints=websecure" - - "traefik.http.routers.athena.service=athena@docker" - - "traefik.http.routers.athena.tls=true" - - "traefik.http.routers.athena.tls.certresolver=retropilot" - # Monitor for image updates and restart automatically - "com.centurylinklabs.watchtower.enable=true" diff --git a/src/server/router/api/admin.js b/src/server/router/api/admin.js index 9119289..b1faeb2 100644 --- a/src/server/router/api/admin.js +++ b/src/server/router/api/admin.js @@ -95,10 +95,4 @@ router.get('/device/:dongle_id/ignore/:ignore_uploads', runAsyncWrapper(async (r return res.status(200).json({ success: true }); })); -router.get('/device/:dongle_id/athena/reboot', runAsyncWrapper(async (req, res) => { - const { dongle_id: dongleId } = req.params; - req.athenaWebsocketTemp.rebootDevice(dongleId); - res.send('ok'); -})); - export default router; diff --git a/src/server/router/api/index.js b/src/server/router/api/index.js index cef784c..5491bd8 100644 --- a/src/server/router/api/index.js +++ b/src/server/router/api/index.js @@ -1,17 +1,11 @@ import express from 'express'; -import rateLimit from 'express-rate-limit'; import log4js from 'log4js'; -import athena from '../../websocket/athena'; - import admin from './admin'; import auth from './auth'; import devices from './devices'; -import realtime from './realtime'; import useradmin from './useradmin'; -const logger = log4js.getLogger(); - // /api const router = express.Router(); @@ -23,23 +17,4 @@ router.use('/useradmin', useradmin); // TODO: setup oauth and twofactor endpoints // app.use(routers.oauthAuthenticator); -if (process.env.ATHENA_ENABLED) { - logger.info('Athena enabled'); - - const athenaRateLimit = rateLimit({ - windowMs: 30000, - max: process.env.ATHENA_API_RATE_LIMIT, - }); - - router.use((req, res, next) => { - req.athenaWebsocketTemp = athena; - return next(); - }); - - router.use('/realtime', athenaRateLimit); - router.use('/realtime', realtime); -} else { - logger.info('Athena disabled'); -} - export default router; diff --git a/src/server/router/api/realtime.js b/src/server/router/api/realtime.js deleted file mode 100644 index e5b857f..0000000 --- a/src/server/router/api/realtime.js +++ /dev/null @@ -1,165 +0,0 @@ -import express from 'express'; - -import { AthenaReturnedData } from '../../../models'; -import authenticationController from '../../controllers/authentication'; -import deviceController from '../../controllers/devices'; -import { requireAuthenticated } from '../../middlewares/authentication'; - -// /api/realtime -const router = express.Router(); - -const whitelistParams = { - getmessage: true, - getversion: true, - setnavdestination: true, - listdatadirectory: true, - reboot: true, - uploadfiletourl: true, - listuploadqueue: true, - cancelupload: true, - primeactivated: true, - getpublickey: true, - getsshauthorizedkeys: true, - getsiminfo: true, - getnetworktype: true, - getnetworks: true, - takesnapshot: true, -}; - -// TODO: use middleware to get device from dongle id - -router.get('/:dongleId/connected', requireAuthenticated, async (req, res) => { - const { account, params: { dongleId } } = req; - - const device = await deviceController.getDeviceFromDongleId(dongleId); - if (!device) { - return res.status(400).json({ - error: true, - errorMsg: 'no_dongle', - errorObject: { authenticated: true, dongle_exists: false }, - }); - } - - // TODO support delegation of access - // TODO remove indication of dongle existing - if (device.account_id !== account.id) { - return res.status(403).json({ - error: true, - errorMsg: 'unauthorised', - errorObject: { authenticated: true, dongle_exists: true, authorised_user: false }, - }); - } - - // eslint-disable-next-line max-len - const isConnected = await req.athenaWebsocketTemp.isDeviceConnected(account.id, device.id, dongleId); - - return res.status(200).json({ - success: true, - dongle_id: device.dongle_id, - data: isConnected, - }); -}); - -// TODO: change to POST request -router.get('/:dongleId/send/:method/', requireAuthenticated, async (req, res) => { - const { account, params: { dongleId, method } } = req; - - if (!whitelistParams[method.toLowerCase()]) { - return res.status(409).json({ - error: true, - errorMsg: 'invalid_method', - errorObject: { method }, - }); - } - - const device = await deviceController.getDeviceFromDongleId(dongleId); - if (!device) { - return res.status(400).json({ - error: true, - errorMsg: 'no_dongle', - errorObject: { authenticated: true, dongle_exists: false }, - }); - } - - // TODO support delegation of access - // TODO remove indication of dongle existing - if (device.account_id !== account.id) { - return res.status(403).json({ - error: true, - errorMsg: 'unauthorised', - errorObject: { authenticated: true, dongle_exists: true, authorised_user: false }, - }); - } - - const data = await req.athenaWebsocketTemp.invoke(method, null, dongleId, account.id); - - return res.status(200).json({ - success: true, - dongle_id: dongleId, - method, - data, - }); -}); - -router.get('/:dongle_id/get', async (req, res) => { - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.status(403).json({ - error: true, - errorMsg: 'Unauthenticated', - errorObject: { authenticated: false }, - }); - } - const device = await deviceController.getDeviceFromDongleId(req.params.dongle_id); - if (!device) { - return res.status(400).json({ - error: true, - errorMsg: 'no_dongle', - errorObject: { - authenticated: true, - dongle_exists: false, - }, - }); - } - if (device.account_id !== account.id) { - return res.status(403).json({ - error: true, - errorMsg: 'unauthorised', - errorObject: { - authenticated: true, - dongle_exists: true, - authorised_user: false, - }, - }); - } - - return res.json(await AthenaReturnedData.findAll({ - where: { device_id: device.id }, - })); -}); - -// TODO: change to POST request -router.get('/:dongle_id/temp/nav/:lat/:long', async (req, res) => { - if (!req.params.lat || !req.params.long) { - return res.status(403).json({ error: true, errorMsg: 'Malformed_Request', errorObject: { malformed: true } }); - } - const account = await authenticationController.getAuthenticatedAccount(req); - if (account == null) { - return res.status(403).json({ error: true, errorMsg: 'Unauthenticated', errorObject: { authenticated: false } }); - } - const device = await deviceController.getDeviceFromDongleId(req.params.dongle_id); - if (!device) { - return res.status(400).json({ error: true, errorMsg: 'no_dongle', errorObject: { authenticated: true, dongle_exists: false } }); - } - if (device.account_id !== account.id) { - return res.status(403).json({ error: true, errorMsg: 'unauthorised', errorObject: { authenticated: true, dongle_exists: true, authorised_user: false } }); - } - - const data = await req.athenaWebsocketTemp.invoke('setNavDestination', { latitude: req.params.lat, longitude: req.params.long }, device.dongle_id, account.id); - - return res.status(200).json({ - success: true, dongle_id: device.dongle_id, method: req.params.method, data, - }); -}); - -export default router; diff --git a/src/server/websocket/athena/helpers.js b/src/server/websocket/athena/helpers.js deleted file mode 100644 index b8a9d58..0000000 --- a/src/server/websocket/athena/helpers.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import { v4 as uuid } from 'uuid'; - -import { AthenaReturnedData } from '../../../models'; - -let realtime; -let wss; - -async function incoming(ws, res, msg) { - return realtime.passData(ws.dongleId, msg); -} - -async function deviceStatus(dongleId, status) { - return realtime.dongleStatus(dongleId, status); -} - -function invoke(command, params, dongleId, accountId, id) { - const websocket = wss.retropilotFunc.findFromDongle(dongleId); - - if (!websocket) { - wss.retropilotFunc.actionLogger(accountId, null, 'ATHENA_USER_INVOKE__FAILED_DISCONNECTED', null, null, null, dongleId); - return { connected: false }; - } - - let uniqueID; - - if (!id) { - uniqueID = uuid(); - } else { - uniqueID = id; - } - - wss.retropilotFunc.actionLogger(accountId, websocket.device_id, 'ATHENA_USER_INVOKE__ISSUED', null, websocket._socket.remoteAddress, JSON.stringify({ command, params, uniqueID }), websocket.dongleId); - - AthenaReturnedData.create({ - device_id: websocket.device_id, - type: command, - created_at: Date.now(), - uuid: uniqueID, - }); - - websocket.send(JSON.stringify(wss.retropilotFunc.commandBuilder(command, params, uniqueID))); - - return { dispatched: true, heartbeat: websocket.heartbeat, id: uniqueID }; -} - -function isDeviceConnected(accountId, deviceId, dongleId) { - const websocket = wss.retropilotFunc.findFromDongle(dongleId); - wss.retropilotFunc.actionLogger(accountId, deviceId, 'ATHENA_USER_STATUS__IS_CONNECTED', null, websocket ? websocket._socket.remoteAddress : null, JSON.stringify({ connected: !!websocket, heartbeat: websocket ? websocket.heartbeat : null }), dongleId); - - if (!websocket) { - return { connected: false }; - } - - return { connected: true, heartbeat: websocket.heartbeat }; -} - -async function realtimeCallback(callback) { - realtime = callback; -} - -export default (websocketServer) => { - wss = websocketServer; - - return { - isDeviceConnected, - invoke, - incoming, - deviceStatus, - realtimeCallback, - }; -}; diff --git a/src/server/websocket/athena/index.js b/src/server/websocket/athena/index.js deleted file mode 100644 index 8146f46..0000000 --- a/src/server/websocket/athena/index.js +++ /dev/null @@ -1,180 +0,0 @@ -import cookie from 'cookie'; -import { readFileSync } from 'fs'; -import httpServer from 'http'; -import httpsServer from 'https'; -import jsonwebtoken from 'jsonwebtoken'; -import log4js from 'log4js'; -import { WebSocketServer } from 'ws'; - -import { AthenaActionLog, AthenaReturnedData } from '../../../models'; -import deviceController from '../../controllers/devices'; -import helperFunctions from './helpers'; - -const logger = log4js.getLogger(); - -// TODO: I think we need to provide wss as a param here -const helpers = helperFunctions(); - -let wss; - -function __server() { - let server; - - if (process.env.ATHENA_SECURE && process.env.SSL_CRT) { - server = httpsServer.createServer({ - cert: readFileSync(process.env.SSL_CRT), - key: readFileSync(process.env.SSL_KEY), - }); - } else { - server = httpServer.createServer(); - } - - wss = new WebSocketServer({ server }, { path: '/ws/v2/', handshakeTimeout: 500 }); - - const interval = setInterval(() => { - wss.clients.forEach((ws) => { - if (ws.isAlive === false) { - logger.info(`Athena(Heartbeat) - Terminated ${ws.dongleId} - ${ws._socket.remoteAddress}`); - wss.retropilotFunc.actionLogger(null, null, 'ATHENA_DEVICE_TIMEOUT_FORCE_DISCONNECT', null, ws._socket.remoteAddress, null, ws.dongleId); - if (ws.dongleId) { - helpers.deviceStatus(ws.dongleId, false); - } - - ws.terminate(); - return; - } - - ws.isAlive = false; - ws.ping(); - }); - }, process.env.ATHENA_SOCKET_HEARTBEAT_FREQ ? process.env.ATHENA_SOCKET_HEARTBEAT_FREQ : 5000); - - server.listen(process.env.ATHENA_SOCKET_PORT, () => { - logger.info(`Athena(Server) - UP @ ${process.env.ATHENA_SOCKET_HOST}:${process.env.ATHENA_SOCKET_PORT}`); - }); - - wss.on('connection', manageConnection); - wss.on('close', () => { - logger.info('Athena(Websocket) - DOWN'); - clearInterval(interval); - }); -} - -async function heartbeat() { - this.isAlive = true; - this.heartbeat = Date.now(); - if (this.dongleId) { - helpers.deviceStatus(this.dongleId, true); - } -} - -async function manageConnection(ws, res) { - logger.info(`Athena(Websocket) - New Connection ${ws._socket.remoteAddress}`); - ws.badMessages = 0; - ws.isAlive = true; - ws.heartbeat = Date.now(); - ws.on('pong', heartbeat); - - const cookies = cookie.parse(res.headers.cookie); - - ws.on('message', async (message) => { - heartbeat.call(ws); - if (!ws.dongleId) { - wss.retropilotFunc.actionLogger(null, null, 'ATHENA_DEVICE_UNAUTHENTICATED_MESSAGE', null, ws._socket.remoteAddress, JSON.stringify([message]), ws.dongleId); - console.log('unauthenticated message, discarded'); - return; - } - - const json = JSON.parse(message.toString('utf8')); - console.log(json); - - console.log({ device_id: ws.device_id, uuid: json.id }); - - console.log(await AthenaReturnedData.update({ - data: JSON.stringify(json), - resolved_at: Date.now(), - }, { where: { device_id: ws.device_id, uuid: json.id } })); - - wss.retropilotFunc.actionLogger(null, null, 'ATHENA_DEVICE_MESSAGE_UNKNOWN', null, ws._socket.remoteAddress, JSON.stringify([message]), ws.dongleId); - - console.log(json); - - helpers.incoming(ws, res, json); - }); - - if (await wss.retropilotFunc.authenticateDongle(ws, res, cookies) === false) { - ws.terminate(); - } - - // ws.send(JSON.stringify(await commandBuilder('reboot'))) -} - -__server(); - -wss.retropilotFunc = { - findFromDongle: (dongleId) => { - let websocket = null; - wss.clients.forEach((value) => { - if (value.dongleId === dongleId) { - websocket = value; - } - }); - - return websocket; - }, - - authenticateDongle: async (ws, res, cookies) => { - let unsafeJwt; - - try { - unsafeJwt = jsonwebtoken.decode(cookies.jwt); - } catch (e) { - logger.info(`Athena(Websocket) - AUTHENTICATION FAILED (INVALID JWT) IP: ${ws._socket.remoteAddress}`); - wss.retropilotFunc.actionLogger(null, null, 'ATHENA_DEVICE_AUTHENTICATE_INVALID', null, ws._socket.remoteAddress, JSON.stringify({ jwt: cookies.jwt }), null); - return false; - } - - const device = await deviceController.getDeviceFromDongleId(unsafeJwt.identity); - - let verifiedJWT; - console.log('JWT', cookies.jwt); - try { - verifiedJWT = jsonwebtoken.verify(cookies.jwt, device.public_key, { ignoreNotBefore: true }); - } catch (err) { - logger.info(`Athena(Websocket) - AUTHENTICATION FAILED (BAD JWT, CHECK SIGNATURE) IP: ${ws._socket.remoteAddress}`); - wss.retropilotFunc.actionLogger(null, null, 'ATHENA_DEVICE_AUTHENTICATE_INVALID', null, ws._socket.remoteAddress, JSON.stringify({ jwt: cookies.jwt }), null); - return false; - } - - if (verifiedJWT.identify === unsafeJwt.identify) { - ws.dongleId = device.dongle_id; - ws.device_id = device.id; - wss.retropilotFunc.actionLogger(null, device.id, 'ATHENA_DEVICE_AUTHENTICATE_SUCCESS', null, ws._socket.remoteAddress, null); - logger.info(`Athena(Websocket) - AUTHENTICATED IP: ${ws._socket.remoteAddress} DONGLE ID: ${ws.dongleId} DEVICE ID: ${ws.device_id}`); - return true; - } - wss.retropilotFunc.actionLogger(null, device.id, 'ATHENA_DEVICE_AUTHENTICATE_FAILURE', null, ws._socket.remoteAddress, JSON.stringify({ jwt: cookies.jwt }), null); - logger.info(`Athena(Websocket) - AUTHENTICATION FAILED (BAD CREDENTIALS) IP: ${ws._socket.remoteAddress}`); - - return false; - }, - - commandBuilder: (method, params, id) => ({ - method, params, jsonrpc: '2.0', id, - }), - - actionLogger: async (accountId, deviceId, action, userIp, deviceIp, meta, dongleId) => { - await AthenaActionLog.create({ - account_id: accountId, - device_id: deviceId, - action, - user_ip: userIp, - device_ip: deviceIp, - meta, - created_at: Date.now(), - dongle_id: dongleId, - }); - }, -}; - -export default helpers; diff --git a/src/server/websocket/index.js b/src/server/websocket/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/server/websocket/web/commands.js b/src/server/websocket/web/commands.js deleted file mode 100644 index 5d91e14..0000000 --- a/src/server/websocket/web/commands.js +++ /dev/null @@ -1,65 +0,0 @@ -// eslint-disable-next-line no-unused-vars -import authenticationController from '../../controllers/authentication'; - -import deviceController from '../../controllers/devices'; -import athenaRealtime from '../athena'; - -// Checks if device is currently online in Athena - -async function isDongleOnline(ws, msg) { - // Checking if the user is authorised to access dongle, this will be used later - // allowing users to delegate access. - const isAuthorised = await deviceController.isUserAuthorised(ws.account.id, msg.data.dongleId); - if (isAuthorised && isAuthorised.success === true) { - ws.send(JSON.stringify({ - command: msg.command, - success: true, - id: msg.id || null, - data: athenaRealtime.isDeviceConnected(ws.account.id, null, msg.data.dongleId), - })); - } else { - ws.send(JSON.stringify({ - command: msg.command, success: false, id: msg.id || null, msg: 'not_authorised', - })); - } -} - -// Checks if device is currently online in Athena - -async function rebootDongle(ws, msg) { - // Checking if the user is authorised to access dongle, this will be used later - // allowing users to delegate access. - const isAuthorised = await deviceController.isUserAuthorised(ws.account.id, msg.data.dongleId); - console.log('is auth', isAuthorised); - if (isAuthorised && isAuthorised.success === true) { - await athenaRealtime.invoke('reboot', null, msg.data.dongleId, ws.account.id, msg.id || null); - ws.send(JSON.stringify({ - command: msg.command, success: true, id: msg.id || null, data: { command_issued: true }, - })); - } else { - ws.send(JSON.stringify({ - command: msg.command, success: false, id: msg.id || null, msg: 'not_authorised', - })); - } -} - -async function takeSnapshot(ws, msg) { - const isAuthorised = await deviceController.isUserAuthorised(ws.account.id, msg.data.dongleId); - console.log('is auth', isAuthorised); - if (isAuthorised && isAuthorised.success === true) { - await athenaRealtime.invoke('takeSnapshot', null, msg.data.dongleId, ws.account.id, msg.id || null); - ws.send(JSON.stringify({ - command: msg.command, success: true, id: msg.id || null, data: { command_issued: true }, - })); - } else { - ws.send(JSON.stringify({ - command: msg.command, success: false, id: msg.id || null, msg: 'not_authorised', - })); - } -} - -export default { - isDongleOnline, - rebootDongle, - takeSnapshot, -}; diff --git a/src/server/websocket/web/controls.js b/src/server/websocket/web/controls.js deleted file mode 100644 index 54e5a4e..0000000 --- a/src/server/websocket/web/controls.js +++ /dev/null @@ -1,55 +0,0 @@ -import deviceController from '../../controllers/devices'; - -let wss; - -async function getDongleOwners(dongleId) { - const owners = await deviceController.getOwnersFromDongle(dongleId); - console.log('dongle owners', owners); - return owners; -} - -async function broadcastToAccounts(owners, data) { - wss.clients.forEach((ws) => { - owners.data.forEach((accountId) => { - if (accountId === ws.account.id) { - ws.send(JSON.stringify(data)); - } - }); - }); -} - -async function dongleStatus(dongleId, status) { - const owners = await getDongleOwners(dongleId); - await broadcastToAccounts(owners, { - command: 'dongle_status', - id: Date.now(), - data: { - dongle_id: dongleId, - online: status, - time: Date.now(), - }, - }); -} - -async function passData(dongleId, msg) { - const owners = await getDongleOwners(dongleId); - await broadcastToAccounts(owners, { - command: 'data_return', - id: msg.id, - data: { - dongle_id: dongleId, - return: msg, - }, - }); - return true; -} - -export default (websocket) => { - wss = websocket; - - return { - getDongleOwners, - dongleStatus, - passData, - }; -}; diff --git a/src/server/websocket/web/index.js b/src/server/websocket/web/index.js deleted file mode 100644 index b4bbeff..0000000 --- a/src/server/websocket/web/index.js +++ /dev/null @@ -1,102 +0,0 @@ -import { WebSocketServer } from 'ws'; -import cookie from 'cookie'; -import httpServer from 'http'; -import log4js from 'log4js'; -import authenticationController from '../../controllers/authentication'; -import athenaRealtime from '../athena'; - -import controlsFunction from './controls'; -import realtimeCommands from './commands'; - -const logger = log4js.getLogger(); - -let server; -let wss; - -// eslint-disable-next-line no-underscore-dangle -function __server() { - server = httpServer.createServer(); - - wss = new WebSocketServer({ server }, { path: '/realtime/v1', handshakeTimeout: 500 }); - - server.listen(process.env.CLIENT_SOCKET_PORT, process.env.CLIENT_SOCKET_HOST, () => { - logger.info(`Web(Server) - UP @ ${process.env.CLIENT_SOCKET_HOST}:${process.env.CLIENT_SOCKET_PORT}`); - }); - - wss.on('connection', manageConnection); - wss.on('close', () => { - logger.info('Web(Websocket) - DOWN'); - }); - return wss; -} - -// eslint-disable-next-line no-unused-vars -function buildResponse(ws, success, msg, data) { - ws.send(JSON.stringify({ - success, msg, data, timestamp: Date.now(), - })); -} - -async function authenticateUser(ws, req) { - // if (req.headers.Authorization) { - // account = await authenticationController.getAccountFromJWT(req.headers.Authorization) - // } - - if (!req.headers.cookie) { - // TODO: send error - ws.terminate(); - return false; - } - - const cookies = cookie.parse(req.headers.cookie); - if (!cookies.jwt) { - // TODO: send error - ws.terminate(); - return false; - } - - const account = await authenticationController.getAccountFromJWT(cookies.jwt); - if (!account) { - // TODO: send error - ws.terminate(); - return false; - } - - ws.account = account; - return true; -} - -async function manageConnection(ws, req) { - logger.info(`Web(Websocket) - New Connection ${ws._socket.remoteAddress}`); - - await authenticateUser(ws, req); - - console.log(ws.account); - - ws.on('message', async (message) => { - console.log(message); - const msg = JSON.parse(message.toString('utf8')); - - switch (msg.command) { - case 'is_dongle_online': - return realtimeCommands.isDongleOnline(ws, msg); - case 'reboot_dongle': - return realtimeCommands.rebootDongle(ws, msg); - case 'take_snapshot': - return realtimeCommands.takeSnapshot(ws, msg); - default: - return ws.send(JSON.stringify({ - error: true, id: msg.id || null, msg: 'VERIFY_DATA', data: { msg }, - })); - } - }); - - return wss; - - // ws.send(JSON.stringify(await commandBuilder('reboot'))) -} - -export const websocketServer = __server(); -export const controls = controlsFunction(websocketServer); - -athenaRealtime.realtimeCallback(controls);