mirror of
https://github.com/BreizhHardware/Jellystat.git
synced 2026-01-19 00:37:22 +01:00
fixed bug where invalid token returned Unable to connect to backend page better state tracking in activity monitor page and jellydin api calls
160 lines
4.9 KiB
JavaScript
160 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 tasks = require("./tasks/tasks");
|
|
|
|
// websocket
|
|
const { setupWebSocketServer } = require("./ws");
|
|
|
|
const app = express();
|
|
const db = knex(knexConfig.development);
|
|
|
|
const PORT = 3000;
|
|
const LISTEN_IP = "0.0.0.0";
|
|
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"));
|
|
});
|
|
|
|
// 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("Invalid token");
|
|
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(() => {
|
|
const server = http.createServer(app);
|
|
|
|
setupWebSocketServer(server);
|
|
server.listen(PORT, LISTEN_IP, async () => {
|
|
console.log(`[JELLYSTAT] Server listening on http://127.0.0.1:${PORT}`);
|
|
ActivityMonitor.ActivityMonitor(1000);
|
|
tasks.FullSyncTask();
|
|
tasks.RecentlyAddedItemsSyncTask();
|
|
tasks.BackupTask();
|
|
});
|
|
});
|
|
});
|
|
} catch (error) {
|
|
console.log("[JELLYSTAT] An error has occured on startup: " + error);
|
|
}
|