Skip to content

Instantly share code, notes, and snippets.

@InsilicoSoft
Last active October 10, 2017 12:40
Show Gist options
  • Select an option

  • Save InsilicoSoft/f01ef04c0a772da10edc552635f6152a to your computer and use it in GitHub Desktop.

Select an option

Save InsilicoSoft/f01ef04c0a772da10edc552635f6152a to your computer and use it in GitHub Desktop.
Social auth using nodejs & couchdb & restify & passportjs
function passportVerify(provider) {
return function(req, accessToken, refreshToken, profile, cb) {
users.view('xxx', 'by_auth_provider_id', { key: [ provider, profile.id ] }, function(err, socialUsers) {
if(!err) {
if (0 < socialUsers.rows.length) {
// found connected user
cb(null, socialUsers.rows[0].value);
} else {
if (profile
&& profile.emails
&& profile.name
&& (profile.name.familyName
|| profile.name.givenName
)
) {
// User exists with the email from social
var userEmails = _.map(profile.emails, function(data) {
return data.value;
});
users.view('xxx', 'by_email', { keys: userEmails, include_docs: true }, function (err, existedUsers) {
if (!err) {
// add social profile to user
if (0 < existedUsers.rows.length) {
var user = existedUsers.rows[0].doc;
user = addAuthInfo(user, provider, profile.id);
users.insert(user, user._id, function (err) {
if (!err) {
cb(null, user);
// cb(null, body);
} else {
cb(null, false, err);
}
});
// register user
} else {
var username = slug((profile.name.givenName + profile.name.familyName), { lower: true });
var user = {
_id: "org.couchdb.user:" + username,
name: username,
roles: [],
avatar: null,
company: null,
email: profile.emails[0].value,
type: "user",
password: "xxx"
};
user = addAuthInfo(user, provider, profile.id)
users.insert(user, user._id, function (err) {
if (!err) {
cb(null, false, { state: 'register', msg: 'Please check your email to activate your account!' });
} else {
cb(null, false, err);
}
});
}
} else {
cb(null, false);
}
})
} else {
cb(null, false, { msg: 'Please add or check your public email, first name and last name in your social profile'});
}
}
} else {
cb(null, false, err);
}
});
};
}
// Create Passport strategies
// Facebook
passport.use(new FacebookStrategy({
clientID: config.social.facebook.clientId,
clientSecret: config.social.facebook.secret,
callbackURL: 'http://example.com/api/auth/facebook/callback',
passReqToCallback: true,
profileFields: ['id', 'email', 'name']
},
passportVerify('facebook')
));
// Google
passport.use(new GoogleStrategy({
clientID: config.social.google.clientId,
clientSecret: config.social.google.secret,
callbackURL: 'http://example.com/api/auth/google/callback',
passReqToCallback: true,
profileFields: ['id', 'email', 'name']
},
passportVerify('google')
));
// LinkedIn
passport.use(new LinkedInStrategy({
clientID: config.social.linkedin.clientId,
clientSecret: config.social.linkedin.secret,
callbackURL: "http://example.com/api/auth/linkedin/callback",
scope: ['r_emailaddress', 'r_basicprofile'],
passReqToCallback: true
},
passportVerify('linkedin')
));
// General Callback
var passportCallback = function (req, res, next, provider) {
passport.authenticate(provider, function(err, user, info) {
var callbackUrl = decodeUrl(req.params.state).toString();
if (err) {
var message = err.msg ? err.msg :'Error occured during social authentication';
message = new Buffer(message).toString('base64');
return res.redirect(callbackUrl + '#/message/error/' + message , next);
} else {
if (!user) {
if (info && ('register' === info.state)) {
var message = new Buffer(info.msg).toString('base64');
return res.redirect(callbackUrl + '#/message/info/' + message, next);
}
return res.redirect(callbackUrl + '', next);
} else {
cca.makeCookie(user.name)
.then(function(cookie){
res.header('Set-Cookie', cookie);
})
.then(function() {
var userData = {
name: user.name,
ok: true,
roles: _.extend([], user.roles)
};
userData = new Buffer(JSON.stringify(userData)).toString('base64')
return res.redirect(callbackUrl + '#/auth/social/' + userData, next);
})
.catch();
}
}
})(req, res, next);
};
var facebookCallback = function(req, res, next) {
passportCallback(req, res, next, 'facebook');
};
server.get('/auth/facebook/callback', facebookCallback);
server.get('/auth/facebook/:callbackUrl', function (req, res, next) {
passport.authenticate('facebook', {
scope: ['email'],
state: req.params.callbackUrl,
})(req, res, next);
});
var googleCallback = function (req, res, next) {
passportCallback(req, res, next, 'google');
};
server.get('auth/google/callback', googleCallback);
server.get('auth/google/:callbackUrl', function (req, res, next) {
passport.authenticate('google', {
state: req.params.callbackUrl,
scope: [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'
]
}
)(req, res, next);
});
var linkedInCallback = function (req, res, next) {
passportCallback(req, res, next, 'linkedin');
};
server.get('auth/linkedin/callback', linkedInCallback);
server.get('auth/linkedin/:callbackUrl', function (req, res, next) {
passport.authenticate('linkedin', {
state: req.params.callbackUrl
})(req, res, next);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment