email validations work, now on to username validations

This commit is contained in:
Michael Q Larson
2014-12-23 18:20:53 -08:00
parent 20475ffcc4
commit fcd457b958
8 changed files with 170 additions and 85 deletions

15
app.js
View File

@ -76,7 +76,13 @@ app.use(connectAssets({
app.use(logger('dev')); app.use(logger('dev'));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator()); app.use(expressValidator({
customValidators: {
matchRegex: function(param, regex) {
return regex.test(param);
}
}
}));
app.use(methodOverride()); app.use(methodOverride());
app.use(cookieParser()); app.use(cookieParser());
app.use(session({ app.use(session({
@ -264,13 +270,12 @@ app.get('/auth/twitter', passport.authenticate('twitter'));
app.get( app.get(
'/auth/twitter/callback', '/auth/twitter/callback',
passport.authenticate('twitter', { passport.authenticate('twitter', {
successRedirect: '/', successRedirect: '/auth/twitter/middle',
failureRedirect: '/auth/twitter/middle' failureRedirect: '/login'
}) })
); );
app.get('/auth/twitter/middle', function(req, res, next) { app.get('/auth/twitter/middle', passportConf.hasEmail);
});
app.get( app.get(
'/auth/linkedin', '/auth/linkedin',

View File

@ -14,7 +14,8 @@ var _ = require('lodash'),
// Login Required middleware. // Login Required middleware.
module.exports = { module.exports = {
isAuthenticated: isAuthenticated, isAuthenticated: isAuthenticated,
isAuthorized: isAuthorized isAuthorized: isAuthorized,
hasEmail: hasEmail
}; };
passport.serializeUser(function(user, done) { passport.serializeUser(function(user, done) {
@ -107,12 +108,6 @@ passport.use(
} else { } else {
User.findOne({ twitter: profile.id }, function(err, existingUser) { User.findOne({ twitter: profile.id }, function(err, existingUser) {
if (err) { return done(err); } if (err) { return done(err); }
//if (existingUser) return done(null, existingUser);
// Twitter will not provide an email address. Period.
// But a persons twitter username is guaranteed to be unique
// so we can "fake" a twitter email address as follows:
//user.email = profile.username + "@twitter.com";
var user = existingUser || new User(); var user = existingUser || new User();
user.twitter = profile.id; user.twitter = profile.id;
user.email = user.email || ''; user.email = user.email || '';
@ -132,15 +127,6 @@ passport.use(
if (err) { return done(err); } if (err) { return done(err); }
done(null, user); done(null, user);
}); });
//TODO: Twitter redirect to capture user email.
//if (!user.email) {
// req.redirect('/account');
// req.flash('errors', {
// msg:
// 'OK, you are signed in. ' +
// 'Please add your email address to your profile.'
// });
//}
}); });
} }
}) })
@ -513,6 +499,21 @@ function isAuthenticated(req, res, next) {
res.redirect('/login'); res.redirect('/login');
} }
function hasEmail(req, res) {
if (req.user) {
console.log('started');
if (req.user.email) {
res.redirect('/');
} else {
console.log('hit');
req.flash('info', {
msg: 'Please add your email address before starting our challenges.'
});
res.redirect('/account');
}
}
}
// Authorization Required middleware. // Authorization Required middleware.
function isAuthorized(req, res, next) { function isAuthorized(req, res, next) {
var provider = req.path.split('/').slice(-1)[0]; var provider = req.path.split('/').slice(-1)[0];

View File

@ -170,10 +170,6 @@ exports.updateProgress = function(req, res) {
}); });
}; };
/** /**
* POST /account/profile * POST /account/profile
* Update profile information. * Update profile information.
@ -182,6 +178,44 @@ exports.updateProgress = function(req, res) {
exports.postUpdateProfile = function(req, res, next) { exports.postUpdateProfile = function(req, res, next) {
User.findById(req.user.id, function(err, user) { User.findById(req.user.id, function(err, user) {
if (err) return next(err); if (err) return next(err);
req.assert('email', 'Email is required').notEmpty();
req.assert('email', 'Please enter a valid email address.').isEmail();
req.assert('username', 'Your username must be between 3 and 20 characters').len(3, 20);
req.assert('username', 'Your username can only use letters, numbers or underscores').matchRegex(/[A-Za-z0-9_]+/);
var errors = req.validationErrors();
if (errors) {
req.flash('errors', errors);
return res.redirect('/account');
}
User.findOne({ email: req.body.email }, function(err, existingEmail) {
if (err) {
return next(err);
}
var user = req.user;
if (existingEmail && existingEmail.email != user.email) {
console.log(user.email);
console.log(existingEmail.email)
req.flash('errors', {
msg: "An account with that email address already exists."
});
return res.redirect('/account');
}
User.findOne({ username: req.body.username }, function(err, existingUsername) {
if (err) {
return next(err);
}
var user = req.user;
if (existingUsername && existingUsername.profile.username != user.profile.username) {
console.log(existingUsername.profile.username)
console.log(user.profile.username)
req.flash('errors', {
msg: 'An account with that username already exists.'
});
return res.redirect('/account');
}
var user = req.user;
user.email = req.body.email || ''; user.email = req.body.email || '';
user.profile.name = req.body.name || ''; user.profile.name = req.body.name || '';
user.profile.username = req.body.username || ''; user.profile.username = req.body.username || '';
@ -194,6 +228,8 @@ exports.postUpdateProfile = function(req, res, next) {
res.redirect('/account'); res.redirect('/account');
}); });
}); });
});
});
}; };
/** /**

View File

@ -3,15 +3,13 @@ var crypto = require('crypto');
var mongoose = require('mongoose'); var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({ var userSchema = new mongoose.Schema({
/*email: { email: {
type: String, type: String,
unique: true, unique: true,
lowercase: true, lowercase: true,
match: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/ trim: true
},*/ },
email: String,
password: String, password: String,
facebook: String, facebook: String,
twitter: String, twitter: String,
google: String, google: String,
@ -283,13 +281,14 @@ var userSchema = new mongoose.Schema({
picture: { picture: {
type: String, type: String,
default: '' default: ''
} },
/*username: { username: {
type: String, type: String,
default: '', default: '',
unique: true, unique: true,
match: /^[a-zA-Z0-9_]+$/ lowercase: true,
}*/ trim: true
}
}, },
resetPasswordToken: String, resetPasswordToken: String,

View File

@ -27,7 +27,7 @@
"express": "^4.10.4", "express": "^4.10.4",
"express-flash": "^0.0.2", "express-flash": "^0.0.2",
"express-session": "^1.9.2", "express-session": "^1.9.2",
"express-validator": "^2.7.0", "express-validator": "^2.8.0",
"fbgraph": "^0.3.0", "fbgraph": "^0.3.0",
"github-api": "^0.7.0", "github-api": "^0.7.0",
"helmet": "^0.5.3", "helmet": "^0.5.3",

View File

@ -259,6 +259,11 @@ ul {
margin: auto; margin: auto;
} }
.btn-link-social {
max-width: 400px;
margin-bottom: 10px;
}
.navbar { .navbar {
background-color: #4a2b0f; background-color: #4a2b0f;
} }
@ -357,3 +362,8 @@ thead {
.nowrap { .nowrap {
white-space: nowrap; white-space: nowrap;
} }
.big-break {
margin-top: 30px;
margin-bottom: 30px;
}

View File

@ -8,9 +8,9 @@ block content
a.btn.btn-lg.btn-block.btn-facebook.btn-social(href='/auth/facebook') a.btn.btn-lg.btn-block.btn-facebook.btn-social(href='/auth/facebook')
i.fa.fa-facebook i.fa.fa-facebook
| Sign in with Facebook | Sign in with Facebook
//a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github') a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github')
// i.fa.fa-github i.fa.fa-github
// | Sign in with GitHub | Sign in with GitHub
a.btn.btn-lg.btn-block.btn-linkedin.btn-social(href='/auth/linkedin') a.btn.btn-lg.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')
i.fa.fa-linkedin i.fa.fa-linkedin
| Sign in with LinkedIn | Sign in with LinkedIn

View File

@ -11,8 +11,8 @@ block content
label.col-sm-2.control-label(for='name') Name label.col-sm-2.control-label(for='name') Name
.col-sm-4 .col-sm-4
input.form-control(type='text', name='name', id='name', value='#{user.profile.name}') input.form-control(type='text', name='name', id='name', value='#{user.profile.name}')
//.form-group .form-group
label.col-sm-2.control-label(for='username') Username label.col-sm-2.control-label(for='username') Username (no spaces)
.col-sm-4 .col-sm-4
input.form-control(type='text', name='username', id='username', value='#{user.profile.username}') input.form-control(type='text', name='username', id='username', value='#{user.profile.username}')
.form-group .form-group
@ -32,7 +32,39 @@ block content
button.btn.btn.btn-primary(type='submit') button.btn.btn.btn-primary(type='submit')
span.ion-edit span.ion-edit
| Update my profile | Update my profile
- if (!user.google || !user.facebook || !user.github || !user.linkedin || !user.twitter)
.panel
.container
h1 Link other services to your account:
- if (!user.google)
.col-xs-12
a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/auth/google')
i.fa.fa-google-plus
| Link Google with your account
- if (!user.facebook)
.col-xs-12
a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/auth/facebook')
i.fa.fa-facebook
| Link Facebook with your account
- if (!user.github)
.col-xs-12
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
i.fa.fa-github
| Link GitHub with your account
- if (!user.linkedin)
.col-xs-12
a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/auth/linkedin')
i.fa.fa-linkedin
| Link LinkedIn with your account
- if (!user.twitter)
.col-xs-12
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/auth/twitter')
i.fa.fa-twitter
| Link Twitter with your account
br
- if (ch[0] > 0)
.panel
.container
h1 Completed Challenges h1 Completed Challenges
.col-xs-12 .col-xs-12
table.table.table-striped table.table.table-striped
@ -45,15 +77,19 @@ block content
tr tr
td= cc[challenge.challengeNumber].name td= cc[challenge.challengeNumber].name
td= moment(ch[challenge.challengeNumber], 'X').format("MMM DD, YYYY") td= moment(ch[challenge.challengeNumber], 'X').format("MMM DD, YYYY")
br
.panel
.container
h3 Danger Zone h3 Danger Zone
button.btn.btn-danger.confirm-deletion button.btn.btn-danger.confirm-deletion
span.ion-trash-b span.ion-trash-b
| I want to delete my account | I want to delete my account
br
script. script.
$('.confirm-deletion').on("click", function() { $('.confirm-deletion').on("click", function() {
$('#modal-dialog').modal('show'); $('#modal-dialog').modal('show');
}); });
br
#modal-dialog.modal.animated.wobble #modal-dialog.modal.animated.wobble
.modal-dialog .modal-dialog
.modal-content .modal-content
@ -74,5 +110,3 @@ block content
button.btn.btn-danger.btn-block(type='submit') button.btn.btn-danger.btn-block(type='submit')
span.ion-trash-b span.ion-trash-b
| Yes, Delete my account | Yes, Delete my account
br
br