Compare commits
No commits in common. "574905f9f8d6a27c4bd1cc0f6e3cd68b9671c5ae" and "4c25aa65febf03d6f9a1963b7339e8adae31d310" have entirely different histories.
574905f9f8
...
4c25aa65fe
16 changed files with 88 additions and 151 deletions
18
package-lock.json
generated
18
package-lock.json
generated
|
@ -17,15 +17,13 @@
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"mongodb": "^5.6.0",
|
"mongodb": "^5.6.0",
|
||||||
"mongoose": "^7.2.2",
|
"mongoose": "^7.2.2"
|
||||||
"uuid": "^9.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/jsonwebtoken": "^9.0.2",
|
"@types/jsonwebtoken": "^9.0.2",
|
||||||
"@types/uuid": "^9.0.2",
|
|
||||||
"nodemon": "^2.0.22"
|
"nodemon": "^2.0.22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -179,12 +177,6 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/uuid": {
|
|
||||||
"version": "9.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz",
|
|
||||||
"integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/webidl-conversions": {
|
"node_modules/@types/webidl-conversions": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||||
|
@ -1559,14 +1551,6 @@
|
||||||
"node": ">= 0.4.0"
|
"node": ">= 0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|
|
@ -19,15 +19,13 @@
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"mongodb": "^5.6.0",
|
"mongodb": "^5.6.0",
|
||||||
"mongoose": "^7.2.2",
|
"mongoose": "^7.2.2"
|
||||||
"uuid": "^9.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/jsonwebtoken": "^9.0.2",
|
"@types/jsonwebtoken": "^9.0.2",
|
||||||
"@types/uuid": "^9.0.2",
|
|
||||||
"nodemon": "^2.0.22"
|
"nodemon": "^2.0.22"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { Cart, ICart } from '../models/cartModel';
|
import { Cart, ICart, Order, Product } from '../mongoose/Schema';
|
||||||
import { Product } from '../models/productModel';
|
|
||||||
import { Order } from '../models/orderModel';
|
|
||||||
import { sendEmailasync } from '../services/sendGrid';
|
import { sendEmailasync } from '../services/sendGrid';
|
||||||
import { config } from 'dotenv';
|
import { config } from 'dotenv';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { Product, IProduct } from '../models/productModel';
|
import { Product, IProduct } from '../mongoose/Schema';
|
||||||
|
|
||||||
export async function createProduct(req: Request, res: Response) {
|
export async function createProduct(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import bcrypt from 'bcryptjs';
|
import bcrypt from 'bcryptjs';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import { User, IUser } from '../models/userModel';
|
import { User, IUser } from '../mongoose/Schema';
|
||||||
import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth';
|
import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth';
|
||||||
import validate from 'deep-email-validator';
|
import validate from 'deep-email-validator';
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ import express from 'express';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import cookieParser from 'cookie-parser';
|
import cookieParser from 'cookie-parser';
|
||||||
|
|
||||||
import userRouter from './routes/userRouter';
|
import userRouter from './routes/user';
|
||||||
import productRouter from './routes/productRouter';
|
import productRouter from './routes/product';
|
||||||
import cartRouter from './routes/cartRoute';
|
import cartRouter from './routes/cart';
|
||||||
|
|
||||||
const env = require('dotenv').config().parsed;
|
const env = require('dotenv').config().parsed;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { v4 as uuidv4, validate as validateUUID } from 'uuid';
|
|
||||||
import { Request, Response, NextFunction } from 'express';
|
|
||||||
|
|
||||||
export function checkUuid(req: Request, res: Response, next: NextFunction) {
|
|
||||||
const { userId } = req.body;
|
|
||||||
if (!validateUUID(userId)) {
|
|
||||||
res.status(400).json({ error: 'Invalid user id' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
import mongoose, { Schema, Document } from 'mongoose';
|
|
||||||
|
|
||||||
interface ICart extends Document {
|
|
||||||
userId: string;
|
|
||||||
products: { [itemId: string]: number };
|
|
||||||
createdAt: Date;
|
|
||||||
updatedAt: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const CartSchema: Schema = new Schema({
|
|
||||||
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true, unique: true },
|
|
||||||
products: { type: Schema.Types.Mixed, default: {} },
|
|
||||||
createdAt: { type: Date, default: Date.now },
|
|
||||||
updatedAt: { type: Date, default: Date.now },
|
|
||||||
});
|
|
||||||
|
|
||||||
const Cart = mongoose.model<ICart>('Cart', CartSchema);
|
|
||||||
|
|
||||||
export {
|
|
||||||
Cart,
|
|
||||||
ICart
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
import mongoose, { Schema, Document } from 'mongoose';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface IOrder extends Document {
|
|
||||||
userId: string;
|
|
||||||
products: { [itemId: string]: number };
|
|
||||||
emailSent: boolean;
|
|
||||||
createdAt: Date;
|
|
||||||
updatedAt: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OrderSchema: Schema = new Schema({
|
|
||||||
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
|
||||||
products: { type: Schema.Types.Mixed, default: {} },
|
|
||||||
emailSent: { type: Boolean, default: false },
|
|
||||||
createdAt: { type: Date, default: Date.now },
|
|
||||||
updatedAt: { type: Date, default: Date.now },
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const Order = mongoose.model<IOrder>('Order', OrderSchema);
|
|
||||||
|
|
||||||
export {
|
|
||||||
Order,
|
|
||||||
IOrder
|
|
||||||
};
|
|
|
@ -1,28 +0,0 @@
|
||||||
import mongoose, { Schema, Document } from 'mongoose';
|
|
||||||
|
|
||||||
interface IProduct extends Document {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
price: number;
|
|
||||||
userId: string;
|
|
||||||
createdAt: Date;
|
|
||||||
updatedAt: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProductSchema: Schema = new Schema({
|
|
||||||
name: { type: String, required: true },
|
|
||||||
description: { type: String, required: true },
|
|
||||||
price: { type: Number, required: true },
|
|
||||||
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
|
||||||
createdAt: { type: Date, default: Date.now },
|
|
||||||
updatedAt: { type: Date, default: Date.now },
|
|
||||||
});
|
|
||||||
|
|
||||||
const Product = mongoose.model<IProduct>('Product', ProductSchema);
|
|
||||||
|
|
||||||
ProductSchema.index({ name: 1, userId: 1 }, { unique: true });
|
|
||||||
|
|
||||||
export {
|
|
||||||
Product,
|
|
||||||
IProduct
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
// src/models/userModel.ts
|
|
||||||
|
|
||||||
import mongoose, { Schema, Document } from 'mongoose';
|
|
||||||
|
|
||||||
interface IUser extends Document {
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
address: string;
|
|
||||||
createdAt: Date;
|
|
||||||
updatedAt: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UserSchema: Schema = new Schema({
|
|
||||||
email: { type: String, required: true, unique: true },
|
|
||||||
password: { type: String, required: true },
|
|
||||||
address: { type: String, required: true },
|
|
||||||
createdAt: { type: Date, default: Date.now },
|
|
||||||
updatedAt: { type: Date, default: Date.now },
|
|
||||||
});
|
|
||||||
|
|
||||||
const User = mongoose.model<IUser>('User', UserSchema);
|
|
||||||
|
|
||||||
export {
|
|
||||||
User,
|
|
||||||
IUser
|
|
||||||
}
|
|
74
src/mongoose/Schema.ts
Normal file
74
src/mongoose/Schema.ts
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import mongoose, { Schema, Document } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IUser extends Document {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
address: string;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IProduct extends Document {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
price: number;
|
||||||
|
userId: string;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICart extends Document {
|
||||||
|
userId: string;
|
||||||
|
products: { [itemId: string]: number };
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IOrder extends Document {
|
||||||
|
userId: string;
|
||||||
|
products: { [itemId: string]: number };
|
||||||
|
emailSent: boolean;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserSchema: Schema = new Schema({
|
||||||
|
email: { type: String, required: true, unique: true },
|
||||||
|
password: { type: String, required: true },
|
||||||
|
address: { type: String, required: true },
|
||||||
|
createdAt: { type: Date, default: Date.now },
|
||||||
|
updatedAt: { type: Date, default: Date.now },
|
||||||
|
});
|
||||||
|
|
||||||
|
const ProductSchema: Schema = new Schema({
|
||||||
|
name: { type: String, required: true },
|
||||||
|
description: { type: String, required: true },
|
||||||
|
price: { type: Number, required: true },
|
||||||
|
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||||
|
createdAt: { type: Date, default: Date.now },
|
||||||
|
updatedAt: { type: Date, default: Date.now },
|
||||||
|
});
|
||||||
|
|
||||||
|
const CartSchema: Schema = new Schema({
|
||||||
|
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true, unique: true },
|
||||||
|
products: { type: Schema.Types.Mixed, default: {} },
|
||||||
|
createdAt: { type: Date, default: Date.now },
|
||||||
|
updatedAt: { type: Date, default: Date.now },
|
||||||
|
});
|
||||||
|
|
||||||
|
const OrderSchema: Schema = new Schema({
|
||||||
|
userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||||
|
products: { type: Schema.Types.Mixed, default: {} },
|
||||||
|
emailSent: { type: Boolean, default: false },
|
||||||
|
createdAt: { type: Date, default: Date.now },
|
||||||
|
updatedAt: { type: Date, default: Date.now },
|
||||||
|
});
|
||||||
|
|
||||||
|
ProductSchema.index({ name: 1, userId: 1 }, { unique: true });
|
||||||
|
|
||||||
|
const User = mongoose.model<IUser>('User', UserSchema);
|
||||||
|
const Product = mongoose.model<IProduct>('Product', ProductSchema);
|
||||||
|
const Cart = mongoose.model<ICart>('Cart', CartSchema);
|
||||||
|
const Order = mongoose.model<IOrder>('Order', OrderSchema);
|
||||||
|
|
||||||
|
export { User, Product, Cart, Order };
|
|
@ -1,14 +1,13 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { authenticateToken } from '../middlewares/checkAuth';
|
import { authenticateToken } from '../middlewares/checkAuth';
|
||||||
import { addToCart, listCart, checkout, clearCart } from '../controllers/cartController';
|
import { addToCart, listCart, checkout, clearCart } from '../controllers/CartController';
|
||||||
import { checkUuid } from '../middlewares/checkUuid';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const cartRouter = express.Router();
|
const cartRouter = express.Router();
|
||||||
|
|
||||||
cartRouter.post('/', [authenticateToken, checkUuid], addToCart);
|
cartRouter.post('/', authenticateToken, addToCart);
|
||||||
cartRouter.get('/', [authenticateToken, checkUuid], listCart);
|
cartRouter.get('/', authenticateToken, listCart);
|
||||||
|
|
||||||
cartRouter.post('/checkout', authenticateToken, checkout);
|
cartRouter.post('/checkout', authenticateToken, checkout);
|
||||||
cartRouter.delete('/', authenticateToken, clearCart)
|
cartRouter.delete('/', authenticateToken, clearCart)
|
|
@ -1,6 +1,6 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { authenticateToken } from '../middlewares/checkAuth';
|
import { authenticateToken } from '../middlewares/checkAuth';
|
||||||
import { createProduct, listProducts, getProduct } from '../controllers/productController';
|
import { createProduct, listProducts, getProduct } from '../controllers/ProductController';
|
||||||
|
|
||||||
const productRouter = express.Router();
|
const productRouter = express.Router();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { createUser, login, logout, getAllUsers, deleteUser } from '../controllers/userController';
|
import { createUser, login, logout, getAllUsers, deleteUser } from '../controllers/UserController';
|
||||||
|
|
||||||
const userRouter = express.Router();
|
const userRouter = express.Router();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { config } from "dotenv";
|
import { config } from "dotenv";
|
||||||
import { Order } from "../models/orderModel";
|
import { User, Order } from "../mongoose/Schema";
|
||||||
import { User } from "../models/userModel";
|
|
||||||
import client from '@sendgrid/mail';
|
import client from '@sendgrid/mail';
|
||||||
config();
|
config();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue