dab9bcb9db
This is used for apps which are using OpenID to login but still need to be able to verify the users password or app password
101 lines
3.4 KiB
JavaScript
Executable File
101 lines
3.4 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import constants from './src/constants.js';
|
|
import fs from 'node:fs';
|
|
import ldapServer from './src/ldapserver.js';
|
|
import net from 'node:net';
|
|
import authServer from './src/authserver.js';
|
|
import oidcServer from './src/oidcserver.js';
|
|
import paths from './src/paths.js';
|
|
import proxyAuth from './src/proxyauth.js';
|
|
import safe from '@cloudron/safetydance';
|
|
import server from './src/server.js';
|
|
import directoryServer from './src/directoryserver.js';
|
|
import logger from './src/logger.js';
|
|
|
|
const { log } = logger('box');
|
|
|
|
let logFd;
|
|
|
|
async function setupLogging() {
|
|
if (constants.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]);
|
|
};
|
|
}
|
|
|
|
// happy eyeballs workaround. when there is no ipv6, nodejs timesout prematurely since the default for ipv4 is just 250ms
|
|
// https://github.com/nodejs/node/issues/54359
|
|
async function setupNetworking() {
|
|
net.setDefaultAutoSelectFamilyAttemptTimeout(2500);
|
|
}
|
|
|
|
// this is also used as the 'uncaughtException' handler which can only have synchronous functions
|
|
function exitSync(status) {
|
|
const ts = new Date().toISOString();
|
|
if (status.message) fs.write(logFd, `${ts} ${status.message}\n`, function () {});
|
|
const msg = status.error.stack.replace(/\n/g, `\n${ts} `); // prefix each line with ts
|
|
if (status.error) fs.write(logFd, `${ts} ${msg}\n`, function () {});
|
|
fs.fsyncSync(logFd);
|
|
fs.closeSync(logFd);
|
|
process.exit(status.code);
|
|
}
|
|
|
|
async function startServers() {
|
|
await setupLogging();
|
|
await setupNetworking();
|
|
await server.start(); // do this first since it also inits the database
|
|
await proxyAuth.start();
|
|
await ldapServer.start();
|
|
|
|
const conf = await directoryServer.getConfig();
|
|
if (conf.enabled) await directoryServer.start();
|
|
}
|
|
|
|
const [error] = await safe(startServers());
|
|
if (error) exitSync({ error, code: 1, message: 'Error starting servers' });
|
|
|
|
process.on('SIGHUP', async function () {
|
|
log('Received SIGHUP. Re-reading configs.');
|
|
const conf = await directoryServer.getConfig();
|
|
if (conf.enabled) await directoryServer.checkCertificate();
|
|
});
|
|
|
|
process.on('SIGINT', async function () {
|
|
log('Received SIGINT. Shutting down.');
|
|
|
|
await proxyAuth.stop();
|
|
await server.stop();
|
|
await directoryServer.stop();
|
|
await ldapServer.stop();
|
|
await oidcServer.stop();
|
|
await authServer.stop();
|
|
|
|
setTimeout(() => {
|
|
log('Shutdown complete');
|
|
process.exit();
|
|
}, 2000); // need to wait for the task processes to die
|
|
});
|
|
|
|
process.on('SIGTERM', async function () {
|
|
log('Received SIGTERM. Shutting down.');
|
|
|
|
await proxyAuth.stop();
|
|
await server.stop();
|
|
await directoryServer.stop();
|
|
await ldapServer.stop();
|
|
await oidcServer.stop();
|
|
await authServer.stop();
|
|
|
|
setTimeout(() => {
|
|
log('Shutdown complete');
|
|
process.exit();
|
|
}, 2000); // need to wait for the task processes to die
|
|
});
|
|
|
|
process.on('uncaughtException', (uncaughtError) => exitSync({ error: uncaughtError, code: 1, message: 'From uncaughtException handler.' }));
|