diff --git a/app/Services/Social/ContentSanitizer.php b/app/Services/Social/ContentSanitizer.php index 9caf900f..f5f73e50 100644 --- a/app/Services/Social/ContentSanitizer.php +++ b/app/Services/Social/ContentSanitizer.php @@ -12,6 +12,7 @@ public function sanitize(string $content, Platform $platform): string { return match ($platform) { Platform::LinkedIn, Platform::LinkedInPage => $this->convertBoldAndStrip($content), + Platform::Mastodon => $this->stripUnsafeHtml($content), default => $this->stripHtml($content), }; } @@ -41,6 +42,17 @@ private function stripHtml(string $content): string return trim($content); } + private function stripUnsafeHtml(string $content): string + { + // Mastodon accepts a subset of HTML: p, strong, em, a, br, span + $content = strip_tags($content, ['p', 'strong', 'em', 'b', 'i', 'a', 'br', 'span']); + + // Decode HTML entities that aren't part of allowed tags + $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + + return trim($content); + } + private function convertBoldAndStrip(string $content): string { // Convert / to Unicode bold characters for LinkedIn diff --git a/tests/Unit/Services/Social/ContentSanitizerTest.php b/tests/Unit/Services/Social/ContentSanitizerTest.php index a2b073bd..dd508444 100644 --- a/tests/Unit/Services/Social/ContentSanitizerTest.php +++ b/tests/Unit/Services/Social/ContentSanitizerTest.php @@ -54,3 +54,25 @@ expect($result)->toContain('- Item one'); expect($result)->toContain('- Item two'); }); + +test('it preserves safe html for mastodon', function () { + $sanitizer = new ContentSanitizer; + $result = $sanitizer->sanitize('

Hello world and italic

', Platform::Mastodon); + expect($result)->toContain('world'); + expect($result)->toContain('italic'); + expect($result)->toContain('

'); +}); + +test('it strips unsafe html for mastodon', function () { + $sanitizer = new ContentSanitizer; + $result = $sanitizer->sanitize('

Hello

block
', Platform::Mastodon); + expect($result)->toContain('

Hello

'); + expect($result)->not->toContain('