PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.6
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.6
3.4.6 3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 All 199 releases
← All changes | includes/class-convertkit-output-restrict-content.php +452 -312 3.3.6 → 3.4.6 View file →
@@ -98,8 +98,17 @@
98 98 */
99 99 public $token = false;
100 100
101 101 /**
102 + * Whether the login modal has been output.
103 + *
104 + * @since 3.4.2
105 + *
106 + * @var bool
107 + */
108 + public $login_modal_output = false;
109 +
110 + /**
102 111 * Constructor. Registers actions and filters to possibly limit output of a Page/Post/CPT's
103 112 * content on the frontend site.
104 113 *
105 114 * @since 2.1.0
@@ -108,8 +117,9 @@
108 117
109 118 add_action( 'rest_api_init', array( $this, 'register_routes' ) );
110 119 add_action( 'init', array( $this, 'initialize_classes' ), 2 );
111 120 add_action( 'init', array( $this, 'maybe_run_subscriber_authentication' ), 3 );
121 + add_action( 'wp', array( $this, 'maybe_run_subscriber_logout' ), 3 );
112 122 add_action( 'wp', array( $this, 'maybe_run_subscriber_verification' ), 4 );
113 123 add_action( 'wp', array( $this, 'register_content_filter' ), 5 );
114 124 add_filter( 'get_previous_post_where', array( $this, 'maybe_change_previous_post_where_clause' ), 10, 5 );
115 125 add_filter( 'get_next_post_where', array( $this, 'maybe_change_next_post_where_clause' ), 10, 5 );
@@ -154,11 +164,12 @@
154 164 },
155 165 'sanitize_callback' => 'absint',
156 166 ),
157 167
158 - // Resource Type: Validate resource type is included in the request and is a string.
168 + // Resource Type: Validate resource type is a string, if included in the request.
169 + // It's not included when logging in using the Member Content Login block.
159 170 'convertkit_resource_type' => array(
160 - 'required' => true,
171 + 'required' => false,
161 172 'validate_callback' => function ( $param ) {
162 173
163 174 return is_string( $param );
164 175
@@ -165,11 +176,12 @@
165 176 },
166 177 'sanitize_callback' => 'sanitize_text_field',
167 178 ),
168 179
169 - // Resource ID: Validate resource ID is included in the request and is an integer.
180 + // Resource ID: Validate resource ID is an integer, if included in the request.
181 + // It's not included when logging in using the Member Content Login block.
170 182 'convertkit_resource_id' => array(
171 - 'required' => true,
183 + 'required' => false,
172 184 'validate_callback' => function ( $param ) {
173 185
174 186 return is_numeric( $param );
175 187
@@ -175,8 +187,32 @@
175 187
176 188 },
177 189 'sanitize_callback' => 'absint',
178 190 ),
191 +
192 + // Spam protection response, if a spam protection provider is enabled.
193 + 'spam_protection_response' => array(
194 + 'required' => false,
195 + 'validate_callback' => function ( $param ) {
196 +
197 + return is_string( $param );
198 +
199 + },
200 + 'sanitize_callback' => 'sanitize_text_field',
201 + ),
202 +
203 + // Whether to display the heading above the login form.
204 + // It's not displayed by the Member Content Login block, as it refers to
205 + // reading the Member Content the subscriber is logging in to view.
206 + 'display_heading' => array(
207 + 'required' => false,
208 + 'default' => true,
209 + 'validate_callback' => function ( $param ) {
210 +
211 + return is_bool( $param );
212 +
213 + },
214 + ),
179 215 ),
180 216 'callback' => function ( $request ) {
181 217
182 218 // Initialize classes that will be used.
@@ -188,8 +224,26 @@
188 224 $post_id = $request->get_param( 'convertkit_post_id' );
189 225 $resource_type = $request->get_param( 'convertkit_resource_type' );
190 226 $resource_id = $request->get_param( 'convertkit_resource_id' );
191 227
228 + // Check spam protection (reCAPTCHA or Cloudflare Turnstile, depending on Plugin settings).
229 + $result = $output_restrict_content->verify_spam_protection( $request->get_param( 'spam_protection_response' ) );
230 +
231 + // If spam protection failed, build the email form view with the error message.
232 + if ( is_wp_error( $result ) ) {
233 + $output_restrict_content->error = $result;
234 +
235 + ob_start();
236 + include CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/' . ( $request->get_param( 'display_heading' ) ? 'login-modal-content-email.php' : 'login-email.php' );
237 + $output = trim( ob_get_clean() );
238 + return rest_ensure_response(
239 + array(
240 + 'success' => false,
241 + 'data' => $output,
242 + )
243 + );
244 + }
245 +
192 246 // Run subscriber authentication.
193 247 $result = $output_restrict_content->subscriber_authentication_send_code(
194 248 $email,
195 249 $post_id
@@ -201,9 +255,9 @@
201 255 $output_restrict_content->error = $result;
202 256
203 257 // Build email form view to return for output with error message.
204 258 ob_start();
205 - include CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/login-modal-content-email.php';
259 + include CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/' . ( $request->get_param( 'display_heading' ) ? 'login-modal-content-email.php' : 'login-email.php' );
206 260 $output = trim( ob_get_clean() );
207 261 return rest_ensure_response(
208 262 array(
209 263 'success' => false,
@@ -364,18 +418,12 @@
364 418 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'convertkit_restrict_content_login' ) ) {
365 419 return;
366 420 }
367 421
368 - // Bail if the expected email, resource type, resource ID or Post ID are missing from the request.
422 + // Bail if the expected email or Post ID are missing from the request.
369 423 if ( ! array_key_exists( 'convertkit_email', $_REQUEST ) ) {
370 424 return;
371 425 }
372 - if ( ! array_key_exists( 'convertkit_resource_type', $_REQUEST ) ) {
373 - return;
374 - }
375 - if ( ! array_key_exists( 'convertkit_resource_id', $_REQUEST ) ) {
376 - return;
377 - }
378 426 if ( ! array_key_exists( 'convertkit_post_id', $_REQUEST ) ) {
379 427 return;
380 428 }
381 429
@@ -385,24 +433,21 @@
385 433 }
386 434
387 435 // Sanitize inputs.
388 436 $email = sanitize_text_field( wp_unslash( $_REQUEST['convertkit_email'] ) );
389 - $this->resource_type = sanitize_text_field( wp_unslash( $_REQUEST['convertkit_resource_type'] ) );
390 - $this->resource_id = absint( $_REQUEST['convertkit_resource_id'] );
437 + $this->resource_type = ( array_key_exists( 'convertkit_resource_type', $_REQUEST ) ? sanitize_text_field( wp_unslash( $_REQUEST['convertkit_resource_type'] ) ) : '' );
438 + $this->resource_id = ( array_key_exists( 'convertkit_resource_id', $_REQUEST ) ? absint( $_REQUEST['convertkit_resource_id'] ) : 0 );
391 439 $this->post_id = absint( $_REQUEST['convertkit_post_id'] );
392 440
393 441 // If Restrict Content is by tag, tag the subscriber.
394 442 if ( $this->resource_type === 'tag' ) {
395 - // Check reCAPTCHA.
396 - $recaptcha = new ConvertKit_Recaptcha();
397 - $recaptcha_response = $recaptcha->verify_recaptcha(
398 - ( isset( $_POST['g-recaptcha-response'] ) ? sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ) : '' ),
399 - 'convertkit_restrict_content_tag'
400 - );
443 + // Check spam protection (reCAPTCHA or Cloudflare Turnstile, depending on Plugin settings).
444 + $spam_protection = new ConvertKit_Spam_Protection();
445 + $spam_check = $spam_protection->verify( 'convertkit_restrict_content_tag' );
401 446
402 - // Bail if reCAPTCHA failed.
403 - if ( is_wp_error( $recaptcha_response ) ) {
404 - $this->error = $recaptcha_response;
447 + // Bail if spam protection failed.
448 + if ( is_wp_error( $spam_check ) ) {
449 + $this->error = $spam_check;
405 450 return;
406 451 }
407 452
408 453 // Tag subscriber.
@@ -412,8 +457,17 @@
412 457 if ( is_wp_error( $result ) ) {
413 458 $this->error = $result;
414 459 return;
415 460 }
461 + } else {
462 + // Check spam protection (reCAPTCHA or Cloudflare Turnstile, depending on Plugin settings).
463 + $spam_check = $this->verify_spam_protection();
464 +
465 + // Bail if spam protection failed.
466 + if ( is_wp_error( $spam_check ) ) {
467 + $this->error = $spam_check;
468 + return;
469 + }
416 470 }
417 471
418 472 // Run subscriber authentication.
419 473 $result = $this->subscriber_authentication_send_code( $email, $this->post_id );
@@ -490,8 +544,140 @@
490 544
491 545 }
492 546
493 547 /**
548 + * Logs the subscriber out by deleting their subscriber ID cookie, when the
549 + * log out button is clicked in the Member Content Login block.
550 + *
551 + * @since 3.4.2
552 + */
553 + public function maybe_run_subscriber_logout() {
554 +
555 + // Bail if no logout request was made.
556 + if ( ! array_key_exists( 'convertkit_logout', $_REQUEST ) ) {
557 + return;
558 + }
559 +
560 + // Bail if no nonce was specified.
561 + if ( ! array_key_exists( '_wpnonce', $_REQUEST ) ) {
562 + return;
563 + }
564 +
565 + // Bail if the nonce failed validation.
566 + if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'convertkit_member_content_logout' ) ) {
567 + return;
568 + }
569 +
570 + // Delete the subscriber ID cookie.
571 + $subscriber = new ConvertKit_Subscriber();
572 + $subscriber->forget();
573 +
574 + // Reload the Post, so the login form displays.
575 + wp_safe_redirect( $this->get_url( get_the_ID(), true ) );
576 + exit();
577 +
578 + }
579 +
580 + /**
581 + * Verifies the spam protection response for the login form, using the spam
582 + * protection provider enabled in the Plugin's settings.
583 + *
584 + * @since 3.4.2
585 + *
586 + * @param bool|string $response Spam protection response, if supplied by a REST API request.
587 + * @return bool|WP_Error
588 + */
589 + public function verify_spam_protection( $response = false ) {
590 +
591 + $spam_protection = new ConvertKit_Spam_Protection();
592 + $provider = $spam_protection->get_active_provider();
593 +
594 + // Return true if no spam protection provider is enabled.
595 + if ( $provider === false ) {
596 + return true;
597 + }
598 +
599 + // Verify the response included in the REST API request.
600 + if ( ! empty( $response ) ) {
601 + return $provider->verify( $response, 'convertkit_member_content_login' );
602 + }
603 +
604 + // Verify the response included in the form submission.
605 + return $spam_protection->verify( 'convertkit_member_content_login' );
606 +
607 + }
608 +
609 + /**
610 + * Enqueues the CSS and JS required by the login form and modal.
611 + *
612 + * @since 3.4.2
613 + */
614 + public function enqueue_scripts_and_styles() {
615 +
616 + // Only load styles if the Disable CSS option is off.
617 + if ( ! $this->settings->css_disabled() ) {
618 + convertkit_enqueue_frontend_css();
619 + }
620 +
621 + // Bail if scripts are disabled.
622 + if ( $this->settings->scripts_disabled() ) {
623 + return;
624 + }
625 +
626 + // Enqueue scripts.
627 + convertkit_enqueue_frontend_js();
628 +
629 + // Define variables.
630 + wp_localize_script(
631 + 'convertkit-js',
632 + 'convertkit_restrict_content',
633 + array(
634 + 'nonce' => wp_create_nonce( 'wp_rest' ),
635 + 'subscriber_authentication_url' => rest_url( 'kit/v1/restrict-content/subscriber-authentication' ),
636 + 'subscriber_verification_url' => rest_url( 'kit/v1/restrict-content/subscriber-verification' ),
637 + 'debug' => $this->settings->debug_enabled(),
638 + )
639 + );
640 +
641 + // Enqueue the active spam protection provider's client-side script, used by the login form.
642 + $spam_protection = new ConvertKit_Spam_Protection();
643 + $spam_provider = $spam_protection->get_active_provider();
644 + if ( $spam_provider !== false ) {
645 + $spam_provider->enqueue_scripts();
646 + }
647 +
648 + }
649 +
650 + /**
651 + * Outputs the login modal in the footer, ensuring it is only output once
652 + * when a Post contains multiple Member Content Login blocks.
653 + *
654 + * @since 3.4.2
655 + *
656 + * @param int $post_id Post ID.
657 + * @param bool|int $resource_id Resource ID.
658 + * @param bool|string $resource_type Resource Type.
659 + */
660 + public function output_login_modal( $post_id, $resource_id = 0, $resource_type = '' ) {
661 +
662 + if ( $this->login_modal_output ) {
663 + return;
664 + }
665 +
666 + $this->login_modal_output = true;
667 +
668 + add_action(
669 + 'wp_footer',
670 + function () use ( $post_id, $resource_id, $resource_type ) {
671 +
672 + include_once CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/login-modal.php';
673 +
674 + }
675 + );
676 +
677 + }
678 +
679 + /**
494 680 * Sends an email to the subscriber with a code and link to authenticate they have access to the email address submitted.
495 681 *
496 682 * @since 3.1.0
497 683 *
@@ -1347,32 +1533,11 @@
1347 1533 * @return string HTML
1348 1534 */
1349 1535 private function get_call_to_action( $post_id ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
1350 1536
1351 - // Only load styles if the Disable CSS option is off.
1352 - if ( ! $this->settings->css_disabled() ) {
1353 - // Enqueue styles.
1354 - convertkit_enqueue_frontend_css();
1355 - }
1537 + // Enqueue CSS and JS.
1538 + $this->enqueue_scripts_and_styles();
1356 1539
1357 - // Only load scripts if the Disable Scripts option is off.
1358 - if ( ! $this->settings->scripts_disabled() ) {
1359 - // Enqueue scripts.
1360 - convertkit_enqueue_frontend_js();
1361 -
1362 - // Define variables.
1363 - wp_localize_script(
1364 - 'convertkit-js',
1365 - 'convertkit_restrict_content',
1366 - array(
1367 - 'nonce' => wp_create_nonce( 'wp_rest' ),
1368 - 'subscriber_authentication_url' => rest_url( 'kit/v1/restrict-content/subscriber-authentication' ),
1369 - 'subscriber_verification_url' => rest_url( 'kit/v1/restrict-content/subscriber-verification' ),
1370 - 'debug' => $this->settings->debug_enabled(),
1371 - )
1372 - );
1373 - }
1374 -
1375 1540 // Output code form if this request is after the user entered their email address,
1376 1541 // which means we're going through the authentication flow.
1377 1542 if ( $this->in_authentication_flow() ) {
1378 1543 ob_start();
@@ -1405,16 +1570,9 @@
1405 1570
1406 1571 // If scripts are enabled, output the email login form in a modal, which will be displayed
1407 1572 // when the 'log in' link is clicked.
1408 1573 if ( ! $this->settings->scripts_disabled() ) {
1409 - add_action(
1410 - 'wp_footer',
1411 - function () use ( $post_id, $resource_id, $resource_type ) {
1412 -
1413 - include_once CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/login-modal.php';
1414 -
1415 - }
1416 - );
1574 + $this->output_login_modal( $post_id, $resource_id, $resource_type );
1417 1575 }
1418 1576
1419 1577 // Output.
1420 1578 ob_start();
@@ -1435,16 +1593,9 @@
1435 1593
1436 1594 // If scripts are enabled, output the email login form in a modal, which will be displayed
1437 1595 // when the 'log in' link is clicked.
1438 1596 if ( ! $this->settings->scripts_disabled() ) {
1439 - add_action(
1440 - 'wp_footer',
1441 - function () use ( $post_id, $resource_id, $resource_type ) {
1442 -
1443 - include_once CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/login-modal.php';
1444 -
1445 - }
1446 - );
1597 + $this->output_login_modal( $post_id, $resource_id, $resource_type );
1447 1598 }
1448 1599
1449 1600 // Output.
1450 1601 ob_start();
@@ -1458,22 +1609,11 @@
1458 1609
1459 1610 // If scripts are enabled, output the email login form in a modal, which will be displayed
1460 1611 // when the 'log in' link is clicked.
1461 1612 if ( ! $this->settings->scripts_disabled() ) {
1462 - add_action(
1463 - 'wp_footer',
1464 - function () use ( $post_id, $resource_id, $resource_type ) {
1465 -
1466 - include_once CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/login-modal.php';
1467 -
1468 - }
1469 - );
1613 + $this->output_login_modal( $post_id, $resource_id, $resource_type );
1470 1614 }
1471 1615
1472 - // Enqueue Google reCAPTCHA JS.
1473 - $recaptcha = new ConvertKit_Recaptcha();
1474 - $recaptcha->enqueue_scripts();
1475 -
1476 1616 // Output.
1477 1617 ob_start();
1478 1618 include CONVERTKIT_PLUGIN_PATH . '/views/frontend/restrict-content/tag.php';
1479 1619 return trim( ob_get_clean() );
@@ -1681,246 +1821,246 @@
1681 1821
1682 1822 // DuckDuckGo.
1683 1823 // https://duckduckgo.com/duckduckgo-help-pages/results/duckduckbot.
1684 1824 'DuckDuckBot' => array(
1685 - '57.152.72.128',
1686 - '51.8.253.152',
1687 - '40.80.242.63',
1688 - '20.12.141.99',
1689 - '20.49.136.28',
1690 - '51.116.131.221',
1691 - '51.107.40.209',
1692 - '20.40.133.240',
1693 - '20.50.168.91',
1694 - '51.120.48.122',
1695 - '20.193.45.113',
1696 - '40.76.173.151',
1697 - '40.76.163.7',
1698 - '20.185.79.47',
1699 - '52.142.26.175',
1700 - '20.185.79.15',
1701 - '52.142.24.149',
1702 - '40.76.162.208',
1703 - '40.76.163.23',
1704 - '40.76.162.191',
1705 - '40.76.162.247',
1706 - '40.88.21.235',
1707 - '20.191.45.212',
1708 - '52.146.59.12',
1709 - '52.146.59.156',
1710 - '52.146.59.154',
1711 - '52.146.58.236',
1712 - '20.62.224.44',
1713 - '51.104.180.53',
1714 - '51.104.180.47',
1715 - '51.104.180.26',
1716 - '51.104.146.225',
1717 - '51.104.146.235',
1718 - '20.73.202.147',
1719 - '20.73.132.240',
1720 - '20.71.12.143',
1721 - '20.56.197.58',
1722 - '20.56.197.63',
1723 - '20.43.150.93',
1724 - '20.43.150.85',
1725 - '20.44.222.1',
1726 - '40.89.243.175',
1727 - '13.89.106.77',
1728 - '52.143.242.6',
1729 - '52.143.241.111',
1730 - '52.154.60.82',
1731 - '20.197.209.11',
1732 - '20.197.209.27',
1733 - '20.226.133.105',
1734 - '191.234.216.4',
1735 - '191.234.216.178',
1736 - '20.53.92.211',
1737 - '20.53.91.2',
1738 - '20.207.99.197',
1739 - '20.207.97.190',
1740 - '40.81.250.205',
1741 - '40.64.106.11',
1742 - '40.64.105.247',
1743 - '20.72.242.93',
1744 - '20.99.255.235',
1745 - '20.113.3.121',
1746 - '52.224.16.221',
1747 - '52.224.21.53',
1748 - '52.224.20.204',
1749 - '52.224.21.19',
1750 - '52.224.20.249',
1751 - '52.224.20.203',
1752 - '52.224.20.190',
1753 - '52.224.16.229',
1754 - '52.224.21.20',
1755 - '52.146.63.80',
1756 - '52.224.20.227',
1757 - '52.224.20.193',
1758 - '52.190.37.160',
1759 - '52.224.21.23',
1760 - '52.224.20.223',
1761 - '52.224.20.181',
1762 - '52.224.21.49',
1763 - '52.224.21.55',
1764 - '52.224.21.61',
1765 - '52.224.19.152',
1766 - '52.224.20.186',
1767 - '52.224.21.27',
1768 - '52.224.21.51',
1769 - '52.224.20.174',
1770 - '52.224.21.4',
1771 - '51.104.164.109',
1772 - '51.104.167.71',
1773 - '51.104.160.177',
1774 - '51.104.162.149',
1775 - '51.104.167.95',
1776 - '51.104.167.54',
1777 - '51.104.166.111',
1778 - '51.104.167.88',
1779 - '51.104.161.32',
1780 - '51.104.163.250',
1781 - '51.104.164.189',
1782 - '51.104.167.19',
1783 - '51.104.160.167',
1784 - '51.104.167.110',
1785 - '20.191.44.119',
1786 - '51.104.167.104',
1787 - '20.191.44.234',
1788 - '51.104.164.215',
1789 - '51.104.167.52',
1790 - '20.191.44.22',
1791 - '51.104.167.87',
1792 - '51.104.167.96',
1793 - '20.191.44.16',
1794 - '51.104.167.61',
1795 - '51.104.164.147',
1796 - '20.50.48.159',
1797 - '40.114.182.172',
1798 - '20.50.50.130',
1799 - '20.50.50.163',
1800 - '20.50.50.46',
1801 - '40.114.182.153',
1802 - '20.50.50.118',
1803 - '20.50.49.55',
1804 - '20.50.49.25',
1805 - '40.114.183.251',
1806 - '20.50.50.123',
1807 - '20.50.49.237',
1808 - '20.50.48.192',
1809 - '20.50.50.134',
1810 - '51.138.90.233',
1811 - '40.114.183.196',
1812 - '20.50.50.146',
1813 - '40.114.183.88',
1814 - '20.50.50.145',
1815 - '20.50.50.121',
1816 - '20.50.49.40',
1817 - '51.138.90.206',
1818 - '40.114.182.45',
1819 - '51.138.90.161',
1820 - '20.50.49.0',
1821 - '40.119.232.215',
1822 - '104.43.55.167',
1823 - '40.119.232.251',
1824 - '40.119.232.50',
1825 - '40.119.232.146',
1826 - '40.119.232.218',
1827 - '104.43.54.127',
1828 - '104.43.55.117',
1829 - '104.43.55.116',
1830 - '104.43.55.166',
1831 - '52.154.169.50',
1832 - '52.154.171.70',
1833 - '52.154.170.229',
1834 - '52.154.170.113',
1835 - '52.154.171.44',
1836 - '52.154.172.2',
1837 - '52.143.244.81',
1838 - '52.154.171.87',
1839 - '52.154.171.250',
1840 - '52.154.170.28',
1841 - '52.154.170.122',
1842 - '52.143.243.117',
1843 - '52.143.247.235',
1844 - '52.154.171.235',
1845 - '52.154.171.196',
1846 - '52.154.171.0',
1847 - '52.154.170.243',
1848 - '52.154.170.26',
1849 - '52.154.169.200',
1850 - '52.154.170.96',
1851 - '52.154.170.88',
1852 - '52.154.171.150',
1853 - '52.154.171.205',
1854 - '52.154.170.117',
1855 - '52.154.170.209',
1856 - '191.235.202.48',
1857 - '191.233.3.202',
1858 - '191.235.201.214',
1859 - '191.233.3.197',
1860 - '191.235.202.38',
1861 - '20.53.78.144',
1862 - '20.193.24.10',
1863 - '20.53.78.236',
1864 - '20.53.78.138',
1865 - '20.53.78.123',
1866 - '20.53.78.106',
1867 - '20.193.27.215',
1868 - '20.193.25.197',
1869 - '20.193.12.126',
1870 - '20.193.24.251',
1871 - '20.204.242.101',
1872 - '20.207.72.113',
1873 - '20.204.242.19',
1874 - '20.219.45.67',
1875 - '20.207.72.11',
1876 - '20.219.45.190',
1877 - '20.204.243.55',
1878 - '20.204.241.148',
1879 - '20.207.72.110',
1880 - '20.204.240.172',
1881 - '20.207.72.21',
1882 - '20.204.246.81',
1883 - '20.207.107.181',
1884 - '20.204.246.254',
1885 - '20.219.43.246',
1886 - '52.149.25.43',
1887 - '52.149.61.51',
1888 - '52.149.58.139',
1889 - '52.149.60.38',
1890 - '52.148.165.38',
1891 - '52.143.95.162',
1892 - '52.149.56.151',
1893 - '52.149.30.45',
1894 - '52.149.58.173',
1895 - '52.143.95.204',
1896 - '52.149.28.83',
1897 - '52.149.58.69',
1898 - '52.148.161.87',
1899 - '52.149.58.27',
1900 - '52.149.28.18',
1901 - '20.79.226.26',
1902 - '20.79.239.66',
1903 - '20.79.238.198',
1904 - '20.113.14.159',
1905 - '20.75.144.152',
1906 - '20.43.172.120',
1907 - '20.53.134.160',
1908 - '20.201.15.208',
1909 - '20.93.28.24',
1910 - '20.61.34.40',
1911 - '52.242.224.168',
1912 - '20.80.129.80',
1913 - '20.195.108.47',
1914 - '4.195.133.120',
1915 - '4.228.76.163',
1916 - '4.182.131.108',
1917 - '4.209.224.56',
1918 - '108.141.83.74',
1919 - '4.213.46.14',
1920 - '172.169.17.165',
1921 - '51.8.71.117',
1922 - '20.3.1.178',
1825 + '57.152.72.128/32',
1826 + '51.8.253.152/32',
1827 + '40.80.242.63/32',
1828 + '20.12.141.99/32',
1829 + '20.49.136.28/32',
1830 + '51.116.131.221/32',
1831 + '51.107.40.209/32',
1832 + '20.40.133.240/32',
1833 + '20.50.168.91/32',
1834 + '51.120.48.122/32',
1835 + '20.193.45.113/32',
1836 + '40.76.173.151/32',
1837 + '40.76.163.7/32',
1838 + '20.185.79.47/32',
1839 + '52.142.26.175/32',
1840 + '20.185.79.15/32',
1841 + '52.142.24.149/32',
1842 + '40.76.162.208/32',
1843 + '40.76.163.23/32',
1844 + '40.76.162.191/32',
1845 + '40.76.162.247/32',
1846 + '40.88.21.235/32',
1847 + '20.191.45.212/32',
1848 + '52.146.59.12/32',
1849 + '52.146.59.156/32',
1850 + '52.146.59.154/32',
1851 + '52.146.58.236/32',
1852 + '20.62.224.44/32',
1853 + '51.104.180.53/32',
1854 + '51.104.180.47/32',
1855 + '51.104.180.26/32',
1856 + '51.104.146.225/32',
1857 + '51.104.146.235/32',
1858 + '20.73.202.147/32',
1859 + '20.73.132.240/32',
1860 + '20.71.12.143/32',
1861 + '20.56.197.58/32',
1862 + '20.56.197.63/32',
1863 + '20.43.150.93/32',
1864 + '20.43.150.85/32',
1865 + '20.44.222.1/32',
1866 + '40.89.243.175/32',
1867 + '13.89.106.77/32',
1868 + '52.143.242.6/32',
1869 + '52.143.241.111/32',
1870 + '52.154.60.82/32',
1871 + '20.197.209.11/32',
1872 + '20.197.209.27/32',
1873 + '20.226.133.105/32',
1874 + '191.234.216.4/32',
1875 + '191.234.216.178/32',
1876 + '20.53.92.211/32',
1877 + '20.53.91.2/32',
1878 + '20.207.99.197/32',
1879 + '20.207.97.190/32',
1880 + '40.81.250.205/32',
1881 + '40.64.106.11/32',
1882 + '40.64.105.247/32',
1883 + '20.72.242.93/32',
1884 + '20.99.255.235/32',
1885 + '20.113.3.121/32',
1886 + '52.224.16.221/32',
1887 + '52.224.21.53/32',
1888 + '52.224.20.204/32',
1889 + '52.224.21.19/32',
1890 + '52.224.20.249/32',
1891 + '52.224.20.203/32',
1892 + '52.224.20.190/32',
1893 + '52.224.16.229/32',
1894 + '52.224.21.20/32',
1895 + '52.146.63.80/32',
1896 + '52.224.20.227/32',
1897 + '52.224.20.193/32',
1898 + '52.190.37.160/32',
1899 + '52.224.21.23/32',
1900 + '52.224.20.223/32',
1901 + '52.224.20.181/32',
1902 + '52.224.21.49/32',
1903 + '52.224.21.55/32',
1904 + '52.224.21.61/32',
1905 + '52.224.19.152/32',
1906 + '52.224.20.186/32',
1907 + '52.224.21.27/32',
1908 + '52.224.21.51/32',
1909 + '52.224.20.174/32',
1910 + '52.224.21.4/32',
1911 + '51.104.164.109/32',
1912 + '51.104.167.71/32',
1913 + '51.104.160.177/32',
1914 + '51.104.162.149/32',
1915 + '51.104.167.95/32',
1916 + '51.104.167.54/32',
1917 + '51.104.166.111/32',
1918 + '51.104.167.88/32',
1919 + '51.104.161.32/32',
1920 + '51.104.163.250/32',
1921 + '51.104.164.189/32',
1922 + '51.104.167.19/32',
1923 + '51.104.160.167/32',
1924 + '51.104.167.110/32',
1925 + '20.191.44.119/32',
1926 + '51.104.167.104/32',
1927 + '20.191.44.234/32',
1928 + '51.104.164.215/32',
1929 + '51.104.167.52/32',
1930 + '20.191.44.22/32',
1931 + '51.104.167.87/32',
1932 + '51.104.167.96/32',
1933 + '20.191.44.16/32',
1934 + '51.104.167.61/32',
1935 + '51.104.164.147/32',
1936 + '20.50.48.159/32',
1937 + '40.114.182.172/32',
1938 + '20.50.50.130/32',
1939 + '20.50.50.163/32',
1940 + '20.50.50.46/32',
1941 + '40.114.182.153/32',
1942 + '20.50.50.118/32',
1943 + '20.50.49.55/32',
1944 + '20.50.49.25/32',
1945 + '40.114.183.251/32',
1946 + '20.50.50.123/32',
1947 + '20.50.49.237/32',
1948 + '20.50.48.192/32',
1949 + '20.50.50.134/32',
1950 + '51.138.90.233/32',
1951 + '40.114.183.196/32',
1952 + '20.50.50.146/32',
1953 + '40.114.183.88/32',
1954 + '20.50.50.145/32',
1955 + '20.50.50.121/32',
1956 + '20.50.49.40/32',
1957 + '51.138.90.206/32',
1958 + '40.114.182.45/32',
1959 + '51.138.90.161/32',
1960 + '20.50.49.0/32',
1961 + '40.119.232.215/32',
1962 + '104.43.55.167/32',
1963 + '40.119.232.251/32',
1964 + '40.119.232.50/32',
1965 + '40.119.232.146/32',
1966 + '40.119.232.218/32',
1967 + '104.43.54.127/32',
1968 + '104.43.55.117/32',
1969 + '104.43.55.116/32',
1970 + '104.43.55.166/32',
1971 + '52.154.169.50/32',
1972 + '52.154.171.70/32',
1973 + '52.154.170.229/32',
1974 + '52.154.170.113/32',
1975 + '52.154.171.44/32',
1976 + '52.154.172.2/32',
1977 + '52.143.244.81/32',
1978 + '52.154.171.87/32',
1979 + '52.154.171.250/32',
1980 + '52.154.170.28/32',
1981 + '52.154.170.122/32',
1982 + '52.143.243.117/32',
1983 + '52.143.247.235/32',
1984 + '52.154.171.235/32',
1985 + '52.154.171.196/32',
1986 + '52.154.171.0/32',
1987 + '52.154.170.243/32',
1988 + '52.154.170.26/32',
1989 + '52.154.169.200/32',
1990 + '52.154.170.96/32',
1991 + '52.154.170.88/32',
1992 + '52.154.171.150/32',
1993 + '52.154.171.205/32',
1994 + '52.154.170.117/32',
1995 + '52.154.170.209/32',
1996 + '191.235.202.48/32',
1997 + '191.233.3.202/32',
1998 + '191.235.201.214/32',
1999 + '191.233.3.197/32',
2000 + '191.235.202.38/32',
2001 + '20.53.78.144/32',
2002 + '20.193.24.10/32',
2003 + '20.53.78.236/32',
2004 + '20.53.78.138/32',
2005 + '20.53.78.123/32',
2006 + '20.53.78.106/32',
2007 + '20.193.27.215/32',
2008 + '20.193.25.197/32',
2009 + '20.193.12.126/32',
2010 + '20.193.24.251/32',
2011 + '20.204.242.101/32',
2012 + '20.207.72.113/32',
2013 + '20.204.242.19/32',
2014 + '20.219.45.67/32',
2015 + '20.207.72.11/32',
2016 + '20.219.45.190/32',
2017 + '20.204.243.55/32',
2018 + '20.204.241.148/32',
2019 + '20.207.72.110/32',
2020 + '20.204.240.172/32',
2021 + '20.207.72.21/32',
2022 + '20.204.246.81/32',
2023 + '20.207.107.181/32',
2024 + '20.204.246.254/32',
2025 + '20.219.43.246/32',
2026 + '52.149.25.43/32',
2027 + '52.149.61.51/32',
2028 + '52.149.58.139/32',
2029 + '52.149.60.38/32',
2030 + '52.148.165.38/32',
2031 + '52.143.95.162/32',
2032 + '52.149.56.151/32',
2033 + '52.149.30.45/32',
2034 + '52.149.58.173/32',
2035 + '52.143.95.204/32',
2036 + '52.149.28.83/32',
2037 + '52.149.58.69/32',
2038 + '52.148.161.87/32',
2039 + '52.149.58.27/32',
2040 + '52.149.28.18/32',
2041 + '20.79.226.26/32',
2042 + '20.79.239.66/32',
2043 + '20.79.238.198/32',
2044 + '20.113.14.159/32',
2045 + '20.75.144.152/32',
2046 + '20.43.172.120/32',
2047 + '20.53.134.160/32',
2048 + '20.201.15.208/32',
2049 + '20.93.28.24/32',
2050 + '20.61.34.40/32',
2051 + '52.242.224.168/32',
2052 + '20.80.129.80/32',
2053 + '20.195.108.47/32',
2054 + '4.195.133.120/32',
2055 + '4.228.76.163/32',
2056 + '4.182.131.108/32',
2057 + '4.209.224.56/32',
2058 + '108.141.83.74/32',
2059 + '4.213.46.14/32',
2060 + '172.169.17.165/32',
2061 + '51.8.71.117/32',
2062 + '20.3.1.178/32',
1923 2063 ),
1924 2064
1925 2065 // OpenAI Search Bot.
1926 2066 // https://platform.openai.com/docs/bots/overview-of-openai-crawlers.