import os from 'os'; import path from 'path'; import http from 'http'; import fs from 'fs-extra'; import Koa, { Context } from 'koa'; import Body from 'koa-body'; import cache from 'koa-static-cache'; import nunjucks from 'nunjucks'; import mongodb from 'mongodb'; import { argv } from 'yargs'; const listenPort = argv.port || 8888; class Loader { getSource(name: string) { // eslint-disable-line class-methods-use-this return { src: ` {{ _('Setup') }}

{{ _('Setup') }}

`, path: name, noCache: false, }; } } const env = new nunjucks.Environment(new Loader(), { autoescape: true, trimBlocks: true }); function render(name: string) { return new Promise((resolve, reject) => { env.render(name, { _: (str: string) => str, }, (err, res) => { if (err) reject(err); else resolve(res); }); }); } async function get(ctx: Context) { ctx.body = await render('setup.html'); ctx.response.type = 'text/html'; } async function post(ctx: Context) { const { host, port, name, username, password, } = ctx.request.body; let mongourl = 'mongodb://'; if (username) mongourl += `${username}:${password}@`; mongourl += `${host}:${port}/${name}`; try { const Database = await mongodb.MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true, }); const db = Database.db(name); await Promise.all([ db.collection('system').updateOne( { _id: 'server.host' }, { $set: { value: ctx.request.host } }, { upsert: true }, ), db.collection('system').updateOne( { _id: 'server.hostname' }, { $set: { value: ctx.request.hostname } }, { upsert: true }, ), db.collection('system').updateOne( { _id: 'server.url' }, { $set: { value: ctx.request.href } }, { upsert: true }, ), db.collection('system').updateOne( { _id: 'server.port' }, { $set: { value: parseInt(listenPort as string, 10) } }, { upsert: true }, ), ]); fs.ensureDirSync(path.resolve(os.homedir(), '.hydro')); fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ host, port, name, username, password, })); ctx.body = `

This page will reload in 3 secs.

`; setTimeout(() => process.exit(0), 500); } catch (e) { ctx.body = `Error connecting to database: ${e.message}\n${e.stack}`; } } export function load() { const app = new Koa(); const server = http.createServer(app.callback()); app.keys = ['Hydro']; app .use(cache(path.join(os.tmpdir(), 'hydro', 'public'), { maxAge: 365 * 24 * 60 * 60, })) .use(Body()) .use((ctx) => { if (ctx.request.method.toLowerCase() === 'post') return post(ctx); return get(ctx); }); server.listen(listenPort); console.log('Server listening at:', listenPort); }