diff --git a/src/apps.js b/src/apps.js index 42a050dda..5ed439393 100644 --- a/src/apps.js +++ b/src/apps.js @@ -818,6 +818,18 @@ function update(appId, data, auditSource, callback) { updateConfig.manifest = manifest; + // prevent user from installing a app with different manifest id over an existing app + // this allows cloudron install -f --app for an app installed from the appStore + if (app.manifest.id !== updateConfig.manifest.id) { + if (!data.force) return callback(new AppsError(AppsError.BAD_FIELD, 'manifest id does not match. force to override')); + // clear appStoreId so that this app does not get updates anymore + updateConfig.appStoreId = ''; + } + + if (app.appStoreId !== '' && semver.lte(updateConfig.manifest.version, app.manifest.version)) { + if (!data.force) return callback(new AppsError(AppsError.BAD_FIELD, 'Downgrades are not permitted for apps installed from AppStore. force to override')); + } + if ('icon' in data) { if (data.icon) { if (!validator.isBase64(data.icon)) return callback(new AppsError(AppsError.BAD_FIELD, 'icon is not base64')); @@ -830,14 +842,6 @@ function update(appId, data, auditSource, callback) { } } - // prevent user from installing a app with different manifest id over an existing app - // this allows cloudron install -f --app for an app installed from the appStore - if (app.manifest.id !== updateConfig.manifest.id) { - if (!data.force) return callback(new AppsError(AppsError.BAD_FIELD, 'manifest id does not match. force to override')); - // clear appStoreId so that this app does not get updates anymore - updateConfig.appStoreId = ''; - } - // do not update apps in debug mode if (app.debugMode && !data.force) return callback(new AppsError(AppsError.BAD_STATE, 'debug mode enabled. force to override'));