This repository has been archived on 2022-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
teemant-old/server/webirc.js

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)