2021-07-19 13:46:38 +03:00
const errors = require ( '@tryghost/errors' ) ;
const tpl = require ( '@tryghost/tpl' ) ;
2021-05-12 15:02:27 +03:00
const MembersSSR = require ( '@tryghost/members-ssr' ) ;
const db = require ( '../../data/db' ) ;
const MembersConfigProvider = require ( './config' ) ;
const MembersCSVImporter = require ( './importer' ) ;
const MembersStats = require ( './stats' ) ;
const createMembersApiInstance = require ( './api' ) ;
const createMembersSettingsInstance = require ( './settings' ) ;
2021-06-15 17:36:27 +03:00
const logging = require ( '@tryghost/logging' ) ;
2021-05-12 15:02:27 +03:00
const urlUtils = require ( '../../../shared/url-utils' ) ;
2021-06-30 16:56:57 +03:00
const settingsCache = require ( '../../../shared/settings-cache' ) ;
2021-05-12 15:02:27 +03:00
const config = require ( '../../../shared/config' ) ;
2021-06-16 11:36:58 +03:00
const ghostVersion = require ( '@tryghost/version' ) ;
2021-05-12 15:02:27 +03:00
const _ = require ( 'lodash' ) ;
2021-07-20 17:42:26 +03:00
const { GhostMailer } = require ( '../mail' ) ;
2021-05-12 15:02:27 +03:00
2021-07-19 13:46:38 +03:00
const messages = {
noLiveKeysInDevelopment : 'Cannot use live stripe keys in development. Please restart in production mode.' ,
sslRequiredForStripe : 'Cannot run Ghost without SSL when Stripe is connected. Please update your url config to use "https://".' ,
remoteWebhooksInDevelopment : 'Cannot use remote webhooks in development. See https://ghost.org/docs/webhooks/#stripe-webhooks for developing with Stripe.'
} ;
2021-07-07 17:49:45 +03:00
// Bind to settings.edited to update systems based on settings changes, similar to the bridge and models/base/listeners
const events = require ( '../../lib/common/events' ) ;
2021-07-20 17:42:26 +03:00
const ghostMailer = new GhostMailer ( ) ;
2021-05-12 15:02:27 +03:00
const membersConfig = new MembersConfigProvider ( {
config ,
settingsCache ,
urlUtils ,
logging ,
ghostVersion
} ) ;
let membersApi ;
let membersSettings ;
function reconfigureMembersAPI ( ) {
const reconfiguredMembersAPI = createMembersApiInstance ( membersConfig ) ;
reconfiguredMembersAPI . bus . on ( 'ready' , function ( ) {
membersApi = reconfiguredMembersAPI ;
} ) ;
reconfiguredMembersAPI . bus . on ( 'error' , function ( err ) {
logging . error ( err ) ;
} ) ;
}
const debouncedReconfigureMembersAPI = _ . debounce ( reconfigureMembersAPI , 600 ) ;
// Bind to events to automatically keep subscription info up-to-date from settings
events . on ( 'settings.edited' , function updateSettingFromModel ( settingModel ) {
if ( ! [
'members_signup_access' ,
'members_from_address' ,
'members_support_address' ,
'members_reply_address' ,
'stripe_publishable_key' ,
'stripe_secret_key' ,
'stripe_product_name' ,
'stripe_plans' ,
'stripe_connect_publishable_key' ,
'stripe_connect_secret_key' ,
'stripe_connect_livemode' ,
'stripe_connect_display_name' ,
'stripe_connect_account_id'
] . includes ( settingModel . get ( 'key' ) ) ) {
return ;
}
debouncedReconfigureMembersAPI ( ) ;
} ) ;
const membersService = {
2021-05-12 15:46:05 +03:00
async init ( ) {
const env = config . get ( 'env' ) ;
const paymentConfig = membersConfig . getStripePaymentConfig ( ) ;
if ( env !== 'production' ) {
if ( ! process . env . WEBHOOK _SECRET && membersConfig . isStripeConnected ( ) ) {
2021-07-12 12:48:52 +03:00
process . env . WEBHOOK _SECRET = 'DEFAULT_WEBHOOK_SECRET' ;
2021-07-19 13:46:38 +03:00
logging . warn ( tpl ( messages . remoteWebhooksInDevelopment ) ) ;
2021-05-12 15:46:05 +03:00
}
if ( paymentConfig && paymentConfig . secretKey . startsWith ( 'sk_live' ) ) {
2021-07-19 13:46:38 +03:00
throw new errors . IncorrectUsageError ( tpl ( messages . noLiveKeysInDevelopment ) ) ;
2021-05-12 15:46:05 +03:00
}
} else {
const siteUrl = urlUtils . getSiteUrl ( ) ;
2021-05-27 20:33:03 +03:00
if ( ! /^https/ . test ( siteUrl ) && membersConfig . isStripeConnected ( ) ) {
2021-07-19 13:46:38 +03:00
throw new errors . IncorrectUsageError ( tpl ( messages . sslRequiredForStripe ) ) ;
2021-05-12 15:46:05 +03:00
}
}
} ,
2021-05-12 15:02:27 +03:00
contentGating : require ( './content-gating' ) ,
config : membersConfig ,
get api ( ) {
if ( ! membersApi ) {
membersApi = createMembersApiInstance ( membersConfig ) ;
membersApi . bus . on ( 'error' , function ( err ) {
logging . error ( err ) ;
} ) ;
}
return membersApi ;
} ,
get settings ( ) {
if ( ! membersSettings ) {
membersSettings = createMembersSettingsInstance ( membersConfig ) ;
}
return membersSettings ;
} ,
ssr : MembersSSR ( {
cookieSecure : urlUtils . isSSL ( urlUtils . getSiteUrl ( ) ) ,
cookieKeys : [ settingsCache . get ( 'theme_session_secret' ) ] ,
cookieName : 'ghost-members-ssr' ,
cookieCacheName : 'ghost-members-ssr-cache' ,
getMembersApi : ( ) => membersService . api
} ) ,
stripeConnect : require ( './stripe-connect' ) ,
2021-07-20 17:42:26 +03:00
importer : new MembersCSVImporter ( {
storagePath : config . getContentPath ( 'data' ) } ,
settingsCache , ( ) => membersApi ,
ghostMailer
) ,
2021-05-12 15:02:27 +03:00
stats : new MembersStats ( {
db : db ,
settingsCache : settingsCache ,
isSQLite : config . get ( 'database:client' ) === 'sqlite3'
} )
} ;
module . exports = membersService ;
module . exports . middleware = require ( './middleware' ) ;