diff --git a/src/apps.js b/src/apps.js index 8a934389c..71f843486 100644 --- a/src/apps.js +++ b/src/apps.js @@ -65,6 +65,7 @@ var addons = require('./addons.js'), superagent = require('superagent'), taskmanager = require('./taskmanager.js'), util = require('util'), + uuid = require('node-uuid'), validator = require('validator'); // http://dustinsenos.com/articles/customErrorsInNode @@ -366,8 +367,7 @@ function downloadManifest(appStoreId, manifest, callback) { }); } -function install(appId, data, auditSource, callback) { - assert.strictEqual(typeof appId, 'string'); +function install(data, auditSource, callback) { assert(data && typeof data === 'object'); assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); @@ -424,6 +424,7 @@ function install(appId, data, auditSource, callback) { error = certificates.validateCertificate(cert, key, config.appFqdn(location)); if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message)); + var appId = uuid.v4(); debug('Will install app with id : ' + appId); purchase(appStoreId, function (error) { @@ -443,7 +444,7 @@ function install(appId, data, auditSource, callback) { eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId: appId, location: location, manifest: manifest }); - callback(null); + callback(null, { id : appId }); }); }); }); diff --git a/src/cloudron.js b/src/cloudron.js index 0b7ebe235..ae3d48d7b 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -664,7 +664,7 @@ function installAppBundle(callback) { accessRestriction: appInfo.accessRestriction || null, }; - apps.install(uuid.v4(), data, { userId: null, username: 'autoinstaller' }, iteratorCallback); + apps.install(data, { userId: null, username: 'autoinstaller' }, iteratorCallback); }, function (error) { if (error) debug('autoInstallApps: ', error); diff --git a/src/routes/apps.js b/src/routes/apps.js index dd71612b1..632e2dc54 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -114,12 +114,9 @@ function installApp(req, res, next) { if ('memoryLimit' in data && typeof data.memoryLimit !== 'number') return next(new HttpError(400, 'memoryLimit is not a number')); if ('altDomain' in data && typeof data.altDomain !== 'string') return next(new HttpError(400, 'altDomain must be a string')); - // allow tests to provide an appId for testing - var appId = (process.env.BOX_ENV === 'test' && typeof data.appId === 'string') ? data.appId : uuid.v4(); + debug('Installing app id:%s data:%j', data); - debug('Installing app id:%s data:%j', appId, data); - - apps.install(appId, data, auditSource(req), function (error) { + apps.install(data, auditSource(req), function (error, app) { if (error && error.reason === AppsError.ALREADY_EXISTS) return next(new HttpError(409, error.message)); if (error && error.reason === AppsError.PORT_RESERVED) return next(new HttpError(409, 'Port ' + error.message + ' is reserved.')); if (error && error.reason === AppsError.PORT_CONFLICT) return next(new HttpError(409, 'Port ' + error.message + ' is already in use.')); @@ -130,7 +127,7 @@ function installApp(req, res, next) { if (error && error.reason === AppsError.EXTERNAL_ERROR) return next(new HttpError(503, error.message)); if (error) return next(new HttpError(500, error)); - next(new HttpSuccess(202, { id: appId } )); + next(new HttpSuccess(202, app)); }); } diff --git a/src/routes/test/apps-test.js b/src/routes/test/apps-test.js index 5f10a21f1..0fd43df31 100644 --- a/src/routes/test/apps-test.js +++ b/src/routes/test/apps-test.js @@ -617,13 +617,13 @@ describe('Apps', function () { superagent.post(SERVER_URL + '/api/v1/apps/install') .query({ access_token: token }) - .send({ appId: APP_ID, appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: null, accessRestriction: null }) + .send({ appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: null, accessRestriction: null }) .end(function (err, res) { expect(res.statusCode).to.equal(202); expect(fake1.isDone()).to.be.ok(); expect(fake2.isDone()).to.be.ok(); expect(res.body.id).to.be.a('string'); - expect(res.body.id).to.be.eql(APP_ID); + APP_ID = res.body.id; checkInstallStatus(); }); }); @@ -1060,12 +1060,12 @@ describe('Apps', function () { superagent.post(SERVER_URL + '/api/v1/apps/install') .query({ access_token: token }) - .send({ appId: APP_ID, appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: { ECHO_SERVER_PORT: 7171 }, accessRestriction: null }) + .send({ appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: { ECHO_SERVER_PORT: 7171 }, accessRestriction: null }) .end(function (err, res) { expect(res.statusCode).to.equal(202); expect(fake1.isDone()).to.be.ok(); expect(fake2.isDone()).to.be.ok(); - expect(res.body.id).to.equal(APP_ID); + APP_ID = res.body.id; checkInstallStatus(); }); }); @@ -1221,7 +1221,7 @@ describe('Apps', function () { it('cannot reconfigure app with missing location', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) + .send({ password: PASSWORD, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1231,7 +1231,7 @@ describe('Apps', function () { it('cannot reconfigure app with missing accessRestriction', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 } }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 } }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1241,7 +1241,7 @@ describe('Apps', function () { it('cannot reconfigure app with only the cert, no key', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1 }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1 }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1251,7 +1251,7 @@ describe('Apps', function () { it('cannot reconfigure app with only the key, no cert', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, key: validKey1 }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, key: validKey1 }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1261,7 +1261,7 @@ describe('Apps', function () { it('cannot reconfigure app with cert not bein a string', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: 1234, key: validKey1 }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: 1234, key: validKey1 }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1271,7 +1271,7 @@ describe('Apps', function () { it('cannot reconfigure app with key not bein a string', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1, key: 1234 }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1, key: 1234 }) .end(function (err, res) { expect(res.statusCode).to.equal(400); done(); @@ -1281,7 +1281,7 @@ describe('Apps', function () { it('non admin cannot reconfigure app', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token_1 }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) .end(function (err, res) { expect(res.statusCode).to.equal(403); done(); @@ -1291,7 +1291,7 @@ describe('Apps', function () { it('can reconfigure app', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null }) .end(function (err, res) { expect(res.statusCode).to.equal(202); checkConfigureStatus(0, done); @@ -1359,7 +1359,7 @@ describe('Apps', function () { it('can reconfigure app with custom certificate', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure') .query({ access_token: token }) - .send({ appId: APP_ID, password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1, key: validKey1 }) + .send({ password: PASSWORD, location: APP_LOCATION_NEW, portBindings: { ECHO_SERVER_PORT: 7172 }, accessRestriction: null, cert: validCert1, key: validKey1 }) .end(function (err, res) { expect(res.statusCode).to.equal(202); checkConfigureStatus(0, done);