diff --git a/config/dbConnection.js b/config/dbConnection.js index e69de29..2611dba 100644 --- a/config/dbConnection.js +++ b/config/dbConnection.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); + +const connectDb = async () => { + await mongoose.connect(process.env.CONNECTION_STRING, { + }).then(() => { + console.log("Database connected: ", mongoose.connection.host, mongoose.connection.name); + }).catch((err) => { + console.log(err); + process.exit(1); + }); +} + +module.exports = connectDb; \ No newline at end of file diff --git a/controllers/userController.js b/controllers/userController.js index e69de29..8f64df4 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -0,0 +1,103 @@ +const asyncHandler = require('express-async-handler'); +const user = require('../models/user'); +const sendToken = require('../utils/jwtToken'); + +// Get all users => GET api/users +const getAllUser = asyncHandler(async (req, res) => { + const users = await user.find(); + res.status(200).json(users); +}); + +// Create new user => POST api/users/create +const createUser = asyncHandler(async (req, res) => { + try { + const { username, + password, + email, + isGoogleAccount } = req.body; + + const users = await user.create({ + username, + password, + email, + isGoogleAccount + }); + + res.status(200).json(users); + } catch(err) { + console.log(err) + } +}); + +// Delete user => api/users/delete/:id +const deleteUser = asyncHandler(async (req, res) => { + try { + const userId = req.params.id; + + const deleteUserId = await user.findById(userId); + + if(!deleteUserId) { + return res.status(404).send('User ID not found!'); + } + + await user.findByIdAndDelete(userId); + + res.status(200).send({ + message: `Deleted ${userId} from database` + }); + } catch(err) { + console.log(err); + } +}); + +// Update user => api/users/update/:id +const updateUser = asyncHandler(async (req, res) => { + let users = await user.findById(req.params.id); + + if(!users) { + return res.status(404).send('User not found!'); + } + + users = await user.findByIdAndUpdate(req.params.id, req.body, { + new: true, + }) + res.status(200).json(users) +}); + +// Login user => api/users/login +const loginUser = asyncHandler(async (req, res) => { + const { email, password } = req.body; + + if(!email || !password) { + return res.status(400).send('Please enter email & password'); + } + + const users = await user.findOne({ email }).select('+password'); + + if(!users) { + return res.status(400).send('Invalid Email or Password'); + } + + const isPasswordMatched = await users.comparePassword(password); + + if(!isPasswordMatched) { + return res.status(401).send('Invalid Email or Password'); + } + + sendToken(users, 200, res); +}); + +// Logout user => api/users/logout +const logoutUser = asyncHandler(async (req, res) => { + res.cookie('token', null, { + expires: new Date(Date.now()), + httpOnly: true + }); + + res.status(200).json({ + success: true, + message: 'Logged out' + }); +}); + +module.exports = { getAllUser, createUser, deleteUser, updateUser, loginUser, logoutUser }; \ No newline at end of file diff --git a/models/user.js b/models/user.js index e69de29..f43fd28 100644 --- a/models/user.js +++ b/models/user.js @@ -0,0 +1,51 @@ +const mongoose = require('mongoose'); +const validator = require('validator'); +const bcrypt = require('bcryptjs'); +const jwt = require('jsonwebtoken'); + +const userSchema = new mongoose.Schema({ + username: { + type: String, + required: true + }, + password: { + type: String, + required: true, + select : false + }, + imgPath: { + type: String, + required: true + }, + email: { + type: String, + required: true + }, + isGoogleAccount: { + type: Boolean + }, + createdAt: { + type: Date, + default: Date.now + } +}); + +userSchema.pre('save', async function (next) { + if(!this.isModified('password')) { + next(); + } + + this.password = await bcrypt.hash(this.password, 10); +}); + +userSchema.methods.comparePassword = async function (enteredPassword) { + return await bcrypt.compare(enteredPassword, this.password); +}; + +userSchema.methods.getJwtToken = function () { + return jwt.sign({ id: this._id }, process.env.JWT_SECRET, { + expiresIn: process.env.JWT_EXPIRES_TIME + }); +}; + +module.exports = mongoose.model('user', userSchema); \ No newline at end of file diff --git a/routes/user.js b/routes/user.js index e69de29..5dd6a7c 100644 --- a/routes/user.js +++ b/routes/user.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const { getAllUser, + createUser, + deleteUser, + updateUser, + loginUser, + logoutUser} = require('../controllers/userController'); + +router.route('/').get(getAllUser); +router.route('/create').post(createUser); +router.route('/delete/:id').delete(deleteUser); +router.route('/update/:id').put(updateUser); +router.route('/login').post(loginUser); +router.route('/logout').get(logoutUser); + +module.exports = router; \ No newline at end of file diff --git a/server.js b/server.js index 941ccb1..9d4b307 100644 --- a/server.js +++ b/server.js @@ -6,6 +6,7 @@ const connectDb = require('./config/dbConnection'); app.use(express.json()); app.use(cors()); +app.use('/api/users', require('./routes/user')); app.listen(process.env.PORT, () => { diff --git a/utils/jwtToken.js b/utils/jwtToken.js index e69de29..5a7e649 100644 --- a/utils/jwtToken.js +++ b/utils/jwtToken.js @@ -0,0 +1,22 @@ +// Create and send token and save in the cookie. +const sendToken = (user, statusCode, res) => { + + // Create Jwt token + const token = user.getJwtToken(); + + // Options for cookie + const options = { + expires: new Date( + Date.now() + 7 * 24 * 60 * 60 * 1000 + ), + httpOnly: true + } + + res.status(statusCode).cookie('token', token, options).json({ + success: true, + token, + user + }); +} + +module.exports = sendToken; \ No newline at end of file