From 515d285d57b04f3afd10c7a702b8c24ed588e018 Mon Sep 17 00:00:00 2001 From: opi Date: Mon, 13 Oct 2014 16:00:30 +0200 Subject: [PATCH] [enh] Warn user about possible security flaws when installing custom app. Fix #78 --- js/app.js | 185 +++++++++++++++++++++++++----------------------- locales/en.json | 3 +- locales/fr.json | 3 +- 3 files changed, 100 insertions(+), 91 deletions(-) diff --git a/js/app.js b/js/app.js index 09aa564a..416bd0a6 100644 --- a/js/app.js +++ b/js/app.js @@ -926,112 +926,119 @@ app = Sammy('#main', function (sam) { // Install custom app from github sam.post('#/apps/install/custom', function(c) { - params = { 'label': c.params['label'], 'app': c.params['url'] } - delete c.params['label']; - delete c.params['url']; + if (confirm(y18n.t('confirm_install_custom_app'))) { + params = { 'label': c.params['label'], 'app': c.params['url'] } + delete c.params['label']; + delete c.params['url']; - // Force trailing slash - params.app = params.app.replace(/\/?$/, '/'); + // Force trailing slash + params.app = params.app.replace(/\/?$/, '/'); - // Get manifest.json to get additional parameters - jQuery.ajax({ - url: params.app.replace('github.com', 'rawgit.com') + 'master/manifest.json', - type: 'GET', - crossdomain: true, - dataType: 'json', - }) - .done(function(manifest) { - manifest = manifest || {}; + // Get manifest.json to get additional parameters + jQuery.ajax({ + url: params.app.replace('github.com', 'rawgit.com') + 'master/manifest.json', + type: 'GET', + crossdomain: true, + dataType: 'json', + }) + .done(function(manifest) { + manifest = manifest || {}; - // Fake appData (see '#/apps/install/:app' route) - var appData = { - manifest : manifest, - id : params.app, - multi_instance : manifest.multi_instance, - }; + // Fake appData (see '#/apps/install/:app' route) + var appData = { + manifest : manifest, + id : params.app, + multi_instance : manifest.multi_instance, + }; - if (typeof appData.manifest.arguments.install !== 'undefined') { - $.each(appData.manifest.arguments.install, function(k, v) { - // Default values - appData.manifest.arguments.install[k].type = 'text'; - appData.manifest.arguments.install[k].required = 'required'; + if (typeof appData.manifest.arguments.install !== 'undefined') { + $.each(appData.manifest.arguments.install, function(k, v) { + // Default values + appData.manifest.arguments.install[k].type = 'text'; + appData.manifest.arguments.install[k].required = 'required'; - // Radio button - if (typeof appData.manifest.arguments.install[k].choices !== 'undefined') { - // Update choices values with key and checked data - $.each(appData.manifest.arguments.install[k].choices, function(ck, cv){ - appData.manifest.arguments.install[k].choices[ck] = { - value: cv, - label: cv, - selected: (cv == appData.manifest.arguments.install[k].default) ? true : false, - }; - }); - } - - // Special case for domain input. - // Display a list of available domains - if (v.name == 'domain') { - appData.manifest.arguments.install[k].choices = []; - $.each(c.params.domains, function(key, domain){ - appData.manifest.arguments.install[k].choices.push({ - value: domain, - label: domain, - selected: false + // Radio button + if (typeof appData.manifest.arguments.install[k].choices !== 'undefined') { + // Update choices values with key and checked data + $.each(appData.manifest.arguments.install[k].choices, function(ck, cv){ + appData.manifest.arguments.install[k].choices[ck] = { + value: cv, + label: cv, + selected: (cv == appData.manifest.arguments.install[k].default) ? true : false, + }; }); - }); - appData.manifest.arguments.install[k].help = ""+y18n.t('manage_domains')+""; - } + } - // Special case for admin input. - // Display a list of available users - if (v.name == 'admin') { - appData.manifest.arguments.install[k].choices = []; - $.each(c.params.users, function(key, user){ - appData.manifest.arguments.install[k].choices.push({ - value: user.username, - label: user.fullname+' ('+user.mail+')', - selected: false + // Special case for domain input. + // Display a list of available domains + if (v.name == 'domain') { + appData.manifest.arguments.install[k].choices = []; + $.each(c.params.domains, function(key, domain){ + appData.manifest.arguments.install[k].choices.push({ + value: domain, + label: domain, + selected: false + }); }); - }); - appData.manifest.arguments.install[k].help = ""+y18n.t('manage_users')+""; - } + appData.manifest.arguments.install[k].help = ""+y18n.t('manage_domains')+""; + } - // Special case for password input. - if (v.name == 'password') { - appData.manifest.arguments.install[k].type = 'password'; - } + // Special case for admin input. + // Display a list of available users + if (v.name == 'admin') { + appData.manifest.arguments.install[k].choices = []; + $.each(c.params.users, function(key, user){ + appData.manifest.arguments.install[k].choices.push({ + value: user.username, + label: user.fullname+' ('+user.mail+')', + selected: false + }); + }); + appData.manifest.arguments.install[k].help = ""+y18n.t('manage_users')+""; + } - // Optional field - if (typeof v.optional !== 'undefined' && v.optional == "true") { - appData.manifest.arguments.install[k].required = ''; - } + // Special case for password input. + if (v.name == 'password') { + appData.manifest.arguments.install[k].type = 'password'; + } - // Multilingual description - appData.manifest.arguments.install[k].label = (typeof appData.manifest.arguments.install[k].ask[y18n.locale] !== 'undefined') ? - appData.manifest.arguments.install[k].ask[y18n.locale] : - appData.manifest.arguments.install[k].ask['en'] + // Optional field + if (typeof v.optional !== 'undefined' && v.optional == "true") { + appData.manifest.arguments.install[k].required = ''; + } + + // Multilingual description + appData.manifest.arguments.install[k].label = (typeof appData.manifest.arguments.install[k].ask[y18n.locale] !== 'undefined') ? + appData.manifest.arguments.install[k].ask[y18n.locale] : + appData.manifest.arguments.install[k].ask['en'] + ; + }); + } + + // Multilingual description + appData.description = (typeof appData.manifest.description[y18n.locale] !== 'undefined') ? + appData.manifest.description[y18n.locale] : + appData.manifest.description['en'] ; - }); - } - // Multilingual description - appData.description = (typeof appData.manifest.description[y18n.locale] !== 'undefined') ? - appData.manifest.description[y18n.locale] : - appData.manifest.description['en'] - ; + // Multi Instance settings + appData.manifest.multi_instance = (appData.manifest.multi_instance == 'true') ? y18n.t('yes') : y18n.t('no'); - // Multi Instance settings - appData.manifest.multi_instance = (appData.manifest.multi_instance == 'true') ? y18n.t('yes') : y18n.t('no'); - - // View app install form - c.view('app/app_install', appData); - }) - .fail(function(xhr) { - c.flash('fail', y18n.t('app_install_custom_no_manifest')); + // View app install form + c.view('app/app_install', appData); + }) + .fail(function(xhr) { + c.flash('fail', y18n.t('app_install_custom_no_manifest')); + store.clear('slide'); + c.redirect('#/apps/install'); + }); + } + else { + c.flash('warning', y18n.t('app_install_cancel')); store.clear('slide'); c.redirect('#/apps/install'); - }); + } }); diff --git a/locales/en.json b/locales/en.json index 84f25739..f13ac301 100644 --- a/locales/en.json +++ b/locales/en.json @@ -117,7 +117,8 @@ "custom_app_install" : "Install custom app", "custom_app_url_only_github" : "Currently only from GitHub", "confirm_install_domain_root" : "You will not be able to install any other app on %s. Continue ?", - "app_install_cancel" : "Installation cancelled", + "app_install_cancel" : "Installation cancelled.", + "confirm_install_custom_app" : "Installing 3rd party applications may compromise the security of your system. Use at your own risks.", "backup" : "Backup", "backup_warning_title" : "The backup system is not implemented yet.", diff --git a/locales/fr.json b/locales/fr.json index e4758a9b..df54e115 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -116,7 +116,8 @@ "custom_app_install" : "Installer une application personnalisée", "custom_app_url_only_github" : "Uniquement depuis GitHub", "confirm_install_domain_root" : "Vous ne pourrez pas installer d'autres applications sur %s. Continuer ?", - "app_install_cancel" : "Installation annulée", + "app_install_cancel" : "Installation annulée.", + "confirm_install_custom_app" : "L'installation d'application tierce peut comprometre la sécurité du système. Continuer à vos risques ?", "backup" : "Sauvegarde", "backup_warning_title" : "Le système de sauvegarde n'est pas encore implémenté.",