Files
cloudron-box/src/routes/cloudron.js

203 lines
6.9 KiB
JavaScript
Raw Normal View History

'use strict';
exports = module.exports = {
reboot: reboot,
isRebootRequired: isRebootRequired,
getConfig: getConfig,
getDisks: getDisks,
getUpdateInfo: getUpdateInfo,
update: update,
checkForUpdates: checkForUpdates,
2017-08-07 16:49:37 +02:00
getLogs: getLogs,
getLogStream: getLogStream,
setDashboardAndMailDomain: setDashboardAndMailDomain,
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
};
2018-12-19 10:54:33 -08:00
let assert = require('assert'),
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'),
cloudron = require('../cloudron.js'),
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'),
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');
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
next(new HttpSuccess(202, {}));
2018-11-25 17:02:29 +01:00
cloudron.reboot(function () {});
}
function isRebootRequired(req, res, next) {
cloudron.isRebootRequired(function (error, result) {
if (error) return next(BoxError.toHttpError(error));
next(new HttpSuccess(200, { rebootRequired: result }));
});
}
function getConfig(req, res, next) {
cloudron.getConfig(function (error, cloudronConfig) {
if (error) return next(BoxError.toHttpError(error));
next(new HttpSuccess(200, cloudronConfig));
});
}
function getDisks(req, res, next) {
2019-08-19 13:50:44 -07:00
disks.getDisks(function (error, result) {
if (error) return next(BoxError.toHttpError(error));
2019-10-22 11:11:41 -07:00
next(new HttpSuccess(200, result));
});
}
function update(req, res, next) {
if ('skipBackup' in req.body && typeof req.body.skipBackup !== 'boolean') return next(new HttpError(400, 'skipBackup must be a boolean'));
// this only initiates the update, progress can be checked via the progress route
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));
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(202, { taskId }));
});
}
function getUpdateInfo(req, res, next) {
next(new HttpSuccess(200, { update: updateChecker.getUpdateInfo() }));
}
function checkForUpdates(req, res, next) {
// it can take a while sometimes to get all the app updates one by one
req.clearTimeout();
async.series([
updateChecker.checkAppUpdates,
updateChecker.checkBoxUpdates
], function () {
next(new HttpSuccess(200, { update: updateChecker.getUpdateInfo() }));
});
}
function getLogs(req, res, next) {
2018-06-11 20:09:38 +02:00
assert.strictEqual(typeof req.params.unit, 'string');
var lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id
if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number'));
var options = {
lines: lines,
follow: false,
format: req.query.format || 'json'
};
2018-06-11 20:09:38 +02:00
cloudron.getLogs(req.params.unit, options, function (error, logStream) {
if (error) return next(BoxError.toHttpError(error));
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');
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,
follow: true,
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) {
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));
});
}
function setDashboardAndMailDomain(req, res, next) {
if (!req.body.domain || typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string'));
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) {
if (error) return next(BoxError.toHttpError(error));
2018-12-07 16:39:22 -08:00
next(new HttpSuccess(204, {}));
});
}
function prepareDashboardDomain(req, res, next) {
if (!req.body.domain || typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string'));
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) {
if (error) return next(BoxError.toHttpError(error));
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) {
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 }));
});
}