├── .gitignore ├── README.md ├── app ├── authentication │ ├── index.js │ ├── init.js │ └── middleware.js ├── index.js ├── layout.hbs ├── note │ ├── index.js │ ├── init.js │ └── overview.hbs └── user │ ├── index.js │ ├── init.js │ ├── profile.hbs │ └── welcome.hbs ├── config └── index.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nodehero-authentication 2 | 3 | 1. `git clone git@github.com:RisingStack/nodehero-authentication.git` 4 | 2. `cd nodehero-authentication` 5 | 3. `npm install` 6 | 4. `REDIS_STORE_URI=redis://localhost REDIS_STORE_SECRET=my-strong-secret npm start` 7 | 8 | ## Pre requirements 9 | 10 | - Running [Redis](https://redis.io/) database 11 | -------------------------------------------------------------------------------- /app/authentication/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | init: require('./init'), 3 | middleware: require('./middleware') 4 | } 5 | -------------------------------------------------------------------------------- /app/authentication/init.js: -------------------------------------------------------------------------------- 1 | const passport = require('passport') 2 | const bcrypt = require('bcrypt') 3 | const LocalStrategy = require('passport-local').Strategy 4 | 5 | const authenticationMiddleware = require('./middleware') 6 | 7 | // Generate Password 8 | const saltRounds = 10 9 | const myPlaintextPassword = 'my-password' 10 | const salt = bcrypt.genSaltSync(saltRounds) 11 | const passwordHash = bcrypt.hashSync(myPlaintextPassword, salt) 12 | 13 | const user = { 14 | username: 'test-user', 15 | passwordHash, 16 | id: 1 17 | } 18 | 19 | function findUser (username, callback) { 20 | if (username === user.username) { 21 | return callback(null, user) 22 | } 23 | return callback(null) 24 | } 25 | 26 | passport.serializeUser(function (user, cb) { 27 | cb(null, user.username) 28 | }) 29 | 30 | passport.deserializeUser(function (username, cb) { 31 | findUser(username, cb) 32 | }) 33 | 34 | function initPassport () { 35 | passport.use(new LocalStrategy( 36 | (username, password, done) => { 37 | findUser(username, (err, user) => { 38 | if (err) { 39 | return done(err) 40 | } 41 | 42 | // User not found 43 | if (!user) { 44 | console.log('User not found') 45 | return done(null, false) 46 | } 47 | 48 | // Always use hashed passwords and fixed time comparison 49 | bcrypt.compare(password, user.passwordHash, (err, isValid) => { 50 | if (err) { 51 | return done(err) 52 | } 53 | if (!isValid) { 54 | return done(null, false) 55 | } 56 | return done(null, user) 57 | }) 58 | }) 59 | } 60 | )) 61 | 62 | passport.authenticationMiddleware = authenticationMiddleware 63 | } 64 | 65 | module.exports = initPassport 66 | -------------------------------------------------------------------------------- /app/authentication/middleware.js: -------------------------------------------------------------------------------- 1 | function authenticationMiddleware () { 2 | return function (req, res, next) { 3 | if (req.isAuthenticated()) { 4 | return next() 5 | } 6 | res.redirect('/') 7 | } 8 | } 9 | 10 | module.exports = authenticationMiddleware 11 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | const express = require('express') 4 | const exphbs = require('express-handlebars') 5 | const bodyParser = require('body-parser') 6 | const passport = require('passport') 7 | const session = require('express-session') 8 | const RedisStore = require('connect-redis')(session) 9 | 10 | const config = require('../config') 11 | const app = express() 12 | 13 | app.use(bodyParser.urlencoded({ 14 | extended: false 15 | })) 16 | 17 | require('./authentication').init(app) 18 | 19 | app.use(session({ 20 | store: new RedisStore({ 21 | url: config.redisStore.url 22 | }), 23 | secret: config.redisStore.secret, 24 | resave: false, 25 | saveUninitialized: false 26 | })) 27 | 28 | app.use(passport.initialize()) 29 | app.use(passport.session()) 30 | 31 | app.engine('.hbs', exphbs({ 32 | defaultLayout: 'layout', 33 | extname: '.hbs', 34 | layoutsDir: path.join(__dirname), 35 | partialsDir: path.join(__dirname) 36 | })) 37 | 38 | app.set('view engine', '.hbs') 39 | app.set('views', path.join(__dirname)) 40 | 41 | require('./user').init(app) 42 | require('./note').init(app) 43 | 44 | module.exports = app 45 | -------------------------------------------------------------------------------- /app/layout.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |