UNPKG

@xrengine/server-core

Version:

Shared components for XREngine server

618 lines (594 loc) 16.7 kB
import dotenv from 'dotenv' import { DataTypes, Sequelize } from 'sequelize' import appConfig from './appconfig' import logger from './ServerLogger' dotenv.config() const db = { username: process.env.MYSQL_USER ?? 'server', password: process.env.MYSQL_PASSWORD ?? 'password', database: process.env.MYSQL_DATABASE ?? 'xrengine', host: process.env.MYSQL_HOST ?? '127.0.0.1', port: process.env.MYSQL_PORT ?? 3306, dialect: 'mysql', url: '' } const nonFeathersStrategies = ['emailMagicLink', 'smsMagicLink'] db.url = process.env.MYSQL_URL ?? `mysql://${db.username}:${db.password}@${db.host}:${db.port}/${db.database}` export const updateAppConfig = async (): Promise<void> => { if (appConfig.db.forceRefresh || !appConfig.kubernetes.enabled) return const sequelizeClient = new Sequelize({ ...(db as any), define: { freezeTableName: true }, logging: false }) as any await sequelizeClient.sync() const promises: any[] = [] const taskServerSetting = sequelizeClient.define('taskServerSetting', { port: { type: DataTypes.STRING, allowNull: true }, processInterval: { type: DataTypes.STRING, allowNull: true } }) const taskServerSettingPromise = taskServerSetting .findAll() .then(([dbTaskServer]) => { const dbTaskServerConfig = dbTaskServer && { port: dbTaskServer.port, processInterval: dbTaskServer.processInterval } if (dbTaskServerConfig) { appConfig.taskserver = { ...appConfig.taskserver, ...dbTaskServerConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read taskServerSetting: ${e.message}`) }) promises.push(taskServerSettingPromise) const authenticationSetting = sequelizeClient.define('authentication', { service: { type: DataTypes.STRING, allowNull: true }, entity: { type: DataTypes.STRING, allowNull: true }, secret: { type: DataTypes.STRING, allowNull: true }, authStrategies: { type: DataTypes.JSON, allowNull: true }, local: { type: DataTypes.JSON, allowNull: true }, jwtOptions: { type: DataTypes.JSON, allowNull: true }, bearerToken: { type: DataTypes.JSON, allowNull: true }, callback: { type: DataTypes.JSON, allowNull: true }, oauth: { type: DataTypes.JSON, allowNull: true } }) const authenticationSettingPromise = authenticationSetting .findAll() .then(([dbAuthentication]) => { let oauth = JSON.parse(dbAuthentication.oauth) let authStrategies = JSON.parse(dbAuthentication.authStrategies) let local = JSON.parse(dbAuthentication.local) let jwtOptions = JSON.parse(dbAuthentication.jwtOptions) let bearerToken = JSON.parse(dbAuthentication.bearerToken) let callback = JSON.parse(dbAuthentication.callback) if (typeof oauth === 'string') oauth = JSON.parse(oauth) if (typeof authStrategies === 'string') authStrategies = JSON.parse(authStrategies) if (typeof local === 'string') local = JSON.parse(local) if (typeof jwtOptions === 'string') jwtOptions = JSON.parse(jwtOptions) if (typeof bearerToken === 'string') bearerToken = JSON.parse(bearerToken) if (typeof callback === 'string') callback = JSON.parse(callback) const dbAuthenticationConfig = dbAuthentication && { service: dbAuthentication.service, entity: dbAuthentication.entity, secret: dbAuthentication.secret, authStrategies: authStrategies, local: local, jwtOptions: jwtOptions, bearerToken: bearerToken, callback: callback, oauth: { ...oauth } } if (dbAuthenticationConfig) { if (oauth.defaults) dbAuthenticationConfig.oauth.defaults = JSON.parse(oauth.defaults) if (oauth.discord) dbAuthenticationConfig.oauth.discord = JSON.parse(oauth.discord) if (oauth.facebook) dbAuthenticationConfig.oauth.facebook = JSON.parse(oauth.facebook) if (oauth.github) dbAuthenticationConfig.oauth.github = JSON.parse(oauth.github) if (oauth.google) dbAuthenticationConfig.oauth.google = JSON.parse(oauth.google) if (oauth.linkedin) dbAuthenticationConfig.oauth.linkedin = JSON.parse(oauth.linkedin) if (oauth.twitter) dbAuthenticationConfig.oauth.twitter = JSON.parse(oauth.twitter) const authStrategies = ['jwt', 'local'] for (let authStrategy of dbAuthenticationConfig.authStrategies) { const keys = Object.keys(authStrategy) for (let key of keys) if (nonFeathersStrategies.indexOf(key) < 0 && authStrategies.indexOf(key) < 0) authStrategies.push(key) } dbAuthenticationConfig.authStrategies = authStrategies appConfig.authentication = { ...appConfig.authentication, ...dbAuthenticationConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read authenticationSetting: ${e.message}`) }) promises.push(authenticationSettingPromise) const awsSetting = sequelizeClient.define('Aws', { keys: { type: DataTypes.JSON, allowNull: true }, route53: { type: DataTypes.JSON, allowNull: true }, s3: { type: DataTypes.JSON, allowNull: true }, cloudfront: { type: DataTypes.JSON, allowNull: true }, sms: { type: DataTypes.JSON, allowNull: true } }) const promisePromise = awsSetting .findAll() .then(([dbAws]) => { let keys = JSON.parse(dbAws.keys) let route53 = JSON.parse(dbAws.route53) let s3 = JSON.parse(dbAws.s3) let cloudfront = JSON.parse(dbAws.cloudfront) let sms = JSON.parse(dbAws.sms) if (typeof keys === 'string') keys = JSON.parse(keys) if (typeof route53 === 'string') route53 = JSON.parse(route53) if (typeof s3 === 'string') s3 = JSON.parse(s3) if (typeof cloudfront === 'string') cloudfront = JSON.parse(cloudfront) if (typeof sms === 'string') sms = JSON.parse(sms) const dbAwsConfig = dbAws && { keys: keys, route53: { ...route53, keys: JSON.parse(route53.keys) }, s3: s3, cloudfront: cloudfront, sms: sms } if (dbAwsConfig) { appConfig.aws = { ...appConfig.aws, ...dbAwsConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read awsSetting: ${e.message}`) }) promises.push(promisePromise) const chargebeeSetting = sequelizeClient.define('chargebeeSetting', { url: { type: DataTypes.STRING, allowNull: true }, apiKey: { type: DataTypes.STRING, allowNull: true } }) const chargebeeSettingPromise = chargebeeSetting .findAll() .then(([dbChargebee]) => { const dbChargebeeConfig = dbChargebee && { url: dbChargebee.url, apiKey: dbChargebee.apiKey } if (dbChargebeeConfig) { appConfig.chargebee = { ...appConfig.chargebee, ...dbChargebeeConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read chargebeeSetting: ${e.message}`) }) promises.push(chargebeeSettingPromise) const coilSetting = sequelizeClient.define('coilSetting', { paymentPointer: { type: DataTypes.STRING, allowNull: true }, clientId: { type: DataTypes.STRING, allowNull: true }, clientSecret: { type: DataTypes.STRING, allowNull: true } }) const coilSettingPromise = coilSetting .findAll() .then(([dbCoil]) => { const dbCoilConfig = dbCoil && { url: dbCoil.url, apiKey: dbCoil.apiKey } if (dbCoilConfig) { appConfig.coil = { ...appConfig.coil, ...dbCoilConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read coilSetting: ${e.message}`) }) promises.push(coilSettingPromise) const clientSetting = sequelizeClient.define('clientSetting', { logo: { type: DataTypes.STRING, allowNull: true }, title: { type: DataTypes.STRING, allowNull: true }, url: { type: DataTypes.STRING, allowNull: true }, releaseName: { type: DataTypes.STRING, allowNull: true }, siteDescription: { type: DataTypes.STRING, allowNull: true }, favicon32px: { type: DataTypes.STRING, allowNull: true }, favicon16px: { type: DataTypes.STRING, allowNull: true }, icon192px: { type: DataTypes.STRING, allowNull: true }, icon512px: { type: DataTypes.STRING, allowNull: true } }) const clientSettingPromise = clientSetting .findAll() .then(([dbClient]) => { const dbClientConfig = dbClient && { logo: dbClient.logo, title: dbClient.title, url: dbClient.url, releaseName: dbClient.releaseName, siteDescription: dbClient.siteDescription, favicon32px: dbClient.favicon32px, favicon16px: dbClient.favicon16px, icon192px: dbClient.icon192px, icon512px: dbClient.icon512px } if (dbClientConfig) { appConfig.client = { ...appConfig.client, ...dbClientConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read clientSetting: ${e.message}`) }) promises.push(clientSettingPromise) const emailSetting = sequelizeClient.define('emailSetting', { smtp: { type: DataTypes.JSON, allowNull: true }, from: { type: DataTypes.STRING, allowNull: true }, subject: { type: DataTypes.JSON, allowNull: true }, smsNameCharacterLimit: { type: DataTypes.INTEGER } }) const emailSettingPromise = emailSetting .findAll() .then(([dbEmail]) => { let smtp = JSON.parse(dbEmail.smtp) let subject = JSON.parse(dbEmail.subject) if (typeof smtp === 'string') smtp = JSON.parse(smtp) if (typeof subject === 'string') subject = JSON.parse(subject) const dbEmailConfig = dbEmail && { from: dbEmail.from, smsNameCharacterLimit: dbEmail.smsNameCharacterLimit, smtp: { ...smtp, auth: JSON.parse(smtp.auth) }, subject: subject } if (dbEmailConfig) { appConfig.email = { ...appConfig.email, ...dbEmailConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read emailSetting: ${e.message}`) }) promises.push(emailSettingPromise) const instanceServerSetting = sequelizeClient.define('instanceServerSetting', { clientHost: { type: DataTypes.STRING, allowNull: true }, rtc_start_port: { type: DataTypes.INTEGER, allowNull: true }, rtc_end_port: { type: DataTypes.INTEGER, allowNull: true }, rtc_port_block_size: { type: DataTypes.INTEGER, allowNull: true }, identifierDigits: { type: DataTypes.INTEGER, allowNull: true }, local: { type: DataTypes.BOOLEAN, allowNull: true }, domain: { type: DataTypes.STRING, allowNull: true }, releaseName: { type: DataTypes.STRING, allowNull: true }, port: { type: DataTypes.STRING, allowNull: true }, mode: { type: DataTypes.STRING, allowNull: true }, locationName: { type: DataTypes.STRING } }) const instanceServerSettingPromise = instanceServerSetting .findAll() .then(([dbInstanceServer]) => { const dbInstanceServerConfig = dbInstanceServer && { clientHost: dbInstanceServer.clientHost, rtc_start_port: dbInstanceServer.rtc_start_port, rtc_end_port: dbInstanceServer.rtc_end_port, rtc_port_block_size: dbInstanceServer.rtc_port_block_size, identifierDigits: dbInstanceServer.identifierDigits, local: dbInstanceServer.local, domain: dbInstanceServer.domain, releaseName: dbInstanceServer.releaseName, port: dbInstanceServer.port, mode: dbInstanceServer.mode, locationName: dbInstanceServer.locationName } if (dbInstanceServerConfig) { appConfig.instanceserver = { ...appConfig.instanceserver, ...dbInstanceServerConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read instanceServerSetting: ${e.message}`) }) promises.push(instanceServerSettingPromise) const redisSetting = sequelizeClient.define('redisSetting', { enabled: { type: DataTypes.BOOLEAN, allowNull: true }, address: { type: DataTypes.STRING, allowNull: true }, port: { type: DataTypes.STRING, allowNull: true }, password: { type: DataTypes.STRING, allowNull: true } }) const redisSettingPromise = redisSetting .findAll() .then(([dbRedis]) => { const dbRedisConfig = dbRedis && { enabled: dbRedis.enabled, address: dbRedis.address, port: dbRedis.port, password: dbRedis.password } if (dbRedisConfig) { appConfig.redis = { ...appConfig.redis, ...dbRedisConfig } } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read redisSetting: ${e.message}`) }) promises.push(redisSettingPromise) const serverSetting = sequelizeClient.define('serverSetting', { hostname: { type: DataTypes.STRING, allowNull: true }, mode: { type: DataTypes.STRING, allowNull: true }, port: { type: DataTypes.STRING, allowNull: true }, clientHost: { type: DataTypes.STRING, allowNull: true }, rootDir: { type: DataTypes.STRING, allowNull: true }, publicDir: { type: DataTypes.STRING, allowNull: true }, nodeModulesDir: { type: DataTypes.STRING, allowNull: true }, localStorageProvider: { type: DataTypes.STRING, allowNull: true }, performDryRun: { type: DataTypes.BOOLEAN, allowNull: true }, storageProvider: { type: DataTypes.STRING, allowNull: true }, gaTrackingId: { type: DataTypes.STRING, allowNull: true }, hub: { type: DataTypes.JSON, allowNull: true }, url: { type: DataTypes.STRING, allowNull: true }, certPath: { type: DataTypes.STRING, allowNull: true }, keyPath: { type: DataTypes.STRING, allowNull: true }, gitPem: { type: DataTypes.STRING(2048), allowNull: true }, local: { type: DataTypes.BOOLEAN, allowNull: true }, releaseName: { type: DataTypes.STRING, allowNull: true }, instanceserverUnreachableTimeoutSeconds: { type: DataTypes.INTEGER, defaultValue: 2 } }) const serverSettingPromise = serverSetting .findAll() .then(([dbServer]) => { let hub = JSON.parse(dbServer.hub) if (typeof hub === 'string') hub = JSON.parse(hub) const dbServerConfig = dbServer && { hostname: dbServer.hostname, mode: dbServer.mode, port: dbServer.port, clientHost: dbServer.clientHost, rootDir: dbServer.rootDir, publicDir: dbServer.publicDir, nodeModulesDir: dbServer.nodeModulesDir, localStorageProvider: dbServer.localStorageProvider, performDryRun: dbServer.performDryRun, storageProvider: dbServer.storageProvider, gaTrackingId: dbServer.gaTrackingId, url: dbServer.url, certPath: dbServer.certPath, keyPath: dbServer.keyPath, gitPem: dbServer.gitPem, local: dbServer.local, releaseName: dbServer.releaseName, instanceserverUnreachableTimeoutSeconds: dbServer.instanceserverUnreachableTimeoutSeconds, hub: hub } appConfig.server = { ...appConfig.server, ...dbServerConfig } }) .catch((e) => { logger.error(e, `[updateAppConfig]: Failed to read serverSetting: ${e.message}`) }) promises.push(serverSettingPromise) await Promise.all(promises) }