diff --git a/CHANGELOG.md b/CHANGELOG.md index 540621ebaf..5728c63beb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,113 @@ +#### v4.4.0 (2025-05-14) + +##### Breaking Changes + +* removal of deprecated privilege hooks (8ea377a4) +* removal of `filter:flags.getFilters` (547fb482) +* removal of `filter:user.verify.code` (7e25946c) +* removal of `filter:post.purge` (df5c1a93) +* removal of `filter:post.purge` (c84b72fb) +* removal of `filter:router.page` (9d8061ea) +* removal of `filter:email.send` (b73a8d3e) + +##### Chores + +* **deps:** + * update redis docker tag to v8.0.1 (#13415) (fbe97b4e) + * update redis docker tag to v8 (#13387) (1df7313c) + * update postgres docker tag to v17.5 (#13398) (d319b0aa) + * update dependency sass-embedded to v1.88.0 (#13402) (694c79bc) + * update dependency lint-staged to v16 (#13404) (9d877481) + * update commitlint monorepo to v19.8.1 (#13394) (7a7a4f0a) + * update dependency lint-staged to v15.5.2 (#13383) (96dc5c89) + * update dependency @eslint/js to v9.26.0 (#13371) (450ce3b8) + * update dependency mocha to v11.2.2 (#13366) (e958010f) +* incrementing version number - v4.3.2 (b92b5d80) +* update changelog for v4.3.2 (0aa9c187) +* incrementing version number - v4.3.1 (308e6b9f) +* remove unused require (15b6a2c1) +* incrementing version number - v4.3.0 (bff291db) +* incrementing version number - v4.2.2 (17fecc24) +* incrementing version number - v4.2.1 (852a270c) +* incrementing version number - v4.2.0 (87581958) +* incrementing version number - v4.1.1 (b2afbb16) +* incrementing version number - v4.1.0 (36c80850) +* incrementing version number - v4.0.6 (4a52fb2e) +* incrementing version number - v4.0.5 (1792a62b) +* incrementing version number - v4.0.4 (b1125cce) +* incrementing version number - v4.0.3 (2b65c735) +* incrementing version number - v4.0.2 (73fe5fcf) +* incrementing version number - v4.0.1 (a461b758) +* incrementing version number - v4.0.0 (c1eaee45) + +##### Documentation Changes + +* remove since-removed `labels` property from api (860ac895) + +##### Bug Fixes + +* adjust Peertube-specific handling to shove mp4 into post attachments, #13324 (799b08db) +* #13081, don't add mention when you are replying to yourself (d5865613) +* add `announces` to postdataobject schema (0f576a42) +* #13375, plus additional tests (fe13c755) +* missing awaits, more comprehensive 1b12 tests (5802c7dd) +* another case (6bfe4e62) +* handle missing orderedItems property in followers route (e042201f) +* missing await (651ebaaf) +* handle missing orderedItems (53bb0bbc) +* extra `orderedItems` property in generated paginated OrderedCollection, #13153 (f83b1fbf) +* #13153, follower and following collections to use generateCollection helper (a2de7aae) +* #13374, updates to posts.edit to handle remote content updates better (b4338489) +* leftover `handle` var (625ce96f) +* AP inbox update handling for non-note objects (f8d012c8) +* 1b12 creates being dropped (9f80d10d) +* update AP api (un)follow ids to be url encoded id instead of handle (7cf61ab0) +* **deps:** + * update dependency diff to v8 (#13409) (919d62ab) + * update dependency sanitize-html to v2.17.0 (#13418) (3e18af1e) + * update dependency satori to v0.13.1 (#13408) (f176d6b2) + * update dependency pg-cursor to v2.15.0 (#13414) (7320a858) + * update dependency nodebb-plugin-markdown to v13.2.1 (#13416) (84b8ecc7) + * update dependency semver to v7.7.2 (#13410) (366651d6) + * update dependency pg to v8.16.0 (#13411) (0825c569) + * update dependency nodebb-plugin-mentions to v4.7.6 (#13417) (383a7ce5) + * update dependency lru-cache to v11 (#12685) (23374fd7) + * update dependency rimraf to v6 (#12686) (6a4ffe02) + * update dependency bootswatch to v5.3.6 (#13400) (7a7cf830) + * update dependency csrf-sync to v4.2.1 (#13401) (ecce9998) + * update dependency sass to v1.88.0 (#13403) (7ffba218) + * update dependency nodemailer to v7.0.3 (#13395) (af3afba0) + * update dependency nodemailer to v7 (#13381) (0b4d403c) + * update dependency csrf-sync to v4.2.0 (#13364) (4f0f67a4) + * update dependency webpack to v5.99.8 (#13390) (c7a164ae) + * update dependency bootstrap to v5.3.6 (#13384) (e6a19612) + * update dependency esbuild to v0.25.4 (#13385) (b6f4de5b) + * update dependency @fontsource/poppins to v5.2.6 (#13376) (e2a8cf98) + * update dependency nodebb-plugin-mentions to v4.7.5 (#13386) (2c0aba02) + * update dependency nodebb-widget-essentials to v7.0.38 (#13380) (7f757615) + * update dependency nodebb-theme-persona to v14.1.11 (#13379) (954aa541) + * update dependency nodebb-theme-peace to v2.2.42 (#13378) (2aa0bfc5) + * update dependency nodebb-theme-harmony to v2.1.12 (#13377) (72b3a215) + * update dependency ace-builds to v1.41.0 (#13372) (4b78710b) + * bump markdown (f3bd8590) + +##### Other Changes + +* //github.com/NodeBB/NodeBB/issues/13367 (39953ee1) + +##### Refactors + +* use a single until (1b0b1da6) +* Helpers.generateCollection so that total count and a bound function can be passed in, #13153 (7f59238d) + +##### Tests + +* a few additional tests for announce handling (61f6806b) +* fix regression from 5802c7ddd9506a4e296f6dbdf2d9a32621c7f4ef (5b118904) +* fix broken test due to adjusted note assertion relation logic (9dc91f11) +* update filter:router.page tests to response:router.page (a819d39c) +* adjustment for now-removed labels property (52df41b9) + #### v4.3.2 (2025-05-12) ##### Chores diff --git a/install/package.json b/install/package.json index dde27f60ed..90f4f723ba 100644 --- a/install/package.json +++ b/install/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPL-3.0", "description": "NodeBB Forum", - "version": "4.3.2", + "version": "4.4.0", "homepage": "https://www.nodebb.org", "repository": { "type": "git", @@ -200,4 +200,4 @@ "url": "https://github.com/barisusakli" } ] -} +} \ No newline at end of file diff --git a/src/activitypub/mocks.js b/src/activitypub/mocks.js index f2a8446d4a..76cc8af01b 100644 --- a/src/activitypub/mocks.js +++ b/src/activitypub/mocks.js @@ -42,7 +42,7 @@ const sanitizeConfig = { Mocks._normalize = async (object) => { // Normalized incoming AP objects into expected types for easier mocking - let { type, attributedTo, url, image, content, source, attachment } = object; + let { type, attributedTo, url, image, mediaType, content, source, attachment } = object; switch (true) { // non-string attributedTo handling case Array.isArray(attributedTo): { @@ -70,6 +70,9 @@ Mocks._normalize = async (object) => { if (sourceContent) { content = null; sourceContent = await activitypub.helpers.remoteAnchorToLocalProfile(sourceContent, true); + } else if (mediaType === 'text/markdown') { + sourceContent = await activitypub.helpers.remoteAnchorToLocalProfile(content, true); + content = null; } else if (content && content.length) { content = sanitize(content, sanitizeConfig); content = await activitypub.helpers.remoteAnchorToLocalProfile(content); @@ -107,9 +110,9 @@ Mocks._normalize = async (object) => { const stream = url.reduce((memo, { type, mediaType, tag }) => { if (!memo) { if (type === 'Link' && mediaType === 'application/x-mpegURL') { - memo = tag.reduce((memo, { type, mediaType, href }) => { + memo = tag.reduce((memo, { type, mediaType, href, width, height }) => { if (!memo && (type === 'Link' && mediaType === 'video/mp4')) { - memo = { type, mediaType, href }; + memo = { mediaType, href, width, height }; } return memo; diff --git a/src/user/digest.js b/src/user/digest.js index 61f4b2f12f..77bc2e93e5 100644 --- a/src/user/digest.js +++ b/src/user/digest.js @@ -88,13 +88,20 @@ Digest.send = async function (data) { return emailsSent; } let errorLogged = false; + const date = new Date(); await batch.processArray(data.subscribers, async (uids) => { - let userData = await user.getUsersFields(uids, ['uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline']); - userData = userData.filter(u => u && u.email && (meta.config.includeUnverifiedEmails || u['email:confirmed'])); + let userData = await user.getUsersFields(uids, [ + 'uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline', + ]); + userData = userData.filter( + u => u && u.email && (meta.config.includeUnverifiedEmails || u['email:confirmed']) + ); if (!userData.length) { return; } - await Promise.all(userData.map(async (userObj) => { + const userSettings = await user.getMultipleUserSettings(userData.map(u => u.uid)); + await Promise.all(userData.map(async (userObj, index) => { + const userSetting = userSettings[index]; const [publicRooms, notifications, topics] = await Promise.all([ getUnreadPublicRooms(userObj.uid), user.notifications.getUnreadInterval(userObj.uid, data.interval), @@ -118,9 +125,8 @@ Digest.send = async function (data) { }); emailsSent += 1; - const now = new Date(); await emailer.send('digest', userObj.uid, { - subject: `[[email:digest.subject, ${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}]]`, + subject: `[[email:digest.subject, ${date.toLocaleDateString(userSetting.userLang)}]]`, username: userObj.username, userslug: userObj.userslug, notifications: unreadNotifs,