Skip to content

Commit eceba72

Browse files
authored
Merge pull request #65 from ik079/feature/cart-controller
Small improvements to make it safer, more robust
2 parents 04a8a1f + 2555893 commit eceba72

1 file changed

Lines changed: 16 additions & 12 deletions

File tree

src/controllers/cart.controller.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import Cart from '../models/cart.model.js';
33
import Product from '../models/product.model.js';
44
import HttpException from '../utils/exceptions/http.exception.js';
55

6-
// Helper to get or create a cart for a user
6+
const MAX_QUANTITY = 100; // reasonable upper bound for quantity per item
7+
8+
// Helper to get or create a cart for a user (atomic/upsert to avoid races)
79
async function findOrCreateCart(userId) {
8-
let cart = await Cart.findOne({ userId });
9-
if (!cart) {
10-
cart = await Cart.create({ userId, items: [] });
11-
}
10+
const cart = await Cart.findOneAndUpdate(
11+
{ userId },
12+
{ $setOnInsert: { userId, items: [] } },
13+
{ new: true, upsert: true }
14+
);
1215
return cart;
1316
}
1417

@@ -37,16 +40,19 @@ export const addToCart = async (req, res, next) => {
3740
const { userId } = req.params;
3841
const { productId, quantity } = req.body || {};
3942

40-
if (!userId || typeof userId !== 'string') {
43+
if (!userId || typeof userId !== 'string' || userId.length > 200) {
4144
return next(new HttpException(400, 'Invalid or missing userId'));
4245
}
4346
if (!productId || !mongoose.Types.ObjectId.isValid(productId)) {
4447
return next(new HttpException(400, 'Invalid or missing productId'));
4548
}
46-
const qty = Number(quantity) || 1;
47-
if (qty < 1) {
49+
let qty = Number(quantity) || 1;
50+
if (!Number.isFinite(qty) || qty < 1) {
4851
return next(new HttpException(400, 'Quantity must be at least 1'));
4952
}
53+
if (qty > MAX_QUANTITY) {
54+
return next(new HttpException(400, `Quantity must be <= ${MAX_QUANTITY}`));
55+
}
5056

5157
const product = await Product.findById(productId);
5258
if (!product) {
@@ -57,9 +63,9 @@ export const addToCart = async (req, res, next) => {
5763

5864
const existing = cart.items.find((it) => it.productId.toString() === productId);
5965
if (existing) {
60-
existing.quantity += qty;
66+
existing.quantity = Math.min(existing.quantity + qty, MAX_QUANTITY);
6167
} else {
62-
cart.items.push({ productId, quantity: qty });
68+
cart.items.push({ productId, quantity: Math.min(qty, MAX_QUANTITY) });
6369
}
6470

6571
await cart.save();
@@ -138,5 +144,3 @@ export const removeFromCart = async (req, res, next) => {
138144
next(new HttpException(500, 'Failed to remove from cart'));
139145
}
140146
}
141-
142-

0 commit comments

Comments
 (0)