I have the following schema for user
and sp
. sp
is short for service provider. Service provider is a user, it has a reference to user.
I am trying to signup and singin using PassportJS module of NodeJS. I have been able to signup an sp
and I could see the data persisted in MongoDB collections in users
and sps
collections, but I am not able to display the complete data of sp on the profile page. I get to display only its user data. For example, I don't see the sp
's spname
data in the profile page after authentication.
Following is some of the code:
Schema for user:
var userSchema = mongoose.Schema({
ip: String,
local : {
email : String,
password : String
}
name: String ,
created: { type: Date, default: Date.now },
})
.plugin(mongooseRole, {
roles: ['public', 'user', 'sp', 'admin'],
accessLevels: {
'public': ['public', 'user', 'sp', 'admin'],
'anon': ['public'],
'user': ['user', 'admin'],
'sp': ['sp', 'admin'],
'admin': ['admin']
}
});
var User = mongoose.model("User", userSchema);
Schema for sp:
var spSchema = mongoose.Schema({
user: { type: Schema.ObjectId, ref: 'User' },
spname: String,
});
var SP = mongoose.model("SP", spSchema);
PassportJS code for logging in:
//serialization/deserialization code
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//authentication code
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'local.email' : email }, function(err, user) {
if(user.role == 'sp') {
SP.findOne({ user: user._id }).populate('user').exec(function(err, sp) {
if (err)
return done(err);
if (!sp.user)
return done(null, false, req.flash('loginMessage', 'No sp user found.'));
if (!sp.user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, sp);
});
}
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, user);
});
}));
Displaying the profile:
app.get('/profile', isLoggedIn, function (req, res) {
res.render('profile', {
user: req.user
});
});
profile.ejs
<%= user %>
Could somebody help me with what should I be doing to display the whole sp
object with all its data?
You're only querying User
schema while deserializing. You need to deserialize sp
if you want it. I'm not entirely sure about your situation but it seems that you're either authenticating a User
or an SP
, in which case you should similarly either deserializing User
or SP
(if User
returns empty). Something like this maybe:
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
if (user.role == 'sp')
SP.findOne({user: user_id}).populate('user').exec(function(err, sp) {
done(err, sp);
});
else done(err, user);
});
});