add login verification of user
This commit is contained in:
parent
c480d986d2
commit
6033a99223
9 changed files with 128 additions and 41 deletions
|
@ -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
|
||||||
}
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
exports.up = function(knex) {
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.down = function(knex) {
|
|
||||||
};
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 };
|
|
@ -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',
|
||||||
});
|
});
|
||||||
|
|
14
packages/server/server/services/userValidate.js
Normal file
14
packages/server/server/services/userValidate.js
Normal 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 };
|
|
@ -4,6 +4,10 @@ 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)
|
||||||
|
@ -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;
|
|
@ -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,7 +31,7 @@ describe('Auth Routes', function() {
|
||||||
|
|
||||||
authSpec(chai, knex, server)
|
authSpec(chai, knex, server)
|
||||||
|
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('API Routes', function() {
|
describe('API Routes', function() {
|
||||||
setupDb();
|
setupDb();
|
||||||
|
@ -43,8 +43,7 @@ describe('API Routes', function() {
|
||||||
if(err) done(err);
|
if(err) done(err);
|
||||||
res.should.status(200);
|
res.should.status(200);
|
||||||
done();
|
done();
|
||||||
})
|
});
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue