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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
client
node_modules
requests
mongodb
src
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MONGODB_URL=
PORT=
JWT_SECRET=
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ node_modules
.env

## upload
uploads
uploads

dist
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM node:16-alpine

WORKDIR /app

COPY package*.json .

RUN npm ci

COPY . .

ENV NODE_ENV=production

CMD ["npm", "start"]
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3'

services:
mongo:
image: mongo
ports:
- 27017:27017
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin
api:
build: .
restart: always
ports:
- 4000:8080
env_file: .env
12 changes: 5 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
{
"name": "FaztWare",
"name": "faztware",
"version": "0.0.1",
"description": "An ecommerce website",
"main": "index.js",
"repository": {
"url": "https://github.com/FaztWeb/faztware"
},
"scripts": {
"start": "node dist/index.js",
"build": "babel src -d dist",
"dev": "nodemon src/index.js --exec babel-node --ignore client"
},
"keywords": [],
"author": "",
"author": "fazttech",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"cloudinary": "^1.26.3",
"core-js": "^3.17.2",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
Expand All @@ -20,7 +26,8 @@
"joi": "^17.4.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.0.1",
"morgan": "^1.10.0"
"morgan": "^1.10.0",
"regenerator-runtime": "^0.13.9"
},
"devDependencies": {
"@babel/cli": "^7.14.8",
Expand Down
2 changes: 1 addition & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ config();
export const MONGODB_URL = process.env.MONGODB_URL || "";

/* Server */
export const PORT = process.env.PORT || 4000;
export const PORT = process.env.PORT || 8080;

/* JWT */
export const JWT_SECRET = process.env.JWT_SECRET || "";
Expand Down
10 changes: 4 additions & 6 deletions src/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { User } from "../models";
import jwt from "jsonwebtoken";
import { JWT_SECRET } from "../config";
import { userSchema } from "../libs/schema.validator";
import createError from "http-errors";
import { signAccessToken } from "../helpers/signAccessToken";
Expand Down Expand Up @@ -28,14 +26,14 @@ export const login = async (req, res, next) => {

export const register = async (req, res, next) => {
try {
const result = await userSchema.validateAsync(req.body);
const payload = await userSchema.validateAsync(req.body);

const userFound = await User.findOne({ email: result.email });
const userFound = await User.findOne({ email: payload.email });

if (userFound) throw createError.Conflict("The user already exists");

const user = new User({ email: result.email, password: result.password });
user.password = await user.generateHash(user.password);
const password = await user.generateHash(payload.password);
const user = new User({ email: payload.email, password });

const userSaved = await user.save();

Expand Down
43 changes: 22 additions & 21 deletions src/controllers/product.controller.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
import Product from "../models/Product";
import { uploadImage } from "../helpers/cloudinary";
import createError from "http-errors";
import { productSchema } from "../libs/schema.validator";

export const getProducts = async (req, res) => {
const products = await Product.find();
res.json(products);
export const getProducts = async (req, res, next) => {
try {
const products = await Product.find();
res.json(products);
} catch (error) {
next(error)
}
};

export const createProduct = async (req, res, next) => {
try {
let imageURL = "";
const { name, price, description, quantity } = req.body;

const payload = await productSchema.validateAsync(req.body);
const { name, price, description, quantity } = payload;
const productFound = await Product.findOne({ name: name });

if (productFound) throw createError.Conflict("Product Already exists");

/* TODO: validate fields */
if (req.files && req.files.image) {
const result = await uploadImage(req.files.image.tempFilePath);
imageURL = result.secure_url;
}

const result = await uploadImage(req.files?.image?.tempFilePath);
const newProduct = new Product({
name,
price,
description,
quantity,
images: {
url: imageURL,
url: result ? result.secure_url : "",
},
});

await newProduct.save();

res.json(newProduct);
} catch (error) {
if (error.isJoi) error.status = 400;
console.log(error);
next(error);
}
Expand All @@ -45,17 +41,22 @@ export const updateProduct = (req, res) => {
res.json("updating products");
};

export const getProduct = (req, res) => {
res.json("get product");
export const getProduct = (req, res, next) => {
try {
const { id } = req.params;
const productFound = await Product.findById(id);
if (!productFound) return res.sendStatus(404);
res.json(productFound);
} catch (error) {
next(error);
}
};

export const deleteProduct = async (req, res) => {
const { id } = req.params;

try {
const productDeleted = await Product.findByIdAndDelete(id);
if (productDeleted) return res.sendStatus(204);

return res.sendStatus(404);
} catch (error) {
console.log(error);
Expand Down
21 changes: 21 additions & 0 deletions src/controllers/users.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import User from "../models/User";

export const getUsers = async (req, res, next) => {
try {
const users = await User.find();
res.json(users);
} catch (error) {
next(error)
}
};

export const getUser = (req, res, next) => {
try {
const { id } = req.params;
const userFound = await User.findById(id);
if (!userFound) return res.sendStatus(404);
res.json(userFound);
} catch (error) {
next(error);
}
};
5 changes: 2 additions & 3 deletions src/helpers/cloudinary.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ cloudinary.config({

export const uploadImage = async (file) => {
try {
const result = await cloudinary.uploader.upload(file);
console.log(result);
return result;
if (!file) return null;
return await cloudinary.uploader.upload(file);
} catch (error) {
console.error(error);
}
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/signAccessToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const signAccessToken = (userId) => {
reject(new Error("userId is required"));
}
jwt.sign({ id: userId }, JWT_SECRET, (err, token) => {
if (err) return reject(err);
if (err) reject(err);
resolve(token);
});
});
Expand Down
8 changes: 5 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import express from "express";
import "core-js/stable";
import "regenerator-runtime/runtime";
import "./config/mongoose";
import cors from "cors";
import morgan from "morgan";
Expand All @@ -8,7 +10,7 @@ import fileUpload from "express-fileupload";
import productRoutes from "./routes/products.routes";
import authRoutes from "./routes/auth.routes";

const app = express();
export const app = express();

app.use(cors());
app.use(morgan("dev"));
Expand All @@ -21,8 +23,8 @@ app.use(
})
);

app.use(productRoutes);
app.use(authRoutes);
app.use("/products", productRoutes);
app.use("/auth", authRoutes);

app.use((err, req, res, next) => {
res.status(err.status || 500);
Expand Down
9 changes: 8 additions & 1 deletion src/libs/schema.validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@ const userSchema = Joi.object({
password: Joi.string().required().min(6).max(30),
});

export { userSchema };
const productSchema = Joi.object({
name: Joi.string().required(),
price: Joi.number().required(),
description: Joi.string().optional(),
quantity: Joi.number().required()
})

export { userSchema, productSchema };
2 changes: 1 addition & 1 deletion src/middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import jwt from "jsonwebtoken";
import { JWT_SECRET } from "../config";

export const verifyToken = (req, res, next) => {
const token = req.headers.authorization;
const token = req.headers?.authorization;

if (!token) return res.status(401).send({ message: "Unauthorized" });

Expand Down
6 changes: 3 additions & 3 deletions src/routes/auth.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { verifyToken } from "../middlewares/auth.middleware";

const router = Router();

router.post("/auth/login", login);
router.post("/login", login);

router.post("/auth/register", register);
router.post("/register", register);

router.get("/auth/profile", verifyToken, profile);
router.get("/profile", verifyToken, profile);

export default router;
10 changes: 5 additions & 5 deletions src/routes/products.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import { verifyToken } from "../middlewares/auth.middleware";

const router = Router();

router.get("/products", getProducts);
router.get("/", getProducts);

router.post("/products", verifyToken, createProduct);
router.post("/", verifyToken, createProduct);

router.get("/products/:id", getProduct);
router.get("/:id", getProduct);

router.put("/products/:id", verifyToken, updateProduct);
router.put("/:id", verifyToken, updateProduct);

router.delete("/products/:id", verifyToken, deleteProduct);
router.delete("/:id", verifyToken, deleteProduct);

export default router;
10 changes: 10 additions & 0 deletions src/routes/users.routes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { Router } from "express";
import {
getUsers,
getUser,
} from "../controllers/user.controller";
import { verifyToken } from "../middlewares/auth.middleware";

const router = Router();

router.get("/", verifyToken, getUsers);

router.get("/:id", verifyToken, getUser);

export default router;