NodeBB
Node.js based forum software built for the modern web
Alternative to: discourse, vanilla forums, circle
v4.15.0
2026-08-12Release build (minor) of NodeBB @ 2026-08-12T20:56:36.190Z
v4.15.0 (2026-08-12)
New Features
- fediverse: allow chat and chat:privileged privileges for fediverse group (915b6acc)
- update uploads to look nicer ™️ (5cdf3aa5)
- when clicking group membership request notification (24b781c3)
- pass opts to filter:user.create and action:user.create (95e7da9c)
- add missing translations for admin restart/rebuild messages (fd3de041)
- activitypub:
- add ap-serve-cache for actors.note and actors.replies (632feba9)
- opportunistically backfill remote topics on queue approval (cb893e19)
- add global age cutoff for incoming post categorization (d8c7486d)
- topic: instant vote UI with rollback for topic and world feed (9f09ee90)
- settings: add toggle to disable IP address logging (db662ff6)
- intents: gate intents logic behind activitypubEnabled config (acdd63dd)
Bug Fixes
-
activitypub:
- use raw content for source in notes.private (3ddadff3)
- add image attachments to chat message notes (abb9663b)
- #14583, add join system messages in assertPrivate alongside addUsersToRoom (3481ca0e)
- validate emoji icon URLs before rendering (7da65694)
- always filter loopback URIs from remote actor persistence (b1222bfb)
- gate TLD requirement on activitypubAllowLoopback (12896b06)
- validate emoji icon URLs before rendering (c0d94a21)
- align middleware keyId extraction with library last-wins behavior (d30f4c2f)
- treat failed signed GET as anonymous instead of 400 (e11c9fc5)
- align middleware keyId extraction with library last-wins behavior (219f0609)
- return 404 for soft-deleted topics (ca48534e)
- refetch object when Update arrives via Announce (c4813e42)
- enforce chat policy in assertPrivate (1528c541)
- reject array-valued attributedTo in inbox origin check (7a071a31)
- reject actors with spoofed id hostname (c0d6d0e2)
- use createtime check for Accept handler instead of follow target (6e7c057d)
- fall through to getParentChain for local topic contexts (189d6366)
- validate webfinger subject hostname to prevent cache poisoning (d3c82555)
- treat failed signed GET as anonymous instead of 400 (44eade67)
- always broadcast relay activities to relay followers (f82c7c8e)
- add existence guards to announce functions (14cfd56f)
- resolve actor from attributedTo in feps.announce (ffd1c50e)
- skip re-broadcast for relayed activities and guard tid check (f18eebed)
- wrap relay broadcast in Announce activity (c8dd4f18)
- send full Follow activity as Accept object for unsolicited follows (9d44d1a5)
- implement relay follower management and broadcast (e2f11847)
- federate posts accepted from post queue (a46e2efe)
- use raw body buffer for digest verification (2d0e90b8)
- do not prune banned remote users (0ead3e37)
- group cid check with createish in announce protection (935cb2a1)
- enforce attributedTo origin check in inbox handlers (870ec669)
- collapse nested Announces in inbox.announce handler (a1d3c492)
- pass digest to _sendMessage in retryFailedMessages (aa072276)
- validate attributedTo origin in assertPrivate (8df796ee)
-
don’t expose user existence if visitor can’t view users (#12447) (61a7a0aa)
-
api url in chats (10b56785)
-
non string messages (713069bf)
-
chat switch, and error display if route is 404 and its not a v3 route (6415d646)
-
wrap on groups (9e148758)
-
only load templates from templates folder (c17452e7)
-
closes #14600, supported nested translations in tx() (251903ef)
-
group descriptions that have links in them on groups listing (287f87d8)
-
padding and ff (d1806d49)
-
export
request.checkfor use inweb-push(280324e7) -
translations (0fbb8616)
-
translation of admin reauth modal (c2fa1707)
-
reject SSO auth via callback handler, if state parameter isn’t passed in by client (unless checkState is false) (6ba24ed8)
-
block off access to Announce(anything but object) from non-cids (1b04a1ab)
-
user name (6f397572)
-
handle both local and remote users’ aboutme identically (488c24ec)
-
guard title regeneration in inbox.update behind posts.isMain (295cdef3)
-
replace outdated .includes() check for AP header in webfinger query method, in favour of Helpers.assertAccept (14c63234)
-
match cid checks in inbox.move with that of inbox.remove (60577d01)
-
restore old behaviour where AP requests to retrieve a note are always done as AP user (4e2fb6f9)
-
parse post data when sending notifications when schedule topics are posted (041f3ba7)
-
#14428, dont log ip in chats/posts/user login/events (455b9f59)
-
layout on errors/analytics (f0bb5f40)
-
save stack trace to db when AP sendError is called (c9d05b28)
-
notifications where bodyLong is a translation string (99691b2e)
-
handle relative_paths in signature verification (227a7e49)
-
on user deletion, remove any generated keys as well (8e35a15f)
-
swap order of checks (rfc first, then draft) (6f60d773)
-
add missing dependency, fix typo (9978f060)
-
signatures as part of ActivityPub object, make calculateDigest an internal method in signatures.js (62104963)
-
add translation for relays.stats—1 (d4906f99)
-
ghost button when data-bs-theme=“dark” is used (ac055a16)
-
mising translations (5aad9c1e)
-
add mb-2 on reject container (7ae6a65c)
-
client-side re-parsing translate bug, tests fix (d3c2327d)
-
vote tooltip, translateKey html escapes already (de00780d)
-
include bare announces in ‘createish’ conditional (e60e12f1)
-
translate (ae65675c)
-
translate test notif email bodyLong (2961473f)
-
notiication email (2fd8b67f)
-
don’t send null into filter:parse.raw (eb50f820)
-
move ban/mute lang keys to the client (4a6bdcd8)
-
encode uid in post queue author (1d96555b)
-
silent return when cid matching protection fails for inbox.announce (502b8149)
-
raise bodyParser limit to 1mb (32de3c00)
-
move post restoration earlier in the chain of events for
inbox.update, because post editing is not allowed if a post is deleted (fae9946c) -
object reference detection in
inbox.announce(d03f54dd) -
move back Annonce(Delete)-specific checks back into its own case (1aaba34b)
-
move Announce(Delete) protections upstream so they also cover Announce(Update) and Announce(Like)… or pretty much anything that isn’t an Announce(Create) or Announce(Note-ish) (ab8e7a48)
-
remove rss_token from exported user profile data (6776cc4d)
-
upgrade privilege check in
api.users.addEmailto checkadmin:usersinstead of justprivileges.users.canEdit, the former of which excludes global moderators (35deb33c) -
tooltip display up themes (202472c9)
-
date selector modal (58b479f5)
-
widgets tx (22dfaa15)
-
dont award ap users (272e9524)
-
pass _18n to compileRender (21f1edc1)
-
use outerHTML so we dont lose wrapping element (c51285bd)
-
filter private category data from crossposts and events (4dfe3009)
-
topics:
- check postingRestrictedToMods mask for remote categories (bfc559eb)
- check postingRestrictedToMods mask for remote categories (6f5607e0)
- require topics:read on source category for owner topic moves (42d6706e)
-
request: add response size limit to prevent memory exhaustion (0f2cc702)
-
post-queue:
- remove socket call for custom reasons by fetching in controller (#14573) (f8d946c8)
- correct category update logic and template regression (6b203c0f)
-
tests:
- grant fediverse group global chat privileges (57b02015)
- verify activitypub announce in crosspost controller flow (67e2f9cd)
-
privileges: route ActivityPub URIs to fediverse pseudo-user check (2da82dbb)
-
auth:
- clear session info when switching users in doLogin (7ef88c37)
- clear session info when switching users in doLogin (dbe448c3)
-
socket.io:
- add topics:read privilege check to loadPostTools (060fb128)
- restrict moderation note editing to admins and original authors (d92eb01d)
-
user: search local and remote users in parallel for partial queries (81323d34)
-
install: reword admin setup warning for clarity (fa5d97a7)
-
posts:
- suppress edit notifications when content unchanged (0acf962d)
- prevent phantom post objects when toPid references non-existent parent (228730f3)
-
minifier: wait for in-flight requests before killing children (23273831)
-
test: use nconf.get(‘url’) in relay broadcast test (b1ddbeb3)
-
cache: add resetAll() to tracker and use in test mock (c98f22f9)
-
users: bind email existence check to requested uid (53e3294e)
-
api:
- exclude cookie header from buildReqObject to prevent session token exposure in post queue (a593b0b0)
- require admin:admins-mods to modify administrators group membership (9ddaec72)
Refactors
- dont crash if null user passed (b770c4d0)
- change to exact match (32bfc96d)
- require reauth on token routes (d87a51b3)
- use write api instead of sockets (c6e8cd8e)
- fallback error string (7bd73114)
- reduce gap (99a4ea06)
- show private/public badge and creation date (abee65d8)
- remove unnecessary txEscapes for 4.15.0 (7a8cc077)
- show stack trace of missing store (19ddee27)
- use api module, get rid of old code (95a80611)
- remove dupe (66ba2101)
- make a single call (7c5422aa)
- show postcount/reputation and group owner text (e9beb469)
- remove world from tags unless requested (beac7c5e)
- upgrade HTTP signature logic to RFC 9421 standard (fb27a657)
- show extension (8fd62b15)
- remove setting hours when updating graph (81b9d0ca)
- getDailyStats (8618d403)
- remove log (eaee9403)
- get rid of unnecessary new Promise (808ad4fc)
- remove datetime, it’s ovewritten in notifications.create (1c38912c)
- translate chat system messages on the backend (6d702226)
- rewards check (8641d47c)
- #14376, migrate translations to use tx (64ed84e6)
- use tx in all admin tpls (24825791)
- federation: move blocklist view modal to a dedicated partial (1f78b445)
- activitypub:
- migrate HTTP message signatures to
@misskey-devlibrary (a7af21a0) - unify relay state into single sorted set with signed scores (adaa376f)
- replace filter with three-tier action system (ca93eda8)
- privilege-filter outbox via category-driven post sets (765d39a4)
- migrate HTTP message signatures to
Tests
- add missing 401 responses (42cf0443)
- fix email test (5d32e427)
- fix tests (bb00277e)
- fix messaging test (ba47a299)
- remove dupe test, was already added on develop (737b458d)
- fix messaging tests (d90a0fb4)
- create test users sequentially :facepalm: (5e46d284)
- be more explicit about ownership test data (b628bfc7)
- fix group ownership schema data for tests (aceea229)
- inbox: fix ap inbox tests (580fd5b4)
- activitypub: add cross-domain actorUri test for Helpers.query (26296e6c)
- relays: test issue where an unecessarily strict .deepStrictEqual was causing test failures due to a race condition (a541c1fe)