refactor(config.js): Extract config file

* Separate different config source to each files
* Freeze config object
This commit is contained in:
BoHong Li 2017-04-13 01:57:55 +08:00 committed by Raccoon Li
parent 4738ba7d36
commit ecb0533605
15 changed files with 767 additions and 618 deletions

92
lib/config/default.js Normal file
View file

@ -0,0 +1,92 @@
'use strict'
module.exports = {
domain: '',
urlpath: '',
port: 3000,
urladdport: false,
alloworigin: ['localhost'],
usessl: false,
protocolusessl: false,
usecdn: true,
allowanonymous: true,
allowfreeurl: false,
defaultpermission: 'editable',
dburl: '',
db: {},
// ssl path
sslkeypath: '',
sslcertpath: '',
sslcapath: '',
dhparampath: '',
// other path
tmppath: './tmp',
defaultnotepath: './public/default.md',
docspath: './public/docs',
indexpath: './public/views/index.ejs',
hackmdpath: './public/views/hackmd.ejs',
errorpath: './public/views/error.ejs',
prettypath: './public/views/pretty.ejs',
slidepath: './public/views/slide.ejs',
// session
sessionname: 'connect.sid',
sessionsecret: 'secret',
sessionlife: 14 * 24 * 60 * 60 * 1000, // 14 days
staticcachetime: 1 * 24 * 60 * 60 * 1000, // 1 day
// socket.io
heartbeatinterval: 5000,
heartbeattimeout: 10000,
// document
documentmaxlength: 100000,
// image upload setting, available options are imgur/s3/filesystem
imageUploadType: 'filesystem',
imgur: {
clientID: undefined
},
s3: {
accessKeyId: undefined,
secretAccessKey: undefined,
region: undefined
},
s3bucket: undefined,
// authentication
facebook: {
clientID: undefined,
clientSecret: undefined
},
twitter: {
consumerKey: undefined,
consumerSecret: undefined
},
github: {
clientID: undefined,
clientSecret: undefined
},
gitlab: {
baseURL: undefined,
clientID: undefined,
clientSecret: undefined,
scope: undefined
},
dropbox: {
clientID: undefined,
clientSecret: undefined
},
google: {
clientID: undefined,
clientSecret: undefined
},
ldap: {
providerName: undefined,
url: undefined,
bindDn: undefined,
bindCredentials: undefined,
tokenSecret: undefined,
searchBase: undefined,
searchFilter: undefined,
searchAttributes: undefined,
tlsca: undefined
},
email: true,
allowemailregister: true
}

17
lib/config/defaultSSL.js Normal file
View file

@ -0,0 +1,17 @@
'use strict'
const fs = require('fs')
function getFile (path) {
if (fs.existsSync(path)) {
return path
}
return undefined
}
module.exports = {
sslkeypath: getFile('/run/secrets/key.pem'),
sslcertpath: getFile('/run/secrets/cert.pem'),
sslcapath: getFile('/run/secrets/ca.pem'),
dhparampath: getFile('/run/secrets/dhparam.pem')
}

View file

@ -0,0 +1,51 @@
'use strict'
const fs = require('fs')
const path = require('path')
const basePath = path.resolve('/var/run/secrets/')
function getSecret (secret) {
const filePath = path.join(basePath, secret)
if (fs.existsSync(filePath)) return fs.readFileSync(filePath)
return undefined
}
if (fs.existsSync(basePath)) {
module.exports = {
sessionsecret: getSecret('sessionsecret'),
sslkeypath: getSecret('sslkeypath'),
sslcertpath: getSecret('sslcertpath'),
sslcapath: getSecret('sslcapath'),
dhparampath: getSecret('dhparampath'),
s3: {
accessKeyId: getSecret('s3_acccessKeyId'),
secretAccessKey: getSecret('s3_secretAccessKey')
},
facebook: {
clientID: getSecret('facebook_clientID'),
clientSecret: getSecret('facebook_clientSecret')
},
twitter: {
consumerKey: getSecret('twitter_consumerKey'),
consumerSecret: getSecret('twitter_consumerSecret')
},
github: {
clientID: getSecret('github_clientID'),
clientSecret: getSecret('github_clientSecret')
},
gitlab: {
clientID: getSecret('gitlab_clientID'),
clientSecret: getSecret('gitlab_clientSecret')
},
dropbox: {
clientID: getSecret('dropbox_clientID'),
clientSecret: getSecret('dropbox_clientSecret')
},
google: {
clientID: getSecret('google_clientID'),
clientSecret: getSecret('google_clientSecret')
},
imgur: getSecret('imgur_clientid')
}
}

