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
convertkit / includes / class-convertkit-recaptcha.php

class-convertkit-recaptcha.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.6, at includes/class-convertkit-recaptcha.php

194 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit reCAPTCHA class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Handles reCAPTCHA verification.
11 *
12 * @since 3.0.0
13 */
14 class ConvertKit_Recaptcha {
15
16 /**
17 * Holds the settings class.
18 *
19 * @since 3.0.0
20 *
21 * @var bool|ConvertKit_Settings
22 */
23 private $settings = false;
24
25 /**
26 * Constructor.
27 *
28 * @since 3.0.0
29 */
30 public function __construct() {
31
32 $this->settings = new ConvertKit_Settings();
33
34 }
35
36 /**
37 * Enqueues the reCAPTCHA scripts if reCAPTCHA site and secret keys are set,
38 * and scripts are enabled.
39 *
40 * @since 3.0.0
41 */
42 public function enqueue_scripts() {
43
44 // Don't run if the reCAPTCHA or scripts are disabled.
45 if ( ! $this->settings->has_recaptcha_site_and_secret_keys() || $this->settings->scripts_disabled() ) {
46 return;
47 }
48
49 // Enqueue Google reCAPTCHA JS.
50 add_filter(
51 'convertkit_output_scripts_footer',
52 function ( $scripts ) {
53
54 $scripts[] = array(
55 'src' => 'https://www.google.com/recaptcha/api.js?',
56 );
57
58 return $scripts;
59
60 }
61 );
62
63 }
64
65 /**
66 * Verifies the reCAPTCHA response, if reCAPTCHA site and secret keys are set,
67 * and scripts are enabled.
68 *
69 * @since 3.0.0
70 *
71 * @param string $recaptcha_response The reCAPTCHA response.
72 * @param string $plugin_action The action to verify the reCAPTCHA response for.
73 * @return bool|WP_Error
74 */
75 public function verify( $recaptcha_response, $plugin_action ) {
76
77 // Don't run if the reCAPTCHA or scripts are disabled.
78 if ( ! $this->settings->has_recaptcha_site_and_secret_keys() || $this->settings->scripts_disabled() ) {
79 return true;
80 }
81
82 // Check if the submission is spam.
83 $response = wp_remote_post(
84 'https://www.google.com/recaptcha/api/siteverify',
85 array(
86 'body' => array(
87 'secret' => $this->settings->recaptcha_secret_key(),
88 'response' => $recaptcha_response,
89 'remoteip' => ( isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '' ),
90 ),
91 )
92 );
93
94 // Bail if an error occurred.
95 if ( is_wp_error( $response ) ) {
96 return $response;
97 }
98
99 // Inspect response.
100 $body = json_decode( wp_remote_retrieve_body( $response ), true );
101
102 // If the response body couldn't be decoded, treat that as a failure.
103 if ( ! is_array( $body ) ) {
104 return new WP_Error(
105 'convertkit_recaptcha_failed',
106 __( 'Google reCAPTCHA failure: invalid response from siteverify.', 'convertkit' )
107 );
108 }
109
110 // If the request wasn't successful, return an error.
111 if ( empty( $body['success'] ) ) {
112 return new WP_Error(
113 'convertkit_recaptcha_failed',
114 sprintf(
115 /* translators: Error codes */
116 __( 'Google reCAPTCHA failure: %s', 'convertkit' ),
117 implode( ', ', isset( $body['error-codes'] ) ? (array) $body['error-codes'] : array() )
118 )
119 );
120 }
121
122 // If the action doesn't match the Plugin action, the token was generated for a different action.
123 // Treat this as a failure, so the minimum score check can't be bypassed.
124 if ( ! isset( $body['action'] ) || $body['action'] !== $plugin_action ) {
125 return new WP_Error(
126 'convertkit_recaptcha_failed',
127 __( 'Google reCAPTCHA failed', 'convertkit' )
128 );
129 }
130
131 // If the score is less than the required minimum score, it's likely a spam submission.
132 if ( ! isset( $body['score'] ) || $body['score'] < $this->settings->recaptcha_minimum_score() ) {
133 return new WP_Error(
134 'convertkit_recaptcha_failed',
135 __( 'Google reCAPTCHA failed', 'convertkit' )
136 );
137 }
138
139 // If here, the submission looks genuine. Continue the request.
140 return true;
141
142 }
143
144 /**
145 * Attaches the reCAPTCHA v3 invisible-badge attributes to the given submit
146 * button element within an existing DOM tree, so that the challenge is
147 * executed when the button is clicked and the form is submitted via the
148 * `convertKitRecaptchaFormSubmit` callback.
149 *
150 * @since 3.3.7
151 *
152 * @param ConvertKit_HTML_Parser $parser Parser wrapping the DOM (unused).
153 * @param DOMElement $button <button> element to attach attributes to.
154 * @param string $plugin_action Plugin action string.
155 */
156 public function attach_to_form_button_dom( $parser, $button, $plugin_action ) {
157
158 unset( $parser );
159
160 $button->setAttribute( 'data-sitekey', esc_attr( $this->settings->recaptcha_site_key() ) );
161 $button->setAttribute( 'data-callback', 'convertKitRecaptchaFormSubmit' );
162 $button->setAttribute( 'data-action', $plugin_action );
163 $button->setAttribute( 'class', trim( $button->getAttribute( 'class' ) . ' g-recaptcha' ) );
164
165 }
166
167 /**
168 * Returns the HTML for a submit button with reCAPTCHA v3 invisible-badge
169 * attributes attached, used by templates that don't have a DOM parser
170 * available (e.g. the Restrict Content tag view).
171 *
172 * @since 3.3.7
173 *
174 * @param string $label Button's visible label.
175 * @param string $plugin_action Plugin action string.
176 * @param string[] $css_classes CSS classes for the button.
177 * @return string
178 */
179 public function get_submit_button_html( $label, $plugin_action, $css_classes = array() ) {
180
181 $css_classes[] = 'g-recaptcha';
182
183 return sprintf(
184 '<input type="submit" class="%1$s" value="%2$s" data-sitekey="%3$s" data-callback="convertKitRecaptchaFormSubmit" data-action="%4$s" />',
185 esc_attr( implode( ' ', $css_classes ) ),
186 esc_attr( $label ),
187 esc_attr( $this->settings->recaptcha_site_key() ),
188 esc_attr( $plugin_action )
189 );
190
191 }
192
193 }
194