Merge pull request #680 from woocommerce/pcp-579-email-validation

Fix form decoding and email handling
This commit is contained in:
Emili Castells 2022-06-14 11:15:53 +02:00 committed by GitHub
commit e9e49fb8f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 14 deletions

View file

@ -15,6 +15,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerName;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerTaxInfo;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Phone;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PhoneWithType;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class PayerFactory
@ -158,6 +159,7 @@ class PayerFactory {
*
* @param array $form_fields The checkout form fields.
* @return Payer
* @throws RuntimeException When invalid data.
*/
public function from_checkout_form( array $form_fields ): Payer {
@ -189,6 +191,14 @@ class PayerFactory {
}
}
if ( ! is_email( $billing_email ) ) {
/*
phpcs:disable WordPress.WP.I18n.TextDomainMismatch
translators: %s: email address
*/
throw new RuntimeException( sprintf( __( '%s is not a valid email address.', 'woocommerce' ), esc_html( $billing_email ) ) );
}
return new Payer(
new PayerName( $first_name, $last_name ),
$billing_email,

View file

@ -20,7 +20,9 @@ class CheckoutActionHandler {
const errorHandler = this.errorHandler;
const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';
const formValues = jQuery(formSelector).serialize();
const formData = new FormData(document.querySelector(formSelector));
// will not handle fields with multiple values (checkboxes, <select multiple>), but we do not care about this here
const formJsonObj = Object.fromEntries(formData);
const createaccount = jQuery('#createaccount').is(":checked") ? true : false;
@ -34,7 +36,7 @@ class CheckoutActionHandler {
order_id:this.config.order_id,
payment_method: getCurrentPaymentMethod(),
funding_source: window.ppcpFundingSource,
form:formValues,
form: formJsonObj,
createaccount: createaccount
})
}).then(function (res) {
@ -59,7 +61,7 @@ class CheckoutActionHandler {
}
}
return;
throw new Error(data.data.message);
}
const input = document.createElement('input');
input.setAttribute('type', 'hidden');

View file

@ -403,9 +403,9 @@ class CreateOrderEndpoint implements EndpointInterface {
}
if ( ! $payer && isset( $data['form'] ) ) {
parse_str( $data['form'], $form_fields );
$form_fields = $data['form'];
if ( isset( $form_fields['billing_email'] ) && '' !== $form_fields['billing_email'] ) {
if ( is_array( $form_fields ) && isset( $form_fields['billing_email'] ) && '' !== $form_fields['billing_email'] ) {
return $this->payer_factory->from_checkout_form( $form_fields );
}
}

View file

@ -81,15 +81,9 @@ class RequestData {
$data = array();
foreach ( (array) $assoc_array as $raw_key => $raw_value ) {
if ( ! is_array( $raw_value ) ) {
/**
* The 'form' key is preserved for url encoded data and needs different
* sanitization.
*/
if ( 'form' !== $raw_key ) {
// Not sure if it is a good idea to sanitize everything at this level,
// but should be fine for now since we do not send any HTML or multi-line texts via ajax.
$data[ sanitize_text_field( (string) $raw_key ) ] = sanitize_text_field( (string) $raw_value );
} else {
$data[ sanitize_text_field( (string) $raw_key ) ] = sanitize_text_field( urldecode( (string) $raw_value ) );
}
continue;
}
$data[ sanitize_text_field( (string) $raw_key ) ] = $this->sanitize( $raw_value );