artsy-passport
Version:
Wires up the common auth handlers for Artsy's [Ezel](ezeljs.com)-based apps using [passport](http://passportjs.org/).
215 lines (195 loc) • 7.78 kB
JavaScript
// Generated by CoffeeScript 1.11.1
(function() {
var Mailcheck, _, _s, artsyXapp, crypto, opts, parse, passport, qs, redirectBack, ref, request, resolve;
_ = require('underscore');
_s = require('underscore.string');
opts = require('../options');
passport = require('passport');
qs = require('querystring');
redirectBack = require('./redirectback');
request = require('superagent');
artsyXapp = require('artsy-xapp');
Mailcheck = require('mailcheck');
crypto = require('crypto');
ref = require('url'), parse = ref.parse, resolve = ref.resolve;
this.onLocalLogin = function(req, res, next) {
if (req.user && !req.xhr) {
return next();
}
return passport.authenticate('local')(req, res, function(err) {
var ref1, ref2;
if (req.xhr) {
if (err) {
return res.send(500, {
success: false,
error: err.message
});
} else {
return next();
}
} else {
if ((err != null ? (ref1 = err.response) != null ? (ref2 = ref1.body) != null ? ref2.error_description : void 0 : void 0 : void 0) === 'invalid email or password') {
return res.redirect(opts.loginPagePath + '?error=Invalid email or password.');
} else if (err) {
return next(err);
} else {
return next();
}
}
});
};
this.onLocalSignup = function(req, res, next) {
req.artsyPassportSignedUp = true;
return request.post(opts.ARTSY_URL + '/api/v1/user').set({
'X-Xapp-Token': artsyXapp.token,
'User-Agent': req.get('user-agent', {
'Referer': req.get('referer')
})
}).send({
name: req.body.name,
email: req.body.email,
password: req.body.password
}).end(function(err, sres) {
var msg, ref1, ref2, ref3, suggestion;
if (err && err.message === 'Email is invalid.') {
suggestion = (ref1 = Mailcheck.run({
email: req.body.email
})) != null ? ref1.full : void 0;
msg = "Email is invalid.";
if (suggestion) {
msg += " Did you mean " + suggestion + "?";
}
if (req.xhr) {
return res.send(403, {
success: false,
error: msg
});
} else {
return res.redirect(opts.signupPagePath + ("?error=" + msg));
}
} else if (err && req.xhr) {
msg = ((ref2 = err.response) != null ? (ref3 = ref2.body) != null ? ref3.error : void 0 : void 0) || err.message;
return res.send(500, {
success: false,
error: msg
});
} else if (err) {
return next(new Error(err));
} else {
return next();
}
});
};
this.beforeSocialAuth = function(provider) {
return function(req, res, next) {
var h, options, rand;
req.session.redirectTo = req.query['redirect-to'];
req.session.skipOnboarding = req.query['skip-onboarding'];
options = {};
options.scope = (function() {
switch (provider) {
case 'linkedin':
return ['r_basicprofile', 'r_emailaddress'];
default:
return 'email';
}
})();
if (provider === 'twitter' && !req.query.state) {
rand = Math.random().toString();
h = crypto.createHash('sha1').update(rand).digest('hex');
req.session.twitterState = h;
options.callbackURL = "" + opts.APP_URL + opts.twitterCallbackPath + "?state=" + h;
}
return passport.authenticate(provider, options)(req, res, next);
};
};
this.afterSocialAuth = function(provider) {
return function(req, res, next) {
var err, linkingAccount, providerName;
if (req.query.denied) {
return next(new Error(provider + " denied"));
}
if (provider === 'twitter' && req.query.state !== req.session.twitterState) {
err = new Error("Must pass a valid `state` param.");
return next(err);
}
providerName = (function() {
switch (provider) {
case 'linkedin':
return 'LinkedIn';
default:
return _s.capitalize(provider);
}
})();
linkingAccount = req.user != null;
return passport.authenticate(provider)(req, res, function(err) {
var msg, ref1, ref2, ref3, ref4, ref5;
if ((err != null ? (ref1 = err.response) != null ? (ref2 = ref1.body) != null ? ref2.error : void 0 : void 0 : void 0) === 'User Already Exists') {
if (req.socialProfileEmail) {
msg = ("A user with the email address " + req.socialProfileEmail + " already ") + "exists. Log in to Artsy via email and password and link " + (providerName + " in your settings instead.");
} else {
msg = (providerName + " account previously linked to Artsy. ") + "Log in to your Artsy account via email and password and link" + (providerName + " in your settings instead.");
}
return res.redirect(opts.loginPagePath + '?error=' + msg);
} else if ((err != null ? (ref3 = err.response) != null ? (ref4 = ref3.body) != null ? ref4.error : void 0 : void 0 : void 0) === 'Another Account Already Linked') {
msg = (providerName + " account already linked to another Artsy account. ") + ("Try logging out and back in with " + providerName + ". Then consider ") + ("deleting that user account and re-linking " + providerName + ". ");
return res.redirect(opts.settingsPagePath + '?error=' + msg);
} else if (err != null ? (ref5 = err.message) != null ? ref5.match('Unauthorized source IP address') : void 0 : void 0) {
msg = "Your IP address was blocked by Facebook.";
return res.redirect(opts.loginPagePath + '?error=' + msg);
} else if (err != null) {
msg = err.message || (typeof err.toString === "function" ? err.toString() : void 0);
return res.redirect(opts.loginPagePath + '?error=' + msg);
} else if (linkingAccount) {
return res.redirect(opts.settingsPagePath);
} else if (req.artsyPassportSignedUp && provider === 'twitter') {
return res.redirect(opts.twitterLastStepPath);
} else if (req.artsyPassportSignedUp && !req.session.skipOnboarding) {
return res.redirect(opts.afterSignupPagePath);
} else {
return next();
}
});
};
};
this.ensureLoggedInOnAfterSignupPage = function(req, res, next) {
var toLogin;
toLogin = opts.loginPagePath + "?redirect-to=" + opts.afterSignupPagePath;
if (req.user == null) {
res.redirect(toLogin);
}
return next();
};
this.onError = function(err, req, res, next) {
if (err.message === 'twitter denied') {
return res.redirect(opts.loginPagePath + "?error=Canceled Twitter login");
} else {
return next(err);
}
};
this.ssoAndRedirectBack = function(req, res, next) {
var domain, parsed, ref1;
if (req.xhr) {
return res.send({
success: true,
user: req.user.toJSON()
});
}
parsed = parse(redirectBack(req));
if (!parsed.hostname) {
parsed = parse(resolve(opts.APP_URL, parsed.path));
}
domain = (ref1 = parsed.hostname) != null ? ref1.split('.').slice(1).join('.') : void 0;
if (domain !== 'artsy.net') {
return redirectBack(req, res);
}
return request.post(opts.ARTSY_URL + "/api/v1/me/trust_token").set({
'X-Access-Token': req.user.get('accessToken')
}).end(function(err, sres) {
if (err) {
return res.redirect(parsed.href);
}
return res.redirect((opts.ARTSY_URL + "/users/sign_in") + ("?trust_token=" + sres.body.trust_token) + ("&redirect_uri=" + parsed.href));
});
};
}).call(this);