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(),
|
ajax: service(),
|
||||||
notifications: service(),
|
notifications: service(),
|
||||||
|
|
||||||
|
isOwner: null,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
@ -27,13 +29,21 @@ export default Component.extend({
|
|||||||
request: 'token',
|
request: 'token',
|
||||||
response: token
|
response: token
|
||||||
}, '*');
|
}, '*');
|
||||||
|
|
||||||
|
this.set('isOwner', true);
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.payload?.errors && error.payload.errors[0]?.type === 'NoPermissionError') {
|
if (error.payload?.errors && error.payload.errors[0]?.type === 'NoPermissionError') {
|
||||||
// noop - user doesn't have permission to access billing
|
// no permission means the current user requesting the token is not the owner of the site.
|
||||||
return;
|
this.set('isOwner', false);
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
// 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
|
// 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) {
|
if (event && event.data && event.data.subscription) {
|
||||||
this.billing.set('subscription', event.data.subscription);
|
this.billing.set('subscription', event.data.subscription);
|
||||||
this.billing.set('checkoutRoute', event.data?.checkoutRoute || '/plans');
|
this.billing.set('checkoutRoute', event.data?.checkoutRoute || '/plans');
|
||||||
|
@ -36,6 +36,7 @@ export default Route.extend(ShortcutsRoute, {
|
|||||||
settings: service(),
|
settings: service(),
|
||||||
ui: service(),
|
ui: service(),
|
||||||
whatsNew: service(),
|
whatsNew: service(),
|
||||||
|
billing: service(),
|
||||||
|
|
||||||
shortcuts,
|
shortcuts,
|
||||||
|
|
||||||
@ -177,6 +178,11 @@ export default Route.extend(ShortcutsRoute, {
|
|||||||
|
|
||||||
await this.session.postAuthPreparation();
|
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({
|
export default AuthenticatedRoute.extend({
|
||||||
billing: service(),
|
billing: service(),
|
||||||
session: service(),
|
session: service(),
|
||||||
|
config: service(),
|
||||||
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
action: {refreshModel: true}
|
action: {refreshModel: true}
|
||||||
@ -13,7 +14,8 @@ export default AuthenticatedRoute.extend({
|
|||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
this._super(...arguments);
|
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');
|
return this.transitionTo('home');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ export default Service.extend({
|
|||||||
router: service(),
|
router: service(),
|
||||||
config: service(),
|
config: service(),
|
||||||
ghostPaths: service(),
|
ghostPaths: service(),
|
||||||
|
store: service(),
|
||||||
|
|
||||||
billingRouteRoot: '#/pro',
|
billingRouteRoot: '#/pro',
|
||||||
billingWindowOpen: false,
|
billingWindowOpen: false,
|
||||||
subscription: null,
|
subscription: null,
|
||||||
previousRoute: null,
|
previousRoute: null,
|
||||||
action: null,
|
action: null,
|
||||||
|
ownerUser: null,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
@ -52,6 +54,21 @@ export default Service.extend({
|
|||||||
return url;
|
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
|
// Sends a route update to a child route in the BMA, because we can't control
|
||||||
// navigating to it otherwise
|
// navigating to it otherwise
|
||||||
sendRouteUpdate() {
|
sendRouteUpdate() {
|
||||||
@ -88,6 +105,9 @@ export default Service.extend({
|
|||||||
// remembering the route from which the action has been triggered - "previousRoute" so it
|
// remembering the route from which the action has been triggered - "previousRoute" so it
|
||||||
// could be reused when closing billing window
|
// could be reused when closing billing window
|
||||||
openBillingWindow(currentRoute, childRoute) {
|
openBillingWindow(currentRoute, childRoute) {
|
||||||
|
// initiate getting owner user in the background
|
||||||
|
this.getOwnerUser();
|
||||||
|
|
||||||
if (this.get('billingWindowOpen')) {
|
if (this.get('billingWindowOpen')) {
|
||||||
// don't attempt to open again
|
// don't attempt to open again
|
||||||
return;
|
return;
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
import Route from '@ember/routing/route';
|
import Route from '@ember/routing/route';
|
||||||
|
import {inject as service} from '@ember/service';
|
||||||
|
|
||||||
Route.reopen({
|
Route.reopen({
|
||||||
|
config: service(),
|
||||||
|
billing: service(),
|
||||||
|
router: service(),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
willTransition(transition) {
|
willTransition(transition) {
|
||||||
if (this.get('upgradeStatus.isRequired')) {
|
if (this.get('upgradeStatus.isRequired')) {
|
||||||
transition.abort();
|
transition.abort();
|
||||||
this.upgradeStatus.requireUpgrade();
|
this.upgradeStatus.requireUpgrade();
|
||||||
return false;
|
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 {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user