2022-11-03 16:58:06 +03:00
import Component from '@glimmer/component' ;
import { action } from '@ember/object' ;
2021-09-30 15:54:54 +03:00
import { htmlSafe } from '@ember/template' ;
2022-11-03 14:14:36 +03:00
import { inject } from 'ghost-admin/decorators/inject' ;
2020-03-02 08:06:54 +03:00
import { inject as service } from '@ember/service' ;
2022-11-03 16:58:06 +03:00
import { tracked } from '@glimmer/tracking' ;
2020-03-02 08:06:54 +03:00
2022-02-01 12:34:03 +03:00
export default class GhBillingIframe extends Component {
2022-12-06 18:20:57 +03:00
@ service ajax ;
2022-02-01 20:03:45 +03:00
@ service billing ;
@ service ghostPaths ;
@ service notifications ;
2022-12-06 18:20:57 +03:00
@ service session ;
2022-02-01 12:34:03 +03:00
2022-11-03 14:14:36 +03:00
@ inject config ;
2022-11-03 16:58:06 +03:00
@ tracked isOwner = null ;
2021-10-22 13:29:55 +03:00
2022-11-03 16:58:06 +03:00
willDestroy ( ) {
super . willDestroy ( ... arguments ) ;
window . removeEventListener ( 'message' , this . handleIframeMessage ) ;
}
2021-07-15 17:27:29 +03:00
2022-11-03 16:58:06 +03:00
@ action
setup ( ) {
2020-05-22 05:44:37 +03:00
this . billing . getBillingIframe ( ) . src = this . billing . getIframeURL ( ) ;
2022-11-03 16:58:06 +03:00
window . addEventListener ( 'message' , this . handleIframeMessage ) ;
}
@ action
async handleIframeMessage ( event ) {
if ( this . isDestroyed || this . isDestroying ) {
return ;
}
2020-05-22 05:44:37 +03:00
2022-11-03 16:58:06 +03:00
// only process messages coming from the billing iframe
if ( event ? . data && this . billing . getIframeURL ( ) . includes ( event ? . origin ) ) {
if ( event . data ? . request === 'token' ) {
this . _handleTokenRequest ( ) ;
}
2020-05-22 05:44:37 +03:00
2022-11-03 16:58:06 +03:00
if ( event . data ? . request === 'forceUpgradeInfo' ) {
this . _handleForceUpgradeRequest ( ) ;
}
2021-10-22 13:29:55 +03:00
2022-11-03 16:58:06 +03:00
if ( event . data ? . subscription ) {
this . _handleSubscriptionUpdate ( event . data ) ;
2021-10-26 15:06:15 +03:00
}
2022-11-03 16:58:06 +03:00
}
2022-02-01 12:34:03 +03:00
}
2021-10-26 15:06:15 +03:00
_handleTokenRequest ( ) {
2022-12-06 18:20:57 +03:00
const handleNoPermission = ( ) => {
// no permission means the current user requesting the token is not the owner of the site.
this . 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
} , '*' ) ;
} ;
2021-10-26 15:06:15 +03:00
2022-12-06 18:20:57 +03:00
if ( ! this . session . user ? . isOwnerOnly ) {
handleNoPermission ( ) ;
return ;
}
const ghostIdentityUrl = this . ghostPaths . url . api ( 'identities' ) ;
2021-10-26 15:06:15 +03:00
this . ajax . request ( ghostIdentityUrl ) . then ( ( response ) => {
2022-12-06 18:20:57 +03:00
const token = response ? . identities ? . [ 0 ] ? . token ;
2021-10-26 15:06:15 +03:00
this . billing . getBillingIframe ( ) . contentWindow . postMessage ( {
request : 'token' ,
response : token
} , '*' ) ;
2022-11-03 16:58:06 +03:00
this . isOwner = true ;
2021-10-26 15:06:15 +03:00
} ) . catch ( ( error ) => {
2022-12-06 18:20:57 +03:00
if ( error . payload ? . errors ? . [ 0 ] ? . type === 'NoPermissionError' ) {
handleNoPermission ( ) ;
2021-10-26 15:06:15 +03:00
} else {
throw error ;
2021-10-22 13:29:55 +03:00
}
2021-10-26 15:06:15 +03:00
} ) ;
2022-02-01 12:34:03 +03:00
}
2021-09-30 15:54:54 +03:00
2021-10-26 15:06:15 +03:00
_handleForceUpgradeRequest ( ) {
// 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 : {
2022-10-07 17:24:03 +03:00
forceUpgrade : this . config . hostSettings ? . forceUpgrade ,
2021-10-26 15:06:15 +03:00
isOwner : this . isOwner ,
ownerUser
2020-03-02 08:06:54 +03:00
}
2021-10-26 15:06:15 +03:00
} , '*' ) ;
2022-02-01 12:34:03 +03:00
}
2021-10-26 15:06:15 +03:00
_handleSubscriptionUpdate ( data ) {
2022-11-03 16:58:06 +03:00
this . billing . subscription = data . subscription ;
this . billing . checkoutRoute = data ? . checkoutRoute ? ? '/plans' ;
2021-10-26 15:06:15 +03:00
2022-10-07 17:24:03 +03:00
if ( data . subscription . status === 'active' && this . config . hostSettings ? . forceUpgrade ) {
2021-10-26 15:43:09 +03:00
// config might not be updated after a subscription has been set to active.
// Until then assume the forceUpgrade is over and the subscription
// was activated successfully.
2022-10-07 17:24:03 +03:00
this . config . hostSettings . forceUpgrade = false ;
2021-10-26 15:43:09 +03:00
}
2021-10-26 15:06:15 +03:00
// Detect if the current subscription is in a grace state and render a notification
if ( data . subscription . status === 'past_due' || data . subscription . status === 'unpaid' ) {
// This notification needs to be shown to every user regardless their permissions to see billing
this . notifications . showAlert ( 'Billing error: This site is queued for suspension. The owner of this site must update payment information.' , { type : 'error' , key : 'billing.overdue' } ) ;
} else {
this . notifications . closeAlerts ( 'billing.overdue' ) ;
}
// Detect if the current member limits are exceeded and render a notification
if (
data ? . exceededLimits
&& data ? . exceededLimits . length
&& data ? . exceededLimits . indexOf ( 'members' ) >= 0
&& data ? . checkoutRoute
) {
// The action param will be picked up on a transition from the router and can
// then send the destination route as a message to the BMA, which then handles the redirect.
2022-11-03 16:58:06 +03:00
const checkoutAction = this . billing . billingRouteRoot + '?action=checkout' ;
2021-10-26 15:06:15 +03:00
this . notifications . showAlert ( htmlSafe ( ` Your audience has grown! To continue publishing, the site owner must confirm pricing for this number of members <a href=" ${ checkoutAction } ">here</a> ` ) , { type : 'warn' , key : 'billing.exceeded' } ) ;
} else {
this . notifications . closeAlerts ( 'billing.exceeded' ) ;
}
2020-03-02 08:06:54 +03:00
}
2022-02-01 12:34:03 +03:00
}