diff --git a/public/class-gdpr-requests-public.php b/public/class-gdpr-requests-public.php index 90f1c1d8..5f7da29d 100644 --- a/public/class-gdpr-requests-public.php +++ b/public/class-gdpr-requests-public.php @@ -40,7 +40,7 @@ public function delete_user( $user, $index ) { if ( parent::remove_from_requests( $index ) ) { $token = GDPR::generate_pin(); - GDPR_Email::send( $user->user_email, 'delete-resolved', array( 'token' => $token ) ); + GDPR_Email::send( $this->get_escaped_user_email_address( $user ), 'delete-resolved', array( 'token' => $token ) ); GDPR_Audit_Log::log( $user->ID, esc_html__( 'User was removed from the site.', 'gdpr' ) ); GDPR_Audit_Log::export_log( $user->ID, $token ); wp_delete_user( $user->ID ); @@ -194,14 +194,15 @@ public function send_request_email() { break; } - $key = parent::add_to_requests( $user->user_email, $type, $data ); + $escaped_user_email = $this->get_escaped_user_email_address( $user ); + $key = parent::add_to_requests( $escaped_user_email, $type, $data ); if ( 'export-data' !== $type ) { $email_args['confirm_url'] = add_query_arg( array( 'type' => $type, 'key' => $key, - 'email' => $user->user_email, + 'email' => $escaped_user_email, ), home_url() ); @@ -210,7 +211,7 @@ public function send_request_email() { array( 'type' => $type, 'key' => $key, - 'email' => $user->user_email, + 'email' => $escaped_user_email, 'format' => 'xml', ), home_url() @@ -219,7 +220,7 @@ public function send_request_email() { array( 'type' => $type, 'key' => $key, - 'email' => $user->user_email, + 'email' => $escaped_user_email, 'format' => 'json', ), home_url() @@ -227,7 +228,7 @@ public function send_request_email() { } if ( GDPR_Email::send( - $user->user_email, + $escaped_user_email, "{$type}-request", $email_args ) ) { @@ -376,7 +377,7 @@ public function request_confirmed() { $format = isset( $_GET['format'] ) ? sanitize_text_field( wp_unslash( $_GET['format'] ) ) : 'xml'; // WPCS: Input var ok, CSRF ok. /* translators: File format. Can be XML or JSON */ GDPR_Audit_Log::log( $user->ID, sprintf( esc_html__( 'User downloaded all their data in %s format.', 'gdpr' ), $format ) ); - $this->file_export_data( $user->user_email, $format, $key ); + $this->file_export_data( $this->get_escaped_user_email_address( $user ), $format, $key ); break; } } @@ -404,4 +405,39 @@ private function file_export_data( $email, $format, $key ) { } die(); } + + /** + * Provides escaping for uncommon, yet valid email address characters. + * + * @param string $email_in The starting email address. + * + * @return mixed|string + */ + private function escape_email_address( $email_in = '' ) { + $email_out = ''; + $email_string_length = \strlen( $email_in ); + + for ( $i = 0; $i < $email_string_length; $i++ ) { + $hex = dechex( ord( $email_in[ $i ] ) ); + if ('' === $hex) { + $email_out .= rawurlencode( $email_in[ $i ] ); + } else { + $email_out = $email_out . '%' . ( ( 1 === strlen( $hex ) ) ? ( '0' . strtoupper( $hex ) ) : strtoupper( $hex ) ); + } + } + $email_out = str_replace( array( '+', '_', '.', '-' ), array( '%20', '%5F', '%2E', '%2D' ), $email_out ); + + return $email_out; + } + + /** + * Get the escpaed user email address. + * + * @param WP_User $user the User object. + * + * @return mixed|string + */ + private function get_escaped_user_email_address( WP_User $user ) { + return $this->escape_email_address( $user->user_email ); + } } diff --git a/public/partials/confirmation-screens.php b/public/partials/confirmation-screens.php index 10e02252..48e715e1 100644 --- a/public/partials/confirmation-screens.php +++ b/public/partials/confirmation-screens.php @@ -55,7 +55,7 @@

diff --git a/src/js/public/gdpr-public.js b/src/js/public/gdpr-public.js index b40c44de..e1719bba 100644 --- a/src/js/public/gdpr-public.js +++ b/src/js/public/gdpr-public.js @@ -98,17 +98,16 @@ $(document).on('submit', '.gdpr-privacy-preferences-frm', function(e) { e.preventDefault(); - var that = $(this); var formData = $(this).serialize(); $.post( GDPR.ajaxurl, formData, - function(response) { - if ( response.success ) { + function(response, textStatus, xhr) { + if ( 200 === xhr.status ) { Cookies.set('gdpr[privacy_bar]', 1, { expires: 365 }); if ( GDPR.refresh ) { - window.location.reload(); + window.location.reload( true ); } else { var scrollDistance = $('body').css('top'); $('.gdpr-overlay').fadeOut(); @@ -116,6 +115,7 @@ $(window).scrollTop(Math.abs( parseInt( scrollDistance, 10 ) ) ); $('.gdpr.gdpr-privacy-preferences .gdpr-wrapper').fadeOut(); $('.gdpr-privacy-bar').fadeOut(); + $( document ).trigger( 'updatedPrivacyPreferences' ); } } else { displayNotification( response.data.title, response.data.content );