mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 22:43:30 +03:00
Added handling for forceUpgrade
state (#2116)
no issue - Lapsed trials and subscriptions will set the site's hosting config to `forceUpgrade` in which case a Ghost(Pro) site does not have a valid subscription or trial - In this state we need to redirect all routes for all staff users to `/#/pro` to ensure the subscription can be put back into an active state - This commit tackles - Route update on startup on the application route level - Catching and redirecting all transition (utils routes) - Fetching the owner user to pass this information to the Ghost(Pro) app for better communication to non-owner staff users - Allowing non-owner users in the force upgrade state to transition to the `/#/pro` route
This commit is contained in:
parent
5b434d5ae6
commit
b63a396423
@ -9,6 +9,8 @@ export default Component.extend({
|
||||
ajax: service(),
|
||||
notifications: service(),
|
||||
|
||||
isOwner: null,
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
@ -27,13 +29,21 @@ export default Component.extend({
|
||||
request: 'token',
|
||||
response: token
|
||||
}, '*');
|
||||
|
||||
this.set('isOwner', true);
|
||||
}).catch((error) => {
|
||||
if (error.payload?.errors && error.payload.errors[0]?.type === 'NoPermissionError') {
|
||||
// noop - user doesn't have permission to access billing
|
||||
return;
|
||||
}
|
||||
// no permission means the current user requesting the token is not the owner of the site.
|
||||
this.set('isOwner', false);
|
||||
|
||||
// Avoid letting the BMA waiting for a message and send an empty token response instead
|
||||
this.billing.getBillingIframe().contentWindow.postMessage({
|
||||
request: 'token',
|
||||
response: null
|
||||
}, '*');
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
// NOTE: the handler is placed here to avoid additional logic to check if iframe has loaded
|
||||
@ -47,6 +57,27 @@ export default Component.extend({
|
||||
}
|
||||
}
|
||||
|
||||
if (event && event.data && event.data.request === 'forceUpgradeInfo') {
|
||||
// Send BMA requested information about forceUpgrade and owner name/email
|
||||
let ownerUser = null;
|
||||
const owner = this.billing.ownerUser;
|
||||
|
||||
if (owner) {
|
||||
ownerUser = {
|
||||
name: owner?.name,
|
||||
email: owner?.email
|
||||
};
|
||||
}
|
||||
this.billing.getBillingIframe().contentWindow.postMessage({
|
||||
request: 'forceUpgradeInfo',
|
||||
response: {
|
||||
forceUpgrade: this.config.get('hostSettings.forceUpgrade'),
|
||||
isOwner: this.isOwner,
|
||||
ownerUser
|
||||
}
|
||||
}, '*');
|
||||
}
|
||||
|
||||
if (event && event.data && event.data.subscription) {
|
||||
this.billing.set('subscription', event.data.subscription);
|
||||
this.billing.set('checkoutRoute', event.data?.checkoutRoute || '/plans');
|
||||
|
@ -36,6 +36,7 @@ export default Route.extend(ShortcutsRoute, {
|
||||
settings: service(),
|
||||
ui: service(),
|
||||
whatsNew: service(),
|
||||
billing: service(),
|
||||
|
||||
shortcuts,
|
||||
|
||||
@ -177,6 +178,11 @@ export default Route.extend(ShortcutsRoute, {
|
||||
|
||||
await this.session.postAuthPreparation();
|
||||
}
|
||||
|
||||
if (this.config.get('hostSettings.forceUpgrade')) {
|
||||
// enforce opening the BMA in a force upgrade state
|
||||
this.billing.openBillingWindow(this.router.currentURL, '/pro');
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -5,6 +5,7 @@ import {inject as service} from '@ember/service';
|
||||
export default AuthenticatedRoute.extend({
|
||||
billing: service(),
|
||||
session: service(),
|
||||
config: service(),
|
||||
|
||||
queryParams: {
|
||||
action: {refreshModel: true}
|
||||
@ -13,7 +14,8 @@ export default AuthenticatedRoute.extend({
|
||||
beforeModel(transition) {
|
||||
this._super(...arguments);
|
||||
|
||||
if (!this.session.user.isOwnerOnly) {
|
||||
// allow non-owner users to access the BMA when we're in a force upgrade state
|
||||
if (!this.session.user.isOwnerOnly && !this.config.get('hostSettings.forceUpgrade')) {
|
||||
return this.transitionTo('home');
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,14 @@ export default Service.extend({
|
||||
router: service(),
|
||||
config: service(),
|
||||
ghostPaths: service(),
|
||||
store: service(),
|
||||
|
||||
billingRouteRoot: '#/pro',
|
||||
billingWindowOpen: false,
|
||||
subscription: null,
|
||||
previousRoute: null,
|
||||
action: null,
|
||||
ownerUser: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
@ -52,6 +54,21 @@ export default Service.extend({
|
||||
return url;
|
||||
},
|
||||
|
||||
async getOwnerUser() {
|
||||
if (!this.get('ownerUser')) {
|
||||
// Try to receive the owner user from the store
|
||||
let user = this.store.peekAll('user').findBy('isOwnerOnly', true);
|
||||
|
||||
if (!user) {
|
||||
// load it when it's not there yet
|
||||
await this.store.findAll('user');
|
||||
user = this.store.peekAll('user').findBy('isOwnerOnly', true);
|
||||
}
|
||||
this.set('ownerUser', user);
|
||||
}
|
||||
return this.get('ownerUser');
|
||||
},
|
||||
|
||||
// Sends a route update to a child route in the BMA, because we can't control
|
||||
// navigating to it otherwise
|
||||
sendRouteUpdate() {
|
||||
@ -88,6 +105,9 @@ export default Service.extend({
|
||||
// remembering the route from which the action has been triggered - "previousRoute" so it
|
||||
// could be reused when closing billing window
|
||||
openBillingWindow(currentRoute, childRoute) {
|
||||
// initiate getting owner user in the background
|
||||
this.getOwnerUser();
|
||||
|
||||
if (this.get('billingWindowOpen')) {
|
||||
// don't attempt to open again
|
||||
return;
|
||||
|
@ -1,12 +1,22 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
Route.reopen({
|
||||
config: service(),
|
||||
billing: service(),
|
||||
router: service(),
|
||||
|
||||
actions: {
|
||||
willTransition(transition) {
|
||||
if (this.get('upgradeStatus.isRequired')) {
|
||||
transition.abort();
|
||||
this.upgradeStatus.requireUpgrade();
|
||||
return false;
|
||||
} else if (this.config.get('hostSettings.forceUpgrade')) {
|
||||
transition.abort();
|
||||
// Catch and redirect every route in a force upgrade state
|
||||
this.billing.openBillingWindow(this.router.currentURL, '/pro');
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user