appstore: add unlink account route
This commit is contained in:
@@ -907,12 +907,12 @@
|
|||||||
"subscriptionChangeAction": "Manage Subscription",
|
"subscriptionChangeAction": "Manage Subscription",
|
||||||
"subscriptionReactivateAction": "Reactivate Subscription",
|
"subscriptionReactivateAction": "Reactivate Subscription",
|
||||||
"emailNotVerified": "Email not yet verified",
|
"emailNotVerified": "Email not yet verified",
|
||||||
"resetDialog": {
|
"account": "Account",
|
||||||
"title": "Really reset Cloudron ID",
|
"unlinkAction": "Unlink Account",
|
||||||
"description": "This will disconnect the Cloudron from the current cloudron.io account."
|
"unlinkDialog": {
|
||||||
},
|
"title": "Unlink Cloudron.io Account",
|
||||||
"resetAction": "Reset Registration",
|
"description": "This will unlink this Cloudron from the current Cloudron.io Account. It can then be <a href=\"https://docs.cloudron.io/appstore/#account-change\" target=\"_blank\">linked</a> with another account."
|
||||||
"account": "Account"
|
}
|
||||||
},
|
},
|
||||||
"timezone": {
|
"timezone": {
|
||||||
"title": "System Time Zone",
|
"title": "System Time Zone",
|
||||||
|
|||||||
@@ -1383,12 +1383,7 @@
|
|||||||
"subscriptionReactivateAction": "Abonnement heractiveren",
|
"subscriptionReactivateAction": "Abonnement heractiveren",
|
||||||
"title": "Cloudron.io Account",
|
"title": "Cloudron.io Account",
|
||||||
"description": "Een Cloudron.io account wordt gebruikt voor toegang tot de App Store en om je abonnement te beheren.",
|
"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",
|
"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"
|
|
||||||
},
|
},
|
||||||
"timezone": {
|
"timezone": {
|
||||||
"title": "Systeem Tijdzone",
|
"title": "Systeem Tijdzone",
|
||||||
|
|||||||
@@ -887,12 +887,7 @@
|
|||||||
"cloudronId": "Id. de Cloudron",
|
"cloudronId": "Id. de Cloudron",
|
||||||
"subscriptionChangeAction": "Gerir Subscrição",
|
"subscriptionChangeAction": "Gerir Subscrição",
|
||||||
"subscriptionReactivateAction": "Reativar Subscrição",
|
"subscriptionReactivateAction": "Reativar Subscrição",
|
||||||
"emailNotVerified": "E-mail ainda não foi verificado",
|
"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"
|
|
||||||
},
|
},
|
||||||
"updates": {
|
"updates": {
|
||||||
"checkForUpdatesAction": "Procurar por Atualizações",
|
"checkForUpdatesAction": "Procurar por Atualizações",
|
||||||
|
|||||||
@@ -1282,12 +1282,7 @@
|
|||||||
"subscriptionEndsAt": "Отменена и завершена",
|
"subscriptionEndsAt": "Отменена и завершена",
|
||||||
"subscriptionChangeAction": "Управление подпиской",
|
"subscriptionChangeAction": "Управление подпиской",
|
||||||
"subscriptionReactivateAction": "Реактивировать подписку",
|
"subscriptionReactivateAction": "Реактивировать подписку",
|
||||||
"emailNotVerified": "Электронная почта не подтверждена",
|
"emailNotVerified": "Электронная почта не подтверждена"
|
||||||
"resetDialog": {
|
|
||||||
"title": "Полностью сбросить Cloudron ID",
|
|
||||||
"description": "Это действие отвяжет настоящий аккаунт cloudron.io от данного Cloudron."
|
|
||||||
},
|
|
||||||
"resetAction": "Сбросить регистрацию"
|
|
||||||
},
|
},
|
||||||
"timezone": {
|
"timezone": {
|
||||||
"title": "Системный часовой пояс",
|
"title": "Системный часовой пояс",
|
||||||
|
|||||||
@@ -1222,12 +1222,7 @@
|
|||||||
"setupAction": "Cài đặt tài khoản",
|
"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ý.",
|
"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",
|
"title": "Tài khoản Cloudron.io",
|
||||||
"emailNotVerified": "Địa chỉ email chưa được xác minh",
|
"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ý"
|
|
||||||
},
|
},
|
||||||
"title": "Hệ thống"
|
"title": "Hệ thống"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ function create() {
|
|||||||
if (error || result.status !== 200) return [error || result];
|
if (error || result.status !== 200) return [error || result];
|
||||||
return [null, result.body];
|
return [null, result.body];
|
||||||
},
|
},
|
||||||
async resetCloudronId() {
|
async unlinkAccount() {
|
||||||
let result;
|
let result;
|
||||||
try {
|
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) {
|
} catch (e) {
|
||||||
return [e];
|
return [e];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ async function refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const inputDialog = useTemplateRef('inputDialog');
|
const inputDialog = useTemplateRef('inputDialog');
|
||||||
async function onAskResetCloudron() {
|
async function onAskUnlinkAccount() {
|
||||||
const yes = await inputDialog.value.confirm({
|
const yes = await inputDialog.value.confirm({
|
||||||
title: t('settings.appstoreAccount.resetDialog.title'),
|
title: t('settings.appstoreAccount.unlinkDialog.title'),
|
||||||
message: t('settings.appstoreAccount.resetDialog.description'),
|
message: t('settings.appstoreAccount.unlinkDialog.description'),
|
||||||
confirmStyle: 'danger',
|
confirmStyle: 'danger',
|
||||||
confirmLabel: t('main.dialog.yes'),
|
confirmLabel: t('main.dialog.yes'),
|
||||||
rejectLabel: t('main.dialog.cancel'),
|
rejectLabel: t('main.dialog.cancel'),
|
||||||
@@ -61,13 +61,13 @@ async function onAskResetCloudron() {
|
|||||||
|
|
||||||
if (!yes) return;
|
if (!yes) return;
|
||||||
|
|
||||||
await onResetCloudron();
|
await onUnlinkAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onResetCloudron() {
|
async function onUnlinkAccount() {
|
||||||
busy.value = true;
|
busy.value = true;
|
||||||
|
|
||||||
const [error] = await appstoreModel.resetCloudronId();
|
const [error] = await appstoreModel.unlinkAccount();
|
||||||
if (error) return console.error(error);
|
if (error) return console.error(error);
|
||||||
|
|
||||||
await refresh();
|
await refresh();
|
||||||
@@ -129,7 +129,7 @@ onUnmounted(() => {
|
|||||||
<span v-else>{{ $t('settings.appstoreAccount.subscriptionChangeAction') }}</span>
|
<span v-else>{{ $t('settings.appstoreAccount.subscriptionChangeAction') }}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button secondary @click="onAskResetCloudron" v-if="email">{{ $t('settings.appstoreAccount.resetAction') }}</Button>
|
<Button secondary @click="onAskUnlinkAccount" v-if="email">{{ $t('settings.appstoreAccount.unlinkAction') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ onUnmounted(() => {
|
|||||||
Unknown Cloudron ID or invalid cloudron.io token.
|
Unknown Cloudron ID or invalid cloudron.io token.
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; align-items: center;">
|
<div style="display: flex; align-items: center;">
|
||||||
<Button @click="onResetCloudron">{{ $t('settings.appstoreAccount.resetAction') }}</Button>
|
<Button @click="onUnlinkAccount">{{ $t('settings.appstoreAccount.unlinkAction') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
</SettingsItem>
|
</SettingsItem>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+12
-3
@@ -17,6 +17,7 @@ exports = module.exports = {
|
|||||||
|
|
||||||
registerCloudron3,
|
registerCloudron3,
|
||||||
updateCloudron,
|
updateCloudron,
|
||||||
|
unlinkAccount,
|
||||||
|
|
||||||
getSubscription,
|
getSubscription,
|
||||||
isFreePlan,
|
isFreePlan,
|
||||||
@@ -32,6 +33,7 @@ exports = module.exports = {
|
|||||||
const assert = require('node:assert'),
|
const assert = require('node:assert'),
|
||||||
BoxError = require('./boxerror.js'),
|
BoxError = require('./boxerror.js'),
|
||||||
constants = require('./constants.js'),
|
constants = require('./constants.js'),
|
||||||
|
dashboard = require('./dashboard.js'),
|
||||||
debug = require('debug')('box:appstore'),
|
debug = require('debug')('box:appstore'),
|
||||||
manifestFormat = require('@cloudron/manifest-format'),
|
manifestFormat = require('@cloudron/manifest-format'),
|
||||||
paths = require('./paths.js'),
|
paths = require('./paths.js'),
|
||||||
@@ -223,9 +225,9 @@ async function getAppUpdate(app, options) {
|
|||||||
return updateInfo;
|
return updateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function registerCloudron3(domain, version) {
|
async function registerCloudron3() {
|
||||||
assert.strictEqual(typeof domain, 'string');
|
const { domain } = await dashboard.getLocation();
|
||||||
assert.strictEqual(typeof version, 'string');
|
const version = constants.VERSION;
|
||||||
|
|
||||||
const token = await settings.get(settings.APPSTORE_API_TOKEN_KEY);
|
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
|
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}`);
|
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) {
|
async function updateCloudron(data) {
|
||||||
assert.strictEqual(typeof data, 'object');
|
assert.strictEqual(typeof data, 'object');
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -151,8 +151,7 @@ async function activate(username, password, email, displayName, ip, auditSource)
|
|||||||
|
|
||||||
debug(`activate: user: ${username} email:${email}`);
|
debug(`activate: user: ${username} email:${email}`);
|
||||||
|
|
||||||
const dashboardLocation = await dashboard.getLocation();
|
await appstore.registerCloudron3();
|
||||||
await appstore.registerCloudron3(dashboardLocation.domain, constants.VERSION);
|
|
||||||
|
|
||||||
const [error, ownerId] = await safe(users.createOwner(email, username, password, displayName, auditSource));
|
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');
|
if (error && error.reason === BoxError.ALREADY_EXISTS) throw new BoxError(BoxError.CONFLICT, 'Already activated');
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ exports = module.exports = {
|
|||||||
getApp,
|
getApp,
|
||||||
getAppVersion,
|
getAppVersion,
|
||||||
|
|
||||||
resetCloudronId,
|
unlinkAccount,
|
||||||
getSubscription
|
getSubscription
|
||||||
};
|
};
|
||||||
|
|
||||||
const appstore = require('../appstore.js'),
|
const appstore = require('../appstore.js'),
|
||||||
assert = require('node:assert'),
|
assert = require('node:assert'),
|
||||||
BoxError = require('../boxerror.js'),
|
BoxError = require('../boxerror.js'),
|
||||||
constants = require('../constants.js'),
|
|
||||||
dashboard = require('../dashboard.js'),
|
|
||||||
HttpSuccess = require('@cloudron/connect-lastmile').HttpSuccess,
|
HttpSuccess = require('@cloudron/connect-lastmile').HttpSuccess,
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
users = require('../users.js'),
|
users = require('../users.js'),
|
||||||
@@ -45,13 +43,10 @@ async function getAppVersion(req, res, next) {
|
|||||||
next(new HttpSuccess(200, manifest));
|
next(new HttpSuccess(200, manifest));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resetCloudronId(req, res, next) {
|
async function unlinkAccount(req, res, next) {
|
||||||
assert.strictEqual(typeof req.body, 'object');
|
assert.strictEqual(typeof req.body, 'object');
|
||||||
|
|
||||||
const [getLocationError, dashboardLocation] = await safe(dashboard.getLocation()); // authenticated route implies already activated
|
const [registerError] = await safe(appstore.unlinkAccount());
|
||||||
if (getLocationError) return next(BoxError.toHttpError(getLocationError));
|
|
||||||
|
|
||||||
const [registerError] = await safe(appstore.registerCloudron3(dashboardLocation.domain, constants.VERSION));
|
|
||||||
if (registerError) return next(BoxError.toHttpError(registerError));
|
if (registerError) return next(BoxError.toHttpError(registerError));
|
||||||
|
|
||||||
next(new HttpSuccess(202, {}));
|
next(new HttpSuccess(202, {}));
|
||||||
|
|||||||
+1
-1
@@ -256,7 +256,7 @@ async function initializeExpressSync() {
|
|||||||
router.post('/api/v1/directory_server/config', json, token, authorizeAdmin, routes.directoryServer.setConfig);
|
router.post('/api/v1/directory_server/config', json, token, authorizeAdmin, routes.directoryServer.setConfig);
|
||||||
|
|
||||||
// appstore and subscription routes
|
// 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/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', token, authorizeAdmin, routes.appstore.getApps);
|
||||||
router.get ('/api/v1/appstore/apps/:appstoreId', token, authorizeAdmin, routes.appstore.getApp);
|
router.get ('/api/v1/appstore/apps/:appstoreId', token, authorizeAdmin, routes.appstore.getApp);
|
||||||
|
|||||||
Reference in New Issue
Block a user