diff --git a/src/cloudron.js b/src/cloudron.js index 070bab94e..676a88dd0 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -15,6 +15,7 @@ exports = module.exports = { onActivated: onActivated, + setAdmin: setAdmin, checkDiskSpace: checkDiskSpace, @@ -24,10 +25,12 @@ exports = module.exports = { var assert = require('assert'), async = require('async'), + clients = require('./clients.js'), config = require('./config.js'), cron = require('./cron.js'), debug = require('debug')('box:cloudron'), domains = require('./domains.js'), + DomainsError = require('./domains.js').DomainsError, df = require('@sindresorhus/df'), fs = require('fs'), mailer = require('./mailer.js'), @@ -82,7 +85,6 @@ CloudronError.INTERNAL_ERROR = 'Internal Error'; CloudronError.EXTERNAL_ERROR = 'External Error'; CloudronError.BAD_STATE = 'Bad state'; CloudronError.ALREADY_UPTODATE = 'No Update Available'; -CloudronError.NOT_FOUND = 'Not found'; function initialize(callback) { assert.strictEqual(typeof callback, 'function'); @@ -349,3 +351,27 @@ function getStatus(callback) { }); }); } + +function setAdmin(domain, callback) { + assert.strictEqual(typeof domain, 'string'); + assert.strictEqual(typeof callback, 'function'); + + debug('setAdmin domain:%s', domain); + + domains.get(domain, function (error, result) { + if (error && error.reason === DomainsError.NOT_FOUND) return callback(new CloudronError(CloudronError.BAD_FIELD, 'No such domain')); + if (error) return callback(new CloudronError(CloudronError.INTERNAL_ERROR, error)); + + config.setAdminDomain(result.domain); + config.setAdminLocation('my'); + config.setAdminFqdn('my' + (result.config.hyphenatedSubdomains ? '-' : '.') + result.domain); + + clients.addDefaultClients(config.adminOrigin(), function (error) { + if (error) return callback(new CloudronError(CloudronError.INTERNAL_ERROR, error)); + + callback(null); + + configureWebadmin(NOOP_CALLBACK); // ## trigger as task + }); + }); +} diff --git a/src/domains.js b/src/domains.js index 1784127c7..a534dbab1 100644 --- a/src/domains.js +++ b/src/domains.js @@ -12,7 +12,6 @@ module.exports = exports = { renewCerts: renewCerts, fqdn: fqdn, - setAdmin: setAdmin, getDnsRecords: getDnsRecords, upsertDnsRecords: upsertDnsRecords, @@ -36,26 +35,20 @@ module.exports = exports = { }; var assert = require('assert'), - caas = require('./caas.js'), config = require('./config.js'), constants = require('./constants.js'), DatabaseError = require('./databaseerror.js'), debug = require('debug')('box:domains'), domaindb = require('./domaindb.js'), eventlog = require('./eventlog.js'), - path = require('path'), reverseProxy = require('./reverseproxy.js'), ReverseProxyError = reverseProxy.ReverseProxyError, safe = require('safetydance'), - shell = require('./shell.js'), sysinfo = require('./sysinfo.js'), tld = require('tldjs'), util = require('util'), _ = require('underscore'); -var RESTART_CMD = path.join(__dirname, 'scripts/restart.sh'); -var NOOP_CALLBACK = function (error) { if (error) debug(error); }; - function DomainsError(reason, errorOrMessage) { assert.strictEqual(typeof reason, 'string'); assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined'); @@ -479,31 +472,6 @@ function waitForDnsRecord(subdomain, domain, type, value, options, callback) { }); } -function setAdmin(domain, callback) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof callback, 'function'); - - debug('setAdmin domain:%s', domain); - - get(domain, function (error, result) { - if (error) return callback(error); - - var setPtrRecord = config.provider() === 'caas' ? caas.setPtrRecord : function (d, next) { next(); }; - - setPtrRecord(domain, function (error) { - if (error) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, 'Error setting PTR record:' + error.message)); - - config.setAdminDomain(result.domain); - config.setAdminLocation('my'); - config.setAdminFqdn('my' + (result.config.hyphenatedSubdomains ? '-' : '.') + result.domain); - - callback(); - - shell.sudo('restart', [ RESTART_CMD ], {}, NOOP_CALLBACK); - }); - }); -} - // removes all fields that are strictly private and should never be returned by API calls function removePrivateFields(domain) { var result = _.pick(domain, 'domain', 'zoneName', 'provider', 'config', 'tlsConfig', 'fallbackCertificate', 'locked'); diff --git a/src/routes/cloudron.js b/src/routes/cloudron.js index 4f5eb5444..38e256941 100644 --- a/src/routes/cloudron.js +++ b/src/routes/cloudron.js @@ -12,6 +12,7 @@ exports = module.exports = { getLogs: getLogs, getLogStream: getLogStream, getStatus: getStatus, + setAdmin: setAdmin }; var appstore = require('../appstore.js'), @@ -173,6 +174,17 @@ function getLogStream(req, res, next) { }); } +function setAdmin(req, res, next) { + if (!req.body.domain || typeof req.body.domain !== 'string') return next(new HttpError(400, 'domain must be a string')); + + cloudron.setAdmin(req.body.domain, function (error) { + if (error && error.reason === CloudronError.BAD_FIELD) return next(new HttpError(404, error.message)); + if (error) return next(new HttpError(500, error)); + + next(new HttpSuccess(200, status)); + }); +} + function getStatus(req, res, next) { cloudron.getStatus(function (error, status) { if (error) return next(new HttpError(500, error)); diff --git a/src/server.js b/src/server.js index 9be46db47..34a2c4a46 100644 --- a/src/server.js +++ b/src/server.js @@ -121,6 +121,7 @@ function initializeExpressSync() { // cloudron routes router.get ('/api/v1/cloudron/update', cloudronScope, routes.cloudron.getUpdateInfo); router.post('/api/v1/cloudron/update', cloudronScope, routes.cloudron.update); + router.post('/api/v1/cloudron/set_admin', cloudronScope, routes.cloudron.setAdmin); router.post('/api/v1/cloudron/check_for_updates', cloudronScope, routes.cloudron.checkForUpdates); router.get ('/api/v1/cloudron/reboot', cloudronScope, routes.cloudron.isRebootRequired); router.post('/api/v1/cloudron/reboot', cloudronScope, routes.cloudron.reboot); diff --git a/src/setup.js b/src/setup.js index 2270b3ebe..d0a48d598 100644 --- a/src/setup.js +++ b/src/setup.js @@ -143,26 +143,17 @@ function provision(dnsConfig, autoconf, auditSource, callback) { tlsConfig: dnsConfig.tlsConfig || { provider: 'letsencrypt-prod' } }; - async.series([ - domains.add.bind(null, domain, data, auditSource), - mail.addDomain.bind(null, domain) - ], function (error) { + domains.add(domain, data, auditSource, function (error) { if (error && error.reason === DomainsError.BAD_FIELD) return callback(new SetupError(SetupError.BAD_FIELD, error.message)); if (error && error.reason === DomainsError.ALREADY_EXISTS) return callback(new SetupError(SetupError.BAD_FIELD, error.message)); if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); - config.setAdminDomain(domain); // set fqdn only after dns config is valid, otherwise cannot re-setup if we failed - config.setAdminFqdn(adminFqdn); - config.setAdminLocation('my'); - - eventlog.add(eventlog.ACTION_PROVISION, auditSource, { }); - - clients.addDefaultClients(config.adminOrigin(), callback); - async.series([ + mail.addDomain.bind(null, domain), + cloudron.setAdmin.bind(null, domain), // triggers task to setup my. dns/cert/reverseproxy autoprovision.bind(null, autoconf), - cloudron.configureWebadmin - ], NOOP_CALLBACK); + eventlog.add.bind(null, eventlog.ACTION_PROVISION, auditSource, { }) + ], callback); }); }); });