passport.js•2.68 kB
/**
* Passport configuration for Facebook OAuth authentication
*/
const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const User = require('../models/user');
const facebookConfig = require('./facebook');
const logger = require('../utils/logger');
const tokenManager = require('../utils/tokenManager');
// Configure Facebook strategy for Passport
passport.use(new FacebookStrategy({
clientID: facebookConfig.appId,
clientSecret: facebookConfig.appSecret,
callbackURL: facebookConfig.callbackURL,
profileFields: ['id', 'displayName', 'email', 'picture.type(large)'],
enableProof: true,
scope: facebookConfig.permissions
},
async (accessToken, refreshToken, profile, done) => {
try {
// Check if user exists in database
let user = await User.findOne({ facebookId: profile.id });
if (user) {
// Update existing user with new tokens
user.accessToken = await tokenManager.encryptToken(accessToken);
user.refreshToken = refreshToken ? await tokenManager.encryptToken(refreshToken) : user.refreshToken;
user.tokenExpiry = new Date(Date.now() + (60 * 60 * 2 * 1000)); // 2 hours from now
user.name = profile.displayName;
user.email = profile.emails && profile.emails[0] ? profile.emails[0].value : user.email;
user.picture = profile.photos && profile.photos[0] ? profile.photos[0].value : user.picture;
await user.save();
logger.info(`User ${user.name} logged in`);
} else {
// Create new user
user = await User.create({
facebookId: profile.id,
name: profile.displayName,
email: profile.emails && profile.emails[0] ? profile.emails[0].value : '',
picture: profile.photos && profile.photos[0] ? profile.photos[0].value : '',
accessToken: await tokenManager.encryptToken(accessToken),
refreshToken: refreshToken ? await tokenManager.encryptToken(refreshToken) : null,
tokenExpiry: new Date(Date.now() + (60 * 60 * 2 * 1000)) // 2 hours from now
});
logger.info(`New user ${user.name} created`);
}
return done(null, user);
} catch (error) {
logger.error(`Error in Facebook authentication: ${error.message}`);
return done(error, false);
}
}
));
// Serialize user to session
passport.serializeUser((user, done) => {
done(null, user.id);
});
// Deserialize user from session
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id);
done(null, user);
} catch (error) {
done(error, null);
}
});