16
lib/config/enum.js Normal file
View file

@ -0,0 +1,16 @@
'use strict'
exports.Environment = {
development: 'development',
production: 'production',
test: 'test'
}
exports.Permission = {
freely: 'freely',
editable: 'editable',
limited: 'limited',
locked: 'locked',
protected: 'protected',
private: 'private'
}

64
lib/config/environment.js Normal file
View file

@ -0,0 +1,64 @@
'use strict'
module.exports = {
domain: process.env.HMD_DOMAIN,
urlpath: process.env.HMD_URL_PATH,
port: process.env.HMD_PORT,
urladdport: process.env.HMD_URL_ADDPORT,
usessl: process.env.HMD_PROTOCOL_USESSL,
alloworigin: process.env.HMD_ALLOW_ORIGIN ? process.env.HMD_ALLOW_ORIGIN.split(',') : undefined,
usecdn: process.env.HMD_USECDN,
allowanonymous: process.env.HMD_ALLOW_ANONYMOUS,
allowfreeurl: process.env.HMD_ALLOW_FREEURL,
defaultpermission: process.env.HMD_DEFAULT_PERMISSION,
dburl: process.env.HMD_DB_URL,
imageUploadType: process.env.HMD_IMAGE_UPLOAD_TYPE,
imgur: {
clientID: process.env.HMD_IMGUR_CLIENTID
},
s3: {
accessKeyId: process.env.HMD_S3_ACCESS_KEY_ID,
secretAccessKey: process.env.HMD_S3_SECRET_ACCESS_KEY,
region: process.env.HMD_S3_REGION
},
s3bucket: process.env.HMD_S3_BUCKET,
facebook: {
clientID: process.env.HMD_FACEBOOK_CLIENTID,
clientSecret: process.env.HMD_FACEBOOK_CLIENTSECRET
},
twitter: {
consumerKey: process.env.HMD_TWITTER_CONSUMERKEY,
consumerSecret: process.env.HMD_TWITTER_CONSUMERSECRET
},
github: {
clientID: process.env.HMD_GITHUB_CLIENTID,
clientSecret: process.env.HMD_GITHUB_CLIENTSECRET
},
gitlab: {
baseURL: process.env.HMD_GITLAB_BASEURL,
clientID: process.env.HMD_GITLAB_CLIENTID,
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET,
scope: process.env.HMD_GITLAB_SCOPE
},
dropbox: {
clientID: process.env.HMD_DROPBOX_CLIENTID,
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET
},
google: {
clientID: process.env.HMD_GOOGLE_CLIENTID,
clientSecret: process.env.HMD_GOOGLE_CLIENTSECRET
},
ldap: {
providerName: process.env.HMD_LDAP_PROVIDERNAME,
url: process.env.HMD_LDAP_URL,
bindDn: process.env.HMD_LDAP_BINDDN,
bindCredentials: process.env.HMD_LDAP_BINDCREDENTIALS,
tokenSecret: process.env.HMD_LDAP_TOKENSECRET,
searchBase: process.env.HMD_LDAP_SEARCHBASE,
searchFilter: process.env.HMD_LDAP_SEARCHFILTER,
searchAttributes: process.env.HMD_LDAP_SEARCHATTRIBUTES,
tlsca: process.env.HMD_LDAP_TLS_CA
},
email: process.env.HMD_EMAIL,
allowemailregister: process.env.HMD_ALLOW_EMAIL_REGISTER
}

112
lib/config/index.js Normal file
View file

