Files
cloudron-box/src/server.js

368 lines
27 KiB
JavaScript
Raw Normal View History

'use strict';
exports = module.exports = {
start: start,
stop: stop
};
2020-02-26 15:49:41 -08:00
let assert = require('assert'),
async = require('async'),
cloudron = require('./cloudron.js'),
constants = require('./constants.js'),
database = require('./database.js'),
debug = require('debug')('box:server'),
eventlog = require('./eventlog.js'),
express = require('express'),
http = require('http'),
middleware = require('./middleware'),
routes = require('./routes/index.js'),
settings = require('./settings.js'),
users = require('./users.js'),
ws = require('ws');
var gHttpServer = null;
function initializeExpressSync() {
var app = express();
var httpServer = http.createServer(app);
const wsServer = new ws.Server({ noServer: true }); // in noServer mode, we have to handle 'upgrade' and call handleUpgrade
var QUERY_LIMIT = '1mb', // max size for json and urlencoded queries (see also client_max_body_size in nginx)
FIELD_LIMIT = 2 * 1024 * 1024; // max fields that can appear in multipart
2020-03-19 13:33:53 -07:00
var REQUEST_TIMEOUT = 20000; // timeout for all requests (see also setTimeout on the httpServer)
var json = middleware.json({ strict: true, limit: QUERY_LIMIT }), // application/json
urlencoded = middleware.urlencoded({ extended: false, limit: QUERY_LIMIT }); // application/x-www-form-urlencoded
2016-05-31 11:14:59 -07:00
app.set('json spaces', 2); // pretty json
// for rate limiting
app.enable('trust proxy');
2017-04-10 14:17:26 +02:00
if (process.env.BOX_ENV !== 'test') {
2019-11-22 11:40:36 +01:00
app.use(middleware.morgan(function (tokens, req, res) {
return [
'Box',
tokens.method(req, res),
tokens.url(req, res).replace(/(access_token=)[^&]+/, '$1' + '<redacted>'),
2019-11-22 11:40:36 +01:00
tokens.status(req, res),
2020-06-18 09:27:09 -07:00
res.errorBody ? res.errorBody.status : '', // attached by connect-lastmile. can be missing when router errors like 404
res.errorBody ? res.errorBody.message : '', // attached by connect-lastmile. can be missing when router errors like 404
2019-11-22 11:40:36 +01:00
tokens['response-time'](req, res), 'ms', '-',
tokens.res(req, res, 'content-length')
].join(' ');
}, {
2017-04-10 14:17:26 +02:00
immediate: false,
// only log failed requests by default
skip: function (req, res) { return res.statusCode < 400; }
}));
}
var router = new express.Router();
router.del = router.delete; // amend router.del for readability further on
app
// the timeout middleware will respond with a 503. the request itself cannot be 'aborted' and will continue
// search for req.clearTimeout in route handlers to see places where this timeout is reset
.use(middleware.timeout(REQUEST_TIMEOUT, { respond: true }))
2017-10-31 12:04:26 -07:00
.use(urlencoded)
.use(middleware.cors({ origins: [ '*' ], allowCredentials: false }))
.use(router)
.use(middleware.lastMile());
2019-12-09 15:02:51 -08:00
// NOTE: routes that use multi-part have to be whitelisted in the reverse proxy
var FILE_SIZE_LIMIT = '256mb', // max file size that can be uploaded (see also client_max_body_size in nginx)
FILE_TIMEOUT = 60 * 1000; // increased timeout for file uploads (1 min)
var multipart = middleware.multipart({ maxFieldsSize: FIELD_LIMIT, limit: FILE_SIZE_LIMIT, timeout: FILE_TIMEOUT });
2020-02-06 16:44:46 +01:00
// to keep routes code short
2020-02-06 14:50:12 +01:00
const password = routes.accesscontrol.passwordAuth;
const token = routes.accesscontrol.tokenAuth;
2020-03-15 11:32:18 -07:00
const authorizeOwner = routes.accesscontrol.authorize(users.ROLE_OWNER);
const authorizeAdmin = routes.accesscontrol.authorize(users.ROLE_ADMIN);
const authorizeUserManager = routes.accesscontrol.authorize(users.ROLE_USER_MANAGER);
// public routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/cloudron/setup', json, routes.provision.providerTokenAuth, routes.provision.setup); // only available until no-domain
router.post('/api/v1/cloudron/restore', json, routes.provision.restore); // only available until activated
router.post('/api/v1/cloudron/activate', json, routes.provision.activate);
router.get ('/api/v1/cloudron/status', routes.provision.getStatus);
router.get ('/api/v1/cloudron/avatar', routes.branding.getCloudronAvatar); // this is a public alias for /api/v1/branding/cloudron_avatar
2020-02-04 14:35:25 +01:00
// login/logout routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/cloudron/login', json, password, routes.cloudron.login);
router.get ('/api/v1/cloudron/logout', routes.cloudron.logout); // this will invalidate the token if any and redirect to /login.html always
router.post('/api/v1/cloudron/password_reset_request', json, routes.cloudron.passwordResetRequest);
router.post('/api/v1/cloudron/password_reset', json, routes.cloudron.passwordReset);
router.post('/api/v1/cloudron/setup_account', json, routes.cloudron.setupAccount);
2020-02-04 14:35:25 +01:00
// developer routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/developer/login', json, password, routes.cloudron.login); // DEPRECATED we should use the regular /api/v1/cloudron/login
// cloudron routes
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/cloudron/update', token, authorizeAdmin, routes.cloudron.getUpdateInfo);
router.post('/api/v1/cloudron/update', json, token, authorizeAdmin, routes.cloudron.update);
router.post('/api/v1/cloudron/prepare_dashboard_domain', json, token, authorizeAdmin, routes.cloudron.prepareDashboardDomain);
router.post('/api/v1/cloudron/set_dashboard_domain', json, token, authorizeAdmin, routes.cloudron.updateDashboardDomain);
2020-07-10 14:10:52 +02:00
router.post('/api/v1/cloudron/renew_certs', json, token, authorizeAdmin, routes.cloudron.renewCerts);
router.post('/api/v1/cloudron/check_for_updates', json, token, authorizeAdmin, routes.cloudron.checkForUpdates);
router.get ('/api/v1/cloudron/reboot', token, authorizeAdmin, routes.cloudron.isRebootRequired);
router.post('/api/v1/cloudron/reboot', json, token, authorizeAdmin, routes.cloudron.reboot);
router.get ('/api/v1/cloudron/graphs', token, authorizeAdmin, routes.graphs.getGraphs);
router.get ('/api/v1/cloudron/disks', token, authorizeAdmin, routes.cloudron.getDisks);
router.get ('/api/v1/cloudron/memory', token, authorizeAdmin, routes.cloudron.getMemory);
router.get ('/api/v1/cloudron/logs/:unit', token, authorizeAdmin, routes.cloudron.getLogs);
router.get ('/api/v1/cloudron/logstream/:unit', token, authorizeAdmin, routes.cloudron.getLogStream);
router.get ('/api/v1/cloudron/eventlog', token, authorizeAdmin, routes.eventlog.list);
router.get ('/api/v1/cloudron/eventlog/:eventId', token, authorizeAdmin, routes.eventlog.get);
router.post('/api/v1/cloudron/sync_external_ldap', json, token, authorizeAdmin, routes.cloudron.syncExternalLdap);
router.get ('/api/v1/cloudron/server_ip', token, authorizeAdmin, routes.cloudron.getServerIp);
// task routes
router.get ('/api/v1/tasks', token, authorizeAdmin, routes.tasks.list);
router.get ('/api/v1/tasks/:taskId', token, authorizeAdmin, routes.tasks.get);
router.get ('/api/v1/tasks/:taskId/logs', token, authorizeAdmin, routes.tasks.getLogs);
router.get ('/api/v1/tasks/:taskId/logstream', token, authorizeAdmin, routes.tasks.getLogStream);
router.post('/api/v1/tasks/:taskId/stop', json, token, authorizeAdmin, routes.tasks.stopTask);
// notification routes
router.get ('/api/v1/notifications', token, routes.notifications.verifyOwnership, routes.notifications.list);
router.get ('/api/v1/notifications/:notificationId', token, routes.notifications.verifyOwnership, routes.notifications.get);
router.post('/api/v1/notifications/:notificationId', json, token, routes.notifications.verifyOwnership, routes.notifications.ack);
// backup routes
router.get ('/api/v1/backups', token, authorizeAdmin, routes.backups.list);
router.post('/api/v1/backups/create', token, authorizeAdmin, routes.backups.startBackup);
router.post('/api/v1/backups/cleanup', json, token, authorizeAdmin, routes.backups.cleanup);
2020-07-28 17:18:47 +02:00
router.get ('/api/v1/backups/check', token, authorizeAdmin, routes.backups.check);
2018-11-19 14:40:32 -08:00
// config route (for dashboard). can return some private configuration unlike status
router.get ('/api/v1/config', token, routes.cloudron.getConfig);
2018-04-26 19:57:44 -07:00
// working off the user behind the provided token
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/profile', token, routes.profile.get);
router.post('/api/v1/profile', json, token, routes.profile.authorize, routes.profile.update);
router.get ('/api/v1/profile/avatar/:identifier', routes.profile.getAvatar); // this is not scoped so it can used directly in img tag
router.post('/api/v1/profile/avatar', json, token, multipart, routes.profile.setAvatar); // avatar is not exposed in LDAP. so it's personal and not locked
2020-07-10 14:10:52 +02:00
router.del ('/api/v1/profile/avatar', token, routes.profile.clearAvatar);
router.post('/api/v1/profile/password', json, token, routes.users.verifyPassword, routes.profile.changePassword);
router.post('/api/v1/profile/twofactorauthentication', json, token, routes.profile.setTwoFactorAuthenticationSecret);
router.post('/api/v1/profile/twofactorauthentication/enable', json, token, routes.profile.enableTwoFactorAuthentication);
router.post('/api/v1/profile/twofactorauthentication/disable', json, token, routes.users.verifyPassword, routes.profile.disableTwoFactorAuthentication);
// app password routes
router.get ('/api/v1/app_passwords', token, routes.appPasswords.list);
router.post('/api/v1/app_passwords', json, token, routes.appPasswords.add);
router.get ('/api/v1/app_passwords/:id', token, routes.appPasswords.get);
router.del ('/api/v1/app_passwords/:id', token, routes.appPasswords.del);
2020-01-31 15:28:42 -08:00
2020-02-07 16:20:05 +01:00
// access tokens
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/tokens', token, routes.tokens.getAll);
router.post('/api/v1/tokens', json, token, routes.tokens.add);
router.get ('/api/v1/tokens/:id', token, routes.tokens.verifyOwnership, routes.tokens.get);
router.del ('/api/v1/tokens/:id', token, routes.tokens.verifyOwnership, routes.tokens.del);
2020-02-07 16:20:05 +01:00
2016-06-02 00:20:33 -07:00
// user routes
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/users', token, authorizeUserManager, routes.users.list);
router.post('/api/v1/users', json, token, authorizeUserManager, routes.users.create);
router.get ('/api/v1/users/:userId', token, authorizeUserManager, routes.users.load, routes.users.get); // this is manage scope because it returns non-restricted fields
router.del ('/api/v1/users/:userId', token, authorizeUserManager, routes.users.load, routes.users.remove);
router.post('/api/v1/users/:userId', json, token, authorizeUserManager, routes.users.load, routes.users.update);
router.post('/api/v1/users/:userId/password', json, token, authorizeUserManager, routes.users.load, routes.users.changePassword);
router.put ('/api/v1/users/:userId/groups', json, token, authorizeUserManager, routes.users.load, routes.users.setGroups);
router.post('/api/v1/users/:userId/send_invite', json, token, authorizeUserManager, routes.users.load, routes.users.sendInvite);
router.post('/api/v1/users/:userId/create_invite', json, token, authorizeUserManager, routes.users.load, routes.users.createInvite);
2020-07-10 07:23:33 -07:00
router.post('/api/v1/users/:userId/avatar', json, token, authorizeUserManager, routes.users.load, multipart, routes.users.setAvatar);
router.del ('/api/v1/users/:userId/avatar', token, authorizeUserManager, routes.users.load, routes.users.clearAvatar);
2016-02-09 13:34:01 -08:00
// Group management
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/groups', token, authorizeUserManager, routes.groups.list);
router.post('/api/v1/groups', json, token, authorizeUserManager, routes.groups.create);
router.get ('/api/v1/groups/:groupId', token, authorizeUserManager, routes.groups.get);
router.put ('/api/v1/groups/:groupId/members', json, token, authorizeUserManager, routes.groups.updateMembers);
router.post('/api/v1/groups/:groupId', json, token, authorizeUserManager, routes.groups.update);
router.del ('/api/v1/groups/:groupId', token, authorizeUserManager, routes.groups.remove);
2016-02-09 13:34:01 -08:00
2019-05-05 13:00:45 -07:00
// appstore and subscription routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/appstore/register_cloudron', json, token, authorizeAdmin, routes.appstore.registerCloudron);
router.post('/api/v1/appstore/user_token', json, token, authorizeAdmin, routes.appstore.createUserToken);
router.get ('/api/v1/appstore/subscription', token, authorizeAdmin, routes.appstore.getSubscription);
router.get ('/api/v1/appstore/apps', token, authorizeAdmin, routes.appstore.getApps);
router.get ('/api/v1/appstore/apps/:appstoreId', token, authorizeAdmin, routes.appstore.getApp);
router.get ('/api/v1/appstore/apps/:appstoreId/versions/:versionId', token, authorizeAdmin, routes.appstore.getAppVersion);
2019-05-04 11:45:03 -07:00
// app routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/apps/install', json, token, authorizeAdmin, routes.apps.install);
router.get ('/api/v1/apps', token, routes.apps.getApps);
router.get ('/api/v1/apps/:id', token, authorizeAdmin, routes.apps.load, routes.apps.getApp);
router.get ('/api/v1/apps/:id/icon', token, routes.apps.load, routes.apps.getAppIcon);
router.post('/api/v1/apps/:id/uninstall', json, token, authorizeAdmin, routes.apps.load, routes.apps.uninstall);
router.post('/api/v1/apps/:id/configure/access_restriction', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAccessRestriction);
router.post('/api/v1/apps/:id/configure/label', json, token, authorizeAdmin, routes.apps.load, routes.apps.setLabel);
router.post('/api/v1/apps/:id/configure/tags', json, token, authorizeAdmin, routes.apps.load, routes.apps.setTags);
router.post('/api/v1/apps/:id/configure/icon', json, token, authorizeAdmin, routes.apps.load, routes.apps.setIcon);
router.post('/api/v1/apps/:id/configure/memory_limit', json, token, authorizeAdmin, routes.apps.load, routes.apps.setMemoryLimit);
router.post('/api/v1/apps/:id/configure/cpu_shares', json, token, authorizeAdmin, routes.apps.load, routes.apps.setCpuShares);
router.post('/api/v1/apps/:id/configure/automatic_backup', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAutomaticBackup);
router.post('/api/v1/apps/:id/configure/automatic_update', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAutomaticUpdate);
router.post('/api/v1/apps/:id/configure/reverse_proxy', json, token, authorizeAdmin, routes.apps.load, routes.apps.setReverseProxyConfig);
router.post('/api/v1/apps/:id/configure/cert', json, token, authorizeAdmin, routes.apps.load, routes.apps.setCertificate);
router.post('/api/v1/apps/:id/configure/debug_mode', json, token, authorizeAdmin, routes.apps.load, routes.apps.setDebugMode);
router.post('/api/v1/apps/:id/configure/mailbox', json, token, authorizeAdmin, routes.apps.load, routes.apps.setMailbox);
router.post('/api/v1/apps/:id/configure/env', json, token, authorizeAdmin, routes.apps.load, routes.apps.setEnvironment);
router.post('/api/v1/apps/:id/configure/data_dir', json, token, authorizeAdmin, routes.apps.load, routes.apps.setDataDir);
router.post('/api/v1/apps/:id/configure/location', json, token, authorizeAdmin, routes.apps.load, routes.apps.setLocation);
router.post('/api/v1/apps/:id/configure/binds', json, token, authorizeAdmin, routes.apps.load, routes.apps.setBinds);
router.post('/api/v1/apps/:id/repair', json, token, authorizeAdmin, routes.apps.load, routes.apps.repair);
router.post('/api/v1/apps/:id/update', json, token, authorizeAdmin, routes.apps.load, routes.apps.update);
router.post('/api/v1/apps/:id/restore', json, token, authorizeAdmin, routes.apps.load, routes.apps.restore);
router.post('/api/v1/apps/:id/import', json, token, authorizeAdmin, routes.apps.load, routes.apps.importApp);
router.post('/api/v1/apps/:id/backup', json, token, authorizeAdmin, routes.apps.load, routes.apps.backup);
router.get ('/api/v1/apps/:id/backups', token, authorizeAdmin, routes.apps.load, routes.apps.listBackups);
router.post('/api/v1/apps/:id/start', json, token, authorizeAdmin, routes.apps.load, routes.apps.start);
router.post('/api/v1/apps/:id/stop', json, token, authorizeAdmin, routes.apps.load, routes.apps.stop);
router.post('/api/v1/apps/:id/restart', json, token, authorizeAdmin, routes.apps.load, routes.apps.restart);
router.get ('/api/v1/apps/:id/logstream', token, authorizeAdmin, routes.apps.load, routes.apps.getLogStream);
router.get ('/api/v1/apps/:id/logs', token, authorizeAdmin, routes.apps.load, routes.apps.getLogs);
router.post('/api/v1/apps/:id/clone', json, token, authorizeAdmin, routes.apps.load, routes.apps.clone);
router.get ('/api/v1/apps/:id/download', token, authorizeAdmin, routes.apps.load, routes.apps.downloadFile);
router.post('/api/v1/apps/:id/upload', json, token, authorizeAdmin, multipart, routes.apps.load, routes.apps.uploadFile);
router.use ('/api/v1/apps/:id/files/*', token, authorizeAdmin, routes.filemanager.proxy);
router.get ('/api/v1/apps/:id/exec', token, authorizeAdmin, routes.apps.load, routes.apps.exec);
// websocket cannot do bearer authentication
router.get ('/api/v1/apps/:id/execws', routes.accesscontrol.websocketAuth.bind(null, users.ROLE_ADMIN), routes.apps.load, routes.apps.execWebSocket);
2020-07-10 14:10:52 +02:00
// branding routes
router.get ('/api/v1/branding/:setting', token, authorizeOwner, routes.branding.get);
router.post('/api/v1/branding/:setting', json, token, authorizeOwner, (req, res, next) => {
2020-03-15 11:32:18 -07:00
return req.params.setting === 'cloudron_avatar' ? multipart(req, res, next) : next();
2020-03-15 16:38:15 -07:00
}, routes.branding.set);
2020-03-15 11:32:18 -07:00
2016-05-06 08:42:27 -07:00
// settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above)
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/settings/:setting', token, authorizeAdmin, routes.settings.get);
router.post('/api/v1/settings/backup_config', json, token, authorizeOwner, routes.settings.setBackupConfig);
router.post('/api/v1/settings/:setting', json, token, authorizeAdmin, routes.settings.set);
2017-06-28 17:06:12 -05:00
// email routes
2020-08-20 23:05:52 -07:00
router.get ('/api/v1/mailserver/eventlog', token, authorizeOwner, routes.mailserver.proxy);
router.get ('/api/v1/mailserver/usage', token, authorizeAdmin, routes.mailserver.proxy);
router.post('/api/v1/mailserver/clear_eventlog', token, authorizeOwner, routes.mailserver.proxy);
router.get ('/api/v1/mailserver/location', token, authorizeAdmin, routes.mailserver.getLocation);
router.post('/api/v1/mailserver/location', json, token, authorizeAdmin, routes.mailserver.setLocation);
router.get ('/api/v1/mailserver/max_email_size', token, authorizeAdmin, routes.mailserver.proxy);
router.post('/api/v1/mailserver/max_email_size', token, authorizeAdmin, routes.mailserver.proxy);
2020-02-07 14:11:52 -08:00
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/mail/:domain', token, authorizeAdmin, routes.mail.getDomain);
router.get ('/api/v1/mail/:domain/status', token, authorizeAdmin, routes.mail.getStatus);
router.post('/api/v1/mail/:domain/mail_from_validation', json, token, authorizeAdmin, routes.mail.setMailFromValidation);
router.post('/api/v1/mail/:domain/catch_all', json, token, authorizeAdmin, routes.mail.setCatchAllAddress);
router.post('/api/v1/mail/:domain/relay', json, token, authorizeAdmin, routes.mail.setMailRelay);
router.post('/api/v1/mail/:domain/enable', json, token, authorizeAdmin, routes.mail.setMailEnabled);
router.post('/api/v1/mail/:domain/dns', json, token, authorizeAdmin, routes.mail.setDnsRecords);
router.post('/api/v1/mail/:domain/send_test_mail', json, token, authorizeAdmin, routes.mail.sendTestMail);
2020-07-15 15:33:53 -07:00
router.get ('/api/v1/mail/:domain/mailbox_count', token, authorizeAdmin, routes.mail.getMailboxCount);
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/mail/:domain/mailboxes', token, authorizeAdmin, routes.mail.listMailboxes);
router.get ('/api/v1/mail/:domain/mailboxes/:name', token, authorizeAdmin, routes.mail.getMailbox);
router.post('/api/v1/mail/:domain/mailboxes', json, token, authorizeAdmin, routes.mail.addMailbox);
router.post('/api/v1/mail/:domain/mailboxes/:name', json, token, authorizeAdmin, routes.mail.updateMailbox);
router.del ('/api/v1/mail/:domain/mailboxes/:name', json, token, authorizeAdmin, routes.mail.removeMailbox);
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/mail/:domain/mailboxes/:name/aliases', token, authorizeAdmin, routes.mail.getAliases);
router.put ('/api/v1/mail/:domain/mailboxes/:name/aliases', json, token, authorizeAdmin, routes.mail.setAliases);
router.get ('/api/v1/mail/:domain/lists', token, authorizeAdmin, routes.mail.getLists);
router.post('/api/v1/mail/:domain/lists', json, token, authorizeAdmin, routes.mail.addList);
router.get ('/api/v1/mail/:domain/lists/:name', token, authorizeAdmin, routes.mail.getList);
router.post('/api/v1/mail/:domain/lists/:name', json, token, authorizeAdmin, routes.mail.updateList);
router.del ('/api/v1/mail/:domain/lists/:name', token, authorizeAdmin, routes.mail.removeList);
// support routes
router.post('/api/v1/support/ticket', json, token, authorizeAdmin, routes.support.canCreateTicket, routes.support.createTicket);
router.get ('/api/v1/support/remote_support', token, authorizeAdmin, routes.support.getRemoteSupport);
router.post('/api/v1/support/remote_support', json, token, authorizeAdmin, routes.support.canEnableRemoteSupport, routes.support.enableRemoteSupport);
2017-10-28 22:18:07 +02:00
// domain routes
2020-07-10 14:10:52 +02:00
router.post('/api/v1/domains', json, token, authorizeAdmin, routes.domains.add);
router.get ('/api/v1/domains', token, routes.domains.getAll);
router.get ('/api/v1/domains/:domain', token, authorizeAdmin, routes.domains.get); // this is manage scope because it returns non-restricted fields
router.put ('/api/v1/domains/:domain', json, token, authorizeAdmin, routes.domains.update);
router.del ('/api/v1/domains/:domain', token, authorizeAdmin, routes.domains.del);
router.get ('/api/v1/domains/:domain/dns_check', token, authorizeAdmin, routes.domains.checkDnsRecords);
2017-10-28 22:18:07 +02:00
2018-11-15 19:59:08 +01:00
// addon routes
2020-07-10 14:10:52 +02:00
router.get ('/api/v1/services', token, authorizeAdmin, routes.services.getAll);
router.get ('/api/v1/services/:service', token, authorizeAdmin, routes.services.get);
router.post('/api/v1/services/:service', json, token, authorizeAdmin, routes.services.configure);
router.get ('/api/v1/services/:service/logs', token, authorizeAdmin, routes.services.getLogs);
router.get ('/api/v1/services/:service/logstream', token, authorizeAdmin, routes.services.getLogStream);
router.post('/api/v1/services/:service/restart', json, token, authorizeAdmin, routes.services.restart);
2018-11-15 19:59:08 +01:00
2016-06-01 16:31:47 -07:00
// disable server socket "idle" timeout. we use the timeout middleware to handle timeouts on a route level
2016-06-01 17:33:04 -07:00
// we rely on nginx for timeouts on the TCP level (see client_header_timeout)
2016-01-18 12:20:09 -08:00
httpServer.setTimeout(0);
// upgrade handler
httpServer.on('upgrade', function (req, socket, head) {
// create a node response object for express
var res = new http.ServerResponse({});
res.assignSocket(socket);
2017-08-17 11:56:51 +02:00
if (req.headers.upgrade === 'websocket') {
res.handleUpgrade = function (callback) {
wsServer.handleUpgrade(req, socket, head, callback);
};
2017-08-17 11:56:51 +02:00
} else {
res.sendUpgradeHandshake = function () { // could extend express.response as well
socket.write('HTTP/1.1 101 TCP Handshake\r\n' +
'Upgrade: tcp\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
};
}
// route through express middleware. if we provide no callback, express will provide a 'finalhandler'
// TODO: it's not clear if socket needs to be destroyed
app(req, res);
});
return httpServer;
}
function start(callback) {
assert.strictEqual(typeof callback, 'function');
assert.strictEqual(gHttpServer, null, 'Server is already up and running.');
debug('==========================================');
debug(` Cloudron ${constants.VERSION} `);
debug('==========================================');
gHttpServer = initializeExpressSync();
async.series([
database.initialize,
settings.initCache, // pre-load very often used settings
2017-01-09 12:35:39 -08:00
cloudron.initialize,
2019-07-25 15:43:51 -07:00
gHttpServer.listen.bind(gHttpServer, constants.PORT, '127.0.0.1'),
eventlog.add.bind(null, eventlog.ACTION_START, { userId: null, username: 'boot' }, { version: constants.VERSION })
], callback);
}
function stop(callback) {
assert.strictEqual(typeof callback, 'function');
if (!gHttpServer) return callback(null);
async.series([
cloudron.uninitialize,
database.uninitialize,
gHttpServer.close.bind(gHttpServer),
], function (error) {
if (error) return callback(error);
gHttpServer = null;
callback(null);
});
}