diff --git a/dashboard/src/js/client.js b/dashboard/src/js/client.js index b5b976a1c..9eae61391 100644 --- a/dashboard/src/js/client.js +++ b/dashboard/src/js/client.js @@ -1148,7 +1148,7 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout }; Client.prototype.getTrustedIps = function (callback) { - get('/api/v1/network/trusted_ips', null, function (error, data, status) { + get('/api/v1/reverseproxy/trusted_ips', null, function (error, data, status) { if (error) return callback(error); if (status !== 200) return callback(new ClientError(status, data)); callback(null, data.trustedIps); @@ -1156,7 +1156,7 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout }; Client.prototype.setTrustedIps = function (trustedIps, callback) { - post('/api/v1/network/trusted_ips', { trustedIps: trustedIps }, null, function (error, data, status) { + post('/api/v1/reverseproxy/trusted_ips', { trustedIps: trustedIps }, null, function (error, data, status) { if (error) return callback(error); if (status !== 200) return callback(new ClientError(status, data)); @@ -2765,7 +2765,7 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout }; Client.prototype.renewCerts = function (options, callback) { - post('/api/v1/cloudron/renew_certs', options, null, function (error, data, status) { + post('/api/v1/reverseproxy/renew_certs', options, null, function (error, data, status) { if (error) return callback(error); if (status !== 202) return callback(new ClientError(status, data)); diff --git a/src/cloudron.js b/src/cloudron.js index 3da217b27..d9387cb70 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -16,7 +16,6 @@ exports = module.exports = { prepareDashboardDomain, setDashboardDomain, updateDashboardDomain, - renewCerts, updateDiskUsage, @@ -299,15 +298,6 @@ async function updateDashboardDomain(domain, auditSource) { await oidc.start(); } -async function renewCerts(options, auditSource) { - assert.strictEqual(typeof options, 'object'); - assert.strictEqual(typeof auditSource, 'object'); - - const taskId = await tasks.add(tasks.TASK_CHECK_CERTS, [ options, auditSource ]); - tasks.startTask(taskId, {}); - return taskId; -} - async function setupDnsAndCert(subdomain, domain, auditSource, progressCallback) { assert.strictEqual(typeof subdomain, 'string'); assert.strictEqual(typeof domain, 'string'); diff --git a/src/reverseproxy.js b/src/reverseproxy.js index f086f4675..285ef0fd8 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -13,6 +13,7 @@ exports = module.exports = { ensureCertificate, + startRenewCerts, checkCerts, // the 'configure' functions ensure a certificate and generate nginx config @@ -55,6 +56,7 @@ const acme2 = require('./acme2.js'), safe = require('safetydance'), settings = require('./settings.js'), shell = require('./shell.js'), + tasks = require('./tasks.js'), util = require('util'), validator = require('validator'); @@ -676,6 +678,15 @@ async function checkCerts(options, auditSource, progressCallback) { await cleanupCerts(locations, auditSource, progressCallback); } +async function startRenewCerts(options, auditSource) { + assert.strictEqual(typeof options, 'object'); + assert.strictEqual(typeof auditSource, 'object'); + + const taskId = await tasks.add(tasks.TASK_CHECK_CERTS, [ options, auditSource ]); + tasks.startTask(taskId, {}); + return taskId; +} + function removeAppConfigs() { debug('removeAppConfigs: removing app nginx configs'); diff --git a/src/routes/cloudron.js b/src/routes/cloudron.js index 222fd347b..78122a96b 100644 --- a/src/routes/cloudron.js +++ b/src/routes/cloudron.js @@ -17,7 +17,6 @@ exports = module.exports = { getLogStream, updateDashboardDomain, prepareDashboardDomain, - renewCerts, getLanguages, getSystemGraphs, getPlatformStatus, @@ -272,15 +271,6 @@ async function prepareDashboardDomain(req, res, next) { next(new HttpSuccess(202, { taskId })); } -async function renewCerts(req, res, next) { - if ('rebuild' in req.body && typeof req.body.rebuild !== 'boolean') return next(new HttpError(400, 'rebuild must be a boolean')); - - const [error, taskId] = await safe(cloudron.renewCerts(req.body, AuditSource.fromRequest(req))); - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(202, { taskId })); -} - async function getLanguages(req, res, next) { const [error, languages] = await safe(translation.getLanguages()); if (error) return next(new BoxError.toHttpError(error)); diff --git a/src/routes/index.js b/src/routes/index.js index d1c243af1..a43ac6655 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -22,6 +22,7 @@ exports = module.exports = { oidc: require('./oidc.js'), profile: require('./profile.js'), provision: require('./provision.js'), + reverseProxy: require('./reverseProxy.js'), services: require('./services.js'), settings: require('./settings.js'), support: require('./support.js'), diff --git a/src/routes/network.js b/src/routes/network.js index 6244c6289..7a41ad69d 100644 --- a/src/routes/network.js +++ b/src/routes/network.js @@ -4,9 +4,6 @@ exports = module.exports = { getBlocklist, setBlocklist, - getTrustedIps, - setTrustedIps, - getDynamicDns, setDynamicDns, @@ -49,24 +46,6 @@ async function setBlocklist(req, res, next) { next(new HttpSuccess(200, {})); } -async function getTrustedIps(req, res, next) { - const [error, trustedIps] = await safe(reverseProxy.getTrustedIps()); - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(200, { trustedIps })); -} - -async function setTrustedIps(req, res, next) { - assert.strictEqual(typeof req.body, 'object'); - - if (typeof req.body.trustedIps !== 'string') return next(new HttpError(400, 'trustedIps must be a string')); - - const [error] = await safe(reverseProxy.setTrustedIps(req.body.trustedIps, AuditSource.fromRequest(req))); - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(200, {})); -} - async function getDynamicDns(req, res, next) { const [error, enabled] = await safe(network.getDynamicDns()); if (error) return next(BoxError.toHttpError(error)); diff --git a/src/routes/reverseproxy.js b/src/routes/reverseproxy.js new file mode 100644 index 000000000..cfeba7679 --- /dev/null +++ b/src/routes/reverseproxy.js @@ -0,0 +1,43 @@ +'use strict'; + +exports = module.exports = { + getTrustedIps, + setTrustedIps, + + renewCerts, +}; + +const assert = require('assert'), + AuditSource = require('../auditsource.js'), + BoxError = require('../boxerror.js'), + HttpError = require('connect-lastmile').HttpError, + HttpSuccess = require('connect-lastmile').HttpSuccess, + reverseProxy = require('../reverseproxy.js'), + safe = require('safetydance'); + +async function getTrustedIps(req, res, next) { + const [error, trustedIps] = await safe(reverseProxy.getTrustedIps()); + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(200, { trustedIps })); +} + +async function setTrustedIps(req, res, next) { + assert.strictEqual(typeof req.body, 'object'); + + if (typeof req.body.trustedIps !== 'string') return next(new HttpError(400, 'trustedIps must be a string')); + + const [error] = await safe(reverseProxy.setTrustedIps(req.body.trustedIps, AuditSource.fromRequest(req))); + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(200, {})); +} + +async function renewCerts(req, res, next) { + if ('rebuild' in req.body && typeof req.body.rebuild !== 'boolean') return next(new HttpError(400, 'rebuild must be a boolean')); + + const [error, taskId] = await safe(reverseProxy.startRenewCerts(req.body, AuditSource.fromRequest(req))); + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(202, { taskId })); +} diff --git a/src/server.js b/src/server.js index 9c80202b9..278cc4837 100644 --- a/src/server.js +++ b/src/server.js @@ -115,7 +115,7 @@ async function initializeExpressSync() { 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); - router.post('/api/v1/cloudron/renew_certs', json, token, authorizeAdmin, routes.cloudron.renewCerts); + 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.cloudron.getSystemGraphs); @@ -309,11 +309,14 @@ async function initializeExpressSync() { router.get ('/api/v1/branding/footer', token, authorizeOwner, routes.branding.getFooter); router.post('/api/v1/branding/footer', json, token, authorizeOwner, routes.branding.setFooter); + // reverseproxy routes + router.post('/api/v1/reverseproxy/renew_certs', json, token, authorizeAdmin, routes.reverseProxy.renewCerts); + router.get ('/api/v1/reverseproxy/trusted_ips', token, authorizeAdmin, routes.reverseProxy.getTrustedIps); + router.post('/api/v1/reverseproxy/trusted_ips', json, token, authorizeAdmin, routes.reverseProxy.setTrustedIps); + // network routes router.get ('/api/v1/network/blocklist', token, authorizeOwner, routes.network.getBlocklist); router.post('/api/v1/network/blocklist', json, token, authorizeOwner, routes.network.setBlocklist); - router.get ('/api/v1/network/trusted_ips', token, authorizeAdmin, routes.network.getTrustedIps); - router.post('/api/v1/network/trusted_ips', json, token, authorizeAdmin, routes.network.setTrustedIps); router.get ('/api/v1/network/dynamic_dns', token, authorizeAdmin, routes.network.getDynamicDns); router.post('/api/v1/network/dynamic_dns', json, token, authorizeAdmin, routes.network.setDynamicDns); router.get ('/api/v1/network/ipv4_config', token, authorizeAdmin, routes.network.getIPv4Config);