Critical Data Loss Alert: ESHOPMAN Order Deletion Bug Fixed in v2.12.4

At Move My Store, we're dedicated to ensuring the stability and data integrity of your ESHOPMAN storefront. We want to bring your attention to a critical bug that was identified and swiftly resolved in ESHOPMAN Core, impacting how draft orders were handled and, in severe cases, leading to the accidental deletion of completed customer orders.

Critical Data Loss Alert: ESHOPMAN Order Deletion Bug Fixed in v2.12.4

A significant issue was discovered in ESHOPMAN Core v2.12.3 and potentially earlier 2.x versions. This bug could lead to catastrophic data loss, specifically the hard-deletion of all completed orders in your ESHOPMAN store. This situation arose when specific draft orders were deleted via the ESHOPMAN Admin API or POS clients.

The Problem: Unintended Cascade Deletion

The core of the issue lay within the OrderModuleService.deleteOrders function. When a draft order was created without explicit shipping or billing addresses (a common scenario for POS hold carts or initial drafts), its shipping_address_id and billing_address_id fields would be null.

The deleteOrders workflow, part of ESHOPMAN's robust order management, constructs a list of address IDs to be deleted. The problematic implementation looked like this:

const orderAddressIds = orders
  .map((order) => [order.shipping_address_id, order.billing_address_id])
  .flat(1)

await this.orderAddressService_.delete(orderAddressIds, sharedContext)

When shipping_address_id or billing_address_id were null, these null values were included in the orderAddressIds array. Crucially, when this array, containing null, was passed to orderAddressService_.delete(...), the underlying database query (observed as delete from "order_address" returning "id") would execute without a proper WHERE id IN (...) clause, effectively wiping out the entire order_address table.

Why This Was Catastrophic for ESHOPMAN Stores

ESHOPMAN's order schema is designed with foreign key relationships for data integrity. Specifically, the order table references order_address with ON DELETE CASCADE:

FOREIGN KEY (shipping_address_id) REFERENCES order_address(id) ON DELETE CASCADE
FOREIGN KEY (billing_address_id) REFERENCES order_address(id) ON DELETE CASCADE

This means that when all rows in order_address were deleted, the database automatically cascade-deleted all associated orders – including your completed and paid customer orders. This resulted in permanent data loss, leaving behind orphaned payment records and a significant void in your sales history.

Steps to Reproduce (Simplified)

  • Create several completed orders that have shipping addresses.
  • Create a draft order in ESHOPMAN Admin or via a POS system, ensuring its shipping/billing address IDs are null.
  • Call DELETE /admin/draft-orders/:id for that specific draft order.
  • Observe: The order_address table is emptied, and your completed orders are gone.

The ESHOPMAN Solution

The ESHOPMAN core team swiftly addressed this critical vulnerability. The fix involved two key improvements to the deleteOrders function:

  1. Filtering Falsy IDs: Ensuring that null or undefined values are removed from the address ID array.
  2. Conditional Deletion: Only attempting to delete addresses if there are valid IDs in the array.

The corrected code now looks like this:

const orderAddressIds = orders
  .map((order) => [order.shipping_address_id, order.billing_address_id])
  .flat(1)
  .filter((id) => !!id) // Filter out null/falsy IDs

if (orderAddressIds.length) { // Only delete if there are valid IDs
  await this.orderAddressService_.delete(orderAddressIds, sharedContext)
}

This robust solution prevents the orderAddressService_.delete from being called with an array containing only nulls or an empty array, thereby safeguarding your order_address table and, by extension, all your completed orders.

Action Required: Update Your ESHOPMAN Core

We are pleased to confirm that this critical bug has been fully resolved in ESHOPMAN Core v2.12.4. If your ESHOPMAN instance is running on v2.12.3 or an earlier 2.x version, we strongly urge you to update immediately to prevent any potential data loss. This update is crucial for maintaining the integrity of your ESHOPMAN storefront and customer data.

At Move My Store, we prioritize the security and reliability of your ESHOPMAN platform, ensuring your e-commerce operations run smoothly and your data remains protected.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools