diff --git a/dashboard/src/js/client.js b/dashboard/src/js/client.js
index a0a777414..cdf26c7df 100644
--- a/dashboard/src/js/client.js
+++ b/dashboard/src/js/client.js
@@ -3495,11 +3495,24 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout
});
};
+ Client.prototype.registerCloudronWithSetupToken = function (setupToken, callback) {
+ var data = {
+ setupToken: setupToken
+ };
+
+ post('/api/v1/appstore/register_cloudron_with_setup_token', data, null, function (error, data, status) {
+ if (error) return callback(error);
+ if (status !== 201) return callback(new ClientError(status, data));
+
+ callback(null);
+ });
+ };
+
Client.prototype.registerCloudron = function (email, password, totpToken, signup, callback) {
var data = {
email: email,
password: password,
- signup: signup,
+ signup: signup
};
if (totpToken) data.totpToken = totpToken;
diff --git a/dashboard/src/views/appstore.html b/dashboard/src/views/appstore.html
index d6089c72d..0253d1211 100644
--- a/dashboard/src/views/appstore.html
+++ b/dashboard/src/views/appstore.html
@@ -281,8 +281,9 @@
-
{{ 'appstore.accountDialog.titleSignUp' | tr }}
- {{ 'appstore.accountDialog.titleLogin' | tr }}
+ {{ 'appstore.accountDialog.titleSignUp' | tr }}
+ {{ 'appstore.accountDialog.titleLogin' | tr }}
+ {{ 'appstore.accountDialog.titleToken' | tr }}
{{ 'appstore.accountDialog.description' | tr }}
@@ -293,54 +294,122 @@
diff --git a/dashboard/src/views/appstore.js b/dashboard/src/views/appstore.js
index 6f46c5543..c50d6dbd1 100644
--- a/dashboard/src/views/appstore.js
+++ b/dashboard/src/views/appstore.js
@@ -416,14 +416,16 @@ angular.module('Application').controller('AppStoreController', ['$scope', '$tran
email: '',
password: '',
totpToken: '',
- register: true,
+ setupType: 'login',
termsAccepted: false,
+ setupToken: '',
submit: function () {
$scope.appstoreLogin.error = {};
$scope.appstoreLogin.busy = true;
- Client.registerCloudron($scope.appstoreLogin.email, $scope.appstoreLogin.password, $scope.appstoreLogin.totpToken, $scope.appstoreLogin.register, function (error) {
+ var func = $scope.appstoreLogin.setupToken ? Client.registerCloudronWithSetupToken.bind(null, $scope.appstoreLogin.setupToken) : Client.registerCloudron.bind(null, $scope.appstoreLogin.email, $scope.appstoreLogin.password, $scope.appstoreLogin.totpToken, $scope.appstoreLogin.register);
+ func(function (error) {
if (error) {
$scope.appstoreLogin.busy = false;
diff --git a/src/appstore.js b/src/appstore.js
index c0ad2c78d..c9db26771 100644
--- a/src/appstore.js
+++ b/src/appstore.js
@@ -13,7 +13,8 @@ exports = module.exports = {
getAppVersion,
downloadIcon,
- registerWithLoginCredentials,
+ registerCloudronWithSetupToken,
+ registerCloudronWithLogin,
updateCloudron,
purchaseApp,
@@ -295,10 +296,10 @@ async function getAppUpdate(app, options) {
async function registerCloudron(data) {
assert.strictEqual(typeof data, 'object');
- const { domain, accessToken, version, existingApps } = data;
+ const { domain, setupToken, accessToken, version, existingApps } = data;
const [error, response] = await safe(superagent.post(`${await getApiServerOrigin()}/api/v1/register_cloudron`)
- .send({ domain, accessToken, version, existingApps })
+ .send({ domain, setupToken, accessToken, version, existingApps })
.timeout(30 * 1000)
.ok(() => true));
@@ -341,13 +342,26 @@ async function updateCloudron(data) {
debug(`updateCloudron: Cloudron updated with data ${JSON.stringify(data)}`);
}
-async function registerWithLoginCredentials(options) {
+async function registerCloudronWithSetupToken(options) {
+ assert.strictEqual(typeof options, 'object');
+
+ const { domain } = await dashboard.getLocation();
+
+ await registerCloudron({ domain, setupToken: options.setupToken, version: constants.VERSION });
+
+ for (const app of await apps.list()) {
+ await purchaseApp({ appId: app.id, appstoreId: app.appStoreId, manifestId: app.manifest.id || 'customapp' });
+ }
+}
+
+async function registerCloudronWithLogin(options) {
assert.strictEqual(typeof options, 'object');
if (options.signup) await registerUser(options.email, options.password);
-
const result = await login(options.email, options.password, options.totpToken || '');
+
const { domain } = await dashboard.getLocation();
+
await registerCloudron({ domain, accessToken: result.accessToken, version: constants.VERSION });
for (const app of await apps.list()) {
diff --git a/src/routes/appstore.js b/src/routes/appstore.js
index 44724ad29..002e2a7ba 100644
--- a/src/routes/appstore.js
+++ b/src/routes/appstore.js
@@ -6,7 +6,8 @@ exports = module.exports = {
getAppVersion,
getWebToken,
- registerCloudron,
+ registerCloudronWithSetupToken,
+ registerCloudronWithLogin,
getSubscription
};
@@ -52,7 +53,18 @@ async function getWebToken(req, res, next) {
next(new HttpSuccess(200, { accessToken }));
}
-async function registerCloudron(req, res, next) {
+async function registerCloudronWithSetupToken(req, res, next) {
+ assert.strictEqual(typeof req.body, 'object');
+
+ if (typeof req.body.setupToken !== 'string') return next(new HttpError(400, 'setupToken must be a string'));
+
+ const [error] = await safe(appstore.registerCloudronWithSetupToken({ setupToken: req.body.setupToken }));
+ if (error) return next(BoxError.toHttpError(error));
+
+ next(new HttpSuccess(201, {}));
+}
+
+async function registerCloudronWithLogin(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (typeof req.body.email !== 'string' || !req.body.email) return next(new HttpError(400, 'email must be string'));
@@ -60,7 +72,7 @@ async function registerCloudron(req, res, next) {
if ('totpToken' in req.body && typeof req.body.totpToken !== 'string') return next(new HttpError(400, 'totpToken must be string'));
if (typeof req.body.signup !== 'boolean') return next(new HttpError(400, 'signup must be a boolean'));
- const [error] = await safe(appstore.registerWithLoginCredentials(req.body));
+ const [error] = await safe(appstore.registerCloudronWithLogin(req.body));
if (error) return next(BoxError.toHttpError(error));
next(new HttpSuccess(201, {}));
diff --git a/src/server.js b/src/server.js
index d617154d3..ae622d02b 100644
--- a/src/server.js
+++ b/src/server.js
@@ -219,7 +219,8 @@ async function initializeExpressSync() {
router.post('/api/v1/directory_server/config', json, token, authorizeAdmin, routes.directoryServer.setConfig);
// appstore and subscription routes
- router.post('/api/v1/appstore/register_cloudron', json, token, authorizeOwner, routes.appstore.registerCloudron);
+ router.post('/api/v1/appstore/register_cloudron', json, token, authorizeOwner, routes.appstore.registerCloudronWithLogin);
+ router.post('/api/v1/appstore/register_cloudron_with_setup_token', json, token, authorizeOwner, routes.appstore.registerCloudronWithSetupToken);
router.get ('/api/v1/appstore/web_token', json, token, authorizeOwner, routes.appstore.getWebToken);
router.get ('/api/v1/appstore/subscription', token, authorizeUser, routes.appstore.getSubscription); // for all users
router.get ('/api/v1/appstore/apps', token, authorizeAdmin, routes.appstore.getApps);