Eric Whale

Add signin, signup functionality

1 const jwt = require("jsonwebtoken"); 1 const jwt = require("jsonwebtoken");
2 const bcrypt = require("bcryptjs"); 2 const bcrypt = require("bcryptjs");
3 // handles "exception" inside of async express routes 3 // handles "exception" inside of async express routes
4 -// (Used for mongoDB error in this project)
5 const asyncHandler = require("express-async-handler"); 4 const asyncHandler = require("express-async-handler");
5 +const User = require("../models/userModel");
6 6
7 // @desc Signup new user 7 // @desc Signup new user
8 // @route POST /api/users 8 // @route POST /api/users
9 // @access Public 9 // @access Public
10 const signupUser = asyncHandler(async (req, res) => { 10 const signupUser = asyncHandler(async (req, res) => {
11 const { username, email, password } = req.body; 11 const { username, email, password } = req.body;
12 - if (!name || !email || !password) { 12 + if (!username || !email || !password) {
13 res.status(400); 13 res.status(400);
14 throw new Error("Please fill in all fields"); 14 throw new Error("Please fill in all fields");
15 } 15 }
16 16
17 // Check if user already exists 17 // Check if user already exists
18 + const userExists = await User.findOne({ email });
19 + if (userExists) {
20 + res.status(400);
21 + throw new Error("User with the email already exists");
22 + }
18 23
19 // Hash password (bcrypt) 24 // Hash password (bcrypt)
25 + const salt = await bcrypt.genSalt(10);
26 + const hashedPassword = await bcrypt.hash(password, salt);
20 27
21 // Create/Build user 28 // Create/Build user
29 + const user = await User.create({
30 + username,
31 + email,
32 + password: hashedPassword,
33 + });
22 34
23 // Send response 35 // Send response
36 + if (user) {
37 + // 201: Resource successfully created
38 + res.status(201).json({
39 + _id: user.id,
40 + username: user.username,
41 + email: user.email,
42 + // TODO: Add token!
43 + });
44 + } else {
45 + res.status(400);
46 + throw new Error("Invalid user data");
47 + }
24 }); 48 });
25 49
50 +// @desc Login user
51 +// @route POST /api/users/login
52 +// @access Public
26 const loginUser = asyncHandler(async (req, res) => { 53 const loginUser = asyncHandler(async (req, res) => {
27 const { email, password } = req.body; 54 const { email, password } = req.body;
28 55
29 - // Check for the user email 56 + // Check email & password
30 - 57 + const userInDB = await User.findOne({ email });
31 - // Send response 58 + const validPassword = await bcrypt.compare(password, userInDB.password);
59 + if (userInDB && validPassword) {
60 + res.status(200).json({
61 + _id: userInDB.id,
62 + username: userInDB.username,
63 + email: userInDB.email,
64 + // TODO: Add Token!
65 + });
66 + } else {
67 + res.status(400);
68 + throw new Error("Invalid credentials");
69 + }
32 }); 70 });
33 71
72 +// @desc Get user(only self)
73 +// @route GET /api/users/self
74 +// @access Private
34 const getSelf = asyncHandler(async (req, res) => {}); 75 const getSelf = asyncHandler(async (req, res) => {});
35 76
36 module.exports = { 77 module.exports = {
......
1 +const jwt = require("jsonwebtoken");
2 +
3 +const authHandler = (err, req, res, next) => {
4 + next();
5 +};
6 +
7 +module.exports = { authHandler };
...@@ -4,7 +4,7 @@ const errorHandler = (err, req, res, next) => { ...@@ -4,7 +4,7 @@ const errorHandler = (err, req, res, next) => {
4 res.status(statusCode); 4 res.status(statusCode);
5 res.json({ 5 res.json({
6 message: err.message, 6 message: err.message,
7 - // stack from mongoDB (maybe...) 7 + // stack from mongoDB TODO: Check it!
8 stack: process.env.NODE_ENV === "production" ? null : err.stack, 8 stack: process.env.NODE_ENV === "production" ? null : err.stack,
9 }); 9 });
10 }; 10 };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
10 "license": "MIT", 10 "license": "MIT",
11 "dependencies": { 11 "dependencies": {
12 "bcryptjs": "^2.4.3", 12 "bcryptjs": "^2.4.3",
13 + "colors": "^1.4.0",
13 "dotenv": "^16.0.1", 14 "dotenv": "^16.0.1",
14 "express": "^4.18.1", 15 "express": "^4.18.1",
15 "express-async-handler": "^1.2.0", 16 "express-async-handler": "^1.2.0",
...@@ -457,6 +458,14 @@ ...@@ -457,6 +458,14 @@
457 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 458 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
458 "dev": true 459 "dev": true
459 }, 460 },
461 + "node_modules/colors": {
462 + "version": "1.4.0",
463 + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
464 + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
465 + "engines": {
466 + "node": ">=0.1.90"
467 + }
468 + },
460 "node_modules/concat-map": { 469 "node_modules/concat-map": {
461 "version": "0.0.1", 470 "version": "0.0.1",
462 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 471 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
...@@ -2591,6 +2600,11 @@ ...@@ -2591,6 +2600,11 @@
2591 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2600 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
2592 "dev": true 2601 "dev": true
2593 }, 2602 },
2603 + "colors": {
2604 + "version": "1.4.0",
2605 + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
2606 + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
2607 + },
2594 "concat-map": { 2608 "concat-map": {
2595 "version": "0.0.1", 2609 "version": "0.0.1",
2596 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2610 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
5 "main": "server.js", 5 "main": "server.js",
6 "scripts": { 6 "scripts": {
7 "start": "node server.js", 7 "start": "node server.js",
8 - "dev": "nodemon server.js" 8 + "server": "nodemon server.js"
9 }, 9 },
10 "repository": { 10 "repository": {
11 "type": "git", 11 "type": "git",
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 "license": "MIT", 15 "license": "MIT",
16 "dependencies": { 16 "dependencies": {
17 "bcryptjs": "^2.4.3", 17 "bcryptjs": "^2.4.3",
18 + "colors": "^1.4.0",
18 "dotenv": "^16.0.1", 19 "dotenv": "^16.0.1",
19 "express": "^4.18.1", 20 "express": "^4.18.1",
20 "express-async-handler": "^1.2.0", 21 "express-async-handler": "^1.2.0",
......
1 const express = require("express"); 1 const express = require("express");
2 const router = express.Router(); 2 const router = express.Router();
3 -const { signupUser, loginUser } = require("../actions/userActions"); 3 +const { signupUser, loginUser, getSelf } = require("../actions/userActions");
4 4
5 router.post("/", signupUser); 5 router.post("/", signupUser);
6 router.post("/login", loginUser); 6 router.post("/login", loginUser);
7 +router.get("/self", getSelf);
7 8
8 module.exports = router; 9 module.exports = router;
......
...@@ -2,7 +2,7 @@ const express = require("express"); ...@@ -2,7 +2,7 @@ const express = require("express");
2 const dotenv = require("dotenv").config(); 2 const dotenv = require("dotenv").config();
3 const { errorHandler } = require("./middleware/errorMiddleware"); 3 const { errorHandler } = require("./middleware/errorMiddleware");
4 const connectDB = require("./config/db"); 4 const connectDB = require("./config/db");
5 -const port = process.env.PORT || 8000; 5 +const port = process.env.PORT || 6000;
6 6
7 connectDB(); 7 connectDB();
8 const app = express(); 8 const app = express();
......