diff --git a/src/setup.js b/src/provision.js similarity index 79% rename from src/setup.js rename to src/provision.js index dff95d0c8..c744f8477 100644 --- a/src/setup.js +++ b/src/provision.js @@ -1,11 +1,11 @@ 'use strict'; exports = module.exports = { - provision: provision, + setup: setup, restore: restore, activate: activate, - SetupError: SetupError + ProvisionError: ProvisionError }; var assert = require('assert'), @@ -16,7 +16,7 @@ var assert = require('assert'), constants = require('./constants.js'), clients = require('./clients.js'), cloudron = require('./cloudron.js'), - debug = require('debug')('box:setup'), + debug = require('debug')('box:provision'), domains = require('./domains.js'), DomainsError = domains.DomainsError, eventlog = require('./eventlog.js'), @@ -37,7 +37,7 @@ var RESTART_CMD = path.join(__dirname, 'scripts/restart.sh'); var NOOP_CALLBACK = function (error) { if (error) debug(error); }; -function SetupError(reason, errorOrMessage) { +function ProvisionError(reason, errorOrMessage) { assert.strictEqual(typeof reason, 'string'); assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined'); @@ -55,13 +55,13 @@ function SetupError(reason, errorOrMessage) { this.nestedError = errorOrMessage; } } -util.inherits(SetupError, Error); -SetupError.BAD_FIELD = 'Field error'; -SetupError.BAD_STATE = 'Bad State'; -SetupError.ALREADY_SETUP = 'Already Setup'; -SetupError.INTERNAL_ERROR = 'Internal Error'; -SetupError.EXTERNAL_ERROR = 'External Error'; -SetupError.ALREADY_PROVISIONED = 'Already Provisioned'; +util.inherits(ProvisionError, Error); +ProvisionError.BAD_FIELD = 'Field error'; +ProvisionError.BAD_STATE = 'Bad State'; +ProvisionError.ALREADY_SETUP = 'Already Setup'; +ProvisionError.INTERNAL_ERROR = 'Internal Error'; +ProvisionError.EXTERNAL_ERROR = 'External Error'; +ProvisionError.ALREADY_PROVISIONED = 'Already Provisioned'; function autoprovision(autoconf, callback) { assert.strictEqual(typeof autoconf, 'object'); @@ -89,7 +89,7 @@ function autoprovision(autoconf, callback) { return iteratorDone(); } }, function (error) { - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); callback(null); }); @@ -111,22 +111,22 @@ function unprovision(callback) { ], callback); } -function provision(dnsConfig, autoconf, auditSource, callback) { +function setup(dnsConfig, autoconf, auditSource, callback) { assert.strictEqual(typeof dnsConfig, 'object'); assert.strictEqual(typeof autoconf, 'object'); assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); users.isActivated(function (error, activated) { - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); - if (activated) return callback(new SetupError(SetupError.ALREADY_SETUP)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); + if (activated) return callback(new ProvisionError(ProvisionError.ALREADY_SETUP)); unprovision(function (error) { - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); let webadminStatus = cloudron.getWebadminStatus(); - if (webadminStatus.configuring || webadminStatus.restore.active) return callback(new SetupError(SetupError.BAD_STATE, 'Already restoring or configuring')); + if (webadminStatus.configuring || webadminStatus.restore.active) return callback(new ProvisionError(ProvisionError.BAD_STATE, 'Already restoring or configuring')); const domain = dnsConfig.domain.toLowerCase(); const zoneName = dnsConfig.zoneName ? dnsConfig.zoneName : (tld.getDomain(domain) || domain); @@ -144,9 +144,9 @@ function provision(dnsConfig, autoconf, auditSource, callback) { }; 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)); + if (error && error.reason === DomainsError.BAD_FIELD) return callback(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error && error.reason === DomainsError.ALREADY_EXISTS) return callback(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); async.series([ mail.addDomain.bind(null, domain), @@ -198,12 +198,12 @@ function activate(username, password, email, displayName, ip, auditSource, callb setTimeZone(ip, function () { }); // TODO: get this from user. note that timezone is detected based on the browser location and not the cloudron region users.createOwner(username, password, email, displayName, auditSource, function (error, userObject) { - if (error && error.reason === UsersError.ALREADY_EXISTS) return callback(new SetupError(SetupError.ALREADY_PROVISIONED, 'Already activated')); - if (error && error.reason === UsersError.BAD_FIELD) return callback(new SetupError(SetupError.BAD_FIELD, error.message)); - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); + if (error && error.reason === UsersError.ALREADY_EXISTS) return callback(new ProvisionError(ProvisionError.ALREADY_PROVISIONED, 'Already activated')); + if (error && error.reason === UsersError.BAD_FIELD) return callback(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); clients.addTokenByUserId('cid-webadmin', userObject.id, Date.now() + constants.DEFAULT_TOKEN_EXPIRATION, {}, function (error, result) { - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); eventlog.add(eventlog.ACTION_ACTIVATE, auditSource, { }); @@ -226,21 +226,21 @@ function restore(backupConfig, backupId, version, autoconf, auditSource, callbac assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); - if (!semver.valid(version)) return callback(new SetupError(SetupError.BAD_STATE, 'version is not a valid semver')); - if (semver.major(config.version()) !== semver.major(version) || semver.minor(config.version()) !== semver.minor(version)) return callback(new SetupError(SetupError.BAD_STATE, `Run cloudron-setup with --version ${version} to restore from this backup`)); + if (!semver.valid(version)) return callback(new ProvisionError(ProvisionError.BAD_STATE, 'version is not a valid semver')); + if (semver.major(config.version()) !== semver.major(version) || semver.minor(config.version()) !== semver.minor(version)) return callback(new ProvisionError(ProvisionError.BAD_STATE, `Run cloudron-setup with --version ${version} to restore from this backup`)); let webadminStatus = cloudron.getWebadminStatus(); - if (webadminStatus.configuring || webadminStatus.restore.active) return callback(new SetupError(SetupError.BAD_STATE, 'Already restoring or configuring')); + if (webadminStatus.configuring || webadminStatus.restore.active) return callback(new ProvisionError(ProvisionError.BAD_STATE, 'Already restoring or configuring')); users.isActivated(function (error, activated) { - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); - if (activated) return callback(new SetupError(SetupError.ALREADY_PROVISIONED, 'Already activated')); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); + if (activated) return callback(new ProvisionError(ProvisionError.ALREADY_PROVISIONED, 'Already activated')); backups.testConfig(backupConfig, function (error) { - if (error && error.reason === BackupsError.BAD_FIELD) return callback(new SetupError(SetupError.BAD_FIELD, error.message)); - if (error && error.reason === BackupsError.EXTERNAL_ERROR) return callback(new SetupError(SetupError.EXTERNAL_ERROR, error.message)); - if (error) return callback(new SetupError(SetupError.INTERNAL_ERROR, error)); + if (error && error.reason === BackupsError.BAD_FIELD) return callback(new ProvisionError(ProvisionError.BAD_FIELD, error.message)); + if (error && error.reason === BackupsError.EXTERNAL_ERROR) return callback(new ProvisionError(ProvisionError.EXTERNAL_ERROR, error.message)); + if (error) return callback(new ProvisionError(ProvisionError.INTERNAL_ERROR, error)); debug(`restore: restoring from ${backupId} from provider ${backupConfig.provider} with format ${backupConfig.format}`); diff --git a/src/routes/index.js b/src/routes/index.js index f74013a93..a0358feed 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -15,9 +15,9 @@ exports = module.exports = { oauth2: require('./oauth2.js'), mail: require('./mail.js'), profile: require('./profile.js'), + provision: require('./provision.js'), services: require('./services.js'), settings: require('./settings.js'), - setup: require('./setup.js'), sysadmin: require('./sysadmin.js'), ssh: require('./ssh.js'), tasks: require('./tasks.js'), diff --git a/src/routes/setup.js b/src/routes/provision.js similarity index 82% rename from src/routes/setup.js rename to src/routes/provision.js index e4b4415ab..ff14e5c26 100644 --- a/src/routes/setup.js +++ b/src/routes/provision.js @@ -3,7 +3,7 @@ exports = module.exports = { providerTokenAuth: providerTokenAuth, setupTokenAuth: setupTokenAuth, - provision: provision, + setup: setup, activate: activate, restore: restore }; @@ -15,8 +15,8 @@ var assert = require('assert'), debug = require('debug')('box:routes/setup'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, - setup = require('../setup.js'), - SetupError = require('../setup.js').SetupError, + provision = require('../provision.js'), + ProvisionError = require('../provision.js').ProvisionError, superagent = require('superagent'); function auditSource(req) { @@ -61,7 +61,7 @@ function setupTokenAuth(req, res, next) { }); } -function provision(req, res, next) { +function setup(req, res, next) { assert.strictEqual(typeof req.body, 'object'); if (!req.body.dnsConfig || typeof req.body.dnsConfig !== 'object') return next(new HttpError(400, 'dnsConfig is required')); @@ -83,10 +83,10 @@ function provision(req, res, next) { // it can take sometime to setup DNS, register cloudron req.clearTimeout(); - setup.provision(dnsConfig, req.body.autoconf || {}, auditSource(req), function (error) { - if (error && error.reason === SetupError.ALREADY_SETUP) return next(new HttpError(409, error.message)); - if (error && error.reason === SetupError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error && error.reason === SetupError.BAD_STATE) return next(new HttpError(409, error.message)); + provision.setup(dnsConfig, req.body.autoconf || {}, auditSource(req), function (error) { + if (error && error.reason === ProvisionError.ALREADY_SETUP) return next(new HttpError(409, error.message)); + if (error && error.reason === ProvisionError.BAD_FIELD) return next(new HttpError(400, error.message)); + if (error && error.reason === ProvisionError.BAD_STATE) return next(new HttpError(409, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(200)); @@ -109,9 +109,9 @@ function activate(req, res, next) { var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; debug('activate: username:%s ip:%s', username, ip); - setup.activate(username, password, email, displayName, ip, auditSource(req), function (error, info) { - if (error && error.reason === SetupError.ALREADY_PROVISIONED) return next(new HttpError(409, 'Already setup')); - if (error && error.reason === SetupError.BAD_FIELD) return next(new HttpError(400, error.message)); + provision.activate(username, password, email, displayName, ip, auditSource(req), function (error, info) { + if (error && error.reason === ProvisionError.ALREADY_PROVISIONED) return next(new HttpError(409, 'Already setup')); + if (error && error.reason === ProvisionError.BAD_FIELD) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); // only in caas case do we have to notify the api server about activation @@ -146,11 +146,11 @@ function restore(req, res, next) { // TODO: validate subfields of these objects if (req.body.autoconf && typeof req.body.autoconf !== 'object') return next(new HttpError(400, 'autoconf must be an object')); - setup.restore(backupConfig, req.body.backupId, req.body.version, req.body.autoconf || {}, auditSource(req), function (error) { - if (error && error.reason === SetupError.ALREADY_SETUP) return next(new HttpError(409, error.message)); - if (error && error.reason === SetupError.BAD_FIELD) return next(new HttpError(400, error.message)); - if (error && error.reason === SetupError.BAD_STATE) return next(new HttpError(409, error.message)); - if (error && error.reason === SetupError.EXTERNAL_ERROR) return next(new HttpError(424, error.message)); + provision.restore(backupConfig, req.body.backupId, req.body.version, req.body.autoconf || {}, auditSource(req), function (error) { + if (error && error.reason === ProvisionError.ALREADY_SETUP) return next(new HttpError(409, error.message)); + if (error && error.reason === ProvisionError.BAD_FIELD) return next(new HttpError(400, error.message)); + if (error && error.reason === ProvisionError.BAD_STATE) return next(new HttpError(409, error.message)); + if (error && error.reason === ProvisionError.EXTERNAL_ERROR) return next(new HttpError(424, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(200)); diff --git a/src/server.js b/src/server.js index 5fae44d54..3bfac1b76 100644 --- a/src/server.js +++ b/src/server.js @@ -108,9 +108,9 @@ function initializeExpressSync() { var csrf = routes.oauth2.csrf(); // public routes - router.post('/api/v1/cloudron/setup', routes.setup.providerTokenAuth, routes.setup.provision); // only available until no-domain - router.post('/api/v1/cloudron/restore', routes.setup.restore); // only available until activated - router.post('/api/v1/cloudron/activate', routes.setup.setupTokenAuth, routes.setup.activate); + router.post('/api/v1/cloudron/setup', routes.provision.providerTokenAuth, routes.provision.setup); // only available until no-domain + router.post('/api/v1/cloudron/restore', routes.provision.restore); // only available until activated + router.post('/api/v1/cloudron/activate', routes.provision.setupTokenAuth, routes.provision.activate); router.get ('/api/v1/cloudron/status', routes.cloudron.getStatus); router.get ('/api/v1/cloudron/avatar', routes.settings.getCloudronAvatar); // this is a public alias for /api/v1/settings/cloudron_avatar