add login verification of user

This commit is contained in:
Sorrel Bri 2020-01-14 23:09:01 -08:00
parent da80bf5f65
commit f7a77b4613
9 changed files with 128 additions and 41 deletions

View file

@ -1,11 +1,14 @@
const knex = require('../data/db') const knex = require('../data/db')
const { hashPassword, compareHash } = require('../services/bcrypt'); const { hashPassword, compareHash } = require('../services/bcrypt');
const signToken = require('../services/signToken'); const signToken = require('../services/signToken');
const { validateSignup, validateLogin } = require('../services/userValidate');
const signUp = async (req, res, next) => { const signup = async (req, res, next) => {
const user = req.body; const user = req.body;
if (!validateSignup(user)) return;
try { try {
const hashedPassword = await hashPassword(user.password); const hashedPassword = await hashPassword(user.password);
@ -24,11 +27,38 @@ const signUp = async (req, res, next) => {
} }
} }
const login = (req, res, next) => { const login = async (req, res, next) => {
const user = req.body;
if (!validateLogin(user)) return;
try {
const queryResults = await knex('user')
.where({username: user.username})
.select('username', 'email', 'password')
.then(queryResults => queryResults);
const savedUser = queryResults[0] || null;
if (!savedUser) return res.status(401).json({err: 'bad credentials'});
const hashedPassword = savedUser.password;
const passwordMatch = await compareHash(user.password, hashedPassword);
if (!passwordMatch) return res.status(401).json({err: 'bad credentials'});
const authorizedUser = {...savedUser};
delete authorizedUser.password;
signToken(res, authorizedUser);
res.send('ok').status(200);
}
catch (err) {
res.status(500).json(err);
}
} }
module.exports = { module.exports = {
signUp, signup,
login login
} }

View file

@ -1,6 +0,0 @@
exports.up = function(knex) {
};
exports.down = function(knex) {
};

View file

@ -4,7 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node ./bin/www", "start": "node ./bin/www",
"test": "mocha ./test/*", "test": "mocha ./test/* --exit",
"make-migration": "./node_modules/.bin/knex migrate:make", "make-migration": "./node_modules/.bin/knex migrate:make",
"migrate": "./node_modules/.bin/knex migrate:latest", "migrate": "./node_modules/.bin/knex migrate:latest",
"migrate-test": "./node_modules/.bin/knex migrate:latest --env test", "migrate-test": "./node_modules/.bin/knex migrate:latest --env test",

View file

@ -3,7 +3,7 @@ const router = express.Router();
const authController = require('../controllers/auth'); const authController = require('../controllers/auth');
router.post('/signup', authController.signUp); router.post('/signup', authController.signup);
router.post('/login', authController.login); router.post('/login', authController.login);
module.exports = router; module.exports = router;

View file

@ -20,12 +20,10 @@ const compareHash = async (password, hash) => {
const success = await new Promise((resolve, reject) => { const success = await new Promise((resolve, reject) => {
bcrypt.compare(password, hash, (err, res) => { bcrypt.compare(password, hash, (err, res) => {
if (err) reject(err); if (err) reject(err);
if (res) return true; if (res) resolve(true);
return false;
}) })
}); });
return success;
return compareHash;
} }
module.exports = { hashPassword, compareHash }; module.exports = { hashPassword, compareHash };

View file

@ -7,7 +7,6 @@ const msHourOffset = 3600000;
const signToken = (res, user) => { const signToken = (res, user) => {
const expiration = process.env.NODE_ENV === 'test' ? msHourOffset : msDayOffset; const expiration = process.env.NODE_ENV === 'test' ? msHourOffset : msDayOffset;
const secret = process.env.NODE_ENV === 'test' ? process.env.TEST_SECRET : process.env.JWT_SECRET; const secret = process.env.NODE_ENV === 'test' ? process.env.TEST_SECRET : process.env.JWT_SECRET;
console.log(process.env.NODE_ENV)
const token = jwt.sign({ user }, secret, { const token = jwt.sign({ user }, secret, {
expiresIn: process.env.NODE_ENV === 'test' ? '1h' : '24h', expiresIn: process.env.NODE_ENV === 'test' ? '1h' : '24h',
}); });

View file

@ -0,0 +1,14 @@
const validateSignup = (user) => {
if (!user.username) throw('no username');
if (!user.email) throw('no email');
if (!user.password) throw('no password');
return true
}
const validateLogin = (user) => {
if (!user.username) throw('no username');
if (!user.password) throw('no password');
return true;
}
module.exports = { validateLogin, validateSignup };

View file

@ -4,18 +4,22 @@ const authSpec = (chai, knex, server) => {
'password':'password', 'password':'password',
'email':'user@example.com' 'email':'user@example.com'
} }
const loginFormData = {
'username':'newUser',
'password':'password'
}
it('post to sign up should return 200 status', done => { it('post to sign up should return 200 status', done => {
chai.request(server) chai.request(server)
.post('/auth/signup') .post('/auth/signup')
.type('form') .type('form')
.send(newUserFormData) .send(newUserFormData)
.end((err, res) => { .end((err, res) => {
if (err) done(err); if (err) done(err);
res.should.status(200); res.should.status(200);
done(); done();
}); });
}); });
it('post to sign up should return token', done => { it('post to sign up should return token', done => {
chai.request(server) chai.request(server)
@ -55,8 +59,57 @@ const authSpec = (chai, knex, server) => {
if (newUser.password !== newUserFormData.password) done(); if (newUser.password !== newUserFormData.password) done();
}) })
}); });
});
it('post to login with non-registered user should return status 401 with bad creds err', done => {
chai.request(server)
.post('/auth/login')
.type('form')
.send(newUserFormData)
.end((err, res) => {
if (err) done(err);
res.should.status(401);
res.body.err.should.equal('bad credentials');
done();
});
}) })
it('post to login with non-registered user should return status 401 with bad creds err', done => {
chai.request(server)
.post('/auth/login')
.type('form')
.send(newUserFormData)
.end((err, res) => {
if (err) done(err);
res.should.status(401);
res.body.err.should.equal('bad credentials');
done();
})
})
it('post to login with registered user should return cookie', function(done) {
this.timeout(5000);
chai.request(server)
.post('/auth/signup')
.type('form')
.send(newUserFormData)
.end((err, res) => {
if (err) done(err);
chai.request(server)
.post('/auth/login')
.type('form')
.send(loginFormData)
.end((err, res) => {
if(err) done(err);
res.should.status(200);
res.should.cookie('token');
done();
})
})
})
} }
module.exports = authSpec; module.exports = authSpec;

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
const chai = require('chai'); const chai = require('chai');
const chaiHttp = require('chai-http'); const chaiHttp = require('chai-http');
var knex = require('../data/db'); const knex = require('../data/db');
const server = require('../server'); const server = require('../server');
@ -31,20 +31,19 @@ describe('Auth Routes', function() {
authSpec(chai, knex, server) authSpec(chai, knex, server)
}) });
describe('API Routes', function() { describe('API Routes', function() {
setupDb(); setupDb();
it('home should return 200 status', done => { it('home should return 200 status', done => {
chai.request(server) chai.request(server)
.get('/') .get('/')
.end((err,res)=> { .end((err,res)=> {
if(err) done(err); if(err) done(err);
res.should.status(200); res.should.status(200);
done(); done();
}) });
}) });
}); });