UNPKG

huskee-install

Version:

Huskee server installer

134 lines (117 loc) 4.35 kB
const https = require('https') const http = require('http') const fs = require('fs') const tls = require('tls') const routing = require('../lib/routing.compiled') const path = require('path') const hosts = require('../conf/hosts') const hostsObject = hosts.map(h => { const orig = h.originsWithAccess || [] h.originsWithAccess = orig.reduce((o, next) => ({ ...o, [next]: true }), {}) return h }).reduce((h, next) => ({ ...h, [next.host]: next }), {}) const config = require('../conf/main') const punycode = require('punycode') require('./socketproxy') const fsStatAsync = path => new Promise(resolve => { fs.stat(path, (err, stats) => err ? resolve(0) : resolve(stats)) }) const secureContext = {} const secureKeys = {} const getSSLKeys = domain => ({ key: fs.readFileSync(`/etc/letsencrypt/live/${domain}/privkey.pem`, 'utf-8'), cert: fs.readFileSync(`/etc/letsencrypt/live/${domain}/fullchain.pem`, 'utf-8'), ca: fs.readFileSync(`/etc/letsencrypt/live/${domain}/chain.pem`, 'utf-8') }) const createSSL = keys => tls.createSecureContext(keys) hosts.forEach(async host => { const key = host.host const wwwPath = path.join(__dirname, `../www/${key}/`) const apiPath = path.join(__dirname, `../dynamic/${key}`) const www = await fsStatAsync(wwwPath) if(!www) fs.mkdir(wwwPath, e => {e}) //TODO: add callback const api = await fsStatAsync(apiPath) if(!api) fs.mkdir(apiPath, e => {e}) //TODO: add callback if(host.ssl === true) { try{ secureKeys[key] = getSSLKeys(key) secureContext[key] = createSSL(secureKeys[key]) } catch(e) { console.log(`No cert for the ${key} host`) } const { onload, host: hostname } = host if(!onload) return if(typeof onload === 'object' && onload.forEach) onload.forEach(loadPath => { const path = `../dynamic/${hostname}/${loadPath}` try { var appToLoad = require(path) } catch(e) { return console.error(`ERROR: can't find ${loadPath} script in ${hostname} settings. Error: ${e}`) } if(typeof appToLoad === 'function') { try { appToLoad() } catch(e) { return console.error(`ERROR: your ${loadPath} script in ${hostname} settings seems to be broken`) } } }) } }) const options = { SNICallback: (domain, cb) => cb(null, secureContext[domain]) } const processConnection = (req, res) => { res.setHeader('Server', 'Huskee') res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTION, DELETE, PUT') res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type') res.setHeader('Access-Control-Allow-Credentials', true) const host = punycode.toUnicode(req.headers.host || '') const { originsWithAccess = {} } = hostsObject[host] || {} const { origin = '' } = req.headers const testOrigin = origin.includes(':') ? origin.split('://')[1] : origin if(originsWithAccess[testOrigin]) res.setHeader('Access-Control-Allow-Origin', origin) let length = 0 let dataString = '' req.on('data', chunk => { dataString = dataString.concat(decodeURI(chunk)) length += Buffer.byteLength(chunk, 'utf-8') if(length/1024 > 10*1024) { res.destroy() } }) req.on('end', () => { new routing.Connection(req, res, dataString) }) } https.createServer(options, (req, res) => { const host = req.headers.host const encryption = secureKeys[host] req.encryption = encryption processConnection(req, res) }).listen(443) http.createServer((req, res) => { const host = req.headers.host const ourHost = hosts.find(h => h.host === host) const { ssl } = ourHost ? ourHost : {} if(ssl) { res.writeHead(301, { 'Location': 'https://' + req.headers.host + req.url }) return res.end() } processConnection(req, res) }).listen(config.port /*'forgetable.ru', null, () => { try { console.log('Old User ID: ' + process.getuid() + ', Old Group ID: ' + process.getgid()) process.setgid('users') process.setuid('lena') console.log('New User ID: ' + process.getuid() + ', New Group ID: ' + process.getgid()) } catch (err) { console.log('Cowardly refusing to keep the process alive as root.') process.exit(1) } }*/)