spring cleaning
parent
43a71d3aad
commit
5e6d0dbcf5
|
@ -8,6 +8,7 @@ DB_HOST=db # If using docker compose, this should match the container service na
|
|||
DB_PORT=5432
|
||||
DB_FORCE_SYNC=false # Whether or not to DROP all tables and recreate to match the current models
|
||||
ALLOW_REGISTRATION=true
|
||||
AUTH_2FA_ISSUER=RetroPilot
|
||||
HTTP_INTERFACE=0.0.0.0
|
||||
HTTP_PORT=3000
|
||||
CAN_SEND_MAIL=true # Set to false to skip sending mail, all attempted mail is logged under DEBUG
|
||||
|
|
|
@ -5,12 +5,17 @@
|
|||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"browser": false // do we need this? none of this code will ever run on a browswer
|
||||
"browser": false // do we need this? none of this code will ever run on a browswer
|
||||
},
|
||||
"plugins": [
|
||||
"no-floating-promise"
|
||||
],
|
||||
"rules": {
|
||||
// enforces no braces where they can be omitted
|
||||
// https://eslint.org/docs/rules/arrow-body-style
|
||||
// retropilot: this seems dumb. do whatever looks nice.
|
||||
"arrow-body-style": "off",
|
||||
|
||||
// disallow use of unary operators, ++ and --
|
||||
// http://eslint.org/docs/rules/no-plusplus
|
||||
// retropilot: we allow them in the for loop
|
||||
|
|
|
@ -6,10 +6,9 @@ WORKDIR /app
|
|||
# Install app dependencies
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
RUN npm install pm2 -g
|
||||
|
||||
# Bundle app source
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["pm2-runtime", "ecosystem.config.js"]
|
||||
CMD ["node", "-r", "esm", "server.js"]
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
import crypto from 'crypto';
|
||||
import jsonwebtoken from 'jsonwebtoken';
|
||||
import log4js from 'log4js';
|
||||
import orm from '../models/index.model';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
|
||||
async function validateJWT(token, key) {
|
||||
try {
|
||||
return jsonwebtoken.verify(token.replace('JWT ', ''), key, { algorithms: ['RS256'], ignoreNotBefore: true });
|
||||
} catch (exception) {
|
||||
logger.warn(`failed to validate JWT ${exception}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function readJWT(token) {
|
||||
try {
|
||||
return jsonwebtoken.decode(token);
|
||||
} catch (exception) {
|
||||
logger.warn(`failed to read JWT ${exception}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function signIn(email, password) {
|
||||
let account = await orm.models.accounts.findOne({ where: { email } });
|
||||
|
||||
if (account && account.dataValues) {
|
||||
account = account.dataValues;
|
||||
const inputPassword = crypto.createHash('sha256').update(password + process.env.APP_SALT).digest('hex');
|
||||
if (account.password === inputPassword) {
|
||||
const token = jsonwebtoken.sign({ accountId: account.id }, process.env.APP_SALT);
|
||||
|
||||
return { success: true, jwt: token };
|
||||
}
|
||||
return { success: false, msg: 'BAD PASSWORD', invalidPassword: true };
|
||||
}
|
||||
return { success: false, msg: 'BAD ACCOUNT', badAccount: true };
|
||||
}
|
||||
|
||||
async function changePassword(account, newPassword, oldPassword) {
|
||||
if (!account || !newPassword || !oldPassword) {
|
||||
return { success: false, error: 'MISSING_DATA' };
|
||||
}
|
||||
const oldPasswordHash = crypto.createHash('sha256').update(oldPassword + process.env.APP_SALT).digest('hex');
|
||||
|
||||
if (account.password === oldPasswordHash) {
|
||||
const newPasswordHash = crypto.createHash('sha256').update(newPassword + process.env.APP_SALT).digest('hex');
|
||||
|
||||
await orm.models.accounts.update(
|
||||
{ password: newPasswordHash },
|
||||
{ where: { id: account.id } },
|
||||
);
|
||||
|
||||
return { success: true, msg: 'PASSWORD CHANGED', changed: true };
|
||||
}
|
||||
return { success: false, msg: 'BAD PASSWORD', passwordCorrect: false };
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: update rest of the code to support authentication rejection reasons
|
||||
*/
|
||||
|
||||
async function getAuthenticatedAccount(req) {
|
||||
const sessionJWT = req.cookies.jwt;
|
||||
if ((!sessionJWT || sessionJWT.expires <= Date.now())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getAccountFromJWT(sessionJWT);
|
||||
}
|
||||
|
||||
async function getAccountFromJWT(jwt, limitData) {
|
||||
let token;
|
||||
|
||||
try {
|
||||
token = jsonwebtoken.verify(jwt, process.env.APP_SALT);
|
||||
} catch (err) {
|
||||
return null;// {success: false, msg: 'BAD_JWT'}
|
||||
}
|
||||
|
||||
if (!token || !token.accountId) {
|
||||
return null; // {success: false, badToken: true}
|
||||
}
|
||||
|
||||
let query = { where: { id: token.accountId } };
|
||||
if (limitData) {
|
||||
query = { ...query, attributes: { exclude: ['password', '2fa_token', 'session_seed'] } };
|
||||
}
|
||||
|
||||
const account = await orm.models.accounts.findOne(query);
|
||||
if (!account.dataValues) {
|
||||
return null; // {success: false, isInvalid: true}
|
||||
}
|
||||
|
||||
try {
|
||||
await orm.models.accounts.update(
|
||||
{ last_ping: Date.now() },
|
||||
{ where: { id: account.id } },
|
||||
);
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
if (!account || account.banned) {
|
||||
return null; // {success: false, isBanned: true}
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
export default {
|
||||
validateJWT,
|
||||
getAuthenticatedAccount,
|
||||
changePassword,
|
||||
signIn,
|
||||
readJWT,
|
||||
getAccountFromJWT,
|
||||
};
|
|
@ -0,0 +1,119 @@
|
|||
import crypto from 'crypto';
|
||||
import jsonwebtoken from 'jsonwebtoken';
|
||||
import log4js from 'log4js';
|
||||
import orm from '../../models/index.model';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
|
||||
export async function validateJWT(token, key) {
|
||||
try {
|
||||
return jsonwebtoken.verify(token.replace('JWT ', ''), key, { algorithms: ['RS256'], ignoreNotBefore: true });
|
||||
} catch (exception) {
|
||||
logger.warn(`failed to validate JWT ${exception}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function readJWT(token) {
|
||||
try {
|
||||
return jsonwebtoken.decode(token);
|
||||
} catch (exception) {
|
||||
logger.warn(`failed to read JWT ${exception}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function signIn(email, password) {
|
||||
let account = await orm.models.accounts.findOne({ where: { email } });
|
||||
|
||||
if (account && account.dataValues) {
|
||||
account = account.dataValues;
|
||||
const inputPassword = crypto.createHash('sha256').update(password + process.env.APP_SALT).digest('hex');
|
||||
if (account.password === inputPassword) {
|
||||
const token = jsonwebtoken.sign({ accountId: account.id }, process.env.APP_SALT);
|
||||
|
||||
return { success: true, jwt: token };
|
||||
}
|
||||
return { success: false, msg: 'BAD PASSWORD', invalidPassword: true };
|
||||
}
|
||||
return { success: false, msg: 'BAD ACCOUNT', badAccount: true };
|
||||
}
|
||||
|
||||
async function changePassword(account, newPassword, oldPassword) {
|
||||
if (!account || !newPassword || !oldPassword) {
|
||||
return { success: false, error: 'MISSING_DATA' };
|
||||
}
|
||||
const oldPasswordHash = crypto.createHash('sha256').update(oldPassword + process.env.APP_SALT).digest('hex');
|
||||
|
||||
if (account.password === oldPasswordHash) {
|
||||
const newPasswordHash = crypto.createHash('sha256').update(newPassword + process.env.APP_SALT).digest('hex');
|
||||
|
||||
await orm.models.accounts.update(
|
||||
{ password: newPasswordHash },
|
||||
{ where: { id: account.id } },
|
||||
);
|
||||
|
||||
return { success: true, msg: 'PASSWORD CHANGED', changed: true };
|
||||
}
|
||||
return { success: false, msg: 'BAD PASSWORD', passwordCorrect: false };
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: update rest of the code to support authentication rejection reasons
|
||||
*/
|
||||
|
||||
async function getAuthenticatedAccount(req) {
|
||||
const sessionJWT = req.cookies.jwt;
|
||||
if ((!sessionJWT || sessionJWT.expires <= Date.now())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getAccountFromJWT(sessionJWT);
|
||||
}
|
||||
|
||||
async function getAccountFromJWT(jwt, limitData) {
|
||||
let token;
|
||||
|
||||
try {
|
||||
token = jsonwebtoken.verify(jwt, process.env.APP_SALT);
|
||||
} catch (err) {
|
||||
return null;// {success: false, msg: 'BAD_JWT'}
|
||||
}
|
||||
|
||||
if (!token || !token.accountId) {
|
||||
return null; // {success: false, badToken: true}
|
||||
}
|
||||
|
||||
let query = { where: { id: token.accountId } };
|
||||
if (limitData) {
|
||||
query = { ...query, attributes: { exclude: ['password', '2fa_token', 'session_seed'] } };
|
||||
}
|
||||
|
||||
const account = await orm.models.accounts.findOne(query);
|
||||
if (!account.dataValues) {
|
||||
return null; // {success: false, isInvalid: true}
|
||||
}
|
||||
|
||||
try {
|
||||
await orm.models.accounts.update(
|
||||
{ last_ping: Date.now() },
|
||||
{ where: { id: account.id } },
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
if (!account || account.banned) {
|
||||
return null; // {success: false, isBanned: true}
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
export default {
|
||||
validateJWT,
|
||||
getAuthenticatedAccount,
|
||||
changePassword,
|
||||
signIn,
|
||||
readJWT,
|
||||
getAccountFromJWT,
|
||||
};
|
|
@ -1 +1 @@
|
|||
//empty
|
||||
// empty
|
||||
|
|
|
@ -7,6 +7,9 @@ export function oauthRegister(email) {
|
|||
const account = getAccountFromEmail(email);
|
||||
|
||||
if (account) return { error: true, ...AUTH_REGISTER_ALREADY_REGISTERED };
|
||||
|
||||
// TODO: finish
|
||||
return { error: false };
|
||||
}
|
||||
|
||||
export default function register() {
|
||||
|
|
|
@ -12,7 +12,7 @@ export async function twoFactorOnboard(account) {
|
|||
if (!account || !account.dataValues) { return { success: false, ...AUTH_2FA_BAD_ACCOUNT }; }
|
||||
if (account['2fa_token'] !== null) return { success: false, ...AUTH_2FA_ONBOARD_ALREADY_ENROLLED };
|
||||
|
||||
const token = await generateSecret(account.email, config.enterprise.name);
|
||||
const token = await generateSecret(account.email, process.env.AUTH_2FA_ISSUER);
|
||||
|
||||
orm.models.account.update(
|
||||
{ '2fa_token': token.secret },
|
||||
|
|
|
@ -2,9 +2,10 @@ import sanitizeFactory from 'sanitize';
|
|||
import crypto from 'crypto';
|
||||
import dirTree from 'directory-tree';
|
||||
import log4js from 'log4js';
|
||||
import authenticationController from './authentication';
|
||||
import orm from '../models/index.model';
|
||||
import usersController from './users';
|
||||
|
||||
import { readJWT, validateJWT } from './authentication';
|
||||
import { getAccountFromId } from './users';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
const sanitize = sanitizeFactory();
|
||||
|
@ -25,7 +26,7 @@ async function pairDevice(account, qrString) {
|
|||
device = await orm.models.device.findOne({ where: { serial } });
|
||||
pairJWT = pairToken;
|
||||
} else {
|
||||
const data = await authenticationController.readJWT(qrString);
|
||||
const data = await readJWT(qrString);
|
||||
if (!data || !data.pair) {
|
||||
return { success: false, noPair: true };
|
||||
}
|
||||
|
@ -33,11 +34,11 @@ async function pairDevice(account, qrString) {
|
|||
pairJWT = qrString;
|
||||
}
|
||||
|
||||
if (deviceQuery == null || !deviceQuery.dataValues) {
|
||||
if (device == null || !device.dataValues) {
|
||||
return { success: false, registered: false, noPair: true };
|
||||
}
|
||||
|
||||
const decoded = await authenticationController.validateJWT(pairJWT, device.public_key);
|
||||
const decoded = await validateJWT(pairJWT, device.public_key);
|
||||
if (decoded == null || !decoded.pair) {
|
||||
return { success: false, badToken: true };
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ async function isUserAuthorised(accountId, dongleId) {
|
|||
return { success: false, msg: 'bad_data' };
|
||||
}
|
||||
|
||||
const account = await usersController.getAccountFromId(accountId);
|
||||
const account = await getAccountFromId(accountId);
|
||||
if (!account || !account.dataValues) {
|
||||
return { success: false, msg: 'bad_account', data: { authorised: false, account_id: accountId } };
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ function simpleStringify(object) {
|
|||
}
|
||||
|
||||
function formatDate(timestampMs) {
|
||||
return new Date(parseInt(timestampMs)).toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
||||
return new Date(parseInt(timestampMs, 10)).toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -6,6 +6,7 @@ import mailing from './mailing';
|
|||
import users from './users';
|
||||
import admin from './admin';
|
||||
import devices from './devices';
|
||||
|
||||
// TO DO, finish up removing this callback stuff
|
||||
export default {
|
||||
authentication,
|
||||
|
|
|
@ -3,6 +3,7 @@ import log4js from 'log4js';
|
|||
import orm from '../models/index.model';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
|
||||
export async function getAccountFromId(id) {
|
||||
return orm.models.accounts.findByPk(id);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,14 @@ services:
|
|||
ports:
|
||||
- "3000:3000"
|
||||
- "4040:4040"
|
||||
worker:
|
||||
build: .
|
||||
command: node -r esm worker.js
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
volumes:
|
||||
- ./:/app
|
||||
db:
|
||||
image: postgres:14-bullseye
|
||||
restart: always
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { DataTypes } from 'sequelize';
|
||||
|
||||
export default (sequelize) => {
|
||||
sequelize.define('athena_returned_data',
|
||||
sequelize.define(
|
||||
'athena_returned_data',
|
||||
{
|
||||
id: {
|
||||
allowNull: false,
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
/* eslint-disable global-require */
|
||||
|
||||
import { Sequelize } from 'sequelize';
|
||||
import devices from './devices.model';
|
||||
import drives from './drives.model';
|
||||
import accounts from './accounts.model';
|
||||
import athena_action_log from './athena_action_log.model';
|
||||
import athena_returned_data from './athena_returned_data.model';
|
||||
import device_authorised_users from './device_authorised_users.model';
|
||||
import drive_segments from './drive_segments.model';
|
||||
import oauth_accounts from './oauth_accounts';
|
||||
|
||||
const sequelize = new Sequelize({
|
||||
username: process.env.DB_USER,
|
||||
|
@ -23,14 +15,14 @@ const sequelize = new Sequelize({
|
|||
sequelize.options.logging = () => {};
|
||||
|
||||
const modelDefiners = [
|
||||
devices,
|
||||
drives,
|
||||
accounts,
|
||||
athena_action_log,
|
||||
athena_returned_data,
|
||||
device_authorised_users,
|
||||
drive_segments,
|
||||
oauth_accounts,
|
||||
require('./devices.model').default,
|
||||
require('./drives.model').default,
|
||||
require('./accounts.model').default,
|
||||
require('./athena_action_log.model').default,
|
||||
require('./athena_returned_data.model').default,
|
||||
require('./device_authorised_users.model').default,
|
||||
require('./drive_segments.model').default,
|
||||
require('./oauth_accounts.model').default,
|
||||
];
|
||||
|
||||
for (const modelDefiner of modelDefiners) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,8 @@
|
|||
import express from 'express';
|
||||
import log4js from 'log4js';
|
||||
|
||||
import { getURL, getToken } from '../../../controllers/authentication/oauth/google';
|
||||
import authenticationController from '../../../controllers/authentication';
|
||||
import log4js from 'log4js';
|
||||
|
||||
const router = express.Router();
|
||||
const logger = log4js.getLogger('default');
|
||||
|
|
|
@ -22,7 +22,7 @@ async function isAuthenticated(req, res, next) {
|
|||
}
|
||||
|
||||
router.get('/authentication/twofactor/enrol', isAuthenticated, async (req, res) => {
|
||||
|
||||
// TODO: implementation
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import express from 'express';
|
||||
import bodyParser from 'body-parser';
|
||||
import crypto from 'crypto';
|
||||
import dirTree from 'directory-tree';
|
||||
import bodyParser from 'body-parser';
|
||||
import deviceSchema from '../../schema/routes/devices';
|
||||
import express from 'express';
|
||||
import log4js from 'log4js';
|
||||
|
||||
import deviceController from '../../controllers/devices';
|
||||
import authenticationController from '../../controllers/authentication';
|
||||
import deviceController from '../../controllers/devices';
|
||||
import { MutateDevice } from '../../schema/routes/devices';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
async function isAuthenticated(req, res, next) {
|
||||
const account = await authenticationController.getAuthenticatedAccount(req);
|
||||
|
||||
|
@ -34,18 +35,17 @@ router.get('/retropilot/0/devices', isAuthenticated, async (req, res) => {
|
|||
|
||||
/*
|
||||
{
|
||||
version: "1.0"
|
||||
2fa: {
|
||||
tokenProvided: false,
|
||||
token: 000000
|
||||
unixTime: 00000
|
||||
},
|
||||
modifications: {
|
||||
nicname: x
|
||||
publicKey: x
|
||||
}
|
||||
version: "1.0"
|
||||
2fa: {
|
||||
tokenProvided: false,
|
||||
token: 000000
|
||||
unixTime: 00000
|
||||
},
|
||||
modifications: {
|
||||
nicname: x
|
||||
publicKey: x
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
router.put('/retropilot/0/device/:dongle_id/', [isAuthenticated, bodyParser.json()], async (req, res) => {
|
||||
|
@ -54,7 +54,9 @@ router.put('/retropilot/0/device/:dongle_id/', [isAuthenticated, bodyParser.json
|
|||
}
|
||||
|
||||
const { body } = req;
|
||||
logger.log(deviceSchema.MutateDevice.isValid(body));
|
||||
logger.log(MutateDevice.isValid(body));
|
||||
// TODO: response?
|
||||
return res.json({ success: true });
|
||||
});
|
||||
|
||||
router.get('/retropilot/0/device/:dongle_id/drives/:drive_identifier/segment', isAuthenticated, async (req, res) => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import bodyParser from 'body-parser';
|
||||
import express from 'express';
|
||||
|
||||
import userController from '../../controllers/users';
|
||||
import { createAccount, verifyEmailToken } from '../../controllers/users';
|
||||
|
||||
const router = express.Router();
|
||||
router.post('/retropilot/0/register/email', bodyParser.urlencoded({ extended: true }), async (req, res) => {
|
||||
|
@ -12,7 +12,7 @@ router.post('/retropilot/0/register/email', bodyParser.urlencoded({ extended: tr
|
|||
return res.status(400).json({ success: false, msg: 'malformed request' });
|
||||
}
|
||||
|
||||
const accountStatus = await userController.createAccount(req.body.email, req.body.password);
|
||||
const accountStatus = await createAccount(req.body.email, req.body.password);
|
||||
if (accountStatus && accountStatus.status) {
|
||||
return res.status(accountStatus.status).json(accountStatus);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ router.get('/retropilot/0/register/verify/:token', bodyParser.urlencoded({ exten
|
|||
return res.status(400).json({ success: false, status: 400, data: { missingToken: true } });
|
||||
}
|
||||
|
||||
const verified = await userController.verifyEmailToken(req.params.token);
|
||||
const verified = await verifyEmailToken(req.params.token);
|
||||
|
||||
if (verified && verified.status) {
|
||||
return res.status(verified.status).json(verified);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable */
|
||||
// TODO: delete useradmin...
|
||||
import express from 'express';
|
||||
import bodyParser from 'body-parser';
|
||||
import crypto from 'crypto';
|
||||
|
@ -517,14 +519,14 @@ router.get('/useradmin/drive/:dongleId/:driveIdentifier', runAsyncWrapper(async
|
|||
<a id="show-button" href="#" onclick="
|
||||
document.getElementById('hide-button').style.display = 'inline';
|
||||
document.getElementById('show-button').style.display = 'none';
|
||||
document.getElementById('car-parameter-div').style.display = 'block';
|
||||
document.getElementById('car-parameter-div').style.display = 'block';
|
||||
return false;">Show</a>
|
||||
<a id="hide-button" style="display: none;" href="#" onclick="
|
||||
document.getElementById('hide-button').style.display = 'none';
|
||||
document.getElementById('show-button').style.display = 'inline';
|
||||
document.getElementById('car-parameter-div').style.display = 'none';
|
||||
document.getElementById('car-parameter-div').style.display = 'none';
|
||||
return false;">Hide</a>
|
||||
|
||||
|
||||
<br><pre id="car-parameter-div" style="display: none; font-size: 0.8em">${carParams}</pre>
|
||||
<br>
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ export const MutateDevice = yup.object().shape({
|
|||
},
|
||||
});
|
||||
|
||||
|
||||
export default {
|
||||
|
||||
};
|
||||
|
|
|
@ -120,7 +120,7 @@ lockfile.lock('retropilot_server', { realpath: false, stale: 30000, update: 2000
|
|||
const httpServer = http.createServer(app);
|
||||
|
||||
httpServer.listen(process.env.HTTP_PORT, () => {
|
||||
logger.info(`Retropilot Server listening at http://${process.env.BASE_URL}`);
|
||||
logger.info(`RetroPilot Server listening at ${process.env.BASE_URL}`);
|
||||
});
|
||||
|
||||
}).catch((e) => {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* eslint-disable no-underscore-dangle */
|
||||
let wss;
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import orm from '../../models/index.model';
|
||||
|
||||
let realtime;
|
||||
let wss;
|
||||
|
||||
async function incoming(ws, res, msg) {
|
||||
return realtime.passData(ws.dongleId, msg);
|
||||
|
|
|
@ -2,11 +2,11 @@ import { WebSocketServer } from 'ws';
|
|||
import cookie from 'cookie';
|
||||
import httpServer from 'http';
|
||||
import log4js from 'log4js';
|
||||
import controlsFunction from './controls.js';
|
||||
import authenticationController from '../../controllers/authentication.js';
|
||||
import authenticationController from '../../controllers/authentication';
|
||||
import athenaRealtime from '../athena';
|
||||
|
||||
import athenaRealtime from '../athena/index.js';
|
||||
import realtimeCommands from './commands.js';
|
||||
import controlsFunction from './controls';
|
||||
import realtimeCommands from './commands';
|
||||
|
||||
const logger = log4js.getLogger('default');
|
||||
|
||||
|
|
Loading…
Reference in New Issue