/* jshint node: true */ var passport = require('passport'), FacebookStrategy = require('passport-facebook').Strategy, TwitterStrategy = require('passport-twitter').Strategy, LocalStrategy = require('passport-local').Strategy, passportSocketIo = require("passport.socketio"), cookieParser = require('express').cookieParser, crypto = require('crypto'), _ = require('lodash'), util = require('./util'), config = require('../../config.json'), User = require('./schemas/User'); var auth = { init: function () { passport.serializeUser(auth.serializeUser); passport.deserializeUser(auth.deserializeUser); passport.use(new LocalStrategy(auth.verifyLocalUser)) 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, express, SessionStore) { io.set('authorization', passportSocketIo.authorize({ cookieParser: 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 return the login middleware login: function (strategy) { return passport.authenticate(strategy); }, loggedIn: function (strategy) { return passport.authenticate(strategy, { successReturnToOrRedirect: '/', failureRedirect: '/login' }); }, loggedInLocal: function (req, res, next) { passport.authenticate("local", function(err, user, info){ if (err) { return res.json({ error: err }); } if (! user) { return info ? res.json(info) : res.redirect("/login"); } req.logIn(user, function(err) { if (err) { return next(err); } return res.json({ status: "OK" }) }); })(req, res, next); }, logout: function (req, res) { req.logout(); res.redirect('/'); }, serializeUser: function (user, done) { done(null, user._id); }, deserializeUser: function (id, done) { User.findOne({ _id: id }, "_id displayName username photo isStaff", function (err, user) { done(err, user); }); }, signup: function (req, res){ var username = util.trim(req.body.username) var password = req.body.password var email = util.trim(req.body.email) var shasum = crypto.createHash('sha1') shasum.update(password) password = shasum.digest('hex'); User.findOne({ username: username }, "_id username", function (err, user) { if (user) { res.json({ error: { errors: { username: { message: "Username has been taken" } } } }) return } var data = { username: username, displayName: username, password: password, email: email, created_ip: util.ip2num(req.connection.remoteAddress), last_ip: util.ip2num(req.connection.remoteAddress), created_at: new Date () } new User(data).save(function(err, user){ if (err || ! data) { return res.json({ error: err }) } req.login(user, function(){ res.json({ status: "OK", payload: user }) }) }) }) }, verifyLocalUser: function (username, password, done) { User.findOne({ username: username }, function(err, user){ if (err) { return done(err); } if (!user) { return done(null, false, { error: { errors: { username: { message: 'Incorrect username.' } }}}) } if (! user.validPassword(password)) { return done(null, false, { error: { errors: { password: { message: 'Incorrect password.' } }}}) } return done(null, user); }); }, 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, twitterName: profile.username, }; 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) }) }); }); }, insertFacebookUser: function (accessToken, refreshToken, profile, done) { 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", facebookUrl: profile.username ? "https://facebook.com/" + profile.username : "" }; 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) }) }); }); }, } module.exports = auth