Merge commit '1bda90731aed8f0ee3d2ef665db8348c4a93a669' into v3.x

isekai-main
Misty Release Bot 2 years ago
commit a39c4ab3fb

@ -1,3 +1,304 @@
#### v3.2.0 (2023-06-28)
##### Chores
* **deps:**
* update dependency lint-staged to v13.2.3 (#11762) (26af152a)
* update commitlint monorepo to v17.6.6 (#11750) (a19e7b5c)
* update dependency sass-embedded to v1.63.6 (#11742) (8a961794)
* update dependency sass-embedded to v1.63.5 (#11738) (94d1dbc7)
* update dependency eslint to v8.43.0 (#11722) (7beadb6b)
* update coverallsapp/github-action action to v2.2.0 (#11690) (9282bc58)
* update dependency eslint to v8.42.0 (#11672) (55e5467d)
* update commitlint monorepo to v17.6.5 (#11648) (3b53f415)
* update dependency jsdom to v22.1.0 (#11640) (9a5d39c0)
* update dependency smtp-server to v3.12.0 (#11628) (57e3f999)
* update dependency eslint to v8.41.0 (#11616) (70bb50cd)
* update redis docker tag to v7 (#10830) (f1e2342d)
* update dependency jquery to v3.7.0 (#11591) (12c03130)
* up harmony (94013139)
* up persona (8b4e2ca9)
* up deps (b1de9472)
* up harmony (db5016cc)
* up harmony (8f6889e0)
* up harmony (c4c06be5)
* up harmony (777c7d09)
* up deps (7f465006)
* up harmony (f9e37829)
* incrementing version number - v3.1.7 (0b4e81ab)
* update changelog for v3.1.7 (8744e412)
* up persona (7a0e5c6d)
* up harmony (be474fb4)
* up harmony (1896b486)
* up persona (09d42076)
* up harmony (cce42fec)
* up markdown (4107d6b8)
* up themes (b2f70a2e)
* up composer (21919524)
* up harmony (64441602)
* incrementing version number - v3.1.6 (b3a3b130)
* up themes (61420fdc)
* up themes (f9990cab)
* bump themes for da02361b13d064763223533368f9b71d998ecf37 (c97977f8)
* up harmony (0f84f597)
* up emoji (4b0d3940)
* up emoji (291aa58e)
* incrementing version number - v3.1.5 (ec19343a)
* up harmony (56ac610b)
* up themes (0bfe361c)
* up themes (67ab222d)
* update lang key (1cc079f3)
* up harmony (590a7237)
* up harmony (ed54c7c0)
* up harmony (91760eef)
* up emoji (7ab05f5d)
* up harmony (43887328)
* up emoji (9a3c62f7)
* up emoji (783fbfd8)
* up emoji (7a3468a1)
* up emoji (933f5a90)
* up harmony (61f4202e)
* up themes (5d089363)
* scroll up alert (ca6f43c5)
* harmony (c48f15c5)
* up themes (14c93cd5)
* up harmony (6188d8be)
* up harmony (9e416d7f)
* incrementing version number - v3.1.4 (2452783c)
* up persona (78c2e29c)
* up markdown (7f5ec0ef)
* up themes (cdfc1bfe)
* up harmony (fd80b612)
* incrementing version number - v3.1.3 (3b4e9d3f)
* incrementing version number - v3.1.2 (40fa3489)
* incrementing version number - v3.1.1 (40250733)
* incrementing version number - v3.1.0 (0cb386bd)
* incrementing version number - v3.0.1 (26f6ea49)
* incrementing version number - v3.0.0 (224e08cd)
* **i18n:**
* fallback strings for new resources: nodebb.admin-appearance-skins (7ca85c60)
* fallback strings for new resources: nodebb.admin-advanced-cache, nodebb.admin-advanced-errors, nodebb.admin-development-logger (fa8e656d)
* fallback strings for new resources: nodebb.admin-appearance-customise (0863afd0)
* fallback strings for new resources: nodebb.user (195b09d5)
* fallback strings for new resources: nodebb.admin-manage-users (934b6792)
* fallback strings for new resources: nodebb.themes-harmony (619c4ff7)
* fallback strings for new resources: nodebb.topic (639eeb44)
* fallback strings for new resources: nodebb.admin-appearance-customise, nodebb.admin-appearance-skins, nodebb.admin-appearance-themes, nodebb.admin-settings-api (d508772c)
* fallback strings for new resources: nodebb.admin-manage-groups (e53929fc)
* fallback strings for new resources: nodebb.users (1ffc9221)
* fallback strings for new resources: nodebb.modules (54a683bb)
* fallback strings for new resources: nodebb.themes-harmony (0aef9a91)
* fallback strings for new resources: nodebb.admin-settings-api (78bc71aa)
##### New Features
* closes #11747, add pagination to tokens page (4b11cd0d)
* add vote privs to topic (#11734) (86faed6f)
* custom skins panel in acp (556fd65d)
* add req and socket to als, closes https://github.com/NodeBB/NodeBB/pull/10304 (68ddca1e)
* #11714, add page title (1a5e18cd)
* #11714, add registrationQueue flag (3080eb7e)
* do not show the replies container in a post's footer if the only reply present is the next post (da02361b)
* add new tab to define bs variables (de68f749)
* bring back noskin option (2edfe0ef)
* add not validated/expired (5fae09f3)
* closes #11671, allow custom classes on body (e89cfd44)
* upgrade fonts (392a7d28)
* allow more params to app.newTopic/newReply (325c1955)
* update progress bar more frequently (99aaa9f1)
* closes #11630 (8c9ab01f)
* add hidden-empty utility (63ae03b4)
* translate bodyShort (ed15cbb0)
* add lang string and drag fix (db9b807c)
* center chat modal attr (4833a2b9)
* token rolling API for admins (4f524e9f)
* token editing and deletion (ce23caf7)
* api token migration, new ACP tokens list, token creation (e4888dea)
* internal utility functions for token management (creation, deletion, etc) (7b8bffd7)
##### Bug Fixes
* **deps:**
* update socket.io packages to v4.7.1 (#11763) (1de2d632)
* update dependency ace-builds to v1.23.1 (#11759) (53ab5931)
* update dependency esbuild to v0.18.10 (#11760) (e7f68aec)
* update dependency pg-cursor to v2.10.1 (#11757) (a814440c)
* update dependency pg to v8.11.1 (#11758) (8b56fa2f)
* update dependency esbuild to v0.18.9 (#11755) (3adc7505)
* update socket.io packages to v4.7.0 (#11744) (b25e7247)
* update dependency semver to v7.5.3 (#11745) (9d0edc36)
* update dependency esbuild to v0.18.8 (#11751) (a7243790)
* update dependency esbuild to v0.18.7 (#11749) (85e5619c)
* update dependency sass to v1.63.6 (#11743) (939e5818)
* update dependency webpack to v5.88.0 (#11741) (c45854d9)
* update dependency sanitize-html to v2.11.0 (#11740) (9d5fadad)
* update dependency esbuild to v0.18.6 (#11736) (e0c137c9)
* update dependency sass to v1.63.5 (#11737) (61e45cb3)
* update dependency ace-builds to v1.23.0 (#11739) (a53e7d21)
* update dependency esbuild to v0.18.5 (#11730) (2a56d21c)
* update dependency esbuild to v0.18.4 (#11721) (ae349004)
* update dependency commander to v11 (#11719) (d454c5c4)
* update dependency lru-cache to v10 (#11716) (b3bdb9d0)
* update dependency semver to v7.5.2 (#11718) (770021e0)
* update dependency esbuild to v0.18.3 (#11715) (9f94b56f)
* update dependency webpack to v5.87.0 (#11713) (f95929b2)
* update dependency nodebb-plugin-2factor to v7.1.3 (#11711) (c9e41e10)
* update dependency sass to v1.63.4 (#11709) (dfcef322)
* update dependency esbuild to v0.18.2 (#11705) (9521c8de)
* update dependency nodebb-plugin-2factor to v7.1.1 (#11703) (fe96d6f8)
* update dependency ace-builds to v1.22.1 (#11699) (b0d91a55)
* update dependency esbuild to v0.18.1 (#11701) (5247f763)
* update dependency nodebb-theme-harmony to v1.0.47 (#11700) (96a7add5)
* update dependency sass to v1.63.3 (#11693) (1512a37d)
* update dependency @fontsource/poppins to v5.0.3 (#11696) (1bd8f898)
* update dependency @fontsource/inter to v5.0.3 (#11695) (ddb41fbe)
* update dependency esbuild to v0.18.0 (#11698) (2b419f93)
* update dependency webpack to v5.86.0 (#11691) (744f399c)
* update dependency connect-pg-simple to v9 (#11692) (32cebaa6)
* update dependency mongodb to v5.6.0 (#11670) (1738f3c5)
* update dependency lru-cache to v9.1.2 (#11668) (09fff40c)
* update dependency nodebb-plugin-emoji to v5.1.0 (#11683) (bf76989e)
* update dependency nodebb-plugin-dbsearch to v6.1.0 (#11689) (9ef40569)
* update dependency nodebb-theme-persona to v13.1.0 (#11688) (6240a8c6)
* update dependency nodebb-plugin-composer-default to v10.2.0 (#11686) (bfdb72ca)
* update dependency nodebb-plugin-mentions to v4.2.0 (#11687) (d58c9d8c)
* update dependency nodebb-plugin-2factor to v7.1.0 (#11685) (64557680)
* update dependency nodebb-plugin-markdown to v12.1.0 (#11684) (ed2d9a96)
* update dependency nodebb-theme-lavender to v7.1.0 (#11682) (c23deb87)
* update dependency nodebb-plugin-spam-be-gone to v2.1.0 (#11681) (5d8d0946)
* update dependency nodebb-theme-harmony to v1.0.43 (#11680) (601a0363)
* update dependency webpack to v5.85.1 (#11678) (ccf3d3bc)
* update dependency nodebb-theme-harmony to v1.0.42 (#11674) (d41651dc)
* update dependency nodebb-plugin-composer-default to v10.1.9 (#11676) (929835de)
* update dependency nodebb-theme-harmony to v1.0.40 (#11669) (b5ee0247)
* pin dependencies (#11660) (1033cd1c)
* update dependency webpack to v5.85.0 (#11663) (e6344db8)
* update dependency @fontsource/inter to v5 (#11661) (e5e8debf)
* update dependency nodebb-theme-harmony to v1.0.39 (#11659) (6d4ab1d0)
* update socket.io packages to v4.6.2 (#11658) (fe10356c)
* update dependency ipaddr.js to v2.1.0 (#11653) (a13b5c40)
* update dependency nodebb-plugin-composer-default to v10.1.8 (#11656) (032425b2)
* update dependency nodebb-plugin-markdown to v12.0.5 (#11657) (a7a1cda5)
* update dependency nodebb-theme-persona to v13.0.73 (#11652) (e4c2015f)
* update dependency nodebb-plugin-composer-default to v10.1.7 (#11654) (d242bc29)
* update dependency nodemailer to v6.9.3 (#11644) (bd93ab8b)
* update dependency nodebb-theme-harmony to v1.0.38 (#11646) (f9ba518a)
* update dependency nodebb-theme-persona to v13.0.72 (#11647) (c474841e)
* update dependency nodebb-widget-essentials to v7.0.13 (#11645) (5daa733c)
* update dependency webpack to v5.84.1 (#11635) (7c333fb1)
* update dependency @popperjs/core to v2.11.8 (#11636) (14ac1206)
* update dependency winston to v3.9.0 (#11637) (45af9333)
* update dependency postcss to v8.4.24 (#11642) (1bc3c384)
* update dependency nodebb-theme-persona to v13.0.71 (#11641) (a6be0cd7)
* update dependency nodebb-plugin-composer-default to v10.1.6 (#11638) (3c9a960e)
* update dependency cron to v2.3.1 (#11633) (f5bcdc87)
* update dependency nodebb-theme-persona to v13.0.70 (#11632) (73d8ac66)
* update dependency webpack to v5.84.0 (#11631) (23532464)
* update dependency nodebb-theme-peace to v2.0.27 (#11629) (b10227dc)
* update dependency ace-builds to v1.22.0 (#11621) (70d0fc1a)
* update dependency nodebb-plugin-emoji to v5.0.16 (#11626) (21b61b37)
* update dependency webpack-merge to v5.9.0 (#11622) (5c70b428)
* update dependency nodebb-theme-peace to v2.0.25 (#11615) (f0336af4)
* update dependency webpack to v5.83.1 (#11608) (a4ae2e08)
* update dependency rimraf to v5.0.1 (#11610) (d1ccfac1)
* update dependency terser-webpack-plugin to v5.3.9 (#11611) (af00ebbe)
* update dependency ace-builds to v1.21.1 (#11607) (d26c9bf8)
* update dependency pg-cursor to v2.10.0 (#11605) (10ed33f1)
* update dependency @socket.io/redis-adapter to v8.2.1 (#11602) (49b3badb)
* update dependency ace-builds to v1.21.0 (#11603) (3d9f6f41)
* update dependency pg to v8.11.0 (#11604) (9840289c)
* update dependency semver to v7.5.1 (#11597) (18606f9c)
* update dependency esbuild to v0.17.19 (#11598) (28fb4e10)
* update dependency mongodb to v5.5.0 (#11593) (88e891fc)
* update dependency nodemailer to v6.9.2 (#11590) (3a883e3f)
* update dependency connect-redis to v7.1.0 (#11592) (97ec0c75)
* update dependency webpack to v5.82.1 (#11585) (90e53177)
* update dependency ace-builds to v1.20.0 (#11587) (326d820f)
* #11761, don't escape topic title twice (01c36f8b)
* use btn instead of icon (aefef763)
* rollback ace-builds 1.23.0 doesnt work (ea150162)
* #11756, fix unique visitor stats in acp table (e45f513b)
* dont overwrite postIndex (c21d7dbc)
* closes #11731, set postIndex on pagination (cbd98c1b)
* pinned topic ordering if parent element has non topic elements (cfedd087)
* delete events not working (281078f5)
* if reply is in different topic dont hide in parent (9ee1d7b0)
* web (6d5f6a15)
* var name (b48a6e26)
* error toast on lost connection (2c89d784)
* dont send 200 status on admin upload errors (#11707) (8ca65b0c)
* #11702, don't escape backgroundImage twice (6740a51e)
* closes #11697, remove min attribute from rep thresholds (4a6249a4)
* skins page revert (33a6b3e1)
* dont add deleted users to users:online (d0e9eb2c)
* #11679, fix username change (db3bff09)
* closes #11673, topic search for harmony (ee8cb378)
* #11664, dont create backlinks for quotes (d3c5a79d)
* wrap on events page (a5b080ea)
* app.newTopic usage (9f3bdf75)
* rtl fixes for code and long text (05460d8e)
* topic count in tools after purge closes #11651 (1974abeb)
* add loadingMore flag to chat infinite load (e0300ab7)
* #11619, fix selector (cdeaef6b)
* text area height calculation in chats (c52916de)
* textarea on error (c77b6224)
* closes #11612 (3cef2535)
* edge case in category filter (5daaa5ea)
* #11572 (29303f4a)
* browser title if options.title is undefined (adf14ea5)
* lang strings (d6ead3d4)
* #11594 (11d315df)
* relocated upgrade script, removed outdated code that called core.api for tokens (3e6dd78d)
##### Other Changes
* fix whitespace (4768d06b)
* fix unused (dcc2bb10)
* //github.com/NodeBB/NodeBB/issues/11612 (cf7d9334)
* up peace (0da8b506)
* use csrf_token in ws handshake (#11573) (63b859f0)
* closes #11577 (ad1ae291)
##### Performance Improvements
* make less db calls to load indices (0b2feb9e)
##### Refactors
* show both emails in user list (daa5ac85)
* move async call to promise.all (e56e44ab)
* remove script (2360d296)
* remove log (9522951f)
* remove log (32f60df1)
* use new params (2cf865e8)
* use app.parseAndTranslate (b1fbc194)
* remove return (e0149462)
##### Reverts
* remove emoji email css (7b8ebd0a)
##### Tests
* fix spec (94f06301)
* make email requirement flag changes more explicit in tests, so cases do not rely on variable values from other cases (a8399aa2)
* fix another test (c638186b)
* fix email tests @julianlam (64718d0c)
* openapi (2f94eb21)
* openapi (bc74afaf)
* remove is touch test (1ab0faa4)
* remove socket.io test (366b18e0)
* log socket.io error (3cb4edf1)
* fix another test (12e75ff4)
* fix test (c201bf45)
* add back missing tests (031ffe49)
* add missing tests (a75fd636)
* fix digest test (aff6d20f)
* add email (4bfebc81)
* digest (61563b01)
* additional tests for .roll() (6765d053)
* fix authentication tests to use new token saving utility functions (f42b636a)
#### v3.1.7 (2023-06-21)
##### Chores

@ -92,16 +92,16 @@
"multiparty": "4.2.3",
"nconf": "0.12.0",
"nodebb-plugin-2factor": "7.1.3",
"nodebb-plugin-composer-default": "10.2.3",
"nodebb-plugin-composer-default": "10.2.4",
"nodebb-plugin-dbsearch": "6.1.0",
"nodebb-plugin-emoji": "5.1.2",
"nodebb-plugin-emoji": "5.1.3",
"nodebb-plugin-emoji-android": "4.0.0",
"nodebb-plugin-markdown": "12.1.4",
"nodebb-plugin-mentions": "4.2.0",
"nodebb-plugin-ntfy": "1.0.15",
"nodebb-plugin-spam-be-gone": "2.1.0",
"nodebb-rewards-essentials": "0.2.3",
"nodebb-theme-harmony": "1.0.64",
"nodebb-theme-harmony": "1.0.65",
"nodebb-theme-lavender": "7.1.1",
"nodebb-theme-peace": "2.0.32",
"nodebb-theme-persona": "13.1.6",
@ -135,7 +135,7 @@
"@socket.io/redis-adapter": "8.2.1",
"sortablejs": "1.15.0",
"spdx-license-list": "6.6.0",
"spider-detector": "2.0.0",
"spider-detector": "2.0.1",
"terser-webpack-plugin": "5.3.9",
"textcomplete": "0.18.2",
"textcomplete.contenteditable": "0.1.1",

@ -13,6 +13,8 @@ define('admin/settings/api', ['settings', 'clipboard', 'bootbox', 'benchpress',
const copyEls = document.querySelectorAll('[data-component="acp/tokens"] [data-action="copy"]');
new clipboard(copyEls);
$('[data-action="create"]').on('click', handleTokenCreation);
handleActions();
};
@ -28,10 +30,6 @@ define('admin/settings/api', ['settings', 'clipboard', 'bootbox', 'benchpress',
const action = subselector.getAttribute('data-action');
switch (action) {
case 'create':
handleTokenCreation();
break;
case 'edit':
handleTokenUpdate(subselector);
break;

@ -440,7 +440,7 @@ define('navigator', [
count = value;
navigator.updateTextAndProgressBar();
setThumbToIndex(index);
toggle(count > 1);
toggle(count > 0);
};
navigator.show = function () {
@ -464,6 +464,7 @@ define('navigator', [
}
paginationBlockEl.toggleClass('ready', flag);
paginationBlockEl.toggleClass('noreplies', count <= 1);
}
navigator.delayedUpdate = function () {
@ -523,7 +524,7 @@ define('navigator', [
setThumbToIndex(index);
}
toggle(count > 1);
toggle(count > 0);
};
navigator.getIndex = () => index;

@ -58,9 +58,10 @@ helpers.buildQueryString = function (query, key, value) {
helpers.addLinkTags = function (params) {
params.res.locals.linkTags = params.res.locals.linkTags || [];
const page = params.page > 1 ? `?page=${params.page}` : '';
params.res.locals.linkTags.push({
rel: 'canonical',
href: `${url}/${params.url}`,
href: `${url}/${params.url}${page}`,
});
params.tags.forEach((rel) => {

@ -91,7 +91,12 @@ recentController.getData = async function (req, url, sort) {
const pageCount = Math.max(1, Math.ceil(data.topicCount / settings.topicsPerPage));
data.pagination = pagination.create(page, pageCount, req.query);
helpers.addLinkTags({ url: url, res: req.res, tags: data.pagination.rel });
helpers.addLinkTags({
url: url,
res: req.res,
tags: data.pagination.rel,
page: page,
});
return data;
};

@ -61,7 +61,12 @@ tagsController.getTag = async function (req, res) {
const pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
templateData.pagination = pagination.create(page, pageCount, req.query);
helpers.addLinkTags({ url: `tags/${tag}`, res: req.res, tags: templateData.pagination.rel });
helpers.addLinkTags({
url: `tags/${tag}`,
res: req.res,
tags: templateData.pagination.rel,
page: page,
});
templateData['feeds:disableRSS'] = meta.config['feeds:disableRSS'];
templateData.rssFeedUrl = `${nconf.get('relative_path')}/tags/${tag}.rss`;

@ -72,15 +72,15 @@ topicsController.get = async function getTopic(req, res, next) {
const sort = req.query.sort || settings.topicPostSort;
const set = sort === 'most_votes' ? `tid:${tid}:posts:votes` : `tid:${tid}:posts`;
const reverse = sort === 'newest_to_oldest' || sort === 'most_votes';
if (settings.usePagination) {
if (!req.query.page) {
currentPage = calculatePageFromIndex(postIndex, settings);
} else {
const top = ((currentPage - 1) * settings.postsPerPage) + 1;
const bottom = top + settings.postsPerPage;
if (!req.params.post_index || (postIndex < top || postIndex > bottom)) {
postIndex = top;
}
if (!req.query.page) {
currentPage = calculatePageFromIndex(postIndex, settings);
}
if (settings.usePagination && req.query.page) {
const top = ((currentPage - 1) * settings.postsPerPage) + 1;
const bottom = top + settings.postsPerPage;
if (!req.params.post_index || (postIndex < top || postIndex > bottom)) {
postIndex = top;
}
}
const { start, stop } = calculateStartStop(currentPage, postIndex, settings);
@ -115,7 +115,7 @@ topicsController.get = async function getTopic(req, res, next) {
await Promise.all([
buildBreadcrumbs(topicData),
addOldCategory(topicData, userPrivileges),
addTags(topicData, req, res),
addTags(topicData, req, res, currentPage),
incrementViewCount(req, tid),
markAsRead(req, tid),
analytics.increment([`pageviews:byCid:${topicData.category.cid}`]),
@ -201,7 +201,7 @@ async function addOldCategory(topicData, userPrivileges) {
}
}
async function addTags(topicData, req, res) {
async function addTags(topicData, req, res, currentPage) {
const postIndex = parseInt(req.params.post_index, 10) || 0;
const postAtIndex = topicData.posts.find(p => parseInt(p.index, 10) === parseInt(Math.max(0, postIndex - 1), 10));
let description = '';
@ -256,10 +256,11 @@ async function addTags(topicData, req, res) {
await addOGImageTags(res, topicData, postAtIndex);
const page = currentPage > 1 ? `?page=${currentPage}` : '';
res.locals.linkTags = [
{
rel: 'canonical',
href: `${url}/topic/${topicData.slug}`,
href: `${url}/topic/${topicData.slug}${page}`,
},
];

@ -51,7 +51,12 @@ unreadController.get = async function (req, res) {
data.pageCount = Math.max(1, Math.ceil(data.topicCount / userSettings.topicsPerPage));
data.pagination = pagination.create(page, data.pageCount, req.query);
helpers.addLinkTags({ url: 'unread', res: req.res, tags: data.pagination.rel });
helpers.addLinkTags({
url: 'unread',
res: req.res,
tags: data.pagination.rel,
page: page,
});
if (userSettings.usePagination && (page < 1 || page > data.pageCount)) {
req.query.page = Math.max(1, Math.min(data.pageCount, page));

@ -25,7 +25,7 @@ module.exports = function (Groups) {
Groups.isMember = async function (uid, groupName) {
if (!uid || parseInt(uid, 10) <= 0 || !groupName) {
return false;
return isMemberOfEphemeralGroup(uid, groupName);
}
const cacheKey = `${uid}:${groupName}`;
@ -43,8 +43,8 @@ module.exports = function (Groups) {
return uids.map(() => false);
}
if (groupName === 'guests') {
return uids.map(uid => parseInt(uid, 10) === 0);
if (groupName === 'guests' || groupName === 'spiders') {
return uids.map(uid => isMemberOfEphemeralGroup(uid, groupName));
}
const cachedData = {};
@ -64,7 +64,7 @@ module.exports = function (Groups) {
Groups.isMemberOfGroups = async function (uid, groups) {
if (!uid || parseInt(uid, 10) <= 0 || !groups.length) {
return groups.map(groupName => groupName === 'guests');
return groups.map(groupName => isMemberOfEphemeralGroup(uid, groupName));
}
const cachedData = {};
const nonCachedGroups = groups.filter(groupName => filterNonCached(cachedData, uid, groupName));
@ -82,6 +82,11 @@ module.exports = function (Groups) {
return groups.map(groupName => cachedData[`${uid}:${groupName}`]);
};
function isMemberOfEphemeralGroup(uid, groupName) {
return (groupName === 'guests' && parseInt(uid, 10) === 0) ||
(groupName === 'spiders' && parseInt(uid, 10) === -1);
}
function filterNonCached(cachedData, uid, groupName) {
const isMember = Groups.cache.get(`${uid}:${groupName}`);
const isInCache = isMember !== undefined;

@ -292,8 +292,11 @@ async function checkReputation(uid) {
if (meta.config['reputation:disabled']) {
return;
}
const reputation = await user.getUserField(uid, 'reputation');
if (meta.config['min:rep:chat'] > reputation) {
const [reputation, isPrivileged] = await Promise.all([
user.getUserField(uid, 'reputation'),
user.isPrivileged(uid),
]);
if (!isPrivileged && meta.config['min:rep:chat'] > reputation) {
throw new Error(`[[error:not-enough-reputation-to-chat, ${meta.config['min:rep:chat']}]]`);
}
}

@ -229,7 +229,7 @@ middleware.delayLoading = function delayLoading(req, res, next) {
middleware.buildSkinAsset = helpers.try(async (req, res, next) => {
// If this middleware is reached, a skin was requested, so it is built on-demand
const targetSkin = path.basename(req.originalUrl).split('.css')[0];
const targetSkin = path.basename(req.originalUrl).split('.css')[0].replace(/-rtl$/, '');
if (!targetSkin) {
return next();
}

@ -142,14 +142,17 @@ module.exports = function (Posts) {
async function checkVoteLimitation(pid, uid, type) {
// type = 'upvote' or 'downvote'
const oneDay = 86400000;
const [reputation, targetUid, votedPidsToday] = await Promise.all([
const [reputation, isPrivileged, targetUid, votedPidsToday] = await Promise.all([
user.getUserField(uid, 'reputation'),
user.isPrivileged(uid),
Posts.getPostField(pid, 'uid'),
db.getSortedSetRevRangeByScore(
`uid:${uid}:${type}`, 0, -1, '+inf', Date.now() - oneDay
),
]);
if (isPrivileged) {
return;
}
if (reputation < meta.config[`min:rep:${type}`]) {
throw new Error(`[[error:not-enough-reputation-to-${type}, ${meta.config[`min:rep:${type}`]}]]`);
}

@ -12,7 +12,9 @@ const languages = require('../languages');
module.exports = function (User) {
User.getSettings = async function (uid) {
if (parseInt(uid, 10) <= 0) {
return await onSettingsLoaded(0, {});
return await onSettingsLoaded(uid, {
usePagination: parseInt(uid, 10) === -1 ? 1 : undefined, // force spiders to use pagination
});
}
let settings = await db.getObject(`user:${uid}:settings`);
settings = settings || {};

@ -209,36 +209,54 @@ describe('Groups', () => {
});
describe('.isMember()', () => {
it('should return boolean true when a user is in a group', (done) => {
Groups.isMember(1, 'Test', (err, isMember) => {
assert.ifError(err);
assert.strictEqual(isMember, true);
done();
});
it('should return boolean true when a user is in a group', async () => {
const isMember = await Groups.isMember(1, 'Test');
assert.strictEqual(isMember, true);
});
it('should return boolean false when a user is not in a group', (done) => {
Groups.isMember(2, 'Test', (err, isMember) => {
assert.ifError(err);
assert.strictEqual(isMember, false);
done();
});
it('should return boolean false when a user is not in a group', async () => {
const isMember = await Groups.isMember(2, 'Test');
assert.strictEqual(isMember, false);
});
it('should return true for uid 0 and guests group', (done) => {
Groups.isMembers([1, 0], 'guests', (err, isMembers) => {
assert.ifError(err);
assert.deepStrictEqual(isMembers, [false, true]);
done();
});
it('should return true for uid 0 and guests group', async () => {
const isMember = await Groups.isMember(0, 'guests');
assert.strictEqual(isMember, true);
});
it('should return true for uid 0 and guests group', (done) => {
Groups.isMemberOfGroups(0, ['guests', 'registered-users'], (err, isMembers) => {
assert.ifError(err);
assert.deepStrictEqual(isMembers, [true, false]);
done();
});
it('should return false for uid 0 and spiders group', async () => {
const isMember = await Groups.isMember(0, 'spiders');
assert.strictEqual(isMember, false);
});
it('should return true for uid -1 and spiders group', async () => {
const isMember = await Groups.isMember(-1, 'spiders');
assert.strictEqual(isMember, true);
});
it('should return false for uid -1 and guests group', async () => {
const isMember = await Groups.isMember(-1, 'guests');
assert.strictEqual(isMember, false);
});
it('should return true for uid 0, false for uid -1 with guests group', async () => {
const isMembers = await Groups.isMembers([1, 0, -1], 'guests');
assert.deepStrictEqual(isMembers, [false, true, false]);
});
it('should return false for uid 0, true for uid -1 with spiders group', async () => {
const isMembers = await Groups.isMembers([1, 0, -1], 'spiders');
assert.deepStrictEqual(isMembers, [false, false, true]);
});
it('should return true for uid 0 and guests group', async () => {
const isMembers = await Groups.isMemberOfGroups(0, ['guests', 'registered-users', 'spiders']);
assert.deepStrictEqual(isMembers, [true, false, false]);
});
it('should return true for uid -1 and spiders group', async () => {
const isMembers = await Groups.isMemberOfGroups(-1, ['guests', 'registered-users', 'spiders']);
assert.deepStrictEqual(isMembers, [false, false, true]);
});
});
@ -406,16 +424,12 @@ describe('Groups', () => {
});
describe('.hide()', () => {
it('should mark the group as hidden', (done) => {
Groups.hide('foo', (err) => {
assert.ifError(err);
Groups.get('foo', {}, (err, groupObj) => {
assert.ifError(err);
assert.strictEqual(1, groupObj.hidden);
done();
});
});
it('should mark the group as hidden', async () => {
await Groups.hide('foo');
const groupObj = await Groups.get('foo', {});
assert.strictEqual(1, groupObj.hidden);
const isMember = await db.isSortedSetMember('groups:visible:createtime', 'foo');
assert.strictEqual(isMember, false);
});
});
@ -798,20 +812,6 @@ describe('Groups', () => {
});
});
describe('.hide()', () => {
it('should make a group hidden', (done) => {
Groups.hide('Test', function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.isSortedSetMember('groups:visible:createtime', 'Test', (err, isMember) => {
assert.ifError(err);
assert.strictEqual(isMember, false);
done();
});
});
});
});
describe('socket methods', () => {
it('should error if data is null', (done) => {
socketGroups.before({ uid: 0 }, 'groups.join', null, (err) => {

Loading…
Cancel
Save