From 145898c3ba5a7408f489d542d64b2d9957478e5b Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 16 Jul 2013 15:22:59 -0400 Subject: [PATCH 1/2] using nconf to manage config file now (issue #24) --- app.js | 310 +++++++++++++++++------------------ package.json | 43 ++--- public/src/ajaxify.js | 4 +- public/src/templates.js | 2 +- public/src/utils.js | 3 +- src/categories.js | 6 +- src/posts.js | 2 +- src/redis.js | 6 +- src/routes/admin.js | 4 +- src/routes/authentication.js | 4 +- src/user.js | 4 +- src/webserver.js | 18 +- src/websockets.js | 4 +- 13 files changed, 203 insertions(+), 207 deletions(-) diff --git a/app.js b/app.js index cbb1e56dd9..256ddfc9d4 100644 --- a/app.js +++ b/app.js @@ -19,21 +19,16 @@ // Read config.js to grab redis info var fs = require('fs'), path = require('path'), + nconf = require('nconf'), utils = require('./public/src/utils.js'), pkg = require('./package.json'), - url = require('url'), - args = {}; + url = require('url'); // Runtime environment global.env = process.env.NODE_ENV || 'production', -// Parse any passed-in arguments -process.argv.slice(2).forEach(function(value) { - if (value.slice(0, 2) === '--') { - var arg = value.slice(2).split('='); - args[arg[0]] = arg[1] || true; - } -}); +// Configuration setup +nconf.argv().file({ file: __dirname + '/config.json'}); // Log GNU copyright info along with server info console.log('Info: NodeBB v' + pkg.version + ' Copyright (C) 2013 DesignCreatePlay Inc.'); @@ -41,173 +36,172 @@ console.log('Info: This program comes with ABSOLUTELY NO WARRANTY.'); console.log('Info: This is free software, and you are welcome to redistribute it under certain conditions.'); console.log('Info: ==='); -fs.readFile(path.join(__dirname, 'config.json'), function(err, data) { - if (!err && args.setup !== true) { - global.config = JSON.parse(data); - global.config.url = global.config.base_url + (global.config.use_port ? ':' + global.config.port : '') + '/'; - global.config.upload_url = global.config.url + 'uploads/'; - - console.log('Info: Initializing NodeBB v' + pkg.version + ', on port ' + global.config.port + ', using Redis store at ' + global.config.redis.host + ':' + global.config.redis.port + '.'); - console.log('Info: Base Configuration OK.'); - - var meta = require('./src/meta.js'); - meta.config.get(function(config) { - for(c in config) { - if (config.hasOwnProperty(c)) { - global.config[c] = config[c]; - } +if (!nconf.get('setup') && nconf.get('base_url')) { + nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + '/'); + nconf.set('upload_url', nconf.get('url') + 'uploads/'); + global.nconf = nconf; + + console.log('Info: Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using Redis store at ' + nconf.get('redis').host + ':' + nconf.get('redis').port + '.'); + console.log('Info: Base Configuration OK.'); + + // TODO: Replace this with nconf-redis + var meta = require('./src/meta.js'); + global.config = {}; + meta.config.get(function(config) { + for(c in config) { + if (config.hasOwnProperty(c)) { + global.config[c] = config[c]; } + } - var categories = require('./src/categories.js'), - RDB = require('./src/redis.js'), - templates = require('./public/src/templates.js'), - webserver = require('./src/webserver.js'), - websockets = require('./src/websockets.js'), - admin = { - 'categories': require('./src/admin/categories.js') - }; + var categories = require('./src/categories.js'), + RDB = require('./src/redis.js'), + templates = require('./public/src/templates.js'), + webserver = require('./src/webserver.js'), + websockets = require('./src/websockets.js'), + admin = { + 'categories': require('./src/admin/categories.js') + }; - DEVELOPMENT = true; + DEVELOPMENT = true; - global.configuration = {}; - global.templates = {}; + global.configuration = {}; + global.templates = {}; - (function(config) { - config['ROOT_DIRECTORY'] = __dirname; + (function(config) { + config['ROOT_DIRECTORY'] = __dirname; - templates.init([ - 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', - 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', - 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/redis', + templates.init([ + 'header', 'footer', 'logout', 'admin/header', 'admin/footer', 'admin/index', + 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext', + 'emails/header', 'emails/footer', 'install/header', 'install/footer', 'install/redis', - 'noscript/header', 'noscript/home', 'noscript/category', 'noscript/topic' - ]); + 'noscript/header', 'noscript/home', 'noscript/category', 'noscript/topic' + ]); - templates.ready(function() { - webserver.init(); - }); + templates.ready(function() { + webserver.init(); + }); - //setup scripts to be moved outside of the app in future. - function setup_categories() { - console.log('Info: Checking categories...'); - categories.getAllCategories(function(data) { - if (data.categories.length === 0) { - console.log('Info: Setting up default categories...'); + //setup scripts to be moved outside of the app in future. + function setup_categories() { + console.log('Info: Checking categories...'); + categories.getAllCategories(function(data) { + if (data.categories.length === 0) { + console.log('Info: Setting up default categories...'); - fs.readFile(config.ROOT_DIRECTORY + '/install/data/categories.json', function(err, default_categories) { - default_categories = JSON.parse(default_categories); + fs.readFile(config.ROOT_DIRECTORY + '/install/data/categories.json', function(err, default_categories) { + default_categories = JSON.parse(default_categories); - for (var category in default_categories) { - console.log(category); - admin.categories.create(default_categories[category]); - } - }); - - - console.log('Info: Hardcoding uid 1 as an admin'); - var user = require('./src/user.js'); - user.makeAdministrator(1); - } else { - console.log('Info: Categories OK. Found ' + data.categories.length + ' categories.'); - } - }); - } - setup_categories(); - }(global.configuration)); - }); - } else { - // New install, ask setup questions - if (args.setup) console.log('Info: NodeBB Setup Triggered via Command Line'); - else console.log('Info: Configuration not found, starting NodeBB setup'); - - var ask = function(question, callback) { - process.stdin.resume(); - process.stdout.write(question + ': '); + for (var category in default_categories) { + admin.categories.create(default_categories[category]); + } + }); - process.stdin.once('data', function(data) { - callback(data.toString().trim()); + + console.log('Info: Hardcoding uid 1 as an admin'); + var user = require('./src/user.js'); + user.makeAdministrator(1); + } else { + console.log('Info: Categories OK. Found ' + data.categories.length + ' categories.'); + } }); } - - process.stdout.write( - "\nWelcome to NodeBB!\nThis looks like a new installation, so you'll have to answer a " + - "few questions about your environment before we can proceed.\n\n" + - "Press enter to accept the default setting (shown in brackets).\n\n\n" + - "What is...\n\n" - ); - - ask('... the publically accessible URL of this installation? (http://localhost)', function(base_url) { - ask('... the port number of your install? (4567)', function(port) { - ask('Will you be using a port number to access NodeBB? (y)', function(use_port) { - ask('... the host IP or address of your Redis instance? (127.0.0.1)', function(redis_host) { - ask('... the host port of your Redis instance? (6379)', function(redis_port) { - ask('... the password of your Redis database? (no password)', function(redis_password) { - ask('... your NodeBB secret? (keyboard mash for a bit here)', function(secret) { - ask('... the number of rounds to use for bcrypt.genSalt? (10)', function(bcrypt_rounds) { - if (!base_url) base_url = 'http://localhost'; - if (!port) port = 4567; - if (!use_port) use_port = true; else use_port = (use_port === 'y' ? true : false); - if (!redis_host) redis_host = '127.0.0.1'; - if (!redis_port) redis_port = 6379; - if (!secret) secret = utils.generateUUID(); - if (!bcrypt_rounds) bcrypt_rounds = 10; - - var urlObject = url.parse(base_url), - relative_path = urlObject.pathname, - host = urlObject.host, - protocol = urlObject.protocol; - - if(relative_path.length === 1) { - relative_path = ''; - } - - var fs = require('fs'), - path = require('path'), - config = { - secret: secret, - base_url: base_url, - relative_path: relative_path, - port: port, - use_port: use_port, - upload_path: '/public/uploads/', - bcrypt_rounds: bcrypt_rounds, - redis: { - host: redis_host, - port: redis_port, - password: redis_password - } + setup_categories(); + }(global.configuration)); + }); +} else { + // New install, ask setup questions + if (nconf.get('setup')) console.log('Info: NodeBB Setup Triggered via Command Line'); + else console.log('Info: Configuration not found, starting NodeBB setup'); + + var ask = function(question, callback) { + process.stdin.resume(); + process.stdout.write(question + ': '); + + process.stdin.once('data', function(data) { + callback(data.toString().trim()); + }); + } + + process.stdout.write( + "\nWelcome to NodeBB!\nThis looks like a new installation, so you'll have to answer a " + + "few questions about your environment before we can proceed.\n\n" + + "Press enter to accept the default setting (shown in brackets).\n\n\n" + + "What is...\n\n" + ); + + ask('... the publically accessible URL of this installation? (http://localhost)', function(base_url) { + ask('... the port number of your install? (4567)', function(port) { + ask('Will you be using a port number to access NodeBB? (y)', function(use_port) { + ask('... the host IP or address of your Redis instance? (127.0.0.1)', function(redis_host) { + ask('... the host port of your Redis instance? (6379)', function(redis_port) { + ask('... the password of your Redis database? (no password)', function(redis_password) { + ask('... your NodeBB secret? (keyboard mash for a bit here)', function(secret) { + ask('... the number of rounds to use for bcrypt.genSalt? (10)', function(bcrypt_rounds) { + if (!base_url) base_url = 'http://localhost'; + if (!port) port = 4567; + if (!use_port) use_port = true; else use_port = (use_port === 'y' ? true : false); + if (!redis_host) redis_host = '127.0.0.1'; + if (!redis_port) redis_port = 6379; + if (!secret) secret = utils.generateUUID(); + if (!bcrypt_rounds) bcrypt_rounds = 10; + + var urlObject = url.parse(base_url), + relative_path = urlObject.pathname, + host = urlObject.host, + protocol = urlObject.protocol; + + if(relative_path.length === 1) { + relative_path = ''; + } + + var fs = require('fs'), + path = require('path'), + config = { + secret: secret, + base_url: base_url, + relative_path: relative_path, + port: port, + use_port: use_port, + upload_path: '/public/uploads/', + bcrypt_rounds: bcrypt_rounds, + redis: { + host: redis_host, + port: redis_port, + password: redis_password } + } - // Server-side config - fs.writeFile(path.join(__dirname, 'config.json'), JSON.stringify(config, null, 4), function(err) { - if (err) throw err; - else { + // Server-side config + fs.writeFile(path.join(__dirname, 'config.json'), JSON.stringify(config, null, 4), function(err) { + if (err) throw err; + else { + process.stdout.write( + "\n\nConfiguration Saved OK\n\n" + ); + if (!nconf.get('setup')) { process.stdout.write( - "\n\nConfiguration Saved OK\n\n" + "Please start NodeBB again and register a new user at " + + base_url + (use_port ? ':' + port : '') + "/register. This user will automatically become an administrator.\n\n" ); - if (!args.setup) { - process.stdout.write( - "Please start NodeBB again and register a new user at " + - base_url + (use_port ? ':' + port : '') + "/register. This user will automatically become an administrator.\n\n" - ); - } - process.stdout.write( - "If at any time you'd like to run this setup again, run the app with the \"--setup\" flag\n\n" - ); - process.exit(); } - }); - - // Client-side config - fs.writeFile(path.join(__dirname, 'public', 'config.json'), JSON.stringify({ - socket: { - address: protocol + '//' + host, - port: port - }, - api_url: protocol + '//' + host + (use_port ? ':' + port : '') + relative_path + '/api/', - relative_path: relative_path - }, null, 4)); + process.stdout.write( + "If at any time you'd like to run this setup again, run the app with the \"--setup\" flag\n\n" + ); + process.exit(); + } }); + + // Client-side config + fs.writeFile(path.join(__dirname, 'public', 'config.json'), JSON.stringify({ + socket: { + address: protocol + '//' + host, + port: port + }, + api_url: protocol + '//' + host + (use_port ? ':' + port : '') + relative_path + '/api/', + relative_path: relative_path + }, null, 4)); }); }); }); @@ -215,5 +209,5 @@ fs.readFile(path.join(__dirname, 'config.json'), function(err, data) { }); }); }); - } -}); \ No newline at end of file + }); +} \ No newline at end of file diff --git a/package.json b/package.json index 49a813b0e0..c00bf663f7 100644 --- a/package.json +++ b/package.json @@ -33,27 +33,28 @@ }, "main": "app.js", "dependencies": { - "socket.io": "0.9.14", - "redis": "0.8.3", - "express": "3.2.0", - "express-namespace": "0.1.1", - "connect": "2.7.6", - "emailjs": "0.3.4", - "cookie": "0.0.6", - "connect-redis": "1.4.5", - "passport": "0.1.16", - "passport-local": "0.1.6", - "passport-twitter": "0.1.4", - "passport-google-oauth": "0.1.5", - "passport-facebook": "0.1.5", - "less-middleware": "0.1.12", - "marked": "0.2.8", - "bcrypt": "0.7.5", - "async": "0.2.8", - "node-imagemagick": "0.1.8", - "node-rss": "1.0.1", - "gravatar": "1.0.6" - }, + "socket.io": "0.9.14", + "redis": "0.8.3", + "express": "3.2.0", + "express-namespace": "0.1.1", + "connect": "2.7.6", + "emailjs": "0.3.4", + "cookie": "0.0.6", + "connect-redis": "1.4.5", + "passport": "0.1.16", + "passport-local": "0.1.6", + "passport-twitter": "0.1.4", + "passport-google-oauth": "0.1.5", + "passport-facebook": "0.1.5", + "less-middleware": "0.1.12", + "marked": "0.2.8", + "bcrypt": "0.7.5", + "async": "0.2.8", + "node-imagemagick": "0.1.8", + "node-rss": "1.0.1", + "gravatar": "1.0.6", + "nconf": "~0.6.7" + }, "bugs": { "url": "https://github.com/designcreateplay/NodeBB/issues" }, diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index ff355ba72b..3aa10071b8 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -109,8 +109,8 @@ var ajaxify = {}; function evalScript(elem) { var data = (elem.text || elem.textContent || elem.innerHTML || "" ), - head = document.getElementsByTagName("head")[0] || - document.documentElement, + head = document.getElementsByTagName("head")[0] || + document.documentElement, script = document.createElement("script"); script.type = "text/javascript"; diff --git a/public/src/templates.js b/public/src/templates.js index 5dba3ebd17..6ebeab82d3 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -181,7 +181,7 @@ if (!templates[tpl_url] || !template_data) return; if(typeof global !== "undefined") - template_data['relative_path'] = global.config.relative_path; + template_data['relative_path'] = global.nconf.get('relative_path'); else template_data['relative_path'] = RELATIVE_PATH; diff --git a/public/src/utils.js b/public/src/utils.js index f9e8deba60..36a13b152f 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -85,7 +85,8 @@ // from http://stackoverflow.com/questions/46155/validate-email-address-in-javascript isEmailValid: function(email) { - var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; + // var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; + var valid = email.indexOf('@') !== -1 ? true : false; return re.test(email); }, diff --git a/src/categories.js b/src/categories.js index 12a2e0e68d..df6902e34d 100644 --- a/src/categories.js +++ b/src/categories.js @@ -32,9 +32,9 @@ var RDB = require('./redis.js'), 'category_id': category_id, 'active_users': [], 'topics' : [], - 'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(global.config.url + 'category/' + category_slug) + '&text=' + encodeURIComponent(category_name), - 'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(global.config.url + 'category/' + category_slug), - 'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(global.config.url + 'category/' + category_slug) + 'twitter-intent-url': 'https://twitter.com/intent/tweet?url=' + encodeURIComponent(global.nconf.get('url') + 'category/' + category_slug) + '&text=' + encodeURIComponent(category_name), + 'facebook-share-url': 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(global.nconf.get('url') + 'category/' + category_slug), + 'google-share-url': 'https://plus.google.com/share?url=' + encodeURIComponent(global.nconf.get('url') + 'category/' + category_slug) }; function getTopics(next) { diff --git a/src/posts.js b/src/posts.js index 38dfac0581..ce850eaee6 100644 --- a/src/posts.js +++ b/src/posts.js @@ -38,7 +38,7 @@ marked.setOptions({ post.username = userData.username || 'anonymous'; post.userslug = userData.userslug || ''; post.user_rep = userData.reputation || 0; - post.picture = userData.picture || require('gravatar').url('', {}, https=global.config.https); + post.picture = userData.picture || require('gravatar').url('', {}, https=global.nconf.get('https')); post.signature = marked(userData.signature || ''); if(post.editor !== '') { diff --git a/src/redis.js b/src/redis.js index 8ef71f16bd..1661952cb1 100644 --- a/src/redis.js +++ b/src/redis.js @@ -2,10 +2,10 @@ var redis = require('redis'), utils = require('./../public/src/utils.js'); - RedisDB.exports = redis.createClient(global.config.redis.port, global.config.redis.host); + RedisDB.exports = redis.createClient(global.nconf.get('redis').port, global.nconf.get('redis').host); - if( global.config.redis.password ) { - RedisDB.exports.auth(global.config.redis.password); + if( global.nconf.get('redis').password ) { + RedisDB.exports.auth(global.nconf.get('redis').password); } RedisDB.exports.handle = function(error) { diff --git a/src/routes/admin.js b/src/routes/admin.js index 7c6619006c..f2c00f6a48 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -14,9 +14,9 @@ var user = require('./../user.js'), Admin.build_header = function(res) { return templates['admin/header'].parse({ - cssSrc: global.config['theme:src'] || global.config.relative_path + '/vendor/bootstrap/css/bootstrap.min.css', + cssSrc: global.config['theme:src'] || global.nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css', csrf:res.locals.csrf_token, - relative_path: global.config.relative_path + relative_path: global.nconf.get('relative_path') }); } diff --git a/src/routes/authentication.js b/src/routes/authentication.js index be27eaeb95..fa026425ae 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -140,10 +140,10 @@ req.login({ uid: uid }, function() { - res.redirect(global.config.relative_path + '/'); + res.redirect(global.nconf.get('relative_path') + '/'); }); } else { - res.redirect(global.config.relative_path + '/register'); + res.redirect(global.nconf.get('relative_path') + '/register'); } }); }); diff --git a/src/user.js b/src/user.js index 843a099f09..b950f50aac 100644 --- a/src/user.js +++ b/src/user.js @@ -350,7 +350,7 @@ var utils = require('./../public/src/utils.js'), options.forcedefault = 'y'; } - return require('gravatar').url(email, options, https=global.config.https); + return require('gravatar').url(email, options, https=global.nconf.get('https')); } User.hashPassword = function(password, callback) { @@ -560,7 +560,7 @@ var utils = require('./../public/src/utils.js'), topics.getTopicField(tid, 'slug', function(slug) { var message = username + ' made a new post'; - notifications.create(message, 5, global.config.url + 'topic/' + slug + '#' + pid, 'notification_'+ Date.now(), function(nid) { + notifications.create(message, 5, global.nconf.get('url') + 'topic/' + slug + '#' + pid, 'notification_'+ Date.now(), function(nid) { notifications.push(nid, followers); }); }); diff --git a/src/webserver.js b/src/webserver.js index 0d68b657f2..eda01e1619 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -5,7 +5,7 @@ var express = require('express'), RedisStore = require('connect-redis')(express), path = require('path'), redis = require('redis'), - redisServer = redis.createClient(global.config.redis.port, global.config.redis.host), + redisServer = redis.createClient(global.nconf.get('redis').port, global.nconf.get('redis').host), marked = require('marked'), utils = require('../public/src/utils.js'), pkg = require('../package.json'), @@ -28,10 +28,10 @@ var express = require('express'), app.build_header = function(res) { return templates['header'].parse({ - cssSrc: global.config['theme:src'] || global.config.relative_path + '/vendor/bootstrap/css/bootstrap.min.css', + cssSrc: global.config['theme:src'] || global.nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css', title: global.config['title'] || 'NodeBB', csrf:res.locals.csrf_token, - relative_path: global.config.relative_path + relative_path: global.nconf.get('relative_path') }); }; @@ -39,7 +39,7 @@ var express = require('express'), app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico'))); app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public') })); //app.use(express.static(path.join(__dirname, '../', 'public'))); - app.use(global.config.relative_path, express.static(path.join(__dirname, '../', 'public'))); + app.use(global.nconf.get('relative_path'), express.static(path.join(__dirname, '../', 'public'))); app.use(express.bodyParser()); // Puts POST vars in request.body app.use(express.cookieParser()); // If you want to parse cookies (res.cookies) app.use(express.compress()); @@ -48,7 +48,7 @@ var express = require('express'), client: redisServer, ttl: 60*60*24*14 }), - secret: global.config.secret, + secret: global.nconf.get('secret'), key: 'express.sid' })); app.use(express.csrf()); @@ -65,7 +65,7 @@ var express = require('express'), app.use(function(req, res, next) { - global.config.https = req.secure; + global.nconf.set('https', req.secure); // Don't bother with session handling for API requests if (/^\/api\//.test(req.url)) return next(); @@ -89,7 +89,7 @@ var express = require('express'), if (req.accepts('html')) { //res.json('404', { url: req.url }); - res.redirect(global.config.relative_path + '/404'); + res.redirect(global.nconf.get('relative_path') + '/404'); return; } @@ -121,7 +121,7 @@ var express = require('express'), }; - app.namespace(global.config.relative_path, function() { + app.namespace(global.nconf.get('relative_path'), function() { auth.create_routes(app); admin.create_routes(app); @@ -414,5 +414,5 @@ var express = require('express'), }(WebServer)); -server.listen(config.port); +server.listen(nconf.get('port')); global.server = server; diff --git a/src/websockets.js b/src/websockets.js index ffc2516890..76ee675a45 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -30,7 +30,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), io.set('authorization', function(handshakeData, accept) { if (handshakeData.headers.cookie) { handshakeData.cookie = cookie.parse(handshakeData.headers.cookie); - handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], global.config.secret); + handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], global.nconf.get('secret')); if (handshakeData.cookie['express.sid'] == handshakeData.sessionID) { return accept('Cookie is invalid.', false); @@ -196,7 +196,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }), uid:0, username: "Anonymous User", email: '', - picture: require('gravatar').url('', {s:'24'}, https=global.config.https) + picture: require('gravatar').url('', {s:'24'}, https=global.nconf.get('https')) }); } From 815bd7c10ae9ae67070b0384dbdcb162f4812409 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 16 Jul 2013 16:12:09 -0400 Subject: [PATCH 2/2] THIS IS A BREAKING CHANGE === Please run `node app --setup` after you pull this commit. refactored install script to its own library in /src, updated redis config params to be nconf compatible --- app.js | 106 +++++++---------------------------------------- src/install.js | 89 +++++++++++++++++++++++++++++++++++++++ src/redis.js | 6 +-- src/webserver.js | 2 +- 4 files changed, 108 insertions(+), 95 deletions(-) create mode 100644 src/install.js diff --git a/app.js b/app.js index 256ddfc9d4..618c31aaad 100644 --- a/app.js +++ b/app.js @@ -18,9 +18,7 @@ // Read config.js to grab redis info var fs = require('fs'), - path = require('path'), nconf = require('nconf'), - utils = require('./public/src/utils.js'), pkg = require('./package.json'), url = require('url'); @@ -41,7 +39,7 @@ if (!nconf.get('setup') && nconf.get('base_url')) { nconf.set('upload_url', nconf.get('url') + 'uploads/'); global.nconf = nconf; - console.log('Info: Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using Redis store at ' + nconf.get('redis').host + ':' + nconf.get('redis').port + '.'); + console.log('Info: Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using Redis store at ' + nconf.get('redis:host') + ':' + nconf.get('redis:port') + '.'); console.log('Info: Base Configuration OK.'); // TODO: Replace this with nconf-redis @@ -115,99 +113,25 @@ if (!nconf.get('setup') && nconf.get('base_url')) { if (nconf.get('setup')) console.log('Info: NodeBB Setup Triggered via Command Line'); else console.log('Info: Configuration not found, starting NodeBB setup'); - var ask = function(question, callback) { - process.stdin.resume(); - process.stdout.write(question + ': '); - - process.stdin.once('data', function(data) { - callback(data.toString().trim()); - }); - } + var install = require('./src/install'); process.stdout.write( "\nWelcome to NodeBB!\nThis looks like a new installation, so you'll have to answer a " + "few questions about your environment before we can proceed.\n\n" + - "Press enter to accept the default setting (shown in brackets).\n\n\n" + - "What is...\n\n" + "Press enter to accept the default setting (shown in brackets).\n\n\n" ); - ask('... the publically accessible URL of this installation? (http://localhost)', function(base_url) { - ask('... the port number of your install? (4567)', function(port) { - ask('Will you be using a port number to access NodeBB? (y)', function(use_port) { - ask('... the host IP or address of your Redis instance? (127.0.0.1)', function(redis_host) { - ask('... the host port of your Redis instance? (6379)', function(redis_port) { - ask('... the password of your Redis database? (no password)', function(redis_password) { - ask('... your NodeBB secret? (keyboard mash for a bit here)', function(secret) { - ask('... the number of rounds to use for bcrypt.genSalt? (10)', function(bcrypt_rounds) { - if (!base_url) base_url = 'http://localhost'; - if (!port) port = 4567; - if (!use_port) use_port = true; else use_port = (use_port === 'y' ? true : false); - if (!redis_host) redis_host = '127.0.0.1'; - if (!redis_port) redis_port = 6379; - if (!secret) secret = utils.generateUUID(); - if (!bcrypt_rounds) bcrypt_rounds = 10; - - var urlObject = url.parse(base_url), - relative_path = urlObject.pathname, - host = urlObject.host, - protocol = urlObject.protocol; - - if(relative_path.length === 1) { - relative_path = ''; - } - - var fs = require('fs'), - path = require('path'), - config = { - secret: secret, - base_url: base_url, - relative_path: relative_path, - port: port, - use_port: use_port, - upload_path: '/public/uploads/', - bcrypt_rounds: bcrypt_rounds, - redis: { - host: redis_host, - port: redis_port, - password: redis_password - } - } - - // Server-side config - fs.writeFile(path.join(__dirname, 'config.json'), JSON.stringify(config, null, 4), function(err) { - if (err) throw err; - else { - process.stdout.write( - "\n\nConfiguration Saved OK\n\n" - ); - if (!nconf.get('setup')) { - process.stdout.write( - "Please start NodeBB again and register a new user at " + - base_url + (use_port ? ':' + port : '') + "/register. This user will automatically become an administrator.\n\n" - ); - } - process.stdout.write( - "If at any time you'd like to run this setup again, run the app with the \"--setup\" flag\n\n" - ); - process.exit(); - } - }); - - // Client-side config - fs.writeFile(path.join(__dirname, 'public', 'config.json'), JSON.stringify({ - socket: { - address: protocol + '//' + host, - port: port - }, - api_url: protocol + '//' + host + (use_port ? ':' + port : '') + relative_path + '/api/', - relative_path: relative_path - }, null, 4)); - }); - }); - }); - }); - }); - }); - }); + install.setup(function(err) { + if (err) { + console.log('Error: There was a problem completing NodeBB setup: ', err.message); + } else { + if (!nconf.get('setup')) { + process.stdout.write( + "Please start NodeBB again and register a new user. This user will automatically become an administrator.\n\n" + ); + } + } + + process.exit(); }); } \ No newline at end of file diff --git a/src/install.js b/src/install.js new file mode 100644 index 0000000000..24709cb5ab --- /dev/null +++ b/src/install.js @@ -0,0 +1,89 @@ +var async = require('async'), + utils = require('../public/src/utils.js'), + fs = require('fs'), + url = require('url'), + path = require('path'), + install = { + questions: [ + 'base_url|Publically accessible URL of this installation? (http://localhost)', + 'port|Port number of your install? (4567)', + 'use_port|Will you be using a port number to access NodeBB? (y)', + 'redis:host|Host IP or address of your Redis instance? (127.0.0.1)', + 'redis:port|Host port of your Redis instance? (6379)', + 'redis:password|Password of your Redis database? (no password)', + 'secret|Your NodeBB secret? (keyboard mash for a bit here)', + 'bcrypt_rounds|The number of rounds to use for bcrypt.genSalt? (10)' + ], + defaults: { + "base_url": 'http://localhost', + "port": 4567, + "use_port": true, + "redis:host": '127.0.0.1', + "redis:port": 6379, + "redis:password": '', + "secret": utils.generateUUID(), + "bcrypt_rounds": 10, + "upload_path": '/public/uploads' + }, + ask: function(question, callback) { + process.stdin.resume(); + process.stdout.write(question + ': '); + + process.stdin.once('data', function(data) { + callback(data.toString().trim()); + }); + }, + setup: function(callback) { + var config = {}; + for(d in install.defaults) config[d] = install.defaults[d]; + + async.eachSeries(install.questions, function(question, next) { + var question = question.split('|'); + install.ask(question[1], function(value) { + if (value !== '') config[question[0]] = value; + next(); + }); + }, function() { + var urlObject = url.parse(config.base_url), + relative_path = (urlObject.pathname && urlObject.pathname.length > 1) ? urlObject.pathname : '', + host = urlObject.host, + protocol = urlObject.protocol, + server_conf = config, + client_conf = { + socket: { + address: protocol + '//' + host, + port: config.port + }, + api_url: protocol + '//' + host + (config.use_port ? ':' + config.port : '') + relative_path + '/api/', + relative_path: relative_path + }; + + server_conf.relative_path = relative_path; + + install.save(server_conf, client_conf, callback); + }); + }, + save: function(server_conf, client_conf, callback) { + // Server Config + async.parallel([ + function(next) { + fs.writeFile(path.join(__dirname, '../', 'config.json'), JSON.stringify(server_conf, null, 4), function(err) { + next(err); + }); + }, + function(next) { + fs.writeFile(path.join(__dirname, '../', 'public', 'config.json'), JSON.stringify(client_conf, null, 4), function(err) { + next(err); + }); + } + ], function(err) { + process.stdout.write( + "\n\nConfiguration Saved OK\n\n" + ); + + callback(err); + }); + } + }; + +module.exports = install; \ No newline at end of file diff --git a/src/redis.js b/src/redis.js index 1661952cb1..54b0850cf9 100644 --- a/src/redis.js +++ b/src/redis.js @@ -2,10 +2,10 @@ var redis = require('redis'), utils = require('./../public/src/utils.js'); - RedisDB.exports = redis.createClient(global.nconf.get('redis').port, global.nconf.get('redis').host); + RedisDB.exports = redis.createClient(global.nconf.get('redis:port'), global.nconf.get('redis:host')); - if( global.nconf.get('redis').password ) { - RedisDB.exports.auth(global.nconf.get('redis').password); + if( global.nconf.get('redis:password') ) { + RedisDB.exports.auth(global.nconf.get('redis:password')); } RedisDB.exports.handle = function(error) { diff --git a/src/webserver.js b/src/webserver.js index eda01e1619..0ae65d7f60 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -5,7 +5,7 @@ var express = require('express'), RedisStore = require('connect-redis')(express), path = require('path'), redis = require('redis'), - redisServer = redis.createClient(global.nconf.get('redis').port, global.nconf.get('redis').host), + redisServer = redis.createClient(global.nconf.get('redis:port'), global.nconf.get('redis:host')), marked = require('marked'), utils = require('../public/src/utils.js'), pkg = require('../package.json'),