-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from andela/ft/167190434-User-signout
#167190434 logs out a user
- Loading branch information
Showing
13 changed files
with
306 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
server/db/migrations/20190729061549-create-token-blacklist.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
'use strict'; | ||
|
||
module.exports = { | ||
up: (queryInterface, Sequelize) => queryInterface.createTable('TokenBlacklists', { | ||
id: { | ||
allowNull: false, | ||
autoIncrement: true, | ||
primaryKey: true, | ||
type: Sequelize.INTEGER | ||
}, | ||
token: { | ||
type: Sequelize.STRING | ||
}, | ||
expires: { | ||
type: Sequelize.BIGINT | ||
}, | ||
createdAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE | ||
}, | ||
updatedAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE | ||
} | ||
}), | ||
// eslint-disable-next-line no-unused-vars | ||
down: (queryInterface, Sequelize) => queryInterface.dropTable('TokenBlacklists') | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
'use strict'; | ||
|
||
module.exports = (sequelize, DataTypes) => { | ||
const TokenBlacklist = sequelize.define('TokenBlacklist', { | ||
token: DataTypes.STRING, | ||
expires: DataTypes.BIGINT | ||
}, {}); | ||
return TokenBlacklist; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import cron from 'node-cron'; | ||
import jwt from 'jsonwebtoken'; | ||
import { Op } from 'sequelize'; | ||
import models from '../db/models'; | ||
|
||
const { TokenBlacklist } = models; | ||
/** | ||
* @Module TokenBlacklist | ||
* @description Authentication related methods | ||
*/ | ||
class Blacklist { | ||
/** | ||
* @static | ||
* @param {string} token - user token | ||
* @returns {null} - no value | ||
* @memberof Blacklist | ||
*/ | ||
static async addToBlacklist(token) { | ||
const { exp } = jwt.decode(token); | ||
await TokenBlacklist.create({ | ||
token, | ||
expires: exp | ||
}); | ||
} | ||
|
||
/** | ||
* @static | ||
* @param {string} token - user token | ||
* @returns {null} - null | ||
* @memberof Blacklist | ||
*/ | ||
static async checkBlacklist(token) { | ||
const blacklistedToken = await TokenBlacklist.findOne({ | ||
where: { token } | ||
}); | ||
return blacklistedToken; | ||
} | ||
|
||
/* istanbul ignore next */ | ||
/** | ||
* @static | ||
* @returns {null} - null | ||
* @memberof Blacklist | ||
*/ | ||
static async startCronJob() { | ||
/* starts a cron job that runs 11:59 (hours) | ||
everyday to clear the BlacklistToken table of expired tokens | ||
*/ | ||
cron.schedule('59 23 * * *', () => { | ||
const presentTime = Date.now().valueOf() / 1000; | ||
TokenBlacklist.destroy({ | ||
where: { | ||
expires: { | ||
[Op.lt]: presentTime | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
Blacklist.startCronJob(); | ||
|
||
export default Blacklist; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import blacklistToken from './blacklistToken'; | ||
import Auth from './auth'; | ||
import passwordHash from './passwordHash'; | ||
import Utilities from './Utilities'; | ||
|
||
const { generateToken } = Auth; | ||
const { hashPassword, comparePassword } = passwordHash; | ||
const { errorStat, successStat } = Utilities; | ||
const { addToBlacklist, checkBlacklist } = blacklistToken; | ||
|
||
export default { | ||
addToBlacklist, | ||
checkBlacklist, | ||
generateToken, | ||
hashPassword, | ||
comparePassword, | ||
errorStat, | ||
successStat | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import jwt from 'jsonwebtoken'; | ||
import utilities from '../helpers'; | ||
|
||
const secret = process.env.SECRET_KEY; | ||
const { errorStat, checkBlacklist } = utilities; | ||
|
||
/** | ||
* @Module Authenticate | ||
* @description Authentication related methods | ||
*/ | ||
class Authenticate { | ||
/** | ||
* @static | ||
* @description Authenticate the routes | ||
* @param {object} req - Request object | ||
* @param {object} res - Response object | ||
* @param {Object} next - Next function call | ||
* @returns {object} Json | ||
* @memberof Authenticate | ||
*/ | ||
static async validateToken(req, res, next) { | ||
const authorizationHeader = req.headers.authorization; | ||
const token = req.headers.authorization.split(' ')[1] || authorizationHeader; | ||
if (!token) return errorStat(res, 401, 'Authorization error'); | ||
jwt.verify(token, secret, async (err) => { | ||
if (err) { | ||
const message = (err.name === 'TokenExpiredError') ? 'token expired' : 'invalid token'; | ||
return errorStat(res, 401, message); | ||
} | ||
const blacklist = await checkBlacklist(token); | ||
if (blacklist) { | ||
return errorStat(res, 401, 'invalid token'); | ||
} | ||
next(); | ||
}); | ||
} | ||
} | ||
|
||
export default Authenticate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Authenticate from './authenticate'; | ||
import InputValidator from './inputValidator'; | ||
|
||
const { validateToken } = Authenticate; | ||
const { validateLogin, validateUser } = InputValidator; | ||
|
||
export default { | ||
validateToken, | ||
validateLogin, | ||
validateUser | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
import express from 'express'; | ||
import UserController from '../controllers/userController'; | ||
import InputValidator from '../middlewares/inputValidator'; | ||
import middlewares from '../middlewares'; | ||
|
||
const userRoute = express(); | ||
|
||
const { signUp, login } = UserController; | ||
const { validateUser, validateLogin } = InputValidator; | ||
const userRoute = express(); | ||
const { validateToken, validateLogin, validateUser } = middlewares; | ||
const { signUp, login, logout } = UserController; | ||
|
||
userRoute.post('/', validateUser, signUp); | ||
userRoute.post('/login', validateLogin, login); | ||
|
||
// logs out a user | ||
userRoute.post('/logout', validateToken, logout); | ||
|
||
export default userRoute; |
Oops, something went wrong.