var mongoose = require('mongoose'), nconf = require('nconf'), express = require('express'), http = require('http'), path = require('path'), app = require('./app.js'); //NConf Configuration nconf.env().file({ file: 'settings.json' }); //Mongoose Configuration mongoose.connect(nconf.get('database:MONGOHQ_URL'), { user: nconf.get('MONGOHQ_USERNAME'), pass: nconf.get('MONGOHQ_PASSWORD') }); mongoose.connection.on('error', function() { console.log("Database error") }); mongoose.connection.once('open', function() { console.log("Database connected") }); //Create Twilio Instance var twilio = require('twilio')(nconf.get('TWILIO_ACCOUNT_SID'), nconf.get('TWILIO_AUTH_TOKEN')); twilio.conferences.list(function (err, data) { data.conferences.forEach(function (conference) { twilio.conferences(conference.sid).participants.list(function (err, data) { data.participants.forEach(function (participant) { console.log("Warning: A conference call is already in progress"); console.log(JSON.stringify(participant)); }); }); }); }); //twilio.calls.list({ to: "19195332114"},
(function (app) { var templates = null, clientScripts; // Minify client-side libraries meta.js.get(function (err, scripts) { clientScripts = scripts.map(function (script) { return script = { script: script } }); }); /** * `options` object requires: req, res * accepts: metaTags */ app.build_header = function (options, callback) { var defaultMetaTags = [{ 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: meta.config.title || 'NodeBB' }], metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])), templateValues = { 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, clientScripts: clientScripts }; translator.translate(templates.header.parse(templateValues), function(template) { callback(null, template); }); }; // Middlewares app.use(express.compress()); app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico'))); app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public'), prefix: nconf.get('relative_path'), yuicompress: true })); app.use(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.session({ store: new RedisStore({ client: RDB, ttl: 60 * 60 * 24 * 30 }), secret: nconf.get('secret'), key: 'express.sid', cookie: { maxAge: 60 * 60 * 24 * 30 * 1000 // 30 days } })); app.use(express.csrf()); app.use(function (req, res, next) { res.locals.csrf_token = req.session._csrf; next(); }); // Static Directories for NodeBB Plugins app.configure(function () { var tailMiddlewares = []; plugins.ready(function () { // Remove some middlewares until the router is gone // This is not recommended behaviour: http://stackoverflow.com/a/13691542/122353 // Also: https://www.exratione.com/2013/03/nodejs-abusing-express-3-to-enable-late-addition-of-middleware/ tailMiddlewares.push(app.stack.pop()); tailMiddlewares.push(app.stack.pop()); tailMiddlewares.push(app.stack.pop()); for (d in plugins.staticDirs) { app.use(nconf.get('relative_path') + '/plugins/' + d, express.static(plugins.staticDirs[d])); } // Push the removed middlewares back onto the application stack tailMiddlewares.reverse(); app.stack.push(tailMiddlewares.shift()); app.stack.push(tailMiddlewares.shift()); app.stack.push(tailMiddlewares.shift()); }); }); module.exports.init = function () { templates = global.templates; // translate all static templates served by webserver here. ex. footer, logout translator.translate(templates['footer'].toString(), function(parsedTemplate) { templates['footer'] = parsedTemplate; }); translator.translate(templates['logout'].toString(), function(parsedTemplate) { templates['logout'] = parsedTemplate; }); server.listen(nconf.get('PORT') || nconf.get('port')); } auth.initialize(app); app.use(function (req, res, next) { nconf.set('https', req.secure); next(); }); app.use(app.router); app.use(function (req, res, next) { res.status(404); // respond with html page if (req.accepts('html')) { //res.json('404', { url: req.url }); res.redirect(nconf.get('relative_path') + '/404'); return; } // respond with json if (req.accepts('json')) { 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 '<script>templates.ready(function(){ajaxify.go("' + url + '", null, "' + tpl + '");});</script>'; }; app.namespace(nconf.get('relative_path'), function () { auth.create_routes(app); admin.create_routes(app); userRoute.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 < ii; i++) { (function (route) { app.get('/' + route, function (req, res) { if ((route === 'login' || route === 'register') && (req.user && req.user.uid > 0)) { user.getUserField(req.user.uid, 'userslug', function (err, userslug) { res.redirect('/user/' + userslug); }); return; } app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route(route) + templates['footer']); }); }); }(routes[i])); } }()); app.get('/', function (req, res) { async.parallel({ "header": function (next) { app.build_header({ req: req, res: res, metaTags: [{ 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); }, "categories": function (next) { categories.getAllCategories(function (returnData) { returnData.categories = returnData.categories.filter(function (category) { if (category.disabled !== '1') return true; else return false; }); next(null, returnData); }, 0); } }, function (err, data) { res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + templates['noscript/home'].parse(data.categories) + '\n\t</noscript>' + app.create_route('') + templates['footer'] ); }) }); app.get('/topic/:topic_id/:slug?', function (req, res) { var tid = req.params.topic_id; if (tid.match(/^\d+\.rss$/)) { tid = tid.slice(0, -4); var rssPath = path.join(__dirname, '../', 'feeds/topics', tid + '.rss'), loadFeed = function () { fs.readFile(rssPath, function (err, data) { if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); else res.type('xml').set('Content-Length', data.length).send(data); }); }; if (!fs.existsSync(rssPath)) { feed.updateTopic(tid, function (err) { if (err) res.redirect('/404'); else loadFeed(); }); } else loadFeed(); return; } async.waterfall([ function (next) { topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function (err, topicData) { if (topicData) { if (topicData.deleted === '1' && topicData.expose_tools === 0) return next(new Error('Topic deleted'), null); } next(err, topicData); }); }, function (topicData, next) { var lastMod = 0, timestamp; for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) { timestamp = parseInt(topicData.posts[x].timestamp, 10); if (timestamp > lastMod) lastMod = timestamp; } app.build_header({ req: req, res: res, metaTags: [{ name: "title", content: topicData.topic_name }, { 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 }, { property: "article:published_time", content: new Date(parseInt(topicData.main_posts[0].timestamp, 10)).toISOString() }, { property: 'article:modified_time', content: new Date(lastMod).toISOString() }, { property: 'article:section', content: topicData.category_name }] }, function (err, header) { next(err, { header: header, topics: topicData }); }); }, ], function (err, data) { if (err) return res.redirect('404'); var topic_url = tid + (req.params.slug ? '/' + req.params.slug : ''); res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + templates['noscript/topic'].parse(data.topics) + '\n\t</noscript>' + '\n\t<script>templates.ready(function(){ajaxify.go("topic/' + topic_url + '");});</script>' + templates['footer'] ); }); }); app.get('/category/:category_id/:slug?', function (req, res) { var cid = req.params.category_id; if (cid.match(/^\d+\.rss$/)) { cid = cid.slice(0, -4); var rssPath = path.join(__dirname, '../', 'feeds/categories', cid + '.rss'), loadFeed = function () { fs.readFile(rssPath, function (err, data) { if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); else res.type('xml').set('Content-Length', data.length).send(data); }); }; if (!fs.existsSync(rssPath)) { feed.updateCategory(cid, function (err) { if (err) res.redirect('/404'); else loadFeed(); }); } else loadFeed(); return; } async.waterfall([ function (next) { categories.getCategoryById(cid, 0, function (err, categoryData) { if (categoryData) { if (categoryData.disabled === '1') return next(new Error('Category disabled'), null); } next(err, categoryData); }); }, function (categoryData, next) { app.build_header({ req: req, res: res, metaTags: [{ name: 'title', content: categoryData.category_name }, { name: 'description', content: categoryData.category_description }, { property: "og:type", content: 'website' }] }, function (err, header) { next(err, { header: header, categories: categoryData }); }); } ], function (err, data) { if (err) return res.redirect('404'); var category_url = cid + (req.params.slug ? '/' + req.params.slug : ''); res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + templates['noscript/category'].parse(data.categories) + '\n\t</noscript>' + '\n\t<script>templates.ready(function(){ajaxify.go("category/' + category_url + '");});</script>' + templates['footer'] ); }); }); app.get('/confirm/:code', function (req, res) { app.build_header({ req: req, res: res }, function (err, header) { res.send(header + '<script>templates.ready(function(){ajaxify.go("confirm/' + req.params.code + '");});</script>' + templates['footer']); }); }); app.get('/sitemap.xml', function (req, res) { var sitemap = require('./sitemap.js'); sitemap.render(function (xml) { res.type('xml').set('Content-Length', xml.length).send(xml); }); }); app.get('/robots.txt', function (req, res) { res.set('Content-Type', 'text/plain'); res.send("User-agent: *\n" + "Disallow: /admin/\n" + "Sitemap: " + nconf.get('url') + "sitemap.xml"); }); app.get('/cid/:cid', function (req, res) { categories.getCategoryData(req.params.cid, function (err, data) { if (data) res.send(data); else res.send(404, "Category doesn't exist!"); }); }); app.get('/tid/:tid', function (req, res) { topics.getTopicData(req.params.tid, function (data) { if (data) res.send(data); else res.send(404, "Topic doesn't exist!"); }); }); app.get('/pid/:pid', function (req, res) { posts.getPostData(req.params.pid, function (data) { if (data) res.send(data); else res.send(404, "Post doesn't exist!"); }); }); app.get('/outgoing', function (req, res) { if (!req.query.url) return res.redirect('/404'); app.build_header({ req: req, res: res }, function (err, header) { res.send( header + '\n\t<script>templates.ready(function(){ajaxify.go("outgoing?url=' + encodeURIComponent(req.query.url) + '", null, null, true);});</script>' + templates['footer'] ); }); }); app.get('/search', function (req, res) { if (!req.user) return res.redirect('/403'); 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) { if (!req.user) return res.redirect('/403'); 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) { return res.json(err); } user.reIndexAll(function (err) { if (err) { return res.json(err); } else { res.send('Topics and users reindexed'); } }); }); }); }); }(WebServer));
module.exports = function loopmocha(grunt) { nconf.env() .argv(); // Load task grunt.loadNpmTasks('grunt-loop-mocha'); // Options return { "src": ["<%=loopmocha.basedir%>/spec/*.js"], "basedir": process.cwd() + "/" + "test/functional", "options": { "mocha": { "reportLocation": grunt.option("reportLocation") || "<%=loopmocha.basedir%>/report", "timeout": grunt.option("timeout") || 600000, "grep": grunt.option("grep") || 0, "debug": grunt.option("debug") || 0, "reporter": grunt.option("reporter") || "spec" }, "nemoData": { "autoBaseDir": "<%=loopmocha.basedir%>", "targetBrowser": nconf.get("TARGET_BROWSER") || "firefox", "targetServer": nconf.get("TARGET_SERVER") || "localhost", "targetBaseUrl": "http://*****:*****@featureGroup1@" } } , { "description": "ci-featuregroup-2", "mocha": { "grep": "@featureGroup2@" } }, { "description": "ci-featuregroup-3", "mocha": { "grep": "@featureGroup3@" } } ] } } }; };
var mongoStore = require('connect-mongo')(express); var passport = require('passport'); // Require needed files var database = require('./shop/data'); var info = require('./package.json'); var nconf = require('nconf'); nconf.env().file({ file: 'secret.json' }); console.log('NodeShop Started!'); console.log('Running Version ' + info.version); // Connect to database database.startup(nconf.get('mongodb_uri')); console.log('Connecting to database...'); // Configure Express app.configure(function() { // Set up jade app.set('views', __dirname + '/shop/views'); app.set('view engine', 'jade'); app.use(express.favicon()); app.use(express.cookieParser()); app.use(express.bodyParser()); // Set up sessions app.use(express.session({
// API v2 middlewares and routes // DEPRECATED AND INACTIVE import express from 'express'; import nconf from 'nconf'; import { NotFound, } from '../libs/errors'; const router = express.Router(); // eslint-disable-line babel/new-cap const BASE_URL = nconf.get('BASE_URL'); router.all('*', function deprecatedV2 (req, res, next) { let error = new NotFound(`API v2 is no longer supported, please use API v3 instead (${BASE_URL}/apidoc).`); return next(error); }); module.exports = router;
function (topicData, next) { var lastMod = topicData.timestamp, description = (function() { var content = ''; if(topicData.posts.length) { content = S(topicData.posts[0].content).stripTags().s; } if (content.length > 255) { content = content.substr(0, 255) + '...'; } return validator.escape(content); })(), timestamp; for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) { timestamp = parseInt(topicData.posts[x].timestamp, 10); if (timestamp > lastMod) { lastMod = timestamp; } } var ogImageUrl = meta.config['brand:logo']; if(ogImageUrl && ogImageUrl.indexOf('http') === -1) { ogImageUrl = nconf.get('url') + ogImageUrl; } app.build_header({ req: req, res: res, metaTags: [ { name: "title", content: topicData.topic_name }, { name: "description", content: description }, { property: 'og:title', content: topicData.topic_name }, { property: 'og:description', content: description }, { property: "og:type", content: 'article' }, { property: "og:url", content: nconf.get('url') + '/topic/' + topicData.slug }, { property: "og:image:url", content: ogImageUrl }, { property: 'og:image', content: topicData.posts.length?topicData.posts[0].picture:'' }, { property: "article:published_time", content: utils.toISOString(topicData.timestamp) }, { property: 'article:modified_time', content: utils.toISOString(lastMod) }, { property: 'article:section', content: topicData.category_name } ], linkTags: [ { rel: 'alternate', type: 'application/rss+xml', href: nconf.get('url') + '/topic/' + tid + '.rss' }, { rel: 'up', href: nconf.get('url') + '/category/' + topicData.category_slug } ] }, function (err, header) { next(err, { header: header, posts: topicData }); }); }
'use strict'; require('../../testutil/configureForTest'); var conf = require('nconf'); var expect = require('must'); var Activity = conf.get('beans').get('activity'); // TODO Activity.fillFromUI with null/undefined in startDate, startTime, endDate, endTime describe('Activity', function () { it('fetches the group long name', function () { var activity = new Activity({ url: 'myURL', assignedGroup: 'group' }); var groups = [ {id: 'group', longName: 'groupname'}, {id: 'other', longName: 'othername'} ]; activity.groupFrom(groups); expect(activity.groupName()).to.equal('groupname'); }); it('fetches a blank string if group not found', function () { var activity = new Activity({ url: 'myURL', assignedGroup: 'group' }); var groups = [ {id: 'each', longName: 'groupname'},
'use strict'; var IRC = require('irc'); var bz = require('bz'); var nconf = require('nconf'); var express = require('express'); var app = express(); nconf.file({ file: './local.json'}).defaults({ PORT: 3000, nick: 'contributor-helper', dev: false }).argv().env(); var config = nconf.get(); var ircChannels = require('./irc_channels.json'); if ( config.dev ) { ircChannels = require('./irc_channels_dev.json'); } var ircClient = new IRC.Client('irc.mozilla.org', config.nick, { secure: true, port: 6697, userName: config.nick, realName: 'The friendly contributor helper', channels: Object.keys(ircChannels) });
'use strict'; var nconf = require('nconf'); var Boom = require('boom'); var profile = require('./profile'); var posts = require('./posts'); var ban = require('./ban'); var utils = require('./utils'); nconf.argv().env().file({ file: 'local.json' }); var ctx = { analytics: nconf.get('analytics') }; exports.home = function (request, reply) { ctx.error = request.query.err || ''; ctx.session = request.session.get('uid') || false; ctx.ops = nconf.get('ops') || {}; if (ctx.ops.length > 0) { var count = 0; var users = {}; ctx.ops.forEach(function (op) { profile.getByUID(op, function (err, user) { count ++; if (user) { users[op] = { uid: op,
function loadConfig(showall) { const cfg = showall ? config.getAll(true) : nconf.get(); return _.omit(cfg, 'type'); }
function(topicSlug, next) { path = nconf.get('relative_path') + '/topic/' + topicSlug + '#' + pid; groups.getByGroupName('administrators', {}, next); },
module.init = function(callback) { callback = callback || function() {}; try { var sessionStore; mongoClient = require('mongodb').MongoClient; if (!nconf.get('redis')) { sessionStore = require('connect-mongo/es5')(session); } else { sessionStore = require('connect-redis')(session); } } catch (err) { winston.error('Unable to initialize MongoDB! Is MongoDB installed? Error :' + err.message); return callback(err); } var usernamePassword = ''; if (nconf.get('mongo:username') && nconf.get('mongo:password')) { usernamePassword = nconf.get('mongo:username') + ':' + encodeURIComponent(nconf.get('mongo:password')) + '@'; } // Sensible defaults for Mongo, if not set if (!nconf.get('mongo:host')) { nconf.set('mongo:host', '127.0.0.1'); } if (!nconf.get('mongo:port')) { nconf.set('mongo:port', 27017); } if (!nconf.get('mongo:database')) { nconf.set('mongo:database', '0'); } var hosts = nconf.get('mongo:host').split(','); var ports = nconf.get('mongo:port').toString().split(','); var servers = []; for (var i = 0; i < hosts.length; i++) { servers.push(hosts[i] + ':' + ports[i]); } var connString = 'mongodb://' + usernamePassword + servers.join() + '/' + nconf.get('mongo:database'); var connOptions = { server: { poolSize: parseInt(nconf.get('mongo:poolSize'), 10) || 10 } }; connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions); mongoClient.connect(connString, connOptions, function(err, _db) { if (err) { winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message); return callback(err); } db = _db; module.client = db; if (!nconf.get('redis')) { module.sessionStore = new sessionStore({ db: db }); } else { module.sessionStore = new sessionStore({ client: require('./redis').connect(), ttl: 60 * 60 * 24 * 14 }); } require('./mongo/main')(db, module); require('./mongo/hash')(db, module); require('./mongo/sets')(db, module); require('./mongo/sorted')(db, module); require('./mongo/list')(db, module); if (nconf.get('mongo:password') && nconf.get('mongo:username')) { db.authenticate(nconf.get('mongo:username'), nconf.get('mongo:password'), function (err) { if (err) { winston.error(err.stack); process.exit(); } createIndices(); }); } else { winston.warn('You have no mongo password setup!'); createIndices(); } function createIndices() { winston.info('[database] Checking database indices.'); async.parallel([ async.apply(createIndex, 'objects', {_key: 1, score: -1}, {background: true}), async.apply(createIndex, 'objects', {_key: 1, value: -1}, {background: true, unique: true, sparse: true}), async.apply(createIndex, 'objects', {expireAt: 1}, {expireAfterSeconds: 0, background: true}) ], function(err) { if (err) { winston.error('Error creating index ' + err.message); } callback(err); }); } function createIndex(collection, index, options, callback) { db.collection(collection).ensureIndex(index, options, callback); } }); };
before: function(value) { value = value || nconf.get('mongo:password') || ''; return value; }
(function(module) { var winston = require('winston'), async = require('async'), nconf = require('nconf'), session = require('express-session'), _ = require('underscore'), semver = require('semver'), db, mongoClient; _.mixin(require('underscore.deep')); module.questions = [ { name: 'mongo:host', description: 'Host IP or address of your MongoDB instance', 'default': nconf.get('mongo:host') || '127.0.0.1' }, { name: 'mongo:port', description: 'Host port of your MongoDB instance', 'default': nconf.get('mongo:port') || 27017 }, { name: 'mongo:username', description: 'MongoDB username', 'default': nconf.get('mongo:username') || '' }, { name: 'mongo:password', description: 'Password of your MongoDB database', hidden: true, before: function(value) { value = value || nconf.get('mongo:password') || ''; return value; } }, { name: "mongo:database", description: "MongoDB database name", 'default': nconf.get('mongo:database') || 0 } ]; module.helpers = module.helpers || {}; module.helpers.mongo = require('./mongo/helpers'); module.init = function(callback) { callback = callback || function() {}; try { var sessionStore; mongoClient = require('mongodb').MongoClient; if (!nconf.get('redis')) { sessionStore = require('connect-mongo/es5')(session); } else { sessionStore = require('connect-redis')(session); } } catch (err) { winston.error('Unable to initialize MongoDB! Is MongoDB installed? Error :' + err.message); return callback(err); } var usernamePassword = ''; if (nconf.get('mongo:username') && nconf.get('mongo:password')) { usernamePassword = nconf.get('mongo:username') + ':' + encodeURIComponent(nconf.get('mongo:password')) + '@'; } // Sensible defaults for Mongo, if not set if (!nconf.get('mongo:host')) { nconf.set('mongo:host', '127.0.0.1'); } if (!nconf.get('mongo:port')) { nconf.set('mongo:port', 27017); } if (!nconf.get('mongo:database')) { nconf.set('mongo:database', '0'); } var hosts = nconf.get('mongo:host').split(','); var ports = nconf.get('mongo:port').toString().split(','); var servers = []; for (var i = 0; i < hosts.length; i++) { servers.push(hosts[i] + ':' + ports[i]); } var connString = 'mongodb://' + usernamePassword + servers.join() + '/' + nconf.get('mongo:database'); var connOptions = { server: { poolSize: parseInt(nconf.get('mongo:poolSize'), 10) || 10 } }; connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions); mongoClient.connect(connString, connOptions, function(err, _db) { if (err) { winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message); return callback(err); } db = _db; module.client = db; if (!nconf.get('redis')) { module.sessionStore = new sessionStore({ db: db }); } else { module.sessionStore = new sessionStore({ client: require('./redis').connect(), ttl: 60 * 60 * 24 * 14 }); } require('./mongo/main')(db, module); require('./mongo/hash')(db, module); require('./mongo/sets')(db, module); require('./mongo/sorted')(db, module); require('./mongo/list')(db, module); if (nconf.get('mongo:password') && nconf.get('mongo:username')) { db.authenticate(nconf.get('mongo:username'), nconf.get('mongo:password'), function (err) { if (err) { winston.error(err.stack); process.exit(); } createIndices(); }); } else { winston.warn('You have no mongo password setup!'); createIndices(); } function createIndices() { winston.info('[database] Checking database indices.'); async.parallel([ async.apply(createIndex, 'objects', {_key: 1, score: -1}, {background: true}), async.apply(createIndex, 'objects', {_key: 1, value: -1}, {background: true, unique: true, sparse: true}), async.apply(createIndex, 'objects', {expireAt: 1}, {expireAfterSeconds: 0, background: true}) ], function(err) { if (err) { winston.error('Error creating index ' + err.message); } callback(err); }); } function createIndex(collection, index, options, callback) { db.collection(collection).ensureIndex(index, options, callback); } }); }; module.checkCompatibility = function(callback) { var mongoPkg = require.main.require('./node_modules/mongodb/package.json'), err = semver.lt(mongoPkg.version, '2.0.0') ? new Error('The `mongodb` package is out-of-date, please run `./nodebb setup` again.') : null; if (err) { err.stacktrace = false; } callback(err); }; module.info = function(db, callback) { async.parallel({ serverStatus: function(next) { db.command({'serverStatus': 1}, next); }, stats: function(next) { db.command({'dbStats': 1}, next); }, listCollections: function(next) { db.listCollections().toArray(function(err, items) { if (err) { return next(err); } async.map(items, function(collection, next) { db.collection(collection.name).stats(next); }, next); }); } }, function(err, results) { if (err) { return callback(err); } var stats = results.stats; var scale = 1024 * 1024; results.listCollections = results.listCollections.map(function(collectionInfo) { return { name: collectionInfo.ns, count: collectionInfo.count, size: collectionInfo.size, avgObjSize: collectionInfo.avgObjSize, storageSize: collectionInfo.storageSize, totalIndexSize: collectionInfo.totalIndexSize, indexSizes: collectionInfo.indexSizes }; }); stats.mem = results.serverStatus.mem; stats.collectionData = results.listCollections; stats.network = results.serverStatus.network; stats.raw = JSON.stringify(stats, null, 4); stats.avgObjSize = stats.avgObjSize.toFixed(2); stats.dataSize = (stats.dataSize / scale).toFixed(2); stats.storageSize = (stats.storageSize / scale).toFixed(2); stats.fileSize = stats.fileSize ? (stats.fileSize / scale).toFixed(2) : 0; stats.indexSize = (stats.indexSize / scale).toFixed(2); stats.storageEngine = results.serverStatus.storageEngine ? results.serverStatus.storageEngine.name : 'mmapv1'; stats.host = results.serverStatus.host; stats.version = results.serverStatus.version; stats.uptime = results.serverStatus.uptime; stats.mongo = true; callback(null, stats); }); }; module.close = function() { db.close(); }; }(exports));
function(next) { // Pre-router middlewares app.use(express.compress()); logger.init(app); // favicon & apple-touch-icon middleware app.use(express.favicon(path.join(__dirname, '../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'))); app.use('/apple-touch-icon', function(req, res) { if (meta.config['brand:logo'] && validator.isURL(meta.config['brand:logo'])) { return res.redirect(meta.config['brand:logo']); } else { return res.sendfile(path.join(__dirname, '../public', meta.config['brand:logo'] || nconf.get('relative_path') + '/logo.png'), { maxAge: app.enabled('cache') ? 5184000000 : 0 }); } }); app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public'), prefix: nconf.get('relative_path'), yuicompress: app.enabled('minification') ? true : false })); 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.session({ store: db.sessionStore, secret: nconf.get('secret'), key: 'express.sid', cookie: { maxAge: 1000 * 60 * 60 * 24 * parseInt(meta.configs.loginDays || 14, 10) } })); app.use(express.csrf()); if (nconf.get('port') != 80 && nconf.get('port') != 443 && nconf.get('use_port') === false) { winston.info('Enabling \'trust proxy\''); app.enable('trust proxy'); } if ((nconf.get('port') == 80 || nconf.get('port') == 443) && process.env.NODE_ENV !== 'development') { winston.info('Using ports 80 and 443 is not recommend; use a proxy instead. See README.md'); } // Local vars, other assorted setup app.use(function (req, res, next) { res.locals.csrf_token = req.session._csrf; // Disable framing res.setHeader('X-Frame-Options', 'SAMEORIGIN'); // Log IP address db.sortedSetAdd('ip:recent', +new Date(), req.ip || 'Unknown'); next(); }); // Authentication Routes auth.initialize(app); next(); },
"use strict"; var SocketIO = require('socket.io'), socketioWildcard = require('socket.io-wildcard'), util = require('util'), async = require('async'), path = require('path'), fs = require('fs'), nconf = require('nconf'), express = require('express'), socketCookieParser = express.cookieParser(nconf.get('secret')), winston = require('winston'), db = require('../database'), user = require('../user'), socketUser = require('./user'), topics = require('../topics'), logger = require('../logger'), meta = require('../meta'), Sockets = {}, Namespaces = {}; /* === */ var io; Sockets.init = function(server) { io = socketioWildcard(SocketIO).listen(server, {
app.use('/apple-touch-icon', function(req, res) { if (meta.config['brand:logo'] && validator.isURL(meta.config['brand:logo'])) { return res.redirect(meta.config['brand:logo']); } else { return res.sendfile(path.join(__dirname, '../public', meta.config['brand:logo'] || nconf.get('relative_path') + '/logo.png'), { maxAge: app.enabled('cache') ? 5184000000 : 0 }); } });
Sockets.init = function(server) { io = socketioWildcard(SocketIO).listen(server, { log: false, transports: ['websocket', 'xhr-polling', 'jsonp-polling', 'flashsocket'], 'browser client minification': true, resource: nconf.get('relative_path') + '/socket.io' }); Sockets.server = io; fs.readdir(__dirname, function(err, files) { files.splice(files.indexOf('index.js'), 1); async.each(files, function(lib, next) { lib = lib.slice(0, -3); Namespaces[lib] = require('./' + lib); next(); }); }); io.sockets.on('connection', function(socket) { var hs = socket.handshake, sessionID, uid; // Validate the session, if present socketCookieParser(hs, {}, function(err) { if(err) { winston.error(err.message); } sessionID = socket.handshake.signedCookies["express.sid"]; db.sessionStore.get(sessionID, function(err, sessionData) { if (!err && sessionData && sessionData.passport && sessionData.passport.user) { uid = parseInt(sessionData.passport.user, 10); } else { uid = 0; } socket.uid = parseInt(uid, 10); /* Need to save some state for the logger & maybe some other modules later on */ socket.state = { user : { uid : uid } }; /* If meta.config.loggerIOStatus > 0, logger.io_one will hook into this socket */ logger.io_one(socket,uid); if (uid) { db.sortedSetAdd('users:online', Date.now(), uid, function(err, data) { socket.join('uid_' + uid); async.parallel({ username: function(next) { user.getUserField(uid, 'username', next); }, isAdmin: function(next) { user.isAdministrator(uid, next); } }, function(err, userData) { socket.emit('event:connect', { status: 1, username: userData.username, isAdmin: userData.isAdmin, uid: uid }); socketUser.isOnline(socket, uid, function(err, data) { socket.broadcast.emit('user.isOnline', err, data); }); }); }); } else { socket.broadcast.emit('user.anonConnect'); socket.emit('event:connect', { status: 1, username: '******', isAdmin: false, uid: 0 }); } }); }); socket.on('disconnect', function() { if (uid && Sockets.getUserSockets(uid).length <= 1) { db.sortedSetRemove('users:online', uid, function(err) { socketUser.isOnline(socket, uid, function(err, data) { socket.broadcast.emit('user.isOnline', err, data); }); }); } if (!uid) { socket.broadcast.emit('user.anonDisconnect'); } emitOnlineUserCount(); for(var roomName in io.sockets.manager.roomClients[socket.id]) { updateRoomBrowsingText(roomName.slice(1)); } }); socket.on('*', function(payload, callback) { function callMethod(method) { if(socket.uid) { user.updateLastOnlineTime(socket.uid); } method.call(null, socket, payload.args.length ? payload.args[0] : null, function(err, result) { if (callback) { callback(err?{message:err.message}:null, result); } }); } if(!payload.name) { return winston.warn('[socket.io] Empty method name'); } var parts = payload.name.toString().split('.'), namespace = parts.slice(0, 1), methodToCall = parts.reduce(function(prev, cur) { if (prev !== null && prev[cur]) { return prev[cur]; } else { return null; } }, Namespaces); if(!methodToCall) { return winston.warn('[socket.io] Unrecognized message: ' + payload.name); } if (Namespaces[namespace].before) { Namespaces[namespace].before(socket, function() { callMethod(methodToCall); }); } else { callMethod(methodToCall); } }); }); };
(function (app) { "use strict"; var clientScripts; plugins.ready(function() { // Minify client-side libraries meta.js.get(function (err, scripts) { clientScripts = scripts.map(function (script) { script = { script: script }; return script; }); }); }); /** * `options` object requires: req, res * accepts: metaTags, linkTags */ app.build_header = function (options, callback) { var custom_header = { 'navigation': [] }; plugins.fireHook('filter:header.build', custom_header, function(err, custom_header) { var defaultMetaTags = [{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, user-scalable=no' }, { name: 'content-type', content: 'text/html; charset=UTF-8' }, { name: 'apple-mobile-web-app-capable', content: 'yes' }, { property: 'og:site_name', content: meta.config.title || 'NodeBB' }, { property: 'keywords', content: meta.config.keywords || '' }], defaultLinkTags = [{ rel: 'apple-touch-icon', href: '/apple-touch-icon' }], templateValues = { bootswatchCSS: meta.config['theme:src'], pluginCSS: plugins.cssFiles.map(function(file) { return { path: nconf.get('relative_path') + file.replace(/\\/g, '/') }; }), title: meta.config.title || '', description: meta.config.description || '', 'brand:logo': meta.config['brand:logo'] || '', 'brand:logo:display': meta.config['brand:logo']?'':'hide', csrf: options.res.locals.csrf_token, relative_path: nconf.get('relative_path'), clientScripts: clientScripts, navigation: custom_header.navigation, 'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '', allowRegistration: meta.config.allowRegistration === undefined || parseInt(meta.config.allowRegistration, 10) === 1, searchEnabled: plugins.hasListeners('filter:search.query') ? true : false }, escapeList = { '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }; var uid = '0'; // Meta Tags templateValues.metaTags = defaultMetaTags.concat(options.metaTags || []).map(function(tag) { tag.content = tag.content.replace(/[&<>'"]/g, function(tag) { return escapeList[tag] || tag; }); return tag; }); // Link Tags templateValues.linkTags = defaultLinkTags.concat(options.linkTags || []); templateValues.linkTags.push({ rel: "icon", type: "image/x-icon", href: nconf.get('relative_path') + '/favicon.ico' }); if(options.req.user && options.req.user.uid) { uid = options.req.user.uid; } // Custom CSS templateValues.useCustomCSS = false; if (meta.config.useCustomCSS === '1') { templateValues.useCustomCSS = true; templateValues.customCSS = meta.config.customCSS; } async.parallel([ function(next) { translator.get('pages:' + path.basename(options.req.url), function(translated) { var metaTitle = templateValues.metaTags.filter(function(tag) { return tag.name === 'title'; }); if (translated) { templateValues.browserTitle = translated; } else if (metaTitle.length > 0 && metaTitle[0].content) { templateValues.browserTitle = metaTitle[0].content; } else { templateValues.browserTitle = meta.config.browserTitle || 'NodeBB'; } next(); }); }, function(next) { user.isAdministrator(uid, function(err, isAdmin) { templateValues.isAdmin = isAdmin || false; next(); }); } ], function() { translator.translate(templates.header.parse(templateValues), function(template) { callback(null, template); }); }); }); }; // Cache static files on production if (global.env !== 'development') { app.enable('cache'); app.enable('minification'); // Configure cache-buster timestamp require('child_process').exec('git describe --tags', { cwd: path.join(__dirname, '../') }, function(err, stdOut) { if (!err) { meta.config['cache-buster'] = stdOut.trim(); // winston.info('[init] Cache buster value set to: ' + stdOut); } else { fs.stat(path.join(__dirname, '../package.json'), function(err, stats) { meta.config['cache-buster'] = new Date(stats.mtime).getTime(); }); } }); } // Middlewares app.configure(function() { async.series([ function(next) { // Pre-router middlewares app.use(express.compress()); logger.init(app); // favicon & apple-touch-icon middleware app.use(express.favicon(path.join(__dirname, '../', 'public', meta.config['brand:favicon'] ? meta.config['brand:favicon'] : 'favicon.ico'))); app.use('/apple-touch-icon', function(req, res) { if (meta.config['brand:logo'] && validator.isURL(meta.config['brand:logo'])) { return res.redirect(meta.config['brand:logo']); } else { return res.sendfile(path.join(__dirname, '../public', meta.config['brand:logo'] || nconf.get('relative_path') + '/logo.png'), { maxAge: app.enabled('cache') ? 5184000000 : 0 }); } }); app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public'), prefix: nconf.get('relative_path'), yuicompress: app.enabled('minification') ? true : false })); 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.session({ store: db.sessionStore, secret: nconf.get('secret'), key: 'express.sid', cookie: { maxAge: 1000 * 60 * 60 * 24 * parseInt(meta.configs.loginDays || 14, 10) } })); app.use(express.csrf()); if (nconf.get('port') != 80 && nconf.get('port') != 443 && nconf.get('use_port') === false) { winston.info('Enabling \'trust proxy\''); app.enable('trust proxy'); } if ((nconf.get('port') == 80 || nconf.get('port') == 443) && process.env.NODE_ENV !== 'development') { winston.info('Using ports 80 and 443 is not recommend; use a proxy instead. See README.md'); } // Local vars, other assorted setup app.use(function (req, res, next) { res.locals.csrf_token = req.session._csrf; // Disable framing res.setHeader('X-Frame-Options', 'SAMEORIGIN'); // Log IP address db.sortedSetAdd('ip:recent', +new Date(), req.ip || 'Unknown'); next(); }); // Authentication Routes auth.initialize(app); next(); }, function(next) { async.parallel([ function(next) { db.getObjectFields('config', ['theme:type', 'theme:id', 'theme:staticDir', 'theme:templates'], function(err, themeData) { var themeId = (themeData['theme:id'] || 'nodebb-theme-vanilla'); // Detect if a theme has been selected, and handle appropriately if (!themeData['theme:type'] || themeData['theme:type'] === 'local') { // Local theme if (process.env.NODE_ENV === 'development') { winston.info('[themes] Using theme ' + themeId); } // Theme's static directory if (themeData['theme:staticDir']) { app.use('/css/assets', express.static(path.join(nconf.get('themes_path'), themeData['theme:id'], themeData['theme:staticDir']), { maxAge: app.enabled('cache') ? 5184000000 : 0 })); if (process.env.NODE_ENV === 'development') { winston.info('Static directory routed for theme: ' + themeData['theme:id']); } } if (themeData['theme:templates']) { app.use('/templates', express.static(path.join(nconf.get('themes_path'), themeData['theme:id'], themeData['theme:templates']), { maxAge: app.enabled('cache') ? 5184000000 : 0 })); if (process.env.NODE_ENV === 'development') { winston.info('Custom templates directory routed for theme: ' + themeData['theme:id']); } } app.use(require('less-middleware')({ src: path.join(nconf.get('themes_path'), themeId), dest: path.join(__dirname, '../public/css'), prefix: nconf.get('relative_path') + '/css', yuicompress: app.enabled('minification') ? true : false })); next(); } else { // If not using a local theme (bootswatch, etc), drop back to vanilla if (process.env.NODE_ENV === 'development') { winston.info('[themes] Using theme ' + themeId); } app.use(require('less-middleware')({ src: path.join(nconf.get('themes_path'), '/nodebb-theme-vanilla'), dest: path.join(__dirname, '../public/css'), prefix: nconf.get('relative_path') + '/css', yuicompress: app.enabled('minification') ? true : false })); next(); } }); // Route paths to screenshots for installed themes meta.themes.get(function(err, themes) { var screenshotPath; async.each(themes, function(themeObj, next) { if (themeObj.screenshot) { screenshotPath = path.join(nconf.get('themes_path'), themeObj.id, themeObj.screenshot); (function(id, path) { fs.exists(path, function(exists) { if (exists) { app.get('/css/previews/' + id, function(req, res) { res.sendfile(path); }); } }); })(themeObj.id, screenshotPath); } else { next(false); } }); }); } ], next); }, function(next) { // Router & post-router middlewares app.use(app.router); // Static directory /public app.use(nconf.get('relative_path'), express.static(path.join(__dirname, '../', 'public'), { maxAge: app.enabled('cache') ? 5184000000 : 0 })); // 404 catch-all app.use(function (req, res, next) { var isLanguage = new RegExp('^' + nconf.get('relative_path') + '/language/[\\w]{2,}/.*.json'), isClientScript = new RegExp('^' + nconf.get('relative_path') + '\\/src\\/forum(\\/admin)?\\/[\\w]+\\.js'); res.status(404); if (isClientScript.test(req.url)) { // Handle missing client-side scripts res.type('text/javascript').send(200, ''); } else if (isLanguage.test(req.url)) { // Handle languages by sending an empty object res.json(200, {}); } else if (req.accepts('html')) { // respond with html page if (process.env.NODE_ENV === 'development') { winston.warn('Route requested but not found: ' + req.url); } res.redirect(nconf.get('relative_path') + '/404'); } else if (req.accepts('json')) { // respond with json if (process.env.NODE_ENV === 'development') { winston.warn('Route requested but not found: ' + req.url); } res.json({ error: 'Not found' }); } else { // 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); var status = err.status || 500; res.status(status); res.json(status, { error: err.message }); }); next(); } ], function(err) { if (err) { winston.error('Errors were encountered while attempting to initialise NodeBB.'); process.exit(); } else { if (process.env.NODE_ENV === 'development') { winston.info('Middlewares loaded.'); } } }); }); module.exports.init = function () { // translate all static templates served by webserver here. ex. footer, logout plugins.fireHook('filter:footer.build', '', function(err, appendHTML) { var footer = templates.footer.parse({ footerHTML: appendHTML }); translator.translate(footer, function(parsedTemplate) { templates.footer = parsedTemplate; }); }); plugins.fireHook('action:app.load', app); translator.translate(templates.logout.toString(), function(parsedTemplate) { templates.logout = parsedTemplate; }); server.on("error", function(e){ if (e.code === 'EADDRINUSE') { winston.error('NodeBB address in use, exiting...'); process.exit(1); } else { throw e; } }); var port = nconf.get('PORT') || nconf.get('port'); winston.info('NodeBB attempting to listen on: ' + ((nconf.get('bind_address') === "0.0.0.0" || !nconf.get('bind_address')) ? '0.0.0.0' : nconf.get('bind_address')) + ':' + port); server.listen(port, nconf.get('bind_address'), function(){ winston.info('NodeBB Ready'); }); }; app.create_route = function (url, tpl) { // to remove var routerScript = '<script> \ ajaxify.initialLoad = true; \ templates.ready(function(){ajaxify.go("' + url + '", null, true);}); \ </script>'; return routerScript; }; app.namespace(nconf.get('relative_path'), function () { auth.registerApp(app); admin.createRoutes(app); userRoute.createRoutes(app); apiRoute.createRoutes(app); feedsRoute.createRoutes(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', 'popular', '403', '404', '500'], loginRequired = ['unread', 'notifications']; async.each(routes.concat(loginRequired), function(route, next) { app.get('/' + route, function (req, res) { if ((route === 'register' || route === 'login') && (req.user && req.user.uid > 0)) { user.getUserField(req.user.uid, 'userslug', function (err, userslug) { res.redirect('/user/' + userslug); }); return; } else if(route === 'register' && meta.config.allowRegistration !== undefined && parseInt(meta.config.allowRegistration, 10) === 0) { return res.redirect('/403'); } else if (loginRequired.indexOf(route) !== -1 && !req.user) { return res.redirect('/403'); } app.build_header({ req: req, res: res }, function (err, header) { res.send((isNaN(parseInt(route, 10)) ? 200 : parseInt(route, 10)), header + app.create_route(route) + templates.footer); }); }); }); }()); app.get('/', function (req, res) { async.parallel({ "header": function (next) { app.build_header({ req: req, res: res, metaTags: [{ 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); }, "categories": function (next) { function canSee(category, next) { CategoryTools.privileges(category.cid, ((req.user) ? req.user.uid || 0 : 0), function(err, privileges) { next(!err && privileges.read); }); } categories.getAllCategories(0, function (err, returnData) { returnData.categories = returnData.categories.filter(function (category) { return !category.disabled; }); async.filter(returnData.categories, canSee, function(visibleCategories) { returnData.categories = visibleCategories; next(null, returnData); }); }); } }, function (err, data) { res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + templates['noscript/home'].parse(data.categories) + '\n\t</noscript>' + app.create_route('') + templates.footer ); }); }); app.get('/topic/:topic_id/:slug?', function (req, res, next) { var tid = req.params.topic_id, page = req.query.page || 1, uid = req.user ? req.user.uid : 0; async.waterfall([ function(next) { ThreadTools.privileges(tid, ((req.user) ? req.user.uid || 0 : 0), function(err, privileges) { if (!err) { if (!privileges.read) { next(new Error('not-enough-privileges')); } else { next(); } } else { next(err); } }); }, function (next) { user.getSettings(uid, function(err, settings) { if (err) { return next(err); } var start = (page - 1) * settings.topicsPerPage, end = start + settings.topicsPerPage - 1; topics.getTopicWithPosts(tid, uid, start, end, true, function (err, topicData) { if (topicData) { if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) { return next(new Error('Topic deleted'), null); } } next(err, topicData); }); }); }, function (topicData, next) { var lastMod = topicData.timestamp, description = (function() { var content = ''; if(topicData.posts.length) { content = S(topicData.posts[0].content).stripTags().s; } if (content.length > 255) { content = content.substr(0, 255) + '...'; } return validator.escape(content); })(), timestamp; for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) { timestamp = parseInt(topicData.posts[x].timestamp, 10); if (timestamp > lastMod) { lastMod = timestamp; } } var ogImageUrl = meta.config['brand:logo']; if(ogImageUrl && ogImageUrl.indexOf('http') === -1) { ogImageUrl = nconf.get('url') + ogImageUrl; } app.build_header({ req: req, res: res, metaTags: [ { name: "title", content: topicData.topic_name }, { name: "description", content: description }, { property: 'og:title', content: topicData.topic_name }, { property: 'og:description', content: description }, { property: "og:type", content: 'article' }, { property: "og:url", content: nconf.get('url') + '/topic/' + topicData.slug }, { property: "og:image:url", content: ogImageUrl }, { property: 'og:image', content: topicData.posts.length?topicData.posts[0].picture:'' }, { property: "article:published_time", content: utils.toISOString(topicData.timestamp) }, { property: 'article:modified_time', content: utils.toISOString(lastMod) }, { property: 'article:section', content: topicData.category_name } ], linkTags: [ { rel: 'alternate', type: 'application/rss+xml', href: nconf.get('url') + '/topic/' + tid + '.rss' }, { rel: 'up', href: nconf.get('url') + '/category/' + topicData.category_slug } ] }, function (err, header) { next(err, { header: header, posts: topicData }); }); } ], function (err, data) { if (err) { if (err.message === 'not-enough-privileges') { return res.redirect('403'); } else { return res.redirect('404'); } } var topic_url = tid + (req.params.slug ? '/' + req.params.slug : ''); var queryString = qs.stringify(req.query); if(queryString.length) { topic_url += '?' + queryString; } // Paginator for noscript data.posts.pages = []; for(var x=1;x<=data.posts.pageCount;x++) { data.posts.pages.push({ page: x, active: x === parseInt(page, 10) }); } translator.translate(templates['noscript/topic'].parse(data.posts), function(translatedHTML) { res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + translatedHTML + '\n\t</noscript>' + '\n\t' + app.create_route('topic/' + topic_url) + templates.footer ); }); }); }); app.get('/category/:category_id/:slug?', function (req, res, next) { var cid = req.params.category_id, page = req.query.page || 1, uid = req.user ? req.user.uid : 0; async.waterfall([ function(next) { CategoryTools.privileges(cid, uid, function(err, privileges) { if (!err) { if (!privileges.read) { next(new Error('not-enough-privileges')); } else { next(); } } else { next(err); } }); }, function (next) { user.getSettings(uid, function(err, settings) { if (err) { return next(err); } var start = (page - 1) * settings.topicsPerPage, end = start + settings.topicsPerPage - 1; categories.getCategoryById(cid, start, end, 0, function (err, categoryData) { if (categoryData) { if (parseInt(categoryData.disabled, 10) === 1) { return next(new Error('Category disabled'), null); } } next(err, categoryData); }); }); }, function (categoryData, next) { app.build_header({ req: req, res: res, metaTags: [ { name: 'title', content: categoryData.category_name }, { property: 'og:title', content: categoryData.category_name }, { name: 'description', content: categoryData.category_description }, { property: "og:type", content: 'website' } ], linkTags: [ { rel: 'alternate', type: 'application/rss+xml', href: nconf.get('url') + '/category/' + cid + '.rss' }, { rel: 'up', href: nconf.get('url') } ] }, function (err, header) { next(err, { header: header, topics: categoryData }); }); } ], function (err, data) { if (err) { if (err.message === 'not-enough-privileges') { return res.redirect('403'); } else { return res.redirect('404'); } } if(data.topics.link) { return res.redirect(data.topics.link); } var category_url = cid + (req.params.slug ? '/' + req.params.slug : ''); var queryString = qs.stringify(req.query); if(queryString.length) { category_url += '?' + queryString; } // Paginator for noscript data.topics.pages = []; for(var x=1;x<=data.topics.pageCount;x++) { data.topics.pages.push({ page: x, active: x === parseInt(page, 10) }); } translator.translate(templates['noscript/category'].parse(data.topics), function(translatedHTML) { res.send( data.header + '\n\t<noscript>\n' + templates['noscript/header'] + translatedHTML + '\n\t</noscript>' + '\n\t' + app.create_route('category/' + category_url) + templates.footer ); }); }); }); app.get('/confirm/:code', function (req, res) { app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('confirm/' + req.params.code) + templates.footer); }); }); app.get('/sitemap.xml', function (req, res) { var sitemap = require('./sitemap.js'); sitemap.render(function (xml) { res.header('Content-Type', 'application/xml'); res.send( xml ); }); }); app.get('/robots.txt', function (req, res) { res.set('Content-Type', 'text/plain'); if (meta.config["robots.txt"]) { res.send(meta.config["robots.txt"]) } else { res.send("User-agent: *\n" + "Disallow: /admin/\n" + "Sitemap: " + nconf.get('url') + "/sitemap.xml"); } }); app.get('/recent/:term?', function (req, res) { // TODO consolidate with /recent route as well -> that can be combined into this area. See "Basic Routes" near top. app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('recent/' + req.params.term, null, 'recent') + templates.footer); }); }); app.get('/popular/:term?', function (req, res) { app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('popular/' + req.params.term, null, 'popular') + templates.footer); }); }); app.get('/outgoing', function (req, res) { if (!req.query.url) { return res.redirect('/404'); } app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('outgoing?url=' + encodeURIComponent(req.query.url)) + templates.footer); }); }); app.get('/search/:term?', function (req, res) { if (!req.user && meta.config.allowGuestSearching !== '1') { return res.redirect('/403'); } if(!req.params.term) { req.params.term = ''; } app.build_header({ req: req, res: res }, function (err, header) { res.send(header + app.create_route('search/' + req.params.term, null, 'search') + templates.footer); }); }); // Other routes require('./routes/plugins')(app); // Debug routes if (process.env.NODE_ENV === 'development') { require('./routes/debug')(app); } var custom_routes = { 'routes': [], 'api': [], 'templates': [] }; app.get_custom_templates = function() { return custom_routes.templates.map(function(tpl) { return tpl.template.split('.tpl')[0]; }); }; plugins.ready(function() { plugins.fireHook('filter:server.create_routes', custom_routes, function(err, custom_routes) { var routes = custom_routes.routes; for (var route in routes) { if (routes.hasOwnProperty(route)) { (function(route) { app[routes[route].method || 'get'](routes[route].route, function(req, res) { routes[route].options(req, res, function(options) { app.build_header({ req: options.req || req, res: options.res || res }, function (err, header) { res.send(header + options.content + templates.footer); }); }); }); }(route)); } } var apiRoutes = custom_routes.api; for (var route in apiRoutes) { if (apiRoutes.hasOwnProperty(route)) { (function(route) { app[apiRoutes[route].method || 'get']('/api' + apiRoutes[route].route, function(req, res) { apiRoutes[route].callback(req, res, function(data) { res.json(data); }); }); }(route)); } } var templateRoutes = custom_routes.templates; for (var route in templateRoutes) { if (templateRoutes.hasOwnProperty(route)) { (function(route) { app.get('/templates/' + templateRoutes[route].template, function(req, res) { res.send(templateRoutes[route].content); }); }(route)); } } }); }); }); }(WebServer));
'use strict'; var async = require('async'); var _ = require('lodash'); var conf = require('nconf'); var beans = conf.get('beans'); var validation = beans.get('validation'); var Member = beans.get('member'); var Group = beans.get('group'); var membersService = beans.get('membersService'); var memberstore = beans.get('memberstore'); var wikiService = beans.get('wikiService'); var groupsAndMembersService = beans.get('groupsAndMembersService'); var groupsService = beans.get('groupsService'); var groupstore = beans.get('groupstore'); var activitiesService = beans.get('activitiesService'); var activitystore = beans.get('activitystore'); var misc = beans.get('misc'); var statusmessage = beans.get('statusmessage'); var notifications = beans.get('notifications'); function memberForNew(req) { return new Member().initFromSessionUser(req.user); } function saveMember(persistentMember, req, res, next) { if (persistentMember && !res.locals.accessrights.canEditMember(persistentMember)) { return res.redirect('/members'); } var member = persistentMember || memberForNew(req);
var nconf = require('nconf'); var stripe = require("stripe")(nconf.get('STRIPE_API_KEY')); var async = require('async'); var payments = require('./index'); var User = require('mongoose').model('User'); var shared = require('../../../../common'); var mongoose = require('mongoose'); var cc = require('coupon-code'); /* Setup Stripe response when posting payment */ exports.checkout = function(req, res, next) { var token = req.body.id; var user = res.locals.user; var gift = req.query.gift ? JSON.parse(req.query.gift) : undefined; var sub = req.query.sub ? shared.content.subscriptionBlocks[req.query.sub] : false; async.waterfall([ function(cb){ if (sub) { async.waterfall([ function(cb2){ if (!sub.discount) return cb2(null, null); if (!req.query.coupon) return cb2('Please provide a coupon code for this plan.'); mongoose.model('Coupon').findOne({_id:cc.validate(req.query.coupon), event:sub.key}, cb2); }, function(coupon, cb2){ if (sub.discount && !coupon) return cb2('Invalid coupon code.'); var customer = { email: req.body.email,
var pg = require('pg'); var nconf = require('nconf'); var request = require("request"); var winston = require('winston'); winston.add(winston.transports.File, {filename: '/var/www/geocloud2/public/logs/meta2ckan.log'}); nconf.argv(); var db = (nconf.get()._[0]); var host = nconf.get("host") || "127.0.0.1"; var ckanHost = nconf.get("ckan-host") || "127.0.0.1"; var gc2Host = nconf.get("gc2-host") || "127.0.0.1"; var user = nconf.get("user") || "postgres"; var key = nconf.get("key") || null; if (nconf.get("help") || !db) { console.log("usage:"); console.log(" pg2es.js database [options]"); console.log("Options:"); console.log(" --host PostGreSQL host. Default 127.0.0.1"); console.log(" --user PostGreSQL user. Default postgres"); console.log(" --ckan-host Ckan host. Default 127.0.0.1"); console.log(" --gc2-host GC2 host. Default 127.0.0.1"); console.log(" --key GC2 api key"); process.exit(1); } /** * @type {{user: (any), database: *, host: (any), port: number, max: number, idleTimeoutMillis: number}} */ var config = { user: user,
(function () { "use strict"; // Configuration setup var nconf = require('nconf'); nconf.argv().env(); var fs = require('fs'), async = require('async'), semver = require('semver'), winston = require('winston'), path = require('path'), pkg = require('./package.json'), utils = require('./public/src/utils.js'), meta; // Runtime environment global.env = process.env.NODE_ENV || 'production'; winston.remove(winston.transports.Console); winston.add(winston.transports.Console, { colorize: true }); winston.add(winston.transports.File, { filename: 'error.log', level: 'error' }); // TODO: remove once https://github.com/flatiron/winston/issues/280 is fixed winston.err = function (err) { winston.error(err.stack); }; require('child_process').exec('/usr/bin/which convert', function(err, stdout, stderr) { if(err || !stdout) { winston.warn('Couldn\'t find convert. Did you install imagemagick?'); } }); // Log GNU copyright info along with server info 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(''); if (!nconf.get('help') && !nconf.get('setup') && !nconf.get('install') && !nconf.get('upgrade') && fs.existsSync(__dirname + '/config.json')) { // Load server-side configs nconf.file({ file: __dirname + '/config.json' }); meta = require('./src/meta'); nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path') + path.sep); nconf.set('upload_url', path.join(path.sep, nconf.get('relative_path'), 'uploads', path.sep)); nconf.set('base_dir', __dirname); winston.info('Initializing NodeBB v' + pkg.version + ', on port ' + nconf.get('port') + ', using ' + nconf.get('database') +' store at ' + nconf.get(nconf.get('database') + ':host') + ':' + nconf.get(nconf.get('database') + ':port') + '.'); winston.info('NodeBB instance bound to: ' + ((nconf.get('bind_address') === "0.0.0.0" || !nconf.get('bind_address')) ? 'Any address (0.0.0.0)' : nconf.get('bind_address'))); if (process.env.NODE_ENV === 'development') { winston.info('Base Configuration OK.'); } if (semver.gt(pkg.dependencies['nodebb-theme-cerulean'], require('./node_modules/nodebb-theme-cerulean/package.json').version)) { winston.error('nodebb-theme-cerulean is out of date - please run npm install.'); } if (!semver.satisfies(require('./node_modules/nodebb-theme-vanilla/package.json').version, pkg.dependencies['nodebb-theme-vanilla'])) { winston.error('nodebb-theme-vanilla is out of date - please run npm install.'); } require('./src/database').init(function(err) { meta.configs.init(function () { var templates = require('./public/src/templates'), translator = require('./public/src/translator'), webserver = require('./src/webserver'), sockets = require('./src/socket.io'), plugins = require('./src/plugins'), notifications = require('./src/notifications'), upgrade = require('./src/upgrade'); templates.setGlobal('relative_path', nconf.get('relative_path')); upgrade.check(function(schema_ok) { if (schema_ok || nconf.get('check-schema') === false) { sockets.init(); plugins.init(); global.templates = {}; global.translator = translator; translator.loadServer(); var customTemplates = meta.config['theme:templates'] ? path.join(__dirname, 'node_modules', meta.config['theme:id'], meta.config['theme:templates']) : false; utils.walk(path.join(__dirname, 'public/templates'), function (err, tplsToLoad) { templates.init(tplsToLoad, customTemplates); }); plugins.ready(function() { templates.ready(webserver.init); }); notifications.init(); } else { winston.warn('Your NodeBB schema is out-of-date. Please run the following command to bring your dataset up to spec:'); winston.warn(' node app --upgrade'); winston.warn('To ignore this error (not recommended):'); winston.warn(' node app --no-check-schema') process.exit(); } }); }); }); } else if (nconf.get('setup') || nconf.get('install') || !fs.existsSync(__dirname + '/config.json')) { // 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'); } nconf.file({ file: __dirname + '/config.json' }); var templates = require('./public/src/templates'), install = require('./src/install'); 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 { winston.info('NodeBB Setup Completed. Run \'node app\' to manually start your NodeBB server.'); } process.exit(); }); } else if (nconf.get('upgrade')) { nconf.file({ file: __dirname + '/config.json' }); require('./src/database').init(function(err) { meta = require('./src/meta.js'); meta.configs.init(function () { require('./src/upgrade').upgrade(); }); }); } else/* if (nconf.get('help') */{ winston.info('Usage: node app [options] [arguments]'); winston.info(' [NODE_ENV=development | NODE_ENV=production] node app [--start] [arguments]'); winston.info(''); winston.info('Options:'); winston.info(' --help displays this usage information'); winston.info(' --setup configure your environment and setup NodeBB'); winston.info(' --upgrade upgrade NodeBB, first read: github.com/designcreateplay/NodeBB/wiki/Upgrading-NodeBB'); winston.info(' --start manually start NodeBB (default when no options are given)'); }; }());
posts = require('./posts'), topics = require('./topics'), ThreadTools = require('./threadTools'), notifications = require('./notifications'), admin = require('./routes/admin'), userRoute = require('./routes/user'), apiRoute = require('./routes/api'), feedsRoute = require('./routes/feeds'), auth = require('./routes/authentication'), meta = require('./meta'), plugins = require('./plugins'), logger = require('./logger'), templates = require('./../public/src/templates'), translator = require('./../public/src/translator'); if(nconf.get('ssl')) { server = require('https').createServer({ key: fs.readFileSync(nconf.get('ssl').key), cert: fs.readFileSync(nconf.get('ssl').cert) }, WebServer); } else { server = require('http').createServer(WebServer); } module.exports.server = server; // Signals var shutdown = function(code) { winston.info('[app] Shutdown (SIGTERM/SIGINT) Initialised.'); db.close(); winston.info('[app] Database connection closed.');
/*jslint node: true*/ var Promise = require('bluebird'); var chai = require("chai"), chaiAsPromised = require("chai-as-promised"), expect = require("chai").expect; chai.use(chaiAsPromised); var argv = require('optimist').demand('config').argv; var environment = argv.config; var nconf = require('nconf'); nconf.argv().env().file({ file: 'config.json' }); var cf_api_url = nconf.get(environment + "_" + 'CF_API_URL'), username = nconf.get(environment + "_" + 'username'), password = nconf.get(environment + "_" + 'password'); var CloudController = require("../../../../lib/model/cloudcontroller/CloudController"); var CloudFoundryUsersUAA = require("../../../../lib/model/uaa/UsersUAA"); var CloudFoundryApps = require("../../../../lib/model/cloudcontroller/Apps"); CloudController = new CloudController(); CloudFoundryUsersUAA = new CloudFoundryUsersUAA(); CloudFoundryApps = new CloudFoundryApps(); describe("Cloud Foundry Users UAA", function () { "use strict"; var authorization_endpoint = null; var token_endpoint = null; var token_type = null; var access_token = null; var refresh_token = null;
plugins.fireHook('filter:header.build', custom_header, function(err, custom_header) { var defaultMetaTags = [{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, user-scalable=no' }, { name: 'content-type', content: 'text/html; charset=UTF-8' }, { name: 'apple-mobile-web-app-capable', content: 'yes' }, { property: 'og:site_name', content: meta.config.title || 'NodeBB' }, { property: 'keywords', content: meta.config.keywords || '' }], defaultLinkTags = [{ rel: 'apple-touch-icon', href: '/apple-touch-icon' }], templateValues = { bootswatchCSS: meta.config['theme:src'], pluginCSS: plugins.cssFiles.map(function(file) { return { path: nconf.get('relative_path') + file.replace(/\\/g, '/') }; }), title: meta.config.title || '', description: meta.config.description || '', 'brand:logo': meta.config['brand:logo'] || '', 'brand:logo:display': meta.config['brand:logo']?'':'hide', csrf: options.res.locals.csrf_token, relative_path: nconf.get('relative_path'), clientScripts: clientScripts, navigation: custom_header.navigation, 'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '', allowRegistration: meta.config.allowRegistration === undefined || parseInt(meta.config.allowRegistration, 10) === 1, searchEnabled: plugins.hasListeners('filter:search.query') ? true : false }, escapeList = { '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }; var uid = '0'; // Meta Tags templateValues.metaTags = defaultMetaTags.concat(options.metaTags || []).map(function(tag) { tag.content = tag.content.replace(/[&<>'"]/g, function(tag) { return escapeList[tag] || tag; }); return tag; }); // Link Tags templateValues.linkTags = defaultLinkTags.concat(options.linkTags || []); templateValues.linkTags.push({ rel: "icon", type: "image/x-icon", href: nconf.get('relative_path') + '/favicon.ico' }); if(options.req.user && options.req.user.uid) { uid = options.req.user.uid; } // Custom CSS templateValues.useCustomCSS = false; if (meta.config.useCustomCSS === '1') { templateValues.useCustomCSS = true; templateValues.customCSS = meta.config.customCSS; } async.parallel([ function(next) { translator.get('pages:' + path.basename(options.req.url), function(translated) { var metaTitle = templateValues.metaTags.filter(function(tag) { return tag.name === 'title'; }); if (translated) { templateValues.browserTitle = translated; } else if (metaTitle.length > 0 && metaTitle[0].content) { templateValues.browserTitle = metaTitle[0].content; } else { templateValues.browserTitle = meta.config.browserTitle || 'NodeBB'; } next(); }); }, function(next) { user.isAdministrator(uid, function(err, isAdmin) { templateValues.isAdmin = isAdmin || false; next(); }); } ], function() { translator.translate(templates.header.parse(templateValues), function(template) { callback(null, template); }); }); });
app.get('/robots.txt', function (req, res) { res.set('Content-Type', 'text/plain'); res.send("User-agent: *\n" + "Disallow: /admin/\n" + "Sitemap: " + nconf.get('url') + "sitemap.xml"); });
pluginCSS: plugins.cssFiles.map(function(file) { return { path: nconf.get('relative_path') + file.replace(/\\/g, '/') }; }),
User.findOne({'auth.local.email':email}, function(err, user){ if (err) return next(err); if (!user) return res.send(500, {err:"Couldn't find a user registered for email " + email}); user.auth.local.salt = salt; user.auth.local.hashed_password = hashed_password; utils.sendEmail({ from: "HabitRPG <*****@*****.**>", to: email, subject: "Password Reset for HabitRPG", text: "Password for " + user.auth.local.username + " has been reset to " + newPassword + ". Log in at " + nconf.get('BASE_URL'), html: "Password for <strong>" + user.auth.local.username + "</strong> has been reset to <strong>" + newPassword + "</strong>. Log in at " + nconf.get('BASE_URL') }); user.save(); return res.send('New password sent to '+ email); });
/* * This file exports a NodeBB Settings Object and a few meta-data of the project. * * See https://docs.nodebb.org/en/latest/plugins/settings.html for more details on the Settings Object. * * This file by default gets meta-replaced (thus @{...} gets resolved within the grunt-tasks). * It is not recommended to add any more files, rather it is recommended to add additional exports here if needed. */ var env = "distribution", dev = env === "development"; /*===================================================== Exports =====================================================*/ exports.urlBase = nconf.get("url") + "/plugins/nodebb-plugin-emoji-one/static"; exports.name = "nodebb-plugin-emoji-one"; exports.id = "emoji-one"; exports.Id = "EmojiOne"; exports.iD = "emojiOne"; exports.ID = "EMOJI_ONE"; exports.dev = dev; exports.env = env; exports.pkg = packageJSON; exports.checkInit = checkInit; /*==================================================== Functions ====================================================*/ function checkInit(onInit) { meta.settings.get(exports.id, function (err, data) { if (!data || +data.initialized !== 1) {