121 lines
3.1 KiB
JavaScript
121 lines
3.1 KiB
JavaScript
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)
|