Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/mstore-api/controllers/flutter-2c2p.php
+++ b/mstore-api/controllers/flutter-2c2p.php
@@ -21,7 +21,7 @@
protected $namespace = 'api/flutter_2c2p';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-auction.php
+++ b/mstore-api/controllers/flutter-auction.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_auction';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
@@ -94,6 +94,15 @@
$product_id = sanitize_text_field($params['product_id']);
$bid_value = sanitize_text_field($params['bid_value']);
+ if (empty($product_id) || !is_numeric($product_id)) {
+ return parent::sendError("invalid_product", 'Product id is required', 400);
+ }
+
+ $product = wc_get_product($product_id);
+ if (!$product || 'trash' === get_post_status($product_id)) {
+ return parent::sendError("invalid_product", 'This product is no longer available.', 400);
+ }
+
WC()->session->set( 'wc_notices', null );
$bid = new WC_Bid();
$result = $bid->placebid($product_id, $bid_value);
--- a/mstore-api/controllers/flutter-b2bking.php
+++ b/mstore-api/controllers/flutter-b2bking.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_b2bking';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-booking.php
+++ b/mstore-api/controllers/flutter-booking.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_booking';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-cc-avenue.php
+++ b/mstore-api/controllers/flutter-cc-avenue.php
@@ -18,7 +18,7 @@
protected $namespace = 'api/flutter_cc_avenue';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-checkout.php
+++ b/mstore-api/controllers/flutter-checkout.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_checkout';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-composite-products.php
+++ b/mstore-api/controllers/flutter-composite-products.php
@@ -20,7 +20,7 @@
protected $namespace = 'api/flutter_composite_products';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-customer.php
+++ b/mstore-api/controllers/flutter-customer.php
@@ -11,7 +11,7 @@
protected $namespace = 'api/flutter_customer';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-delivery.php
+++ b/mstore-api/controllers/flutter-delivery.php
@@ -20,7 +20,7 @@
protected $namespace = 'delivery';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-discount-rules.php
+++ b/mstore-api/controllers/flutter-discount-rules.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_discount_rules';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-expresspay.php
+++ b/mstore-api/controllers/flutter-expresspay.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_expresspay';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-fib.php
+++ b/mstore-api/controllers/flutter-fib.php
@@ -20,7 +20,7 @@
protected $namespace = 'api/flutter_fib';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-fibo-search.php
+++ b/mstore-api/controllers/flutter-fibo-search.php
@@ -22,7 +22,7 @@
protected $namespace = 'api/flutter_fibo_search';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
@@ -119,14 +119,6 @@
// Get settings
$suggestions_limit = (int)$settings->getOption('suggestions_limit', 10);
$min_chars = (int)$settings->getOption('min_chars', 3);
- $show_image = $settings->getOption('show_product_image') === 'on';
- $show_price = $settings->getOption('show_product_price') === 'on';
- $show_desc = $settings->getOption('show_product_desc') === 'on';
- $show_sku = $settings->getOption('show_product_sku') === 'on';
- $search_in_content = $settings->getOption('search_in_product_content') === 'on';
- $search_in_excerpt = $settings->getOption('search_in_product_excerpt') === 'on';
- $search_in_sku = $settings->getOption('search_in_product_sku') === 'on';
- $exclude_out_of_stock = $settings->getOption('exclude_out_of_stock') === 'on';
$show_matching_categories = $settings->getOption('show_product_tax_product_cat') === 'on';
$show_matching_tags = $settings->getOption('show_product_tax_product_tag') === 'on';
@@ -203,72 +195,68 @@
)
);
- if ($show_image) {
- $images = array();
- // Get featured image
- $featured_image_id = $wc_product->get_image_id();
- if ($featured_image_id) {
- $images[] = wp_get_attachment_image_url($featured_image_id);
- }
-
- // Get gallery images
- $gallery_image_ids = $wc_product->get_gallery_image_ids();
- foreach ($gallery_image_ids as $gallery_image_id) {
- $images[] = wp_get_attachment_image_url($gallery_image_id);
- }
- $product_data['images'] = $images;
- }
-
- if ($show_price) {
- if ($wc_product->is_type('variable')) {
- $variation_prices = $wc_product->get_variation_prices();
- $min_price = current($variation_prices['price']) ?: '';
- $max_price = end($variation_prices['price']) ?: '';
- $min_regular = current($variation_prices['regular_price']) ?: '';
- $max_regular = end($variation_prices['regular_price']) ?: '';
- $min_sale = current($variation_prices['sale_price']) ?: '';
- $max_sale = end($variation_prices['sale_price']) ?: '';
- } else {
- $price = $wc_product->get_price() ?: '';
- $min_price = $max_price = $price;
- $min_regular = $max_regular = $wc_product->get_regular_price() ?: '';
- $min_sale = $max_sale = $wc_product->get_sale_price() ?: '';
- }
- $product_data['price'] = $wc_product->get_price() ?: '';
- $product_data['regular_price'] = $wc_product->get_regular_price() ?: '';
- $product_data['sale_price'] = $wc_product->get_sale_price() ?: '';
- $product_data['min_price'] = $min_price;
- $product_data['max_price'] = $max_price;
- $product_data['min_regular_price'] = $min_regular;
- $product_data['max_regular_price'] = $max_regular;
- $product_data['min_sale_price'] = $min_sale;
- $product_data['max_sale_price'] = $max_sale;
- $product_data['price_formatted'] = wc_price($product_data['price']);
- $product_data['regular_price_formatted'] = wc_price($product_data['regular_price']);
- $product_data['sale_price_formatted'] = $product_data['sale_price'] ? wc_price($product_data['sale_price']) : '';
- $product_data['price_range'] = $wc_product->get_price_html();
- }
+ // Get images
+ $images = array();
+ // Get featured image
+ $featured_image_id = $wc_product->get_image_id();
+ if ($featured_image_id) {
+ $images[] = wp_get_attachment_image_url($featured_image_id);
+ }
+
+ // Get gallery images
+ $gallery_image_ids = $wc_product->get_gallery_image_ids();
+ foreach ($gallery_image_ids as $gallery_image_id) {
+ $images[] = wp_get_attachment_image_url($gallery_image_id);
+ }
+ $product_data['images'] = $images;
+
+ // Get price
+ if ($wc_product->is_type('variable')) {
+ $variation_prices = $wc_product->get_variation_prices();
+ $min_price = current($variation_prices['price']) ?: '';
+ $max_price = end($variation_prices['price']) ?: '';
+ $min_regular = current($variation_prices['regular_price']) ?: '';
+ $max_regular = end($variation_prices['regular_price']) ?: '';
+ $min_sale = current($variation_prices['sale_price']) ?: '';
+ $max_sale = end($variation_prices['sale_price']) ?: '';
+ } else {
+ $price = $wc_product->get_price() ?: '';
+ $min_price = $max_price = $price;
+ $min_regular = $max_regular = $wc_product->get_regular_price() ?: '';
+ $min_sale = $max_sale = $wc_product->get_sale_price() ?: '';
+ }
+ $product_data['price'] = $wc_product->get_price() ?: '';
+ $product_data['regular_price'] = $wc_product->get_regular_price() ?: '';
+ $product_data['sale_price'] = $wc_product->get_sale_price() ?: '';
+ $product_data['min_price'] = $min_price;
+ $product_data['max_price'] = $max_price;
+ $product_data['min_regular_price'] = $min_regular;
+ $product_data['max_regular_price'] = $max_regular;
+ $product_data['min_sale_price'] = $min_sale;
+ $product_data['max_sale_price'] = $max_sale;
+ $product_data['price_formatted'] = wc_price($product_data['price']);
+ $product_data['regular_price_formatted'] = wc_price($product_data['regular_price']);
+ $product_data['sale_price_formatted'] = $product_data['sale_price'] ? wc_price($product_data['sale_price']) : '';
+ $product_data['price_range'] = $wc_product->get_price_html();
+
+ // Get description
+ $short_description = $wc_product->get_short_description();
+ // Convert HTML to plain text
+ $short_description = wp_strip_all_tags($short_description);
+ $short_description = html_entity_decode($short_description);
+ $short_description = preg_replace('/s+/', ' ', $short_description);
+ $short_description = trim($short_description);
+ $product_data['short_description'] = $short_description;
+ $description = $wc_product->get_description();
+ // Convert HTML to plain text
+ $description = wp_strip_all_tags($description); // Remove HTML tags
+ $description = html_entity_decode($description); // Convert HTML entities to characters
+ $description = preg_replace('/s+/', ' ', $description); // Replace multiple spaces with single space
+ $description = trim($description); // Remove leading/trailing spaces
+ $product_data['description'] = $description;
- if ($show_desc) {
- $short_description = $wc_product->get_short_description();
- // Convert HTML to plain text
- $short_description = wp_strip_all_tags($short_description);
- $short_description = html_entity_decode($short_description);
- $short_description = preg_replace('/s+/', ' ', $short_description);
- $short_description = trim($short_description);
- $product_data['short_description'] = $short_description;
- $description = $wc_product->get_description();
- // Convert HTML to plain text
- $description = wp_strip_all_tags($description); // Remove HTML tags
- $description = html_entity_decode($description); // Convert HTML entities to characters
- $description = preg_replace('/s+/', ' ', $description); // Replace multiple spaces with single space
- $description = trim($description); // Remove leading/trailing spaces
- $product_data['description'] = $description;
- }
-
- if ($show_sku) {
- $product_data['sku'] = $wc_product->get_sku();
- }
+ // Get SKU
+ $product_data['sku'] = $wc_product->get_sku();
// Get attributes
$attributes = array();
--- a/mstore-api/controllers/flutter-flow-flow.php
+++ b/mstore-api/controllers/flutter-flow-flow.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_flow_flow';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-flutterwave.php
+++ b/mstore-api/controllers/flutter-flutterwave.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_flutterwave';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-home.php
+++ b/mstore-api/controllers/flutter-home.php
@@ -22,7 +22,7 @@
private $supportedLayouts = ["fourColumn","threeColumn","twoColumn","staggered","saleOff","card","listTile","largeCardHorizontalListItems","largeCard","simpleVerticalListItems","simpleList"];
private $unSupportedVerticalLayouts = ["menu","menuCustom"];
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-iyzico.php
+++ b/mstore-api/controllers/flutter-iyzico.php
@@ -21,7 +21,7 @@
protected $namespace = 'api/flutter_iyzico';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-midtrans.php
+++ b/mstore-api/controllers/flutter-midtrans.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_midtrans';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-modempay.php
+++ b/mstore-api/controllers/flutter-modempay.php
@@ -0,0 +1,235 @@
+<?php
+require_once(__DIR__ . '/flutter-base.php');
+
+/*
+ * Base REST Controller for flutter
+ *
+ * @since 1.4.0
+ *
+ * @package Modempay
+ */
+
+class FlutterModempay extends FlutterBaseController
+{
+ /**
+ * Endpoint namespace
+ *
+ * @var string
+ */
+ protected $namespace = 'api/flutter_modempay';
+
+ /**
+ * Register all routes related with stores
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ add_action('rest_api_init', array($this, 'register_flutter_modempay_routes'));
+ }
+
+ public function register_flutter_modempay_routes()
+ {
+ register_rest_route($this->namespace, '/payment_success', array(
+ array(
+ 'methods' => "POST",
+ 'callback' => array($this, 'payment_success'),
+ 'permission_callback' => function () {
+ return parent::checkApiPermission();
+ }
+ ),
+ ));
+ }
+
+ /**
+ * Reuse logic from the payment gateway plugin
+ * Source: https://docs.modempay.com/plugins/woocommerce
+ */
+ public function payment_success($request)
+ {
+ // Parse webhook payload
+ $json = file_get_contents('php://input');
+ $webhook_data = json_decode($json, true);
+
+ // Validate webhook structure
+ if (!isset($webhook_data['event']) || !isset($webhook_data['payload'])) {
+ return new WP_Error('invalid_webhook', 'Invalid webhook structure', array('status' => 400));
+ }
+
+ $event = $webhook_data['event'];
+ $payload = $webhook_data['payload'];
+
+ // Only process successful charge events
+ if ($event !== 'charge.succeeded') {
+ return new WP_Error('unsupported_event', 'Unsupported event type: ' . $event, array('status' => 400));
+ }
+
+ // Extract order ID from metadata
+ $metadata = array();
+ if (isset($payload['metadata'])) {
+ if (is_array($payload['metadata'])) {
+ $metadata = $payload['metadata'];
+ } elseif (is_string($payload['metadata'])) {
+ $decoded_metadata = json_decode($payload['metadata'], true);
+ if (is_array($decoded_metadata)) {
+ $metadata = $decoded_metadata;
+ }
+ }
+ }
+ $order_id = isset($metadata['order_id']) ? sanitize_text_field($metadata['order_id']) : null;
+
+ if (empty($order_id)) {
+ return new WP_Error('missing_order_id', 'Order ID not found in webhook metadata', array('status' => 400));
+ }
+
+ // Get order
+ $order = wc_get_order($order_id);
+ if (!$order) {
+ return new WP_Error('order_not_found', 'Order not found: ' . $order_id, array('status' => 404));
+ }
+
+ // Get transaction ID (try multiple fields)
+ $transaction_id = $this->get_transaction_id($payload);
+ if (empty($transaction_id)) {
+ return new WP_Error('missing_transaction_id', 'Transaction ID not found in webhook payload', array('status' => 400));
+ }
+
+ // SECURITY CHECK 1: Check if already paid to prevent duplicate processing
+ if ($order->is_paid()) {
+ $order->add_order_note('Webhook received but order already paid. Transaction ID: ' . $transaction_id);
+ return array(
+ 'success' => true,
+ 'message' => 'Order already paid'
+ );
+ }
+
+ // SECURITY CHECK 2: Check for duplicate transaction ID across all orders
+ $existing_orders = wc_get_orders(array(
+ 'meta_key' => '_modempay_transaction_id',
+ 'meta_value' => $transaction_id,
+ 'status' => array('processing', 'completed', 'on-hold'),
+ 'exclude' => array($order_id)
+ ));
+
+ if (!empty($existing_orders)) {
+ $order->add_order_note(sprintf(
+ 'SECURITY: Duplicate transaction ID %s already used for Order #%s',
+ $transaction_id,
+ $existing_orders[0]->get_id()
+ ));
+ return new WP_Error('duplicate_transaction', 'Transaction already processed for another order', array('status' => 400));
+ }
+
+ // SECURITY CHECK 3: Verify transaction amount matches order total
+ $expected_amount = floatval($order->get_total());
+ $transaction_amount = isset($payload['amount']) ? floatval($payload['amount']) : 0;
+
+ if (abs($expected_amount - $transaction_amount) > 0.01) {
+ $order->add_order_note(sprintf(
+ 'SECURITY: Amount mismatch. Expected: %s %s, Received: %s %s',
+ $expected_amount,
+ $order->get_currency(),
+ $transaction_amount,
+ isset($payload['currency']) ? $payload['currency'] : 'N/A'
+ ));
+ return new WP_Error('amount_mismatch', 'Transaction amount does not match order total', array('status' => 400));
+ }
+
+ // SECURITY CHECK 4: Verify customer email matches (if available)
+ $order_email = strtolower(trim($order->get_billing_email()));
+ $transaction_email = isset($payload['customer_email']) ? strtolower(trim($payload['customer_email'])) : '';
+
+ if (!empty($transaction_email) && $order_email !== $transaction_email) {
+ $order->add_order_note(sprintf(
+ 'SECURITY: Customer email mismatch. Order: %s, Transaction: %s',
+ $order_email,
+ $transaction_email
+ ));
+ return new WP_Error('email_mismatch', 'Customer email does not match', array('status' => 400));
+ }
+
+ // SECURITY CHECK 5: Check transaction age (reject if older than 24 hours)
+ if (isset($payload['createdAt'])) {
+ $transaction_time = strtotime($payload['createdAt']);
+ $current_time = current_time('timestamp');
+ $time_diff = $current_time - $transaction_time;
+
+ if ($time_diff > (24 * 60 * 60)) {
+ $order->add_order_note(sprintf(
+ 'SECURITY: Transaction too old. Created: %s (%.2f hours ago)',
+ $payload['createdAt'],
+ $time_diff / 3600
+ ));
+ return new WP_Error('transaction_expired', 'Transaction has expired', array('status' => 400));
+ }
+ }
+
+ // SECURITY CHECK 6: Verify transaction status is successful
+ $status = isset($payload['status']) ? strtolower($payload['status']) : '';
+ $valid_statuses = array('success', 'successful', 'completed', 'paid');
+
+ if (!in_array($status, $valid_statuses)) {
+ $order->add_order_note('Webhook received with invalid status: ' . esc_html($status));
+ return new WP_Error('invalid_status', 'Transaction status is not successful: ' . $status, array('status' => 400));
+ }
+
+ // Store transaction metadata
+ $order->update_meta_data('_modempay_transaction_id', $transaction_id);
+ $order->update_meta_data('_modempay_payment_reference', isset($payload['reference']) ? sanitize_text_field($payload['reference']) : '');
+ $order->update_meta_data('_modempay_payment_method', isset($payload['payment_method']) ? sanitize_text_field($payload['payment_method']) : '');
+ $order->update_meta_data('_modempay_transaction', $json);
+ $order->update_meta_data('_modempay_webhook_received', current_time('mysql'));
+ $order->save();
+
+ // Complete the payment
+ $order->payment_complete($transaction_id);
+
+ // Build detailed order note
+ $note_parts = array(
+ 'Modem Pay payment successful via webhook',
+ 'Transaction ID: ' . esc_html($transaction_id),
+ 'Reference: ' . esc_html(isset($payload['reference']) ? $payload['reference'] : 'N/A'),
+ 'Payment Method: ' . esc_html(isset($payload['payment_method']) ? $payload['payment_method'] : 'N/A'),
+ 'Amount: ' . esc_html($transaction_amount) . ' ' . esc_html(isset($payload['currency']) ? $payload['currency'] : ''),
+ 'Customer: ' . esc_html(isset($payload['customer_name']) ? $payload['customer_name'] : 'N/A'),
+ 'Phone: ' . esc_html(isset($payload['customer_phone']) ? $payload['customer_phone'] : 'N/A'),
+ 'Email: ' . esc_html($transaction_email),
+ 'Source: ' . esc_html(isset($metadata['source']) ? $metadata['source'] : 'mobile_app')
+ );
+
+ if (isset($payload['test_mode']) && $payload['test_mode']) {
+ $note_parts[] = '<strong>TEST MODE</strong>';
+ }
+
+ $order->add_order_note(implode('<br/>', $note_parts));
+
+ // Return success response
+ return array(
+ 'success' => true,
+ 'message' => 'Payment processed successfully',
+ 'order_id' => $order_id,
+ 'transaction_id' => $transaction_id
+ );
+ }
+
+ /**
+ * Get transaction ID from payload (handles various field names)
+ */
+ private function get_transaction_id($payload)
+ {
+ if (isset($payload['id'])) {
+ return sanitize_text_field($payload['id']);
+ } elseif (isset($payload['transaction_id'])) {
+ return sanitize_text_field($payload['transaction_id']);
+ } elseif (isset($payload['transaction_reference'])) {
+ return sanitize_text_field($payload['transaction_reference']);
+ } elseif (isset($payload['reference'])) {
+ return sanitize_text_field($payload['reference']);
+ } elseif (isset($payload['payment_intent_id'])) {
+ return sanitize_text_field($payload['payment_intent_id']);
+ }
+ return '';
+ }
+}
+
+new FlutterModempay;
--- a/mstore-api/controllers/flutter-multi-vendor.php
+++ b/mstore-api/controllers/flutter-multi-vendor.php
@@ -11,7 +11,7 @@
protected $namespace = 'api/flutter_multi_vendor';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-myfatoorah.php
+++ b/mstore-api/controllers/flutter-myfatoorah.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_myfatoorah';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-notification.php
+++ b/mstore-api/controllers/flutter-notification.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_notification';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-order.php
+++ b/mstore-api/controllers/flutter-order.php
@@ -11,7 +11,7 @@
protected $namespace = 'api/flutter_order';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-paid-memberships-pro.php
+++ b/mstore-api/controllers/flutter-paid-memberships-pro.php
@@ -20,7 +20,7 @@
protected $namespace = 'api/flutter_paid_memberships_pro';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-paypal.php
+++ b/mstore-api/controllers/flutter-paypal.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_paypal';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-paystack.php
+++ b/mstore-api/controllers/flutter-paystack.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_paystack';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-paytm.php
+++ b/mstore-api/controllers/flutter-paytm.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_paytm';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-phonepe.php
+++ b/mstore-api/controllers/flutter-phonepe.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_phonepe';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-points-offline-store.php
+++ b/mstore-api/controllers/flutter-points-offline-store.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_osp';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-razorpay.php
+++ b/mstore-api/controllers/flutter-razorpay.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_razorpay';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-rental.php
+++ b/mstore-api/controllers/flutter-rental.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_rental';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-smart-cod.php
+++ b/mstore-api/controllers/flutter-smart-cod.php
@@ -18,7 +18,7 @@
protected $namespace = 'api/flutter_smart_cod';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-store-locator.php
+++ b/mstore-api/controllers/flutter-store-locator.php
@@ -20,7 +20,7 @@
protected $namespace = 'api/flutter_store_locator';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-stripe.php
+++ b/mstore-api/controllers/flutter-stripe.php
@@ -27,7 +27,7 @@
protected $dokan_stripe_bootstrapped = false;
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-tera-wallet.php
+++ b/mstore-api/controllers/flutter-tera-wallet.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_tera_wallet';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-thawani.php
+++ b/mstore-api/controllers/flutter-thawani.php
@@ -19,7 +19,7 @@
protected $namespace = 'api/flutter_thawani';
/**
- * Register all routes releated with stores
+ * Register all routes related with stores
*
* @return void
*/
--- a/mstore-api/controllers/flutter-user.php
+++ b/mstore-api/controllers/flutter-user.php
@@ -5,6 +5,30 @@
class FlutterUserController extends FlutterBaseController
{
+ private $allowed_profile_meta_keys = array(
+ 'billing_first_name',
+ 'billing_last_name',
+ 'billing_company',
+ 'billing_address_1',
+ 'billing_address_2',
+ 'billing_city',
+ 'billing_state',
+ 'billing_postcode',
+ 'billing_country',
+ 'billing_email',
+ 'billing_phone',
+ 'shipping_first_name',
+ 'shipping_last_name',
+ 'shipping_company',
+ 'shipping_address_1',
+ 'shipping_address_2',
+ 'shipping_city',
+ 'shipping_state',
+ 'shipping_postcode',
+ 'shipping_country',
+ 'shipping_email',
+ 'shipping_phone',
+ );
/**
* Endpoint namespace
@@ -13,8 +37,66 @@
*/
protected $namespace = 'api/flutter_user';
- public function __construct()
+ public function __construct() {}
+
+ private function sanitize_profile_text($value)
+ {
+ if (is_scalar($value)) {
+ return sanitize_text_field(wp_unslash((string)$value));
+ }
+
+ return '';
+ }
+
+ private function sanitize_profile_meta_value($meta_key, $value)
+ {
+ if (!is_scalar($value)) {
+ return '';
+ }
+
+ $value = wp_unslash((string)$value);
+
+ switch ($meta_key) {
+ case 'billing_email':
+ case 'shipping_email':
+ return sanitize_email($value);
+ case 'billing_postcode':
+ case 'shipping_postcode':
+ return wc_clean($value);
+ default:
+ return sanitize_text_field($value);
+ }
+ }
+
+ private function sanitize_meta_data($meta_data)
{
+ $sanitized_meta_data = array();
+
+ if (!is_array($meta_data)) {
+ return $sanitized_meta_data;
+ }
+
+ foreach ($meta_data as $item) {
+ if (!is_object($item) && !is_array($item)) {
+ continue;
+ }
+
+ $key = is_array($item) ? ($item['key'] ?? null) : ($item->key ?? null);
+ $value = is_array($item) ? ($item['value'] ?? null) : ($item->value ?? null);
+
+ if (!is_string($key) || !in_array($key, $this->allowed_profile_meta_keys, true)) {
+ continue;
+ }
+
+ if (!is_scalar($value)) {
+ continue;
+ }
+
+ $sanitized_value = $this->sanitize_profile_meta_value($key, $value);
+ $sanitized_meta_data[$key] = $sanitized_value;
+ }
+
+ return $sanitized_meta_data;
}
public function register_routes()
@@ -343,7 +425,6 @@
$params = json_decode($json, TRUE);
$usernameReq = $params["user_login"];
- $errors = new WP_Error();
if (empty($usernameReq) || !is_string($usernameReq)) {
return parent::sendError("empty_username", "Enter a username or email address.", 400);
} elseif (strpos($usernameReq, '@')) {
@@ -407,9 +488,9 @@
$referralCodeReq = $params["referral_code"];
}
- if(isset($params['wcfm_membership_application_status'])){
- $wcfm_membership_application_status = $params['wcfm_membership_application_status'];
- }
+ if (isset($params['wcfm_membership_application_status'])) {
+ $wcfm_membership_application_status = $params['wcfm_membership_application_status'];
+ }
$username = sanitize_user($usernameReq);
$email = sanitize_email($emailReq);
@@ -445,12 +526,29 @@
return parent::sendError("existed_email", "E-mail address is already in use.", 400);
} else {
if (!$userPassReq) {
- $params->user_pass = wp_generate_password();
+ $params['user_pass'] = wp_generate_password();
}
- $allowed_params = array('user_login', 'user_email', 'user_pass', 'display_name', 'user_nicename', 'user_url', 'nickname', 'first_name',
- 'last_name', 'description', 'rich_editing', 'user_registered', 'role', 'jabber', 'aim', 'yim',
- 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front',
+ $allowed_params = array(
+ 'user_login',
+ 'user_email',
+ 'user_pass',
+ 'display_name',
+ 'user_url',
+ 'nickname',
+ 'first_name',
+ 'last_name',
+ 'description',
+ 'rich_editing',
+ 'user_registered',
+ 'role',
+ 'jabber',
+ 'aim',
+ 'yim',
+ 'comment_shortcuts',
+ 'admin_color',
+ 'use_ssl',
+ 'show_admin_bar_front',
);
$dataRequest = $params;
@@ -473,34 +571,41 @@
}
$_POST['user_role'] = $user['role']; //fix to register account with role in listeo
- //
if (isset($referralCodeReq) && $referralCodeReq) {
- $_COOKIE['woo_wallet_referral'] = sanitize_text_field( wp_unslash( $referralCodeReq ) );
+ $_COOKIE['woo_wallet_referral'] = sanitize_text_field(wp_unslash($referralCodeReq));
}
$user_id = wp_insert_user($user);
if (is_wp_error($user_id)) {
return parent::sendError($user_id->get_error_code(), $user_id->get_error_message(), 400);
- } elseif (isset($params["phone"])) {
- update_user_meta($user_id, 'billing_phone', $params["phone"]);
- update_user_meta($user_id, 'registered_phone_number', $params["phone"]);
+ } else {
+ // Reapply role to override WooCommerce's automatic assignment
+ if (isset($user['role']) && !empty($user['role'])) {
+ $wp_user = new WP_User($user_id);
+ $wp_user->set_role($user['role']);
+ }
+
+ if (isset($params["phone"])) {
+ update_user_meta($user_id, 'billing_phone', $params["phone"]);
+ update_user_meta($user_id, 'registered_phone_number', $params["phone"]);
+ }
}
}
}
wp_new_user_notification($user_id, null, 'both');
- if(isset( $wcfm_membership_application_status) && $wcfm_membership_application_status == 'pending'){
- update_user_meta($user_id,'store_name', $user['display_name']);
+ if (isset($wcfm_membership_application_status) && $wcfm_membership_application_status == 'pending') {
+ update_user_meta($user_id, 'store_name', $user['display_name']);
//fix crash when approve membership in WCFM
- $wcfmvm_static_infos = (array) get_user_meta( $member_id, 'wcfmvm_static_infos', true );
+ $wcfmvm_static_infos = (array) get_user_meta($user_id, 'wcfmvm_static_infos', true);
$wcfmvm_static_infos['phone'] = $params["phone"] ?? '';
update_user_meta($user_id, 'wcfmvm_static_infos', $wcfmvm_static_infos);
update_user_meta($user_id, 'billing_phone', $params["phone"] ?? '');
- update_user_meta($user_id,'temp_wcfm_membership', true);
+ update_user_meta($user_id, 'temp_wcfm_membership', true);
global $WCFMvm;
- $WCFMvm->send_approval_reminder_admin( $user_id );
+ $WCFMvm->send_approval_reminder_admin($user_id);
}
if (isset($params['dokan_enable_selling'])) {
@@ -572,15 +677,15 @@
}
$is_driver_available = false;
- if(is_plugin_active('local-delivery-drivers-for-woocommerce/local-delivery-drivers-for-woocommerce.php')){
+ if (is_plugin_active('local-delivery-drivers-for-woocommerce/local-delivery-drivers-for-woocommerce.php') || is_plugin_active('local-delivery-drivers-for-woocommerce-premium/local-delivery-drivers-for-woocommerce.php')) {
$is_driver_available = get_user_meta($user->ID, 'lddfw_driver_availability', true);
- }
- else if(is_plugin_active('delivery-drivers-for-woocommerce/delivery-drivers-for-woocommerce.php') ||
- is_plugin_active('delivery-drivers-for-woocommerce-master/delivery-drivers-for-woocommerce.php')){
+ } else if (
+ is_plugin_active('delivery-drivers-for-woocommerce/delivery-drivers-for-woocommerce.php') ||
+ is_plugin_active('delivery-drivers-for-woocommerce-master/delivery-drivers-for-woocommerce.php')
+ ) {
$is_driver_available = get_user_meta($user->ID, 'ddwc_driver_availability', true);
- }
- else{
- $is_driver_available = in_array('administrator',$user->roles) || in_array('wcfm_delivery_boy',$user->roles);
+ } else {
+ $is_driver_available = in_array('administrator', $user->roles) || in_array('wcfm_delivery_boy', $user->roles);
}
// Check order status change capability
@@ -612,7 +717,7 @@
"url" => $user->user_url,
"registered" => $user->user_registered,
"displayname" => $user->display_name,
- "firstname" => $user->user_firstname,
+ "firstname" => $user->first_name,
"lastname" => $user->last_name,
"nickname" => $user->nickname,
"description" => $user->user_description,
@@ -659,17 +764,27 @@
);
}
- function createSocialAccount($email, $name, $firstName, $lastName, $userName)
+ function createSocialAccount($email, $name, $firstName, $lastName)
{
$email_exists = email_exists($email);
if ($email_exists) {
$user = get_user_by('email', $email);
$user_id = $user->ID;
} else {
+ // Extract and sanitize the username from the email local part
+ $userName = sanitize_user(explode('@', $email)[0], true);
+
+ // Fall back to a random name if the local part had no valid characters
+ if (empty($userName)) {
+ $userName = 'user_' . time() . '_' . wp_rand(1000, 9999);
+ }
+
+ // Append an incrementing counter to guarantee uniqueness
+ $baseUserName = $userName;
$i = 0;
while (username_exists($userName)) {
$i++;
- $userName = strtolower($userName) . '.' . $i;
+ $userName = $baseUserName . '.' . $i;
}
$random_password = wp_generate_password($length = 12, $include_standard_special_chars = false);
$userdata = array(
@@ -678,8 +793,12 @@
'user_pass' => $random_password,
'display_name' => $name,
'first_name' => $firstName,
- 'last_name' => $lastName);
+ 'last_name' => $lastName
+ );
$user_id = wp_insert_user($userdata);
+ if (is_wp_error($user_id)) {
+ return $user_id;
+ }
}
$cookie = generateCookieByUserId($user_id);
@@ -695,7 +814,6 @@
public function fb_connect($request)
{
$fields = 'id,name,first_name,last_name,email';
- $enable_ssl = true;
$access_token = $request["access_token"];
if (!isset($access_token)) {
return parent::sendError("invalid_login", "You must include a 'access_token' variable. Get the valid access_token for this app from Facebook API.", 400);
@@ -720,8 +838,7 @@
}
if (isset($result["email"])) {
- $user_name = strtolower($result['first_name'] . '.' . $result['last_name']);
- return $this->createSocialAccount($result["email"], $result['name'], $result['first_name'], $result['last_name'], $user_name);
+ return $this->createSocialAccount($result["email"], $result['name'], $result['first_name'], $result['last_name']);
} else {
return parent::sendError("invalid_login", "Your 'access_token' did not return email of the user. Without 'email' user can't be logged in or registered. Get user email extended permission while joining the Facebook app.", 400);
}
@@ -752,12 +869,10 @@
if (isset($result["phone"])) {
$user_name = $result["phone"]["number"];
$user_email = $result["phone"]["number"] . "@flutter.io";
- return $this->createSocialAccount($user_email, $user_name, $user_name, "", $user_name);
+ return $this->createSocialAccount($user_email, $user_name, $user_name, "");
} else {
return parent::sendError("invalid_login", "Your 'access_token' did not return email of the user. Without 'email' user can't be logged in or registered. Get user email extended permission while joining the Facebook app.", 400);
}
- return $response;
-
}
private function firebase_sms_verify_id_token($request)
@@ -793,7 +908,7 @@
}
$user_name = $phone;
$user_email = $phone . "@" . $domain;
- return $this->createSocialAccount($user_email, $user_name, $user_name, "", $user_name);
+ return $this->createSocialAccount($user_email, $user_name, $user_name, "");
}
private function firebase_sms_login_v2($phone)
@@ -802,31 +917,18 @@
return parent::sendError("invalid_login", "You must include a 'phone' variable.", 400);
}
- if (isset($phone)) {
- $args = array('meta_key' => 'registered_phone_number', 'meta_value' => $phone);
- $search_users = get_users($args);
- if (empty($search_users)) {
- $domain = $_SERVER['SERVER_NAME'] == 'default_server' ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
- if (count(explode(".", $domain)) == 1) {
- $domain = "flutter.io";
- }
- $user_name = $phone;
- $user_email = $phone . "@" . $domain;
- $user = get_user_by('email', $user_email);
- if (!$user) {
- return parent::sendError("invalid_login", "User does not exist", 400);
- }
- $cookie = generateCookieByUserId($user->ID);
- $response['wp_user_id'] = $user->ID;
- $response['cookie'] = $cookie;
- $response['user_login'] = $user->user_login;
- $response['user'] = $this->getResponseUserInfo($user);
- return $response;
+ $args = array('meta_key' => 'registered_phone_number', 'meta_value' => $phone);
+ $search_users = get_users($args);
+ if (empty($search_users)) {
+ $domain = $_SERVER['SERVER_NAME'] == 'default_server' ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
+ if (count(explode(".", $domain)) == 1) {
+ $domain = "flutter.io";
}
- if (count($search_users) > 1) {
- return parent::sendError("invalid_login", "Too many users with the same phone number", 400);
+ $user_email = $phone . "@" . $domain;
+ $user = get_user_by('email', $user_email);
+ if (!$user) {
+ return parent::sendError("invalid_login", "User does not exist", 400);
}
- $user = $search_users[0];
$cookie = generateCookieByUserId($user->ID);
$response['wp_user_id'] = $user->ID;
$response['cookie'] = $cookie;
@@ -834,7 +936,16 @@
$response['user'] = $this->getResponseUserInfo($user);
return $response;
}
- return parent::sendError("invalid_login", "Unknown Error", 400);
+ if (count($search_users) > 1) {
+ return parent::sendError("invalid_login", "Too many users with the same phone number", 400);
+ }
+ $user = $search_users[0];
+ $cookie = generateCookieByUserId($user->ID);
+ $response['wp_user_id'] = $user->ID;
+ $response['cookie'] = $cookie;
+ $response['user_login'] = $user->user_login;
+ $response['user'] = $this->getResponseUserInfo($user);
+ return $response;
}
@@ -855,11 +966,11 @@
$lastName = $params["last_name"];
$teamId = $params["team_id"];
$bundleId = $params["bundle_id"];
- if(!FlutterAppleSignInUtils::is_file_existed()){
+ if (!FlutterAppleSignInUtils::is_file_existed()) {
return parent::sendError("invalid_login", "You need to upload AuthKey_XXXX.p8 file to MStore Api plugin", 400);
}
- $token = AppleSignInHelper::generate_token($bundleId,$teamId,$authorization_code);
- if($token == false || is_wp_error($token)){
+ $token = AppleSignInHelper::generate_token($bundleId, $teamId, $authorization_code);
+ if ($token == false || is_wp_error($token)) {
return is_wp_error($token) ? $token : parent::sendError("invalid_login", "Invalid authorization_code", 400);
}
$decoded = $this->jwtDecode($token);
@@ -868,15 +979,14 @@
return parent::sendError("invalid_login", "Can't get the email to create account.", 400);
}
$display_name = explode("@", $user_email)[0];
- if(isset($firstName) && isset($lastName) && !empty($firstName)){
- $display_name = $firstName.' '.$lastName;
- }else{
+ if (isset($firstName) && isset($lastName) && !empty($firstName)) {
+ $display_name = $firstName . ' ' . $lastName;
+ } else {
$firstName = $display_name;
$lastName = "";
}
- $user_name = $display_name;
- return $this->createSocialAccount($user_email, $display_name, $firstName, $lastName, $user_name);
+ return $this->createSocialAccount($user_email, $display_name, $firstName, $lastName);
}
public function google_login($request)
@@ -896,8 +1006,7 @@
$lastName = $result["family_name"];
$email = $result["email"];
$display_name = $firstName . " " . $lastName;
- $user_name = $firstName . "." . $lastName;
- return $this->createSocialAccount($email, $display_name, $firstName, $lastName, $user_name);
+ return $this->createSocialAccount($email, $display_name, $firstName, $lastName);
} else {
return parent::sendError("invalid_login", "Your 'token' did not return email of the user. Without 'email' user can't be logged in or registered. Get user email extended permission while joining the Google app.", 400);
}
@@ -1011,6 +1120,12 @@
global $json_api;
$json = file_get_contents('php://input');
$params = json_decode($json);
+ if (!is_object($params)) {
+ return new WP_Error("invalid_request", "Invalid request payload.", array('status' => 400));
+ }
+ if (!isset($params->cookie) || !is_string($params->cookie) || '' === trim($params->cookie)) {
+ return new WP_Error("invalid_cookie", "Missing or invalid cookie parameter.", array('status' => 400));
+ }
$cookie = $params->cookie;
$user_id = validateCookieLogin($cookie);
if (is_wp_error($user_id)) {
@@ -1018,100 +1133,144 @@
}
$user_update = array('ID' => $user_id);
+ $pending_meta_updates = array();
+ $pending_avatar = null;
if (isset($params->user_pass)) {
$user_update['user_pass'] = $params->user_pass;
}
if (isset($params->user_nicename)) {
- $user_update['user_nicename'] = $params->user_nicename;
+ if (!is_scalar($params->user_nicename)) {
+ return new WP_Error("invalid_user_nicename", "Invalid user nicename.", array('status' => 400));
+
+ }
+ $user_update['user_nicename'] = sanitize_title((string) $params->user_nicename);
}
+
if (isset($params->user_email)) {
- $user_update['user_email'] = $params->user_email;
+ if (!is_scalar($params->user_email)) {
+ return new WP_Error("invalid_user_email", "Invalid email address.", array('status' => 400));
+ }
+
+ $user_email = sanitize_email((string) $params->user_email);
+ if ($user_email === '' || !is_email($user_email)) {
+ return new WP_Error("invalid_user_email", "Invalid email address.", array('status' => 400));
+ }
+ $user_update['user_email'] = $user_email;
}
+
if (isset($params->user_url)) {
- $user_update['user_url'] = $params->user_url;
+ if (!is_scalar($params->user_url)) {
+ return new WP_Error("invalid_user_url", "Invalid user URL.", array('status' => 400));
+ }
+
+ $raw_user_url = (string) $params->user_url;
+ $user_url = esc_url_raw($raw_user_url);
+ if ($raw_user_url !== '' && $user_url === '') {
+ return new WP_Error("invalid_user_url", "Invalid user URL.", array('status' => 400));
+ }
+
+ $user_update['user_url'] = $user_url;
}
if (isset($params->display_name)) {
- $user_update['display_name'] = $params->display_name;
+ $user_update['display_name'] = $this->sanitize_profile_text($params->display_name);
}
if (isset($params->first_name)) {
- $user_update['first_name'] = $params->first_name;
- update_user_meta($user_id, 'shipping_first_name', $params->first_name, '');
- update_user_meta($user_id, 'billing_first_name', $params->first_name, '');
+ $first_name = $this->sanitize_profile_text($params->first_name);
+ $user_update['first_name'] = $first_name;
+ $pending_meta_updates['shipping_first_name'] = $first_name;
+ $pending_meta_updates['billing_first_name'] = $first_name;
}
if (isset($params->last_name)) {
- $user_update['last_name'] = $params->last_name;
- update_user_meta($user_id, 'shipping_last_name', $params->last_name, '');
- update_user_meta($user_id, 'billing_last_name', $params->last_name, '');
+ $last_name = $this->sanitize_profile_text($params->last_name);
+ $user_update['last_name'] = $last_name;
+ $pending_meta_updates['shipping_last_name'] = $last_name;
+ $pending_meta_updates['billing_last_name'] = $last_name;
}
if (isset($params->phone)) {
- update_user_meta($user_id, 'shipping_phone', $params->phone, '');
- update_user_meta($user_id, 'billing_phone', $params->phone, '');
+ $phone = $this->sanitize_profile_text($params->phone);
+ $pending_meta_updates['shipping_phone'] = $phone;
+ $pending_meta_updates['billing_phone'] = $phone;
}
if (isset($params->shipping_company)) {
- update_user_meta($user_id, 'shipping_company', $params->shipping_company, '');
- update_user_meta($user_id, 'billing_company', $params->shipping_company, '');
+ $shipping_company = $this->sanitize_profile_text($params->shipping_company);
+ $pending_meta_updates['shipping_company'] = $shipping_company;
+ $pending_meta_updates['billing_company'] = $shipping_company;
}
if (isset($params->shipping_state)) {
- update_user_meta($user_id, 'shipping_state', $params->shipping_state, '');
- update_user_meta($user_id, 'billing_state', $params->shipping_state, '');
+ $shipping_state = $this->sanitize_profile_text($params->shipping_state);
+ $pending_meta_updates['shipping_state'] = $shipping_state;
+ $pending_meta_updates['billing_state'] = $shipping_state;
}
if (isset($params->shipping_address_1)) {
- update_user_meta($user_id, 'shipping_address_1', $params->shipping_address_1, '');
- update_user_meta($user_id, 'billing_address_1', $params->shipping_address_1, '');
+ $shipping_address_1 = $this->sanitize_profile_text($params->shipping_address_1);
+ $pending_meta_updates['shipping_address_1'] = $shipping_address_1;
+ $pending_meta_updates['billing_address_1'] = $shipping_address_1;
}
if (isset($params->shipping_address_2)) {
- update_user_meta($user_id, 'shipping_address_2', $params->shipping_address_2, '');
- update_user_meta($user_id, 'billing_address_2', $params->shipping_address_2, '');
+ $shipping_address_2 = $this->sanitize_profile_text($params->shipping_address_2);
+ $pending_meta_updates['shipping_address_2'] = $shipping_address_2;
+ $pending_meta_updates['billing_address_2'] = $shipping_address_2;
}
if (isset($params->shipping_city)) {
- update_user_meta($user_id, 'shipping_city', $params->shipping_city, '');
- update_user_meta($user_id, 'billing_city', $params->shipping_city, '');
+ $shipping_city = $this->sanitize_profile_text($params->shipping_city);
+ $pending_meta_updates['shipping_city'] = $shipping_city;
+ $pending_meta_updates['billing_city'] = $shipping_city;
}
if (isset($params->shipping_country)) {
- update_user_meta($user_id, 'shipping_country', $params->shipping_country, '');
- update_user_meta($user_id, 'billing_country', $params->shipping_country, '');
+ $shipping_country = $this->sanitize_profile_text($params->shipping_country);
+ $pending_meta_updates['shipping_country'] = $shipping_country;
+ $pending_meta_updates['billing_country'] = $shipping_country;
}
if (isset($params->shipping_postcode)) {
- update_user_meta($user_id, 'shipping_postcode', $params->shipping_postcode, '');
- update_user_meta($user_id, 'billing_postcode', $params->shipping_postcode, '');
+ $shipping_postcode = wc_clean(wp_unslash((string)$params->shipping_postcode));
+ $pending_meta_updates['shipping_postcode'] = $shipping_postcode;
+ $pending_meta_updates['billing_postcode'] = $shipping_postcode;
+ }
+ $pending_meta_updates = array_merge(
+ $pending_meta_updates,
+ $this->sanitize_meta_data($params->meta_data ?? null)
+ );
+
+ if (isset($params->avatar)) {
+ $pending_avatar = $params->avatar;
}
- if (isset($params->meta_data) && is_array($params->meta_data)) {
- foreach ($params->meta_data as $item) {
- update_user_meta($user_id, $item->key, $item->value, '');
- }
+
+
+ $user_data = wp_update_user($user_update);
+
+ if (is_wp_error($user_data)) {
+ return $user_data;
}
- if (isset($params->avatar)) {
+ foreach ($pending_meta_updates as $meta_key => $meta_value) {
+ update_user_meta($user_id, $meta_key, $meta_value, '');
+ }
+
+ if ($pending_avatar !== null) {
$count = 1;
try {
- $attachment_id = upload_image_from_mobile($params->avatar, $count, $user_id);
+ $attachment_id = upload_image_from_mobile($pending_avatar, $count, $user_id);
$url = wp_get_attachment_image_src($attachment_id);
update_user_meta($user_id, 'user_avatar', $url, '');
- } catch (Exception $e) {
+ } catch (Exception $e) {
return new WP_Error("invalid_avatar", $e->getMessage(), array('status' => 400));
}
}
-
- $user_data = wp_update_user($user_update);
-
- if (is_wp_error($user_data)) {
- // There was an error; possibly this user doesn't exist.
- echo 'Error.';
- }
$user = get_userdata($user_id);
if (isset($params->deviceToken)) {
+ $device_token = $this->sanitize_profile_text($params->deviceToken);
if (isset($params->is_manager) && $params->is_manager) {
- update_user_meta($user_id, "mstore_manager_device_token",