in api/services/passport.js [67:179]
passport.connect = function (req, query, profile, next) {
var user = {}
, provider;
// Get the authentication provider from the query.
query.provider = req.param('provider');
// Use profile.provider or fallback to the query.provider if it is undefined
// as is the case for OpenID, for example
provider = profile.provider || query.provider;
// If the provider cannot be identified we cannot match it to a passport so
// throw an error and let whoever's next in line take care of it.
if (!provider){
return next(new Error('No authentication provider was identified.'));
}
// If the profile object contains a list of emails, grab the first one and
// add it to the user.
if (profile.hasOwnProperty('emails')) {
user.email = profile.emails[0].value;
}
// If the profile object contains a username, add it to the user.
if (profile.hasOwnProperty('username')) {
user.username = profile.username;
}
// If neither an email or a username was available in the profile, we don't
// have a way of identifying the user in the future. Throw an error and let
// whoever's next in the line take care of it.
if (!user.username && !user.email) {
return next(new Error('Neither a username nor email was available'));
}
Passport.findOne({
provider : provider
, identifier : query.identifier.toString()
}, function (err, passport) {
if (err) {
return next(err);
}
if (!req.user) {
// Scenario: A new user is attempting to sign up using a third-party
// authentication provider.
// Action: Create a new user and assign them a passport.
if (!passport) {
// Validate user should have access
GitHub.validateUser(query.tokens.accessToken, function(err) {
if (err) return next(err);
User.findOrCreate({ username: user.username }, user, function (err, user) {
if (err) return next(err);
query.user = user.id;
Passport.create(query, function (err, passport) {
// If a passport wasn't created, bail out
if (err) return next(err);
next(err, user);
});
});
});
}
// Scenario: An existing user is trying to log in using an already
// connected passport.
// Action: Get the user associated with the passport.
else {
// If the tokens have changed since the last session, update them
if (query.hasOwnProperty('tokens') && query.tokens !== passport.tokens) {
passport.tokens = query.tokens;
}
GitHub.validateUser(query.tokens.accessToken, function(err) {
if (err) return next(err);
// Save any updates to the Passport before moving on
passport.save(function (err, passport) {
if (err) return next(err);
// Fetch the user associated with the Passport
User.findOne(passport.user.id, next);
});
});
}
} else {
// Scenario: A user is currently logged in and trying to connect a new
// passport.
// Action: Create and assign a new passport to the user.
if (!passport) {
query.user = req.user.id;
GitHub.validateUser(query.tokens.accessToken, function(err) {
if (err) return next(err);
Passport.create(query, function (err, passport) {
// If a passport wasn't created, bail out
if (err) return next(err);
next(err, req.user);
});
});
}
// Scenario: The user is already logged in or pushed the back-button.
// Action: Simply pass along the already established session.
else {
next(null, req.user);
}
}
});
};