diff --git a/dashboard/public/translation/en.json b/dashboard/public/translation/en.json index d553a0804..e70061628 100644 --- a/dashboard/public/translation/en.json +++ b/dashboard/public/translation/en.json @@ -907,12 +907,12 @@ "subscriptionChangeAction": "Manage Subscription", "subscriptionReactivateAction": "Reactivate Subscription", "emailNotVerified": "Email not yet verified", - "resetDialog": { - "title": "Really reset Cloudron ID", - "description": "This will disconnect the Cloudron from the current cloudron.io account." - }, - "resetAction": "Reset Registration", - "account": "Account" + "account": "Account", + "unlinkAction": "Unlink Account", + "unlinkDialog": { + "title": "Unlink Cloudron.io Account", + "description": "This will unlink this Cloudron from the current Cloudron.io Account. It can then be linked with another account." + } }, "timezone": { "title": "System Time Zone", diff --git a/dashboard/public/translation/nl.json b/dashboard/public/translation/nl.json index 7dafb378c..d95b692ea 100644 --- a/dashboard/public/translation/nl.json +++ b/dashboard/public/translation/nl.json @@ -1383,12 +1383,7 @@ "subscriptionReactivateAction": "Abonnement heractiveren", "title": "Cloudron.io Account", "description": "Een Cloudron.io account wordt gebruikt voor toegang tot de App Store en om je abonnement te beheren.", - "emailNotVerified": "E-mail is niet geverifieerd", - "resetDialog": { - "title": "Weet je zeker dat je je Cloudron ID wilt resetten", - "description": "Hierdoor wordt deze Cloudron losgekoppeld van het huidige Cloudron.io account." - }, - "resetAction": "Reset Registratie" + "emailNotVerified": "E-mail is niet geverifieerd" }, "timezone": { "title": "Systeem Tijdzone", diff --git a/dashboard/public/translation/pt.json b/dashboard/public/translation/pt.json index 61e6883da..00936a099 100644 --- a/dashboard/public/translation/pt.json +++ b/dashboard/public/translation/pt.json @@ -887,12 +887,7 @@ "cloudronId": "Id. de Cloudron", "subscriptionChangeAction": "Gerir Subscrição", "subscriptionReactivateAction": "Reativar Subscrição", - "emailNotVerified": "E-mail ainda não foi verificado", - "resetDialog": { - "title": "Deseja redefinir a Id. do Cloudron", - "description": "Isto desligará o Cloudron da conta Cloudron.io atual." - }, - "resetAction": "Reiniciar Registo" + "emailNotVerified": "E-mail ainda não foi verificado" }, "updates": { "checkForUpdatesAction": "Procurar por Atualizações", diff --git a/dashboard/public/translation/ru.json b/dashboard/public/translation/ru.json index d01c9cb49..2758ec196 100644 --- a/dashboard/public/translation/ru.json +++ b/dashboard/public/translation/ru.json @@ -1282,12 +1282,7 @@ "subscriptionEndsAt": "Отменена и завершена", "subscriptionChangeAction": "Управление подпиской", "subscriptionReactivateAction": "Реактивировать подписку", - "emailNotVerified": "Электронная почта не подтверждена", - "resetDialog": { - "title": "Полностью сбросить Cloudron ID", - "description": "Это действие отвяжет настоящий аккаунт cloudron.io от данного Cloudron." - }, - "resetAction": "Сбросить регистрацию" + "emailNotVerified": "Электронная почта не подтверждена" }, "timezone": { "title": "Системный часовой пояс", diff --git a/dashboard/public/translation/vi.json b/dashboard/public/translation/vi.json index f3fb96eea..d93915b42 100644 --- a/dashboard/public/translation/vi.json +++ b/dashboard/public/translation/vi.json @@ -1222,12 +1222,7 @@ "setupAction": "Cài đặt tài khoản", "description": "Tài khoản Cloudron.io được dùng để truy cập Cửa hàng App và quản lý gói đăng ký.", "title": "Tài khoản Cloudron.io", - "emailNotVerified": "Địa chỉ email chưa được xác minh", - "resetDialog": { - "title": "Chắc chắn cài đặt lại Cloudron ID", - "description": "Việc này sẽ ngắt kết nối Cloudron khỏi tài khoản cloudron.io hiện tại." - }, - "resetAction": "Cài đặt lại Đăng ký" + "emailNotVerified": "Địa chỉ email chưa được xác minh" }, "title": "Hệ thống" }, diff --git a/dashboard/src/models/AppstoreModel.js b/dashboard/src/models/AppstoreModel.js index 73e696a7b..a4036fd5e 100644 --- a/dashboard/src/models/AppstoreModel.js +++ b/dashboard/src/models/AppstoreModel.js @@ -42,10 +42,10 @@ function create() { if (error || result.status !== 200) return [error || result]; return [null, result.body]; }, - async resetCloudronId() { + async unlinkAccount() { let result; try { - result = await fetcher.post(`${API_ORIGIN}/api/v1/appstore/reset_cloudron_id`, {}, { access_token: accessToken }); + result = await fetcher.post(`${API_ORIGIN}/api/v1/appstore/unlink_account`, {}, { access_token: accessToken }); } catch (e) { return [e]; } diff --git a/dashboard/src/views/CloudronAccountView.vue b/dashboard/src/views/CloudronAccountView.vue index 4aecdb6e1..d3b407769 100644 --- a/dashboard/src/views/CloudronAccountView.vue +++ b/dashboard/src/views/CloudronAccountView.vue @@ -49,10 +49,10 @@ async function refresh() { } const inputDialog = useTemplateRef('inputDialog'); -async function onAskResetCloudron() { +async function onAskUnlinkAccount() { const yes = await inputDialog.value.confirm({ - title: t('settings.appstoreAccount.resetDialog.title'), - message: t('settings.appstoreAccount.resetDialog.description'), + title: t('settings.appstoreAccount.unlinkDialog.title'), + message: t('settings.appstoreAccount.unlinkDialog.description'), confirmStyle: 'danger', confirmLabel: t('main.dialog.yes'), rejectLabel: t('main.dialog.cancel'), @@ -61,13 +61,13 @@ async function onAskResetCloudron() { if (!yes) return; - await onResetCloudron(); + await onUnlinkAccount(); } -async function onResetCloudron() { +async function onUnlinkAccount() { busy.value = true; - const [error] = await appstoreModel.resetCloudronId(); + const [error] = await appstoreModel.unlinkAccount(); if (error) return console.error(error); await refresh(); @@ -129,7 +129,7 @@ onUnmounted(() => { {{ $t('settings.appstoreAccount.subscriptionChangeAction') }} - + @@ -147,7 +147,7 @@ onUnmounted(() => { Unknown Cloudron ID or invalid cloudron.io token.
- +
diff --git a/src/appstore.js b/src/appstore.js index c9d80fb2e..dd43f8f78 100644 --- a/src/appstore.js +++ b/src/appstore.js @@ -17,6 +17,7 @@ exports = module.exports = { registerCloudron3, updateCloudron, + unlinkAccount, getSubscription, isFreePlan, @@ -32,6 +33,7 @@ exports = module.exports = { const assert = require('node:assert'), BoxError = require('./boxerror.js'), constants = require('./constants.js'), + dashboard = require('./dashboard.js'), debug = require('debug')('box:appstore'), manifestFormat = require('@cloudron/manifest-format'), paths = require('./paths.js'), @@ -223,9 +225,9 @@ async function getAppUpdate(app, options) { return updateInfo; } -async function registerCloudron3(domain, version) { - assert.strictEqual(typeof domain, 'string'); - assert.strictEqual(typeof version, 'string'); +async function registerCloudron3() { + const { domain } = await dashboard.getLocation(); + const version = constants.VERSION; const token = await settings.get(settings.APPSTORE_API_TOKEN_KEY); if (token) { // when installed using setupToken, this updates the domain record when called during provisioning @@ -250,6 +252,13 @@ async function registerCloudron3(domain, version) { debug(`registerCloudron3: Cloudron registered with id ${response.body.cloudronId}`); } +async function unlinkAccount() { + debug('unlinkAccount: Unlinking existing account.'); + + await unregister(); + return await registerCloudron3(); +} + async function updateCloudron(data) { assert.strictEqual(typeof data, 'object'); diff --git a/src/provision.js b/src/provision.js index 2559ab1a8..f87fe32ef 100644 --- a/src/provision.js +++ b/src/provision.js @@ -151,8 +151,7 @@ async function activate(username, password, email, displayName, ip, auditSource) debug(`activate: user: ${username} email:${email}`); - const dashboardLocation = await dashboard.getLocation(); - await appstore.registerCloudron3(dashboardLocation.domain, constants.VERSION); + await appstore.registerCloudron3(); const [error, ownerId] = await safe(users.createOwner(email, username, password, displayName, auditSource)); if (error && error.reason === BoxError.ALREADY_EXISTS) throw new BoxError(BoxError.CONFLICT, 'Already activated'); diff --git a/src/routes/appstore.js b/src/routes/appstore.js index cf106d5db..bb8815251 100644 --- a/src/routes/appstore.js +++ b/src/routes/appstore.js @@ -5,15 +5,13 @@ exports = module.exports = { getApp, getAppVersion, - resetCloudronId, + unlinkAccount, getSubscription }; const appstore = require('../appstore.js'), assert = require('node:assert'), BoxError = require('../boxerror.js'), - constants = require('../constants.js'), - dashboard = require('../dashboard.js'), HttpSuccess = require('@cloudron/connect-lastmile').HttpSuccess, safe = require('safetydance'), users = require('../users.js'), @@ -45,13 +43,10 @@ async function getAppVersion(req, res, next) { next(new HttpSuccess(200, manifest)); } -async function resetCloudronId(req, res, next) { +async function unlinkAccount(req, res, next) { assert.strictEqual(typeof req.body, 'object'); - const [getLocationError, dashboardLocation] = await safe(dashboard.getLocation()); // authenticated route implies already activated - if (getLocationError) return next(BoxError.toHttpError(getLocationError)); - - const [registerError] = await safe(appstore.registerCloudron3(dashboardLocation.domain, constants.VERSION)); + const [registerError] = await safe(appstore.unlinkAccount()); if (registerError) return next(BoxError.toHttpError(registerError)); next(new HttpSuccess(202, {})); diff --git a/src/server.js b/src/server.js index b927dceae..d7a27c5c6 100644 --- a/src/server.js +++ b/src/server.js @@ -256,7 +256,7 @@ 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/reset_cloudron_id', json, token, authorizeOwner, routes.appstore.resetCloudronId); + router.post('/api/v1/appstore/unlink_account', json, token, authorizeOwner, routes.appstore.unlinkAccount); 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); router.get ('/api/v1/appstore/apps/:appstoreId', token, authorizeAdmin, routes.appstore.getApp);