Skip to content

Commit 5274c65

Browse files
committed
Authentication & profile
1 parent e804aac commit 5274c65

14 files changed

+232
-85
lines changed

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
node_modules/
22
credentials.json
3-
.env
3+
.env

Diff for: index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ const morgan = require("morgan");
66
require("dotenv").config();
77
const app = express();
88
const initMongoose = require("./init/mongoose");
9-
const initRedis = require("./init/redis");
109
const PATH_TO_FRONTEND_STATIC = path.join(__dirname, "../articles-app/build");
1110

11+
app.use(express.static("public"));
1212
app.use(cors());
1313
app.use(morgan("dev"));
1414

1515
app.use(express.static(PATH_TO_FRONTEND_STATIC));
1616
app.use(bodyParser.json());
17+
1718
/* API ROUTES */
1819
app.use("/api", require("./modules/api.routes"));
1920

@@ -22,7 +23,6 @@ app.use("**", (req, res) => {
2223
});
2324
const PORT = process.env.PORT;
2425

25-
/* initRedis(); */
2626
initMongoose();
2727
app.listen(PORT, () => {
2828
console.log(`Successfully started server on port http://localhost:${PORT}`);

Diff for: init/redis.js

-8
This file was deleted.

Diff for: middleware/withAuth.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,14 @@ module.exports = (error = true) => (req, res, next) => {
55
const { authorization } = req.headers;
66
try {
77
const token = authorization.split(" ")[1];
8-
console.log("token", token);
9-
const payload = jwt.verify(token, "secret");
10-
req.jwtPayload = payload;
8+
req.jwtPayload = jwt.verify(token, "secret");
119
next();
1210
} catch (e) {
1311
console.log("error token decode", e);
1412
if (error) {
15-
return res
16-
.status(401)
17-
.json({ message: e.message || "Not authenticated!" });
13+
return res.status(401).json({
14+
message: e.message || "Not authenticated!",
15+
});
1816
}
1917
req.jwtPayload = {};
2018
next();

Diff for: modules/auth/auth.controller.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ module.exports = {
104104
refreshToken: async (req, res) => {
105105
const { refreshToken } = req.body;
106106
try {
107-
const foundToken = await Token.findOne({ refreshToken }).exec();
107+
const foundToken = await Token.findOne({
108+
refreshToken,
109+
}).exec();
108110
if (!!foundToken) {
109111
const { _id, userId } = foundToken;
110112
const newTokensPair = generateTokens(userId);
@@ -114,10 +116,8 @@ module.exports = {
114116
refreshToken: newTokensPair.refreshToken,
115117
});
116118

117-
await Promise.all([
118-
newRefreshToken.save(),
119-
Token.findByIdAndDelete(_id).exec(),
120-
]);
119+
await newRefreshToken.save();
120+
await Token.findByIdAndDelete(_id).exec();
121121

122122
return res
123123
.status(200)

Diff for: modules/comments/comments.controller.js

+33-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ module.exports = {
1515
},
1616
getOne: (req, res) => {},
1717
addOne: async (req, res) => {
18+
const { _id } = req.jwtPayload;
1819
try {
1920
const newComment = new Comment({
2021
...req.body,
21-
author: "5dc3f0c64aef5c18da1a785b",
22+
author: _id,
2223
});
2324
const createdComment = await newComment.save();
2425
const comment = await createdComment.populate("author").execPopulate();
@@ -29,5 +30,35 @@ module.exports = {
2930
res.status(500).json({ message: "Cannot create comment", error });
3031
}
3132
},
32-
update: (req, res) => {},
33+
update: async (req, res) => {
34+
const { id: commentId } = req.params;
35+
const { _id } = req.jwtPayload;
36+
try {
37+
const result = await Comment.findOneAndUpdate(
38+
{ author: _id, _id: commentId },
39+
req.body,
40+
{
41+
new: true,
42+
}
43+
)
44+
.populate("author")
45+
.exec();
46+
return res
47+
.status(201)
48+
.json({ message: "Comment updated", comment: result });
49+
} catch (error) {}
50+
},
51+
52+
delete: async (req, res) => {
53+
const { id: commentId } = req.params;
54+
const { _id } = req.jwtPayload;
55+
56+
try {
57+
await Comment.findOneAndDelete({
58+
author: _id,
59+
_id: commentId,
60+
}).exec();
61+
return res.status(200).json({ message: "Comment deleted" });
62+
} catch (error) {}
63+
},
3364
};

Diff for: modules/comments/index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
const router = require("express").Router();
22
const controller = require("./comments.controller");
3+
const withAuth = require("../../middleware/withAuth");
34

45
router.get("/", controller.getAll);
56
router.get("/:id", controller.getOne);
6-
router.post("/", controller.addOne);
7-
router.patch("/", controller.update);
7+
router.post("/", withAuth(), controller.addOne);
8+
router.put("/:id", withAuth(), controller.update);
9+
router.delete("/:id", withAuth(), controller.delete);
810

911
module.exports = router;

Diff for: modules/posts/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ const withAuth = require("../../middleware/withAuth");
55
router.get("/", withAuth(false), controller.getPaginated);
66
router.get("/:id", controller.getOne);
77
router.post("/", withAuth(), controller.addOne);
8-
router.put("/:id", controller.update);
8+
router.put("/:id", withAuth(), controller.update);
99

1010
module.exports = router;

Diff for: modules/users/index.js

+48-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,56 @@
11
const router = require("express").Router();
22
const controller = require("./users.controller");
3+
const multer = require("multer");
4+
const withAuth = require("../../middleware/withAuth");
5+
const fs = require("fs");
6+
const path = require("path");
37

8+
const PATH_TO_IMG = "images";
9+
const fullPath = path.join("public", PATH_TO_IMG);
10+
const folderExists = fs.existsSync(fullPath);
11+
12+
const ACCEPTABLE_MIME_TYPES = ["image/jpeg", "image/jpg"];
13+
14+
const fileFilter = (req, file, callback) => {
15+
if (ACCEPTABLE_MIME_TYPES.includes(file.mimetype)) {
16+
return callback(null, true);
17+
}
18+
req.multerError = "Invalid file format";
19+
return callback(null, false);
20+
};
21+
22+
const storage = multer.diskStorage({
23+
destination: (req, file, callback) => {
24+
if (folderExists) {
25+
callback(null, fullPath);
26+
} else {
27+
fs.mkdirSync(fullPath);
28+
callback(null, fullPath);
29+
}
30+
},
31+
filename: (req, file, callback) => {
32+
const nameAsArray = file.originalname.split(".");
33+
const fileExtension = nameAsArray[nameAsArray.length - 1];
34+
const fileName = `${file.fieldname}-${Date.now()}${Math.floor(
35+
Math.random() * 100
36+
)}.${fileExtension}`;
37+
callback(null, fileName);
38+
},
39+
});
40+
const upload = multer({
41+
storage,
42+
fileFilter,
43+
});
44+
45+
router.get("/me", withAuth(), controller.getCurrentUser);
446
router.get("/", controller.getAll);
547
router.get("/:id", controller.getOne);
648
router.post("/", controller.addOne);
7-
router.patch("/", controller.update);
49+
router.patch(
50+
"/profile",
51+
withAuth(),
52+
upload.single("avatar"),
53+
controller.update
54+
);
855

956
module.exports = router;

Diff for: modules/users/users.controller.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ const User = require("./users.model");
22
const { signJWT } = require("../../utils");
33

44
module.exports = {
5+
getCurrentUser: async (req, res) => {
6+
const { _id } = req.jwtPayload;
7+
try {
8+
const me = await User.findById(_id).exec();
9+
res.status(200).json({ me });
10+
} catch (error) {
11+
res.status(500).json({ message: "Cannot fetch users", error });
12+
}
13+
},
514
getAll: async (req, res) => {
615
try {
716
const users = await User.find().exec();
@@ -28,5 +37,25 @@ module.exports = {
2837
res.status(500).json({ message: "Cannot create user", error });
2938
}
3039
},
31-
update: (req, res) => {},
40+
update: async (req, res) => {
41+
let update = req.body;
42+
let multerError = req.multerError;
43+
if (multerError) {
44+
return res.status(400).json({ message: multerError });
45+
}
46+
if (req.file) {
47+
update.avatar = {
48+
fileName: req.file.filename,
49+
originalFileName: req.file.originalname,
50+
};
51+
}
52+
53+
const { _id } = req.jwtPayload;
54+
try {
55+
const profile = await User.findByIdAndUpdate(_id, update).exec();
56+
return res.status(201).json({ message: "Updated", profile });
57+
} catch (error) {
58+
return res.status(500).json({ message: "Cannot update profile" });
59+
}
60+
},
3261
};

Diff for: modules/users/users.model.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
const bcrypt = require("bcrypt");
22
const { Schema, model } = require("mongoose");
33

4+
const AvatarSchema = new Schema({
5+
fileName: { type: String, required: true },
6+
originalFileName: { type: String, required: true },
7+
});
8+
49
const UserSchema = new Schema(
510
{
611
gmailId: { type: String, required: false, default: null },
12+
email: { type: String, immutable: true, required: true },
713
nickName: { type: String, required: true },
8-
email: { type: String, required: true },
914
/* If no gmailId was provided i.e password is required otherwise don't have password with social authentication */
15+
firstName: { type: String },
16+
lastName: { type: String },
17+
avatar: AvatarSchema,
1018
password: {
1119
type: String,
1220
select: false,
@@ -39,8 +47,7 @@ UserSchema.method("comparePasswords", async function(userPassword) {
3947

4048
UserSchema.pre("save", async function(next) {
4149
if (this.password) {
42-
const hashedPassword = await bcrypt.hash(this.password, 10);
43-
this.password = hashedPassword;
50+
this.password = await bcrypt.hash(this.password, 10);
4451
}
4552
next();
4653
});

Diff for: package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"lodash": "^4.17.15",
1818
"mongodb": "^3.3.3",
1919
"mongoose": "^5.7.7",
20-
"passport": "^0.4.0",
21-
"qs": "^6.9.1",
22-
"redis": "^2.8.0"
20+
"multer": "^1.4.2",
21+
"qs": "^6.9.1"
2322
},
2423
"devDependencies": {
2524
"morgan": "^1.9.1",

Diff for: utils/index.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ const getConnectionUrl = auth => {
3636
* Create the google url to be sent to the client.
3737
*/
3838
const getUrlGoogle = () => {
39-
const url = getConnectionUrl(createConnection());
40-
return url;
39+
return getConnectionUrl(createConnection());
4140
};
4241

4342
const setGooglePeopleClient = auth => {
@@ -49,7 +48,7 @@ const setGooglePeopleClient = auth => {
4948

5049
module.exports = {
5150
signJWT: (payload, secret, expiresIn) => {
52-
console.log("expiresIn", expiresIn);
51+
console.log("expiresIn", expiresIn, secret);
5352
return jwt.sign(payload, secret, {
5453
expiresIn: Number(expiresIn),
5554
});

0 commit comments

Comments
 (0)