From 83b5a20c7c538bf1decc30d93ac64ea64a4a1b6e Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Thu, 14 May 2020 09:31:51 +0000 Subject: [PATCH 01/26] Latest translations and fallbacks --- public/language/sr/notifications.json | 4 ++-- public/language/sr/recent.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/language/sr/notifications.json b/public/language/sr/notifications.json index 3889746710..5f3cfd6e66 100644 --- a/public/language/sr/notifications.json +++ b/public/language/sr/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 других су почели да вас прате.", @@ -54,7 +54,7 @@ "notificationType_upvote": "Када неко гласа за вашу поруку", "notificationType_new-topic": "Када неко кога пратите постави тему", "notificationType_new-reply": "Када је постављен нови одговор у теми коју надгледате", - "notificationType_post-edit": "When a post is edited in a topic you are watching", + "notificationType_post-edit": "Када је порука уређена у теми коју надгледате", "notificationType_follow": "Када неко почне да вас прати", "notificationType_new-chat": "Када примите поруку за ћаскање", "notificationType_group-invite": "Када примите позивницу за групу", diff --git a/public/language/sr/recent.json b/public/language/sr/recent.json index 7358156231..3e39d9d0c4 100644 --- a/public/language/sr/recent.json +++ b/public/language/sr/recent.json @@ -9,9 +9,9 @@ "no_popular_topics": "Нема популарних тема.", "there-is-a-new-topic": "Постоји нова тема.", "there-is-a-new-topic-and-a-new-post": "Постоје нова тема и нова порука.", - "there-is-a-new-topic-and-new-posts": "Постоји нова тема и нових порука: %1.", + "there-is-a-new-topic-and-new-posts": "Постоји нова тема и укупно нових порука: %1.", "there-are-new-topics": "Број нових тема: %1.", - "there-are-new-topics-and-a-new-post": "Постоји нова порука и нових тема: %1.", + "there-are-new-topics-and-a-new-post": "Постоји нова порука и укупно нових тема: %1.", "there-are-new-topics-and-new-posts": "Број нових тема: %1 и нових порука: %2.", "there-is-a-new-post": "Постоји нова порука.", "there-are-new-posts": "Број нових порука: %1.", From 765b8156d526ddb90aada3d342c7b5216a848b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 14 May 2020 16:19:32 -0400 Subject: [PATCH 02/26] feat: parse quick search tpl even if no results allows showing "no results found" in theme --- public/src/app.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 70375a8869..c2ee6f82f6 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -570,6 +570,7 @@ app.cacheBuster = null; } app.enableTopicSearch = function (options) { + console.log('enableTopicSearch', options, new Error('a').stack); var quickSearchResults = options.resultEl; var inputEl = options.inputEl; var template = options.template || 'partials/quick-search-results'; @@ -595,16 +596,16 @@ app.cacheBuster = null; }; $(window).trigger('action:search.quick', { data: data }); search.api(data, function (data) { - if (!data.matchCount) { - quickSearchResults.html('').addClass('hidden'); - return; - } data.posts.forEach(function (p) { p.snippet = utils.escapeHTML($(p.content).text().slice(0, 80) + '...'); }); app.parseAndTranslate(template, data, function (html) { - html.find('.timeago').timeago(); - quickSearchResults.html(html).removeClass('hidden').show(); + if (html.length) { + html.find('.timeago').timeago(); + quickSearchResults.html(html).removeClass('hidden').show(); + } else { + quickSearchResults.html('').addClass('hidden'); + } }); }); }); From 40b5cbab2cc6a69a0c6a663c7494d5bcd7e594db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 14 May 2020 16:19:50 -0400 Subject: [PATCH 03/26] refactor: remove console.log --- public/src/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/src/app.js b/public/src/app.js index c2ee6f82f6..67058eb516 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -570,7 +570,6 @@ app.cacheBuster = null; } app.enableTopicSearch = function (options) { - console.log('enableTopicSearch', options, new Error('a').stack); var quickSearchResults = options.resultEl; var inputEl = options.inputEl; var template = options.template || 'partials/quick-search-results'; From a219285e10e7de882fa19dd0f3cb258d3514ca72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 14 May 2020 23:10:36 -0400 Subject: [PATCH 04/26] feat: ignore mongodb playground file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4be45e03e6..12fd822539 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ test/files/normalise.jpg.png test/files/normalise-resized.jpg package-lock.json /package.json +*.mongodb \ No newline at end of file From 5e3760d27692d4bbae92adabe4b3cf0378c841bb Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Fri, 15 May 2020 09:33:38 +0000 Subject: [PATCH 05/26] Latest translations and fallbacks --- public/language/fr/notifications.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/language/fr/notifications.json b/public/language/fr/notifications.json index ff001a7886..312ca64b86 100644 --- a/public/language/fr/notifications.json +++ b/public/language/fr/notifications.json @@ -35,7 +35,7 @@ "user_posted_to_dual": "%1 et %2 ont posté une réponse à : %3", "user_posted_to_multiple": "%1 et %2 autres ont posté une réponse à : %3", "user_posted_topic": "%1 a posté un nouveau sujet: %2.", - "user_edited_post": "%1 has edited a post in %2", + "user_edited_post": "%1 a édité un message dans %2", "user_started_following_you": "%1 vous suit.", "user_started_following_you_dual": "%1 et %2 se sont abonnés à votre compte.", "user_started_following_you_multiple": "%1 et %2 autres se sont abonnés à votre compte.", @@ -54,7 +54,7 @@ "notificationType_upvote": "Lorsque quelqu'un a voté pour un de vos messages", "notificationType_new-topic": "Lorsque quelqu'un que vous suivez publie un sujet", "notificationType_new-reply": "Lorsqu'une nouvelle réponse est ajoutée dans un sujet que vous suivez", - "notificationType_post-edit": "When a post is edited in a topic you are watching", + "notificationType_post-edit": "Lorsqu'un article est modifié dans un sujet que vous regardez", "notificationType_follow": "Lorsque quelqu'un commence à vous suivre", "notificationType_new-chat": "Lorsque vous recevez un message du chat ", "notificationType_group-invite": "Lorsque vous recevez une invitation d'un groupe", From bdda0222381a0030e792d928cc9cb57973e5bdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 10:52:04 -0400 Subject: [PATCH 06/26] fix: undefined uid when downloading posts --- src/controllers/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/user.js b/src/controllers/user.js index 861a88485a..452b2cca62 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -104,7 +104,7 @@ userController.exportPosts = async function (req, res) { checkSchemaDifferences: false, emptyFieldValue: '', }); - res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + req.params.uid + '_posts.csv"').send(csv); + res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + req.locals.uid + '_posts.csv"').send(csv); }; userController.exportUploads = function (req, res, next) { From dfae664e292df1ac196d51ba525b901f42b7af47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 10:59:38 -0400 Subject: [PATCH 07/26] fix: exporting posts --- src/controllers/user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controllers/user.js b/src/controllers/user.js index 452b2cca62..5bd643d63e 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -99,12 +99,15 @@ userController.exportPosts = async function (req, res) { return post; }); payload = payload.concat(postData); + }, { + batch: 500, }); + const csv = await json2csv(payload, { checkSchemaDifferences: false, emptyFieldValue: '', }); - res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + req.locals.uid + '_posts.csv"').send(csv); + res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + res.locals.uid + '_posts.csv"').send(csv); }; userController.exportUploads = function (req, res, next) { From 1d3fa3bc4e7f6f4b38c6478e74e486c06f4d3441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 15:23:01 -0400 Subject: [PATCH 08/26] feat: throw error if uid is missing for update --- src/user/profile.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/user/profile.js b/src/user/profile.js index 2b6a59e025..4eea3ee22a 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -16,7 +16,9 @@ module.exports = function (User) { 'username', 'email', 'fullname', 'website', 'location', 'groupTitle', 'birthday', 'signature', 'aboutme', ]; - + if (!data.uid) { + throw new Error('[[error:invalid-update-uid]]'); + } const updateUid = data.uid; const result = await plugins.fireHook('filter:user.updateProfile', { uid: uid, data: data, fields: fields }); From f0323b6cfa19161e7b8f72543a3adade1c84fb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 15:29:28 -0400 Subject: [PATCH 09/26] feat: closes #8316, add more data to export profile --- install/package.json | 2 +- public/language/en-GB/user.json | 2 +- src/controllers/admin/errors.js | 11 ++--- src/controllers/user.js | 79 ++++++++++++++++++++++++++------- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/install/package.json b/install/package.json index 8063b62b64..4aebe67aac 100644 --- a/install/package.json +++ b/install/package.json @@ -65,7 +65,7 @@ "ipaddr.js": "^1.9.1", "jquery": "3.5.1", "jsesc": "3.0.1", - "json-2-csv": "^3.6.2", + "json2csv": "5.0.1", "jsonwebtoken": "^8.5.1", "less": "^3.11.1", "lodash": "^4.17.15", diff --git a/public/language/en-GB/user.json b/public/language/en-GB/user.json index 18d17aeb18..f1c3b8f7fe 100644 --- a/public/language/en-GB/user.json +++ b/public/language/en-GB/user.json @@ -191,7 +191,7 @@ "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } diff --git a/src/controllers/admin/errors.js b/src/controllers/admin/errors.js index accefbdae2..f609ecca3d 100644 --- a/src/controllers/admin/errors.js +++ b/src/controllers/admin/errors.js @@ -1,7 +1,6 @@ 'use strict'; -const json2csv = require('json-2-csv').json2csv; -const util = require('util'); +const json2csvAsync = require('json2csv').parseAsync; const meta = require('../../meta'); const analytics = require('../../analytics'); @@ -17,12 +16,10 @@ errorsController.get = async function (req, res) { res.render('admin/advanced/errors', data); }; -const json2csvAsync = util.promisify(function (data, callback) { - json2csv(data, (err, output) => callback(err, output)); -}); - errorsController.export = async function (req, res) { const data = await meta.errors.get(false); - const csv = await json2csvAsync(data); + const fields = data.length ? Object.keys(data[0]) : []; + const opts = { fields }; + const csv = await json2csvAsync(data, opts); res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="404.csv"').send(csv); }; diff --git a/src/controllers/user.js b/src/controllers/user.js index 5bd643d63e..8c172808fd 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -1,11 +1,11 @@ 'use strict'; +const _ = require('lodash'); const path = require('path'); const fs = require('fs'); const winston = require('winston'); -const converter = require('json-2-csv'); +const json2csvAsync = require('json2csv').parseAsync; const archiver = require('archiver'); -const util = require('util'); const db = require('../database'); const user = require('../user'); @@ -85,10 +85,6 @@ userController.getUserDataByUID = async function (callerUid, uid) { return userData; }; -const json2csv = util.promisify(function (payload, options, callback) { - converter.json2csv(payload, callback, options); -}); - userController.exportPosts = async function (req, res) { var payload = []; await batch.processSortedSet('uid:' + res.locals.uid + ':posts', async function (pids) { @@ -103,10 +99,9 @@ userController.exportPosts = async function (req, res) { batch: 500, }); - const csv = await json2csv(payload, { - checkSchemaDifferences: false, - emptyFieldValue: '', - }); + const fields = payload.length ? Object.keys(payload[0]) : []; + const opts = { fields }; + const csv = await json2csvAsync(payload, opts); res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + res.locals.uid + '_posts.csv"').send(csv); }; @@ -192,15 +187,67 @@ userController.exportUploads = function (req, res, next) { }; userController.exportProfile = async function (req, res) { - const targetUid = res.locals.uid; - const objects = await db.getObjects(['user:' + targetUid, 'user:' + targetUid + ':settings']); - Object.assign(objects[0], objects[1]); - delete objects[0].password; + const targetUid = parseInt(res.locals.uid, 10); + const [userData, userSettings, ips, sessions, usernames, emails, bookmarks, watchedTopics, upvoted, downvoted, following] = await Promise.all([ + db.getObject('user:' + targetUid), + db.getObject('user:' + targetUid + ':settings'), + user.getIPs(targetUid, 9), + user.auth.getSessions(targetUid, req.sessionID), + user.getHistory('user:' + targetUid + ':usernames'), + user.getHistory('user:' + targetUid + ':emails'), + getSetData('uid:' + targetUid + ':bookmarks', 'post:'), + getSetData('uid:' + targetUid + ':followed_tids', 'topic:'), + getSetData('uid:' + targetUid + ':upvote', 'post:'), + getSetData('uid:' + targetUid + ':downvote', 'post:'), + getSetData('following:' + targetUid, 'user:'), + ]); + delete userData.password; + const followingData = following.map(u => ({ username: u.username, uid: u.uid })); - const csv = await json2csv(objects[0], {}); - res.set('Content-Type', 'text/csv').set('Content-Disposition', 'attachment; filename="' + targetUid + '_profile.csv"').send(csv); + let chatData = []; + await batch.processSortedSet('uid:' + targetUid + ':chat:rooms', async (roomIds) => { + var result = await Promise.all(roomIds.map(roomId => getRoomMessages(targetUid, roomId))); + chatData = chatData.concat(_.flatten(result)); + }, { batch: 100 }); + + res.set('Content-Type', 'application/json') + .set('Content-Disposition', 'attachment; filename="' + targetUid + '_profile.json"') + .send({ + user: userData, + settings: userSettings, + ips: ips, + sessions: sessions, + usernames: usernames, + emails: emails, + messages: chatData, + bookmarks: bookmarks, + watchedTopics: watchedTopics, + upvoted: upvoted, + downvoted: downvoted, + following: followingData, + }); }; +async function getRoomMessages(uid, roomId) { + let data = []; + await batch.processSortedSet('uid:' + uid + ':chat:room:' + roomId + ':mids', async (mids) => { + const messageData = await db.getObjects(mids.map(mid => 'message:' + mid)); + data = data.concat(messageData.filter(m => m && m.fromuid === uid && !m.system) + .map(m => ({ content: m.content, timestamp: m.timestamp })) + ); + }, { batch: 500 }); + return data; +} + +async function getSetData(set, keyPrefix) { + let data = []; + await batch.processSortedSet(set, async (ids) => { + data = data.concat(await db.getObjects(ids.map(mid => keyPrefix + mid))); + }, { batch: 500 }); + return data; +} + + require('../promisify')(userController, [ 'getCurrentUser', 'getUserByUID', 'getUserByUsername', 'getUserByEmail', 'exportPosts', 'exportUploads', 'exportProfile', From 5fd81c5c049ee5f91ab98e52f869d3d37f7812eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 15:44:39 -0400 Subject: [PATCH 10/26] fix: check privileges before exporting post/topic data --- src/controllers/user.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/controllers/user.js b/src/controllers/user.js index 8c172808fd..c60d55c969 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -195,11 +195,11 @@ userController.exportProfile = async function (req, res) { user.auth.getSessions(targetUid, req.sessionID), user.getHistory('user:' + targetUid + ':usernames'), user.getHistory('user:' + targetUid + ':emails'), - getSetData('uid:' + targetUid + ':bookmarks', 'post:'), - getSetData('uid:' + targetUid + ':followed_tids', 'topic:'), - getSetData('uid:' + targetUid + ':upvote', 'post:'), - getSetData('uid:' + targetUid + ':downvote', 'post:'), - getSetData('following:' + targetUid, 'user:'), + getSetData('uid:' + targetUid + ':bookmarks', 'post:', targetUid), + getSetData('uid:' + targetUid + ':followed_tids', 'topic:', targetUid), + getSetData('uid:' + targetUid + ':upvote', 'post:', targetUid), + getSetData('uid:' + targetUid + ':downvote', 'post:', targetUid), + getSetData('following:' + targetUid, 'user:', targetUid), ]); delete userData.password; const followingData = following.map(u => ({ username: u.username, uid: u.uid })); @@ -239,15 +239,19 @@ async function getRoomMessages(uid, roomId) { return data; } -async function getSetData(set, keyPrefix) { +async function getSetData(set, keyPrefix, uid) { let data = []; await batch.processSortedSet(set, async (ids) => { - data = data.concat(await db.getObjects(ids.map(mid => keyPrefix + mid))); + if (keyPrefix === 'post:') { + ids = await privileges.posts.filter('topics:read', ids, uid); + } else if (keyPrefix === 'topic:') { + ids = await privileges.topics.filterTids('topics:read', ids, uid); + } + data = data.concat(await db.getObjects(ids.map(id => keyPrefix + id))); }, { batch: 500 }); return data; } - require('../promisify')(userController, [ 'getCurrentUser', 'getUserByUID', 'getUserByUsername', 'getUserByEmail', 'exportPosts', 'exportUploads', 'exportProfile', From 526b3cd9ec52c934dfdedc149c8534f65b665e6d Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 15 May 2020 16:41:05 -0400 Subject: [PATCH 11/26] fix: #8142 invalid session warning if server-side session destroyed Resolved regression caused by 5a0c7c1497ed2de84ad317f7e3fcc6b1354b08eb --- src/middleware/headers.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/middleware/headers.js b/src/middleware/headers.js index 453c75736f..e1486145fa 100644 --- a/src/middleware/headers.js +++ b/src/middleware/headers.js @@ -56,8 +56,9 @@ module.exports = function (middleware) { } // Ensure that the session is valid. This block guards against edge-cases where the server-side session has - // been deleted (but client-side cookie still exists) - if (req.uid > 0 && !req.session.meta && !res.get('Set-Cookie')) { + // been deleted (but client-side cookie still exists). + // req.session.flash is present if you visit register/login, so all logged-in users have it, but it is missing if your server-side session got destroyed. + if (!req.session.flash && !req.session.meta && !res.get('Set-Cookie')) { res.clearCookie(nconf.get('sessionKey'), meta.configs.cookie.get()); } From 81e33b9391cd7adac662a697e735f989d911852e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 15 May 2020 22:10:50 -0400 Subject: [PATCH 12/26] fix: #8317 --- src/topics/fork.js | 8 ++++++++ test/topics.js | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/topics/fork.js b/src/topics/fork.js index 40edecf6b8..15c784a926 100644 --- a/src/topics/fork.js +++ b/src/topics/fork.js @@ -52,6 +52,14 @@ module.exports = function (Topics) { await Topics.updateLastPostTime(tid, Date.now()); + await Promise.all([ + Topics.setTopicFields(tid, { + upvotes: postData.upvotes, + downvotes: postData.downvotes, + }), + db.sortedSetsAdd(['topics:votes', 'cid:' + cid + ':tids:votes'], postData.votes, tid), + ]); + plugins.fireHook('action:topic.fork', { tid: tid, fromTid: fromTid, uid: uid }); return await Topics.getTopicData(tid); diff --git a/test/topics.js b/test/topics.js index 80380b5a3d..0ef388fca4 100644 --- a/test/topics.js +++ b/test/topics.js @@ -906,6 +906,22 @@ describe('Topic\'s', function () { }, ], done); }); + + it('should properly update topic vote count after forking', async () => { + const result = await topics.post({ uid: fooUid, cid: categoryObj.cid, title: 'fork vote test', content: 'main post' }); + const reply1 = await topics.reply({ tid: result.topicData.tid, uid: fooUid, content: 'test reply 1' }); + const reply2 = await topics.reply({ tid: result.topicData.tid, uid: fooUid, content: 'test reply 2' }); + const reply3 = await topics.reply({ tid: result.topicData.tid, uid: fooUid, content: 'test reply 3' }); + await posts.upvote(result.postData.pid, adminUid); + await posts.upvote(reply1.pid, adminUid); + assert.strictEqual(await db.sortedSetScore('topics:votes', result.topicData.tid), 1); + assert.strictEqual(await db.sortedSetScore('cid:' + categoryObj.cid + ':tids:votes', result.topicData.tid), 1); + const newTopic = await topics.createTopicFromPosts(adminUid, 'Fork test, vote update', [reply1.pid, reply2.pid], result.topicData.tid); + + assert.strictEqual(await db.sortedSetScore('topics:votes', newTopic.tid), 1); + assert.strictEqual(await db.sortedSetScore('cid:' + categoryObj.cid + ':tids:votes', newTopic.tid), 1); + assert.strictEqual(await topics.getTopicField(newTopic.tid, 'upvotes'), 1); + }); }); describe('controller', function () { From a032e12b7ee1de6a242518d2537b88834ac93b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 16 May 2020 00:25:44 -0400 Subject: [PATCH 13/26] fix: tests --- test/controllers-admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers-admin.js b/test/controllers-admin.js index 371685866f..d38f2884c3 100644 --- a/test/controllers-admin.js +++ b/test/controllers-admin.js @@ -395,7 +395,7 @@ describe('Admin Controllers', function () { request(nconf.get('url') + '/api/admin/advanced/errors/export', { jar: jar }, function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 200); - assert(body); + assert.strictEqual(body, ''); done(); }); }); From 981db6429a37573b2067bb4f811e413c9cba15f4 Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Sat, 16 May 2020 09:27:39 +0000 Subject: [PATCH 14/26] Latest translations and fallbacks --- public/language/ar/user.json | 2 +- public/language/bg/user.json | 2 +- public/language/bn/user.json | 2 +- public/language/cs/user.json | 2 +- public/language/da/user.json | 2 +- public/language/de/user.json | 2 +- public/language/el/user.json | 2 +- public/language/en-US/user.json | 2 +- public/language/en-x-pirate/user.json | 2 +- public/language/es/user.json | 2 +- public/language/et/user.json | 2 +- public/language/fa-IR/user.json | 2 +- public/language/fi/user.json | 2 +- public/language/fr/user.json | 2 +- public/language/gl/user.json | 2 +- public/language/he/user.json | 2 +- public/language/hr/user.json | 2 +- public/language/hu/user.json | 2 +- public/language/id/user.json | 2 +- public/language/it/user.json | 2 +- public/language/ja/user.json | 2 +- public/language/ko/user.json | 2 +- public/language/lt/user.json | 2 +- public/language/lv/user.json | 2 +- public/language/ms/user.json | 2 +- public/language/nb/user.json | 2 +- public/language/nl/user.json | 2 +- public/language/pl/user.json | 2 +- public/language/pt-BR/user.json | 2 +- public/language/pt-PT/user.json | 2 +- public/language/ro/user.json | 2 +- public/language/ru/user.json | 2 +- public/language/rw/user.json | 2 +- public/language/sc/user.json | 2 +- public/language/sk/user.json | 2 +- public/language/sl/user.json | 2 +- public/language/sr/user.json | 2 +- public/language/sv/user.json | 2 +- public/language/th/user.json | 2 +- public/language/tr/user.json | 2 +- public/language/uk/user.json | 2 +- public/language/vi/user.json | 2 +- public/language/zh-CN/user.json | 2 +- public/language/zh-TW/user.json | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/public/language/ar/user.json b/public/language/ar/user.json index 4203bc55c3..0c3c5a4517 100644 --- a/public/language/ar/user.json +++ b/public/language/ar/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/bg/user.json b/public/language/bg/user.json index 1bc9a7f1a8..ebb13c3178 100644 --- a/public/language/bg/user.json +++ b/public/language/bg/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Във всеки един момент можете да оттеглите съгласието си за събиране и/или обработка на данни, като изтриете акаунта си. Вашият профил може да бъде изтрит, но публикуваното от Вас съдържание ще остане. Ако искате да изтриете както акаунта, така и съдържанието, публикувано от Вас, моля, свържете се с администрационния екип на уеб сайта.", "consent.right_to_data_portability": "Имате право на пренос на данни", "consent.right_to_data_portability_description": "Можете да изискате от нас всички събрани за Вас и акаунта Ви данни в машинен формат. Можете да направите това като натиснете съответния бутон по-долу.", - "consent.export_profile": "Изнасяне на профила (.csv)", + "consent.export_profile": "Изнасяне на профила (.json)", "consent.export_uploads": "Изнасяне на каченото съдържание (.zip)", "consent.export_posts": "Изнасяне на публикациите (.csv)" } \ No newline at end of file diff --git a/public/language/bn/user.json b/public/language/bn/user.json index f9034d4f4c..7fa7d1ae3d 100644 --- a/public/language/bn/user.json +++ b/public/language/bn/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/cs/user.json b/public/language/cs/user.json index 2659c48ed5..c31fda6483 100644 --- a/public/language/cs/user.json +++ b/public/language/cs/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Kdykoliv můžete změnit svůj souhlas se shromažďováním dat a/nebo zpracování odstraněním vašeho účtu. Váš profil bude odstraněn, ačkoliv vaše příspěvky budou zachovány. Pokud si přejete odstranění jak účtu tak i obsahu, prosím kontaktujte správce této stránky.", "consent.right_to_data_portability": "Máte právo na přenositelnost dat", "consent.right_to_data_portability_description": "Můžete od nás požadovat strojně čitelné data, která byla sesbírána o Vás a vašem účtu. Učiníte tak kliknutím na tlačítka zobrazená níže.", - "consent.export_profile": "Exportovat profil (*.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportovat nahraný obsah (*.zip)", "consent.export_posts": "Exportovat příspěvky (*.csv)" } \ No newline at end of file diff --git a/public/language/da/user.json b/public/language/da/user.json index 94778b1c67..fe52cee283 100644 --- a/public/language/da/user.json +++ b/public/language/da/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/de/user.json b/public/language/de/user.json index cef04efd03..60e53f8d47 100644 --- a/public/language/de/user.json +++ b/public/language/de/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Du kannst deine Zustimmung zur Datensammlung und/oder Verarbeitung von Daten jederzeit widerrufen, indem du dein Konto löschst. Dein Individuelles Profil kann gelöscht werden, jedoch blieben deine Beiträge und sonstigen Inhalte. Wenn du sowohl dein Konto sowie auch deine Inhalten löschen willst, kontaktiere bitte die Administratoren dieser Seite.", "consent.right_to_data_portability": "Du hast das Recht auf Datenportabilität", "consent.right_to_data_portability_description": "Du kannst von uns eine Maschinen-Lesbare Datei von jeglichen gesammelten Daten von dir und deinem Konto anfordern, indem du unten auf den entsprechenden Knopf drückst. ", - "consent.export_profile": "Profil exportieren (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Hochgeladene Dateien exportieren (.zip)", "consent.export_posts": "Beiträge exportieren (.csv)" } \ No newline at end of file diff --git a/public/language/el/user.json b/public/language/el/user.json index d0f3121bda..e4f10a6f29 100644 --- a/public/language/el/user.json +++ b/public/language/el/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/en-US/user.json b/public/language/en-US/user.json index 49b77622b4..2cf3684ac1 100644 --- a/public/language/en-US/user.json +++ b/public/language/en-US/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/en-x-pirate/user.json b/public/language/en-x-pirate/user.json index 270ce18a88..f18892c02b 100644 --- a/public/language/en-x-pirate/user.json +++ b/public/language/en-x-pirate/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/es/user.json b/public/language/es/user.json index 1c6b2988b5..c57c9af970 100644 --- a/public/language/es/user.json +++ b/public/language/es/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "En cualquier momento, usted puede revocar su consentimiento a la recolección y/o procesado de datos mediante el borrado de su cuenta. Su perfil individual puede ser borrado, aunque sus respuestas y entradas permanecerán. Si desea borrar su cuenta y el contenido (entradas, temas, respuestas...), por favor contacte el equipo administrativo de este sitio web.", "consent.right_to_data_portability": "Usted tiene el Derecho a la Portabilidad de Datos", "consent.right_to_data_portability_description": "Puede pedir de nosotros una exportación legible por máquinas de cualquier dato recolectado sobre usted y su cuenta. Puede hacerlo haciendo click en el botón apropiado abajo.", - "consent.export_profile": "Exportar Perfil (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportar Contenido Subido (.zip)", "consent.export_posts": "Exportar Entradas y Respuestas (.csv)" } \ No newline at end of file diff --git a/public/language/et/user.json b/public/language/et/user.json index 8656cdeee6..9dee4ec6b8 100644 --- a/public/language/et/user.json +++ b/public/language/et/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/fa-IR/user.json b/public/language/fa-IR/user.json index 46d7e3c5b8..c334301bcd 100644 --- a/public/language/fa-IR/user.json +++ b/public/language/fa-IR/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "صادر کردن مشخصات کاربری (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/fi/user.json b/public/language/fi/user.json index 9c9ce75f52..0c7f8bc9c7 100644 --- a/public/language/fi/user.json +++ b/public/language/fi/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/fr/user.json b/public/language/fr/user.json index 854c89f02b..3ebac70093 100644 --- a/public/language/fr/user.json +++ b/public/language/fr/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Vous pouvez à tout moment révoquer votre accord à la collecte et/ou aux traitements de données en supprimant votre compte. Votre profil individuel peut être supprimé, bien que le contenu que vous avez publié restera affiché. Si vous souhaitez supprimer à la fois votre compte et votre contenu, veuillez contacter l'équipe administrative pour ce site.", "consent.right_to_data_portability": "Vous avez la possibilité de portabilité des données.", "consent.right_to_data_portability_description": "Vous pouvez exporter de toutes vos données collectées. Vous pouvez le faire en cliquant sur le bouton ci-dessous.", - "consent.export_profile": "Exporter votre profile (.csv)", + "consent.export_profile": "Exporter Profile (.json)", "consent.export_uploads": "Exporter le contenu de vos fichiers envoyés (.zip)", "consent.export_posts": "Exporter vos messages (.csv)" } \ No newline at end of file diff --git a/public/language/gl/user.json b/public/language/gl/user.json index 085f701aeb..f94155e39f 100644 --- a/public/language/gl/user.json +++ b/public/language/gl/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/he/user.json b/public/language/he/user.json index ca31c2f78e..cfe5491d9e 100644 --- a/public/language/he/user.json +++ b/public/language/he/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "בכל עת תוכל לבטל את הסכמתך לאיסוף נתונים ו / או עיבודם על ידי מחיקת חשבונך. מחיקת הפרופיל שלך לא תגרום למחיקת התוכנים שפרסמת. על מנת למחוק את חשבונך ואת התוכן המקושר לו צור קשר עם צוות הניהול של האתר.", "consent.right_to_data_portability": "זכותך לניוד הנתונים", "consent.right_to_data_portability_description": "באפרותך לבקש ייצוא של כל הנתונים שנאספו מחשבונך אודותיך. תוכל לעשות זאת על ידי לחיצה על הלחצן המתאים מטה.", - "consent.export_profile": "יצוא פרופיל (CVS.)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "יצוא תוכן שהועלה (ZIP.)", "consent.export_posts": "יצוא פוסטים (CVS.)" } \ No newline at end of file diff --git a/public/language/hr/user.json b/public/language/hr/user.json index f4456a7bb4..58922e2b76 100644 --- a/public/language/hr/user.json +++ b/public/language/hr/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/hu/user.json b/public/language/hu/user.json index c87fc14fe5..e9d2c3ca92 100644 --- a/public/language/hu/user.json +++ b/public/language/hu/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Az adatgyűjtésre és/vagy feldolgozásra adott jóváhagyásodat bármikor hatálytalaníthatod fiókod törlésével. Noha egyéni profilod törlésre ítélhető, közzétett tartalmaid megmaradnak. Ha törölni kívánod mind profilod és tartalmaid, kérlek lépj kapcsolatba az oldal adminisztratív csapatával.", "consent.right_to_data_portability": "Jogodban áll az adathordozhatóság", "consent.right_to_data_portability_description": "Kérelmezhetsz tőlünk egy gép által olvasható kivonatot bármilyen, a rólad és fiókodról gyűjtött adatról. Ezt alább a megfelelő gomb megnyomásával teheted meg.", - "consent.export_profile": "Profil exportálása (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Feltöltött tartalom exportálása (.zip)", "consent.export_posts": "Hozzászólások exportálása (.csv)" } \ No newline at end of file diff --git a/public/language/id/user.json b/public/language/id/user.json index 63d6d09b3f..59c6318438 100644 --- a/public/language/id/user.json +++ b/public/language/id/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/it/user.json b/public/language/it/user.json index e57a828965..4a9545fc17 100644 --- a/public/language/it/user.json +++ b/public/language/it/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "In qualsiasi momento, puoi revocare il tuo consenso alla raccolta e / o al trattamento dei dati eliminando il tuo account. Il tuo profilo individuale può essere eliminato, anche se i contenuti pubblicati rimarranno. Se desideri eliminare entrambi i tuoi account e i tuoi contenuti, contatta il team amministrativo per questo sito Web.", "consent.right_to_data_portability": "Hai i privilegi alla portabilità dei dati", "consent.right_to_data_portability_description": "Puoi richiedere da noi un'esportazione leggibile meccanicamente di tutti i dati raccolti su di te e sul tuo account. Puoi farlo facendo clic sul pulsante appropriato in basso.", - "consent.export_profile": "Esporta i profili (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Esporta i contenuti caricati (.zip)", "consent.export_posts": "Esporta i post (.csv)" } \ No newline at end of file diff --git a/public/language/ja/user.json b/public/language/ja/user.json index 4129dc8bf7..24846d67b5 100644 --- a/public/language/ja/user.json +++ b/public/language/ja/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "あなたはデータを移動する権利があります", "consent.right_to_data_portability_description": "あなたは私たちにあなたとあなたのアカウントに関して収集されたデータの機械読み取り可能なエクスポートを要求することができます。 下の適切なボタンをクリックしてそれを行うことができます。", - "consent.export_profile": "プロファイルをエクスポート(.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "アップデートしたコンテンツをエクスポート(.zip)", "consent.export_posts": "投稿をエクスポート (.csv)" } \ No newline at end of file diff --git a/public/language/ko/user.json b/public/language/ko/user.json index f10e316bfb..0658903567 100644 --- a/public/language/ko/user.json +++ b/public/language/ko/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "당신은 데이터 이동 권한이 있습니다.", "consent.right_to_data_portability_description": "당신은 우리가 수집한 당신과 당신의 계정에 대한 어떠한 수집 데이터라도 기계가 읽을 수 있는 형태로 출력본을 요청할 수 있습니다. 아래에 적절한 버튼을 클릭하여 해당 처리를 수행할 수 있습니다.", - "consent.export_profile": "프로필 내보내기 (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "업로드한 콘텐츠 내보내기 (.zip)", "consent.export_posts": "포스트 내보내기 (.csv)" } \ No newline at end of file diff --git a/public/language/lt/user.json b/public/language/lt/user.json index 1887143155..a26739a154 100644 --- a/public/language/lt/user.json +++ b/public/language/lt/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "Turite teisę į duomenų perkėlimą", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Eksportuoti profilį (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/lv/user.json b/public/language/lv/user.json index 923fd5fcda..b38c29fd66 100644 --- a/public/language/lv/user.json +++ b/public/language/lv/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "Tev ir tiesības pārnest savus datus", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Eksportēt profilu (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Eksportēt augšupielādēto saturu (.zip)", "consent.export_posts": "Eksportēt rakstus (.csv)" } \ No newline at end of file diff --git a/public/language/ms/user.json b/public/language/ms/user.json index c4acf0c8f7..24fb25b7a4 100644 --- a/public/language/ms/user.json +++ b/public/language/ms/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/nb/user.json b/public/language/nb/user.json index 93abc8ab47..a37d074181 100644 --- a/public/language/nb/user.json +++ b/public/language/nb/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/nl/user.json b/public/language/nl/user.json index 1b5c37caf7..75b04d1586 100644 --- a/public/language/nl/user.json +++ b/public/language/nl/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Uw toestemming om gegevens te verzamelen en te verwerken kunt u op ieder moment intrekken door uw account te verwijderen. Uw individuele profiel kan worden verwijderd hoewel uw berichten blijven staan. Als u zowel uw account en uw berichten wilt verwijderen, neem dan contact op met het administrator team van deze website.", "consent.right_to_data_portability": "U hebt Recht op Dataportabiliteit", "consent.right_to_data_portability_description": "U kan van ons machine-leesbare export opvragen van verzamelde gegevens van u en uw account. U kan dit doen door te klikken op de van toepassing zijnde knop hieronder.", - "consent.export_profile": "Exporteer profiel (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exporteer geuploade inhoud (.zip)", "consent.export_posts": "Exporteer berichten (.csv)" } \ No newline at end of file diff --git a/public/language/pl/user.json b/public/language/pl/user.json index d5346c094c..4db229c546 100644 --- a/public/language/pl/user.json +++ b/public/language/pl/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Możesz w każdej chwili cofnąć zgodę na gromadzenie lub przetwarzanie danych poprzez usunięcie konta. Twój profil zostanie usunięty, ale zamieszczone przez Ciebie treści pozostaną dostępne. Jeśli chcesz usunąć swoje konto oraz swoje treści, skontaktuj się z administratorami tej strony.", "consent.right_to_data_portability": "Masz prawo do przenoszenia danych", "consent.right_to_data_portability_description": "Możesz poprosić nas o eksport wszelkich danych gromadzonych na temat Ciebie i Twojego konta w formie do odczytu elektronicznego. W tym celu kliknij stosowny przycisk poniżej.", - "consent.export_profile": "Eksportuj profil (csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Eksportuj przesłane treści (zip)", "consent.export_posts": "Eksportuj wpisy (csv)" } \ No newline at end of file diff --git a/public/language/pt-BR/user.json b/public/language/pt-BR/user.json index 5a93b3a45b..e99077931d 100644 --- a/public/language/pt-BR/user.json +++ b/public/language/pt-BR/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "A qualquer momento, você pode revogar o consentimento à coleta e/ou ao processamento de dados excluindo sua conta. Seu perfil individual pode ser excluído, no entanto, as suas postagens serão mantidas. Se você desejar deletar tanto a sua conta e as suas postagens, por favor, entre em contato com a equipe administrativa deste site.", "consent.right_to_data_portability": "Você tem o Direito de Portabilidade de Dados", "consent.right_to_data_portability_description": "Você pode solicitar de nós uma exportação legível por máquina de quaisquer dados coletados sobre você e sua conta. Você pode fazer isso clicando no botão apropriado abaixo.", - "consent.export_profile": "Exportar Perfil (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportar Arquivos Enviados (.zip)", "consent.export_posts": "Exportar Posts (.csv)" } \ No newline at end of file diff --git a/public/language/pt-PT/user.json b/public/language/pt-PT/user.json index d8edd4e954..6758cfa54a 100644 --- a/public/language/pt-PT/user.json +++ b/public/language/pt-PT/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Exportar Perfil (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportar Arquivos Enviados (.zip)", "consent.export_posts": "Exportar Publicações (.csv)" } \ No newline at end of file diff --git a/public/language/ro/user.json b/public/language/ro/user.json index f762e7e3c8..1049991c6e 100644 --- a/public/language/ro/user.json +++ b/public/language/ro/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/ru/user.json b/public/language/ru/user.json index 98c4cfba66..116a50253b 100644 --- a/public/language/ru/user.json +++ b/public/language/ru/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "В любое время вы можете отозвать свое согласие на сбор и/или обработку данных, удалив свою учётную запись. Ваш индивидуальный профиль можно удалить, хотя ваши сообщения останутся. Если вы хотите удалить как свою учётную запись, так и контент, пожалуйста, свяжитесь с администрацией сайта.", "consent.right_to_data_portability": "У вас есть право на перенос данных", "consent.right_to_data_portability_description": "Вы можете запросить у нас машиночитаемый экспорт любых собранных данных о вас и вашей учетной записи. Вы можете сделать это, нажав соответствующую кнопку ниже.", - "consent.export_profile": "Экспорт профиля (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Экспорт загруженного контента (.zip)", "consent.export_posts": "Экспорт сообщений (.csv)" } \ No newline at end of file diff --git a/public/language/rw/user.json b/public/language/rw/user.json index fbe6bb752e..964e2ba881 100644 --- a/public/language/rw/user.json +++ b/public/language/rw/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/sc/user.json b/public/language/sc/user.json index 07f11da723..edaacd7153 100644 --- a/public/language/sc/user.json +++ b/public/language/sc/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/sk/user.json b/public/language/sk/user.json index 4f37bfc7d0..4f7e6b9345 100644 --- a/public/language/sk/user.json +++ b/public/language/sk/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Kedykoľvek môžete zmeniť svoj súhlas so zhromažďovaním údajov a/alebo spracovaním odstránenia Vášho účtu. Váš profil bude odstránený, hoci Vaše príspevky budú zachované. Ak si prajete odstránenie ako účtu tak aj obsahu, prosím kontaktujte správcov tejto stránky.", "consent.right_to_data_portability": "Máte právo na prenositeľnosť údajov ", "consent.right_to_data_portability_description": "Môžete od nás požadovať strojovo čitateľné údaje, ktoré boli zozbierané o Vás a Vašom účte. Urobíte tak kliknutím na tlačidlá zobrazené nižšie.", - "consent.export_profile": "Exportovať profil (*.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportovať nahraný obsah (*.zip)", "consent.export_posts": "Exportovať príspevky (*.csv)" } \ No newline at end of file diff --git a/public/language/sl/user.json b/public/language/sl/user.json index f9fd1d9234..3e61bf35e8 100644 --- a/public/language/sl/user.json +++ b/public/language/sl/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/sr/user.json b/public/language/sr/user.json index da0034f309..6d401d9a35 100644 --- a/public/language/sr/user.json +++ b/public/language/sr/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "У било које време, у могућности сте да опозовете вашу сагласност за прикупљање и/или обраду података брисањем вашег налога. Ваш појединачни профил може бити избрисан, иако ће ваш објављени садржај остати. Ако желите да избришете и свој налог и садржај, молимо контактирајте администрацију овог веб сајта.", "consent.right_to_data_portability": "Имате право на преносивост података", "consent.right_to_data_portability_description": "Можете тражити од нас машински читљив извоз прикупљених података о вама и вашем налогу. То можете урадити кликом на одговарајуће дугме испод.", - "consent.export_profile": "Извези профил (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Извези отпремљени садржај (.zip)", "consent.export_posts": "Извези поруке (.csv)" } \ No newline at end of file diff --git a/public/language/sv/user.json b/public/language/sv/user.json index fe3974fd85..747f1b07c4 100644 --- a/public/language/sv/user.json +++ b/public/language/sv/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Du kan när som helst ta tillbaka ditt medgivande till datainsamling och/eller behandling genom att radera ditt konto. Din individuella profil kan raderas, men innehåll du lagt upp kommer bestå. Om du vill radera både din profiloch ditt innehåll, vänligen kontakta detta forums administrativa team.", "consent.right_to_data_portability": "Du har rätten till dataförflyttbarhet", "consent.right_to_data_portability_description": "Du kan hämta en maskinläslig export av all insamlad data om dig och ditt konto. Du kan göra det genom att klicka på passande knapp nedan.", - "consent.export_profile": "Exportera profil (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Exportera uppladdat innehåll (.zip)", "consent.export_posts": "Exportera poster (.csv)" } \ No newline at end of file diff --git a/public/language/th/user.json b/public/language/th/user.json index 22eafa6028..293dad9aed 100644 --- a/public/language/th/user.json +++ b/public/language/th/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "At any time, you are able to revoke your consent to data collection and/or processing by deleting your account. Your individual profile can be deleted, although your posted content will remain. If you wish to delete both your account and your content, please contact the administrative team for this website.", "consent.right_to_data_portability": "You have the Right to Data Portability", "consent.right_to_data_portability_description": "You may request from us a machine-readable export of any collected data about you and your account. You can do so by clicking the appropriate button below.", - "consent.export_profile": "Export Profile (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Export Uploaded Content (.zip)", "consent.export_posts": "Export Posts (.csv)" } \ No newline at end of file diff --git a/public/language/tr/user.json b/public/language/tr/user.json index 37a1378e25..422585cb1c 100644 --- a/public/language/tr/user.json +++ b/public/language/tr/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Herhangi bir zamanda, hesabınızı silerek veri toplama ve / veya işlemeye onayınızı iptal edebilirsiniz. Gönderilen içeriğiniz kalsa da, bireysel profiliniz silinebilir. Hem hesabınızı hem de içeriğinizi silmek isterseniz, lütfen bu web sitesi için yönetim ekibine başvurun.", "consent.right_to_data_portability": "Veri taşıma hakkına sahipsiniz", "consent.right_to_data_portability_description": "Sizden ve hesabınız hakkında toplanan verilere makine tarafından okunabilir bir veri talep edebilirsiniz. Aşağıdaki uygun düğmeyi tıklayarak bunu yapabilirsiniz.", - "consent.export_profile": "Profili Dışarı Çıkar (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Karşıya Yüklenmiş İçeriği Dışarı Aktar (.zip)", "consent.export_posts": "Gönderileri Dışa Aktar (.csv)" } \ No newline at end of file diff --git a/public/language/uk/user.json b/public/language/uk/user.json index 961edbaa4a..565ad2cd18 100644 --- a/public/language/uk/user.json +++ b/public/language/uk/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "У будь-який час ви можете відкликати свою згоду на збір та/або обробку інформації шляхом видалення власного акаунту. Ваш особистий профіль можна видалити, але розміщений вами контент залишиться. Якщо ви хочете видалити ваш акаунт разом з контентом, будь-ласка зверніться до команди адміністраторів цього веб-сайту.", "consent.right_to_data_portability": "У вас є Право на Переносимість Даних", "consent.right_to_data_portability_description": "Ви можете отримати від нас експортовану копію машинно-читабельних даних, які були зібрані про вас і ваш акаунт. Ви можете це зробити, натиснувши на відповідну кнопку внизу.", - "consent.export_profile": "Експортувати Профіль (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Експортувати Завантажений Контент (.zip)", "consent.export_posts": "Експортувати Пости (.csv)" } \ No newline at end of file diff --git a/public/language/vi/user.json b/public/language/vi/user.json index da7837e5de..eac4a6f330 100644 --- a/public/language/vi/user.json +++ b/public/language/vi/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "Bất cứ lúc nào, bạn có thể thu hồi sự đồng ý của bạn để thu thập và / hoặc xử lý dữ liệu bằng cách xóa tài khoản của bạn. Hồ sơ cá nhân của bạn có thể bị xóa, mặc dù nội dung được đăng của bạn sẽ vẫn còn. Nếu bạn muốn xóa cả tài khoản nội dung của mình, vui lòng liên hệ với nhóm quản trị cho trang web này.", "consent.right_to_data_portability": "Bạn có quyền di chuyển dữ liệu", "consent.right_to_data_portability_description": "Bạn có thể yêu cầu chúng tôi xuất khẩu có thể đọc được bằng máy đối với bất kỳ dữ liệu được thu thập nào về bạn và tài khoản của bạn. Bạn có thể làm như vậy bằng cách nhấp vào nút thích hợp bên dưới.", - "consent.export_profile": "Xuất hồ sơ(.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "Xuất nội dung đã tải lên (.zip)", "consent.export_posts": "Xuất bài viết (.csv)" } \ No newline at end of file diff --git a/public/language/zh-CN/user.json b/public/language/zh-CN/user.json index 6dae66f4ba..e251ae2846 100644 --- a/public/language/zh-CN/user.json +++ b/public/language/zh-CN/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "您随时都可以通过删除帐号,来撤销数据收集和处理的许可。您的个人资料可以被删除,但是您发表的内容仍然会保留。如果您想要同时删除您的帐号内容,请联系此网站的管理团队。", "consent.right_to_data_portability": "您拥有数据转移权", "consent.right_to_data_portability_description": "您也许想导出有关您和您的账号的机器可读副本。您可以点击下方的按钮来获取它们。", - "consent.export_profile": "导出个人资料 (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "导出上传文件 (.zip)", "consent.export_posts": "导出帖子 (.csv)" } \ No newline at end of file diff --git a/public/language/zh-TW/user.json b/public/language/zh-TW/user.json index 58eba30922..902545924c 100644 --- a/public/language/zh-TW/user.json +++ b/public/language/zh-TW/user.json @@ -170,7 +170,7 @@ "consent.right_to_erasure_description": "您隨時都可以通過刪除帳戶,來撤銷資料收集和處理的許可。您的個人檔案可以被刪除,但是您發表的內容仍然會保留。如果您想要同時刪除您的帳戶內容,請聯繫此網站的管理團隊。", "consent.right_to_data_portability": "您擁有資料轉移權", "consent.right_to_data_portability_description": "您也許想導出有關您和您的帳戶的機器可讀副本。您可以點擊下方的按鈕來獲取它們。", - "consent.export_profile": "導出個人資料 (.csv)", + "consent.export_profile": "Export Profile (.json)", "consent.export_uploads": "導出上傳檔案 (.zip)", "consent.export_posts": "導出貼文 (.csv)" } \ No newline at end of file From 2587112f9d7f00e42e17279163797b3b466137fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 16 May 2020 09:36:17 -0400 Subject: [PATCH 15/26] feat: if only one value is passed used faster function --- src/database/mongo/sorted.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 672de041be..67a3e074d8 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -235,24 +235,25 @@ module.exports = function (module) { } module.sortedSetRanks = async function (key, values) { - return await sortedSetRanks(module.getSortedSetRange, key, values); + return await sortedSetRanks(false, key, values); }; module.sortedSetRevRanks = async function (key, values) { - return await sortedSetRanks(module.getSortedSetRevRange, key, values); + return await sortedSetRanks(true, key, values); }; - async function sortedSetRanks(method, key, values) { - const sortedSet = await method(key, 0, -1); - - var result = values.map(function (value) { + async function sortedSetRanks(reverse, key, values) { + if (values.length === 1) { + return [await getSortedSetRank(reverse, key, values[0])]; + } + const sortedSet = await module[reverse ? 'getSortedSetRevRange' : 'getSortedSetRange'](key, 0, -1); + return values.map(function (value) { if (!value) { return null; } - var index = sortedSet.indexOf(value.toString()); + const index = sortedSet.indexOf(value.toString()); return index !== -1 ? index : null; }); - return result; } module.sortedSetScore = async function (key, value) { From a0d76ff0a664cd5988515ebd7b2a39c40b45fc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 16 May 2020 20:20:47 -0400 Subject: [PATCH 16/26] fix: #8318, clean expired sessions on login and get --- src/user/auth.js | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/user/auth.js b/src/user/auth.js index a9874ab79c..bc7126dad2 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -66,43 +66,44 @@ module.exports = function (User) { const sessionStoreDestroy = util.promisify((sid, callback) => db.sessionStore.destroy(sid, err => callback(err))); User.auth.getSessions = async function (uid, curSessionId) { + await cleanExpiredSessions(uid); const sids = await db.getSortedSetRevRange('uid:' + uid + ':sessions', 0, 19); let sessions = await Promise.all(sids.map(sid => getSessionFromStore(sid))); - sessions.forEach(function (sessionObj, idx) { - if (sessionObj && sessionObj.meta) { - sessionObj.meta.current = curSessionId === sids[idx]; - } - }); - - // Revoke any sessions that have expired, return filtered list - const expiredSids = []; - sessions = sessions.filter(function (sessionObj, idx) { - const expired = !sessionObj || !sessionObj.hasOwnProperty('passport') || - !sessionObj.passport.hasOwnProperty('user') || - parseInt(sessionObj.passport.user, 10) !== parseInt(uid, 10); - - if (expired) { - expiredSids.push(sids[idx]); - } - - return !expired; - }); - await Promise.all(expiredSids.map(s => User.auth.revokeSession(s, uid))); - - sessions = sessions.map(function (sessObj) { - if (sessObj.meta) { + sessions = sessions.map(function (sessObj, idx) { + if (sessObj && sessObj.meta) { + sessObj.meta.current = curSessionId === sids[idx]; sessObj.meta.datetimeISO = new Date(sessObj.meta.datetime).toISOString(); sessObj.meta.ip = validator.escape(String(sessObj.meta.ip)); } - return sessObj.meta; + return sessObj && sessObj.meta; }).filter(Boolean); return sessions; }; + async function cleanExpiredSessions(uid) { + const uuidMapping = await db.getObject('uid:' + uid + ':sessionUUID:sessionId'); + const expiredUUIDs = []; + const expiredSids = []; + await Promise.all(Object.keys(uuidMapping).map(async (uuid) => { + const sid = uuidMapping[uuid]; + const sessionObj = await getSessionFromStore(sid); + const expired = !sessionObj || !sessionObj.hasOwnProperty('passport') || + !sessionObj.passport.hasOwnProperty('user') || + parseInt(sessionObj.passport.user, 10) !== parseInt(uid, 10); + if (expired) { + expiredUUIDs.push(uuid); + expiredSids.push(sid); + } + })); + await db.deleteObjectFields('uid:' + uid + ':sessionUUID:sessionId', expiredUUIDs); + await db.sortedSetRemove('uid:' + uid + ':sessions', expiredSids); + } + User.auth.addSession = async function (uid, sessionId) { if (!(parseInt(uid, 10) > 0)) { return; } + await cleanExpiredSessions(uid); await db.sortedSetAdd('uid:' + uid + ':sessions', Date.now(), sessionId); }; From 8bf980cb6365956648cfc37027b75a709b537438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 16 May 2020 22:17:20 -0400 Subject: [PATCH 17/26] fix: tests, handle no sessions --- src/controllers/authentication.js | 4 +++- src/user/auth.js | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index 29eb6603c9..2256b6b905 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -350,10 +350,12 @@ authenticationController.onSuccessfulLogin = async function (req, uid) { }); await Promise.all([ user.auth.addSession(uid, req.sessionID), - (uid > 0) ? db.setObjectField('uid:' + uid + ':sessionUUID:sessionId', uuid, req.sessionID) : null, user.updateLastOnlineTime(uid), user.updateOnlineUsers(uid), ]); + if (uid > 0) { + await db.setObjectField('uid:' + uid + ':sessionUUID:sessionId', uuid, req.sessionID); + } // Force session check for all connected socket.io clients with the same session id sockets.in('sess_' + req.sessionID).emit('checkSession', uid); diff --git a/src/user/auth.js b/src/user/auth.js index bc7126dad2..da8551d831 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -82,6 +82,9 @@ module.exports = function (User) { async function cleanExpiredSessions(uid) { const uuidMapping = await db.getObject('uid:' + uid + ':sessionUUID:sessionId'); + if (!uuidMapping) { + return; + } const expiredUUIDs = []; const expiredSids = []; await Promise.all(Object.keys(uuidMapping).map(async (uuid) => { From 7a801abade51f8cb65f937064beed4323b9a144f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sat, 16 May 2020 22:49:34 -0400 Subject: [PATCH 18/26] fix: tests on redis --- src/database/redis/hash.js | 3 +++ test/database/hash.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/database/redis/hash.js b/src/database/redis/hash.js index 6dc2444283..afa2b7e016 100644 --- a/src/database/redis/hash.js +++ b/src/database/redis/hash.js @@ -154,6 +154,9 @@ module.exports = function (module) { }; module.deleteObjectFields = async function (key, fields) { + if (!Array.isArray(fields) || !fields.length) { + return; + } await module.client.async.hdel(key, fields); cache.delObjectCache(key); }; diff --git a/test/database/hash.js b/test/database/hash.js index 5c33ef91a3..b6aba5852f 100644 --- a/test/database/hash.js +++ b/test/database/hash.js @@ -410,6 +410,10 @@ describe('Hash methods', function () { }); }); + it('should not error if fields is empty array', async () => { + await db.deleteObjectFields('someKey', []); + }); + it('should not error if key is undefined', function (done) { db.deleteObjectField(undefined, 'someField', function (err) { assert.ifError(err); From 0437ecc2ea9158cc41927f1006384c2bda0941b0 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 17 May 2020 14:40:46 +0000 Subject: [PATCH 19/26] fix(deps): update dependency sharp to v0.25.3 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index 4aebe67aac..e82356f5e3 100644 --- a/install/package.json +++ b/install/package.json @@ -110,7 +110,7 @@ "sanitize-html": "^1.23.0", "semver": "^7.2.1", "serve-favicon": "^2.5.0", - "sharp": "0.25.2", + "sharp": "0.25.3", "sitemap": "^6.1.0", "socket.io": "2.3.0", "socket.io-adapter-cluster": "^1.0.1", From ae2db423ee812472119fa2810cb83d5996fc408e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 17 May 2020 14:56:42 -0400 Subject: [PATCH 20/26] feat: cookie SameSite property More information: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1 https://web.dev/samesite-cookies-explained/ --- src/meta/configs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/meta/configs.js b/src/meta/configs.js index c28d3e2ff8..da07f68fbd 100644 --- a/src/meta/configs.js +++ b/src/meta/configs.js @@ -164,6 +164,9 @@ Configs.cookie = { cookie.path = relativePath; } + // Ideally configurable from ACP, but cannot be "Strict" as then top-level access will treat it as guest. + cookie.sameSite = 'Lax'; + return cookie; }, }; From a532e2bb838229a10e9b4296452cfe1a2d1c3b8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:52:01 -0400 Subject: [PATCH 21/26] fix(deps): update dependency postcss to v7.0.30 (#8288) Co-authored-by: Renovate Bot --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index e82356f5e3..35c3554369 100644 --- a/install/package.json +++ b/install/package.json @@ -98,7 +98,7 @@ "passport-local": "1.0.0", "pg": "^8.0.2", "pg-cursor": "^2.1.9", - "postcss": "7.0.27", + "postcss": "7.0.30", "postcss-clean": "1.1.0", "promise-polyfill": "^8.1.3", "prompt": "^1.0.0", From 12c6bc2e072b97b871bca6634e647010bb246882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 19 May 2020 00:22:54 -0400 Subject: [PATCH 22/26] feat: convert queries so they used indices directly --- src/database/mongo/sorted.js | 20 ++++++++++++++++---- src/database/mongo/sorted/union.js | 1 - test/database/sorted.js | 21 ++++++--------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 67a3e074d8..2899a86188 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -306,7 +306,11 @@ module.exports = function (module) { return; } value = helpers.valueToString(value); - const result = await module.client.collection('objects').findOne({ _key: key, value: value }, { projection: { _id: 0, _key: 0, score: 0 } }); + const result = await module.client.collection('objects').findOne({ + _key: key, value: value, + }, { + projection: { _id: 0, value: 1 }, + }); return !!result; }; @@ -315,7 +319,11 @@ module.exports = function (module) { return; } values = values.map(helpers.valueToString); - const results = await module.client.collection('objects').find({ _key: key, value: { $in: values } }, { projection: { _id: 0, _key: 0, score: 0 } }).toArray(); + const results = await module.client.collection('objects').find({ + _key: key, value: { $in: values }, + }, { + projection: { _id: 0, value: 1 }, + }).toArray(); var isMember = {}; results.forEach(function (item) { @@ -332,7 +340,11 @@ module.exports = function (module) { return []; } value = helpers.valueToString(value); - const results = await module.client.collection('objects').find({ _key: { $in: keys }, value: value }, { projection: { _id: 0, score: 0 } }).toArray(); + const results = await module.client.collection('objects').find({ + _key: { $in: keys }, value: value, + }, { + projection: { _id: 0, _key: 1, value: 1 }, + }).toArray(); var isMember = {}; results.forEach(function (item) { @@ -351,7 +363,7 @@ module.exports = function (module) { const data = await module.client.collection('objects').find({ _key: keys.length === 1 ? keys[0] : { $in: keys }, - }, { projection: { _id: 0, score: 0 } }).sort({ score: 1 }).toArray(); + }, { projection: { _id: 0, _key: 1, value: 1 } }).toArray(); var sets = {}; data.forEach(function (set) { diff --git a/src/database/mongo/sorted/union.js b/src/database/mongo/sorted/union.js index 116e1e011f..523d37ee16 100644 --- a/src/database/mongo/sorted/union.js +++ b/src/database/mongo/sorted/union.js @@ -10,7 +10,6 @@ module.exports = function (module) { { $match: { _key: { $in: keys } } }, { $group: { _id: { value: '$value' } } }, { $group: { _id: null, count: { $sum: 1 } } }, - { $project: { _id: 0, count: '$count' } }, ]).toArray(); return Array.isArray(data) && data.length ? data[0].count : 0; }; diff --git a/test/database/sorted.js b/test/database/sorted.js index 922c70a9cb..c8d3d4c5cf 100644 --- a/test/database/sorted.js +++ b/test/database/sorted.js @@ -992,21 +992,12 @@ describe('Sorted Set methods', function () { }); }); - it('should remove value from multiple keys', function (done) { - db.sortedSetAdd('multiTest3', [1, 2, 3, 4], ['one', 'two', 'three', 'four'], function (err) { - assert.ifError(err); - db.sortedSetAdd('multiTest4', [3, 4, 5, 6], ['three', 'four', 'five', 'six'], function (err) { - assert.ifError(err); - db.sortedSetRemove(['multiTest3', 'multiTest4'], 'three', function (err) { - assert.ifError(err); - db.getSortedSetsMembers(['multiTest3', 'multiTest4'], function (err, members) { - assert.ifError(err); - assert.deepEqual(members, [['one', 'two', 'four'], ['four', 'five', 'six']]); - done(); - }); - }); - }); - }); + it('should remove value from multiple keys', async function () { + await db.sortedSetAdd('multiTest3', [1, 2, 3, 4], ['one', 'two', 'three', 'four']); + await db.sortedSetAdd('multiTest4', [3, 4, 5, 6], ['three', 'four', 'five', 'six']); + await db.sortedSetRemove(['multiTest3', 'multiTest4'], 'three'); + assert.deepStrictEqual(await db.getSortedSetRange('multiTest3', 0, -1), ['one', 'two', 'four']); + assert.deepStrictEqual(await db.getSortedSetRange('multiTest4', 0, -1), ['four', 'five', 'six']); }); it('should remove multiple values from multiple keys', function (done) { From 2203398efcdb666b693fcbe0d58cea17a6a17c7c Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Tue, 19 May 2020 09:29:49 +0000 Subject: [PATCH 23/26] Latest translations and fallbacks --- public/language/de/admin/advanced/events.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/public/language/de/admin/advanced/events.json b/public/language/de/admin/advanced/events.json index 112bdb4993..0390a4d2cb 100644 --- a/public/language/de/admin/advanced/events.json +++ b/public/language/de/admin/advanced/events.json @@ -2,10 +2,10 @@ "events": "Ereignisse", "no-events": "Es gibt keine Ereignisse", "control-panel": "Ereignis-Steuerung", - "filters": "Filters", - "filters-apply": "Apply Filters", - "filter-type": "Event Type", - "filter-start": "Start Date", - "filter-end": "End Date", - "filter-perPage": "Per Page" + "filters": "Filter", + "filters-apply": "Filter anwenden", + "filter-type": "Ereignistyp", + "filter-start": "Start-Datum", + "filter-end": "End-Datum", + "filter-perPage": "Pro Seite" } \ No newline at end of file From 4263efa091f2f370e10243bedda72d6469d47b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 19 May 2020 14:18:07 -0400 Subject: [PATCH 24/26] feat: don't overwrite req.query.lang if it exists --- src/middleware/headers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/middleware/headers.js b/src/middleware/headers.js index e1486145fa..a3642f3fbb 100644 --- a/src/middleware/headers.js +++ b/src/middleware/headers.js @@ -73,11 +73,11 @@ module.exports = function (middleware) { let langs = []; middleware.autoLocale = function autoLocale(req, res, next) { - if (parseInt(req.uid, 10) > 0 || !meta.config.autoDetectLang) { + if (parseInt(req.uid, 10) > 0 || !meta.config.autoDetectLang || req.query.lang) { return next(); } - var lang = req.acceptsLanguages(langs); + const lang = req.acceptsLanguages(langs); if (!lang) { return next(); } From bf8a2c2e9edd8a0c95a185c5a05ea651612c3e05 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 19 May 2020 16:44:52 +0000 Subject: [PATCH 25/26] fix(deps): update dependency nodebb-plugin-composer-default to v6.3.29 --- install/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/package.json b/install/package.json index 35c3554369..825b154812 100644 --- a/install/package.json +++ b/install/package.json @@ -79,7 +79,7 @@ "mousetrap": "^1.6.5", "@nodebb/mubsub": "^1.6.0", "nconf": "^0.10.0", - "nodebb-plugin-composer-default": "6.3.28", + "nodebb-plugin-composer-default": "6.3.29", "nodebb-plugin-dbsearch": "4.0.7", "nodebb-plugin-emoji": "^3.3.0", "nodebb-plugin-emoji-android": "2.0.0", From 2a00b0e973ca6f2d04482f037afda5bc7a22b6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 19 May 2020 17:42:44 -0400 Subject: [PATCH 26/26] fix: utils.params({url: ''}) --- public/src/utils.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/public/src/utils.js b/public/src/utils.js index b71c9dda48..47fd4f9a73 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -661,17 +661,21 @@ // get all the url params in a single key/value hash params: function (options) { - var a; var hash = {}; - var params; options = options || {}; options.skipToType = options.skipToType || {}; - if (options.url) { - a = utils.urlToLocation(options.url); + var searchStr = window.location.search; + if (options.hasOwnProperty('url')) { + if (options.url) { + var a = utils.urlToLocation(options.url); + searchStr = a ? a.search : ''; + } else { + searchStr = ''; + } } - params = (a ? a.search : window.location.search).substring(1).split('&'); + var params = searchStr.substring(1).split('&'); params.forEach(function (param) { var val = param.split('=');