2022-01-27 14:06:29 +00:00
const _ = require ( 'lodash' ) ;
2021-07-19 11:46:38 +01:00
const errors = require ( '@tryghost/errors' ) ;
const tpl = require ( '@tryghost/tpl' ) ;
2021-05-12 13:02:27 +01:00
const MembersSSR = require ( '@tryghost/members-ssr' ) ;
const db = require ( '../../data/db' ) ;
const MembersConfigProvider = require ( './config' ) ;
2021-07-21 19:34:11 +04:00
const MembersCSVImporter = require ( '@tryghost/members-importer' ) ;
2021-08-18 11:48:07 +04:00
const MembersStats = require ( './stats/members-stats' ) ;
2021-05-12 13:02:27 +01:00
const createMembersSettingsInstance = require ( './settings' ) ;
2021-06-15 15:36:27 +01:00
const logging = require ( '@tryghost/logging' ) ;
2021-05-12 13:02:27 +01:00
const urlUtils = require ( '../../../shared/url-utils' ) ;
2021-07-20 18:42:57 +04:00
const labsService = require ( '../../../shared/labs' ) ;
2021-06-30 14:56:57 +01:00
const settingsCache = require ( '../../../shared/settings-cache' ) ;
2021-05-12 13:02:27 +01:00
const config = require ( '../../../shared/config' ) ;
2021-07-27 13:27:59 +04:00
const models = require ( '../../models' ) ;
2021-07-20 18:42:26 +04:00
const { GhostMailer } = require ( '../mail' ) ;
2021-07-20 19:21:59 +04:00
const jobsService = require ( '../jobs' ) ;
2022-01-27 14:06:29 +00:00
const VerificationTrigger = require ( '@tryghost/verification-trigger' ) ;
2022-02-24 10:33:24 +01:00
const DomainEvents = require ( '@tryghost/domain-events' ) ;
const { LastSeenAtUpdater } = require ( '@tryghost/members-events-service' ) ;
2022-03-28 16:12:32 +01:00
const DatabaseInfo = require ( '@tryghost/database-info' ) ;
2021-05-12 13:02:27 +01:00
2021-07-19 11:46:38 +01: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://".' ,
2022-02-03 16:20:37 +00:00
remoteWebhooksInDevelopment : 'Cannot use remote webhooks in development. See https://ghost.org/docs/webhooks/#stripe-webhooks for developing with Stripe.'
2021-07-19 11:46:38 +01:00
} ;
2021-07-20 18:42:26 +04:00
const ghostMailer = new GhostMailer ( ) ;
2021-05-12 13:02:27 +01:00
const membersConfig = new MembersConfigProvider ( {
config ,
settingsCache ,
2021-12-14 15:18:46 +00:00
urlUtils
2021-05-12 13:02:27 +01:00
} ) ;
2022-01-27 14:06:29 +00:00
const membersStats = new MembersStats ( {
db : db ,
settingsCache : settingsCache ,
2022-03-28 16:12:32 +01:00
isSQLite : DatabaseInfo . isSQLite ( db . knex )
2022-01-27 14:06:29 +00:00
} ) ;
2021-05-12 13:02:27 +01:00
let membersApi ;
let membersSettings ;
2022-01-27 14:06:29 +00:00
let verificationTrigger ;
2021-07-23 20:37:29 +04:00
2021-07-23 16:58:35 +04:00
const membersImporter = new MembersCSVImporter ( {
storagePath : config . getContentPath ( 'data' ) ,
getTimezone : ( ) => settingsCache . get ( 'timezone' ) ,
2022-01-18 17:56:47 +02:00
getMembersApi : ( ) => module . exports . api ,
2021-07-23 16:58:35 +04:00
sendEmail : ghostMailer . send . bind ( ghostMailer ) ,
isSet : labsService . isSet . bind ( labsService ) ,
addJob : jobsService . addJob . bind ( jobsService ) ,
knex : db . knex ,
2022-04-06 15:20:50 -04:00
urlFor : urlUtils . urlFor . bind ( urlUtils ) ,
context : {
importer : true
}
2021-07-23 16:58:35 +04:00
} ) ;
2021-07-28 16:36:20 +04:00
const processImport = async ( options ) => {
const result = await membersImporter . process ( options ) ;
2022-04-14 16:04:26 +01:00
// Check whether all imports in last 30 days > threshold
await verificationTrigger . testImportThreshold ( ) ;
2021-07-23 20:37:29 +04:00
return result ;
2021-07-23 16:58:35 +04:00
} ;
2021-05-12 13:02:27 +01:00
2022-01-18 17:56:47 +02:00
module . exports = {
2021-05-12 13:46:05 +01:00
async init ( ) {
2022-01-18 17:56:47 +02:00
const stripeService = require ( '../stripe' ) ;
const createMembersApiInstance = require ( './api' ) ;
2021-05-12 13:46:05 +01:00
const env = config . get ( 'env' ) ;
2022-01-18 17:56:47 +02:00
// @TODO Move to stripe service
2021-05-12 13:46:05 +01:00
if ( env !== 'production' ) {
2021-10-04 13:18:22 +02:00
if ( stripeService . api . configured && stripeService . api . mode === 'live' ) {
2021-12-01 11:22:14 +00:00
throw new errors . IncorrectUsageError ( {
message : tpl ( messages . noLiveKeysInDevelopment )
} ) ;
2021-05-12 13:46:05 +01:00
}
} else {
const siteUrl = urlUtils . getSiteUrl ( ) ;
2021-10-04 13:18:22 +02:00
if ( ! /^https/ . test ( siteUrl ) && stripeService . api . configured ) {
2021-12-01 11:22:14 +00:00
throw new errors . IncorrectUsageError ( {
message : tpl ( messages . sslRequiredForStripe )
} ) ;
2021-05-12 13:46:05 +01:00
}
}
2021-05-12 13:02:27 +01:00
if ( ! membersApi ) {
membersApi = createMembersApiInstance ( membersConfig ) ;
membersApi . bus . on ( 'error' , function ( err ) {
logging . error ( err ) ;
} ) ;
}
2022-01-04 10:21:36 +01:00
2022-02-20 16:02:42 +02:00
module . exports . ssr = MembersSSR ( {
cookieSecure : urlUtils . isSSL ( urlUtils . getSiteUrl ( ) ) ,
cookieKeys : [ settingsCache . get ( 'theme_session_secret' ) ] ,
cookieName : 'ghost-members-ssr' ,
getMembersApi : ( ) => module . exports . api
} ) ;
2022-01-27 14:06:29 +00:00
verificationTrigger = new VerificationTrigger ( {
configThreshold : _ . get ( config . get ( 'hostSettings' ) , 'emailVerification.importThreshold' ) ,
isVerified : ( ) => config . get ( 'hostSettings:emailVerification:verified' ) === true ,
isVerificationRequired : ( ) => settingsCache . get ( 'email_verification_required' ) === true ,
sendVerificationEmail : ( { subject , message , amountImported } ) => {
const escalationAddress = config . get ( 'hostSettings:emailVerification:escalationAddress' ) ;
const fromAddress = config . get ( 'user_email' ) ;
2022-02-24 10:33:24 +01:00
2022-01-27 14:06:29 +00:00
if ( escalationAddress ) {
2022-02-01 12:00:01 +00:00
ghostMailer . send ( {
2022-01-27 14:06:29 +00:00
subject ,
html : tpl ( message , {
2022-02-01 15:13:28 +00:00
importedNumber : amountImported ,
2022-02-01 13:54:13 +00:00
siteUrl : urlUtils . getSiteUrl ( )
2022-01-27 14:06:29 +00:00
} ) ,
forceTextContent : true ,
from : fromAddress ,
to : escalationAddress
} ) ;
}
} ,
membersStats ,
Settings : models . Settings ,
eventRepository : membersApi . events
} ) ;
2022-02-24 10:33:24 +01:00
new LastSeenAtUpdater ( {
services : {
domainEvents : DomainEvents ,
settingsCache
2022-05-04 12:42:27 +02:00
} ,
async getMembersApi ( ) {
return membersApi ;
2022-02-24 10:33:24 +01:00
}
} ) ;
2022-01-04 10:21:36 +01:00
( async ( ) => {
try {
const collection = await models . SingleUseToken . fetchAll ( ) ;
await collection . invokeThen ( 'destroy' ) ;
} catch ( err ) {
logging . error ( err ) ;
}
} ) ( ) ;
2022-01-18 17:56:47 +02:00
2022-01-24 16:38:16 +02:00
try {
await stripeService . migrations . execute ( ) ;
} catch ( err ) {
logging . error ( err ) ;
}
2021-10-04 13:18:22 +02:00
} ,
contentGating : require ( './content-gating' ) ,
config : membersConfig ,
get api ( ) {
2021-05-12 13:02:27 +01:00
return membersApi ;
} ,
get settings ( ) {
if ( ! membersSettings ) {
membersSettings = createMembersSettingsInstance ( membersConfig ) ;
}
return membersSettings ;
} ,
2022-02-20 16:02:42 +02:00
ssr : null ,
2021-05-12 13:02:27 +01:00
stripeConnect : require ( './stripe-connect' ) ,
2021-07-23 16:58:35 +04:00
processImport : processImport ,
2021-05-12 13:02:27 +01:00
2022-05-20 21:25:23 +01:00
stats : membersStats ,
export : require ( './exporter/query' )
2022-01-18 17:56:47 +02:00
} ;
2021-05-12 13:02:27 +01:00
module . exports . middleware = require ( './middleware' ) ;