Skip to content

Commit 212723f

Browse files
author
Matheus Ishiyama
authored
Create user's friends workflow (#3)
2 parents ca97b32 + ebb3a7d commit 212723f

File tree

11 files changed

+534
-6
lines changed

11 files changed

+534
-6
lines changed

src/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ app.use(express.urlencoded({ extended: true }));
88
//* routes
99
app.use("/user", require("./routes/user"));
1010
app.use("/auth", require("./routes/auth"));
11+
app.use("/friend", require("./routes/friends"));
1112

1213
module.exports = app;

src/controllers/user.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const UserController = {
1616
verified: false,
1717
password: hashPassword,
1818
createdAt: Date.now(),
19+
friendList: [],
1920
});
2021
await newUser.save();
2122

@@ -39,6 +40,88 @@ const UserController = {
3940

4041
return res.status(200).json({ message: "User confirmed" });
4142
},
43+
44+
async addPending(req, res) {
45+
const userId = req.userId;
46+
const newPendingId = req.body.friendId;
47+
48+
//* add friendId to pending status
49+
await User.findOneAndUpdate(
50+
{ _id: userId },
51+
{ $push: { pending: newPendingId } }
52+
);
53+
54+
//* add userId to request status in friendUser
55+
await User.findOneAndUpdate(
56+
{ _id: newPendingId },
57+
{ $push: { requests: userId } }
58+
);
59+
60+
return res.status(200).json({ message: "Pending added" });
61+
},
62+
63+
async removePending(req, res) {
64+
const userId = req.userId;
65+
const removePendingId = req.body.friendId;
66+
67+
//* remove friendId from pending status
68+
await User.findOneAndUpdate(
69+
{ _id: userId },
70+
{ $pull: { pending: removePendingId } }
71+
);
72+
73+
//* remove userId from request status in friendUser
74+
await User.findOneAndUpdate(
75+
{ _id: removePendingId },
76+
{ $pull: { requests: userId } }
77+
);
78+
79+
return res.status(200).json({ message: "Pending removed" });
80+
},
81+
82+
async addFriend(req, res) {
83+
const userId = req.userId;
84+
const newFriendId = req.body.friendId;
85+
86+
//* add newFriend to user's friends
87+
await User.findOneAndUpdate(
88+
{ _id: userId },
89+
{
90+
$push: { friendList: newFriendId },
91+
$pull: { requests: newFriendId },
92+
}
93+
);
94+
95+
//* add user to newFriend's friends
96+
await User.findOneAndUpdate(
97+
{ _id: newFriendId },
98+
{
99+
$push: { friendList: userId },
100+
$pull: { pending: userId },
101+
}
102+
);
103+
104+
return res.status(200).json({ message: "Friend added" });
105+
},
106+
107+
async removeFriend(req, res) {
108+
const userId = req.userId;
109+
const removeFriendId = req.body.friendId;
110+
111+
//* remove friend from user's friends
112+
await User.findOneAndUpdate(
113+
{ _id: userId },
114+
{ $pull: { friendList: removeFriendId } }
115+
);
116+
117+
//* remove user from friends's friends
118+
await User.findOneAndUpdate(
119+
{ _id: removeFriendId },
120+
{ $pull: { friendList: userId } }
121+
);
122+
123+
return res.status(200).json({ message: "Friend removed" });
124+
},
42125
};
43126

44127
module.exports = UserController;

src/middlewares/authenticate.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const jwt = require("jsonwebtoken");
2+
require("dotenv").config();
3+
4+
const authenticate = (req, res, next) => {
5+
const authHeader = req.headers.authorization;
6+
if (!authHeader)
7+
return res.status(401).json({ message: "No token provided" });
8+
9+
const parts = authHeader.split(" ");
10+
11+
if (!(parts.length === 2))
12+
return res.status(401).json({ message: "Token error" });
13+
14+
const [scheme, token] = parts;
15+
16+
if (!/^Bearer$/i.test(scheme))
17+
return res.status(401).json({ message: "Token malformatted" });
18+
19+
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
20+
if (err) return res.status(401).json({ message: "Invalid token" });
21+
22+
req.userId = decoded.id;
23+
next();
24+
});
25+
};
26+
27+
module.exports = authenticate;

src/middlewares/validateFriend.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const User = require("../models/user");
2+
3+
const validateFriend = async (req, res, next) => {
4+
const { friendId } = req.body;
5+
6+
if (!friendId)
7+
return res.status(400).json({ message: "No friendId provided" });
8+
9+
try {
10+
const isValid = await User.findOne({ _id: friendId });
11+
12+
if (!isValid)
13+
return res.status(404).json({ message: "User not found" });
14+
15+
if (!isValid.verified)
16+
return res.status(404).json({ message: "User not found" });
17+
} catch (error) {
18+
return res.status(404).json({ message: "User not found" });
19+
}
20+
21+
next();
22+
};
23+
24+
module.exports = validateFriend;

src/models/user.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const User = new database.Schema(
99
verified: Boolean,
1010
password: String,
1111
createdAt: Date,
12+
friendList: Array,
13+
pending: Array,
14+
requests: Array,
1215
},
1316
{
1417
versionKey: false,

src/routes/friends.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const express = require("express");
2+
const friendRoutes = express.Router();
3+
const userController = require("../controllers/user");
4+
const authenticate = require("../middlewares/authenticate");
5+
const validateFriend = require("../middlewares/validateFriend");
6+
7+
friendRoutes.put("/pending/add", authenticate, validateFriend, (req, res) => {
8+
userController.addPending(req, res);
9+
});
10+
11+
friendRoutes.put(
12+
"/pending/remove",
13+
authenticate,
14+
validateFriend,
15+
(req, res) => {
16+
userController.removePending(req, res);
17+
}
18+
);
19+
20+
friendRoutes.put("/accept", authenticate, validateFriend, (req, res) => {
21+
userController.addFriend(req, res);
22+
});
23+
24+
friendRoutes.put("/decline", authenticate, validateFriend, (req, res) => {
25+
userController.removeFriend(req, res);
26+
});
27+
28+
module.exports = friendRoutes;

src/services/authenticate.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ const authenticate = async (username, password, res) => {
2121
if (!userExists.verified)
2222
return res.status(401).json({ message: "User unverified" });
2323

24-
const token = jwt.sign(userExists.username, process.env.JWT_SECRET);
24+
const token = jwt.sign(
25+
{ id: userExists._id },
26+
process.env.JWT_SECRET
27+
);
2528

2629
return res.status(202).json({ token });
2730
}

0 commit comments

Comments
 (0)