Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/latepoint/latepoint.php
+++ b/latepoint/latepoint.php
@@ -2,7 +2,7 @@
/**
* Plugin Name: LatePoint
* Description: Appointment Scheduling Software for WordPress
- * Version: 5.5.0
+ * Version: 5.5.1
* Author: LatePoint
* Author URI: https://latepoint.com
* Plugin URI: https://latepoint.com
@@ -29,7 +29,7 @@
* LatePoint version.
*
*/
- public $version = '5.5.0';
+ public $version = '5.5.1';
public $db_version = '2.3.0';
@@ -1147,15 +1147,24 @@
}
public function save_connected_wordpress_user( $customer ) {
+ if ( ! $customer instanceof OsCustomerModel ) {
+ return;
+ }
+
if ( $customer->is_new_record() ) {
return;
}
- if ( $customer instanceof OsCustomerModel ) {
- if ( $customer->wordpress_user_id ) {
- // has connected wp user
- $wp_user = get_user_by( 'id', $customer->wordpress_user_id );
- if ( $wp_user && ! is_super_admin( $wp_user->ID ) ) {
- // update linked wordpress user
+
+ if ( $customer->wordpress_user_id ) {
+ // has connected wp user
+ $wp_user = get_user_by( 'id', $customer->wordpress_user_id );
+ if ( $wp_user && ! is_super_admin( $wp_user->ID ) ) {
+ // Only sync to the linked WP user when request comes from the account owner or an admin.
+ // This prevents unauthenticated guest booking requests from overwriting WP user data.
+ $current_user_id = get_current_user_id();
+ $wp_user_id = (int) $customer->wordpress_user_id;
+ $is_owner_or_admin = is_user_logged_in() && ( $current_user_id === $wp_user_id || current_user_can( 'manage_options' ) );
+ if ( $is_owner_or_admin ) {
if ( $customer->first_name && $customer->first_name != $wp_user->first_name ) {
$wp_user->first_name = $customer->first_name;
}
@@ -1172,10 +1181,10 @@
// update user cookies because their data has changed
}
}
- } else {
- if ( OsAuthHelper::can_wp_users_login_as_customers() ) {
- OsCustomerHelper::create_wp_user_for_customer( $customer );
- }
+ }
+ } else {
+ if ( OsAuthHelper::can_wp_users_login_as_customers() ) {
+ OsCustomerHelper::create_wp_user_for_customer( $customer );
}
}
}
--- a/latepoint/lib/controllers/activities_controller.php
+++ b/latepoint/lib/controllers/activities_controller.php
@@ -194,10 +194,10 @@
$status_html = '';
if ( ! empty( $data['status'] ) ) {
- $status_html = '<div class="status-item">' . __( 'Status:', 'latepoint' ) . ' <strong>' . $data['status'] . '</strong></div>';
- $status_html .= '<div class="status-item">' . __( 'Processed on:', 'latepoint' ) . ' <strong>' . $data['processed_datetime'] . '</strong></div>';
+ $status_html = '<div class="status-item">' . __( 'Status:', 'latepoint' ) . ' <strong>' . esc_html( $data['status'] ) . '</strong></div>';
+ $status_html .= '<div class="status-item">' . __( 'Processed on:', 'latepoint' ) . ' <strong>' . esc_html( $data['processed_datetime'] ) . '</strong></div>';
if ( ! empty( $data['errors'] ) ) {
- $status_html .= '<div class="status-item">' . __( 'Errors:', 'latepoint' ) . '<strong>' . ( is_array( $data['errors'] ) ? implode( ', ', $data['errors'] ) : $data['errors'] ) . '</strong></div>';
+ $status_html .= '<div class="status-item">' . __( 'Errors:', 'latepoint' ) . '<strong>' . esc_html( is_array( $data['errors'] ) ? implode( ', ', $data['errors'] ) : $data['errors'] ) . '</strong></div>';
}
}
@@ -206,28 +206,28 @@
case 'order_intent_updated':
$link_to_order = $activity->order_id ? '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>' : '';
$meta_html = '<div class="activity-preview-to">' . ( $link_to_order ? ( '<span class="os-value">' . $link_to_order . '</span>' ) : '' ) . '<span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'order_intent_created':
$link_to_order = $activity->order_id ? '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>' : '';
$meta_html = '<div class="activity-preview-to">' . ( $link_to_order ? ( '<span class="os-value">' . $link_to_order . '</span>' ) : '' ) . '<span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'order_intent_converted':
$link_to_order = '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_order . '</span><span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'order_created':
$link_to_order = '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_order . '</span><span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span><span class="os-label">' . esc_html__( 'by:', 'latepoint' ) . '</span><span class="os-value">' . $activity->get_user_link() . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['order_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'order_updated':
$link_to_order = '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_order . '</span><span class="os-label">' . __( 'Updated On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span><span class="os-label">' . esc_html__( 'by:', 'latepoint' ) . '</span><span class="os-value">' . $activity->get_user_link() . '</span></div>';
$changes = OsUtilHelper::compare_model_data_vars( $data['order_data_vars']['new'], $data['order_data_vars']['old'] );
- $content_html = '<pre class="format-json">' . wp_json_encode( $changes, JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $changes, JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'customer_created':
@@ -244,48 +244,48 @@
case 'payment_request_created':
$link_to_order = '<a href="#" ' . OsOrdersHelper::quick_order_btn_html( $activity->order_id ) . '>' . __( 'View Order', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_order . '</span><span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['payment_request_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['payment_request_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
// bookings
case 'booking_change_status':
$link_to_order = $activity->order_id ? '<a href="#" ' . OsBookingHelper::quick_booking_btn_html( $activity->booking_id ) . '>' . __( 'View Booking', 'latepoint' ) . '</a>' : '';
$meta_html = '<div class="activity-preview-to">' . ( $link_to_order ? ( '<span class="os-value">' . $link_to_order . '</span>' ) : '' ) . '<span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span><span class="os-label">' . esc_html__( 'by:', 'latepoint' ) . '</span><span class="os-value">' . $activity->get_user_link() . '</span></div>';
- $content_html = '<div class="activity-preview-content">' . $activity->description . '</div>';
+ $content_html = '<div class="activity-preview-content">' . wp_kses_post( $activity->description ) . '</div>';
break;
case 'booking_created':
$link_to_booking = '<a href="#" ' . OsBookingHelper::quick_booking_btn_html( $activity->booking_id ) . '>' . __( 'View Booking', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_booking . '</span><span class="os-label">' . __( 'Created On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span><span class="os-label">' . esc_html__( 'by:', 'latepoint' ) . '</span><span class="os-value">' . $activity->get_user_link() . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['booking_data_vars'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['booking_data_vars'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'booking_updated':
$link_to_booking = '<a href="#" ' . OsBookingHelper::quick_booking_btn_html( $activity->booking_id ) . '>' . __( 'View Booking', 'latepoint' ) . '</a>';
$meta_html = '<div class="activity-preview-to"><span class="os-value">' . $link_to_booking . '</span><span class="os-label">' . __( 'Updated On:', 'latepoint' ) . '</span><span class="os-value">' . $activity->nice_created_at . '</span><span class="os-label">' . esc_html__( 'by:', 'latepoint' ) . '</span><span class="os-value">' . $activity->get_user_link() . '</span></div>';
$changes = OsUtilHelper::compare_model_data_vars( $data['booking_data_vars']['new'], $data['booking_data_vars']['old'] );
- $content_html = '<pre class="format-json">' . wp_json_encode( $changes, JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $changes, JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'email_sent':
$meta_html = '<div class="activity-preview-subject">' . esc_html( $data['extra_data']['subject'] ) . '</div>';
$meta_html .= '<div class="activity-preview-to"><span class="os-label">' . __( 'To:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $data['to'] ) . '</span></div>';
- $content_html = '<div class="activity-preview-content">' . $data['content'] . '</div>';
+ $content_html = '<div class="activity-preview-content">' . wp_kses_post( $data['content'] ) . '</div>';
break;
case 'sms_sent':
$meta_html = '<div class="activity-preview-to"><span class="os-label">' . __( 'To:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $data['to'] ) . '</span></div>';
- $content_html = '<div class="activity-preview-content">' . $data['content'] . '</div>';
+ $content_html = '<div class="activity-preview-content">' . wp_kses_post( $data['content'] ) . '</div>';
break;
case 'http_request':
$meta_html = '<div class="activity-preview-to"><span class="os-label">' . __( 'URL:', 'latepoint' ) . '</span><span class="os-value"><a href="#" target="_blank">' . esc_html( $data['to'] ) . '</a></span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['content'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['content'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
case 'process_job_run':
$job = new OsProcessJobModel( $data['job_id'] );
$name = $job->process->name . ', ID: ' . $job->process->id;
$meta_html = '<div class="activity-preview-to"><span class="os-label">' . __( 'Process:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $name ) . '</span></div>';
- $content_html = '<pre class="format-json">' . $data['run_result'] . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( $data['run_result'] ) . '</pre>';
break;
case 'error':
$meta_html = '<div class="activity-preview-to"><span class="os-label">' . __( 'Error Message:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $data['message'] ) . ' | ' . esc_html( $data['error_code'] ) . '</span></div>';
- $content_html = '<pre class="format-json">' . wp_json_encode( $data['extra_description'], JSON_PRETTY_PRINT ) . '</pre>';
+ $content_html = '<pre class="format-json">' . esc_html( wp_json_encode( $data['extra_description'], JSON_PRETTY_PRINT | JSON_HEX_TAG ) ) . '</pre>';
break;
default:
--- a/latepoint/lib/helpers/analytics_helper.php
+++ b/latepoint/lib/helpers/analytics_helper.php
@@ -65,7 +65,10 @@
self::events();
// Plugin activated (dedup ensures).
- self::events()->track( 'plugin_activated', LATEPOINT_VERSION );
+ $referer_key = defined( 'BSF_UTM_ANALYTICS_REFERER' ) ? BSF_UTM_ANALYTICS_REFERER : 'bsf_product_referers';
+ $bsf_referrers = get_option( $referer_key, array() );
+ $source = ! empty( $bsf_referrers['latepoint'] ) ? $bsf_referrers['latepoint'] : 'self';
+ self::events()->track( 'plugin_activated', LATEPOINT_VERSION, [ 'source' => $source ] );
// Plugin updated. Fires once per version change via OsUpdateHelper.
add_action( 'latepoint_update_after', [ __CLASS__, 'on_plugin_updated' ] );
--- a/latepoint/lib/helpers/order_intent_helper.php
+++ b/latepoint/lib/helpers/order_intent_helper.php
@@ -119,7 +119,7 @@
$order_intent->presets_data = wp_json_encode( $presets_data );
// override only if not empty
if ( ! empty( $booking_form_page_url ) ) {
- $order_intent->booking_form_page_url = urldecode( $booking_form_page_url );
+ $order_intent->booking_form_page_url = esc_url_raw( urldecode( $booking_form_page_url ) );
}
if ( empty( $customer_id ) ) {
--- a/latepoint/lib/helpers/steps_helper.php
+++ b/latepoint/lib/helpers/steps_helper.php
@@ -289,9 +289,9 @@
'methods' => 'POST',
'callback' => 'OsSettingsHelper::force_bite',
'permission_callback' => '__return_true',
- )
+ )
);
- }
+ }
);
add_action(
'rest_api_init',
@@ -303,9 +303,9 @@
'methods' => 'POST',
'callback' => 'OsSettingsHelper::force_release',
'permission_callback' => '__return_true',
- )
+ )
);
- }
+ }
);
self::confirm_hash();
}
@@ -330,9 +330,9 @@
'fields_to_update' => self::$fields_to_update,
'callback' => $error_data['callback'] ?? '',
'callback_data' => $error_data['callback_data'] ?? '',
- )
+ )
);
- }
+ }
}
}
$step_function_name = 'process_step_' . $step_code;
@@ -349,7 +349,7 @@
'fields_to_update' => self::$fields_to_update,
'callback' => $error_data['callback'] ?? '',
'callback_data' => $error_data['callback_data'] ?? '',
- )
+ )
);
}
}
@@ -399,7 +399,7 @@
[
'add_string_to_id' => $step->code,
'theme' => 'bordered',
- ]
+ ]
); ?>
</div>
</div>
@@ -416,7 +416,7 @@
[
'add_string_to_id' => $step->code,
'theme' => 'bordered',
- ]
+ ]
); ?>
</div>
</div>
@@ -433,7 +433,7 @@
[
'add_string_to_id' => $step->code,
'theme' => 'bordered',
- ]
+ ]
); ?>
</div>
</div>
@@ -463,7 +463,7 @@
[
'class' => 'latepoint-btn',
'add_string_to_id' => $step->code,
- ]
+ ]
); ?>
</div>
</form>
@@ -541,7 +541,7 @@
'is_first_step' => true,
'is_last_step' => true,
'is_pre_last_step' => false,
- ]
+ ]
);
return;
@@ -565,7 +565,7 @@
'message' => $result->get_error_message(),
'send_to_step' => $send_to_step,
'fields_to_update' => self::$fields_to_update,
- )
+ )
);
return;
@@ -587,7 +587,7 @@
'message' => $result->get_error_message(),
'send_to_step' => $send_to_step,
'fields_to_update' => self::$fields_to_update,
- )
+ )
);
return;
@@ -617,7 +617,7 @@
'is_first_step' => self::is_first_step( self::$step_to_prepare ),
'is_last_step' => self::is_last_step( self::$step_to_prepare ),
'is_pre_last_step' => self::is_pre_last_step( self::$step_to_prepare ),
- ]
+ ]
);
}
}
@@ -726,7 +726,7 @@
self::$step_codes_in_order,
function ( $step ) use ( $parent_step_code ) {
return strpos( $step, $parent_step_code . '__' ) !== 0;
- }
+ }
);
}
@@ -1122,7 +1122,7 @@
// preselected calendar start date
if ( isset( $restrictions['calendar_start_date'] ) && OsTimeHelper::is_valid_date( $restrictions['calendar_start_date'] ) ) {
self::$restrictions['calendar_start_date'] = $restrictions['calendar_start_date'];
- }
+ }
}
/**
@@ -1725,7 +1725,7 @@
[
'agent_id' => self::$booking_object->agent_id,
'location_id' => self::$booking_object->location_id,
- ]
+ ]
);
// if "show only specific services" is selected (restrictions) - remove ids that are not found in connection
$show_services_arr = ( ! empty( $show_selected_services_arr ) && ! empty( $connected_ids ) ) ? array_intersect( $connected_ids, $show_selected_services_arr ) : $connected_ids;
@@ -1759,7 +1759,7 @@
[
'service_id' => self::$booking_object->service_id,
'location_id' => self::$booking_object->location_id,
- ]
+ ]
);
// If date/time is selected - filter agents who are available at that time
@@ -1904,7 +1904,7 @@
'notes',
'password',
'password_confirmation',
- ]
+ ]
);
if ( ! empty( $customer_params['first_name'] ) ) {
@@ -1961,6 +1961,14 @@
if ( $customer ) {
$is_new_customer = false;
$old_customer_data = $customer->get_data_vars();
+ // When merging by phone and the existing customer has a linked WP user,
+ // do not allow an unauthenticated request to overwrite their identity fields.
+ // Protects email (account takeover via password reset) and name fields (record integrity).
+ if ( 'phone' === $contact_merge && ! empty( $customer->wordpress_user_id ) && ! is_user_logged_in() ) {
+ unset( $sanitized_customer_params['email'] );
+ unset( $sanitized_customer_params['first_name'] );
+ unset( $sanitized_customer_params['last_name'] );
+ }
} else {
$is_new_customer = true;
$customer = new OsCustomerModel();
@@ -2005,7 +2013,7 @@
array(
'email' => $sanitized_customer_params['email'],
'id !=' => $logged_in_customer->id,
- )
+ )
)->set_limit( 1 )->get_results_as_models();
// check if another customer (or if wp user login enabled - another wp user) exists with the email that this user tries to update to
if ( $customer_with_email_exist || ( OsAuthHelper::can_wp_users_login_as_customers() && email_exists( $sanitized_customer_params['email'] ) ) ) {
@@ -2021,7 +2029,7 @@
[
'callback' => 'latepoint_show_verify_contact_form_with_otp_code',
'callback_data' => $otp_form_html,
- ]
+ ]
);
}
}
@@ -2035,7 +2043,7 @@
array(
'phone' => $sanitized_customer_params['phone'],
'id !=' => $logged_in_customer->id,
- )
+ )
)->set_limit( 1 )->get_results_as_models();
// check if another customer (or if wp user login enabled - another wp user) exists with the phone that this user tries to update to
if ( $customer_with_phone_exist ) {
@@ -2051,7 +2059,7 @@
[
'callback' => 'latepoint_show_verify_contact_form_with_otp_code',
'callback_data' => $otp_form_html,
- ]
+ ]
);
}
}
@@ -2100,7 +2108,7 @@
[
'callback' => 'latepoint_show_verify_contact_form_with_otp_code',
'callback_data' => $otp_form_html,
- ]
+ ]
);
}
}
@@ -2121,7 +2129,7 @@
[
'callback' => 'latepoint_show_verify_contact_form_with_otp_code',
'callback_data' => $otp_form_html,
- ]
+ ]
);
}
}
@@ -2320,7 +2328,7 @@
// is not bookable
self::$booking_object->add_error( 'booking_error', self::$booking_object->get_error_messages() );
}
- }
+ }
} else {
$order_intent = OsOrderIntentHelper::create_or_update_order_intent( self::$cart_object, self::$restrictions, self::$presets, '', self::get_customer_object_id() );
if ( $order_intent->is_processing() ) {
@@ -2464,7 +2472,7 @@
'timebox' => 'Time Boxes',
'timeline' => 'Timeline',
],
- OsStepsHelper::get_time_pick_style()
+ OsStepsHelper::get_time_pick_style()
);
$step_settings_html .= OsFormHelper::select_field(
'steps_settings[booking__datepicker][calendar_style]',
@@ -2473,7 +2481,7 @@
'modern' => 'Modern',
'classic' => 'Classic',
],
- OsStepsHelper::get_calendar_style()
+ OsStepsHelper::get_calendar_style()
);
$step_settings_html .= OsFormHelper::toggler_field( 'steps_settings[booking__datepicker][hide_timepicker_when_one_slot_available]', __( 'Hide time picker if single slot', 'latepoint' ), OsUtilHelper::is_on( self::get_step_setting_value( $selected_step_code, 'hide_timepicker_when_one_slot_available' ) ), false, false, [ 'sub_label' => __( 'If a single slot is available in a day, it will be preselected.', 'latepoint' ) ] );
$step_settings_html .= OsFormHelper::toggler_field( 'steps_settings[booking__datepicker][hide_slot_availability_count]', __( 'Hide slot availability count', 'latepoint' ), OsStepsHelper::hide_slot_availability_count(), false, false, [ 'sub_label' => __( 'Slot counter tooltip will not appear when hovering a day.', 'latepoint' ) ] );
@@ -2488,7 +2496,7 @@
'green' => __( 'Green', 'latepoint' ),
'yellow' => __( 'Yellow', 'latepoint' ),
],
- self::get_step_setting_value( $selected_step_code, 'order_confirmation_message_style', 'green' )
+ self::get_step_setting_value( $selected_step_code, 'order_confirmation_message_style', 'green' )
);
break;
}
@@ -3145,4 +3153,4 @@
];
}
}
-}
No newline at end of file
+}
--- a/latepoint/lib/misc/process_action.php
+++ b/latepoint/lib/misc/process_action.php
@@ -603,21 +603,21 @@
$preview_content_html = '';
switch ( $this->type ) {
case 'send_email':
- $preview_content_html .= '<div class="action-preview-subject"><span class="os-label">' . __( 'Subject:', 'latepoint' ) . '</span> ' . $this->prepared_data_for_run['subject'] . '</div>';
+ $preview_content_html .= '<div class="action-preview-subject"><span class="os-label">' . __( 'Subject:', 'latepoint' ) . '</span> ' . esc_html( $this->prepared_data_for_run['subject'] ) . '</div>';
$preview_content_html .= '<div class="action-preview-to"><span class="os-label">' . __( 'To:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $this->prepared_data_for_run['to'] ) . '</div>';
- $preview_content_html .= '<div class="action-preview-content">' . $this->prepared_data_for_run['content'] . '</div>';
+ $preview_content_html .= '<div class="action-preview-content">' . wp_kses_post( $this->prepared_data_for_run['content'] ) . '</div>';
break;
case 'send_sms':
$preview_content_html .= '<div class="action-preview-to"><span class="os-label">' . __( 'To:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $this->prepared_data_for_run['to'] ) . '</span></div>';
- $preview_content_html .= '<div class="action-preview-content">' . $this->prepared_data_for_run['content'] . '</div>';
+ $preview_content_html .= '<div class="action-preview-content">' . wp_kses_post( $this->prepared_data_for_run['content'] ) . '</div>';
break;
case 'send_whatsapp':
$preview_content_html .= '<div class="action-preview-to"><span class="os-label">' . __( 'To:', 'latepoint' ) . '</span><span class="os-value">' . esc_html( $this->prepared_data_for_run['to'] ) . '</span></div>';
$preview_content_html .= '<div class="action-preview-content">';
$preview_content_html .= '<div class="latepoint-whatsapp-template-preview-messages">';
$preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message">';
- $preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message-header">' . $this->prepared_data_for_run['content_for_header'] . '</div>';
- $preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message-body">' . $this->prepared_data_for_run['content_for_body'] . '</div>';
+ $preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message-header">' . wp_kses_post( $this->prepared_data_for_run['content_for_header'] ) . '</div>';
+ $preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message-body">' . wp_kses_post( $this->prepared_data_for_run['content_for_body'] ) . '</div>';
if ( $this->prepared_data_for_run['content_for_buttons'] ) {
$preview_content_html .= '<div class="latepoint-whatsapp-template-preview-message-buttons">';
foreach ( $this->prepared_data_for_run['content_for_buttons'] as $button ) {
--- a/latepoint/lib/models/customer_model.php
+++ b/latepoint/lib/models/customer_model.php
@@ -374,9 +374,18 @@
}
public function prepare_data_before_it_is_set( $data ) {
+ if ( isset( $data['first_name'] ) ) {
+ $data['first_name'] = sanitize_text_field( $data['first_name'] );
+ }
+ if ( isset( $data['last_name'] ) ) {
+ $data['last_name'] = sanitize_text_field( $data['last_name'] );
+ }
if ( isset( $data['phone'] ) ) {
$data['phone'] = OsUtilHelper::sanitize_phone_number( $data['phone'] );
}
+ if ( isset( $data['notes'] ) ) {
+ $data['notes'] = sanitize_textarea_field( $data['notes'] );
+ }
return $data;
}