Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules
.env
66 changes: 66 additions & 0 deletions controllers/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const passport = require('passport');
const localStrategy = require('passport-local').Strategy;
const userModel = require('../model/userModel');
const JWTstrategy = require('passport-jwt').Strategy;
const ExtractJWT = require('passport-jwt').ExtractJwt;


passport.use(
new JWTstrategy({
secretOrKey: process.env.JWT_SECRET,
jwtFromRequest: ExtractJWT.fromUrlQueryParameter('secret_token')
},
async(token, done) => {
try {
return done(null, token.user);
} catch (error) {
done(error);
}
}
)
);

passport.use(
'signup',
new localStrategy({
usernameField: 'username',
passwordField: 'password'
},
async(username, password, done) => {
try {
const user = await userModel.create({ username, password });
return done(null, user);
} catch (error) {
done(error);
}
}
)
);

passport.use(
'login',
new localStrategy({
usernameField: 'username',
passwordField: 'password'
},
async(username, password, done) => {
try {
const user = await userModel.findOne({ username });

if (!user) {
return done(null, false, { message: 'user not found, pls signup if you do not have an account' });
}

const validate = await user.isValidPassword(password);

if (!validate) {
return done(null, false, { message: 'Wrong password, Pls input valid password' });
}

return done(null, user, { message: 'Login successful' })
} catch (error) {
return done(error)
}
}
)
);
14 changes: 14 additions & 0 deletions controllers/errHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const errorHandler = (error, req, res, next) => {
try {
if (error.name === "CastError") {
return res
.status(400)
.send({ error: "Unable to find order with provided ID" });
}
return res.status(500).send({ error: "Error occured" });
} catch (error) {
res.status(400).json({ error: true, message: "Order not to found" });
}
};

module.exports = errorHandler;
192 changes: 192 additions & 0 deletions controllers/orderController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
const express = require("express");
const { object } = require("webidl-conversions");
const router = express.Router();
const orderModel = require("../model/orderModel");

/*Get Information about all orders*/
const getOrderInfo = async(rq, res, next) => {
try {
//Check if user is authenticated

const orders = await orderModel.find({});
const resObj = {};
resObj.numberOfOrders = orders.length;
resObj.states = orders.reduce((obj, x) => {
if (!obj[x.state]) obj[x.state] = 0;
obj[x.state]++;
return obj;
}, {});
return res.json({ status: true, data: resObj });
} catch (err) {
next(err);
}
};

/*Get all orders*/
const getAllOrders = async(req, res, next) => {
try {
let orders,
returnObject = {};

//PAGINATION
let limitFromQuery = parseInt(req.query.limit);
let pageFromQuery = parseInt(req.query.page);

let limit = 5,
page = 1; // default values
if (!isNaN(limitFromQuery) && limitFromQuery > 0) limit = limitFromQuery;

const numberOfOrders = await orderModel.find().countDocuments().exec();
const totalPages = Math.ceil(numberOfOrders / limit);
if (!isNaN(pageFromQuery) && pageFromQuery <= totalPages)
page = pageFromQuery;

const startIndex = (page - 1) * limit;
const endIndex = page * limit;

const { price, date } = req.query;

if (price) {
const value = price === "asc" ? 1 : price === "desc" ? -1 : false;
if (value)
orders = await orderModel
.find(filter)
.populate("user", { username: 1 })
.sort({ total_price: value })
.limit(limit)
.skip(startIndex);
} else if (date) {
const value = date === "asc" ? 1 : date === "desc" ? -1 : false;
if (value)
orders = await orderModel
.find()
.populate("user", { username: 1 })
.sort({ created_at: value })
.limit(limit)
.skip(startIndex);
}
if (!orders)
orders = await orderModel
.find()
.populate("user", { username: 1 })
.limit(limit)
.skip(startIndex);

if (startIndex > 0) {
returnObject.previousPage = {
page: page - 1,
limit: limit,
};
}
returnObject.currentPage = page;

if (endIndex < numberOfOrders) {
returnObject.nextPage = {
page: page + 1,
limit: limit,
};
}
returnObject.totalPages = totalPages;
returnObject.orders = orders;

return res.json({ status: true, data: returnObject });
} catch (err) {
next(err);
}
};

