mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 03:26:04 +01:00
refactoring installation scripts to use node prompt module, lots of other fixes
fixed #263, fixed #264, fixed #265
This commit is contained in:
64
app.js
64
app.js
@@ -50,15 +50,9 @@ winston.err = function(err) {
|
||||
winston.info('NodeBB v' + pkg.version + ' Copyright (C) 2013 DesignCreatePlay Inc.');
|
||||
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('===');
|
||||
winston.info('');
|
||||
|
||||
|
||||
|
||||
if(nconf.get('upgrade')) {
|
||||
meta.configs.init(function() {
|
||||
require('./src/upgrade').upgrade();
|
||||
});
|
||||
} else if (!nconf.get('setup') && nconf.get('base_url')) {
|
||||
if (!nconf.get('setup') && !nconf.get('upgrade') && 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/');
|
||||
|
||||
@@ -82,14 +76,7 @@ if(nconf.get('upgrade')) {
|
||||
'categories': require('./src/admin/categories.js')
|
||||
};
|
||||
|
||||
DEVELOPMENT = true;
|
||||
|
||||
global.configuration = {};
|
||||
global.templates = {};
|
||||
|
||||
(function(config) {
|
||||
config['ROOT_DIRECTORY'] = __dirname;
|
||||
|
||||
templates.init([
|
||||
'header', 'footer', 'logout', 'outgoing', 'admin/header', 'admin/footer', 'admin/index',
|
||||
'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext',
|
||||
@@ -99,60 +86,29 @@ if(nconf.get('upgrade')) {
|
||||
]);
|
||||
|
||||
templates.ready(webserver.init);
|
||||
|
||||
//setup scripts to be moved outside of the app in future.
|
||||
function setup_categories() {
|
||||
if (process.env.NODE_ENV === 'development') winston.info('Checking categories...');
|
||||
categories.getAllCategories(function(data) {
|
||||
if (data.categories.length === 0) {
|
||||
winston.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) {
|
||||
admin.categories.create(default_categories[category]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
winston.info('Hardcoding uid 1 as an admin');
|
||||
var user = require('./src/user.js');
|
||||
user.makeAdministrator(1);
|
||||
|
||||
|
||||
} else {
|
||||
if (process.env.NODE_ENV === 'development') winston.info('Categories OK. Found ' + data.categories.length + ' categories.');
|
||||
}
|
||||
} else if (nconf.get('upgrade')) {
|
||||
meta.configs.init(function() {
|
||||
require('./src/upgrade').upgrade();
|
||||
});
|
||||
}
|
||||
|
||||
setup_categories();
|
||||
}(global.configuration));
|
||||
});
|
||||
|
||||
} else {
|
||||
// New install, ask setup questions
|
||||
if (nconf.get('setup')) winston.info('NodeBB Setup Triggered via Command Line');
|
||||
else winston.warn('Configuration not found, starting NodeBB setup');
|
||||
|
||||
meta.config = {};
|
||||
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"
|
||||
);
|
||||
winston.info('Welcome to NodeBB!');
|
||||
winston.info('This looks like a new installation, so you\'ll have to answer a few questions about your environment before we can proceed.');
|
||||
winston.info('Press enter to accept the default setting (shown in brackets).');
|
||||
|
||||
install.setup(function(err) {
|
||||
if (err) {
|
||||
winston.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"
|
||||
);
|
||||
}
|
||||
winston.info('NodeBB Setup Completed.');
|
||||
}
|
||||
|
||||
process.exit();
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
"winston": "~0.7.2",
|
||||
"nodebb-plugin-mentions": "~0.1.0",
|
||||
"nodebb-plugin-markdown": "~0.1.0",
|
||||
"rss": "~0.2.0"
|
||||
"rss": "~0.2.0",
|
||||
"prompt": "~0.2.11"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/designcreateplay/NodeBB/issues"
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
for (var t in templatesToLoad) {
|
||||
(function(file) {
|
||||
fs.readFile(global.configuration.ROOT_DIRECTORY + '/public/templates/' + file + '.tpl', function(err, html) {
|
||||
fs.readFile(__dirname + '/../templates/' + file + '.tpl', function(err, html) {
|
||||
var template = function() {
|
||||
this.toString = function() {
|
||||
return this.html;
|
||||
@@ -90,8 +90,6 @@
|
||||
config = config_data[0];
|
||||
available_templates = templates_data[0];
|
||||
|
||||
|
||||
|
||||
templates.ready();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
//Adapted from http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
|
||||
walk: function(dir, done) {
|
||||
var main_dir = global.configuration.ROOT_DIRECTORY + '/public/templates/';
|
||||
var results = [];
|
||||
var results = [],
|
||||
templateExtract = /\/([\w\d\-_]+)\.tpl$/;
|
||||
fs.readdir(dir, function(err, list) {
|
||||
if (err) return done(err);
|
||||
var pending = list.length;
|
||||
@@ -32,7 +32,10 @@
|
||||
if (!--pending) done(null, results);
|
||||
});
|
||||
} else {
|
||||
results.push(file.replace(main_dir, '').replace('.tpl', ''));
|
||||
var templateMatch = file.match(templateExtract);
|
||||
|
||||
if (templateMatch) results.push(templateMatch[1]);
|
||||
// results.push(file.replace(main_dir, '').replace('.tpl', ''));
|
||||
if (!--pending) done(null, results);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ var RDB = require('./../redis.js'),
|
||||
|
||||
RDB.set('categoryslug:' + slug + ':cid', cid);
|
||||
|
||||
if (callback) callback({'status': 1});
|
||||
if (callback) callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var async = require('async'),
|
||||
User = require('./user'),
|
||||
RDB = RDB || require('./redis'),
|
||||
Groups = {
|
||||
list: function(options, callback) {
|
||||
RDB.hvals('group:gid', function(err, gids) {
|
||||
|
||||
212
src/install.js
212
src/install.js
@@ -4,70 +4,84 @@ var async = require('async'),
|
||||
url = require('url'),
|
||||
path = require('path'),
|
||||
meta = require('./meta'),
|
||||
User = require('./user'),
|
||||
Groups = require('./groups'),
|
||||
Categories = require('./categories'),
|
||||
prompt = require('prompt'),
|
||||
admin = {
|
||||
categories: require('./admin/categories')
|
||||
},
|
||||
winston = require('winston'),
|
||||
|
||||
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)'
|
||||
{
|
||||
name: 'base_url',
|
||||
description: 'URL of this installation',
|
||||
'default': 'http://localhost',
|
||||
pattern: /^http(?:s)?:\/\//,
|
||||
message: 'Base URL must begin with \'http://\' or \'https://\'',
|
||||
},
|
||||
{
|
||||
name: 'port',
|
||||
description: 'Port number of your NodeBB',
|
||||
'default': 4567
|
||||
},
|
||||
{
|
||||
name: 'use_port',
|
||||
description: 'Use a port number to access NodeBB?',
|
||||
'default': 'y',
|
||||
pattern: /y[es]*|n[o]?/,
|
||||
message: 'Please enter \'yes\' or \'no\'',
|
||||
},
|
||||
{
|
||||
name: 'secret',
|
||||
description: 'Please enter a NodeBB secret',
|
||||
'default': utils.generateUUID()
|
||||
},
|
||||
{
|
||||
name: 'redis:host',
|
||||
description: 'Host IP or address of your Redis instance',
|
||||
'default': '127.0.0.1'
|
||||
},
|
||||
{
|
||||
name: 'redis:port',
|
||||
description: 'Host port of your Redis instance',
|
||||
'default': 6379
|
||||
},
|
||||
{
|
||||
name: 'redis:password',
|
||||
description: 'Password of your Redis database'
|
||||
}
|
||||
],
|
||||
defaults: {
|
||||
"base_url": 'http://localhost',
|
||||
"port": 4567,
|
||||
"use_port": true,
|
||||
"redis": {
|
||||
"host": '127.0.0.1',
|
||||
"port": 6379,
|
||||
"password": ''
|
||||
},
|
||||
"secret": utils.generateUUID(),
|
||||
"bcrypt_rounds": 12,
|
||||
"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.series([
|
||||
function(next) {
|
||||
// prompt prepends "prompt: " to questions, let's clear that.
|
||||
prompt.start();
|
||||
prompt.message = '';
|
||||
prompt.delimiter = '';
|
||||
|
||||
async.eachSeries(install.questions, function(question, next) {
|
||||
var question = question.split('|');
|
||||
install.ask(question[1], function(value) {
|
||||
switch(question[0]) {
|
||||
case 'use_port':
|
||||
value = value.toLowerCase();
|
||||
if (['y', 'yes', ''].indexOf(value) === -1) config[question[0]] = false;
|
||||
break;
|
||||
case 'redis:host':
|
||||
config.redis = config.redis || {};
|
||||
if (value !== '') config.redis.host = value;
|
||||
break;
|
||||
case 'redis:port':
|
||||
config.redis = config.redis || {};
|
||||
if (value !== '') config.redis.port = value;
|
||||
break;
|
||||
case 'redis:password':
|
||||
config.redis = config.redis || {};
|
||||
if (value !== '') config.redis.password = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (value !== '') config[question[0]] = value;
|
||||
break;
|
||||
prompt.get(install.questions, function(err, config) {
|
||||
if (!config) {
|
||||
winston.warn('NodeBB Setup Aborted.');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
}, function() {
|
||||
// Translate redis properties into redis object
|
||||
config.redis = {
|
||||
host: config['redis:host'],
|
||||
port: config['redis:port'],
|
||||
password: config['redis:password']
|
||||
};
|
||||
delete config['redis:host'];
|
||||
delete config['redis:port'];
|
||||
delete config['redis:password'];
|
||||
|
||||
// Add hardcoded values
|
||||
config['bcrypt_rounds'] = 12,
|
||||
config['upload_path'] = '/public/uploads';
|
||||
|
||||
var urlObject = url.parse(config.base_url),
|
||||
relative_path = (urlObject.pathname && urlObject.pathname.length > 1) ? urlObject.pathname : '',
|
||||
host = urlObject.host,
|
||||
@@ -92,7 +106,84 @@ var async = require('async'),
|
||||
meta.configs.set('minimumPasswordLength', 6);
|
||||
meta.configs.set('imgurClientID', '');
|
||||
|
||||
install.save(server_conf, client_conf, callback);
|
||||
install.save(server_conf, client_conf, next);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
// Check if an administrator needs to be created
|
||||
Groups.getGidFromName('Administrators', function(err, gid) {
|
||||
if (err) return next(new Error('Could not save configs'));
|
||||
|
||||
if (gid) {
|
||||
Groups.get(gid, {}, function(err, groupObj) {
|
||||
if (groupObj.count > 0) {
|
||||
winston.info('Administrator found, skipping Admin setup');
|
||||
next();
|
||||
} else install.createAdmin(next);
|
||||
});
|
||||
} else install.createAdmin(next);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
// Categories
|
||||
categories.getAllCategories(function(data) {
|
||||
if (data.categories.length === 0) {
|
||||
winston.warn('No categories found, populating instance with default categories')
|
||||
|
||||
fs.readFile(path.join(__dirname, '../', 'install/data/categories.json'), function(err, default_categories) {
|
||||
default_categories = JSON.parse(default_categories);
|
||||
|
||||
async.eachSeries(default_categories, function(category, next) {
|
||||
admin.categories.create(category, next);
|
||||
}, function(err) {
|
||||
if (!err) next();
|
||||
else winston.error('Could not set up categories');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
winston.info('Categories OK. Found ' + data.categories.length + ' categories.');
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
},
|
||||
createAdmin: function(callback) {
|
||||
winston.warn('No administrators have been detected, running initial user setup');
|
||||
var questions = [
|
||||
{
|
||||
name: 'username',
|
||||
description: 'Administrator username',
|
||||
required: true,
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
description: 'Administrator email address',
|
||||
pattern: /.+@.+/,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'password',
|
||||
description: 'Password',
|
||||
required: true,
|
||||
hidden: true,
|
||||
type: 'string'
|
||||
}
|
||||
];
|
||||
|
||||
prompt.get(questions, function(err, results) {
|
||||
nconf.set('bcrypt_rounds', 12);
|
||||
User.create(results.username, results.password, results.email, function(err, uid) {
|
||||
Groups.getGidFromName('Administrators', function(err, gid) {
|
||||
if (gid) Groups.join(gid, uid, callback);
|
||||
else {
|
||||
Groups.create('Administrators', 'Forum Administrators', function(err, groupObj) {
|
||||
Groups.join(groupObj.gid, uid, callback);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
save: function(server_conf, client_conf, callback) {
|
||||
@@ -109,10 +200,7 @@ var async = require('async'),
|
||||
});
|
||||
}
|
||||
], function(err) {
|
||||
process.stdout.write(
|
||||
"\n\nConfiguration Saved OK\n\n"
|
||||
);
|
||||
|
||||
winston.info('Configuration Saved OK');
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ var user = require('./user.js'),
|
||||
(function(Login){
|
||||
|
||||
Login.loginViaLocal = function(username, password, next) {
|
||||
|
||||
if (!username || !password) {
|
||||
return next({
|
||||
status: 'error',
|
||||
@@ -26,8 +25,7 @@ var user = require('./user.js'),
|
||||
}
|
||||
|
||||
user.getUserFields(uid, ['password', 'banned'], function(err, userData) {
|
||||
if(err)
|
||||
return next(err);
|
||||
if(err) return next(err);
|
||||
|
||||
if(userData.banned && userData.banned === '1') {
|
||||
return next({
|
||||
@@ -38,7 +36,7 @@ var user = require('./user.js'),
|
||||
|
||||
bcrypt.compare(password, userData.password, function(err, res) {
|
||||
if(err) {
|
||||
winston.err(err);
|
||||
winston.err(err.message);
|
||||
next({
|
||||
status: "error",
|
||||
message: 'bcrypt compare error'
|
||||
|
||||
@@ -4,13 +4,14 @@ var user = require('./../user.js'),
|
||||
categories = require('./../categories.js')
|
||||
utils = require('./../../public/src/utils.js'),
|
||||
pkg = require('../../package.json'),
|
||||
meta = require('./../meta.js');
|
||||
meta = require('./../meta.js'),
|
||||
path = require('path');
|
||||
|
||||
|
||||
(function(Api) {
|
||||
Api.create_routes = function(app) {
|
||||
app.get('/api/get_templates_listing', function(req, res) {
|
||||
utils.walk(global.configuration.ROOT_DIRECTORY + '/public/templates', function(err, data) {
|
||||
utils.walk(path.join(__dirname, '../../', 'public/templates'), function(err, data) {
|
||||
res.json(data);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -131,7 +131,7 @@ var user = require('./../user.js'),
|
||||
return;
|
||||
}
|
||||
|
||||
var absolutePath = path.join(global.configuration['ROOT_DIRECTORY'], global.nconf.get('upload_path'), path.basename(oldpicture));
|
||||
var absolutePath = path.join(__dirname, '../', global.nconf.get('upload_path'), path.basename(oldpicture));
|
||||
|
||||
fs.unlink(absolutePath, function(err) {
|
||||
if(err) {
|
||||
@@ -152,7 +152,7 @@ var user = require('./../user.js'),
|
||||
}
|
||||
|
||||
var filename = uid + '-profileimg' + extension;
|
||||
var uploadPath = path.join(global.configuration['ROOT_DIRECTORY'], global.nconf.get('upload_path'), filename);
|
||||
var uploadPath = path.join(__dirname, '../', global.nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: '+ uploadPath);
|
||||
|
||||
|
||||
19
src/user.js
19
src/user.js
@@ -84,7 +84,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
RDB.incr('usercount', function(err, count) {
|
||||
RDB.handle(err);
|
||||
|
||||
io.sockets.emit('user.count', {count: count});
|
||||
if (typeof io !== 'undefined') io.sockets.emit('user.count', {count: count});
|
||||
});
|
||||
|
||||
RDB.zadd('users:joindate', timestamp, uid);
|
||||
@@ -93,16 +93,15 @@ var utils = require('./../public/src/utils.js'),
|
||||
|
||||
userSearch.index(username, uid);
|
||||
|
||||
io.sockets.emit('user.latest', {userslug: userslug, username: username});
|
||||
if (typeof io !== 'undefined') io.sockets.emit('user.latest', {userslug: userslug, username: username});
|
||||
|
||||
if (password !== undefined) {
|
||||
User.hashPassword(password, function(hash) {
|
||||
User.hashPassword(password, function(err, hash) {
|
||||
User.setUserField(uid, 'password', hash);
|
||||
});
|
||||
}
|
||||
|
||||
callback(null, uid);
|
||||
});
|
||||
} else callback(null, uid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -309,7 +308,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
}
|
||||
|
||||
if (res) {
|
||||
User.hashPassword(data.newPassword, function(hash) {
|
||||
User.hashPassword(data.newPassword, function(err, hash) {
|
||||
User.setUserField(uid, 'password', hash);
|
||||
|
||||
callback({err:null});
|
||||
@@ -382,9 +381,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
}
|
||||
|
||||
bcrypt.genSalt(nconf.get('bcrypt_rounds'), function(err, salt) {
|
||||
bcrypt.hash(password, salt, function(err, hash) {
|
||||
callback(hash);
|
||||
});
|
||||
bcrypt.hash(password, salt, callback);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -906,7 +903,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
RDB.handle(err);
|
||||
}
|
||||
|
||||
User.hashPassword(password, function(hash) {
|
||||
User.hashPassword(password, function(err, hash) {
|
||||
User.setUserField(uid, 'password', hash);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user