2015-07-20 00:09:47 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
/* global angular */
|
|
|
|
|
|
|
|
|
|
angular.module('Application').service('Client', ['$http', 'md5', 'Notification', function ($http, md5, Notification) {
|
|
|
|
|
var client = null;
|
|
|
|
|
|
2016-07-26 16:56:53 +02:00
|
|
|
// variable available only here to avoid this._property pattern
|
|
|
|
|
var token = null;
|
|
|
|
|
|
2016-02-25 18:19:59 -08:00
|
|
|
// Keep this in sync with docs and constants.js, docker.js
|
|
|
|
|
var DEFAULT_MEMORY_LIMIT = 1024 * 1024 * 256;
|
2015-10-22 11:13:49 +02:00
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
function ClientError(statusCode, messageOrObject) {
|
|
|
|
|
Error.call(this);
|
|
|
|
|
this.name = this.constructor.name;
|
|
|
|
|
this.statusCode = statusCode;
|
|
|
|
|
if (messageOrObject === null || typeof messageOrObject === 'undefined') {
|
|
|
|
|
this.message = 'Empty message or object';
|
|
|
|
|
} else if (typeof messageOrObject === 'string') {
|
|
|
|
|
this.message = messageOrObject;
|
|
|
|
|
} else if (messageOrObject.message) {
|
|
|
|
|
this.message = messageOrObject.message;
|
|
|
|
|
} else {
|
|
|
|
|
this.message = JSON.stringify(messageOrObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function defaultErrorHandler(callback) {
|
|
|
|
|
return function (data, status) {
|
2015-09-10 14:16:59 +02:00
|
|
|
if (status === 401) return client.login();
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status === 503) {
|
|
|
|
|
// this could indicate a update/upgrade/restore/migration
|
|
|
|
|
client.progress(function (error, result) {
|
|
|
|
|
if (error) {
|
|
|
|
|
client.error(error);
|
|
|
|
|
return callback(new ClientError(status, data));
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-29 14:15:44 +02:00
|
|
|
if (result.update && result.update.percent !== -1) window.location.href = '/update.html';
|
2015-07-20 00:09:47 -07:00
|
|
|
else callback(new ClientError(status, data));
|
|
|
|
|
}, function (data, status) {
|
|
|
|
|
client.error(data);
|
|
|
|
|
return callback(new ClientError(status, data));
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (status >= 500) {
|
|
|
|
|
client.error(data);
|
|
|
|
|
return callback(new ClientError(status, data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var obj = data;
|
|
|
|
|
try {
|
|
|
|
|
obj = JSON.parse(data);
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
callback(new ClientError(status, obj));
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-26 16:56:53 +02:00
|
|
|
// XHR wrapper to set the auth header
|
|
|
|
|
function get(url, config) {
|
|
|
|
|
config = config || {};
|
|
|
|
|
config.headers = config.headers || {};
|
|
|
|
|
config.headers.Authorization = 'Bearer ' + token;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
return $http.get(client.apiOrigin + url, config);
|
2016-07-26 16:56:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function post(url, data, config) {
|
|
|
|
|
data = data || {};
|
|
|
|
|
config = config || {};
|
|
|
|
|
config.headers = config.headers || {};
|
|
|
|
|
config.headers.Authorization = 'Bearer ' + token;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
return $http.post(client.apiOrigin + url, data, config);
|
2016-07-26 16:56:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function put(url, data, config) {
|
|
|
|
|
data = data || {};
|
|
|
|
|
config = config || {};
|
|
|
|
|
config.headers = config.headers || {};
|
|
|
|
|
config.headers.Authorization = 'Bearer ' + token;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
return $http.put(client.apiOrigin + url, data, config);
|
2016-07-26 16:56:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function del(url, config) {
|
|
|
|
|
config = config || {};
|
|
|
|
|
config.headers = config.headers || {};
|
|
|
|
|
config.headers.Authorization = 'Bearer ' + token;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
return $http.delete(client.apiOrigin + url, config);
|
2016-07-26 16:56:53 +02:00
|
|
|
}
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
function Client() {
|
|
|
|
|
this._ready = false;
|
|
|
|
|
this._configListener = [];
|
|
|
|
|
this._readyListener = [];
|
|
|
|
|
this._userInfo = {
|
2015-10-28 22:07:30 +01:00
|
|
|
id: null,
|
2015-07-20 00:09:47 -07:00
|
|
|
username: null,
|
|
|
|
|
email: null,
|
|
|
|
|
admin: false
|
|
|
|
|
};
|
|
|
|
|
this._config = {
|
|
|
|
|
apiServerOrigin: null,
|
|
|
|
|
webServerOrigin: null,
|
|
|
|
|
fqdn: null,
|
|
|
|
|
ip: null,
|
|
|
|
|
revision: null,
|
|
|
|
|
update: { box: null, apps: null },
|
|
|
|
|
progress: {},
|
|
|
|
|
isCustomDomain: false,
|
|
|
|
|
region: null,
|
2015-10-22 11:13:49 +02:00
|
|
|
size: null,
|
2017-06-20 12:58:14 +02:00
|
|
|
memory: 0,
|
|
|
|
|
isPaying: false
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
this._installedApps = [];
|
|
|
|
|
this._clientId = '<%= oauth.clientId %>';
|
|
|
|
|
this._clientSecret = '<%= oauth.clientSecret %>';
|
|
|
|
|
this.apiOrigin = '<%= oauth.apiOrigin %>';
|
2016-01-20 17:14:50 +01:00
|
|
|
this.avatar = '';
|
|
|
|
|
|
|
|
|
|
this.resetAvatar();
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
this.setToken(localStorage.token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Client.prototype.error = function (error) {
|
|
|
|
|
var message = '';
|
|
|
|
|
|
|
|
|
|
if (typeof error === 'object') {
|
|
|
|
|
message = error.message || error;
|
|
|
|
|
} else {
|
|
|
|
|
message = error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-14 15:08:27 +01:00
|
|
|
Notification.error({ title: 'Cloudron Error', message: message });
|
|
|
|
|
};
|
|
|
|
|
|
2016-01-14 15:56:23 +01:00
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
Example usage with an action:
|
|
|
|
|
|
|
|
|
|
var actionScope = $scope.$new(true);
|
|
|
|
|
actionScope.action = '/#/certs';
|
|
|
|
|
|
|
|
|
|
Client.notify('title', 'message', true, actionScope);
|
|
|
|
|
|
|
|
|
|
*/
|
2016-01-18 13:39:27 +01:00
|
|
|
Client.prototype.notify = function (title, message, persitent, type, actionScope) {
|
|
|
|
|
var options = { title: title, message: message};
|
|
|
|
|
|
|
|
|
|
if (persitent) options.delay = 'never'; // any non Number means never timeout
|
2016-01-14 15:54:14 +01:00
|
|
|
|
|
|
|
|
if (actionScope) {
|
|
|
|
|
if (typeof actionScope.action !== 'string') throw('an actionScope has to have an action url');
|
|
|
|
|
options.scope = actionScope;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-18 13:39:27 +01:00
|
|
|
if (type === 'error') Notification.error(options);
|
|
|
|
|
else if (type === 'success') Notification.success(options);
|
|
|
|
|
else if (type === 'info') Notification.info(options);
|
2016-10-11 10:32:05 +02:00
|
|
|
else if (type === 'warning') Notification.warning(options);
|
2016-01-18 13:39:27 +01:00
|
|
|
else throw('Invalid notification type "' + type + '"');
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.setReady = function () {
|
|
|
|
|
if (this._ready) return;
|
|
|
|
|
|
|
|
|
|
this._ready = true;
|
|
|
|
|
this._readyListener.forEach(function (callback) {
|
|
|
|
|
callback();
|
|
|
|
|
});
|
2016-07-27 16:34:15 +02:00
|
|
|
|
|
|
|
|
// clear the listeners, we only callback once!
|
|
|
|
|
this._readyListener = [];
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.onReady = function (callback) {
|
|
|
|
|
if (this._ready) callback();
|
2016-07-27 16:34:15 +02:00
|
|
|
else this._readyListener.push(callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.onConfig = function (callback) {
|
|
|
|
|
this._configListener.push(callback);
|
2016-04-08 17:29:07 +02:00
|
|
|
if (this._config && this._config.apiServerOrigin) callback(this._config);
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2016-01-20 17:14:50 +01:00
|
|
|
Client.prototype.resetAvatar = function () {
|
|
|
|
|
this.avatar = this.apiOrigin + '/api/v1/cloudron/avatar?' + String(Math.random()).slice(2);
|
|
|
|
|
|
|
|
|
|
var favicon = $('#favicon');
|
|
|
|
|
if (favicon) favicon.attr('href', this.avatar);
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.setUserInfo = function (userInfo) {
|
|
|
|
|
// In order to keep the angular bindings alive, set each property individually
|
2015-10-28 22:07:30 +01:00
|
|
|
this._userInfo.id = userInfo.id;
|
2015-07-20 00:09:47 -07:00
|
|
|
this._userInfo.username = userInfo.username;
|
|
|
|
|
this._userInfo.email = userInfo.email;
|
2016-09-28 11:47:26 +02:00
|
|
|
this._userInfo.alternateEmail = userInfo.alternateEmail;
|
2016-02-25 15:09:52 +01:00
|
|
|
this._userInfo.displayName = userInfo.displayName;
|
2015-07-20 00:09:47 -07:00
|
|
|
this._userInfo.admin = !!userInfo.admin;
|
2016-09-28 12:05:48 +02:00
|
|
|
this._userInfo.gravatar = 'https://www.gravatar.com/avatar/' + md5.createHash(userInfo.alternateEmail || userInfo.email) + '.jpg?s=24&d=mm';
|
|
|
|
|
this._userInfo.gravatarHuge = 'https://www.gravatar.com/avatar/' + md5.createHash(userInfo.alternateEmail || userInfo.email) + '.jpg?s=128&d=mm';
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.setConfig = function (config) {
|
|
|
|
|
var that = this;
|
|
|
|
|
|
2016-07-28 12:10:11 +02:00
|
|
|
// provide fallback to caas
|
|
|
|
|
if (!config.provider) config.provider = 'caas';
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
angular.copy(config, this._config);
|
|
|
|
|
|
|
|
|
|
this._configListener.forEach(function (callback) {
|
|
|
|
|
callback(that._config);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getInstalledApps = function () {
|
|
|
|
|
return this._installedApps;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getUserInfo = function () {
|
|
|
|
|
return this._userInfo;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getConfig = function () {
|
|
|
|
|
return this._config;
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 16:56:53 +02:00
|
|
|
Client.prototype.setToken = function (accessToken) {
|
|
|
|
|
if (!accessToken) localStorage.removeItem('token');
|
|
|
|
|
else localStorage.token = accessToken;
|
|
|
|
|
|
|
|
|
|
// set the token closure
|
|
|
|
|
token = accessToken;
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rest API wrappers
|
|
|
|
|
*/
|
|
|
|
|
Client.prototype.config = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/cloudron/config').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.userInfo = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/profile').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.changeCloudronAvatar = function (avatarFile, callback) {
|
|
|
|
|
var fd = new FormData();
|
|
|
|
|
fd.append('avatar', avatarFile);
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/settings/cloudron_avatar', fd, {
|
2015-07-20 00:09:47 -07:00
|
|
|
headers: { 'Content-Type': undefined },
|
|
|
|
|
transformRequest: angular.identity
|
|
|
|
|
}).success(function(data, status) {
|
|
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-28 12:41:15 +02:00
|
|
|
Client.prototype.changeCloudronName = function (name, callback) {
|
|
|
|
|
var data = {
|
|
|
|
|
name: name
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
post('/api/v1/settings/cloudron_name', data).success(function(data, status) {
|
|
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.installApp = function (id, manifest, title, config, callback) {
|
|
|
|
|
var that = this;
|
2015-10-28 20:50:55 +01:00
|
|
|
var data = {
|
2016-06-04 13:23:13 -07:00
|
|
|
appStoreId: id + '@' + manifest.version,
|
2015-10-28 20:50:55 +01:00
|
|
|
location: config.location,
|
|
|
|
|
portBindings: config.portBindings,
|
|
|
|
|
accessRestriction: config.accessRestriction,
|
|
|
|
|
cert: config.cert,
|
2016-11-22 11:51:53 +01:00
|
|
|
key: config.key,
|
|
|
|
|
sso: config.sso
|
2015-10-28 20:50:55 +01:00
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/install', data).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202 || typeof data !== 'object') return defaultErrorHandler(callback);
|
|
|
|
|
|
|
|
|
|
// put new app with amended title in cache
|
|
|
|
|
data.manifest = { title: title };
|
|
|
|
|
var icons = that.getAppIconUrls(data);
|
|
|
|
|
data.iconUrl = icons.cloudron;
|
|
|
|
|
data.iconUrlStore = icons.store;
|
|
|
|
|
data.progress = 0;
|
|
|
|
|
|
|
|
|
|
that._installedApps.push(data);
|
|
|
|
|
|
|
|
|
|
callback(null, data.id);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-13 10:13:54 -07:00
|
|
|
Client.prototype.restoreApp = function (appId, backupId, password, callback) {
|
|
|
|
|
var data = { password: password, backupId: backupId };
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + appId + '/restore', data).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.uninstallApp = function (appId, password, callback) {
|
|
|
|
|
var data = { password: password };
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + appId + '/uninstall', data).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.configureApp = function (id, password, config, callback) {
|
2015-10-27 18:02:41 +01:00
|
|
|
var data = {
|
|
|
|
|
appId: id,
|
|
|
|
|
password: password,
|
|
|
|
|
location: config.location,
|
|
|
|
|
portBindings: config.portBindings,
|
|
|
|
|
accessRestriction: config.accessRestriction,
|
|
|
|
|
cert: config.cert,
|
2016-02-11 17:29:00 +01:00
|
|
|
key: config.key,
|
2016-04-19 00:36:09 -07:00
|
|
|
memoryLimit: config.memoryLimit,
|
2016-07-15 11:18:04 +02:00
|
|
|
altDomain: config.altDomain || null,
|
2016-11-11 22:30:18 +05:30
|
|
|
xFrameOptions: config.xFrameOptions
|
2015-10-27 18:02:41 +01:00
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + id + '/configure', data).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.updateApp = function (id, manifest, portBindings, password, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = {
|
|
|
|
|
appStoreId: manifest.id + '@' + manifest.version,
|
|
|
|
|
password: password,
|
|
|
|
|
portBindings: portBindings
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + id + '/update', data).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.startApp = function (id, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + id + '/start').success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.stopApp = function (id, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/apps/' + id + '/stop').success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.progress = function (callback, errorCallback) {
|
|
|
|
|
// this is used in the defaultErrorHandler itself, and avoids a loop
|
|
|
|
|
if (typeof errorCallback !== 'function') errorCallback = defaultErrorHandler(callback);
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/cloudron/progress').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(errorCallback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.version = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/cloudron/status').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-29 10:58:26 +01:00
|
|
|
Client.prototype.getStatus = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/cloudron/status').success(function(data, status) {
|
2015-12-29 10:58:26 +01:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2017-04-18 15:34:32 -07:00
|
|
|
Client.prototype.makeURL = function (url) {
|
|
|
|
|
if (url.indexOf('?') === -1) {
|
|
|
|
|
return this.apiOrigin + url + '?access_token=' + token;
|
|
|
|
|
} else {
|
|
|
|
|
return this.apiOrigin + url + '&access_token=' + token;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-06-12 13:18:08 +02:00
|
|
|
Client.prototype.setCatchallAddresses = function (addresses, callback) {
|
|
|
|
|
put('/api/v1/settings/catch_all_address', { address: addresses }).success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getCatchallAddresses = function (callback) {
|
|
|
|
|
get('/api/v1/settings/catch_all_address').success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.address);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-22 16:09:34 +02:00
|
|
|
Client.prototype.setBackupConfig = function (backupConfig, callback) {
|
|
|
|
|
post('/api/v1/settings/backup_config', backupConfig).success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getBackupConfig = function (callback) {
|
|
|
|
|
get('/api/v1/settings/backup_config').success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-27 12:02:47 -07:00
|
|
|
Client.prototype.setDnsConfig = function (dnsConfig, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/settings/dns_config', dnsConfig).success(function(data, status) {
|
2015-10-27 12:02:47 -07:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-29 14:34:25 +01:00
|
|
|
Client.prototype.getDnsConfig = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/settings/dns_config').success(function(data, status) {
|
2016-07-26 15:19:14 +02:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-26 21:30:29 -08:00
|
|
|
Client.prototype.setAutoupdatePattern = function (pattern, callback) {
|
|
|
|
|
post('/api/v1/settings/autoupdate_pattern', { pattern: pattern }).success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-12 18:06:18 -07:00
|
|
|
Client.prototype.checkForUpdates = function (callback) {
|
|
|
|
|
post('/api/v1/cloudron/check_for_updates', { }).success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-26 21:30:29 -08:00
|
|
|
Client.prototype.getAutoupdatePattern = function (callback) {
|
|
|
|
|
get('/api/v1/settings/autoupdate_pattern').success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-03-09 15:43:13 -08:00
|
|
|
Client.prototype.getEmailStatus = function (callback) {
|
|
|
|
|
get('/api/v1/settings/email_status').success(function(data, status) {
|
2016-12-09 09:19:23 +01:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 15:19:14 +02:00
|
|
|
Client.prototype.setAppstoreConfig = function (config, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = config;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/settings/appstore_config', data).success(function(data, status) {
|
2016-08-01 16:09:30 +02:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
2016-07-26 15:19:14 +02:00
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getAppstoreConfig = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/settings/appstore_config').success(function(data, status) {
|
2015-10-29 14:34:25 +01:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-08-30 22:07:38 -07:00
|
|
|
Client.prototype.getMailConfig = function (callback) {
|
|
|
|
|
get('/api/v1/settings/mail_config').success(function (data, status) {
|
|
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.setMailConfig = function (config, callback) {
|
|
|
|
|
post('/api/v1/settings/mail_config', config).success(function (data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-03-07 16:07:25 +01:00
|
|
|
Client.prototype.addAuthorizedKey = function (key, callback) {
|
|
|
|
|
put('/api/v1/cloudron/ssh/authorized_keys', { key: key }).success(function (data, status) {
|
|
|
|
|
if (status !== 201) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.delAuthorizedKey = function (identifier, callback) {
|
|
|
|
|
del('/api/v1/cloudron/ssh/authorized_keys/' + identifier).success(function (data, status) {
|
|
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getAuthorizedKeys = function (callback) {
|
|
|
|
|
get('/api/v1/cloudron/ssh/authorized_keys').success(function (data, status) {
|
|
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.keys);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.getBackups = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/backups').success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.backups);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.backup = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/backups').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-05-06 17:18:47 +02:00
|
|
|
Client.prototype.getEventLogs = function (action, search, page, perPage, callback) {
|
2016-04-30 18:57:55 -07:00
|
|
|
var config = {
|
|
|
|
|
params: {
|
2016-05-06 17:18:47 +02:00
|
|
|
action: action,
|
|
|
|
|
search: search,
|
2016-04-30 18:57:55 -07:00
|
|
|
page: page,
|
|
|
|
|
per_page: perPage
|
|
|
|
|
}
|
|
|
|
|
};
|
2016-07-26 16:56:53 +02:00
|
|
|
|
2017-04-18 14:53:08 -07:00
|
|
|
get('/api/v1/cloudron/eventlog', config).success(function (data, status) {
|
2016-04-30 18:57:55 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
|
|
|
|
|
callback(null, data.eventlogs);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.getApps = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/apps').success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.apps);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 15:34:32 -07:00
|
|
|
Client.prototype.getAppLogs = function (appId, callback) {
|
|
|
|
|
get('/api/v1/apps/' + appId + '/logs').success(function (data, status) {
|
2017-04-12 13:03:34 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
2017-04-18 15:34:32 -07:00
|
|
|
callback(null);
|
2017-04-12 13:03:34 -07:00
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getAppBackups = function (appId, callback) {
|
|
|
|
|
get('/api/v1/apps/' + appId + '/backups').success(function (data, status) {
|
|
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.backups);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-16 18:06:49 +02:00
|
|
|
Client.prototype.getUsers = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/users').success(function (data, status) {
|
2015-10-16 18:06:49 +02:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.users);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-10 14:25:08 +01:00
|
|
|
Client.prototype.getGroups = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/groups').success(function (data, status) {
|
2016-02-10 14:25:08 +01:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.groups);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-10 14:47:35 +01:00
|
|
|
Client.prototype.setGroups = function (userId, groupIds, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
put('/api/v1/users/' + userId + '/groups', { groupIds: groupIds }).success(function (data, status) {
|
2016-02-10 15:01:51 +01:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
2016-02-10 14:47:35 +01:00
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-13 12:42:38 +01:00
|
|
|
Client.prototype.getGroup = function (groupId, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/groups/' + groupId).success(function (data, status) {
|
2016-02-13 12:42:38 +01:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-10 16:37:46 +01:00
|
|
|
Client.prototype.createGroup = function (name, callback) {
|
|
|
|
|
var data = {
|
|
|
|
|
name: name
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/groups', data).success(function(data, status) {
|
2016-02-10 16:37:46 +01:00
|
|
|
if (status !== 201 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-02-10 17:12:58 +01:00
|
|
|
Client.prototype.removeGroup = function (groupId, password, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var config = {
|
|
|
|
|
data: {
|
|
|
|
|
password: password
|
|
|
|
|
},
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
2016-02-10 17:12:58 +01:00
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
del('/api/v1/groups/' + groupId, config).success(function(data, status) {
|
2016-02-10 17:12:58 +01:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-27 16:28:07 +02:00
|
|
|
Client.prototype.getNonApprovedApps = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/developer/apps').success(function (data, status) {
|
2015-07-27 16:28:07 +02:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.apps || []);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.getApp = function (appId, callback) {
|
|
|
|
|
var appFound = null;
|
|
|
|
|
this._installedApps.some(function (app) {
|
|
|
|
|
if (app.id === appId) {
|
|
|
|
|
appFound = app;
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (appFound) return callback(null, appFound);
|
|
|
|
|
else return callback(new Error('App not found'));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.getAppIconUrls = function (app) {
|
|
|
|
|
return {
|
2016-07-26 16:56:53 +02:00
|
|
|
cloudron: app.iconUrl ? (this.apiOrigin + app.iconUrl + '?access_token=' + token) : null,
|
2016-01-20 16:01:21 +01:00
|
|
|
store: app.appStoreId ? (this._config.apiServerOrigin + '/api/v1/apps/' + app.appStoreId + '/versions/' + app.manifest.version + '/icon') : null
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-03 01:05:36 +02:00
|
|
|
Client.prototype.sendInvite = function (user, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/users/' + user.id + '/invite').success(function (data, status) {
|
2016-01-18 15:45:44 +01:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
2016-04-04 18:15:24 +02:00
|
|
|
callback(null, data.resetToken);
|
2016-01-18 15:45:44 +01:00
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-05 11:53:05 +01:00
|
|
|
Client.prototype.setupDnsConfig = function (dnsConfig, callback) {
|
2017-01-05 20:37:26 +01:00
|
|
|
post('/api/v1/cloudron/dns_setup', dnsConfig).success(function(data, status) {
|
2017-01-05 11:53:05 +01:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-01-19 23:58:08 -08:00
|
|
|
Client.prototype.createAdmin = function (username, password, email, displayName, setupToken, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var that = this;
|
|
|
|
|
|
|
|
|
|
var data = {
|
2015-07-20 00:09:47 -07:00
|
|
|
username: username,
|
|
|
|
|
password: password,
|
2016-01-19 23:58:08 -08:00
|
|
|
email: email,
|
|
|
|
|
displayName: displayName
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2017-03-16 09:37:28 +01:00
|
|
|
var query = '';
|
|
|
|
|
if (setupToken) query = '?setupToken=' + setupToken;
|
|
|
|
|
|
|
|
|
|
post('/api/v1/cloudron/activate' + query, data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 201 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
|
|
|
|
|
that.setToken(data.token);
|
|
|
|
|
that.setUserInfo({ username: username, email: email, admin: true });
|
|
|
|
|
|
|
|
|
|
callback(null, data.activated);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 13:17:02 +02:00
|
|
|
Client.prototype.getOAuthClients = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/oauth/clients').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.clients);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 10:49:11 +02:00
|
|
|
Client.prototype.createOAuthClient = function (appId, scope, redirectURI, callback) {
|
2016-06-07 10:45:35 +02:00
|
|
|
var data = {
|
|
|
|
|
appId: appId,
|
|
|
|
|
scope: scope,
|
|
|
|
|
redirectURI: redirectURI
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/oauth/clients', data).success(function(data, status) {
|
2016-06-07 10:45:35 +02:00
|
|
|
if (status !== 201 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.clients);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 13:12:53 +02:00
|
|
|
Client.prototype.delOAuthClient = function (id, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
del('/api/v1/oauth/clients/' + id).success(function(data, status) {
|
2016-06-07 13:12:53 +02:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 15:54:30 +02:00
|
|
|
Client.prototype.createTokenByClientId = function (id, expiresAt, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/oauth/clients/' + id + '/tokens?expiresAt=' + expiresAt).success(function(data, status) {
|
2016-06-07 14:19:20 +02:00
|
|
|
if (status !== 201) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.token);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 12:37:04 +02:00
|
|
|
Client.prototype.getTokensByClientId = function (id, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/oauth/clients/' + id + '/tokens').success(function(data, status) {
|
2016-06-07 12:37:04 +02:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.tokens);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.delTokensByClientId = function (id, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
del('/api/v1/oauth/clients/' + id + '/tokens').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-07 15:38:42 +02:00
|
|
|
Client.prototype.delToken = function (clientId, tokenId, callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
del('/api/v1/oauth/clients/' + clientId + '/tokens/' + tokenId).success(function(data, status) {
|
2016-06-07 15:38:42 +02:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.update = function (password, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = { password: password };
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/cloudron/update', data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.reboot = function (callback) {
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/cloudron/reboot').success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-02 17:33:30 -05:00
|
|
|
Client.prototype.migrate = function (options, password, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = options;
|
|
|
|
|
data.password = password;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/cloudron/migrate', data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.setCertificate = function (certificateFile, keyFile, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = {
|
|
|
|
|
cert: certificateFile,
|
|
|
|
|
key: keyFile
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/settings/certificate', data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-29 12:29:25 +01:00
|
|
|
Client.prototype.setAdminCertificate = function (certificateFile, keyFile, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var data = {
|
|
|
|
|
cert: certificateFile,
|
|
|
|
|
key: keyFile
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/settings/admin_certificate', data).success(function(data, status) {
|
2015-10-29 12:29:25 +01:00
|
|
|
if (status !== 202) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-07 18:46:09 +02:00
|
|
|
Client.prototype.disks = function (callback) {
|
|
|
|
|
get('/api/v1/cloudron/disks').success(function (data, status) {
|
|
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.graphs = function (targets, from, callback) {
|
|
|
|
|
var config = {
|
|
|
|
|
params: {
|
|
|
|
|
target: targets,
|
|
|
|
|
format: 'json',
|
|
|
|
|
from: from
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
get('/api/v1/cloudron/graphs', config).success(function (data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-08-04 23:30:53 +02:00
|
|
|
Client.prototype.feedback = function (type, subject, description, callback) {
|
2015-08-04 14:44:39 +02:00
|
|
|
var data = {
|
2015-08-04 23:30:53 +02:00
|
|
|
type: type,
|
2015-08-04 14:44:39 +02:00
|
|
|
subject: subject,
|
|
|
|
|
description: description
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 14:49:28 -07:00
|
|
|
post('/api/v1/feedback', data).success(function (data, status) {
|
2015-08-04 14:44:39 +02:00
|
|
|
if (status !== 201) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-23 17:55:21 -07:00
|
|
|
Client.prototype.getAliases = function (userId, callback) {
|
|
|
|
|
get('/api/v1/users/' + userId + '/aliases').success(function(data, status) {
|
|
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data.aliases);
|
2016-05-29 18:56:40 -07:00
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-23 17:55:21 -07:00
|
|
|
Client.prototype.setAliases = function (userId, aliases, callback) {
|
2016-05-29 22:45:48 -07:00
|
|
|
var data = {
|
|
|
|
|
aliases: aliases
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-23 17:55:21 -07:00
|
|
|
put('/api/v1/users/' + userId + '/aliases', data).success(function(data, status) {
|
2016-05-29 23:26:49 -07:00
|
|
|
if (status !== 200) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
2016-05-29 22:45:48 -07:00
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-01-19 23:58:52 -08:00
|
|
|
Client.prototype.createUser = function (username, email, displayName, sendInvite, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
var data = {
|
2016-01-18 16:44:11 +01:00
|
|
|
email: email,
|
2016-01-19 23:58:52 -08:00
|
|
|
displayName: displayName,
|
2016-01-18 16:53:51 +01:00
|
|
|
invite: !!sendInvite
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2017-02-02 01:10:01 -08:00
|
|
|
if (username !== null) data.username = username;
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/users', data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 201 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
2016-01-25 15:14:42 +01:00
|
|
|
};
|
|
|
|
|
|
2016-02-25 14:15:48 +01:00
|
|
|
Client.prototype.updateUser = function (user, callback) {
|
2016-01-25 15:14:42 +01:00
|
|
|
var data = {
|
|
|
|
|
email: user.email,
|
|
|
|
|
displayName: user.displayName
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/users/' + user.id, data).success(function(data, status) {
|
2016-01-25 15:29:36 +01:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
2016-01-25 15:14:42 +01:00
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.removeUser = function (userId, password, callback) {
|
2016-07-26 16:56:53 +02:00
|
|
|
var config = {
|
|
|
|
|
data: {
|
|
|
|
|
password: password
|
|
|
|
|
},
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
del('/api/v1/users/' + userId, config).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-28 15:49:33 -07:00
|
|
|
Client.prototype.updateProfile = function (data, callback) {
|
|
|
|
|
post('/api/v1/profile', data).success(function(data, status) {
|
|
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.changePassword = function (currentPassword, newPassword, callback) {
|
|
|
|
|
var data = {
|
|
|
|
|
password: currentPassword,
|
|
|
|
|
newPassword: newPassword
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/profile/password', data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 204) return callback(new ClientError(status, data));
|
|
|
|
|
callback(null, data);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.refreshUserInfo = function (callback) {
|
|
|
|
|
var that = this;
|
|
|
|
|
|
|
|
|
|
callback = typeof callback === 'function' ? callback : function () {};
|
|
|
|
|
|
|
|
|
|
this.userInfo(function (error, result) {
|
|
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
that.setUserInfo(result);
|
|
|
|
|
callback(null);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.refreshConfig = function (callback) {
|
|
|
|
|
var that = this;
|
|
|
|
|
|
|
|
|
|
callback = typeof callback === 'function' ? callback : function () {};
|
|
|
|
|
|
|
|
|
|
this.config(function (error, result) {
|
|
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
that.setConfig(result);
|
2016-04-08 17:29:07 +02:00
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
callback(null);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-02 12:31:02 +02:00
|
|
|
Client.prototype.appPostProcess = function (app) {
|
|
|
|
|
// calculate the icon paths
|
|
|
|
|
var icons = this.getAppIconUrls(app);
|
|
|
|
|
app.iconUrl = icons.cloudron;
|
|
|
|
|
app.iconUrlStore = icons.store;
|
|
|
|
|
|
2017-04-05 16:42:11 +02:00
|
|
|
// FIXME have a real message structure, not some string to randomly parse
|
2016-04-02 12:31:02 +02:00
|
|
|
// extract progress percentage
|
|
|
|
|
var installationProgress = app.installationProgress || '';
|
2016-06-14 14:21:24 -07:00
|
|
|
var progress = parseInt(installationProgress.split(',')[0], 10);
|
2017-04-05 16:42:11 +02:00
|
|
|
// Unfortunatelly some errors are not actual progress messages, but still have a number in fron like a http status code
|
|
|
|
|
if (isNaN(progress) || progress > 100) {
|
|
|
|
|
app.progress = 0;
|
|
|
|
|
app.message = installationProgress;
|
|
|
|
|
} else {
|
|
|
|
|
app.progress = progress;
|
|
|
|
|
app.message = installationProgress.replace(/.*, /,'');
|
|
|
|
|
}
|
2016-04-02 12:31:02 +02:00
|
|
|
|
|
|
|
|
return app;
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.refreshInstalledApps = function (callback) {
|
|
|
|
|
var that = this;
|
|
|
|
|
|
|
|
|
|
callback = typeof callback === 'function' ? callback : function () {};
|
|
|
|
|
|
|
|
|
|
this.getApps(function (error, apps) {
|
|
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
// insert or update new apps
|
|
|
|
|
apps.forEach(function (app) {
|
|
|
|
|
var found = false;
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < that._installedApps.length; ++i) {
|
|
|
|
|
if (that._installedApps[i].id === app.id) {
|
|
|
|
|
found = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tmp = {};
|
|
|
|
|
angular.copy(app, tmp);
|
|
|
|
|
|
2016-04-02 12:31:02 +02:00
|
|
|
that.appPostProcess(tmp);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-02 12:31:02 +02:00
|
|
|
// only replace if the app is already known
|
2015-07-20 00:09:47 -07:00
|
|
|
if (found !== false) {
|
|
|
|
|
angular.copy(tmp, that._installedApps[found]);
|
|
|
|
|
} else {
|
|
|
|
|
that._installedApps.push(tmp);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// filter out old entries, going backwards to allow splicing
|
|
|
|
|
for(var i = that._installedApps.length - 1; i >= 0; --i) {
|
|
|
|
|
if (!apps.some(function (elem) { return (elem.id === that._installedApps[i].id); })) {
|
|
|
|
|
that._installedApps.splice(i, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
callback(null);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2015-09-10 14:16:59 +02:00
|
|
|
Client.prototype.login = function () {
|
|
|
|
|
this.setToken(null);
|
|
|
|
|
this._userInfo = {};
|
|
|
|
|
|
|
|
|
|
var callbackURL = window.location.protocol + '//' + window.location.host + '/login_callback.html';
|
2015-10-15 12:50:48 +02:00
|
|
|
var scope = 'root,profile,apps';
|
2015-09-10 14:16:59 +02:00
|
|
|
|
|
|
|
|
// generate a state id to protect agains csrf
|
|
|
|
|
var state = Math.floor((1 + Math.random()) * 0x1000000000000).toString(16).substring(1);
|
|
|
|
|
window.localStorage.oauth2State = state;
|
|
|
|
|
|
2015-10-01 16:11:39 +02:00
|
|
|
// stash for further use in login_callback
|
|
|
|
|
window.localStorage.returnTo = '/' + window.location.hash;
|
|
|
|
|
|
2015-09-10 14:16:59 +02:00
|
|
|
window.location.href = this.apiOrigin + '/api/v1/oauth/dialog/authorize?response_type=token&client_id=' + this._clientId + '&redirect_uri=' + callbackURL + '&scope=' + scope + '&state=' + state;
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
Client.prototype.logout = function () {
|
|
|
|
|
this.setToken(null);
|
|
|
|
|
this._userInfo = {};
|
|
|
|
|
|
|
|
|
|
// logout from OAuth session
|
2015-09-10 14:16:59 +02:00
|
|
|
var origin = window.location.protocol + "//" + window.location.host;
|
|
|
|
|
window.location.href = this.apiOrigin + '/api/v1/session/logout?redirect=' + origin;
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Client.prototype.exchangeCodeForToken = function (code, callback) {
|
|
|
|
|
var data = {
|
|
|
|
|
grant_type: 'authorization_code',
|
|
|
|
|
code: code,
|
|
|
|
|
redirect_uri: window.location.protocol + '//' + window.location.host,
|
|
|
|
|
client_id: this._clientId,
|
|
|
|
|
client_secret: this._clientSecret
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-26 17:02:55 +02:00
|
|
|
post('/api/v1/oauth/token?response_type=token&client_id=' + this._clientId, data).success(function(data, status) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (status !== 200 || typeof data !== 'object') return callback(new ClientError(status, data));
|
|
|
|
|
|
|
|
|
|
callback(null, data.access_token);
|
|
|
|
|
}).error(defaultErrorHandler(callback));
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-22 10:40:33 +02:00
|
|
|
Client.prototype.enoughResourcesAvailable = function (app) {
|
2016-02-25 18:19:59 -08:00
|
|
|
var needed = app.manifest.memoryLimit || DEFAULT_MEMORY_LIMIT; // RAM+Swap
|
2016-09-13 18:05:38 -07:00
|
|
|
var used = this.getInstalledApps().reduce(function (prev, cur) { return prev + (cur.memoryLimit || cur.manifest.memoryLimit || DEFAULT_MEMORY_LIMIT); }, 0);
|
2016-02-25 17:16:11 -08:00
|
|
|
var roundedMemory = Math.round(this.getConfig().memory / (1024 * 1024 * 1024)) * 1024 * 1024 * 1024; // round to nearest GB
|
2016-11-02 14:52:13 +01:00
|
|
|
var totalMemory = roundedMemory * 1.2; // cloudron-system-setup.sh creates equal amount of swap. 1.2 factor is arbitrary
|
2016-02-25 18:19:59 -08:00
|
|
|
var available = (totalMemory || 0) - used;
|
2015-10-22 11:13:49 +02:00
|
|
|
|
2016-02-26 00:18:47 +01:00
|
|
|
return (available - needed) >= 0;
|
2015-10-22 10:40:33 +02:00
|
|
|
};
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
client = new Client();
|
|
|
|
|
return client;
|
|
|
|
|
}]);
|