import dns from 'dns' import fs from 'fs' import path from 'path' import config from './server/config' import logger from './server/logger' const webircDataPath = path.join(__dirname, '..', 'webirc.data.json') let webircData = {} let timeouts = {} function writeToFile () { fs.writeFile(webircDataPath, JSON.stringify(webircData, null, '\t'), (err) => { if (err) throw err }) } function timeoutRefresh (address, seconds) { if (timeouts[address]) clearTimeout(timeouts[address]) timeouts[address] = setTimeout(() => resolveAddress(address), seconds * 1000) } function resolveAddress (address, force) { logger.debugLog('** WEBIRC ** Attempting to update IP for', address) let obj = webircData[address] if (!obj) return if ((Date.now() - obj.last_update) / 1000 < config.webirc.resolveInterval && !force) { let nextTime = (config.webirc.resolveInterval - (Date.now() - obj.last_update) / 1000) logger.debugLog(`** WEBIRC ** ${address} IP is ${obj.cachedIP}, refresh in ${Math.floor(nextTime)} seconds`) return timeoutRefresh(address, nextTime) } new Promise((resolve, reject) => { if (address === '127.0.0.1' || address === '0.0.0.0' || address === 'localhost') { logger.debugLog('** WEBIRC ** Ignoring localhost entry..') return resolve('127.0.0.1') } dns.resolve(address, (err, data) => { if (err != null) return reject(err) let ip = data.length > 0 ? data[0] : null if (ip) { resolve(ip) } else { reject(new Error('no ips')) } }) }).then((data) => { logger.debugLog('** WEBIRC ** Updated DNS for {0}; IP is now {1}'.format(address, data)) webircData[address].last_update = Date.now() webircData[address].cachedIP = data writeToFile() timeoutRefresh(address, config.webirc.resolveInterval) }, (err) => { logger.debugLog(`** WEBIRC ** Failed to updated DNS for ${address}; IP is still ${webircData[address].cachedIP}:`, err.message) timeoutRefresh(address, config.webirc.resolveInterval + 60) }) } function reload (force) { if (!config.webirc.enabled) return try { fs.accessSync(webircDataPath, fs.F_OK) webircData = require(webircDataPath) if (require.cache && require.cache[webircDataPath]) { delete require.cache[webircDataPath] } } catch (e) { writeToFile() } for (let adr in webircData) { resolveAddress(adr, force) } } function getPassword (serverIP) { let ip = null for (let a in webircData) { if (webircData[a].cachedIP !== serverIP) continue ip = webircData[a] } return ip } class WebIRCAuthenticator { constructor (userInfo) { this.userInfo = userInfo } authenticate (connection) { let serverpass = getPassword(connection.config.address) if (serverpass) { connection.socket.write(`WEBIRC ${serverpass.password} ${connection.config.username} ${this.userInfo.hostname} ${this.userInfo.ipaddr}\r\n`) } } } module.exports = { Authenticator: WebIRCAuthenticator, reload, getPassword, writeToFile } process.on('SIGUSR1', () => { logger.log('\n!!! Received SIGUSR1; Reloading webirc data.. !!!\n') reload(true) }) reload(false)