2013-12-06 22:21:46 -05:00
var passport = require ( 'passport' ) ;
var LocalStrategy = require ( 'passport-local' ) . Strategy ;
var OAuthStrategy = require ( 'passport-oauth' ) . OAuthStrategy ;
2013-12-07 12:30:54 -05:00
var OAuth2Strategy = require ( 'passport-oauth' ) . OAuth2Strategy ;
2013-12-06 22:21:46 -05:00
var FacebookStrategy = require ( 'passport-facebook' ) . Strategy ;
var TwitterStrategy = require ( 'passport-twitter' ) . Strategy ;
var GitHubStrategy = require ( 'passport-github' ) . Strategy ;
var GoogleStrategy = require ( 'passport-google-oauth' ) . OAuth2Strategy ;
var User = require ( '../models/User' ) ;
2013-12-20 01:31:16 -05:00
var secrets = require ( './secrets' ) ;
2013-12-08 02:23:59 -05:00
var _ = require ( 'underscore' ) ;
2013-11-18 19:43:45 -05:00
2013-11-14 02:29:55 -05:00
passport . serializeUser ( function ( user , done ) {
done ( null , user . id ) ;
} ) ;
2013-11-13 22:19:37 -05:00
2013-11-14 02:29:55 -05:00
passport . deserializeUser ( function ( id , done ) {
User . findById ( id , function ( err , user ) {
done ( err , user ) ;
2013-11-13 22:19:37 -05:00
} ) ;
2013-11-14 02:29:55 -05:00
} ) ;
2013-11-13 22:19:37 -05:00
2014-01-07 15:48:21 -05:00
passport . use ( new LocalStrategy ( { usernameField : 'email' } , function ( email , password , done ) {
User . findOne ( { email : email } , function ( err , user ) {
2014-01-23 22:47:21 -05:00
if ( ! user ) return done ( null , false , { message : 'Email ' + email + ' not found' } ) ;
2013-11-14 02:29:55 -05:00
user . comparePassword ( password , function ( err , isMatch ) {
2014-01-23 22:47:21 -05:00
if ( isMatch ) {
2013-11-13 22:19:37 -05:00
return done ( null , user ) ;
} else {
2014-01-12 15:31:17 -05:00
return done ( null , false , { message : 'Invalid email or password.' } ) ;
2013-11-13 22:19:37 -05:00
}
} ) ;
2013-11-14 02:29:55 -05:00
} ) ;
} ) ) ;
2014-01-31 16:28:12 -05:00
/ * *
2014-01-31 23:56:50 -05:00
* Sign in with Facebook .
* /
2014-01-31 16:28:12 -05:00
2014-02-05 16:37:48 +00:00
passport . use ( new FacebookStrategy ( secrets . facebook , function ( req , accessToken , refreshToken , profile , done ) {
2013-12-14 01:32:33 -05:00
if ( req . user ) {
2014-01-31 22:23:19 -05:00
User . findOne ( { $or : [ { facebook : profile . id } , { email : profile . email } ] } , function ( err , existingUser ) {
2014-01-31 16:28:12 -05:00
if ( existingUser ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'errors' , { msg : 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.' } ) ;
done ( err ) ;
2014-01-31 16:28:12 -05:00
} else {
User . findById ( req . user . id , function ( err , user ) {
user . facebook = profile . id ;
user . tokens . push ( { kind : 'facebook' , accessToken : accessToken } ) ;
user . profile . name = user . profile . name || profile . displayName ;
user . profile . gender = user . profile . gender || profile . _json . gender ;
2014-01-31 22:23:19 -05:00
user . profile . picture = user . profile . picture || 'https://graph.facebook.com/' + profile . id + '/picture?type=large' ;
2014-01-31 16:28:12 -05:00
user . save ( function ( err ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'info' , { msg : 'Facebook account has been linked.' } ) ;
2014-01-31 16:28:12 -05:00
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-02 19:16:27 -05:00
} ) ;
2013-12-14 01:32:33 -05:00
} else {
User . findOne ( { facebook : profile . id } , function ( err , existingUser ) {
2014-01-31 22:23:19 -05:00
console . log ( profile )
2013-12-14 01:32:33 -05:00
if ( existingUser ) return done ( null , existingUser ) ;
var user = new User ( ) ;
2014-01-07 16:04:28 -05:00
user . email = profile . _json . email ;
2013-12-14 01:32:33 -05:00
user . facebook = profile . id ;
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'facebook' , accessToken : accessToken } ) ;
2013-12-14 01:32:33 -05:00
user . profile . name = profile . displayName ;
user . profile . gender = profile . _json . gender ;
2014-01-31 22:23:19 -05:00
user . profile . picture = 'https://graph.facebook.com/' + profile . id + '/picture?type=large' ;
2014-02-04 13:28:27 -05:00
user . profile . location = ( profile . _json . location ) ? profile . _json . location . name : '' ;
2013-12-14 01:32:33 -05:00
user . save ( function ( err ) {
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-06 20:16:39 -05:00
} ) ) ;
2013-12-06 01:44:45 -05:00
2014-01-31 22:39:13 -05:00
/ * *
* Sign in with GitHub .
* /
2013-12-20 01:31:16 -05:00
passport . use ( new GitHubStrategy ( secrets . github , function ( req , accessToken , refreshToken , profile , done ) {
2013-12-14 01:29:49 -05:00
if ( req . user ) {
2014-01-31 22:39:13 -05:00
User . findOne ( { $or : [ { github : profile . id } , { email : profile . email } ] } , function ( err , existingUser ) {
if ( existingUser ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'errors' , { msg : 'There is already a GitHub account that belongs to you. Sign in with that account or delete it, then link it with your current account.' } ) ;
done ( err ) ;
2014-01-31 22:39:13 -05:00
} else {
User . findById ( req . user . id , function ( err , user ) {
user . github = profile . id ;
user . tokens . push ( { kind : 'github' , accessToken : accessToken } ) ;
user . profile . name = user . profile . name || profile . displayName ;
user . profile . picture = user . profile . picture || profile . _json . avatar _url ;
user . profile . location = user . profile . location || profile . _json . location ;
user . profile . website = user . profile . website || profile . _json . blog ;
user . save ( function ( err ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'info' , { msg : 'GitHub account has been linked.' } ) ;
2014-01-31 22:39:13 -05:00
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-03 17:38:14 -05:00
} ) ;
2013-12-14 01:29:49 -05:00
} else {
User . findOne ( { github : profile . id } , function ( err , existingUser ) {
if ( existingUser ) return done ( null , existingUser ) ;
var user = new User ( ) ;
2014-01-07 16:04:28 -05:00
user . email = profile . _json . email ;
2013-12-14 01:29:49 -05:00
user . github = profile . id ;
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'github' , accessToken : accessToken } ) ;
2013-12-14 01:29:49 -05:00
user . profile . name = profile . displayName ;
user . profile . picture = profile . _json . avatar _url ;
user . profile . location = profile . _json . location ;
user . profile . website = profile . _json . blog ;
user . save ( function ( err ) {
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-06 20:16:39 -05:00
} ) ) ;
2013-12-06 01:24:12 -05:00
2014-01-31 23:17:58 -05:00
/ * *
* Sign in with Twitter .
* /
2013-12-20 01:31:16 -05:00
passport . use ( new TwitterStrategy ( secrets . twitter , function ( req , accessToken , tokenSecret , profile , done ) {
2013-12-14 01:27:10 -05:00
if ( req . user ) {
2014-01-31 23:56:50 -05:00
User . findOne ( { twitter : profile . id } , function ( err , existingUser ) {
2014-01-31 23:17:58 -05:00
if ( existingUser ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'errors' , { msg : 'There is already a Twitter account that belongs to you. Sign in with that account or delete it, then link it with your current account.' } ) ;
done ( err ) ;
2014-01-31 23:17:58 -05:00
} else {
User . findById ( req . user . id , function ( err , user ) {
user . twitter = profile . id ;
user . tokens . push ( { kind : 'twitter' , accessToken : accessToken , tokenSecret : tokenSecret } ) ;
user . profile . name = user . profile . name || profile . displayName ;
user . profile . location = user . profile . location || profile . _json . location ;
user . profile . picture = user . profile . picture || profile . _json . profile _image _url ;
user . save ( function ( err ) {
2014-01-31 23:58:59 -05:00
req . flash ( 'info' , { msg : 'Twitter account has been linked.' } ) ;
2014-01-31 23:17:58 -05:00
done ( err , user ) ;
} ) ;
} ) ;
}
2013-11-19 01:03:11 -05:00
} ) ;
2014-01-31 23:17:58 -05:00
2013-12-14 01:27:10 -05:00
} else {
User . findOne ( { twitter : profile . id } , function ( err , existingUser ) {
if ( existingUser ) return done ( null , existingUser ) ;
var user = new User ( ) ;
2014-02-04 08:23:52 -08:00
// Twitter will not provide an email address. Period.
// But a person’ s twitter username is guaranteed to be unique
2014-02-04 13:28:27 -05:00
// so we can "fake" a twitter email address as follows:
2014-02-04 08:23:52 -08:00
user . email = profile . username + "@twitter.com" ;
2013-12-14 01:27:10 -05:00
user . twitter = profile . id ;
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'twitter' , accessToken : accessToken , tokenSecret : tokenSecret } ) ;
2013-12-14 01:27:10 -05:00
user . profile . name = profile . displayName ;
user . profile . location = profile . _json . location ;
user . profile . picture = profile . _json . profile _image _url ;
user . save ( function ( err ) {
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-06 20:16:39 -05:00
} ) ) ;
2013-11-19 01:03:11 -05:00
2014-01-31 22:39:13 -05:00
/ * *
* Sign in with Google .
* /
2013-12-20 01:31:16 -05:00
passport . use ( new GoogleStrategy ( secrets . google , function ( req , accessToken , refreshToken , profile , done ) {
2013-12-13 00:28:29 -05:00
if ( req . user ) {
2014-01-31 22:39:13 -05:00
User . findOne ( { $or : [ { google : profile . id } , { email : profile . email } ] } , function ( err , existingUser ) {
if ( existingUser ) {
2014-01-31 23:56:50 -05:00
req . flash ( 'errors' , { msg : 'There is already a Google account that belongs to you. Sign in with that account or delete it, then link it with your current account.' } ) ;
done ( err ) ;
2014-01-31 22:39:13 -05:00
} else {
User . findById ( req . user . id , function ( err , user ) {
user . google = profile . id ;
user . tokens . push ( { kind : 'google' , accessToken : accessToken } ) ;
user . profile . name = user . profile . name || profile . displayName ;
user . profile . gender = user . profile . gender || profile . _json . gender ;
user . profile . picture = user . profile . picture || profile . _json . picture ;
user . save ( function ( err ) {
2014-01-31 23:56:50 -05:00
req . flash ( 'info' , { msg : 'Google account has been linked.' } ) ;
2014-01-31 22:39:13 -05:00
done ( err , user ) ;
} ) ;
} ) ;
}
2013-11-21 14:20:38 -05:00
} ) ;
2013-12-13 00:28:29 -05:00
} else {
User . findOne ( { google : profile . id } , function ( err , existingUser ) {
if ( existingUser ) return done ( null , existingUser ) ;
var user = new User ( ) ;
2014-01-07 16:04:28 -05:00
user . email = profile . _json . email ;
2013-12-13 00:28:29 -05:00
user . google = profile . id ;
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'google' , accessToken : accessToken } ) ;
2013-12-13 00:28:29 -05:00
user . profile . name = profile . displayName ;
user . profile . gender = profile . _json . gender ;
user . profile . picture = profile . _json . picture ;
user . save ( function ( err ) {
done ( err , user ) ;
} ) ;
} ) ;
}
2013-12-06 20:16:39 -05:00
} ) ) ;
2013-11-18 19:43:45 -05:00
2014-02-05 16:37:48 +00:00
/ * *
* Sign in with Tumblr .
* /
2013-12-06 22:49:40 -05:00
passport . use ( 'tumblr' , new OAuthStrategy ( {
requestTokenURL : 'http://www.tumblr.com/oauth/request_token' ,
accessTokenURL : 'http://www.tumblr.com/oauth/access_token' ,
userAuthorizationURL : 'http://www.tumblr.com/oauth/authorize' ,
2013-12-20 01:31:16 -05:00
consumerKey : secrets . tumblr . consumerKey ,
consumerSecret : secrets . tumblr . consumerSecret ,
callbackURL : secrets . tumblr . callbackURL ,
2013-12-07 00:29:32 -05:00
passReqToCallback : true
2013-12-06 22:49:40 -05:00
} ,
2013-12-07 00:29:32 -05:00
function ( req , token , tokenSecret , profile , done ) {
User . findById ( req . user . _id , function ( err , user ) {
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'tumblr' , accessToken : token , tokenSecret : tokenSecret } ) ;
2013-12-07 00:29:32 -05:00
user . save ( function ( err ) {
2013-12-07 02:18:26 -05:00
done ( err , user ) ;
2013-12-07 00:29:32 -05:00
} ) ;
2013-12-06 22:49:40 -05:00
} ) ;
2013-12-04 07:44:07 -05:00
}
2013-12-06 22:49:40 -05:00
) ) ;
2014-02-05 16:37:48 +00:00
/ * *
* Sign in with Foursquare .
* /
2013-12-07 12:30:54 -05:00
passport . use ( 'foursquare' , new OAuth2Strategy ( {
authorizationURL : 'https://foursquare.com/oauth2/authorize' ,
tokenURL : 'https://foursquare.com/oauth2/access_token' ,
2013-12-20 01:31:16 -05:00
clientID : secrets . foursquare . clientId ,
clientSecret : secrets . foursquare . clientSecret ,
callbackURL : secrets . foursquare . redirectUrl ,
2013-12-07 12:30:54 -05:00
passReqToCallback : true
} ,
function ( req , accessToken , refreshToken , profile , done ) {
User . findById ( req . user . _id , function ( err , user ) {
2013-12-20 13:48:33 -05:00
user . tokens . push ( { kind : 'foursquare' , accessToken : accessToken } ) ;
2013-12-07 12:30:54 -05:00
user . save ( function ( err ) {
done ( err , user ) ;
} ) ;
} ) ;
}
) ) ;
2013-12-08 02:23:59 -05:00
exports . isAuthenticated = function ( req , res , next ) {
2013-12-06 22:49:40 -05:00
if ( req . isAuthenticated ( ) ) return next ( ) ;
2013-11-14 02:29:55 -05:00
res . redirect ( '/login' ) ;
2013-12-08 02:10:49 -05:00
} ;
2013-12-08 04:30:43 -05:00
exports . isAuthorized = function ( req , res , next ) {
var provider = req . path . split ( '/' ) . slice ( - 1 ) [ 0 ] ;
if ( _ . findWhere ( req . user . tokens , { kind : provider } ) ) next ( ) ;
else res . redirect ( '/auth/' + provider ) ;
2013-12-20 01:31:16 -05:00
} ;