<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>wirelab: wydania / releases</title>
<link>https://updates.wirelab.pl/</link>
<atom:link href="https://updates.wirelab.pl/feed.xml" rel="self" type="application/rss+xml"/>
<description>Nowe wersje pluginów i aplikacji wirelab. New versions of wirelab plugins and apps.</description>
<language>pl</language>
<lastBuildDate>Thu, 01 Oct 2026 14:42:38 +0000</lastBuildDate>
<ttl>360</ttl>
<item>
<title>Odznaki rang 1.2.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-rank-badges</link>
<guid isPermaLink="false">nodebb-plugin-rank-badges@1.2.0</guid>
<pubDate>Thu, 01 Oct 2026 14:34:48 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Update notices on the ACP page: &amp;quot;Version X is available — what&amp;#x27;s new&amp;quot;, linking to the release notes. The plugin fetches &lt;code&gt;https://updates.wirelab.pl/api/nodebb-plugin-rank-badges.json&lt;/code&gt; at most once a day (in the background and when the ACP page is opened, from a cache kept in the database; an hour after a failed attempt) with a plain &lt;code&gt;GET&lt;/code&gt;: no query string, no cookies, no data about the forum, &lt;code&gt;User-Agent: nodebb-plugin-rank-badges/&amp;lt;version&amp;gt;&lt;/code&gt;, 5 s timeout. Network errors are logged at verbose level only.&lt;/li&gt;
&lt;li&gt;&amp;quot;Check for updates&amp;quot; switch on the ACP page, on by default, saved on its own (settings hash &lt;code&gt;rank-badges-update-check&lt;/code&gt;). When it is off, no request is made at all.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lib/update-check.js&lt;/code&gt;, shared by the wirelab plugins; no new dependencies.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Ikony tematów 1.2.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-topic-icons</link>
<guid isPermaLink="false">nodebb-plugin-topic-icons@1.2.0</guid>
<pubDate>Thu, 01 Oct 2026 14:33:41 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Update notices on the ACP page: &amp;quot;Version X is available — what&amp;#x27;s new&amp;quot;, linking to the release notes. The plugin fetches &lt;code&gt;https://updates.wirelab.pl/api/nodebb-plugin-topic-icons.json&lt;/code&gt; at most once a day (in the background and when the ACP page is opened, from a cache kept in the database; an hour after a failed attempt) with a plain &lt;code&gt;GET&lt;/code&gt;: no query string, no cookies, no data about the forum, &lt;code&gt;User-Agent: nodebb-plugin-topic-icons/&amp;lt;version&amp;gt;&lt;/code&gt;, 5 s timeout. Network errors are logged at verbose level only.&lt;/li&gt;
&lt;li&gt;&amp;quot;Check for updates&amp;quot; switch on the ACP page, on by default, saved on its own (settings hash &lt;code&gt;topic-icons-update-check&lt;/code&gt;). When it is off, no request is made at all.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lib/update-check.js&lt;/code&gt;, shared by the wirelab plugins; no new dependencies.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Shoutbox 1.2.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-wirelab-shoutbox</link>
<guid isPermaLink="false">nodebb-plugin-wirelab-shoutbox@1.2.0</guid>
<pubDate>Thu, 01 Oct 2026 14:32:45 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Update notices on the ACP page: &amp;quot;Version X is available — what&amp;#x27;s new&amp;quot;, linking to the release notes. The plugin fetches &lt;code&gt;https://updates.wirelab.pl/api/nodebb-plugin-wirelab-shoutbox.json&lt;/code&gt; at most once a day (in the background and when the ACP page is opened, from a cache kept in the database; an hour after a failed attempt) with a plain &lt;code&gt;GET&lt;/code&gt;: no query string, no cookies, no data about the forum, &lt;code&gt;User-Agent: nodebb-plugin-wirelab-shoutbox/&amp;lt;version&amp;gt;&lt;/code&gt;, 5 s timeout. Network errors are logged at verbose level only.&lt;/li&gt;
&lt;li&gt;&amp;quot;Check for updates&amp;quot; switch on the ACP page, on by default, saved on its own (settings hash &lt;code&gt;shoutbox-update-check&lt;/code&gt;). When it is off, no request is made at all.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lib/update-check.js&lt;/code&gt;, shared by the wirelab plugins; no new dependencies.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Shoutbox 1.1.2</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-wirelab-shoutbox-1.1.2</link>
<guid isPermaLink="false">nodebb-plugin-wirelab-shoutbox@1.1.2</guid>
<pubDate>Thu, 01 Oct 2026 12:39:00 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Use express-rate-limit for the request limits. The ACP page limit is unchanged (60 loads per minute per user) and now comes from &lt;code&gt;express-rate-limit&lt;/code&gt; (new dependency), which replaces &lt;code&gt;lib/ratelimit.js&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Odznaki rang 1.1.2</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-rank-badges-1.1.2</link>
<guid isPermaLink="false">nodebb-plugin-rank-badges@1.1.2</guid>
<pubDate>Thu, 01 Oct 2026 12:37:56 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Use express-rate-limit for the request limits. Unchanged (60 ACP page loads and 300 &lt;code&gt;ladder&lt;/code&gt; requests per minute per user, guests per IP address, IPv6 grouped by /56) and now come from &lt;code&gt;express-rate-limit&lt;/code&gt; (new dependency), which replaces &lt;code&gt;lib/ratelimit.js&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Ikony tematów 1.1.2</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-topic-icons-1.1.2</link>
<guid isPermaLink="false">nodebb-plugin-topic-icons@1.1.2</guid>
<pubDate>Thu, 01 Oct 2026 12:37:52 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Use express-rate-limit and rebuild upload paths from a fixed directory. Request limits are unchanged (20 uploads, 60 ACP page loads and 300 API requests per minute per user, guests per IP address, IPv6 grouped by /56) and now come from &lt;code&gt;express-rate-limit&lt;/code&gt; (new dependency), which replaces &lt;code&gt;lib/ratelimit.js&lt;/code&gt;. The path of an uploaded file is rebuilt from the system temporary folder fixed at start-up and the bare file name, which must be a multer name (32 hex digits); it must still be a regular file and not a symbolic link.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Ikony tematów 1.1.1</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-topic-icons-1.1.1</link>
<guid isPermaLink="false">nodebb-plugin-topic-icons@1.1.1</guid>
<pubDate>Thu, 01 Oct 2026 11:24:37 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Uploads: only multer&amp;#x27;s temporary file is read, copied and deleted. Its path must resolve to a regular file inside the system temporary folder, without &lt;code&gt;..&lt;/code&gt; segments and not through a symbolic link (&lt;code&gt;lib/safe-path.js&lt;/code&gt;); anything else is refused. Applies to icon and category cover uploads.&lt;/li&gt;
&lt;li&gt;The clean-up of unused uploaded files accepts plain file names inside the plugin&amp;#x27;s upload folder only.&lt;/li&gt;
&lt;li&gt;Request limits per user (guests: per IP address), counted in memory without new dependencies (&lt;code&gt;lib/ratelimit.js&lt;/code&gt;): 20 uploads per minute, checked after the administrator check and before the file is received; 60 loads of the ACP page per minute; 300 requests per minute to the &lt;code&gt;choices&lt;/code&gt; and &lt;code&gt;icons&lt;/code&gt; API routes. Above the limit the answer is &lt;code&gt;429&lt;/code&gt; with &lt;code&gt;Retry-After&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Icons re-rendered in the viewer&amp;#x27;s language are built from the icon data with DOM methods (the URL checked again), no longer by inserting HTML from the API response.&lt;/li&gt;
&lt;li&gt;Findings reported by Snyk Code (CWE-23, CWE-770, CWE-79).&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Shoutbox 1.1.1</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-wirelab-shoutbox-1.1.1</link>
<guid isPermaLink="false">nodebb-plugin-wirelab-shoutbox@1.1.1</guid>
<pubDate>Thu, 01 Oct 2026 11:23:54 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The ACP page (active mutes and moderation log) is limited to 60 loads per minute per user, counted in memory without new dependencies (&lt;code&gt;lib/ratelimit.js&lt;/code&gt;); above that the answer is &lt;code&gt;429&lt;/code&gt; with &lt;code&gt;Retry-After&lt;/code&gt;. Finding reported by Snyk Code (CWE-770).&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Odznaki rang 1.1.1</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-rank-badges-1.1.1</link>
<guid isPermaLink="false">nodebb-plugin-rank-badges@1.1.1</guid>
<pubDate>Thu, 01 Oct 2026 11:23:29 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Security&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ACP preview and badges re-rendered in the viewer&amp;#x27;s language are built with DOM methods from the badge data that the ladder route now also returns (&lt;code&gt;view&lt;/code&gt;: classes, data attributes, colour, image, icon, bar, plain-text name and label; &lt;code&gt;lib/badge-dom.js&lt;/code&gt;). Classes, colours, icons and image URLs (forum paths or https only) are checked again in the browser; no HTML from the response is inserted any more. &lt;code&gt;html&lt;/code&gt; stays in the response for other consumers.&lt;/li&gt;
&lt;li&gt;Request limits per user (guests: per IP address), counted in memory without new dependencies (&lt;code&gt;lib/ratelimit.js&lt;/code&gt;): 60 loads of the ACP page and 300 requests to the ladder route per minute. Above the limit the answer is &lt;code&gt;429&lt;/code&gt; with &lt;code&gt;Retry-After&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Findings reported by Snyk Code (CWE-79, CWE-770).&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Ikony tematów 1.1.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-topic-icons-1.1.0</link>
<guid isPermaLink="false">nodebb-plugin-topic-icons@1.1.0</guid>
<pubDate>Thu, 01 Oct 2026 10:07:52 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Topic covers, working with NodeBB&amp;#x27;s topic thumbnails. A topic without thumbnails can show the first image of its first post (forum uploads; images from other sites only when allowed in the ACP) or the default cover of its category, in that order. Covers are added at display time and never saved as thumbnails, so a changed category cover shows everywhere at once. Each part can be switched off; the first image and images from other sites are off by default.&lt;/li&gt;
&lt;li&gt;The first image is looked up once per first post (topic field &lt;code&gt;coverScan&lt;/code&gt;), again when the first post is edited, so an image removed in an edit takes the cover away immediately; code blocks and comments are skipped.&lt;/li&gt;
&lt;li&gt;Uniform frame for topic thumbnails in lists and in the topic header: 4:3 or square, cropped, rounded, also in topic lists on phones (optional), dark mode through Bootstrap variables, topic title as &lt;code&gt;alt&lt;/code&gt; text; CSS custom properties &lt;code&gt;--topic-cover-*&lt;/code&gt; for themes.&lt;/li&gt;
&lt;li&gt;ACP: &amp;quot;Topic covers&amp;quot; section and a default cover per category (upload, site path or https URL), with a separate admin-only upload route (&lt;code&gt;upload-cover&lt;/code&gt;) for PNG, JPEG, WebP, GIF and SVG up to 2 MB; unused uploaded covers are deleted on save.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;topicCover&lt;/code&gt; in topic data for themes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Changed&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The ACP upload checks accept a list of types and a size limit per kind of upload; JPEG and GIF are recognised by content (icons still accept PNG, WebP and SVG only).&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Shoutbox 1.1.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-wirelab-shoutbox-1.1.0</link>
<guid isPermaLink="false">nodebb-plugin-wirelab-shoutbox@1.1.0</guid>
<pubDate>Thu, 01 Oct 2026 07:50:37 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The widget can be collapsed (*Collapse chat* / *Show chat*). When it is the only widget in the sidebar, the sidebar column disappears on large screens and the page takes the full width, with a narrow tab to bring it back; next to other widgets and on phones it folds to one line.&lt;/li&gt;
&lt;li&gt;The state is remembered in &lt;code&gt;localStorage&lt;/code&gt; and applied before the first paint by a small inline script in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; (no layout jump); &lt;code&gt;aria-expanded&lt;/code&gt; / &lt;code&gt;aria-controls&lt;/code&gt;, reduced motion respected.&lt;/li&gt;
&lt;li&gt;en-GB and pl strings &lt;code&gt;widget.collapse&lt;/code&gt;, &lt;code&gt;widget.expand&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
<item>
<title>Rozwiązane tematy 1.1.1</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-solved</link>
<guid isPermaLink="false">nodebb-plugin-solved@1.1.1</guid>
<pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate>
<category>nodebb-plugin</category>
<description>Prywatny plugin, aktualizacja skryptem wirelab. / Private plugin, updated with the wirelab deployment script.</description>
</item>
<item>
<title>Karta projektu 1.1.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-project-card</link>
<guid isPermaLink="false">nodebb-plugin-project-card@1.1.0</guid>
<pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate>
<category>nodebb-plugin</category>
<description>Prywatny plugin, aktualizacja skryptem wirelab. / Private plugin, updated with the wirelab deployment script.</description>
</item>
<item>
<title>Shoutbox 1.0.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-wirelab-shoutbox-1.0.0</link>
<guid isPermaLink="false">nodebb-plugin-wirelab-shoutbox@1.0.0</guid>
<pubDate>Wed, 30 Sep 2026 23:14:20 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;p&gt;First release. Requires NodeBB 4.15 or newer and Node.js 22 or newer.&lt;/p&gt;
&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Dock on every page (a modal bottom sheet on phones) with unread counter, mention marker, &amp;quot;new messages&amp;quot; pill, older messages on demand and the number of users online; &lt;code&gt;/?shoutbox=open&lt;/code&gt; opens it.&lt;/li&gt;
&lt;li&gt;Widget with the three latest messages and a button that opens the dock.&lt;/li&gt;
&lt;li&gt;Messages over the NodeBB websocket, stored in the NodeBB database (Redis, PostgreSQL, MongoDB); kept for 7 days or up to 2000 messages.&lt;/li&gt;
&lt;li&gt;Plain text with inline Markdown, http(s) autolinks, &lt;code&gt;@mentions&lt;/code&gt; with suggestions and notifications, emoji through nodebb-plugin-emoji; everything rendered and escaped on the server.&lt;/li&gt;
&lt;li&gt;Global privileges &lt;code&gt;shoutbox:read&lt;/code&gt;, &lt;code&gt;shoutbox:write&lt;/code&gt;, &lt;code&gt;shoutbox:moderate&lt;/code&gt;, granted once on first start to guests / registered users / Global Moderators.&lt;/li&gt;
&lt;li&gt;Writing rules configurable in the ACP: confirmed email, minimum account age, minimum forum posts, links from a rank level of nodebb-plugin-rank-badges or from a number of posts, rate limit.&lt;/li&gt;
&lt;li&gt;Moderation: delete messages, mute for 15 min, 1 h, 24 h or permanently with a reason; active mutes and a moderation log in the ACP.&lt;/li&gt;
&lt;li&gt;Configurable chat name (default: &amp;quot;Live&amp;quot; / &amp;quot;Na żywo&amp;quot; from the language files).&lt;/li&gt;
&lt;li&gt;Optional rank badge images next to names (nodebb-plugin-rank-badges).&lt;/li&gt;
&lt;li&gt;Accessible dock and mention list; reduced motion respected; colours as &lt;code&gt;--sb-*&lt;/code&gt; custom properties.&lt;/li&gt;
&lt;li&gt;en-GB and pl translations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[1.1.1]: https://github.com/nairdaweb/nodebb-plugin-wirelab-shoutbox/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/nairdaweb/nodebb-plugin-wirelab-shoutbox/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/nairdaweb/nodebb-plugin-wirelab-shoutbox/releases/tag/v1.0.0&lt;/p&gt;</description>
</item>
<item>
<title>Ikony tematów 1.0.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-topic-icons-1.0.0</link>
<guid isPermaLink="false">nodebb-plugin-topic-icons@1.0.0</guid>
<pubDate>Wed, 30 Sep 2026 23:08:54 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;p&gt;First release. Requires NodeBB 4.15 or newer and Node.js 22 or newer.&lt;/p&gt;
&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Icon picker in the composer (nodebb-plugin-composer-default) for new topics and when editing the first post, with the icons of the selected category and a preview of the topic row. Keyboard support (arrow keys, Home, End), focus returns to the button; the pick is kept in drafts; a current icon that is no longer available is marked and can be replaced or removed.&lt;/li&gt;
&lt;li&gt;ACP page: icon library (upload, rename, order, categories, active, remove with confirmation), per-category and forum-wide default icons, &amp;quot;who can choose&amp;quot; setting, display switches; category tree, warning about unsaved changes and about a missing group (a chooser group that no longer exists stays selected and is marked); validation in the browser and on the server.&lt;/li&gt;
&lt;li&gt;Icons in topic lists and the topic header, with &lt;code&gt;topicIcon&lt;/code&gt; in template and API data and a client-side fallback for themes without a slot; names in the viewer&amp;#x27;s language, also for guests on API routes and for topic lists loaded through API v3.&lt;/li&gt;
&lt;li&gt;Server-side rules for the picked icon: checked when a topic is posted, when it is put in the post queue and when the first post is edited; removing an icon needs the same right as setting one; an icon that became invalid while a topic waited in the queue is dropped on approval; a topic moved to a category where its icon is not available loses it.&lt;/li&gt;
&lt;li&gt;Removing an icon from the library clears it from its topics (per-icon index) and deletes uploaded images no icon uses.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getTopicIcons(tids, { lang })&lt;/code&gt; for other plugins and themes.&lt;/li&gt;
&lt;li&gt;Admin-only upload route (the administrator check runs before the file is received) with CSRF, type/content/size checks, refusal of SVGs with scripts, event handlers (also &lt;code&gt;&amp;lt;svg/onload=…&amp;gt;&lt;/code&gt;), external links or external style resources, and unique file names.&lt;/li&gt;
&lt;li&gt;Eight built-in SVG icons; en-GB and pl translations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[1.1.1]: https://github.com/nairdaweb/nodebb-plugin-topic-icons/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/nairdaweb/nodebb-plugin-topic-icons/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/nairdaweb/nodebb-plugin-topic-icons/releases/tag/v1.0.0&lt;/p&gt;</description>
</item>
<item>
<title>Odznaki rang 1.1.0</title>
<link>https://updates.wirelab.pl/#nodebb-plugin-rank-badges-1.1.0</link>
<guid isPermaLink="false">nodebb-plugin-rank-badges@1.1.0</guid>
<pubDate>Sun, 27 Sep 2026 20:09:49 +0000</pubDate>
<category>nodebb-plugin</category>
<description>&lt;h4&gt;Changed&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zero thresholds:&lt;/strong&gt; level 1 is the starting rank; for every other rank a threshold of 0 means &amp;quot;no requirement&amp;quot; and never grants the rank by itself. In &amp;quot;reputation only&amp;quot; mode the default ladder no longer puts every new user (also with negative reputation) at level 2; in &amp;quot;posts only&amp;quot; mode a rank with only a reputation threshold is no longer free. A later rank whose counted thresholds are all 0 cannot be reached, and the ACP says so.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Empty rank list&lt;/strong&gt; means no rank badges; the default ladder is used only until the settings are saved for the first time (previously an empty list silently brought back the six default ranks).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Group precedence:&lt;/strong&gt; administrators, then Global Moderators (including category moderators when enabled), then the other groups in list order. A category moderator who is also in another listed group now gets the Moderator badge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reputation disabled:&lt;/strong&gt; every mode counts posts only, so posts and profiles show the same rank.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hidden groups:&lt;/strong&gt; their badges are not shown unless the new per-group &amp;quot;Show if hidden&amp;quot; option is on; even then the group name is left out of &lt;code&gt;data-group&lt;/code&gt; and of &lt;code&gt;rankBadge.group&lt;/code&gt;. Badges of groups that do not exist are not shown.&lt;/li&gt;
&lt;li&gt;Group badges with a colour pick black or white text from the colour&amp;#x27;s luminance.&lt;/li&gt;
&lt;li&gt;Level bars of ladders with more than 10 ranks show &amp;quot;level/total&amp;quot;; long names end with an ellipsis.&lt;/li&gt;
&lt;li&gt;The public ladder route returns 403 to viewers who cannot read any category, and now also lists group badges (without group names) and an &lt;code&gt;id&lt;/code&gt; per badge.&lt;/li&gt;
&lt;li&gt;Requires Node.js 22 (as NodeBB 4.16 does). The redundant en-US language files were removed; en-US and other languages fall back to en-GB.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Fixed&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Badges in the viewer&amp;#x27;s language after ajaxify navigation, on infinite scroll, for new replies pushed over the websocket and in API responses (previously the forum default language).&lt;/li&gt;
&lt;li&gt;Translation tokens typed in rank or group names were expanded in &lt;code&gt;aria-label&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt;. Labels are now translated with a placeholder and the escaped name is inserted afterwards; &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; are encoded as &lt;code&gt;&amp;amp;lsqb;&lt;/code&gt; / &lt;code&gt;&amp;amp;rsqb;&lt;/code&gt;, which NodeBB&amp;#x27;s translator leaves alone.&lt;/li&gt;
&lt;li&gt;A badge rendered from the old settings could stay cached after the settings were saved (race between rendering and invalidation). Caches are written only when the settings did not change in the meantime, and rendered badges are keyed by the settings generation.&lt;/li&gt;
&lt;li&gt;Caches use least-recently-used eviction instead of being emptied when full, so many &lt;code&gt;?lang=&lt;/code&gt; values on the public ladder route no longer flush the badges in use.&lt;/li&gt;
&lt;li&gt;ACP: saving shows a confirmation or the error; a failed load disables saving instead of letting the defaults overwrite the stored settings.&lt;/li&gt;
&lt;li&gt;ACP: thresholds such as &lt;code&gt;1e3&lt;/code&gt; were saved as 1; only integers written with digits are accepted now, in the ACP and on the server.&lt;/li&gt;
&lt;li&gt;ACP: a rank without a name was saved and shown as an empty badge; it is refused now, and a rank without any name renders as &amp;quot;Rank N&amp;quot;.&lt;/li&gt;
&lt;li&gt;ACP: names in languages removed from &amp;quot;Languages for rank names&amp;quot; stayed active but invisible; they are deleted on save.&lt;/li&gt;
&lt;li&gt;Upload with &lt;code&gt;relative_path&lt;/code&gt;: only a leading prefix is removed (a file named &lt;code&gt;forum-logo.png&lt;/code&gt; on a forum in &lt;code&gt;/forum&lt;/code&gt; lost part of its name).&lt;/li&gt;
&lt;li&gt;Upload: the file type (PNG, JPG, WebP, GIF, SVG) and size (512 KB) are checked in the browser, and each file gets a unique name, so uploads no longer overwrite each other.&lt;/li&gt;
&lt;li&gt;An image that fails to load falls back to the level bar, the group icon or a generic icon, also when the level bar is turned off.&lt;/li&gt;
&lt;li&gt;Presets: every folder in &lt;code&gt;presets/&lt;/code&gt; with a &lt;code&gt;preset.json&lt;/code&gt; is offered, as documented (previously only &lt;code&gt;wirelab&lt;/code&gt;); preset ids and image file names are validated.&lt;/li&gt;
&lt;li&gt;Zero-width and bidirectional control characters are removed from names.&lt;/li&gt;
&lt;li&gt;Inaccurate code comments and documentation (escaping, upload checks, search results).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Added&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ACP translated into English and Polish, with validation errors and warnings (ranks out of order, equal or unreachable ranks, empty rank list, missing or hidden groups, reputation disabled).&lt;/li&gt;
&lt;li&gt;Server-side validation of the settings (&lt;code&gt;filter:settings.set&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;referrerpolicy=&amp;quot;no-referrer&amp;quot;&lt;/code&gt; on badge images.&lt;/li&gt;
&lt;li&gt;Tests for the rank rules, validation, group precedence, escaping with a translator, hidden groups, contrast, language choice and the LRU cache; the logic moved from &lt;code&gt;library.js&lt;/code&gt; to &lt;code&gt;lib/&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Removed&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Unused translation key &lt;code&gt;ladder.title&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
</item>
</channel>
</rss>
