diff --git a/src/apps.js b/src/apps.js index 48ca83fe9..eaca27421 100644 --- a/src/apps.js +++ b/src/apps.js @@ -347,20 +347,33 @@ function purchase(appStoreId, callback) { }); } -function install(appId, appStoreId, manifest, location, portBindings, accessRestriction, icon, cert, key, memoryLimit, altDomain, auditSource, callback) { +function install(appId, data, auditSource, callback) { assert.strictEqual(typeof appId, 'string'); + assert(data && typeof data === 'object'); + assert.strictEqual(typeof auditSource, 'object'); + assert.strictEqual(typeof callback, 'function'); + + var appStoreId = data.appStoreId, + manifest = data.manifest, + location = data.location, + portBindings = data.portBindings || null, + accessRestriction = data.accessRestriction || null, + icon = data.icon || null, + cert = data.cert || null, + key = data.key || null, + memoryLimit = data.memoryLimit || 0, + altDomain = data.altDomain || null; + assert.strictEqual(typeof appStoreId, 'string'); assert(manifest && typeof manifest === 'object'); assert.strictEqual(typeof location, 'string'); assert.strictEqual(typeof portBindings, 'object'); assert.strictEqual(typeof accessRestriction, 'object'); - assert(!icon || typeof icon === 'string'); + assert(icon === null || typeof icon === 'string'); assert(cert === null || typeof cert === 'string'); assert(key === null || typeof key === 'string'); assert.strictEqual(typeof memoryLimit, 'number'); assert(altDomain === null || typeof altDomain === 'string'); - assert.strictEqual(typeof auditSource, 'object'); - assert.strictEqual(typeof callback, 'function'); var error = manifestFormat.parse(manifest); if (error) return callback(new AppsError(AppsError.BAD_FIELD, 'Manifest error: ' + error.message)); diff --git a/src/cloudron.js b/src/cloudron.js index b3730d6e0..abec2904d 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -667,10 +667,15 @@ function installAppBundle(callback) { debug('autoInstall: installing %s at %s', appstoreId, appInfo.location); - apps.install(uuid.v4(), appstoreId, result.body.manifest, appInfo.location, - appInfo.portBindings || null, appInfo.accessRestriction || null, - null /* icon */, null /* cert */, null /* key */, 0 /* default mem limit */, - null /* altDomain */, { userId: null, username: 'autoinstaller' }, iteratorCallback); + var data = { + appStoreId: appstoreId, + manifest: result.body.manifest, + location: appInfo.location, + portBindings: appInfo.portBindings || null, + accessRestriction: appInfo.accessRestriction || null, + }; + + apps.install(uuid.v4(), 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 a9f7671cf..c1344763c 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -95,11 +95,14 @@ function installApp(req, res, next) { var data = req.body; + // required if (!data.manifest || typeof data.manifest !== 'object') return next(new HttpError(400, 'manifest is required')); if (typeof data.appStoreId !== 'string') return next(new HttpError(400, 'appStoreId is required')); if (typeof data.location !== 'string') return next(new HttpError(400, 'location is required')); - if (('portBindings' in data) && typeof data.portBindings !== 'object') return next(new HttpError(400, 'portBindings must be an object')); if (typeof data.accessRestriction !== 'object') return next(new HttpError(400, 'accessRestriction is required')); + + // optional + if (('portBindings' in data) && typeof data.portBindings !== 'object') return next(new HttpError(400, 'portBindings must be an object')); if ('icon' in data && typeof data.icon !== 'string') return next(new HttpError(400, 'icon is not a string')); if (data.cert && typeof data.cert !== 'string') return next(new HttpError(400, 'cert must be a string')); if (data.key && typeof data.key !== 'string') return next(new HttpError(400, 'key must be a string')); @@ -111,9 +114,9 @@ function installApp(req, res, next) { // 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 storeid:%s loc:%s port:%j accessRestriction:%j memoryLimit:%s manifest:%j', appId, data.appStoreId, data.location, data.portBindings, data.accessRestriction, data.memoryLimit, data.manifest); + debug('Installing app id:%s data:%j', appId, data); - apps.install(appId, data.appStoreId, data.manifest, data.location, data.portBindings || null, data.accessRestriction, data.icon || null, data.cert || null, data.key || null, data.memoryLimit || 0, data.altDomain || null, auditSource(req), function (error) { + apps.install(appId, data, auditSource(req), function (error) { 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.'));