implemented Passport local authentication
This commit is contained in:
parent
93814b745a
commit
235f3b611a
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
||||
/build
|
||||
|
||||
npm-debug.log*
|
||||
sessions
|
||||
|
@ -3,6 +3,7 @@ module.exports = router
|
||||
const ascii = require('../ascii')
|
||||
|
||||
router.use('/tasks', require('./tasks'))
|
||||
router.use('/users', require('./users'))
|
||||
router.use('/projects', require('./projects'))
|
||||
|
||||
router.get('/', async (req, res, next) => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
const Sequelize = require('sequelize')
|
||||
const crypto = require('crypto')
|
||||
const db = require('../db')
|
||||
|
||||
const User = db.define('users', {
|
||||
@ -11,6 +12,23 @@ const User = db.define('users', {
|
||||
type: Sequelize.STRING,
|
||||
},
|
||||
|
||||
password: {
|
||||
type: Sequelize.STRING,
|
||||
// Making `.password` act like a func hides it when serializing to JSON.
|
||||
// This is a hack to get around Sequelize's lack of a "private" option.
|
||||
get() {
|
||||
return () => this.getDataValue('password')
|
||||
},
|
||||
},
|
||||
salt: {
|
||||
type: Sequelize.STRING,
|
||||
// Making `.salt` act like a function hides it when serializing to JSON.
|
||||
// This is a hack to get around Sequelize's lack of a "private" option.
|
||||
get() {
|
||||
return () => this.getDataValue('salt')
|
||||
},
|
||||
},
|
||||
|
||||
avatar: {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: 'default-user-img.png',
|
||||
@ -18,3 +36,39 @@ const User = db.define('users', {
|
||||
})
|
||||
|
||||
module.exports = User
|
||||
|
||||
User.prototype.correctPassword = function(candidatePwd) {
|
||||
return User.encryptPassword(candidatePwd, this.salt()) === this.password()
|
||||
}
|
||||
|
||||
/**
|
||||
* classMethods
|
||||
*/
|
||||
User.generateSalt = function() {
|
||||
return crypto.randomBytes(16).toString('base64')
|
||||
}
|
||||
|
||||
User.encryptPassword = function(plainText, salt) {
|
||||
console.log('inside of encryptPassword', plainText, salt)
|
||||
return crypto
|
||||
.createHash('RSA-SHA256')
|
||||
.update(plainText)
|
||||
.update(salt)
|
||||
.digest('hex')
|
||||
}
|
||||
|
||||
/**
|
||||
* hooks
|
||||
*/
|
||||
const setSaltAndPassword = user => {
|
||||
if (user.changed('password')) {
|
||||
user.salt = User.generateSalt()
|
||||
user.password = User.encryptPassword(user.password(), user.salt())
|
||||
}
|
||||
}
|
||||
|
||||
User.beforeCreate(setSaltAndPassword)
|
||||
User.beforeUpdate(setSaltAndPassword)
|
||||
User.beforeBulkCreate(users => {
|
||||
users.forEach(setSaltAndPassword)
|
||||
})
|
||||
|
@ -22,8 +22,8 @@ const testTasks = [
|
||||
const testProjects = [{ name: 'Anarchy Planet' }, { name: 'Tilde' }]
|
||||
|
||||
const testUsers = [
|
||||
{ name: 'nn', email: 'nn@ap.org' },
|
||||
{ name: 'dn', email: 'dn@ap.org' },
|
||||
{ name: 'nn', email: 'nn@ap.org', password: '123' },
|
||||
{ name: 'dn', email: 'dn@ap.org', password: '123' },
|
||||
]
|
||||
|
||||
async function runSeed() {
|
||||
|
77
index.js
77
index.js
@ -4,20 +4,89 @@ const app = express()
|
||||
const morgan = require('morgan')
|
||||
const ascii = require('./ascii')
|
||||
const cors = require('cors')
|
||||
|
||||
var passport = require('passport')
|
||||
var Strategy = require('passport-local').Strategy
|
||||
const session = require('express-session')
|
||||
const FileStore = require('session-file-store')(session)
|
||||
|
||||
const { User } = require('./db/models')
|
||||
|
||||
const port = process.env.PORT || 1337
|
||||
|
||||
passport.use(
|
||||
new Strategy({ usernameField: 'email' }, async (email, password, cb) => {
|
||||
const user = await User.findOne({ where: { email: email } })
|
||||
if (!user) return cb(null, false)
|
||||
if (!user.correctPassword(password)) return cb(null, false)
|
||||
return cb(null, user)
|
||||
})
|
||||
)
|
||||
|
||||
passport.serializeUser((user, cb) => {
|
||||
cb(null, user.id)
|
||||
})
|
||||
|
||||
passport.deserializeUser(async (id, cb) => {
|
||||
try {
|
||||
const user = await User.findByPk(id)
|
||||
cb(null, user)
|
||||
} catch (err) {
|
||||
return cb(err)
|
||||
}
|
||||
})
|
||||
|
||||
app.use(morgan('tiny'))
|
||||
app.use(cors())
|
||||
// body parsing middleware
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
app.use(require('body-parser').text())
|
||||
|
||||
app.use(
|
||||
session({
|
||||
store: new FileStore(),
|
||||
secret: 'keyboard cat',
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
})
|
||||
)
|
||||
app.use(passport.initialize())
|
||||
app.use(passport.session())
|
||||
|
||||
app.use('/api', require('./api'))
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// Express will serve up production assets
|
||||
app.use(express.static(path.join(__dirname, 'dist')))
|
||||
}
|
||||
// if (process.env.NODE_ENV === 'production') {
|
||||
// // Express will serve up production assets
|
||||
// app.use(express.static(path.join(__dirname, 'dist')))
|
||||
// }
|
||||
|
||||
app.get('/login', (req, res) => {
|
||||
res.send('Not logged in.\n')
|
||||
})
|
||||
|
||||
app.post('/login', async (req, res, next) => {
|
||||
try {
|
||||
const user = await User.findOne({ where: { email: req.body.email } })
|
||||
if (!user) {
|
||||
console.log('User does not exist:', req.body.email)
|
||||
res.status(401).send('Wrong username and/or password')
|
||||
} else if (!user.correctPassword(req.body.password)) {
|
||||
console.log('Incorrect password for user:', req.body.email)
|
||||
res.status(401).send('Wrong username and/or password')
|
||||
} else {
|
||||
req.login(user, err => (err ? next(err) : res.json(user)))
|
||||
}
|
||||
} catch (err) {
|
||||
next(err)
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/logout', function(req, res) {
|
||||
req.logout()
|
||||
res.redirect('/')
|
||||
})
|
||||
|
||||
app.get('*', (req, res) => {
|
||||
res.sendFile(path.resolve(__dirname, '..', 'public', 'index.html'))
|
||||
})
|
||||
|
141
package-lock.json
generated
141
package-lock.json
generated
@ -145,6 +145,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"bagpipe": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/bagpipe/-/bagpipe-0.3.5.tgz",
|
||||
"integrity": "sha1-40HRZPyyTN8E6n4Ft2XsEMiupqE="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
@ -795,6 +800,38 @@
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"express-session": {
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz",
|
||||
"integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==",
|
||||
"requires": {
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
"on-headers": "~1.0.2",
|
||||
"parseurl": "~1.3.3",
|
||||
"safe-buffer": "5.1.2",
|
||||
"uid-safe": "~2.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||
},
|
||||
"depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
|
||||
},
|
||||
"on-headers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
@ -962,6 +999,23 @@
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"graceful-fs": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
|
||||
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
|
||||
@ -1846,6 +1900,14 @@
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||
@ -2323,6 +2385,28 @@
|
||||
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
|
||||
},
|
||||
"passport": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz",
|
||||
"integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=",
|
||||
"requires": {
|
||||
"passport-strategy": "1.x.x",
|
||||
"pause": "0.0.1"
|
||||
}
|
||||
},
|
||||
"passport-local": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
|
||||
"integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
|
||||
"requires": {
|
||||
"passport-strategy": "1.x.x"
|
||||
}
|
||||
},
|
||||
"passport-strategy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||
"integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
|
||||
@ -2353,6 +2437,11 @@
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"pause": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"pg": {
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.11.0.tgz",
|
||||
@ -2485,6 +2574,11 @@
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"random-bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
@ -2612,6 +2706,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
|
||||
},
|
||||
"retry-as-promised": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz",
|
||||
@ -2739,6 +2838,30 @@
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"session-file-store": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/session-file-store/-/session-file-store-1.3.0.tgz",
|
||||
"integrity": "sha512-NKGM/77UDGbV4iMGhrbauMrmrBn0JrLVUpwAFYGZSgI+1SCQYZ+K/neFbkX6x7Z8Wd7gFuEV+35dfjrNUnzLrw==",
|
||||
"requires": {
|
||||
"bagpipe": "^0.3.5",
|
||||
"fs-extra": "^8.0.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"retry": "^0.12.0",
|
||||
"write-file-atomic": "1.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"write-file-atomic": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.1.tgz",
|
||||
"integrity": "sha1-fUW6MjFjKN0ex9kPYOvA2EW7dZo=",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.11",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"slide": "^1.1.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
@ -2793,6 +2916,11 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"slide": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
|
||||
"integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
@ -3165,6 +3293,14 @@
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"uid-safe": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||
"requires": {
|
||||
"random-bytes": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"undefsafe": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
|
||||
@ -3213,6 +3349,11 @@
|
||||
"crypto-random-string": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
@ -8,11 +8,15 @@
|
||||
"concurrently": "^4.0.1",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.16.2",
|
||||
"http-proxy-middleware": "^0.19.0",
|
||||
"morgan": "^1.9.1",
|
||||
"nodemon": "^1.19.1",
|
||||
"passport": "^0.4.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"pg": "^7.11.0",
|
||||
"sequelize": "^5.8.11"
|
||||
"sequelize": "^5.8.11",
|
||||
"session-file-store": "^1.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"seed": "node db/seed.js",
|
||||
|
Loading…
x
Reference in New Issue
Block a user