mirror of
https://github.com/BreizhHardware/Jellystat.git
synced 2026-01-18 16:27:20 +01:00
Changed Dockerfile as previos file was failing to build consistently removed some unused packages added compression to json payloads changed vite ports to 3000 to not break existing builds backend and frontend both use port 3000 now
166 lines
4.9 KiB
JavaScript
166 lines
4.9 KiB
JavaScript
// core
|
|
require('dotenv').config();
|
|
const http = require('http');
|
|
const path = require('path');
|
|
const express = require('express');
|
|
const compression = require('compression');
|
|
const cors = require('cors');
|
|
const jwt = require('jsonwebtoken');
|
|
const knex = require('knex');
|
|
const swaggerUi = require('swagger-ui-express');
|
|
const swaggerDocument = require('./swagger.json');
|
|
|
|
// db
|
|
const dbInstance = require('./db');
|
|
const createdb = require('./create_database');
|
|
const knexConfig = require('./migrations');
|
|
|
|
// routes
|
|
const authRouter = require('./routes/auth');
|
|
const apiRouter = require('./routes/api');
|
|
const proxyRouter = require('./routes/proxy');
|
|
const syncRouter = require('./routes/sync');
|
|
const statsRouter = require('./routes/stats');
|
|
const backupRouter = require('./routes/backup');
|
|
const logRouter = require('./routes/logging');
|
|
const utilsRouter = require('./routes/utils');
|
|
|
|
// tasks
|
|
const ActivityMonitor = require('./tasks/ActivityMonitor');
|
|
const SyncTask = require('./tasks/SyncTask');
|
|
const BackupTask = require('./tasks/BackupTask');
|
|
|
|
// websocket
|
|
const { setupWebSocketServer } = require('./ws');
|
|
|
|
const app = express();
|
|
const db = knex(knexConfig.development);
|
|
|
|
const PORT = 3000;
|
|
const LISTEN_IP = '127.0.0.1';
|
|
const JWT_SECRET = process.env.JWT_SECRET;
|
|
|
|
if (JWT_SECRET === undefined) {
|
|
console.log('JWT Secret cannot be undefined');
|
|
process.exit(1); // end the program with error status code
|
|
}
|
|
|
|
// middlewares
|
|
app.use(express.json()); // middleware to parse JSON request bodies
|
|
app.use(cors());
|
|
app.set('trust proxy', 1);
|
|
app.disable('x-powered-by');
|
|
app.use(compression());
|
|
|
|
|
|
// initiate routes
|
|
app.use('/auth', authRouter, () => {
|
|
/* #swagger.tags = ['Auth'] */
|
|
}); // mount the API router at /auth
|
|
app.use('/proxy', proxyRouter, () => {
|
|
/* #swagger.tags = ['Proxy']*/
|
|
}); // mount the API router at /proxy
|
|
app.use('/api', authenticate, apiRouter, () => {
|
|
/* #swagger.tags = ['API']*/
|
|
}); // mount the API router at /api, with JWT middleware
|
|
app.use('/sync', authenticate, syncRouter.router, () => {
|
|
/* #swagger.tags = ['Sync']*/
|
|
}); // mount the API router at /sync, with JWT middleware
|
|
app.use('/stats', authenticate, statsRouter, () => {
|
|
/* #swagger.tags = ['Stats']*/
|
|
}); // mount the API router at /stats, with JWT middleware
|
|
app.use('/backup', authenticate, backupRouter.router, () => {
|
|
/* #swagger.tags = ['Backup']*/
|
|
}); // mount the API router at /backup, with JWT middleware
|
|
app.use('/logs', authenticate, logRouter.router, () => {
|
|
/* #swagger.tags = ['Logs']*/
|
|
}); // mount the API router at /logs, with JWT middleware
|
|
app.use('/utils', authenticate, utilsRouter, () => {
|
|
/* #swagger.tags = ['Utils']*/
|
|
}); // mount the API router at /utils, with JWT middleware
|
|
|
|
// Swagger
|
|
app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
|
|
|
|
// for deployment of static page
|
|
const root = path.join(__dirname, '..', 'dist');
|
|
app.use(express.static(root));
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(__dirname, '..', 'dist', 'index.html'));
|
|
});
|
|
|
|
const server = http.createServer(app);
|
|
|
|
setupWebSocketServer(server);
|
|
|
|
// JWT middleware
|
|
async function authenticate(req, res, next) {
|
|
const token = req.headers.authorization;
|
|
const apiKey = req.headers['x-api-token'] || req.query.apiKey;
|
|
|
|
if (!token && !apiKey) {
|
|
return res.status(401).json({
|
|
message: 'Authentication failed. No token or API key provided.',
|
|
});
|
|
}
|
|
|
|
if (token) {
|
|
const extracted_token = token.split(' ')[1];
|
|
if (!extracted_token || extracted_token === 'null') {
|
|
return res.sendStatus(403);
|
|
}
|
|
|
|
try {
|
|
const decoded = jwt.verify(extracted_token, JWT_SECRET);
|
|
req.user = decoded.user;
|
|
next();
|
|
} catch (error) {
|
|
console.log(error);
|
|
return res.status(401).json({ message: 'Invalid token' });
|
|
}
|
|
} else {
|
|
if (apiKey) {
|
|
const keysjson = await dbInstance
|
|
.query('SELECT api_keys FROM app_config where "ID"=1')
|
|
.then((res) => res.rows[0].api_keys);
|
|
|
|
if (!keysjson || Object.keys(keysjson).length === 0) {
|
|
return res.status(404).json({ message: 'No API keys configured' });
|
|
}
|
|
const keys = keysjson || [];
|
|
|
|
const keyExists = keys.some((obj) => obj.key === apiKey);
|
|
|
|
if (keyExists) {
|
|
next();
|
|
} else {
|
|
return res.status(403).json({ message: 'Invalid API key' });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// start server
|
|
try {
|
|
createdb.createDatabase().then((result) => {
|
|
if (result) {
|
|
console.log('[JELLYSTAT] Database created');
|
|
} else {
|
|
console.log('[JELLYSTAT] Database exists. Skipping creation');
|
|
}
|
|
|
|
db.migrate.latest().then(() => {
|
|
server.listen(PORT, async () => {
|
|
console.log(
|
|
`[JELLYSTAT] Server listening on http://${LISTEN_IP}:${PORT}`
|
|
);
|
|
ActivityMonitor.ActivityMonitor(1000);
|
|
SyncTask.SyncTask();
|
|
BackupTask.BackupTask();
|
|
});
|
|
});
|
|
});
|
|
} catch (error) {
|
|
console.log('[JELLYSTAT] An error has occured on startup: ' + error);
|
|
}
|