From 2059be60461c1577324ab3b51d967e18aa2e700e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 6 Jun 2014 11:39:24 -0400 Subject: sign in with facebook / twitter --- package.json | 1 + server/index.js | 37 ++------------- server/lib/auth.js | 110 +++++++++++++++++++++++++++++++++++++++------ server/lib/schemas/User.js | 3 ++ views/partials/signin.ejs | 54 +++++++++++----------- 5 files changed, 131 insertions(+), 74 deletions(-) diff --git a/package.json b/package.json index 93ed51a..554a678 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "connect-mongo": "~0.4.1", "passport": "~0.2.0", "passport-twitter": "~1.0.2", + "passport-facebook": "~1.0.3", "passport.socketio": "~3.0.1", "node-restful": "~0.1.14", "ejs": "^0.8.8", diff --git a/server/index.js b/server/index.js index 3a28f0e..d5afe6e 100644 --- a/server/index.js +++ b/server/index.js @@ -12,9 +12,7 @@ var config = require('../config.json'), var http = require('http'), express = require('express'), MongoStore = require('connect-mongo')(express), - TwitterStrategy = require('passport-twitter').Strategy, passport = require('passport'), - passportSocketIo = require("passport.socketio"), path = require('path'), mongoose = require('mongoose'); @@ -52,13 +50,7 @@ app.get('env') === 'development' && app.use(express.errorHandler()); // Configure user authentication -passport.serializeUser(auth.serializeUser); -passport.deserializeUser(auth.deserializeUser); -passport.use(new TwitterStrategy({ - consumerKey: process.env.VVALLS_TWITTER_KEY || '0L5blfBIapqhpons8bCXdIoGM', - consumerSecret: process.env.VVALLS_TWITTER_SECRET || '5EKW7m7inoODqYSKbp7cadBKFp1FghBl4MBDoXNcUjKtodZfuP', - callbackURL: 'http://' + config.host + '/auth/twitter/callback' -}, auth.insertUser)); +auth.init() // Essential middleware // app.all('*', middleware.enableCORS); @@ -69,34 +61,13 @@ app.get('/login', views.login); app.get('/logout', auth.logout); app.get('/auth/twitter', auth.login('twitter')); app.get('/auth/twitter/callback', auth.loggedIn('twitter')); +app.get('/auth/facebook', auth.login('facebook')); +app.get('/auth/facebook/callback', auth.loggedIn('facebook')); /* -io.set('authorization', passportSocketIo.authorize({ - cookieParser: express.cookieParser, - passport: passport, - key: 'posthang.sid', // the name of the cookie where express/connect stores its session_id - secret: '1337machine', // the session_secret to parse the cookie - store: SessionStore, // we NEED to use a sessionstore. no memorystore please - success: onAuthorizeSuccess, // *optional* callback on success - read more below - fail: onAuthorizeFail, // *optional* callback on fail/error - read more below -})); - -function onAuthorizeSuccess (data, accept) { - // console.error('successful connection to socket.io'); - accept(null, true); -} -function onAuthorizeFail(data, message, error, accept){ - if (error) { - throw new Error(message); - } - // console.log(data) - console.error('failed connection to socket.io:', message); - - // We use this callback to log all of our failed connections. - accept(null, false); -} +auth.initSockets(io) */ http.createServer(app).listen(app.get('port'), function () { diff --git a/server/lib/auth.js b/server/lib/auth.js index 04ab346..22917c3 100644 --- a/server/lib/auth.js +++ b/server/lib/auth.js @@ -1,48 +1,132 @@ /* jshint node: true */ var passport = require('passport'), + FacebookStrategy = require('passport-facebook').Strategy, + TwitterStrategy = require('passport-twitter').Strategy, + passportSocketIo = require("passport.socketio"), _ = require('lodash'), config = require('../../config.json'), User = require('./schemas/User'); var auth = { - login: function (method) { - return passport.authenticate(method); + init: function () { + passport.serializeUser(auth.serializeUser); + passport.deserializeUser(auth.deserializeUser); + + passport.use(new TwitterStrategy({ + consumerKey: process.env.VVALLS_TWITTER_KEY || '0L5blfBIapqhpons8bCXdIoGM', + consumerSecret: process.env.VVALLS_TWITTER_SECRET || '5EKW7m7inoODqYSKbp7cadBKFp1FghBl4MBDoXNcUjKtodZfuP', + callbackURL: 'http://' + config.host + '/auth/twitter/callback' + }, auth.insertTwitterUser)); + + passport.use(new FacebookStrategy({ + clientID: process.env.VVALLS_FACEBOOK_KEY || '719828821410310', + clientSecret: process.env.VVALLS_FACEBOOK_SECRET || 'f9aba78e08f37f621eadb88b1409d48c', + callbackURL: 'http://' + config.host + '/auth/facebook/callback', + enableProof: false, + }, auth.insertFacebookUser)); }, + + initSockets: function (io, cookieParser, SessionStore) { + io.set('authorization', passportSocketIo.authorize({ + cookieParser: express.cookieParser, + passport: passport, + key: 'vvalls.sid', // the name of the cookie where express/connect stores its session_id + secret: 'flibbertigibbet', // the session_secret to parse the cookie + store: SessionStore, // we NEED to use a sessionstore. no memorystore please + success: auth.socketSuccess, + fail: auth.socketFail, + })); + }, + + socketSuccess: function (data, accept) { + // console.error('successful connection to socket.io'); + accept(null, true); + }, + + socketFail: function (data, message, error, accept){ + if (error) { + throw new Error(message); + } + // console.log(data) + console.error('failed connection to socket.io:', message); + // We use this callback to log all of our failed connections. + accept(null, false); + }, + + // technically these returns the login middleware + login: function (strategy) { + return passport.authenticate(strategy); + }, + + loggedIn: function (strategy) { + return passport.authenticate(strategy, { + successReturnToOrRedirect: '/', + failureRedirect: '/login' + }); + }, + logout: function (req, res) { req.logout(); res.redirect('/'); }, serializeUser: function (user, done) { - done(null, user.twitter_id); + done(null, user._id); }, deserializeUser: function (id, done) { - User.findOne({ twitter_id: id }, "_id displayName username photo", function (err, user) { + User.findOne({ _id: id }, "_id displayName username photo", function (err, user) { done(err, user); }); }, - insertUser: function (accessToken, refreshToken, profile, done) { + insertTwitterUser: function (accessToken, refreshToken, profile, done) { process.nextTick(function () { var userData = { + twitter_id: profile.id, username: profile.username, displayName: profile.displayName, - photo: profile.photos[0].value + photo: profile.photos[0].value, + links: ["https://twitter.com/" + profile.username] }; - User.update({twitter_id: profile.id}, userData, {upsert: true}, function (userData, profile, err) { - return done(err, _.merge(userData, {twitter_id: profile.id})); - }.bind(this, userData, profile)); + + User.findOne({twitter_id: profile.id}, function(err, data){ + if (! err && data) { + return done(err, data); + } + new User(userData).save(function(err, data){ + if (err) { console.error(err) } + return done(err, data) + }) + }); + }); }, - loggedIn: function () { - return passport.authenticate('twitter', { - successReturnToOrRedirect: '/', - failureRedirect: '/login' + insertFacebookUser: function (accessToken, refreshToken, profile, done) { + console.log(profile) + process.nextTick(function () { + var userData = { + facebook_id: profile.id, + username: profile.username || profile.displayName.toLowerCase().replace(/ /g,'-'), + displayName: profile.displayName, + photo: "http://graph.facebook.com/" + profile.id + "/picture?type=large", + links: [profile.profileUrl] + }; + + User.findOne({facebook_id: profile.id}, function(err, data){ + if (! err && data) { + return done(err, data); + } + new User(userData).save(function(err, data){ + if (err) { console.error(err) } + return done(err, data) + }) + }); + }); }, diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index 1441631..9fd07e5 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -8,6 +8,8 @@ var mongoose = require('mongoose'), var UserSchema = new mongoose.Schema({ twitter_id: String, + facebook_id: String, + displayName: String, username: { type: String, @@ -26,6 +28,7 @@ var UserSchema = new mongoose.Schema({ case 'assets': case 'admin': case 'terms': + case 'assets': case '': return false } diff --git a/views/partials/signin.ejs b/views/partials/signin.ejs index 535b24c..6d5e530 100644 --- a/views/partials/signin.ejs +++ b/views/partials/signin.ejs @@ -2,22 +2,21 @@ X
- + – or the ol' fashion way –
  • - -
    - -
    + +
    + +
  • - -
    - -
    + +
    + +
  • -
  • @@ -28,34 +27,33 @@ X
    - + – or the ol' fashion way –
  • - -
    - -
    + +
    + +
  • - -
    - -
    + +
    + +
  • - -
    - -
    + +
    + +
  • - -
    - -
    + +
    + +
  • -
  • -- cgit v1.2.3-70-g09d2