Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
hmalik88 committed Nov 25, 2020
1 parent 5ba2a4f commit 84e855c
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 37 deletions.
5 changes: 4 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ const { create } = require('lodash');
const logger = require('morgan');
const app = express();
const indexRouter = require('./routes/index');
const cors = require('cors');

app.disable('etag');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
Expand All @@ -19,7 +22,7 @@ app.use(function (req, res, next) {
})

app.use(function (err, req, res, next) {
res.status(err.status || 500).send({error: err.message});
res.status(err.status || 500).send({errors: err});
})


Expand Down
6 changes: 4 additions & 2 deletions controllers/follower.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ exports.create_following = async function(req, res, next) {
else {
const token = req.header('x-authentication-token');
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const following = await models.Follower.create({user_id: req.params.id, follower_id: userId});
const followed = await models.User.findOne({where: {userName: req.params.username}});
const following = await models.Follower.create({user_id: followed.id, follower_id: userId});
res.status(200).send({following: following});
}
}
Expand All @@ -27,9 +28,10 @@ exports.delete_following = async function(req, res, next) {
else {
const token = req.header('x-authentication-token');
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const followed = await models.User.findOne({where: {userName: req.params.username}});
const deletedFollowing = await models.Follower.destroy({
where: {
user_id: req.params.id,
user_id: followed.id,
follower_id: userId
}
});
Expand Down
39 changes: 31 additions & 8 deletions controllers/tweet.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { validateTweet } = require('../validators/tweetValidations');
const { isEmpty } = require('lodash');
const { validateToken } = require('../validators/userValidations');
const jwt = require('jsonwebtoken');
const User = require('../models/User');

//we want to validate the token sent in the header
// then we want to grab the user's tweets through the association we setup
Expand All @@ -29,30 +30,52 @@ exports.create_tweet = async function(req, res, next) {
// then we want to fetch all he tweets of the users that our user is following

exports.show_timeline = async function(req, res, next) {
let errors = await validateToken({}, req);
const errors = await validateToken({}, req);
if (!isEmpty(errors)) next(errors);
else {
const token = req.header('x-authentication-token');
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const userTweets = await models.Tweet.findAll({where: {user_id: userId}});
const userFriends = await models.Follower.findAll({where: {follower_id: userId}});
const userIds = userFriends.map(friend => friend.user_id);
const friendTweets = await models.Tweet.findAll({where: {user_id: userIds}});
const timeline = [...userTweets, ...friendTweets];
res.status(200).send({timeline: timeline});
res.status(200).send({timeline: friendTweets});
}
}

// first we validate the token
// grab all the tweets where there is a true property of isTweeth

exports.show_tweeths = async function(req, res, next) {
let errors = await validateToken({}, req);
const errors = await validateToken({}, req);
if (!isEmpty(errors)) next(errors);
else {
const token = req.header('x-authentication-token');
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const userTweeths = await models.Tweet.findAll({where: {user_id: userId, isTweeth: true}});
const username = req.params.username;
const user = await models.User.findOne({where: {userName: username}});
const userTweeths = await models.Tweet.findAll({where: {user_id: user.id, isTweeth: true}});
res.status(200).send({tweeths: userTweeths});
}
}

exports.show_tweets = async function(req, res, next) {
const errors = await validateToken({}, req);
if (!isEmpty(errors)) next(errors);
else {
const username = req.params.username;
const user = await models.User.findOne({where: {userName: username}});
const userTweets = await models.Tweet.findAll({where: {user_id: user.id, isTweeth: false}});
res.status(200).send({tweets: userTweets});
}
}

exports.show_likes = async function(req, res, next) {
const errors = await validateToken({}, req);
if (!isEmpty(errors)) next(errors);
else {
const username = req.params.username;
const user = await models.User.findOne({where: {userName: username}});
const likes = await models.Like.findAll({where: {user_id: user.id}});
const tweetIds = likes.map(like => like.tweet_id);
const likedTweets = await models.Tweet.findAll({where: {id: tweetIds}});
res.status(200).send({likes: likedTweets});
}
}
31 changes: 25 additions & 6 deletions controllers/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { validateSignup, validateLogin } = require('../validators/userValidations');
const { validateSignup, validateLogin, validateToken } = require('../validators/userValidations');
const { isEmpty } = require('lodash');
const models = require('../models');

Expand All @@ -15,14 +15,12 @@ exports.signup = async function(req, res, next) {
const newUser = await models.User.create({
email: req.body.email,
password: generateHash(req.body.password),
firstName: req.body.firstName,
lastName: req.body.lastName,
name: req.body.name,
ethAddress: req.body.ethAddress,
userName: req.body.userName

});
const jwtToken = jwt.sign({id: newUser.id}, process.env.ACCESS_TOKEN_SECRET);
res.status(200).send({ token: jwtToken });
res.status(200).send({ token: jwtToken, userName: newUser.userName });
}
}

Expand All @@ -32,6 +30,27 @@ exports.login = async function(req, res, next) {
else {
const user = await models.User.findOne({where: {email: req.body.email}});
const jwtToken = jwt.sign({id: user.id}, process.env.ACCESS_TOKEN_SECRET);
res.status(200).send({ token: jwtToken });
res.status(200).send({ token: jwtToken, userName: user.userName });
}
}

exports.show_user = async function (req, res, next) {
const errors = await validateToken({}, req);
if (!isEmpty(errors)) next(errors);
else {
const token = req.header('x-authentication-token')
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const { username } = req.params;
const userInfo = {};
const user = await models.User.findOne({where: {userName: username}});
userInfo['joined-date'] = user.createdAt;
userInfo['name'] = user.name;
const followers = await models.Follower.findAll({where: {user_id: user.id}});
userInfo['followers'] = followers.length;
const following = await models.Follower.findAll({where: {follower_id: user.id}});
userInfo['following'] = following.length;
const isFollowed = !!followers.filter(follower => follower.follower_id == userId).length;
userInfo['isFollowed'] = isFollowed;
res.status(200).send(userInfo);
}
}
6 changes: 1 addition & 5 deletions migrations/202011031728-CreateUserTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ module.exports = {
allowNull: false,
type: Sequelize.DATE
},
firstName: {
allowNull: false,
type: Sequelize.STRING
},
lastName: {
name: {
allowNull: false,
type: Sequelize.STRING
},
Expand Down
6 changes: 1 addition & 5 deletions models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,10 @@ module.exports = (sequelize, DataTypes, Deferrable) => {
allowNull: false,
unique: true
},
firstName: {
name: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
allowNull: true
},
password: {
type: DataTypes.STRING,
allowNull: false
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"bcrypt": "^5.0.0",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"http-errors": "^1.8.0",
Expand Down
11 changes: 7 additions & 4 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ const follower = require('../controllers/follower');

router.post('/signup', user.signup);
router.post('/login', user.login);
router.get('/users/:username', user.show_user)


// follow routes

router.post('/follow/:id', follower.create_following);
router.delete('/follow/:id', follower.delete_following);
router.post('/follow/:username', follower.create_following);
router.delete('/follow/:username', follower.delete_following);


// tweet routes

router.post('/tweets', tweet.create_tweet);
router.get('/users/:id/timeline', tweet.show_timeline);
router.get('/users/:id/tweeths', tweet.show_tweeths);
router.get('/timeline', tweet.show_timeline);
router.get('/users/:username/tweeths', tweet.show_tweeths);
router.get('/users/:username/tweets', tweet.show_tweets);
router.get('/users/:username/likes', tweet.show_likes);

// like routes

Expand Down
9 changes: 6 additions & 3 deletions validators/followerValidations.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ const jwt = require('jsonwebtoken');
// make sure the follower_id matches up with the id in the JWT

exports.validateFollowing = async function(errors, req) {
if (req.params.id == null) {
if (req.params.username == null) {
errors["status"] = 400;
errors["message"] = "id params must be present."
return errors;
}
const token = req.header('x-authentication-token');
const userId = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET).id;
const users = await models.User.findAll({where: {id: [userId, req.params.id]}});
if (users == null || users.length !== 2) {
const followed = await models.User.findOne({where: {userName: req.params.username}});
const follower = await models.User.findOne({where: {id: userId}});
const users = [followed, follower];
const invalidUsers = users.some(user => !user);
if (invalidUsers) {
errors["status"] = 400;
errors["message"] = "Both follower and followee must be valid users."
return errors;
Expand Down
7 changes: 4 additions & 3 deletions validators/userValidations.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ exports.validateSignup = async function(errors, req) {
errors["messages"] = [];
if (emailFound) errors["messages"].push("Email is already in use. Please login or use another email to signup.");
if (userNameFound) errors["messages"].push("Username is already in use. Please use another username to signup.");
if (ethAddFound) errors["messages"].push("Ethereum address is already in use. Please use another address to signup.");
if (ethAddFound) errors["messages"].push("Ethereum address is already in use. Please use another ethereum address to signup.");
}
return errors;
}
Expand All @@ -60,7 +60,7 @@ exports.validateLogin = async function(errors, req) {
const user = await models.User.findOne({where: {email: req.body.email}});
if (user == null) {
errors["status"] = 400;
errors["message"] = "No such user found for this email. Please use a valid email.";
errors["message"] = "Please use a valid email.";
} else {
if (!bcrypt.compareSync(req.body.password, user.password)) {
errors["status"] = 401;
Expand Down Expand Up @@ -88,4 +88,5 @@ exports.validateToken = async function(errors, req) {
}
}
return errors;
}
}

0 comments on commit 84e855c

Please sign in to comment.