2013-05-09 06:26:32 +00:00
( function ( Auth ) {
2014-03-02 14:45:57 -05:00
"use strict" ;
2013-05-09 06:26:32 +00:00
var passport = require ( 'passport' ) ,
passportLocal = require ( 'passport-local' ) . Strategy ,
2013-07-21 14:25:42 -04:00
nconf = require ( 'nconf' ) ,
2014-08-12 21:41:23 -04:00
Password = require ( '../password' ) ,
2014-01-27 13:37:31 -05:00
winston = require ( 'winston' ) ,
2014-05-25 13:08:56 -04:00
async = require ( 'async' ) ,
2014-09-19 22:53:57 -04:00
express = require ( 'express' ) ,
2014-01-27 13:37:31 -05:00
2014-08-12 21:41:23 -04:00
meta = require ( '../meta' ) ,
user = require ( '../user' ) ,
plugins = require ( '../plugins' ) ,
2014-05-04 17:26:56 -04:00
db = require ( '../database' ) ,
2014-09-19 22:53:57 -04:00
hotswap = require ( '../hotswap' ) ,
2014-08-12 21:41:23 -04:00
utils = require ( '../../public/src/utils' ) ,
2014-01-27 13:37:31 -05:00
2014-09-19 22:53:57 -04:00
login _strategies = [ ] ,
controllers = require ( '../controllers' ) ;
2013-05-09 06:26:32 +00:00
2014-03-17 14:18:58 -04:00
function logout ( req , res ) {
if ( req . user && parseInt ( req . user . uid , 10 ) > 0 ) {
winston . info ( '[Auth] Session ' + req . sessionID + ' logout (uid: ' + req . user . uid + ')' ) ;
var ws = require ( '../socket.io' ) ;
ws . logoutUser ( req . user . uid ) ;
req . logout ( ) ;
}
res . send ( 200 ) ;
}
function login ( req , res , next ) {
2014-05-25 13:08:56 -04:00
var continueLogin = function ( ) {
passport . authenticate ( 'local' , function ( err , userData , info ) {
if ( err ) {
2014-08-31 22:41:13 -04:00
req . flash ( 'error' , info ) ;
return res . redirect ( nconf . get ( 'relative_path' ) + '/login' ) ;
2014-05-25 13:08:56 -04:00
}
2014-04-08 15:29:51 -04:00
2014-05-25 13:08:56 -04:00
if ( ! userData ) {
2014-08-31 22:41:13 -04:00
if ( typeof info === 'object' ) {
info = '[[error:invalid-username-or-password]]' ;
}
req . flash ( 'error' , info ) ;
return res . redirect ( nconf . get ( 'relative_path' ) + '/login' ) ;
2014-05-25 13:08:56 -04:00
}
2014-03-17 14:18:58 -04:00
2014-05-25 13:08:56 -04:00
// Alter user cookie depending on passed-in option
if ( req . body . remember === 'true' ) {
var duration = 1000 * 60 * 60 * 24 * parseInt ( meta . configs . loginDays || 14 , 10 ) ;
req . session . cookie . maxAge = duration ;
req . session . cookie . expires = new Date ( Date . now ( ) + duration ) ;
} else {
req . session . cookie . maxAge = false ;
req . session . cookie . expires = false ;
}
2013-11-28 11:13:03 -05:00
2014-05-25 13:08:56 -04:00
req . login ( {
uid : userData . uid
} , function ( ) {
if ( userData . uid ) {
user . logIP ( userData . uid , req . ip ) ;
2014-09-19 08:27:27 -04:00
plugins . fireHook ( 'action:user.loggedIn' , userData . uid ) ;
2014-05-25 13:08:56 -04:00
}
2014-03-17 14:18:58 -04:00
2014-08-31 22:41:13 -04:00
if ( ! req . session . returnTo ) {
res . redirect ( nconf . get ( 'relative_path' ) + '/' ) ;
} else {
var next = req . session . returnTo ;
delete req . session . returnTo ;
res . redirect ( nconf . get ( 'relative_path' ) + next ) ;
}
2014-05-25 13:08:56 -04:00
} ) ;
} ) ( req , res , next ) ;
} ;
if ( meta . config . allowLocalLogin !== undefined && parseInt ( meta . config . allowLocalLogin , 10 ) === 0 ) {
return res . send ( 404 ) ;
}
2014-03-17 14:18:58 -04:00
2014-05-25 13:08:56 -04:00
if ( req . body . username && utils . isEmailValid ( req . body . username ) ) {
user . getUsernameByEmail ( req . body . username , function ( err , username ) {
if ( err ) {
return next ( err ) ;
}
req . body . username = username ? username : req . body . username ;
continueLogin ( ) ;
2014-03-17 14:18:58 -04:00
} ) ;
2014-05-25 13:08:56 -04:00
} else {
continueLogin ( ) ;
}
2014-03-17 14:18:58 -04:00
}
2014-03-17 14:56:00 -04:00
2014-03-17 14:18:58 -04:00
function register ( req , res ) {
if ( meta . config . allowRegistration !== undefined && parseInt ( meta . config . allowRegistration , 10 ) === 0 ) {
return res . send ( 403 ) ;
}
2014-06-04 18:54:41 -04:00
2014-06-04 18:54:11 -04:00
var userData = { } ;
2014-03-17 14:18:58 -04:00
2014-06-04 18:54:11 -04:00
for ( var key in req . body ) {
if ( req . body . hasOwnProperty ( key ) ) {
userData [ key ] = req . body [ key ] ;
}
}
2014-03-17 14:56:00 -04:00
2014-05-19 21:28:26 -04:00
plugins . fireHook ( 'filter:register.check' , req , res , userData , function ( err , req , res , userData ) {
2014-03-17 14:56:00 -04:00
if ( err ) {
2014-05-15 03:10:15 -04:00
return res . redirect ( nconf . get ( 'relative_path' ) + '/register' + ( err . message ? '?error=' + err . message : '' ) ) ;
2014-03-17 14:56:00 -04:00
}
user . create ( userData , function ( err , uid ) {
if ( err || ! uid ) {
2014-03-17 14:56:32 -04:00
return res . redirect ( nconf . get ( 'relative_path' ) + '/register' ) ;
2014-03-17 14:56:00 -04:00
}
2014-03-17 14:18:58 -04:00
req . login ( {
uid : uid
} , function ( ) {
2014-04-29 14:08:05 -04:00
user . logIP ( uid , req . ip ) ;
2014-03-17 14:18:58 -04:00
require ( '../socket.io' ) . emitUserCount ( ) ;
2014-06-04 18:54:41 -04:00
plugins . fireHook ( 'filter:register.complete' , uid , req . body . referrer , function ( err , uid , destination ) {
2014-06-06 18:36:02 +07:00
if ( destination ) {
res . redirect ( nconf . get ( 'relative_path' ) + destination ) ;
2014-06-04 18:54:41 -04:00
} else {
res . redirect ( nconf . get ( 'relative_path' ) + '/' ) ;
}
} ) ;
2014-03-17 14:18:58 -04:00
} ) ;
2014-03-17 14:56:00 -04:00
} ) ;
2013-11-28 10:30:29 -05:00
} ) ;
2014-03-17 14:18:58 -04:00
}
2013-11-28 10:30:29 -05:00
2014-09-21 14:29:27 -04:00
Auth . initialize = function ( app , middleware ) {
2013-05-09 06:26:32 +00:00
app . use ( passport . initialize ( ) ) ;
app . use ( passport . session ( ) ) ;
2014-09-21 14:29:27 -04:00
Auth . app = app ;
Auth . middleware = middleware ;
2014-03-02 14:45:57 -05:00
} ;
2013-08-23 13:14:36 -04:00
2013-05-09 06:26:32 +00:00
Auth . get _login _strategies = function ( ) {
return login _strategies ;
2014-03-02 14:45:57 -05:00
} ;
2013-05-09 06:26:32 +00:00
2014-09-19 22:53:57 -04:00
Auth . reloadRoutes = function ( callback ) {
var router = express . Router ( ) ;
router . hotswapId = 'auth' ;
2014-03-17 14:18:58 -04:00
plugins . ready ( function ( ) {
2014-09-21 14:29:27 -04:00
// Reset the registered login strategies
login _strategies . length = 0 ;
2014-03-17 14:18:58 -04:00
plugins . fireHook ( 'filter:auth.init' , login _strategies , function ( err ) {
2014-03-11 23:26:33 -04:00
if ( err ) {
2014-03-17 14:18:58 -04:00
winston . error ( 'filter:auth.init - plugin failure' ) ;
2014-03-11 23:26:33 -04:00
}
2013-05-09 06:26:32 +00:00
2014-07-18 19:10:53 -04:00
var deprecList = [ ] ;
2014-03-17 14:18:58 -04:00
for ( var i in login _strategies ) {
if ( login _strategies . hasOwnProperty ( i ) ) {
var strategy = login _strategies [ i ] ;
2014-07-18 11:09:33 -04:00
/ *
Backwards compatibility block for v0 . 6.0
Remove this upon release of v0 . 6.0 - 1
Ref : nodebb / nodebb # 1849
* /
if ( strategy . icon . slice ( 0 , 3 ) !== 'fa-' ) {
2014-07-18 19:10:53 -04:00
deprecList . push ( strategy . name ) ;
2014-07-18 11:09:33 -04:00
strategy . icon = 'fa-' + strategy . icon + '-square' ;
}
/* End backwards compatibility block */
2014-06-23 10:20:23 -04:00
if ( strategy . url ) {
2014-09-19 22:53:57 -04:00
router . get ( strategy . url , passport . authenticate ( strategy . name , {
2014-06-23 10:20:23 -04:00
scope : strategy . scope
} ) ) ;
}
2014-03-17 14:18:58 -04:00
2014-09-19 22:53:57 -04:00
router . get ( strategy . callbackURL , passport . authenticate ( strategy . name , {
2014-08-31 22:43:00 -04:00
successReturnToOrRedirect : nconf . get ( 'relative_path' ) + '/' ,
2014-06-06 18:05:26 +07:00
failureRedirect : nconf . get ( 'relative_path' ) + '/login'
2014-03-17 14:18:58 -04:00
} ) ) ;
2014-01-04 17:10:56 -05:00
}
2013-05-09 06:26:32 +00:00
}
2014-03-17 14:18:58 -04:00
2014-07-18 19:10:53 -04:00
/ *
Backwards compatibility block for v0 . 6.0
Remove this upon release of v0 . 6.0 - 1
Ref : nodebb / nodebb # 1849
* /
if ( deprecList . length ) {
winston . warn ( '[plugins] Deprecation notice: SSO plugins should now pass in the full fontawesome icon name (e.g. "fa-facebook-o"). Please update the following plugins:' ) ;
for ( var x = 0 , numDeprec = deprecList . length ; x < numDeprec ; x ++ ) {
process . stdout . write ( ' * ' + deprecList [ x ] + '\n' ) ;
}
}
/* End backwards compatibility block */
2014-09-19 22:53:57 -04:00
router . post ( '/logout' , logout ) ;
router . post ( '/register' , Auth . middleware . applyCSRF , register ) ;
router . post ( '/login' , Auth . middleware . applyCSRF , login ) ;
hotswap . replace ( 'auth' , router ) ;
if ( typeof callback === 'function' ) {
callback ( ) ;
}
2013-05-09 06:26:32 +00:00
} ) ;
} ) ;
2014-03-02 14:45:57 -05:00
} ;
2014-01-27 13:37:31 -05:00
Auth . login = function ( username , password , next ) {
if ( ! username || ! password ) {
2014-08-31 22:41:13 -04:00
next ( new Error ( '[[error:invalid-password]]' ) ) ;
return ;
2014-02-20 18:30:15 -05:00
}
var userslug = utils . slugify ( username ) ;
user . getUidByUserslug ( userslug , function ( err , uid ) {
if ( err ) {
return next ( err ) ;
}
2014-01-27 13:37:31 -05:00
2014-09-02 11:48:28 -04:00
if ( ! uid ) {
return next ( null , false , '[[error:no-user]]' ) ;
2014-02-20 18:30:15 -05:00
}
2014-01-27 13:37:31 -05:00
2014-05-11 11:45:20 -04:00
user . auth . logAttempt ( uid , function ( err ) {
2014-01-27 13:37:31 -05:00
if ( err ) {
2014-05-11 11:45:20 -04:00
return next ( null , false , err . message ) ;
2014-01-27 13:37:31 -05:00
}
2014-05-11 11:45:20 -04:00
db . getObjectFields ( 'user:' + uid , [ 'password' , 'banned' ] , function ( err , userData ) {
2014-02-20 18:30:15 -05:00
if ( err ) {
2014-05-11 11:45:20 -04:00
return next ( err ) ;
2014-01-27 13:37:31 -05:00
}
2014-05-11 11:45:20 -04:00
if ( ! userData || ! userData . password ) {
return next ( new Error ( '[[error:invalid-user-data]]' ) ) ;
2014-02-20 18:30:15 -05:00
}
2014-05-11 11:45:20 -04:00
if ( userData . banned && parseInt ( userData . banned , 10 ) === 1 ) {
return next ( null , false , '[[error:user-banned]]' ) ;
}
2014-08-12 21:41:23 -04:00
Password . compare ( password , userData . password , function ( err , res ) {
2014-05-11 11:45:20 -04:00
if ( err ) {
return next ( new Error ( 'bcrypt compare error' ) ) ;
}
if ( ! res ) {
return next ( null , false , '[[error:invalid-password]]' ) ;
}
user . auth . clearLoginAttempts ( uid ) ;
next ( null , {
uid : uid
} , '[[success:authentication-successful]]' ) ;
} ) ;
2014-01-27 13:37:31 -05:00
} ) ;
} ) ;
2014-02-20 18:30:15 -05:00
} ) ;
2014-03-02 14:45:57 -05:00
} ;
2014-02-20 18:30:15 -05:00
passport . use ( new passportLocal ( Auth . login ) ) ;
passport . serializeUser ( function ( user , done ) {
done ( null , user . uid ) ;
} ) ;
passport . deserializeUser ( function ( uid , done ) {
done ( null , {
uid : uid
} ) ;
} ) ;
2014-04-10 20:31:57 +01:00
} ( exports ) ) ;