Merge branch 'master' into develop

This commit is contained in:
Julian Lam
2025-05-15 14:00:20 -04:00
4 changed files with 129 additions and 10 deletions

View File

@@ -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) #### v4.3.2 (2025-05-12)
##### Chores ##### Chores

View File

@@ -2,7 +2,7 @@
"name": "nodebb", "name": "nodebb",
"license": "GPL-3.0", "license": "GPL-3.0",
"description": "NodeBB Forum", "description": "NodeBB Forum",
"version": "4.3.2", "version": "4.4.0",
"homepage": "https://www.nodebb.org", "homepage": "https://www.nodebb.org",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -42,7 +42,7 @@ const sanitizeConfig = {
Mocks._normalize = async (object) => { Mocks._normalize = async (object) => {
// Normalized incoming AP objects into expected types for easier mocking // 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 switch (true) { // non-string attributedTo handling
case Array.isArray(attributedTo): { case Array.isArray(attributedTo): {
@@ -70,6 +70,9 @@ Mocks._normalize = async (object) => {
if (sourceContent) { if (sourceContent) {
content = null; content = null;
sourceContent = await activitypub.helpers.remoteAnchorToLocalProfile(sourceContent, true); 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) { } else if (content && content.length) {
content = sanitize(content, sanitizeConfig); content = sanitize(content, sanitizeConfig);
content = await activitypub.helpers.remoteAnchorToLocalProfile(content); content = await activitypub.helpers.remoteAnchorToLocalProfile(content);
@@ -107,9 +110,9 @@ Mocks._normalize = async (object) => {
const stream = url.reduce((memo, { type, mediaType, tag }) => { const stream = url.reduce((memo, { type, mediaType, tag }) => {
if (!memo) { if (!memo) {
if (type === 'Link' && mediaType === 'application/x-mpegURL') { 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')) { if (!memo && (type === 'Link' && mediaType === 'video/mp4')) {
memo = { type, mediaType, href }; memo = { mediaType, href, width, height };
} }
return memo; return memo;

View File

@@ -88,13 +88,20 @@ Digest.send = async function (data) {
return emailsSent; return emailsSent;
} }
let errorLogged = false; let errorLogged = false;
const date = new Date();
await batch.processArray(data.subscribers, async (uids) => { await batch.processArray(data.subscribers, async (uids) => {
let userData = await user.getUsersFields(uids, ['uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline']); let userData = await user.getUsersFields(uids, [
userData = userData.filter(u => u && u.email && (meta.config.includeUnverifiedEmails || u['email:confirmed'])); 'uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline',
]);
userData = userData.filter(
u => u && u.email && (meta.config.includeUnverifiedEmails || u['email:confirmed'])
);
if (!userData.length) { if (!userData.length) {
return; 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([ const [publicRooms, notifications, topics] = await Promise.all([
getUnreadPublicRooms(userObj.uid), getUnreadPublicRooms(userObj.uid),
user.notifications.getUnreadInterval(userObj.uid, data.interval), user.notifications.getUnreadInterval(userObj.uid, data.interval),
@@ -118,9 +125,8 @@ Digest.send = async function (data) {
}); });
emailsSent += 1; emailsSent += 1;
const now = new Date();
await emailer.send('digest', userObj.uid, { 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, username: userObj.username,
userslug: userObj.userslug, userslug: userObj.userslug,
notifications: unreadNotifs, notifications: unreadNotifs,