diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 1a9300881..6101f5479 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -29,12 +29,10 @@ use Friendica\Content\Item; use Friendica\Content\OEmbed; use Friendica\Content\PageInfo; use Friendica\Content\Smilies; -use Friendica\Content\Text\HTMLPurifier_URIScheme_cid; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; -use Friendica\Core\System; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Event; @@ -1877,28 +1875,23 @@ class BBCode $text ); - \HTMLPurifier_URISchemeRegistry::instance()->register('cid', new HTMLPurifier_URIScheme_cid()); + // Default iframe allowed domains/path + $allowedIframeDomains = [ + DI::baseUrl()->getHostname() + . (DI::baseUrl()->getUrlPath() ? '/' . DI::baseUrl()->getUrlPath() : '') + . '/oembed/', # The path part has to change with the source in Content\Oembed::iframe + 'www.youtube.com/embed/', + 'player.vimeo.com/video/', + ]; - $config = \HTMLPurifier_HTML5Config::createDefault(); - $config->set('HTML.Doctype', 'HTML5'); - $config->set('HTML.SafeIframe', true); - $config->set('URI.SafeIframeRegexp', '%^(?: - https://www.youtube.com/embed/ - | - https://player.vimeo.com/video/ - | - ' . DI::baseUrl() . '/oembed/ # Has to change with the source in Content\Oembed::iframe - )%xi'); - $config->set('Attr.AllowedRel', [ - 'noreferrer' => true, - 'noopener' => true, - ]); - $config->set('Attr.AllowedFrameTargets', [ - '_blank' => true, - ]); + $allowedIframeDomains = array_merge( + $allowedIframeDomains, + DI::config()->get('system', 'allowed_oembed') ? + explode(',', DI::config()->get('system', 'allowed_oembed')) + : [] + ); - $HTMLPurifier = new \HTMLPurifier($config); - $text = $HTMLPurifier->purify($text); + $text = HTML::purify($text, $allowedIframeDomains); return $text; } diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php index 975be8b1f..c77b84db8 100644 --- a/src/Content/Text/HTML.php +++ b/src/Content/Text/HTML.php @@ -961,4 +961,63 @@ class HTML { return str_replace('&', '&', $s); } + + /** + * Clean an HTML text for potentially harmful code + * + * @param string $text + * @param array $allowedIframeDomains List of allowed iframe source domains without the scheme + * @return string + */ + public static function purify(string $text, array $allowedIframeDomains = []): string + { + // Allows cid: URL scheme + \HTMLPurifier_URISchemeRegistry::instance()->register('cid', new HTMLPurifier_URIScheme_cid()); + + $config = \HTMLPurifier_HTML5Config::createDefault(); + $config->set('HTML.Doctype', 'HTML5'); + + // Used to remove iframe with src attribute filtered out + $config->set('AutoFormat.RemoveEmpty', true); + + $config->set('HTML.SafeIframe', true); + + array_walk($allowedIframeDomains, function (&$domain) { + // Allow the domain and all its eventual sub-domains + $domain = '(?:(?!-)[A-Za-z0-9-]{1,63}(?set('URI.SafeIframeRegexp', + '%^https://(?: + ' . implode('|', $allowedIframeDomains) . ' + ) + (?:/|$) # Prevents bogus domains like youtube.com.fake.tld + %xi' + ); + + $config->set('Attr.AllowedRel', [ + 'noreferrer' => true, + 'noopener' => true, + ]); + $config->set('Attr.AllowedFrameTargets', [ + '_blank' => true, + ]); + + /* Uncomment to debug HTMLPurifier behavior + $config->set('Core.CollectErrors', true); + $config->set('Core.MaintainLineNumbers', true); + */ + + $HTMLPurifier = new \HTMLPurifier($config); + + $text = $HTMLPurifier->purify($text); + + /** @var \HTMLPurifier_ErrorCollector $errorCollector */ + /* Uncomment to debug HTML Purifier behavior + $errorCollector = $HTMLPurifier->context->get('ErrorCollector'); + var_dump($errorCollector->getRaw()); + */ + + return $text; + } } diff --git a/src/Module/Admin/Site.php b/src/Module/Admin/Site.php index 8cd2648cf..dff2a1076 100644 --- a/src/Module/Admin/Site.php +++ b/src/Module/Admin/Site.php @@ -624,7 +624,7 @@ class Site extends BaseAdmin '$allowed_sites' => ['allowed_sites', DI::l10n()->t('Allowed friend domains'), DI::config()->get('system', 'allowed_sites'), DI::l10n()->t('Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains')], '$allowed_email' => ['allowed_email', DI::l10n()->t('Allowed email domains'), DI::config()->get('system', 'allowed_email'), DI::l10n()->t('Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains')], '$no_oembed_rich_content' => ['no_oembed_rich_content', DI::l10n()->t('No OEmbed rich content'), DI::config()->get('system', 'no_oembed_rich_content'), DI::l10n()->t('Don\'t show the rich content (e.g. embedded PDF), except from the domains listed below.')], - '$allowed_oembed' => ['allowed_oembed', DI::l10n()->t('Allowed OEmbed domains'), DI::config()->get('system', 'allowed_oembed'), DI::l10n()->t('Comma separated list of domains which oembed content is allowed to be displayed. Wildcards are accepted.')], + '$allowed_oembed' => ['allowed_oembed', DI::l10n()->t('Trusted third-party domains'), DI::config()->get('system', 'allowed_oembed'), DI::l10n()->t('Comma separated list of domains from which content is allowed to be embedded in posts like with OEmbed. All sub-domains of the listed domains are allowed as well.')], '$block_public' => ['block_public', DI::l10n()->t('Block public'), DI::config()->get('system', 'block_public'), DI::l10n()->t('Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.')], '$force_publish' => ['publish_all', DI::l10n()->t('Force publish'), DI::config()->get('system', 'publish_all'), DI::l10n()->t('Check to force all profiles on this site to be listed in the site directory.') . '' . DI::l10n()->t('Enabling this may violate privacy laws like the GDPR') . ''], '$global_directory' => ['directory', DI::l10n()->t('Global directory URL'), DI::config()->get('system', 'directory'), DI::l10n()->t('URL to the global directory. If this is not set, the global directory is completely unavailable to the application.')], diff --git a/src/Module/Debug/Babel.php b/src/Module/Debug/Babel.php index 322b742fb..52f661445 100644 --- a/src/Module/Debug/Babel.php +++ b/src/Module/Debug/Babel.php @@ -180,9 +180,7 @@ class Babel extends BaseModule 'content' => $html ]; - $config = \HTMLPurifier_Config::createDefault(); - $HTMLPurifier = new \HTMLPurifier($config); - $purified = $HTMLPurifier->purify($html); + $purified = Text\HTML::purify($html); $results[] = [ 'title' => DI::l10n()->t('HTML Purified (raw)'), diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php index 2eb5d1903..b34ddd355 100644 --- a/tests/src/Content/Text/BBCodeTest.php +++ b/tests/src/Content/Text/BBCodeTest.php @@ -63,6 +63,9 @@ class BBCodeTest extends MockedTest $this->configMock->shouldReceive('get') ->with('system', 'big_emojis') ->andReturn(false); + $this->configMock->shouldReceive('get') + ->with('system', 'allowed_oembed') + ->andReturn(''); $l10nMock = Mockery::mock(L10n::class); $l10nMock->shouldReceive('t')->withAnyArgs()->andReturnUsing(function ($args) { return $args; }); @@ -75,6 +78,8 @@ class BBCodeTest extends MockedTest $this->dice->shouldReceive('create') ->with(BaseURL::class) ->andReturn($baseUrlMock); + $baseUrlMock->shouldReceive('getHostname')->withNoArgs()->andReturn('friendica.local'); + $baseUrlMock->shouldReceive('getUrlPath')->withNoArgs()->andReturn(''); $config = \HTMLPurifier_HTML5Config::createDefault(); $config->set('HTML.Doctype', 'HTML5'); diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 574fcd739..80b1cbbc2 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2021.03-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-03-10 09:43-0500\n" +"POT-Creation-Date: 2021-03-14 13:43-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -912,7 +912,7 @@ msgstr "" msgid "Previous" msgstr "" -#: mod/cal.php:277 mod/events.php:421 src/Module/Install.php:196 +#: mod/cal.php:277 mod/events.php:421 src/Module/Install.php:207 msgid "Next" msgstr "" @@ -1290,12 +1290,12 @@ msgstr "" #: src/Module/Admin/Blocklist/Server.php:99 #: src/Module/Admin/Blocklist/Server.php:100 #: src/Module/Admin/Item/Delete.php:70 src/Module/Debug/Probe.php:60 -#: src/Module/Install.php:189 src/Module/Install.php:222 -#: src/Module/Install.php:227 src/Module/Install.php:246 -#: src/Module/Install.php:257 src/Module/Install.php:262 +#: src/Module/Install.php:200 src/Module/Install.php:233 +#: src/Module/Install.php:238 src/Module/Install.php:257 #: src/Module/Install.php:268 src/Module/Install.php:273 -#: src/Module/Install.php:287 src/Module/Install.php:302 -#: src/Module/Install.php:329 src/Module/Register.php:135 +#: src/Module/Install.php:279 src/Module/Install.php:284 +#: src/Module/Install.php:298 src/Module/Install.php:313 +#: src/Module/Install.php:340 src/Module/Register.php:135 #: src/Module/Security/TwoFactor/Verify.php:99 #: src/Module/Settings/TwoFactor/Index.php:133 #: src/Module/Settings/TwoFactor/Verify.php:141 @@ -1341,11 +1341,11 @@ msgstr "" #: src/Module/Admin/Item/Source.php:65 src/Module/Contact/Advanced.php:132 #: src/Module/Contact/Poke.php:155 src/Module/Contact.php:604 #: src/Module/Debug/ActivityPubConversion.php:141 -#: src/Module/Debug/Babel.php:315 src/Module/Debug/Localtime.php:64 +#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Probe.php:55 src/Module/Debug/WebFinger.php:53 #: src/Module/Delegation.php:152 src/Module/FriendSuggest.php:129 -#: src/Module/Install.php:234 src/Module/Install.php:276 -#: src/Module/Install.php:313 src/Module/Invite.php:175 +#: src/Module/Install.php:245 src/Module/Install.php:287 +#: src/Module/Install.php:324 src/Module/Invite.php:175 #: src/Module/Item/Compose.php:144 src/Module/Profile/Profile.php:243 #: src/Module/Settings/Profile/Index.php:237 src/Object/Post.php:954 #: view/theme/duepuntozero/config.php:69 view/theme/frio/config.php:160 @@ -2058,7 +2058,7 @@ msgid "Resubscribing to OStatus contacts" msgstr "" #: mod/repair_ostatus.php:50 src/Module/Debug/ActivityPubConversion.php:130 -#: src/Module/Debug/Babel.php:295 src/Module/Security/TwoFactor/Verify.php:96 +#: src/Module/Debug/Babel.php:293 src/Module/Security/TwoFactor/Verify.php:96 msgid "Error" msgid_plural "Errors" msgstr[0] "" @@ -3198,7 +3198,7 @@ msgstr "" msgid "Email" msgstr "" -#: src/Content/ContactSelector.php:127 src/Module/Debug/Babel.php:309 +#: src/Content/ContactSelector.php:127 src/Module/Debug/Babel.php:307 msgid "Diaspora" msgstr "" @@ -3620,11 +3620,11 @@ msgstr "" msgid "Site map" msgstr "" -#: src/Content/OEmbed.php:269 +#: src/Content/OEmbed.php:270 msgid "Embedding disabled" msgstr "" -#: src/Content/OEmbed.php:387 +#: src/Content/OEmbed.php:388 msgid "Embedded content" msgstr "" @@ -3636,39 +3636,39 @@ msgstr "" msgid "last" msgstr "" -#: src/Content/Text/BBCode.php:963 src/Content/Text/BBCode.php:1607 -#: src/Content/Text/BBCode.php:1608 +#: src/Content/Text/BBCode.php:961 src/Content/Text/BBCode.php:1605 +#: src/Content/Text/BBCode.php:1606 msgid "Image/photo" msgstr "" -#: src/Content/Text/BBCode.php:1065 +#: src/Content/Text/BBCode.php:1063 #, php-format msgid "" "%2$s %3$s" msgstr "" -#: src/Content/Text/BBCode.php:1090 src/Model/Item.php:2732 +#: src/Content/Text/BBCode.php:1088 src/Model/Item.php:2732 #: src/Model/Item.php:2738 msgid "link to source" msgstr "" -#: src/Content/Text/BBCode.php:1525 src/Content/Text/HTML.php:947 +#: src/Content/Text/BBCode.php:1523 src/Content/Text/HTML.php:947 msgid "Click to open/close" msgstr "" -#: src/Content/Text/BBCode.php:1556 +#: src/Content/Text/BBCode.php:1554 msgid "$1 wrote:" msgstr "" -#: src/Content/Text/BBCode.php:1610 src/Content/Text/BBCode.php:1611 +#: src/Content/Text/BBCode.php:1608 src/Content/Text/BBCode.php:1609 msgid "Encrypted content" msgstr "" -#: src/Content/Text/BBCode.php:1824 +#: src/Content/Text/BBCode.php:1822 msgid "Invalid source protocol" msgstr "" -#: src/Content/Text/BBCode.php:1839 +#: src/Content/Text/BBCode.php:1837 msgid "Invalid link protocol" msgstr "" @@ -3916,8 +3916,8 @@ msgid "" "or mysql." msgstr "" -#: src/Core/Installer.php:199 src/Module/Install.php:195 -#: src/Module/Install.php:354 +#: src/Core/Installer.php:199 src/Module/Install.php:206 +#: src/Module/Install.php:365 msgid "Please see the file \"doc/INSTALL.md\"." msgstr "" @@ -5822,15 +5822,15 @@ msgstr "" msgid "Open" msgstr "" -#: src/Module/Admin/Site.php:522 src/Module/Install.php:204 +#: src/Module/Admin/Site.php:522 src/Module/Install.php:215 msgid "No SSL policy, links will track page SSL state" msgstr "" -#: src/Module/Admin/Site.php:523 src/Module/Install.php:205 +#: src/Module/Admin/Site.php:523 src/Module/Install.php:216 msgid "Force all links to use SSL" msgstr "" -#: src/Module/Admin/Site.php:524 src/Module/Install.php:206 +#: src/Module/Admin/Site.php:524 src/Module/Install.php:217 msgid "Self-signed certificate, use SSL for local links only (discouraged)" msgstr "" @@ -5993,11 +5993,11 @@ msgstr "" msgid "Theme for mobile devices" msgstr "" -#: src/Module/Admin/Site.php:608 src/Module/Install.php:214 +#: src/Module/Admin/Site.php:608 src/Module/Install.php:225 msgid "SSL link policy" msgstr "" -#: src/Module/Admin/Site.php:608 src/Module/Install.php:216 +#: src/Module/Admin/Site.php:608 src/Module/Install.php:227 msgid "Determines whether generated links should be forced to use SSL" msgstr "" @@ -6149,13 +6149,14 @@ msgid "" msgstr "" #: src/Module/Admin/Site.php:627 -msgid "Allowed OEmbed domains" +msgid "Trusted third-party domains" msgstr "" #: src/Module/Admin/Site.php:627 msgid "" -"Comma separated list of domains which oembed content is allowed to be " -"displayed. Wildcards are accepted." +"Comma separated list of domains from which content is allowed to be embedded " +"in posts like with OEmbed. All sub-domains of the listed domains are allowed " +"as well." msgstr "" #: src/Module/Admin/Site.php:628 @@ -8063,87 +8064,87 @@ msgstr "" msgid "HTML Input" msgstr "" -#: src/Module/Debug/Babel.php:188 +#: src/Module/Debug/Babel.php:186 msgid "HTML Purified (raw)" msgstr "" -#: src/Module/Debug/Babel.php:193 +#: src/Module/Debug/Babel.php:191 msgid "HTML Purified (hex)" msgstr "" -#: src/Module/Debug/Babel.php:198 +#: src/Module/Debug/Babel.php:196 msgid "HTML Purified" msgstr "" -#: src/Module/Debug/Babel.php:204 +#: src/Module/Debug/Babel.php:202 msgid "HTML::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:210 +#: src/Module/Debug/Babel.php:208 msgid "HTML::toBBCode => BBCode::convert" msgstr "" -#: src/Module/Debug/Babel.php:215 +#: src/Module/Debug/Babel.php:213 msgid "HTML::toBBCode => BBCode::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:221 +#: src/Module/Debug/Babel.php:219 msgid "HTML::toBBCode => BBCode::toPlaintext" msgstr "" -#: src/Module/Debug/Babel.php:227 +#: src/Module/Debug/Babel.php:225 msgid "HTML::toMarkdown" msgstr "" -#: src/Module/Debug/Babel.php:233 +#: src/Module/Debug/Babel.php:231 msgid "HTML::toPlaintext" msgstr "" -#: src/Module/Debug/Babel.php:239 +#: src/Module/Debug/Babel.php:237 msgid "HTML::toPlaintext (compact)" msgstr "" -#: src/Module/Debug/Babel.php:257 +#: src/Module/Debug/Babel.php:255 msgid "Decoded post" msgstr "" -#: src/Module/Debug/Babel.php:278 +#: src/Module/Debug/Babel.php:276 msgid "Post array before expand entities" msgstr "" -#: src/Module/Debug/Babel.php:285 +#: src/Module/Debug/Babel.php:283 msgid "Post converted" msgstr "" -#: src/Module/Debug/Babel.php:290 +#: src/Module/Debug/Babel.php:288 msgid "Converted body" msgstr "" -#: src/Module/Debug/Babel.php:296 +#: src/Module/Debug/Babel.php:294 msgid "Twitter addon is absent from the addon/ folder." msgstr "" -#: src/Module/Debug/Babel.php:306 +#: src/Module/Debug/Babel.php:304 msgid "Babel Diagnostic" msgstr "" -#: src/Module/Debug/Babel.php:307 +#: src/Module/Debug/Babel.php:305 msgid "Source text" msgstr "" -#: src/Module/Debug/Babel.php:308 +#: src/Module/Debug/Babel.php:306 msgid "BBCode" msgstr "" -#: src/Module/Debug/Babel.php:310 +#: src/Module/Debug/Babel.php:308 msgid "Markdown" msgstr "" -#: src/Module/Debug/Babel.php:311 +#: src/Module/Debug/Babel.php:309 msgid "HTML" msgstr "" -#: src/Module/Debug/Babel.php:313 +#: src/Module/Debug/Babel.php:311 msgid "Twitter Source / Tweet URL (requires API key)" msgstr "" @@ -8420,155 +8421,155 @@ msgstr "" msgid "Method Not Allowed." msgstr "" -#: src/Module/Install.php:177 +#: src/Module/Install.php:188 msgid "Friendica Communications Server - Setup" msgstr "" -#: src/Module/Install.php:188 +#: src/Module/Install.php:199 msgid "System check" msgstr "" -#: src/Module/Install.php:190 src/Module/Install.php:247 -#: src/Module/Install.php:330 +#: src/Module/Install.php:201 src/Module/Install.php:258 +#: src/Module/Install.php:341 msgid "Requirement not satisfied" msgstr "" -#: src/Module/Install.php:191 +#: src/Module/Install.php:202 msgid "Optional requirement not satisfied" msgstr "" -#: src/Module/Install.php:192 +#: src/Module/Install.php:203 msgid "OK" msgstr "" -#: src/Module/Install.php:197 +#: src/Module/Install.php:208 msgid "Check again" msgstr "" -#: src/Module/Install.php:212 +#: src/Module/Install.php:223 msgid "Base settings" msgstr "" -#: src/Module/Install.php:219 +#: src/Module/Install.php:230 msgid "Host name" msgstr "" -#: src/Module/Install.php:221 +#: src/Module/Install.php:232 msgid "" "Overwrite this field in case the determinated hostname isn't right, " "otherweise leave it as is." msgstr "" -#: src/Module/Install.php:224 +#: src/Module/Install.php:235 msgid "Base path to installation" msgstr "" -#: src/Module/Install.php:226 +#: src/Module/Install.php:237 msgid "" "If the system cannot detect the correct path to your installation, enter the " "correct path here. This setting should only be set if you are using a " "restricted system and symbolic links to your webroot." msgstr "" -#: src/Module/Install.php:229 +#: src/Module/Install.php:240 msgid "Sub path of the URL" msgstr "" -#: src/Module/Install.php:231 +#: src/Module/Install.php:242 msgid "" "Overwrite this field in case the sub path determination isn't right, " "otherwise leave it as is. Leaving this field blank means the installation is " "at the base URL without sub path." msgstr "" -#: src/Module/Install.php:242 +#: src/Module/Install.php:253 msgid "Database connection" msgstr "" -#: src/Module/Install.php:243 +#: src/Module/Install.php:254 msgid "" "In order to install Friendica we need to know how to connect to your " "database." msgstr "" -#: src/Module/Install.php:244 +#: src/Module/Install.php:255 msgid "" "Please contact your hosting provider or site administrator if you have " "questions about these settings." msgstr "" -#: src/Module/Install.php:245 +#: src/Module/Install.php:256 msgid "" "The database you specify below should already exist. If it does not, please " "create it before continuing." msgstr "" -#: src/Module/Install.php:254 +#: src/Module/Install.php:265 msgid "Database Server Name" msgstr "" -#: src/Module/Install.php:259 +#: src/Module/Install.php:270 msgid "Database Login Name" msgstr "" -#: src/Module/Install.php:265 +#: src/Module/Install.php:276 msgid "Database Login Password" msgstr "" -#: src/Module/Install.php:267 +#: src/Module/Install.php:278 msgid "For security reasons the password must not be empty" msgstr "" -#: src/Module/Install.php:270 +#: src/Module/Install.php:281 msgid "Database Name" msgstr "" -#: src/Module/Install.php:274 src/Module/Install.php:304 +#: src/Module/Install.php:285 src/Module/Install.php:315 msgid "Please select a default timezone for your website" msgstr "" -#: src/Module/Install.php:289 +#: src/Module/Install.php:300 msgid "Site settings" msgstr "" -#: src/Module/Install.php:299 +#: src/Module/Install.php:310 msgid "Site administrator email address" msgstr "" -#: src/Module/Install.php:301 +#: src/Module/Install.php:312 msgid "" "Your account email address must match this in order to use the web admin " "panel." msgstr "" -#: src/Module/Install.php:308 +#: src/Module/Install.php:319 msgid "System Language:" msgstr "" -#: src/Module/Install.php:310 +#: src/Module/Install.php:321 msgid "" "Set the default language for your Friendica installation interface and to " "send emails." msgstr "" -#: src/Module/Install.php:322 +#: src/Module/Install.php:333 msgid "Your Friendica site database has been installed." msgstr "" -#: src/Module/Install.php:332 +#: src/Module/Install.php:343 msgid "Installation finished" msgstr "" -#: src/Module/Install.php:352 +#: src/Module/Install.php:363 msgid "

What next

" msgstr "" -#: src/Module/Install.php:353 +#: src/Module/Install.php:364 msgid "" "IMPORTANT: You will need to [manually] setup a scheduled task for the worker." msgstr "" -#: src/Module/Install.php:356 +#: src/Module/Install.php:367 #, php-format msgid "" "Go to your new Friendica node registration page " @@ -10427,7 +10428,7 @@ msgstr "" msgid "Show fewer" msgstr "" -#: src/Protocol/Diaspora.php:3414 +#: src/Protocol/Diaspora.php:3443 msgid "Attachments:" msgstr ""