@ -0,0 +1,112 @@
'use strict'
const fs = require('fs')
const path = require('path')
const {merge} = require('lodash')
const deepFreeze = require('deep-freeze')
const {Environment, Permission} = require('./enum')
const appRootPath = path.join(__dirname, '../../')
const env = process.env.NODE_ENV || Environment.development
const debugConfig = {
debug: (env === Environment.development)
}
const packageConfig = {
version: '0.5.1',
minimumCompatibleVersion: '0.5.0'
}
const configFilePath = path.join(__dirname, '../../config.json')
const fileConfig = fs.existsSync(configFilePath) ? require(configFilePath)[env] : undefined
let config = require('./default')
merge(config, require('./defaultSSL'))
merge(config, debugConfig)
merge(config, packageConfig)
merge(config, fileConfig)
merge(config, require('./oldEnvironment'))
merge(config, require('./environment'))
merge(config, require('./dockerSecret'))
// load LDAP CA
if (config.ldap.tlsca) {
let ca = config.ldap.tlsca.split(',')
let caContent = []
for (let i of ca) {
if (fs.existsSync(ca[i])) {
caContent.push(fs.readFileSync(ca[i], 'utf8'))
}
}
let tlsOptions = {
ca: caContent
}
config.ldap.tlsOptions = config.ldap.tlsOptions ? Object.assign(config.ldap.tlsOptions, tlsOptions) : tlsOptions
}
// Permission
config.permission = Permission
if (!config.allowanonymous) {
delete config.permission.freely
}
if (!(config.defaultpermission in config.permission)) {
config.defaultpermission = config.permission.editable
}
// cache result, cannot change config in runtime!!!
config.isStandardHTTPsPort = (function isStandardHTTPsPort () {
return config.usessl && config.port === 443
})()
config.isStandardHTTPPort = (function isStandardHTTPPort () {
return !config.usessl && config.port === 80
})()
// cache serverURL
config.serverurl = (function getserverurl () {
var url = ''
if (config.domain) {
var protocol = config.protocolusessl ? 'https://' : 'http://'
url = protocol + config.domain
if (config.urladdport) {
if (!config.isStandardHTTPPort || !config.isStandardHTTPsPort) {
url += ':' + config.port
}
}
}
if (config.urlpath) {
url += '/' + config.urlpath
}
return url
})()
config.Environment = Environment
// auth method
config.isFacebookEnable = config.facebook.clientID && config.facebook.clientSecret
config.isGoogleEnable = config.google.clientID && config.google.clientSecret
config.isDropboxEnable = config.dropbox.clientID && config.dropbox.clientSecret
config.isTwitterEnable = config.twitter.consumerKey && config.twitter.consumerSecret
config.isEmailEnable = config.email
config.isGitHubEnable = config.github.clientID && config.github.clientSecret
config.isGitLabEnable = config.gitlab.clientID && config.gitlab.clientSecret
config.isLDAPEnable = config.ldap.url
// generate correct path
config.sslcapath = path.join(appRootPath, config.sslcapath)
config.sslcertpath = path.join(appRootPath, config.sslcertpath)
config.sslkeypath = path.join(appRootPath, config.sslkeypath)
config.dhparampath = path.join(appRootPath, config.dhparampath)
config.tmppath = path.join(appRootPath, config.tmppath)
config.defaultnotepath = path.join(appRootPath, config.defaultnotepath)
config.docspath = path.join(appRootPath, config.docspath)
config.indexpath = path.join(appRootPath, config.indexpath)
config.hackmdpath = path.join(appRootPath, config.hackmdpath)
config.errorpath = path.join(appRootPath, config.errorpath)
config.prettypath = path.join(appRootPath, config.prettypath)
config.slidepath = path.join(appRootPath, config.slidepath)
// maek config readonly
config = deepFreeze(config)
module.exports = config

View file

@ -0,0 +1,8 @@
'use strict'
module.exports = {
debug: process.env.DEBUG,
dburl: process.env.DATABASE_URL,
urlpath: process.env.URL_PATH,
port: process.env.PORT
}