All checks were successful
Build and Push Docker Image / build (push) Successful in 39s
#1 Session cookie: add secure (production-only) and sameSite=strict to prevent transmission over HTTP and cross-site request abuse. #2 Remove Emby AccessToken from cookie payload — it was stored in the browser cookie but is never needed client-side; reduces blast radius if cookie is ever exposed. #3 Add requireAuth middleware to all proxy routes (/api/emby, /api/sabnzbd, /api/sonarr, /api/radarr) — previously unauthenticated, now require a valid emby_user session cookie. #4 Remove open CORS wildcard (cors() with no options). The frontend is served from the same origin so no CORS headers are required. Also update clearCookie() to include matching cookie options.
85 lines
2.9 KiB
JavaScript
85 lines
2.9 KiB
JavaScript
const express = require('express');
|
|
const path = require('path');
|
|
const cookieParser = require('cookie-parser');
|
|
const fs = require('fs');
|
|
require('dotenv').config();
|
|
|
|
// Setup logging with levels
|
|
// Levels: debug (0), info (1), warn (2), error (3), silent (4)
|
|
const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
|
|
const currentLevel = LOG_LEVELS[(process.env.LOG_LEVEL || 'info').toLowerCase()] || 1;
|
|
|
|
const logFile = fs.createWriteStream(path.join(__dirname, '../server.log'), { flags: 'a' });
|
|
const originalConsoleLog = console.log;
|
|
const originalConsoleError = console.error;
|
|
const originalConsoleWarn = console.warn;
|
|
const originalConsoleDebug = console.debug;
|
|
|
|
function shouldLog(level) {
|
|
return level >= currentLevel;
|
|
}
|
|
|
|
console.debug = function(...args) {
|
|
if (!shouldLog(LOG_LEVELS.debug)) return;
|
|
const message = args.join(' ');
|
|
originalConsoleDebug.apply(console, args);
|
|
logFile.write(`[${new Date().toISOString()}] DEBUG: ${message}\n`);
|
|
};
|
|
|
|
console.log = function(...args) {
|
|
if (!shouldLog(LOG_LEVELS.info)) return;
|
|
const message = args.join(' ');
|
|
originalConsoleLog.apply(console, args);
|
|
logFile.write(`[${new Date().toISOString()}] ${message}\n`);
|
|
};
|
|
|
|
console.warn = function(...args) {
|
|
if (!shouldLog(LOG_LEVELS.warn)) return;
|
|
const message = args.join(' ');
|
|
originalConsoleWarn.apply(console, args);
|
|
logFile.write(`[${new Date().toISOString()}] WARN: ${message}\n`);
|
|
};
|
|
|
|
console.error = function(...args) {
|
|
if (!shouldLog(LOG_LEVELS.error)) return;
|
|
const message = args.join(' ');
|
|
originalConsoleError.apply(console, args);
|
|
logFile.write(`[${new Date().toISOString()}] ERROR: ${message}\n`);
|
|
};
|
|
|
|
const sabnzbdRoutes = require('./routes/sabnzbd');
|
|
const sonarrRoutes = require('./routes/sonarr');
|
|
const radarrRoutes = require('./routes/radarr');
|
|
const embyRoutes = require('./routes/emby');
|
|
const dashboardRoutes = require('./routes/dashboard');
|
|
const authRoutes = require('./routes/auth');
|
|
const { startPoller, POLL_INTERVAL, POLLING_ENABLED } = require('./utils/poller');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
app.use(cookieParser());
|
|
app.use(express.json());
|
|
app.use(express.static(path.join(__dirname, '../public')));
|
|
|
|
app.use('/api/sabnzbd', sabnzbdRoutes);
|
|
app.use('/api/sonarr', sonarrRoutes);
|
|
app.use('/api/radarr', radarrRoutes);
|
|
app.use('/api/emby', embyRoutes);
|
|
app.use('/api/dashboard', dashboardRoutes);
|
|
app.use('/api/auth', authRoutes);
|
|
|
|
app.get('/', (req, res) => {
|
|
res.sendFile(path.join(__dirname, '../public/index.html'));
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`=================================`);
|
|
console.log(` sofarr - Your Downloads Dashboard`);
|
|
console.log(` Server running on port ${PORT}`);
|
|
console.log(` Log level: ${process.env.LOG_LEVEL || 'info'}`);
|
|
console.log(` Polling: ${POLLING_ENABLED ? POLL_INTERVAL + 'ms' : 'disabled (on-demand)'}`);
|
|
console.log(`=================================`);
|
|
startPoller();
|
|
});
|