Browse Source

handlebars to jade csrf issue

windhamdavid 8 years ago
parent
commit
a7c6793318
13 changed files with 182 additions and 78 deletions
  1. 1 7
      .jshintrc
  2. 3 25
      .jslintrc
  3. 69 12
      app.js
  4. 59 0
      controllers/user.js
  5. 30 19
      gulpfile.js
  6. 6 10
      models/user.js
  7. 3 1
      package.json
  8. BIN
      src/img/favicon.png
  9. 6 0
      src/img/header.svg
  10. 1 1
      src/index.html
  11. 1 1
      src/views/account/register.hbs
  12. 3 2
      src/views/layouts/main.hbs
  13. 0 0
      src/views/partials/flash.hbs

+ 1 - 7
.jshintrc

@@ -1,10 +1,4 @@
 {
-  "globals": { 
-    "console": false,
-    "exports": false,
-    "module": false,
-    "require": false
-  },
   "predef": [
     "console",
     "exports",
@@ -21,5 +15,5 @@
 	"noarg": true,
 	"undef": true,
 	"unused": "vars",
-	"strict": true
+	"strict": false
 }

+ 3 - 25
.jslintrc

@@ -6,13 +6,9 @@
     "__dirname"
   ],
 
-
   "bitwise":      true,
   "curly":        true,
-  "eqeqeq":       false,
-  "forin":        false,
   "immed":        true,
-  "latedef":      false,
   "newcap":       true,
   "noarg":        true,
   "noempty":      true,
@@ -20,13 +16,8 @@
   "plusplus":     false,
   "regexp":       false,
   "undef":        true,
-  "strict":       false,
   "trailing":     true,
-
-
-  "asi":          false,
   "boss":         true,
-  "debug":        false,
   "eqnull":       true,
   "es5":          true,
   "esnext":       true,
@@ -45,27 +36,14 @@
   "regexdash":    false,
   "scripturl":    false,
   "shadow":       true,
-  "smarttabs":    true,
+  "smarttabs":    false,
   "sub":          false,
   "supernew":     false,
   "validthis":    true,
-
-
+  "white":        true,
   "browser":      true,
-  "couch":        false,
-  "devel":        false,
-  "dojo":         false,
   "jquery":       true,
-  "mootools":     false,
   "node":         true,
-  "nonstandard":  false,
-  "prototypejs":  false,
-  "rhino":        false,
-  "wsh":          false,
+  "strict":       false
 
-  
-  "nomen":        false,
-  "onevar":       false,
-  "passfail":     false,
-  "white":        false
 }

+ 69 - 12
app.js

@@ -1,9 +1,8 @@
-/*global require:true, __dirname:true */
+/********** depend **************/
 
 var express = require('express');
 var exphbs = require('express-handlebars');
 var session = require('express-session');
-var expressValidator = require('express-validator');
 var flash = require('express-flash');
 var cookieParser = require('cookie-parser');
 var bodyParser = require('body-parser');
@@ -13,12 +12,17 @@ var events = require('events');
 var http = require('http');
 var path = require('path');
 var logger = require('morgan');
-var lusca = require('lusca');
-var methodOverride = require('method-override');
+
 var _ = require('lodash');
 var mongoose = require('mongoose');
 var MongoStore = require('connect-mongo')(session);
+var methodOverride = require('method-override');
 var passport = require('passport');
+var lusca = require('lusca');
+var expressValidator = require('express-validator');
+
+
+/********** config **************/
 
 var app = express();
 
@@ -29,22 +33,18 @@ var config = {
 var secure = require('./config/secure');
 var passportConf = require('./config/passport');
 
+
+/********** MongoDB **************/
+
 mongoose.connect(secure.db);
 mongoose.connection.on('error', function() {
   console.log('MongoDB Connection Error!');
   process.exit(1);
 });
 
-var homeController = require('./controllers/home');
-var userController = require('./controllers/user');
 
-app.use(errorHandler());
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({ extended: false }));
-app.use(cookieParser());
 
