mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
Merge branch 'unstable' into enh_change_label
This commit is contained in:
commit
0d2fe76fe7
27 changed files with 647 additions and 199 deletions
60
debian/changelog
vendored
60
debian/changelog
vendored
|
@ -1,3 +1,63 @@
|
|||
yunohost-admin (2.7.5) stable; urgency=low
|
||||
|
||||
(Bumping version number for stable release)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 02 Dec 2017 12:34:45 -0500
|
||||
|
||||
yunohost-admin (2.7.4) testing; urgency=low
|
||||
|
||||
* [i18n] Improve French. German translations
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 28 Nov 2017 18:58:04 -0500
|
||||
|
||||
yunohost-admin (2.7.3) testing; urgency=low
|
||||
|
||||
* [i18n] Improve french translation (#170)
|
||||
* [fix] Add "OK" in translatable strings (#171)
|
||||
* [enh] Be able to upgrade single apps (#172)
|
||||
* [enh] Reboot/shutdown from admin interface (#173)
|
||||
|
||||
Thanks to all contributors <3 ! (opi, ljf, ariasuni, Jibec)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 12 Oct 2017 16:51:24 -0400
|
||||
|
||||
yunohost-admin (2.7.2) stable; urgency=low
|
||||
|
||||
Releasing as stable
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 22 Aug 2017 21:36:35 -0400
|
||||
|
||||
yunohost-admin (2.7.1) testing; urgency=low
|
||||
|
||||
[ Alexandre Aubin ]
|
||||
* [fix] Tell user that domain dns-conf shows a recommendation only
|
||||
|
||||
[ Translations ]
|
||||
* Added translation using Weblate (Russian) (Evgeniy Ozhiganov)
|
||||
* [i18n] Translated using Weblate (Esperanto) (MCMic)
|
||||
|
||||
Thanks to all contributors (MCMic, Aleks, Ozhiganov) <3 !
|
||||
|
||||
-- Laurent Peuch <cortex@worlddomination.be> Sat, 19 Aug 2017 22:43:15 +0000
|
||||
|
||||
yunohost-admin (2.7.0) testing; urgency=low
|
||||
|
||||
* [enh] Variable assignment code cleanup. (#161)
|
||||
* [fix] Friendlier and more meaningful 'error 500' (#166)
|
||||
* [i18n] Started Russian translation (#167)
|
||||
|
||||
Thanks to all contributors (opi, Aleks, Ozhiganov) <3 !
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 07 Aug 2017 12:49:55 -0400
|
||||
|
||||
yunohost-admin (2.6.2) stable; urgency=low
|
||||
|
||||
## Minor fix
|
||||
|
||||
* 'hooks' key is now 'system' in backup info (#165)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 26 Jul 2017 12:09:03 -0400
|
||||
|
||||
yunohost-admin (2.6.1) stable; urgency=low
|
||||
|
||||
Major changes since 2.6.0
|
||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -12,7 +12,7 @@ Architecture: all
|
|||
Conflicts: yunohost-apps-admin
|
||||
Replaces: yunohost-apps-admin
|
||||
Depends: ${misc:Depends}
|
||||
, yunohost (>= 2.3.6)
|
||||
, yunohost (>= 2.7.1)
|
||||
Description: web administration interface for yunohost
|
||||
YunoHost aims to make self-hosting accessible to everyone. It configures
|
||||
an email, Web and IM server alongside a LDAP base. It also provides
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// List installed apps
|
||||
app.get('#/apps', function (c) {
|
||||
c.api('/apps?installed', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
apps = data['apps'];
|
||||
var apps = data['apps'];
|
||||
c.arraySortById(apps);
|
||||
c.view('app/app_list', {apps: apps});
|
||||
});
|
||||
|
@ -21,7 +21,7 @@
|
|||
app.get('#/apps/install', function (c) {
|
||||
c.api('/apps', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
c.api('/apps?raw', function(dataraw) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
apps = [];
|
||||
var apps = [];
|
||||
$.each(data['apps'], function(k, v) {
|
||||
// Keep only uninstalled apps, or multi-instance apps
|
||||
if ((!v['installed'] || dataraw[v['id']].manifest.multi_instance) && !v['id'].match(/__[0-9]{1,5}$/)) {
|
||||
|
@ -169,7 +169,7 @@
|
|||
|
||||
// Helper function that build app installation form
|
||||
app.helper('appInstallForm', function(appId, manifest, params) {
|
||||
data = {
|
||||
var data = {
|
||||
id: appId,
|
||||
manifest: manifest
|
||||
};
|
||||
|
@ -286,10 +286,11 @@
|
|||
|
||||
// Clone a hidden input with empty value
|
||||
// https://stackoverflow.com/questions/476426/submit-an-html-form-with-empty-checkboxes
|
||||
inputClone = {};
|
||||
inputClone.name = data.manifest.arguments.install[k].name;
|
||||
inputClone.inputType = 'hidden';
|
||||
inputClone.default = 0;
|
||||
var inputClone = {
|
||||
name : data.manifest.arguments.install[k].name,
|
||||
inputType : 'hidden',
|
||||
default : 0
|
||||
};
|
||||
data.manifest.arguments.install.push(inputClone);
|
||||
}
|
||||
|
||||
|
@ -319,13 +320,11 @@
|
|||
// App installation form
|
||||
app.get('#/apps/install/:app', function (c) {
|
||||
c.api('/apps?raw', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
|
||||
|
||||
c.appInstallForm(
|
||||
c.params['app'],
|
||||
data[c.params['app']].manifest,
|
||||
c.params
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -333,11 +332,14 @@
|
|||
app.post('#/apps', function(c) {
|
||||
// Warn admin if app is going to be installed on domain root.
|
||||
if (c.params['path'] !== '/' || confirm(y18n.t('confirm_install_domain_root', [c.params['domain']]))) {
|
||||
params = { 'label': c.params['label'], 'app': c.params['app'] };
|
||||
delete c.params['label'];
|
||||
delete c.params['app'];
|
||||
var params = {
|
||||
label: c.params['label'],
|
||||
app: c.params['app']
|
||||
};
|
||||
|
||||
// Check for duplicate arg produced by empty checkbox. (See inputClone)
|
||||
delete c.params['label'];
|
||||
delete c.params['app'];
|
||||
$.each(c.params, function(k, v) {
|
||||
if (typeof(v) === 'object' && Array.isArray(v)) {
|
||||
// And return only first value
|
||||
|
@ -346,6 +348,7 @@
|
|||
});
|
||||
|
||||
params['args'] = c.serialize(c.params.toHash());
|
||||
|
||||
// Do not pass empty args.
|
||||
if (params['args'] === "") {
|
||||
delete params['args'];
|
||||
|
@ -365,7 +368,10 @@
|
|||
// Install custom app from github
|
||||
app.post('#/apps/install/custom', function(c) {
|
||||
|
||||
params = { 'label': c.params['label'], 'app': c.params['url'] };
|
||||
var params = {
|
||||
label: c.params['label'],
|
||||
app: c.params['url']
|
||||
};
|
||||
delete c.params['label'];
|
||||
delete c.params['url'];
|
||||
|
||||
|
@ -475,7 +481,10 @@
|
|||
y18n.t('applications'),
|
||||
y18n.t('confirm_access_remove_all', [c.params['app']]),
|
||||
function() {
|
||||
params = {'apps': c.params['app'], 'users':[]};
|
||||
var params = {
|
||||
apps: c.params['app'],
|
||||
users: []
|
||||
};
|
||||
c.api('/access?'+c.serialize(params), function(data) { // http://api.yunohost.org/#!/app/app_removeaccess_delete_12
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app']+ '/access');
|
||||
|
@ -494,7 +503,10 @@
|
|||
y18n.t('applications'),
|
||||
y18n.t('confirm_access_remove_user', [c.params['app'], c.params['user']]),
|
||||
function() {
|
||||
params = {'apps': c.params['app'], 'users': c.params['user']};
|
||||
var params = {
|
||||
apps: c.params['app'],
|
||||
users: c.params['user']
|
||||
};
|
||||
c.api('/access?'+c.serialize(params), function(data) { // http://api.yunohost.org/#!/app/app_removeaccess_delete_12
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app']+ '/access');
|
||||
|
@ -513,7 +525,10 @@
|
|||
y18n.t('applications'),
|
||||
y18n.t('confirm_access_add', [c.params['app']]),
|
||||
function() {
|
||||
params = {'apps': c.params['app'], 'users': null};
|
||||
var params = {
|
||||
apps: c.params['app'],
|
||||
users: null
|
||||
};
|
||||
c.api('/access', function() { // http://api.yunohost.org/#!/app/app_addaccess_put_13
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app'] +'/access');
|
||||
|
@ -528,7 +543,10 @@
|
|||
|
||||
// Grant access for a specific user
|
||||
app.post('#/apps/:app/access/add', function (c) {
|
||||
params = {'users': c.params['user'], 'apps': c.params['app']};
|
||||
var params = {
|
||||
users: c.params['user'],
|
||||
apps: c.params['app']
|
||||
};
|
||||
c.api('/access', function() { // http://api.yunohost.org/#!/app/app_addaccess_put_13
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app'] +'/access');
|
||||
|
@ -541,7 +559,9 @@
|
|||
y18n.t('applications'),
|
||||
y18n.t('confirm_access_clear', [c.params['app']]),
|
||||
function() {
|
||||
params = {'apps': c.params['app']};
|
||||
var params = {
|
||||
apps: c.params['app']
|
||||
};
|
||||
c.api('/access', function() { //
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app'] +'/access');
|
||||
|
@ -592,4 +612,50 @@
|
|||
}, 'PUT', params);
|
||||
});
|
||||
|
||||
// Get app change URL page
|
||||
app.get('#/apps/:app/changeurl', function (c) {
|
||||
c.api('/apps/'+c.params['app']+'?raw', function(app_data) {
|
||||
c.api('/domains', function(domain_data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
||||
|
||||
// Display a list of available domains
|
||||
var domains = [];
|
||||
$.each(domain_data.domains, function(k, domain) {
|
||||
domains.push({
|
||||
value: domain,
|
||||
label: domain,
|
||||
// Select current domain
|
||||
selected: (domain == app_data.settings.domain ? true : false)
|
||||
});
|
||||
});
|
||||
|
||||
data = {
|
||||
id: c.params['app'],
|
||||
label: app_data.manifest.name,
|
||||
domains: domains,
|
||||
// Pre-fill with current path
|
||||
path: app_data.settings.path
|
||||
};
|
||||
c.view('app/app_changeurl', data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Change app URL
|
||||
app.post('#/apps/:app/changeurl', function (c) {
|
||||
c.confirm(
|
||||
y18n.t('applications'),
|
||||
y18n.t('confirm_app_change_url', [c.params['app']]),
|
||||
function() {
|
||||
params = {'domain': c.params['domain'], 'path': c.params['path']};
|
||||
c.api('/apps/' + c.params['app'] + '/changeurl', function(data) { // Call changeurl API
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app']);
|
||||
}, 'PUT', params);
|
||||
},
|
||||
function() {
|
||||
store.clear('slide');
|
||||
c.redirect('#/apps/'+ c.params['app'] + '/changeurl');
|
||||
}
|
||||
);
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
'system_yunohost',
|
||||
'system_nginx'
|
||||
];
|
||||
|
||||
// Storage list
|
||||
app.get('#/backup', function (c) {
|
||||
var storages = [];
|
||||
|
@ -44,14 +45,14 @@
|
|||
|
||||
// Create a backup
|
||||
app.get('#/backup/:storage/create', function (c) {
|
||||
var data=[];
|
||||
data['storage']={
|
||||
var data = [];
|
||||
data['storage'] = {
|
||||
id:c.params['storage'],
|
||||
name:y18n.t('local_archives')
|
||||
};
|
||||
c.api('/hooks/backup', function(hooks) {
|
||||
data['hooks']=c.groupHooks(hooks['hooks']);
|
||||
data['apps']={};
|
||||
data['hooks'] = c.groupHooks(hooks['hooks']);
|
||||
data['apps'] = {};
|
||||
c.api('/apps?with_backup', function(apps_list) {
|
||||
data['apps'] = apps_list.apps;
|
||||
c.view('backup/backup_create', data);
|
||||
|
@ -74,13 +75,13 @@
|
|||
y18n.t('backup'),
|
||||
y18n.t('confirm_restore', [c.params['archive']]),
|
||||
$.proxy(function(c){
|
||||
var params=c.ungroupHooks(c.params['hooks'],c.params['apps']);
|
||||
params['force']='';
|
||||
var params = c.ungroupHooks(c.params['hooks'],c.params['apps']);
|
||||
params['force'] = '';
|
||||
c.api('/backup/restore/'+c.params['archive'], function(data) {
|
||||
store.clear('slide');
|
||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
||||
}, 'POST', params);
|
||||
},this,c),
|
||||
}, this, c),
|
||||
function(){
|
||||
store.clear('slide');
|
||||
c.redirect('#/backup/'+ c.params['storage']+'/'+c.params['archive']);
|
||||
|
@ -127,14 +128,14 @@
|
|||
// Get archive info
|
||||
app.get('#/backup/:storage/:archive', function (c) {
|
||||
c.api('/backup/archives/'+c.params['archive']+'?with_details', function(data) {
|
||||
data['storage']={
|
||||
id:c.params['storage'],
|
||||
name:y18n.t('local_archives')
|
||||
data.storage = {
|
||||
id: c.params['storage'],
|
||||
name: y18n.t('local_archives')
|
||||
};
|
||||
data['other_storages']=[];
|
||||
data['name']=c.params['archive'];
|
||||
data['hooks']=c.groupHooks(Object.keys(data['system']));
|
||||
data['items']=(data['hooks']!={} || data['apps']!=[]);
|
||||
data.other_storages = [];
|
||||
data.name = c.params['archive'];
|
||||
data.hooks = c.groupHooks(Object.keys(data['system']));
|
||||
data.items = (data['hooks']!={} || data['apps']!=[]);
|
||||
c.view('backup/backup_info', data);
|
||||
});
|
||||
});
|
||||
|
@ -142,16 +143,16 @@
|
|||
// Archive list
|
||||
app.get('#/backup/:storage', function (c) {
|
||||
c.api('/backup/archives?with_info', function(data) {
|
||||
data['storage']={
|
||||
id:'local',
|
||||
name:y18n.t('local_archives')
|
||||
data.storage = {
|
||||
id: 'local',
|
||||
name: y18n.t('local_archives')
|
||||
};
|
||||
data['archives2']=[];
|
||||
data.archives2 = [];
|
||||
$.each(data['archives'], function(name, info) {
|
||||
info['name']=name;
|
||||
data['archives2'].unshift(info)
|
||||
info.name = name;
|
||||
data.archives2.unshift(info)
|
||||
});
|
||||
data['archives']=data['archives2'];
|
||||
data.archives = data.archives2;
|
||||
c.view('backup/backup_list', data);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
app.get('#/domains', function (c) {
|
||||
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
|
||||
c.api('/domains/main', function(data2) {
|
||||
domains = [];
|
||||
var domains = [];
|
||||
$.each(data.domains, function(k, domain) {
|
||||
domains.push({
|
||||
url: domain,
|
||||
|
@ -21,11 +21,14 @@
|
|||
});
|
||||
|
||||
// Do not show main domain form if we have only 1 domain
|
||||
main_domain_form = (domains.length > 1) ? true: false;
|
||||
var main_domain_form = (domains.length > 1) ? true: false;
|
||||
|
||||
// Sort domains with main domain first
|
||||
domains.sort(function(a, b){ return -2*(a.main) + 1; });
|
||||
c.view('domain/domain_list', {domains: domains, main_domain_form: main_domain_form});
|
||||
c.view('domain/domain_list', {
|
||||
domains: domains,
|
||||
main_domain_form: main_domain_form
|
||||
});
|
||||
}, 'PUT');
|
||||
});
|
||||
});
|
||||
|
@ -40,10 +43,10 @@
|
|||
c.params.ddomains = ['.nohost.me', '.noho.st'];
|
||||
})
|
||||
.always(function() {
|
||||
data = {
|
||||
ddomains : c.params.ddomains,
|
||||
domains : c.params.domains,
|
||||
allowDyndnsDomain : true
|
||||
var data = {
|
||||
ddomains: c.params.ddomains,
|
||||
domains: c.params.domains,
|
||||
allowDyndnsDomain: true
|
||||
};
|
||||
|
||||
// Allow only 1 DynDns domain.
|
||||
|
@ -60,17 +63,18 @@
|
|||
|
||||
// Add domain (POST)
|
||||
app.post('#/domains/add', function (c) {
|
||||
var params = {};
|
||||
var endurl = '';
|
||||
if (c.params['domain'] === '') {
|
||||
if (c.params['ddomain'] === '') {
|
||||
c.flash('fail', y18n.t('error_select_domain'));
|
||||
store.clear('slide');
|
||||
c.redirect('#/domains/add');
|
||||
}
|
||||
params = {'domain': c.params['ddomain'] + c.params['ddomain-ext']};
|
||||
params.domain = c.params['ddomain'] + c.params['ddomain-ext'];
|
||||
endurl = 'dyndns';
|
||||
} else {
|
||||
params = { 'domain': c.params['domain'] };
|
||||
endurl = '';
|
||||
params.domain = c.params['domain'];
|
||||
}
|
||||
|
||||
c.api('/domains?'+endurl, function(data) { // http://api.yunohost.org/#!/domain/domain_add_post_1
|
||||
|
@ -87,16 +91,15 @@
|
|||
// for apps installed) should be removed once letsencrypt_ynh
|
||||
// is not used by many people anymore. Probably around 07/2017
|
||||
// or end of 2017...
|
||||
enable_cert_management_ = true;
|
||||
var enable_cert_management_ = true;
|
||||
$.each(data['apps'], function(k, v) {
|
||||
if (v.id == "letsencrypt")
|
||||
{
|
||||
if (v.id == "letsencrypt") {
|
||||
enable_cert_management_ = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
domain = {
|
||||
var domain = {
|
||||
name: c.params['domain'],
|
||||
main: (c.params['domain'] == dataMain.current_main_domain) ? true : false,
|
||||
url: "https://"+c.params['domain'],
|
||||
|
@ -110,10 +113,10 @@
|
|||
// Domain DNS
|
||||
app.get('#/domains/:domain/dns', function (c) {
|
||||
c.api('/domains/' + c.params['domain'] + '/dns', function(data) {
|
||||
domain = {
|
||||
var domain = {
|
||||
name: c.params['domain'],
|
||||
dns: data
|
||||
}
|
||||
};
|
||||
c.view('domain/domain_dns', domain);
|
||||
});
|
||||
});
|
||||
|
@ -122,16 +125,15 @@
|
|||
app.get('#/domains/:domain/cert-management', function (c) {
|
||||
c.api('/domains/cert-status/' + c.params['domain'] + '?full', function(data) {
|
||||
|
||||
s = data["certificates"][c.params['domain']]
|
||||
var s = data["certificates"][c.params['domain']];
|
||||
var status_ = {
|
||||
CA_type: s.CA_type.verbose,
|
||||
CA_name: s.CA_name,
|
||||
validity: s.validity,
|
||||
ACME_eligible: s.ACME_eligible
|
||||
};
|
||||
|
||||
status_ = {}
|
||||
status_.CA_type = s.CA_type.verbose
|
||||
status_.CA_name = s.CA_name
|
||||
status_.validity = s.validity
|
||||
status_.ACME_eligible = s.ACME_eligible
|
||||
|
||||
switch (s.summary.code)
|
||||
{
|
||||
switch (s.summary.code) {
|
||||
case "critical" :
|
||||
status_.alert_type = "danger";
|
||||
status_.alert_icon = "exclamation-circle" ;
|
||||
|
@ -143,14 +145,12 @@
|
|||
status_.alert_message = y18n.t('certificate_alert_selfsigned');
|
||||
break;
|
||||
case "attention" :
|
||||
if (status_.CA_type == "lets-encrypt")
|
||||
{
|
||||
if (status_.CA_type == "lets-encrypt") {
|
||||
status_.alert_type = "warning";
|
||||
status_.alert_icon = "clock-o";
|
||||
status_.alert_message = y18n.t('certificate_alert_letsencrypt_about_to_expire');
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
status_.alert_type = "danger";
|
||||
status_.alert_icon = "clock-o";
|
||||
status_.alert_message = y18n.t('certificate_alert_about_to_expire');
|
||||
|
@ -173,14 +173,14 @@
|
|||
break;
|
||||
}
|
||||
|
||||
actions_enabled = {};
|
||||
actions_enabled.install_letsencrypt = false;
|
||||
actions_enabled.manual_renew_letsencrpt = false;
|
||||
actions_enabled.regen_selfsigned = false;
|
||||
actions_enabled.replace_with_selfsigned = false;
|
||||
var actions_enabled = {
|
||||
install_letsencrypt: false,
|
||||
manual_renew_letsencrpt: false,
|
||||
regen_selfsigned: false,
|
||||
replace_with_selfsigned: false
|
||||
};
|
||||
|
||||
switch (s.CA_type.code)
|
||||
{
|
||||
switch (s.CA_type.code) {
|
||||
case "self-signed" :
|
||||
actions_enabled.install_letsencrypt = true;
|
||||
actions_enabled.regen_selfsigned = true;
|
||||
|
@ -305,14 +305,16 @@
|
|||
y18n.t('domains'),
|
||||
y18n.t('confirm_change_maindomain'),
|
||||
function(){
|
||||
params = {'new_domain': c.params['domain']};
|
||||
var params = {
|
||||
new_domain: c.params['domain']
|
||||
};
|
||||
c.api('/domains/main', function(data) { // http://api.yunohost.org/#!/tools/tools_maindomain_put_1
|
||||
store.clear('slide');
|
||||
c.redirect('#/domains');
|
||||
}, 'PUT', params);
|
||||
|
||||
// Wait 15s and refresh the page
|
||||
refreshDomain = window.setTimeout(function(){
|
||||
var refreshDomain = window.setTimeout(function(){
|
||||
store.clear('slide');
|
||||
c.redirect('#/domains');
|
||||
}, 15000);
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
app.get('#/tools/firewall', function (c) {
|
||||
c.api('/firewall?raw', function(data) {
|
||||
var firewall = {
|
||||
ports : {},
|
||||
upnp : false
|
||||
ports: {},
|
||||
upnp: false
|
||||
};
|
||||
|
||||
// Reorganize ports
|
||||
|
@ -41,7 +41,9 @@
|
|||
// confirm_upnp_enable and confirm_upnp_disable
|
||||
y18n.t('confirm_upnp_' + c.params['action'].toLowerCase()),
|
||||
function(){
|
||||
params = {'action' : c.params['action']};
|
||||
var params = {
|
||||
action : c.params['action']
|
||||
};
|
||||
c.api('/firewall/upnp', function(data) {
|
||||
store.clear('slide');
|
||||
c.redirect('#/tools/firewall');
|
||||
|
@ -110,8 +112,8 @@
|
|||
// --ipv6-only:
|
||||
// --no-upnp:
|
||||
var params = {
|
||||
'port' : port,
|
||||
'protocol' : protocol,
|
||||
port : port,
|
||||
protocol : protocol
|
||||
};
|
||||
c.api('/firewall/port?'+endurl, function(data) {
|
||||
store.clear('slide');
|
||||
|
|
|
@ -35,9 +35,10 @@
|
|||
|
||||
// Loop through items in a reverse order (older first)
|
||||
$($('item', xml).get().reverse()).each(function(k, v) {
|
||||
var link=$('link', v).text();
|
||||
if (typeof link == 'string' && link !== '' && link.charAt(0) == '/')
|
||||
link=forumUrl+link;
|
||||
var link = $('link', v).text();
|
||||
if (typeof link == 'string' && link !== '' && link.charAt(0) == '/') {
|
||||
link = forumUrl+link;
|
||||
}
|
||||
|
||||
// var description=$('description', v).text();
|
||||
// description=description.replace('href="/','href="'+forumUrl+'/');
|
||||
|
@ -70,6 +71,13 @@
|
|||
c.flash('fail', y18n.t('error_retrieve_feed', [securityFeed]));
|
||||
});
|
||||
|
||||
c.api("/diagnosis", function(data) {
|
||||
console.log(data);
|
||||
if (data.security["CVE-2017-5754"].vulnerable) {
|
||||
c.flash('danger', y18n.t('meltdown'));
|
||||
}
|
||||
});
|
||||
|
||||
c.view('home');
|
||||
});
|
||||
});
|
||||
|
@ -138,8 +146,8 @@
|
|||
// Store url from params, it could have change form 'run' state
|
||||
store.set('url', c.params['domain'] +'/yunohost/api');
|
||||
|
||||
params = {
|
||||
'password': c.params['password']
|
||||
var params = {
|
||||
password: c.params['password']
|
||||
};
|
||||
c.api('/login', function(data) {
|
||||
store.set('connected', true);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// Server monitoring
|
||||
app.get('#/tools/monitor', function (c) {
|
||||
monitorData = {};
|
||||
var monitorData = {};
|
||||
|
||||
// Why this method ?
|
||||
c.api('/services/glances', function(data) { // ?
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
$('#masthead').hide();
|
||||
$.get('https://dyndns.yunohost.org/domains', function() {})
|
||||
.done(function(data){
|
||||
c.params.ddomains = data.map(function(dom){return '.'+dom;});
|
||||
c.params['ddomains'] = data.map(function(dom){return '.'+dom;});
|
||||
})
|
||||
.fail(function() {
|
||||
c.params.ddomains = ['.nohost.me', '.noho.st'];
|
||||
c.params['ddomains'] = ['.nohost.me', '.noho.st'];
|
||||
})
|
||||
.always(function() {
|
||||
c.view('postinstall/postinstall_2', c.params, function() {
|
||||
|
@ -77,14 +77,16 @@
|
|||
store.clear('slide');
|
||||
c.redirect('#/postinstall/domain');
|
||||
} else {
|
||||
params = { 'domain': c.params['domain'].toLowerCase() };
|
||||
var params = {
|
||||
domain: c.params['domain'].toLowerCase()
|
||||
};
|
||||
}
|
||||
|
||||
c.confirm(
|
||||
y18n.t('postinstall'),
|
||||
y18n.t('confirm_postinstall', [c.params['domain']]),
|
||||
function(){
|
||||
params['password'] = c.params['password'];
|
||||
params.password = c.params['password'];
|
||||
|
||||
store.set('url', window.location.hostname +'/yunohost/api');
|
||||
store.set('user', 'admin');
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
// All services status
|
||||
app.get('#/services', function (c) {
|
||||
c.api('/services', function(data) { // ?
|
||||
data2 = { 'services': [] };
|
||||
var data2 = {
|
||||
services: []
|
||||
};
|
||||
$.each(data, function(k, v) {
|
||||
v.name = k;
|
||||
// Handlebars want booleans
|
||||
|
@ -29,7 +31,9 @@
|
|||
// Status & actions for a service
|
||||
app.get('#/services/:service', function (c) {
|
||||
c.api('/services/'+ c.params['service'], function(data) { // ?
|
||||
data2 = { 'service': data };
|
||||
var data2 = {
|
||||
service: data
|
||||
};
|
||||
data2.service.name = c.params['service'];
|
||||
// Handlebars want booleans
|
||||
data2.service.is_loaded = (data.loaded=='enabled') ? true : false;
|
||||
|
@ -44,7 +48,9 @@
|
|||
|
||||
// Service log
|
||||
app.get('#/services/:service/log', function (c) {
|
||||
params = { 'number': 50 };
|
||||
var params = {
|
||||
number: 50
|
||||
};
|
||||
c.api('/services/'+ c.params['service'] +'/log', function(data) { // ?
|
||||
data2 = { 'logs': [], 'name': c.params['service'] };
|
||||
$.each(data, function(k, v) {
|
||||
|
@ -62,7 +68,8 @@
|
|||
// confirm_service_start, confirm_service_stop, confirm_service_enable and confirm_service_disable
|
||||
y18n.t('confirm_service_' + c.params['action'].toLowerCase(), [c.params['service']]),
|
||||
function(){
|
||||
var method = null, endurl = c.params['service'];
|
||||
var method = null,
|
||||
endurl = c.params['service'];
|
||||
|
||||
switch (c.params['action']) {
|
||||
case 'start':
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
// Update administration password (PUT)
|
||||
app.put('#/tools/adminpw', function (c) {
|
||||
params = {};
|
||||
var params = {};
|
||||
$.each(c.params.toHash(), function(key, value) {
|
||||
if (value !== '') { params[key] = value; }
|
||||
});
|
||||
|
@ -49,7 +49,7 @@
|
|||
// System update & upgrade
|
||||
app.get('#/update', function (c) {
|
||||
c.api('/update', function(data) {
|
||||
packagesLength = data.packages.length;
|
||||
var packagesLength = data.packages.length;
|
||||
for(var i = 0; i < packagesLength; i++) {
|
||||
data.packages[i].delayed = false;
|
||||
data.packages[i].changelog = data.packages[i].changelog.replace(/\n/g, '<br />');
|
||||
|
@ -77,7 +77,7 @@
|
|||
// confirm_update_apps and confirm_update_packages
|
||||
y18n.t('confirm_update_' + c.params['type'].toLowerCase()),
|
||||
function(){
|
||||
endurl = '';
|
||||
var endurl = '';
|
||||
if (c.params['type'] == 'packages') {endurl = 'ignore_apps';}
|
||||
else if (c.params['type'] == 'apps') {endurl = 'ignore_packages';}
|
||||
|
||||
|
@ -96,6 +96,27 @@
|
|||
}
|
||||
});
|
||||
|
||||
// Upgrade a specific apps
|
||||
app.get('#/upgrade/apps/:app', function (c) {
|
||||
c.confirm(
|
||||
y18n.t('tools'),
|
||||
y18n.t('confirm_update_specific_app', [c.params['app']]),
|
||||
function(){
|
||||
c.api('/upgrade/apps?app='+c.params['app'].toLowerCase(),
|
||||
function(data) {
|
||||
// 'log' is a reserved name, maybe in handlebars
|
||||
data.logs = data.log;
|
||||
c.view('upgrade/upgrade', data);
|
||||
}, 'PUT');
|
||||
},
|
||||
function(){
|
||||
store.clear('slide');
|
||||
c.redirect('#/update');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
// Download SSL Certificate Authority
|
||||
app.get('#/tools/ca', function (c) {
|
||||
c.view('tools/tools_ca');
|
||||
|
@ -103,7 +124,7 @@
|
|||
|
||||
// Security feed
|
||||
app.get('#/tools/security-feed', function (c) {
|
||||
data = {
|
||||
var data = {
|
||||
items: []
|
||||
};
|
||||
|
||||
|
@ -125,11 +146,12 @@
|
|||
.done(function(xml){
|
||||
// Loop through items
|
||||
$('item', xml).each(function(k, v) {
|
||||
var link=$('link', v)[0].innerHTML;
|
||||
if (typeof link == 'string' && link !== '' && link.charAt(0) == '/')
|
||||
link=forumUrl+link;
|
||||
var description=$('description', v)[0].textContent;
|
||||
description=description.replace('href="/','href="'+forumUrl+'/');
|
||||
var link = $('link', v)[0].innerHTML;
|
||||
if (typeof link == 'string' && link !== '' && link.charAt(0) == '/') {
|
||||
link = forumUrl+link;
|
||||
}
|
||||
var description = $('description', v)[0].textContent;
|
||||
description = description.replace('href="/','href="'+forumUrl+'/');
|
||||
|
||||
var item = {
|
||||
guid: $('guid', v)[0].innerHTML,
|
||||
|
@ -156,12 +178,69 @@
|
|||
});
|
||||
});
|
||||
|
||||
// Reboot or shutdown button
|
||||
app.get('#/tools/reboot', function (c) {
|
||||
c.view('tools/tools_reboot');
|
||||
});
|
||||
|
||||
// Reboot or shutdown actions
|
||||
app.get('#/tools/reboot/:action', function (c) {
|
||||
var action = c.params['action'].toLowerCase();
|
||||
if (action == 'reboot' || action == 'shutdown') {
|
||||
c.confirm(
|
||||
y18n.t('tools_' + action),
|
||||
// confirm_reboot_action_reboot or confirm_reboot_action_shutdown
|
||||
y18n.t('confirm_reboot_action_' + action),
|
||||
function(){
|
||||
c.api('/'+action+'?force', function(data) {
|
||||
// This code is not executed due to 502 response (reboot or shutdown)
|
||||
c.redirect('#/logout');
|
||||
}, 'PUT', {}, false, function (xhr) {
|
||||
c.flash('success', y18n.t('tools_' + action + '_done'))
|
||||
// Disconnect from the webadmin
|
||||
store.clear('url');
|
||||
store.clear('connected');
|
||||
store.set('path', '#/');
|
||||
|
||||
// Rename the page to allow refresh without ask for rebooting
|
||||
window.location.href = window.location.href.split('#')[0] + '#/';
|
||||
// Display reboot or shutdown info
|
||||
// We can't use template because now the webserver is off
|
||||
if (action == 'reboot') {
|
||||
$('#main').replaceWith('<div id="main"><div class="alert alert-warning"><i class="fa-refresh"></i> ' + y18n.t('tools_rebooting') + '</div></div>');
|
||||
}
|
||||
else {
|
||||
$('#main').replaceWith('<div id="main"><div class="alert alert-warning"><i class="fa-power-off"></i> ' + y18n.t('tools_shuttingdown') + '</div></div>');
|
||||
}
|
||||
|
||||
// Remove loader if any
|
||||
$('div.loader').remove();
|
||||
|
||||
// Force scrollTop on page load
|
||||
$('html, body').scrollTop(0);
|
||||
store.clear('slide');
|
||||
});
|
||||
|
||||
},
|
||||
function(){
|
||||
store.clear('slide');
|
||||
c.redirect('#/tools/reboot');
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
c.flash('fail', y18n.t('unknown_action', [action]));
|
||||
store.clear('slide');
|
||||
c.redirect('#/tools/reboot');
|
||||
}
|
||||
});
|
||||
|
||||
// Diagnosis
|
||||
app.get('#/tools/diagnosis(/:private)?', function (c) {
|
||||
// See http://sammyjs.org/docs/routes for splat documentation
|
||||
private = (c.params.splat[0] == 'private');
|
||||
var private = (c.params.splat[0] == 'private');
|
||||
|
||||
endurl = (private) ? '?private' : '';
|
||||
var endurl = (private) ? '?private' : '';
|
||||
c.api('/diagnosis'+endurl, function(diagnosis) {
|
||||
c.view('tools/tools_diagnosis', {
|
||||
'diagnosis' : JSON.stringify(diagnosis, undefined, 4),
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
data.password_min_length = PASSWORD_MIN_LENGTH;
|
||||
|
||||
// User email use a fake splitted field
|
||||
email = data.mail.split('@');
|
||||
var email = data.mail.split('@');
|
||||
data.email = {
|
||||
username : email[0],
|
||||
domain : email[1]
|
||||
|
@ -156,7 +156,7 @@
|
|||
c.params['mailalias'] = c.params['mailforward'] = '';
|
||||
|
||||
// Remove empty inputs
|
||||
params = {};
|
||||
var params = {};
|
||||
$.each(c.params.toHash(), function(key, value) {
|
||||
if (value.length > 0 && key !== 'user') { params[key] = value; }
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
app.bind('login', function(e, data) {
|
||||
this.api('/version', function(versions) {
|
||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost]));
|
||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@
|
|||
},
|
||||
|
||||
// API call
|
||||
api: function(uri, callback, method, data, websocket) {
|
||||
api: function(uri, callback, method, data, websocket, callbackOnFailure) {
|
||||
c = this;
|
||||
|
||||
call = function(uri, callback, method, data) {
|
||||
call = function(uri, callback, method, data, callbackOnFailure) {
|
||||
method = typeof method !== 'undefined' ? method : 'GET';
|
||||
data = typeof data !== 'undefined' ? data : {};
|
||||
if (window.navigator && window.navigator.language && (typeof data.locale === 'undefined')) {
|
||||
|
@ -80,26 +80,12 @@
|
|||
}, 1500);
|
||||
}
|
||||
|
||||
loaded = false;
|
||||
app.loaded = false;
|
||||
if ($('div.loader').length === 0) {
|
||||
$('#main').append('<div class="loader loader-content"></div>');
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: 'https://' + store.get('url') + uri,
|
||||
type: method,
|
||||
crossdomain: true,
|
||||
data: data,
|
||||
traditional: true,
|
||||
dataType: 'json'
|
||||
})
|
||||
.always(function(xhr, ts, error) {
|
||||
})
|
||||
.done(function(data) {
|
||||
data = data || {};
|
||||
callback(data);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
if (typeof callbackOnFailure !== 'function') {
|
||||
callbackOnFailure = function(xhr) {
|
||||
// Postinstall is a custom case, we have to wait that
|
||||
// operation is done before doing anything
|
||||
if (uri === '/postinstall') {
|
||||
|
@ -133,6 +119,13 @@
|
|||
c.redirect('#/login');
|
||||
}
|
||||
}
|
||||
// 500
|
||||
else if (xhr.status == 500) {
|
||||
error_log = JSON.parse(xhr.responseText);
|
||||
error_log.route = error_log.route.join(' ') + '\n';
|
||||
error_log.arguments = JSON.stringify(error_log.arguments);
|
||||
c.flash('fail', y18n.t('internal_exception', [error_log.route, error_log.arguments, error_log.traceback]));
|
||||
}
|
||||
// 502 Bad gateway means API is down
|
||||
else if (xhr.status == 502) {
|
||||
c.flash('fail', y18n.t('api_not_responding'));
|
||||
|
@ -154,14 +147,31 @@
|
|||
$('html, body').scrollTop(0);
|
||||
store.clear('slide');
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.ajax({
|
||||
url: 'https://' + store.get('url') + uri,
|
||||
type: method,
|
||||
crossdomain: true,
|
||||
data: data,
|
||||
traditional: true,
|
||||
dataType: 'json'
|
||||
})
|
||||
.always(function(xhr, ts, error) {
|
||||
})
|
||||
.done(function(data) {
|
||||
data = data || {};
|
||||
callback(data);
|
||||
})
|
||||
.fail(callbackOnFailure);
|
||||
};
|
||||
|
||||
websocket = typeof websocket !== 'undefined' ? websocket : true;
|
||||
if (websocket) {
|
||||
|
||||
// Open a WebSocket connection to retrieve live messages from the moulinette
|
||||
ws = new WebSocket('wss://'+ store.get('url') +'/messages');
|
||||
var ws = new WebSocket('wss://'+ store.get('url') +'/messages');
|
||||
ws.onmessage = function(evt) {
|
||||
// console.log(evt.data);
|
||||
$.each($.parseJSON(evt.data), function(k, v) {
|
||||
|
@ -174,9 +184,9 @@
|
|||
|
||||
ws.onclose = function() {};
|
||||
|
||||
ws.onopen = call(uri, callback, method, data);
|
||||
ws.onopen = call(uri, callback, method, data, callbackOnFailure);
|
||||
} else {
|
||||
call(uri, callback, method, data);
|
||||
call(uri, callback, method, data, callbackOnFailure);
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -189,14 +199,14 @@
|
|||
callback = typeof callback !== 'undefined' ? callback : function() {};
|
||||
enableSlide = (typeof enableSlide !== 'undefined') ? enableSlide : true; // Change to false to disable animation
|
||||
|
||||
loaded = true;
|
||||
app.loaded = true;
|
||||
|
||||
// Hide loader and modal
|
||||
$('div.loader').remove();
|
||||
$('#modal').modal('hide');
|
||||
|
||||
// Render content
|
||||
rendered = this.render('views/'+ view +'.ms', data);
|
||||
var rendered = this.render('views/'+ view +'.ms', data);
|
||||
|
||||
// Update content helper
|
||||
var leSwap = function() {
|
||||
|
@ -254,7 +264,7 @@
|
|||
cancelCallback = typeof cancelCallback !== 'undefined' ? cancelCallback : function() {};
|
||||
|
||||
// Get modal element
|
||||
box = $('#modal');
|
||||
var box = $('#modal');
|
||||
|
||||
// Modal title
|
||||
if (typeof title === 'string' && title.length) {
|
||||
|
@ -312,8 +322,8 @@
|
|||
},
|
||||
|
||||
groupHooks: function(hooks) {
|
||||
data={};
|
||||
var rules=[
|
||||
var data = {};
|
||||
var rules = [
|
||||
{
|
||||
id:'configuration',
|
||||
isIn:function (hook) {
|
||||
|
@ -350,7 +360,7 @@
|
|||
},
|
||||
|
||||
ungroupHooks: function(hooks,apps) {
|
||||
var data={};
|
||||
var data = {};
|
||||
data['apps'] = apps || [];
|
||||
data['hooks'] = hooks || [];
|
||||
|
||||
|
|
|
@ -42,6 +42,23 @@
|
|||
return new Handlebars.SafeString(result);
|
||||
});
|
||||
|
||||
// Block helper to add a tooltip to any element
|
||||
Handlebars.registerHelper('tooltip', function(tooltip, options) {
|
||||
return new Handlebars.SafeString(
|
||||
'<span data-toggle="tooltip" title="' + tooltip + '" data-placement="right">'
|
||||
+ options.fn(this)
|
||||
+ '</span>');
|
||||
});
|
||||
|
||||
// Load tooltips on the page; needed if using tooltips
|
||||
Handlebars.registerHelper('load_tooltips', function() {
|
||||
return new Handlebars.SafeString(
|
||||
'<script>'
|
||||
+ '$(document).ready(function(){'
|
||||
+ '$(\'[data-toggle="tooltip"]\').tooltip();'
|
||||
+ '});'
|
||||
+ '</script>');
|
||||
});
|
||||
|
||||
// Look for supported type of storage to use
|
||||
/**
|
||||
|
@ -77,7 +94,7 @@
|
|||
// Get YunoHost version
|
||||
if (sam.store.get('connected')) {
|
||||
this.api('/version', function(versions) {
|
||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost]));
|
||||
$('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
defaultLocale: "en",
|
||||
locale: "en",
|
||||
placeholder: /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm,
|
||||
translations: {},
|
||||
translations: {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -335,5 +335,34 @@
|
|||
"confirm_upnp_enable": "Möchtest du wirklich UPnP aktivieren?",
|
||||
"confirm_upnp_disable": "Möchtest du wirklich UPnP deaktivieren?",
|
||||
"confirm_firewall_open": "Möchtest du wirklich Port %s1 öffnen? (Protokoll: %s2, Verbindung: %s3)",
|
||||
"confirm_firewall_close": "Möchtest du wirklich Port %s1 schließen? (Protokoll: %s2, Verbindung: %s3)"
|
||||
"confirm_firewall_close": "Möchtest du wirklich Port %s1 schließen? (Protokoll: %s2, Verbindung: %s3)",
|
||||
"remove": "Entfernen",
|
||||
"confirm_update_specific_app": "Möchtest du wirklich %s aktualisieren?",
|
||||
"confirm_reboot_action_reboot": "Möchtest du wirklich den Server neustarten?",
|
||||
"confirm_reboot_action_shutdown": "Möchtest du wirklich den Server herunterfahren?",
|
||||
"domain_dns_conf_is_just_a_recommendation": "Diese Seite zeigt dir die *empfohlene* Konfiguration. Sie konfiguriert *nicht* den DNS für dich. Es liegt in deiner Verantwortung, deine Zone bei deinem Registrar entsprechend dieser Empfehlung zu konfigurieren.",
|
||||
"ok": "OK",
|
||||
"system_upgrade_all_applications_btn": "Aktualisiere alle Applikationen",
|
||||
"system_upgrade_all_packages_btn": "Aktualisiere alle Pakete",
|
||||
"tools_reboot": "Starte deine Server neu",
|
||||
"tools_reboot_btn": "Neustart",
|
||||
"tools_reboot_done": "Starte neu...",
|
||||
"tools_rebooting": "Dein Server startet neu. Um zur Verwaltungsoberfläche zurückzukehren, musst du warten bis der Server hochgefahren ist. Feststellen kannst du es, in dem du die Seite neu lädst.",
|
||||
"tools_shutdown": "Fahre deinen Server herunter",
|
||||
"tools_shutdown_btn": "Herunterfahren",
|
||||
"tools_shutdown_done": "Fahre herunter...",
|
||||
"tools_shuttingdown": "Dein Server wird heruntergefahren. Solange dein Server ausgeschaltet ist, kannst du das Verwaltungsoberfläche nicht benutzen.",
|
||||
"tools_shutdown_reboot": "Herunterfahren/Neustarten",
|
||||
"appslists": "Applikationslisten",
|
||||
"appslists_no_lists": "Keine Applikationslisten",
|
||||
"appslists_custom": "Eigene Applikationslisten",
|
||||
"appslists_manage": "Verwalte Applikationslisten",
|
||||
"appslists_confirm_remove": "Möchtest du wirklich diese Applikationsliste entfernen?",
|
||||
"appslists_info_refresh_desc": "Aktualisiere die Paketinformationen für diese Liste.",
|
||||
"appslists_info_remove_desc": "Applikationen aus dieser Liste werden nicht mehr verfügbar sein.",
|
||||
"appslists_last_update": "Letzte Aktualisierung",
|
||||
"appslists_unknown_list": "Die Liste %s ist unbekannt",
|
||||
"appslists_community_list": "Applikationsliste der Community",
|
||||
"name": "Name",
|
||||
"install_community_appslists_warning": "Nimm zur Kenntnis, dass diese Applikationen <strong>nicht</strong> offiziell sind und nicht von YunoHost gepflegt werden.<br /> Diese Applikationen sind auf eigenes Risiko zu installieren und können dein System demolieren."
|
||||
}
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
"app_access_removeall_desc": "No users will have access to %s.",
|
||||
"app_access_title": "%s access",
|
||||
"app_change_label": "Change Label",
|
||||
"app_change_url": "Change URL",
|
||||
"app_debug_no_logs": "Application's logs are not available",
|
||||
"app_debug_tab": "Display debug information",
|
||||
"app_info_access_desc": "Manage user access. Allowed users: %s",
|
||||
"app_info_changelabel_desc": "Change app label in the portal.",
|
||||
"app_info_debug_desc": "Display debugging information for this application.",
|
||||
"app_info_default_desc": "Redirect domain root to this application (%s).",
|
||||
"app_info_changeurl_desc": "Change the access URL of this application (domain and/or path).",
|
||||
"app_info_change_url_disabled_tooltip": "This feature hasn't been implemented in this app yet",
|
||||
"app_info_uninstall_desc": "Remove this application.",
|
||||
"app_install_cancel": "Installation cancelled.",
|
||||
"app_install_custom_no_manifest": "No manifest.json file",
|
||||
|
@ -62,6 +65,7 @@
|
|||
"confirm_access_clear": "Are you sure you want to clear all access to %s ?",
|
||||
"confirm_access_remove_all": "Are you sure you want to remove all access to %s ?",
|
||||
"confirm_access_remove_user": "Are you sure you want to remove access to %s for %s ?",
|
||||
"confirm_app_change_url": "Are you sure you want to change the app access URL ?",
|
||||
"confirm_app_default": "Are you sure you want to make this app default ?",
|
||||
"confirm_change_maindomain": "Are you sure you want to change the main domain ?",
|
||||
"confirm_delete": "Are you sure you want to delete %s ?",
|
||||
|
@ -78,8 +82,11 @@
|
|||
"confirm_uninstall": "Are you sure you want to uninstall %s ?",
|
||||
"confirm_update_apps": "Are you sure you want to update all applications?",
|
||||
"confirm_update_packages": "Are you sure you want to update all packages?",
|
||||
"confirm_update_specific_app": "Are you sure you want to update %s?",
|
||||
"confirm_upnp_enable": "Are you sure you want to enable UPnP?",
|
||||
"confirm_upnp_disable": "Are you sure you want to disable UPnP?",
|
||||
"confirm_reboot_action_reboot": "Are you sure you want to reboot your server?",
|
||||
"confirm_reboot_action_shutdown": "Are you sure you want to shutdown your server?",
|
||||
"connection": "Connection",
|
||||
"copy": "Copy",
|
||||
"count_min": "%s min",
|
||||
|
@ -91,6 +98,7 @@
|
|||
"default": "Default",
|
||||
"delete": "Delete",
|
||||
"description": "Description",
|
||||
"domain_dns_conf_is_just_a_recommendation": "This page shows you the *recommended* configuration. It does *not* configure the DNS for you. It is your responsability to configure your DNS zone in your DNS registrar according to this recommendation.",
|
||||
"diagnosis": "Diagnosis",
|
||||
"diagnosis_hide_private": "Show diagnostic information without private data",
|
||||
"diagnosis_view_private": "Show diagnostic information including private data",
|
||||
|
@ -129,7 +137,7 @@
|
|||
"everyone_has_access": "Everyone has access.",
|
||||
"filesystem": "Filesystem",
|
||||
"firewall": "Firewall",
|
||||
"footer_version" : "Powered by <a href='https://yunohost.org'>YunoHost</a> %s.",
|
||||
"footer_version" : "Powered by <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
|
||||
"form_input_example" : "Example: %s",
|
||||
"free": "Free",
|
||||
"fs_type": "FS Type",
|
||||
|
@ -161,6 +169,7 @@
|
|||
"installed_apps": "Installed apps",
|
||||
"installing": "Installing",
|
||||
"interface": "Interface",
|
||||
"internal_exception": "<strong>Yunohost encountered an internal error :/</strong><br><em>Really sorry about that.<br>You should look for help on <a href=\"https://forum.yunohost.org/\">the forum</a> or <a href=\"https://chat.yunohost.org/\">the chat</a> to fix the situation, or report the bug on <a href=\"https://dev.yunohost.org/projects/yunohost/issues\">the bugtracker</a>.</em><br>The following information might be useful for the person helping you :<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
|
||||
"io": "I/O",
|
||||
"ipv4": "IPv4",
|
||||
"ipv6": "IPv6",
|
||||
|
@ -197,6 +206,7 @@
|
|||
"no_log": "No log.",
|
||||
"no_user_to_add": "No more users to add.",
|
||||
"non_compatible_api": "Non-compatible API",
|
||||
"ok": "OK",
|
||||
"open": "Open",
|
||||
"operations": "Operations",
|
||||
"os": "OS",
|
||||
|
@ -208,6 +218,7 @@
|
|||
"passwords_dont_match": "Passwords don't match",
|
||||
"passwords_too_short": "Password is too short",
|
||||
"path": "Path",
|
||||
"path_url": "Path",
|
||||
"port": "Port",
|
||||
"ports": "Ports",
|
||||
"postinstall": "Post-installation",
|
||||
|
@ -254,6 +265,8 @@
|
|||
"system_update": "System update",
|
||||
"system_upgrade": "System upgrade",
|
||||
"system_upgrade_btn": "Upgrade",
|
||||
"system_upgrade_all_applications_btn": "Upgrade all applications",
|
||||
"system_upgrade_all_packages_btn": "Upgrade all packages",
|
||||
"tcp": "TCP",
|
||||
"time_since_update": "Time since update: ",
|
||||
"tools": "Tools",
|
||||
|
@ -268,6 +281,15 @@
|
|||
"tools_security_feed_no_items": "No security notifications",
|
||||
"tools_security_feed_subscribe_rss": "Subscribe to security notifications RSS",
|
||||
"tools_security_feed_view_items": "View all security notifications",
|
||||
"tools_reboot": "Reboot your server",
|
||||
"tools_reboot_btn": "Reboot",
|
||||
"tools_reboot_done": "Rebooting...",
|
||||
"tools_rebooting": "Your server is rebooting. To return on the web administration interface you need to wait your server to be up. You can check that by refreshing regularly this page (F5).",
|
||||
"tools_shutdown": "Shutdown your server",
|
||||
"tools_shutdown_btn": "Shutdown",
|
||||
"tools_shutdown_done": "Shutting down...",
|
||||
"tools_shuttingdown": "Your server is powerring off. As long as your server is off, you won't be able to use the web administration.",
|
||||
"tools_shutdown_reboot": "Shutdown/Reboot",
|
||||
"total": "Total",
|
||||
"transmission": "Transmission",
|
||||
"udp": "UDP",
|
||||
|
@ -328,6 +350,7 @@
|
|||
"install_letsencrypt_cert" : "Install a Let's Encrypt certificate",
|
||||
"manually_renew_letsencrypt_message" : "Certificate will be automatically renewed during the last 15 days of validity. You can manually renew it if you want to. (Not recommended).",
|
||||
"manually_renew_letsencrypt" : "Manually renew now",
|
||||
"meltdown" : "You are vulnerable to the <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a> critical security vulnerability. To fix that, you need to <a href=\"#/update\">update your system</a> then <a href=\"#/tools/reboot\">reboot it</a> to load the new linux kernel.",
|
||||
"regenerate_selfsigned_cert_message" : "If you want, you can regenerate the self-signed certificate.",
|
||||
"regenerate_selfsigned_cert" : "Regenerate self-signed certificate",
|
||||
"revert_to_selfsigned_cert_message" : "If you really want to, you can reinstall a self-signed certificate. (Not recommended)",
|
||||
|
@ -347,4 +370,3 @@
|
|||
"install_community_appslists_warning" : "Note that these applications packages are <strong>not</strong> official and not maintained by the YunoHost team.<br />Installing these applications is at your own risk and could break your system.",
|
||||
"install_custom_app_appslists_info" : "Note that you can use alternative applications lists to install some other apps maintained by the YunoHost community."
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
{}
|
||||
{
|
||||
"password": "Pasvorto",
|
||||
"login": "Ensaluti",
|
||||
"logout": "Elsaluti",
|
||||
"cancel": "Nuligi"
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@
|
|||
"wrong_password": "Mot de passe incorrect",
|
||||
"yes": "Oui",
|
||||
"form_input_example": "Exemple : %s",
|
||||
"footer_version": "Propulsé par <a href='https://yunohost.org'>YunoHost</a> %s.",
|
||||
"footer_version": "Propulsé par <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
|
||||
"certificate_alert_not_valid": "Critique : le certificat actuel est invalide ! Le HTTPS ne fonctionnera pas du tout !",
|
||||
"certificate_alert_selfsigned": "Attention : le certification actuel est auto-signé. Les navigateurs afficheront une alerte effrayante aux nouveaux visiteurs !",
|
||||
"certificate_alert_letsencrypt_about_to_expire": "Le certificat actuel est sur le point d’expirer. Il doit être renouvelé automatiquement prochainement.",
|
||||
|
@ -349,5 +349,22 @@
|
|||
"name": "Nom",
|
||||
"install_community_appslists_info": "La liste des applications communautaires vous permet d’installer les applications maintenues par la communauté. <br />Parcourez la liste complète sur <a href='https://yunohost.org/apps_in_progress'>yunohost.org/apps_in_progress_fr</a>.",
|
||||
"install_community_appslists_warning": "Ces applications <strong>ne sont ni</strong> officielles, ni maintenues par l’équipe YunoHost. <br />Installer ces applications est à vos risques et périls, et peut casser votre système.",
|
||||
"install_custom_app_appslists_info": "Vous pouvez utiliser des listes alternatives d’applications pour installer d’autres applications maintenues par la communauté YunoHost."
|
||||
"install_custom_app_appslists_info": "Vous pouvez utiliser des listes alternatives d’applications pour installer d’autres applications maintenues par la communauté YunoHost.",
|
||||
"domain_dns_conf_is_just_a_recommendation": "Cette page montre la configuration *recommandée*. Elle ne configure *pas* le DNS pour vous. Il est de votre responsabilité que de configurer votre zone DNS chez votre registrar DNS avec cette recommandation.",
|
||||
"internal_exception": "<strong>YunoHost a rencontré une erreur interne :/</strong><br><em>Vraiment navré.<br>Vous devriez chercher de l’aide sur <a href=\"https://forum.yunohost.org/\">le forum</a> ou <a href=\"https://chat.yunohost.org/\">le salon</a> pour résoudre le problème, ou rapporter le bogue sur <a href=\"https://dev.yunohost.org/projects/yunohost/issues\">l’outil de suivi</a>.</em><br>Les informations suivantes peuvent être utile à l’interlocuteur vous aidant :<h3>Action</h3><pre>%s %s</pre><h3>Trace</h3><pre>%s</pre>",
|
||||
"confirm_reboot_action_reboot": "Êtes vous sûr de vouloir redémarrer votre serveur ?",
|
||||
"confirm_reboot_action_shutdown": "Êtes vous sûr de vouloir éteindre votre serveur ?",
|
||||
"confirm_update_specific_app": "Êtes vous sûr de vouloir mettre à jour %s ?",
|
||||
"ok": "OK",
|
||||
"system_upgrade_all_applications_btn": "Mettre à jour toutes les applications",
|
||||
"system_upgrade_all_packages_btn": "Mettre à jour tous les paquets",
|
||||
"tools_reboot": "Redémarrer votre serveur",
|
||||
"tools_reboot_btn": "Redémarrer",
|
||||
"tools_reboot_done": "Redémarrage...",
|
||||
"tools_rebooting": "Votre serveur redémarre. Pour retourner sur l'interface d'administration vous devez attendre que votre serveur soit démarré. Pour pouvez vérifier cela en actualisant cette page (F5).",
|
||||
"tools_shutdown": "Eteindre votre serveur",
|
||||
"tools_shutdown_btn": "Eteindre",
|
||||
"tools_shutdown_done": "Arrêt en cours...",
|
||||
"tools_shuttingdown": "Votre serveur est éteint. Tant que votre serveur est éteint vous ne pouvez plus utiliser l'interface d'administration.",
|
||||
"tools_shutdown_reboot": "Arrêter/Redémarrer"
|
||||
}
|
||||
|
|
31
src/locales/ru.json
Normal file
31
src/locales/ru.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"action": "Действие",
|
||||
"add": "Добавить",
|
||||
"administration_password": "Пароль администратора",
|
||||
"allowed_users": "Разрешенные пользователи",
|
||||
"api_not_responding": "API не отвечает",
|
||||
"app_access": "Доступ",
|
||||
"app_access_addall_btn": "Включить доступ ко всем",
|
||||
"app_access_addall_desc": "Все существующие пользователи будут иметь доступ к %s.",
|
||||
"app_access_clearall_btn": "Очистить доступы",
|
||||
"app_access_clearall_desc": "Каждый пользователь будет иметь доступ к %s.",
|
||||
"app_access_removeall_btn": "Удалить все доступы",
|
||||
"app_access_removeall_desc": "Пользователи не получат доступа к %s.",
|
||||
"app_access_title": "%s доступ",
|
||||
"app_debug_no_logs": "Журналы приложений недоступны",
|
||||
"app_debug_tab": "Отображать отладочную информацию",
|
||||
"app_info_access_desc": "Управление доступом пользователей. Разрешенные пользователи: %s",
|
||||
"remove": "Удалить",
|
||||
"app_info_default_desc": "Перенаправить домен root в это приложение (%s).",
|
||||
"app_info_uninstall_desc": "Удалите это приложение.",
|
||||
"app_install_cancel": "Установка отменена.",
|
||||
"app_install_custom_no_manifest": "Нет файла manifest.json",
|
||||
"app_list": "Нет файла manifest.json",
|
||||
"app_make_default": "Использовать по умолчанию",
|
||||
"app_repository": "Происхождение приложения: ",
|
||||
"app_state": "Состояние приложения: ",
|
||||
"app_state_inprogress": "Выполняется",
|
||||
"app_state_validated": "Проверенный",
|
||||
"app_state_working": "Работает",
|
||||
"password": "Пароль"
|
||||
}
|
38
src/views/app/app_changeurl.ms
Normal file
38
src/views/app/app_changeurl.ms
Normal file
|
@ -0,0 +1,38 @@
|
|||
<div class="btn-breadcrumb">
|
||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
||||
<a href="#/apps" class="hidden-xs">{{t 'applications'}}</a>
|
||||
<a href="#/apps" class="visible-xs">…</a>
|
||||
<a href="#/apps/{{id}}">{{label}}</a>
|
||||
<a href="#/apps/{{id}}/changeurl">{{t 'app_change_url'}}</a>
|
||||
</div>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<form action="#/apps/{{id}}/changeurl" method="POST" class="form-horizontal form-app-install">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title"><span class="fa-fw fa-exchange"></span> {{t 'app_change_url'}}</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label for="domain" class="col-sm-12">{{t 'domain'}}</label>
|
||||
<div class="col-sm-12">
|
||||
<select id="domain" name="domain" required class="form-control" {{{attributes}}}>
|
||||
{{#each domains}}<option value="{{this.value}}" {{#if selected}}selected{{/if}}>{{this.label}}</option>{{/each}}
|
||||
</select>
|
||||
<span class="help-block help-block--link"><a href='#/domains'>{{t 'manage_domains'}}</a></span>
|
||||
</div>
|
||||
|
||||
<label for="path" class="col-sm-12">{{t 'path_url'}}</label>
|
||||
<div class="col-sm-12">
|
||||
<input class="col-sm-12" type="text" id="path" name="path" class="form-control" value="{{path}}" required="required">
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<input type="hidden" name="app" value="{{id}}">
|
||||
<div class="text-center">
|
||||
<input type="submit" class="btn btn-success slide back" value="{{t 'app_change_url'}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -57,6 +57,21 @@
|
|||
</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="container">
|
||||
<p>{{t 'app_info_changeurl_desc' settings.domain}}</p>
|
||||
{{#if change_url}}
|
||||
<a href="#/apps/{{settings.id}}/changeurl" class="btn btn-info slide">
|
||||
<span class="fa-exchange"></span> {{t 'app_change_url'}}
|
||||
</a>
|
||||
{{else}}
|
||||
{{#tooltip (t 'app_info_change_url_disabled_tooltip') }}
|
||||
<a href="#/apps/{{settings.id}}/changeurl" class="btn btn-info slide disabled">
|
||||
<span class="fa-exchange"></span> {{t 'app_change_url'}}
|
||||
</a>
|
||||
{{/tooltip}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<hr>
|
||||
<div class="container">
|
||||
<p>{{t 'app_info_uninstall_desc'}}</p>
|
||||
<a href="#/apps/{{settings.id}}/uninstall" class="btn btn-danger slide back">
|
||||
|
@ -72,3 +87,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{load_tooltips}}
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
<a href="#/domains/{{name}}">{{name}}</a>
|
||||
<a href="#/domains/{{name}}/dns">{{t 'dns'}}</a>
|
||||
</div>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<span class="fa-fw fa-warning"></span> {{t 'domain_dns_conf_is_just_a_recommendation' }}
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
<span class="fa-chevron-right pull-right"></span>
|
||||
<h2 class="list-group-item-heading">{{t 'tools_security_feed'}}</h2>
|
||||
</a>
|
||||
<a href="#/tools/reboot" class="list-group-item slide clearfix">
|
||||
<span class="pull-right fa-chevron-right"></span>
|
||||
<h2 class="list-group-item-heading">{{t 'tools_shutdown_reboot'}}</h2>
|
||||
</a>
|
||||
<a href="#/tools/versions" class="list-group-item slide clearfix">
|
||||
<span class="pull-right fa-chevron-right"></span>
|
||||
<h2 class="list-group-item-heading">{{t 'versions'}}</h2>
|
||||
|
|
28
src/views/tools/tools_reboot.ms
Normal file
28
src/views/tools/tools_reboot.ms
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="btn-breadcrumb">
|
||||
<a href="#/" ><i class="fa-home"></i><span class="sr-only">{{t 'home'}}</span></a>
|
||||
<a href="#/tools">{{t 'tools'}}</a>
|
||||
<a href="#/tools/reboot">{{t 'tools_shutdown_reboot'}}</a>
|
||||
</div>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
<span class="fa-fw fa-wrench"></span> {{t 'operations'}}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
<a href="#/tools/reboot/reboot" class="btn btn-danger">
|
||||
<i class="fa-refresh"></i> {{t 'tools_reboot_btn'}}
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="#/tools/reboot/shutdown" class="btn btn-danger">
|
||||
<i class="fa-power-off"></i> {{t 'tools_shutdown_btn'}}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
|
@ -26,7 +26,7 @@
|
|||
{{/packages}}
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="#/upgrade/packages" class="btn btn-success">{{t 'system_upgrade_btn'}}</a>
|
||||
<a href="#/upgrade/packages" class="btn btn-success">{{t 'system_upgrade_all_packages_btn'}}</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel-body">
|
||||
|
@ -42,13 +42,14 @@
|
|||
{{#if apps}}
|
||||
<div class="list-group">
|
||||
{{#apps}}
|
||||
<div class="list-group-item">
|
||||
<div class="list-group-item clearfix">
|
||||
<a href="#/upgrade/apps/{{id}}" class="btn btn-success pull-right">{{t 'system_upgrade_btn'}}</a>
|
||||
<h3 class="list-group-item-heading">{{label}} <small>{{id}}</small></h3>
|
||||
</div>
|
||||
{{/apps}}
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="#/upgrade/apps" class="btn btn-success">{{t 'system_upgrade_btn'}}</a>
|
||||
<a href="#/upgrade/apps" class="btn btn-success">{{t 'system_upgrade_all_applications_btn'}}</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel-body">
|
||||
|
|
Loading…
Add table
Reference in a new issue