glintcms-starter-glintcms
Version:
This is a WebSite implementation with GlintCMS. It shows how you can use GlintCMS.
426 lines (405 loc) • 16.9 kB
JavaScript
var _ = require('lodash');
var passport = require('passport');
var InstagramStrategy = require('passport-instagram').Strategy;
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GitHubStrategy = require('passport-github').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;
var OAuthStrategy = require('passport-oauth').OAuthStrategy;
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
var secrets = require('./secrets');
var User = require('./model');
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, model) {
if (!model) return done(err);
done(err, model.toJSON());
});
});
/**
* Sign in using Email and Password.
*/
passport.use(new LocalStrategy({usernameField: 'email'}, function (email, password, done) {
email = email.toLowerCase();
User.findOne({email: email}, function (err, model) {
if (err) return done(null, false, {message: 'Uups, an error occured, please try again later'});
if (!model) return done(null, false, {message: 'Email ' + email + ' not found'});
User.authenticate(model, password, function (err, model) {
if (model) {
return done(null, model.toJSON());
} else {
return done(null, false, {message: 'Invalid email or password.'});
}
});
});
}));
/**
* Sign in with Instagram.
*/
passport.use(new InstagramStrategy(secrets.instagram, function (req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({instagram: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already an Instagram account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.instagram(profile.id);
user.tokens(user.tokens().push({kind: 'instagram', accessToken: accessToken}));
user.profileName(user.profileName || profile.displayName);
user.profilePicture(user.profilePicture || profile._json.data.profile_picture);
user.profileWebsite(user.profileWebsite || profile._json.data.website);
user.save(function (err) {
req.flash('info', {msg: 'Instagram account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({instagram: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
var user = new User();
user.instagram(profile.id);
user.tokens(user.tokens().push({kind: 'instagram', accessToken: accessToken}));
// Similar to Twitter API, assigns a temporary e-mail address
// to get on with the registration process. It can be changed later
// to a valid e-mail address in Profile Management.
user.email(profile.username + "@instagram.com");
user.profileName(profile.displayName);
user.profileWebsite(profile._json.data.website);
user.profilePicture(profile._json.data.profile_picture);
user.save(function (err) {
done(err, user);
});
});
}
}));
/**
* OAuth Strategy Overview
*
* - User is already logged in.
* - Check if there is an existing account with a provider id.
* - If there is, return an error message. (Account merging not supported)
* - Else link new OAuth account with currently logged-in user.
* - User is not logged in.
* - Check if it's a returning user.
* - If returning user, sign in and we are done.
* - Else check if there is an existing account with user's email.
* - If there is, return an error message.
* - Else create a new account.
*/
/**
* Sign in with Facebook.
*/
passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({facebook: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.facebook(profile.id);
user.tokens(user.tokens().push({kind: 'facebook', accessToken: accessToken}));
user.profileName(user.profile.name || profile.displayName);
user.profileGender(user.profile.gender || profile._json.gender);
user.profilePicture(user.profile.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large');
user.save(function (err) {
req.flash('info', {msg: 'Facebook account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({facebook: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
User.findOne({email: profile._json.email}, function (err, existingEmailUser) {
if (existingEmailUser) {
req.flash('errors', {msg: 'There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings.'});
done(err);
} else {
var user = new User();
user.email(profile._json.email);
user.facebook(profile.id);
user.tokens(user.tokens().push({kind: 'facebook', accessToken: accessToken}));
user.profileName(profile.displayName);
user.profileGender(profile._json.gender);
user.profilePicture('https://graph.facebook.com/' + profile.id + '/picture?type=large');
user.profileLocation((profile._json.location) ? profile._json.location.name : '');
user.save(function (err) {
done(err, user);
});
}
});
});
}
}));
/**
* Sign in with GitHub.
*/
passport.use(new GitHubStrategy(secrets.github, function (req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({github: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already a GitHub account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.github(profile.id);
user.tokens(user.tokens().push({kind: 'github', accessToken: accessToken}));
user.profileName(user.profile.name || profile.displayName);
user.profilePicture(user.profile.picture || profile._json.avatar_url);
user.profileLocation(user.profile.location || profile._json.location);
user.profileWebsite(user.profile.website || profile._json.blog);
user.save(function (err) {
req.flash('info', {msg: 'GitHub account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({github: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
User.findOne({email: profile._json.email}, function (err, existingEmailUser) {
if (existingEmailUser) {
req.flash('errors', {msg: 'There is already an account using this email address. Sign in to that account and link it with GitHub manually from Account Settings.'});
done(err);
} else {
var user = new User();
user.email(profile._json.email);
user.github(profile.id);
user.tokens(user.tokens().push({kind: 'github', accessToken: accessToken}));
user.profileName(profile.displayName);
user.profilePicture(profile._json.avatar_url);
user.profileLocation(profile._json.location);
user.profileWebsite(profile._json.blog);
user.save(function (err) {
done(err, user);
});
}
});
});
}
}));
/**
* Sign in with Twitter.
*/
passport.use(new TwitterStrategy(secrets.twitter, function (req, accessToken, tokenSecret, profile, done) {
if (req.user) {
User.findOne({twitter: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already a Twitter account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.twitter(profile.id);
user.tokens(user.tokens().push({kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret}));
user.profileName(user.profileName || profile.displayName);
user.profileLocation(user.profileLocation || profile._json.location);
user.profilePicture(user.profilePicture || profile._json.profile_image_url_https);
user.save(function (err) {
req.flash('info', {msg: 'Twitter account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({twitter: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
var user = new User();
// Twitter will not provide an email address. Period.
// But a person’s twitter username is guaranteed to be unique
// so we can "fake" a twitter email address as follows:
user.email(profile.username + "@twitter.com");
user.twitter(profile.id);
user.tokens(user.tokens().push({kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret}));
user.profileName(profile.displayName);
user.profileLocation(profile._json.location);
user.profilePicture(profile._json.profile_image_url_https);
user.save(function (err) {
done(err, user);
});
});
}
}));
/**
* Sign in with Google.
*/
passport.use(new GoogleStrategy(secrets.google, function (req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({google: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already a Google account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.google(profile.id);
user.tokens(user.tokens().push({kind: 'google', accessToken: accessToken}));
user.profileName(user.profileName || profile.displayName);
user.profileGender(user.profileGender || profile._json.gender);
user.profilePicture(user.profilePicture || profile._json.picture);
user.save(function (err) {
req.flash('info', {msg: 'Google account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({google: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
User.findOne({email: profile._json.email}, function (err, existingEmailUser) {
if (existingEmailUser) {
req.flash('errors', {msg: 'There is already an account using this email address. Sign in to that account and link it with Google manually from Account Settings.'});
done(err);
} else {
var user = new User();
user.email(profile._json.email);
user.google(profile.id);
user.tokens(user.tokens().push({kind: 'google', accessToken: accessToken}));
user.profileName(profile.displayName);
user.profileGender(profile._json.gender);
user.profilePicture(profile._json.picture);
user.save(function (err) {
done(err, user);
});
}
});
});
}
}));
/**
* Sign in with LinkedIn.
*/
passport.use(new LinkedInStrategy(secrets.linkedin, function (req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({linkedin: profile.id}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', {msg: 'There is already a LinkedIn account that belongs to you. Sign in with that account or delete it, then link it with your current account.'});
done(err);
} else {
User.findById(req.user.id, function (err, user) {
user.linkedin(profile.id);
user.tokens(user.tokens().push({kind: 'linkedin', accessToken: accessToken}));
user.profileName(user.profileName || profile.displayName);
user.profileLocation(user.profileLocation || profile._json.location.name);
user.profilePicture(user.profilePicture || profile._json.pictureUrl);
user.profileWebsite(user.profileWebsite || profile._json.publicProfileUrl);
user.save(function (err) {
req.flash('info', {msg: 'LinkedIn account has been linked.'});
done(err, user);
});
});
}
});
} else {
User.findOne({linkedin: profile.id}, function (err, existingUser) {
if (existingUser) return done(null, existingUser);
User.findOne({email: profile._json.emailAddress}, function (err, existingEmailUser) {
if (existingEmailUser) {
req.flash('errors', {msg: 'There is already an account using this email address. Sign in to that account and link it with LinkedIn manually from Account Settings.'});
done(err);
} else {
var user = new User();
user.linkedin(profile.id);
user.tokens(user.tokens().push({kind: 'linkedin', accessToken: accessToken}));
user.email(profile._json.emailAddress);
user.profileName(profile.displayName);
user.profileLocation(profile._json.location.name);
user.profilePicture(profile._json.pictureUrl);
user.profileWebsite(profile._json.publicProfileUrl);
user.save(function (err) {
done(err, user);
});
}
});
});
}
}));
/**
* Tumblr API OAuth.
*/
passport.use('tumblr', new OAuthStrategy({
requestTokenURL: 'http://www.tumblr.com/oauth/request_token',
accessTokenURL: 'http://www.tumblr.com/oauth/access_token',
userAuthorizationURL: 'http://www.tumblr.com/oauth/authorize',
consumerKey: secrets.tumblr.consumerKey,
consumerSecret: secrets.tumblr.consumerSecret,
callbackURL: secrets.tumblr.callbackURL,
passReqToCallback: true
},
function (req, token, tokenSecret, profile, done) {
User.findById(req.user._id, function (err, user) {
user.tokens(user.tokens().push({kind: 'tumblr', accessToken: token, tokenSecret: tokenSecret}));
user.save(function (err) {
done(err, user);
});
});
}
));
/**
* Foursquare API OAuth.
*/
passport.use('foursquare', new OAuth2Strategy({
authorizationURL: 'https://foursquare.com/oauth2/authorize',
tokenURL: 'https://foursquare.com/oauth2/access_token',
clientID: secrets.foursquare.clientId,
clientSecret: secrets.foursquare.clientSecret,
callbackURL: secrets.foursquare.redirectUrl,
passReqToCallback: true
},
function (req, accessToken, refreshToken, profile, done) {
User.findById(req.user._id, function (err, user) {
user.tokens(user.tokens().push({kind: 'foursquare', accessToken: accessToken}));
user.save(function (err) {
done(err, user);
});
});
}
));
/**
* Venmo API OAuth.
*/
passport.use('venmo', new OAuth2Strategy({
authorizationURL: 'https://api.venmo.com/v1/oauth/authorize',
tokenURL: 'https://api.venmo.com/v1/oauth/access_token',
clientID: secrets.venmo.clientId,
clientSecret: secrets.venmo.clientSecret,
callbackURL: secrets.venmo.redirectUrl,
passReqToCallback: true
},
function (req, accessToken, refreshToken, profile, done) {
User.findById(req.user._id, function (err, user) {
user.tokens(user.tokens().push({kind: 'venmo', accessToken: accessToken}));
user.save(function (err) {
done(err, user);
});
});
}
));
/**
* Login Required middleware.
*/
exports.isAuthenticated = function (req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect('/login');
};
/**
* Authorization Required middleware.
*/
exports.isAuthorized = function (req, res, next) {
var provider = req.path.split('/').slice(-1)[0];
if (_.find(req.user.tokens, {kind: provider})) {
next();
} else {
res.redirect('/auth/' + provider);
}
};