Merge branch 'nconf'

v1.18.x
Julian Lam 12 years ago
commit 3c62b86096

268
app.js

@ -18,22 +18,15 @@
// Read config.js to grab redis info
var fs = require('fs'),
path = require('path'),
utils = require('./public/src/utils.js'),
nconf = require('nconf'),
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,179 +34,104 @@ 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...');
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 + ': ');
process.stdin.once('data', function(data) {
callback(data.toString().trim());
});
}
//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);
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 {
process.stdout.write(
"\n\nConfiguration Saved OK\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));
});
});
});
for (var category in default_categories) {
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 (nconf.get('setup')) console.log('Info: NodeBB Setup Triggered via Command Line');
else console.log('Info: Configuration not found, starting NodeBB setup');
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"
);
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();
});
}

@ -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"
},

@ -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";

@ -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;

@ -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);
},

@ -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) {

@ -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;

@ -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 !== '') {

@ -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) {

@ -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')
});
}

@ -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');
}
});
});

@ -353,7 +353,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) {
@ -563,7 +563,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);
});
});

@ -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;

@ -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'))
});
}

Loading…
Cancel
Save