From 0cc34aea31496d4173119f08a610287ffba6f50f Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Wed, 15 Jul 2026 14:43:39 +0800 Subject: [PATCH] Remove Store Subscriber Email as ID --- includes/class-convertkit-output.php | 59 ------- includes/class-convertkit-subscriber.php | 50 ------ resources/frontend/js/convertkit.js | 114 ------------ .../SubscriberEmailToIDOnFormSubmitCest.php | 162 ------------------ .../RESTAPIRestrictContentTest.php | 29 ---- tests/Integration/RESTAPITest.php | 116 ------------- 6 files changed, 530 deletions(-) delete mode 100644 tests/EndToEnd/general/other/SubscriberEmailToIDOnFormSubmitCest.php diff --git a/includes/class-convertkit-output.php b/includes/class-convertkit-output.php index 93a830528..e1e2f8bc3 100644 --- a/includes/class-convertkit-output.php +++ b/includes/class-convertkit-output.php @@ -67,7 +67,6 @@ class ConvertKit_Output { */ public function __construct() { - add_action( 'rest_api_init', array( $this, 'register_routes' ) ); add_action( 'wp', array( $this, 'maybe_tag_subscriber' ) ); add_action( 'template_redirect', array( $this, 'output_form' ) ); add_action( 'template_redirect', array( $this, 'page_takeover' ) ); @@ -80,62 +79,6 @@ public function __construct() { } - /** - * Register REST API routes. - * - * @since 3.1.7 - */ - public function register_routes() { - - // Register route to store the Kit subscriber's email's ID in a cookie. - register_rest_route( - 'kit/v1', - '/subscriber/store-email-as-id-in-cookie', - array( - 'methods' => WP_REST_Server::CREATABLE, - 'args' => array( - // Email: Validate email is included in the request, a valid email address - // and sanitize the email address. - 'email' => array( - 'required' => true, - 'validate_callback' => function ( $param ) { - - return is_string( $param ) && is_email( $param ); - - }, - 'sanitize_callback' => 'sanitize_email', - ), - ), - 'callback' => function ( $request ) { - - // Get email address. - $email = $request->get_param( 'email' ); - - // Get subscriber ID. - $subscriber = new ConvertKit_Subscriber(); - $subscriber_id = $subscriber->validate_and_store_subscriber_email( $email ); - - // Bail if an error occurred i.e. API hasn't been configured. - if ( is_wp_error( $subscriber_id ) ) { - return rest_ensure_response( $subscriber_id ); - } - - // Return the subscriber ID. - return rest_ensure_response( - array( - 'id' => $subscriber_id, - ) - ); - - }, - - // No authentication required, as this is on the frontend site. - 'permission_callback' => '__return_true', - ) - ); - - } - /** * Tags the subscriber, if: * - a subscriber ID exists in the cookie or URL, @@ -820,9 +763,7 @@ public function enqueue_scripts() { 'convertkit-js', 'convertkit', array( - 'ajaxurl' => rest_url( 'kit/v1/subscriber/store-email-as-id-in-cookie' ), 'debug' => $settings->debug_enabled(), - 'nonce' => wp_create_nonce( 'wp_rest' ), 'subscriber_id' => $this->subscriber_id, ) ); diff --git a/includes/class-convertkit-subscriber.php b/includes/class-convertkit-subscriber.php index 5f851000f..34c47df99 100644 --- a/includes/class-convertkit-subscriber.php +++ b/includes/class-convertkit-subscriber.php @@ -50,56 +50,6 @@ public function get_subscriber_id() { } - /** - * Validates the given subscriber email by querying the API to confirm - * the subscriber exists before storing their ID in a cookie. - * - * @since 2.0.0 - * - * @param string $subscriber_email Possible Subscriber Email. - * @return WP_Error|int|string Error | Confirmed Subscriber ID or Signed Subscriber ID - */ - public function validate_and_store_subscriber_email( $subscriber_email ) { - - // Bail if the API hasn't been configured. - $settings = new ConvertKit_Settings(); - if ( ! $settings->has_access_and_refresh_token() ) { - return new WP_Error( - 'convertkit_subscriber_get_subscriber_id_from_request_error', - __( 'Access Token not configured in Plugin Settings.', 'convertkit' ) - ); - } - - // Initialize the API. - $api = new ConvertKit_API_V4( - CONVERTKIT_OAUTH_CLIENT_ID, - CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI, - $settings->get_access_token(), - $settings->get_refresh_token(), - $settings->debug_enabled(), - 'subscriber' - ); - - // Get subscriber by email, to ensure they exist. - $subscriber_id = $api->get_subscriber_id( $subscriber_email ); - - // Bail if no subscriber exists with the given subscriber ID, or an error occurred. - if ( is_wp_error( $subscriber_id ) ) { - // Delete the cookie. - $this->forget(); - - // Return error. - return $subscriber_id; - } - - // Store the subscriber ID as a cookie. - $this->set( $subscriber_id ); - - // Return subscriber ID. - return $subscriber_id; - - } - /** * Gets the subscriber ID from the `ck_subscriber_id` cookie. * diff --git a/resources/frontend/js/convertkit.js b/resources/frontend/js/convertkit.js index 48db9ecfe..669791f57 100644 --- a/resources/frontend/js/convertkit.js +++ b/resources/frontend/js/convertkit.js @@ -6,60 +6,6 @@ * @author ConvertKit */ -/** - * Gets the subscriber ID for the given email address, storing - * it in the `ck_subscriber_id` cookie if it exists. - * - * Typically called when the user completes a ConvertKit Form - * that has either "Auto-confirm new subscribers" or - * "Send subscriber to thank you page" enabled (both scenarios - * include a ck_subscriber_id). - * - * @since 1.9.6 - * - * @param {string} emailAddress Email Address - */ -function convertStoreSubscriberEmailAsIDInCookie(emailAddress) { - if (convertkit.debug) { - console.log('convertStoreSubscriberEmailAsIDInCookie'); - console.log(emailAddress); - } - - fetch(convertkit.ajaxurl, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-WP-Nonce': convertkit.nonce, - }, - body: new URLSearchParams({ - email: emailAddress, - }), - }) - .then(function (response) { - if (convertkit.debug) { - console.log(response); - } - - return response.json(); - }) - .then(function (result) { - if (convertkit.debug) { - console.log(result); - } - - // Emit custom event with subscriber ID. - convertKitEmitCustomEvent('convertkit_user_subscribed', { - id: result.id, - email: emailAddress, - }); - }) - .catch(function (error) { - if (convertkit.debug) { - console.error(error); - } - }); -} - /** * Remove the url subscriber_id url param * @@ -106,21 +52,6 @@ function convertKitRemoveSubscriberIDFromURL(url) { }); } -/** - * Utility function to pause for the given number of milliseconds - * - * @since 1.9.6 - * @param {number} milliseconds Number of milliseconds to pause for. - */ -function convertKitSleep(milliseconds) { - const start = new Date().getTime(); - for (let i = 0; i < 1e7; i++) { - if (new Date().getTime() - start > milliseconds) { - break; - } - } -} - /** * Emit a custom event with optional detail data. * @@ -171,51 +102,6 @@ if (typeof convertkit !== 'undefined') { // Removes `ck_subscriber_id` from the URI. convertKitRemoveSubscriberIDFromURL(window.location.href); - // Store subscriber ID as a cookie from the email address used when a ConvertKit Form is submitted. - document.addEventListener('click', function (e) { - // Check if the form submit button was clicked, or the span element was clicked and its parent is the form submit button. - if ( - !e.target.matches('.formkit-submit') && - (!e.target.parentElement || - !e.target.parentElement.matches('.formkit-submit')) - ) { - if (convertkit.debug) { - console.log('not a ck form'); - } - - return; - } - - // Get email address. - const emailAddress = document.querySelector( - 'input[name="email_address"]' - ).value; - - // If the email address is empty, don't attempt to get the subscriber ID by email. - if (!emailAddress.length) { - if (convertkit.debug) { - console.log('email empty'); - } - - return; - } - - // If the email address is invalid, don't attempt to get the subscriber ID by email. - const validator = - /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - if (!validator.test(emailAddress.toLowerCase())) { - if (convertkit.debug) { - console.log('email not an email address'); - } - - return; - } - - // Wait a moment before sending the AJAX request. - convertKitSleep(2000); - convertStoreSubscriberEmailAsIDInCookie(emailAddress); - }); - // Set a cookie if any scripts with data-kit-limit-per-session attribute exist. if ( document.querySelectorAll('script[data-kit-limit-per-session="1"]') diff --git a/tests/EndToEnd/general/other/SubscriberEmailToIDOnFormSubmitCest.php b/tests/EndToEnd/general/other/SubscriberEmailToIDOnFormSubmitCest.php deleted file mode 100644 index 74634add3..000000000 --- a/tests/EndToEnd/general/other/SubscriberEmailToIDOnFormSubmitCest.php +++ /dev/null @@ -1,162 +0,0 @@ -activateKitPlugin($I); - $I->setupKitPlugin($I); - $I->setupKitPluginResources($I); - } - - /** - * Test that no API call to the subscribers endpoint is made to fetch a subscriber ID - * by email address when a Kit Form is submitted with no email address. - * - * @since 1.9.6.7 - * - * @param EndToEndTester $I Tester. - */ - public function testWhenFormSubmittedWithNoEmailAddress(EndToEndTester $I) - { - // Create Page with Shortcode. - $I->havePageInDatabase( - [ - 'post_name' => 'kit-subscriber-email-to-id-no-email', - 'post_content' => 'No Email', - ] - ); - - // Load the Page on the frontend site. - $I->amOnPage('/kit-subscriber-email-to-id-no-email'); - $I->waitForElementVisible('body.page'); - - // Check that no PHP warnings or notices were output. - $I->checkNoWarningsAndNoticesOnScreen($I); - - // Submit Form. - $I->waitForElementVisible('.formkit-submit'); - $I->click('.formkit-submit'); - - // Wait for JS to complete. - $I->wait(2); - - // Check log does not contain get_subscriber_by_email() call with no email value. - $I->loadKitSettingsToolsScreen($I); - $I->dontSeeInSource('API: get_subscriber_by_email(): [ email: ]'); - } - - /** - * Test that no API call to the subscribers endpoint is made to fetch a subscriber ID - * by email address when a Kit Form is submitted with an invalid email address format. - * - * @since 1.9.6.7 - * - * @param EndToEndTester $I Tester. - */ - public function testWhenFormSubmittedWithInvalidEmailAddress(EndToEndTester $I) - { - // Create Page with Shortcode. - $I->havePageInDatabase( - [ - 'post_name' => 'kit-subscriber-email-to-id-invalid-email', - 'post_content' => 'Invalid Email', - ] - ); - - // Load the Page on the frontend site. - $I->amOnPage('/kit-subscriber-email-to-id-invalid-email'); - $I->waitForElementVisible('body.page'); - - // Check that no PHP warnings or notices were output. - $I->checkNoWarningsAndNoticesOnScreen($I); - - // Generate email address for this test. - $emailAddress = 'invalid-email'; - - // Submit Form. - $I->waitForElementVisible('input[name="email_address"]'); - $I->fillField('email_address', $emailAddress); - $I->click('.formkit-submit'); - - // Wait for JS to complete. - $I->wait(2); - - // Check log does not contain get_subscriber_by_email() call with no email value. - $I->loadKitSettingsToolsScreen($I); - $I->dontSeeInSource('API: get_subscriber_by_email(): [ email: ' . $emailAddress . ']'); - } - - /** - * Test that an API call to the subscribers endpoint is made to fetch a subscriber ID - * by email address when a Kit Form is submitted with a valid email address format. - * - * @since 1.9.6.7 - * - * @param EndToEndTester $I Tester. - */ - public function testWhenFormSubmittedWithValidEmailAddress(EndToEndTester $I) - { - // Create Page with Shortcode. - $I->havePageInDatabase( - [ - 'post_name' => 'kit-subscriber-email-to-id-valid-email', - 'post_content' => 'Valid Email', - ] - ); - - // Load the Page on the frontend site. - $I->amOnPage('/kit-subscriber-email-to-id-valid-email'); - $I->waitForElementVisible('body.page'); - - // Check that no PHP warnings or notices were output. - $I->checkNoWarningsAndNoticesOnScreen($I); - - // Generate email address for this test. - $emailAddress = $I->generateEmailAddress(); - - // Submit Form. - $I->waitForElementVisible('input[name="email_address"]'); - $I->fillField('email_address', $emailAddress); - $I->click('.formkit-submit'); - - // Wait for JS and AJAX request to complete. - $I->wait(5); - - // Check log contains get_subscriber_by_email() call with masked email value. - $I->loadKitSettingsToolsScreen($I); - $I->seeInSource('API: GET subscribers: {"email_address":"w********-2***'); - } - - /** - * Deactivate and reset Plugin(s) after each test, if the test passes. - * We don't use _after, as this would provide a screenshot of the Plugin - * deactivation and not the true test error. - * - * @since 1.9.6.7 - * - * @param EndToEndTester $I Tester. - */ - public function _passed(EndToEndTester $I) - { - $I->deactivateKitPlugin($I); - $I->resetKitPlugin($I); - } -} diff --git a/tests/Integration/RESTAPIRestrictContentTest.php b/tests/Integration/RESTAPIRestrictContentTest.php index 02cd7e5eb..b6873b6bc 100644 --- a/tests/Integration/RESTAPIRestrictContentTest.php +++ b/tests/Integration/RESTAPIRestrictContentTest.php @@ -277,33 +277,4 @@ public function testRestrictContentSubscriberAuthenticationProductInvalidEmail() $this->assertFalse( $data['success'] ); $this->assertArrayHasKey( 'data', $data ); } - - /** - * Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API route stores - * the subscriber ID in a cookie when a valid email address is given. - * - * @since 3.1.7 - */ - public function testStoreEmailAsIDInCookie() - { - // Build request. - $request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' ); - $request->set_header( 'Content-Type', 'application/json' ); - $request->set_body_params( - [ - 'email' => $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'], - ], - ); - - // Send request. - $response = rest_get_server()->dispatch( $request ); - - // Assert response is successful. - $this->assertSame( 200, $response->get_status() ); - - // Assert response data has the expected keys and data. - $data = $response->get_data(); - $this->assertIsArray( $data ); - $this->assertEquals( (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], (int) $data['id'] ); - } } diff --git a/tests/Integration/RESTAPITest.php b/tests/Integration/RESTAPITest.php index 22388667d..a9f59b534 100644 --- a/tests/Integration/RESTAPITest.php +++ b/tests/Integration/RESTAPITest.php @@ -311,122 +311,6 @@ public function testRefreshResourcesRestrictContent() $this->assertArrayHasKeys( $data['products'][0], [ 'id', 'name', 'url', 'published' ] ); } - /** - * Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API route stores - * the subscriber ID in a cookie when a valid email address is given. - * - * @since 3.1.7 - */ - public function testStoreEmailAsIDInCookie() - { - // Build request. - $request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' ); - $request->set_header( 'Content-Type', 'application/json' ); - $request->set_body_params( - [ - 'email' => $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'], - ], - ); - - // Send request. - $response = rest_get_server()->dispatch( $request ); - - // Assert response is successful. - $this->assertSame( 200, $response->get_status() ); - - // Assert response data has the expected keys and data. - $data = $response->get_data(); - $this->assertIsArray( $data ); - $this->assertEquals( (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], (int) $data['id'] ); - } - - /** - * Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns - * no subscriber ID when a non-subscriber email address is given. - * - * @since 3.1.7 - */ - public function testStoreEmailAsIDInCookieWithNonSubscriberEmail() - { - // Build request. - $request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' ); - $request->set_header( 'Content-Type', 'application/json' ); - $request->set_body_params( - [ - 'email' => 'fail@kit.com', - ], - ); - - // Send request. - $response = rest_get_server()->dispatch( $request ); - - // Assert response is successful. - $this->assertSame( 200, $response->get_status() ); - - // Assert response data has the expected keys and data. - $data = $response->get_data(); - $this->assertIsArray( $data ); - $this->assertEquals( 0, (int) $data['id'] ); - } - - /** - * Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns - * an error when no email address is given. - * - * @since 3.1.7 - */ - public function testStoreEmailAsIDInCookieWithNoEmail() - { - // Build request. - $request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' ); - $request->set_header( 'Content-Type', 'application/json' ); - $request->set_body_params( - [ - 'email' => '', - ], - ); - - // Send request. - $response = rest_get_server()->dispatch( $request ); - - // Assert response failed. - $this->assertSame( 400, $response->get_status() ); - - // Assert response data has the expected keys and data. - $data = $response->get_data(); - $this->assertEquals( 'rest_invalid_param', $data['code'] ); - $this->assertEquals( 'Invalid parameter(s): email', $data['message'] ); - } - - /** - * Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns - * an error when an invalid email address is given. - * - * @since 3.1.7 - */ - public function testStoreEmailAsIDInCookieWithInvalidEmail() - { - // Build request. - $request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' ); - $request->set_header( 'Content-Type', 'application/json' ); - $request->set_body_params( - [ - 'email' => 'not-an-email', - ], - ); - - // Send request. - $response = rest_get_server()->dispatch( $request ); - - // Assert response failed. - $this->assertSame( 400, $response->get_status() ); - - // Assert response data has the expected keys and data. - $data = $response->get_data(); - $this->assertEquals( 'rest_invalid_param', $data['code'] ); - $this->assertEquals( 'Invalid parameter(s): email', $data['message'] ); - } - /** * Act as an editor user. *