Permalink
Browse files

Added Google, Facebook, and Email API endpoints for authentication, r…

…efactored an extensive amount of code
  • Loading branch information...
niftylettuce committed Oct 17, 2014
1 parent 8864955 commit 750b3280684b5133b3dd8db41a200573cddeb8f1
View
@@ -5,6 +5,8 @@
"it",
"console",
"describe",
"after",
"before",
"beforeEach",
"waits",
"waitsFor",
@@ -46,5 +48,7 @@
"sub": true,
"strict": false,
"white": false,
"asi": false
"asi": false,
"expr": true
}
View
@@ -0,0 +1,27 @@
// # api
exports = module.exports = function() {
function login(req, res, next) {
res.json(req.user);
}
function updateUser(req, res, next) {
// we are simply re-using eskimo's default
// user update method in the users controller
// that ships with eskimo; just to save time
// we are manually setting the id param here
// and then calling `next()` to continue along
req.params.id = req.user.id;
next();
}
return {
login: login,
updateUser: updateUser
};
};
exports['@singleton'] = true;
View
@@ -1,41 +1,19 @@
// # signup
var passport = require('passport');
var util = require('util');
var _ = require('underscore');
var _str = require('underscore.string');
_.mixin(_str.exports());
var validator = require('validator');
var randomstring = require('randomstring-extended');
exports = module.exports = function(settings, logger, email, User) {
exports = module.exports = function(settings, User) {
function create(req, res, next) {
// email
if (_.isBlank(req.body.email)) {
return next({
message: 'Email was blank',
param: 'email'
});
}
// name
if (_.isBlank(req.body.name)) {
return next({
message: 'First name was blank',
param: 'name'
});
}
// surname
if (_.isBlank(req.body.surname)) {
return next({
message: 'Last name was blank',
param: 'surname'
});
}
// password validation
User.validatePassword(req.body.password, function(errorMessage) {
@@ -60,23 +38,20 @@ exports = module.exports = function(settings, logger, email, User) {
return next(err);
}
if (!user) {
return next(new Error('An error has occured while registering, please try later'));
}
req.flash('success', 'Successfully signed up, check your inbox soon for a welcome email');
next();
// Send welcome email here
email('welcome', {
user: user,
url: settings.url
}, {
to: user.full_email,
subject: 'Eskimo - Welcome to Eskimo'
}, function(err, responseStatus) {
if (err) {
return logger.error(err);
}
logger.info('Sent welcome email to %s', user.email);
});
passport.authenticate('local', {
successReturnToOrRedirect: '/',
successFlash: true,
failureFlash: true,
failureRedirect: true
})(req, res, next);
user.sendWelcomeEmail();
}
@@ -88,4 +63,4 @@ exports = module.exports = function(settings, logger, email, User) {
};
exports['@singleton'] = true;
exports['@require'] = [ 'igloo/settings', 'igloo/logger', 'igloo/email', 'models/user' ];
exports['@require'] = [ 'igloo/settings', 'models/user' ];
View
@@ -12,8 +12,9 @@ var strength = require('strength');
var passportLocalMongoose = require('passport-local-mongoose');
var validator = require('validator');
var mongoosePaginate = require('mongoose-paginate');
var randomstring = require('randomstring-extended');
exports = module.exports = function(settings, mongoose, iglooMongoosePlugin) {
exports = module.exports = function(settings, mongoose, iglooMongoosePlugin, email, logger) {
var nameType = {
type: String,
@@ -33,7 +34,24 @@ exports = module.exports = function(settings, mongoose, iglooMongoosePlugin) {
name: nameType,
surname: nameType,
reset_token: String,
reset_at: Date
reset_at: Date,
api_token: String,
facebook_id: String,
facebook_access_token: String,
facebook_refresh_token: String,
google_id: String,
google_access_token: String,
google_refresh_token: String
});
// pre save
User.pre('save', function(next) {
var user = this;
// set an API token for the user
if (!user.api_token) {
user.api_token = randomstring.token(32);
}
next();
});
// virtuals
@@ -52,6 +70,29 @@ exports = module.exports = function(settings, mongoose, iglooMongoosePlugin) {
return util.format('%s %s <%s>', user.name, user.surname, user.email);
});
// methods
User.methods.sendWelcomeEmail = function sendWelcomeEmail(callback) {
var user = this;
email('welcome', {
user: user,
url: settings.url
}, {
to: user.full_email,
subject: util.format('Eskimo - Welcome %s!', user.name)
}, function(err, responseStatus) {
if (_.isFunction(callback)) {
return callback(err, responseStatus);
}
if (err) {
return logger.error(err);
}
logger.info('Sent welcome email to %s', user.email);
});
};
// statics
User.static('validatePassword', function(password, callback) {
@@ -100,4 +141,4 @@ exports = module.exports = function(settings, mongoose, iglooMongoosePlugin) {
};
exports['@singleton'] = true;
exports['@require'] = [ 'igloo/settings', 'igloo/mongo', 'igloo/mongoose-plugin' ];
exports['@require'] = [ 'igloo/settings', 'igloo/mongo', 'igloo/mongoose-plugin', 'igloo/email', 'igloo/logger' ];
View
@@ -38,4 +38,6 @@ html.no-js
script(src='/bower/bootbox/bootbox.js')
script(src='/js/plugins.js')
script(src='/js/main.js')
if settings.facebook.enabled
script(src='/js/fb-appended-hash-bug-fix.js')
<!-- endbuild -->
View
@@ -7,7 +7,17 @@ block content
.container
.row
.col-md-4.col-md-offset-4
h1 Log in
if settings.facebook.enabled
a(href='/auth/facebook').btn.btn-lg.btn-primary.btn-block
i.fa.fa-facebook-square
| Log in with Facebook
hr
if settings.google.enabled
a(href='/auth/google').btn.btn-lg.btn-primary.btn-block
i.fa.fa-google-plus
| Log in with Google
hr
h1.text-center Log in
form(action='/login', method='POST')
input(type='hidden', name='_csrf', value=csrf)
.form-group
@@ -10,3 +10,4 @@ block content
h1 My Account
h3 Email: #{req.user.email}
h3 Name: #{req.user.full_name}
h3 API Token: #{req.user.api_token}
View
@@ -7,7 +7,17 @@ block content
.container
.row
.col-md-4.col-md-offset-4
h1 Sign up
if settings.facebook.enabled
a(href='/auth/facebook').btn.btn-lg.btn-primary.btn-block
i.fa.fa-facebook-square
| Sign up with Facebook
hr
if settings.google.enabled
a(href='/auth/google').btn.btn-lg.btn-primary.btn-block
i.fa.fa-google-plus
| Sign up with Google
hr
h1.text-center Sign up
form(action='/signup', method='POST', autocomplete='off')
input(type='hidden', name='_csrf', value=csrf)
.form-group
@@ -0,0 +1,22 @@
(function(window) {
// Remove the ugly Facebook appended hash
// <https://github.com/jaredhanson/passport-facebook/issues/12>
(function removeFacebookAppendedHash() {
if (!window.location.hash || window.location.hash !== '#_=_')
return;
if (window.history && window.history.replaceState)
return window.history.replaceState("", document.title, window.location.pathname);
// Prevent scrolling by storing the page's current scroll offset
var scroll = {
top: document.body.scrollTop,
left: document.body.scrollLeft
};
window.location.hash = "";
// Restore the scroll offset, should be flicker free
document.body.scrollTop = scroll.top;
document.body.scrollLeft = scroll.left;
}());
}(window));
View
@@ -1,7 +1,8 @@
(function(window, $) {
'use strict';
$(function() {
});
//$(function() {
//});
}(window, jQuery));
@@ -1,3 +1,4 @@
// Avoid `console` errors in browsers that lack a console.
(function(window) {
'use strict';
View
@@ -20,6 +20,21 @@ exports = module.exports = function() {
return {
defaults: {
facebook: {
enabled: false,
appID: '',
appSecret: '',
scope: [ 'email' ]
},
google: {
enabled: false,
scope: [
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'
],
clientID: '',
clientSecret: ''
},
pkg: pkg,
cache: false,
showStack: true,
View
@@ -2,23 +2,54 @@
// app - policies
var connectEnsureLogin = require('connect-ensure-login');
var auth = require('basic-auth');
var _ = require('underscore');
exports = module.exports = function(IoC) {
exports = module.exports = function(IoC, User) {
// policy/middleware helpers
var ensureLoggedIn = connectEnsureLogin.ensureLoggedIn;
var ensureLoggedOut = connectEnsureLogin.ensureLoggedOut;
// Here is where you'd have things like isAdmin or isMember, for example
// since there are issues with `passport-http` right now
// this is implemented as a temporary solution
function ensureApiToken(req, res, next) {
var creds = auth(req);
if (!creds || !_.isString(creds.name)) {
res.statusCode = 401;
return next({
message: 'API token missing',
param: 'username'
});
}
User.findOne({
api_token: creds.name
}, function(err, user) {
if (err) return next(err);
if (!user) {
return next({
message: 'Invalid API token provided',
param: 'username'
});
}
req.user = user;
next();
});
}
var policies = {
ensureLoggedIn: ensureLoggedIn,
ensureLoggedOut: ensureLoggedOut
ensureLoggedOut: ensureLoggedOut,
ensureApiToken: ensureApiToken
};
return policies;
};
exports['@singleton'] = true;
exports['@require'] = [ '$container' ];
exports['@require'] = [ '$container', 'models/user' ];
Oops, something went wrong.

0 comments on commit 750b328

Please sign in to comment.