-app.use(express.static(path.join(__dirname, 'app')));
-app.use(favicon(path.join(__dirname, 'app/img', 'favicon.ico')));
+/********** app.engine **************/
 
 app.engine('.hbs', exphbs({ 
   defaultLayout: 'main', 
@@ -55,15 +55,72 @@ app.engine('.hbs', exphbs({
 app.set('view engine', '.hbs');
 app.set('views', path.join(__dirname, 'app/views'));
 
+
+
+/********** app.use **************/
+
+app.use(express.static(path.join(__dirname, 'app'), { maxAge: 31557600000 }));
+app.use(favicon(path.join(__dirname, 'app/img', 'favicon.png')));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(expressValidator());
+app.use(methodOverride());
+app.use(cookieParser());
+app.use(session({
+  resave: true,
+  saveUninitialized: true,
+  secret: secure.sessionSecret,
+  store: new MongoStore({ url: secure.db, autoReconnect: true })
+}));
+app.use(passport.initialize());
+app.use(passport.session());
+app.use(flash());
+app.use(lusca({
+  csrf: true,
+  xframe: 'SAMEORIGIN',
+  xssProtection: true
+}));
+app.use(function(req, res, next) {
+  res.locals.user = req.user;
+  next();
+});
+app.use(function(req, res, next) {
+  if (/api/i.test(req.path)) {
+    req.session.returnTo = req.path;
+  }
+  next();
+});
+
+
+
+/********** app controllers **************/
+
+var homeController = require('./controllers/home');
+var userController = require('./controllers/user');
+
 app.get('/', homeController.index);
 app.get('/login', userController.getLogin);
+//app.post('/login', userController.postLogin);
+app.get('/register', userController.getSignup);
+app.post('/register', userController.postSignup);
+
 
 
+/************* log **************/
+
 var logger = new events.EventEmitter();
 logger.on('newEvent', function(event, data) {
   console.log('%s: %s', event, JSON.stringify(data));
 });
 
+
+/************* errors **************/
+
+app.use(errorHandler());
+
+
+/********** app.listen **************/
+
 app.listen(conf.port), function() {
   console.log('listening on port %d in %s mode', app.get('port'), app.get('env'));
 }

+ 59 - 0
controllers/user.js

@@ -1,3 +1,14 @@
+var _ = require('lodash');
+var async = require('async');
+var crypto = require('crypto');
+var nodemailer = require('nodemailer');
+var passport = require('passport');
+var User = require('../models/user');
+var secure = require('../config/secure');
+
+
+/********** GET / Login **************/
+
 exports.getLogin = function (req, res) {
   if (req.user) {
     return res.redirect('/');
@@ -7,6 +18,9 @@ exports.getLogin = function (req, res) {
   });
 };
 
+
+/********** POST / Login **************/
+
 exports.postLogin = function(req, res, next) {
   req.assert('email', 'Email is not valid').isEmail();
   req.assert('password', 'Password cannot be blank').notEmpty();
@@ -36,11 +50,17 @@ exports.postLogin = function(req, res, next) {
   })(req, res, next);
 };
 
+
+/********** GET / Logout **************/
+
 exports.logout = function(req, res) {
   req.logout();
   res.redirect('/');
 };
 
+
+/********** GET / Register **************/
+
 exports.getSignup = function(req, res) {
   if (req.user) {
     return res.redirect('/');
@@ -48,4 +68,43 @@ exports.getSignup = function(req, res) {
   res.render('account/register', {
     title: 'Register'
   });
+};
+
+
+/********** POST / Register **************/
+
+exports.postSignup = function(req, res, next) {
+  req.assert('email', 'Email is not valid').isEmail();
+  req.assert('password', 'Password must be at least 4 characters long').len(4);
+  req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password);
+
+  var errors = req.validationErrors();
+
+  if (errors) {
+    req.flash('errors', errors);
+    return res.redirect('/register');
+  }
+
+  var user = new User({
+    email: req.body.email,
+    password: req.body.password
+  });
+
+  User.findOne({ email: req.body.email }, function(err, existingUser) {
+    if (existingUser) {
+      req.flash('errors', { msg: 'Account with that email address already exists.' });
+      return res.redirect('/register');
+    }
+    user.save(function(err) {
+      if (err) {
+        return next(err);
+      }
+      req.logIn(user, function(err) {
+        if (err) {
+          return next(err);
+        }
+        res.redirect('/');
+      });
+    });
+  });
 };

+ 30 - 19
gulpfile.js

@@ -1,5 +1,3 @@
-/*global require:true, console:true */
-
 var gulp = require('gulp');
 var nodemon = require('gulp-nodemon');
 var jshint = require('gulp-jshint');
@@ -9,7 +7,7 @@ var minifycss = require('gulp-minify-css');
 var concat = require('gulp-concat');
 var del = require('del');
 
-var hintTask = function () {
+var hintTask = function() {
   gulp.src(['*.js', './src/js/**/*.js'])
     .pipe(jshint('.jshintrc'))
     .pipe(jshint.reporter('jshint-stylish'));
@@ -19,7 +17,8 @@ gulp.task('hint', function() {
   hintTask();
 });
 
-var cleanTask = function () {
+
+var cleanTask = function() {
   console.log('CLEAN: Clean Complete');
   return del([
     'app/**/*',
@@ -28,6 +27,8 @@ var cleanTask = function () {
     '!app/fonts/',
     '!app/js/',
     '!app/views/',
+    '!app/models/',
+    '!app/controllers/'
   ]);
 };
 
@@ -35,22 +36,19 @@ gulp.task('clean', function() {
   cleanTask();
 });
 
+
 var buildTask = function() {
-  gulp.src('./src/app.js')
-    .pipe(gulp.dest('./app'));
   gulp.src('./src/index.html')
     .pipe(minifyHTML())
     .pipe(gulp.dest('./app'));
-  gulp.src('./src/views/**/*')
-    .pipe(gulp.dest('./app/views'));
-  gulp.src('./src/views/layouts/*')
-    .pipe(gulp.dest('./app/views/layouts'));
-  gulp.src('./src/img/*')
-    .pipe(gulp.dest('./app/img'));
   gulp.src(['./src/css/bootstrap.css','./src/css/main.css'])
     .pipe(concat('style.min.css'))
     .pipe(minifycss())
     .pipe(gulp.dest('./app/css'));
+  gulp.src('./src/img/*')
+    .pipe(gulp.dest('./app/img'));
+  gulp.src('./src/fonts/*')
+    .pipe(gulp.dest('./app/fonts'));
   gulp.src(['./src/js/jquery.js','./src/js/bootstrap.js'])
     .pipe(concat('lib.min.js'))
     .pipe(uglify())
@@ -59,18 +57,21 @@ var buildTask = function() {
     .pipe(concat('main.min.js'))
     .pipe(uglify())
     .pipe(gulp.dest('./app/js'));
-  console.log('\033[31m BUILD: Build Complete');
+  gulp.src('./src/views/**/*')
+    .pipe(gulp.dest('./app/views'));
+  gulp.src('./src/models/**/*')
+    .pipe(gulp.dest('./app/models'));
+  gulp.src('./src/controllers/**/*')
+    .pipe(gulp.dest('./app/controllers'));
+  console.log('BUILD: Build Complete');
 };
 
 gulp.task('build', function() {
   buildTask();
 });
 
+
 var watchTask = function() {
-  gulp.src('./app.js')
-    .pipe(gulp.dest('./'));
-  gulp.src('./src/views/*')
-    .pipe(gulp.dest('./app/views'));
   gulp.src('./src/index.html')
     .pipe(minifyHTML())
     .pipe(gulp.dest('./app'));
@@ -82,13 +83,23 @@ var watchTask = function() {
     .pipe(concat('main.min.js'))
     .pipe(uglify())
     .pipe(gulp.dest('./app/js'));
-  console.log('\033[31m WATCH: Watch Complete');
+  gulp.src('./src/views/**/*')
+    //.pipe(uglify())
+    .pipe(gulp.dest('./app/views'));
+  gulp.src('./src/models/**/*')
+    //.pipe(uglify())
+    .pipe(gulp.dest('./app/models'));
+  gulp.src('./src/controllers/**/*')
+    //.pipe(uglify())
+    .pipe(gulp.dest('./app/controllers'));
+  console.log('WATCH: Watch Complete');
 };
 
 gulp.task('watch', function() {
   watchTask();
 });
 
+
 var nodemonTask = function() {
   nodemon({
     tasks: ['watch'],
@@ -96,7 +107,7 @@ var nodemonTask = function() {
     verbose: true,
     env: { 'NODE_ENV': 'development' },
     watch: ['./src/'],
-    ext: 'css js html'
+    ext: 'css js html hbs'
   });
 };
 

+ 6 - 10
models/user.js

@@ -17,6 +17,9 @@ var userSchema = new mongoose.Schema({
   resetPasswordExpires: Date
 });
 
+
+/********** PASS HASH **************/
+
 userSchema.pre('save', function(next) {
   var user = this;
   if (!user.isModified('password')) {
@@ -36,6 +39,9 @@ userSchema.pre('save', function(next) {
   });
 });
 
+
+/********** PASS Valid **************/
+
 userSchema.methods.comparePassword = function(candidatePassword, cb) {
   bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
     if (err) {
@@ -45,15 +51,5 @@ userSchema.methods.comparePassword = function(candidatePassword, cb) {
   });
 };
 
-userSchema.methods.gravatar = function(size) {
-  if (!size) {
-    size = 200;
-  }
-  if (!this.email) {
-    return 'https://gravatar.com/avatar/?s=' + size + '&d=retro';
-  }
-  var md5 = crypto.createHash('md5').update(this.email).digest('hex');
-  return 'https://gravatar.com/avatar/' + md5 + '?s=' + size + '&d=retro';
-};
 
 module.exports = mongoose.model('User', userSchema);

+ 3 - 1
package.json

@@ -13,6 +13,7 @@
     "node": ">=4.0.0"
   },
   "dependencies": {
+    "async": "^1.5.0",
     "bcrypt-nodejs": "0.0.3",
     "bcryptjs": "^2.3.0",
     "body-parser": "^1.14.1",
@@ -30,6 +31,7 @@
     "method-override": "^2.3.5",
     "mongoose": "^4.2.9",
     "morgan": "~1.6.1",
+    "nodemailer": "^1.10.0",
     "passport": "^0.3.2",
     "passport-local": "^1.0.0",
     "serve-favicon": "~2.3.0"
@@ -39,10 +41,10 @@
     "gulp": "^3.9.0",
     "gulp-concat": "^2.6.0",
     "gulp-jshint": "^2.0.0",
-    "gulp-uglify": "^1.5.1",
     "gulp-minify-css": "^1.2.1",
     "gulp-minify-html": "^1.0.4",
     "gulp-nodemon": "^2.0.4",
+    "gulp-uglify": "^1.5.1",
     "jshint-stylish": "^2.1.0",
     "nodemon": "^1.8.1"
   },

BIN
src/img/favicon.png


+ 6 - 0
src/img/header.svg

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="392 -267 800 550" style="enable-background:new 392 -267 800 550;" xml:space="preserve">
+</svg>

+ 1 - 1
src/index.html

@@ -23,7 +23,7 @@
 
          <div class="collapse navbar-collapse" id="navbar-collapse">
              <ul class="nav navbar-nav navbar-right">
-                 <li><a class="btn page-scroll" href="#">Sign In</a></li>
+                 <li><a class="btn page-scroll" href="login">Sign In</a></li>
              </ul>
          </div>
      </div>

+ 1 - 1
src/views/account/register.hbs

@@ -1,5 +1,5 @@
 <form id="signup-form" method="POST" class="form-horizontal">
-   <input type="hidden" name="_csrf" value="Ho631wzoqHU7byq539m5MkUk68pvgyS6nnH3o=">
+   <input type="hidden" name="_csrf" value="_csrf">
    <div class="form-group">
       <label for="email" class="col-sm-3 control-label">Email</label>
       <div class="col-sm-7">

+ 3 - 2
src/views/layouts/main.hbs

@@ -18,12 +18,13 @@
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
              </button>
-             <a class="navbar-brand page-scroll" href="#page-top">Juryd</a>
+             <a class="navbar-brand page-scroll" href="/">Juryd</a>
          </div>
 
          <div class="collapse navbar-collapse" id="navbar-collapse">
              <ul class="nav navbar-nav navbar-right">
-                 <li><a class="btn page-scroll" href="#">Sign In</a></li>
+                 <li><a class="btn page-scroll" href="login">Sign In</a></li>
+                 <li><a class="btn page-scroll" href="register">Register</a></li>
              </ul>
          </div>
      </div>

+ 0 - 0
src/views/partials/flash.hbs