2

I'm rather new to Node.js and Express. I'm trying to finish the configuration of everyauth with Twitter and I'm trying to access the 'res.user' on the server side which according to the documentation of everyauth requires that .findByUserId gets configured. That's where I'm having my trouble. How do you configure findByUserId?

Here's what I got. It's currently working to create a new user or log them in, I haven't setup the .findByUserId correctly yet giving me access to req.user which I need on the server side. If you have other suggestions on how to optimize this code, please let me know too since I'm just learning.

Code edited below...

App.js

var express = require('express')
  , everyauth   = require('everyauth')
  , util        = require('util')
  , Promise     = everyauth.Promise
  , users       = require('./lib/users')
  , config      = require('./config.js')
  , twitter     = require('./lib/twitter')
  , games        = require('./lib/games')

  everyauth.twitter
    .consumerKey(config.twitter.consumerKey)
    .consumerSecret(config.twitter.consumerSecret)
    .findOrCreateUser( function (session, accessToken, accessTokenSecret, twitterUserMetadata) {
      var promise = this.Promise();
      users.findOrCreateUserbyTwitterData(twitterUserMetadata, accessToken, accessTokenSecret, promise)
      return promise;
    })
    .redirectPath('/');
  everyauth.everymodule.findUserById(function (userId, callback) {
      users.findById(userId, callback);
  });

var app = module.exports = express.createServer();
everyauth.helpExpress(app);
// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser());
  app.use(express.session({secret: "FxT10477A93d54HJx5"}));
  app.use(everyauth.middleware());
  app.set('view engine', 'jade');
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

app.get('/', function(req, res){
  console.log(req.user);
  res.render('index', { title: 'Zeitheist 2' });
});

Users.js

var twitter = require(__dirname + "/twitter");
var mongoose = require('mongoose');
var Schema = mongoose.Schema
  , ObjectId = Schema.ObjectId;

var userSchema = new Schema({
    user                  : ObjectId
    , id                  : Number
    , twitterId           : Number
    , twitterName         : String
    , profileImageUrl     : String
    , name                : String
    , dateCreated         : Date
    , session             : String
    , accessToken         : String
    , accessTokenSecret   : String
});

var conn = mongoose.createConnection('mongodb://localhost/zeitheist2_test');
var userModel = conn.model('User', userSchema);

this.findOrCreateUserbyTwitterData = function(twitterData, accessToken, accessTokenSecret, promise) {
  userModel.find({'twitterId' : twitterData.id}, function(err, users) {
     if(err) throw err;
     if(users.length > 0) {
       promise.fulfill(users[0]);
     } else {
       var user = new userModel();
       user.twitterId = twitterData.id
       user.twitterName = twitterData.screen_name
       user.profileImageUrl = twitterData.profile_image_url
       user.name = twitterData.name
       user.accessToken = accessToken
       user.accessTokenSecret = accessTokenSecret
       user.save(function(err) {
         if (err) throw err;
         twitter.follow(accessToken, accessTokenSecret);
         promise.fulfill(user);
       });
     }
   });
}
this.findById = function(userId, callback) {
  userModel.findOne({'_id' : userId}, function(err, user) {
    if(err) throw err;
    if(callback) 
      callback(user);
    else
      return user;
  }); 
}

How does the everyauth.everymodule.findUserById need to look in order for me to access req.user? In the default route when I log req.user after I successfully login, it's showing "undefined"

aressidi
  • 680
  • 1
  • 10
  • 26

1 Answers1

0

Your code should look something like this:

everyauth.everymodule.findUserById(function (userId, callback) {
    userModel.findById(userId, callback);
});

In your code you're returning values from functions that should be calling callbacks instead. Remember, most everything in node is async and uses callbacks to return the results of anything involving I/O like database lookups.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Hi JohnnyHK, I made updates to the code in the original post as per your suggestion. Specifically I changed the everyauth.everymodule.findUserById function to match your example and also updated my .findById accessor my users.js. I'm still not getting a req.user. Any other ideas? – aressidi Apr 30 '12 at 23:11
  • By default, everyauth uses a primary key field of "id" from your user object so it's that field that is persisted to the session and passed into your registered findUserById callback. So if you haven't modified the default you'd need to change findById's findOne call to pass {'id': userId} instead. – JohnnyHK May 01 '12 at 00:11