├── vercel.json ├── .gitignore ├── models ├── Product.js ├── Cart.js ├── Wishlist.js ├── Review.js ├── Payment.js └── User.js ├── config.js ├── routes ├── forgotPassword.js ├── paymentRoute.js ├── wishlist.js ├── cart.js ├── review.js ├── product.js ├── auth.js └── Admin │ └── AdminAuth.js ├── middleware ├── authUser.js └── authAdmin.js ├── package.json ├── controller ├── AllProductInfo.js ├── deleteUser.js ├── AdminControl.js ├── paymentController.js └── forgotPasswordController.js ├── index.js └── README.md /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "backend", 4 | "builds": [ 5 | { 6 | "src": "index.js", 7 | "use": "@vercel/node" 8 | } 9 | ], 10 | "routes": [ 11 | { 12 | "src": "/(.*)", 13 | "dest": "/index.js" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .env 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /models/Product.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | const ProductSchema = new Schema({ 4 | name: String, 5 | brand: String, 6 | price: Number, 7 | category: String, 8 | image: String, 9 | rating: Number, 10 | type: String, 11 | author: String, 12 | description: String, 13 | gender: String, 14 | }) 15 | 16 | module.exports = mongoose.model("product", ProductSchema) -------------------------------------------------------------------------------- /models/Cart.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | const CartSchema = new Schema({ 4 | user: { 5 | type: mongoose.Schema.Types.ObjectId, 6 | ref: 'user' 7 | }, 8 | productId: { 9 | type: mongoose.Schema.Types.ObjectId, 10 | ref: 'product' 11 | }, 12 | quantity: { 13 | type: Number 14 | } 15 | 16 | }, { timestamps: true }) 17 | 18 | module.exports = mongoose.model("cart", CartSchema) -------------------------------------------------------------------------------- /models/Wishlist.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | const WishlistSchema = new Schema({ 4 | user: { 5 | type: mongoose.Schema.Types.ObjectId, 6 | ref: 'user' 7 | }, 8 | productId: { 9 | type: mongoose.Schema.Types.ObjectId, 10 | ref: 'product' 11 | }, 12 | date: { 13 | type: Date, 14 | default: Date.now 15 | }, 16 | }) 17 | 18 | module.exports = mongoose.model("wishlist", WishlistSchema) -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const dotenv = require('dotenv'); 3 | dotenv.config() 4 | 5 | const URL = process.env.MONGO_URL 6 | mongoose.set('strictQuery', true) 7 | const connectToMongo = async () => { 8 | try { 9 | let db = await mongoose.connect(URL) 10 | console.log(db.connection.host); 11 | } catch (error) { 12 | console.log(error); 13 | } 14 | 15 | // const f = await User.find(); 16 | // console.log(f); 17 | } 18 | 19 | module.exports = connectToMongo; -------------------------------------------------------------------------------- /routes/forgotPassword.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const authUser = require('../middleware/authUser'); 4 | 5 | const dotenv = require('dotenv'); 6 | const { sendEmailLink, resetPassword,setNewPassword } = require('../controller/forgotPasswordController'); 7 | dotenv.config() 8 | 9 | router.post('/forgot-password', sendEmailLink); 10 | router.post('/forgot-password/:id/:token',setNewPassword ); 11 | router.post('/reset/password', authUser, resetPassword); 12 | module.exports = router -------------------------------------------------------------------------------- /models/Review.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | const ReviewSchema = new Schema({ 4 | user: { 5 | type: mongoose.Schema.Types.ObjectId, 6 | ref: 'user' 7 | }, 8 | productId: { 9 | type: mongoose.Schema.Types.ObjectId, 10 | ref: 'product' 11 | }, 12 | rating: { 13 | type: Number, 14 | }, 15 | comment: { 16 | type: String 17 | }, 18 | 19 | 20 | }, { timestamps: true }) 21 | 22 | 23 | module.exports = mongoose.model("review", ReviewSchema) -------------------------------------------------------------------------------- /middleware/authUser.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const dotenv = require('dotenv'); 3 | dotenv.config() 4 | 5 | const fetchUser = (req, res, next) => { 6 | // get the user from the jwt token and id to req objectPosition: 7 | const token = req.header('Authorization'); 8 | if (!token) { 9 | return res.status(400).send("Access denied" ) 10 | } 11 | try { 12 | const data = jwt.verify(token, process.env.JWT_SECRET) 13 | req.user = data.user 14 | next() 15 | } catch (error) { 16 | res.status(400).send( "Access denied" ) 17 | 18 | } 19 | 20 | 21 | } 22 | 23 | module.exports = fetchUser -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "server": "nodemon index.js", 9 | "start": "node index.js" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "bcrypt": "^5.1.0", 16 | "body-parser": "^1.20.1", 17 | "cors": "^2.8.5", 18 | "dotenv": "^16.0.3", 19 | "express": "^4.18.2", 20 | "express-validator": "^6.14.2", 21 | "jsonwebtoken": "^8.5.1", 22 | "mongoose": "^6.10.4", 23 | "nodemailer": "^6.9.1", 24 | "nodemon": "^2.0.20", 25 | "razorpay": "^2.8.4" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /controller/AllProductInfo.js: -------------------------------------------------------------------------------- 1 | const User = require("../models/User"); 2 | const Cart = require("../models/Cart"); 3 | const Wishlist = require("../models/Wishlist"); 4 | const Review = require("../models/Review"); 5 | const Payment = require("../models/Payment") 6 | const Product = require("../models/Product") 7 | 8 | 9 | const chartData = async (req, res) => { 10 | try { 11 | const cart = await Cart.find().populate("productId"); 12 | const wishlist = await Wishlist.find().populate("productId"); 13 | 14 | const payment = await Payment.find(); 15 | const product = await Product.find(); 16 | const review = await Review.find(); 17 | res.send({ review, product, payment, wishlist, cart }); 18 | } catch (error) { 19 | res.send(error); 20 | 21 | } 22 | } 23 | module.exports = { chartData } -------------------------------------------------------------------------------- /models/Payment.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | const PaymentSchema = new Schema({ 4 | razorpay_order_id: { 5 | type: String, 6 | required: true, 7 | }, 8 | razorpay_payment_id: { 9 | type: String, 10 | required: true, 11 | }, 12 | razorpay_signature: { 13 | type: String, 14 | required: true, 15 | }, 16 | productData: { 17 | type: Object, 18 | required: true, 19 | }, 20 | userData: { 21 | type: Object, 22 | required: true, 23 | }, 24 | user: { 25 | type: mongoose.Schema.Types.ObjectId, 26 | ref: 'user' 27 | }, 28 | totalAmount: { 29 | type: Number, 30 | }, 31 | 32 | 33 | }, { timestamps: true }) 34 | 35 | module.exports = mongoose.model("payment", PaymentSchema) -------------------------------------------------------------------------------- /middleware/authAdmin.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const dotenv = require('dotenv'); 3 | const User = require('../models/User.js') 4 | dotenv.config() 5 | 6 | const checkAdmin = async (req, res, next) => { 7 | // get the user from the jwt token and id to req objectPosition: 8 | const token = req.header('Authorization'); 9 | if (!token) { 10 | return res.status(401).send("Access denied") 11 | } 12 | try { 13 | const data = jwt.verify(token, process.env.JWT_SECRET) 14 | req.user = data.user 15 | const checkAdmin = await User.findById(req.user.id) 16 | if (checkAdmin.isAdmin == true) { 17 | next() 18 | } 19 | else { 20 | res.status(401).send("Access denied") 21 | } 22 | } catch (error) { 23 | res.status(401).send("Access denied") 24 | 25 | } 26 | 27 | 28 | } 29 | 30 | module.exports = checkAdmin -------------------------------------------------------------------------------- /routes/paymentRoute.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { checkout, paymentVerification } = require('../controller/paymentController'); 3 | const router = express.Router() 4 | const Payment = require('../models/Payment') 5 | const User = require('../models/User') 6 | const authUser = require('../middleware/authUser') 7 | const dotenv = require('dotenv'); 8 | dotenv.config() 9 | 10 | router.route('/checkout').post(checkout) 11 | router.route('/paymentverification').post(paymentVerification) 12 | router.route('/getkey').get((req, res) => res.status(200).json({ key: process.env.RAZORPAY_API_KEY })) 13 | 14 | 15 | 16 | router.get('/getPreviousOrders', authUser, async (req, res) => { 17 | try { 18 | const data = await Payment.find({ user: req.user.id }).sort({ createdAt: -1 }) 19 | res.send(data) 20 | } 21 | catch (error) { 22 | res.status(500).send("Something went wrong") 23 | } 24 | }) 25 | 26 | module.exports = router -------------------------------------------------------------------------------- /controller/deleteUser.js: -------------------------------------------------------------------------------- 1 | const User = require("../models/User"); 2 | const Cart = require("../models/Cart"); 3 | const Wishlist = require("../models/Wishlist"); 4 | const Review = require("../models/Review"); 5 | 6 | const deleteAllUserData = async (req, res) => { 7 | const { userId } = req.params; 8 | const findUser = await User.findById(userId) 9 | if (findUser) { 10 | try { 11 | const deleteUser = await User.findByIdAndDelete(userId); 12 | const deleteCart = await Cart.deleteMany({ user: userId }); 13 | const deleteWishlist = await Wishlist.deleteMany({ user: userId }); 14 | const deleteReview = await Review.deleteMany({ user: userId }); 15 | res.send("delete successfully") 16 | } catch (error) { 17 | res.send("Something went wrong") 18 | } 19 | } 20 | else { 21 | res.status(400).send("User Not Found") 22 | } 23 | 24 | } 25 | module.exports = { deleteAllUserData } -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { Schema } = mongoose; 3 | 4 | const UserSchema = new Schema({ 5 | firstName: { 6 | type: String, 7 | required: true 8 | }, 9 | lastName: { 10 | type: String, 11 | required: true 12 | }, 13 | phoneNumber: { 14 | type: Number, 15 | required: true, 16 | unique: true, 17 | }, 18 | email: { 19 | type: String, 20 | required: true, 21 | unique: true 22 | }, 23 | password: { 24 | type: String, 25 | required: true 26 | }, 27 | isAdmin:{ 28 | default:false, 29 | type:Boolean 30 | }, 31 | address: { 32 | type: String 33 | }, 34 | zipCode: { 35 | type: String 36 | }, 37 | city: { 38 | type: String 39 | }, 40 | userState: { 41 | type: String 42 | } 43 | 44 | }, { timestamps: true }); 45 | module.exports = mongoose.model('user', UserSchema) -------------------------------------------------------------------------------- /routes/wishlist.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const Wishlist = require('../models/Wishlist') 4 | const authUser = require('../middleware/authUser') 5 | 6 | 7 | router.get('/fetchwishlist', authUser, async (req, res) => { 8 | try { 9 | const wishlistData = await Wishlist.find({ user: req.user.id }).populate("productId") 10 | res.send(wishlistData) 11 | } 12 | catch (error) { 13 | res.status(500).send("Something went wrong") 14 | } 15 | }) 16 | router.post('/addwishlist', authUser, async (req, res) => { 17 | 18 | try { 19 | const { _id } = req.body 20 | const user = req.header 21 | const findProduct = await Wishlist.findOne({ $and: [{ productId: _id }, { user: req.user.id }] }) 22 | if (findProduct) { 23 | return res.status(400).json({ msg: "Product already in a wishlist" }) 24 | } 25 | else { 26 | const wishlistData = new Wishlist({ user: req.user.id, productId: _id }) 27 | const savedWishlist = await wishlistData.save() 28 | res.send(savedWishlist) 29 | } 30 | } 31 | catch (error) { 32 | res.status(500).send("Something went wrong") 33 | } 34 | }) 35 | router.delete('/deletewishlist/:id', authUser, async (req, res) => { 36 | const { id } = req.params; 37 | try { 38 | const result = await Wishlist.findByIdAndDelete(id) 39 | res.send(result) 40 | } catch (error) { 41 | res.status(500).send("Something went wrong") 42 | } 43 | 44 | 45 | 46 | }) 47 | module.exports = router -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const connectToMongo = require('./config'); 2 | const bodyParser = require('body-parser') 3 | const express = require('express') 4 | const cors = require('cors') 5 | const path = require('path'); 6 | 7 | const auth = require('./routes/auth'); 8 | const cart = require('./routes/cart') 9 | const wishlist = require('./routes/wishlist') 10 | const product = require('./routes/product') 11 | const review = require('./routes/review') 12 | const paymentRoute = require('./routes/paymentRoute') 13 | const forgotPassword = require('./routes/forgotPassword') 14 | const AdminRoute = require('./routes/Admin/AdminAuth') 15 | const dotenv = require('dotenv'); 16 | dotenv.config() 17 | 18 | connectToMongo(); 19 | 20 | const port = 5000 21 | 22 | const app = express() 23 | 24 | // create application/json parser 25 | app.use(bodyParser.json()) 26 | // create application/x-www-form-urlencoded parser 27 | app.use(bodyParser.urlencoded({ extended: false })) 28 | app.use(express.urlencoded({ extended: true })) 29 | 30 | 31 | 32 | app.use(express.json()) 33 | app.use(cors()); 34 | app.use(express.static(path.join(__dirname, 'build'))); 35 | 36 | // Available Routes 37 | app.use('/api/auth', auth) 38 | 39 | app.use('/api/product', product) 40 | 41 | app.use('/api/cart', cart) 42 | 43 | app.use('/api/wishlist', wishlist) 44 | 45 | app.use('/api/review', review) 46 | app.use('/api/admin', AdminRoute) 47 | // payment route 48 | app.use('/api', paymentRoute) 49 | 50 | // forgot Password route 51 | app.use('/api/password', forgotPassword) 52 | 53 | app.listen(port, () => { 54 | console.log(`E-commerce backend listening at http://localhost:${port}`) 55 | }) 56 | -------------------------------------------------------------------------------- /routes/cart.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const Cart = require("../models/Cart"); 4 | const authUser = require("../middleware/authUser"); 5 | 6 | // get all cart products 7 | router.get("/fetchcart", authUser, async (req, res) => { 8 | try { 9 | const cart = await Cart.find({ user: req.user.id }) 10 | .populate("productId", "name price image rating type") 11 | .populate("user", "name email"); 12 | res.send(cart); 13 | } catch (error) { 14 | res.status(500).send("Internal server error"); 15 | } 16 | }); 17 | 18 | // add to cart 19 | 20 | router.post("/addcart", authUser, async (req, res) => { 21 | try { 22 | const { _id, quantity } = req.body; 23 | const findProduct = await Cart.findOne({ $and: [{ productId: _id }, { user: req.user.id }] }) 24 | if (findProduct) { 25 | return res.status(400).json({ msg: "Product already in a cart" }) 26 | } 27 | else { 28 | const user = req.header; 29 | const cart = new Cart({ 30 | user: req.user.id, 31 | productId: _id, 32 | quantity, 33 | }); 34 | const savedCart = await cart.save(); 35 | res.send(savedCart); 36 | } 37 | } catch (error) { 38 | res.status(500).send("Internal server error"); 39 | } 40 | }); 41 | 42 | // remove from cart 43 | router.delete("/deletecart/:id", authUser, async (req, res) => { 44 | const { id } = req.params; 45 | try { 46 | const result = await Cart.findByIdAndDelete(id) 47 | res.send(result); 48 | } catch (error) { 49 | res.status(500).send("Internal server error"); 50 | } 51 | }); 52 | module.exports = router; 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Live Link 2 | 3 | You can access the live application at [https://e-shopit.vercel.app/](https://e-shopit.vercel.app/). 4 | 5 | # MERN-E-Commerce-Backend 6 | 7 | MERN-E-Commerce-Backend is the backend of an e-commerce web application built with MongoDB, NodeJS, and ExpressJS. 8 | 9 | The frontend of the application is built with ReactJS, Material UI, React-router-dom,ContextAPI. The source code for the frontend can be found at [https://github.com/luckypenny1632333/E-Shopit-Frontend.git](https://github.com/luckypenny1632333/E-Shopit-Frontend.git). 10 | 11 | ## Features 12 | 13 | - User authentication and authorization(JWT) 14 | - Admin dashboard for managing products, orders, users and to show statistics 15 | - Payemnt Gateway 16 | - Mail Service 17 | - Forgot Password & Reset Password 18 | - Product listing and search 19 | - Product details and reviews 20 | - Cart management 21 | - Order history 22 | 23 | ## Tech Stack 24 | 25 | - ReactJS 26 | - MongoDB 27 | - NodeJS 28 | - ExpressJS 29 | 30 | ## Images 31 | 32 | ![Dashboard](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853694/Stat1_asehhd.png) 33 | ![Dashboard](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853694/Stat2_tw25cm.png) 34 | ![Dashboard](https://res.cloudinary.com/dxguqzge7/image/upload/v1682956688/Stat3_rslfzi.png) 35 | ![Orders](https://res.cloudinary.com/dxguqzge7/image/upload/v1682956689/Orders_cyfzkp.png) 36 | ![Users](https://res.cloudinary.com/dxguqzge7/image/upload/v1682956689/Users_nxx1cs.png) 37 | ![HomePage](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853694/Home_bcr44v.png) 38 | ![Products](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853695/Products_vxf8pr.png) 39 | ![Product](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853694/Product_tnba6w.png) 40 | ![Payment](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853693/Payment_xrucd9.png) 41 | ![Cart](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853693/Cart_zpzmwr.png) 42 | ![UserProfile](https://res.cloudinary.com/dxguqzge7/image/upload/v1682853694/User_lyfday.png) 43 | 44 | ## Tech Stack 45 | 46 | - ReactJS 47 | - MongoDB 48 | - NodeJS 49 | - ExpressJS 50 | 51 | ## Installation and Usage 52 | 53 | To run the backend server on your local machine, follow these steps: 54 | 55 | 1. Clone the repository: 56 | 57 | ``` 58 | git clone https://github.com/luckypenny1632333/E-Shopit-Backend.git 59 | ``` 60 | 61 | 2. Install the dependencies: 62 | 63 | ``` 64 | cd E-Shopit-Backend 65 | npm install 66 | ``` 67 | 68 | 3. Start the development server: 69 | 70 | ``` 71 | npm run server 72 | ``` 73 | 74 | ## Contributing 75 | 76 | Contributions to the project are welcome. If you find a bug or want to add a new feature, please create a new issue or pull request. 77 | 78 | ## License 79 | 80 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information. 81 | -------------------------------------------------------------------------------- /routes/review.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const Review = require('../models/Review') 4 | const authUser = require('../middleware/authUser') 5 | 6 | router.post('/fetchreview/:id', async (req, res) => { 7 | const { filterType } = req.body 8 | try { 9 | if (filterType === 'all') { 10 | const reviewData = await Review.find({ productId: req.params.id }).populate("user", "firstName lastName") 11 | res.send(reviewData) 12 | } 13 | else if (filterType === 'mostrecent') { 14 | const reviewData = await Review.find({ productId: req.params.id }).populate("user", "firstName lastName").sort({ createdAt: -1 }) 15 | res.send(reviewData) 16 | } 17 | else if (filterType === 'old') { 18 | const reviewData = await Review.find({ productId: req.params.id }).populate("user", "firstName lastName").sort({ createdAt: 1 }) 19 | res.send(reviewData) 20 | } 21 | else if (filterType === 'positivefirst') { 22 | const reviewData = await Review.find({ productId: req.params.id, }).populate("user", "firstName lastName").sort({ rating: -1 }) 23 | res.send(reviewData) 24 | } 25 | else if (filterType === 'negativefirst') { 26 | const reviewData = await Review.find({ productId: req.params.id }).populate("user", "firstName lastName").sort({ rating: 1 }) 27 | res.send(reviewData) 28 | } 29 | else { 30 | const reviewData = await Review.find({ productId: req.params.id }).populate("user", "firstName lastName") 31 | res.send(reviewData) 32 | } 33 | 34 | } 35 | catch (error) { 36 | res.status(500).send("Internal server error") 37 | } 38 | }) 39 | 40 | router.post('/addreview', authUser, async (req, res) => { 41 | try { 42 | const { id, comment, rating } = req.body 43 | const user = req.header 44 | const findReview = await Review.findOne({ $and: [{ user: req.user.id }, { productId: id }] }) 45 | if (findReview) { 46 | return res.status(400).json({ msg: "Already reviewed that product " }) 47 | } 48 | else { 49 | const reviewData = new Review({ user: req.user.id, productId: id, comment: comment, rating: rating }) 50 | const savedReview = await reviewData.save() 51 | res.send({ msg: "Review added successfully" }) 52 | } 53 | } 54 | catch (error) { 55 | res.status(500).send("Something went wrong") 56 | } 57 | }) 58 | 59 | 60 | 61 | router.delete('/deletereview/:id', authUser, async (req, res) => { 62 | const { id } = req.params 63 | try { 64 | let deleteReview = await Review.deleteOne({ $and: [{ user: req.user.id }, { _id: id }] }) 65 | res.send({ msg: "Review deleted successfully" }) 66 | } catch (error) { 67 | res.send({ msg: "Something went wrong,Please try again letter" }) 68 | } 69 | 70 | }) 71 | 72 | 73 | 74 | router.put('/editreview', authUser, async (req, res) => { 75 | const { id, comment, rating } = req.body 76 | 77 | const review = await Review.findById(id) 78 | try { 79 | if (review) { 80 | let updateDetails = await Review.findByIdAndUpdate(id, { $set: { rating: rating, comment: comment } }) 81 | success = true 82 | res.status(200).send({ success, msg: "Review edited successfully" }) 83 | } 84 | else { 85 | return res.status(400).send({ success, error: "User Not Found" }) 86 | } 87 | } catch (error) { 88 | res.send("Something went wrong") 89 | } 90 | }) 91 | module.exports = router -------------------------------------------------------------------------------- /routes/product.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const Product = require('../models/Product') 4 | 5 | // to fetch all products 6 | router.get('/fetchproduct', async (req, res) => { 7 | try { 8 | 9 | const product = await Product.find() 10 | res.send(product) 11 | } 12 | catch (error) { 13 | 14 | res.status(500).send("Something went wrong") 15 | } 16 | }) 17 | // To get Single product 18 | router.get('/fetchproduct/:id', async (req, res) => { 19 | try { 20 | const product = await Product.findById(req.params.id) 21 | 22 | res.send(product) 23 | } catch (error) { 24 | res.status(500).send("Something went wrong") 25 | } 26 | }) 27 | // to get products for single category 28 | router.post('/fetchproduct/type', async (req, res) => { 29 | const { userType } = req.body 30 | try { 31 | const product = await Product.find({ type: userType }) 32 | res.send(product) 33 | } catch (error) { 34 | res.status(500).send("Something went wrong") 35 | } 36 | }) 37 | // to get products category wise 38 | router.post('/fetchproduct/category', async (req, res) => { 39 | const { userType, userCategory } = req.body 40 | try { 41 | if (userCategory == "all") { 42 | const product = await Product.find({ type: userType }) 43 | res.send(product) 44 | } 45 | else if (userCategory == "pricelowtohigh") { 46 | const product = await Product.find({ type: userType }).sort({ price: 1 }) 47 | res.send(product) 48 | } 49 | else if (userCategory == "pricehightolow") { 50 | const product = await Product.find({ type: userType }).sort({ price: -1 }) 51 | res.send(product) 52 | } 53 | else if (userCategory == "highrated") { 54 | const product = await Product.find({ type: userType }).sort({ rating: -1 }) 55 | res.send(product) 56 | } 57 | else if (userCategory == "lowrated") { 58 | const product = await Product.find({ type: userType }).sort({ rating: 1 }) 59 | res.send(product) 60 | } 61 | else { 62 | const product = await Product.find({ type: userType, category: userCategory }) 63 | res.send(product) 64 | } 65 | } catch (error) { 66 | res.status(500).send("Something went wrong") 67 | } 68 | }) 69 | // to search products added search filters on frontend so no need to create separate api for this 70 | 71 | // router.get('/search/:key', async (req, res) => { 72 | // const { key } = req.params 73 | // try { 74 | // if (key.length > 0) { 75 | // const product = await Product.find({ 76 | // $or: [ 77 | // { name: { $regex: key, $options: "i" } }, 78 | // { type: { $regex: key, $options: "i" } }, 79 | // { brand: { $regex: key, $options: "i" } }, 80 | // { category: { $regex: key, $options: "i" } }, 81 | // { author: { $regex: key, $options: "i" } }, 82 | // { description: { $regex: key, $options: "i" } }, 83 | // { gender: { $regex: key, $options: "i" } }, 84 | // ] 85 | // }) 86 | // if (product.length <= 0) { 87 | // res.status(400).send("Product not found") 88 | // } 89 | // else { 90 | // res.send(product) 91 | // } 92 | // } 93 | 94 | // } catch (error) { 95 | // res.status(400).send("Something went wrong") 96 | // } 97 | // }) 98 | 99 | 100 | 101 | 102 | module.exports = router -------------------------------------------------------------------------------- /routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const jwt = require("jsonwebtoken"); 3 | const User = require('../models/User'); 4 | const router = express.Router(); 5 | const bcrypt = require('bcrypt'); 6 | const { body, validationResult } = require('express-validator'); 7 | const authUser = require('../middleware/authUser'); 8 | const dotenv = require('dotenv'); 9 | const { deleteAllUserData } = require('../controller/deleteUser'); 10 | dotenv.config() 11 | 12 | 13 | // create a user :post "/auth",!auth 14 | let success = false 15 | router.post('/register', [ 16 | 17 | body('firstName', 'Enter a valid name').isLength({ min: 1 }), 18 | body('lastName', 'Enter a valid name').isLength({ min: 1 }), 19 | body('email', 'Enter a valid email').isEmail(), 20 | body('password', 'Password must be at least 5 characters').isLength({ min: 5 }), 21 | body('phoneNumber', 'Enter a valid phone number').isLength({ min: 10, max: 10 }) 22 | 23 | 24 | ], async (req, res) => { 25 | 26 | res.c 27 | const errors = validationResult(req); 28 | if (!errors.isEmpty()) { 29 | 30 | return res.status(400).json({ error: errors.array() }) 31 | } 32 | const { firstName, lastName, email, phoneNumber, password,isAdmin } = req.body 33 | 34 | try { 35 | let user = await User.findOne({ $or: [{ email: email }, { phoneNumber: phoneNumber }] }); 36 | if (user) { 37 | return res.status(400).send({ error: "Sorry a user already exists" }) 38 | } 39 | 40 | // password hashing 41 | const salt = await bcrypt.genSalt(10) 42 | const secPass = await bcrypt.hash(password, salt) 43 | 44 | // create a new user 45 | user = await User.create({ 46 | firstName, 47 | lastName, 48 | email, 49 | phoneNumber, 50 | password: secPass, 51 | isAdmin 52 | }) 53 | const data = { 54 | user: { 55 | id: user.id 56 | } 57 | } 58 | success = true 59 | const authToken = jwt.sign(data, process.env.JWT_SECRET) 60 | res.send({ success, authToken }) 61 | } 62 | catch (error) { 63 | res.status(500).send("Internal server error") 64 | } 65 | }) 66 | 67 | 68 | // login Route 69 | router.post('/login', [ 70 | 71 | body('email', 'Enter a valid email').isEmail(), 72 | body('password', 'Password cannot be blank').exists(), 73 | 74 | ], async (req, res) => { 75 | const errors = validationResult(req); 76 | if (!errors.isEmpty()) { 77 | return res.status(400).json({ error: errors.array() }) 78 | } 79 | 80 | const { email, password, } = req.body; 81 | try { 82 | let user = await User.findOne({ email }); 83 | if (!user) { 84 | 85 | return res.status(400).send({ success, error: "User not found" }) 86 | } 87 | const passComp = await bcrypt.compare(password, user.password) 88 | if (!passComp) { 89 | return res.status(400).send({ success, error: "Please try to login with correct credentials" }) 90 | } 91 | 92 | const data = { 93 | user: { 94 | id: user._id 95 | } 96 | } 97 | 98 | const authToken = jwt.sign(data, process.env.JWT_SECRET) 99 | success = true 100 | res.send({ success, authToken }) 101 | } 102 | catch (error) { 103 | res.status(500).send("Internal server error002") 104 | } 105 | } 106 | ); 107 | // logged in user details 108 | 109 | router.get('/getuser', authUser, async (req, res) => { 110 | 111 | try { 112 | const user = await User.findById(req.user.id).select("-password") 113 | success = true 114 | res.send(user) 115 | 116 | } catch (error) { 117 | res.status(400).send("Something went wrong") 118 | } 119 | } 120 | ) 121 | 122 | 123 | // update user details 124 | router.put('/updateuser', authUser, async (req, res) => { 125 | const { userDetails } = req.body 126 | let convertData = JSON.parse(userDetails) 127 | try { 128 | const user = await User.findById(req.user.id) 129 | if (user) { 130 | let updateDetails = await User.findByIdAndUpdate(req.user.id, { $set: convertData }) 131 | success = true 132 | res.status(200).send({ success }) 133 | } 134 | else { 135 | return res.status(400).send("User Not Found") 136 | } 137 | } catch (error) { 138 | res.send("Something went wrong") 139 | } 140 | }) 141 | 142 | // delete user and user data 143 | router.delete('/delete/user/:userId', authUser, deleteAllUserData) 144 | module.exports = router -------------------------------------------------------------------------------- /routes/Admin/AdminAuth.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const jwt = require("jsonwebtoken"); 3 | const User = require('../../models/User'); 4 | const router = express.Router(); 5 | const bcrypt = require('bcrypt'); 6 | const authAdmin = require("../../middleware/authAdmin"); 7 | const { body, validationResult } = require('express-validator'); 8 | const dotenv = require('dotenv'); 9 | const { getAllUsersInfo, getSingleUserInfo, getUserCart, getUserWishlist, getUserReview, deleteUserReview, deleteUserCartItem, deleteUserWishlistItem, updateProductDetails, userPaymentDetails, addProduct, deleteProduct } = require('../../controller/AdminControl'); 10 | const { chartData } = require('../../controller/AllProductInfo'); 11 | dotenv.config() 12 | 13 | 14 | let success = false 15 | let adminKey = process.env.ADMIN_KEY 16 | router.get('/getusers', authAdmin, getAllUsersInfo); 17 | router.get('/geteuser/:userId', authAdmin, getSingleUserInfo); 18 | router.get('/getcart/:userId', authAdmin, getUserCart); 19 | router.get('/getwishlist/:userId', authAdmin, getUserWishlist); 20 | router.get('/getreview/:userId', authAdmin, getUserReview); 21 | router.get('/getorder/:id', authAdmin, userPaymentDetails); 22 | router.get('/chartdata', chartData); 23 | 24 | router.post('/login', [ 25 | body('email', 'Enter a valid email').isEmail(), 26 | body('password', 'Password cannot be blank').exists(), 27 | 28 | ], async (req, res) => { 29 | const errors = validationResult(req); 30 | if (!errors.isEmpty()) { 31 | return res.status(400).json({ error: errors.array() }) 32 | } 33 | 34 | const { email, password, key } = req.body; 35 | try { 36 | let user = await User.findOne({ email }); 37 | if (user && user.isAdmin == true && key == adminKey) { 38 | 39 | const passComp = await bcrypt.compare(password, user.password) 40 | if (!passComp) { 41 | return res.status(400).send({ success, error: "Please try to login with correct credentials" }) 42 | } 43 | 44 | const data = { 45 | user: { 46 | id: user._id 47 | } 48 | } 49 | 50 | const authToken = jwt.sign(data, process.env.JWT_SECRET) 51 | success = true 52 | res.send({ success, authToken }) 53 | } 54 | 55 | else { 56 | return res.status(400).send({ success, error: "Invalid User" }) 57 | } 58 | 59 | } 60 | catch (error) { 61 | res.status(500).send("Internal server error002") 62 | } 63 | } 64 | ); 65 | router.post('/register', [ 66 | 67 | body('firstName', 'Enter a valid name').isLength({ min: 3 }), 68 | body('lastName', 'Enter a valid name').isLength({ min: 3 }), 69 | body('email', 'Enter a valid email').isEmail(), 70 | body('password', 'Password must be at least 5 characters').isLength({ min: 5 }), 71 | body('phoneNumber', 'Enter a valid phone number').isLength({ min: 10, max: 10 }) 72 | 73 | 74 | ], async (req, res) => { 75 | const errors = validationResult(req); 76 | if (!errors.isEmpty()) { 77 | 78 | return res.status(400).json({ error: errors.array() }) 79 | } 80 | const { firstName, lastName, email, phoneNumber, password, key } = req.body 81 | 82 | try { 83 | let user = await User.findOne({ $or: [{ email: email }, { phoneNumber: phoneNumber }] }); 84 | if (user) { 85 | return res.status(400).send({ error: "Sorry a user already exists" }) 86 | } 87 | 88 | if (key != adminKey) { 89 | return res.status(400).send({ error: "Invalid User" }) 90 | } 91 | // password hashing 92 | const salt = await bcrypt.genSalt(10) 93 | const secPass = await bcrypt.hash(password, salt) 94 | 95 | // create a new user 96 | user = await User.create({ 97 | firstName, 98 | lastName, 99 | email, 100 | phoneNumber, 101 | password: secPass, 102 | isAdmin: true 103 | }) 104 | const data = { 105 | user: { 106 | id: user.id 107 | } 108 | } 109 | success = true 110 | const authToken = jwt.sign(data, process.env.JWT_SECRET) 111 | res.send({ success, authToken }) 112 | } 113 | catch (error) { 114 | res.status(500).send("Internal server error") 115 | } 116 | }) 117 | router.post('/addproduct', authAdmin, addProduct); 118 | 119 | 120 | 121 | router.put('/updateproduct/:id', authAdmin, updateProductDetails) 122 | 123 | 124 | 125 | router.delete('/review/:id', authAdmin, deleteUserReview); 126 | router.delete('/usercart/:id', authAdmin, deleteUserCartItem); 127 | router.delete('/userwishlist/:id', authAdmin, deleteUserWishlistItem); 128 | router.delete('/deleteproduct/:id', authAdmin, deleteProduct); 129 | 130 | 131 | module.exports = router -------------------------------------------------------------------------------- /controller/AdminControl.js: -------------------------------------------------------------------------------- 1 | const User = require("../models/User"); 2 | const Cart = require("../models/Cart"); 3 | const Wishlist = require("../models/Wishlist"); 4 | const Review = require("../models/Review"); 5 | const Product = require("../models/Product"); 6 | const Payment = require("../models/Payment"); 7 | let success = false; 8 | const getAllUsersInfo = async (req, res) => { 9 | try { 10 | const data = await User.find().select('-password'); 11 | // console.log(data); 12 | res.send(data) 13 | 14 | } catch (error) { 15 | console.log(error); 16 | res.status(400).send("Something went wrong") 17 | } 18 | } 19 | const getSingleUserInfo = async (req, res) => { 20 | const { userId } = req.params; 21 | const findUser = await User.findById(userId) 22 | if (findUser) { 23 | try { 24 | const findUser = await User.findById(userId).select('-password'); 25 | res.send(findUser); 26 | } catch (error) { 27 | res.send("Something went wrong") 28 | } 29 | } 30 | else { 31 | res.status(400).send("User Not Found") 32 | } 33 | 34 | } 35 | const getUserCart = async (req, res) => { 36 | const { userId } = req.params; 37 | const findUser = await User.findById(userId) 38 | if (findUser) { 39 | try { 40 | const findUserCart = await Cart.find({ user: userId }) 41 | .populate("productId", "name price image rating type") 42 | .populate("user", "name email"); 43 | res.send(findUserCart); 44 | } catch (error) { 45 | res.send("Something went wrong") 46 | } 47 | } 48 | else { 49 | res.status(400).send("User Not Found") 50 | } 51 | 52 | } 53 | const getUserWishlist = async (req, res) => { 54 | const { userId } = req.params; 55 | const findUser = await User.findById(userId) 56 | if (findUser) { 57 | try { 58 | const findUserWishlist = await Wishlist.find({ user: userId }).populate("productId") 59 | res.send(findUserWishlist); 60 | } catch (error) { 61 | res.send("Something went wrong") 62 | } 63 | } 64 | else { 65 | res.status(400).send("User Not Found") 66 | } 67 | 68 | } 69 | const getUserReview = async (req, res) => { 70 | const { userId } = req.params; 71 | const findUser = await User.findById(userId) 72 | if (findUser) { 73 | try { 74 | 75 | const findUserReview = await Review.find({ user: userId }) 76 | .populate("productId", "name price image rating type") 77 | .populate("user", "firstName lastName"); 78 | res.send(findUserReview); 79 | } catch (error) { 80 | res.send("Something went wrong") 81 | } 82 | } 83 | else { 84 | res.status(400).send("User Not Found") 85 | } 86 | 87 | } 88 | 89 | const deleteUserReview = async (req, res) => { 90 | const { id } = req.params; 91 | try { 92 | let deleteReview = await Review.findByIdAndDelete(id) 93 | res.send({ msg: "Review deleted successfully" }) 94 | } catch (error) { 95 | res.status(400).send({ msg: "Something went wrong,Please try again letter", error }) 96 | } 97 | } 98 | 99 | 100 | const deleteUserCartItem = async (req, res) => { 101 | const { id } = req.params; 102 | try { 103 | let deleteCart = await Cart.findByIdAndDelete(id) 104 | success = true 105 | res.send({ success, msg: "Review deleted successfully" }) 106 | } catch (error) { 107 | res.status(400).send({ msg: "Something went wrong,Please try again letter1" }) 108 | } 109 | } 110 | const deleteUserWishlistItem = async (req, res) => { 111 | const { id } = req.params; 112 | console.log(id); 113 | try { 114 | let deleteCart = await Wishlist.findByIdAndDelete(id) 115 | success = true 116 | res.send({ success, msg: "Review deleted successfully" }) 117 | } catch (error) { 118 | res.status(400).send({ msg: "Something went wrong,Please try again letter" }) 119 | } 120 | } 121 | 122 | 123 | const updateProductDetails = async (req, res) => { 124 | const updateProduct = req.body.productDetails; 125 | updateProduct.price = parseFloat(updateProduct.price); 126 | updateProduct.rating = parseFloat(updateProduct.rating); 127 | const { id } = req.params; 128 | const product = await Product.findById(id) 129 | if (product) { 130 | try { 131 | let update = await Product.findByIdAndUpdate(id, { $set: updateProduct }) 132 | success = true 133 | const findType = await Product.find({ type: "book" }).distinct('category') 134 | 135 | res.send({ success, msg: "Product updated successfully", findType }) 136 | 137 | } catch (error) { 138 | // return res.status(400).send({ success, error: error }) 139 | return res.status(400).send(error) 140 | } 141 | } 142 | else { 143 | return res.status(400).send({ success, error: "Product not found" }) 144 | } 145 | 146 | } 147 | 148 | const userPaymentDetails = async (req, res) => { 149 | const { id } = req.params; 150 | const findPayment = await Payment.find({ user: id }) 151 | if (findPayment) { 152 | try { 153 | res.send(findPayment) 154 | } catch (error) { 155 | return res.status(400).send(error) 156 | } 157 | } 158 | else { 159 | return res.status(400).send({ total: 0 }) 160 | } 161 | } 162 | 163 | const addProduct = async (req, res) => { 164 | const { name, brand, price, category, image, rating, type, author, description, gender } = req.body; 165 | try { 166 | await Product.create({ name, brand, price, category, image, rating, type, author, description, gender }) 167 | success = true 168 | res.send(success) 169 | 170 | } catch (error) { 171 | console.log(error); 172 | return res.status(400).send(error) 173 | } 174 | } 175 | 176 | const deleteProduct = async (req, res) => { 177 | const { id } = req.params; 178 | let findProduct = await Product.findById(id); 179 | if (findProduct) { 180 | try { 181 | await Product.findByIdAndDelete(id) 182 | success = true 183 | res.send(success) 184 | } catch (error) { 185 | return res.status(400).send(error) 186 | } 187 | } 188 | else { 189 | return res.status(400).send({ success, msg: "Product Not Found" }) 190 | } 191 | } 192 | 193 | module.exports = { 194 | getAllUsersInfo, getSingleUserInfo, 195 | getUserCart, getUserWishlist, 196 | getUserReview, deleteUserReview, 197 | deleteUserCartItem, deleteUserWishlistItem, 198 | updateProductDetails, userPaymentDetails, addProduct, deleteProduct 199 | } -------------------------------------------------------------------------------- /controller/paymentController.js: -------------------------------------------------------------------------------- 1 | const Razorpay = require('razorpay'); 2 | const crypto = require('crypto'); 3 | const Payment = require('../models/Payment'); 4 | const Cart = require('../models/Cart'); 5 | const nodemailer = require('nodemailer'); 6 | const dotenv = require('dotenv'); 7 | dotenv.config() 8 | 9 | 10 | let productInfo = {}; 11 | let userData = {}; 12 | let userInfo; 13 | let totalAmount; 14 | const instance = new Razorpay({ 15 | key_id: process.env.RAZORPAY_API_KEY, 16 | key_secret: process.env.RAZORPAY_API_SECRET, 17 | }); 18 | const checkout = async (req, res) => { 19 | 20 | try { 21 | const { amount, userId, productDetails, userDetails } = req.body 22 | totalAmount = Number(amount) 23 | userInfo = userId 24 | productInfo = JSON.parse(productDetails) 25 | userData = JSON.parse(userDetails) 26 | 27 | 28 | const options = { 29 | amount: Number(amount * 100), 30 | currency: "INR", 31 | }; 32 | const order = await instance.orders.create(options); 33 | 34 | 35 | res.status(200).json({ 36 | success: true, 37 | order 38 | }); 39 | 40 | } catch (error) { 41 | console.log(error); 42 | } 43 | 44 | 45 | }; 46 | // 47 | 48 | const paymentVerification = async (req, res) => { 49 | 50 | const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = req.body; 51 | 52 | const body = razorpay_order_id + "|" + razorpay_payment_id; 53 | 54 | const expectedSignature = crypto 55 | .createHmac("sha256", process.env.RAZORPAY_API_SECRET) 56 | .update(body.toString()) 57 | .digest("hex"); 58 | 59 | const isAuthentic = expectedSignature === razorpay_signature; 60 | try { 61 | if (isAuthentic) { 62 | // Database comes here 63 | const transport = nodemailer.createTransport({ 64 | service: "gmail", 65 | host: "smtp.gmail.email", 66 | port: 465, 67 | auth: { 68 | user: process.env.EMAIL, 69 | pass: process.env.EMAIL_PASSWORD 70 | }, 71 | }) 72 | const mailOptions = { 73 | from: process.env.EMAIL, 74 | to: userData.userEmail, 75 | subject: "Order Confirm", 76 | html: ` 77 | 78 | 79 | 80 | Order Confirmation 81 | 144 | 145 | 146 |

Order Confirmation

147 |

Dear ${userData.firstName} ${userData.lastName},

148 |

Thank you for your recent purchase on our website. We have received your payment of ₹${totalAmount} and have processed your order.

149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | ${productInfo.map((product) => { 159 | return ` 160 | 161 | 162 | 163 | 164 | 165 | ` 166 | }).join('') 167 | } 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
Product NameQuantityPrice
${product.productId.name}${product.quantity}₹${product.productId.price}
Shipping Charge₹100
Total₹${totalAmount}
180 |
181 |

Shipping Address

182 |

${userData.firstName} ${userData.lastName}

183 |

${userData.address}

184 |

${userData.city}-${userData.zipCode}

185 |

${userData.userState}

186 |
187 |

Thank you for choosing our website. If you have any questions or concerns, please don't hesitate to contact us.

188 |
189 |

Best regards,

190 |

ShopIt.com

191 |
192 | 193 | 194 | `, 195 | text: ` 196 | 197 | 198 | 199 | Order Confirmation 200 | 263 | 264 | 265 |

Order Confirmation

266 |

Dear ${userData.firstName} ${userData.lastName},

267 |

Thank you for your recent purchase on our website. We have received your payment of ₹${totalAmount} and have processed your order.

268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | ${productInfo.map((product) => { 278 | return ` 279 | 280 | 281 | 282 | 283 | 284 | ` 285 | }).join('') 286 | } 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 |
Product NameQuantityPrice
${product.productId.name}${product.quantity}₹${product.productId.price}
Shipping Charge₹100
Total₹${totalAmount}
299 |
300 |

Shipping Address

301 |

${userData.firstName} ${userData.lastName}

302 |

${userData.address}

303 |

${userData.city}-${userData.zipCode}

304 |

${userData.userState}

305 |
306 |

Thank you for choosing our website. If you have any questions or concerns, please don't hesitate to contact us.

307 |
308 |

Best regards,

309 |

ShopIt.com

310 |
311 | 312 | 313 | ` 314 | 315 | } 316 | 317 | transport.sendMail(mailOptions, (error, info) => { 318 | if (error) { 319 | console.log(error); 320 | // res.send({ msg: error }); 321 | } 322 | else { 323 | return res.send({ success, msg: "Order Confirm" }) 324 | } 325 | }) 326 | await Payment.create({ 327 | razorpay_order_id, 328 | razorpay_payment_id, 329 | razorpay_signature, 330 | user: userInfo, 331 | productData: productInfo, 332 | userData, 333 | totalAmount 334 | }); 335 | const deleteCart = await Cart.deleteMany({ user: userInfo }) 336 | 337 | res.redirect(`${process.env.PAYMENT_SUCCESS}=${razorpay_payment_id} `); 338 | } 339 | else { 340 | res.status(400).json({ 341 | success: false, 342 | }); 343 | } 344 | } 345 | catch (error) { 346 | console.log(error); 347 | } 348 | } 349 | 350 | 351 | module.exports = { checkout, paymentVerification } -------------------------------------------------------------------------------- /controller/forgotPasswordController.js: -------------------------------------------------------------------------------- 1 | const User = require('../models/User'); 2 | const jwt = require("jsonwebtoken"); 3 | const dotenv = require('dotenv'); 4 | const nodemailer = require('nodemailer'); 5 | const bcrypt = require('bcrypt'); 6 | dotenv.config() 7 | let success = false; 8 | const sendEmailLink = async (req, res) => { 9 | const { email } = req.body; 10 | const findUser = await User.findOne({ email: email }) 11 | if (findUser) { 12 | try { 13 | const secretKey = findUser._id + process.env.JWT_SECRET; 14 | const token = jwt.sign({ userID: findUser._id }, secretKey, { expiresIn: '5m' }); 15 | 16 | const link = `${process.env.FORGOT_PASSWORD}/${findUser._id}/${token}`; 17 | 18 | const transport = nodemailer.createTransport({ 19 | service: "gmail", 20 | host: "smtp.gmail.email", 21 | port: 465, 22 | auth: { 23 | user: process.env.EMAIL, 24 | pass: process.env.EMAIL_PASSWORD 25 | }, 26 | }) 27 | const mailOptions = { 28 | from: process.env.EMAIL, 29 | to: email, 30 | subject: "Password Reset Request", 31 | html: ` 32 | 33 | 34 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 271 | 272 | 273 |
130 | 131 | 132 | 133 |
134 |
135 |
136 | 137 | 138 | 139 |
140 |
141 |
142 | 143 | 144 | 145 | 146 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 163 | 164 | 165 | 166 | 167 |
168 |
169 |
170 | 171 | 172 |
173 |
174 |
175 | 176 | 177 | 178 |
179 |
180 |
181 | 182 | 183 | 184 |
185 |
186 |
187 | 188 | 189 | 190 | 191 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 214 | 215 | 216 | 217 | 218 |
219 |
220 |
221 | 222 | 223 |
224 |
225 |
226 | 227 | 228 | 229 |
230 |
231 |
232 | 233 | 234 | 235 |
236 |
237 |
238 | 239 | 240 | 241 | 242 | 255 | 256 | 257 |
243 | 244 | 245 | 246 | 247 | 250 | 251 | 252 |
248 |   249 |
253 | 254 |
258 | 259 |
260 |
261 |
262 | 263 | 264 |
265 |
266 |
267 | 268 | 269 | 270 |
274 | 275 | 276 | 277 | 278 | 279 | `, 280 | 281 | } 282 | transport.sendMail(mailOptions, (error, info) => { 283 | if (error) { 284 | return res.send({ msg: error }); 285 | } 286 | else { 287 | success = true 288 | return res.send({ msg: "Email Sent Please Check Your Email" }) 289 | } 290 | }) 291 | } catch (error) { 292 | return res.send({ msg: error }) 293 | } 294 | } 295 | else { 296 | return res.status(400).json({ msg: "User not found" }) 297 | } 298 | } 299 | {/* 300 | 301 | 306 | 307 |
302 | 303 | image 304 | 305 |
*/} 308 | const setNewPassword = async (req, res) => { 309 | const { newPassword } = req.body; 310 | const { id, token } = req.params; 311 | try { 312 | if (newPassword && id && token) { 313 | const findUser = await User.findById(id) 314 | const secretKey = findUser._id + process.env.JWT_SECRET; 315 | const isValid = await jwt.verify(token, secretKey); 316 | if (isValid) { 317 | const isUser = await User.findById(id); 318 | // password hashing 319 | const salt = await bcrypt.genSalt(10) 320 | const hashedPass = await bcrypt.hash(newPassword, salt) 321 | const isSuccess = await User.findByIdAndUpdate(isUser._id, { 322 | $set: { 323 | password: hashedPass 324 | } 325 | }) 326 | if (isSuccess) { 327 | success = true 328 | const transport = nodemailer.createTransport({ 329 | service: "gmail", 330 | host: "smtp.gmail.email", 331 | port: 465, 332 | auth: { 333 | user: process.env.EMAIL, 334 | pass: process.env.EMAIL_PASSWORD 335 | }, 336 | }) 337 | const mailOptions = { 338 | from: process.env.EMAIL, 339 | to: isUser.email, 340 | subject: "Password Change Confirmation", 341 | html: ` 342 | 343 | 344 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 561 | 562 | 563 |
440 | 441 | 442 | 443 |
444 |
445 |
446 | 447 | 448 | 449 |
450 |
451 |
452 | 453 | 454 | 455 | 456 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 |
483 |
484 |
485 | 486 | 487 | 488 |
489 |
490 |
491 | 492 |
493 | 494 | 495 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 545 | 546 | 547 | 548 | 549 |
550 |
551 |
552 | 553 | 554 |
555 |
556 |
557 | 558 | 559 | 560 |
564 | 565 | 566 | 567 | 568 | `, 569 | 570 | } 571 | transport.sendMail(mailOptions, (error, info) => { 572 | if (error) { 573 | res.send({ msg: error }); 574 | } 575 | else { 576 | return res.send({ msg: "Password Changed Successfully" }) 577 | } 578 | }) 579 | } 580 | else { 581 | return res.status(400).json({ msg: "some thing went wrong" }); 582 | } 583 | } 584 | else { 585 | return res.status(400).json({ msg: "Link has been expired" }); 586 | } 587 | 588 | } 589 | else { 590 | return res.status(400).json({ msg: "All fields are required" }); 591 | } 592 | } catch (error) { 593 | return res.send({ msg: error }) 594 | } 595 | } 596 | 597 | const resetPassword = async (req, res) => { 598 | const { id, currentPassword, newPassword } = req.body; 599 | const findUser = await User.findById(id) 600 | if (findUser) { 601 | try { 602 | const oldPassword = findUser.password; 603 | const passwordCompare = await bcrypt.compare(currentPassword, oldPassword) 604 | if (!passwordCompare) { 605 | return res.status(400).send("Please enter correct password"); 606 | } 607 | else { 608 | const salt = await bcrypt.genSalt(10) 609 | const hashedPass = await bcrypt.hash(newPassword, salt) 610 | const isSuccess = await User.findByIdAndUpdate(findUser, { 611 | $set: { 612 | password: hashedPass 613 | } 614 | }) 615 | if (isSuccess) { 616 | success = true 617 | const transport = nodemailer.createTransport({ 618 | service: "gmail", 619 | host: "smtp.gmail.email", 620 | port: 465, 621 | auth: { 622 | user: process.env.EMAIL, 623 | pass: process.env.EMAIL_PASSWORD 624 | }, 625 | }) 626 | const mailOptions = { 627 | from: process.env.EMAIL, 628 | to: findUser.email, 629 | subject: "Password Change Confirmation", 630 | html: ` 631 | 632 | 633 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 872 | 873 | 874 |
729 | 730 | 731 | 732 |
733 |
734 |
735 | 736 | 737 | 738 |
739 |
740 |
741 | 742 | 743 | 744 | 745 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 778 | 779 | 780 | 781 | 782 |
783 |
784 |
785 | 786 | 787 |
788 |
789 |
790 | 791 | 792 | 793 |
794 |
795 |
796 | 797 | 798 | 799 |
800 |
801 |
802 | 803 | 804 | 805 | 806 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 856 | 857 | 858 | 859 | 860 |
861 |
862 |
863 | 864 | 865 |
866 |
867 |
868 | 869 | 870 | 871 |
875 | 876 | 877 | 878 | 879 | `, 880 | 881 | } 882 | transport.sendMail(mailOptions, (error, info) => { 883 | if (error) { 884 | return res.status(400).send(error); 885 | } 886 | else { 887 | return res.send("Password Changed Successfully") 888 | } 889 | }) 890 | } 891 | } 892 | } catch (error) { 893 | return res.status(400).send("Something went wrong") 894 | 895 | } 896 | } 897 | else { 898 | return res.status(400).json("User not found"); 899 | } 900 | } 901 | 902 | module.exports = { sendEmailLink, setNewPassword, resetPassword } --------------------------------------------------------------------------------