2013-04-22 16:51:32 +00:00
var express = require ( 'express' ) ,
2013-04-22 15:17:41 -04:00
WebServer = express ( ) ,
server = require ( 'http' ) . createServer ( WebServer ) ,
2013-04-28 13:58:19 -04:00
RedisStore = require ( 'connect-redis' ) ( express ) ,
path = require ( 'path' ) ,
2013-06-20 16:48:17 -04:00
redis = require ( 'redis' ) ,
2013-05-27 14:02:57 -04:00
redisServer = redis . createClient ( global . config . redis . port , global . config . redis . host ) ,
2013-05-22 12:06:23 -04:00
marked = require ( 'marked' ) ,
2013-05-23 13:29:21 -04:00
utils = require ( '../public/src/utils.js' ) ,
2013-05-22 21:43:01 -04:00
fs = require ( 'fs' ) ,
2013-05-09 06:26:32 +00:00
2013-05-04 18:20:22 -04:00
user = require ( './user.js' ) ,
2013-05-14 12:13:29 -04:00
categories = require ( './categories.js' ) ,
posts = require ( './posts.js' ) ,
topics = require ( './topics.js' ) ,
2013-05-22 21:43:01 -04:00
notifications = require ( './notifications.js' ) ,
2013-05-09 03:33:53 +00:00
admin = require ( './routes/admin.js' ) ,
2013-05-14 13:04:12 -04:00
userRoute = require ( './routes/user.js' ) ,
2013-05-24 13:14:41 -04:00
installRoute = require ( './routes/install.js' ) ,
2013-05-25 20:32:22 -04:00
auth = require ( './routes/authentication.js' ) ,
meta = require ( './meta.js' ) ;
2013-05-02 15:57:43 -04:00
2013-04-22 16:51:32 +00:00
( function ( app ) {
2013-06-20 16:04:58 -04:00
var templates = null ;
2013-06-20 16:29:44 -04:00
app . build _header = function ( res ) {
2013-06-20 16:04:58 -04:00
return templates [ 'header' ] . parse ( {
cssSrc : global . config [ 'theme:src' ] || '/vendor/bootstrap/css/bootstrap.min.css' ,
2013-06-20 16:29:44 -04:00
title : global . config [ 'title' ] || 'NodeBB' ,
csrf : res . locals . csrf _token
2013-06-20 16:04:58 -04:00
} ) ;
} ;
2013-04-22 16:51:32 +00:00
2013-04-24 16:42:12 -04:00
// Middlewares
app . use ( express . favicon ( ) ) ; // 2 args: string path and object options (i.e. expire time etc)
2013-05-24 15:38:23 -04:00
app . use ( require ( 'less-middleware' ) ( { src : path . join ( _ _dirname , '../' , 'public' ) } ) ) ;
2013-04-28 13:58:19 -04:00
app . use ( express . static ( path . join ( _ _dirname , '../' , 'public' ) ) ) ;
2013-04-24 16:42:12 -04:00
app . use ( express . bodyParser ( ) ) ; // Puts POST vars in request.body
app . use ( express . cookieParser ( ) ) ; // If you want to parse cookies (res.cookies)
2013-04-28 13:58:19 -04:00
app . use ( express . compress ( ) ) ;
2013-04-25 11:15:03 -04:00
app . use ( express . session ( {
2013-04-25 12:59:31 -04:00
store : new RedisStore ( {
2013-05-01 12:54:04 -04:00
client : redisServer ,
2013-04-25 12:59:31 -04:00
ttl : 60 * 60 * 24 * 14
} ) ,
2013-05-27 14:02:57 -04:00
secret : global . config . secret ,
2013-04-25 11:15:03 -04:00
key : 'express.sid'
} ) ) ;
2013-06-20 12:41:22 -04:00
app . use ( express . csrf ( ) ) ;
app . use ( function ( req , res , next ) {
res . locals . csrf _token = req . session . _csrf ;
next ( ) ;
} ) ;
2013-05-17 13:36:35 -04:00
module . exports . init = function ( ) {
templates = global . templates ;
}
2013-05-09 06:26:32 +00:00
auth . initialize ( app ) ;
2013-04-25 12:59:31 -04:00
app . use ( function ( req , res , next ) {
2013-04-28 13:58:19 -04:00
// Don't bother with session handling for API requests
2013-04-28 22:26:27 -04:00
if ( /^\/api\// . test ( req . url ) ) return next ( ) ;
2013-04-28 21:15:47 -04:00
2013-05-01 21:03:37 -04:00
if ( req . user && req . user . uid ) {
2013-05-14 12:13:29 -04:00
user . session _ping ( req . sessionID , req . user . uid ) ;
2013-04-25 12:59:31 -04:00
}
2013-04-28 13:58:19 -04:00
// (Re-)register the session as active
2013-05-14 12:13:29 -04:00
user . active . register ( req . sessionID ) ;
2013-04-28 13:58:19 -04:00
2013-04-25 12:59:31 -04:00
next ( ) ;
} ) ;
2013-05-07 10:56:30 -04:00
2013-05-09 06:26:32 +00:00
auth . create _routes ( app ) ;
admin . create _routes ( app ) ;
2013-05-14 13:04:12 -04:00
userRoute . create _routes ( app ) ;
2013-05-24 13:14:41 -04:00
installRoute . create _routes ( app ) ;
2013-04-25 19:13:23 +00:00
2013-05-02 09:13:09 -04:00
2013-05-09 06:26:32 +00:00
app . create _route = function ( url , tpl ) { // to remove
2013-05-07 21:29:28 +00:00
return '<script>templates.ready(function(){ajaxify.go("' + url + '", null, "' + tpl + '");});</script>' ;
2013-05-09 06:26:32 +00:00
} ;
2013-05-07 21:29:28 +00:00
2013-05-01 22:19:54 +00:00
// Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section)
( function ( ) {
2013-06-14 13:01:24 -04:00
var routes = [ 'login' , 'register' , 'account' , 'latest' , 'popular' , 'active' , '403' , '404' ] ;
2013-04-25 21:55:11 +00:00
2013-05-01 22:19:54 +00:00
for ( var i = 0 , ii = routes . length ; i < ii ; i ++ ) {
( function ( route ) {
2013-05-06 14:27:15 -04:00
2013-05-01 22:19:54 +00:00
app . get ( '/' + route , function ( req , res ) {
2013-05-06 14:27:15 -04:00
if ( ( route === 'login' || route === 'register' ) && ( req . user && req . user . uid > 0 ) ) {
res . redirect ( '/account' ) ;
return ;
}
2013-06-20 16:29:44 -04:00
res . send ( app . build _header ( res ) + app . create _route ( route ) + templates [ 'footer' ] ) ;
2013-05-01 22:19:54 +00:00
} ) ;
} ( routes [ i ] ) ) ;
}
} ( ) ) ;
2013-05-03 21:19:28 +00:00
// Complex Routes
2013-06-14 13:01:24 -04:00
app . get ( '/' , function ( req , res ) {
categories . getAllCategories ( function ( returnData ) {
res . send (
2013-06-20 16:29:44 -04:00
app . build _header ( res ) +
2013-06-14 13:01:24 -04:00
'\n\t<noscript>\n' + templates [ 'noscript/header' ] + templates [ 'noscript/home' ] . parse ( returnData ) + '\n\t</noscript>' +
app . create _route ( '' ) +
templates [ 'footer' ]
) ;
} , 0 ) ;
} ) ;
2013-05-03 21:19:28 +00:00
app . get ( '/topic/:topic_id/:slug?' , function ( req , res ) {
2013-05-30 16:02:13 -04:00
var tid = req . params . topic _id ;
if ( tid . match ( '.rss' ) ) {
fs . readFile ( 'feeds/topics/' + tid , function ( err , data ) {
if ( err ) {
res . send ( "Unable to locate an rss feed at this location." ) ;
return ;
}
2013-06-05 11:54:44 -04:00
res . setHeader ( 'Content-Type' , 'application/xml' ) ;
res . setHeader ( 'Content-Length' , data . length ) ;
res . end ( data ) ;
2013-05-30 16:02:13 -04:00
} ) ;
return ;
}
var topic _url = tid + ( req . params . slug ? '/' + req . params . slug : '' ) ;
2013-06-11 15:40:50 -04:00
topics . getTopicById ( tid , ( ( req . user ) ? req . user . uid : 0 ) , function ( topic ) {
2013-05-28 14:11:27 -04:00
res . send (
2013-06-20 16:29:44 -04:00
app . build _header ( res ) +
2013-06-14 13:01:24 -04:00
'\n\t<noscript>\n' + templates [ 'noscript/header' ] + templates [ 'noscript/topic' ] . parse ( topic ) + '\n\t</noscript>' +
2013-06-06 15:34:12 -04:00
'\n\t<script>templates.ready(function(){ajaxify.go("topic/' + topic _url + '");});</script>' +
2013-05-28 14:11:27 -04:00
templates [ 'footer' ]
) ;
} ) ;
2013-05-03 21:19:28 +00:00
} ) ;
2013-04-25 21:55:11 +00:00
2013-05-06 22:05:42 +00:00
app . get ( '/category/:category_id/:slug?' , function ( req , res ) {
2013-06-04 12:58:04 -04:00
var cid = req . params . category _id ;
if ( cid . match ( '.rss' ) ) {
fs . readFile ( 'feeds/categories/' + cid , function ( err , data ) {
if ( err ) {
res . send ( "Unable to locate an rss feed at this location." ) ;
return ;
}
2013-06-05 11:54:44 -04:00
res . setHeader ( 'Content-Type' , 'application/xml' ) ;
res . setHeader ( 'Content-Length' , data . length ) ;
res . end ( data ) ;
2013-06-04 12:58:04 -04:00
} ) ;
return ;
}
var category _url = cid + ( req . params . slug ? '/' + req . params . slug : '' ) ;
2013-06-14 13:01:24 -04:00
categories . getCategoryById ( cid , 0 , function ( returnData ) {
res . send (
2013-06-20 16:29:44 -04:00
app . build _header ( res ) +
2013-06-14 13:01:24 -04:00
'\n\t<noscript>\n' + templates [ 'noscript/header' ] + templates [ 'noscript/category' ] . parse ( returnData ) + '\n\t</noscript>' +
'\n\t<script>templates.ready(function(){ajaxify.go("category/' + category _url + '");});</script>' +
templates [ 'footer' ]
) ;
} ) ;
2013-05-06 22:05:42 +00:00
} ) ;
2013-05-05 13:05:05 -04:00
app . get ( '/confirm/:code' , function ( req , res ) {
2013-06-20 16:29:44 -04:00
res . send ( app . build _header ( res ) + '<script>templates.ready(function(){ajaxify.go("confirm/' + req . params . code + '");});</script>' + templates [ 'footer' ] ) ;
2013-05-05 13:05:05 -04:00
} ) ;
2013-05-09 06:26:32 +00:00
2013-05-03 21:19:28 +00:00
// These functions are called via ajax once the initial page is loaded to populate templates with data
2013-05-24 11:18:28 -04:00
function api _method ( req , res ) {
var uid = ( req . user ) ? req . user . uid : 0 ;
2013-05-14 14:04:19 -04:00
2013-04-25 19:13:23 +00:00
switch ( req . params . method ) {
2013-05-17 15:20:08 -04:00
case 'get_templates_listing' :
utils . walk ( global . configuration . ROOT _DIRECTORY + '/public/templates' , function ( err , data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-17 15:20:08 -04:00
} ) ;
break ;
2013-04-25 19:13:23 +00:00
case 'home' :
2013-05-21 21:07:26 -04:00
categories . getAllCategories ( function ( data ) {
2013-06-03 14:51:02 -04:00
data . motd _class = ( config . show _motd === '1' || config . show _motd === undefined ) ? '' : 'none' ;
2013-05-23 13:04:25 -04:00
data . motd = marked ( config . motd || "# NodeBB v0.1\nWelcome to NodeBB, the discussion platform of the future.\n\n<a target=\"_blank\" href=\"http://www.nodebb.org\" class=\"btn btn-large\"><i class=\"icon-comment\"></i> Get NodeBB</a> <a target=\"_blank\" href=\"https://github.com/designcreateplay/NodeBB\" class=\"btn btn-large\"><i class=\"icon-github-alt\"></i> Fork us on Github</a> <a target=\"_blank\" href=\"https://twitter.com/dcplabs\" class=\"btn btn-large\"><i class=\"icon-twitter\"></i> @dcplabs</a>" ) ;
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-24 11:18:28 -04:00
} , uid ) ;
2013-04-25 19:13:23 +00:00
break ;
2013-05-02 16:36:26 +00:00
case 'login' :
var data = { } ,
2013-05-09 06:26:32 +00:00
login _strategies = auth . get _login _strategies ( ) ,
2013-05-02 16:36:26 +00:00
num _strategies = login _strategies . length ;
if ( num _strategies == 0 ) {
data = {
'login_window:spansize' : 'span12' ,
'alternate_logins:display' : 'none'
} ;
} else {
data = {
'login_window:spansize' : 'span6' ,
'alternate_logins:display' : 'block'
}
for ( var i = 0 , ii = num _strategies ; i < ii ; i ++ ) {
2013-05-02 14:47:00 -04:00
data [ login _strategies [ i ] + ':display' ] = 'active' ;
2013-05-02 16:36:26 +00:00
}
}
2013-05-02 19:48:14 +00:00
2013-06-20 12:41:22 -04:00
data . token = res . locals . csrf _token ;
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-13 14:16:33 -04:00
break ;
case 'register' :
var data = { } ,
login _strategies = auth . get _login _strategies ( ) ,
num _strategies = login _strategies . length ;
if ( num _strategies == 0 ) {
data = {
'register_window:spansize' : 'span12' ,
'alternate_logins:display' : 'none'
} ;
} else {
data = {
'register_window:spansize' : 'span6' ,
'alternate_logins:display' : 'block'
}
for ( var i = 0 , ii = num _strategies ; i < ii ; i ++ ) {
data [ login _strategies [ i ] + ':display' ] = 'active' ;
}
}
2013-06-20 12:41:22 -04:00
data . token = res . locals . csrf _token ;
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-02 16:36:26 +00:00
break ;
2013-05-01 21:26:47 +00:00
case 'topic' :
2013-05-24 11:18:28 -04:00
topics . getTopicById ( req . params . id , uid , function ( data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-24 11:18:28 -04:00
} ) ;
2013-05-01 21:26:47 +00:00
break ;
2013-05-06 22:05:42 +00:00
case 'category' :
2013-05-24 11:18:28 -04:00
categories . getCategoryById ( req . params . id , uid , function ( data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-24 11:18:28 -04:00
} , req . params . id , uid ) ;
2013-05-06 22:05:42 +00:00
break ;
2013-05-07 16:52:35 +00:00
case 'latest' :
2013-05-24 11:18:28 -04:00
categories . getLatestTopics ( uid , 0 , 9 , function ( data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-07 16:52:35 +00:00
} ) ;
break ;
case 'popular' :
2013-05-24 11:18:28 -04:00
categories . getLatestTopics ( uid , 0 , 9 , function ( data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-07 16:52:35 +00:00
} ) ;
break ;
case 'active' :
2013-05-24 11:18:28 -04:00
categories . getLatestTopics ( uid , 0 , 9 , function ( data ) {
2013-06-20 15:08:33 -04:00
res . json ( data ) ;
2013-05-07 16:52:35 +00:00
} ) ;
break ;
2013-05-05 13:05:05 -04:00
case 'confirm' :
2013-05-14 12:13:29 -04:00
user . email . confirm ( req . params . id , function ( data ) {
2013-05-05 13:05:05 -04:00
if ( data . status === 'ok' ) {
2013-06-20 15:08:33 -04:00
res . json ( {
2013-05-05 13:05:05 -04:00
'alert-class' : 'alert-success' ,
title : 'Email Confirmed' ,
text : 'Thank you for vaidating your email. Your account is now fully activated.'
2013-06-20 15:08:33 -04:00
} ) ;
2013-05-05 13:05:05 -04:00
} else {
2013-06-20 15:08:33 -04:00
res . json ( {
2013-05-05 13:05:05 -04:00
'alert-class' : 'alert-error' ,
title : 'An error occurred...' ,
text : 'There was a problem validating your email address. Perhaps the code was invalid or has expired.'
2013-06-20 15:08:33 -04:00
} ) ;
2013-05-05 13:05:05 -04:00
}
} ) ;
break ;
2013-04-25 19:13:23 +00:00
default :
2013-06-20 15:08:33 -04:00
res . json ( { } ) ;
2013-04-28 13:28:20 -04:00
break ;
2013-04-25 19:13:23 +00:00
}
2013-05-01 21:26:47 +00:00
}
2013-05-07 21:17:22 +00:00
2013-05-01 21:26:47 +00:00
app . get ( '/api/:method' , api _method ) ;
app . get ( '/api/:method/:id' , api _method ) ;
2013-05-07 21:17:22 +00:00
// ok fine MUST ADD RECURSION style. I'll look for a better fix in future but unblocking baris for this:
app . get ( '/api/:method/:id/:section?' , api _method ) ;
2013-05-01 21:26:47 +00:00
app . get ( '/api/:method/:id*' , api _method ) ;
2013-05-06 10:05:00 -04:00
2013-06-20 12:41:22 -04:00
app . all ( '/test' , function ( req , res ) {
2013-06-21 12:09:22 -04:00
var RDB = require ( './redis.js' ) ;
RDB . lpush ( 'administrators' , 1 , function ( err , data ) {
// console.log(err, data);
res . send ( ) ;
} ) ;
2013-05-09 10:20:25 -04:00
} ) ;
2013-05-15 15:42:24 -04:00
//START TODO: MOVE TO GRAPH.JS
app . get ( '/graph/users/:username/picture' , function ( req , res ) {
user . get _uid _by _username ( req . params . username , function ( uid ) {
2013-05-15 15:55:39 -04:00
if ( uid == null ) {
res . send ( '{status:0}' ) ;
return ;
}
2013-05-15 15:42:24 -04:00
user . getUserField ( uid , 'picture' , function ( picture ) {
2013-05-29 14:55:43 -04:00
if ( picture == null ) res . redirect ( 'http://www.gravatar.com/avatar/a938b82215dfc96c4cabeb6906e5f953&default=identicon' ) ;
2013-05-15 15:42:24 -04:00
res . redirect ( picture ) ;
} ) ;
} ) ;
} ) ;
//END TODO: MOVE TO GRAPH.JS
2013-04-22 16:51:32 +00:00
} ( WebServer ) ) ;
2013-04-22 15:17:41 -04:00
server . listen ( config . port ) ;
2013-04-22 15:23:02 -04:00
global . server = server ;