From 0c58ead6d869f5605cbd2b8aca129984b7493bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frane=20Poli=C4=87?= <16856471+fPolic@users.noreply.github.com> Date: Sun, 7 May 2023 13:12:06 +0200 Subject: [PATCH] fix(medusa): Validate `customer_id` when completing a cart (#3967) --- .changeset/odd-plants-mate.md | 5 ++++ .../api/__tests__/store/cart/cart.js | 27 +++++++++++++++++++ .../plugins/__tests__/inventory/cart/cart.js | 4 +-- packages/medusa/src/services/order.ts | 11 ++++++-- 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 .changeset/odd-plants-mate.md diff --git a/.changeset/odd-plants-mate.md b/.changeset/odd-plants-mate.md new file mode 100644 index 0000000000..9c5a679547 --- /dev/null +++ b/.changeset/odd-plants-mate.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +fix(medusa): validate `customer_id` when completing a cart diff --git a/integration-tests/api/__tests__/store/cart/cart.js b/integration-tests/api/__tests__/store/cart/cart.js index 3d83b677f9..762aa551b0 100644 --- a/integration-tests/api/__tests__/store/cart/cart.js +++ b/integration-tests/api/__tests__/store/cart/cart.js @@ -2152,6 +2152,33 @@ describe("/store/carts", () => { }) }) + it("complete cart throws if there is no customer on the cart", async () => { + const api = useApi() + const product = await simpleProductFactory(dbConnection) + const region = await simpleRegionFactory(dbConnection, { tax_rate: 10 }) + const cart = await simpleCartFactory(dbConnection, { + region: region.id, + line_items: [ + { + variant_id: product.variants[0].id, + quantity: 1, + unit_price: 1000, + }, + ], + }) + + await api.post(`/store/carts/${cart.id}/payment-sessions`) + + try { + await api.post(`/store/carts/${cart.id}/complete`) + } catch (err) { + expect(err.response.status).toEqual(400) + expect(err.response.data.message).toEqual( + "Cannot create an order from the cart without a customer" + ) + } + }) + describe("POST /store/carts/:id/shipping-methods", () => { beforeEach(async () => { await cartSeeder(dbConnection) diff --git a/integration-tests/plugins/__tests__/inventory/cart/cart.js b/integration-tests/plugins/__tests__/inventory/cart/cart.js index a4a2675dd6..337182d5c2 100644 --- a/integration-tests/plugins/__tests__/inventory/cart/cart.js +++ b/integration-tests/plugins/__tests__/inventory/cart/cart.js @@ -222,8 +222,7 @@ describe("/store/carts", () => { expect(getRes.response.status).toEqual(400) expect(getRes.response.data).toEqual({ type: "invalid_data", - message: - "Can't insert null value in field customer_id on insert in table order", + message: "Cannot create an order from the cart without a customer", }) const inventoryService = appContainer.resolve("inventoryService") @@ -232,6 +231,7 @@ describe("/store/carts", () => { }) expect(count).toEqual(0) }) + it("fails to add a item on the cart if the inventory isn't enough", async () => { const api = useApi() diff --git a/packages/medusa/src/services/order.ts b/packages/medusa/src/services/order.ts index 6dd906fa1f..31f128c661 100644 --- a/packages/medusa/src/services/order.ts +++ b/packages/medusa/src/services/order.ts @@ -637,6 +637,13 @@ class OrderService extends TransactionBaseService { ) } + if (!cart.customer_id) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + "Cannot create an order from the cart without a customer" + ) + } + const { payment, region, total } = cart // Would be the case if a discount code is applied that covers the item @@ -667,7 +674,7 @@ class OrderService extends TransactionBaseService { // Is the cascade insert really used? Also, is it really necessary to pass the entire entities when creating or updating? // We normally should only pass what is needed? const shippingMethods = cart.shipping_methods.map((method) => { - (method.tax_lines as any) = undefined + ;(method.tax_lines as any) = undefined return method }) @@ -775,7 +782,7 @@ class OrderService extends TransactionBaseService { // TODO: Due to cascade insert we have to remove the tax_lines that have been added by the cart decorate totals. // Is the cascade insert really used? Also, is it really necessary to pass the entire entities when creating or updating? // We normally should only pass what is needed? - (method.tax_lines as any) = undefined + ;(method.tax_lines as any) = undefined return shippingOptionServiceTx.updateShippingMethod(method.id, { order_id: order.id, })