fix: Mastodon preserves safe HTML (strong, em, a, p, br) instead of stripping everything

This commit is contained in:
Paulo Castellano 2026-04-01 12:05:22 -03:00
parent a1df51234b
commit 57ad4e2c7f
2 changed files with 34 additions and 0 deletions

View file

@ -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 <strong>/<b> to Unicode bold characters for LinkedIn

View file

@ -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('<p>Hello <strong>world</strong> and <em>italic</em></p>', Platform::Mastodon);
expect($result)->toContain('<strong>world</strong>');
expect($result)->toContain('<em>italic</em>');
expect($result)->toContain('<p>');
});
test('it strips unsafe html for mastodon', function () {
$sanitizer = new ContentSanitizer;
$result = $sanitizer->sanitize('<p>Hello</p><script>alert("xss")</script><div>block</div>', Platform::Mastodon);
expect($result)->toContain('<p>Hello</p>');
expect($result)->not->toContain('<script>');
expect($result)->not->toContain('<div>');
});
test('it preserves links for mastodon', function () {
$sanitizer = new ContentSanitizer;
$result = $sanitizer->sanitize('<p>Check <a href="https://example.com">this</a></p>', Platform::Mastodon);
expect($result)->toContain('<a href="https://example.com">this</a>');
});