Commit 33fd23a321b for woocommerce

commit 33fd23a321b1f1bc3b6334d9e394e228f6495a35
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date:   Fri Oct 30 15:13:32 2026 +0100

    Only accept Back In Stock sign ups in products viewable by the user (#70407)

    * Only accept Back In Stock sign ups in products viewable by the user

    * Improve changelog message

    * Simplify tests

diff --git a/plugins/woocommerce/changelog/fix-WOO6-376-bis-visible-products b/plugins/woocommerce/changelog/fix-WOO6-376-bis-visible-products
new file mode 100644
index 00000000000..6c91b6e415d
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-WOO6-376-bis-visible-products
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Reject back-in-stock sign-ups for products the shopper cannot view
diff --git a/plugins/woocommerce/src/Internal/StockNotifications/Frontend/SignupService.php b/plugins/woocommerce/src/Internal/StockNotifications/Frontend/SignupService.php
index 134db09c2d4..2a81469c396 100644
--- a/plugins/woocommerce/src/Internal/StockNotifications/Frontend/SignupService.php
+++ b/plugins/woocommerce/src/Internal/StockNotifications/Frontend/SignupService.php
@@ -133,7 +133,7 @@ class SignupService {
 		}

 		$product = wc_get_product( $product_id );
-		if ( ! $product ) {
+		if ( ! $product || ! $product->is_viewable() ) {
 			return new \WP_Error( self::ERROR_INVALID_PRODUCT );
 		}

@@ -381,7 +381,7 @@ class SignupService {
 		}

 		$product = wc_get_product( $product_id );
-		if ( ! $product instanceof \WC_Product ) {
+		if ( ! $product instanceof \WC_Product || ! $product->is_viewable() ) {
 			return new \WP_Error( self::ERROR_INVALID_PRODUCT );
 		}

diff --git a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/SignupServiceTests.php b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/SignupServiceTests.php
index 9cada6a3654..e52bb840928 100644
--- a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/SignupServiceTests.php
+++ b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/SignupServiceTests.php
@@ -3,6 +3,7 @@
 declare( strict_types = 1 );
 namespace Automattic\WooCommerce\Tests\Internal\StockNotifications\Frontend;

+use Automattic\WooCommerce\Enums\ProductStatus;
 use Automattic\WooCommerce\Enums\ProductStockStatus;
 use Automattic\WooCommerce\Internal\StockNotifications\Emails\EmailManager;
 use Automattic\WooCommerce\Internal\StockNotifications\Enums\NotificationStatus;
@@ -583,6 +584,43 @@ class SignupServiceTests extends \WC_Unit_Test_Case {
 		$this->assertSame( SignupService::ERROR_INVALID_EMAIL, $data->get_error_code() );
 	}

+	/**
+	 * @testdox parse() should reject a product the requester cannot view.
+	 */
+	public function test_parse_rejects_product_the_guest_cannot_view(): void {
+		$product = $this->create_out_of_stock_product();
+		$product->set_status( ProductStatus::DRAFT );
+		$product->save();
+
+		$data = $this->sut->parse(
+			array(
+				'wc_bis_product_id' => $product->get_id(),
+				'wc_bis_email'      => 'guest@example.com',
+			)
+		);
+
+		$this->assertInstanceOf( \WP_Error::class, $data );
+		$this->assertSame( SignupService::ERROR_INVALID_PRODUCT, $data->get_error_code() );
+	}
+
+	/**
+	 * @testdox A user who can edit an unpublished product should still be able to sign up for it.
+	 */
+	public function test_signup_accepts_unpublished_product_for_user_who_can_edit_it(): void {
+		$product = $this->create_out_of_stock_product();
+		$product->set_status( ProductStatus::DRAFT );
+		$product->save();
+
+		$user_id = $this->factory()->user->create( array( 'role' => 'shop_manager' ) );
+		\wp_set_current_user( $user_id );
+
+		$data = $this->sut->parse( array( 'wc_bis_product_id' => $product->get_id() ) );
+		$this->assertIsArray( $data );
+
+		$result = $this->sut->signup( $data['product_id'], $data['user_id'], $data['user_email'] );
+		$this->assertSame( SignupService::SIGNUP_SUCCESS, $result->get_code() );
+	}
+
 	/**
 	 * @testdox parse() should reject a posted variation attribute value the store does not offer.
 	 */