diff options
-rw-r--r-- | app.js | 42 | ||||
-rw-r--r-- | config/config.js | 25 | ||||
-rw-r--r-- | config/express.js | 60 | ||||
-rw-r--r-- | config/passport.js | 109 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | router.js | 44 |
6 files changed, 208 insertions, 74 deletions
@@ -5,55 +5,39 @@ var express = require('express') , path = require('path') - , bcrypt = require('bcrypt') , passport = require('passport'); + var app = express(); // initiates express /** * App configuration */ +var port = process.env.PORT || 3000 + , env = process.env.NODE_ENV || 'development' + , config = require('./config/config')[env]; -app.configure(function(){ - // this controls the port the application will be running on. - // by adding 'process.enc.PORT' we enable the app to run on automated systems like heroku - app.set('port', process.env.PORT || 3000); - - app.set('views', __dirname + '/views'); // sets views to the right directory - app.set('view engine', 'ejs'); // initiates viewengine. We use EJS, or embedded js - http://embeddedjs.com/ - app.use(express.favicon(__dirname + '/public/faviconb.ico')); // sets favicon - app.use(express.logger('dev')); - app.use(express.bodyParser()); - app.use(express.cookieParser()); - app.use(express.session({ secret: 'lsdrghoi4hgqio42nqf2uqi32f3bilu23fl23b' })); - app.use(express.methodOverride()); - app.use(require('less-middleware')({ src: __dirname + '/public' })); - app.use(express.static(path.join(__dirname, 'public'))); - app.use(passport.initialize()); - app.use(passport.session()); -}); - -app.configure('development', function(){ - app.use(express.errorHandler()); -}); +/** + * Express + */ +var app = express(); +// express settings +require('./config/express')(app, config, passport); /** * Routes */ - -require('./router')(app); - +require('./router')(app, config); /** * Server initiation */ -app.listen(app.get('port'), function() { - console.log("Express server listening on port " + app.get('port')); +app.listen(port, function() { + console.log("Express server listening on port " + port); }); - diff --git a/config/config.js b/config/config.js new file mode 100644 index 0000000..8d120b2 --- /dev/null +++ b/config/config.js @@ -0,0 +1,25 @@ +var path = require('path') + , rootPath = path.normalize(__dirname + '/..'); + + +module.exports = { + development: { + db: 'mongodb://localhost/test', + root: rootPath, + app: { + name: 'Divid' + }, + facebook: { + clientID: "504825706245603", + clientSecret: "e5ea0faed85d8749cafd38732530ef35", + callbackURL: "https://divid.no/auth/facebook/callback" + }, + twitter: { + clientID: "CONSUMER KEY", + clientSecret: "CONSUMER SECRET", + callbackURL: "https://divid.no/auth/twitter/callback" + } + } +} + + diff --git a/config/express.js b/config/express.js new file mode 100644 index 0000000..4afd827 --- /dev/null +++ b/config/express.js @@ -0,0 +1,60 @@ + +/** + * Module dependencies + */ + +var express = require('express'); + + +/** + * Module + */ + +module.exports = function (app, config, passport) { + + //sets view engine and path + app.set('views', config.root + '/views'); + app.set('view engine', 'ejs'); + + app.use(express.static(config.root + '/public')); + + // don't use logger for test enc + if (process.env.NODE_ENV !== 'test') app.use(express.logger('dev')); + + + app.configure(function () { + + app.use(express.cookieParser()); //must be above sessions + + app.use(express.bodyParser()); //must be above methodOverride + + app.use(express.methodOverride()); + + app.use(express.session({ secret: 'lsdrghoi4hgqio42nqf2uqi32f3bilu23fl23b' })); + + // use passport session + app.use(passport.initialize()); + app.use(passport.session()); + + app.use(express.favicon(__dirname + '/public/faviconb.ico')); + + // use LESS for CSS + app.use(require('less-middleware')({ src: config.root + '/public' })); + + app.use(app.router); + + app.use(function(err, req, res, next) { + if (~err.message.indexOf('not fount')) return next(); // treat like 404 + + console.error(err.stack); + + res.status(500).render('500', { error: err.stack }); // render page + }); + + app.use(function(req, res, next) { + res.status(404).render('404', { url: req.originalUrl, error: 'Not found' }); // render page + }); + }); +} + + diff --git a/config/passport.js b/config/passport.js new file mode 100644 index 0000000..9518409 --- /dev/null +++ b/config/passport.js @@ -0,0 +1,109 @@ +// dependencies +var mongoose = require('mongoose') + , LocalStrategy = require('passport-local').Strategy + , FacebookStrategy = require('passport-facebook').Strategy + , TwitterStrategy = require('passport-twitter').Strategy + , User = mongoose.model('User'); + +/** + * This is where the magic happends + */ + +module.exports = function (passport, config) { + + // serialize sessions + passport.serializeUser( function(user, done) { + done(null, user.id); + }); + passport.deserializeUser( function(id, done) { + User.findOne({ _id: id }, function(err, user) { + done(err, user); + }); + }); + + + /** + * Local strategy + */ + passport.use(new LocalStrategy({ + usernameField: 'email', + passwordField: 'password' + }, function(email, password, done) { + + // looks up the user in the database, and check if password matches + User.findOne({ email: email }, function(err, user) { + if (err) return done(err); + if (!user) return done(null, false, { message: 'Unknown user' }); + if (!user.authenticate(password)) return done(null, false, { message: 'Invalid password' }); + return done(null, user); + }); + })); + + + /** + * Facebook strategy + */ + passport.use(new FacebookStrategy({ + clientID: config.facebook.clientID + , clientSecret: config.facebook.clientSecret + , callbackURL: config.facebook.callbackURL + }, function(accessToken, refreshToken, profile, done) { + + // looks up the user in the database. Will create the user if it does not exist + User.findOne({ 'facebook.id': profile.id }, function(err, user) { + if(err) return done(err); + if (!user) { + user = new User({ + name: profile.displayName + , email: profile.emails[0].value + , username: profile.username + , provider: 'facebook' + , facebook: profile._json + }); + user.save(function(err) { + if (err) console.log(err); + return done(err, user); + }); + } else { + return done(err, user); + } + }); + })); + + + /** + * Twitter strategy + */ + passport.use(new TwitterStrategy({ + consumerKey: config.twitter.clientID + , consumerSecret: config.twitter.clientSecret + , callbackURL: config.twitter.callbackURL + }, function(token, tokenSecret, profile, done) { + + // looks up the user in the database. Will create the user if it does not exist + User.findOne({ 'twitter.id': profile.id }, function(err, user) { + if (err) return done(err); + if (!user) { + user = new User({ + name: profile.displayName + , username: profile.username + , provider: 'twitter' + , twitter: profile._json + }); + user.save(function(err) { + if (err) console.log(err); + return done(err, user); + }); + } else { + return done(err, user); + } + }); + })); + + + + + + +} + diff --git a/package.json b/package.json index 48ae466..08595cb 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ , "bcrypt": "latest" , "nodemon": "latest" } - , "decDependencies": { + , "devDependencies": { "mocha": "latest" } } @@ -1,13 +1,9 @@ var passport = require('passport') - , LocalStrategy = require('passport-local').Strategy - , FacebookStrategy = require('passport-facebook').Strategy , mongodb = require('mongodb') , mongoose = require('mongoose') , bcrypt = require('bcrypt') , SALT_WORK_FACTOR = 15; -var FACEBOOK_APP_ID = "504825706245603"; -var FACEBOOK_APP_SECRET = "e5ea0faed85d8749cafd38732530ef35"; // connects to mongodb mongoose.connect('localhost', 'test'); @@ -110,46 +106,6 @@ passport.deserializeUser( function(token, done) { } else { done(null, token); } }); -// Use the LocalStrategy within Passport. -// Strategies in passport require a `verify` function, which accept -// credentials (in this case, a username and password), and invoke a callback -// with a user object. In the real world, this would query a database; -// however, in this example we are using a baked-in set of users. -passport.use(new LocalStrategy(function(username, password, done) { - User.findOne({ username: username }, function(err, user) { - if (err) return done(err); - if (!user) { return done(null, false, { message: 'Unknown user ' + username }); } - user.comparePassword(password, function(err, isMatch) { - if (err) return done(err); - if (isMatch) { - return done(null, user); - } else { - return done(null, false, { message: 'Invalid password' }); - } - }); - }); -})); - -// Use the FacebookStrategy within Passport. -// Strategies in Passport require a `verify` function, which accept -// credentials (in this case, an accessToken, refreshToken, and Facebook -// profile), and invoke a callback with a user object. -passport.use(new FacebookStrategy({ - clientID: FACEBOOK_APP_ID, - clientSecret: FACEBOOK_APP_SECRET, - callbackURL: "https://divid.no/auth/facebook/callback" -}, function(accessToken, refreshToken, profile, done) { - // asynchronous verification, for effect... - process.nextTick(function() { - - // To keep the example simple, the user's Facebook profile is returned to - // represent the logged-in user. In a typical application, you would want - // to associate the Facebook account with a user record in your database, - // and return that user instead. - return done(null, profile); - }); - } -)); // to ensure that users are logged in function ensureAuthenticated(req, res, next) { |