diff --git a/gulpfile.js b/gulpfile.js
index 4659bb1b4..f7be34c74 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -80,7 +80,6 @@ gulp.task('js-index', function () {
return gulp.src([
'src/js/index.js',
'src/js/client.js',
- 'src/js/appstore.js',
'src/js/main.js',
'src/views/*.js'
])
@@ -198,7 +197,7 @@ gulp.task('watch', function (done) {
gulp.watch(['src/js/restore.js', 'src/js/client.js'], gulp.series(['js-restore']));
gulp.watch(['src/js/logs.js', 'src/js/client.js'], gulp.series(['js-logs']));
gulp.watch(['src/js/terminal.js', 'src/js/client.js'], gulp.series(['js-terminal']));
- gulp.watch(['src/js/index.js', 'src/js/client.js', 'src/js/appstore.js', 'src/js/main.js', 'src/views/*.js'], gulp.series(['js-index']));
+ gulp.watch(['src/js/index.js', 'src/js/client.js', 'src/js/main.js', 'src/views/*.js'], gulp.series(['js-index']));
gulp.watch(['src/3rdparty/**/*'], gulp.series(['3rdparty']));
done();
});
diff --git a/src/js/appstore.js b/src/js/appstore.js
deleted file mode 100644
index 38b482070..000000000
--- a/src/js/appstore.js
+++ /dev/null
@@ -1,93 +0,0 @@
-'use strict';
-
-/* global angular:false */
-
-angular.module('Application').service('AppStore', ['$http', '$base64', 'Client', function ($http, $base64, Client) {
-
- function AppStoreError(statusCode, message) {
- Error.call(this);
- this.name = this.constructor.name;
- this.statusCode = statusCode;
- if (typeof message == 'string') {
- this.message = message;
- } else {
- this.message = JSON.stringify(message);
- }
- }
-
- function AppStore() {
- }
-
- AppStore.prototype.register = function (email, password, callback) {
- if (Client.getConfig().apiServerOrigin === null) return callback(new AppStoreError(420, 'Enhance Your Calm'));
-
- var data = {
- email: email,
- password: password
- };
-
- $http.post(Client.getConfig().apiServerOrigin + '/api/v1/users', data).success(function (data, status) {
- if (status !== 201) return callback(new AppStoreError(status, data));
- return callback(null, data);
- }).error(function (data, status) {
- return callback(new AppStoreError(status, data));
- });
- };
-
- AppStore.prototype.login = function (email, password, totpToken, callback) {
- if (Client.getConfig().apiServerOrigin === null) return callback(new AppStoreError(420, 'Enhance Your Calm'));
-
- var data = {
- email: email,
- password: password,
- persistent: true,
- totpToken: totpToken
- };
-
- $http.post(Client.getConfig().apiServerOrigin + '/api/v1/login', data).success(function (data, status) {
- if (status !== 200) return callback(new AppStoreError(status, data));
- return callback(null, data);
- }).error(function (data, status) {
- return callback(new AppStoreError(status, data));
- });
- };
-
- AppStore.prototype.logout = function (email, password, callback) {
- if (Client.getConfig().apiServerOrigin === null) return callback(new AppStoreError(420, 'Enhance Your Calm'));
-
- $http.post(Client.getConfig().apiServerOrigin + '/api/v1/logout').success(function (data, status) {
- if (status !== 200) return callback(new AppStoreError(status, data));
- return callback(null);
- }).error(function (data, status) {
- return callback(new AppStoreError(status, data));
- });
- };
-
- AppStore.prototype.getProfile = function (token, callback) {
- if (Client.getConfig().apiServerOrigin === null) return callback(new AppStoreError(420, 'Enhance Your Calm'));
-
- $http.get(Client.getConfig().apiServerOrigin + '/api/v1/profile', { params: { accessToken: token }}).success(function (data, status) {
- if (status !== 200) return callback(new AppStoreError(status, data));
-
- // just some helper property, since angular bindings cannot dot his easily
- data.profile.emailEncoded = encodeURIComponent(data.profile.email);
-
- return callback(null, data.profile);
- }).error(function (data, status) {
- return callback(new AppStoreError(status, data));
- });
- };
-
- AppStore.prototype.getSubscription = function (appstoreConfig, callback) {
- if (Client.getConfig().apiServerOrigin === null) return callback(new AppStoreError(420, 'Enhance Your Calm'));
-
- $http.get(Client.getConfig().apiServerOrigin + '/api/v1/users/' + appstoreConfig.userId + '/cloudrons/' + appstoreConfig.cloudronId + '/subscription', { params: { accessToken: appstoreConfig.token }}).success(function (data, status) {
- if (status !== 200) return callback(new AppStoreError(status, data));
- return callback(null, data.subscription);
- }).error(function (data, status) {
- return callback(new AppStoreError(status, data));
- });
- };
-
- return new AppStore();
-}]);
diff --git a/src/js/client.js b/src/js/client.js
index fc97f5977..2dd87a219 100644
--- a/src/js/client.js
+++ b/src/js/client.js
@@ -611,24 +611,6 @@ angular.module('Application').service('Client', ['$http', '$interval', 'md5', 'N
});
};
- Client.prototype.setAppstoreConfig = function (appstoreConfig, callback) {
- post('/api/v1/settings/appstore_config', appstoreConfig, null, function (error, data, status) {
- if (error) return callback(error);
- if (status !== 202) return callback(new ClientError(status, data));
-
- callback(null);
- });
- };
-
- Client.prototype.getAppstoreConfig = function (callback) {
- get('/api/v1/settings/appstore_config', null, function (error, data, status) {
- if (error) return callback(error);
- if (status !== 200) return callback(new ClientError(status, data));
-
- callback(null, data);
- });
- };
-
Client.prototype.getRemoteSupport = function (callback) {
get('/api/v1/support/remote_support', null, function (error, data, status) {
if (error) return callback(error);
diff --git a/src/js/main.js b/src/js/main.js
index 6a0240cf6..9c94a6360 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -3,7 +3,7 @@
/* global angular:false */
/* global $:false */
-angular.module('Application').controller('MainController', ['$scope', '$route', '$timeout', '$location', 'Client', 'AppStore', function ($scope, $route, $timeout, $location, Client, AppStore) {
+angular.module('Application').controller('MainController', ['$scope', '$route', '$timeout', '$location', 'Client', function ($scope, $route, $timeout, $location, Client) {
$scope.initialized = false; // used to animate the UI
$scope.user = Client.getUserInfo();
$scope.installedApps = Client.getInstalledApps();
diff --git a/src/views/appstore.html b/src/views/appstore.html
index adca97592..0864d7746 100644
--- a/src/views/appstore.html
+++ b/src/views/appstore.html
@@ -161,7 +161,7 @@
- Setup Subscription
+ Setup Subscription
@@ -189,7 +189,7 @@
-
+
Sign up with Cloudron.io
Login to Cloudron.io
@@ -255,12 +255,12 @@
-
+
-
+
diff --git a/src/views/appstore.js b/src/views/appstore.js
index 4108e1374..09df3bf17 100644
--- a/src/views/appstore.js
+++ b/src/views/appstore.js
@@ -3,7 +3,7 @@
/* global angular:false */
/* global $:false */
-angular.module('Application').controller('AppStoreController', ['$scope', '$location', '$timeout', '$routeParams', 'Client', 'AppStore', function ($scope, $location, $timeout, $routeParams, Client, AppStore) {
+angular.module('Application').controller('AppStoreController', ['$scope', '$location', '$timeout', '$routeParams', 'Client', function ($scope, $location, $timeout, $routeParams, Client) {
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
$scope.HOST_PORT_MIN = 1024;
@@ -19,9 +19,9 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
$scope.category = '';
$scope.cachedCategory = ''; // used to cache the selected category while searching
$scope.searchString = '';
- $scope.validAppstoreAccount = false;
- $scope.appstoreConfig = null;
+ $scope.validSubscription = false;
$scope.unstableApps = false;
+ $scope.subscription = {};
$scope.showView = function (view) {
// wait for dialog to be fully closed to avoid modal behavior breakage when moving to a different view already
@@ -241,70 +241,7 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
$scope.appstoreLogin.error = {};
$scope.appstoreLogin.busy = true;
- function login() {
- AppStore.login($scope.appstoreLogin.email, $scope.appstoreLogin.password, $scope.appstoreLogin.totpToken, function (error, result) {
- if (error) {
- $scope.appstoreLogin.busy = false;
-
- if (error.statusCode === 401) {
- if (error.message.indexOf('TOTP token missing') !== -1) {
- $scope.appstoreLogin.error.totpToken = 'A 2FA token is required';
- setTimeout(function () { $('#inputAppstoreLoginTotpToken').focus(); }, 0);
- } else if (error.message.indexOf('TOTP token invalid') !== -1) {
- $scope.appstoreLogin.error.totpToken = 'Wrong 2FA token';
- $scope.appstoreLogin.totpToken = '';
- setTimeout(function () { $('#inputAppstoreLoginTotpToken').focus(); }, 0);
- } else {
- $scope.appstoreLogin.error.password = 'Wrong email or password';
- $scope.appstoreLogin.password = '';
- $('#inputAppstoreLoginPassword').focus();
- $scope.appstoreLoginForm.password.$setPristine();
- }
- } else {
- console.error(error);
- }
-
- return;
- }
-
- var config = {
- userId: result.userId,
- token: result.accessToken
- };
-
- Client.setAppstoreConfig(config, function (error) {
- if (error) {
- $scope.appstoreLogin.busy = false;
-
- if (error.statusCode === 424) {
- if (error.message === 'wrong user') {
- $scope.appstoreLogin.error.generic = 'Wrong cloudron.io account';
- $scope.appstoreLogin.email = '';
- $scope.appstoreLogin.password = '';
- $scope.appstoreLoginForm.email.$setPristine();
- $scope.appstoreLoginForm.password.$setPristine();
- $('#inputAppstoreLoginEmail').focus();
- } else {
- console.error(error);
- $scope.appstoreLogin.error.generic = 'Please retry later';
- }
- } else {
- console.error(error);
- }
-
- return;
- }
-
- fetchAppstoreConfig(function (error) {
- if (error) return console.error('Unable to fetch appstore config.', error);
- });
- });
- });
- }
-
- if (!$scope.appstoreLogin.register) return login();
-
- AppStore.register($scope.appstoreLogin.email, $scope.appstoreLogin.password, function (error) {
+ Client.subscribeCloudron($scope.appstoreLogin.email, $scope.appstoreLogin.password, $scope.appstoreLogin.totpToken, $scope.appstoreLogin.register, function (error) {
if (error) {
$scope.appstoreLogin.busy = false;
@@ -314,6 +251,32 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
$scope.appstoreLoginForm.email.$setPristine();
$scope.appstoreLoginForm.password.$setPristine();
$('#inputAppstoreLoginEmail').focus();
+ } else if (error.statusCode === 412) {
+ if (error.message.indexOf('TOTP token missing') !== -1) {
+ $scope.appstoreLogin.error.totpToken = 'A 2FA token is required';
+ setTimeout(function () { $('#inputAppstoreLoginTotpToken').focus(); }, 0);
+ } else if (error.message.indexOf('TOTP token invalid') !== -1) {
+ $scope.appstoreLogin.error.totpToken = 'Wrong 2FA token';
+ $scope.appstoreLogin.totpToken = '';
+ setTimeout(function () { $('#inputAppstoreLoginTotpToken').focus(); }, 0);
+ } else {
+ $scope.appstoreLogin.error.password = 'Wrong email or password';
+ $scope.appstoreLogin.password = '';
+ $('#inputAppstoreLoginPassword').focus();
+ $scope.appstoreLoginForm.password.$setPristine();
+ }
+ } else if (error.statusCode === 424) {
+ if (error.message === 'wrong user') {
+ $scope.appstoreLogin.error.generic = 'Wrong cloudron.io account';
+ $scope.appstoreLogin.email = '';
+ $scope.appstoreLogin.password = '';
+ $scope.appstoreLoginForm.email.$setPristine();
+ $scope.appstoreLoginForm.password.$setPristine();
+ $('#inputAppstoreLoginEmail').focus();
+ } else {
+ console.error(error);
+ $scope.appstoreLogin.error.generic = error.message;
+ }
} else {
console.error(error);
$scope.appstoreLogin.error.generic = 'Please retry later';
@@ -321,8 +284,6 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
return;
}
-
- login();
});
}
};
@@ -475,42 +436,21 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
});
}
- function fetchAppstoreConfig(callback) {
- callback = callback || function (error) { if (error) console.error(error); };
+ function getSubscription(callback) {
+ Client.getSubscription(function (error, subscription) {
+ if (error) { // error.statusCode will be 402
+ $scope.validSubscription = false;
+ } else {
+ $scope.subscription = subscription;
+ }
- if ($scope.user.admin && $scope.config.managed) {
- $scope.validAppstoreAccount = true;
- return callback();
- }
+ // clear busy state when a login/signup was performed
+ $scope.appstoreLogin.busy = false;
- Client.getAppstoreConfig(function (error, result) {
- if (error) return callback(error);
+ // also update the root controller status
+ if ($scope.$parent) $scope.$parent.updateSubscriptionStatus();
- if (!result.token || !result.cloudronId) return callback();
-
- var appstoreConfig = result;
-
- AppStore.getProfile(appstoreConfig.token, function (error, result) {
- if (error) return console.error(error);
-
- // assign late to avoid UI flicketing on update
- appstoreConfig.profile = result;
- $scope.appstoreConfig = appstoreConfig;
-
- $scope.validAppstoreAccount = true;
-
- // clear busy state when a login/signup was performed
- $scope.appstoreLogin.busy = false;
-
- // also update the root controller status
- if ($scope.$parent) {
- $scope.$parent.fetchAppstoreProfileAndSubscription(function (error) {
- if (error) console.error(error);
- });
- }
-
- callback();
- });
+ callback();
});
}
@@ -541,7 +481,7 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
// hashChangeListener calls $apply, so make sure we don't double digest here
setTimeout(hashChangeListener, 1);
- fetchAppstoreConfig(function (error) {
+ getSubscription(function (error) {
if (error) console.error(error);
$scope.ready = true;
@@ -575,7 +515,7 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$loca
});
// autofocus if appstore login is shown
- $scope.$watch('validAppstoreAccount', function (newValue/*, oldValue */) {
+ $scope.$watch('validSubscription', function (newValue/*, oldValue */) {
if (!newValue) setTimeout(function () { $('[name=appstoreLoginForm]').find('[autofocus]:first').focus(); }, 1000);
});
diff --git a/src/views/settings.js b/src/views/settings.js
index 19747e578..4cbfb6e8e 100644
--- a/src/views/settings.js
+++ b/src/views/settings.js
@@ -3,7 +3,7 @@
/* global angular:false */
/* global $:false */
-angular.module('Application').controller('SettingsController', ['$scope', '$location', '$rootScope', '$timeout', 'Client', 'AppStore', function ($scope, $location, $rootScope, $timeout, Client, AppStore) {
+angular.module('Application').controller('SettingsController', ['$scope', '$location', '$rootScope', '$timeout', 'Client', function ($scope, $location, $rootScope, $timeout, Client) {
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
$scope.client = Client;
@@ -314,7 +314,7 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
$scope.subscription = result;
// also reload the subscription on the main controller
- $scope.$parent.updateSubscriptionStatus(function () {});
+ $scope.$parent.updateSubscriptionStatus();
// check again to give more immediate feedback once a subscription was setup
if (result.plan.id === 'free') $timeout(getSubscription, 10000);