diff --git a/.github/changelog/2082-from-description b/.github/changelog/2082-from-description new file mode 100644 index 000000000..b0adafae8 --- /dev/null +++ b/.github/changelog/2082-from-description @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix malformed ActivityPub handles for users with email-based logins (e.g., from Site Kit Google authentication) diff --git a/includes/model/class-user.php b/includes/model/class-user.php index 0facb74d3..948a46513 100644 --- a/includes/model/class-user.php +++ b/includes/model/class-user.php @@ -169,7 +169,14 @@ public function get_alternate_url() { * @return string The preferred username. */ public function get_preferred_username() { - return \get_the_author_meta( 'login', $this->_id ); + $login = \get_the_author_meta( 'login', $this->_id ); + + // Handle cases where login is an email address (e.g., from Site Kit Google login). + if ( \filter_var( $login, FILTER_VALIDATE_EMAIL ) ) { + $login = \get_the_author_meta( 'user_nicename', $this->_id ); + } + + return $login; } /** diff --git a/tests/includes/model/class-test-user.php b/tests/includes/model/class-test-user.php index a0d207176..56234dc6d 100644 --- a/tests/includes/model/class-test-user.php +++ b/tests/includes/model/class-test-user.php @@ -128,4 +128,50 @@ public function test_get_moved_to() { $this->assertArrayHasKey( 'movedTo', $user ); $this->assertSame( 'https://example.com', $user['movedTo'] ); } + + /** + * Test that email-based usernames are properly sanitized for ActivityPub handles. + * + * @covers ::get_preferred_username + * @covers ::get_webfinger + */ + public function test_email_username_sanitization() { + // Test with email-based login (e.g., from Site Kit Google login). + $user_id = self::factory()->user->create( + array( + 'role' => 'author', + 'user_login' => 'testuser123@gmail.com', + ) + ); + $user = User::from_wp_user( $user_id ); + + // Preferred username should be sanitized. + $this->assertSame( 'testuser123gmail-com', $user->get_preferred_username() ); + + // Webfinger should not have double @. + $expected_webfinger = 'testuser123gmail-com@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); + $this->assertSame( $expected_webfinger, $user->get_webfinger() ); + + // Test another email format. + $user_id2 = self::factory()->user->create( + array( + 'role' => 'author', + 'user_login' => 'admin@googlemail.com', + ) + ); + $user2 = User::from_wp_user( $user_id2 ); + + $this->assertSame( 'admingooglemail-com', $user2->get_preferred_username() ); + + // Test normal username (no email) remains unchanged. + $user_id3 = self::factory()->user->create( + array( + 'role' => 'author', + 'user_login' => 'normaluser', + ) + ); + $user3 = User::from_wp_user( $user_id3 ); + + $this->assertSame( 'normaluser', $user3->get_preferred_username() ); + } }