diff --git a/fmdx_list.js b/fmdx_list.js new file mode 100644 index 0000000..8d957ef --- /dev/null +++ b/fmdx_list.js @@ -0,0 +1,101 @@ +/* Libraries / Imports */ +const fs = require('fs'); +const { logDebug, logError, logInfo, logWarn } = require('./console'); +const { serverConfig, configUpdate, configSave } = require('./server_config') + +let timeoutID = null; + +function send(request) { + const url = "https://list.fmdx.pl/api/"; + + const options = { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request) + }; + + fetch(url, options) + .then(response => response.json()) + .then(data => { + if (data.success && data.token) + { + if (!serverConfig.identification.token) + { + logInfo("Succesfully registered in FM-DX Server Map."); + serverConfig.identification.token = data.token; + configSave(); + } + else + { + logInfo("Succesfully updated FM-DX Server Map."); + } + } + else + { + logWarn("Failed to update FM-DX Server Map: " + (data.error ? data.error : 'unknown error')); + } + }) + .catch(error => { + logWarn("Failed to update FM-DX Server Map: " + error); + }); +} + +function sendKeepalive() { + if (!serverConfig.identification.token) + { + return; + } + + const request = { + token: serverConfig.identification.token, + status: (serverConfig.lockToAdmin ? 2 : 1) + }; + + send(request); +} + +function sendUpdate() { + const request = { + status: (serverConfig.lockToAdmin ? 2 : 1), + coords: [serverConfig.identification.lat, serverConfig.identification.lon], + name: serverConfig.identification.tunerName, + desc: serverConfig.identification.tunerDesc + }; + + if (serverConfig.identification.token) + { + request.token = serverConfig.identification.token; + } + + if (serverConfig.identification.proxyIp.length) + { + request.url = serverConfig.identification.proxyIp; + } + else + { + request.port = serverConfig.webserver.webserverPort; + } + + send(request); +} + +function update() { + if (timeoutID !== null) { + clearTimeout(timeoutID); + } + + if (!serverConfig.identification.broadcastTuner) + { + return; + } + + sendUpdate(); + timeoutID = setInterval(sendKeepalive, 5 * 60 * 1000); +} + +module.exports = { + update +}; diff --git a/index.js b/index.js index 82fcc80..3e1d0b5 100644 --- a/index.js +++ b/index.js @@ -23,47 +23,18 @@ const crypto = require('crypto'); const fs = require('fs'); const commandExists = require('command-exists-promise'); const dataHandler = require('./datahandler'); +const fmdxList = require('./fmdx_list'); const consoleCmd = require('./console'); const audioStream = require('./stream/index.js'); const { parseAudioDevice } = require('./stream/parser.js'); const configPath = path.join(__dirname, 'config.json'); +const { serverConfig, configUpdate, configSave } = require('./server_config') const { logDebug, logError, logInfo, logWarn } = consoleCmd; let currentUsers = 0; let streamEnabled = false; let incompleteDataBuffer = ''; -let serverConfig = { - webserver: { - webserverIp: "0.0.0.0", - webserverPort: "8080", - audioPort: "8081" - }, - xdrd: { - xdrdIp: "127.0.0.1", - xdrdPort: "7373", - xdrdPassword: "" - }, - identification: { - tunerName: "", - tunerDesc: "", - lat: "0", - lon: "0", - broadcastTuner: false, - proxyIp: "", - }, - password: { - tunePass: "", - adminPass: "" - }, - publicTuner: true, - lockToAdmin: false -}; - -if(fs.existsSync('config.json')) { - const configFileContents = fs.readFileSync('config.json', 'utf8'); - serverConfig = JSON.parse(configFileContents); -} app.use(bodyParser.urlencoded({ extended: true })); const sessionMiddleware = session({ @@ -119,8 +90,9 @@ function connectToXdrd() { const authDataHandler = (data) => { const receivedData = data.toString(); const lines = receivedData.split('\n'); - + for (const line of lines) { + if (!authFlags.receivedPassword) { authFlags.receivedSalt = line.trim(); authenticateWithXdrd(client, authFlags.receivedSalt, serverConfig.xdrd.xdrdPassword); @@ -311,18 +283,21 @@ app.post('/saveData', (req, res) => { const data = req.body; let firstSetup; if(req.session.isAdminAuthenticated || !fs.existsSync('config.json')) { + configUpdate(data); + fmdxList.update(); + if(!fs.existsSync('config.json')) { firstSetup = true; } + + /* TODO: Refactor to server_config.js */ // Save data to a JSON file - fs.writeFile('config.json', JSON.stringify(data, null, 2), (err) => { + fs.writeFile('config.json', JSON.stringify(serverConfig, null, 2), (err) => { if (err) { logError(err); res.status(500).send('Internal Server Error'); } else { logInfo('Server config changed successfully.'); - const configFileContents = fs.readFileSync('config.json', 'utf8'); - serverConfig = JSON.parse(configFileContents); if(firstSetup === true) { res.status(200).send('Data saved successfully!\nPlease, restart the server to load your configuration.'); } else { @@ -438,6 +413,4 @@ httpServer.listen(serverConfig.webserver.webserverPort, serverConfig.webserver.w logInfo(`Web server is running at \x1b[34mhttp://${serverConfig.webserver.webserverIp}:${serverConfig.webserver.webserverPort}\x1b[0m.`); }); -module.exports = { - serverConfig -} +fmdxList.update(); diff --git a/server_config.js b/server_config.js new file mode 100644 index 0000000..ca828f8 --- /dev/null +++ b/server_config.js @@ -0,0 +1,65 @@ +/* Libraries / Imports */ +const fs = require('fs'); +const { logDebug, logError, logInfo, logWarn } = require('./console'); + +let serverConfig = { + webserver: { + webserverIp: "0.0.0.0", + webserverPort: "8080", + audioPort: "8081" + }, + xdrd: { + xdrdIp: "127.0.0.1", + xdrdPort: "7373", + xdrdPassword: "" + }, + identification: { + token: null, + tunerName: "", + tunerDesc: "", + lat: "0", + lon: "0", + broadcastTuner: false, + proxyIp: "", + }, + password: { + tunePass: "", + adminPass: "" + }, + publicTuner: true, + lockToAdmin: false +}; + +function deepMerge(target, source) +{ + Object.keys(source).forEach(function(key) { + if (typeof target[key] === 'object' && target[key] !== null) { + deepMerge(target[key], source[key]); + } else { + target[key] = source[key]; + } + }); +} + +function configUpdate(newConfig) { + deepMerge(serverConfig, newConfig); +} + +function configSave() { + fs.writeFile('config.json', JSON.stringify(serverConfig, null, 2), (err) => { + if (err) { + logError(err); + } else { + logInfo('Server config saved successfully.'); + } + }); +} + +if (fs.existsSync('config.json')) { + const configFileContents = fs.readFileSync('config.json', 'utf8'); + serverConfig = JSON.parse(configFileContents); +} + +module.exports = { + serverConfig, configUpdate, configSave +};