2015-07-20 00:09:47 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = {
|
|
|
|
|
reboot: reboot,
|
2018-11-25 17:02:01 +01:00
|
|
|
isRebootRequired: isRebootRequired,
|
2015-07-20 00:09:47 -07:00
|
|
|
getConfig: getConfig,
|
2017-04-07 18:45:36 +02:00
|
|
|
getDisks: getDisks,
|
2018-06-28 17:43:20 -07:00
|
|
|
getUpdateInfo: getUpdateInfo,
|
2015-07-20 00:09:47 -07:00
|
|
|
update: update,
|
2017-04-18 15:15:35 -07:00
|
|
|
checkForUpdates: checkForUpdates,
|
2017-08-07 16:49:37 +02:00
|
|
|
getLogs: getLogs,
|
2018-11-11 09:29:11 -08:00
|
|
|
getLogStream: getLogStream,
|
2019-02-26 19:43:18 -08:00
|
|
|
setDashboardAndMailDomain: setDashboardAndMailDomain,
|
2018-12-15 15:27:16 -08:00
|
|
|
prepareDashboardDomain: prepareDashboardDomain,
|
2019-08-29 17:19:51 +02:00
|
|
|
renewCerts: renewCerts,
|
2019-11-07 10:41:15 -08:00
|
|
|
getServerIp: getServerIp,
|
2019-08-29 17:19:51 +02:00
|
|
|
syncExternalLdap: syncExternalLdap
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2018-12-19 10:54:33 -08:00
|
|
|
let assert = require('assert'),
|
2016-06-07 20:24:41 -07:00
|
|
|
async = require('async'),
|
2019-03-25 15:07:06 -07:00
|
|
|
auditSource = require('../auditsource.js'),
|
2019-10-22 14:06:19 -07:00
|
|
|
BoxError = require('../boxerror.js'),
|
2015-07-20 00:09:47 -07:00
|
|
|
cloudron = require('../cloudron.js'),
|
2019-05-14 19:20:45 -07:00
|
|
|
custom = require('../custom.js'),
|
2019-08-19 13:50:44 -07:00
|
|
|
disks = require('../disks.js'),
|
2019-10-25 15:58:11 -07:00
|
|
|
externalLdap = require('../externalldap.js'),
|
2015-07-20 00:09:47 -07:00
|
|
|
HttpError = require('connect-lastmile').HttpError,
|
|
|
|
|
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
2019-11-07 10:41:15 -08:00
|
|
|
sysinfo = require('../sysinfo.js'),
|
2018-07-31 11:35:23 -07:00
|
|
|
updater = require('../updater.js'),
|
2019-10-23 09:39:26 -07:00
|
|
|
updateChecker = require('../updatechecker.js');
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
function reboot(req, res, next) {
|
2018-11-25 17:02:29 +01:00
|
|
|
// Finish the request, to let the appstore know we triggered the reboot
|
2015-07-20 00:09:47 -07:00
|
|
|
next(new HttpSuccess(202, {}));
|
|
|
|
|
|
2018-11-25 17:02:29 +01:00
|
|
|
cloudron.reboot(function () {});
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2018-11-25 17:02:01 +01:00
|
|
|
function isRebootRequired(req, res, next) {
|
|
|
|
|
cloudron.isRebootRequired(function (error, result) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2018-11-25 17:02:01 +01:00
|
|
|
|
|
|
|
|
next(new HttpSuccess(200, { rebootRequired: result }));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
function getConfig(req, res, next) {
|
|
|
|
|
cloudron.getConfig(function (error, cloudronConfig) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
next(new HttpSuccess(200, cloudronConfig));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-07 18:45:36 +02:00
|
|
|
function getDisks(req, res, next) {
|
2019-08-19 13:50:44 -07:00
|
|
|
disks.getDisks(function (error, result) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2019-10-22 11:11:41 -07:00
|
|
|
|
2017-04-07 18:45:36 +02:00
|
|
|
next(new HttpSuccess(200, result));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
function update(req, res, next) {
|
2019-05-12 13:28:53 -07:00
|
|
|
if ('skipBackup' in req.body && typeof req.body.skipBackup !== 'boolean') return next(new HttpError(400, 'skipBackup must be a boolean'));
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
// this only initiates the update, progress can be checked via the progress route
|
2019-05-12 13:28:53 -07:00
|
|
|
updater.updateToLatest(req.body, auditSource.fromRequest(req), function (error, taskId) {
|
2019-10-23 09:39:26 -07:00
|
|
|
if (error && error.reason === BoxError.NOT_FOUND) return next(new HttpError(422, error.message));
|
|
|
|
|
if (error && error.reason === BoxError.BAD_STATE) return next(new HttpError(409, error.message));
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return next(new HttpError(500, error));
|
|
|
|
|
|
2018-12-08 18:50:06 -08:00
|
|
|
next(new HttpSuccess(202, { taskId }));
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-28 17:43:20 -07:00
|
|
|
function getUpdateInfo(req, res, next) {
|
|
|
|
|
next(new HttpSuccess(200, { update: updateChecker.getUpdateInfo() }));
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-07 20:24:41 -07:00
|
|
|
function checkForUpdates(req, res, next) {
|
2018-11-13 10:38:15 -08:00
|
|
|
// it can take a while sometimes to get all the app updates one by one
|
|
|
|
|
req.clearTimeout();
|
|
|
|
|
|
2016-06-07 20:24:41 -07:00
|
|
|
async.series([
|
|
|
|
|
updateChecker.checkAppUpdates,
|
|
|
|
|
updateChecker.checkBoxUpdates
|
|
|
|
|
], function () {
|
|
|
|
|
next(new HttpSuccess(200, { update: updateChecker.getUpdateInfo() }));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 15:15:35 -07:00
|
|
|
function getLogs(req, res, next) {
|
2018-06-11 20:09:38 +02:00
|
|
|
assert.strictEqual(typeof req.params.unit, 'string');
|
|
|
|
|
|
2019-01-08 12:10:53 -08:00
|
|
|
var lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id
|
2017-04-18 15:15:35 -07:00
|
|
|
if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number'));
|
|
|
|
|
|
2017-04-18 20:32:57 -07:00
|
|
|
var options = {
|
|
|
|
|
lines: lines,
|
|
|
|
|
follow: false,
|
2019-01-08 12:10:53 -08:00
|
|
|
format: req.query.format || 'json'
|
2017-04-18 20:32:57 -07:00
|
|
|
};
|
|
|
|
|
|
2018-06-11 20:09:38 +02:00
|
|
|
cloudron.getLogs(req.params.unit, options, function (error, logStream) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2017-04-18 15:15:35 -07:00
|
|
|
|
|
|
|
|
res.writeHead(200, {
|
|
|
|
|
'Content-Type': 'application/x-logs',
|
|
|
|
|
'Content-Disposition': 'attachment; filename="log.txt"',
|
|
|
|
|
'Cache-Control': 'no-cache',
|
|
|
|
|
'X-Accel-Buffering': 'no' // disable nginx buffering
|
|
|
|
|
});
|
|
|
|
|
logStream.pipe(res);
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-08-07 16:49:37 +02:00
|
|
|
|
|
|
|
|
function getLogStream(req, res, next) {
|
2018-06-11 20:09:38 +02:00
|
|
|
assert.strictEqual(typeof req.params.unit, 'string');
|
|
|
|
|
|
2019-01-08 12:10:53 -08:00
|
|
|
var lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id
|
2017-08-07 16:49:37 +02:00
|
|
|
if (isNaN(lines)) return next(new HttpError(400, 'lines must be a valid number'));
|
|
|
|
|
|
|
|
|
|
function sse(id, data) { return 'id: ' + id + '\ndata: ' + data + '\n\n'; }
|
|
|
|
|
|
|
|
|
|
if (req.headers.accept !== 'text/event-stream') return next(new HttpError(400, 'This API call requires EventStream'));
|
|
|
|
|
|
|
|
|
|
var options = {
|
|
|
|
|
lines: lines,
|
2017-08-07 18:26:03 +02:00
|
|
|
follow: true,
|
2019-01-08 12:10:53 -08:00
|
|
|
format: req.query.format || 'json'
|
2017-08-07 16:49:37 +02:00
|
|
|
};
|
|
|
|
|
|
2018-06-11 20:09:38 +02:00
|
|
|
cloudron.getLogs(req.params.unit, options, function (error, logStream) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2017-08-07 16:49:37 +02:00
|
|
|
|
|
|
|
|
res.writeHead(200, {
|
|
|
|
|
'Content-Type': 'text/event-stream',
|
|
|
|
|
'Cache-Control': 'no-cache',
|
|
|
|
|
'Connection': 'keep-alive',
|
|
|
|
|
'X-Accel-Buffering': 'no', // disable nginx buffering
|
|
|
|
|
'Access-Control-Allow-Origin': '*'
|
|
|
|
|
});
|
|
|
|
|
res.write('retry: 3000\n');
|
|
|
|
|
res.on('close', logStream.close);
|
|
|
|
|
logStream.on('data', function (data) {
|
|
|
|
|
var obj = JSON.parse(data);
|
|
|
|
|
res.write(sse(obj.monotonicTimestamp, JSON.stringify(obj))); // send timestamp as id
|
|
|
|
|
});
|
|
|
|
|
logStream.on('end', res.end.bind(res));
|
|
|
|
|
logStream.on('error', res.end.bind(res, null));
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-11-11 09:29:11 -08:00
|
|
|
|
2019-02-26 19:43:18 -08:00
|
|
|
function setDashboardAndMailDomain(req, res, next) {
|
2018-12-07 16:15:21 -08:00
|
|
|
if (!req.body.domain || typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string'));
|
|
|
|
|
|
2019-05-14 19:20:45 -07:00
|
|
|
if (!custom.spec().domains.changeDashboardDomain) return next(new HttpError(405, 'feature disabled by admin'));
|
|
|
|
|
|
2019-03-25 15:07:06 -07:00
|
|
|
cloudron.setDashboardAndMailDomain(req.body.domain, auditSource.fromRequest(req), function (error) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2018-12-07 16:15:21 -08:00
|
|
|
|
2018-12-07 16:39:22 -08:00
|
|
|
next(new HttpSuccess(204, {}));
|
2018-12-07 16:15:21 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 15:27:16 -08:00
|
|
|
function prepareDashboardDomain(req, res, next) {
|
2018-12-14 09:57:28 -08:00
|
|
|
if (!req.body.domain || typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string'));
|
|
|
|
|
|
2019-05-14 19:20:45 -07:00
|
|
|
if (!custom.spec().domains.changeDashboardDomain) return next(new HttpError(405, 'feature disabled by admin'));
|
|
|
|
|
|
2019-03-25 15:07:06 -07:00
|
|
|
cloudron.prepareDashboardDomain(req.body.domain, auditSource.fromRequest(req), function (error, taskId) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2018-12-14 09:57:28 -08:00
|
|
|
|
|
|
|
|
next(new HttpSuccess(202, { taskId }));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-10 20:20:53 -08:00
|
|
|
function renewCerts(req, res, next) {
|
2019-03-25 15:07:06 -07:00
|
|
|
cloudron.renewCerts({ domain: req.body.domain || null }, auditSource.fromRequest(req), function (error, taskId) {
|
2019-10-24 18:05:14 -07:00
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
2018-12-10 20:20:53 -08:00
|
|
|
|
2018-12-11 10:16:38 -08:00
|
|
|
next(new HttpSuccess(202, { taskId }));
|
2018-12-10 20:20:53 -08:00
|
|
|
});
|
|
|
|
|
}
|
2019-08-29 17:19:51 +02:00
|
|
|
|
|
|
|
|
function syncExternalLdap(req, res, next) {
|
2019-10-25 15:58:11 -07:00
|
|
|
externalLdap.startSyncer(function (error, taskId) {
|
2019-08-29 17:19:51 +02:00
|
|
|
if (error) return next(new HttpError(500, error.message));
|
|
|
|
|
|
|
|
|
|
next(new HttpSuccess(202, { taskId: taskId }));
|
|
|
|
|
});
|
|
|
|
|
}
|
2019-11-07 10:41:15 -08:00
|
|
|
|
|
|
|
|
function getServerIp(req, res, next) {
|
|
|
|
|
sysinfo.getServerIp(function (error, ip) {
|
|
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
|
|
|
|
|
|
|
|
|
next(new HttpSuccess(200, { ip }));
|
|
|
|
|
});
|
|
|
|
|
}
|