From b2e14e9e00350d2cadfef1f08e0241a55f637610 Mon Sep 17 00:00:00 2001 From: Alex Kirk Date: Thu, 19 Dec 2024 14:21:33 +0100 Subject: [PATCH] Add test for HTML in direct messages (#1093) Co-authored-by: Matthias Pfefferle --- CHANGELOG.md | 6 +++ includes/class-mailer.php | 9 +++- readme.txt | 4 ++ tests/includes/class-test-mailer.php | 66 ++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc16e41..5b0be9d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Improved + +* Direct Messages: Improve HTML to e-mail text conversion + ## [4.5.1] - 2024-12-18 ### Improved diff --git a/includes/class-mailer.php b/includes/class-mailer.php index de479b10..ceec4c66 100644 --- a/includes/class-mailer.php +++ b/includes/class-mailer.php @@ -171,10 +171,17 @@ public static function direct_message( $activity, $user_id ) { $email = $user->user_email; } + $content = \html_entity_decode( + \wp_strip_all_tags( + str_replace( '

', PHP_EOL . PHP_EOL, $activity['object']['content'] ) + ), + ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 + ); + /* translators: 1: Blog name, 2 Actor name */ $subject = \sprintf( \esc_html__( '[%1$s] Direct Message from: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \esc_html( $actor['name'] ) ); /* translators: 1: Blog name, 2: Actor name */ - $message = \sprintf( \esc_html__( 'New Direct Message: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \wp_strip_all_tags( $activity['object']['content'] ) ) . "\r\n\r\n"; + $message = \sprintf( \esc_html__( 'New Direct Message: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), $content ) . "\r\n\r\n"; /* translators: Actor name */ $message .= \sprintf( \esc_html__( 'From: %s', 'activitypub' ), \esc_html( $actor['name'] ) ) . "\r\n"; /* translators: Actor URL */ diff --git a/readme.txt b/readme.txt index bd14ea97..b7977494 100644 --- a/readme.txt +++ b/readme.txt @@ -132,6 +132,10 @@ For reasons of data protection, it is not possible to see the followers of other == Changelog == += Unreleased = + +* Improved: HTML to e-mail text conversion + = 4.5.1 = * Improved: Reactions block: Remove the `wp-block-editor` dependency for frontend views diff --git a/tests/includes/class-test-mailer.php b/tests/includes/class-test-mailer.php index 78b596b0..a424be08 100644 --- a/tests/includes/class-test-mailer.php +++ b/tests/includes/class-test-mailer.php @@ -307,4 +307,70 @@ function ( $args ) { remove_all_filters( 'wp_mail' ); wp_delete_user( $user_id ); } + + /** + * Data provider for direct message notification text. + * + * @return array + */ + public function direct_message_text_provider() { + return array( + 'HTML entities' => array( + json_decode( '"

Interesting story from @test<\/span><\/a><\/span> about people who don't own their own domain.<\/p>

"This is not a new issue, of course, but Service\u2019s implementation shows limitations."<\/p>"' ), + 'Interesting story from @test about people who don\'t own their own domain.' . PHP_EOL . PHP_EOL . '"This is not a new issue, of course, but Service’s implementation shows limitations."', + ), + 'invalid HTML' => array( + json_decode( '" 'https://example.com/author', + 'object' => array( + 'content' => $text, + ), + ); + + // Mock remote metadata. + add_filter( + 'pre_get_remote_metadata_by_actor', + function () { + return array( + 'name' => 'Test Sender', + 'url' => 'https://example.com/author', + ); + } + ); + + // Capture email. + add_filter( + 'wp_mail', + function ( $args ) use ( $expected, $user_id ) { + $this->assertStringContainsString( $expected, $args['message'] ); + $this->assertEquals( get_user_by( 'id', $user_id )->user_email, $args['to'] ); + return $args; + } + ); + + Mailer::direct_message( $activity, $user_id ); + + // Clean up. + remove_all_filters( 'pre_get_remote_metadata_by_actor' ); + remove_all_filters( 'wp_mail' ); + wp_delete_user( $user_id ); + } }