1
0
mirror of https://github.com/KubaPro010/fm-dx-webserver.git synced 2026-02-26 14:11:59 +01:00

fix minor typos, potential mem leaks

This commit is contained in:
Amateur Audio Dude
2025-07-07 22:32:04 +10:00
committed by GitHub
parent 4ece21d513
commit f29570261e
6 changed files with 17 additions and 103 deletions

View File

@@ -272,7 +272,7 @@ function rdsReceived() {
rdsTimeoutTimer = null;
}
if (serverConfig.webserver.rdsTimeout && serverConfig.webserver.rdsTimeout != 0) {
rdsTimeoutTimer = setInterval(rdsReset, serverConfig.webserver.rdsTimeout * 1000);
rdsTimeoutTimer = setTimeout(rdsReset, serverConfig.webserver.rdsTimeout * 1000);
}
}

View File

@@ -21,7 +21,7 @@ router.get('/', (req, res) => {
let requestIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const normalizedIp = requestIp?.replace(/^::ffff:/, '');
const ipList = normalizedIp.split(',').map(ip => ip.trim()); // in case there are multiple IPs (proxy), we need to check all of them
const ipList = (normalizedIp || '').split(',').map(ip => ip.trim()).filter(Boolean); // in case there are multiple IPs (proxy), we need to check all of them
const isBanned = ipList.some(ip => serverConfig.webserver.banlist.some(banEntry => banEntry[0] === ip));
@@ -140,12 +140,14 @@ router.get('/wizard', (req, res) => {
audioDevices: result.videoDevices,
serialPorts: serialPorts,
memoryUsage: (process.memoryUsage.rss() / 1024 / 1024).toFixed(1) + ' MB',
memoryHeap: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(1) + ' MB',
processUptime: formattedProcessUptime,
consoleOutput: logs,
plugins: allPluginConfigs,
enabledPlugins: updatedConfig.plugins,
onlineUsers: dataHandler.dataToSend.users,
connectedUsers: storage.connectedUsers,
device: serverConfig.device,
banlist: updatedConfig.webserver.banlist // Updated banlist from the latest config
});
});
@@ -369,6 +371,14 @@ const logHistory = {};
function canLog(id) {
const now = Date.now();
const sixtyMinutes = 60 * 60 * 1000; // 60 minutes in milliseconds
// Remove expired entries
for (const [entryId, timestamp] of Object.entries(logHistory)) {
if ((now - timestamp) >= sixtyMinutes) {
delete logHistory[entryId];
}
}
if (logHistory[id] && (now - logHistory[id]) < sixtyMinutes) {
return false; // Deny logging if less than 60 minutes have passed
}

View File

@@ -326,59 +326,6 @@ app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, '../web'));
app.use('/', endpoints);
function antispamProtection(message, clientIp, ws, userCommands, lastWarn, userCommandHistory, lengthCommands, endpointName) {
const command = message.toString();
const now = Date.now();
if (endpointName === 'text') logDebug(`Command received from \x1b[90m${clientIp}\x1b[0m: ${command}`);
// Initialize user command history if not present
if (!userCommandHistory[clientIp]) {
userCommandHistory[clientIp] = [];
}
// Record the current timestamp for the user
userCommandHistory[clientIp].push(now);
// Remove timestamps older than 20 ms from the history
userCommandHistory[clientIp] = userCommandHistory[clientIp].filter(timestamp => now - timestamp <= 20);
// Check if there are 8 or more commands in the last 20 ms
if (userCommandHistory[clientIp].length >= 8) {
logWarn(`User \x1b[90m${clientIp}\x1b[0m is spamming with rapid commands. Connection will be terminated and user will be banned.`);
// Add to banlist if not already banned
if (!serverConfig.webserver.banlist.includes(clientIp)) {
serverConfig.webserver.banlist.push(clientIp);
logInfo(`User \x1b[90m${clientIp}\x1b[0m has been added to the banlist due to extreme spam.`);
console.log(serverConfig.webserver.banlist);
configSave();
}
ws.close(1008, 'Bot-like behavior detected');
return command; // Return command value before closing connection
}
// Update the last message time for general spam detection
lastMessageTime = now;
// Initialize command history for rate-limiting checks
if (!userCommands[command]) {
userCommands[command] = [];
}
// Record the current timestamp for this command
userCommands[command].push(now);
// Remove timestamps older than 1 second
userCommands[command] = userCommands[command].filter(timestamp => now - timestamp <= 1000);
// If command count exceeds limit, close connection
if (userCommands[command].length > lengthCommands) {
if (now - lastWarn.time > 1000) { // Check if 1 second has passed
logWarn(`User \x1b[90m${clientIp}\x1b[0m is spamming command "${command}" in /${endpointName}. Connection will be terminated.`);
lastWarn.time = now; // Update the last warning time
}
ws.close(1008, 'Spamming detected');
return command; // Return command value before closing connection
}
return command; // Return command value for normal execution
}
/**
* WEBSOCKET BLOCK
*/
@@ -390,12 +337,12 @@ wss.on('connection', (ws, request) => {
const userCommandHistory = {};
const normalizedClientIp = clientIp?.replace(/^::ffff:/, '');
if (serverConfig.webserver.banlist?.includes(clientIp)) {
if (clientIp && serverConfig.webserver.banlist?.includes(clientIp)) {
ws.close(1008, 'Banned IP');
return;
}
if (clientIp.includes(',')) {
if (clientIp && clientIp.includes(',')) {
clientIp = clientIp.split(',')[0].trim();
}
@@ -641,50 +588,6 @@ pluginsWss.on('connection', (ws, request) => {
});
});
// Additional web socket for using plugins
pluginsWss.on('connection', (ws, request) => {
const clientIp = request.headers['x-forwarded-for'] || request.connection.remoteAddress;
const userCommandHistory = {};
if (serverConfig.webserver.banlist?.includes(clientIp)) {
ws.close(1008, 'Banned IP');
return;
}
// Anti-spam tracking for each client
const userCommands = {};
let lastWarn = { time: 0 };
ws.on('message', message => {
// Anti-spam
const command = antispamProtection(message, clientIp, ws, userCommands, lastWarn, userCommandHistory, '10', 'data_plugins');
let messageData;
try {
messageData = JSON.parse(message); // Attempt to parse the JSON
} catch (error) {
// console.error("Failed to parse message:", error); // Log the error
return; // Exit if parsing fails
}
const modifiedMessage = JSON.stringify(messageData);
// Broadcast the message to all other clients
pluginsWss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(modifiedMessage); // Send the message to all clients
}
});
});
ws.on('close', () => {
// logInfo('WebSocket Extra connection closed'); // Use custom logInfo function
});
ws.on('error', error => {
logError('WebSocket Extra error: ' + error); // Use custom logError function
});
});
function isPortOpen(host, port, timeout = 1000) {
return new Promise((resolve) => {
const socket = new net.Socket();

View File

@@ -155,7 +155,7 @@ function configUpdate(newConfig) {
function configSave() {
try {
fs.writeFileSync(configPath, JSON.stringify(serverConfig, null, 2));
logInfo('Server config saved successfully.');
setTimeout(() => logInfo('Server config saved successfully.'), 0);
} catch (err) {
logError(err);
}

View File

@@ -31,7 +31,7 @@ if (typeof algorithms[algoSetting] !== 'undefined') {
// IIFE to build the local TX DB cache from the endpoint.
(async () => {
try {
consoleCmd.logInfo('Fetching transmitter database...');
setTimeout(() => consoleCmd.logInfo('Fetching transmitter database...'), 0);
const response = await fetch(`https://maps.fmdx.org/api?qth=${serverConfig.identification.lat},${serverConfig.identification.lon}`);
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
localDb = await response.json();

View File

@@ -76,6 +76,7 @@
<div class="panel-33 p-20">
<span class="text-medium-big color-5"><%= memoryUsage %></span>
<span class="text-small color-4" style="display: block; font-size: 1em; line-height: 0;">(<%= memoryHeap %> heap)</span>
<p>Memory usage</p>
</div>