/*Get order by id*/
const getOrderById = async(req, res, next) => {
try {
const { orderId } = req.params;
const order = await orderModel.findById(orderId);
if (!order) {
return res.status(404).send.json({ status: false, order: null });
}
return res.status(404).json({ status: true, order });
} catch (err) {
next(err);
}
};

/*Create a new order*/
const createOrder = async(req, res, next) => {
try {
const body = req.body;

const total_price = body.items.reduce((prev, curr) => {
return (prev += curr.quantity * curr.price);
}, 0);

const orderObject = {
items: body.items,
created_at: new Date(),
total_price,
};

const order = new orderModel(orderObject);
order
.save()
.then((result) => {
return res.status(201).json({ status: true, result });
})
.catch((err) => {
res.send(500);
console.log("Error creating order", err.message);
return res.json({ error: "Error creating order" });
});
} catch (err) {
next();
}
};

/*Update order state*/
const updateOrder = async(req, res, next) => {
try {
const { id } = req.params;
const { state } = req.body;

const order = await orderModel.findById(id);

if (!order) {
return res.status(404).json({ status: false, order: null });
}
if (state < order.state) {
return res
.status(422)
.json({ status: false, order: null, message: "Invalid operaton" });
}
order.state = state;

await order.save();

return res.json({ status: true, order });
} catch (err) {
console.log(err);
next(err);
}
};

/*Delete order*/
const deleteOrder = async(req, res, next) => {
try {
const { id } = req.params;

const order = await orderModel.findOne({ _id: id });
const deleted = await order.remove();
if (deleted) {
return res.status(204).json({ status: true });
}
} catch (err) {
next(err);
}
};

module.exports = {
getOrderInfo,
getAllOrders,
getOrderById,
createOrder,
updateOrder,
deleteOrder,
};
74 changes: 74 additions & 0 deletions controllers/userController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// const express = require("express");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const userModel = require("../model/userModel");

// const router = express.Router();

/*Get all users*/
const getAllUsers = async(req, res) => {
try {
//hash the password
req.body.password = await bcrypt.hash(req.body.password, 10);
//create a new user
const user = await userModel.create(req.body);
return res.json({ status: true, user });
} catch (err) {
return res.json({ status: false, data: err.message });
}
};

const createUser = async(req, res) => {
try {
const { username, password, email } = req.body;
const emailExists = await userModel.findOne({ email });
if (!emailExists) {
const hashPassword = bcrypt.hashSync(password, 10);
const userObject = {
username,
email,
password: hashPassword,
};
console.log("userObject =>", userObject);
const user = await userModel.create(userObject);
res
.status(201)
.json({ message: "user created successfully", data: user });
} else {
throw new Error("email exists");
}
} catch (err) {
res.status(409).json({ message: err.message });
}
};

const loginUser = async(req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
throw new Error("username and password are required to login");
}

const user = await userModel.findOne({ email });
if (user) {
const verifyPassword = await bcrypt.compare(password, user.password);
if (verifyPassword) {
const data = { id: user._id, email: user.email };
const token = jwt.sign(data, process.env.JWT_SECRET, {
expiresIn: "30d",
});
return res
.status(200)
.json({ message: "user logged in sucessfully", token });
} else {
throw Error("email or password not correct");
}
} else {
throw new Error("user not found");
}
} catch (error) {
res.status(400).json({ message: error.message });
}
};

module.exports = { getAllUsers, createUser, loginUser };
17 changes: 17 additions & 0 deletions db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const mongoose = require("mongoose");
require("dotenv").config();

const Mongo_DB_Connection_URL = process.env.Mongo_DB_Connection_URL;

function connectToMongoDB() {
mongoose.connect(Mongo_DB_Connection_URL);

mongoose.connection.on("connected", () => {
console.log("Successfully connected to MongoDB");
});
mongoose.connection.on("error", (err) => {
console.log("Error connecting to MongoDB", err);
});
}

module.exports = {connectToMongoDB};
Loading