#!/usr/bin/env node 'use strict'; const fs = require('fs'), ldap = require('./src/ldap.js'), oidc = require('./src/oidc.js'), paths = require('./src/paths.js'), proxyAuth = require('./src/proxyauth.js'), safe = require('safetydance'), server = require('./src/server.js'), settings = require('./src/settings.js'), directoryServer = require('./src/directoryserver.js'); let logFd; async function setupLogging() { if (process.env.BOX_ENV === 'test') return; logFd = fs.openSync(paths.BOX_LOG_FILE, 'a'); // we used to write using a stream before but it caches internally and there is no way to flush it when things crash process.stdout.write = process.stderr.write = function (...args) { const callback = typeof args[args.length-1] === 'function' ? args.pop() : function () {}; // callback is required for fs.write fs.write.apply(fs, [logFd, ...args, callback]); }; } // this is also used as the 'uncaughtException' handler which can only have synchronous functions function exitSync(status) { if (status.error) fs.write(logFd, status.error.stack + '\n', function () {}); fs.fsyncSync(logFd); fs.closeSync(logFd); process.exit(status.code); } async function startServers() { await setupLogging(); await server.start(); // do this first since it also inits the database await proxyAuth.start(); await ldap.start(); const conf = await settings.getDirectoryServerConfig(); if (conf.enabled) await directoryServer.start(); } async function main() { const [error] = await safe(startServers()); if (error) return exitSync({ error: new Error(`Error starting server: ${JSON.stringify(error)}`), code: 1 }); // require this here so that logging handler is already setup const debug = require('debug')('box:box'); process.on('SIGHUP', async function () { debug('Received SIGHUP. Re-reading configs.'); const conf = await settings.getDirectoryServerConfig(); if (conf.enabled) await directoryServer.checkCertificate(); }); process.on('SIGINT', async function () { debug('Received SIGINT. Shutting down.'); await proxyAuth.stop(); await server.stop(); await directoryServer.stop(); await ldap.stop(); await oidc.stop(); setTimeout(process.exit.bind(process), 3000); }); process.on('SIGTERM', async function () { debug('Received SIGTERM. Shutting down.'); await proxyAuth.stop(); await server.stop(); await directoryServer.stop(); await ldap.stop(); await oidc.stop(); setTimeout(process.exit.bind(process), 3000); }); process.on('uncaughtException', (error) => exitSync({ error, code: 1 })); console.log(`Cloudron is up and running. Logs are at ${paths.BOX_LOG_FILE}`); // this goes to journalctl } main();