From cf157c9bfd4fdab2495e691a2c458b8d78cde37d Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Thu, 26 Nov 2020 01:11:08 +0000 Subject: [PATCH 001/116] chore: update changelog for v1.15.3 --- CHANGELOG.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c541932a77..c6c077fb5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,94 @@ +#### v1.15.3 (2020-11-26) + +##### Chores + +* bump persona (720170a9) +* remove console.log (6a819944) +* move topic route schema up two levels as slug and index are optional (ae402e21) +* move category route schema up two levels as slug and index are optional (b3b501d7) +* up persona (0ffc091b) +* up persona (2f2f0ab7) +* up persona (5c9ff18e) +* add missing plugin hook deprecation warning (98a05e4d) +* pin autoprefixer to latest (46eb7701) +* incrementing version number - v1.15.3-beta.0 (28fa03bd) +* up persona (81984285) +* up slick (5f2fe883) +* incrementing version number - v1.15.2 (5867a5b9) +* update changelog for v1.15.2 (37965d45) +* **spec:** replace ugly hack with another hack for optional properties (45a4f136) +* **deps:** + * update dependency lint-staged to v10.5.2 (db205e2e) + * update dependency eslint to v7.14.0 (80404216) + +##### New Features + +* add topicOwnerPost #8778 (c037779f) +* clear reset tokens on user delete (4f37eddc) +* select/clear all checkboxes in privilege table (#8941) (00e75de7) +* show ban reason and expiry in write api responses, if user is banned (afb26bfe) +* automatically unban users in onSuccessfulLogin (6e5ec3f8) +* #8925, #8924 (3f337b5d) +* human readable uptime (672d4da0) +* allow ACP API access to bearer tokens (3b1c03ed) +* allow pins to expire (if set) (#8908) (046d0b16) +* #8637 (903e9d82) +* add displayname into user obj #8637 (#8909) (9ca44e6f) + +##### Bug Fixes + +* **deps:** + * update dependency nodebb-theme-persona to v10.2.87 (#8946) (167ab3a4) + * update dependency nodebb-theme-persona to v10.2.86 (#8945) (5af5cb85) + * update dependency nconf to ^0.11.0 (58152606) + * update dependency postcss to v8.1.10 (5363ebbb) + * update dependency nodebb-theme-persona to v10.2.85 (#8928) (abc32d62) + * update dependency postcss to v8.1.9 (d1cb5d48) + * update dependency postcss to v8.1.8 (b47a470b) + * update dependency nodebb-theme-vanilla to v11.3.4 (#8914) (589f7a56) + * update dependency nodebb-theme-persona to v10.2.80 (#8913) (38127b04) + * update dependency nodebb-theme-persona to v10.2.79 (#8907) (8e1b2458) + * update dependency nodebb-theme-persona to v10.2.75 (b9856179) +* add topic uid to infinitescroll (6771ca15) +* #8943, session mismatch modal thrown on login (race condition) (d5845169) +* #8912 (ac734b83) +* #8918 (e32cd31e) +* basepath for r.js modules (3af4d13f) +* test (61c6a762) +* move meta.getServerTime call to admin namespace (1c0e8c16) +* add client side check for userslug #8939 (f20c12ee) +* #8939, fix username change notification getting filtered out (0ca40af8) +* #8931, fix lang string (cf903e4e) +* #8932, fix client side error when updating username (95a3f030) +* bug with Topics.resizeAndUploadThumb not checking for extension validity (eab4ca71) +* #8933 (2b73a14e) +* #8929, fix popular, top rss feed urls (77f0bff5) +* a derp (5dd3b031) +* spec (b18e7e31) +* improper handling of scheme-relative URLs in topic thumb logic (4ca62dc4) +* https://github.com/NodeBB/NodeBB/pull/8685 (5fa09832) +* on OP edit, call helper method to upload and resize thumb (f33a9185) +* https://github.com/NodeBB/NodeBB/pull/8759 (9ee1fb49) +* spec (c2bb6123) +* guest displayname (1be08b2e) +* show messages after app load (46acbfda) +* restart on js changes in vendor (814771bd) +* #8915, fix queue not being cleared after firing click events (6ef7e867) +* spec, only call modifyUser on unique user objects (dbd814c2) +* setting (ae5d4405) +* spec (8d060065) +* group userTitles translation escapes (e9585b9b) +* remove params from error log (965671a9) +* **spec:** always show thumb in topic response (493c568a) + +##### Refactors + +* remove unused require (db1c140f) +* move API banned response handler to separate internal method (906d7d73) +* move plugin hook methods to plugin.hooks.* (6e2da996) +* remove breaking change in pin expiry (ef3df47a) +* use categoryCommand local method for pin/lock in category tools (#8917) (00aee84b) + #### v1.15.2 (2020-11-18) ##### Chores From d1ae08fa4a6654b13d0b5ff4f2f534947a208f37 Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Thu, 26 Nov 2020 01:11:08 +0000 Subject: [PATCH 002/116] chore: incrementing version number - v1.15.3 (cherry picked from commit c0d406ae68c285da3ad6ce630e7e73d20f1a7a22) Signed-off-by: Misty (Bot) --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index bebcbd3864..86e6eb322a 100644 --- a/install/package.json +++ b/install/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPL-3.0", "description": "NodeBB Forum", - "version": "1.15.3-beta.0", + "version": "1.15.3", "homepage": "http://www.nodebb.org", "repository": { "type": "git", From 93863bb3c6704d4eac15d69b4a2a5951247f8742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 00:01:59 -0500 Subject: [PATCH 003/116] fix: #8949, faster upgrade script --- src/upgrades/1.15.0/verified_users_group.js | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/upgrades/1.15.0/verified_users_group.js b/src/upgrades/1.15.0/verified_users_group.js index 7e5bcd4c64..7f6736b1ef 100644 --- a/src/upgrades/1.15.0/verified_users_group.js +++ b/src/upgrades/1.15.0/verified_users_group.js @@ -7,7 +7,7 @@ const user = require('../../user'); const groups = require('../../groups'); const meta = require('../../meta'); const privileges = require('../../privileges'); - +const now = Date.now(); module.exports = { name: 'Create verified/unverified user groups', timestamp: Date.UTC(2020, 9, 13), @@ -46,14 +46,17 @@ module.exports = { const verified = userData.filter(u => parseInt(u['email:confirmed'], 10) === 1); const unverified = userData.filter(u => parseInt(u['email:confirmed'], 10) !== 1); - for (const user of verified) { - // eslint-disable-next-line no-await-in-loop - await groups.join('verified-users', user.uid); - } - for (const user of unverified) { - // eslint-disable-next-line no-await-in-loop - await groups.join('unverified-users', user.uid); - } + await db.sortedSetAdd( + 'group:verified-users:members', + verified.map(() => now), + verified.map(u => u.uid) + ); + + await db.sortedSetAdd( + 'group:unverified-users:members', + verified.map(() => now), + unverified.map(u => u.uid) + ); }, { batch: 500, progress: this.progress, @@ -61,6 +64,11 @@ module.exports = { await db.delete('users:notvalidated'); await updatePrivilges(); + + const verifiedCount = await db.sortedSetCard('group:verified-users:members'); + const unverifiedCount = await db.sortedSetCard('group:unverified-users:members'); + await db.setObjectField('group:verified-users', 'memberCount', verifiedCount); + await db.setObjectField('group:unverified-users', 'memberCount', unverifiedCount); }, }; From 97c037f0a1226699fb2a174fa35ed1dafe24fae2 Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Thu, 26 Nov 2020 09:07:31 +0000 Subject: [PATCH 004/116] Latest translations and fallbacks --- public/language/bg/admin/settings/api.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/language/bg/admin/settings/api.json b/public/language/bg/admin/settings/api.json index 4cc23fc914..0e153563ba 100644 --- a/public/language/bg/admin/settings/api.json +++ b/public/language/bg/admin/settings/api.json @@ -1,12 +1,12 @@ { "tokens": "Кодове", - "settings": "Settings", + "settings": "Настройки", "lead-text": "На тази страница можете да настроите достъпа до ППИ за писане в NodeBB.", "intro": "По подразбиране ППИ за писане удостоверява потребителите чрез бисквитката им за сесията, но NodeBB поддържа и удостоверяване чрез метода „Bearer“, използвайки кодовете от тази страница.", "docs": "Щракнете тук за достъп до пълната документация на ППИ", - "require-https": "Require API usage via HTTPS only", - "require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.", + "require-https": "Ползването на ППИ да работи само чрез HTTPS", + "require-https-caveat": "Забележка: В някои случаи, когато се ползват програми за балансиране на натоварването, е възможно заявките към NodeBB да се препращат чрез HTTP – тогава тази настройка трябва да остане изключена.", "uid": "Потребителски ИД", "uid-help-text": "Посочете потребителски ИД, който да бъде свързан с този код. Ако ИД е 0, това ще се счита за главен код, който може да приема идентичността на всеки от другите потребители чрез параметъра _uid", From 21d6225ce0e2a29021141144b6e64c43306d100f Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 26 Nov 2020 11:05:45 -0500 Subject: [PATCH 005/116] fix: 'already-deleting' error on subsequent account content deletions --- src/user/delete.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/user/delete.js b/src/user/delete.js index d5ca3ccc4b..8168942244 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -36,6 +36,7 @@ module.exports = function (User) { await deleteTopics(callerUid, uid); await deleteUploads(uid); await deleteQueued(uid); + delete deletesInProgress[uid]; }; async function deletePosts(callerUid, uid) { From 39dae0aaff4c323553cb66d1d8dd80f70c98953e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 26 Nov 2020 11:25:09 -0500 Subject: [PATCH 006/116] fix: #8955, popstate to purged topic should go to homepage --- public/src/ajaxify.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 76b1a545ba..32bcfdf8da 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -423,16 +423,34 @@ ajaxify = window.ajaxify || {}; $(document).ready(function () { $(window).on('popstate', function (ev) { ev = ev.originalEvent; + let url = ev.state.url; + const execute = function () { + ajaxify.go(url, function () { + $(window).trigger('action:popstate', { url: url }); + }, true); + }; if (ev !== null && ev.state) { - if (ev.state.url === null && ev.state.returnPath !== undefined) { + if (url === null && ev.state.returnPath !== undefined) { window.history.replaceState({ url: ev.state.returnPath, }, ev.state.returnPath, config.relative_path + '/' + ev.state.returnPath); - } else if (ev.state.url !== undefined) { - ajaxify.go(ev.state.url, function () { - $(window).trigger('action:popstate', { url: ev.state.url }); - }, true); + } else if (url !== undefined) { + if (url.startsWith('topic/')) { + // Check topic exists + fetch(`${config.relative_path}/${url}`, { + method: 'HEAD', + cache: 'no-cache', + }).then((res) => { + if (res.status === 404) { + url = ''; + } + + execute(); + }); + } else { + execute(); + } } } }); From 5bb5ec46188420b942240b897ebe86c75e84d5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 12:04:01 -0500 Subject: [PATCH 007/116] fix: #8954, clear purged replies and toPids (#8959) * fix: #8954, clear purged replies and toPids * fix: redis test --- src/database/mongo/hash.js | 8 +++-- src/database/postgres/hash.js | 30 +++++++++++-------- src/database/redis/hash.js | 11 +++++-- src/posts/delete.js | 17 +++++++---- src/upgrades/1.15.4/clear_purged_replies.js | 33 +++++++++++++++++++++ test/database/hash.js | 10 +++++++ test/topics.js | 16 ++++++++++ 7 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 src/upgrades/1.15.4/clear_purged_replies.js diff --git a/src/database/mongo/hash.js b/src/database/mongo/hash.js index 58db98c537..1997d0b02d 100644 --- a/src/database/mongo/hash.js +++ b/src/database/mongo/hash.js @@ -149,7 +149,7 @@ module.exports = function (module) { }; module.deleteObjectFields = async function (key, fields) { - if (!key || !Array.isArray(fields) || !fields.length) { + if (!key || (Array.isArray(key) && !key.length) || !Array.isArray(fields) || !fields.length) { return; } fields = fields.filter(Boolean); @@ -162,8 +162,12 @@ module.exports = function (module) { field = helpers.fieldToString(field); data[field] = ''; }); + if (Array.isArray(key)) { + await module.client.collection('objects').updateMany({ _key: { $in: key } }, { $unset: data }); + } else { + await module.client.collection('objects').updateOne({ _key: key }, { $unset: data }); + } - await module.client.collection('objects').updateOne({ _key: key }, { $unset: data }); cache.del(key); }; diff --git a/src/database/postgres/hash.js b/src/database/postgres/hash.js index 6094c3bb72..a1f91d5dab 100644 --- a/src/database/postgres/hash.js +++ b/src/database/postgres/hash.js @@ -247,20 +247,26 @@ SELECT (h."data" ? $2::TEXT AND h."data"->>$2::TEXT IS NOT NULL) b }; module.deleteObjectFields = async function (key, fields) { - if (!key || !Array.isArray(fields) || !fields.length) { + if (!key || (Array.isArray(key) && !key.length) || !Array.isArray(fields) || !fields.length) { return; } - - await module.pool.query({ - name: 'deleteObjectFields', - text: ` -UPDATE "legacy_hash" - SET "data" = COALESCE((SELECT jsonb_object_agg("key", "value") - FROM jsonb_each("data") - WHERE "key" <> ALL ($2::TEXT[])), '{}') - WHERE "_key" = $1::TEXT`, - values: [key, fields], - }); + async function delKey(key, fields) { + await module.pool.query({ + name: 'deleteObjectFields', + text: ` + UPDATE "legacy_hash" + SET "data" = COALESCE((SELECT jsonb_object_agg("key", "value") + FROM jsonb_each("data") + WHERE "key" <> ALL ($2::TEXT[])), '{}') + WHERE "_key" = $1::TEXT`, + values: [key, fields], + }); + } + if (Array.isArray(key)) { + await Promise.all(key.map(k => delKey(k, fields))); + } else { + await delKey(key, fields); + } }; module.incrObjectField = async function (key, field) { diff --git a/src/database/redis/hash.js b/src/database/redis/hash.js index f32f7be0e5..b495c7d44a 100644 --- a/src/database/redis/hash.js +++ b/src/database/redis/hash.js @@ -150,14 +150,21 @@ module.exports = function (module) { }; module.deleteObjectFields = async function (key, fields) { - if (!key || !Array.isArray(fields) || !fields.length) { + if (!key || (Array.isArray(key) && !key.length) || !Array.isArray(fields) || !fields.length) { return; } fields = fields.filter(Boolean); if (!fields.length) { return; } - await module.client.async.hdel(key, fields); + if (Array.isArray(key)) { + const batch = module.client.batch(); + key.forEach(k => batch.hdel(k, fields)); + await helpers.execBatch(batch); + } else { + await module.client.async.hdel(key, fields); + } + cache.del(key); }; diff --git a/src/posts/delete.js b/src/posts/delete.js index 0504eec5f4..ed85a73110 100644 --- a/src/posts/delete.js +++ b/src/posts/delete.js @@ -122,13 +122,18 @@ module.exports = function (Posts) { } async function deletePostFromReplies(postData) { - if (!parseInt(postData.toPid, 10)) { - return; + const replyPids = await db.getSortedSetMembers('pid:' + postData.pid + ':replies'); + const promises = [ + db.deleteObjectFields( + replyPids.map(pid => 'post:' + pid), ['toPid'] + ), + db.delete('pid:' + postData.pid + ':replies'), + ]; + if (parseInt(postData.toPid, 10)) { + promises.push(db.sortedSetRemove('pid:' + postData.toPid + ':replies', postData.pid)); + promises.push(db.decrObjectField('post:' + postData.toPid, 'replies')); } - await Promise.all([ - db.sortedSetRemove('pid:' + postData.toPid + ':replies', postData.pid), - db.decrObjectField('post:' + postData.toPid, 'replies'), - ]); + await Promise.all(promises); } async function deletePostFromGroups(postData) { diff --git a/src/upgrades/1.15.4/clear_purged_replies.js b/src/upgrades/1.15.4/clear_purged_replies.js new file mode 100644 index 0000000000..df4655116d --- /dev/null +++ b/src/upgrades/1.15.4/clear_purged_replies.js @@ -0,0 +1,33 @@ +'use strict'; + +const _ = require('lodash'); +const db = require('../../database'); + +const batch = require('../../batch'); + +module.exports = { + name: 'Clear purged replies and toPid', + timestamp: Date.UTC(2020, 10, 26), + method: async function () { + const progress = this.progress; + + await batch.processSortedSet('posts:pid', async function (pids) { + progress.incr(pids.length); + let postData = await db.getObjects(pids.map(pid => 'post:' + pid)); + postData = postData.filter(p => p && parseInt(p.toPid, 10)); + if (!postData.length) { + return; + } + const toPids = postData.map(p => p.toPid); + const exists = await db.exists(toPids.map(pid => 'post:' + pid)); + const pidsToDelete = postData.filter((p, index) => !exists[index]).map(p => p.pid); + await db.deleteObjectFields(pidsToDelete.map(pid => 'post:' + pid), ['toPid']); + + const repliesToDelete = _.uniq(toPids.filter((pid, index) => !exists[index])); + await db.deleteAll(repliesToDelete.map(pid => 'pid:' + pid + ':replies')); + }, { + progress: progress, + batchSize: 500, + }); + }, +}; diff --git a/test/database/hash.js b/test/database/hash.js index d3a5535d5d..123967b1da 100644 --- a/test/database/hash.js +++ b/test/database/hash.js @@ -415,6 +415,16 @@ describe('Hash methods', function () { }); }); + it('should delete multiple fields of multiple objects', async function () { + await db.setObject('deleteFields1', { foo: 'foo1', baz: '2' }); + await db.setObject('deleteFields2', { foo: 'foo2', baz: '3' }); + await db.deleteObjectFields(['deleteFields1', 'deleteFields2'], ['baz']); + const obj1 = await db.getObject('deleteFields1'); + const obj2 = await db.getObject('deleteFields2'); + assert.deepStrictEqual(obj1, { foo: 'foo1' }); + assert.deepStrictEqual(obj2, { foo: 'foo2' }); + }); + it('should not error if fields is empty array', async () => { await db.deleteObjectFields('someKey', []); }); diff --git a/test/topics.js b/test/topics.js index 6ef9d4a4b8..239cf055d5 100644 --- a/test/topics.js +++ b/test/topics.js @@ -190,6 +190,22 @@ describe('Topic\'s', function () { done(); }); }); + + it('should delete nested relies properly', async function () { + const result = await topics.post({ uid: fooUid, title: 'nested test', content: 'main post', cid: topic.categoryId }); + const reply1 = await topics.reply({ uid: fooUid, content: 'reply post 1', tid: result.topicData.tid }); + const reply2 = await topics.reply({ uid: fooUid, content: 'reply post 2', tid: result.topicData.tid, toPid: reply1.pid }); + let replies = await socketPosts.getReplies({ uid: fooUid }, reply1.pid); + assert.strictEqual(replies.length, 1); + assert.strictEqual(replies[0].content, 'reply post 2'); + let toPid = await posts.getPostField(reply2.pid, 'toPid'); + assert.strictEqual(parseInt(toPid, 10), parseInt(reply1.pid, 10)); + await posts.purge(reply1.pid, fooUid); + replies = await socketPosts.getReplies({ uid: fooUid }, reply1.pid); + assert.strictEqual(replies.length, 0); + toPid = await posts.getPostField(reply2.pid, 'toPid'); + assert.strictEqual(toPid, null); + }); }); describe('Get methods', function () { From 47a19d67631efb0a633aa6ffcff50a57f7a52607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 12:22:24 -0500 Subject: [PATCH 008/116] fix: error message --- src/cli/manage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/manage.js b/src/cli/manage.js index 94f185f5b4..2f541149c0 100644 --- a/src/cli/manage.js +++ b/src/cli/manage.js @@ -65,7 +65,7 @@ async function activate(plugin) { }); process.exit(0); } catch (err) { - winston.error('An error occurred during plugin activation', err.stack); + winston.error('An error occurred during plugin activation\n' + err.stack); throw err; } } From 5ceda148746a5e20a48a11e3e4c25556417d136c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 12:23:41 -0500 Subject: [PATCH 009/116] Revert "fix: #8955, popstate to purged topic should go to homepage" This reverts commit 39dae0aaff4c323553cb66d1d8dd80f70c98953e. --- public/src/ajaxify.js | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 32bcfdf8da..76b1a545ba 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -423,34 +423,16 @@ ajaxify = window.ajaxify || {}; $(document).ready(function () { $(window).on('popstate', function (ev) { ev = ev.originalEvent; - let url = ev.state.url; - const execute = function () { - ajaxify.go(url, function () { - $(window).trigger('action:popstate', { url: url }); - }, true); - }; if (ev !== null && ev.state) { - if (url === null && ev.state.returnPath !== undefined) { + if (ev.state.url === null && ev.state.returnPath !== undefined) { window.history.replaceState({ url: ev.state.returnPath, }, ev.state.returnPath, config.relative_path + '/' + ev.state.returnPath); - } else if (url !== undefined) { - if (url.startsWith('topic/')) { - // Check topic exists - fetch(`${config.relative_path}/${url}`, { - method: 'HEAD', - cache: 'no-cache', - }).then((res) => { - if (res.status === 404) { - url = ''; - } - - execute(); - }); - } else { - execute(); - } + } else if (ev.state.url !== undefined) { + ajaxify.go(ev.state.url, function () { + $(window).trigger('action:popstate', { url: ev.state.url }); + }, true); } } }); From 7e6427bca784779436a9beb4d17cec79cfdc499b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 12:26:03 -0500 Subject: [PATCH 010/116] fix: dont go back after delete account actions --- public/src/modules/accounts/delete.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/src/modules/accounts/delete.js b/public/src/modules/accounts/delete.js index 3be11dd4a1..a1f5d90b84 100644 --- a/public/src/modules/accounts/delete.js +++ b/public/src/modules/accounts/delete.js @@ -45,8 +45,6 @@ define('accounts/delete', ['api', 'bootbox'], function (api) { if (typeof callback === 'function') { return callback(); } - - history.back(); }); }); } From 414caac01b52d280701cc7786a6e378379b9ac8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 12:45:02 -0500 Subject: [PATCH 011/116] fix: #8957 --- src/socket.io/posts/move.js | 5 +++++ test/posts.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/socket.io/posts/move.js b/src/socket.io/posts/move.js index bfd614b063..c1637fad51 100644 --- a/src/socket.io/posts/move.js +++ b/src/socket.io/posts/move.js @@ -19,6 +19,11 @@ module.exports = function (SocketPosts) { throw new Error('[[error:invalid-data]]'); } + const canMove = await privileges.topics.isAdminOrMod(data.tid, socket.uid); + if (!canMove) { + throw new Error('[[error:no-privileges]]'); + } + for (const pid of data.pids) { /* eslint-disable no-await-in-loop */ const canMove = await privileges.posts.canMove(pid, socket.uid); diff --git a/test/posts.js b/test/posts.js index aad50e2684..b777230f93 100644 --- a/test/posts.js +++ b/test/posts.js @@ -721,6 +721,21 @@ describe('Post\'s', function () { }); }); }); + + it('should fail to move post if not moderator of target category', async function () { + const cat1 = await categories.create({ name: 'Test Category', description: 'Test category created by testing script' }); + const cat2 = await categories.create({ name: 'Test Category', description: 'Test category created by testing script' }); + const result = await socketTopics.post({ uid: globalModUid }, { title: 'target topic', content: 'queued topic', cid: cat2.cid }); + const modUid = await user.create({ username: 'modofcat1' }); + await privileges.categories.give(privileges.userPrivilegeList, cat1.cid, modUid); + let err; + try { + await socketPosts.movePost({ uid: modUid }, { pid: replyPid, tid: result.tid }); + } catch (_err) { + err = _err; + } + assert.strictEqual(err.message, '[[error:no-privileges]]'); + }); }); describe('getPostSummaryByPids', function () { From b8cafefce225a7e0fb2881881ac88f1a8206f5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 13:56:34 -0500 Subject: [PATCH 012/116] fix: winston usages --- app.js | 2 ++ src/analytics.js | 2 +- src/cli/reset.js | 2 +- src/controllers/admin/dashboard.js | 2 +- src/database/redis.js | 2 +- src/database/redis/connection.js | 2 +- src/flags.js | 2 +- src/notifications.js | 2 +- src/prestart.js | 14 ++++++++++++++ src/webserver.js | 2 +- 10 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index 1c7e5017d5..d9d92f545d 100644 --- a/app.js +++ b/app.js @@ -45,6 +45,8 @@ prestart.setupWinston(); prestart.versionCheck(); winston.verbose('* using configuration stored in: %s', configFile); +winston.error('oppps we faled', new Error('yah')); + if (!process.send) { // If run using `node app`, log GNU copyright info along with server info winston.info('NodeBB v' + nconf.get('version') + ' Copyright (C) 2013-' + (new Date()).getFullYear() + ' NodeBB Inc.'); diff --git a/src/analytics.js b/src/analytics.js index d1ec60af2d..1fe00f9803 100644 --- a/src/analytics.js +++ b/src/analytics.js @@ -139,7 +139,7 @@ Analytics.writeData = async function () { try { await Promise.all(dbQueue); } catch (err) { - winston.error('[analytics] Encountered error while writing analytics to data store', err.stack); + winston.error('[analytics] Encountered error while writing analytics to data store\n' + err.stack); throw err; } }; diff --git a/src/cli/reset.js b/src/cli/reset.js index 9edbfee8e7..a7822ba2c1 100644 --- a/src/cli/reset.js +++ b/src/cli/reset.js @@ -133,7 +133,7 @@ async function resetPlugin(pluginId) { winston.info('[reset] No action taken.'); } } catch (err) { - winston.error('[reset] Could not disable plugin: ' + pluginId + ' encountered error %s', err.stack); + winston.error('[reset] Could not disable plugin: ' + pluginId + ' encountered error %s\n' + err.stack); throw err; } } diff --git a/src/controllers/admin/dashboard.js b/src/controllers/admin/dashboard.js index cef8c8921a..49e34db80a 100644 --- a/src/controllers/admin/dashboard.js +++ b/src/controllers/admin/dashboard.js @@ -69,7 +69,7 @@ async function getLatestVersion() { try { return await versions.getLatestVersion(); } catch (err) { - winston.error('[acp] Failed to fetch latest version', err.stack); + winston.error('[acp] Failed to fetch latest version\n' + err.stack); } return null; } diff --git a/src/database/redis.js b/src/database/redis.js index 7de6efd5b4..b0fd76f284 100644 --- a/src/database/redis.js +++ b/src/database/redis.js @@ -40,7 +40,7 @@ redisModule.init = function (callback) { callback = callback || function () { }; redisModule.client = connection.connect(nconf.get('redis'), function (err) { if (err) { - winston.error('NodeBB could not connect to your Redis database. Redis returned the following error', err.stack); + winston.error('NodeBB could not connect to your Redis database. Redis returned the following error\n' + err.stack); return callback(err); } require('./redis/promisify')(redisModule.client); diff --git a/src/database/redis/connection.js b/src/database/redis/connection.js index b291b1f284..b79c154f63 100644 --- a/src/database/redis/connection.js +++ b/src/database/redis/connection.js @@ -58,7 +58,7 @@ connection.connect = function (options, callback) { if (dbIdx >= 0) { cxn.select(dbIdx, function (err) { if (err) { - winston.error('NodeBB could not select Redis database. Redis returned the following error', err.stack); + winston.error('NodeBB could not select Redis database. Redis returned the following error\n' + err.stack); throw err; } }); diff --git a/src/flags.js b/src/flags.js index 8c716765b2..ae954d1607 100644 --- a/src/flags.js +++ b/src/flags.js @@ -79,7 +79,7 @@ Flags.init = async function () { const data = await plugins.hooks.fire('filter:flags.getFilters', hookData); Flags._filters = data.filters; } catch (err) { - winston.error('[flags/init] Could not retrieve filters', err.stack); + winston.error('[flags/init] Could not retrieve filters\n' + err.stack); Flags._filters = {}; } }; diff --git a/src/notifications.js b/src/notifications.js index f4f526c6d5..11d3ac05c8 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -333,7 +333,7 @@ Notifications.prune = async function () { }, { batch: 500, interval: 100 }); } catch (err) { if (err) { - winston.error('Encountered error pruning notifications', err.stack); + winston.error('Encountered error pruning notifications\n' + err.stack); } } }; diff --git a/src/prestart.js b/src/prestart.js index ed61e28c16..a46e7d3299 100644 --- a/src/prestart.js +++ b/src/prestart.js @@ -13,6 +13,20 @@ function setupWinston() { return; } + // allow winton.error to log error objects properly + // https://github.com/NodeBB/NodeBB/issues/6848 + // const winstonError = winston.error; + // winston.error = function (msg, error) { + // if (msg instanceof Error) { + // winstonError(msg); + // } else if (error instanceof Error) { + // msg = msg + '\n' + error.stack; + // winstonError(msg); + // } else { + // winstonError.apply(null, arguments); + // } + // }; + var formats = []; if (nconf.get('log-colorize') !== 'false') { formats.push(winston.format.colorize()); diff --git a/src/webserver.js b/src/webserver.js index 4a6898f9a0..827baa5cc4 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -278,7 +278,7 @@ function listen(callback) { oldUmask = process.umask('0000'); module.exports.testSocket(socketPath, function (err) { if (err) { - winston.error('[startup] NodeBB was unable to secure domain socket access (' + socketPath + ')', err.stack); + winston.error('[startup] NodeBB was unable to secure domain socket access (' + socketPath + ')\n' + err.stack); throw err; } From 07fe959ce50803da2e7c636b091f8ce5b7154281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 13:56:53 -0500 Subject: [PATCH 013/116] chore: remove test code --- app.js | 2 -- src/prestart.js | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/app.js b/app.js index d9d92f545d..1c7e5017d5 100644 --- a/app.js +++ b/app.js @@ -45,8 +45,6 @@ prestart.setupWinston(); prestart.versionCheck(); winston.verbose('* using configuration stored in: %s', configFile); -winston.error('oppps we faled', new Error('yah')); - if (!process.send) { // If run using `node app`, log GNU copyright info along with server info winston.info('NodeBB v' + nconf.get('version') + ' Copyright (C) 2013-' + (new Date()).getFullYear() + ' NodeBB Inc.'); diff --git a/src/prestart.js b/src/prestart.js index a46e7d3299..ed61e28c16 100644 --- a/src/prestart.js +++ b/src/prestart.js @@ -13,20 +13,6 @@ function setupWinston() { return; } - // allow winton.error to log error objects properly - // https://github.com/NodeBB/NodeBB/issues/6848 - // const winstonError = winston.error; - // winston.error = function (msg, error) { - // if (msg instanceof Error) { - // winstonError(msg); - // } else if (error instanceof Error) { - // msg = msg + '\n' + error.stack; - // winstonError(msg); - // } else { - // winstonError.apply(null, arguments); - // } - // }; - var formats = []; if (nconf.get('log-colorize') !== 'false') { formats.push(winston.format.colorize()); From 6c316be4775c34130452f9d8f9f53196c27df5dc Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Nov 2020 19:02:37 +0000 Subject: [PATCH 014/116] fix(deps): update dependency benchpressjs to v2.3.0 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index 86e6eb322a..ac54bcbc65 100644 --- a/install/package.json +++ b/install/package.json @@ -41,7 +41,7 @@ "async": "^3.2.0", "autoprefixer": "10.0.2", "bcryptjs": "2.4.3", - "benchpressjs": "2.2.2", + "benchpressjs": "2.3.0", "body-parser": "^1.19.0", "bootbox": "4.4.0", "bootstrap": "^3.4.1", From 15c6f32c9388d591cf11f5faeb9eb3a60f01ac30 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 26 Nov 2020 15:49:09 -0500 Subject: [PATCH 015/116] refactor: pin/lock threadTools to use topicCommand, rewrote topicCommand to match categoryCommand signature --- public/src/client/category/tools.js | 41 +----------- public/src/client/topic/threadTools.js | 89 +++++++++++++++++++++----- 2 files changed, 75 insertions(+), 55 deletions(-) diff --git a/public/src/client/category/tools.js b/public/src/client/category/tools.js index e9ae03431c..bc27ea7416 100644 --- a/public/src/client/category/tools.js +++ b/public/src/client/category/tools.js @@ -4,11 +4,12 @@ define('forum/category/tools', [ 'topicSelect', + 'forum/topic/threadTools', 'components', 'translator', 'api', 'bootbox', -], function (topicSelect, components, translator, api, bootbox) { +], function (topicSelect, threadTools, components, translator, api, bootbox) { var CategoryTools = {}; CategoryTools.init = function () { @@ -149,7 +150,7 @@ define('forum/category/tools', [ break; case 'pin': - requestPinExpiry(body, execute.bind(null, true)); + threadTools.requestPinExpiry(body, execute.bind(null, true)); break; default: @@ -158,42 +159,6 @@ define('forum/category/tools', [ } } - function requestPinExpiry(body, onSuccess) { - app.parseAndTranslate('modals/set-pin-expiry', {}, function (html) { - const modal = bootbox.dialog({ - title: '[[topic:thread_tools.pin]]', - message: html, - onEscape: true, - size: 'small', - buttons: { - save: { - label: '[[global:save]]', - className: 'btn-primary', - callback: function () { - const expiryEl = modal.get(0).querySelector('#expiry'); - let expiry = expiryEl.value; - - // No expiry set - if (expiry === '') { - return onSuccess(); - } - - // Expiration date set - expiry = new Date(expiry); - - if (expiry && expiry.getTime() > Date.now()) { - body.expiry = expiry.getTime(); - onSuccess(); - } else { - app.alertError('[[error:invalid-date]]'); - } - }, - }, - }, - }); - }); - } - CategoryTools.removeListeners = function () { socket.removeListener('event:topic_deleted', setDeleteState); socket.removeListener('event:topic_restored', setDeleteState); diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index ab1383fbd0..1cc5bf32f3 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -12,41 +12,43 @@ define('forum/topic/threadTools', [ ThreadTools.init = function (tid, topicContainer) { renderMenu(topicContainer); + // function topicCommand(method, path, command, onComplete) { topicContainer.on('click', '[component="topic/delete"]', function () { - topicCommand('delete', tid); + topicCommand('del', '/state', 'delete'); return false; }); topicContainer.on('click', '[component="topic/restore"]', function () { - topicCommand('restore', tid); + topicCommand('put', '/state', 'restore'); return false; }); topicContainer.on('click', '[component="topic/purge"]', function () { - topicCommand('purge', tid); + topicCommand('del', '', 'purge'); return false; }); topicContainer.on('click', '[component="topic/lock"]', function () { - api.put(`/topics/${tid}/lock`); + topicCommand('put', '/lock', 'lock'); return false; }); topicContainer.on('click', '[component="topic/unlock"]', function () { - api.del(`/topics/${tid}/lock`); + topicCommand('del', '/lock', 'unlock'); return false; }); topicContainer.on('click', '[component="topic/pin"]', function () { - api.put(`/topics/${tid}/pin`); + topicCommand('put', '/pin', 'pin'); return false; }); topicContainer.on('click', '[component="topic/unpin"]', function () { - api.del(`/topics/${tid}/pin`); + topicCommand('del', '/pin', 'unpin'); return false; }); + // todo: should also use topicCommand, but no write api call exists for this yet topicContainer.on('click', '[component="topic/mark-unread"]', function () { socket.emit('topics.markUnread', tid, function (err) { if (err) { @@ -174,19 +176,72 @@ define('forum/topic/threadTools', [ }); } - function topicCommand(command, tid) { - translator.translate('[[topic:thread_tools.' + command + '_confirm]]', function (msg) { - bootbox.confirm(msg, function (confirm) { - if (!confirm) { - return; - } + function topicCommand(method, path, command, onComplete) { + if (!onComplete) { + onComplete = function () {}; + } + const tid = ajaxify.data.tid; + const body = {}; + const execute = function (ok) { + if (ok) { + api[method](`/topics/${tid}${path}`, body) + .then(onComplete) + .catch(app.alertError); + } + }; - const method = command === 'restore' ? 'put' : 'del'; - const suffix = command !== 'purge' ? '/state' : ''; - api[method](`/topics/${tid}${suffix}`, undefined, undefined, 'default'); + switch (command) { + case 'delete': + case 'restore': + case 'purge': + bootbox.confirm(`[[topic:thread_tools.${command}_confirm]]`, execute); + break; + + case 'pin': + ThreadTools.requestPinExpiry(body, execute.bind(null, true)); + break; + + default: + execute(true); + break; + } + } + + ThreadTools.requestPinExpiry = function (body, onSuccess) { + app.parseAndTranslate('modals/set-pin-expiry', {}, function (html) { + const modal = bootbox.dialog({ + title: '[[topic:thread_tools.pin]]', + message: html, + onEscape: true, + size: 'small', + buttons: { + save: { + label: '[[global:save]]', + className: 'btn-primary', + callback: function () { + const expiryEl = modal.get(0).querySelector('#expiry'); + let expiry = expiryEl.value; + + // No expiry set + if (expiry === '') { + return onSuccess(); + } + + // Expiration date set + expiry = new Date(expiry); + + if (expiry && expiry.getTime() > Date.now()) { + body.expiry = expiry.getTime(); + onSuccess(); + } else { + app.alertError('[[error:invalid-date]]'); + } + }, + }, + }, }); }); - } + }; ThreadTools.setLockedState = function (data) { var threadEl = components.get('topic'); From e1432caf927607cdab8fc3ff93cdd6224c94435a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 26 Nov 2020 15:53:47 -0500 Subject: [PATCH 016/116] feat: add cancel button to pin expiration modal --- public/src/client/topic/threadTools.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index 1cc5bf32f3..6a6b03d372 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -215,6 +215,10 @@ define('forum/topic/threadTools', [ onEscape: true, size: 'small', buttons: { + cancel: { + label: '[[modules:bootbox.cancel]]', + className: 'btn-link', + }, save: { label: '[[global:save]]', className: 'btn-primary', From ba3981e270de3e2c049f8da3273dd2468374cc97 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Thu, 26 Nov 2020 14:59:23 -0700 Subject: [PATCH 017/116] fix: use package.name for theme.id (#8965) Prevents cases like #8953 --- src/meta/themes.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/meta/themes.js b/src/meta/themes.js index 8c184f776d..1120591609 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -25,9 +25,16 @@ Themes.get = async () => { themes = _.flatten(themes).filter(Boolean); themes = await Promise.all(themes.map(async (theme) => { const config = path.join(themePath, theme, 'theme.json'); + const pack = path.join(themePath, theme, 'package.json'); try { - const file = await fs.promises.readFile(config, 'utf8'); - const configObj = JSON.parse(file); + const [configFile, packageFile] = await Promise.all([ + fs.promises.readFile(config, 'utf8'), + fs.promises.readFile(pack, 'utf8'), + ]); + const configObj = JSON.parse(configFile); + const packageObj = JSON.parse(packageFile); + + configObj.id = packageObj.name; // Minor adjustments for API output configObj.type = 'local'; From a56a657759262201439c660d7e09fd8b0b9fff81 Mon Sep 17 00:00:00 2001 From: gasoved Date: Fri, 27 Nov 2020 01:25:26 +0300 Subject: [PATCH 018/116] fix: missing select/clear all checkbox added to category privileges template (#8967) --- public/language/en-GB/admin/manage/privileges.json | 1 + public/src/admin/manage/privileges.js | 2 +- src/views/admin/partials/privileges/category.tpl | 4 ++++ src/views/admin/partials/privileges/global.tpl | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/public/language/en-GB/admin/manage/privileges.json b/public/language/en-GB/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/en-GB/admin/manage/privileges.json +++ b/public/language/en-GB/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/src/admin/manage/privileges.js b/public/src/admin/manage/privileges.js index 424d12881e..0fab84ed20 100644 --- a/public/src/admin/manage/privileges.js +++ b/public/src/admin/manage/privileges.js @@ -29,7 +29,7 @@ define('admin/manage/privileges', [ }; Privileges.setupPrivilegeTable = function () { - $('.privilege-table-container').on('change', 'input[type="checkbox"]', function () { + $('.privilege-table-container').on('change', 'input[type="checkbox"]:not(.checkbox-helper)', function () { var checkboxEl = $(this); var wrapperEl = checkboxEl.parent(); var privilege = wrapperEl.attr('data-privilege'); diff --git a/src/views/admin/partials/privileges/category.tpl b/src/views/admin/partials/privileges/category.tpl index 99150e05b9..392feddfab 100644 --- a/src/views/admin/partials/privileges/category.tpl +++ b/src/views/admin/partials/privileges/category.tpl @@ -20,6 +20,7 @@ [[admin/manage/categories:privileges.section-group]] + [[admin/manage/privileges:select-clear-all]] {privileges.labels.groups.name} @@ -46,6 +47,7 @@ + {function.spawnPrivilegeStates, privileges.groups.name, ../privileges} @@ -99,6 +101,7 @@ [[admin/manage/categories:privileges.section-user]] + [[admin/manage/privileges:select-clear-all]] {privileges.labels.users.name} @@ -115,6 +118,7 @@ {privileges.users.username} + {function.spawnPrivilegeStates, privileges.users.username, ../privileges} diff --git a/src/views/admin/partials/privileges/global.tpl b/src/views/admin/partials/privileges/global.tpl index 2c704ea7b4..ba2106230b 100644 --- a/src/views/admin/partials/privileges/global.tpl +++ b/src/views/admin/partials/privileges/global.tpl @@ -3,7 +3,7 @@ [[admin/manage/categories:privileges.section-group]] - Select/Clear All + [[admin/manage/privileges:select-clear-all]] {privileges.labels.groups.name} @@ -47,7 +47,7 @@ [[admin/manage/categories:privileges.section-user]] - Select/Clear All + [[admin/manage/privileges:select-clear-all]] {privileges.labels.users.name} From b2f0d38f5c695d1e36eba05832349c9e61921d1a Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Nov 2020 22:10:05 +0000 Subject: [PATCH 019/116] fix(deps): update dependency autoprefixer to v10.0.3 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index ac54bcbc65..d7a7ef3357 100644 --- a/install/package.json +++ b/install/package.json @@ -39,7 +39,7 @@ "ace-builds": "^1.4.9", "archiver": "^5.0.0", "async": "^3.2.0", - "autoprefixer": "10.0.2", + "autoprefixer": "10.0.3", "bcryptjs": "2.4.3", "benchpressjs": "2.3.0", "body-parser": "^1.19.0", From 4c7374ea33da4749d1f970c614acfbff46d1ca52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 26 Nov 2020 21:37:17 -0500 Subject: [PATCH 020/116] fix: flicker on tooltips if server call takes long time --- public/src/client/topic/votes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/src/client/topic/votes.js b/public/src/client/topic/votes.js index 8ea9091089..731b7f63ba 100644 --- a/public/src/client/topic/votes.js +++ b/public/src/client/topic/votes.js @@ -15,6 +15,7 @@ define('forum/topic/votes', [ var $this = $(this); var el = $this.parent(); + el.find('.tooltip').css('display', 'none'); var pid = el.parents('[data-pid]').attr('data-pid'); socket.emit('posts.getUpvoters', [pid], function (err, data) { @@ -32,6 +33,7 @@ define('forum/topic/votes', [ function createTooltip(el, data) { function doCreateTooltip(title) { el.attr('title', title).tooltip('fixTitle').tooltip('show'); + el.parent().find('.tooltip').css('display', ''); } var usernames = data.usernames .filter(name => name !== '[[global:former_user]]'); From 664614bbe33a236e14c284a7c3cc48cff4be48be Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Fri, 27 Nov 2020 09:09:22 +0000 Subject: [PATCH 021/116] Latest translations and fallbacks --- .../language/ar/admin/manage/privileges.json | 1 + .../language/bg/admin/manage/privileges.json | 1 + .../language/bn/admin/manage/privileges.json | 1 + .../language/cs/admin/manage/privileges.json | 1 + .../language/da/admin/manage/privileges.json | 1 + .../language/de/admin/manage/privileges.json | 1 + .../language/el/admin/manage/privileges.json | 1 + .../en-US/admin/manage/privileges.json | 1 + .../en-x-pirate/admin/manage/privileges.json | 1 + .../language/es/admin/manage/privileges.json | 1 + .../language/et/admin/manage/privileges.json | 1 + .../fa-IR/admin/manage/privileges.json | 1 + .../language/fi/admin/manage/privileges.json | 1 + .../language/fr/admin/manage/privileges.json | 1 + public/language/fr/admin/settings/api.json | 6 +- .../language/gl/admin/manage/privileges.json | 1 + .../language/he/admin/advanced/database.json | 6 +- .../he/admin/appearance/customise.json | 10 +-- .../language/he/admin/appearance/skins.json | 4 +- .../language/he/admin/appearance/themes.json | 16 ++-- public/language/he/admin/extend/rewards.json | 2 +- .../language/he/admin/manage/privileges.json | 1 + public/language/he/admin/menu.json | 16 ++-- public/language/he/email.json | 26 +++---- public/language/he/error.json | 78 +++++++++---------- public/language/he/flags.json | 4 +- public/language/he/ip-blacklist.json | 4 +- public/language/he/notifications.json | 16 ++-- public/language/he/register.json | 4 +- public/language/he/reset_password.json | 4 +- public/language/he/search.json | 6 +- public/language/he/tags.json | 2 +- public/language/he/users.json | 2 +- .../language/hr/admin/manage/privileges.json | 1 + .../language/hu/admin/manage/privileges.json | 1 + .../language/id/admin/manage/privileges.json | 1 + .../language/it/admin/manage/privileges.json | 1 + .../language/ja/admin/manage/privileges.json | 1 + .../language/ko/admin/manage/privileges.json | 1 + .../language/lt/admin/manage/privileges.json | 1 + .../language/lv/admin/manage/privileges.json | 1 + .../language/ms/admin/manage/privileges.json | 1 + .../language/nb/admin/manage/privileges.json | 1 + .../language/nl/admin/manage/privileges.json | 1 + .../language/pl/admin/manage/privileges.json | 1 + .../pt-BR/admin/manage/privileges.json | 1 + .../pt-PT/admin/manage/privileges.json | 1 + .../language/ro/admin/manage/privileges.json | 1 + .../language/ru/admin/manage/privileges.json | 1 + .../language/rw/admin/manage/privileges.json | 1 + .../language/sc/admin/manage/privileges.json | 1 + .../language/sk/admin/manage/privileges.json | 1 + .../language/sl/admin/manage/privileges.json | 1 + .../language/sr/admin/manage/privileges.json | 1 + .../language/sv/admin/manage/privileges.json | 1 + .../language/th/admin/manage/privileges.json | 1 + .../language/tr/admin/manage/privileges.json | 1 + .../language/uk/admin/manage/privileges.json | 1 + .../language/vi/admin/manage/privileges.json | 1 + .../zh-CN/admin/manage/privileges.json | 1 + .../zh-TW/admin/manage/privileges.json | 1 + 61 files changed, 147 insertions(+), 103 deletions(-) diff --git a/public/language/ar/admin/manage/privileges.json b/public/language/ar/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/ar/admin/manage/privileges.json +++ b/public/language/ar/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/bg/admin/manage/privileges.json b/public/language/bg/admin/manage/privileges.json index 10f407dcdd..0b481eb69f 100644 --- a/public/language/bg/admin/manage/privileges.json +++ b/public/language/bg/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Правомощия за групите", "user-privileges": "Правомощия за потребителите", "edit-privileges": "Редактиране на правомощията", + "select-clear-all": "Избиране/изчистване на всичко", "chat": "Разговор", "upload-images": "Качване на изображения", "upload-files": "Качване на файлове", diff --git a/public/language/bn/admin/manage/privileges.json b/public/language/bn/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/bn/admin/manage/privileges.json +++ b/public/language/bn/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/cs/admin/manage/privileges.json b/public/language/cs/admin/manage/privileges.json index 16f257ae6c..5e3a34dc4b 100644 --- a/public/language/cs/admin/manage/privileges.json +++ b/public/language/cs/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Oprávnění skupiny", "user-privileges": "Oprávnění uživatele", "edit-privileges": "Upravit oprávnění", + "select-clear-all": "Select/Clear All", "chat": "Konverzace", "upload-images": "Nahrát obrázky", "upload-files": "Náhrát soubory", diff --git a/public/language/da/admin/manage/privileges.json b/public/language/da/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/da/admin/manage/privileges.json +++ b/public/language/da/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/de/admin/manage/privileges.json b/public/language/de/admin/manage/privileges.json index 010833b7c2..767631b11b 100644 --- a/public/language/de/admin/manage/privileges.json +++ b/public/language/de/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Bilder hochladen", "upload-files": "Dateien hochladen", diff --git a/public/language/el/admin/manage/privileges.json b/public/language/el/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/el/admin/manage/privileges.json +++ b/public/language/el/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/en-US/admin/manage/privileges.json b/public/language/en-US/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/en-US/admin/manage/privileges.json +++ b/public/language/en-US/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/en-x-pirate/admin/manage/privileges.json b/public/language/en-x-pirate/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/en-x-pirate/admin/manage/privileges.json +++ b/public/language/en-x-pirate/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/es/admin/manage/privileges.json b/public/language/es/admin/manage/privileges.json index b40262ebb9..118cc2d722 100644 --- a/public/language/es/admin/manage/privileges.json +++ b/public/language/es/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Subir imágenes", "upload-files": "Subir Archivos", diff --git a/public/language/et/admin/manage/privileges.json b/public/language/et/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/et/admin/manage/privileges.json +++ b/public/language/et/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/fa-IR/admin/manage/privileges.json b/public/language/fa-IR/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/fa-IR/admin/manage/privileges.json +++ b/public/language/fa-IR/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/fi/admin/manage/privileges.json b/public/language/fi/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/fi/admin/manage/privileges.json +++ b/public/language/fi/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/fr/admin/manage/privileges.json b/public/language/fr/admin/manage/privileges.json index b9f4fcb5ef..4f274df88f 100644 --- a/public/language/fr/admin/manage/privileges.json +++ b/public/language/fr/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Privilèges de groupe", "user-privileges": "Privilèges d'utilisateur", "edit-privileges": "Éditer les privilèges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Images envoyées", "upload-files": "Fichiers envoyés", diff --git a/public/language/fr/admin/settings/api.json b/public/language/fr/admin/settings/api.json index 85a6230fd5..f6e04bd349 100644 --- a/public/language/fr/admin/settings/api.json +++ b/public/language/fr/admin/settings/api.json @@ -1,12 +1,12 @@ { "tokens": "Tokens", - "settings": "Settings", + "settings": "Paramètres", "lead-text": "À partir de cette page, vous pouvez configurer l'accès à l'API d'écriture dans NodeBB.", "intro": "Par défaut, l'API d'écriture authentifie les utilisateurs en fonction de leur cookie de session, mais NodeBB prend également en charge l'authentification du porteur via des tokens générés via cette page.", "docs": "Cliquez ici pour accéder à la spécification complète de l'API", - "require-https": "Require API usage via HTTPS only", - "require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.", + "require-https": "Forcer l'utilisation de l'API via HTTPS uniquement", + "require-https-caveat": "Remarque: certaines installations impliquant des load balancer peuvent transmettre leurs requêtes à NodeBB via HTTP, auquel cas cette option doit rester désactivée.", "uid": "ID Utilisateur", "uid-help-text": "Spécifiez un ID utilisateur à associer à ce token. Si l'ID utilisateur est 0, il sera considéré comme un token maître, qui peut prendre l'identité d'autres utilisateurs en fonction du paramètre _uid", diff --git a/public/language/gl/admin/manage/privileges.json b/public/language/gl/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/gl/admin/manage/privileges.json +++ b/public/language/gl/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/he/admin/advanced/database.json b/public/language/he/admin/advanced/database.json index 356a4cd919..1e66929a54 100644 --- a/public/language/he/admin/advanced/database.json +++ b/public/language/he/admin/advanced/database.json @@ -1,12 +1,12 @@ { - "x-b": "%1 בתים", + "x-b": "%1 ביטים", "x-mb": "%1 מגה בייט", "x-gb": "%1 ג'יגה בייט", "uptime-seconds": "זמן מאתחול אחרון בשניות", "uptime-days": "זמן מאתחול אחרון בימים", "mongo": "Mongo", - "mongo.version": "גרסאת MongoDB", + "mongo.version": "גרסת MongoDB", "mongo.storage-engine": "מנוע אחסון", "mongo.collections": "אוסף", "mongo.objects": "אובייקטים", @@ -36,7 +36,7 @@ "redis.memory-frag-ratio": "יחס פיצול זכרון", "redis.total-connections-recieved": "סך כל החיבורים שהתקבלו", "redis.total-commands-processed": "סך כל הפקודות שעובדו", - "redis.iops": "Instantaneous Ops. Per Second", + "redis.iops": "אפשרויות מידיות לשניה", "redis.iinput": "Instantaneous Input Per Second", "redis.ioutput": "Instantaneous Output Per Second", "redis.total-input": "סך הכל מידע נכנס", diff --git a/public/language/he/admin/appearance/customise.json b/public/language/he/admin/appearance/customise.json index 12b86b47fc..c203bc61d9 100644 --- a/public/language/he/admin/appearance/customise.json +++ b/public/language/he/admin/appearance/customise.json @@ -7,10 +7,10 @@ "custom-js.description": "הזן כאן javascript משלך. זה יבוצע לאחר טעינת הדף לחלוטין.", "custom-js.enable": "אפשר Javascript מותאם אישית", - "custom-header": "Custom Header", - "custom-header.description": "Enter custom HTML here (ex. Meta Tags, etc.), which will be appended to the <head> section of your forum's markup. Script tags are allowed, but are discouraged, as the Custom Javascript tab is available.", - "custom-header.enable": "Enable Custom Header", + "custom-header": "HTML מותאם אישית", + "custom-header.description": "הזן כאן HTML משלך (לדוגמא תגיות מטא), שיתווספו לתגית ה-head של הפורום. ניתן להכניס סקריפטים, אך מומלץ להכניס אותם בכרטיסיית Javascript מותאם אישית.", + "custom-header.enable": "אפשר HTML מותאם אישית", - "custom-css.livereload": "Enable Live Reload", - "custom-css.livereload.description": "Enable this to force all sessions on every device under your account to refresh whenever you click save" + "custom-css.livereload": "אפשר טעינה מחדש אוטומטית.", + "custom-css.livereload.description": "אפשר זאת כדי שכל החיבורים מכל מכשיר יתרעננו כאשר אתה שומר." } \ No newline at end of file diff --git a/public/language/he/admin/appearance/skins.json b/public/language/he/admin/appearance/skins.json index 59c15008c7..4f49fb6e2b 100644 --- a/public/language/he/admin/appearance/skins.json +++ b/public/language/he/admin/appearance/skins.json @@ -4,6 +4,6 @@ "select-skin": "סקין נבחר", "current-skin": "סקין נוכחי", "skin-updated": "סקין מעודכן", - "applied-success": "%1 skin was succesfully applied", - "revert-success": "Skin reverted to base colours" + "applied-success": "העיצוב %1 הוחל בהצלחה", + "revert-success": "העיצובהוחזר לצבעים הבסיסיים" } \ No newline at end of file diff --git a/public/language/he/admin/appearance/themes.json b/public/language/he/admin/appearance/themes.json index f8cfca3c8e..00210bdbd0 100644 --- a/public/language/he/admin/appearance/themes.json +++ b/public/language/he/admin/appearance/themes.json @@ -1,11 +1,11 @@ { - "checking-for-installed": "Checking for installed themes...", + "checking-for-installed": "בודק ערכות נושא מותקנות...", "homepage": "דף הבית", - "select-theme": "Select Theme", - "current-theme": "Current Theme", - "no-themes": "No installed themes found", - "revert-confirm": "Are you sure you wish to restore the default NodeBB theme?", - "theme-changed": "Theme Changed", - "revert-success": "You have successfully reverted your NodeBB back to it's default theme.", - "restart-to-activate": "Please rebuild and restart your NodeBB to fully activate this theme." + "select-theme": "בחר ערכת נושא", + "current-theme": "ערכת נושא נוכחית", + "no-themes": "לא נמצאו ערכות נושא מותקנות", + "revert-confirm": "האם אתה בטוח שאתה רוצה לשחזר את ערכת הנושא הרגילה של NodeBB?", + "theme-changed": "ערכת הנושא שונתה", + "revert-success": "החזרת בהצלחה את הפורום שלך לערכת הנושא ברירת המחדל.", + "restart-to-activate": "אנא בצע בנייה והפעלה מחדש כדי להחיל את ערכת הנושא הזו." } \ No newline at end of file diff --git a/public/language/he/admin/extend/rewards.json b/public/language/he/admin/extend/rewards.json index f78c4b2c56..3c4310ffef 100644 --- a/public/language/he/admin/extend/rewards.json +++ b/public/language/he/admin/extend/rewards.json @@ -1,7 +1,7 @@ { "rewards": "פרסים", "condition-if-users": "אם המשתמשים", - "condition-is": "Is:", + "condition-is": "הוא:", "condition-then": "אז:", "max-claims": "מספר הפעמים הניתן לדרוש פרס", "zero-infinite": "הזן 0 לאינסוף", diff --git a/public/language/he/admin/manage/privileges.json b/public/language/he/admin/manage/privileges.json index fb7d158d7f..d6b879ccd5 100644 --- a/public/language/he/admin/manage/privileges.json +++ b/public/language/he/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "הרשאות קבוצתיות", "user-privileges": "הרשאות משתמש", "edit-privileges": "עריכת הרשאות", + "select-clear-all": "Select/Clear All", "chat": "צ'אט", "upload-images": "העלאת תמונות", "upload-files": "העלאת קבצים", diff --git a/public/language/he/admin/menu.json b/public/language/he/admin/menu.json index ba334339a0..30b433b86d 100644 --- a/public/language/he/admin/menu.json +++ b/public/language/he/admin/menu.json @@ -13,7 +13,7 @@ "manage/groups": "קבוצות", "manage/ip-blacklist": "רשימה שחורה של כתובות IP", "manage/uploads": "העלאות", - "manage/digest": "Digests", + "manage/digest": "תקצירים", "section-settings": "הגדרות", "settings/general": "כללי", @@ -44,14 +44,14 @@ "section-appearance": "מראה חיצוני", "appearance/themes": "ערכות נושא", "appearance/skins": "עיצובים", - "appearance/customise": "תוכן מותאם אישי (HTML/JS/CSS)", + "appearance/customise": "תוכן מותאם אישית (HTML/JS/CSS)", - "section-extend": "Extend", + "section-extend": "הרחב", "extend/plugins": "תוספים", "extend/widgets": "וידג'טים", - "extend/rewards": "תגמולים", + "extend/rewards": "פרסים", - "section-social-auth": "אימות חברתי", + "section-social-auth": "אימות חיצוני", "section-plugins": "תוספים", "extend/plugins.install": "תוספים מותקנים", @@ -60,16 +60,16 @@ "advanced/database": "מסד נתונים", "advanced/events": "ארועים", "advanced/hooks": "Hooks", - "advanced/logs": "Logs", + "advanced/logs": "רישומים", "advanced/errors": "שגיאות", "advanced/cache": "עוגיות", - "development/logger": "Logger", + "development/logger": "כותב הרישומים", "development/info": "מידע", "rebuild-and-restart-forum": "בנה והפעל מחדש את הפורום", "restart-forum": "הפעל מחדש את הפורום", "logout": "התנתק", - "view-forum": "צפה בפורום", + "view-forum": "כניסה לפורום", "search.placeholder": "לחץ "/" בכדי לחפש הגדרה", "search.no-results": "אין תוצאות...", diff --git a/public/language/he/email.json b/public/language/he/email.json index 9e1e4c93a0..20b9ebaa02 100644 --- a/public/language/he/email.json +++ b/public/language/he/email.json @@ -21,31 +21,31 @@ "reset.notify.text1": "אנו מודיעים לך שב%1, סיסמתך שונתה בהצלחה.", "reset.notify.text2": "אם לא אישרת בקשה זו, אנא הודע למנהל מיד.", "digest.latest_topics": "נושאים אחרונים מ%1", - "digest.top-topics": "Top topics from %1", - "digest.popular-topics": "Popular topics from %1", + "digest.top-topics": "נושאים עם הכי הרבה הצבעות מ-%1", + "digest.popular-topics": "הנושאים הכי פופולריים מ-%1", "digest.cta": "לחץ כאן כדי לבקר ב %1", "digest.unsub.info": "תקציר זה נשלח אליך על-פי הגדרות החשבון שלך.", "digest.day": "יום", "digest.week": "שבוע", "digest.month": "חודש", "digest.subject": "מקבץ עבור %1", - "digest.title.day": "Your Daily Digest", - "digest.title.week": "Your Weekly Digest", - "digest.title.month": "Your Monthly Digest", + "digest.title.day": "התקציר היומי שלך", + "digest.title.week": "התקציר השבועי שלך", + "digest.title.month": "התקציר החודשי שלך", "notif.chat.subject": "הודעת צ'אט חדשה התקבלה מ%1", "notif.chat.cta": "לחץ כאן כדי להמשיך את השיחה", "notif.chat.unsub.info": "התראה הצ'אט הזו נשלחה אליך על-פי הגדרות החשבון שלך.", "notif.post.unsub.info": "התראת הפוסט הזו נשלחה אליך על-פי הגדרות החשבון שלך.", - "notif.post.unsub.one-click": "Alternatively, unsubscribe from future emails like this, by clicking", - "notif.cta": "To the forum", - "notif.cta-new-reply": "View Post", - "notif.cta-new-chat": "View Chat", - "notif.test.short": "Testing Notifications", - "notif.test.long": "This is a test of the notifications email. Send help!", + "notif.post.unsub.one-click": "ניתן גם להפסיק את קבלת המיילים כמו זה, בלחיצה על", + "notif.cta": "כניסה לפורום", + "notif.cta-new-reply": "הצג פוסט", + "notif.cta-new-chat": "הצג צ'אט", + "notif.test.short": "בדיקת התראות.", + "notif.test.long": "זוהי בדיקה של ההתראות במייל.", "test.text1": "זהו אימייל ניסיון על מנת לוודא שהגדרות המייל בוצעו כהלכה בהגדרות NodeBB.", "unsub.cta": "לחץ כאן לשנות הגדרות אלו", - "unsubscribe": "unsubscribe", - "unsub.success": "You will no longer receive emails from the %1 mailing list", + "unsubscribe": "בטל רישום", + "unsub.success": "אתה לא תקבל יותר מיילים מרשימת התפוצה של %1", "banned.subject": "הורחקת מ %1", "banned.text1": "המשתמש %1 הורחק מ %2.", "banned.text2": "הרחקה זו תמשך עד %1", diff --git a/public/language/he/error.json b/public/language/he/error.json index fa55378caf..47ca223064 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -9,7 +9,7 @@ "invalid-tid": "זהוי נושא שגוי", "invalid-pid": "זהוי פוסט שגוי", "invalid-uid": "זהוי משתמש שגוי", - "invalid-date": "A valid date must be provided", + "invalid-date": "יש לציין תאריך תקין", "invalid-username": "שם משתמש שגוי", "invalid-email": "אימייל שגוי", "invalid-fullname": "שם מלא לא תקין", @@ -30,16 +30,16 @@ "email-invited": "כבר נשלחה הזמנה למייל זה", "email-not-confirmed": "אין באפשרותך לפרסם עד אישור הודעת הדוא\"ל שלך, לחץ כאן כדי לאשר את הדוא\"ל שלך.", "email-not-confirmed-chat": "אין באפשרותך לשוחח עד שהדוא\"ל שלך יאושר, אנא לחץ כאן כדי לאשר את הדוא\"ל שלך.", - "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email. You won't be able to post or chat until your email is confirmed.", + "email-not-confirmed-email-sent": "האימייל שלך עדין לא אושר. אנא בדוק בתיבת הדואר בנוגע לאישור האימייל שנשלח לך על ידנו. לא תוכל לכתוב פוסטים ולהשתמש בצ'אט לפני אימות המייל שלך.", "no-email-to-confirm": "פורום זה דורש אישור בדוא\"ל, אנא לחץ כאן כדי להכניס לדואר אלקטרוני", "email-confirm-failed": "לא הצלחנו לאשר את הדוא\"ל שלך, תנסה שוב אחר כך", "confirm-email-already-sent": "מייל האישור כבר נשלח, אנא המתן %1 דקות כדי לשלוח מייל נוסף.", - "sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.", - "digest-not-enabled": "This user does not have digests enabled, or the system default is not configured to send digests", + "sendmail-not-found": "תוכנת sendmail לא נמצאה, נא בדוק שהיא מותקת וניתנת להרצה על ידי המשתמש שמריץ את NodeBB.", + "digest-not-enabled": "משתמש זה ביטל את התקצירים, או שברירת המחדל של המערכת היא לכבות תקצירים.", "username-too-short": "שם משתמש קצר מדי", "username-too-long": "שם משתמש ארוך מדי", "password-too-long": "הסיסמה ארוכה מדי", - "reset-rate-limited": "Too many password reset requests (rate limited)", + "reset-rate-limited": "יותר מידי בקשות לאימות סיסמא (הקצב מוגבל)", "user-banned": "המשתמש מושעה", "user-banned-reason": "מצטערים, חשבון זה הורחק (סיבה: %1)", "user-banned-reason-until": "מצטערים, חשבון זה הורחק עד %1 (סיבה: %2)", @@ -63,11 +63,11 @@ "post-edit-duration-expired-days": "אתה רשאי לערוך פוסט(ים) רק למשך %1 ימים מרגע פרסומו", "post-edit-duration-expired-days-hours": "אתה רשאי לערוך פוסט(ים) רק למשך %1 שעות %2 דקות מרגע פרסומו(ם)", "post-delete-duration-expired": "אתה רשאי למחוק פוסט(ים) רק למשך %1 שניות מרגע פרסומו", - "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting", - "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting", - "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting", - "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting", - "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", + "post-delete-duration-expired-minutes": "הנך רשאי למחוק תגובה עד %1 דק(ות) מרגע פרסום התגובה.", + "post-delete-duration-expired-minutes-seconds": "הנך רשאי למחוק תגובה עד %1 דק(ות) ו-%2 שני(ות) מרגע פרסום התגובה.", + "post-delete-duration-expired-hours": "הנך רשאי למחוק תגובה עד %1 שע(ות) מרגע פרסום התגובה.", + "post-delete-duration-expired-hours-minutes": "הנך רשאי למחוק פוסט למשך %1 שע(ות) ו-%2 דק(ות) מרגע פרסומו.", + "post-delete-duration-expired-days": "אתה רשאי למחוק פוסט(ים) רק למשך %1 ימים מרגע פרסומם", "post-delete-duration-expired-days-hours": "אתה מורשה למחוק פוסט רק %1 ימים ו %2 שעות אחרי פרסומו", "cant-delete-topic-has-reply": "אינך יכול למחוק נושא אחרי שכבר הגיבו בו.", "cant-delete-topic-has-replies": "לא ניתן למחוק את הנושא לאחר שקיבל %1 תגובות", @@ -85,7 +85,7 @@ "still-uploading": "אנא המתן לסיום ההעלאות", "file-too-big": "הגודל המקסימלי של הקובץ הוא %1 קילובייט - אנא העלה קובץ קטן יותר", "guest-upload-disabled": "העלאת אורחים אינה מאופשרת", - "cors-error": "Unable to upload image due to misconfigured CORS", + "cors-error": "לא ניתן להעלות את התמונה עקב שגיאת CORS.", "already-bookmarked": "כבר הוספת פוסט זה לרשימת המסומנים", "already-unbookmarked": "כבר הסרת פוסט זה מרשימת המסומנים", "cant-ban-other-admins": "אינך יכול לחסום מנהלים אחרים!", @@ -95,7 +95,7 @@ "invalid-image-type": "פורמט תמונה לא תקין. הפורמטים המורשים הם: %1", "invalid-image-extension": "פורמט תמונה לא תקין", "invalid-file-type": "פורמט הקובץ לא תקין. הפורמטים המורשים הם: %1", - "invalid-image-dimensions": "Image dimensions are too big", + "invalid-image-dimensions": "ממדי התמונה גדולים מדי", "group-name-too-short": "שם הקבוצה קצר מדי", "group-name-too-long": "שם הקבוצה ארוך מידי", "group-already-exists": "הקבוצה כבר קיימת", @@ -105,8 +105,8 @@ "group-needs-owner": "קבוצה זו חייבת לפחות מנהל אחד", "group-already-invited": "משתמש זה כבר הוזמן", "group-already-requested": "בקשת החברות שלך כבר נשלחה", - "group-join-disabled": "You are not able to join this group at this time", - "group-leave-disabled": "You are not able to leave this group at this time", + "group-join-disabled": "אתה לא רשאי להצטרף לקבוצה כרגע", + "group-leave-disabled": "אתה לא רשאי לעזוב את הקבוצה כרגע", "post-already-deleted": "פוסט זה כבר נמחק", "post-already-restored": "פוסט זה כבר שוחזר", "topic-already-deleted": "נושא זה כבר נמחק", @@ -126,34 +126,34 @@ "cant-edit-chat-message": "אתה לא רשאי לערוך הודעה זו", "cant-remove-last-user": "אינך יכול למחוק את המשתמש האחרון", "cant-delete-chat-message": "אתה לא רשאי למחוק הודעה זו", - "chat-edit-duration-expired": "You are only allowed to edit chat messages for %1 second(s) after posting", - "chat-delete-duration-expired": "You are only allowed to delete chat messages for %1 second(s) after posting", - "chat-deleted-already": "This chat message has already been deleted.", - "chat-restored-already": "This chat message has already been restored.", + "chat-edit-duration-expired": "אתה רשאי לערוך הודעות צ'אט רק ל-%1 שניות לאחר הפרסום", + "chat-delete-duration-expired": "הנך רשאי למחוק הודעת צ'אט עד %1 דק(ות) מרגע פרסום התגובה.", + "chat-deleted-already": "הודעות הצ'אט הזו כבר נמחקה.", + "chat-restored-already": "הודעות הצ'אט הזו כבר שוחזרה.", "already-voting-for-this-post": "הצבעת כבר בנושא זה", "reputation-system-disabled": "מערכת המוניטין לא פעילה.", "downvoting-disabled": "היכולת להצביע נגד לא פעילה", "not-enough-reputation-to-downvote": "אין לך מספיק מוניטין כדי להוריד את הדירוג של פוסט זה", "not-enough-reputation-to-flag": "אין לך מוניטין מספק על מנת לסמן את הפוסט הזה", - "not-enough-reputation-min-rep-website": "You do not have enough reputation to add a website", - "not-enough-reputation-min-rep-aboutme": "You do not have enough reputation to add an about me", - "not-enough-reputation-min-rep-signature": "You do not have enough reputation to add a signature", - "not-enough-reputation-min-rep-profile-picture": "You do not have enough reputation to add a profile picture", - "not-enough-reputation-min-rep-cover-picture": "You do not have enough reputation to add a cover picture", - "post-already-flagged": "You have already flagged this post", - "user-already-flagged": "You have already flagged this user", - "post-flagged-too-many-times": "This post has been flagged by others already", - "user-flagged-too-many-times": "This user has been flagged by others already", + "not-enough-reputation-min-rep-website": "אין לך מספיק מוניטין כדי להוסיף אתר", + "not-enough-reputation-min-rep-aboutme": "אין לך מספיק מוניטין כדי להוסיף טקסט אודות", + "not-enough-reputation-min-rep-signature": "אין לך מספיק מוניטין כדי להוסיף חתימה", + "not-enough-reputation-min-rep-profile-picture": "אין לך מספיק מוניטין כדי להוסיף תמונת פרופיל", + "not-enough-reputation-min-rep-cover-picture": "אין לך מספיק מוניטין כדי להוסיף תמונת רקע", + "post-already-flagged": "כבר דיווחת על הפוסט הזה", + "user-already-flagged": "כבר דיווחת על המשתמש הזה", + "post-flagged-too-many-times": "התקבל כבר דיווח על פוסט זה.", + "user-flagged-too-many-times": "התקבל דיווח על משתמש זה.", "self-vote": "אי אפשר להצביע בפרסום שיצרת", - "too-many-downvotes-today": "You can only downvote %1 times a day", - "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", + "too-many-downvotes-today": "אתה יכול להצביע נגד %1 פעמים ביום", + "too-many-downvotes-today-user": "אתה יכול להצביע נגד משתמש %1 פעמים ביום", "reload-failed": "אירעה תקלה ב NodeBB בזמן הטעינה של: \"%1\". המערכת תמשיך להגיש דפים קיימים, אבל כדאי שתשחזר את הפעולות שלך מהפעם האחרונה שהמערכת עבדה כראוי.", "registration-error": "שגיאה בהרשמה", "parse-error": "אירעה שגיאה בעת בעת ניתוח תגובת השרת", "wrong-login-type-email": "בבקשה השתמש בכתובת המייל שלך להתחברות", "wrong-login-type-username": "בבקשה השתמש בשם המשתמש שלך להתחברות", "sso-registration-disabled": "ההרשמה בוטלה ל%1 מהחשבונות, תחילה הרשם עם כתובת דוא\"ל בבקשה", - "sso-multiple-association": "You cannot associate multiple accounts from this service to your NodeBB account. Please dissociate your existing account and try again.", + "sso-multiple-association": "אתה לא יכול לחבר מספר חשבונות משירות זה לחשבון שלך. אנא בטל את שיוך החשבון הקיים ונסה שוב.", "invite-maximum-met": "הזמנת את הכמות המירבית של אנשים (%1 מתוך %2).", "no-session-found": "לא נמצאו מושבי התחברות!", "not-in-room": "משתמש זה לא בצ'אט", @@ -163,13 +163,13 @@ "invalid-session": "מושב לא תואם", "invalid-session-text": "נראה שסשן ההתחברות שלך כבר לא פעיל. אנא טען מחדש את העמוד.", "no-topics-selected": "לא נבחרו נושאים!", - "cant-move-to-same-topic": "Can't move post to same topic!", - "cant-move-topic-to-same-category": "Can't move topic to the same category!", - "cannot-block-self": "You cannot block yourself!", - "cannot-block-privileged": "You cannot block administrators or global moderators", - "cannot-block-guest": "Guest are not able to block other users", - "already-blocked": "This user is already blocked", - "already-unblocked": "This user is already unblocked", - "no-connection": "There seems to be a problem with your internet connection", - "plugin-not-whitelisted": "Unable to install plugin – only plugins whitelisted by the NodeBB Package Manager can be installed via the ACP" + "cant-move-to-same-topic": "אתה לא יכול להעביר פוסט לאותו נושא!", + "cant-move-topic-to-same-category": "לא ניתן להעביר נושא לאותה קטגוריה!", + "cannot-block-self": "אתה לא יכול לחסום את עצמך!", + "cannot-block-privileged": "אתה לא יכול לחסום מנהלים ראשיים ומנהלים גלובליים", + "cannot-block-guest": "אורח לא יכול לחסום משתמשים אחרים", + "already-blocked": "המשתמש כבר חסום", + "already-unblocked": "המשתמש כבר לא חסום", + "no-connection": "נראה שיש בעיות בחיבור האינטרנט שלך..", + "plugin-not-whitelisted": "לא ניתן להתקין את התוסף – ניתן להתקין דרך הניהול רק תוספים שנמצאים ברשימה הלבנה של מנהל החבילות של NodeBB." } \ No newline at end of file diff --git a/public/language/he/flags.json b/public/language/he/flags.json index 1656b0bbf3..bd60a02dbf 100644 --- a/public/language/he/flags.json +++ b/public/language/he/flags.json @@ -67,7 +67,7 @@ "sort-upvotes": "הכי הרבה הצבעות", "sort-replies": "הכי הרבה תגובות", - "modal-title": "Report Content", + "modal-title": "תוכן הדיווח", "modal-body": "אנא ציין את הסיבה לסימון %1 %2 לצורך בקרה. לחלופין, השתמש באחד מכפתורי הדיווח המהיר אם אפשר.", "modal-reason-spam": "זבל", "modal-reason-offensive": "פוגעני", @@ -79,7 +79,7 @@ "modal-submit-confirm-text": "כבר ציינת סיבה. האם אתה בטוח שאתה רוצה לשלוח על ידי דיווח-מהיר?", "modal-submit-confirm-text-help": "שליחת דיווח מהיר תבטל כל סיבה קודמת שהוגדרה.", - "bulk-actions": "Bulk Actions", + "bulk-actions": "פעולות כלליות", "bulk-resolve": "השלם דיווחים", "bulk-success": "%1 דיווחים עודכנו" } \ No newline at end of file diff --git a/public/language/he/ip-blacklist.json b/public/language/he/ip-blacklist.json index 5f1b6a2ffe..7208f8842b 100644 --- a/public/language/he/ip-blacklist.json +++ b/public/language/he/ip-blacklist.json @@ -1,6 +1,6 @@ { "lead": "רשימת IP שחורה", - "description": "Occasionally, a user account ban is not enough of a deterrant. Other times, restricting access to the forum to a specific IP or a range of IPs is the best way to protect a forum. In these scenarios, you can add troublesome IP addresses or entire CIDR blocks to this blacklist, and they will be prevented from logging in to or registering a new account.", + "description": "לעיתים, הרחקת חשבון משתמש אינו מספיק כדי להרתיע. בפעמים אחרות, הגבלת הגישה לפורום ל- IP ספציפי או לטווח של IP היא הדרך הטובה ביותר להגן על הפורום. בתרחישים אלה, תוכלו להוסיף כתובות IP מטרידות או טווחי CIDR שלמים לרשימה השחורה הזו, וימנע מהם להיכנס לחשבון חדש או לרשום אותו.", "active-rules": "כללים פעילים", "validate": "בדיקת רשימה", "apply": "החל רשימה", @@ -14,6 +14,6 @@ "alerts.applied-success": "הרשימה השחורה נשמרה", "analytics.blacklist-hourly": "Figure 1 – כתובות נחסמו ביחס לשעה.", - "analytics.blacklist-daily": "Figure 2 – Blacklist hits per day", + "analytics.blacklist-daily": "Figure 2 – כתובות נחסמו ביחס ליום.", "ip-banned": "כתובת הIP הורחקה." } \ No newline at end of file diff --git a/public/language/he/notifications.json b/public/language/he/notifications.json index 797ca6f387..99b0474c1f 100644 --- a/public/language/he/notifications.json +++ b/public/language/he/notifications.json @@ -35,7 +35,7 @@ "user_posted_to_dual": "%1 ו%2 הגיבו ל: %3", "user_posted_to_multiple": "%1 ו%2 אחרים הגיבו ל: %3", "user_posted_topic": "%1 העלה נושא חדש: %2", - "user_edited_post": "%1 has edited a post in %2", + "user_edited_post": "%1 ערך פוסט ב%2", "user_started_following_you": "%1 התחיל לעקוב אחריך.", "user_started_following_you_dual": "%1 ו-%2 התחילו לעקוב אחריך.", "user_started_following_you_multiple": "%1 ו%2 התחילו לעקוב אחריך.", @@ -43,9 +43,9 @@ "new_register_multiple": "ישנן %1 בקשות הרשמה שמחכות לבדיקה.", "flag_assigned_to_you": "דיווח %1 הוקצה עבורך", "post_awaiting_review": "הפוסט ממתין לאישור", - "profile-exported": "%1 profile exported, click to download", - "posts-exported": "%1 posts exported, click to download", - "uploads-exported": "%1 uploads exported, click to download", + "profile-exported": "%1 פרופיל יוצא, לחץ כדי להוריד.", + "posts-exported": "%1 פוסטים יוצאו, לחץ כדי להוריד.", + "uploads-exported": "%1 העלאות יוצאו, לחץ כדי להוריד.", "email-confirmed": "כתובת המייל אושרה", "email-confirmed-message": "תודה שאישרת את כתובת המייל שלך. החשבון שלך פעיל כעת.", "email-confirm-error-message": "אירעה שגיאה בעת אישור המייל שלך. ייתכן כי הקוד היה שגוי או פג תוקף.", @@ -56,13 +56,13 @@ "notification_and_email": "התראות & דוא\"ל", "notificationType_upvote": "כאשר מישהו מצביע בעד הפוסט שלך", "notificationType_new-topic": "כשמישהו שאתה עוקב אחריו פרסם נושא", - "notificationType_new-reply": "כשתגובה חדשה מפורסמת בנושא שאתה צופה בו", - "notificationType_post-edit": "When a post is edited in a topic you are watching", + "notificationType_new-reply": "כשתגובה חדשה מפורסמת בנושא שאתה עוקב אחריו", + "notificationType_post-edit": "כשפוסט נערך בנושא שאתה עוקב אחריו", "notificationType_follow": "כשמישהו מתחיל לעקוב אחריך", "notificationType_new-chat": "כשאתה מקבל הודעת צאט", - "notificationType_new-group-chat": "When you receive a group chat message", + "notificationType_new-group-chat": "כשאתה מקבל הודעת צ'אט קבוצתית", "notificationType_group-invite": "כשאתה מקבל הזמנה מקבוצה", - "notificationType_group-request-membership": "When someone requests to join a group you own", + "notificationType_group-request-membership": "כשמישהו מבקש להירשם לקבוצה שאתה מנהל", "notificationType_new-register": "כאשר מישהו מתווסף לתור הרישום", "notificationType_post-queue": "כשהודעה חדשה נכנסת לתור", "notificationType_new-post-flag": "כאשר פוסט מסומן", diff --git a/public/language/he/register.json b/public/language/he/register.json index 5e66599e67..0905771a84 100644 --- a/public/language/he/register.json +++ b/public/language/he/register.json @@ -18,8 +18,8 @@ "agree_to_terms_of_use": "אני מסכים לתנאי השימוש", "terms_of_use_error": "אתה מוכרח להסכים לתנאי השימוש", "registration-added-to-queue": "הבקשה שלך להרשמה נשלחה. תקבל בקרוב מייל אישור לכתובת האימייל שהכנסת כשמנהל יאשר את הבקשה.", - "registration-queue-average-time": "Our average time for approving memberships is %1 hours %2 minutes.", - "registration-queue-auto-approve-time": "Your membership to this forum will be fully activated in up to %1 hours.", + "registration-queue-average-time": "הזמן הממוצע לאישור משתמשים הוא %1 שעות ו-%2 דקות.", + "registration-queue-auto-approve-time": "חשבונך יאושר תוך %1 שעות.", "interstitial.intro": "אנו דורשים מידע נוסף לפני שנוכל ליצור עבורך את החשבון.", "interstitial.errors-found": "לא הצלחנו להשלים את הרישום שלך:", "gdpr_agree_data": "אני מסכים שפורום זה יאגור ויעבד את נתוני האישיים", diff --git a/public/language/he/reset_password.json b/public/language/he/reset_password.json index 10f58e8c7c..38f8fa4b3e 100644 --- a/public/language/he/reset_password.json +++ b/public/language/he/reset_password.json @@ -7,10 +7,10 @@ "wrong_reset_code.message": "קוד האיפוס שקבלנו שגוי. אנא נסה שוב, או בקש קוד איפוס חדש.", "new_password": "סיסמה חדשה", "repeat_password": "אמת סיסמה", - "changing_password": "Changing Password", + "changing_password": "משנה סיסמה", "enter_email": "אנא הקלד את כתובת האימייל שלך ואנו נשלח לך הוראות כיצד לאפס את חשבונך", "enter_email_address": "הכנס כתובת אימייל", - "password_reset_sent": "If the specified address corresponds to an existing user account, a password reset email was sent. Please note that only one email will be sent per minute.", + "password_reset_sent": "אם כתובת המייל משוייכת לחשבון קיים, לכתובת המוגדרת נשלח מייל לשחזור חשבון. שים לב שרק מייל שחזור אחד ישלח כל דקה.", "invalid_email": "מייל שגוי / כתובת מייל לא נמצאה", "password_too_short": "הסיסמה שבחרת קצרה מדי, אנא בחר סיסמה שונה.", "passwords_do_not_match": "הסיסמאות שהזנת אינן תואמות.", diff --git a/public/language/he/search.json b/public/language/he/search.json index a6682f3938..fcad1a9ea0 100644 --- a/public/language/he/search.json +++ b/public/language/he/search.json @@ -31,7 +31,7 @@ "sort-by": "סדר על-פי", "last-reply-time": "תאריך תגובה אחרון", "topic-title": "כותרת הנושא", - "topic-votes": "Topic votes", + "topic-votes": "הצבעות בנושא", "number-of-replies": "מספר התגובות", "number-of-views": "מספר הצפיות", "topic-start-date": "זמן תחילת הנושא", @@ -44,6 +44,6 @@ "search-preferences-saved": "חפש העדפות שנשמרו", "search-preferences-cleared": "חפש העדפות שנוקו", "show-results-as": "צפה בתוצאות בתור", - "see-more-results": "See more results (%1)", - "search-in-category": "Search in \"%1\"" + "see-more-results": "צפה בתוצאות נוספות (%1)", + "search-in-category": "חפש ב-\"%1\"" } \ No newline at end of file diff --git a/public/language/he/tags.json b/public/language/he/tags.json index 1e52cbc67c..6604da7815 100644 --- a/public/language/he/tags.json +++ b/public/language/he/tags.json @@ -4,5 +4,5 @@ "enter_tags_here": "הכנס תגים כאן, כאשר כל אחד בין %1 ל%2 תווים.", "enter_tags_here_short": "הכנס תגיות", "no_tags": "אין עדיין תגיות.", - "select_tags": "Select Tags" + "select_tags": "בחר תגיות" } \ No newline at end of file diff --git a/public/language/he/users.json b/public/language/he/users.json index 86d603aaf6..eb9adf7bea 100644 --- a/public/language/he/users.json +++ b/public/language/he/users.json @@ -11,7 +11,7 @@ "online-only": "אונליין בלבד", "invite": "הזמן", "prompt-email": "מיילים:", - "groups-to-join": "Groups to be joined when invite is accepted:", + "groups-to-join": "קבוצות שתירשם אליהם כאשר ההזמנה תאושר:", "invitation-email-sent": "מייל הזמנה נשלח ל%1", "user_list": "רשימת משתמשים", "recent_topics": "נושאים אחרונים", diff --git a/public/language/hr/admin/manage/privileges.json b/public/language/hr/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/hr/admin/manage/privileges.json +++ b/public/language/hr/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/hu/admin/manage/privileges.json b/public/language/hu/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/hu/admin/manage/privileges.json +++ b/public/language/hu/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/id/admin/manage/privileges.json b/public/language/id/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/id/admin/manage/privileges.json +++ b/public/language/id/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/it/admin/manage/privileges.json b/public/language/it/admin/manage/privileges.json index 1d3327aab7..3e10a33b8e 100644 --- a/public/language/it/admin/manage/privileges.json +++ b/public/language/it/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Privilegi di gruppo", "user-privileges": "Privilegi utente", "edit-privileges": "Modifica privilegi", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Carica immagini", "upload-files": "Carica file", diff --git a/public/language/ja/admin/manage/privileges.json b/public/language/ja/admin/manage/privileges.json index c747ae74fd..8afef9882b 100644 --- a/public/language/ja/admin/manage/privileges.json +++ b/public/language/ja/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "チャット", "upload-images": "画像をアップロード", "upload-files": "ファイルをアップロード", diff --git a/public/language/ko/admin/manage/privileges.json b/public/language/ko/admin/manage/privileges.json index 797e19bd85..f135f9a1b8 100644 --- a/public/language/ko/admin/manage/privileges.json +++ b/public/language/ko/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "대화", "upload-images": "이미지 업로드", "upload-files": "파일 업로드", diff --git a/public/language/lt/admin/manage/privileges.json b/public/language/lt/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/lt/admin/manage/privileges.json +++ b/public/language/lt/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/lv/admin/manage/privileges.json b/public/language/lv/admin/manage/privileges.json index 3a030df713..1bd5ca057c 100644 --- a/public/language/lv/admin/manage/privileges.json +++ b/public/language/lv/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Sarunāties", "upload-images": "Augšupielādēt bildes", "upload-files": "Augšupielādēt failus", diff --git a/public/language/ms/admin/manage/privileges.json b/public/language/ms/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/ms/admin/manage/privileges.json +++ b/public/language/ms/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/nb/admin/manage/privileges.json b/public/language/nb/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/nb/admin/manage/privileges.json +++ b/public/language/nb/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/nl/admin/manage/privileges.json b/public/language/nl/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/nl/admin/manage/privileges.json +++ b/public/language/nl/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/pl/admin/manage/privileges.json b/public/language/pl/admin/manage/privileges.json index fa3530abac..4e845d4e35 100644 --- a/public/language/pl/admin/manage/privileges.json +++ b/public/language/pl/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Uprawnienia grup", "user-privileges": "Uprawnienia użytkownika", "edit-privileges": "Edytuj uprawnienia", + "select-clear-all": "Select/Clear All", "chat": "Dostęp do czatu", "upload-images": "Przesyłanie zdjęć", "upload-files": "Przesyłanie plików", diff --git a/public/language/pt-BR/admin/manage/privileges.json b/public/language/pt-BR/admin/manage/privileges.json index a54d8b9712..8c669d01a5 100644 --- a/public/language/pt-BR/admin/manage/privileges.json +++ b/public/language/pt-BR/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Conversar", "upload-images": "Enviar Imagens", "upload-files": "Enviar Arquivos", diff --git a/public/language/pt-PT/admin/manage/privileges.json b/public/language/pt-PT/admin/manage/privileges.json index 81e7ad9634..ca35e46541 100644 --- a/public/language/pt-PT/admin/manage/privileges.json +++ b/public/language/pt-PT/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Privilégios de Grupos", "user-privileges": "Privilégios de Utilizadores", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Conversa", "upload-images": "Enviar Imagens", "upload-files": "Enviar Ficheiros", diff --git a/public/language/ro/admin/manage/privileges.json b/public/language/ro/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/ro/admin/manage/privileges.json +++ b/public/language/ro/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/ru/admin/manage/privileges.json b/public/language/ru/admin/manage/privileges.json index 556d5cce86..a09c20ab31 100644 --- a/public/language/ru/admin/manage/privileges.json +++ b/public/language/ru/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Права групп", "user-privileges": "Права пользователей", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Чат", "upload-images": "Загрузка изображений", "upload-files": "Загрузка файлов", diff --git a/public/language/rw/admin/manage/privileges.json b/public/language/rw/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/rw/admin/manage/privileges.json +++ b/public/language/rw/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/sc/admin/manage/privileges.json b/public/language/sc/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/sc/admin/manage/privileges.json +++ b/public/language/sc/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/sk/admin/manage/privileges.json b/public/language/sk/admin/manage/privileges.json index 45f4974589..b787c7dd0f 100644 --- a/public/language/sk/admin/manage/privileges.json +++ b/public/language/sk/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Konverzácia", "upload-images": "Nahrať obrázky", "upload-files": "Nahrať súbory", diff --git a/public/language/sl/admin/manage/privileges.json b/public/language/sl/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/sl/admin/manage/privileges.json +++ b/public/language/sl/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/sr/admin/manage/privileges.json b/public/language/sr/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/sr/admin/manage/privileges.json +++ b/public/language/sr/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/sv/admin/manage/privileges.json b/public/language/sv/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/sv/admin/manage/privileges.json +++ b/public/language/sv/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/th/admin/manage/privileges.json b/public/language/th/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/th/admin/manage/privileges.json +++ b/public/language/th/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/tr/admin/manage/privileges.json b/public/language/tr/admin/manage/privileges.json index 821d8607bf..fd11b7201d 100644 --- a/public/language/tr/admin/manage/privileges.json +++ b/public/language/tr/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Grup Ayrıcalıkları", "user-privileges": "Kullanıcı Ayrıcalıkları", "edit-privileges": "Ayrıcalıkları Düzenle", + "select-clear-all": "Select/Clear All", "chat": "Sohbet", "upload-images": "Resim Yükle", "upload-files": "Dosya Yükle", diff --git a/public/language/uk/admin/manage/privileges.json b/public/language/uk/admin/manage/privileges.json index 08558a58bd..d1ddb942f3 100644 --- a/public/language/uk/admin/manage/privileges.json +++ b/public/language/uk/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Чат", "upload-images": "Завантаження Зображень", "upload-files": "Завантаження Файлів", diff --git a/public/language/vi/admin/manage/privileges.json b/public/language/vi/admin/manage/privileges.json index 3b24b1cc3e..d90fb7893d 100644 --- a/public/language/vi/admin/manage/privileges.json +++ b/public/language/vi/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "Group Privileges", "user-privileges": "User Privileges", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "Chat", "upload-images": "Upload Images", "upload-files": "Upload Files", diff --git a/public/language/zh-CN/admin/manage/privileges.json b/public/language/zh-CN/admin/manage/privileges.json index d48c61b0e9..3d8b8bbd72 100644 --- a/public/language/zh-CN/admin/manage/privileges.json +++ b/public/language/zh-CN/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "群组权限", "user-privileges": "用户权限", "edit-privileges": "编辑权限", + "select-clear-all": "Select/Clear All", "chat": "对话", "upload-images": "上传图片", "upload-files": "上传文件", diff --git a/public/language/zh-TW/admin/manage/privileges.json b/public/language/zh-TW/admin/manage/privileges.json index b80f3bf5f6..88d37d2f19 100644 --- a/public/language/zh-TW/admin/manage/privileges.json +++ b/public/language/zh-TW/admin/manage/privileges.json @@ -4,6 +4,7 @@ "group-privileges": "群組權限", "user-privileges": "使用者權限", "edit-privileges": "Edit Privileges", + "select-clear-all": "Select/Clear All", "chat": "聊天", "upload-images": "上傳圖片", "upload-files": "上傳檔案", From c8554b78b9e937687c1caf56fb0d3fb0333d3d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 10:30:33 -0500 Subject: [PATCH 022/116] fix: #8968, don't show topic search if search is not enabled --- public/src/app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/src/app.js b/public/src/app.js index 4bec1e1e69..7e61d467be 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -444,6 +444,9 @@ app.cacheBuster = null; } app.enableTopicSearch = function (options) { + if (!config.searchEnabled) { + return; + } /* eslint-disable-next-line */ var searchOptions = Object.assign({ in: 'titles' }, options.searchOptions); var quickSearchResults = options.searchElements.resultEl; From 22715d54131e2d768e76c589fcd144e5a11f3bc6 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 10:29:44 -0500 Subject: [PATCH 023/116] refactor: add TopicObjectSlim common schema --- .../components/schemas/TopicObject.yaml | 66 +++- public/openapi/read/topic/tid/id.yaml | 60 +--- public/openapi/read/topic/topic_id.yaml | 46 +-- public/openapi/read/unread.yaml | 306 ++++++++---------- 4 files changed, 209 insertions(+), 269 deletions(-) diff --git a/public/openapi/components/schemas/TopicObject.yaml b/public/openapi/components/schemas/TopicObject.yaml index 590872e03e..2e5085158f 100644 --- a/public/openapi/components/schemas/TopicObject.yaml +++ b/public/openapi/components/schemas/TopicObject.yaml @@ -13,8 +13,7 @@ TopicObject: description: A category identifier mainPid: type: number - description: The post id of the first post in this topic (also called the - "original post") + description: The post id of the first post in this topic (also called the "original post") title: type: string slug: @@ -55,6 +54,7 @@ TopicObject: description: An ISO 8601 formatted date string (complementing `timestamp`) lastposttimeISO: type: string + description: An ISO 8601 formatted date string (complementing `lastposttime`) votes: type: number category: @@ -230,5 +230,65 @@ TopicObject: description: A topic identifier thumb: type: string + pinExpiry: + type: number + description: A UNIX timestamp indicating when a pinned topic will no longer be pinned (i.e. the pin has expired) + pinExpiryISO: + type: string + description: "`pinExpiry` rendered as an ISO 8601 format" required: - - tid \ No newline at end of file + - tid +TopicObjectSlim: + description: The output of a call to `Topics.getTopicField`, these properties are always present no matter the fields passed in + type: object + properties: + tid: + type: number + description: A topic identifier + uid: + type: number + description: A user identifier + cid: + type: number + description: A category identifier + mainPid: + type: number + description: The post id of the first post in this topic (also called the "original post") + postcount: + type: number + viewcount: + type: number + postercount: + type: number + deleted: + type: number + deleterUid: + type: number + locked: + type: number + pinned: + type: number + description: Whether or not this particular topic is pinned to the top of the + category + timestamp: + type: number + timestampISO: + type: string + description: An ISO 8601 formatted date string (complementing `timestamp`) + lastposttime: + type: number + lastposttimeISO: + type: string + description: An ISO 8601 formatted date string (complementing `lastposttime`) + pinExpiry: + type: number + description: A UNIX timestamp indicating when a pinned topic will no longer be pinned (i.e. the pin has expired) + pinExpiryISO: + type: string + description: "`pinExpiry` rendered as an ISO 8601 format" + upvotes: + type: number + downvotes: + type: number + votes: + type: number \ No newline at end of file diff --git a/public/openapi/read/topic/tid/id.yaml b/public/openapi/read/topic/tid/id.yaml index cdc638a1f5..5305a99c7f 100644 --- a/public/openapi/read/topic/tid/id.yaml +++ b/public/openapi/read/topic/tid/id.yaml @@ -15,50 +15,16 @@ get: content: application/json: schema: - type: object - properties: - tid: - type: number - uid: - type: number - cid: - type: number - mainPid: - type: number - teaserPid: - type: number - nullable: true - title: - type: string - slug: - type: string - timestamp: - type: number - lastposttime: - type: number - postercount: - type: number - postcount: - type: number - viewcount: - type: number - deleted: - type: number - locked: - type: number - pinned: - type: number - upvotes: - type: number - downvotes: - type: number - deleterUid: - type: number - titleRaw: - type: string - timestampISO: - type: string - lastposttimeISO: - type: string - votes: - type: number \ No newline at end of file + allOf: + - $ref: ../../../components/schemas/TopicObject.yaml#/TopicObjectSlim + - type: object + properties: + teaserPid: + type: number + nullable: true + title: + type: string + slug: + type: string + titleRaw: + type: string \ No newline at end of file diff --git a/public/openapi/read/topic/topic_id.yaml b/public/openapi/read/topic/topic_id.yaml index 88081d23dc..67f7ef3096 100644 --- a/public/openapi/read/topic/topic_id.yaml +++ b/public/openapi/read/topic/topic_id.yaml @@ -30,62 +30,18 @@ get: application/json: schema: allOf: + - $ref: ../../components/schemas/TopicObject.yaml#/TopicObjectSlim - type: object properties: - tid: - type: number - description: A topic identifier - uid: - type: number - description: A user identifier - cid: - type: number - description: A category identifier title: type: string slug: type: string - timestamp: - type: number - lastposttime: - type: number - postcount: - type: number - viewcount: - type: number - postercount: - type: number - description: The number of unique users who made a post in this topic - mainPid: - type: number - description: The post id of the first post in this topic (also called the - "original post") teaserPid: type: number nullable: true - upvotes: - type: number - downvotes: - type: number - deleted: - type: number - locked: - type: number - pinned: - type: number - description: Whether or not this particular topic is pinned to the top of the - category - deleterUid: - type: number titleRaw: type: string - timestampISO: - type: string - description: An ISO 8601 formatted date string (complementing `timestamp`) - lastposttimeISO: - type: string - votes: - type: number tags: type: array items: diff --git a/public/openapi/read/unread.yaml b/public/openapi/read/unread.yaml index a5fe83348e..e2b48faee9 100644 --- a/public/openapi/read/unread.yaml +++ b/public/openapi/read/unread.yaml @@ -22,162 +22,42 @@ get: topics: type: array items: - type: object - properties: - tid: - type: number - description: A topic identifier - uid: - type: number - description: A user identifier - cid: - type: number - description: A category identifier - mainPid: - type: number - description: The post id of the first post in this topic (also called the - "original post") - title: - type: string - slug: - type: string - timestamp: - type: number - lastposttime: - type: number - postcount: - type: number - viewcount: - type: number - postercount: - type: number - teaserPid: - type: number - nullable: true - upvotes: - type: number - downvotes: - type: number - deleterUid: - type: number - deleted: - type: number - locked: - type: number - pinned: - type: number - description: Whether or not this particular topic is pinned to the top of the - category - titleRaw: - type: string - timestampISO: - type: string - description: An ISO 8601 formatted date string (complementing `timestamp`) - lastposttimeISO: - type: string - votes: - type: number - category: - type: object + allOf: + - $ref: ../components/schemas/TopicObject.yaml#/TopicObjectSlim + - type: object properties: - cid: - type: number - description: A category identifier - name: + title: type: string slug: type: string - icon: - type: string - backgroundImage: - nullable: true - imageClass: + teaserPid: + type: number nullable: true + titleRaw: type: string - bgColor: - type: string - color: - type: string - disabled: - type: number - user: - type: object - properties: - uid: - type: number - description: A user identifier - username: - type: string - description: A friendly name for a given user account - displayname: - type: string - description: This is either username or fullname depending on forum and user settings - fullname: - type: string - userslug: - type: string - description: An URL-safe variant of the username (i.e. lower-cased, spaces - removed, etc.) - reputation: - type: number - postcount: - type: number - picture: - nullable: true - type: string - signature: - nullable: true - type: string - banned: - type: number - status: - type: string - icon:text: - type: string - description: A single-letter representation of a username. This is used in the - auto-generated icon given to users without - an avatar - icon:bgColor: - type: string - description: A six-character hexadecimal colour code assigned to the user. This - value is used in conjunction with - `icon:text` for the user's auto-generated - icon - example: "#f44336" - banned_until_readable: - type: string - required: - - uid - - username - - userslug - - reputation - - postcount - - picture - - signature - - banned - - status - - icon:text - - icon:bgColor - - banned_until_readable - teaser: - type: object - nullable: true - properties: - pid: - type: number - uid: - type: number - description: A user identifier - timestamp: - type: number - tid: - type: number - description: A topic identifier - content: - type: string - timestampISO: - type: string - description: An ISO 8601 formatted date string (complementing `timestamp`) + category: + type: object + properties: + cid: + type: number + description: A category identifier + name: + type: string + slug: + type: string + icon: + type: string + backgroundImage: + nullable: true + imageClass: + nullable: true + type: string + bgColor: + type: string + color: + type: string + disabled: + type: number user: type: object properties: @@ -187,47 +67,125 @@ get: username: type: string description: A friendly name for a given user account + displayname: + type: string + description: This is either username or fullname depending on forum and user settings + fullname: + type: string userslug: type: string description: An URL-safe variant of the username (i.e. lower-cased, spaces removed, etc.) + reputation: + type: number + postcount: + type: number picture: nullable: true type: string + signature: + nullable: true + type: string + banned: + type: number + status: + type: string icon:text: type: string description: A single-letter representation of a username. This is used in the - auto-generated icon given to users - without an avatar + auto-generated icon given to users without + an avatar icon:bgColor: type: string description: A six-character hexadecimal colour code assigned to the user. This value is used in conjunction with - `icon:text` for the user's - auto-generated icon + `icon:text` for the user's auto-generated + icon example: "#f44336" + banned_until_readable: + type: string + required: + - uid + - username + - userslug + - reputation + - postcount + - picture + - signature + - banned + - status + - icon:text + - icon:bgColor + - banned_until_readable + teaser: + type: object + nullable: true + properties: + pid: + type: number + uid: + type: number + description: A user identifier + timestamp: + type: number + tid: + type: number + description: A topic identifier + content: + type: string + timestampISO: + type: string + description: An ISO 8601 formatted date string (complementing `timestamp`) + user: + type: object + properties: + uid: + type: number + description: A user identifier + username: + type: string + description: A friendly name for a given user account + userslug: + type: string + description: An URL-safe variant of the username (i.e. lower-cased, spaces + removed, etc.) + picture: + nullable: true + type: string + icon:text: + type: string + description: A single-letter representation of a username. This is used in the + auto-generated icon given to users + without an avatar + icon:bgColor: + type: string + description: A six-character hexadecimal colour code assigned to the user. This + value is used in conjunction with + `icon:text` for the user's + auto-generated icon + example: "#f44336" + index: + type: number + tags: + type: array + items: + $ref: ../components/schemas/TagObject.yaml#/TagObject + isOwner: + type: boolean + ignored: + type: boolean + unread: + type: boolean + bookmark: + nullable: true + unreplied: + type: boolean + icons: + type: array + items: + type: string index: type: number - tags: - type: array - items: - $ref: ../components/schemas/TagObject.yaml#/TagObject - isOwner: - type: boolean - ignored: - type: boolean - unread: - type: boolean - bookmark: - nullable: true - unreplied: - type: boolean - icons: - type: array - items: - type: string - index: - type: number topicCount: type: number title: From ad8e7700371b1fc305f512ebdb1ff50f102bfe5f Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 10:30:03 -0500 Subject: [PATCH 024/116] feat: add pinExpiry and pinExpiryISO to topic data --- src/topics/data.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/topics/data.js b/src/topics/data.js index 720d2e63ad..f518a5f5c0 100644 --- a/src/topics/data.js +++ b/src/topics/data.js @@ -11,7 +11,7 @@ const plugins = require('../plugins'); const intFields = [ 'tid', 'cid', 'uid', 'mainPid', 'postcount', 'viewcount', 'postercount', 'deleted', 'locked', 'pinned', - 'timestamp', 'upvotes', 'downvotes', 'lastposttime', + 'pinExpiry', 'timestamp', 'upvotes', 'downvotes', 'lastposttime', 'deleterUid', ]; @@ -110,6 +110,10 @@ function modifyTopic(topic, fields) { topic.lastposttimeISO = utils.toISOString(topic.lastposttime); } + if (topic.hasOwnProperty('pinExpiry')) { + topic.pinExpiryISO = utils.toISOString(topic.pinExpiry); + } + if (topic.hasOwnProperty('upvotes') && topic.hasOwnProperty('downvotes')) { topic.votes = topic.upvotes - topic.downvotes; } From 5c3deb4b0ec96b03690b3655502c2f61ba40f982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 10:46:25 -0500 Subject: [PATCH 025/116] fix: #8973, fix timestamp on ban modal --- public/src/sockets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/sockets.js b/public/src/sockets.js index 4c8e1bc5f3..97c95affdf 100644 --- a/public/src/sockets.js +++ b/public/src/sockets.js @@ -179,7 +179,7 @@ socket = window.socket; } function onEventBanned(data) { - var message = data.until ? '[[error:user-banned-reason-until, ' + $.timeago(data.until) + ', ' + data.reason + ']]' : '[[error:user-banned-reason, ' + data.reason + ']]'; + var message = data.until ? '[[error:user-banned-reason-until, ' + utils.toISOString(data.until) + ', ' + data.reason + ']]' : '[[error:user-banned-reason, ' + data.reason + ']]'; bootbox.alert({ title: '[[error:user-banned]]', From 12b3aa0d8f6ded12fdfdf6b45f765df6a5aae4b9 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 10:54:55 -0500 Subject: [PATCH 026/116] feat: add translation key for pin icon label with expiry --- public/language/en-GB/topic.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en-GB/topic.json b/public/language/en-GB/topic.json index 8dc2f22401..05b89bb4fc 100644 --- a/public/language/en-GB/topic.json +++ b/public/language/en-GB/topic.json @@ -32,6 +32,7 @@ "tools": "Tools", "locked": "Locked", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", From ad60bc0641d0aaf5f2719d41e5c44d7df4a0b9be Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Nov 2020 15:59:15 +0000 Subject: [PATCH 027/116] fix(deps): update dependency nodebb-theme-persona to v10.2.89 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index d7a7ef3357..f0e0928cdd 100644 --- a/install/package.json +++ b/install/package.json @@ -103,7 +103,7 @@ "nodebb-plugin-spam-be-gone": "0.7.6", "nodebb-rewards-essentials": "0.1.4", "nodebb-theme-lavender": "5.0.14", - "nodebb-theme-persona": "10.2.88", + "nodebb-theme-persona": "10.2.89", "nodebb-theme-slick": "1.3.3", "nodebb-theme-vanilla": "11.3.4", "nodebb-widget-essentials": "4.1.2", From 19fe24933424a7923c6aa25d964dcbbb04493a6d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Nov 2020 16:01:23 +0000 Subject: [PATCH 028/116] fix(deps): update dependency nodebb-theme-vanilla to v11.3.5 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index f0e0928cdd..982b415a83 100644 --- a/install/package.json +++ b/install/package.json @@ -105,7 +105,7 @@ "nodebb-theme-lavender": "5.0.14", "nodebb-theme-persona": "10.2.89", "nodebb-theme-slick": "1.3.3", - "nodebb-theme-vanilla": "11.3.4", + "nodebb-theme-vanilla": "11.3.5", "nodebb-widget-essentials": "4.1.2", "nodemailer": "^6.4.6", "nprogress": "0.2.0", From 5664807d1807857ff663d2c766b190044ec2dfbf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Nov 2020 16:01:15 +0000 Subject: [PATCH 029/116] fix(deps): update dependency nodebb-theme-persona to v10.2.90 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index 982b415a83..6899030510 100644 --- a/install/package.json +++ b/install/package.json @@ -103,7 +103,7 @@ "nodebb-plugin-spam-be-gone": "0.7.6", "nodebb-rewards-essentials": "0.1.4", "nodebb-theme-lavender": "5.0.14", - "nodebb-theme-persona": "10.2.89", + "nodebb-theme-persona": "10.2.90", "nodebb-theme-slick": "1.3.3", "nodebb-theme-vanilla": "11.3.5", "nodebb-widget-essentials": "4.1.2", From 5b269bc5aa0df2590eedb3c2c7a0aed425ff1f23 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 11:05:09 -0500 Subject: [PATCH 030/116] chore: fallbacks for nodebb.topic --- public/language/ar/topic.json | 1 + public/language/bg/topic.json | 1 + public/language/bn/topic.json | 1 + public/language/cs/topic.json | 1 + public/language/da/topic.json | 1 + public/language/de/topic.json | 1 + public/language/el/topic.json | 1 + public/language/en-US/topic.json | 1 + public/language/en-x-pirate/topic.json | 1 + public/language/es/topic.json | 1 + public/language/et/topic.json | 1 + public/language/fa-IR/topic.json | 1 + public/language/fi/topic.json | 1 + public/language/fr/topic.json | 1 + public/language/gl/topic.json | 1 + public/language/he/topic.json | 1 + public/language/hr/topic.json | 1 + public/language/hu/topic.json | 1 + public/language/id/topic.json | 1 + public/language/it/topic.json | 1 + public/language/ja/topic.json | 1 + public/language/ko/topic.json | 1 + public/language/lt/topic.json | 1 + public/language/lv/topic.json | 1 + public/language/ms/topic.json | 1 + public/language/nb/topic.json | 1 + public/language/nl/topic.json | 1 + public/language/pl/topic.json | 1 + public/language/pt-BR/topic.json | 1 + public/language/pt-PT/topic.json | 1 + public/language/ro/topic.json | 1 + public/language/ru/topic.json | 1 + public/language/rw/topic.json | 1 + public/language/sc/topic.json | 1 + public/language/sk/topic.json | 1 + public/language/sl/topic.json | 1 + public/language/sr/topic.json | 1 + public/language/sv/topic.json | 1 + public/language/th/topic.json | 1 + public/language/tr/topic.json | 1 + public/language/uk/topic.json | 1 + public/language/vi/topic.json | 1 + public/language/zh-CN/topic.json | 1 + public/language/zh-TW/topic.json | 1 + 44 files changed, 44 insertions(+) diff --git a/public/language/ar/topic.json b/public/language/ar/topic.json index 7a4d167f84..934a527745 100644 --- a/public/language/ar/topic.json +++ b/public/language/ar/topic.json @@ -29,6 +29,7 @@ "tools": "أدوات", "locked": "مقفل", "pinned": "مثبت", + "pinned-with-expiry": "Pinned until %1", "moved": "منقول", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/bg/topic.json b/public/language/bg/topic.json index ae33515955..ca391a1e80 100644 --- a/public/language/bg/topic.json +++ b/public/language/bg/topic.json @@ -29,6 +29,7 @@ "tools": "Инструменти", "locked": "Заключена", "pinned": "Закачена", + "pinned-with-expiry": "Pinned until %1", "moved": "Преместена", "moved-from": "Преместена от %1", "copy-ip": "Копиране на IP адреса", diff --git a/public/language/bn/topic.json b/public/language/bn/topic.json index f896cdbd24..2b83a71e0a 100644 --- a/public/language/bn/topic.json +++ b/public/language/bn/topic.json @@ -29,6 +29,7 @@ "tools": "টুলস", "locked": "বন্ধ", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/cs/topic.json b/public/language/cs/topic.json index 4a51e68865..7e2dea8dad 100644 --- a/public/language/cs/topic.json +++ b/public/language/cs/topic.json @@ -29,6 +29,7 @@ "tools": "Nástroje", "locked": "Uzamknuto", "pinned": "Připnuto", + "pinned-with-expiry": "Pinned until %1", "moved": "Přesunuto", "moved-from": "Moved from %1", "copy-ip": "Kopírovat IP", diff --git a/public/language/da/topic.json b/public/language/da/topic.json index 94c5dacfb0..746ee0321e 100644 --- a/public/language/da/topic.json +++ b/public/language/da/topic.json @@ -29,6 +29,7 @@ "tools": "Værktøjer", "locked": "Låst", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Flyttet", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/de/topic.json b/public/language/de/topic.json index b0cee934e6..2530c85fb1 100644 --- a/public/language/de/topic.json +++ b/public/language/de/topic.json @@ -29,6 +29,7 @@ "tools": "Werkzeuge", "locked": "Gesperrt", "pinned": "Angeheftet", + "pinned-with-expiry": "Pinned until %1", "moved": "Verschoben", "moved-from": "Moved from %1", "copy-ip": "IP-Adresse Kopieren", diff --git a/public/language/el/topic.json b/public/language/el/topic.json index 7f28aeb626..fb2de10e43 100644 --- a/public/language/el/topic.json +++ b/public/language/el/topic.json @@ -29,6 +29,7 @@ "tools": "Εργαλεία", "locked": "Κλειδωμένο", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/en-US/topic.json b/public/language/en-US/topic.json index a38f9433fc..6d2c704c8e 100644 --- a/public/language/en-US/topic.json +++ b/public/language/en-US/topic.json @@ -29,6 +29,7 @@ "tools": "Tools", "locked": "Locked", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/en-x-pirate/topic.json b/public/language/en-x-pirate/topic.json index a38f9433fc..6d2c704c8e 100644 --- a/public/language/en-x-pirate/topic.json +++ b/public/language/en-x-pirate/topic.json @@ -29,6 +29,7 @@ "tools": "Tools", "locked": "Locked", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/es/topic.json b/public/language/es/topic.json index 98c6231be0..bb83a4de4a 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -29,6 +29,7 @@ "tools": "Herramientas", "locked": "Cerrado", "pinned": "Fijo", + "pinned-with-expiry": "Pinned until %1", "moved": "Movido", "moved-from": "Moved from %1", "copy-ip": "Copiar IP", diff --git a/public/language/et/topic.json b/public/language/et/topic.json index 7e1a451d1c..266a5ff264 100644 --- a/public/language/et/topic.json +++ b/public/language/et/topic.json @@ -29,6 +29,7 @@ "tools": "Tööriistad", "locked": "Lukustatud", "pinned": "Märgistatud", + "pinned-with-expiry": "Pinned until %1", "moved": "Liigutatud", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/fa-IR/topic.json b/public/language/fa-IR/topic.json index 57a6712040..3d6763045c 100644 --- a/public/language/fa-IR/topic.json +++ b/public/language/fa-IR/topic.json @@ -29,6 +29,7 @@ "tools": "ابزارها", "locked": "قفل شده است", "pinned": "سنجاق شده", + "pinned-with-expiry": "Pinned until %1", "moved": "منتقل شده", "moved-from": "Moved from %1", "copy-ip": "کپی IP", diff --git a/public/language/fi/topic.json b/public/language/fi/topic.json index e3508fef34..1e280acdee 100644 --- a/public/language/fi/topic.json +++ b/public/language/fi/topic.json @@ -29,6 +29,7 @@ "tools": "Työkalut", "locked": "Lukittu", "pinned": "Kiinnitetty", + "pinned-with-expiry": "Pinned until %1", "moved": "Siirretty", "moved-from": "Moved from %1", "copy-ip": "Kopioi IP", diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index 399972e7a7..a76f9693c1 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -29,6 +29,7 @@ "tools": "Outils", "locked": "Verrouillé", "pinned": "Épinglé", + "pinned-with-expiry": "Pinned until %1", "moved": "Déplacé", "moved-from": "Déplacé de %1", "copy-ip": "Copier l'IP", diff --git a/public/language/gl/topic.json b/public/language/gl/topic.json index 91bacd38cb..fc1f5b2d63 100644 --- a/public/language/gl/topic.json +++ b/public/language/gl/topic.json @@ -29,6 +29,7 @@ "tools": "Ferramentas", "locked": "Pechado", "pinned": "Fixo", + "pinned-with-expiry": "Pinned until %1", "moved": "Movido", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/he/topic.json b/public/language/he/topic.json index f7f3c94bff..851d3f65a5 100644 --- a/public/language/he/topic.json +++ b/public/language/he/topic.json @@ -29,6 +29,7 @@ "tools": "כלים", "locked": "נעול", "pinned": "נעוץ", + "pinned-with-expiry": "Pinned until %1", "moved": "הועבר", "moved-from": "הועבר מ-%1", "copy-ip": "העתק IP", diff --git a/public/language/hr/topic.json b/public/language/hr/topic.json index fd3c6ce0a3..a27401f276 100644 --- a/public/language/hr/topic.json +++ b/public/language/hr/topic.json @@ -29,6 +29,7 @@ "tools": "Alati", "locked": "Zaključano", "pinned": "Zakačeno", + "pinned-with-expiry": "Pinned until %1", "moved": "Premješteno", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/hu/topic.json b/public/language/hu/topic.json index b5ddcc01db..889c0c8289 100644 --- a/public/language/hu/topic.json +++ b/public/language/hu/topic.json @@ -29,6 +29,7 @@ "tools": "Eszközök", "locked": "Zárolva", "pinned": "Rögzített", + "pinned-with-expiry": "Pinned until %1", "moved": "Áthelyezett", "moved-from": "Moved from %1", "copy-ip": "IP-cím másolása", diff --git a/public/language/id/topic.json b/public/language/id/topic.json index 93a3d03f86..d806d3d2b4 100644 --- a/public/language/id/topic.json +++ b/public/language/id/topic.json @@ -29,6 +29,7 @@ "tools": "Perangkat", "locked": "Terkunci", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/it/topic.json b/public/language/it/topic.json index 4de7332d7d..8106215698 100644 --- a/public/language/it/topic.json +++ b/public/language/it/topic.json @@ -29,6 +29,7 @@ "tools": "Strumenti", "locked": "Bloccato", "pinned": "Appeso", + "pinned-with-expiry": "Pinned until %1", "moved": "Spostato", "moved-from": "Spostato da %1", "copy-ip": "Copia indirizzo IP", diff --git a/public/language/ja/topic.json b/public/language/ja/topic.json index 9c1bb2accf..d02cf2f6fe 100644 --- a/public/language/ja/topic.json +++ b/public/language/ja/topic.json @@ -29,6 +29,7 @@ "tools": "ツール", "locked": "ロック", "pinned": "ピンされた", + "pinned-with-expiry": "Pinned until %1", "moved": "移動しました", "moved-from": "Moved from %1", "copy-ip": "IPをコピー", diff --git a/public/language/ko/topic.json b/public/language/ko/topic.json index f28052fc2a..aa8dc7edaa 100644 --- a/public/language/ko/topic.json +++ b/public/language/ko/topic.json @@ -29,6 +29,7 @@ "tools": "도구", "locked": "잠긴 게시물", "pinned": "고정된 게시물", + "pinned-with-expiry": "Pinned until %1", "moved": "이동된 게시물", "moved-from": "Moved from %1", "copy-ip": "IP 복사", diff --git a/public/language/lt/topic.json b/public/language/lt/topic.json index a6c2f24fe4..1a6ac1157e 100644 --- a/public/language/lt/topic.json +++ b/public/language/lt/topic.json @@ -29,6 +29,7 @@ "tools": "Įrankiai", "locked": "Užrakinta", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Perkelta", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/lv/topic.json b/public/language/lv/topic.json index c7065f7216..2009861e0e 100644 --- a/public/language/lv/topic.json +++ b/public/language/lv/topic.json @@ -29,6 +29,7 @@ "tools": "Rīki", "locked": "Slēgtie", "pinned": "Piespraustie", + "pinned-with-expiry": "Pinned until %1", "moved": "Pārvietots", "moved-from": "Moved from %1", "copy-ip": "Kopēt IP adresi", diff --git a/public/language/ms/topic.json b/public/language/ms/topic.json index 2cce10e948..37779531e6 100644 --- a/public/language/ms/topic.json +++ b/public/language/ms/topic.json @@ -29,6 +29,7 @@ "tools": "Perkakas", "locked": "Kunci", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/nb/topic.json b/public/language/nb/topic.json index ae86a6dba1..403af0984a 100644 --- a/public/language/nb/topic.json +++ b/public/language/nb/topic.json @@ -29,6 +29,7 @@ "tools": "Verktøy", "locked": "Låst", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index df807acdbf..559701bac0 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -29,6 +29,7 @@ "tools": "Extra", "locked": "Gesloten", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Verplaatst", "moved-from": "Moved from %1", "copy-ip": "Kopieer IP", diff --git a/public/language/pl/topic.json b/public/language/pl/topic.json index 6975bc7338..eced539558 100644 --- a/public/language/pl/topic.json +++ b/public/language/pl/topic.json @@ -29,6 +29,7 @@ "tools": "Narzędzia", "locked": "Zablokowany", "pinned": "Przypięty", + "pinned-with-expiry": "Pinned until %1", "moved": "Przeniesiony", "moved-from": "Moved from %1", "copy-ip": "Kopiuj IP", diff --git a/public/language/pt-BR/topic.json b/public/language/pt-BR/topic.json index 50198172b4..a314182af6 100644 --- a/public/language/pt-BR/topic.json +++ b/public/language/pt-BR/topic.json @@ -29,6 +29,7 @@ "tools": "Ferramentas", "locked": "Trancado", "pinned": "Fixado", + "pinned-with-expiry": "Pinned until %1", "moved": "Movido", "moved-from": "Moved from %1", "copy-ip": "Copiar IP", diff --git a/public/language/pt-PT/topic.json b/public/language/pt-PT/topic.json index 968100b863..83ce7a5f4b 100644 --- a/public/language/pt-PT/topic.json +++ b/public/language/pt-PT/topic.json @@ -29,6 +29,7 @@ "tools": "Ferramentas", "locked": "Bloqueado", "pinned": "Afixado", + "pinned-with-expiry": "Pinned until %1", "moved": "Movido", "moved-from": "Moved from %1", "copy-ip": "Copiar IP", diff --git a/public/language/ro/topic.json b/public/language/ro/topic.json index 29468abb41..6c0cb6a3dd 100644 --- a/public/language/ro/topic.json +++ b/public/language/ro/topic.json @@ -29,6 +29,7 @@ "tools": "Unelte", "locked": "Închis", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/ru/topic.json b/public/language/ru/topic.json index 8bd0e00f81..95007ad2a5 100644 --- a/public/language/ru/topic.json +++ b/public/language/ru/topic.json @@ -29,6 +29,7 @@ "tools": "Действия", "locked": "Закрыта", "pinned": "Прикреплена", + "pinned-with-expiry": "Pinned until %1", "moved": "Перенесена", "moved-from": "Moved from %1", "copy-ip": "Копировать IP", diff --git a/public/language/rw/topic.json b/public/language/rw/topic.json index 62fc31c281..fcec29f32d 100644 --- a/public/language/rw/topic.json +++ b/public/language/rw/topic.json @@ -29,6 +29,7 @@ "tools": "Ibikoresho", "locked": "Birafungiranye", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/sc/topic.json b/public/language/sc/topic.json index 1068121b5e..732ba8656a 100644 --- a/public/language/sc/topic.json +++ b/public/language/sc/topic.json @@ -29,6 +29,7 @@ "tools": "Ainas", "locked": "Locked", "pinned": "Pinned", + "pinned-with-expiry": "Pinned until %1", "moved": "Moved", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/sk/topic.json b/public/language/sk/topic.json index 055ecf9a24..bf5e9eab74 100644 --- a/public/language/sk/topic.json +++ b/public/language/sk/topic.json @@ -29,6 +29,7 @@ "tools": "Nástroje", "locked": "Uzamknuté", "pinned": "Pripnuté", + "pinned-with-expiry": "Pinned until %1", "moved": "Presunuté", "moved-from": "Moved from %1", "copy-ip": "Kopírovať IP adresu", diff --git a/public/language/sl/topic.json b/public/language/sl/topic.json index 50a1770a2f..35d240096d 100644 --- a/public/language/sl/topic.json +++ b/public/language/sl/topic.json @@ -29,6 +29,7 @@ "tools": "Orodja", "locked": "Zaklenjeno", "pinned": "Pripeto", + "pinned-with-expiry": "Pinned until %1", "moved": "Premaknjeno", "moved-from": "Moved from %1", "copy-ip": "Copy IP", diff --git a/public/language/sr/topic.json b/public/language/sr/topic.json index 7d0c11555f..659be3f156 100644 --- a/public/language/sr/topic.json +++ b/public/language/sr/topic.json @@ -29,6 +29,7 @@ "tools": "Алатке", "locked": "Закључано", "pinned": "Закачено", + "pinned-with-expiry": "Pinned until %1", "moved": "Премештено", "moved-from": "Moved from %1", "copy-ip": "Копирај IP", diff --git a/public/language/sv/topic.json b/public/language/sv/topic.json index aac9c5dc61..e663a7c1d1 100644 --- a/public/language/sv/topic.json +++ b/public/language/sv/topic.json @@ -29,6 +29,7 @@ "tools": "Verktyg", "locked": "Låst", "pinned": "Fäst", + "pinned-with-expiry": "Pinned until %1", "moved": "Flyttad", "moved-from": "Moved from %1", "copy-ip": "Kopiera IP", diff --git a/public/language/th/topic.json b/public/language/th/topic.json index af5b612a0f..20e407e618 100644 --- a/public/language/th/topic.json +++ b/public/language/th/topic.json @@ -29,6 +29,7 @@ "tools": "เครื่องมือ", "locked": "ถูกล็อก", "pinned": "ถูกปักหมุด", + "pinned-with-expiry": "Pinned until %1", "moved": "ถูกย้าย", "moved-from": "Moved from %1", "copy-ip": "คัดลอก IP", diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index 0816900cb2..145c676adf 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -29,6 +29,7 @@ "tools": "Araçlar", "locked": "Kilitli", "pinned": "Sabitlendi", + "pinned-with-expiry": "Pinned until %1", "moved": "Taşındı", "moved-from": "Şuradan taşındı: %1", "copy-ip": "IP Kopyala", diff --git a/public/language/uk/topic.json b/public/language/uk/topic.json index afc79fc17f..bd2d6bd39b 100644 --- a/public/language/uk/topic.json +++ b/public/language/uk/topic.json @@ -29,6 +29,7 @@ "tools": "Інструменти", "locked": "Заблокована", "pinned": "Закріплена", + "pinned-with-expiry": "Pinned until %1", "moved": "Переміщена", "moved-from": "Moved from %1", "copy-ip": "Копіювати IP", diff --git a/public/language/vi/topic.json b/public/language/vi/topic.json index a4115ca2c5..a3cf7bdfaa 100644 --- a/public/language/vi/topic.json +++ b/public/language/vi/topic.json @@ -29,6 +29,7 @@ "tools": "Công cụ", "locked": "Khóa", "pinned": "Đã ghim", + "pinned-with-expiry": "Pinned until %1", "moved": "Chuyển đi", "moved-from": "Moved from %1", "copy-ip": "Sao chép IP", diff --git a/public/language/zh-CN/topic.json b/public/language/zh-CN/topic.json index 6580a4cfcf..6f7796d154 100644 --- a/public/language/zh-CN/topic.json +++ b/public/language/zh-CN/topic.json @@ -29,6 +29,7 @@ "tools": "工具", "locked": "已锁定", "pinned": "已固定", + "pinned-with-expiry": "Pinned until %1", "moved": "已移动", "moved-from": "移自1%版 ", "copy-ip": "复制IP", diff --git a/public/language/zh-TW/topic.json b/public/language/zh-TW/topic.json index 4a28540245..7ff78f52aa 100644 --- a/public/language/zh-TW/topic.json +++ b/public/language/zh-TW/topic.json @@ -29,6 +29,7 @@ "tools": "工具", "locked": "已鎖定", "pinned": "已置頂", + "pinned-with-expiry": "Pinned until %1", "moved": "已移動", "moved-from": "Moved from %1", "copy-ip": "複製IP", From fdca8b16ca3a8ddb2d5ad409ea7bedc814b67b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 11:17:28 -0500 Subject: [PATCH 031/116] fix: #8974, dont show wrong message on register queue configs don't support booleans --- install/data/defaults.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/data/defaults.json b/install/data/defaults.json index 2682dde707..29ece08946 100644 --- a/install/data/defaults.json +++ b/install/data/defaults.json @@ -111,7 +111,7 @@ "maximumInvites": 0, "username:disableEdit": 0, "email:disableEdit": 0, - "email:smtpTransport:pool": false, + "email:smtpTransport:pool": 0, "hideFullname": 0, "hideEmail": 0, "showFullnameAsDisplayName": 0, @@ -140,7 +140,7 @@ "necroThreshold": 7, "categoryWatchState": "watching", "submitPluginUsage": 1, - "showAverageApprovalTime": true, + "showAverageApprovalTime": 1, "autoApproveTime": 0, "maxUserSessions": 10, "useCompression": 0, From dadb2527dae113a023af2517947f94d80ceb1fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 11:34:14 -0500 Subject: [PATCH 032/116] fix: #8974, with password login for approval queue --- src/user/approval.js | 5 ++++- src/user/password.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/user/approval.js b/src/user/approval.js index 8ea5916610..507aa7ef1b 100644 --- a/src/user/approval.js +++ b/src/user/approval.js @@ -66,7 +66,10 @@ module.exports = function (User) { } const creation_time = await db.sortedSetScore('registration:queue', username); const uid = await User.create(userData); - await User.setUserField(uid, 'password', userData.hashedPassword); + await User.setUserFields(uid, { + password: userData.hashedPassword, + 'password:shaWrapped': 1, + }); await removeFromQueue(username); await markNotificationRead(username); await plugins.hooks.fire('filter:register.complete', { uid: uid }); diff --git a/src/user/password.js b/src/user/password.js index acb89a6c60..23a2816fd8 100644 --- a/src/user/password.js +++ b/src/user/password.js @@ -17,7 +17,10 @@ module.exports = function (User) { User.isPasswordCorrect = async function (uid, password, ip) { password = password || ''; - var { password: hashedPassword, 'password:shaWrapped': shaWrapped } = await db.getObjectFields('user:' + uid, ['password', 'password:shaWrapped']); + var { + password: hashedPassword, + 'password:shaWrapped': shaWrapped, + } = await db.getObjectFields('user:' + uid, ['password', 'password:shaWrapped']); if (!hashedPassword) { // Non-existant user, submit fake hash for comparison hashedPassword = ''; From 1e7cf1cbc442feed48659047463245706f806d50 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 11:54:27 -0500 Subject: [PATCH 033/116] fix: #8971, disallow flags of privileged users (mods, gmods, admins) --- public/language/en-GB/error.json | 1 + src/controllers/accounts/helpers.js | 1 + src/flags.js | 9 +++++++++ src/privileges/posts.js | 12 ++++++++++-- src/privileges/users.js | 18 ++++++++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/public/language/en-GB/error.json b/public/language/en-GB/error.json index 1b054dee4e..1b0b005805 100644 --- a/public/language/en-GB/error.json +++ b/public/language/en-GB/error.json @@ -169,6 +169,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index ed07c2a6f9..08a9fd260d 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -70,6 +70,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID) { userData.isSelfOrAdminOrGlobalModerator = isSelf || isAdmin || isGlobalModerator; userData.canEdit = results.canEdit; userData.canBan = results.canBanUser; + userData.canFlag = (await privileges.users.canFlag(callerUID, userData.uid)).flag; userData.canChangePassword = isAdmin || (isSelf && !meta.config['password:disableEdit']); userData.isSelf = isSelf; userData.isFollowing = results.isFollowing; diff --git a/src/flags.js b/src/flags.js index ae954d1607..8bf57257fd 100644 --- a/src/flags.js +++ b/src/flags.js @@ -251,6 +251,15 @@ Flags.validate = async function (payload) { throw new Error('[[error:user-banned]]'); } + // Disallow flagging of profiles/content of privileged users + const [targetPrivileged, reporterPrivileged] = await Promise.all([ + user.isPrivileged(target.uid), + user.isPrivileged(reporter.uid), + ]); + if (targetPrivileged && !reporterPrivileged) { + throw new Error('[[error:cant-flag-privileged]]'); + } + if (payload.type === 'post') { const editable = await privileges.posts.canEdit(payload.id, payload.uid); if (!editable.flag && !meta.config['reputation:disabled'] && reporter.reputation < meta.config['min:rep:flag']) { diff --git a/src/privileges/posts.js b/src/privileges/posts.js index cfbfeedb1c..c7ab882aed 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -176,12 +176,20 @@ module.exports = function (privileges) { }; privileges.posts.canFlag = async function (pid, uid) { - const [userReputation, isAdminOrModerator] = await Promise.all([ + const targetUid = await posts.getPostField(pid, 'uid'); + const [userReputation, isAdminOrModerator, targetPrivileged, reporterPrivileged] = await Promise.all([ user.getUserField(uid, 'reputation'), isAdminOrMod(pid, uid), + user.isPrivileged(targetUid), + user.isPrivileged(uid), ]); const minimumReputation = meta.config['min:rep:flag']; - const canFlag = isAdminOrModerator || (userReputation >= minimumReputation); + let canFlag = isAdminOrModerator || (userReputation >= minimumReputation); + + if (targetPrivileged && !reporterPrivileged) { + canFlag = false; + } + return { flag: canFlag }; }; diff --git a/src/privileges/users.js b/src/privileges/users.js index b23df4d198..4c40f3a3f7 100644 --- a/src/privileges/users.js +++ b/src/privileges/users.js @@ -3,6 +3,8 @@ const _ = require('lodash'); +const user = require('../user'); +const meta = require('../meta'); const groups = require('../groups'); const plugins = require('../plugins'); const helpers = require('./helpers'); @@ -107,6 +109,22 @@ module.exports = function (privileges) { return data.canBan; }; + privileges.users.canFlag = async function (callerUid, uid) { + const [userReputation, targetPrivileged, reporterPrivileged] = await Promise.all([ + user.getUserField(callerUid, 'reputation'), + user.isPrivileged(uid), + user.isPrivileged(callerUid), + ]); + const minimumReputation = meta.config['min:rep:flag']; + let canFlag = reporterPrivileged || (userReputation >= minimumReputation); + + if (targetPrivileged && !reporterPrivileged) { + canFlag = false; + } + + return { flag: canFlag }; + }; + privileges.users.hasBanPrivilege = async uid => await hasGlobalPrivilege('ban', uid); privileges.users.hasInvitePrivilege = async uid => await hasGlobalPrivilege('invite', uid); From 82ca3760120ee229d412cdfd48001221acb8bb08 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 11:58:05 -0500 Subject: [PATCH 034/116] chore: fallbacks for nodebb.error --- public/language/ar/error.json | 1 + public/language/bg/error.json | 1 + public/language/bn/error.json | 1 + public/language/cs/error.json | 1 + public/language/da/error.json | 1 + public/language/de/error.json | 1 + public/language/el/error.json | 1 + public/language/en-US/error.json | 1 + public/language/en-x-pirate/error.json | 1 + public/language/es/error.json | 1 + public/language/et/error.json | 1 + public/language/fa-IR/error.json | 1 + public/language/fi/error.json | 1 + public/language/fr/error.json | 1 + public/language/gl/error.json | 1 + public/language/he/error.json | 1 + public/language/hr/error.json | 1 + public/language/hu/error.json | 1 + public/language/id/error.json | 1 + public/language/it/error.json | 1 + public/language/ja/error.json | 1 + public/language/ko/error.json | 1 + public/language/lt/error.json | 1 + public/language/lv/error.json | 1 + public/language/ms/error.json | 1 + public/language/nb/error.json | 1 + public/language/nl/error.json | 1 + public/language/pl/error.json | 1 + public/language/pt-BR/error.json | 1 + public/language/pt-PT/error.json | 1 + public/language/ro/error.json | 1 + public/language/ru/error.json | 1 + public/language/rw/error.json | 1 + public/language/sc/error.json | 1 + public/language/sk/error.json | 1 + public/language/sl/error.json | 1 + public/language/sr/error.json | 1 + public/language/sv/error.json | 1 + public/language/th/error.json | 1 + public/language/tr/error.json | 1 + public/language/uk/error.json | 1 + public/language/vi/error.json | 1 + public/language/zh-CN/error.json | 1 + public/language/zh-TW/error.json | 1 + 44 files changed, 44 insertions(+) diff --git a/public/language/ar/error.json b/public/language/ar/error.json index db0e62c4a1..4da828ca70 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/bg/error.json b/public/language/bg/error.json index adbbe80085..7af90b3802 100644 --- a/public/language/bg/error.json +++ b/public/language/bg/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Вече сте докладвали този потребител", "post-flagged-too-many-times": "Тази публикация вече е докладвана от други хора", "user-flagged-too-many-times": "Този потребител вече е докладван от други хора", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Не можете да гласувате за собствената си публикация", "too-many-downvotes-today": "Можете да гласувате отрицателно не повече от %1 пъти на ден", "too-many-downvotes-today-user": "Можете да гласувате отрицателно за потребител не повече от %1 пъти на ден", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index 870e3ea1df..9e22c50bab 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index 54ac427e51..f3a8b77a3f 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "U svého vlastního příspěvku nemůžete hlasovat", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/da/error.json b/public/language/da/error.json index b343475b1b..42217160cc 100644 --- a/public/language/da/error.json +++ b/public/language/da/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/de/error.json b/public/language/de/error.json index a04522f273..22fe0affb4 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Du hast diesen Benutzer bereits gemeldet", "post-flagged-too-many-times": "Dieser Beitrag wurde bereits von anderen Benutzern gemeldet", "user-flagged-too-many-times": "Dieser Benutzer wurde bereits von anderen Benutzern gemeldet", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Du kannst deine eigenen Beiträge nicht bewerten", "too-many-downvotes-today": "Du kannst nur %1 mal am Tag eine schlechte Bewertung abgeben", "too-many-downvotes-today-user": "Du kannst einen Benutzer nur %1 mal am Tag schlecht bewerten", diff --git a/public/language/el/error.json b/public/language/el/error.json index 4f706777c7..bbdfc500da 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/en-US/error.json b/public/language/en-US/error.json index c50e9c05cd..bc38125be6 100644 --- a/public/language/en-US/error.json +++ b/public/language/en-US/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/en-x-pirate/error.json b/public/language/en-x-pirate/error.json index c50e9c05cd..bc38125be6 100644 --- a/public/language/en-x-pirate/error.json +++ b/public/language/en-x-pirate/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/es/error.json b/public/language/es/error.json index 342c3a3c10..d75ccad60c 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "No puedes votar en tu propio mensaje", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/et/error.json b/public/language/et/error.json index 93b5d2f213..3523645fe1 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/fa-IR/error.json b/public/language/fa-IR/error.json index b2b5726174..4c48464af9 100644 --- a/public/language/fa-IR/error.json +++ b/public/language/fa-IR/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "شما نمی توانید به پست خود رای بدهید", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index 8befaea4bd..7bb5b3fb35 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/fr/error.json b/public/language/fr/error.json index 0dfa71bab6..7b3d6ebfde 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Vous avez déjà signalé cet utilisateur", "post-flagged-too-many-times": "Ce message a déjà été signalé par d'autres", "user-flagged-too-many-times": "Cet utilisateur a déjà été signalé par d'autres", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Vous ne pouvez pas voter sur votre propre message", "too-many-downvotes-today": "Vous ne pouvez noter négativement que %1 fois par jour", "too-many-downvotes-today-user": "Vous ne pouvez noter négativement un utilisateur que %1 fois par jour", diff --git a/public/language/gl/error.json b/public/language/gl/error.json index 3377d8805b..fe9e6b72f9 100644 --- a/public/language/gl/error.json +++ b/public/language/gl/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/he/error.json b/public/language/he/error.json index 47ca223064..ba156680e9 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "כבר דיווחת על המשתמש הזה", "post-flagged-too-many-times": "התקבל כבר דיווח על פוסט זה.", "user-flagged-too-many-times": "התקבל דיווח על משתמש זה.", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "אי אפשר להצביע בפרסום שיצרת", "too-many-downvotes-today": "אתה יכול להצביע נגד %1 פעמים ביום", "too-many-downvotes-today-user": "אתה יכול להצביע נגד משתמש %1 פעמים ביום", diff --git a/public/language/hr/error.json b/public/language/hr/error.json index be8b52316f..d0ad8e654e 100644 --- a/public/language/hr/error.json +++ b/public/language/hr/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index ec4ab33aff..b76bf3d750 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/id/error.json b/public/language/id/error.json index 615ee12b07..4d2f48fddf 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/it/error.json b/public/language/it/error.json index c5fcbb72fb..e1b85f3897 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Hai già segnalato questo utente", "post-flagged-too-many-times": "Questo post è già stato segnalato da altri", "user-flagged-too-many-times": "Questo utente è già stato segnalato da altri", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Non puoi votare la tua stessa discussione", "too-many-downvotes-today": "È possibile votare negativamente solo %1 volta al giorno", "too-many-downvotes-today-user": "È possibile votare negativamente un utente solo %1 volta al giorno", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index 29e9d24829..bf39fa6c01 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "自分のポストに評価することはできません。", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index b6c411577e..54c7ea2ed5 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "자신의 게시물에는 투표 할 수 없습니다.", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index 3f1535d6d3..18ecdae867 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Negalima balsuoti už savo įrašą", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/lv/error.json b/public/language/lv/error.json index a206838a88..40ba1b62c1 100644 --- a/public/language/lv/error.json +++ b/public/language/lv/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Nevar balsot pats par savu rakstu", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index 2844037466..5bc1e320a3 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/nb/error.json b/public/language/nb/error.json index 7a6406736a..1e56997cd2 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/nl/error.json b/public/language/nl/error.json index 6dab2ab6ee..17f7860afe 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Je hebt deze gebruiker al gerapporteerd", "post-flagged-too-many-times": "Dit bericht is al door anderen gerapporteerd", "user-flagged-too-many-times": "Deze gebruiker is al door anderen gerapporteerd", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Het is niet mogelijk om op je eigen bericht te stemmen", "too-many-downvotes-today": "Je kunt slecht %1 keer per dag downvoten", "too-many-downvotes-today-user": "Je kunt een gebruiker slecht %1 keer per dag downvoten", diff --git a/public/language/pl/error.json b/public/language/pl/error.json index 9d9d0264b8..00cb18650d 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Ten użytkownik został już przez ciebie oflagowany", "post-flagged-too-many-times": "Ten post został już oflagowany przez innych użytkowników", "user-flagged-too-many-times": "Ten użytkownik został już oflagowany przez innych użytkowników", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Nie możesz głosować na swój własny wpis.", "too-many-downvotes-today": "Możesz głosować przeciw postowi tylko %1 razy dziennie", "too-many-downvotes-today-user": "Możesz głosować przeciwko użytkownikowi tylko %1 razy dziennie", diff --git a/public/language/pt-BR/error.json b/public/language/pt-BR/error.json index 8659e2babe..ccc6730a55 100644 --- a/public/language/pt-BR/error.json +++ b/public/language/pt-BR/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Você não pode votar no seu próprio post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/pt-PT/error.json b/public/language/pt-PT/error.json index 68cee9c04d..5c679c6621 100644 --- a/public/language/pt-PT/error.json +++ b/public/language/pt-PT/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Não podes votar na tua própria publicação", "too-many-downvotes-today": "Tu só podes votar negativamente %1 vezes por dia", "too-many-downvotes-today-user": "Tu só podes votar negativamente um utilizador %1 vezes por dia", diff --git a/public/language/ro/error.json b/public/language/ro/error.json index 6b3a0ce877..3ae027e399 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 073729fefa..703554e400 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Вы уже пожаловались на этого пользователя", "post-flagged-too-many-times": "На это сообщение уже пожаловались другие пользователи", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Вы не можете голосовать за свои собственные сообщения", "too-many-downvotes-today": "Вы можете проголосовать против только %1 раз за день", "too-many-downvotes-today-user": "Вы можете проголосовать против участника только %1 раз за день.", diff --git a/public/language/rw/error.json b/public/language/rw/error.json index 9dc57e058e..41de06bec4 100644 --- a/public/language/rw/error.json +++ b/public/language/rw/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index c50e9c05cd..bc38125be6 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index ab126c2bb8..9095048ff2 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Za svoj vlastný príspevok nemôžete hlasovať", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/sl/error.json b/public/language/sl/error.json index a90966f1d1..4b5b3c9f06 100644 --- a/public/language/sl/error.json +++ b/public/language/sl/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/sr/error.json b/public/language/sr/error.json index 1ce2004430..bdf711e82c 100644 --- a/public/language/sr/error.json +++ b/public/language/sr/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Не можете гласати за своју поруку", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index 8a41d072b9..78ced4cccf 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Du kan inte rösta på ditt eget inlägg.", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/th/error.json b/public/language/th/error.json index 4d35c24254..f614f6c299 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "You cannot vote on your own post", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 9d70592675..ddef7c83dd 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "Bu kullanıcıyı önceden şikayet etmişsiniz.", "post-flagged-too-many-times": "Bu ileti başkaları tarafından halihazırda şikayet edilmiş.", "user-flagged-too-many-times": "Bu kullanıcı başkaları tarafından halihazırda şikayet edilmiş.", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Kendi iletinize oy veremezsiniz", "too-many-downvotes-today": "Bir günde sadece %1 eksi oy verebilirsiniz", "too-many-downvotes-today-user": "Bir kullanıcıya bir günde sadece %1 eksi oy verebilirsiniz", diff --git a/public/language/uk/error.json b/public/language/uk/error.json index b9a542a5ec..88733c3b30 100644 --- a/public/language/uk/error.json +++ b/public/language/uk/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Ви не можете проголосувати за власний пост", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 458760585f..68b71c19ce 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "Bạn không thể tự bầu cho bài đăng của mình", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", diff --git a/public/language/zh-CN/error.json b/public/language/zh-CN/error.json index bdb7df459a..295f877add 100644 --- a/public/language/zh-CN/error.json +++ b/public/language/zh-CN/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "您已举报此用户", "post-flagged-too-many-times": "此贴已被其他用户举报", "user-flagged-too-many-times": "此用户已被其他用户举报", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "您不能对您自己的帖子投票", "too-many-downvotes-today": "您每天只能踩 %1 次", "too-many-downvotes-today-user": "您每天只能对一个用户踩 %1 次", diff --git a/public/language/zh-TW/error.json b/public/language/zh-TW/error.json index 3bdcf3ba32..c68df18241 100644 --- a/public/language/zh-TW/error.json +++ b/public/language/zh-TW/error.json @@ -144,6 +144,7 @@ "user-already-flagged": "You have already flagged this user", "post-flagged-too-many-times": "This post has been flagged by others already", "user-flagged-too-many-times": "This user has been flagged by others already", + "cant-flag-privileged": "You are not allowed to flag the profiles or content of privileged users (moderators/global moderators/admins)", "self-vote": "您不能讚您自己的貼文", "too-many-downvotes-today": "You can only downvote %1 times a day", "too-many-downvotes-today-user": "You can only downvote a user %1 times a day", From bf171adc8362decff3473958ee9b5a723fc464c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 12:26:45 -0500 Subject: [PATCH 035/116] fix: #8979 --- install/data/defaults.json | 1 + src/controllers/tags.js | 1 + 2 files changed, 2 insertions(+) diff --git a/install/data/defaults.json b/install/data/defaults.json index 29ece08946..aee61b65df 100644 --- a/install/data/defaults.json +++ b/install/data/defaults.json @@ -104,6 +104,7 @@ "maximumGroupTitleLength": 40, "preventTopicDeleteAfterReplies": 0, "feeds:disableSitemap": 0, + "feeds:disableRSS": 0, "sitemapTopics": 500, "maintenanceMode": 0, "maintenanceModeStatus": 503, diff --git a/src/controllers/tags.js b/src/controllers/tags.js index 9191aa07c3..1484a12a37 100644 --- a/src/controllers/tags.js +++ b/src/controllers/tags.js @@ -53,6 +53,7 @@ tagsController.getTag = async function (req, res) { templateData.pagination = pagination.create(page, pageCount); helpers.addLinkTags({ url: 'tags/' + tag, res: req.res, tags: templateData.pagination.rel }); + templateData['feeds:disableRSS'] = meta.config['feeds:disableRSS']; templateData.rssFeedUrl = nconf.get('relative_path') + '/tags/' + tag + '.rss'; res.render('tag', templateData); }; From f4d217d829b67efa0f4de7a9ac2efbe8771128b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 12:38:43 -0500 Subject: [PATCH 036/116] fix: #8980, fix lang string --- src/socket.io/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 9dad7cda4b..9d57d08c68 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -165,7 +165,8 @@ async function checkMaintenance(socket) { if (isAdmin) { return; } - throw new Error('[[error:forum-maintenance]]'); + const validator = require('validator'); + throw new Error('[[pages:maintenance.text, ' + validator.escape(String(meta.config.title || 'NodeBB')) + ']]'); } const getSessionAsync = util.promisify((sid, callback) => db.sessionStore.get(sid, (err, sessionObj) => callback(err, sessionObj || null))); From 88e5cda5b4a0e56488f01e34eef54173069f05cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 12:46:12 -0500 Subject: [PATCH 037/116] fix: spec for /tag --- public/openapi/read/tags/tag.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/openapi/read/tags/tag.yaml b/public/openapi/read/tags/tag.yaml index cae61daf61..aaa2138a37 100644 --- a/public/openapi/read/tags/tag.yaml +++ b/public/openapi/read/tags/tag.yaml @@ -255,6 +255,8 @@ get: type: string rssFeedUrl: type: string + feeds:disableRSS: + type: boolean required: - topics - tag From f5714452b1824431d36a4fba534f07856035485d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Nov 2020 17:53:52 +0000 Subject: [PATCH 038/116] fix(deps): update dependency nodebb-plugin-markdown to v8.12.2 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index 6899030510..72e50323fe 100644 --- a/install/package.json +++ b/install/package.json @@ -97,7 +97,7 @@ "nodebb-plugin-dbsearch": "4.1.2", "nodebb-plugin-emoji": "^3.3.0", "nodebb-plugin-emoji-android": "2.0.0", - "nodebb-plugin-markdown": "8.12.1", + "nodebb-plugin-markdown": "8.12.2", "nodebb-plugin-mentions": "2.13.5", "nodebb-plugin-soundpack-default": "1.0.0", "nodebb-plugin-spam-be-gone": "0.7.6", From 1b1205a9ced3f8033ed7c652efeea451c01fc23c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 13:36:25 -0500 Subject: [PATCH 039/116] fix(spec): broken test due to canFlag addition --- .../components/schemas/UserObject.yaml | 2 + .../openapi/read/user/userslug/watched.yaml | 191 +----------------- 2 files changed, 3 insertions(+), 190 deletions(-) diff --git a/public/openapi/components/schemas/UserObject.yaml b/public/openapi/components/schemas/UserObject.yaml index 2edc402156..d1621e13df 100644 --- a/public/openapi/components/schemas/UserObject.yaml +++ b/public/openapi/components/schemas/UserObject.yaml @@ -412,6 +412,8 @@ UserObjectFull: type: boolean canBan: type: boolean + canFlag: + type: boolean canChangePassword: type: boolean isSelf: diff --git a/public/openapi/read/user/userslug/watched.yaml b/public/openapi/read/user/userslug/watched.yaml index 9069465791..11e6cf9266 100644 --- a/public/openapi/read/user/userslug/watched.yaml +++ b/public/openapi/read/user/userslug/watched.yaml @@ -16,200 +16,11 @@ get: application/json: schema: allOf: - - $ref: ../../../components/schemas/UserObject.yaml#/UserObject + - $ref: ../../../components/schemas/UserObject.yaml#/UserObjectFull - type: object properties: - aboutmeParsed: - type: string - age: - type: number - emailClass: - type: string - ips: - type: array - items: - type: string - counts: - type: object - properties: - best: - type: number - blocks: - type: number - bookmarks: - type: number - categoriesWatched: - type: number - downvoted: - type: number - followers: - type: number - following: - type: number - groups: - type: number - ignored: - type: number - posts: - type: number - topics: - type: number - uploaded: - type: number - upvoted: - type: number - watched: - type: number - isBlocked: - type: boolean - blocksCount: - type: number - yourid: - type: number - theirid: - type: number - isTargetAdmin: - type: boolean - isAdmin: - type: boolean - isGlobalModerator: - type: boolean - isModerator: - type: boolean - isAdminOrGlobalModerator: - type: boolean - isAdminOrGlobalModeratorOrModerator: - type: boolean - isSelfOrAdminOrGlobalModerator: - type: boolean - canEdit: - type: boolean - canBan: - type: boolean - canChangePassword: - type: boolean - isSelf: - type: boolean - isFollowing: - type: boolean - hasPrivateChat: - type: number - showHidden: - type: boolean - groups: - type: array - items: - type: object - properties: - name: - type: string - slug: - type: string - createtime: - type: number - userTitle: - type: string - description: - type: string - memberCount: - type: number - deleted: - oneOf: - - type: string - - type: number - hidden: - type: number - system: - type: number - private: - type: number - ownerUid: - type: number - icon: - type: string - labelColor: - type: string - userTitleEnabled: - type: number - disableJoinRequests: - type: number - disableLeave: - type: number - nameEncoded: - type: string - displayName: - type: string - textColor: - type: string - createtimeISO: - type: string - cover:thumb:url: - type: string - cover:url: - type: string - cover:position: - type: string - disableSignatures: - type: boolean - reputation:disabled: - type: boolean - downvote:disabled: - type: boolean - profile_links: - type: array - items: - type: object - properties: - id: - type: string - route: - type: string - name: - type: string - visibility: - type: object - properties: - self: - type: boolean - other: - type: boolean - moderator: - type: boolean - globalMod: - type: boolean - admin: - type: boolean - canViewInfo: - type: boolean - public: - type: boolean - icon: - type: string - sso: - type: array - items: - type: object - properties: - associated: - type: boolean - url: - type: string - deauthUrl: - type: string - name: - type: string - icon: - type: string - websiteLink: - type: string - websiteName: - type: string moderationNote: type: string - username:disableEdit: - type: boolean - email:disableEdit: - type: boolean topics: type: array items: From 007a3258a01532c38fd4fce6281b4b9e2799783d Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 27 Nov 2020 15:12:55 -0500 Subject: [PATCH 040/116] feat: add handler for 501 api response --- src/controllers/helpers.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/controllers/helpers.js b/src/controllers/helpers.js index 62ee51106c..78772b065d 100644 --- a/src/controllers/helpers.js +++ b/src/controllers/helpers.js @@ -448,6 +448,12 @@ helpers.generateError = (statusCode, message) => { case 500: payload.status.code = 'internal-server-error'; payload.status.message = message || payload.status.message; + break; + + case 501: + payload.status.code = 'not-implemented'; + payload.status.message = message || 'The route you are trying to call is not implemented yet, please try again tomorrow'; + break; } return payload; From 6e6a7a8f8a9a75500ba1f336cabc882234212f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 27 Nov 2020 15:38:22 -0500 Subject: [PATCH 041/116] fix: #8969, export csv to file --- public/language/en-GB/admin/manage/users.json | 4 ++- public/language/en-GB/notifications.json | 1 + public/src/admin/manage/users.js | 28 ++++++++++++++++ src/controllers/admin/users.js | 33 +++++++++++-------- src/socket.io/admin/user.js | 25 ++++++++++++++ src/user/admin.js | 29 +++++++++++++++- src/views/admin/manage/users.tpl | 2 +- 7 files changed, 106 insertions(+), 16 deletions(-) diff --git a/public/language/en-GB/admin/manage/users.json b/public/language/en-GB/admin/manage/users.json index d0d95b380f..76488baeb7 100644 --- a/public/language/en-GB/admin/manage/users.json +++ b/public/language/en-GB/admin/manage/users.json @@ -102,5 +102,7 @@ "alerts.prompt-email": "Emails: ", "alerts.email-sent-to": "An invitation email has been sent to %1", - "alerts.x-users-found": "%1 user(s) found, (%2 seconds)" + "alerts.x-users-found": "%1 user(s) found, (%2 seconds)", + "export-users-started": "Exporting users as csv, this might take a while. You will receive a notification when it is complete.", + "export-users-completed": "Users exported as csv, click here to download." } \ No newline at end of file diff --git a/public/language/en-GB/notifications.json b/public/language/en-GB/notifications.json index 17d7a23bdf..92811490ff 100644 --- a/public/language/en-GB/notifications.json +++ b/public/language/en-GB/notifications.json @@ -50,6 +50,7 @@ "profile-exported": "%1 profile exported, click to download", "posts-exported": "%1 posts exported, click to download", "uploads-exported": "%1 uploads exported, click to download", + "users-csv-exported": "Users csv exported, click to download", "email-confirmed": "Email Confirmed", "email-confirmed-message": "Thank you for validating your email. Your account is now fully activated.", diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index bba44bf21d..a6f9c887d3 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -13,6 +13,34 @@ define('admin/manage/users', [ ajaxify.go(window.location.pathname + '?' + qs); }); + $('.export-csv').on('click', function () { + socket.once('event:export-users-csv', function () { + app.removeAlert('export-users-start'); + app.alert({ + alert_id: 'export-users', + type: 'success', + title: '[[global:alert.success]]', + message: '[[admin/manage/users:export-users-completed]]', + clickfn: function () { + window.location.href = config.relative_path + '/api/admin/users/csv'; + }, + timeout: 0, + }); + }); + socket.emit('admin.user.exportUsersCSV', {}, function (err) { + if (err) { + return app.alertError(err); + } + app.alert({ + alert_id: 'export-users-start', + message: '[[admin/manage/users:export-users-started]]', + timeout: (ajaxify.data.userCount / 5000) * 500, + }); + }); + + return false; + }); + function getSelectedUids() { var uids = []; diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index ccb7fa1e42..2e5cd2438a 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -1,6 +1,5 @@ 'use strict'; -const nconf = require('nconf'); const validator = require('validator'); const user = require('../../user'); @@ -242,7 +241,7 @@ async function render(req, res, data) { filterBy.forEach(function (filter) { data['filterBy_' + validator.escape(String(filter))] = true; }); - + data.userCount = await db.getObjectField('global', 'userCount'); if (data.adminInviteOnly) { data.showInviteButton = await privileges.users.isAdministrator(req.uid); } else { @@ -252,19 +251,27 @@ async function render(req, res, data) { res.render('admin/manage/users', data); } -usersController.getCSV = async function (req, res) { - var referer = req.headers.referer; - - if (!referer || !referer.replace(nconf.get('url'), '').startsWith('/admin/manage/users')) { - return res.status(403).send('[[error:invalid-origin]]'); - } - events.log({ +usersController.getCSV = async function (req, res, next) { + await events.log({ type: 'getUsersCSV', uid: req.uid, ip: req.ip, }); - const data = await user.getUsersCSV(); - res.attachment('users.csv'); - res.setHeader('Content-Type', 'text/csv'); - res.end(data); + const path = require('path'); + const { baseDir } = require('../../constants').paths; + res.sendFile('users.csv', { + root: path.join(baseDir, 'build/export'), + headers: { + 'Content-Type': 'text/csv', + 'Content-Disposition': 'attachment; filename=users.csv', + }, + }, function (err) { + if (err) { + if (err.code === 'ENOENT') { + res.locals.isAPI = false; + return next(); + } + return next(err); + } + }); }; diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index 91dfb49646..bf0325e484 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -1,6 +1,7 @@ 'use strict'; const async = require('async'); +const winston = require('winston'); const db = require('../../database'); const api = require('../../api'); @@ -157,3 +158,27 @@ User.loadGroups = async function (socket, uids) { }); return { users: userData }; }; + +User.exportUsersCSV = async function (socket) { + await events.log({ + type: 'exportUsersCSV', + uid: socket.uid, + ip: socket.ip, + }); + setTimeout(async function () { + try { + await user.exportUsersCSV(); + socket.emit('event:export-users-csv'); + const notifications = require('../../notifications'); + const n = await notifications.create({ + bodyShort: '[[notifications:users-csv-exported]]', + path: '/api/admin/users/csv', + nid: 'users:csv:export', + from: socket.uid, + }); + await notifications.push(n, [socket.uid]); + } catch (err) { + winston.error(err); + } + }, 0); +}; diff --git a/src/user/admin.js b/src/user/admin.js index 981fd921b4..45226bfe85 100644 --- a/src/user/admin.js +++ b/src/user/admin.js @@ -1,9 +1,12 @@ 'use strict'; +const fs = require('fs'); +const path = require('path'); const winston = require('winston'); const validator = require('validator'); +const { baseDir } = require('../constants').paths; const db = require('../database'); const plugins = require('../plugins'); const batch = require('../batch'); @@ -36,11 +39,35 @@ module.exports = function (User) { await batch.processSortedSet('users:joindate', async (uids) => { const usersData = await User.getUsersFields(uids, data.fields); csvContent += usersData.reduce((memo, user) => { - memo += user.email + ',' + user.username + ',' + user.uid + '\n'; + memo += data.fields.map(field => user[field]).join(',') + '\n'; return memo; }, ''); }, {}); return csvContent; }; + + User.exportUsersCSV = async function () { + winston.verbose('[user/exportUsersCSV] Exporting User CSV data'); + + const data = await plugins.hooks.fire('filter:user.csvFields', { fields: ['email', 'username', 'uid'] }); + const fd = await fs.promises.open( + path.join(baseDir, 'build/export', 'users.csv'), + 'w' + ); + fs.promises.appendFile(fd, data.fields.join(',') + '\n'); + await batch.processSortedSet('users:joindate', async (uids) => { + const usersData = await User.getUsersFields(uids, data.fields.slice()); + let line = ''; + usersData.forEach(function (user) { + line += data.fields.map(field => user[field]).join(',') + '\n'; + }); + + await fs.promises.appendFile(fd, line); + }, { + batch: 5000, + interval: 250, + }); + await fd.close(); + }; }; diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 826ed34411..0cdd099ae2 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -6,7 +6,7 @@ - [[admin/manage/users:download-csv]] + [[admin/manage/users:download-csv]]