Compare commits

...

3 commits

Author SHA1 Message Date
574905f9f8 renaming router 2023-06-15 10:00:39 +03:00
9d13727f3e renaming router 2023-06-15 10:00:22 +03:00
8329a33271 using model for each instance 2023-06-14 21:30:04 +03:00
16 changed files with 151 additions and 88 deletions

18
package-lock.json generated
View file

@ -17,13 +17,15 @@
"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"
} }
}, },
@ -177,6 +179,12 @@
"@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",
@ -1551,6 +1559,14 @@
"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",

View file

@ -19,13 +19,15 @@
"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"
} }
} }

View file

@ -1,5 +1,7 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Cart, ICart, Order, Product } from '../mongoose/Schema'; import { Cart, ICart } from '../models/cartModel';
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';

View file

@ -1,5 +1,5 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Product, IProduct } from '../mongoose/Schema'; import { Product, IProduct } from '../models/productModel';
export async function createProduct(req: Request, res: Response) { export async function createProduct(req: Request, res: Response) {
try { try {

View file

@ -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 '../mongoose/Schema'; import { User, IUser } from '../models/userModel';
import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth'; import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth';
import validate from 'deep-email-validator'; import validate from 'deep-email-validator';

View file

@ -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/user'; import userRouter from './routes/userRouter';
import productRouter from './routes/product'; import productRouter from './routes/productRouter';
import cartRouter from './routes/cart'; import cartRouter from './routes/cartRoute';
const env = require('dotenv').config().parsed; const env = require('dotenv').config().parsed;

View file

@ -0,0 +1,11 @@
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();
}

23
src/models/cartModel.ts Normal file
View file

@ -0,0 +1,23 @@
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
}

27
src/models/orderModel.ts Normal file
View file

@ -0,0 +1,27 @@
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
};

View file

@ -0,0 +1,28 @@
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
}

26
src/models/userModel.ts Normal file
View file

@ -0,0 +1,26 @@
// 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
}

View file

@ -1,74 +0,0 @@
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 };

View file

@ -1,13 +1,14 @@
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, addToCart); cartRouter.post('/', [authenticateToken, checkUuid], addToCart);
cartRouter.get('/', authenticateToken, listCart); cartRouter.get('/', [authenticateToken, checkUuid], listCart);
cartRouter.post('/checkout', authenticateToken, checkout); cartRouter.post('/checkout', authenticateToken, checkout);
cartRouter.delete('/', authenticateToken, clearCart) cartRouter.delete('/', authenticateToken, clearCart)

View file

@ -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();

View file

@ -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();

View file

@ -1,5 +1,6 @@
import { config } from "dotenv"; import { config } from "dotenv";
import { User, Order } from "../mongoose/Schema"; import { Order } from "../models/orderModel";
import { User } from "../models/userModel";
import client from '@sendgrid/mail'; import client from '@sendgrid/mail';
config(); config();