Permalink
Browse files

Added User Signup Email Verification

  • Loading branch information...
1 parent 828ba27 commit c6ff7402fcaf56e481bf0030b18d78200235594a @dstroot committed Mar 5, 2014
View
@@ -76,6 +76,7 @@ Features
+ Link multiple OAuth strategies to one account
+ Delete Account
+ Password Reset
+ + User Email Verification [1]
- **Administrative Pages**
+ **Real-time** Dashboard
+ Accounts Listing
@@ -84,7 +85,17 @@ Features
+ Contact Form
+ Boilerplate Terms and Privacy pages. Note: **I am not a lawyer**. These have never been reviewed or even **seen** by a lawyer as far as you know. Use them only as a starting point with **your lawyer.**
-Oh, and it's pretty optimized due to the Gulp build pipeline. This is running on one drone at Nodejitsu ($9/mo!):
+[1] If account verification is turned on (via config.js) then we require people who sign up for a local account to verify their email address first before they can log in. We send them an email with a verification token and when they click the link they are verified and signed in.
+
+This is pretty minimal at this point - since we don't have an easy way to regenerate/resend a verification email we don't expire the verification token - it remains good until used. There is also no cleanup of unverifed accounts.
+
+People who signup via a social OAUTH provider are not required to verify their accounts in any case (even if account verification is turned on) since they are already considered "valid" via the account provider. The one loophole is that Twitter does not provide us with the user's email address so we are trusting the user in this case to give us a valid email.
+
+I am not a big fan of this practice since it raises the barrier to entry and therefore have not built the functionality out very far. It is turned off in the live example.
+
+#### Best Practices
+
+The Gulp build pipeline makes sure our assets are optimized. The only thing we haven't done is break up our CSS into "Above the fold" and "Below the fold". This is running on one drone at Nodejitsu ($9/mo!):
![Alt](https://raw.github.com/dstroot/skeleton/master/public/img/pagespeed.jpg)
View
12 app.js
@@ -148,7 +148,7 @@ app.disable('x-powered-by'); // Don't advertise our server type
app.use(passport.initialize());
app.use(passport.session());
-// Keep user information and csrf token available
+// Keep user, csrf token and config available
app.use(function(req, res, next) {
res.locals.user = req.user;
res.locals.token = req.csrfToken();
@@ -159,14 +159,14 @@ app.use(function(req, res, next) {
// for flash messages
app.use(flash());
-// "app.router" positioned above the middleware defined below, this means
-// that Express will attempt to match & call routes before continuing on.
+// "app.router" positioned above the middleware defined below, this
+// means that Express will match & call routes before continuing on.
app.use(app.router);
// Now setup our static serving from /public
app.use(express.static(path.join(__dirname, 'public'), { maxAge: config.session.maxAge }));
-// Assume 404, as no routes responded or static assets found
+// If nothing responded above we can assume 404 (no routes responded or static assets found)
// Test:
// $ curl http://localhost:3000/notfound
@@ -235,6 +235,8 @@ if ( app.get('env') === 'development') {
}
// Robots...
+// www.robotstxt.org/
+// www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
app.configure('development', function() {
// In dev, keep search engines out
app.all('/robots.txt', function(req,res) {
@@ -245,8 +247,6 @@ app.configure('development', function() {
app.configure('production', function() {
// Allow all search engines
- // www.robotstxt.org/
- // www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
app.all('/robots.txt', function(req,res) {
res.charset = 'text/plain';
res.send('User-agent: *');
View
@@ -84,6 +84,7 @@ config.gmail.password = process.env.SMTP_PASSWORD || 'appspecificpasswo
*/
config.localAuth = true;
+config.verificationRequired = false; // user email verification at signup
// Facebook
config.facebookAuth = true;
View
@@ -40,20 +40,28 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, function (email, pass
if (!user) {
return done(null, false, { message: 'Invalid email or password.' });
}
- user.comparePassword(password, function(err, isMatch) {
- if (isMatch) {
- // update the user's record with login timestamp
- user.activity.last_logon = Date.now();
- user.save(function(err) {
- if (err) {
- return (err);
- }
- });
- return done(null, user);
- } else {
- return done(null, false, { message: 'Invalid email or password.' });
- }
- });
+
+ // Only authenticate if the user is verified
+ if (user.verified) {
+ user.comparePassword(password, function(err, isMatch) {
+ if (isMatch) {
+
+ // update the user's record with login timestamp
+ user.activity.last_logon = Date.now();
+ user.save(function(err) {
+ if (err) {
+ return (err);
+ }
+ });
+
+ return done(null, user);
+ } else {
+ return done(null, false, { message: 'Invalid email or password.' });
+ }
+ });
+ } else {
+ return done(null, false, { message: 'Your account must be verified first!' });
+ }
});
}));
Oops, something went wrong.

0 comments on commit c6ff740

Please sign in to comment.