diff --git a/app.js b/app.js
index f5a03e401d..8a7603b045 100644
--- a/app.js
+++ b/app.js
@@ -19,7 +19,8 @@
var fs = require('fs'),
winston = require('winston'),
pkg = require('./package.json'),
- url = require('url');
+ url = require('url'),
+ meta = require('./src/meta.js');
nconf = require('nconf');
// Runtime environment
@@ -49,25 +50,20 @@ winston.info('This program comes with ABSOLUTELY NO WARRANTY.');
winston.info('This is free software, and you are welcome to redistribute it under certain conditions.');
winston.info('===');
+
+
if(nconf.get('upgrade')) {
- require('./src/upgrade').upgrade();
+ meta.configs.init(function() {
+ require('./src/upgrade').upgrade();
+ });
} else if (!nconf.get('setup') && nconf.get('base_url')) {
nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + '/');
nconf.set('upload_url', nconf.get('url') + 'uploads/');
-
winston.info('Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using Redis store at ' + nconf.get('redis:host') + ':' + nconf.get('redis:port') + '.');
winston.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];
- }
- }
+ meta.configs.init(function() {
var categories = require('./src/categories.js'),
templates = require('./public/src/templates.js'),
@@ -112,7 +108,7 @@ if(nconf.get('upgrade')) {
}
});
-
+
winston.info('Hardcoding uid 1 as an admin');
var user = require('./src/user.js');
user.makeAdministrator(1);
@@ -127,6 +123,7 @@ if(nconf.get('upgrade')) {
setup_categories();
}(global.configuration));
});
+
} else {
// New install, ask setup questions
if (nconf.get('setup')) winston.info('NodeBB Setup Triggered via Command Line');
@@ -150,7 +147,7 @@ if(nconf.get('upgrade')) {
);
}
}
-
+
process.exit();
});
}
\ No newline at end of file
diff --git a/src/install.js b/src/install.js
index 5312350d7e..1afd20ad69 100644
--- a/src/install.js
+++ b/src/install.js
@@ -79,16 +79,16 @@ var async = require('async'),
port: config.port
},
api_url: protocol + '//' + host + (config.use_port ? ':' + config.port : '') + relative_path + '/api/',
- relative_path: relative_path
+ relative_path: relative_path
};
server_conf.base_url = protocol + '//' + host;
server_conf.relative_path = relative_path;
-
- meta.config.set('postDelay', 10000);
- meta.config.set('minimumPostLength', 8);
- meta.config.set('minimumTitleLength', 3);
- meta.config.set('imgurClientID', '');
+
+ meta.configs.set('postDelay', 10000);
+ meta.configs.set('minimumPostLength', 8);
+ meta.configs.set('minimumTitleLength', 3);
+ meta.configs.set('imgurClientID', '');
install.save(server_conf, client_conf, callback);
});
diff --git a/src/login.js b/src/login.js
index 0adb9311f5..f4ada02e5f 100644
--- a/src/login.js
+++ b/src/login.js
@@ -24,14 +24,18 @@ var user = require('./user.js'),
message: 'invalid-user'
});
}
-
- user.getUserFields(uid, ['password', 'banned'], function(userData) {
+
+ user.getUserFields(uid, ['password', 'banned'], function(err, userData) {
+ if(err)
+ return next(err);
+
if(userData.banned && userData.banned === '1') {
return next({
status: "error",
message: "user-banned"
});
}
+
bcrypt.compare(password, userData.password, function(err, res) {
if(err) {
winston.err(err);
@@ -41,7 +45,7 @@ var user = require('./user.js'),
});
return;
}
-
+
if (res) {
next({
status: "ok",
diff --git a/src/meta.js b/src/meta.js
index e12eb4ed9a..cc84b964c1 100644
--- a/src/meta.js
+++ b/src/meta.js
@@ -5,7 +5,14 @@ var utils = require('./../public/src/utils.js'),
fs = require('fs');
(function(Meta) {
- Meta.config = {
+
+ Meta.configs = {
+ init: function(callback) {
+ Meta.configs.get(function(config) {
+ Meta.config = config;
+ callback();
+ });
+ },
get: function(callback) {
RDB.hgetall('config', function(err, config) {
if (!err) {
@@ -80,8 +87,8 @@ var utils = require('./../public/src/utils.js'),
}, function(err, values) {
var title;
- if (err) title = global.config.title || 'NodeBB';
- else title = (values.title ? values.title + ' | ' : '') + (global.config.title || 'NodeBB');
+ if (err) title = Meta.config.title || 'NodeBB';
+ else title = (values.title ? values.title + ' | ' : '') + (Meta.config.title || 'NodeBB');
callback(null, title, values.notifCount);
});
@@ -110,4 +117,6 @@ var utils = require('./../public/src/utils.js'),
} else callback(null);
}
}
-}(exports));
\ No newline at end of file
+
+}(exports));
+
diff --git a/src/postTools.js b/src/postTools.js
index 02c1ea70ed..8d8969a768 100644
--- a/src/postTools.js
+++ b/src/postTools.js
@@ -4,13 +4,14 @@ var RDB = require('./redis.js'),
threadTools = require('./threadTools.js'),
user = require('./user.js'),
async = require('async'),
-
+
utils = require('../public/src/utils'),
plugins = require('./plugins'),
reds = require('reds'),
postSearch = reds.createSearch('nodebbpostsearch'),
topicSearch = reds.createSearch('nodebbtopicsearch'),
- winston = require('winston');
+ winston = require('winston'),
+ meta = require('./meta.js');
(function(PostTools) {
PostTools.isMain = function(pid, tid, callback) {
@@ -21,8 +22,8 @@ var RDB = require('./redis.js'),
}
PostTools.privileges = function(pid, uid, callback) {
- //todo: break early if one condition is true
-
+ //todo: break early if one condition is true
+
function getThreadPrivileges(next) {
posts.getPostField(pid, 'tid', function(tid) {
threadTools.privileges(tid, uid, function(privileges) {
@@ -41,7 +42,7 @@ var RDB = require('./redis.js'),
function hasEnoughRep(next) {
user.getUserField(uid, 'reputation', function(reputation) {
- next(null, reputation >= global.config['privileges:manage_content']);
+ next(null, reputation >= meta.config['privileges:manage_content']);
});
}
@@ -95,7 +96,7 @@ var RDB = require('./redis.js'),
PostTools.delete = function(uid, pid) {
var success = function() {
posts.setPostField(pid, 'deleted', 1);
-
+
postSearch.remove(pid);
posts.getPostFields(pid, ['tid', 'uid'], function(postData) {
@@ -103,7 +104,7 @@ var RDB = require('./redis.js'),
user.decrementUserFieldBy(postData.uid, 'postcount', 1, function(err, postcount) {
RDB.zadd('users:postcount', postcount, postData.uid);
});
-
+
io.sockets.in('topic_' + postData.tid).emit('event:post_deleted', {
pid: pid
});
@@ -116,8 +117,8 @@ var RDB = require('./redis.js'),
});
} else {
posts.getPostField(pid, 'timestamp', function(timestamp) {
- topics.updateTimestamp(postData.tid, timestamp);
- });
+ topics.updateTimestamp(postData.tid, timestamp);
+ });
}
});
});
@@ -141,11 +142,11 @@ var RDB = require('./redis.js'),
io.sockets.in('topic_' + postData.tid).emit('event:post_restored', {
pid: pid
});
-
+
threadTools.get_latest_undeleted_pid(postData.tid, function(err, pid) {
posts.getPostField(pid, 'timestamp', function(timestamp) {
topics.updateTimestamp(postData.tid, timestamp);
- });
+ });
});
postSearch.index(postData.content, pid);
@@ -170,7 +171,7 @@ var RDB = require('./redis.js'),
if (md && md.length > 0) {
var parsedContentDOM = cheerio.load(marked(md));
var domain = nconf.get('url');
-
+
parsedContentDOM('a').each(function() {
this.attr('rel', 'nofollow');
var href = this.attr('href');
@@ -180,7 +181,7 @@ var RDB = require('./redis.js'),
if (!isSignature) this.append(' ');
}
});
-
+
html = parsedContentDOM.html();
} else {
diff --git a/src/posts.js b/src/posts.js
index 05f4ae5c59..3115dd8661 100644
--- a/src/posts.js
+++ b/src/posts.js
@@ -11,6 +11,7 @@ var RDB = require('./redis.js'),
plugins = require('./plugins'),
reds = require('reds'),
nconf = require('nconf'),
+ meta = require('./meta.js'),
postSearch = reds.createSearch('nodebbpostsearch'),
winston = require('winston');
@@ -32,7 +33,9 @@ var RDB = require('./redis.js'),
}
Posts.addUserInfoToPost = function(post, callback) {
- user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(userData) {
+ user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(err, userData) {
+ if(err)
+ return callback();
post.username = userData.username || 'anonymous';
post.userslug = userData.userslug || '';
@@ -43,7 +46,9 @@ var RDB = require('./redis.js'),
post.signature = postTools.markdownToHTML(userData.signature, true);
if(post.editor !== '') {
- user.getUserFields(post.editor, ['username', 'userslug'], function(editorData) {
+ user.getUserFields(post.editor, ['username', 'userslug'], function(err, editorData) {
+ if(err)
+ return callback();
post.editorname = editorData.username;
post.editorslug = editorData.userslug;
callback();
@@ -146,7 +151,12 @@ var RDB = require('./redis.js'),
postData.content = postTools.markdownToHTML(postData.content);
if(postData.uploadedImages) {
- postData.uploadedImages = JSON.parse(postData.uploadedImages);
+ try {
+ postData.uploadedImages = JSON.parse(postData.uploadedImages);
+ } catch(err) {
+ postData.uploadedImages = [];
+ winston.err(err);
+ }
} else {
postData.uploadedImages = [];
}
@@ -184,7 +194,7 @@ var RDB = require('./redis.js'),
type: 'error',
timeout: 2000,
title: 'Content too short',
- message: "Please enter a longer post. At least " + config.minimumPostLength + " characters.",
+ message: "Please enter a longer post. At least " + meta.config.minimumPostLength + " characters.",
alert_id: 'post_error'
});
}
@@ -192,7 +202,7 @@ var RDB = require('./redis.js'),
Posts.emitTooManyPostsAlert = function(socket) {
socket.emit('event:alert', {
title: 'Too many posts!',
- message: 'You can only post every '+ config.postDelay/1000 + ' seconds.',
+ message: 'You can only post every '+ meta.config.postDelay/1000 + ' seconds.',
type: 'error',
timeout: 2000
});
@@ -203,13 +213,13 @@ var RDB = require('./redis.js'),
content = content.trim();
}
- if (!content || content.length < config.minimumPostLength) {
+ if (!content || content.length < meta.config.minimumPostLength) {
callback(new Error('content-too-short'), null);
return;
}
user.getUserField(uid, 'lastposttime', function(lastposttime) {
- if(Date.now() - lastposttime < config.postDelay) {
+ if(Date.now() - lastposttime < meta.config.postDelay) {
callback(new Error('too-many-posts'), null);
return;
}
@@ -264,7 +274,7 @@ var RDB = require('./redis.js'),
'editor': '',
'edited': 0,
'deleted': 0,
- 'uploadedImages': [],
+ 'uploadedImages': '[]',
'fav_button_class': '',
'fav_star_class': 'icon-star-empty',
'show_banned': 'hide',
@@ -310,7 +320,6 @@ var RDB = require('./redis.js'),
next(null, []);
} else {
next(null, uploadedImages);
- Posts.setPostField(pid, 'uploadedImages', postData.uploadedImages);
}
});
},
@@ -321,6 +330,7 @@ var RDB = require('./redis.js'),
}
}, function(err, results) {
postData.uploadedImages = results.uploadedImages;
+ Posts.setPostField(pid, 'uploadedImages', JSON.stringify(postData.uploadedImages));
postData.content = results.content;
callback(postData);
});
@@ -338,7 +348,7 @@ var RDB = require('./redis.js'),
function uploadPostImages(postData, images, callback) {
var imgur = require('./imgur');
- imgur.setClientID(config.imgurClientID);
+ imgur.setClientID(meta.config.imgurClientID);
var uploadedImages = [];
diff --git a/src/routes/api.js b/src/routes/api.js
index e3eee6e534..d3bbbdc1cd 100644
--- a/src/routes/api.js
+++ b/src/routes/api.js
@@ -16,19 +16,14 @@ var user = require('./../user.js'),
});
app.get('/api/config', function(req, res, next) {
- meta.config.getFields(['postDelay', 'minimumTitleLength', 'minimumPostLength', 'imgurClientID'], function(err, metaConfig) {
- if(err) return next();
- var clientConfig = require('../../public/config.json');
+ var config = require('../../public/config.json');
- for (var attrname in metaConfig) {
- clientConfig[attrname] = metaConfig[attrname];
- }
-
- clientConfig['imgurClientIDSet'] = !!clientConfig['imgurClientID'];
- delete clientConfig['imgurClientID'];
+ config['postDelay'] = meta.config['postDelay'];
+ config['minimumTitleLength'] = meta.config['minimumTitleLength'];
+ config['minimumPostLength'] = meta.config['minimumPostLength'];
+ config['imgurClientIDSet'] = !!meta.config['imgurClientID'];
- res.json(200, clientConfig);
- })
+ res.json(200, config);
});
app.get('/api/home', function(req, res) {
@@ -48,8 +43,8 @@ var user = require('./../user.js'),
}
require('async').each(data.categories, iterator, function(err) {
- data.motd_class = (config.show_motd === '1' || config.show_motd === undefined) ? '' : 'none';
- data.motd = marked(config.motd || "# NodeBB v " + pkg.version + "\nWelcome to NodeBB, the discussion platform of the future.\n\n Get NodeBB Fork us on Github @dcplabs");
+ data.motd_class = (meta.config.show_motd === '1' || meta.config.show_motd === undefined) ? '' : 'none';
+ data.motd = marked(meta.config.motd || "# NodeBB v " + pkg.version + "\nWelcome to NodeBB, the discussion platform of the future.\n\n Get NodeBB Fork us on Github @dcplabs");
res.json(data);
});
diff --git a/src/routes/authentication.js b/src/routes/authentication.js
index ddd5114859..0d0255becb 100644
--- a/src/routes/authentication.js
+++ b/src/routes/authentication.js
@@ -6,6 +6,7 @@
passportFacebook = require('passport-facebook').Strategy,
login_strategies = [],
nconf = require('nconf'),
+ meta = require('../meta'),
user = require('../user'),
winston = require('winston'),
login_module = require('./../login.js');
@@ -17,10 +18,10 @@
});
}));
- if (global.config['social:twitter:key'] && global.config['social:twitter:secret']) {
+ if (meta.config['social:twitter:key'] && meta.config['social:twitter:secret']) {
passport.use(new passportTwitter({
- consumerKey: global.config['social:twitter:key'],
- consumerSecret: global.config['social:twitter:secret'],
+ consumerKey: meta.config['social:twitter:key'],
+ consumerSecret: meta.config['social:twitter:secret'],
callbackURL: nconf.get('url') + 'auth/twitter/callback'
}, function(token, tokenSecret, profile, done) {
login_module.loginViaTwitter(profile.id, profile.username, profile.photos, function(err, user) {
@@ -32,10 +33,10 @@
login_strategies.push('twitter');
}
- if (global.config['social:google:id'] && global.config['social:google:secret']) {
+ if (meta.config['social:google:id'] && meta.config['social:google:secret']) {
passport.use(new passportGoogle({
- clientID: global.config['social:google:id'],
- clientSecret: global.config['social:google:secret'],
+ clientID: meta.config['social:google:id'],
+ clientSecret: meta.config['social:google:secret'],
callbackURL: nconf.get('url') + 'auth/google/callback'
}, function(accessToken, refreshToken, profile, done) {
login_module.loginViaGoogle(profile.id, profile.displayName, profile.emails[0].value, function(err, user) {
@@ -47,10 +48,10 @@
login_strategies.push('google');
}
- if (global.config['social:facebook:app_id'] && global.config['social:facebook:secret']) {
+ if (meta.config['social:facebook:app_id'] && meta.config['social:facebook:secret']) {
passport.use(new passportFacebook({
- clientID: global.config['social:facebook:app_id'],
- clientSecret: global.config['social:facebook:secret'],
+ clientID: meta.config['social:facebook:app_id'],
+ clientSecret: meta.config['social:facebook:secret'],
callbackURL: nconf.get('url') + 'auth/facebook/callback'
}, function(accessToken, refreshToken, profile, done) {
login_module.loginViaFacebook(profile.id, profile.displayName, profile.emails[0].value, function(err, user) {
@@ -76,7 +77,7 @@
app.use(passport.initialize());
app.use(passport.session());
}
-
+
Auth.get_login_strategies = function() {
return login_strategies;
@@ -136,7 +137,7 @@
res.send(header + app.create_route('reset') + templates['footer']);
});
});
-
+
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if(err) {
@@ -152,7 +153,7 @@
});
})(req, res, next);
});
-
+
app.post('/register', function(req, res) {
user.create(req.body.username, req.body.password, req.body.email, function(err, uid) {
diff --git a/src/routes/user.js b/src/routes/user.js
index eee9964572..a4c6c38c88 100644
--- a/src/routes/user.js
+++ b/src/routes/user.js
@@ -281,7 +281,7 @@ var user = require('./../user.js'),
});
});
- app.get('/api/users/:userslug/settings', function(req, res) {
+ app.get('/api/users/:userslug/settings', function(req, res, next) {
var callerUID = req.user ? req.user.uid : 0;
user.get_uid_by_userslug(req.params.userslug, function(uid) {
@@ -294,7 +294,10 @@ var user = require('./../user.js'),
res.json(403, { error: 'Not allowed!' });
return;
}
- user.getUserFields(uid, ['username','userslug','showemail'], function(userData) {
+ user.getUserFields(uid, ['username','userslug','showemail'], function(err, userData) {
+ if(err)
+ return next(err);
+
if(userData) {
if(userData.showemail && userData.showemail === "1")
userData.showemail = "checked";
@@ -322,7 +325,10 @@ var user = require('./../user.js'),
return;
}
- user.getUserFields(uid, ['username','userslug'], function(userData) {
+ user.getUserFields(uid, ['username','userslug'], function(err, userData) {
+ if(err)
+ return next(err);
+
if(userData) {
posts.getFavourites(uid, function(err, posts) {
if(err)
diff --git a/src/threadTools.js b/src/threadTools.js
index 4e9efe9311..5bf5321a19 100644
--- a/src/threadTools.js
+++ b/src/threadTools.js
@@ -7,7 +7,8 @@ var RDB = require('./redis.js'),
posts = require('./posts'),
reds = require('reds'),
topicSearch = reds.createSearch('nodebbtopicsearch'),
- winston = require('winston');
+ winston = require('winston'),
+ meta = require('./meta');
(function(ThreadTools) {
@@ -17,10 +18,10 @@ var RDB = require('./redis.js'),
callback(!!ismember || false);
});
}
-
+
ThreadTools.privileges = function(tid, uid, callback) {
- //todo: break early if one condition is true
-
+ //todo: break early if one condition is true
+
function getCategoryPrivileges(next) {
topics.getTopicField(tid, 'cid', function(err, cid) {
categories.privileges(cid, uid, function(privileges) {
@@ -31,10 +32,10 @@ var RDB = require('./redis.js'),
function hasEnoughRep(next) {
user.getUserField(uid, 'reputation', function(reputation) {
- next(null, reputation >= global.config['privileges:manage_topic']);
+ next(null, reputation >= meta.config['privileges:manage_topic']);
});
}
-
+
async.parallel([getCategoryPrivileges, hasEnoughRep], function(err, results) {
callback({
@@ -87,7 +88,7 @@ var RDB = require('./redis.js'),
ThreadTools.delete = function(tid, uid, callback) {
ThreadTools.privileges(tid, uid, function(privileges) {
if (privileges.editable || uid === -1) {
-
+
topics.setTopicField(tid, 'deleted', 1);
ThreadTools.lock(tid, uid);
@@ -110,12 +111,12 @@ var RDB = require('./redis.js'),
topics.setTopicField(tid, 'deleted', 0);
ThreadTools.unlock(tid, uid);
- if (socket) {
- io.sockets.in('topic_' + tid).emit('event:topic_restored', {
- tid: tid,
- status: 'ok'
- });
+ io.sockets.in('topic_' + tid).emit('event:topic_restored', {
+ tid: tid,
+ status: 'ok'
+ });
+ if (socket) {
socket.emit('api:topic.restore', {
status: 'ok',
tid: tid
@@ -132,12 +133,12 @@ var RDB = require('./redis.js'),
ThreadTools.pin = function(tid, uid, socket) {
ThreadTools.privileges(tid, uid, function(privileges) {
if (privileges.editable) {
-
+
topics.setTopicField(tid, 'pinned', 1);
topics.getTopicField(tid, 'cid', function(err, cid) {
RDB.zadd('categories:' + cid + ':tid', Math.pow(2,53), tid);
});
-
+
if (socket) {
io.sockets.in('topic_' + tid).emit('event:topic_pinned', {
tid: tid,
@@ -156,7 +157,7 @@ var RDB = require('./redis.js'),
ThreadTools.unpin = function(tid, uid, socket) {
ThreadTools.privileges(tid, uid, function(privileges) {
if (privileges.editable) {
-
+
topics.setTopicField(tid, 'pinned', 0);
topics.getTopicFields(tid, ['cid', 'lastposttime'], function(topicData) {
RDB.zadd('categories:' + topicData.cid + ':tid', topicData.lastposttime, tid);
@@ -177,17 +178,17 @@ var RDB = require('./redis.js'),
}
ThreadTools.move = function(tid, cid, socket) {
-
+
topics.getTopicFields(tid, ['cid', 'lastposttime'], function(topicData) {
var oldCid = topicData.cid;
var multi = RDB.multi();
multi.zrem('categories:' + oldCid + ':tid', tid);
multi.zadd('categories:' + cid + ':tid', topicData.lastposttime, tid);
-
+
multi.exec(function(err, result) {
- if (!err && result === 1) {
+ if (!err && result[0] === 1 && result[1] === 1) {
topics.setTopicField(tid, 'cid', cid);
@@ -258,7 +259,7 @@ var RDB = require('./redis.js'),
ThreadTools.notify_followers = function(tid, exceptUid) {
async.parallel([
function(next) {
-
+
topics.getTopicField(tid, 'title', function(err, title) {
topics.getTeaser(tid, function(err, teaser) {
if (!err) {
@@ -268,8 +269,8 @@ var RDB = require('./redis.js'),
} else next(err);
});
});
-
-
+
+
},
function(next) {
ThreadTools.get_followers(tid, function(err, followers) {
@@ -290,14 +291,14 @@ var RDB = require('./redis.js'),
var numPosts = posts.length;
if(!numPosts)
return callback(new Error('no-undeleted-pids-found'));
-
+
while(numPosts--) {
if(posts[numPosts].deleted !== '1') {
callback(null, posts[numPosts].pid);
return;
}
}
-
+
callback(new Error('no-undeleted-pids-found'));
});
}
diff --git a/src/topics.js b/src/topics.js
index ed437cc2f3..98545bfbfe 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -20,7 +20,7 @@ marked.setOptions({
(function(Topics) {
-
+
Topics.getTopicData = function(tid, callback) {
RDB.hgetall('topic:' + tid, function(err, data) {
@@ -45,15 +45,15 @@ marked.setOptions({
posts.getPostsByTid(tid, start, end, function(postData) {
if(Array.isArray(postData) && !postData.length)
return callback([]);
-
+
function getFavouritesData(next) {
var pids = [];
- for(var i=0; i 150) {
next({error:'Signature can\'t be longer than 150 characters!'}, false);
} else {
- next(null, true);
- }
+ next(null, true);
+ }
}
-
+
function isEmailAvailable(next) {
if(!data['email']) {
return next(null, true);
@@ -227,18 +224,18 @@ var utils = require('./../public/src/utils.js'),
User.getUserField(uid, 'email', function(email) {
if(email !== data['email']) {
User.isEmailAvailable(data['email'], function(available) {
- if(!available) {
+ if(!available) {
next({error:'Email not available!'}, false);
} else {
- next(null, true);
+ next(null, true);
}
});
} else {
- next(null, true);
+ next(null, true);
}
});
}
-
+
async.series([isSignatureValid, isEmailAvailable], function(err, results) {
if(err) {
console.log(err);
@@ -261,8 +258,11 @@ var utils = require('./../public/src/utils.js'),
if(field === 'email') {
var gravatarpicture = User.createGravatarURLFromEmail(data[field]);
User.setUserField(uid, 'gravatarpicture', gravatarpicture);
- User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(userData) {
- RDB.del('email:' + userData['email'] + ':uid');
+ User.getUserFields(uid, ['email', 'picture', 'uploadedpicture'], function(err, userData) {
+ if(err)
+ return callback(err);
+
+ RDB.del('email:' + userData['email'] + ':uid');
RDB.set('email:' + data['email'] + ':uid', uid);
User.setUserField(uid, field, data[field]);
if(userData.picture !== userData.uploadedpicture) {
@@ -275,9 +275,9 @@ var utils = require('./../public/src/utils.js'),
return;
} else if(field === 'signature') {
data[field] = utils.strip_tags(data[field]);
- }
+ }
- User.setUserField(uid, field, data[field]);
+ User.setUserField(uid, field, data[field]);
callback(null);
} else {
@@ -301,7 +301,7 @@ var utils = require('./../public/src/utils.js'),
User.changePassword = function(uid, data, callback) {
if(!utils.isPasswordValid(data.newPassword)) {
callback({err:'Invalid password!'});
- return;
+ return;
}
User.getUserField(uid, 'password', function(user_password) {
@@ -343,12 +343,12 @@ var utils = require('./../public/src/utils.js'),
User.getUsers = function(set, start, stop, callback) {
var data = [];
-
+
RDB.zrevrange(set, start, stop, function(err, uids) {
if(err) {
return callback(err, null);
}
-
+
function iterator(uid, callback) {
User.getUserData(uid, function(userData) {
if(userData) {
@@ -357,7 +357,7 @@ var utils = require('./../public/src/utils.js'),
callback(null);
});
}
-
+
async.eachSeries(uids, iterator, function(err) {
callback(err, data);
});
@@ -370,7 +370,7 @@ var utils = require('./../public/src/utils.js'),
default: 'identicon',
rating: 'pg'
};
-
+
if (!email) {
email = '';
options.forcedefault = 'y';
@@ -385,7 +385,7 @@ var utils = require('./../public/src/utils.js'),
return;
}
- bcrypt.genSalt(config.bcrypt_rounds, function(err, salt) {
+ bcrypt.genSalt(nconf.get('bcrypt_rounds'), function(err, salt) {
bcrypt.hash(password, salt, function(err, hash) {
callback(hash);
});
@@ -421,7 +421,7 @@ var utils = require('./../public/src/utils.js'),
User.incrementUserFieldBy(uid, 'postcount', 1, function(err, newpostcount) {
RDB.zadd('users:postcount', newpostcount, uid);
});
-
+
User.setUserField(uid, 'lastposttime', timestamp);
User.sendPostNotificationToFollowers(uid, tid, pid);
@@ -450,9 +450,9 @@ var utils = require('./../public/src/utils.js'),
}
User.sendConfirmationEmail = function (email) {
- if (global.config['email:host'] && global.config['email:port'] && global.config['email:from']) {
+ if (meta.config['email:host'] && meta.config['email:port'] && meta.config['email:from']) {
var confirm_code = utils.generateUUID(),
- confirm_link = config.url + 'confirm/' + confirm_code,
+ confirm_link = nconf.get('url') + 'confirm/' + confirm_code,
confirm_email = global.templates['emails/header'] + global.templates['emails/email_confirm'].parse({'CONFIRM_LINK': confirm_link}) + global.templates['emails/footer'],
confirm_email_plaintext = global.templates['emails/email_confirm_plaintext'].parse({ 'CONFIRM_LINK': confirm_link });
@@ -466,10 +466,10 @@ var utils = require('./../public/src/utils.js'),
RDB.set(confirm_key, email);
RDB.expire(confirm_key, expiry_time);
- // Send intro email w/ confirm code
+ // Send intro email w/ confirm code
var message = emailjs.message.create({
text: confirm_email_plaintext,
- from: config.mailer.from,
+ from: meta.config.mailer.from,
to: email,
subject: '[NodeBB] Registration Email Verification',
attachment: [
@@ -577,7 +577,7 @@ var utils = require('./../public/src/utils.js'),
callback(null);
});
}
-
+
async.eachSeries(uids, iterator, function(err) {
callback(returnData);
});
@@ -625,8 +625,9 @@ var utils = require('./../public/src/utils.js'),
RDB.zrevrange('users:joindate', 0, 0, function(err, uid) {
RDB.handle(err);
- User.getUserFields(uid, ['username', 'userslug'], function(userData) {
- socket.emit('user.latest', {userslug: userData.userslug, username: userData.username});
+ User.getUserFields(uid, ['username', 'userslug'], function(err, userData) {
+ if(!err && userData)
+ socket.emit('user.latest', {userslug: userData.userslug, username: userData.username});
});
});
}
@@ -664,7 +665,7 @@ var utils = require('./../public/src/utils.js'),
}
async.eachSeries(uids, iterator, function(err) {
- callback(usernames);
+ callback(usernames);
});
}
@@ -683,7 +684,7 @@ var utils = require('./../public/src/utils.js'),
}
async.eachSeries(uids, iterator, function(err) {
- callback(userslugs);
+ callback(userslugs);
});
}
@@ -792,7 +793,7 @@ var utils = require('./../public/src/utils.js'),
User.reset = {
validate: function(socket, code, callback) {
-
+
if (typeof callback !== 'function') {
callback = null;
}
@@ -848,7 +849,7 @@ var utils = require('./../public/src/utils.js'),
var message = emailjs.message.create({
text: reset_email_plaintext,
- from: config.mailer?config.mailer.from:'localhost@example.org',
+ from: meta.config.mailer?meta.config.mailer.from:'localhost@example.org',
to: email,
subject: 'Password Reset Requested',
attachment: [
diff --git a/src/webserver.js b/src/webserver.js
index e642441d6a..9a57c2aa25 100644
--- a/src/webserver.js
+++ b/src/webserver.js
@@ -10,7 +10,7 @@ var express = require('express'),
utils = require('../public/src/utils.js'),
pkg = require('../package.json'),
fs = require('fs'),
-
+
user = require('./user.js'),
categories = require('./categories.js'),
posts = require('./posts.js'),
@@ -26,7 +26,7 @@ var express = require('express'),
(function(app) {
var templates = null;
-
+
/**
* `options` object requires: req, res
* accepts: metaTags
@@ -36,13 +36,13 @@ var express = require('express'),
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
{ name: 'content-type', content: 'text/html; charset=UTF-8' },
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
- { property: 'og:site_name', content: global.config.title || 'NodeBB' },
+ { property: 'og:site_name', content: meta.config.title || 'NodeBB' },
],
metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])),
templateValues = {
- cssSrc: global.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css',
- title: global.config['title'] || 'NodeBB',
- browserTitle: global.config['title'] || 'NodeBB',
+ cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css',
+ title: meta.config['title'] || 'NodeBB',
+ browserTitle: meta.config['title'] || 'NodeBB',
csrf: options.res.locals.csrf_token,
relative_path: nconf.get('relative_path'),
meta_tags: metaString
@@ -83,11 +83,11 @@ var express = require('express'),
}
auth.initialize(app);
-
+
app.use(function(req, res, next) {
-
+
nconf.set('https', req.secure);
-
+
// Don't bother with session handling for API requests
if (/^\/api\//.test(req.url)) return next();
@@ -100,7 +100,7 @@ var express = require('express'),
next();
});
-
+
app.use(app.router);
app.use(function(req, res, next) {
@@ -118,28 +118,28 @@ var express = require('express'),
res.send({ error: 'Not found' });
return;
}
-
+
// default to plain-text. send()
res.type('txt').send('Not found');
});
app.use(function(err, req, res, next) {
-
+
// we may use properties of the error object
// here and next(err) appropriately, or if
// we possibly recovered from the error, simply next().
console.error(err.stack);
-
+
res.status(err.status || 500);
-
+
res.json('500', { error: err.message });
- });
-
+ });
+
app.create_route = function(url, tpl) { // to remove
return '';
};
-
+
app.namespace(nconf.get('relative_path'), function() {
@@ -149,20 +149,20 @@ var express = require('express'),
installRoute.create_routes(app);
testBed.create_routes(app);
apiRoute.create_routes(app);
-
-
+
+
// Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section)
(function() {
var routes = ['login', 'register', 'account', 'recent', 'unread', 'popular', 'active', '403', '404'];
-
+
for (var i=0, ii=routes.length; i 0)) {
-
+
user.getUserField(req.user.uid, 'userslug', function(userslug) {
- res.redirect('/users/'+userslug);
+ res.redirect('/users/'+userslug);
});
return;
}
@@ -174,7 +174,7 @@ var express = require('express'),
}(routes[i]));
}
}());
-
+
app.get('/', function(req, res) {
async.parallel({
@@ -183,9 +183,9 @@ var express = require('express'),
req: req,
res: res,
metaTags: [
- { name: "title", content: global.config.title || 'NodeBB' },
- { name: "description", content: global.config.description || '' },
- { property: 'og:title', content: 'Index | ' + (global.config.title || 'NodeBB') },
+ { name: "title", content: meta.config.title || 'NodeBB' },
+ { name: "description", content: meta.config.description || '' },
+ { property: 'og:title', content: 'Index | ' + (meta.config.title || 'NodeBB') },
{ property: "og:type", content: 'website' }
]
}, next);
@@ -204,7 +204,7 @@ var express = require('express'),
);
})
});
-
+
app.get('/topic/:topic_id/:slug?', function(req, res) {
var tid = req.params.topic_id;
@@ -214,7 +214,7 @@ var express = require('express'),
res.type('text').send(404, "Unable to locate an rss feed at this location.");
return;
}
-
+
res.type('xml').set('Content-Length', data.length).send(data);
});
return;
@@ -241,7 +241,7 @@ var express = require('express'),
res: res,
metaTags: [
{ name: "title", content: topicData.topic_name },
- { property: 'og:title', content: topicData.topic_name + ' | ' + (global.config.title || 'NodeBB') },
+ { property: 'og:title', content: topicData.topic_name + ' | ' + (meta.config.title || 'NodeBB') },
{ property: "og:type", content: 'article' },
{ property: "og:url", content: nconf.get('url') + 'topic/' + topicData.slug },
{ property: 'og:image', content: topicData.main_posts[0].picture },
@@ -271,7 +271,7 @@ var express = require('express'),
app.get('/category/:category_id/:slug?', function(req, res) {
var cid = req.params.category_id;
-
+
if (cid.match(/^\d+\.rss$/)) {
fs.readFile('feeds/categories/' + cid, function (err, data) {
if (err) {
@@ -378,20 +378,20 @@ var express = require('express'),
templates['footer']
);
});
- });
+ });
app.get('/search', function(req, res) {
app.build_header({ req: req, res: res }, function(err, header) {
res.send(header + app.create_route("search", null, "search") + templates['footer']);
});
});
-
+
app.get('/search/:term', function(req, res) {
app.build_header({ req: req, res: res }, function(err, header) {
res.send(header + app.create_route("search/"+req.params.term, null, "search") + templates['footer']);
});
});
-
+
app.get('/reindex', function(req, res) {
topics.reIndexAll(function(err) {
if(err) {
@@ -401,7 +401,7 @@ var express = require('express'),
}
});
});
-
+
});
}(WebServer));
diff --git a/src/websockets.js b/src/websockets.js
index 1496100b4b..cb4f7b68dc 100644
--- a/src/websockets.js
+++ b/src/websockets.js
@@ -28,7 +28,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
},
plugins = require('./plugins'),
winston = require('winston');
-
+
(function(io) {
var users = {},
userSockets = {},
@@ -49,11 +49,11 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
userSockets[uid] = userSockets[uid] || [];
userSockets[uid].push(socket);
-
+
if(uid) {
socket.join('uid_' + uid);
io.sockets.in('global').emit('api:user.isOnline', isUserOnline(uid));
-
+
user.getUserField(uid, 'username', function(username) {
socket.emit('event:connect', {status: 1, username:username});
});
@@ -61,10 +61,10 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
});
});
-
-
+
+
socket.on('disconnect', function() {
-
+
var index = userSockets[uid].indexOf(socket);
if(index !== -1) {
userSockets[uid].splice(index, 1);
@@ -74,17 +74,17 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
delete users[sessionID];
if(uid)
io.sockets.in('global').emit('api:user.isOnline', isUserOnline(uid));
- }
-
+ }
+
for(var roomName in rooms) {
socket.leave(roomName);
if(rooms[roomName][socket.id]) {
delete rooms[roomName][socket.id];
- }
-
- updateRoomBrowsingText(roomName);
+ }
+
+ updateRoomBrowsingText(roomName);
}
});
@@ -106,7 +106,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
function getAnonymousCount(roomName) {
var clients = io.sockets.clients(roomName);
var anonCount = 0;
-
+
for(var i=0; i' + '' + users[i].username + '';
}
-
- var joiner = anonymousCount + userCount == 1 ? 'is' : 'are',
+
+ var joiner = anonymousCount + userCount == 1 ? 'is' : 'are',
userList = anonymousCount > 0 ? usernames.concat(util.format('%d guest%s', anonymousCount, anonymousCount > 1 ? 's' : '')) : usernames,
lastUser = userList.length > 1 ? ' and ' + userList.pop() : '';
@@ -146,18 +146,18 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
}
socket.on('event:enter_room', function(data) {
-
+
if (data.leave !== null) {
socket.leave(data.leave);
}
-
+
socket.join(data.enter);
rooms[data.enter] = rooms[data.enter] || {};
if (uid) {
rooms[data.enter][socket.id] = uid;
-
+
if (data.leave && rooms[data.leave] && rooms[data.leave][socket.id]) {
delete rooms[data.leave][socket.id];
}
@@ -168,18 +168,20 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
updateRoomBrowsingText(data.enter);
- if (data.enter != 'admin')
+ if (data.enter != 'admin')
io.sockets.in('admin').emit('api:get_all_rooms', io.sockets.manager.rooms);
-
+
});
// BEGIN: API calls (todo: organize)
socket.on('api:updateHeader', function(data) {
if(uid) {
- user.getUserFields(uid, data.fields, function(fields) {
- fields.uid = uid;
- socket.emit('api:updateHeader', fields);
+ user.getUserFields(uid, data.fields, function(err, fields) {
+ if(!err && fields) {
+ fields.uid = uid;
+ socket.emit('api:updateHeader', fields);
+ }
});
}
else {
@@ -190,9 +192,9 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
picture: require('gravatar').url('', {s:'24'}, https=nconf.get('https'))
});
}
-
+
});
-
+
socket.on('user.exists', function(data) {
user.exists(utils.slugify(data.username), function(exists){
socket.emit('user.exists', {exists: exists});
@@ -233,12 +235,12 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
socket.on('api:user.get_online_users', function(data) {
var returnData = [];
-
+
for(var i=0; i 0) {
topics.getTopicData(data.tid, function(topicData) {
- if (data.body)
+ if (data.body)
topicData.body = data.body;
socket.emit('api:composer.push', {
@@ -555,14 +561,16 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
});
});
} else if (parseInt(data.cid) > 0) {
- user.getUserFields(uid, ['username', 'picture'], function(userData) {
- socket.emit('api:composer.push', {
- tid: 0,
- cid: data.cid,
- username: userData.username,
- picture: userData.picture,
- title: undefined
- });
+ user.getUserFields(uid, ['username', 'picture'], function(err, userData) {
+ if(!err && userData) {
+ socket.emit('api:composer.push', {
+ tid: 0,
+ cid: data.cid,
+ username: userData.username,
+ picture: userData.picture,
+ title: undefined
+ });
+ }
});
} else if (parseInt(data.pid) > 0) {
async.parallel([
@@ -630,16 +638,16 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
socket.on('api:topic.loadMore', function(data, callback) {
var start = data.after,
end = start + 9;
-
+
topics.getTopicPosts(data.tid, start, end, uid, function(posts) {
callback({posts:posts});
});
});
-
+
socket.on('api:category.loadMore', function(data, callback) {
var start = data.after,
end = start + 9;
-
+
categories.getCategoryTopics(data.cid, start, end, uid, function(topics) {
callback({topics:topics});
});
@@ -653,11 +661,11 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
callback(latestTopics);
});
});
-
+
socket.on('api:topics.loadMoreUnreadTopics', function(data, callback) {
var start = data.after,
end = start + 9;
-
+
topics.getUnreadTopics(uid, start, end, function(unreadTopics) {
callback(unreadTopics);
});
@@ -666,14 +674,14 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
socket.on('api:users.loadMore', function(data, callback) {
var start = data.after,
end = start + 19;
-
+
user.getUsers(data.set, start, end, function(err, data) {
if(err) {
winston.err(err);
} else {
callback({users:data});
}
- });
+ });
});
socket.on('api:admin.topics.getMore', function(data, callback) {
@@ -685,13 +693,13 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
socket.on('api:admin.categories.update', function(data) {
admin.categories.update(data, socket);
});
-
+
socket.on('api:admin.user.makeAdmin', function(theirid) {
if(uid && uid > 0) {
admin.user.makeAdmin(uid, theirid, socket);
}
});
-
+
socket.on('api:admin.user.removeAdmin', function(theirid) {
if(uid && uid > 0) {
admin.user.removeAdmin(uid, theirid, socket);
@@ -744,5 +752,5 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
});
});
});
-
+
}(SocketIO));