yunohost-admin/js/app.js

1405 lines
50 KiB
JavaScript
Raw Normal View History

2013-07-01 15:56:32 +02:00
app = Sammy('#main', function (sam) {
2013-07-02 12:35:31 +02:00
/**
* Sammy Configuration
*
*/
// Plugins
sam.use('Handlebars', 'ms');
2013-07-01 15:56:32 +02:00
2014-02-18 23:26:11 +01:00
Handlebars.registerHelper('ucwords', function(str) {
return (str + '').replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function ($1) {
return $1.toUpperCase();
});
});
Handlebars.registerHelper('humanSize', function(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]];
});
2014-02-14 20:28:16 +01:00
Handlebars.registerHelper('humanTime', function(time) {
return Math.round(time) + 's';
});
2014-02-14 22:59:49 +01:00
Handlebars.registerHelper('bitRate', function(bytes, time) {
var sizes = ['b', 'Kb', 'Mb', 'Gb', 'Tb'];
if (time == 0) return 'n/a';
var bps = bytes / time * 8;
var i = parseInt(Math.floor(Math.log(bps) / Math.log(1024)));
return Math.round(bps / Math.pow(1024, i), 2) + ' ' + sizes[[i]] + '/s';
});
2014-05-12 18:28:42 +02:00
Handlebars.registerHelper('t', function(y18n_key) {
var result = y18n.t(y18n_key, Array.prototype.slice.call(arguments, 1));
return new Handlebars.SafeString(result);
});
2013-12-15 17:14:42 +01:00
// Look for supported type of storage to use
var storageType;
if (Sammy.Store.isAvailable('session')) {
storageType = 'session';
} else if (Sammy.Store.isAvailable('cookie')) {
storageType = 'cookie';
} else {
storageType = 'memory';
}
2013-07-02 12:35:31 +02:00
// Initialize storage
2013-12-15 17:14:42 +01:00
var store = new Sammy.Store({name: 'storage', type: storageType});
2013-11-23 13:02:55 +01:00
var loaded = false;
2013-07-01 15:56:32 +02:00
2013-07-02 12:35:31 +02:00
/**
* Helpers
*
*/
2013-07-01 19:32:11 +02:00
sam.helpers({
2013-07-02 12:35:31 +02:00
2013-11-22 15:31:47 +01:00
// Serialize an object
serialize : function(obj) {
var str = [];
for(var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
},
2013-07-02 12:35:31 +02:00
// Flash helper to diplay instant notifications
2013-07-01 19:32:11 +02:00
flash: function (level, message) {
if (!store.get('flash')) {
store.set('flash', true);
}
if (level == 'fail') { alertClass = 'alert-danger'; }
else { alertClass = 'alert-'+ level; }
if ($('#flash .alert').last().hasClass(alertClass)) {
if (level == 'log') {
$('#flash .alert').last().append('<p style="display: none">'+ message +'</p>');
} else {
$('#flash .alert').last().append('<p>'+ message +'</p>');
}
} else {
if (level == 'log') {
$('#flash').append('<pre style="display:none" class="alert alert-dismissable '+ alertClass +'"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><div><button type="button" class="btn btn-default btn-small">'+ y18n.t('log') +'</button></div><p style="display: none">'+ message +'</p></pre>').show();
} else {
$('#flash').append('<div style="display:none" class="alert alert-dismissable '+ alertClass +'"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><p>'+ message +'</p></div>').show();
}
$('#flash .alert').last().fadeIn();
2013-07-01 19:32:11 +02:00
}
document.body.scrollTop = document.documentElement.scrollTop = 0;
$('#flash .alert-log button.btn-small').on('click', function() {
$('#flash .alert-log p:hidden').fadeIn();
$('#flash .alert-log div').hide();
});
2013-07-01 19:32:11 +02:00
},
2013-07-02 12:35:31 +02:00
2014-05-25 23:11:47 +02:00
checkInstall: function(callback) {
2014-05-25 22:13:42 +02:00
domain = window.location.hostname;
$.ajax({
dataType: "json",
url: 'https://'+ domain +'/yunohost/api/installed',
timeout: 3000
})
.success(function(data) {
2014-05-25 23:11:47 +02:00
callback(data.installed);
2014-05-25 22:13:42 +02:00
})
.fail(function() {
2014-05-26 00:17:42 +02:00
callback(undefined);
2014-05-25 22:13:42 +02:00
});
},
// API call
api: function(uri, callback, method, data, websocket) {
2014-05-20 10:54:13 +02:00
c = this;
call = function(uri, callback, method, data) {
method = typeof method !== 'undefined' ? method : 'GET';
data = typeof data !== 'undefined' ? data : {};
if (window.navigator && window.navigator.language && (typeof data.locale === 'undefined')) {
data.locale = window.navigator.language;
}
2013-10-31 20:37:43 +01:00
var args = data;
// auth = "Basic "+ btoa('admin' +':'+ atob('yolo'));
if (uri === '/postinstall') {
var installing = false;
2013-11-23 13:02:55 +01:00
setInterval(function () {
installing = true;
}, 1500);
2014-05-25 22:13:42 +02:00
}
2014-05-25 23:27:25 +02:00
loaded = false;
2014-05-25 22:13:42 +02:00
if ($('div.loader').length == 0) {
setInterval(function () {
if (!loaded && $('div.loader').length == 0) {
$('#main').append('<div class="loader loader-content"></div>');
}
}, 500);
2013-11-23 13:02:55 +01:00
}
jQuery.ajax({
url: 'https://'+ store.get('url') + uri,
type: method,
crossdomain: true,
data: data,
traditional: true,
dataType: 'json',
// beforeSend: function(req) {
// req.setRequestHeader('Authorization', auth);
// }
})
/*
.always(function(data) {
if (data.status !== 'undefined' && uri === '/login') {
if (data.status === 401) {
c.flash('fail', y18n.t('wrong_password'));
}
// 200 & empty response TODO: better comment
// /login
else if (data.status === 200) {
// data = typeof data !== 'undefined' ? data : {};
if (typeof data.win !== 'undefined') {
$.each(data.win, function(k, v) {
c.flash('success', v);
});
}
callback(data);
2014-05-17 00:38:47 +02:00
}
}
loaded = true;
$('div.loader').remove();
2014-05-17 00:38:47 +02:00
})
2014-05-17 00:38:47 +02:00
*/
.always(function(xhr, ts, error) {
// console.log("always");
// console.log(xhr);
// console.log(ts);
// console.log(error);
})
.done(function(data) {
// console.log('success');console.log(data);
// data = typeof data !== 'undefined' ? data : {};
data = data || {};
callback(data);
})
.fail(function(xhr) {
// console.log('fail');console.log(xhr);
2014-06-07 14:51:36 +02:00
if (xhr.status == 200) {
// Fail with 200, WTF
callback({});
} else if (xhr.status == 401) {
if (uri === '/login') {
c.flash('fail', y18n.t('wrong_password'));
} else {
c.flash('fail', y18n.t('unauthorized'));
c.redirect('#/login');
}
} else if (typeof xhr.responseJSON !== 'undefined') {
c.flash('fail', xhr.responseJSON.error);
} else if (typeof xhr.responseText !== 'undefined' && uri !== '/postinstall') {
c.flash('fail', xhr.responseText);
} else {
2014-05-26 00:33:51 +02:00
if (uri === '/postinstall') {
if (installing) {
interval = window.location.hostname === args.domain ? 20000 : 5000;
checkInstall = setInterval(function () {
c.checkInstall(function(isInstalled) {
if (isInstalled || typeof isInstalled === 'undefined') {
c.flash('success', y18n.t('installation_complete'));
clearInterval(checkInstall);
window.location.href = 'https://'+ window.location.hostname +'/yunohost/admin/';
}
});
}, interval);
} else {
c.flash('fail', y18n.t('error_occured'));
}
2013-11-21 10:54:33 +01:00
} else {
c.flash('fail', y18n.t('error_server'));
2013-10-31 20:37:43 +01:00
}
}
2014-05-26 00:33:51 +02:00
if (uri !== '/postinstall') {
store.clear('slide');
c.redirect(store.get('path-1'));
};
});
}
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');
ws.onmessage = function(evt) {
2014-06-16 16:15:28 +02:00
// console.log(evt.data);
$.each($.parseJSON(evt.data), function(k, v) {
c.flash(k, v);
});
}
// If not connected, WebSocket connection will raise an error, but we do not want to interrupt API request
ws.onerror = ws.onopen;
ws.onclose = function() {
store.clear('flash');
}
ws.onopen = call(uri, callback, method, data);
} else {
call(uri, callback, method, data);
}
},
2013-07-02 12:35:31 +02:00
// Render view (cross-browser)
2014-05-25 22:13:42 +02:00
view: function (view, data, callback) {
callback = typeof callback !== 'undefined' ? callback : function() {};
2013-09-21 19:46:26 +02:00
rendered = this.render('views/'+ view +'.ms', data);
2013-09-25 21:49:12 +02:00
enableSlide = true; // Change to false to disable animation
2013-11-23 13:02:55 +01:00
loaded = true;
2014-05-16 18:38:46 +02:00
$('div.loader').remove();
2013-11-23 13:02:55 +01:00
2013-09-25 21:49:12 +02:00
if (enableSlide) {
function leSwap() {
rendered.swap(function() {
$('.slide').on('click', function() {
$(this).addClass('active');
if ($(this).hasClass('back')) {
store.set('slide', 'back');
} else {
store.set('slide', 'to');
}
});
2014-05-25 22:13:42 +02:00
callback();
// Force scrollTop on page load
$('html, body').scrollTop(0);
2013-09-21 19:46:26 +02:00
});
2013-09-25 21:49:12 +02:00
}
2013-09-21 20:59:47 +02:00
2013-09-25 21:49:12 +02:00
blockSize = $('#slider').width();
// Slide back effect
if (store.get('slide') == 'back') {
store.clear('slide');
$('#slideBack').css('display', 'none');
$('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
$('#slideTo').show().html($('#main').html());
leSwap();
$('#slider-container').addClass('move').css('margin-left', '0px');
// Slide to effect
} else if (store.get('slide') == 'to') {
store.clear('slide');
$('#slideTo').css('display', 'none');
$('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
$('#slider-container').removeClass('move').css('margin-left', '0px');
$('#slideBack').show().html($('#main').html());
leSwap();
$('#slider-container').addClass('move').css('margin-left', '-'+ blockSize +'px');
2013-09-25 02:33:39 +02:00
2013-09-25 21:49:12 +02:00
} else {
leSwap();
}
2013-09-21 19:46:26 +02:00
} else {
rendered.swap(function(){
callback()
// Force scrollTop on page load
$('html, body').scrollTop(0);
});
2013-09-21 19:46:26 +02:00
}
2013-07-01 15:56:32 +02:00
}
2013-07-01 19:32:11 +02:00
});
2013-07-01 15:56:32 +02:00
2013-07-02 12:35:31 +02:00
/**
* Filters
*
*/
sam.before(/apps\/install\//, function (req){
// Preload domains list.
req.params.domains = [];
req.api('/domains', function(data) {
2014-05-17 00:38:47 +02:00
req.params.domains = data.domains;
});
});
sam.before(/apps\/install\//, function (req){
// Preload users lists.
req.params.users = [];
req.api('/users', function(data) {
2014-05-17 00:38:47 +02:00
req.params.users = data.users;
});
});
2013-07-02 12:35:31 +02:00
2014-05-25 22:13:42 +02:00
sam.before({except: {path: ['#/logout', '#/login', '#/postinstall', '#/postinstall/domain', '#/postinstall/password']}}, function (req) {
2013-07-02 12:35:31 +02:00
// Store path for further redirections
2013-09-23 21:18:51 +02:00
store.set('path-1', store.get('path'));
2013-07-01 15:56:32 +02:00
store.set('path', req.path);
2013-07-02 12:35:31 +02:00
2013-09-21 12:10:54 +02:00
// Redirect to login page if no credentials stored
2013-12-19 02:02:32 +01:00
if (!store.get('connected')) {
2013-07-01 15:56:32 +02:00
req.redirect('#/login');
return false;
}
2013-07-02 12:35:31 +02:00
// Clear flash display
if (!store.get('flash')) {
2013-09-22 21:31:51 +02:00
$('#flash').fadeOut(function() { $('#flash').html(''); });
2013-07-02 12:35:31 +02:00
}
2013-07-01 15:56:32 +02:00
});
2013-07-02 12:35:31 +02:00
sam.after(function () {
// Clear flash notifications
store.clear('flash');
2013-07-01 15:56:32 +02:00
});
2013-07-02 12:35:31 +02:00
2014-06-11 18:22:33 +02:00
/**
* Errors
*/
sam.notFound = function(){
// Redirect to home page on 404.
window.location = '#/';
};
2013-07-02 12:35:31 +02:00
/**
* Routes
*
* Note: var "c" is Sammy's route context
* @doc http://sammyjs.org/docs/api/#Sammy.EventContext
*
*/
sam.get('#/', function (c) {
c.api('/users', function(data) {
// Warn admin if no users are created.
2014-05-17 00:38:47 +02:00
if (data.users.length == 0) {
c.flash('warning', y18n.t('warning_first_user'));
}
c.view('home');
});
2013-07-01 15:56:32 +02:00
});
sam.get('#/login', function (c) {
2014-05-25 22:13:42 +02:00
$('#masthead').show();
$('.logout-button').hide();
store.set('path-1', '#/login');
2014-05-27 20:27:19 +02:00
if ($('div.loader').length == 0) {
setInterval(function () {
if (!loaded && $('div.loader').length == 0) {
$('#main').append('<div class="loader loader-content"></div>');
}
}, 500);
}
2014-05-25 23:11:47 +02:00
c.checkInstall(function(isInstalled) {
if (isInstalled) {
domain = window.location.hostname;
2014-05-27 20:27:19 +02:00
$('div.loader').remove();
2014-05-25 23:11:47 +02:00
c.view('login', { 'domain': domain });
} else if (typeof isInstalled === 'undefined') {
2014-05-27 20:27:19 +02:00
setTimeout(function() {
c.redirect('#/');
}, 5000);
2014-05-25 23:11:47 +02:00
} else {
2014-05-27 20:27:19 +02:00
$('div.loader').remove();
2014-05-25 23:27:25 +02:00
c.redirect('#/postinstall');
2014-05-25 23:11:47 +02:00
}
});
2013-07-01 15:56:32 +02:00
});
sam.post('#/login', function (c) {
2014-05-20 10:54:13 +02:00
store.set('url', c.params['domain'] +'/yunohost/api');
2014-05-17 00:38:47 +02:00
// c.api('/api', function(data) {
// if (data.apiVersion) {
params = {
'password': c.params['password']
}
c.api('/login', function(data) {
2013-09-25 21:49:12 +02:00
store.set('connected', true);
2014-05-17 00:38:47 +02:00
$('.logout-button').fadeIn();
c.flash('success', y18n.t('logged_in'));
2013-09-25 21:49:12 +02:00
if (store.get('path')) {
c.redirect(store.get('path'));
} else {
c.redirect('#/');
}
}, 'POST', params, false);
2014-05-17 00:38:47 +02:00
// } else {
// c.flash('fail', y18n.t('non_compatible_api'));
// c.redirect('#/login');
// }
// });
2013-07-01 15:56:32 +02:00
});
2013-07-02 12:35:31 +02:00
sam.get('#/logout', function (c) {
2014-05-17 00:38:47 +02:00
c.api('/logout', function (data) {
store.clear('url');
store.clear('connected');
store.set('path', '#/');
c.flash('success', y18n.t('logged_out'));
c.redirect('#/login');
}, 'GET', {}, false);
});
2013-10-01 12:40:59 +02:00
sam.get('#/postinstall', function(c) {
2014-05-25 22:13:42 +02:00
$('#masthead').hide();
c.checkInstall(function(isInstalled) {
if (isInstalled || typeof isInstalled === 'undefined') {
c.redirect('#/login');
} else {
c.view('postinstall/postinstall_1');
}
});
2014-05-25 22:13:42 +02:00
});
sam.get('#/postinstall/domain', function(c) {
$('#masthead').hide();
c.view('postinstall/postinstall_2', {'ddomains': ['.nohost.me', '.noho.st']}, function() {
$('#domain, #ddomain').keyup(function(event){
if(event.keyCode == 13){
$('a.savedomain').click();
}
});
$('a.savedomain').on('click', function(e) {
if ($('#domain').val() === '') {
if ($('#ddomain').val() === '') {
e.preventDefault();
store.clear('slide');
c.flash('fail', y18n.t('error_select_domain'));
} else {
domain = $('#ddomain').val() + $('select[name="ddomain-ext"]').val();
}
} else {
domain = $('#domain').val();
}
store.set('maindomain', domain);
});
});
2014-05-25 22:13:42 +02:00
});
sam.get('#/postinstall/password', function(c) {
$('#masthead').hide();
$('#flash .alert').remove();
if (!store.get('maindomain')) {
store.clear('slide');
c.redirect('#/postinstall/domain');
} else {
c.view('postinstall/postinstall_3', { 'domain': store.get('maindomain') });
}
2013-10-01 12:40:59 +02:00
});
sam.post('#/postinstall', function (c) {
if (c.params['password'] == '' || c.params['confirmation'] == '') {
2014-05-25 22:13:42 +02:00
c.flash('fail', y18n.t('password_empty'));
}
else if (c.params['password'] == c.params['confirmation']) {
2014-05-25 22:13:42 +02:00
if (c.params['domain'] === '') {
c.flash('fail', y18n.t('error_select_domain'));
store.clear('slide');
c.redirect('#/postinstall/domain');
2013-10-01 12:40:59 +02:00
} else {
2013-10-01 12:45:56 +02:00
params = { 'domain': c.params['domain'] }
2013-10-01 12:40:59 +02:00
}
2014-05-25 22:13:42 +02:00
if (confirm(y18n.t('confirm_postinstall', [c.params['domain']]))) {
params['password'] = c.params['password']
2013-10-01 12:40:59 +02:00
2014-05-25 22:13:42 +02:00
store.set('url', window.location.hostname +'/yunohost/api');
store.set('user', 'admin');
c.api('/postinstall', function(data) { // http://api.yunohost.org/#!/tools/tools_postinstall_post_0
c.redirect('#/login');
}, 'POST', params);
}
2013-10-01 12:40:59 +02:00
} else {
c.flash('fail', y18n.t('passwords_dont_match'));
2013-10-01 12:40:59 +02:00
}
});
/**
* Users
*
*/
2013-09-22 21:31:51 +02:00
sam.get('#/users', function (c) {
c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_list_get_3
c.view('user/user_list', data);
2013-09-22 21:31:51 +02:00
});
});
2013-09-23 13:31:57 +02:00
sam.get('#/users/create', function (c) {
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
c.view('user/user_create', data);
2013-09-23 13:31:57 +02:00
});
});
sam.post('#/users', function (c) {
if (c.params['password'] == c.params['confirmation']) {
if (c.params['password'].length < 4) {
c.flash('fail', y18n.t('password_too_short'));
store.clear('slide');
}
else {
c.params['mail'] = c.params['email'] + c.params['domain'];
c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_create_post_2
c.redirect('#/users');
}, 'POST', c.params.toHash());
}
2013-09-23 13:31:57 +02:00
} else {
c.flash('fail', y18n.t('passwords_dont_match'));
2013-09-23 13:31:57 +02:00
store.clear('slide');
//c.redirect('#/users/create');
}
});
2013-07-02 12:35:31 +02:00
sam.get('#/users/:user', function (c) {
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
c.view('user/user_info', data);
2013-07-02 12:35:31 +02:00
});
});
2013-09-23 00:40:14 +02:00
sam.get('#/users/:user/edit', function (c) {
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
c.api('/domains', function(dataDomains) { // http://api.yunohost.org/#!/domain/domain_list_get_2
email = data.mail.split('@');
data.email = {
username : email[0],
domain : email[1]
}
data.domains = []
$.each(dataDomains.domains, function(key, value) {
data.domains.push({
domain: value,
selected: (value == data.email.domain) ? true : false
})
});
c.view('user/user_edit', data);
});
2013-09-23 00:40:14 +02:00
});
});
2013-09-23 12:31:35 +02:00
sam.put('#/users/:user', function (c) {
params = {}
// concat email/domain pseudo field
if (c.params['mail'] !== c.params['email'] + c.params['domain']) {
c.params['mail'] = c.params['email'] + c.params['domain'];
}
else {
c.params['mail'] = '';
}
c.params['email'] = '';
c.params['domain'] = '';
2013-09-23 12:31:35 +02:00
$.each(c.params.toHash(), function(key, value) {
if (value !== '' && key !== 'user') { params[key] = value; }
2013-09-23 12:31:35 +02:00
});
2013-09-23 12:31:35 +02:00
if ($.isEmptyObject(params)) {
c.flash('fail', y18n.t('error_modify_something'));
2013-09-23 12:31:35 +02:00
store.clear('slide');
// c.redirect('#/users/'+ c.params['user'] + '/edit');
2013-09-23 12:31:35 +02:00
} else {
if (params['password']) {
if (params['password'] == params['confirmation']) {
if (params['password'].length < 4) {
c.flash('fail', y18n.t('password_too_short'));
store.clear('slide');
}
else {
params['change_password'] = params['password'];
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
c.redirect('#/users/'+ c.params['user']);
}, 'PUT', params);
}
} else {
c.flash('fail', y18n.t('passwords_dont_match'));
store.clear('slide');
}
}
else {
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
c.redirect('#/users/'+ c.params['user']);
}, 'PUT', params);
}
2013-09-23 12:31:35 +02:00
}
});
2013-09-23 13:31:57 +02:00
2013-09-23 12:43:11 +02:00
sam.get('#/users/:user/delete', function (c) {
if (confirm(y18n.t('confirm_delete', [c.params['user']]))) {
c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_delete_delete_4
2013-09-23 12:43:11 +02:00
c.redirect('#/users');
}, 'DELETE');
} else {
store.clear('slide');
c.redirect('#/users/'+ c.params['user']);
}
});
/**
* Domains
*
*/
sam.get('#/domains', function (c) {
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
c.api('/domains/main', function(data2) {
2014-03-03 20:20:48 +01:00
domains = [];
2014-05-17 00:38:47 +02:00
$.each(data.domains, function(k, domain) {
2014-03-03 20:20:48 +01:00
domains.push({
url: domain,
main: (domain == data2.current_main_domain) ? true : false
});
})
// Sort domains with main domain first
2014-05-17 00:38:47 +02:00
domains.sort(function(a, b){ return -2*(a.main) + 1; });
c.view('domain/domain_list', {domains: domains});
2014-05-17 00:38:47 +02:00
}, 'PUT');
});
});
sam.get('#/domains/add', function (c) {
2014-05-17 00:38:47 +02:00
c.view('domain/domain_add', {'ddomains': ['.nohost.me', '.noho.st']});
});
sam.post('#/domains/add', function (c) {
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'] }
} else {
params = { 'domain': c.params['domain'] }
}
c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_add_post_1
c.redirect('#/domains');
}, 'POST', params);
});
2013-09-24 22:54:48 +02:00
2014-03-02 20:07:02 +01:00
sam.get('#/domains/:domain/delete', function (c) {
if (confirm(y18n.t('confirm_delete', [c.params['domain']]))) {
c.api('/domains/'+ c.params['domain'], function(data) { // http://api.yunohost.org/#!/domain/domain_remove_delete_3
2014-03-02 20:07:02 +01:00
store.clear('slide');
c.redirect('#/domains');
}, 'DELETE');
} else {
store.clear('slide');
c.redirect('#/domains');
}
});
2014-03-03 20:20:48 +01:00
// Set default domain
sam.post('#/domains', function (c) {
if (c.params['domain'] == '') {
c.flash('fail', y18n.t('error_select_domain'));
2014-03-03 20:20:48 +01:00
store.clear('slide');
c.redirect('#/domains');
} else if (confirm(y18n.t('confirm_change_maindomain'))) {
2014-03-03 20:20:48 +01:00
params = {'new_domain': c.params['domain']}
c.api('/domains/main', function(data) { // http://api.yunohost.org/#!/tools/tools_maindomain_put_1
2014-03-03 20:20:48 +01:00
store.clear('slide');
c.redirect('#/domains');
}, 'PUT', params);
// Wait 15s and refresh the page
refreshDomain = window.setTimeout(function(){
store.clear('slide');
c.redirect('#/domains')
}, 15000);
} else {
store.clear('slide');
c.redirect('#/domains');
}
});
2014-03-02 20:07:02 +01:00
2013-09-24 22:54:48 +02:00
/**
* Apps
*
*/
sam.get('#/apps', function (c) {
2013-11-22 12:16:52 +01:00
c.api('/apps', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
2013-09-24 22:54:48 +02:00
// Keep only installed apps
2014-05-17 00:38:47 +02:00
data2 = { 'apps': [], 'installed': true }
$.each(data['apps'], function(k, v) {
if (v['installed']) data2['apps'].push(v);
2013-09-24 22:54:48 +02:00
});
c.view('app/app_list', data2);
2013-09-24 22:54:48 +02:00
});
});
sam.get('#/apps/install', function (c) {
2013-11-22 12:16:52 +01:00
c.api('/apps', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
2014-05-17 00:38:47 +02:00
c.api('/apps?raw', function(dataraw) { // http://api.yunohost.org/#!/app/app_list_get_8
// Keep only uninstalled apps
data2 = { 'apps': [] }
$.each(data['apps'], function(k, v) {
if (dataraw[v['id']].manifest.multi_instance) v['installed'] = false;
if (!v['installed'] && !v['id'].match(/__[0-9]{1,5}$/)) data2['apps'].push(v);
});
c.view('app/app_list', data2);
2013-09-24 22:54:48 +02:00
});
2013-11-22 12:16:52 +01:00
});
});
2013-11-26 18:22:12 +01:00
sam.get('#/apps/refresh', function (c) {
c.api('/appslists', function(data) { // http://api.yunohost.org/#!/app/app_fetchlist_put_5
2014-05-17 00:38:47 +02:00
// c.redirect(store.get('path'));
c.redirect('#/apps/install');
2013-11-26 18:22:12 +01:00
}, 'PUT');
});
2013-11-22 12:16:52 +01:00
sam.get('#/apps/:app', function (c) {
c.api('/apps/'+c.params['app']+'?raw', function(data) { // http://api.yunohost.org/#!/app/app_info_get_9
// Presentation
2014-05-17 00:38:47 +02:00
data.settings.allowed_users = (data.settings.allowed_users) ? data.settings.allowed_users.replace(',', ', ') : '';
// Multilingual description
data.description = (typeof data.manifest.description[y18n.locale] !== 'indefined') ?
data.manifest.description[y18n.locale] :
data.manifest.description['en']
;
// Multi Instance settings
data.manifest.multi_instance = (data.manifest.multi_instance == 'true') ? y18n.t('yes') : y18n.t('no');
// Installation date
var d = new Date(data.settings.install_time * 1000);
data.install_time = d.getDate() + '/' + (d.getMonth()+1) + '/' + d.getFullYear();
c.view('app/app_info', data);
2013-11-22 12:16:52 +01:00
});
});
sam.get('#/apps/install/:app', function (c) {
c.api('/apps?raw', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
appData = data[c.params['app']];
// Loop through installation arguments
if (typeof appData.manifest.arguments.install !== 'undefined') {
$.each(appData.manifest.arguments.install, function(k, v) {
appData.manifest.arguments.install[k].allowedValues = [];
// 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,
key: ck,
checked: (cv == appData.manifest.arguments.install[k].default) ? true : false,
};
});
}
// Special case for domain input.
// Display a list of available domains
if (v.name == 'domain') {
$.each(c.params.domains, function(key, domain){
appData.manifest.arguments.install[k].allowedValues.push({
value: domain,
label: domain,
});
})
appData.manifest.arguments.install[k].help = "<a href='#/domains'>"+y18n.t('manage_domains')+"</a>";
}
// Special case for admin input.
// Display a list of available users
if (v.name == 'admin') {
$.each(c.params.users, function(key, user){
appData.manifest.arguments.install[k].allowedValues.push({
value: user.username,
label: user.fullname+' ('+user.mail+')'
});
})
appData.manifest.arguments.install[k].help = "<a href='#/users'>"+y18n.t('manage_users')+"</a>";
}
// 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
2014-06-10 17:12:43 +02:00
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');
c.view('app/app_install', appData);
2013-11-22 12:16:52 +01:00
});
2013-09-24 22:54:48 +02:00
});
2013-11-22 15:31:47 +01:00
sam.post('#/apps', function(c) {
params = { 'label': c.params['label'], 'app': c.params['app'] }
delete c.params['label'];
delete c.params['app'];
params['args'] = c.serialize(c.params.toHash());
// Do not pass empty args.
if (params['args'] == "") {
delete params['args'];
}
c.api('/apps', function() { // http://api.yunohost.org/#!/app/app_install_post_2
2013-11-22 15:31:47 +01:00
c.redirect('#/apps');
}, 'POST', params);
});
2013-11-22 16:01:02 +01:00
sam.get('#/apps/:app/uninstall', function (c) {
if (confirm(y18n.t('confirm_uninstall', [c.params['app']]))) {
c.api('/apps/'+ c.params['app'], function() { // http://api.yunohost.org/#!/app/app_remove_delete_4
2013-11-22 16:01:02 +01:00
c.redirect('#/apps');
2013-11-22 17:56:51 +01:00
}, 'DELETE');
2013-11-22 16:01:02 +01:00
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']);
}
});
2014-01-29 18:32:22 +01:00
2014-03-02 19:30:46 +01:00
// Manage app access
sam.get('#/apps/:app/access', function (c) {
c.api('/apps/'+c.params['app']+'?raw', function(data) { // http://api.yunohost.org/#!/app/app_info_get_9
2014-03-02 19:30:46 +01:00
c.api('/users', function(dataUsers) {
// allowed_users as array
if (typeof data.settings.allowed_users !== 'undefined') {
if (data.settings.allowed_users.length === 0) {
// Force empty array, means no user has access
data.settings.allowed_users = [];
}
else {
data.settings.allowed_users = data.settings.allowed_users.split(',');
}
} else {
data.settings.allowed_users = []; // Force array
// if 'allowed_users' is undefined, everyone has access
// that means that undefined is different from empty array
data.settings.allow_everyone = true;
}
// Available users
data.users = [];
2014-05-17 00:38:47 +02:00
$.each(dataUsers.users, function(key, user){
2014-03-02 19:30:46 +01:00
// Do not list allowed_users in select list
2014-05-17 00:38:47 +02:00
if ( data.settings.allowed_users.indexOf(user.username) === -1 ) {
2014-03-02 19:30:46 +01:00
data.users.push({
2014-05-17 00:38:47 +02:00
value: user.username,
label: user.fullname+' ('+user.mail+')'
2014-03-02 19:30:46 +01:00
});
} else {
// Complete allowed_users data
2014-05-17 00:38:47 +02:00
data.settings.allowed_users[data.settings.allowed_users.indexOf(user.username)] = {
username: user.username,
fullname: user.fullname,
mail: user.mail,
2014-03-02 19:30:46 +01:00
}
}
})
c.view('app/app_access', data);
2014-03-02 19:30:46 +01:00
});
});
});
// Remove all access
sam.get('#/apps/:app/access/remove', function (c) {
if (confirm(y18n.t('confirm_access_remove_all', [c.params['app']]))) {
2014-03-02 19:30:46 +01:00
params = {'apps': c.params['app'], 'users':[]}
c.api('/access?'+c.serialize(params), function(data) { // http://api.yunohost.org/#!/app/app_removeaccess_delete_12
2014-03-02 19:30:46 +01:00
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}, 'DELETE', params);
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}
});
// Remove access to a specific user
sam.get('#/apps/:app/access/remove/:user', function (c) {
if (confirm(y18n.t('confirm_access_remove_user', [c.params['app'], c.params['user']]))) {
2014-03-02 19:30:46 +01:00
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
2014-03-02 19:30:46 +01:00
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}, 'DELETE', params); // passing 'params' here is useless because jQuery doesn't handle ajax datas for DELETE requests. Passing parameters through uri.
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}
});
// Grant all access
sam.get('#/apps/:app/access/add', function (c) {
2014-05-13 22:59:33 +02:00
if (confirm(y18n.t('confirm_access_add', [c.params['app']]))) {
2014-03-02 19:30:46 +01:00
params = {'apps': c.params['app'], 'users': null}
c.api('/access', function() { // http://api.yunohost.org/#!/app/app_addaccess_put_13
2014-03-02 19:30:46 +01:00
store.clear('slide');
c.redirect('#/apps/'+ c.params['app'] +'/access');
}, 'PUT', params);
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}
});
// Grant access for a specific user
sam.post('#/apps/:app/access/add', function (c) {
params = {'users': c.params['user'], 'apps': c.params['app']}
c.api('/access', function() { // http://api.yunohost.org/#!/app/app_addaccess_put_13
2014-03-02 19:30:46 +01:00
store.clear('slide');
c.redirect('#/apps/'+ c.params['app'] +'/access');
}, 'PUT', params);
});
// Clear access (reset)
sam.get('#/apps/:app/access/clear', function (c) {
2014-05-13 22:59:33 +02:00
if (confirm(y18n.t('confirm_access_clear', [c.params['app']]))) {
2014-03-02 19:30:46 +01:00
params = {'apps': c.params['app']}
c.api('/access', function() { //
2014-03-02 19:30:46 +01:00
store.clear('slide');
c.redirect('#/apps/'+ c.params['app'] +'/access');
}, 'POST', params);
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']+ '/access');
}
});
// Make app default
sam.get('#/apps/:app/default', function (c) {
if (confirm(y18n.t('confirm_app_default'))) {
c.api('/apps/'+ c.params['app'] +'/default', function() { //
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']);
}, 'PUT');
} else {
store.clear('slide');
c.redirect('#/apps/'+ c.params['app']);
}
});
2014-03-02 19:30:46 +01:00
2014-01-29 18:32:22 +01:00
/**
* Services
*
*/
// All services status
sam.get('#/services', function (c) {
c.api('/services', function(data) { // ?
2014-01-29 18:32:22 +01:00
data2 = { 'services': [] }
$.each(data, function(k, v) {
v.name = k;
v.is_loaded = (v.loaded=='enabled') ? true : false;
v.is_running = (v.status=='running') ? true : false;
data2.services.push(v);
});
c.view('service/service_list', data2);
2014-01-29 18:32:22 +01:00
});
});
// Status & actions for a service
sam.get('#/services/:service', function (c) {
c.api('/services/'+ c.params['service'], function(data) { // ?
2014-01-29 18:32:22 +01:00
data2 = { 'service': data }
data2.service.name = c.params['service'];
data2.service.is_loaded = (data.loaded=='enabled') ? true : false;
data2.service.is_running = (data.status=='running') ? true : false;
store.clear('slide');
c.view('service/service_info', data2);
}, 'GET');
2014-01-29 18:32:22 +01:00
});
// Service log
sam.get('#/services/:service/log', function (c) {
params = { 'number': 50 }
c.api('/services/'+ c.params['service'] +'/log', function(data) { // ?
2014-01-29 18:32:22 +01:00
data2 = { 'logs': [], 'name': c.params['service'] }
$.each(data, function(k, v) {
data2.logs.push({filename: k, filecontent: v.join('\n')});
2014-01-29 18:32:22 +01:00
});
c.view('service/service_log', data2);
2014-01-29 18:32:22 +01:00
}, 'GET', params);
});
// Enable/Disable & Start/Stop service
sam.get('#/services/:service/:action', function (c) {
if (confirm(y18n.t('confirm_service_action', [y18n.t(c.params['action']), c.params['service']]))) {
var method = null, endurl = c.params['service'];
switch (c.params['action']) {
case 'start':
method = 'PUT';
break;
case 'stop':
method = 'DELETE';
break;
case 'enable':
method = 'PUT';
endurl += '/enable';
break;
case 'disable':
method = 'DELETE';
endurl += '/enable';
break;
default:
c.flash('fail', y18n.t('unknown_action', [c.params['action']]));
store.clear('slide');
c.redirect('#/services/'+ c.params['service']);
}
2014-05-17 00:38:47 +02:00
if (method && endurl) {
c.api('/services/'+ endurl, function(data) {
store.clear('slide');
c.redirect('#/services/'+ c.params['service']);
}, method);
}
2014-01-29 18:32:22 +01:00
} else {
store.clear('slide');
c.redirect('#/services/'+ c.params['service']);
}
});
/**
* Firewall
*
*/
// Firewall status
sam.get('#/firewall', function (c) {
c.api('/firewall?raw', function(data) {
var firewall = {
ports : {},
upnp : false
};
// Reorganize ports
$.each(['ipv4', 'ipv6', 'uPnP'], function(i, protocol) {
$.each(['TCP', 'UDP'], function(j, connection) {
firewall.ports[connection] = firewall.ports[connection] || {}; 
$.each(data[protocol][connection], function(k, port) {
firewall.ports[connection][port] = firewall.ports[connection][port] || {}; 
firewall.ports[connection][port][protocol] = true;
});
});
});
// Get UPnP status
firewall.upnp = data.uPnP.enabled;
c.view('firewall/firewall', firewall);
});
});
// Enable/Disable UPnP
sam.get('#/firewall/upnp/:action', function (c) {
if (confirm(y18n.t('confirm_upnp_action', [y18n.t(c.params['action'])] ))) {
params = {'action' : c.params['action']}
c.api('/firewall/upnp', function(data) {
store.clear('slide');
c.redirect('#/firewall');
}, 'GET', params);
}
else {
store.clear('slide');
c.redirect('#/firewall');
}
});
// Toggle port status
sam.helper('togglePort', function(port, protocol, connection, action) {
var method = null
, endurl = []
, c = this
;
if (port != parseInt(port) || port < 0 || port > 65535) {
c.flash('fail', y18n.t('unknown_argument', [port]));
store.clear('slide');
c.redirect('#/firewall');
}
switch (connection) {
case 'ipv4':
break;
case 'ipv6':
endurl = 'ipv6'
break;
}
switch (protocol) {
case 'udp':
protocol = 'UDP';
break;
case 'both':
protocol = 'Both';
break;
case 'tcp':
default:
protocol = [];
}
switch (action) {
case "open":
method = 'POST';
break;
case "close":
method = 'DELETE';
break;
default:
c.flash('fail', y18n.t('unknown_action', [action]));
store.clear('slide');
c.redirect('#/firewall');
}
if (method !== null && protocol !== null && port != null) {
// port:
// protocol:
// - UDP
// - TCP
// - Both
// --ipv6:
// --no-upnp:
var params = {
'port' : port,
'protocol' : protocol,
}
c.api('/firewall/port?'+endurl, function(data) {
store.clear('slide');
c.redirect('#/firewall');
}, method, params);
}
else {
store.clear('slide');
c.redirect('#/firewall');
}
return;
});
// #/firewall/port/{{@key}}/tcp/ipv4/close
sam.get('#/firewall/port/:port/:protocol/:connection/:action', function (c) {
if (confirm(y18n.t('confirm_firewall', [ y18n.t(c.params['action']), c.params['port'], y18n.t(c.params['protocol']), y18n.t(c.params['connection']) ]))) {
c.togglePort(
c.params['port'],
c.params['protocol'],
c.params['connection'],
c.params['action']
);
}
else {
store.clear('slide');
c.redirect('#/firewall');
}
});
sam.post('#/firewall/port', function (c) {
if (confirm(y18n.t('confirm_firewall', [ y18n.t(c.params['action']), c.params['port'], y18n.t(c.params['protocol']), y18n.t(c.params['connection']) ]))) {
c.togglePort(
c.params['port'],
c.params['protocol'],
c.params['connection'],
c.params['action']
);
}
else {
store.clear('slide');
c.redirect('#/firewall');
}
});
2014-01-29 18:32:22 +01:00
/**
* Monitor
*
*/
//
sam.get('#/monitor', function (c) {
monitorData = {}
// Why this method ?
c.api('/services/glances', function(data) { // ?
2014-02-14 20:36:01 +01:00
monitorData.status = true;
if (data.status == 'running') {
c.api('/monitor/system', function(data) {
monitorData.system = data;
2014-02-14 20:36:01 +01:00
c.api('/monitor/disk', function(data) {
monitorData.disk = data;
2014-02-14 20:36:01 +01:00
c.api('/monitor/network', function(data) {
monitorData.network = data;
2014-02-14 20:36:01 +01:00
// Remove useless interface
delete monitorData.network.usage.lo;
c.view('monitor/monitor', monitorData);
2014-02-14 20:36:01 +01:00
});
});
2014-02-14 20:36:01 +01:00
});
}
else {
monitorData.status = false;
c.view('monitor/monitor', monitorData);
2014-02-14 20:36:01 +01:00
}
}, 'GET');
});
2014-02-20 12:36:16 +01:00
/**
* Tools
*
*/
sam.get('#/tools', function (c) {
c.view('tools/tools_list');
2014-02-20 12:36:16 +01:00
});
// Update administration password
sam.get('#/tools/adminpw', function (c) {
c.view('tools/tools_adminpw');
2014-02-20 12:36:16 +01:00
});
sam.put('#/tools/adminpw', function (c) {
params = {}
$.each(c.params.toHash(), function(key, value) {
if (value !== '') { params[key] = value; }
});
if ($.isEmptyObject(params)) {
c.flash('fail', y18n.t('error_modify_something'));
2014-02-20 12:36:16 +01:00
store.clear('slide');
c.redirect('#/tools/adminpw');
} else if (params['new_password'] !== params['confirm_new_password']) {
c.flash('fail', y18n.t('passwords_dont_match'));
2014-02-20 12:36:16 +01:00
store.clear('slide');
c.redirect('#/tools/adminpw');
} else {
// Remove useless variable
delete params['confirm_new_password'];
// Update password and redirect to the home
c.api('/adminpw', function(data) { // http://api.yunohost.org/#!/tools/tools_adminpw_put_3
store.set('password', btoa(params['new_password']));
2014-05-17 00:38:47 +02:00
c.redirect('#/logout');
2014-02-20 12:36:16 +01:00
}, 'PUT', params);
}
});
// System update & upgrade
sam.get('#/tools/update', function (c) {
c.api('/update', function(data) {
2014-05-09 23:54:45 +02:00
packagesLength = data.packages.length;
for(var i = 0; i < packagesLength; i++) {
data.packages[i].changelog = data.packages[i].changelog.replace(/\n/g, '<br />');
}
c.view('tools/tools_update', data);
}, 'PUT');
});
sam.get('#/tools/upgrade/:type', function (c) {
if (c.params['type'] !== 'apps' && c.params['type'] !== 'packages') {
c.flash('fail', y18n.t('error_server'));
store.clear('slide');
c.redirect('#/tools/update');
}
if (confirm(y18n.t('confirm_update_type', [y18n.t('system_'+c.params['type']).toLowerCase()]))) {
params = []
if (c.params['type'] == 'packages') {params.push('ignore-apps');}
if (c.params['type'] == 'apps') {params.push('ignore-packages');}
c.api('/upgrade', function(data) {
// 'log' is a reserved name, maybe in handlebars
data.logs = data.log;
c.view('tools/tools_upgrade', data);
}, 'PUT', params);
} else {
store.clear('slide');
c.redirect('#/tools/update');
}
});
// Download SSL Certificate Authority
sam.get('#/tools/ca', function (c) {
c.view('tools/tools_ca');
});
2014-02-20 12:36:16 +01:00
/**
* Backup
*
*/
sam.get('#/backup', function (c) {
c.view('backup/backup');
});
2013-07-01 15:56:32 +02:00
});
2013-07-02 12:35:31 +02:00
/**
* Run the app
*
*/
2014-05-12 18:28:42 +02:00
2013-07-01 15:56:32 +02:00
$(document).ready(function () {
2014-05-12 18:28:42 +02:00
/**
* Translations
*/
// Default language
$.getJSON('locales/en.json', function(data){
y18n.translations['en'] = data;
});
// User language
if (window.navigator && window.navigator.language) {
y18n.locale = window.navigator.language.substr(0, 2);
if (y18n.locale !== 'en') {
$.getJSON('locales/'+ y18n.locale +'.json', function(data){
y18n.translations[y18n.locale] = data;
});
}
2014-05-12 18:28:42 +02:00
}
/**
* Application
*/
2013-07-01 15:56:32 +02:00
app.run('#/');
2013-09-25 21:49:12 +02:00
// Fixes for sliding effect
2013-09-25 11:34:40 +02:00
$('#slider-container').width(2*$('#slider').width() +'px');
2013-09-24 19:02:12 +02:00
$(window).resize(function() {
2013-09-25 12:01:01 +02:00
$('#slideBack').css('display', 'none');
$('#slideTo').css('display', 'none');
$('#slider-container').width(2*$('#slider').width() +'px').removeClass('move').css('margin-left', '0px');
2013-09-24 19:02:12 +02:00
});
2013-07-01 15:56:32 +02:00
});